Exemple #1
0
		private void MIDI(byte Cmd, byte Val1, byte Val2)
		{
			/* 
			 * Just a small note on the code for setting up a midi event:
			 * You can use the VstEventCollection class (Framework) to setup one or more events
			 * and then call the ToArray() method on the collection when passing it to
			 * ProcessEvents. This will save you the hassle of dealing with arrays explicitly.
			 * http://computermusicresource.com/MIDI.Commands.html
			 * 
			 * Freq to Midi notes etc:
			 * http://www.sengpielaudio.com/calculator-notenames.htm
			 * 
			 * Example to use NAudio Midi support
			 * http://stackoverflow.com/questions/6474388/naudio-and-midi-file-reading
			 */

			var midiData = new byte[4];
			midiData[0] = Cmd;
			midiData[1] = Val1;
			midiData[2] = Val2;
			midiData[3] = 0;    // Reserved, unused

			var vse = new VstMidiEvent(/*DeltaFrames*/ 0,
			                                    /*NoteLength*/ 0,
			                                    /*NoteOffset*/  0,
			                                    midiData,
			                                    /*Detune*/        0,
			                                    /*NoteOffVelocity*/ 127);

			var ve = new VstEvent[1];
			ve[0] = vse;

			PluginContext.PluginCommandStub.ProcessEvents(ve);
		}
Exemple #2
0
        public VstMidiEvent ProcessEvent(VstMidiEvent inEvent)
        {
            if (!MidiHelper.IsNoteOff(inEvent.Data) && !MidiHelper.IsNoteOn(inEvent.Data))
            {
                return inEvent;
            }

            byte[] outData = new byte[4];
            inEvent.Data.CopyTo(outData, 0);

            outData[2] += (byte)_gainMgr.CurrentValue;

            if (outData[2] > 127)
            {
                outData[2] = 127;
            }

            if (outData[2] < 0)
            {
                outData[2] = 0;
            }

            VstMidiEvent outEvent = new VstMidiEvent(
                inEvent.DeltaFrames, inEvent.NoteLength, inEvent.NoteOffset,
                outData, inEvent.Detune, inEvent.NoteOffVelocity);

            return outEvent;
        }
Exemple #3
0
        private void MIDI(byte Cmd,byte Val1,byte Val2)
        {
            byte[] midiData = new byte[4];
            midiData[0] = Cmd;
            midiData[1] = Val1;
            midiData[2] = Val2;
            midiData[3] = 0;    // Reserved, unused

            VstMidiEvent vse = new VstMidiEvent(/*DeltaFrames*/ 0,
                /*NoteLength*/ 0,
                /*NoteOffset*/  0,
                 midiData,
                /*Detune*/        0,
                /*NoteOffVelocity*/ 127);

            VstEvent[] ve = new VstEvent[1];
            ve[0] = vse;

            pluginContext.PluginCommandStub.ProcessEvents(ve);
        }
Exemple #4
0
        public void ProcessCurrentEvents()
        {
            if (CurrentEvents == null || CurrentEvents.Count == 0)
            {
                return;
            }

            // always expect some hosts not to support this.
            if (_midiHost != null)
            {
                VstEventCollection outEvents = new VstEventCollection();

                // NOTE: other types of events could be in the collection!
                foreach (VstEvent evnt in CurrentEvents)
                {
                    switch (evnt.EventType)
                    {
                    case VstEventTypes.MidiEvent:
                        VstMidiEvent midiEvent = (VstMidiEvent)evnt;

                        midiEvent = Gain.ProcessEvent(midiEvent);
                        midiEvent = Transpose.ProcessEvent(midiEvent);

                        outEvents.Add(midiEvent);
                        break;

                    default:
                        // non VstMidiEvent
                        outEvents.Add(evnt);
                        break;
                    }
                }

                _midiHost.Process(outEvents);
            }

            // Clear the cache, we've processed the events.
            CurrentEvents = null;
        }
        /// <summary>
        ///     Receives processed MssEvents from the IWetMssEventOutputPort.
        /// </summary>
        /// <param name="mssEvents">List of processed mss events</param>
        /// <param name="sampleTimeAtEndOfProcessingCycle">
        ///     If wetMssEventOutputPort is configured to only output when a processing cycle ends then
        ///     sampleTimeAtEndOfProcessingCycle will contain the end time the cycle that just ended.
        /// </param>
        public void IWetMssEventOutputPort_SendingWetMssEvents(List <MssEvent> mssEvents,
                                                               long sampleTimeAtEndOfProcessingCycle)
        {
            if (this.vstHost == null)
            {
                return;
            }

            // a plugin must implement IVstPluginMidiSource or this call will throw an exception.
            IVstMidiProcessor midiHost = this.vstHost.GetInstance <IVstMidiProcessor>();

            // always expect some hosts not to support this.
            if (midiHost != null)
            {
                //Attempts to convert each MssEvent to a VstMidiEvent and add it to outEvents
                foreach (MssEvent mssEvent in mssEvents)
                {
                    //This will return null if there is no valid conversion.
                    VstMidiEvent midiEvent =
                        ConvertMssEventToVstMidiEvent(mssEvent,
                                                      this.SampleTimeAtStartOfProcessingCycle,
                                                      this.hostInfoOutputPort.SampleRate);
                    if (midiEvent != null)
                    {
                        this.outEvents.Add(midiEvent);
                        //midiHost.Process(outEvents);
                        //outEvents.Clear();
                    }
                }

                //TODO: Figure out why it doesn't work to send all of the events at once.
                //Sends VstMidiEvents to host
                midiHost.Process(outEvents);
                outEvents.Clear();
            }

            OnProcessingCycleEnd(sampleTimeAtEndOfProcessingCycle);
        }
        //*******************************Helpers*******************************


        //if testMssToMidi is true then this method tests ConvertMssEventToVstMidiEvent. Otherwise this method tests ConvertVstMidiEventToMssEvent
        protected void Test_MsgConversion(MssMsgType msgType, int midiChannel, int midiParam1, int midiParam2, bool testMssToMidi)
        {
            long sampleTimeAtStartOfCycle = 12345;
            int  deltaFrames = 789;

            MidiHandlerProtectedWrapper midiHandler = Factory_MidiHandler_Basic();

            MssEvent mssEvent = new MssEvent();

            if (msgType == MssMsgType.PitchBend)
            {
                mssEvent.mssMsg = new MssMsg(msgType, midiChannel, MssMsgUtil.UNUSED_MSS_MSG_DATA, (midiParam2 << 7) + midiParam1);
            }
            else
            {
                mssEvent.mssMsg = new MssMsg(msgType, midiChannel, midiParam1, midiParam2);
            }
            mssEvent.sampleTime = sampleTimeAtStartOfCycle + deltaFrames;

            byte[]       midiData  = MidiUtil.CreateMidiData(msgType, midiChannel, (byte)midiParam1, (byte)midiParam2);
            VstMidiEvent midiEvent = new VstMidiEvent(deltaFrames, 0, 0, midiData, 0, 0x00);

            if (testMssToMidi == true)
            {
                MssEvent convertedMssEvent = midiHandler.ConvertVstMidiEventToMssEventWrapper(
                    midiEvent, sampleTimeAtStartOfCycle, this.hostInfoOutputPort.SampleRate);
                Assert.AreEqual(mssEvent, convertedMssEvent);
            }
            else
            {
                VstMidiEvent ConvertedMidiEvent = midiHandler.ConvertMssEventToVstMidiEventWrapper(
                    mssEvent, sampleTimeAtStartOfCycle, this.hostInfoOutputPort.SampleRate);
                Assert.AreEqual(midiEvent.Data, ConvertedMidiEvent.Data);
                Assert.AreEqual(midiEvent.DeltaFrames, ConvertedMidiEvent.DeltaFrames);
            }
        }
Exemple #7
0
        public void Test_VstMidiEvent_Constructor()
        {
            int deltaFrames = 12;
            int noteLength  = 100;
            int noteOffset  = 1;

            byte[] midiData        = new byte[] { 0x9C, 0x7F, 0x40 };
            short  detune          = -24;
            byte   noteOffVelocity = 64;

            VstMidiEvent me = new VstMidiEvent(deltaFrames, noteLength, noteOffset, midiData, detune, noteOffVelocity);

            Assert.AreEqual(VstEventTypes.MidiEvent, me.EventType, "VstMidiEvent.EventType");
            Assert.AreEqual(deltaFrames, me.DeltaFrames, "VstMidiEvent.DeltaFrames");
            Assert.AreEqual(noteLength, me.NoteLength, "VstMidiEvent.NoteLength");
            Assert.AreEqual(noteOffset, me.NoteOffset, "VstMidiEvent.NoteOffset");
            Assert.IsNotNull(me.Data, "VstMidiEvent.Data is null");
            Assert.AreEqual(3, me.Data.Length, "VstMidiEvent.Data.Length");
            Assert.AreEqual(0x9C, me.Data[0], "VstMidiEvent.Data[0]");
            Assert.AreEqual(0x7F, me.Data[1], "VstMidiEvent.Data[1]");
            Assert.AreEqual(0x40, me.Data[2], "VstMidiEvent.Data[2]");
            Assert.AreEqual(detune, me.Detune, "VstMidiEvent.Detune");
            Assert.AreEqual(noteOffVelocity, me.NoteOffVelocity, "VstMidiEvent.NoteOffVelocity");
        }
Exemple #8
0
        public void Test_VstMidiEvent_Constructor()
        {
            int deltaFrames = 12;
            int noteLength  = 100;
            int noteOffset  = 1;

            byte[] midiData        = new byte[] { 0x9C, 0x7F, 0x40 };
            short  detune          = -24;
            byte   noteOffVelocity = 64;

            var me = new VstMidiEvent(deltaFrames, noteLength, noteOffset, midiData, detune, noteOffVelocity);

            me.EventType.Should().Be(VstEventTypes.MidiEvent);
            me.DeltaFrames.Should().Be(deltaFrames);
            me.NoteLength.Should().Be(noteLength);
            me.NoteOffset.Should().Be(noteOffset);
            me.Data.Should().NotBeNull();
            me.Data.Length.Should().Be(midiData.Length);
            me.Data[0].Should().Be(midiData[0]);
            me.Data[1].Should().Be(midiData[1]);
            me.Data[2].Should().Be(midiData[2]);
            me.Detune.Should().Be(detune);
            me.NoteOffVelocity.Should().Be(noteOffVelocity);
        }
        private void MIDI(byte Cmd, byte Val1, byte Val2, int deltaFrames = 0)
        {
            /*
             * Just a small note on the code for setting up a midi event:
             * You can use the VstEventCollection class (Framework) to setup one or more events
             * and then call the ToArray() method on the collection when passing it to
             * ProcessEvents. This will save you the hassle of dealing with arrays explicitly.
             * http://computermusicresource.com/MIDI.Commands.html
             *
             * Freq to Midi notes etc:
             * http://www.sengpielaudio.com/calculator-notenames.htm
             *
             * Example to use NAudio Midi support
             * http://stackoverflow.com/questions/6474388/naudio-and-midi-file-reading
             */

            var midiData = new byte[4];

            midiData[0] = Cmd;
            midiData[1] = Val1;
            midiData[2] = Val2;
            midiData[3] = 0; // Reserved, unused

            var vse = new VstMidiEvent(deltaFrames,
                                       /*NoteLength*/ 0,
                                       /*NoteOffset*/ 0,
                                       midiData,
                                       /*Detune*/ 0,
                                       /*NoteOffVelocity*/ 127);

            var ve = new VstEvent[1];

            ve[0] = vse;

            PluginContext.PluginCommandStub.ProcessEvents(ve);
        }
        // Process the incoming VST events.  *** This is the core of the VST right here. ***
        public void Process(VstEventCollection inputEvents)
        {
            if (_plugin == null) return;

            _plugin.callCount++;

            bool thrudone = false;

            foreach (VstEvent evnt in inputEvents)
            {
                _plugin.eventCount++;

                // Skip non-MIDI Events
                if (evnt.EventType != VstEventTypes.MidiEvent)
                {
                    continue;
                }

                _plugin.midiCount++;

                // If set in options, keep the original event as well
                if (_plugin.Options.MidiThruAll)
                {
                    Events.Add(evnt);
                    thrudone = true;
                }

                // Don't do any more if we aren't running.
                if (_plugin.CurrentMode != Constants.Modes.RUN) continue;

                // Construct a MIDI event and act on it
                VstMidiEvent midiInputEvent = (VstMidiEvent)evnt;
                byte command = (byte)(midiInputEvent.Data[0] & 0xF0);
                byte channel = (byte)(midiInputEvent.Data[0] & 0x0F);
                byte note = midiInputEvent.Data[1];
                byte velocity = midiInputEvent.Data[2];

                MapNoteItem map = _plugin.NoteMaps[note];
                byte[] midiData = null;

                // Filter out everything except Note On/Note Off and CC events
                switch (command)
                {
                    case 0x90: // Note On
                        map.Triggered(Constants.MapTypes.ON);

                        if (map.isDefined(Constants.MapTypes.ON))
                        {
                            _plugin.hitCount++;
                            midiData = MapNoteItem.StringToBytes(map.OutputBytesStringOn, channel, velocity);
                        }
                        break;

                    case 0x80: // Note Off
                        map.Triggered(Constants.MapTypes.OFF);

                        if (map.isDefined(Constants.MapTypes.OFF))
                        {
                            _plugin.hitCount++;
                            midiData = MapNoteItem.StringToBytes(map.OutputBytesStringOff, channel, velocity);
                        }
                        break;

                    case 0xB0: // Continuous Controller
                        map.Triggered(Constants.MapTypes.CC);

                        if (map.isDefined(Constants.MapTypes.CC))
                        {
                            _plugin.hitCount++;
                            midiData = MapNoteItem.StringToBytes(map.OutputBytesStringCC, channel, velocity);
                        }
                        break;

                    default:
                        // Ignore everything else, but keep going below
                        break;
                }

                // Check that we got a result.  If not - no match.
                if (midiData == null)
                {
                    if (_plugin.Options.MidiThru)
                    {
                        // add original event, if not added already.
                        if (!thrudone)
                        {
                            Events.Add(evnt);
                        }
                    }
                    continue;
                }

                // In most cases, use VstMidiSysExEvent in place of VstMidiEvent, since this seems to allow arbitary bytes.
                if (_plugin.Options.AlwaysSysEx)
                {
                    VstMidiSysExEvent mappedEvent = new VstMidiSysExEvent(midiInputEvent.DeltaFrames, midiData);
                    Events.Add(mappedEvent);
                }
                else  // Ugly!  Split message into three-byte chunks and send them all.
                {
                    List<byte[]> midichunks = new List<byte[]>();

                    for (int i = 0; i < midiData.Length; i += 3)
                    {
                        midichunks.Add(midiData.Skip(i).Take(3).ToArray());
                    }

                    foreach (byte[] midi in midichunks)
                    {
                        VstMidiEvent mappedEvent = new VstMidiEvent(midiInputEvent.DeltaFrames, midiInputEvent.NoteLength, midiInputEvent.NoteOffset, midi, midiInputEvent.Detune, midiInputEvent.NoteOffVelocity);
                        Events.Add(mappedEvent);
                    }
                }
            } // foreach
        }
 public MssEvent ConvertVstMidiEventToMssEventWrapper(VstMidiEvent midiEvent,
     long processingCycleStartTime,
     double sampleRate)
 {
     return ConvertVstMidiEventToMssEvent(midiEvent, processingCycleStartTime, sampleRate);
 }
