# \[Solved\] VST3 and preset changes driving me nuts

**URL:** <https://forum.juce.com/t/solved-vst3-and-preset-changes-driving-me-nuts/63951>\
**Category:** General JUCE discussion\
**Created:** [October 26, 2024, 11:06am UTC](https://forum.juce.com/t/solved-vst3-and-preset-changes-driving-me-nuts/63951 "2024-10-26T11:06:03Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![dsp56300](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dsp56300/32/19813_2.png) [@dsp56300](https://forum.juce.com/u/dsp56300)\
**Post date:** [October 26, 2024, 11:06am UTC](https://forum.juce.com/t/solved-vst3-and-preset-changes-driving-me-nuts/63951/1 "2024-10-26T11:06:04Z")

</div>

Hi,

I am trying to solve a strange bug with regards to preset changes when we’re running as VST3 plugin and I’m pulling my hair out already…

As VST2, CLAP, AU everything works fine but not as VST3.

When a preset is changed, this can either be done by selecting a new preset via our built-in patch manager or just by sending a midi sysex to the plugin, we do the following:

Update parameters to the new values, parameters are derived from `juce::RangedAudioParameter`, we prevent to do that via `setValueNotifyingHost()` because when 2000+ parameters are modified some hosts don’t like that at all and go crazy (Ableton, Logic). Therefore we just use `setValue()`

After all parameters have been updated we call  
`updateHostDisplay (AudioProcessorListener::ChangeDetails().withProgramChanged (true));`

If I’m not wrong this should be the correct way to do it and in VST2/CLAP/AU the DAW is nicely picking up the new values and everything is nice, but not when running as VST3.

The VST3 wrapper checks if the program parameter has changed, but as we don’t have something like that (and will never have due to multimode) I patched our Juce fork to call `restartComponent` as soon as `updateHostDisplay` is called with `withProgramChanged`.

However, it still doesn’t work. I verified that `restartComponent()` is called with the flag `kParamValuesChanged` but neither Cubase, nor Tracktion/Waveform 13 nor Bitwig are picking up the new parameter values. The function `getValue()` of our parameters is never called after calling `updateHostDisplay()`

My current guess is that `setParamNormalized` should be called by Juce without doing a `performEdit()` after `updateHostDisplay()` gets called by the plugin because, according to the VST3 doc, the edit controller should have the new values before the host calls it to query the new values. But I am not super certain here.

Who can shed some light into this?

Thanks!

---

<div class="post-metadata">

**Author:** ![dsp56300](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dsp56300/32/19813_2.png) [@dsp56300](https://forum.juce.com/u/dsp56300)\
**Post date:** [October 26, 2024, 11:18am UTC](https://forum.juce.com/t/solved-vst3-and-preset-changes-driving-me-nuts/63951/2 "2024-10-26T11:18:29Z")

</div>

Okay I dug deeper and I think that is the problem indeed:

Cubase is nicely picking up the `restartComponent()` call, but Juce returns incorrect parameter values because the `JuceVST3EditController` didn’t overwrite the method `getParamNormalized`.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/3X/a/6/a6db4f39504bf5016f68a10127c3f92b4f7c3dea.png)

---

<div class="post-metadata">

**Author:** ![dsp56300](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dsp56300/32/19813_2.png) [@dsp56300](https://forum.juce.com/u/dsp56300)\
**Post date:** [October 26, 2024, 11:37am UTC](https://forum.juce.com/t/solved-vst3-and-preset-changes-driving-me-nuts/63951/3 "2024-10-26T11:37:28Z")

</div>

I fixed it. The problem is a conceptual difference in Juce between VST3 and other plugin formats:  
Whenever a host is querying a parameter value, this ends up in a call to `AudioProcessorParameter::getValue()` and my guess is that this is what is supposed to happen.

However, the implementation for VST3 is different, it does not work like that because the value is cached in `JuceVST3EditController::Param`.

The fix requires a change in two locations:

A very small function in `JuceVST3EditController::Param`:

```auto
void updateParameterValue()
{
    // retrieve the current value from Juce::AudioProcessorParameter and update
    // the value stored in Vst::Parameter to ensure its up-to-date
    setNormalized(param.getValue());
}

```

And now the most important part, update the cached value so that the host sees the most recent value and not a possibly outdated one:

```auto
Vst::ParamValue getParamNormalized(Vst::ParamID id) override
{
	// cached parameter value might be outdated, update it before returning
	if (auto* parameter = getParameterObject (id))
	{
		if(auto* juceParam = dynamic_cast<Param*>(parameter))
			juceParam->updateParameterValue();
		return parameter->getNormalized();
	}
	return EditController::getParamNormalized(id);
}

```

---

<div class="post-metadata">

**Author:** ![jpo](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jpo/32/503_2.png) [@jpo](https://forum.juce.com/u/jpo)\
**Post date:** [December 8, 2025, 4:48pm UTC](https://forum.juce.com/t/solved-vst3-and-preset-changes-driving-me-nuts/63951/4 "2025-12-08T16:48:49Z")

</div>

Hi, I just noticed this thread. I did start a thread based on similar frustration with VST3 preset changes (with the difference that I was not able to figure a fix..):

> [@VST3 parameter updates: automation vs. host refresh](https://forum.juce.com/t/vst3-parameter-updates-automation-vs-host-refresh/67373):
>
> tldr: In JUCE-based VST3s with an internal preset browser, preset changes don’t update parameter values in the host unless you notify it manually — but doing so may trigger unwanted automation recording. There are basically two ways the host can be notified that some parameters have changed: automation recordable : the parameter is explicitly modified by the user, for example by dragging a slider. not recorded by automation: the parameter is modified indirectly, for example the user switches …

Just tried your suggested patch and it seems to work perfectly ! Have you run into any issues with it ?
