internal static MidiFileData ReadMidiFile(string filePath) { var data = new MidiFileData(); var reader = FileReaderFactory.CreateReader(filePath); data.Header = reader.ReadNextChunk() as MThdChunk; var tracks = new List <MTrkChunk>(); for (int i = 0; i < data.Header.NumberOfTracks; i++) { try { var track = reader.ReadNextChunk() as MTrkChunk; if (track != null) { tracks.Add(track); } else { Console.WriteLine(String.Format("Track '{0}' was not read successfully.", i + 1)); } } catch (Exception e) { reader.SkipCurrentChunk(); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Failed to read track: " + (i + 1)); Console.WriteLine(e); Console.ForegroundColor = ConsoleColor.Gray; } } data.Tracks = tracks; return(data); }
private static MidiOutPortBase ProcessStreaming(int outPortId, MidiFileData fileData, IEnumerable <MidiFileEvent> notes, MidiOutPortCaps caps) { var outPort = new MidiOutStreamPort(); outPort.Open(outPortId); outPort.BufferManager.Initialize(10, 1024); outPort.TimeDivision = fileData.Header.TimeDivision; // TODO: extract Tempo from meta messages from the file. // 120 bpm (uSec/QuarterNote). outPort.Tempo = 500000; Console.WriteLine(String.Format("Midi Out Stream Port '{0}' is now open.", caps.Name)); MidiMessageOutStreamWriter writer = null; MidiBufferStream buffer = null; MidiFileEvent lastNote = null; foreach (var note in notes) { if (writer == null) { // brute force buffer aqcuirement. // when callbacks are implemented this will be more elegant. do { buffer = outPort.BufferManager.RetrieveBuffer(); if (buffer != null) { break; } Thread.Sleep(50); } while (buffer == null); writer = new MidiMessageOutStreamWriter(buffer); } if (writer.CanWrite(note.Message)) { if (lastNote != null) { // fixup delta time artifically... writer.Write(note.Message, (int)(note.AbsoluteTime - lastNote.AbsoluteTime)); } else { writer.Write(note.Message, (int)note.DeltaTime); } } else { outPort.LongData(buffer); writer = null; Console.WriteLine("Buffer sent..."); if (!outPort.HasStatus(MidiPortStatus.Started)) { outPort.Restart(); } } lastNote = note; } return(outPort); }