VST3 ProgramParameter always zero upon re-instating plugin state as of JUCE 6.0.7

Hi all,

Running into an issue since the JUCE 6.0.7 update for a VST3 plugin with multiple programs. Whenever a plugin state is updated by the host via setStateInformation(), followed by a updateHostDisplay() call, the VST3 Program Parameter value is always zero instead of the value returned by getCurrentProgram().

There were many VST3 program parameter updates in the last v6.0.7 update; has anyone seen this?

This happens with the following simple workflow:

  • Load a VST3 plugin with multiple programs in Reaper 6 (only tested Windows so far)
  • Change the program index in the plugin UI
  • Save the Reaper project
  • Load the Reaper project → plugin program index is now erroneously set to 0

This used to work perfectly fine (even from JUCE 5 onwards) but something seems to be broken in the last update?

And I can confirm if I roll back the juce_VST3_Wrapper.cpp to the previous version prior to JUCE 6.0.7, the program index is set correctly again.

One solution that seems to work, indicating that there is some order issue happening, is to change the ProgramChangeParameter::setNormalized() function into:

bool setNormalized (Vst::ParamValue v) override
{
    auto programValue = roundToInt (toPlain (v));

    if (isPositiveAndBelow (programValue, owner.getNumPrograms()))
    {
        if (valueNormalized != v)
        {
            valueNormalized = v;
            changed();

				if (programValue != owner.getCurrentProgram())
					owner.setCurrentProgram(programValue);

            return true;
        }
    }

    return false;
}

Note that the owner.setCurrentProgram() is now happening after the valueNormalized =v; changed() calls instead of before. I’m not 100% sure this is in line with the intention of the code but at least it solves the program index issue for us.

How are you saving and recalling the current program value in get/setStateInformation()?

Hi @ed95 thanks for the quick response. We have an internal variable in the AudioProcessor (derived) class that determines our internal program index. The host can read and set it with the getCurrentProgram/setCurrentProgram functions.

When the host requests the plugin state via getStateInformation(), we include the value of this variable in the binary blob. Similarly, when we receive a state blob via setStateInformation(), we read the program index value from the blob and set our internal parameter accordingly. We then call a updateHostDisplay() to let the host know about all changes in parameters, in the expectation that the host will call getCurrentProgram() to figure out what the current program index is.

Even without the updateHostDisplay() call this worked fine in the past (as I’m assuming a host ‘knows’ a plugin state has changed after its sets the plugin state via setStateInformation()).

This used to work fine for years but perhaps we need to explicitly set the VST3 ProgramParameter value now? If so how do we do this from within the AudioProcessor class? I guess I’m not 100% sure how a plugin needs to interact with the VST3 ProgramParameter that lives in the VST3 wrapper…?

No that shouldn’t be necessary, the recent changes to the program parameter were internal to the VST3 wrapper and shouldn’t require any changes in your plug-in code. I was able to reproduce the behaviour in Reaper and we’ve pushed a fix to the develop branch here:

Does this fix the issue for you?

Awesome @ed95! That was very fast :slight_smile: And yes it fixed the issue for me. Thanks much for the quick turnaround :+1: