public static void Main(string[] args) { string midiFileName = null; int outPortId = 0; if (args.Length > 0) { midiFileName = args[0]; } if (args.Length > 1) { outPortId = Int16.Parse(args[1]); } if (args.Length <= 0) { Console.WriteLine("Usage: MidiFilePlayer 'C:\\Folder\\MidiFile.mid' [MidiOutPortId]"); return; } Console.WriteLine("Reading midi file: " + midiFileName); var fileData = ReadMidiFile(midiFileName); IEnumerable <MidiFileEvent> notes = null; // merge all track notes and filter out sysex and meta events foreach (var track in fileData.Tracks) { if (notes == null) { notes = from note in track.Events where !(note.Message is MidiLongMessage) select note; } else { notes = (from note in track.Events where !(note.Message is MidiLongMessage) select note).Union(notes); } } // order track notes by absolute-time. notes = from note in notes orderby note.AbsoluteTime select note; // At this point the DeltaTime properties are invalid because other events from other // tracks are now merged between notes where the initial delta-time was calculated for. // We fix this in the play back routine. WriteHeaderInfoToConsole(fileData.Header); var caps = MidiOutPort.GetPortCapabilities(outPortId); MidiOutPortBase outPort = null; try { outPort = ProcessStreaming(outPortId, fileData, notes, caps); } catch (Exception e) { Console.WriteLine(); Console.WriteLine(e.ToString()); } Console.WriteLine("Press any key to exit..."); Console.ReadKey(); if (outPort != null) { outPort.Reset(); if (!outPort.BufferManager.WaitForBuffersReturned(1000)) { Console.WriteLine("Buffers failed to return in 1 sec."); } outPort.Close(); outPort.Dispose(); } }