A better way for complex BusesProperties

Hey all,

edit:
I’ve edited this post to show the working solution as well as the first attempt.

you may be doing something like this to construct audio processors:

TestAudioProcessor::TestAudioProcessor()
     : AudioProcessor (BusesProperties()
                       .withInput  ("Input",  AudioChannelSet::stereo(), true)
                       .withOutput ("Output", AudioChannelSet::stereo(), true)
                       )

this is great for a couple inputs & ouputs, but if you have crazy complex processors, you may want to do something like this to keep things more standardized:

class TestAudioProcessorBusesProperties : public BusesProperties
{
public:
    TestAudioProcessorBusesProperties() {
        withInput  ("Input",  AudioChannelSet::stereo(), true);
        withOutput ("Output", AudioChannelSet::stereo(), true);
    }
    ~TestAudioProcessorBusesProperties() { }
}

Well, that doesn’t appear to work, but, you can define a simple function right inside of the class such as this:

AudioProcessor::BusesProperties TestNodeBusesProperties()
{
    return BusesProperties()

    .withInput("InputLeft",  AudioChannelSet::mono(), true)
    .withInput("InputRight",  AudioChannelSet::mono(), true)

    .withInput("OtherInput1",  AudioChannelSet::mono(), true)
    .withInput("OtherInput2",  AudioChannelSet::mono(), true)

    .withOutput("OutputLeft", AudioChannelSet::mono(), true)
    .withOutput("OutputRight", AudioChannelSet::mono(), true);
}

and then the constructor could be something like:

TestAudioProcessor::TestAudioProcessor()
     : AudioProcessor (TestNodeBusesProperties())
{
}

now the constructor is all neat :blush: and you can easily jump into the buses properties to check them out

Thanks @dave96!

1 Like

Don’t you just want something like a helper function?

static AudioProcessor::BusesProperties createTestBusesProperties()
{
    return BusesProperties()
        .withInput  ("Input",  AudioChannelSet::stereo(), true)
        .withOutput ("Output", AudioChannelSet::stereo(), true);
}

then

TestAudioProcessor::TestAudioProcessor()
     : AudioProcessor (createTestBusesProperties())
{
}

?
(This is untested btw)

1 Like

Dave with the blazing quick reply, you know i just went and tested the post right after writing it xP and it works fine, but yeah actually maybe a set of static functions such as this in a helper file would be a better way to go. Thanks man! love it!

for some reason i thought the busesproperties being a struct would stop it from subclassing, which i was wrong about. But, i think the static function is better anyways.

edit: you can’t actually make it a static function external to the processor because the AudioProcessor::BusesProperties class is a protected member of AudioProcessor. I’m updating the post

After hitting a pain point with this again…

I do feel that the busesproperties shouldn’t be protected members so they could be defined externally without having to do strange stuff like subclass from the AudioProcessor class

Take it a step further, bus configurations in configuration files (along with parameters), something like TOML/JSON/YAML, parse it for code generation in a CMakeLists.txt file.

Wouldn’t this be great?

# plugin-config.toml 
[plugin.bus_properties]
inputs  = ["mono", "stereo", "surround"]
outputs = ["mono", "stereo", "surround"]
default = ["stereo", "stereo"]
1 Like

Yeah, that’s how I do it as well, it’s very nice and then I have an app which spits out my c++ classes, but I’d like to keep the processors themselves separated from the Buses, meaning they need to be separate files & classes, right now I have to subclass from the AudioProcessor, just so it can generate the bus config : (