Exemple #12
0
 public void AddMidiEvent(VstMidiEvent evt)
 {
     lstEvent.Add(evt);
 }
Exemple #13
0
        // Process the incoming VST events.  This is the core of the app right here.  !!!!
        public void Process(VstEventCollection inputEvents)
        {
            _plugin.callCount++;

            foreach (VstEvent evnt in inputEvents)
            {
                _plugin.eventCount++;

                // Skip non-MIDI Events
                if (evnt.EventType != VstEventTypes.MidiEvent)
                {
                    continue;
                }

                _plugin.midiCount++;

                VstMidiEvent midiInputEvent = (VstMidiEvent)evnt;

                // Filter out everything except Note On/Note Off events
                byte midiCommand = (byte)(midiInputEvent.Data[0] & 0xF0);
                if ((midiCommand == 0x90) || (midiCommand == 0x80))
                {
                    byte triggerNoteNum = midiInputEvent.Data[1];

                    if (_plugin.NoteMap.Contains(triggerNoteNum))
                    {
                        _plugin.hitCount++;

                        byte channel  = (byte)(midiInputEvent.Data[0] & 0x0F);
                        byte velocity = midiInputEvent.Data[2];

                        MapNoteItem item = _plugin.NoteMap[triggerNoteNum];

                        byte[] midiData = null;
                        if (midiCommand == 0x90)
                        {
                            midiData = MapNoteItem.StringToBytes(item.OutputBytesStringOn, channel, velocity);
                        }
                        else if (midiCommand == 0x80)
                        {
                            midiData = MapNoteItem.StringToBytes(item.OutputBytesStringOff, channel, velocity);
                        }
                        // else midiData remains null, which should never happen

                        // If OutputBytes was empty, ignore this event.   Could try sending the event with an empty array (not null) - not sure what would happen.
                        if (midiData == null)
                        {
                            continue;
                        }

                        // Trick: Use VstMidiSysExEvent in place of VstMidiEvent, since this seems to allow arbitary bytes.
                        VstMidiSysExEvent mappedEvent = new VstMidiSysExEvent(midiInputEvent.DeltaFrames, midiData);

                        Events.Add(mappedEvent);
                    }
                    else if (_plugin.midiThru)
                    {
                        // add original event
                        Events.Add(evnt);
                    }
                    // Otherwise ignore silently
                }
            }
        }
Exemple #14
0
        public void OrderNoteOnEventsWithOctaves()
        {
            // mindegyik Note On eventből csak egy legyen (az AddOctaves() miatt kell)
            List <VstMidiEvent> distinctList = makeCopy(_octavesAddedOrderedNoteOnEvents);

            distinctList = distinctList.GroupBy(e => e.Data[1])
                           .Select(grp => grp.First())
                           .ToList();

            switch (Direction)
            {
            case Directions.up:
                _octavesAddedOrderedNoteOnEvents = distinctList.OrderBy(midiEvent => midiEvent.Data[1]).ToList();
                break;

            case Directions.down:
                _octavesAddedOrderedNoteOnEvents = distinctList.OrderByDescending(midiEvent => midiEvent.Data[1]).ToList();
                break;

            case Directions.updown:
                _octavesAddedOrderedNoteOnEvents = distinctList.OrderBy(midiEvent => midiEvent.Data[1]).ToList();
                List <VstMidiEvent> descendingList = distinctList.OrderByDescending(midiEvent => midiEvent.Data[1]).ToList();
                if (descendingList.Count != 0)
                {
                    descendingList.RemoveAt(0);                             // first item
                }
                if (descendingList.Count != 0)
                {
                    descendingList.RemoveAt(descendingList.Count - 1);      // last item
                }
                _octavesAddedOrderedNoteOnEvents.AddRange(descendingList);
                break;


            case Directions.downup:
                _octavesAddedOrderedNoteOnEvents = distinctList.OrderByDescending(midiEvent => midiEvent.Data[1]).ToList();
                List <VstMidiEvent> ascendingList = distinctList.OrderBy(midiEvent => midiEvent.Data[1]).ToList();
                if (ascendingList.Count != 0)
                {
                    ascendingList.RemoveAt(0);                             // first item
                }
                if (ascendingList.Count != 0)
                {
                    ascendingList.RemoveAt(ascendingList.Count - 1);      // last item
                }
                _octavesAddedOrderedNoteOnEvents.AddRange(ascendingList);
                break;

            case Directions.random:
                Random rand = new Random();
                _octavesAddedOrderedNoteOnEvents = distinctList.ToList();
                int n = _octavesAddedOrderedNoteOnEvents.Count;
                while (n > 1)
                {
                    n--;
                    int          k = rand.Next(n + 1);
                    VstMidiEvent e = _octavesAddedOrderedNoteOnEvents[k];
                    _octavesAddedOrderedNoteOnEvents[k] = distinctList[n];
                    _octavesAddedOrderedNoteOnEvents[n] = e;
                }
                break;

            default:
                break;
            }
        }
        //*******************************Helpers*******************************
        //if testMssToMidi is true then this method tests ConvertMssEventToVstMidiEvent. Otherwise this method tests ConvertVstMidiEventToMssEvent
        protected void Test_MsgConversion(MssMsgType msgType, int midiChannel, int midiParam1, int midiParam2, bool testMssToMidi)
        {
            long sampleTimeAtStartOfCycle = 12345;
            int deltaFrames = 789;

            MidiHandlerProtectedWrapper midiHandler = Factory_MidiHandler_Basic();

            MssEvent mssEvent = new MssEvent();

            if (msgType == MssMsgType.PitchBend)
            {
                mssEvent.mssMsg = new MssMsg(msgType, midiChannel, MssMsgUtil.UNUSED_MSS_MSG_DATA, (midiParam2 << 7) + midiParam1);
            }
            else
            {
                mssEvent.mssMsg = new MssMsg(msgType, midiChannel, midiParam1, midiParam2);
            }
            mssEvent.sampleTime = sampleTimeAtStartOfCycle + deltaFrames;

            byte[] midiData = MidiUtil.CreateMidiData(msgType, midiChannel, (byte)midiParam1, (byte)midiParam2);
            VstMidiEvent midiEvent = new VstMidiEvent(deltaFrames, 0, 0, midiData, 0, 0x00);

            if (testMssToMidi == true)
            {
                MssEvent convertedMssEvent = midiHandler.ConvertVstMidiEventToMssEventWrapper(
                    midiEvent, sampleTimeAtStartOfCycle, this.hostInfoOutputPort.SampleRate);
                Assert.AreEqual(mssEvent, convertedMssEvent);
            }
            else
            {
                VstMidiEvent ConvertedMidiEvent = midiHandler.ConvertMssEventToVstMidiEventWrapper(
                    mssEvent, sampleTimeAtStartOfCycle, this.hostInfoOutputPort.SampleRate);
                Assert.AreEqual(midiEvent.Data, ConvertedMidiEvent.Data);
                Assert.AreEqual(midiEvent.DeltaFrames, ConvertedMidiEvent.DeltaFrames);
            }
        }
