Plugin with fixed number of output channels, but non-fixed nb of buses


My plugin is stereo by default, but can output up to 5 output channels. I used to maintain my own patches to the au/aax wrappers so that it could be instanciated in Logic as either:

  • a mono plugin
  • a stereo plugin
  • a multi-mono plugin (5 mono tracks)
  • a stereo + 3 mono aux track

Now I’m trying to achieve a similar result with the new BusesLayout stuff of the develop branch. But I can’t figure how to do it, or if it is just not possible at all. The difficulity being that with my plugin, it is not the number of buses that is enforced, but the max number of channels. For example, if I create the AudioProcessor with
.withOutput(“Output”, AudioChannelSet::stereo(), true)
.withOutput(“Aux1”, AudioChannelSet::mono(), false)
.withOutput(“Aux2”, AudioChannelSet::mono(), false)
.withOutput(“Aux3”, AudioChannelSet::mono(), false)
.withOutput(“Aux4”, AudioChannelSet::mono(), false)

Then Logic is suggesting to instanciate the plugin as either ‘mono’, ‘stereo’, ‘5x mono’ , ‘stereo + 4x mono’, ‘5x stereo’ , so the last two suggestions are not very satisfactory, and I would prefer to have them replaced with ‘stereo + 3x mono’ and maybe ‘3x stereo’. Is this possible ?

Are you restricting the layouts of the individual buses by overriding the AudioProcessor::isBusesLayoutSupported and returning false for the layouts that you don’t support? Can you copy&paste a copy of your AudioProcessor::isBusesLayoutSupported implementation? Also, any change to that callback and you will need to re-scan the plug-in in the plug-in manager in Logic.

Hi Fabian, yes I think I have tried all combinations of options between

  • the initial BusProperties layout
  • allowing the canAddBus and canRemoveBus
  • return false for layouts that I do not want in isBusesLayoutSupported or not

So my attempts look like:

// the default layout set in the constructor
BusesProperties defaultBusesProperties() {
  AudioProcessor::BusesProperties b;
  b.addBus(false, "Output", AudioChannelSet::stereo());
  return b;

bool isBusesLayoutSupported(const BusesLayout& layouts) const {
  const AudioChannelSet& mainOutput = layouts.getMainOutputChannelSet();
  if (mainOutput.isDisabled()) return false;

  int nch = 0;
  for (int ibus=0; ibus < layouts.outputBuses.size(); ++ibus) {
    int nchb = layouts.getNumChannels(false, ibus);
    if (nchb > 2) return false;
    if (nchb == 0) return false;
    nch += nchb;
  if (nch > 6) return false;
  return true;

bool canAddBus(bool is_input) const {
  if (is_input) return false;

  return true; 

bool canRemoveBus(bool is_input) const {
  int nbus = getBusCount(is_input);
  return (is_input ? nbus > 0 : nbus > 1);

When I do this, after rescanning in Logic Pro X, it always suggest to instanciate the plugin as ‘mono’, ‘stereo’, ‘multi-output (16x mono)’, ‘multi output (1 stereo, 15 mono)’, ‘multi output (8 stereo, 8 mono)’, ‘multi output (16 stereo)’. Moreover, if I attempt to instanciate the plugin in one of these ‘multi-output configurations’, Logic says ‘Failed to load Audio Unit, please contact the manufacturer for an updated version or further assistance.

However , I found out that adding these line at the end of the getAUChannelInfo of juce_AU_Shared.h seems to enforce the number of channels in Logic:

AUChannelInfo info; info.inChannels=0; info.outChannels=-5;

Wtih that added, logic now shows ‘mono’, ‘stereo’, ‘multi output (5x mono)’ ‘multi output (1x stereo, 3x mono)’ and ‘multi output (3x stereo)’

This is a bit of a difficult one as AU will only ever add one bus at a time. This means that there must be valid layouts for every step when transitioning from one bus to five buses. This is a limitation of AU not of JUCE.

However, it’s really strange that your change to AUChannelInfo works. I’ve always assumed the AUChannelInfo to only relate to the main bus?!? I’ll need to investigate this a bit further.