Notifying Host about AudioProcessorParameter Changes

I am currently developing an Audio-Plugin where automations are started within the AudioPluginProcessor. These automations update parameter values (AudioProcessorParameter) in each call of processBlock(). For example, audio files are played and the current position of the played audio file is given as a parameter to the host. These paramters are used for reading out via RPC and wont be automated via a DAW.

Now I have the problem that some DAW’s don’t recognize if automated parameters get changed by the plugin and wont display the right paramter value.

The JUCE AudioPluginHost updates the parameters correctly, as well as Ableton. Buf if I test it in Reaper or Elk Sushi, the parameters are not updated when the GUI is closed. When the GUI is opened the parameters are updated in all DAWs.

Here is a snippet of the code:

                std::make_unique<juce::AudioParameterFloat>(
                        "trackPos", // parameter ID
                        "Tack Position", // parameter name
                        juce::NormalisableRange<float>(0.0f, 1.0f), // parameter range
                        0.0f, // parameter init value
                        "HH:MM:SS", // parameter unit
                        juce::AudioProcessorParameter::genericParameter,
                        [this] (float value, int) {
                            juce::ignoreUnused(this);
                            return juce::String(convertToHHMMSS(value));
                        }
                )

So far I have update the parameters this way:

juce::Value new_param_trackPos = parameters.getParameterAsValue ("trackPos");
new_param_trackPos  = new_value;

And I also tried to update the paramters this way:

parameters.getParameter("trackPos")->beginChangeGesture();
parameters.getParameter("trackPos")->setValueNotifyingHost(new_value);
parameters.getParameter("trackPos")->endChangeGesture();

Is there any other way to notify the host DAW that some paramters got changed?

Firstly, please make sure you’re using a recent version of JUCE (ideally from the develop branch). There have been quite a lot of improvements to do with parameter handling and automation since the release of JUCE 6.

I modified the AudioPluginDemo to do something similar to your second code snippet inside processBlock. Here’s what I see on develop in REAPER:

trimmed

Here, I have an AU, a VST2, and a VST3 plugin all loaded with their editors closed. I’ve added automation lanes for all of the automatically-changing parameters. From the moving dials, it’s clear that the host is aware of the parameter changes, regardless of the plugin format. However, only the AU version seems to allow recording automation data when the editor is closed. If I open all of the editors, then the automation envelopes in all lanes start moving.

If you just need to notify the host that a parameter has changed, it’s probably enough to call beginChangeGesture(), setValueNotifyingHost(), endChangeGesture() inside your process block. If you also need this automation data to be recorded, that might be more difficult. At least in REAPER, it looks like VST2/VST3 plugins require the editor to be open in order to record automation data.

Of course, this being REAPER there’s probably an option somewhere to change this behaviour. To any REAPER experts, please let me know if I’ve overlooked some setting that enables recording of VST2/VST3 parameters when the editor is closed!

1 Like

Hi @reuk, thanks for your response!

I changed to the develop branch and can understand your rebuild your example. Works fine!

But the problem stays the same: I still don’t get the parameter values changed by the automations in the host DAW (ELK Sushi, Reaper) with a closed editor. Is there any other way to force the DAW to update the paramters than beginChangeGesture(), setValueNotifyingHost(), endChangeGesture() ? I dont need to record the automation data, but would like to send every second the correct parameter values from the host via RPC.

setValueNotifyingHost is the correct function to notify the host about a changed parameter value. There are no suitable alternatives as far as I’m aware.

Do you know for a fact that the desired behaviour is possible in REAPER? Are you aware of any VST(3) plugins that are able to update REAPER’s automation envelope when their UIs are closed? Unless other plugins are successfully doing this, I’d assume that this is an issue in REAPER rather than in JUCE.

There’s another similar issue report here: Reaper does not write param automation if GUI is closed
Perhaps it’s worth asking on the REAPER forum whether the behaviour you’re seeing is intentional (and maybe linking back to these threads too).

Alright, thanks! In fact, I also don’t know any plugin that supports that.

Would it be possible to share the source code of your modified AudioPluginDemo Plugin to make sure I update my parameters the right way?

Here’s what I tried:

audioplugindemo.patch (1.1 KB)

