GetSpeakerArrangement (VST2) Bug

I believe that we’ve come across a bug in getSpeakerArrangementWrapper() for VST plugins. According to the VST docs from back then (audioeffectx.cpp):

/*!
\fn bool AudioEffectX::getSpeakerArrangement (VstSpeakerArrangement** pluginInput, VstSpeakerArrangement** pluginOutput)

\param pluginInput A pointer to the input's #VstSpeakerArrangement structure.
\param pluginOutput A pointer to the output's #VstSpeakerArrangement structure.
\return \e true on success
\note setSpeakerArrangement() and getSpeakerArrangement() are always called in suspended state. 
(like setSampleRate() or setBlockSize()).\n
<pre>Here an example code to show how the host uses getSpeakerArrangement()
VstSpeakerArrangement *plugInputVstArr = 0;
VstSpeakerArrangement *plugOutputVstArr = 0;
if (getFormatVersion () >= 2300 && #getSpeakerArrangement (&plugInputVstArr, &plugOutputVstArr))
	....
</pre>	
\sa setSpeakerArrangement()
*/

Which is to say that the output parameter gets a pointer to the (static) speaker arrangement of the plugin, not a copy of the speaker arrangement, which is what the existing code is anticipating (by allocating a memory block and passing it in). The existing code will not retrieve the speaker arrangements.

I’d be happy to provide a PR if there’s no conceptual disagreement with this conclusion.

Thanks, Jeremy

Yep. Have just hit this same issue.

Is the speaker arrangement definitely a static? In my case getSpeakerArrangement populated nothing but returned non-zero. The fact that inArrBlock and outArrBlock allocate a single element meant arr is non-null in the following check (resulting in mono out):

            if (arr != nullptr)
                layout = SpeakerMappings::vstArrangementTypeToChannelSet (*arr);
            else
                layout = AudioChannelSet::canonicalChannelSet (maxChannels);

The api docs do seem to suggest the pointer will be set to the effect instances VstSpeakerArrangement so maybe it is indeed in static mem? I should debug a little further …

I think getSpeakerArrangementWrapper in juce_VSTPluginFormat should probably be taking a pointer -> pointer. Otherwise we’re populating a temporary which is why I’m not seeing any speaker arrangements returned.

    static bool getSpeakerArrangementWrapper (Vst2::AEffect* effect,
                                          Vst2::VstSpeakerArrangement** inArr,
                                          Vst2::VstSpeakerArrangement** outArr)