Listening to const AudioProcessorParameter changes

Hello everyone,

I recently went into the problem of attaching a listener to a const AudioProcessorParameter. I think, this should be possible as the Listener methods don’t expose and mutable reference of the parameter. Is that something that could be considered in general for this library? There are other spots where that might be also applicable.

Not sure what you want to achieve… you can use the juce::AudioProcessorValueTreeState::Listener to listen to parameter changes.

What is the use case for a const AudioProcessorParameter?

That kind of blows away the modularisation, so that’s not an option in my situation.

I don’t want to hand mutable references of AudioProcessorParameters to the audio processing code. A lot of the callbacks hooked as listeners into the parameters by JUCE (e.g. the component attachments) are not realtime safe and I decided it is easier to just don’t change audio parameters from the audio thread, than redesign half the framework to only do non-blocking/non-waiting stuff in the parameter listener implementations.
To get a compile time guard against changing audio parameters on the audio thread, I simply only ever pass const references to realtime threads.

1 Like

You could just not even pass parameter references to the audio code at all – either poll for changes at the start of every processing callback, or store an atomic for each parameter that gets updated from a setter function

I don’t see the benefit of doing that. Copying all audio parameters at the start of every processing block has the potential to massively increase the constant costs of my audio unit as every atomic is guaranteed to be read in every block vs. only reading them when I actually need it (e.g. at the start of a new note in a sampler).
Storing an atomic also doesn’t make much sense to me, as the audio parameter with it’s atomic core already serves exactly that purpose.
And both don’t really fit my use-case, that my audio codes wants to be able to attach code when the value changes. This observer pattern would need to be programmed on top of new parallel data structure even though the audio parameter is already capable of doing that.

As you said, you should not work with the JUCE parameter classes directly. This is how i do things like that:

I create a wrapper class that holds a copy of all parameter values (all defined as atomic). For a modular you may even use a hashmap that maps the ID to the parameter. Or a plain array with an additional enumeration that maps the values to the ParameterID string. Or just simple atomic values that you update.

Then you can use juce::AudioProcessorValueTreeState::Listener in that class to catch parameter changes and update the atomic values. You can now pass that class into your audio processor and get the values from there with some getter methods or direct access.