Exemple #16
0
        private VstEvent[] filterMidiInMessages(int midiInCount, VstInstrumentPlugin plugin)
        {
            //bool active, int lowerNote, int upperNote, int transpose, ControlPedalAction pedal)
            //, ch.KeyZoneLower, ch.KeyZoneUpper, ch.Transpose, ch.ControlPedalAction
            int pitch;

            mFilteredMidiEvents.Clear();

            bool wrongChannel = false;

            for (int i = 0; i < midiInCount; i++)
            {
                MidiMessage msg = mMidiInMessages[i];

                wrongChannel = ((msg.Channel + 1) != (int)plugin.MidiChannel) && (plugin.MidiChannel != MidiChannel.ChannelAll);

                // Add note to selection
                // Copy event
                byte[] data = new byte[4];
                msg.Data.CopyTo(data, 0);
                VstMidiEvent newEv = new VstMidiEvent(
                    /*DeltaFrames*/ 0,
                    /*NoteLength*/ 0,
                    /*NoteOffset*/ 0,
                    data,
                    /*Detune*/ 0,
                    /*NoteOffVelocity*/ 127);

                // Force to midi channel 1 = 0xn0
                data[0] = (byte)(data[0] & 0xf0);

                if (data[0] == 176 && data[1] == 11)
                {
                    switch (plugin.ExpressionPedalFunction)
                    {
                    case ExpressionPedalFunction.EffectControl:
                        // Re-route foot control to wheel!
                        data[1] = 1;

                        if (plugin.UseExtendedEffectRange)
                        {
                            int wheel = data[2] * 2;
                            if (wheel > 255)
                            {
                                wheel = 255;
                            }
                            // Most plugins use an inverted direction. So default is to invert.
                            // If ExpressionPedalInvert; do not invert data
                            if (plugin.ExpressionPedalInvert)
                            {
                                data[2] = (byte)wheel;
                            }
                            else
                            {
                                data[2] = (byte)(255 - wheel);
                            }
                        }
                        else
                        {
                            // Most plugins use an inverted direction. So default is to invert.
                            // If ExpressionPedalInvert; do not invert data
                            if (!plugin.ExpressionPedalInvert)
                            {
                                data[2] = (byte)(127 - data[2]);
                            }
                        }
                        break;

                    case ExpressionPedalFunction.VolumeControl:
                        // Do nothing;
                        break;

                    case ExpressionPedalFunction.None:
                        // Next for; do not handle this midi command
                        continue;

                    default:
                        // Do nothing
                        break;
                    }
                }

                if (msg.IsNoteOn(out pitch))
                {
                    // Note-on event
                    if (wrongChannel || (plugin.State != PluginState.Activated || plugin.KeyZoneActive && (pitch < plugin.KeyZoneLower || pitch > plugin.KeyZoneUpper)))
                    {
                        // Ignore note-on
                        continue;
                    }
                    plugin.Notes[pitch].Pressed  = true;
                    plugin.Notes[pitch].Velocity = data[2];
                    newEv.Data[1] += (byte)plugin.Transpose;
                    mFilteredMidiEvents.Add(newEv);
                }
                else if (msg.IsNoteOff(out pitch))
                {
                    // Note-off event
                    if (wrongChannel || (plugin.KeyZoneActive && (pitch < plugin.KeyZoneLower || pitch > plugin.KeyZoneUpper)))
                    {
                        // Ignore note-off
                        continue;
                    }
                    newEv.Data[1] += (byte)plugin.Transpose;
                    if (plugin.Notes[pitch].PressedTime >= plugin.NoteDropDelay)
                    {
                        // Also send note-off message for note-dropped note
                        byte[] noteOffData = new byte[4];
                        noteOffData[0] = 128;
                        noteOffData[1] = (byte)(pitch - 12);
                        noteOffData[2] = plugin.Notes[pitch].Velocity;
                        noteOffData[3] = 112;
                        VstMidiEvent noteOffEvent = new VstMidiEvent(
                            /*DeltaFrames*/ 0,
                            /*NoteLength*/ 0,
                            /*NoteOffset*/ 0,
                            noteOffData,
                            /*Detune*/ 0,
                            /*NoteOffVelocity*/ 127);
                        mFilteredMidiEvents.Add(noteOffEvent);
                    }
                    plugin.Notes[pitch].Pressed = false;
                    mFilteredMidiEvents.Add(newEv);
                }
                else if (msg.IsSustain())
                {
                    if (plugin.SustainEnabled)
                    {
                        mFilteredMidiEvents.Add(newEv);
                    }
                    continue;
                }
                else
                {
                    // All other events
                    mFilteredMidiEvents.Add(newEv);
                }
            }


            // Process note on times; for now only required when NoteDrop = true
            if (plugin.NoteDrop)
            {
                for (int i = 0; i < 255; i++)
                {
                    if (plugin.Notes[i].Pressed)
                    {
                        plugin.Notes[i].PressedTime++;
                        if (plugin.Notes[i].PressedTime == plugin.NoteDropDelay)
                        {
                            byte[] noteDropData = new byte[4];
                            noteDropData[0] = 144;
                            noteDropData[1] = (byte)(i - 12);
                            noteDropData[2] = plugin.Notes[i].Velocity;
                            noteDropData[3] = 112;
                            VstMidiEvent newEv = new VstMidiEvent(
                                /*DeltaFrames*/ 0,
                                /*NoteLength*/ 0,
                                /*NoteOffset*/ 0,
                                noteDropData,
                                /*Detune*/ 0,
                                /*NoteOffVelocity*/ 127);
                            mFilteredMidiEvents.Add(newEv);
                        }
                    }
                }
            }

            return(mFilteredMidiEvents.ToArray());
        }
        /// <summary>
        ///     Attempts to create a VstMidiEvent representation of <paramref name="mssEvent"/>.
        /// </summary>
        /// <returns>The VstMidiEvent representation of mssEvent or null of there is no valid conversion.</returns>
        protected static VstMidiEvent ConvertMssEventToVstMidiEvent(MssEvent mssEvent,
            long sampleTimeAtStartOfProcessingCycle,
            double sampleRate)
        {
            Debug.Assert(mssEvent.sampleTime >= sampleTimeAtStartOfProcessingCycle);

            //Calculate delta frames
            int deltaFrames = (int)(mssEvent.sampleTime - sampleTimeAtStartOfProcessingCycle);

            byte[] midiData = new byte[3];

            //Get status half of first byte.
            byte statusByte;

            if (MidiUtil.GetStatusFromMssMsgType(mssEvent.mssMsg.Type, out statusByte) == false)
            {
                return null;
            }

            //subtract 1 becasue channels are 0 based in midi but 1 based in mss
            byte channelByte = (byte)(mssEvent.mssMsg.Data1AsInt - 1);

            midiData[0] = (byte) (statusByte | channelByte);

            if (mssEvent.mssMsg.Type == MssMsgType.PitchBend) {
                //most significant bits
                int MsbVal = (mssEvent.mssMsg.Data3AsInt) >> 7;
                midiData[2] = (byte)MsbVal;
                midiData[1] = (byte)((mssEvent.mssMsg.Data3AsInt) - (MsbVal << 7));
            }
            else if (mssEvent.mssMsg.Type == MssMsgType.ChanAftertouch)
            {
                midiData[1] = (byte)mssEvent.mssMsg.Data3AsInt;
                midiData[2] = 0;
            }
            else
            {
                midiData[1] = (byte)mssEvent.mssMsg.Data2AsInt;
                midiData[2] = (byte)mssEvent.mssMsg.Data3AsInt;
            }
            VstMidiEvent midiEvent = new VstMidiEvent(deltaFrames, 0, 0, midiData, 0, 0);

            return midiEvent;
        }
Exemple #18
0
        public void ProcessCurrentEvents()
        {
            if (CurrentEvents == null || CurrentEvents.Count == 0)
            {
                return;
            }

            // a plugin must implement IVstPluginMidiSource or this call will throw an exception.
            IVstMidiProcessor midiHost = _plugin.Host.GetInstance <IVstMidiProcessor>();

            // always expect some hosts not to support this.
            if (midiHost != null)
            {
                VstEventCollection outEvents = new VstEventCollection();

                // NOTE: other types of events could be in the collection!
                foreach (VstEvent evnt in CurrentEvents)
                {
                    switch (evnt.EventType)
                    {
                    case VstEventTypes.MidiEvent:
                        VstMidiEvent midiEvent = (VstMidiEvent)evnt;

                        //General midi effects for all inputs
                        midiEvent = Gain.ProcessEvent(midiEvent);
                        midiEvent = Transpose.ProcessEvent(midiEvent);

                        //Process Midi Note in SampleManager
                        if ((midiEvent.Data[0] & 0xF0) == 0x80)
                        {
                            _plugin.SampleManager.ProcessNoteOffEvent(midiEvent.Data[1]);
                        }

                        if ((midiEvent.Data[0] & 0xF0) == 0x90)
                        {
                            // note on with velocity = 0 is a note off
                            if (MidiHelper.IsNoteOff(midiEvent.Data))
                            {
                                _plugin.SampleManager.ProcessNoteOffEvent(midiEvent.Data[1]);
                            }
                            else
                            {
                                _plugin.SampleManager.ProcessNoteOnEvent(midiEvent.Data[1]);
                            }
                        }

                        outEvents.Add(midiEvent);
                        break;

                    default:
                        // non VstMidiEvent
                        outEvents.Add(evnt);
                        break;
                    }
                }

                midiHost.Process(outEvents);
            }

            // Clear the cache, we've processed the events.
            CurrentEvents = null;
        }
