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 2aae192862..04fce34f58 100644 --- a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp @@ -2551,26 +2551,31 @@ public: //============================================================================== tresult PLUGIN_API setActive (TBool state) override { - active = (state != 0); + const auto willBeActive = (state != 0); - if (! state) + active = false; + // Some hosts may call setBusArrangements in response to calls made during prepareToPlay + // or releaseResources. Specifically, Wavelab 11.1 calls setBusArrangements in the same + // call stack when the AudioProcessor calls setLatencySamples inside prepareToPlay. + // In order for setBusArrangements to return successfully, the plugin must not be activated + // until after prepareToPlay has completely finished. + const ScopeGuard scope { [&] { active = willBeActive; } }; + + if (willBeActive) { - getPluginInstance().releaseResources(); + const auto sampleRate = processSetup.sampleRate > 0.0 + ? processSetup.sampleRate + : getPluginInstance().getSampleRate(); + + const auto bufferSize = processSetup.maxSamplesPerBlock > 0 + ? (int) processSetup.maxSamplesPerBlock + : getPluginInstance().getBlockSize(); + + preparePlugin (sampleRate, bufferSize, CallPrepareToPlay::yes); } else { - auto sampleRate = getPluginInstance().getSampleRate(); - auto bufferSize = getPluginInstance().getBlockSize(); - - sampleRate = processSetup.sampleRate > 0.0 - ? processSetup.sampleRate - : sampleRate; - - bufferSize = processSetup.maxSamplesPerBlock > 0 - ? (int) processSetup.maxSamplesPerBlock - : bufferSize; - - preparePlugin (sampleRate, bufferSize, CallPrepareToPlay::yes); + getPluginInstance().releaseResources(); } return kResultOk;