From cbb07a811b3f3220ac005342acc7a159e786b700 Mon Sep 17 00:00:00 2001 From: Ben Crossman Date: Wed, 16 Oct 2019 08:49:40 +1100 Subject: [PATCH] Revised attempt at: https://github.com/falkTX/Carla/pull/489 (#782) * Revised attempt at: https://github.com/falkTX/Carla/pull/489 * Redid the changes to CarlaPluginJuce.cpp * Fixed warning --- source/backend/plugin/CarlaPluginBridge.cpp | 23 +++++++++++++++- source/backend/plugin/CarlaPluginJuce.cpp | 30 ++++++++++++++++++--- source/backend/plugin/CarlaPluginVST2.cpp | 26 +++++++++++------- 3 files changed, 65 insertions(+), 14 deletions(-) diff --git a/source/backend/plugin/CarlaPluginBridge.cpp b/source/backend/plugin/CarlaPluginBridge.cpp index f98439af7..a9e82a36e 100644 --- a/source/backend/plugin/CarlaPluginBridge.cpp +++ b/source/backend/plugin/CarlaPluginBridge.cpp @@ -1286,10 +1286,31 @@ public: fShmRtClientControl.writeUShort(event.ctrl.param); fShmRtClientControl.commitWrite(); } + else if ((pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) != 0) + { + // VST2's that use banks usually require both a MSB bank message and a LSB bank message. The MSB bank message can just be 0 + fShmRtClientControl.writeOpcode(kPluginBridgeRtClientMidiEvent); + fShmRtClientControl.writeUInt(event.time); + fShmRtClientControl.writeByte(0); // port + fShmRtClientControl.writeByte(3); // size + fShmRtClientControl.writeByte(uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT))); + fShmRtClientControl.writeByte(MIDI_CONTROL_BANK_SELECT); + fShmRtClientControl.writeByte(0); + fShmRtClientControl.commitWrite(); + + fShmRtClientControl.writeOpcode(kPluginBridgeRtClientMidiEvent); + fShmRtClientControl.writeUInt(event.time); + fShmRtClientControl.writeByte(0); // port + fShmRtClientControl.writeByte(3); // size + fShmRtClientControl.writeByte(uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT))); + fShmRtClientControl.writeByte(MIDI_CONTROL_BANK_SELECT__LSB); + fShmRtClientControl.writeByte(uint8_t(event.ctrl.param)); + fShmRtClientControl.commitWrite(); + } break; case kEngineControlEventTypeMidiProgram: - if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) + if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES || pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) { fShmRtClientControl.writeOpcode(kPluginBridgeRtClientControlEventMidiProgram); fShmRtClientControl.writeUInt(event.time); diff --git a/source/backend/plugin/CarlaPluginJuce.cpp b/source/backend/plugin/CarlaPluginJuce.cpp index 22f35b5b7..ebb8cc152 100644 --- a/source/backend/plugin/CarlaPluginJuce.cpp +++ b/source/backend/plugin/CarlaPluginJuce.cpp @@ -185,6 +185,7 @@ public: options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH; options |= PLUGIN_OPTION_SEND_PITCHBEND; options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF; + options |= PLUGIN_OPTION_SEND_PROGRAM_CHANGES; } return options; @@ -893,6 +894,18 @@ public: } // case kEngineControlEventTypeParameter case kEngineControlEventTypeMidiBank: + if ((pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) != 0) + { + uint8_t midiData[3]; + midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); + midiData[1] = MIDI_CONTROL_BANK_SELECT; + midiData[2] = 0; + fMidiBuffer.addEvent(midiData, 3, static_cast(event.time)); + + midiData[1] = MIDI_CONTROL_BANK_SELECT__LSB; + midiData[2] = uint8_t(ctrlEvent.value*127.0f); + fMidiBuffer.addEvent(midiData, 3, static_cast(event.time)); + } break; case kEngineControlEventTypeMidiProgram: @@ -901,9 +914,15 @@ public: if (ctrlEvent.param < pData->prog.count) { setProgramRT(ctrlEvent.param); - break; } } + else if ((pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) != 0) + { + uint8_t midiData[3]; + midiData[0] = uint8_t(MIDI_STATUS_PROGRAM_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); + midiData[1] = uint8_t(ctrlEvent.value*127.0f); + fMidiBuffer.addEvent(midiData, 2, static_cast(event.time)); + } break; case kEngineControlEventTypeAllSoundOff: @@ -1310,9 +1329,6 @@ public: pData->options |= PLUGIN_OPTION_FIXED_BUFFERS; pData->options |= PLUGIN_OPTION_USE_CHUNKS; - if (fInstance->getNumPrograms() > 1) - pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES; - if (fInstance->acceptsMidi()) { pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE; @@ -1322,8 +1338,14 @@ public: if (options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) pData->options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES; + + if (options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) + pData->options |= PLUGIN_OPTION_SEND_PROGRAM_CHANGES; } + if (fInstance->getNumPrograms() > 1 && ((pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) == 0)) + pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES; + return true; } diff --git a/source/backend/plugin/CarlaPluginVST2.cpp b/source/backend/plugin/CarlaPluginVST2.cpp index 96fc9e7d3..025bdc28e 100644 --- a/source/backend/plugin/CarlaPluginVST2.cpp +++ b/source/backend/plugin/CarlaPluginVST2.cpp @@ -1396,15 +1396,23 @@ public: if (fMidiEventCount >= kPluginMaxMidiEvents*2) continue; - VstMidiEvent& vstMidiEvent(fMidiEvents[fMidiEventCount++]); - carla_zeroStruct(vstMidiEvent); - - vstMidiEvent.type = kVstMidiType; - vstMidiEvent.byteSize = kVstMidiEventSize; - vstMidiEvent.deltaFrames = static_cast(isSampleAccurate ? startTime : eventTime); - vstMidiEvent.midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); - vstMidiEvent.midiData[1] = MIDI_CONTROL_BANK_SELECT; - vstMidiEvent.midiData[2] = char(ctrlEvent.param); + VstMidiEvent& vstMidiEvent_MSB(fMidiEvents[fMidiEventCount++]); + carla_zeroStruct(vstMidiEvent_MSB); + vstMidiEvent_MSB.type = kVstMidiType; + vstMidiEvent_MSB.byteSize = kVstMidiEventSize; + vstMidiEvent_MSB.deltaFrames = static_cast(isSampleAccurate ? startTime : event.time); + vstMidiEvent_MSB.midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); + vstMidiEvent_MSB.midiData[1] = MIDI_CONTROL_BANK_SELECT; + vstMidiEvent_MSB.midiData[2] = 0; + + VstMidiEvent& vstMidiEvent_LSB(fMidiEvents[fMidiEventCount++]); + carla_zeroStruct(vstMidiEvent_LSB); + vstMidiEvent_LSB.type = kVstMidiType; + vstMidiEvent_LSB.byteSize = kVstMidiEventSize; + vstMidiEvent_LSB.deltaFrames = static_cast(isSampleAccurate ? startTime : eventTime); + vstMidiEvent_LSB.midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); + vstMidiEvent_LSB.midiData[1] = MIDI_CONTROL_BANK_SELECT__LSB; + vstMidiEvent_LSB.midiData[2] = char(ctrlEvent.param); } break;