Getting multiple buses working for AU and VST3

I’m developing a plugin that, by default, is just a stereo drum synth. However, I’d like the user (through the DAW) to be able to add 6 extra buses, one for each of the channel outputs to have a multiout mode.

At various points, I’ve had Logic recognise my plugin as having Stereo and (7xStereo) modes and Reaper equally happy to send stuff to multiple channels, however not at the same time. Logic sometimes displays (3xStereo, 4xMono) and now refuses to give me any options other than Stereo, 16xStereo and 25xStereo - but crashes anyway loading the ones that aren’t just regular Stereo. I’ve Reset and Rescanned, etc. etc. but no luck.

I want the stereo mode to output audio if there are no other available/enabled buses, but if another bus is available (like Logic has added one or Reaper’s pin is connected) it takes the ‘next’ track out of the main output and just uses the Bus.

I’ve got various parts of this working at various points today across Reaper, Ableton and Logic but never all at once and it seems I change one thing, it breaks, I revert and its still broken! I’ve also noticed that I had it working for AU on Reaper (or some of it was working) but then loading the VST3 version it was just mono coming out of the left ear with no other buses or channels used.

For my isBusesLayoutSupported;

if (layout.inputBuses.size() > 1) {
    return false;
  }
  
  if (layout.getMainOutputChannelSet() == AudioChannelSet::disabled()
      || layout.getMainOutputChannelSet() != AudioChannelSet::stereo()) {
    return false;
  }
  
  int numActiveOutputBuses = 0;
  for (auto bus : layout.outputBuses) {
    //each bus must be stereo if its enabled
    if (bus != AudioChannelSet::stereo() &&
	(!bus.isDisabled())) {
      return false;
    }
    if (!bus.isDisabled()) {
      numActiveOutputBuses++;
    }
  }
  // I need at least 1 buffer and dont need more than 7 (1 main and 6 tracks)
  return numActiveOutputBuses >= 1 && numActiveOutputBuses <= NUM_TRACKS+1;

My constructor;

AudioProcessor (BusesProperties()
		    .withOutput("Stereo Output", juce::AudioChannelSet::stereo(), true)
		    .withOutput("Voice 1", juce::AudioChannelSet::stereo(), false)
		    .withOutput("Voice 2", juce::AudioChannelSet::stereo(), false)
		    .withOutput("Voice 3", juce::AudioChannelSet::stereo(), false)
		    .withOutput("Voice 4", juce::AudioChannelSet::stereo(), false)
		    .withOutput("Voice 5", juce::AudioChannelSet::stereo(), false)
		    .withOutput("Voice 6", juce::AudioChannelSet::stereo(), false))

Once I’ve got Logic displaying Stereo and 7xStereo and Reaper being happy to assign all 14 channels, then I can move back to the processBlock to get the outputs going the right places at the right time.

Any help much appreciated

Feels like I’m pedalling round a roundabout at this point. I’ve tried all manor of stuff, and now Reaper and Ableton work. Monitoring the bus out doesn’t take from the Main Out, but I can live with this if it works.

Logic still nothing. Says Stereo, Multi Output (16xStereo) and Multi Output (25xStereo) and no recompile, reset, rescan, reAuval, reload or restart will get it to change. It crashes loading either of the Multi Output anyway so I don’t know why its letting me even select them. Auval says nothing of 16x outputs and looks the same as another drum synth (Capulet by Reel Audio) which supports Stereo and Multi Output (5xStereo) in Logic.

VERIFYING DEFAULT SCOPE FORMATS:
Input Scope Bus Configuration:
 Default Bus Count:0

Output Scope Bus Configuration:
 Default Bus Count:7
    Bus Name: Stereo Output
    Format Bus 0: AudioStreamBasicDescription:  2 ch,  44100 Hz, Float32, deinterleaved
    Bus Name: Voice 1
    Format Bus 1: AudioStreamBasicDescription:  2 ch,  44100 Hz, Float32, deinterleaved
    Bus Name: Voice 2
    Format Bus 2: AudioStreamBasicDescription:  2 ch,  44100 Hz, Float32, deinterleaved
    Bus Name: Voice 3
    Format Bus 3: AudioStreamBasicDescription:  2 ch,  44100 Hz, Float32, deinterleaved
    Bus Name: Voice 4
    Format Bus 4: AudioStreamBasicDescription:  2 ch,  44100 Hz, Float32, deinterleaved
    Bus Name: Voice 5
    Format Bus 5: AudioStreamBasicDescription:  2 ch,  44100 Hz, Float32, deinterleaved
    Bus Name: Voice 6
    Format Bus 6: AudioStreamBasicDescription:  2 ch,  44100 Hz, Float32, deinterleaved
    Bus 0, Has Channel Layouts: 0x650002 0x660002 0x670002 0x6A0002
    Default Layout (bus 0):
	Tag=0x650002, Num Chan Descs=0
FORMAT TESTS:

Reported Channel Capabilities (explicit):
      [0, 2]