Exemple #19
0
        // deep copy (reference type)
        private VstMidiEvent makeCopy(VstMidiEvent e)
        {
            VstMidiEvent newEvent = new VstMidiEvent(e.DeltaFrames, e.NoteLength, e.NoteOffset, e.Data, e.Detune, e.NoteOffVelocity);

            return(newEvent);
        }
Exemple #20
0
        private IEnumerable <VstEvent> CreateCascadeNotes(VstMidiEvent inEvent, int quartersPassed, VstTimeInfo timeInfo)
        {
            //Log("CreateCascadeNotes");
            var origNote = inEvent.Data[1] % 12;
            //Log("origNote" + origNote);
            var step = Array.IndexOf(A_MINOR_MIDI, origNote);
            var note = inEvent.Data[1];

            if (step == -1)
            {
                //Log("rounding");
                note++;                 //rounding into scale
                step = Array.IndexOf(A_MINOR_MIDI, (origNote + 1) % 12);
            }
            var upDown = CascadeMgr.CurrentValue > 0.5 ? 1 : -1;

            //Log("doing " + note + " " + quartersPassed);
            for (int x = 0; x < quartersPassed; x++)
            {
                //Log("stepping " + MINOR[step]);

                //todo: up or down
                note += (byte)(MINOR[upDown == 1 ? step : ((step + 6) % 7)] * upDown);
                step  = (step + 7 + upDown) % 7;
            }

            var name = NAMES[note % 12];

            Log("step" + name);


            var delta = (int)(TimeInfos[inEvent.Data[1]].SamplePosition + spb * quartersPassed - timeInfo.SamplePosition);

            Log("delta " + delta);
            //outData[1] pitch
            //outData[2] volume
            var outDataOn = new byte[] {
                0x90,
                note,
                inEvent.Data[2],
                0
            };

            var outEventOn = new VstMidiEvent(
                delta,
                0,
                0,
                outDataOn,
                0,
                0);

            var outDataOff = new byte[] {
                0x80,
                note,
                0,
                0
            };

            var outEventOff = new VstMidiEvent(
                delta + (int)spb,                 // quarter length
                0,
                0,
                outDataOff,
                0,
                0);

            return(new VstEvent[] { outEventOn, outEventOff });
        }
Exemple #21
0
        public void Process(VstEventCollection events)
        {
            foreach (VstEvent evnt in events)
            {
                if (evnt.EventType != VstEventTypes.MidiEvent)
                {
                    continue;
                }

                VstMidiEvent midiEvent = (VstMidiEvent)evnt;


                //  note on
                if ((midiEvent.Data[0] & 0xF0) == 0x90)
                {
                    // note off
                    // You can treat note-on midi events with a velocity of 0 (zero) as a note-off midi event.
                    if (midiEvent.Data[2] == 0)
                    {
                        lock (((ICollection)NoteOffNumbers).SyncRoot)
                        {
                            lock (((ICollection)_noteOnEvents).SyncRoot)
                            {
                                lock (((ICollection)_octavesAddedOrderedNoteOnEvents).SyncRoot)
                                {
                                    NoteOffNumbers.Enqueue(midiEvent.Data[1]);
                                    _noteOnEvents.RemoveAll(n => n.Data[1] == midiEvent.Data[1]);

                                    AddOctaves();
                                    OrderNoteOnEventsWithOctaves();
                                }
                            }
                        }
                    }

                    // note on
                    else
                    {
                        lock (((ICollection)NoteOnNumbers).SyncRoot)
                        {
                            lock (((ICollection)_noteOnEvents).SyncRoot)
                            {
                                lock (((ICollection)_octavesAddedOrderedNoteOnEvents).SyncRoot)
                                {
                                    NoteOnNumbers.Enqueue(midiEvent.Data[1]);
                                    _noteOnEvents.Add(midiEvent);

                                    AddOctaves();
                                    OrderNoteOnEventsWithOctaves();
                                }
                            }
                        }
                    }
                }

                // note off
                else if ((midiEvent.Data[0] & 0xF0) == 0x80)
                {
                    lock (((ICollection)NoteOffNumbers).SyncRoot)
                    {
                        lock (((ICollection)_noteOnEvents).SyncRoot)
                        {
                            lock (((ICollection)_octavesAddedOrderedNoteOnEvents).SyncRoot)
                            {
                                NoteOffNumbers.Enqueue(midiEvent.Data[1]);

                                /* FOR TESTING ADDOCTAVES()
                                 * string notes = "";
                                 * foreach (VstMidiEvent e in _noteOnEvents)
                                 *  notes += e.Data[1] + " ";
                                 *
                                 * MessageBox.Show("Process method: \nNoteOnEvents: " + notes);
                                 */

                                _noteOnEvents.RemoveAll(n => n.Data[1] == midiEvent.Data[1]);

                                AddOctaves();
                                OrderNoteOnEventsWithOctaves();
                            }
                        }
                    }
                }
            }
        }
Exemple #22
0
 public MidiMessage(VstMidiEvent vstMidiEvent)
 {
     _vstMidiEvent = vstMidiEvent;
 }
Exemple #23
0
 public void SetMidiEvent(int deltaFrames, byte[] msg)
 {
     if (FCanEvents)
     {
         VstEvent evt = new VstMidiEvent(deltaFrames, 0, 0, msg, 0, 0);
         MidiEvents.Add(evt);
         FHasEvents = true;
     }
 }
        /// <summary>
        ///     Attempts to create an MssEvent representation of <paramref name="midiEvent"/>.
        /// </summary>
        /// <returns>The MssEvent representation of midiEvent or null of there is no valid conversion.</returns>
        protected static MssEvent ConvertVstMidiEventToMssEvent(VstMidiEvent midiEvent, 
            long sampleTimeAtStartOfProcessingCycle,
            double sampleRate)
        {
            MssEvent mssEvent = new MssEvent();

            //Sets the sample time for mssEvent.
            mssEvent.sampleTime = sampleTimeAtStartOfProcessingCycle + midiEvent.DeltaFrames;

            MssMsgType msgType = MidiUtil.GetMssTypeFromMidiData(midiEvent.Data);
            mssEvent.mssMsg.Type = msgType;

            //If msgType is "Unsupported" then midiEvent cannot be represented as an MssEvent
            if (msgType == MssMsgType.Unsupported)
            {
                return null;
            }

            //Sets mssEvent's Data1 (midi channel).
            //Adds one because channels in an MssMsg start at 1 but channels in a VstMidiEvent start at 0
            mssEvent.mssMsg.Data1 = (midiEvent.Data[0] & 0x0F) + 1;

            //Sets mssEvent's Data2 and Data3 (the midi message's data bytes).
            if (msgType == MssMsgType.PitchBend)
            {
                //The two data bytes for pitch bend are used to store one 14-bit number so this number is stored in
                //mssEvent.Data3 and mssEvent.Data2 is not used.
                mssEvent.mssMsg.Data2 = MssMsgUtil.UNUSED_MSS_MSG_DATA;

                //data1 contains the least significant 7 bits of the pitch bend value and data2 contains the most
                //significant 7 bits
                mssEvent.mssMsg.Data3 = (midiEvent.Data[2] << 7) + midiEvent.Data[1];
            }
            else if (msgType == MssMsgType.ChanAftertouch)
            {
                mssEvent.mssMsg.Data2 = MssMsgUtil.UNUSED_MSS_MSG_DATA;
                mssEvent.mssMsg.Data3 = midiEvent.Data[1];
            }
            else
            {
                mssEvent.mssMsg.Data2 = midiEvent.Data[1];
                mssEvent.mssMsg.Data3 = midiEvent.Data[2];
            }

            return mssEvent;
        }
