Logic is passing audio to my plugin in the wrong order

Hi,
I’m writing a plugin with some level meters and I’m having an issue where Logic is passing audio to my plugin processor in the wrong order.

E.g. I have a 5.1 plugin chain of

  1. Signal generator (Test Oscillator)
  2. Logic’s Multichannel Gain
  3. My meters

In Logic’s multichannel gain, when I mute the “centre” channel I’m finding that the audio buffer being passed into processBlock() has the muted audio in buffer index 4, but I’d expect it to come through into buffer index 2 right? Since the JUCE “order” is L R C LFE Ls Rs

I’ve tried out the example SurroundPlugin and that receives the audio correctly, as do other JUCE-based plugins, and attaching a debugger reveals that the audio buffer passed in to SurroundPlugin has the muted audio in buffer index 2, as expected.

Is there something I need to declare in preprocessor definitions?
Thanks for any help!

Similar issues were discussed here:

The problem isn’t that JUCE is doing some remapping of the channel order between the audio coming in to the plugin and what my processor sees in processBlock().

The issue is that something about the remapping in Logic and only Logic is going wrong for my plugin but not the JUCE example plugin.

Make sure you’re not using JucePlugin_PreferredChannelConfigurations (“Plugin Channel Configurations” in the Projucer). If that is set, the plugin will declare that it only supports layouts with discrete channels when built as an AU.

To debug this further, you can use AudioProcessor::getChannelLayoutOfBus to find the layout that is currently applied to each bus, and AudioChannelSet::getTypeOfChannel to find the channel type for each channel index in the bus.

Make sure you’re not using JucePlugin_PreferredChannelConfigurations (“Plugin Channel Configurations” in the Projucer). If that is set, the plugin will declare that it only supports layouts with discrete channels when built as an AU.

The project configures via cmake, but I don’t have the preferred channel configurations defined as a macro. I’m using isBusesLayoutSupported() instead.

To debug this further, you can use AudioProcessor::getChannelLayoutOfBus to find the layout that is currently applied to each bus, and AudioChannelSet::getTypeOfChannel to find the channel type for each channel index in the bus.

I’ve had no luck putting any code into SurroundPlugin and adding breakpoints (Xcode doesn’t seem to want to break in the correct location, even when I use DBG macros), but in my plugin the channel set was the expected 5.1 set: “L R C LFE Ls Rs”
But the muted “Logic C” audio is still coming through on index 4, which using the index/type converters says “Ls”.

If the SurroundPlugin has the correct channel ordering, then I think this is unlikely to be a bug in JUCE, but I can’t think where else the channel orderings might be getting confused. Can you adapt the AudioPlugin CMake example to produce the same behaviour? If so, then please provide these changes and we can take a look.

Oh sorry, I wasn’t trying to say it’s a bug in JUCE!

I’m having some trouble getting the Audio Plugin Example to open in Logic in 5.1
I’ve changed isBusesLayoutSupported() to

bool AudioPluginAudioProcessor::isBusesLayoutSupported(const BusesLayout& layouts)
{
    if (layouts.getMainInputChannels() != layouts.getMainOutputChannels())
        return false;

    return true;
}

and auval confirms that this has worked, but Logic doesn’t seem to want to open in anything above stereo…
I should note that it opens in multi-mono on a surround track, but that isn’t useful for me right now

You might need to go to the Plugin Manager and click on “Full Audio Unit Reset”, then quit and re-open Logic. That’s how we fix a similar issue we’ve seen in Logic not respecting a change we made in the supported layout.

:man_facepalming: That’s done it, thanks!

@reuk I have results!
With the cmake Audio Plugin Example, I can see that the muted “Logic C” audio is coming through in buffer channel index 4!
Compared to the Projucer SurroundPlugin, where it comes through in buffer channel index 2.

I saw this by putting breakpoints at:
Audio Plugin Example - PluginProcessor.cpp Line 136, checking the value of the pointer data
SurroundPlugin - SurroundPluginDemo.h Line 188, checking the value of newMax

The JUCE AU wrapper checks to see whether the AudioProcessor cares about “real” channel layouts by seeing whether it will accept a nonsense discrete channel layout with discrete channels starting at 128 rather than at 0. If you want your plugin to get remapped channels, you must return false from isBusesLayoutSupported for such layouts.

e.g. if you want to ensure that the plugin only uses matching layouts on the input and output, but gets the correct channel orderings, you could use the following implementation of isBusesLayoutSupported:

    const auto isSetValid = [] (const juce::AudioChannelSet& set)
    {
        return ! set.isDisabled()
               && ! (set.isDiscreteLayout() && set.getChannelIndexForType (juce::AudioChannelSet::discreteChannel0) == -1);
    };

    return isSetValid (layouts.getMainOutputChannelSet())
           && layouts.getMainInputChannelSet() == layouts.getMainOutputChannelSet();
1 Like

That’s fixed it!

Thanks for all your help!

@reuk Sorry to come back to this, but Reaper AU at 10 channels only gives me discrete channels, even with this change.
I’m getting the same behaviour in the SurroundPlugin this time.