VST3, Cubase and Multiple main configuration

Hi,

Modifying the MultiOutSynth example in order to support multiple main configuration and stereo aux
do not seems to work in Cubase 12.

    bool isBusesLayoutSupported (const BusesLayout& layout) const override
    {
      std::vector<AudioChannelSet> validMains = {AudioChannelSet::mono(), AudioChannelSet::stereo(), AudioChannelSet::create5point1()};
      for (size_t i = 0 ; i < validMains.size(); i++)
      {
        if (layout.getMainInputChannelSet() == AudioChannelSet::disabled() &&
            layout.getMainOutputChannelSet() == validMains[i])
        {
          if (layout.outputBuses.size() >= 1)
          {
            bool validAux = true;
            for (int j = 1; j < layout.outputBuses.size(); j++)
            {
              validAux &= layout.getChannelSet(false, j) == AudioChannelSet::stereo();
            }
            return validAux;
          }
        }
      }
      return false;
    }

This is the right code to do right ?

Thanks !

I’ve just tested this out a bit, and I think there are a few issues:

  • Cubase 12 doesn’t seem to have any UI to pick the layout of each of the instrument’s output buses. (I tried clicking around a bit, and searched on Google too. Maybe this is just a well-hidden feature. Please let me know if I missed it.) Instead, Cubase seems to just use the default layout of each bus. That is, when I set the main bus of the MultiOutSynth demo to 5.1, but all other output buses to stereo, Cubase loads the plugin in this configuration, but there doesn’t seem to be any way of switching the main bus to stereo after loading the plugin. Loading the plugin on a stereo channel doesn’t seem to have any effect; the main bus is still set to 5.1.
  • After loading the plugin, it’s possible to enable and disable each output bus individually, but doing so causes the host to pass malformed audio buffers to the plugin. Specifically:
    • I loaded the MultiOutSynth plugin with a 5.1 main output, and stereo aux outputs. The main bus was automatically enabled, the aux buses were not.
    • I enabled “Output #2 [Stereo]”. The host deactivated the plugin, called activateBus to let the plugin know that this bus is now enabled, then reactivated the plugin.
    • On the next call to process, the first output bus was only given 2 channels, instead of 6. The host did not call setBusArrangements to notify the plugin that the first bus should be stereo. The plugin was then unable to process properly, because the host failed to supply the correct channel layout.
    • When I toggled the second bus on and off a few times, Cubase sometimes wrote junk data to the output channels. As a sanity check, I tried sticking this at the top of the process call to silence all of the output channels provided by the host. Even with this code in place, the output meters sometimes lit up when enabling/disabling an aux output bus. This audio must come from Cubase, because the plugin always cleared all of the output channels. Remember to turn your speakers off if you test this yourself!
      std::for_each (data.outputs, data.outputs + data.numOutputs, [&] (const auto& bus)
      {
          const auto clearBus = [&] (auto channelBuffer)
          {
              std::for_each (channelBuffer, channelBuffer + bus.numChannels, [&] (auto* ptr)
              {
                  if (ptr != nullptr)
                      std::fill (ptr, ptr + data.numSamples, 0.0);
              });
          };
      
          if (data.symbolicSampleSize == Steinberg::Vst::kSample32)
              clearBus (bus.channelBuffers32);
          else
              clearBus (bus.channelBuffers64);
      });
      
      return kResultTrue;
      

I think your code is almost there, but in VST3 plugins the bus count is fixed, so the if (layout.outputBuses.size() >= 1) will always be true. If you want to allow the additional buses to be enabled or disabled, you should allow AudioChannelSet::disabled() too:

return std::all_of (std::next (layout.outputBuses.begin()), layout.outputBuses.end(), [] (auto& set)
{
    return set == AudioChannelSet::stereo() || set == AudioChannelSet::disabled();
});

With that change, the AudioPluginHost allows the first bus to be set to mono, stereo, or 5.1, and forces it to be enabled. The other buses can be enabled or disabled, and can only be set to stereo.

Following the latest commit. I still don’t know how to enable a surround version of my VST plugin in Cubase.

As I posted above, setting the default layout of the main bus to a surround sound layout causes Cubase to use that layout.

The behaviour does seem to be a bit broken - I can’t find any way of switching between main bus layouts, so it doesn’t seem to be possible to support both stereo and surround buses with the same version of the plugin. It’s not clear whether this is a bug on the host or client side - if you’re aware of instrument plugins that do allow reconfiguring the main bus layout, that would indicate that the issue is on our side. However, given that the layout can be reconfigured in other hosts (e.g. the AudioPluginHost) I think it’s more likely that this feature isn’t implemented in Cubase.