diff --git a/source/backend/plugin/CarlaPluginLV2.cpp b/source/backend/plugin/CarlaPluginLV2.cpp index 788244548..3e2005350 100644 --- a/source/backend/plugin/CarlaPluginLV2.cpp +++ b/source/backend/plugin/CarlaPluginLV2.cpp @@ -3206,7 +3206,7 @@ public: { if (event.channel == pData->ctrlChannel) { - const uint32_t nextProgramId = ctrlEvent.param; + const uint32_t nextProgramId(ctrlEvent.param); for (uint32_t k=0; k < pData->midiprog.count; ++k) { diff --git a/source/backend/plugin/CarlaPluginNative.cpp b/source/backend/plugin/CarlaPluginNative.cpp index 9d25392c5..797640021 100644 --- a/source/backend/plugin/CarlaPluginNative.cpp +++ b/source/backend/plugin/CarlaPluginNative.cpp @@ -1592,33 +1592,66 @@ public: } case kEngineControlEventTypeMidiBank: - if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0) - nextBankId = ctrlEvent.param; + if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) + { + if (event.channel == pData->ctrlChannel) + nextBankId = ctrlEvent.param; + } + else if (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) + { + if (fMidiEventCount >= kPluginMaxMidiEvents*2) + continue; + + NativeMidiEvent& nativeEvent(fMidiEvents[fMidiEventCount++]); + carla_zeroStruct(nativeEvent); + + nativeEvent.time = sampleAccurate ? startTime : event.time; + nativeEvent.data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); + nativeEvent.data[1] = MIDI_CONTROL_BANK_SELECT; + nativeEvent.data[2] = uint8_t(ctrlEvent.param); + nativeEvent.size = 3; + } break; case kEngineControlEventTypeMidiProgram: - if (event.channel < MAX_MIDI_CHANNELS && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0) + if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) { - const uint32_t nextProgramId(ctrlEvent.param); - - for (uint32_t k=0; k < pData->midiprog.count; ++k) + if (event.channel < MAX_MIDI_CHANNELS) { - if (pData->midiprog.data[k].bank == nextBankId && pData->midiprog.data[k].program == nextProgramId) + const uint32_t nextProgramId(ctrlEvent.param); + + for (uint32_t k=0; k < pData->midiprog.count; ++k) { - fDescriptor->set_midi_program(fHandle, event.channel, nextBankId, nextProgramId); + if (pData->midiprog.data[k].bank == nextBankId && pData->midiprog.data[k].program == nextProgramId) + { + fDescriptor->set_midi_program(fHandle, event.channel, nextBankId, nextProgramId); - if (fHandle2 != nullptr) - fDescriptor->set_midi_program(fHandle2, event.channel, nextBankId, nextProgramId); + if (fHandle2 != nullptr) + fDescriptor->set_midi_program(fHandle2, event.channel, nextBankId, nextProgramId); - fCurMidiProgs[event.channel] = static_cast(k); + fCurMidiProgs[event.channel] = static_cast(k); - if (event.channel == pData->ctrlChannel) - pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, static_cast(k), 0, 0.0f); + if (event.channel == pData->ctrlChannel) + pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, static_cast(k), 0, 0.0f); - break; + break; + } } } } + else if (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) + { + if (fMidiEventCount >= kPluginMaxMidiEvents*2) + continue; + + NativeMidiEvent& nativeEvent(fMidiEvents[fMidiEventCount++]); + carla_zeroStruct(nativeEvent); + + nativeEvent.time = sampleAccurate ? startTime : event.time; + nativeEvent.data[0] = uint8_t(MIDI_STATUS_PROGRAM_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); + nativeEvent.data[1] = uint8_t(ctrlEvent.param); + nativeEvent.size = 2; + } break; case kEngineControlEventTypeAllSoundOff: