From 8a754b08cf173efda4948d5fabed390d58439c88 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sat, 12 Jun 2021 20:15:20 +0200 Subject: [PATCH] Only initialize VST2 audio buffers on activation Ardour apparently always calls `effMainsChanged()` with a value argument of 0 when unloading the plugin, regardless of whether it has actually initialized audio processing before that point. --- src/plugin/bridges/vst2.cpp | 26 ++++++++++++++++++-------- src/wine-host/bridges/vst2.cpp | 6 +++++- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/plugin/bridges/vst2.cpp b/src/plugin/bridges/vst2.cpp index d3c2b40e..fbceb1c4 100644 --- a/src/plugin/bridges/vst2.cpp +++ b/src/plugin/bridges/vst2.cpp @@ -227,8 +227,16 @@ class DispatchDataConverter : public DefaultDataConverter { break; case effMainsChanged: // At this point we'll set up our audio buffers since we (in - // theory) now know how large they need to be - return WantsAudioShmBufferConfig{}; + // theory) now know how large they need to be. A value argument + // of 1 means that audio playback should be initialized. + // NOTE: Ardour unconditionally calls this with a value of 0 + // unconditionally when unloading a plugin, even if it has + // never initialized audio playback + if (value == 1) { + return WantsAudioShmBufferConfig{}; + } else { + return nullptr; + } case effEditGetRect: return WantsVstRect(); break; @@ -367,12 +375,14 @@ class DispatchDataConverter : public DefaultDataConverter { update_aeffect(plugin, updated_plugin); } break; case effMainsChanged: { - const auto& audio_buffer_config = - std::get(response.payload); - if (!process_buffers) { - process_buffers.emplace(audio_buffer_config); - } else { - process_buffers->resize(audio_buffer_config); + if (const auto* audio_buffer_config = + std::get_if( + &response.payload)) { + if (!process_buffers) { + process_buffers.emplace(*audio_buffer_config); + } else { + process_buffers->resize(*audio_buffer_config); + } } } break; case effEditGetRect: { diff --git a/src/wine-host/bridges/vst2.cpp b/src/wine-host/bridges/vst2.cpp index 58993e37..c2e46cb4 100644 --- a/src/wine-host/bridges/vst2.cpp +++ b/src/wine-host/bridges/vst2.cpp @@ -470,7 +470,11 @@ void Vst2Bridge::run() { // the same buffers. We cannot use `Vst2Bridge::dispatch_wrapper()` // for this because we need to directly return payload data that // won't be visible to the plugin at all. - if (event.opcode == effMainsChanged) { + // NOTE: Ardour will call `effMainsChanged()` with a value of 1 + // unconditionally when unloading a plugin, even when audio + // playback has never been initialized (and `effSetBlockSize` + // has never been called) + if (event.opcode == effMainsChanged && event.value == 1) { // Returning another result this way is a bit ugly, but sadly // optimizations have never made code nicer to read return Vst2EventResult{.return_value = result.return_value,