@@ -478,8 +478,27 @@ class PluginVst : public ParameterAndNotesHelper
478478
479479 switch (opcode)
480480 {
481+ #if DISTRHO_PLUGIN_WANT_PROGRAMS
482+ case VST_EFFECT_OPCODE_02: // set program
483+ // Some hosts cannot distinguish between user presets (states) and built-in programs.
484+ // They will invoke VST_EFFECT_OPCODE_02 (set program) regardless of the preset type.
485+ // We need to set a switch when calling VST_EFFECT_OPCODE_18 (set chunk), and check it here,
486+ // so that programs will not be loaded unexpectedly when loading a user preset.
487+ if (fUserPresetLoaded )
488+ {
489+ fProgramIndex = 0 ;
490+ fUserPresetLoaded = false ;
491+ return 1 ;
492+ }
493+
494+ fPlugin .loadProgram (value);
495+ fProgramIndex = value;
496+ return 1 ;
497+ break ;
498+ #endif
499+
481500 case VST_EFFECT_OPCODE_03: // get program
482- return 0 ;
501+ return fProgramIndex ;
483502
484503 case VST_EFFECT_OPCODE_04: // set program name
485504 if (char * const programName = (char *)ptr)
@@ -500,7 +519,11 @@ class PluginVst : public ParameterAndNotesHelper
500519 case VST_EFFECT_OPCODE_1D: // get program name indexed
501520 if (char * const programName = (char *)ptr)
502521 {
522+ #if DISTRHO_PLUGIN_WANT_PROGRAMS
523+ d_strncpy (programName, fPlugin .getProgramName (index), 24 );
524+ #else
503525 d_strncpy (programName, fProgramName , 24 );
526+ #endif
504527 return 1 ;
505528 }
506529 break ;
@@ -862,6 +885,9 @@ class PluginVst : public ParameterAndNotesHelper
862885 }
863886 }
864887
888+ // mark that we have loaded user preset from host
889+ fUserPresetLoaded = true ;
890+
865891 return 1 ;
866892 }
867893#endif // DISTRHO_PLUGIN_WANT_STATE
@@ -1123,6 +1149,8 @@ class PluginVst : public ParameterAndNotesHelper
11231149
11241150 // Temporary data
11251151 char fProgramName [32 ];
1152+ int fProgramIndex = 0 ;
1153+ int fUserPresetLoaded = false ;
11261154
11271155#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
11281156 uint32_t fMidiEventCount ;
@@ -1697,7 +1725,11 @@ const vst_effect* VSTPluginMain(const vst_host_callback audioMaster)
16971725
16981726 // plugin fields
16991727 effect->num_params = numParams;
1728+ #if DISTRHO_PLUGIN_WANT_PROGRAMS
1729+ effect->num_programs = sPlugin ->getProgramCount ();
1730+ #else
17001731 effect->num_programs = 1 ;
1732+ #endif
17011733 effect->num_inputs = DISTRHO_PLUGIN_NUM_INPUTS;
17021734 effect->num_outputs = DISTRHO_PLUGIN_NUM_OUTPUTS;
17031735
0 commit comments