private static Record ReadRecord( StreamReader streamReader, int lineNumber, MidiFileCsvConversionSettings settings) { var line = Enumerable.Range(0, int.MaxValue) .Select(i => new { LineNumber = lineNumber + i, Line = streamReader.ReadLine()?.Trim() }) .FirstOrDefault(l => l.Line != string.Empty); if (string.IsNullOrEmpty(line.Line)) { return(null); } var lineNumberOffset = 0; var parts = CsvUtilities.SplitCsvValues(line.Line, settings.CsvDelimiter, () => { var nextLine = streamReader.ReadLine(); if (nextLine != null) { lineNumberOffset++; } return(nextLine); }); if (parts.Length < 3) { ThrowBadFormat(line.LineNumber, "Missing required parameters."); } int parsedTrackNumber; var trackNumber = int.TryParse(parts[0], out parsedTrackNumber) ? (int?)parsedTrackNumber : null; ITimeSpan time = null; TimeSpanUtilities.TryParse(parts[1], settings.TimeType, out time); var recordType = parts[2]; if (string.IsNullOrEmpty(recordType)) { ThrowBadFormat(line.LineNumber, "Record type isn't specified."); } var parameters = parts.Skip(3).ToArray(); lineNumber = line.LineNumber + lineNumberOffset; return(new Record(line.LineNumber, trackNumber, time, recordType, parameters)); }
private static TimedMidiEvent[] ParseNote(Record record, MidiFileCsvConversionSettings settings) { if (record.TrackNumber == null) { CsvError.ThrowBadFormat(record.LineNumber, "Invalid track number."); } if (record.Time == null) { CsvError.ThrowBadFormat(record.LineNumber, "Invalid time."); } var parameters = record.Parameters; if (parameters.Length < 5) { CsvError.ThrowBadFormat(record.LineNumber, "Invalid number of parameters provided."); } var i = -1; try { var channel = (FourBitNumber)TypeParser.FourBitNumber(parameters[++i], settings); var noteNumber = (SevenBitNumber)TypeParser.NoteNumber(parameters[++i], settings); ITimeSpan length = null; TimeSpanUtilities.TryParse(parameters[++i], settings.NoteLengthType, out length); var velocity = (SevenBitNumber)TypeParser.SevenBitNumber(parameters[++i], settings); var offVelocity = (SevenBitNumber)TypeParser.SevenBitNumber(parameters[++i], settings); return(new[] { new TimedMidiEvent(record.Time, new NoteOnEvent(noteNumber, velocity) { Channel = channel }), new TimedMidiEvent(record.Time.Add(length, TimeSpanMode.TimeLength), new NoteOffEvent(noteNumber, offVelocity) { Channel = channel }), }); } catch { CsvError.ThrowBadFormat(record.LineNumber, $"Parameter ({i}) is invalid."); } return(null); }
public static void Parse(string input, ITimeSpan expectedTimeSpan) { TimeSpanUtilities.TryParse(input, out var actualTimeSpan); Assert.AreEqual(expectedTimeSpan, actualTimeSpan, "TryParse: incorrect result."); actualTimeSpan = TimeSpanUtilities.Parse(input); Assert.AreEqual(expectedTimeSpan, actualTimeSpan, "Parse: incorrect result."); Assert.AreEqual(expectedTimeSpan, TimeSpanUtilities.Parse(expectedTimeSpan.ToString()), "Parse: string representation was not parsed to the original time span."); }
private static Record ReadRecord(CsvReader csvReader, int lineNumber, MidiFileCsvConversionSettings settings) { var record = csvReader.ReadRecord(); if (record == null) { return(null); } var values = record.Values; if (values.Length < 3) { CsvError.ThrowBadFormat(record.LineNumber, "Missing required parameters."); } int parsedTrackNumber; var trackNumber = int.TryParse(values[0], out parsedTrackNumber) ? (int?)parsedTrackNumber : null; ITimeSpan time = null; TimeSpanUtilities.TryParse(values[1], settings.TimeType, out time); var recordType = values[2]; if (string.IsNullOrEmpty(recordType)) { CsvError.ThrowBadFormat(record.LineNumber, "Record type isn't specified."); } var parameters = values.Skip(3).ToArray(); return(new Record(record.LineNumber, trackNumber, time, recordType, parameters)); }
public static IEnumerable <Note> ConvertToNotes(Stream stream, TempoMap tempoMap, NoteCsvConversionSettings settings) { using (var csvReader = new CsvReader(stream, settings.CsvDelimiter)) { CsvRecord record = null; while ((record = csvReader.ReadRecord()) != null) { var values = record.Values; if (values.Length < 6) { CsvError.ThrowBadFormat(record.LineNumber, "Missing required parameters."); } ITimeSpan time; if (!TimeSpanUtilities.TryParse(values[0], settings.TimeType, out time)) { CsvError.ThrowBadFormat(record.LineNumber, "Invalid time."); } FourBitNumber channel; if (!FourBitNumber.TryParse(values[1], out channel)) { CsvError.ThrowBadFormat(record.LineNumber, "Invalid channel."); } SevenBitNumber noteNumber; if (!TryParseNoteNumber(values[2], settings.NoteNumberFormat, out noteNumber)) { CsvError.ThrowBadFormat(record.LineNumber, "Invalid note number or letter."); } ITimeSpan length; if (!TimeSpanUtilities.TryParse(values[3], settings.NoteLengthType, out length)) { CsvError.ThrowBadFormat(record.LineNumber, "Invalid length."); } SevenBitNumber velocity; if (!SevenBitNumber.TryParse(values[4], out velocity)) { CsvError.ThrowBadFormat(record.LineNumber, "Invalid velocity."); } SevenBitNumber offVelocity; if (!SevenBitNumber.TryParse(values[5], out offVelocity)) { CsvError.ThrowBadFormat(record.LineNumber, "Invalid off velocity."); } var convertedTime = TimeConverter.ConvertFrom(time, tempoMap); var convertedLength = LengthConverter.ConvertFrom(length, convertedTime, tempoMap); yield return(new Note(noteNumber, convertedLength, convertedTime) { Channel = channel, Velocity = velocity, OffVelocity = offVelocity }); } } }