Multibus and Speaker Arrangement

Hi
Developing a plugin host, and have converted all code to the new multi bus system.
One issue that is popping up is many plugins (vst) uses the getSpeakerArrangement to figure out if they should work as surround/mono/stereo. So they seem to ignore the Juce bus layout.
So my question is, how is the “old” set/getSpeakerArrangement handled in the new system?
How can I tell a plugin that I want it to load as 5.1?
Should adding a input/output bus, and then adding the channels using AudioChannelSet::create5point1 () be enough ?

I’m not sure what you mean. The getSpeakerArrangement callback is a callback in the vst-2 plug-in called by the host to figure out which bus layout it currently has. JUCE will use this as the default layout of the AudioProcessor (i.e. myVstProcessor->getChannelLayoutOfBus (isInputBus, 0) just after creating the plug-in).

If you want to change the layout of the plug-in simply change the bus layout:

myVstProcessor->setChannelLayoutOfBus (true, 0, AudioChannelSet::create5point1());

I’m struggling with exactly the same thing. Did anybody manage to host surround plug-in reliably with the new multibus system? Calls to setChannelLayoutOfBus don’t seem to have any effect at all and a subsequent call to setChannelLayoutOfBus on the same bus returns another channel layout than specified. How is this supposed be used?

Can you let me know which plug-in you are trying to host? Then I’ll post some sample code.

Thanks, Fabian! I’ve been trying with our own Verberate Surround plug-in as well as some surround capable plug-ins from NUGEN audio.

Here’s my current code:

	m_juceProcessor->setPlayConfigDetails (inputFormat.getNumOfChannels(), outputFormat.getNumOfChannels(),
										   inputFormat.getSampleRate(), m_estimatedBlockSize);

	m_juceProcessor->setChannelLayoutOfBus (true, 0, AudioChannelSet::canonicalChannelSet (inputFormat.getNumOfChannels()));
	m_juceProcessor->setChannelLayoutOfBus (false, 0, AudioChannelSet::canonicalChannelSet (outputFormat.getNumOfChannels()));

The calls to setChannelLayoutOfBus fail and getChannelLayoutOfBus returns the old layout, hence the code below from the VST plug-in processor detects the wrong layout:

    SpeakerMappings::channelSetToVstArrangement (getChannelLayoutOfBus (true,  0), inArr);
    SpeakerMappings::channelSetToVstArrangement (getChannelLayoutOfBus (false, 0), outArr);

Best,
Stian

What’s the value of inputFormat/outputFormat?

It depends on the format of the edited file, but I’ve been testing with a 5.1 surround file in which case both values would be 6.

Can you try the code below:

const int numInChannels  = inputFormat .getNumOfChannels();
const int numOutChannels = outputFormat.getNumOfChannels();

m_juceProcessor->setRateAndBufferSizeDetails (inputFormat.getSampleRate(), m_estimatedBlockSize);

AudioChannelSet inLayout  = m_juceProcessor->getBus (true,  0)->supportedLayoutWithChannels (numInChannels);
AudioChannelSet outLayout = m_juceProcessor->getBus (false, 0)->supportedLayoutWithChannels (numOutChannels);

// What does this print?
DBG (inLayout.getDescription());
DBG (outLayout.getDescription());

m_juceProcessor->setChannelLayoutOfBus (true,  0, inLayout);
m_juceProcessor->setChannelLayoutOfBus (false, 0, outLayout);

Edit: had a typo in the above code. Please try again!

Thanks for your help! Here’s the debug output:

Disabled
Disabled

Another question, do you have any surround capable plug-ins that you usually test with? If yes, which ones?

OK it seems that JUCE thinks that your plug-in does not support any layout with 6 channels.

Yes, we regularly test surround capable plug-ins. First and foremost, we test Apple’s standard AUs (such as AUFilePlayer (playing surround files), AUMultiChannelMixer, AUSpatialMixer and the different panners.

Then I regularly test the waves surround plugins:

http://www.waves.com/plugins/surround

Which I test with all available plug-in formats.

Then I also test JUCE’s Surround plug-in example.

Thanks for the info, Fabian. Why is that? I’ve tested with major plug-ins from NUGEN, Exponential Audio and our own and no VST2 plug-in has worked so far. All three companies use JUCE as far as I know. I’ll download and test Waves’ surround plug-ins.

I just tried the NUGEN Halo Downmix plug-ins and they seem to work perfectly.

Thanks – I got Waves C360 5.1 to work. Older JUCE plug-ins written prior to the new multibus API don’t seem to work, however. I debugged the code and the problem seems to be in the detection of the bus counts. The hosting works when I comment out the check as below:

bool isBusesLayoutSupported (const BusesLayout& layouts) const override
{
    const int numInputBuses  = getBusCount (true);
    const int numOutputBuses = getBusCount (false);

    // it's not possible to change layout if there are sidechains/aux buses
    //if (numInputBuses > 1 || numOutputBuses > 1)
    //    return (layouts == getBusesLayout());

    return (layouts.getNumChannels (true,  0) <= vstEffect->numInputChannels
         && layouts.getNumChannels (false, 0) <= vstEffect->numOutputChannels);
}

Sorry for being late to the party, and thanks to both of you for looking in to this.
Stians post above is the same as I have experienced. many surround plugins (or any multi channel setup) work fine. but then again many plugins don’t and the once I have come across are old juce plugins.

Any news on this, Fabian? It seems as if 8 channel VST2.4 plug-ins are treated as 4 stereo busses per default.

@stian Have do seen any drawbacks with your fix? (commenting out the lines above)?
Tempted to do the same but I’m a bit afraid it will trigger a storm of support request for other plugins :fearful:

I’m not really sure – it would be great with some feedback from @fabian or @jules

Hi @stian,

Sorry for the delay in answering this but it seems that every surround plug-in I try or that you have mentioned seems to work just fine for me - I’m probably just using the wrong ones.

  • I’ve tested NUGEN plug-ins Downmix, Upmix and others and they seem to work just fine.
  • All the waves plug-ins seem to work as well

I’ve created the simplest 8 channel VST2.4 plug-in that I can think of (see pasted code below) and this one also works.

Can you point me to a specific plug-in that does not work?

Thanks,

Fabian

#include <pluginterfaces/vst2.x/aeffect.h>
#include <pluginterfaces/vst2.x/aeffectx.h>
#include <public.sdk/source/vst2.x/audioeffect.h>
#include <public.sdk/source/vst2.x/audioeffectx.h>

#include <public.sdk/source/vst2.x/audioeffect.cpp>
#include <public.sdk/source/vst2.x/audioeffectx.cpp>
#include <public.sdk/source/vst2.x/vstplugmain.cpp>

#include <cstdint>
#include <sstream>

class EightChannelVST : public AudioEffectX
{
public:
    EightChannelVST (audioMasterCallback audioMaster)
        : AudioEffectX (audioMaster, 1, 1)
    {
        setNumInputs (8);
        setNumOutputs (8);
        setUniqueID ('8ch');
        canProcessReplacing ();
    }

    bool getProgramNameIndexed (VstInt32, VstInt32 index, char* text) override
    {
        if (index == 0)
        {
            strcpy (text, "Default");
            return true;
        }

        return false;
    }

    bool getVendorString  (char* text) override   { strcpy (text, "ROLI Ltd.");    return true; }
    bool getProductString (char* text) override   { strcpy (text, "Eight Channel Plug-In"); return true; }
    bool getEffectName    (char* text) override   { strcpy (text, "Eight Channel Plug-In"); return true; }

    void processReplacing (float**, float** outputs, VstInt32 sampleFrames) override
    {
        for (int i = 0; i < 8; ++i)
            if (float* output = outputs[i])
                memset (output, 0, static_cast<size_t> (sampleFrames) * sizeof (float));
    }

    static AEffect* VST2TestPluginEntry (audioMasterCallback audioMaster)
    {
        // Get VST Version of the Host
        if (!audioMaster (0, audioMasterVersion, 0, 0, 0, 0))
            return 0;  // old version

        // Create the AudioEffect
        AudioEffect* effect = new EightChannelVST (audioMaster);
        if (!effect)
            return 0;
        
        // Return the VST AEffect structur
        return effect->getAeffect ();
    }
private:
    VstSpeakerArrangement* inArrangement, *outArrangement;
};

AudioEffect* createEffectInstance (audioMasterCallback audioMaster)
{
    return new EightChannelVST (audioMaster);
}

Thanks, Fabian! Here are some that didn’t work here before commenting out the section in isBusesLayoutSupported:

  • NUGEN ISL2
  • Exponential Audio R2 Surround (I ran the demo version)
  • Acon Digital Verberate Surround (which is our own – I can send an NFR license if you send me a PM).

I suppose that the plug-ins causing problems were written prior to the new multibus system in JUCE.

Best,
Stian