1 Like

I still don’t get the parameter values changed by the automations in the host DAW (ELK Sushi, Reaper)

For testing, did a program (compiled to VST 2 and VST3 ), that reacts on and outputs the state of a single value in multiple interfaces:
Midi in and out
DAW Parameter (“automation”) in and out (e.g. in Reaper visible in the track Header, if enabled)
A slider in the Main GUI
A Slider in the (Reaper custom extension based) additional GUI in the Track Header or Mixer

Works like charm.
Do you want to see the code ?
-Michael

Hi @reuk, sorry to barge in.
When it comes to VST3 plugins in particular, I found out several years ago that notifying parameter changes from the plugin to the host must happen on the main thread. Unless something has changed in JUCE recently, I believe that calling beginChangeGesture, setValueNotifyingHost and endChangeGesture from the audio thread isn’t the best approach. I remember seeing the same issue in Logic Pro X with AUs as well (if memory still serves me well).
After a quick look into the current develop branch, I see things are still being called synchronously.

I rewrote quite a lot of the VST3 parameter handling implementation recently. Now, parameter changes that are made on the audio thread will be communicated to the host using ProcessData::outputParameterChanges at the end of each audio block. Changes made on the main thread will use the normal IComponentHandler beginEdit, performEdit, endEdit functions to notify the host about the parameter change.

1 Like

Wow, this is really great news. I can now get rid of my workarounds… thanks!

hi @mschnell,

sure, would be very helpful if you could also share the code with me. Thanks!

here you are. → www.bschnell.de/JUCE-reaper-embedded-fx-gui_new.zip
-Michael

notifying parameter changes from the plugin to the host must happen on the main thread.

With VST3 you can do “sample accurate parameter modulation”. AFAIK this is not yet implemented in Juce, but this might influence on which thread the handling of parameter changes need to be done.
There is an “audioProcessorParameterChanged” event, and hence Juce decides in whoch thread same is fired.
In my code I have this comment:

Warning:

AFAIK, it is not garanteed, that the host calls this function in the GUI context.
hence when calling non thread safe functions we should use e.g. AsyncUpdater and AbstractFIFO
to notify the other Thread and transfer data, or simply save the data somewher and use puire GUI
means to make sure that they are acknowledged by the GUI thread.
According to JUCE, setValue(e.g. for a slider) is thread save, so no problem here.
But calling Reaper API functions definitively is not thread save.

But maybe the comment by reuk might obsolate this warning.

-Michael

Yup, this is what I usually do myself.

Exactly what I was thinking.

Cheers!

He says:

Then means we can rely on being on the main thread and can e.g. call the Reaper API.
But OTOH this seems to mean that sample accurate parameter modulation is not implemented, only blockwise. OTOH using another thread would not help in any way for that. I don’t know the VST3 specs on that, but I suppose sample accurate parameter changes would need to come with a kind of time step each - similar to Midi events - be that on the main thread or the GUI thread. But for taking decently advantage of s.a. parameter modulation, I suppose it needs to be completely handled in the audio engine, i.e. the audio thread.
In fact regarding the audio engine, even blockwise parameter modulation could be delayed a lot (multiple blocks) if handled on the main thread.
-Michael

Even worse if you consider an offline bounce (non real time). The message thread is much slower relative to the audio callbacks than in real time.

So maybe the message by reuk is not really a good idea ?!?!?!?
Supposedly we still need to be able to acknowlage the parameter change in the audio thread…
-Michael

@reuk:
Do we have both options:

  • deal with the parameter changes in the Audio-engine thread for low latency and
  • deal with the parameter changes in the GUI thread for easily interfacing with other functio9nality ?

-Michael

Yes, you can make changes from either thread, and the wrapper code should do the right thing.

OK, but I wanted to know about changes the DAW initiates. I suppose in the VST2 interface they are on the GUI thread. But on the VST3 interface - that supports sample accurate parameter modulation - they need to be (potentially) done on the audio thread, as otherwise the “current” block would be missed.
Here it might be a good idea if the user could decide on which thread he wants the notification.
(As said, in my project, I transferred the notification on the GUI thread toi be able to use the Reaper API.)
-Michael