diff --git "a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp" "b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp" index f3e59e579..4cfe6db84 100644 --- "a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp" +++ "b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp" @@ -77,6 +77,12 @@ JUCE_BEGIN_NO_SANITIZE ("vptr") #endif #endif +#ifndef JUCE_VST3_EMULATE_MIDI_PROGRAM_CHANGES_WITH_PARAMETERS +#if JucePlugin_WantsMidiInput +#define JUCE_VST3_EMULATE_MIDI_PROGRAM_CHANGES_WITH_PARAMETERS 1 +#endif +#endif + #if JUCE_LINUX || JUCE_BSD #include "juce_events/native/juce_linux_EventLoopInternal.h" #include @@ -414,9 +420,9 @@ public: //============================================================================== enum InternalParameters { - paramPreset = 0x70727374, // 'prst' - paramMidiControllerOffset = 0x6d636d00, // 'mdm*' - paramBypass = 0x62797073 // 'byps' + paramPreset = 0x70727374, // 'prst' + paramMidiControllerOffset = 0x6d636d00, // 'mcm*' + paramBypass = 0x62797073 // 'byps' }; //============================================================================== @@ -551,6 +557,13 @@ public: const Array& getParamIDs() const noexcept { return vstParamIDs; } Vst::ParamID getBypassParamID() const noexcept { return bypassParamID; } Vst::ParamID getProgramParamID() const noexcept { return programParamID; } + + bool isProgramParam(Vst::ParamID paramID) + { + return (paramID==programParamID); + //return (paramID>=programParamID && programParamID (numElementsInArray (parameterToMidiController)))); } + inline bool isMidiProgramChangeParamID (Vst::ParamID paramID) const noexcept + { + return audioProcessor->isProgramParam(paramID); + } + + /* + inline int32 getMidiProgramChangeChannel(Vst::ParamID paramID) const noexcept + { + return (1+paramID-audioProcessor->getProgramParamID()); + } + */ + //============================================================================== Steinberg::int32 PLUGIN_API getUnitCount() override { @@ -1542,7 +1567,7 @@ private: { auto vstParamID = audioProcessor->getVSTParamIDForIndex (i); - if (vstParamID == audioProcessor->getProgramParamID()) + if (audioProcessor->isProgramParam(vstParamID)) continue; auto* juceParam = audioProcessor->getParamForVSTParamID (vstParamID); @@ -2420,7 +2445,7 @@ class JuceVST3Component : public Vst::IComponent, { public: JuceVST3Component (Vst::IHostApplication* h) - : pluginInstance (createPluginFilterOfType (AudioProcessor::wrapperType_VST3)), + : pluginInstance (createPluginFilterOfType (AudioProcessor::wrapperType_VST3).release()), host (h) { inParameterChangedCallback = false; @@ -3439,6 +3464,20 @@ public: } else #endif + #if JUCE_VST3_EMULATE_MIDI_PROGRAM_CHANGES_WITH_PARAMETERS + if (juceVST3EditController != nullptr && juceVST3EditController->isMidiProgramChangeParamID (vstParamID)) + { + for (Steinberg::int32 point = 0; point < numPoints; ++point) + { + if (const auto change = getPointFromQueue (paramQueue, point)) + { + midiBuffer.addEvent (MidiMessage::programChange (1, + jlimit (0, 127, (int) (change->value * 128.0))), change->offsetSamples); + } + } + } + else + #endif if (const auto change = getPointFromQueue (paramQueue, numPoints - 1)) { if (auto* param = comPluginInstance->getParamForVSTParamID (vstParamID))