Possible issue with AudioProcessor::setChannelLayoutOfBus?

Hi All,

I ran into an assertion in a VST3 host I’ve written when loading a JUCE plugin (as a VST3 plugin.) It’s entirely possible that the issue is on my end, i.e how I’m configuring my buses for plugin rendering.

Here is my rendering shutdown function

void StopRendering(IComponent* vst3Effect)
{
	tresult result = vst3Effect->setActive(false);
	ASSERT(result == kResultOk);

	result = vst3Effect->activateBus(kAudio, kInput, 0, false);
	ASSERT(result == kResultOk);
	result = vst3Effect->activateBus(kAudio, kOutput, 0, false);
	ASSERT(result == kResultOk);
}

When I call activateBus with false as the last parameter, the JUCE VST3 wrapper will eventually call AudioProcessor::Bus::enable (false), which then calls AudioProcessor::Bus::setCurrentLayout (AudioChannelSet::disabled()).

Ultimately that AudioChannelSet::disabled() instance gets to AudioProcessor::setChannelLayoutOfBus, where it is compared using the == operator with the an existing channel set. However that == operator will never return true unless the existing channel set was already disabled (I think.)

Because I’m deactivating an existing channel set the function returns false, which triggered an assert on my end.

Is there something I’m doing wrong on my end? I don’t see how the AudioProcessor::setChannelLayoutOfBus could work when disabling a channel layout unless the function is rewritten to look like this:

bool AudioProcessor::setChannelLayoutOfBus (bool isInputBus, int busIndex, const AudioChannelSet& layout)
{
    if (auto* bus = getBus (isInputBus, busIndex))
    {
        auto layouts = bus->getBusesLayoutForLayoutChangeOfBus (layout);

        if (layouts.getChannelSet (isInputBus, busIndex) == layout || layout.isDisabled())
            return applyBusLayouts (layouts);

        return false;
    }

    jassertfalse;  // busIndex parameter is invalid
    return false;
}

With the additional isDisabled check appended to the end of the conditional.

Thoughts?

I’m bumping this - can any ROLI devs comment as to why the original function is written in this way and what the proper solution is? Looking at the implementation of applyBusLayout, it seems like the channel counts must not be equal in order for the function to apply… but here they’re being checked for equality? See our version here

https://github.com/Celemony/JUCE_ARA/commit/fbcd1577625d199e985d5d146815327f5391d89b

I suspect that it isn’t compared to the existing channel set, but that getBusesLayoutForLayoutChangeOfBus returns the buses layout with the change (which is what I read from “ForLayoutChangeOfBus”)