I think there’s a little bug in the JUCE VST3 wrapper that causes erratic behaviour when handling presets.
In line 461 of juce_VST3_Wrapper.cpp, we convert the (integer) program number to a floating point representation [0, 1]:
Then in line 1891, we do the inverse, taking the float [0,1] and mapping it back to an integer program number:
const int numPrograms = pluginInstance->getNumPrograms();
const int programValue = roundToInt (value * numPrograms);
This mapping seems to cause the wrong integer program number as we divide by (numPrograms-1) but multiply by (numPrograms) instead of (numPrograms-1). Shouldn’t this be symmetric?
I have seen cases where Cubase reads the program number and writes it back again a little later (and has the intermediate float representation) whenever an ‘updateHostDisplay()’ is called, randomly changing presets due to the above.