Audio buffers have null channel data pointers

I am trying to create a VST3 plugin. It has 2 inputs and 6 outputs. My processor constructor looks like this:
PhoenixPluginAudioProcessor::PhoenixPluginAudioProcessor()
#ifndef JucePlugin_PreferredChannelConfigurations
: AudioProcessor (BusesProperties()
.withInput (“Input”, AudioChannelSet::stereo(), true)
.withOutput (“Output”, AudioChannelSet::create6point0(), true)
)
#endif
{
}

My isBusesLayout Supported looks like this:
bool PhoenixPluginAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
{
// This is the place where you check if the layout is supported.
// stereo in and 6.0 out is supported
if (layouts.getMainInputChannelSet() == AudioChannelSet::disabled()
|| layouts.getMainOutputChannelSet() == AudioChannelSet::disabled())
return false;
if (layouts.getMainOutputChannelSet() == AudioChannelSet::create6point0()
&& layouts.getMainInputChannelSet() == AudioChannelSet::stereo())
return true;
else
return false;
}
When I break in processBlock and inspect the input AudioBuffer all of the channel data pointers are 0.

Do I need to allocate memory for these buffers or are they allocated in the Juce framework for audio plugins?

The buffers are allocated by Juce (or by the host) if things are working as they should. If you are getting null pointers for the channel data buffers, the host probably wasn’t able to determine how the I/O for your plugin should work or doesn’t support the configuration you are trying to use.

The I/O configurations can be quite tricky to get right with the Juce’s modern buses stuff, if you attempt anything beyond trivial stereo in/stereo out kind of stuff. You could test with the legacy plugin I/O configuration method where you provide Juce with a string like {2,6} to get 2 inputs and 6 outputs. (It’s the JucePlugin_PreferredChannelConfigurations define that the plugin’s constructor is checking. You can add that into your AppConfig.h file or set it in the Projucer’s Plugin Channel Configurations field.)

IMHO the Juce developers massively overcomplicated all this and I greatly prefer just using the legacy channel configuration method…(It’s using the new channel configuration code anyway, but the old method is easier to use in one’s own code.)

1 Like

I am not sure what the legacy I/O configuration looks like. Is there a function that is overloaded that will allow {2,6} as a parameter?

Probably easiest to add the line in the Projucer and re-export the IDE project. Adding that should disable all the modern bus handling stuff from your code. The legacy I/O config is not a method, it’s just a preprocessor text string that the Juce code parses.

It looks like this in your project’s AppConfig.h file :

#ifndef  JucePlugin_PreferredChannelConfigurations
 #define JucePlugin_PreferredChannelConfigurations  {8,8},{2,2},{2,4}
#endif

I changed the Plugin Channel Configuration in Projucer and added {2,6}. I then exported. I was worried that the changes in my source code would change but they remained intact. But when I tried to recompile I discovered that a bunch of compiler properties had changed. Is there away in Projucer to keep that from happening?
I will let you know if this works once I can compile again.

The Projucer will overwrite your Xcode/Cmake/VS projects at will and without mercy. If you need specific compiler/linker flags you can add them to the Projucer project by clicking on the exporter and typing them in the relevant fields.

You might be right, if you only consider one bus in, one bus out. But side chains and other trickery require a little more flexibility.

If you want to allow all channelSets that have 6 channels, it is better to just check the size() of the bus instead comparing to a specific format. E.g. AudioChannelSet::canonicalChannelSet (6) is also 6 channels, and might be what your host wants to use when it fails to find a workable configuration:

bool PhoenixPluginAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
{
    // stereo in and 6.0 out is supported
    if (layouts.getMainInputChannelSet().size() == 2
        && layouts.getMainOutputChannelSet().size() == 6)
        return true;

    return false;
}

The implementation of isBusesLayoutSupported() is surrounded by #ifndef JucePlugin_PreferredChannelConfigurations, so if you put anything in the “Preferred Channel Configurations”, that code is excluded, but seems you are aware of that.

Hope that helps a bit

Thanks for help I was able to get my plugin working in Reaper.
I was wondering, there is the call back isBusesLayoutSupported is there a similar way to negotiate with the DAW for blocksize and sample rate?

No, that one is dictated by the host. Sometimes directly from the audio hardware, but sometimes the host also subdivides buffers, e.g. to send finer automation data (automated parameters are usually updated only once per processBlock call). The host might even resample internally, if it regards that user setting higher than the current audio device.

So always expect any size of buffers at any time, even zero size buffers are technically allowed and might occur.

But you can rely on that the sampleRate can only change with a prepareToPlay call.