audioProcessorChanged callback does not respect the current number of presets in custom user preset backend

Hi everybody,

we have a plugin that uses a custom preset backend that supports user presets. When a new preset is added and updateHostDisplay() is called, the VST3 program parameter will not reflect the current number of presets available as it uses a cached preset list that was generated during construction.

In juce_VST3_Wrapper.cpp, the following code is given:

        if (details.programChanged)
        {
            const auto programParameterId = audioProcessor->getProgramParamID();

            if (audioProcessor->getParamForVSTParamID (programParameterId) != nullptr)
            {
                const auto currentProgram = pluginInstance->getCurrentProgram();
                const auto paramValue = roundToInt (EditController::normalizedParamToPlain (programParameterId,
                                                                                            EditController::getParamNormalized (programParameterId)));

                if (currentProgram != paramValue)
                {
                    beginGesture (programParameterId);
                    paramChanged (audioProcessor->findCacheIndexForParamID (programParameterId),
                                  programParameterId,
                                  EditController::plainParamToNormalized (programParameterId, currentProgram));
                    endGesture (programParameterId);

                    flags |= Vst::kParamValuesChanged;
                }
            }
        }

Here the line with “const auto paramValue” will always result in a wrong integer value, when the number of presets in the backend have been changed since start of the plugin.

Do you how this could be fixed?

Many thanks in advance :slight_smile:

The VST3 docs say the following:

  • If the plug-in defines a program list to be used as pool of factory presets, it must not allow the user to change these presets by the means of parameter editing. Instead, it should load the corresponding data into a kind of working memory and store possible modifications as component state. In addition, the user can be allowed to store the modifications as preset file.
  • If the plug-in defines a program list to be used as a pool of user presets that are initially in an ‘empty’ state, modifications can be applied to the list items directly. This way of using program lists should only be chosen if programs do require a lot of resources that need to be cached in order to achieve fast program changes (good examples for this are sample-based plug-ins).

https://developer.steinberg.help/pages/viewpage.action?pageId=9798267

So, I think your options are either to avoid setting user presets via the program parameter altogether, or to pick a maximum number of user presets and to initialise unused presets to some default state.

1 Like