MIDI automation and AudioProcessorValueTreeState

I’m developing my first plugin with the AudioProcessorValueTreeState. It works well, but i’m not sure how to implement MIDI Learn support for the plugin itself.

I have two questions:

  1. Is there an easy way to find out the last moved plugin slider or clicked button without adding listeners for every parameter? Is there some kind of listener for all parameter changes or should i hook into the old setParameter(id, value) method?

  2. Whats the most easy and safest way to set a parameter from the processing loop. Is there something like a setParameterAsync that dispatches the change to the Message thread without blocking the audio thread? Or do i need to do that myself and what’s the best way to do this? I had a queue that creates messages in our older plugins, but i don’t like this solution…

Any help is welcome!

It doesn’t really make sense to talk about “last moved” controls, as multiple parameters can (and will!) change at the same time. Sure, you could make your GUI components keep track of the last one that’s interacted with, but even there the user could be using a multi-touch input device and move more than one at once.

The AudioProcessorValueTreeState takes care of the async parameter stuff, you shouldn’t need to do anything like that yourself. You can just call AudioProcessorParameter::setValue, but I can’t really think why you’d want to do that, as it’s the host’s job to call it, and the underlying wrapper code takes care of handling it.

We often have a MIDI LEARN Button on our plugins. When this button is enabled, the user can move a plugin slider followed by a hardware knob. After that the slider is attached to the hardware controller. It’s some kind of direct MIDI control without any host interaction. You record direct MIDI data for the plugin automation.

Maybe i can just leave that feature, because hosts can do this… but it looks that people still like this kind of mapping. You can assign every slider and button to your hardware and it’s possible to save this within a preset. So it’s easy to recall them when you open a new instance of the plugin without doing anything.

TBH I’d leave that up to the host.

Otherwise, you wouldn’t be able to actually give any of your parameters meaningful names, as you’d be allowing the user to remap any parameter to something else!

Just made a google search. Seems that this is still a common feature at least on synth plugins. I really hate to do that… especially the MIDI processing, but i have to do this too. Otherwise i will get a lot of user requests for this feature.

It was unexpected easy to implement that :slight_smile: I take the latest clicked slider. Think it’s a better choice. It seems that setValue() does exactly what i need.

Just to be sure… calling treeState->getParameter(midiMap[controllerNumnber])->setValue(midiValue); in the audio thread is fast and safe?

It’s a virtual method so that depends entirely on what the parameter object does in there! But yes, it’s thread-safe in AudioProcessorValueTreeState if that’s what you’re using. (With the caveat that it will call your parameter’s optional lambda when the parameter changes, so you mustn’t do anything time-consuming in there)

Great to hear that. Thanks for the response. I really start to like the new way to handle parameters.