Multibus API

This is a limitation with the “JUCE plugin host”. Currently, it only supports a subset of layouts (mono, stereo, LCR, quadrophonic, 5.0, 5.1, 6.0, 6.1, …) but no discrete layouts yet.

I want to stress that JUCE does support discrete channels in general. It’s just the host that doesn’t support it.

That doesn’t sound good. The IO count in the AEffect struct should be the maximum number of channels the plug-in can handle.

Right, I would expect that too, but some of the GRM Tools plugins don’t work that way. For the time being, I added a pretty ugly hack into the JUCE VST2 hosting code that checks for the GRM plugin names and does some of the channel count and bus initialization stuff differently if the name matches. I should probably drop the GRM developer an email about this…(AFAIK they also use JUCE for developing the plugins, so it’s a pity their plugins don’t work out of the box with the JUCE hosting code. :confused: )

By the way, at least one of the GRM plugins (the Spaces surround panner) does report 32 ins and outs initially and JUCE interprets that as 16 x 2 channel busses per signal direction, is that the intended behavior? Is it because the JUCE hosting code does not support the discrete channel layouts? (For that plugin the channel layout should probably be one bus of 32 channels per signal direction, the plugin internally handles stereo, quad, 5.1 etc formats.)

It does! It’s just that the “hosting demo code” doesn’t.

would be nice if it did - since thats something i’ll be using a lot in my host code and plugin code ( plugins like kontakt in 32 or 64 discrete output mode - or more accurately 16 or 32 stereo outputs )

Hmmm … I’ve got a few synths that are crashing the scanner as well.

Not sure if it’s related, but it seems that any synth with 0 inputs, 2 outputs is causing some craziness.
Verified in plugin host demo, but also in several other host apps that I put together.

Maybe these are just discrete layouts? Not completely sure how to check that?

Yes, we found a similar problem with some plugins calling plugInOpcodeGetSpeakerArrangement: Latest JUCE updates in develop crashes OBXD plugin

I don’t think this used to be called pre-multi-bus. It sounds like a bug with those plugins but perhaps there’s some work around?

On the topic of the new MultiBus API I still haven’t received a single reply from the JUCE team about this problem i posted about some weeks back.

Fabian is the multi-bus guru and he’s been on holiday… I know he’s been answering a few of the simpler forum posts in his time off, but probably saving the more complex ones until he’s back!

I’m still seeing a lot of crashes in plugins due to the introduction of the plugInOpcodeGetSpeakerArrangement call in queryBusIO.

All these plugins worked before the multi-bus re-write (presumably because this was never called?).

I’ve looked all over the VST spec (which is incredibly difficult now that all the JUCE implementation is named differently) and the only thing I can find that’s related is this: http://www.dith.it/listing/vst_stuff/vstsdk2.4/doc/html/class_audio_effect_x.html#bdc7ed0ea2ae1c8c3fdb419d803309ff

Which has two points of interest:

  1. getSpeakerArrangement() are always called in suspended state
    Which I don’t think applies here because the plugin isn’t even fully initialised yet
  2. The check for > getFormatVersion () >= 2300
    However, if I find this using plugInOpcodeGetVstInterfaceVersion, it returns 2400 for the below plugin so is unlikely to be much help.

A lightweight plugin that exhibits this behaviour is: Wiggle https://2ndsenseaudio.com/
If you build the plugin host and scan the VST you’ll see it crash after the call to queryBusIO.
Commenting out the call to dispatchFunction (effect, plugInOpcodeGetSpeakerArrangement enabled the plugin to scan correctly so I’m really hoping there’s some way of deciding at run time if this opcode is safe to call?

I’m not ruling out that this isn’t a bug in the plugins but they must have worked in other hosts that queried the speaker arrangement as there are so many that exhibit this behaviour.

Any chance this could get a look at?

1 Like

Thanks dave96,
I’ve been looking into this but needed a lightweight plugin to further test changes - so thanks for the reference to Wiggle.

One issue is that an old public JUCE version (I think the initial JUCE 4 release) had a hard to spot nullptr dereference. Any plug-in made with that version (this includes an old version of equator) can crash if queryBusIO is called. However, I could not find a workaround to detect if a plug-in was built with that broken version of JUCE.

I’ll look into this tomorrow.

Fabian

1 Like

Ah. That could well be it. I’ve spotted crashes there in plugins that don’t have their symbols hidden.

Strange that they wouldn’t crash in other hosts though (I’ve tried Reaper at the least)? I wonder how this manages to bypass calling that method?

Hmm this is going to be really tough to fix. I can see that Wiggle was built with the infamous JUCE 4.1 release and will therefore randomly crash in BigInteger. The offending line in JUCE 4.1 is this one: it tries to get the plug-in input layout which will crash if the plug-in is a synth - and therefore doesn’t have any input buses.

I workaround is to not call getSpeakerArrangement if the plug-in is a synth. Although not ideal, I’ve pushed this workaround to develop for now.

Hmm, that is a doozy. I can’t think of any better solutions for the time being though.

I thought this might ruin the channel counts of synths but things seem to be ok (tried with Kontact 16-out).
What is the effect of not calling plugInOpcodeGetSpeakerArrangement?

The layout information will be lost for plug-ins that do not implement getPinProperties. In these cases, if your synth has 6 output channels, JUCE will not know if this is 5.1 surround, hexaphonic or 6.0 surround.

Ah ok. That’s actually fine for my use case :slight_smile:

What is the status of this bug? Turns out Helm is also affected by this. Commenting out the offending line was a workaround, but I don’t like having to modify JUCE code just to have a working build. Did that fix get moved from develop into master?

If you are using the latest version of JUCE (both master and develop), then Helm should not be affected by this bug.

Hi everyone, I wonder if someone has encountered this issue: I’m trying to build an Audio Unit plug-in which supports mono and stereo input, and from mono to 7.1 surround output. This is how I wrote it:

#ifndef JucePlugin_PreferredChannelConfigurations
bool Shuffling::isBusesLayoutSupported(const BusesLayout& layouts) const
{
#if JucePlugin_IsMidiEffect
    ignoreUnused (layouts);
    return true;
#else 
    if(layouts.getMainInputChannelSet()==AudioChannelSet::mono())
    {
        if (!layouts.getMainInputChannelSet().isDisabled())
        {
            if (!layouts.getMainOutputChannelSet().isDisabled())
            {
                if (layouts.getMainOutputChannelSet()==AudioChannelSet::mono())
                    return true;
                else if (layouts.getMainOutputChannelSet()==AudioChannelSet::stereo())
                    return true;
                else if (layouts.getMainOutputChannelSet()==AudioChannelSet::quadraphonic())
                    return true;
                else if (layouts.getMainOutputChannelSet()==AudioChannelSet::create5point0())
                    return true;
                else if(layouts.getMainOutputChannelSet()==AudioChannelSet::create5point1())
                    return true;
                else if (layouts.getMainOutputChannelSet()==AudioChannelSet::create7point1())
                    return true;
                else
                    return false;
            }
            else
                return false;
        }
        else
            return false;
    }

    if (layouts.getMainInputChannelSet()==AudioChannelSet::stereo())
    {
        if (!layouts.getMainInputChannelSet().isDisabled())
        {
            if (!layouts.getMainOutputChannelSet().isDisabled())
            {
                if (layouts.getMainOutputChannelSet()==AudioChannelSet::stereo())
                    return true;
                else if (layouts.getMainOutputChannelSet()==AudioChannelSet::quadraphonic())
                    return true;
                else if (layouts.getMainOutputChannelSet()==AudioChannelSet::create5point0())
                    return true;
                else if(layouts.getMainOutputChannelSet()==AudioChannelSet::create5point1())
                    return true;
                else if (layouts.getMainOutputChannelSet()==AudioChannelSet::create7point1())
                    return true;
                else
                    return false;
            }
            else
                return false;
        }
        else
             return false;
    }

    return false;
#endif
}
#endif

However, the way the plug-in behaves depends on the constructor: if I start my plug-in with a stereo input like this:

Shuffling::Shuffling()
#ifndef JucePlugin_PreferredChannelConfigurations
: MyEffect(BusesProperties().withInput("Input", AudioChannelSet::stereo()).withOutput("Output", AudioChannelSet::stereo()))
#endif

the plug-in won’t support mono input with anything else than mono or stereo output, like shown in the auval analysis:

FORMAT TESTS:

Reported Channel Capabilities (explicit):
      [1, 1]  [1, 2]  [2, 2]  [2, 4]  [2, 5]  [2, 6]  [2, 8]  

Input/Output Channel Handling:
1-1   1-2   1-4   1-5   1-6   1-7   1-8   2-2   2-4   2-5   2-6   2-7   2-8   4-4   4-5   5-5   6-6   7-7   8-8
X     X                                   X     X     X     X           X                                         
In: 1 , Out: 1
In: 1 , Out: 2
In: 1 , Out: 4
WARNING: Can Initialize Unit to un-supported num channels:InputChan:1, OutputChan:4
In: 1 , Out: 5
WARNING: Can Initialize Unit to un-supported num channels:InputChan:1, OutputChan:5
In: 1 , Out: 6
WARNING: Can Initialize Unit to un-supported num channels:InputChan:1, OutputChan:6
ca_require: ValidFormat(inScope, inElement, newDesc) InvalidFormat /Users/stagiaireprod/Desktop/Octave_Roulleau/GRm_vst_wrapper/Shuffling_test_AU/GRM_Tools_SRC/Common/au/CoreAudioUtilityClasses/AUBase.cpp:870
In: 1 , Out: 8
WARNING: Can Initialize Unit to un-supported num channels:InputChan:1, OutputChan:8
In: 2 , Out: 2
In: 2 , Out: 4
In: 2 , Out: 5
In: 2 , Out: 6
ca_require: ValidFormat(inScope, inElement, newDesc) InvalidFormat /Users/stagiaireprod/Desktop/Octave_Roulleau/GRm_vst_wrapper/Shuffling_test_AU/GRM_Tools_SRC/Common/au/CoreAudioUtilityClasses/AUBase.cpp:870
In: 2 , Out: 8
ca_require: ValidFormat(inScope, inElement, newDesc) InvalidFormat /Users/stagiaireprod/Desktop/Octave_Roulleau/GRm_vst_wrapper/Shuffling_test_AU/GRM_Tools_SRC/Common/au/CoreAudioUtilityClasses/AUBase.cpp:870
ca_require: ValidFormat(inScope, inElement, newDesc) InvalidFormat /Users/stagiaireprod/Desktop/Octave_Roulleau/GRm_vst_wrapper/Shuffling_test_AU/GRM_Tools_SRC/Common/au/CoreAudioUtilityClasses/AUBase.cpp:870
ca_require: ValidFormat(inScope, inElement, newDesc) InvalidFormat /Users/stagiaireprod/Desktop/Octave_Roulleau/GRm_vst_wrapper/Shuffling_test_AU/GRM_Tools_SRC/Common/au/CoreAudioUtilityClasses/AUBase.cpp:870
ca_require: ValidFormat(inScope, inElement, newDesc) InvalidFormat /Users/stagiaireprod/Desktop/Octave_Roulleau/GRm_vst_wrapper/Shuffling_test_AU/GRM_Tools_SRC/Common/au/CoreAudioUtilityClasses/AUBase.cpp:870
ca_require: ValidFormat(inScope, inElement, newDesc) InvalidFormat /Users/stagiaireprod/Desktop/Octave_Roulleau/GRm_vst_wrapper/Shuffling_test_AU/GRM_Tools_SRC/Common/au/CoreAudioUtilityClasses/AUBase.cpp:870
ca_require: ValidFormat(inScope, inElement, newDesc) InvalidFormat /Users/stagiaireprod/Desktop/Octave_Roulleau/GRm_vst_wrapper/Shuffling_test_AU/GRM_Tools_SRC/Common/au/CoreAudioUtilityClasses/AUBase.cpp:870
In: 2 , Out: 2
ca_require: IsStreamFormatWritable(inScope, inElement) NotWritable /Users/stagiaireprod/Desktop/Octave_Roulleau/GRm_vst_wrapper/Shuffling_test_AU/GRM_Tools_SRC/Common/au/CoreAudioUtilityClasses/AUBase.cpp:875

This will also be the case if I switch from stereo to mono input in the constructor: the plug-in won’t support stereo output with anything else than stereo output, while all the mono input configurations seem to work fine.

The problem doesn’t occur when I define the JucePlugin_PreferredChannelConfigurations macro instead.

I tried that with Juce version 4.3.1, 5.0.1 and 5.0.2 but nothing changes. Does anyone kwon how to work my way around that?

Thanks for the report. I was able to reproduce this bug and will report back once it’s fixed.

This should be fixed on develop now.