How are VST3 (built-in) presets handled in JUCE?

I was (finally) trying to make a VST3 version of a an effect plugin (now that Steinberg decided to immediately stop supporting VST2 in Cubase on Apple Silicon-based Macs).
So I added the VST3 target in the Projucer, re-saved the project, built, and got my .vst3 alright (the magic of JUCE, still grateful for that!).

But when I load the VST3 plugin in Cubase (11 and 12, for now testing on Windows), I’m not seeing any of the preset programs I do see for the VST2 version. The same happens in Live 11: no presets.
Reaper and FLStudio however do show the preset programs correctly, and I can switch between them.

All the program-related methods are implemented (getNumPrograms returns 127, getProgramName returns the name of the program, etc…).
All 4 state-related methods are also implemented (get/setStateInformation and get/setCurrentProgramStateInformation).
This has worked fine for years for VST2 and AU (not for AAX, where there is only ever 1 program).

So: how does one setup/handle built-in presets correctly for VST3 in JUCE these days?
(I found a few old posts suggesting the use of discrete preset files on disk, but then why does it seem to work with Reaper and FLStudio, as expected?)
Thanks for any insights!

JUCE implements the IUnitInfo interface and the program-parameter mechanism, which is why this works in FL and REAPER. I guess that Cubase and Live choose not to make this parameter directly available to users, although I was able to switch programs in Cubase 12 by opening the “quick controls” view for the plugin and adjusting the program parameter from there.

As far as I can tell, in order to get presets to show up in the browser view in Cubase, they need to be stored as .vstpreset files in specific locations (detailed here). I don’t think there’s currently a way of generating these files automatically in JUCE, but perhaps you could iterate through all the presets and use ExtensionsVisitor::VST3Client::getPreset to dump the data into files that you can then include in your installer.

Thanks for the info @reuk.
I can confirm that I can indeed change the program via the Quick Controls (or the Remote Control Editor) in Cubase 12.

So I then tried to just go through a few of them that way and save each program one by one. This gives me the discrete .vstpreset files in the location you mentioned.

However: when I do that, it is getStateInformation that gets called in my plugin, and not getCurrentProgramStateInformation (which is what I would expect to happen). So these files actually contain the state for all the programs, not (just) the one I’m saving.

If I then change some parameters in my GUI and select one of these previously saved presets (which do show in the preset list now), I don’t get back the correct parameters, and it is setStateInformation that gets called (not setCurrentProgramStateInformation).

I read the VST3 info related to this: Presets & Program Lists - VST 3 Developer Portal
and it sounds as if this should be possible via that IProgramListData interface, but I’m not sure if this is done in JUCE and it’s also all not 100% clear I must say…

I’m doubting about using the “simple plugin” approach perhaps ( Presets & Program Lists - VST 3 Developer Portal ) where I then only have 1 program + discrete vstpreset files, but then that will no longer make things work in Reaper and FLStudio I suppose…

I just did a few more tests (in Cubase 12) that give strange results:

I first did this:

  • remove the VST3 version, put the VST2 version in place (I can see in the GUI if it is VST2 or VST3, so I’m sure the right version gets used)
  • create a project with 2 audio tracks, each with my VST2 plugin as insert effect
  • on track 1, don’t change the program, but change the parameters to something easily recognizable
  • on track 2, change the program to say program index 8, and then adjust the parameters to something easily recognizable
  • save the project

→ If I restart Cubase and reload the project, all is fine as has been the case for years now: the parameters for the effect on each tracks are the way they were when the project was saved.

Then I did this:

  • remove the VST2 version, put the VST3 version in place
  • start Cubase and reload the project

→ Since the JUCE_VST3_CAN_REPLACE_VST2 flag is set, the original VST2 version correctly gets replaced by the VST3 version, so that works fine.

→ But the settings are only correctly restored for the 1st track. For the second track, I see the default settings (settings for 1st program), not the ones the project got saved with.

Digging a bit deeper, I then set a breakpoint in my plugin’s setCurrentProgram method,. And I can see that this breakpoint never gets hit for the VST3 version when the project is loaded, which seems a bit weird to me…

For the VST2 version, the breakpoint does get hit:
First a call to setStateInformation happens (which restores the plugin’s full state from the saved project, so all parameters of all programs), and then setCurrentProgram happens with the correct index (0 for the plugin on the 1st track, 8 for the plugin on the 2nd track) which is all normal.

So, for some reason the setCurrentProgram call never happens for the VST3 version (the breakpoint does get hit when you change the program via the Quick Controls).

You would expect this to be called at some point when a project loads, right?
Maybe I am missing a new JUCE VST3 flag that could be related this?

By using the Quick Controls on the plugin on the 2nd track, I can actually change the program to index 8 myself, and then I can see that the changed settings (as they were saved) are there indeed. It’s just the setCurrentProgram that is not being called apparently for the VST3.

Edit 2:
This is with Cubase 12.0.20 (Build 263) on Windows 10.
And also seeing the same symptoms in Cubase 11.0.41 on Windows 10.

1 Like