No Input, Output Chans:
0-1   0-2   0-4   0-5   0-6   0-7   0-8
      X

# # AudioChannelLayouts (4), Output Scope:
ChannelLayout is Writable: T
The Unit publishes the following Channel Layouts:
  0x650002, 0x660002, 0x670002, 0x6A0002,

Is Audio Channel Layout Available:
Mono    Stereo  Binau.  AU_4    Ambi.   AU_5    AU_5_0  AU_6    AU_6_0  AU_7_0  AU_7_0F AU_8    AU_5_1  AU_6_1  AU_7_1  AU_7_1F
        X       X

Current Format:AudioStreamBasicDescription:  2 ch,  44100 Hz, Float32, deinterleaved
Current Format Tag = 0x650002, New Format Tag = 0x650002, Successsful

Current Format:AudioStreamBasicDescription:  2 ch,  44100 Hz, Float32, deinterleaved
Current Format Tag = 0x650002, New Format Tag = 0x6A0002, Successsful

* * PASS
AudioProcessor (BusesProperties()
		    .withOutput("Stereo Output", juce::AudioChannelSet::stereo(), true)
		    .withOutput("Voice 1", juce::AudioChannelSet::stereo(), true)
		    .withOutput("Voice 2", juce::AudioChannelSet::stereo(), true)
		    .withOutput("Voice 3", juce::AudioChannelSet::stereo(), true)
		    .withOutput("Voice 4", juce::AudioChannelSet::stereo(), true)
		    .withOutput("Voice 5", juce::AudioChannelSet::stereo(), true)
		    .withOutput("Voice 6", juce::AudioChannelSet::stereo(), true))

bool ALMDrumAudioProcessor::isBusesLayoutSupported (const BusesLayout& layout) const
{
  if (layout.getMainOutputChannelSet() != AudioChannelSet::stereo()) {
    return false;
  }
  int numActiveOutputBuses = 0;
  for (auto bus : layout.outputBuses) {
    numActiveOutputBuses++;
  }
  return numActiveOutputBuses >= 1 && numActiveOutputBuses <= NUM_TRACKS+1;
}

Maybe someone can spot something I cant

Hello, I’m scouring the forum for multibus issues and found yours. I’m similarly trying to get all sorts of combination of layouts woking acceptably in Logic, Cubase and Pro Tools. One thing I can’t see if you’ve mentioned with your Logic issue is whether you do a full reset for the rescan. I’ve found having to do this between changing supported layouts. The brute force script seems to be this (found elsewhere):

#!/bin/sh
sudo killall -9 AudioComponentRegistrar
rm ~/Library/Caches/AudioUnitCache/com.apple.audiounits.cache
rm ~/Library/Caches/com.apple.audiounits.cache
rm ~/Library/Preferences/com.apple.audio.InfoHelper.plist
rm ~/Library/Preferences/com.apple.logic.pro.cs
rm ~/Library/Preferences/com.apple.logic10.plist
rm ~/Library/Preferences/com.cockos.reaper.plist

But you coudl probably experiment to remove some of those lines. Note: this zaps your Logc prefs so you’ll need to reset some things like “Advanced” mode at least.

1 Like

Hey, thanks for the idea. Luckily I’ve managed to get it all working now. I’ll post the working solutions below.
Constructor for custom audio processor

MyAudioProcessor() : AudioProcessor(BusesProperties()
		   .withOutput("Output", juce::AudioChannelSet::stereo(), true)
#if !JUCE_IOS
		   .withOutput("Aux 1", juce::AudioChannelSet::stereo(), true)
		   .withOutput("Aux 2", juce::AudioChannelSet::stereo(), true)
		   .withOutput("Aux 3", juce::AudioChannelSet::stereo(), true)
		   .withOutput("Aux 4", juce::AudioChannelSet::stereo(), true)
		   .withOutput("Aux 5", juce::AudioChannelSet::stereo(), true)
		   .withOutput("Aux 6", juce::AudioChannelSet::stereo(), true)
#endif
{
...
}

Bus layout

bool MyAudioProcessor::isBusesLayoutSupported(const BusesLayout& layouts) const
{
  if (PluginHostType::getPluginLoadedAs() != AudioProcessor::wrapperType_Standalone) {
    if (layouts.getMainInputChannelSet() != juce::AudioChannelSet::disabled())
        return false;

    if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())
        return false;

    int additionalStereoBuses = 0;
    for (int busIdx = 1; busIdx < layouts.outputBuses.size(); ++busIdx) {
        if (layouts.outputBuses[busIdx] == juce::AudioChannelSet::stereo()) {
            additionalStereoBuses++;
        }
    }

    return additionalStereoBuses == 6;
  }
  return true;
}

DO NOT override canAddBus or canRemoveBus in your processor either - I believe this was what was breaking Logic.
Killing Logic definitely helps. And clearing the ~/Library/Caches/AudioUnitCache also helped.
Hope that helps other people in the future.

1 Like