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 278392a3b4..3acee56ec9 100644 --- a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp @@ -241,7 +241,12 @@ public: if (v != valueNormalized) { valueNormalized = v; - owner.setParameter (paramIndex, static_cast (v)); + + // Only update the AudioProcessor here if we're not playing, + // otherwise we get parallel streams of parameter value updates + // during playback + if (owner.vst3IsPlaying.get() == 0) + owner.setParameter (paramIndex, static_cast (v)); changed(); return true; @@ -636,7 +641,6 @@ private: #endif Vst::ParamID bypassParamID; - //============================================================================== void setupParameters() { @@ -2032,9 +2036,15 @@ public: return kResultFalse; if (data.processContext != nullptr) + { processContext = *data.processContext; + pluginInstance->vst3IsPlaying = processContext.state & Vst::ProcessContext::kPlaying; + } else + { zerostruct (processContext); + pluginInstance->vst3IsPlaying = 0; + } midiBuffer.clear(); diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h index 313c006da9..314fb912d0 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -1614,6 +1614,12 @@ private: template void processBypassed (AudioBuffer&, MidiBuffer&); + #if JucePlugin_Build_VST3 + friend class JuceVST3EditController; + friend class JuceVST3Component; + Atomic vst3IsPlaying { 0 }; + #endif + // This method is no longer used - you can delete it from your AudioProcessor classes. JUCE_DEPRECATED_WITH_BODY (virtual bool silenceInProducesSilenceOut() const, { return false; })