Esempio n. 1
0
 /// <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);
             }
         }
     }
 }
Esempio n. 2
0
        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());
        }
Esempio n. 3
0
        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));
        }
Esempio n. 5
0
        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;
 }
Esempio n. 7
0
        /// <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);
        }
    }
Esempio n. 8
0
        /// <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);
        }
Esempio n. 9
0
        /// <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??
        }
Esempio n. 10
0
        /// <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;
            }
        }
Esempio n. 11
0
        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;
        }