public void Process_SysExEvent_NothingSentToRelay() { VstEventCollection vstEvents = new VstEventCollection(); VstMidiSysExEvent unsupportedEvent = new VstMidiSysExEvent(0, new byte[3]); vstEvents.Add(unsupportedEvent); Test_Process_VstEventCollection_SentToReplay(vstEvents, 0); }
public void Test_VstMidiSysExEvent_Constructor() { int deltaFrames = 12; byte[] sysexData = new byte[] { 0x9C, 0x7F, 0x40 }; var me = new VstMidiSysExEvent(deltaFrames, sysexData); me.EventType.Should().Be(VstEventTypes.MidiSysExEvent); me.DeltaFrames.Should().Be(deltaFrames); me.Data.Should().NotBeNull(); me.Data.Length.Should().Be(sysexData.Length); me.Data[0].Should().Be(sysexData[0]); me.Data[1].Should().Be(sysexData[1]); me.Data[2].Should().Be(sysexData[2]); }
public void Test_VstMidiSysExEvent_Constructor() { int deltaFrames = 12; byte[] sysexData = new byte[] { 0x9C, 0x7F, 0x40 }; VstMidiSysExEvent me = new VstMidiSysExEvent(deltaFrames, sysexData); Assert.AreEqual(VstEventTypes.MidiSysExEvent, me.EventType, "VstMidiSysExEvent.EventType"); Assert.AreEqual(deltaFrames, me.DeltaFrames, "VstMidiSysExEvent.DeltaFrames"); Assert.IsNotNull(me.Data, "VstMidiSysExEvent.Data is null"); Assert.AreEqual(3, me.Data.Length, "VstMidiSysExEvent.Data.Length"); Assert.AreEqual(0x9C, me.Data[0], "VstMidiSysExEvent.Data[0]"); Assert.AreEqual(0x7F, me.Data[1], "VstMidiSysExEvent.Data[1]"); Assert.AreEqual(0x40, me.Data[2], "VstMidiSysExEvent.Data[2]"); }
public void Process_SomeSupportedSomeUnsupporedEvents_SomeSentToRelay() { VstEventCollection vstEvents = new VstEventCollection(); //Supported event type vstEvents.Add(Factory_VstMidiEvent_Basic(0, CreateMidiDataWithDefaultValues(MssMsgType.PitchBend))); //Unsupported event type VstMidiSysExEvent unsupportedEvent = new VstMidiSysExEvent(0, new byte[3]); vstEvents.Add(unsupportedEvent); //Supported event type vstEvents.Add(Factory_VstMidiEvent_Basic(0, CreateMidiDataWithDefaultValues(MssMsgType.PolyAftertouch))); Test_Process_VstEventCollection_SentToReplay(vstEvents, 2); }
// 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 } } }
// 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 }