Exemple #25
0
        // 44100 sample frame = 1 sec
        // az_octavesAddedOrderedNoteOnEventset dolgozza fel
        public void Arpeggiate()
        {
            countQuarter(); // if new Tempo was set

            VstMidiEvent newMidiEvent;

            if (_octavesAddedOrderedNoteOnEvents.Count == 0)
            {
                _rythmCounter = 0;
            }

            if (_processedFrames == 0 && _octavesAddedOrderedNoteOnEvents.Count > 0) // kör eleje, van lejátszandó hang
            {
                _actualMidiEvent = makeCopy(_octavesAddedOrderedNoteOnEvents[_counter]);

                // probability
                randomValue = random.Next(1, 101);                            // 1-100

                if (_rythm[_rythmCounter].note && randomValue <= Probability) // ha nem szünet
                {
                    byte[] midiData = new byte[4];
                    midiData[0] = 0x90;
                    midiData[1] = _actualMidiEvent.Data[1];
                    if (_rythm[_rythmCounter].accent)
                    {
                        midiData[2] = 0x7F;
                    }
                    else
                    {
                        midiData[2] = _actualMidiEvent.Data[2];
                    }
                    midiData[3] = 0;

                    newMidiEvent = new VstMidiEvent(_remainder, _actualMidiEvent.NoteLength, _actualMidiEvent.NoteOffset, midiData, _actualMidiEvent.Detune, _actualMidiEvent.NoteOffVelocity);
                    Events.Add(newMidiEvent);
                    _processedFrames += 512;
                }
                else // ha szünet
                {
                    _processedFrames += 512;
                }
            }

            // ha a még legalább egy kör van hátra addig, amíg a hangot ki kell játszani
            else if (_processedFrames < _rythm[_rythmCounter].frames - 512 && _actualMidiEvent != null) // kör léptetése
            {
                _processedFrames += 512;
            }

            else if (_actualMidiEvent != null) // note off. a processedFrames belépett a kritikus szakaszba
            {
                // && randomValue <= Probability
                if (_rythm[_rythmCounter].note)  // ha nem szünet, akkor note off az előző hangra
                {
                    // create note off event
                    byte[] midiData = new byte[4];
                    midiData[0]  = 0x80;
                    midiData[1]  = _actualMidiEvent.Data[1];
                    midiData[2]  = _actualMidiEvent.Data[2];
                    midiData[3]  = 0;
                    newMidiEvent = new VstMidiEvent(Convert.ToInt32(_rythm[_rythmCounter].frames) - _processedFrames, _actualMidiEvent.NoteLength, _actualMidiEvent.NoteOffset, midiData, _actualMidiEvent.Detune, _actualMidiEvent.NoteOffVelocity);
                    Events.Add(newMidiEvent);
                }

                if (_counter + 1 < _octavesAddedOrderedNoteOnEvents.Count)    // note on a következő hangra az _octavesAddedOrderedNoteOnEvents listából
                {
                    // rythm
                    if (_rythm[_rythmCounter].note) // ha nem szünet volt, akkor lépthethetem az events listát. a probability itt nem érdekes
                    {
                        _counter++;
                    }

                    if ((_rythmCounter + 1) < _rythm.Count)
                    {
                        _rythmCounter++;
                    }
                    else
                    {
                        _rythmCounter = 0;
                        _counter      = 0;   // ha a ritmusképlet körbeért, a hangok is kezdődjenek elölről
                    }

                    _actualMidiEvent = makeCopy(_octavesAddedOrderedNoteOnEvents[_counter]);
                    randomValue      = random.Next(1, 101);

                    // következő hang
                    if (_rythm[_rythmCounter].note && randomValue <= Probability) // ha nem szünet, jöhet a következő hang note on-ja is, a note off-fal egyidőben
                    {
                        // note on
                        byte[] midiData = new byte[4];
                        midiData[0] = 0x90;
                        midiData[1] = _actualMidiEvent.Data[1];
                        if (_rythm[_rythmCounter].accent)
                        {
                            midiData[2] = 0x7F;
                        }
                        else
                        {
                            midiData[2] = _actualMidiEvent.Data[2];
                        }
                        midiData[3] = 0;

                        newMidiEvent = new VstMidiEvent(Convert.ToInt32(_rythm[_rythmCounter].frames) - _processedFrames, _actualMidiEvent.NoteLength, _actualMidiEvent.NoteOffset, midiData, _actualMidiEvent.Detune, _actualMidiEvent.NoteOffVelocity);
                        Events.Add(newMidiEvent);

                        _remainder       = 512 - (Convert.ToInt32(_rythm[_rythmCounter].frames) - _processedFrames);
                        _processedFrames = 0;
                    }
                    else // ha a következő hang szünet
                    {
                        _remainder       = 512 - (Convert.ToInt32(_rythm[_rythmCounter].frames) - _processedFrames);
                        _processedFrames = 0;
                    }
                }
                else // végigért az _octavesAddedOrderedNoteOnEvents listán, kör eleje
                {
                    _counter         = 0;
                    _actualMidiEvent = null;
                    _remainder       = 0;
                    _processedFrames = 0;


                    // rythm
                    if ((_rythmCounter + 1) < _rythm.Count)
                    {
                        _rythmCounter++;
                    }
                    else
                    {
                        _rythmCounter = 0;
                        _counter      = 0;   // ha a ritmusképlet körbeért, a hangok is kezdődjenek elölről
                    }
                }
            }
        }
