AudioProcessorValueTreeState, or AudioProcessorParameterGroup?

Hey everyone,

So I’m trying to make somewhat of a complex system within my app, for creating and managing both in-app/native plugins, as well as user-imported plugins. The app itself is an interface for connecting up any range and order of plugins to the audio stream.

I’m a little bit confused about the state of AudioProcessorValueTreeState (APVTS), and AudioProcessorParameterGroup (APPG). I see pro’s and con’s on both, and was planning on using them in conjunction, but it seems a little messy and I want to clear up some things first.

Please let me know your thoughts on some of these points:

  • First off, sounds like maybe the APVTS might be deprecated. What’s up with the header to this documentation file? [A parameter class that maintains backwards compatibility with deprecated AudioProcessorValueTreeState]

  • The ValueTree data structure, as magical as it is (I am using it to manage everythingggg) doesn’t have a clear integration structure to a separate ValueTree that manages plugins/AudioProcessors, due to how it is meant to be initialised and how its parent should really be the AudioProcessor. I can see how I can get around these inconveniences, but the APPG seems easier to manage when thrown around the place, say, on another tree.

  • The AudioProcessorParameter only handles floats… I’d like to manage all types of parameters. But seems the APVTS can still do other types (but I can’t find how to integrate a ComboBox).

  • On the other hand, APPG doesn’t seem to have a native system for Parameter Listeners (unlike AudioProcessorValueTreeState::Listener), doesn’t have native “Attachment” components (addressing the same issue), and maybe most importantly, does not have a built-in undomanager functionality. Those three seem very convenient and useful and I’d ideally like to integrate their functionality.

I guess I’m trying to iron out my own mental mapping of functionality… Right now I’m thinking of using ParameterGroups to handle everything before and for AudioProcessor creation, and handling everything with the ValueTreeState from there on.

Thoughts?

[Bonus note: can anyone point me to finding out wth “Programs” are for within an AudioProcessor?? Cheers. ]

I’m already realising that the functionality of APVTS is not deprecated, and there’s plenty in RangedAudioParameter that covers for parameter types, like using ints for the Choice Parameter. But please explain as hard as you can if you’re replying - I need that knowledge ~(* o *)~

[Edit no. 2]
I’ve ran myself into the ground trying to have AudioProcessorParameterGroup then become APVTS - first I used different checks (isBoolean(), isDiscrete(), getAllValueStrings()), but then realised that I had to go through a mess of a process to deal with Parameter IDs, which AudioProcessorParameter does not hold.

So I’m dropping it and going purely with AudioProcessorValueTree. I don’t know if that ends this discussion, lol.

The question is, are you currently hosting an AudioProcessor or are you writing an AudioProcessor?

In the AudioProcessor, the classes are as what you created them: you can always use

auto* group = dynamic_cast<AudioParameterGroup*>(state.getParameter ("groupID"));
jassert (group); // will always fail or never fail, verifies the parameter setup

To a host though, all parameters are seen as AudioPluginInstance::Parameter, which is a plain AudioProcessorParameter. In a host the AudioProcessorValueTreeState has no counterpart, so it is useless in that context.

That’s great to know. I also found that AudioProcessorGraph::IOProcessor uses AudioPluginInstance, so it looks like I’ll actually side with AudioProcessorParameterGroup.

To answer your question, my app performs both tasks. I have custom AudioProcessors mixed with hosted AudioProcessors, but it seems like the ParameterGroup is a good way to mix the two. Thankfully there’s no need to edit individual processor parameters, but to have a structure that can flexibly be attached to parents and children is ideal. If a hosted plugin can’t have its parameters included by a top-most “container” plugin, then it’s not quite fit for the job, as with the ValueTreeState.