From 36653e8b300ec933d0800553035bbbe65bb7591a Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 20 Apr 2021 13:10:41 +0100 Subject: [PATCH] VST Host: Correctly retrieve results of effGetSpeakerArrangement The plugin should interpret the arguments as VstSpeakerArrangement** instances. It should modify the pointed-to VstSpeakerArrangement* so that it points to a long-lived VstSpeakerArrangement in the plugin. --- .../format_types/juce_VSTPluginFormat.cpp | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index fa0e346b3e..8e9e1949d9 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -2186,20 +2186,14 @@ private: (pointer_sized_int) &canonicalIn.get(), (void*) &canonicalOut.get(), 0.0f); } - HeapBlock inArrBlock (1, true), outArrBlock (1, true); - - auto* inArr = inArrBlock.get(); - auto* outArr = outArrBlock.get(); - - if (! getSpeakerArrangementWrapper (effect, inArr, outArr)) - inArr = outArr = nullptr; + const auto arrangement = getSpeakerArrangementWrapper (effect); for (int dir = 0; dir < 2; ++dir) { const bool isInput = (dir == 0); const int opcode = (isInput ? Vst2::effGetInputProperties : Vst2::effGetOutputProperties); const int maxChannels = (isInput ? effect->numInputs : effect->numOutputs); - const Vst2::VstSpeakerArrangement* arr = (isInput ? inArr : outArr); + const auto* arr = (isInput ? arrangement.in : arrangement.out); bool busAdded = false; Vst2::VstPinProperties pinProps; @@ -2250,12 +2244,7 @@ private: static bool pluginHasDefaultChannelLayouts (Vst2::AEffect* effect) { - HeapBlock inArrBlock (1, true), outArrBlock (1, true); - - auto* inArr = inArrBlock.get(); - auto* outArr = outArrBlock.get(); - - if (getSpeakerArrangementWrapper (effect, inArr, outArr)) + if (getSpeakerArrangementWrapper (effect).isValid()) return true; for (int dir = 0; dir < 2; ++dir) @@ -2283,19 +2272,35 @@ private: return false; } - static bool getSpeakerArrangementWrapper (Vst2::AEffect* effect, - Vst2::VstSpeakerArrangement* inArr, - Vst2::VstSpeakerArrangement* outArr) + struct SpeakerArrangements + { + const Vst2::VstSpeakerArrangement* in; + const Vst2::VstSpeakerArrangement* out; + + bool isValid() const noexcept { return in != nullptr && out != nullptr; } + }; + + static SpeakerArrangements getSpeakerArrangementWrapper (Vst2::AEffect* effect) { // Workaround: unfortunately old JUCE VST-2 plug-ins had a bug and would crash if // you try to get the speaker arrangement when there are no input channels present. // Hopefully, one day (when there are no more old JUCE plug-ins around), we can // comment out the next two lines. if (effect->numInputs == 0) - return false; + return { nullptr, nullptr }; - return (effect->dispatcher (effect, Vst2::effGetSpeakerArrangement, 0, - reinterpret_cast (&inArr), &outArr, 0.0f) != 0); + SpeakerArrangements result; + const auto dispatchResult = effect->dispatcher (effect, + Vst2::effGetSpeakerArrangement, + 0, + reinterpret_cast (&result.in), + &result.out, + 0.0f); + + if (dispatchResult != 0) + return result; + + return { nullptr, nullptr }; } //==============================================================================