juce_Vst_Wrapper setSpeakerArrangement suggestion

Hi,

I’d like to suggest some improvements to the vst_Wrapper setSpeakerArrangement:
Right now the only way it works in all hosts I’ve tested, you can only specify a maximum number of Ins and Outs via JucePlugin_MaxNumInputChannels / JucePlugin_MaxNumOutputChannels. (Setting up the JucePlugin_PreferredChannelConfigurations led to crashes of some host for some channel configurations if it contained a configuration other than the max Ins / max Outs.)

If you have your Plugin set up to have for example 5 Ins and 4 Outs and insert it into a channel providing 2 Ins and 2 Outs, your Configuration won’t match and therefore the getNumInputChannels / getNumOutputChannels will return 5 respectively 4 and not the channel configuration the host is providing for the specific channel.
Since most people expect that these two functions will return the channel numbers the host is actually using, I modified the setSpeakerArrangement. With these modifications you could add your 5 In 4 Out plugin into a channel that is Mono (1 In / 1 Out) and the getNumI/OputChannels would return 1 / 1, which is what I would expect it to do.

I will post the code below. It was tested with Sonar, Live, Cubase/Nuendo, Samplitude, Minihost, VstHost (note that not all of these hosts are calling the setSpeakerArrangement at all).

There are two possibilities: the first one assumes, that you want to use the JucePlugin_PreferredChannelConfigurations and enables you to specify any arbitrary configuration. Therefore the preferred configurations have to be sorted (the reason for the ChannelConfigComparator).
The second suggestion is only suitable if a max number of Ins and Outs is specified and the JucePlugin_PreferredChannelConfigurations isn’t used. In my opinion the first solution should be preferred.

In both versions, if the channel configuration of the host has more Ins or Outs than the plugins maximum the getNumInputChannels/getNumOutChannels will return the maximum your plugin can handle ( same as it has been without the suggested changes).

So here is my code, Version 1:

[code]
template
class ChannelConfigComparator
{
public:
static int compareElements (ElementType first, ElementType second)
{
if(first[0] < second[0])
return -1;
else if(first[0] > second[0])
return 1;
else if(first[1] < second[1])
return -1;
else if(first[1] > second[1])
return 1;
else return 0;
}
};

bool setSpeakerArrangement (VstSpeakerArrangement* pluginInput,
VstSpeakerArrangement* pluginOutput)
{
short channelConfigs[][2] = { JucePlugin_PreferredChannelConfigurations };
Array <short*> channelConfigsSorted;
ChannelConfigComparator<short*> comp;

for (int i = 0; i < numElementsInArray (channelConfigs); ++i)
	channelConfigsSorted.addSorted(comp, channelConfigs[i]);


for (int i = channelConfigsSorted.size()-1; i >= 0; --i)
{
    bool inCountMatches  = (channelConfigsSorted[i][0] == pluginInput->numChannels);
    bool outCountMatches = (channelConfigsSorted[i][1] == pluginOutput->numChannels);

    if (inCountMatches && outCountMatches)
    {
        speakerIn = (VstSpeakerArrangementType) pluginInput->type;
        speakerOut = (VstSpeakerArrangementType) pluginOutput->type;
        speakerInChans = pluginInput->numChannels;
        speakerOutChans = pluginOutput->numChannels;

		numInChans = speakerInChans;
		numOutChans = speakerOutChans;

        filter->setPlayConfigDetails (speakerInChans, speakerOutChans,
                                      filter->getSampleRate(),
                                      filter->getBlockSize());
        return true;
    }
}

return false;

}[/code]

And the code for the max Ins / max Outs only Vesion:

bool setSpeakerArrangement (VstSpeakerArrangement* pluginInput,
							VstSpeakerArrangement* pluginOutput)
{
	if (pluginInput->numChannels <= JucePlugin_MaxNumInputChannels && pluginOutput->numChannels <= JucePlugin_MaxNumOutputChannels)
	{
		speakerIn = (VstSpeakerArrangementType) pluginInput->type;
		speakerOut = (VstSpeakerArrangementType) pluginOutput->type;
		speakerInChans = pluginInput->numChannels;
		speakerOutChans = pluginOutput->numChannels;

		numInChans = speakerInChans;
		numOutChans = speakerOutChans;

		filter->setPlayConfigDetails (speakerInChans, speakerOutChans,
			filter->getSampleRate(),
			filter->getBlockSize());
		return true;
	}

	return false;
}

If someone encounters problems with any host I’ve not tested, please let me know.

Are the above changes still required with the latest tip? If it is, where do I place the version 1 code?

If you want the behaviour as described above for VST Plugins, you still have to change the vst_Wrapper, since nothing has changed up to the latest tip.

You simply have to copy the code as it is in the post to your vst_Warpper file and delete the existing setSpeakerArrangement function.

If you encounter any problems, please let me know.

Hi,

I have a problem in FL9 with normal Stereo Input/Output {1,1}{2,2}. The demo seems to have this issue too. It seems that your code doesnt fix that problem, i tried both snippets. Have you an idea how to fix that?

My post about the FL9 issue:
http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?p=23809#23809

FL9 shows up 2 Stereo Inputs and Outputs, not 1 as expected and inputs the input signal to the plugin twice. Have you tried your code in the Fruity Loops 9 Demo version?

FL9 seems to be the only host that has this issue…

FYI this is linked to the following topic as well and it looks like the fix should be in git soon:

http://www.rawmaterialsoftware.com/viewtopic.php?f=8&t=4873