public void Import( EditorFile file, string filename, PorterOptions options ) { var midifile = new MidiFile(filename, false); var trackcontainer = file[TrackControllerContainer.ItemName] as TrackControllerContainer; var musictrackfactory = trackcontainer .Tracks .FactorySet .Factories .FirstOrDefault(_ => _ is MusicTrackFactory) .Name; for (int track_index = 0; track_index < midifile.Tracks; track_index++) { var events = midifile.Events.GetTrackEvents(track_index); var track = (MusicTrack)trackcontainer.Tracks.Create(musictrackfactory); foreach (var e in events) { switch (e.CommandCode) { case MidiCommandCode.NoteOn: { var e1 = (NoteOnEvent)e; var start = ImportTime(e1.AbsoluteTime, midifile); var length = ImportTime(e1.NoteLength, midifile); var duration = new Duration { Start = start, Length = length }; track.Melody.AddNote(new SemiTone(e1.NoteNumber - 12), duration); break; } case MidiCommandCode.NoteOff: { var e1 = (NoteEvent)e; break; } case MidiCommandCode.MetaEvent: { var meta = (MetaEvent)e; switch (meta.MetaEventType) { case MetaEventType.Copyright: break; case MetaEventType.CuePoint: break; case MetaEventType.DeviceName: break; case MetaEventType.EndTrack: break; case MetaEventType.KeySignature: { var keysigevent = (KeySignatureEvent)meta; var circle5index = (sbyte)keysigevent.SharpsFlats; Mode mode; switch (keysigevent.MajorMinor) { case 1: mode = Mode.Major; break; case 0: mode = Mode.Minor; break; default: throw new InvalidOperationException(); } PitchTransform transform; var key = CircleOfFifths.Index(circle5index, ChromaticPitchClass.C, out transform); var sig = KeySignature.Create( key, transform, mode ); var start = ImportTime(keysigevent.AbsoluteTime, midifile); track .Adornment .KeySignatures .OverwriteEverythingToRight( sig, start ); break; } case MetaEventType.Lyric: break; case MetaEventType.Marker: break; case MetaEventType.MidiChannel: break; case MetaEventType.MidiPort: break; case MetaEventType.ProgramName: break; case MetaEventType.SequencerSpecific: break; case MetaEventType.SequenceTrackName: { var text = (TextEvent)meta; track.Name.Value = text.Text; break; } case MetaEventType.SetTempo: var tempoevent = meta as TempoEvent; // Can midi files have linear varying tempos? // if so, then this code doesn't handle all midis. if (options.PortTempo) { track .Tempo .SetTempo( ImportTime(tempoevent.AbsoluteTime, midifile), (float)tempoevent.Tempo / 4 ); } break; case MetaEventType.SmpteOffset: break; case MetaEventType.TextEvent: break; case MetaEventType.TimeSignature: var timesigevent = (TimeSignatureEvent)meta; var timesig = new TimeSignature( new Simple( timesigevent.Numerator, timesigevent.Denominator ) ); track .Rhythm .TimeSignatures .OverwriteEverythingToRight( timesig, ImportTime(timesigevent.AbsoluteTime, midifile) ); break; case MetaEventType.TrackInstrumentName: break; case MetaEventType.TrackSequenceNumber: break; default: throw new InvalidOperationException(); } break; } case MidiCommandCode.PatchChange: { break; } case MidiCommandCode.ControlChange: { break; } default: throw new InvalidOperationException(); } } } }