Exemple #26
0
		void midiIn_MessageReceived(object sender, MidiInMessageEventArgs e)
		{
			progressLog1.LogMessage(Color.Blue, String.Format("Time {0} Message 0x{1:X8} Event {2}",
			                                                  e.Timestamp, e.RawMessage, e.MidiEvent));

			//SendMidiOutMessage(e.MidiEvent);
			if (VSTForm.vst != null) {
				MidiEvent midiEvent = e.MidiEvent;
				byte[] midiData = { 0, 0, 0 };
				if (midiEvent is NAudio.Midi.NoteEvent)
				{
					var me = (NAudio.Midi.NoteEvent) midiEvent;
					midiData = new byte[] {
						0x90, 					// Cmd
						(byte) me.NoteNumber,	// Val 1
						(byte) me.Velocity,		// Val 2
					};
				}
				else if (midiEvent is NAudio.Midi.ControlChangeEvent)
				{
					var cce = (NAudio.Midi.ControlChangeEvent) midiEvent;
					midiData = new byte[] {
						0xB0, 						// Cmd
						(byte)cce.Controller,		// Val 1
						(byte)cce.ControllerValue,	// Val 2
					};
				}
				else if (midiEvent is NAudio.Midi.PitchWheelChangeEvent)
				{
					// Pitch Wheel Value 0 is minimum, 0x2000 (8192) is default, 0x4000 (16384) is maximum
					NAudio.Midi.PitchWheelChangeEvent pe = (PitchWheelChangeEvent) midiEvent;
					midiData = new byte[] {
						0xE0, 							// Cmd
						(byte)(pe.Pitch & 0x7f),		// Val 1
						(byte)((pe.Pitch >> 7) & 0x7f),	// Val 2
					};
				}
				progressLog1.LogMessage(Color.Chocolate, String.Format("Sending mididata 0x00{0:X2}{1:X2}{2:X2}",
				                                                       midiData[2], midiData[1], midiData[0]));
				var vse =
					new VstMidiEvent(/*DeltaFrames*/ 0,
					                 /*NoteLength*/ 0,
					                 /*NoteOffset*/ 0,
					                 midiData,
					                 /*Detune*/ 0,
					                 /*NoteOffVelocity*/ 0);

				var ve = new VstEvent[1];
				ve[0] = vse;
				
				VSTForm.vst.pluginContext.PluginCommandStub.ProcessEvents(ve);
			}
		}
Exemple #27
0
        private VstEvent[] CreateMidiEvent(byte statusByte, byte midiNote, byte midiVelocity)
        {
            /*
             * Just a small note on the code for setting up a midi event:
             * You can use the VstEventCollection class (Framework) to setup one or more events
             * and then call the ToArray() method on the collection when passing it to
             * ProcessEvents. This will save you the hassle of dealing with arrays explicitly.
             * http://computermusicresource.com/MIDI.Commands.html
             *
             * Freq to Midi notes etc:
             * http://www.sengpielaudio.com/calculator-notenames.htm
             *
             * Example to use NAudio Midi support
             * http://stackoverflow.com/questions/6474388/naudio-and-midi-file-reading
             */
            byte[] midiData = new byte[4];

            midiData[0] = statusByte;
            midiData[1] = midiNote;   	// Midi note
            midiData[2] = midiVelocity; // Note strike velocity
            midiData[3] = 0;    		// Reserved, unused

            VstMidiEvent vse = new VstMidiEvent(/*DeltaFrames*/ 	0,
                                                /*NoteLength*/ 	0,
                                                /*NoteOffset*/ 	0,
                                                midiData,
                                                /*Detune*/    		0,
                                                /*NoteOffVelocity*/ 127); // previously 0

            VstEvent[] ve = new VstEvent[1];
            ve[0] = vse;
            return ve;
        }
Exemple #28
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="settingsMgr"></param>
        /// <param name="channels"></param>
        public AudioPluginEngine(SettingsManager settingsMgr, VuMeter[] meters, Panel hostScrollPanel)
        {
            // Add editor panel to host to allow scrolling
            mHostScrollPanel = hostScrollPanel;
            Panel hostEditorPanel = new Panel();

            hostScrollPanel.Controls.Add(hostEditorPanel);

            PluginChannels = new VstPluginChannel[NrOfPluginChannels];
            mMidiPanic     = new bool[NrOfPluginChannels];

            // Create all channel, effect and master effect plugins
            for (int i = 0; i < NrOfPluginChannels; i++)
            {
                PluginChannels[i] = new VstPluginChannel(settingsMgr.Settings.AsioBufferSize);
                mMidiPanic[i]     = false;
            }
            MasterEffectPluginChannel = new VstPluginChannel(settingsMgr.Settings.AsioBufferSize);

            foreach (VstPlugin plugin in PluginChannels.SelectMany(x => x.AllPlugins))
            {
                plugin.EditorPanel = hostEditorPanel;
                // Let controls know if other control loaded an editor
                plugin.OnEditorOpening += chCtrl_OnEditorOpen;
                plugin.OnEditorOpened  += chCtrl_OnEditorOpened;
                plugin.OnEditorClosed  += chCtrl_OnEditorClose;
            }

            mSettingsMgr = settingsMgr;
            mVUMeters    = meters;

            if (mSettingsMgr.Settings.VSTPluginFolders != null)
            {
                foreach (string path in mSettingsMgr.Settings.VSTPluginFolders)
                {
                    addPath(path);
                }
            }

            MasterPan = mSettingsMgr.Settings.MasterPan;

            // Send all notes off on midi channel 1
            byte[] midiData = new byte[4];
            // http://www.midi.org/techspecs/midimessages.php
            midiData[0] = 176;  // Send all notes off on midi channel 1
            midiData[1] = 123;  // All Notes Off
            midiData[2] = 0;
            midiData[3] = 0;

            VstMidiEvent midiPanicEvent = new VstMidiEvent(
                /*DeltaFrames*/ 0,
                /*NoteLength*/ 0,
                /*NoteOffset*/ 0,
                midiData,
                /*Detune*/ 0,
                /*NoteOffVelocity*/ 127);

            mMidiPanicEvents    = new VstEvent[1];
            mMidiPanicEvents[0] = midiPanicEvent;

            mMidiDevice = new MidiDevice();
        }
 public MssEvent ConvertVstMidiEventToMssEventWrapper(VstMidiEvent midiEvent,
                                                      long processingCycleStartTime,
                                                      double sampleRate)
 {
     return(ConvertVstMidiEventToMssEvent(midiEvent, processingCycleStartTime, sampleRate));
 }