/// <summary> /// Send a controller/pitch midi message. /// </summary> /// <param name="channel"></param> /// <param name="id"></param> /// <param name="value"></param> public void SendController(int channel, int id, int value) { if (_mdev != null) { lock (_lock) { if (id == NpMidiEventArgs.PITCH_CONTROL) { PitchWheelChangeEvent pevt = new PitchWheelChangeEvent(0, channel, value); int msg = pevt.GetAsShortMessage(); _mdev.Send(msg); } else { ControlChangeEvent nevt = new ControlChangeEvent(0, channel, (MidiController)id, value); int msg = nevt.GetAsShortMessage(); _mdev.Send(msg); } } } }
public void GetAsShortMessageReturnsCorrectValue() { int channel = 2; int pitch = 0x3FFF; // 0x2000 is the default PitchWheelChangeEvent p = new PitchWheelChangeEvent(0, channel, pitch); Assert.AreEqual(0x007F7FE1, p.GetAsShortMessage()); }
public bool Apply(MidiEvent inEvent, EventRuleArgs args) { bool match = false; if (inEvent.CommandCode == MidiCommandCode.PitchWheelChange) { PitchWheelChangeEvent pitchWheelEvent = (PitchWheelChangeEvent)inEvent; if (inChannels.IsValueIncluded(pitchWheelEvent.Channel)) { pitchWheelEvent.Pitch = outValue.ProcessValue(pitchWheelEvent.Pitch); pitchWheelEvent.Channel = outChannel.ProcessValue(pitchWheelEvent.Channel); match = true; } } return(match); }
public static MidiRResult ReadMidi(string MidiPath, string TrackName) { MidiFile midifile = new MidiFile(MidiPath); List <PitchWheelEvent> Pitchs = new List <PitchWheelEvent>(); List <NoteOnEvent> Notes = new List <NoteOnEvent>(); for (int t = 0; t < midifile.Tracks; t++) { List <MidiEvent> Events = (List <MidiEvent>)midifile.Events[t]; for (int i = 0; i < Events.Count; i++) { if (Events[i].GetType() == typeof(TextEvent)) { TextEvent te = (TextEvent)Events[i]; if (te.MetaEventType == MetaEventType.SequenceTrackName) { string trackname = te.Text; if (trackname != TrackName) { Pitchs.Clear(); Notes.Clear(); break; } } } else if (Events[i].GetType() == typeof(PitchWheelChangeEvent)) { PitchWheelChangeEvent pw = (PitchWheelChangeEvent)Events[i]; PitchWheelEvent pwe = new PitchWheelEvent(pw); pwe.PBS = 12; int EachNote = 8192 / 12; pwe.PIT = pwe.PitchWheelChangeEvent.Pitch - 8192; pwe.pNotePlus = pwe.PIT / EachNote; Pitchs.Add(pwe); } else if (Events[i].GetType() == typeof(NoteOnEvent)) { NoteOnEvent ne = (NoteOnEvent)Events[i]; if (ne.Velocity != 0) { Notes.Add(ne); } } } } return(new MidiRResult(Pitchs, Notes)); }
public void ExportsCorrectValue() { var ms = new MemoryStream(); var writer = new BinaryWriter(ms); int channel = 2; int pitch = 0x207D; // 0x2000 is the default PitchWheelChangeEvent p = new PitchWheelChangeEvent(0, channel, pitch); long time = 0; p.Export(ref time, writer); Assert.AreEqual(4, ms.Length); byte[] b = ms.GetBuffer(); Assert.AreEqual(0x0, b[0]); // event time Assert.AreEqual(0xE1, b[1]); Assert.AreEqual(0x7D, b[2]); Assert.AreEqual(0x40, b[3]); }
public PitchWheelEvent(PitchWheelChangeEvent pwce) { PitchWheelChangeEvent = pwce; }
/// <summary> /// Convert neb steps to midi file. /// </summary> /// <param name="steps"></param> /// <param name="midiFileName"></param> /// <param name="channels">Map of channel number to channel name.</param> /// <param name="bpm">Beats per minute.</param> /// <param name="info">Extra info to add to midi file.</param> public static void ExportToMidi(StepCollection steps, string midiFileName, Dictionary <int, string> channels, double bpm, string info) { int exportPpq = 96; // Events per track. Dictionary <int, IList <MidiEvent> > trackEvents = new(); ///// Meta file stuff. MidiEventCollection events = new(1, exportPpq); ///// Add Header chunk stuff. IList <MidiEvent> lhdr = events.AddTrack(); //lhdr.Add(new TimeSignatureEvent(0, 4, 2, (int)ticksPerClick, 8)); //TimeSignatureEvent me = new TimeSignatureEvent(long absoluteTime, int numerator, int denominator, int ticksInMetronomeClick, int no32ndNotesInQuarterNote); // - numerator of the time signature (as notated). // - denominator of the time signature as a negative power of 2 (ie 2 represents a quarter-note, 3 represents an eighth-note, etc). // - number of MIDI clocks between metronome clicks. // - number of notated 32nd-notes in a MIDI quarter-note (24 MIDI Clocks). The usual value for this parameter is 8. //lhdr.Add(new KeySignatureEvent(0, 0, 0)); // - number of flats (-ve) or sharps (+ve) that identifies the key signature (-7 = 7 flats, -1 = 1 //flat, 0 = key of C, 1 = 1 sharp, etc). // - major (0) or minor (1) key. // - abs time. // Tempo. lhdr.Add(new TempoEvent(0, 0) { Tempo = bpm }); // General info. lhdr.Add(new TextEvent("Midi file created by Nebulator.", MetaEventType.TextEvent, 0)); lhdr.Add(new TextEvent(info, MetaEventType.TextEvent, 0)); lhdr.Add(new MetaEvent(MetaEventType.EndTrack, 0, 0)); ///// Make one midi event collection per track. foreach (int channel in channels.Keys) { IList <MidiEvent> le = events.AddTrack(); trackEvents.Add(channel, le); le.Add(new TextEvent(channels[channel], MetaEventType.SequenceTrackName, 0)); // >> 0 SequenceTrackName G.MIDI Acou Bass } // Make a transformer. MidiTime mt = new() { InternalPpq = Time.SubdivsPerBeat, MidiPpq = exportPpq, Tempo = bpm }; // Run through the main steps and create a midi event per. foreach (Time time in steps.Times) { long mtime = mt.InternalToMidi(time.TotalSubdivs); foreach (Step step in steps.GetSteps(time)) { MidiEvent evt; switch (step) { case StepNoteOn stt: evt = new NoteEvent(mtime, stt.ChannelNumber, MidiCommandCode.NoteOn, (int)MathUtils.Constrain(stt.NoteNumber, 0, Definitions.MAX_MIDI), (int)(MathUtils.Constrain(stt.VelocityToPlay, 0, 1.0) * Definitions.MAX_MIDI)); trackEvents[step.ChannelNumber].Add(evt); if (stt.Duration.TotalSubdivs > 0) // specific duration { evt = new NoteEvent(mtime + mt.InternalToMidi(stt.Duration.TotalSubdivs), stt.ChannelNumber, MidiCommandCode.NoteOff, (int)MathUtils.Constrain(stt.NoteNumber, 0, Definitions.MAX_MIDI), 0); trackEvents[step.ChannelNumber].Add(evt); } break; case StepNoteOff stt: evt = new NoteEvent(mtime, stt.ChannelNumber, MidiCommandCode.NoteOff, (int)MathUtils.Constrain(stt.NoteNumber, 0, Definitions.MAX_MIDI), 0); trackEvents[step.ChannelNumber].Add(evt); break; case StepControllerChange stt: if (stt.ControllerId == ControllerDef.NoteControl) { // Shouldn't happen, ignore. } else if (stt.ControllerId == ControllerDef.PitchControl) { evt = new PitchWheelChangeEvent(mtime, stt.ChannelNumber, (int)MathUtils.Constrain(stt.Value, 0, Definitions.MAX_MIDI)); trackEvents[step.ChannelNumber].Add(evt); } else // CC { evt = new ControlChangeEvent(mtime, stt.ChannelNumber, (MidiController)stt.ControllerId, (int)MathUtils.Constrain(stt.Value, 0, Definitions.MAX_MIDI)); trackEvents[step.ChannelNumber].Add(evt); } break; case StepPatch stt: evt = new PatchChangeEvent(mtime, stt.ChannelNumber, (int)stt.Patch); trackEvents[step.ChannelNumber].Add(evt); break; default: break; } } } // Finish up channels with end marker. foreach (IList <MidiEvent> let in trackEvents.Values) { long ltime = let.Last().AbsoluteTime; let.Add(new MetaEvent(MetaEventType.EndTrack, 0, ltime)); } MidiFile.Export(midiFileName, events); } }
/// <summary> /// Return information about a midifile : patch change, copyright, ... /// </summary> /// <param name="pathfilename"></param> /// <param name="Info"></param> static public List <string> GeneralInfo(string pathfilename, bool withNoteOn, bool withNoteOff, bool withControlChange, bool withPatchChange, bool withAfterTouch, bool withMeta, bool withOthers) { List <string> Info = new List <string>(); try { int NumberBeatsMeasure; int NumberQuarterBeat; MidiLoad midifile = new MidiLoad(); midifile.KeepNoteOff = withNoteOff; midifile.MPTK_Load(pathfilename); if (midifile != null) { Info.Add(string.Format("Format: {0}", midifile.midifile.FileFormat)); Info.Add(string.Format("Tracks: {0}", midifile.midifile.Tracks)); Info.Add(string.Format("Events count: {0}", midifile.MidiSorted.Count())); Info.Add(string.Format("Duration: {0} ({1} seconds) {2} Ticks", midifile.MPTK_RealDuration, midifile.MPTK_RealDuration.TotalSeconds, midifile.MPTK_TickLast)); Info.Add(string.Format("Initial Tempo: {0,0:F2} BPM", midifile.MPTK_InitialTempo)); Info.Add(string.Format("Beats in a measure: {0}", midifile.MPTK_NumberBeatsMeasure)); Info.Add(string.Format("Quarters count in a beat:{0}", midifile.MPTK_NumberQuarterBeat)); Info.Add(string.Format("Ticks per Quarter Note: {0}", midifile.midifile.DeltaTicksPerQuarterNote)); Info.Add(""); //if (false) { foreach (TrackMidiEvent trackEvent in midifile.MidiSorted) { switch (trackEvent.Event.CommandCode) { case MidiCommandCode.NoteOn: if (withNoteOn) { if (((NoteOnEvent)trackEvent.Event).OffEvent != null) { NoteOnEvent noteon = (NoteOnEvent)trackEvent.Event; Info.Add(BuildInfoTrack(trackEvent) + string.Format("NoteOn {0,3} ({1,3}) Len:{2,3} Vel:{3,3}", noteon.NoteName, noteon.NoteNumber, noteon.NoteLength, noteon.Velocity)); } } break; case MidiCommandCode.NoteOff: if (withNoteOff) { NoteEvent noteoff = (NoteEvent)trackEvent.Event; Info.Add(BuildInfoTrack(trackEvent) + string.Format("NoteOff {0,3} ({1,3}) Vel:{2,3}", noteoff.NoteName, noteoff.NoteNumber, noteoff.Velocity)); } break; case MidiCommandCode.PitchWheelChange: if (withOthers) { PitchWheelChangeEvent aftertouch = (PitchWheelChangeEvent)trackEvent.Event; Info.Add(BuildInfoTrack(trackEvent) + string.Format("PitchWheelChange {0,3}", aftertouch.Pitch)); } break; case MidiCommandCode.KeyAfterTouch: if (withAfterTouch) { NoteEvent aftertouch = (NoteEvent)trackEvent.Event; Info.Add(BuildInfoTrack(trackEvent) + string.Format("KeyAfterTouch {0,3} ({1,3}) Pressure:{2,3}", aftertouch.NoteName, aftertouch.NoteNumber, aftertouch.Velocity)); } break; case MidiCommandCode.ChannelAfterTouch: if (withAfterTouch) { ChannelAfterTouchEvent aftertouch = (ChannelAfterTouchEvent)trackEvent.Event; Info.Add(BuildInfoTrack(trackEvent) + string.Format("ChannelAfterTouch Pressure:{0,3}", aftertouch.AfterTouchPressure)); } break; case MidiCommandCode.ControlChange: if (withControlChange) { ControlChangeEvent controlchange = (ControlChangeEvent)trackEvent.Event; Info.Add(BuildInfoTrack(trackEvent) + string.Format("ControlChange {0,3} ({1,3}) Value:{2,3}", controlchange.Controller, controlchange.Controller, controlchange.ControllerValue)); } break; case MidiCommandCode.PatchChange: if (withPatchChange) { PatchChangeEvent change = (PatchChangeEvent)trackEvent.Event; Info.Add(BuildInfoTrack(trackEvent) + string.Format("PatchChange {0,3:000} {1}", change.Patch, PatchChangeEvent.GetPatchName(change.Patch))); } break; case MidiCommandCode.MetaEvent: if (withMeta) { MetaEvent meta = (MetaEvent)trackEvent.Event; switch (meta.MetaEventType) { case MetaEventType.SetTempo: TempoEvent tempo = (TempoEvent)meta; Info.Add(BuildInfoTrack(trackEvent) + string.Format("SetTempo Tempo:{0} MicrosecondsPerQuarterNote:{1}", Math.Round(tempo.Tempo, 0), tempo.MicrosecondsPerQuarterNote)); //tempo.Tempo break; case MetaEventType.TimeSignature: TimeSignatureEvent timesig = (TimeSignatureEvent)meta; // Numerator: counts the number of beats in a measure. // For example a numerator of 4 means that each bar contains four beats. // Denominator: number of quarter notes in a beat.0=ronde, 1=blanche, 2=quarter, 3=eighth, etc. // Set default value NumberBeatsMeasure = timesig.Numerator; NumberQuarterBeat = System.Convert.ToInt32(Mathf.Pow(2, timesig.Denominator)); Info.Add(BuildInfoTrack(trackEvent) + string.Format("TimeSignature Beats Measure:{0} Beat Quarter:{1}", NumberBeatsMeasure, NumberQuarterBeat)); break; default: string text = meta is TextEvent ? " '" + ((TextEvent)meta).Text + "'" : ""; Info.Add(BuildInfoTrack(trackEvent) + meta.MetaEventType.ToString() + text); break; } } break; default: // Other midi event if (withOthers) { Info.Add(BuildInfoTrack(trackEvent) + string.Format(" {0} ({1})", trackEvent.Event.CommandCode, (int)trackEvent.Event.CommandCode)); } break; } } } //else DebugMidiSorted(midifile.MidiSorted); } else { Info.Add("Error reading midi file"); } } catch (System.Exception ex) { MidiPlayerGlobal.ErrorDetail(ex); } return(Info); }
/// <summary> /// Process input midi event. /// </summary> void NpMidiIn_MessageReceived(object sender, MidiInMessageEventArgs e) { // Decode the message. We only care about a few. MidiEvent me = MidiEvent.FromRawMessage(e.RawMessage); NpMidiEventArgs mevt = null; switch (me.CommandCode) { case MidiCommandCode.NoteOn: { NoteOnEvent evt = me as NoteOnEvent; mevt = new NpMidiEventArgs() { channel = evt.Channel, note = evt.NoteNumber, velocity = evt.Velocity }; } break; case MidiCommandCode.NoteOff: { NoteEvent evt = me as NoteEvent; mevt = new NpMidiEventArgs() { channel = evt.Channel, note = evt.NoteNumber, velocity = 0 }; } break; case MidiCommandCode.ControlChange: { ControlChangeEvent evt = me as ControlChangeEvent; mevt = new NpMidiEventArgs() { channel = evt.Channel, controllerId = (int)evt.Controller, controllerValue = evt.ControllerValue }; } break; case MidiCommandCode.PitchWheelChange: { PitchWheelChangeEvent evt = me as PitchWheelChangeEvent; mevt = new NpMidiEventArgs() { channel = evt.Channel, controllerId = NpMidiEventArgs.PITCH_CONTROL, controllerValue = evt.Pitch }; } break; } if (mevt != null) { // Pass it up for handling. InputEvent?.Invoke(this, mevt); } // else ignore?? }
/// <summary> /// Add a TrackMidiEvent to a list of MPTKEvent. /// </summary> /// <param name="mptkEvents">Must be alloc before the call</param> /// <param name="trackEvent"></param> /// <returns></returns> private void ConvertToEvent(List <MPTKEvent> mptkEvents, TrackMidiEvent trackEvent) { MPTKEvent midievent = null; switch (trackEvent.Event.CommandCode) { case MidiCommandCode.NoteOn: //if (((NoteOnEvent)trackEvent.Event).OffEvent != null) { NoteOnEvent noteon = (NoteOnEvent)trackEvent.Event; //Debug.Log(string.Format("Track:{0} NoteNumber:{1,3:000} AbsoluteTime:{2,6:000000} NoteLength:{3,6:000000} OffDeltaTime:{4,6:000000} ", track, noteon.NoteNumber, noteon.AbsoluteTime, noteon.NoteLength, noteon.OffEvent.DeltaTime)); if (noteon.OffEvent != null) { midievent = new MPTKEvent() { Track = trackEvent.IndexTrack, Tick = trackEvent.AbsoluteQuantize, Command = MPTKCommand.NoteOn, Value = noteon.NoteNumber, Channel = trackEvent.Event.Channel - 1, Velocity = noteon.Velocity, Duration = Convert.ToInt64(noteon.NoteLength * MPTK_PulseLenght), Length = noteon.NoteLength, }; mptkEvents.Add(midievent); if (LogEvents && seek_ticks < 0) { string notename = (midievent.Channel != 9) ? String.Format("{0}{1}", NoteNames[midievent.Value % 12], midievent.Value / 12) : "Drum"; Debug.Log(BuildInfoTrack(trackEvent) + string.Format("NoteOn {0,3:000}\t{1,-4}\tLenght:{2,5}\t{3}\tVeloc:{4,3}", midievent.Value, notename, noteon.NoteLength, NoteLength(midievent), noteon.Velocity)); } } else // It's a noteoff { if (KeepNoteOff) { midievent = new MPTKEvent() { Track = trackEvent.IndexTrack, Tick = trackEvent.AbsoluteQuantize, Command = MPTKCommand.NoteOff, Value = noteon.NoteNumber, Channel = trackEvent.Event.Channel - 1, Velocity = noteon.Velocity, Duration = Convert.ToInt64(noteon.NoteLength * MPTK_PulseLenght), Length = noteon.NoteLength, }; mptkEvents.Add(midievent); if (LogEvents && seek_ticks < 0) { string notename = (midievent.Channel != 9) ? String.Format("{0}{1}", NoteNames[midievent.Value % 12], midievent.Value / 12) : "Drum"; Debug.Log(BuildInfoTrack(trackEvent) + string.Format("NoteOff {0,3:000}\t{1,-4}\tLenght:{2}", midievent.Value, notename, " Note Off")); } } } } break; case MidiCommandCode.NoteOff: if (KeepNoteOff) { NoteEvent noteoff = (NoteEvent)trackEvent.Event; //Debug.Log(string.Format("Track:{0} NoteNumber:{1,3:000} AbsoluteTime:{2,6:000000} NoteLength:{3,6:000000} OffDeltaTime:{4,6:000000} ", track, noteon.NoteNumber, noteon.AbsoluteTime, noteon.NoteLength, noteon.OffEvent.DeltaTime)); midievent = new MPTKEvent() { Track = trackEvent.IndexTrack, Tick = trackEvent.AbsoluteQuantize, Command = MPTKCommand.NoteOff, Value = noteoff.NoteNumber, Channel = trackEvent.Event.Channel - 1, Velocity = noteoff.Velocity, Duration = 0, Length = 0, }; mptkEvents.Add(midievent); if (LogEvents && seek_ticks < 0) { string notename = (midievent.Channel != 9) ? String.Format("{0}{1}", NoteNames[midievent.Value % 12], midievent.Value / 12) : "Drum"; Debug.Log(BuildInfoTrack(trackEvent) + string.Format("NoteOff {0,3:000}\t{1,-4}\tLenght:{2}", midievent.Value, notename, " Note Off")); } } break; case MidiCommandCode.PitchWheelChange: PitchWheelChangeEvent pitch = (PitchWheelChangeEvent)trackEvent.Event; midievent = new MPTKEvent() { Track = trackEvent.IndexTrack, Tick = trackEvent.AbsoluteQuantize, Command = MPTKCommand.PitchWheelChange, Channel = trackEvent.Event.Channel - 1, Value = pitch.Pitch, // Pitch Wheel Value 0 is minimum, 0x2000 (8192) is default, 0x3FFF (16383) is maximum }; mptkEvents.Add(midievent); if (LogEvents && seek_ticks < 0) { Debug.Log(BuildInfoTrack(trackEvent) + string.Format("PitchWheelChange {0}", pitch.Pitch)); } break; case MidiCommandCode.ControlChange: ControlChangeEvent controlchange = (ControlChangeEvent)trackEvent.Event; midievent = new MPTKEvent() { Track = trackEvent.IndexTrack, Tick = trackEvent.AbsoluteQuantize, Command = MPTKCommand.ControlChange, Channel = trackEvent.Event.Channel - 1, Controller = (MPTKController)controlchange.Controller, Value = controlchange.ControllerValue, }; //if ((MPTKController)controlchange.Controller != MPTKController.Sustain) mptkEvents.Add(midievent); // Other midi event if (LogEvents && seek_ticks < 0) { Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Control {0} {1}", controlchange.Controller, controlchange.ControllerValue)); } break; case MidiCommandCode.PatchChange: PatchChangeEvent change = (PatchChangeEvent)trackEvent.Event; midievent = new MPTKEvent() { Track = trackEvent.IndexTrack, Tick = trackEvent.AbsoluteQuantize, Command = MPTKCommand.PatchChange, Channel = trackEvent.Event.Channel - 1, Value = change.Patch, }; mptkEvents.Add(midievent); if (LogEvents && seek_ticks < 0) { Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Patch {0,3:000} {1}", change.Patch, PatchChangeEvent.GetPatchName(change.Patch))); } break; case MidiCommandCode.MetaEvent: MetaEvent meta = (MetaEvent)trackEvent.Event; midievent = new MPTKEvent() { Track = trackEvent.IndexTrack, Tick = trackEvent.AbsoluteQuantize, Command = MPTKCommand.MetaEvent, Channel = trackEvent.Event.Channel - 1, Meta = (MPTKMeta)meta.MetaEventType, }; switch (meta.MetaEventType) { case MetaEventType.EndTrack: midievent.Info = "End Track"; break; case MetaEventType.TimeSignature: AnalyzeTimeSignature(meta, trackEvent); break; case MetaEventType.SetTempo: if (EnableChangeTempo) { TempoEvent tempo = (TempoEvent)meta; // Tempo change will be done in MidiFilePlayer midievent.Duration = (long)tempo.Tempo; MPTK_MicrosecondsPerQuarterNote = tempo.MicrosecondsPerQuarterNote; fluid_player_set_midi_tempo(tempo.MicrosecondsPerQuarterNote); // Force exit loop if (LogEvents && seek_ticks < 0) { Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Meta {0,-15} Tempo:{1} MicrosecondsPerQuarterNote:{2}", meta.MetaEventType, tempo.Tempo, tempo.MicrosecondsPerQuarterNote)); } } break; case MetaEventType.SequenceTrackName: midievent.Info = ((TextEvent)meta).Text; if (!string.IsNullOrEmpty(SequenceTrackName)) { SequenceTrackName += "\n"; } SequenceTrackName += string.Format("T{0,2:00} {1}", trackEvent.IndexTrack, midievent.Info); break; case MetaEventType.ProgramName: midievent.Info = ((TextEvent)meta).Text; ProgramName += midievent.Info + " "; break; case MetaEventType.TrackInstrumentName: midievent.Info = ((TextEvent)meta).Text; if (!string.IsNullOrEmpty(TrackInstrumentName)) { TrackInstrumentName += "\n"; } TrackInstrumentName += string.Format("T{0,2:00} {1}", trackEvent.IndexTrack, midievent.Info); break; case MetaEventType.TextEvent: midievent.Info = ((TextEvent)meta).Text; TextEvent += midievent.Info + " "; break; case MetaEventType.Copyright: midievent.Info = ((TextEvent)meta).Text; Copyright += midievent.Info + " "; break; case MetaEventType.Lyric: // lyric midievent.Info = ((TextEvent)meta).Text; TextEvent += midievent.Info + " "; break; case MetaEventType.Marker: // marker midievent.Info = ((TextEvent)meta).Text; TextEvent += midievent.Info + " "; break; case MetaEventType.CuePoint: // cue point case MetaEventType.DeviceName: break; } if (LogEvents && !string.IsNullOrEmpty(midievent.Info) && seek_ticks < 0) { Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Meta {0,-15} '{1}'", midievent.Meta, midievent.Info)); } mptkEvents.Add(midievent); //Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Meta {0} {1}", meta.MetaEventType, meta.ToString())); break; default: // Other midi event if (LogEvents && seek_ticks < 0) { Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Other {0,-15} Not handle by MPTK", trackEvent.Event.CommandCode)); } break; } }
private void sr_OnTrackEvent(object sender, TrackEventArgs e) { long counter = 0; long notesBefore = TotalNotes; foreach (var ev in e.Events.Where(x => x is MidiUtils.IO.MidiEvent)) { counter++; // Convert the event to NAudio's system so we can get a shortMessage var em = (MidiUtils.IO.MidiEvent)ev; if (ev.Type == EventType.NoteOn) { TotalNotes++; } MidiEvent me; try { switch (ev.Type) { case EventType.NoteOn: case EventType.NoteOff: case EventType.PolyphonicKeyPressure: if (em.Data2 > 0 && ev.Type == EventType.NoteOn) { me = new NoteOnEvent(ev.Tick, em.Channel + 1, em.Data1, em.Data2, 0); } else { me = new NoteEvent(ev.Tick, em.Channel + 1, (MidiCommandCode)(int)ev.Type, em.Data1, em.Data2); } break; case EventType.ControlChange: me = new ControlChangeEvent(ev.Tick, em.Channel + 1, (MidiController)em.Data1, em.Data2); break; case EventType.ProgramChange: me = new PatchChangeEvent(ev.Tick, em.Channel + 1, em.Data1); break; case EventType.ChannelPressure: me = new ChannelAfterTouchEvent(ev.Tick, em.Channel + 1, em.Data1); break; case EventType.Pitchbend: me = new PitchWheelChangeEvent(ev.Tick, em.Channel + 1, em.Data1 + (em.Data2 << 7)); break; default: throw new InvalidOperationException("Unsupported MIDI event type: " + ev.Type); } } catch (Exception ex) { Exceptions++; continue; } // Send the message try { _midi.Send(me.GetAsShortMessage()); } catch (MmException ex) { if ((int)ex.Result == 67) { Overloads++; } else { Exceptions++; } continue; } if (ev.Type == EventType.NoteOn) { SuccessNotes++; } } PeakNotesPerInterval = Math.Max(PeakNotesPerInterval, TotalNotes - notesBefore); PeakEventsPerInterval = Math.Max(PeakEventsPerInterval, counter); TotalEvents += counter; }