i experienced this issue with ableton in an uncommon situation (a VST3 wrapper for an AUv3 plugin) and i had to do something like this in the VST3 to get it working (ymmv, this was essentially proxying changes from host ↔ vst3 ↔ auv3):
// in processor
juce::ThreadLocalValue<bool> inAudioProcessorParameterChangedCallback;
void parameterChanged(const juce::String ¶meterID, float newValue) {
// we only want to listen for changes that come from the host so we can pass
// them on. however - it's possible to end up here in the
// audioProcessorParameterChanged callback when we call
// setValueNotifyingHost(). the inAudioProcessorParameterChangedCallback flag
// is an attempt to avoid this loop (change from slider in our editor ->
// audioProcessorParameterChanged -> setValueNotifyingHost -> parameterChanged
// -> setValue on on processor -> audioProcessorParameterChanged) see also the
// similar "inParameterChangedCallback" code in the au wrappers
if (inAudioProcessorParameterChangedCallback.get()) {
inAudioProcessorParameterChangedCallback = false;
return;
}
// otherwise this handles changes from host -> processor
}
void audioProcessorParameterChanged(
juce::AudioProcessor *, int parameterIndex, float newValue) {
if (getParameters()[parameterIndex] != nullptr) {
inAudioProcessorParameterChangedCallback = true;
getParameters()[parameterIndex]->setValueNotifyingHost(newValue);
}
}
there is code that does something like this already but it may not be doing the right thing?