@@ -402,6 +402,11 @@ class PluginVst : public ParameterAndNotesHelper
402402 std::memset (fProgramName , 0 , sizeof (fProgramName ));
403403 std::strcpy (fProgramName , " Default" );
404404
405+ #if DISTRHO_PLUGIN_WANT_PROGRAMS
406+ fProgramIndex = 0 ;
407+ fUserPresetLoaded = false ;
408+ #endif
409+
405410 const uint32_t parameterCount = fPlugin .getParameterCount ();
406411
407412 if (parameterCount != 0 )
@@ -478,8 +483,31 @@ class PluginVst : public ParameterAndNotesHelper
478483
479484 switch (opcode)
480485 {
486+ #if DISTRHO_PLUGIN_WANT_PROGRAMS
487+ case VST_EFFECT_OPCODE_02: // set program
488+ // Some hosts cannot distinguish between user presets (states) and built-in programs.
489+ // They will invoke VST_EFFECT_OPCODE_02 (set program) regardless of the preset type.
490+ // We need to set a switch when calling VST_EFFECT_OPCODE_18 (set chunk), and check it here,
491+ // so that programs will not be loaded unexpectedly when loading a user preset.
492+ if (fUserPresetLoaded )
493+ {
494+ fProgramIndex = 0 ;
495+ fUserPresetLoaded = false ;
496+ return 1 ;
497+ }
498+
499+ fPlugin .loadProgram (value);
500+ fProgramIndex = value;
501+ return 1 ;
502+ break ;
503+ #endif
504+
481505 case VST_EFFECT_OPCODE_03: // get program
506+ #if DISTRHO_PLUGIN_WANT_PROGRAMS
507+ return fProgramIndex ;
508+ #else
482509 return 0 ;
510+ #endif
483511
484512 case VST_EFFECT_OPCODE_04: // set program name
485513 if (char * const programName = (char *)ptr)
@@ -500,7 +528,11 @@ class PluginVst : public ParameterAndNotesHelper
500528 case VST_EFFECT_OPCODE_1D: // get program name indexed
501529 if (char * const programName = (char *)ptr)
502530 {
531+ #if DISTRHO_PLUGIN_WANT_PROGRAMS
532+ d_strncpy (programName, fPlugin .getProgramName (index), 24 );
533+ #else
503534 d_strncpy (programName, fProgramName , 24 );
535+ #endif
504536 return 1 ;
505537 }
506538 break ;
@@ -862,6 +894,11 @@ class PluginVst : public ParameterAndNotesHelper
862894 }
863895 }
864896
897+ # if DISTRHO_PLUGIN_WANT_PROGRAMS
898+ // mark that we have loaded user preset from host
899+ fUserPresetLoaded = true ;
900+ # endif
901+
865902 return 1 ;
866903 }
867904#endif // DISTRHO_PLUGIN_WANT_STATE
@@ -1124,6 +1161,11 @@ class PluginVst : public ParameterAndNotesHelper
11241161 // Temporary data
11251162 char fProgramName [32 ];
11261163
1164+ #if DISTRHO_PLUGIN_WANT_PROGRAMS
1165+ int fProgramIndex ;
1166+ bool fUserPresetLoaded ;
1167+ #endif
1168+
11271169#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
11281170 uint32_t fMidiEventCount ;
11291171 MidiEvent fMidiEvents [kMaxMidiEvents ];
@@ -1697,7 +1739,11 @@ const vst_effect* VSTPluginMain(const vst_host_callback audioMaster)
16971739
16981740 // plugin fields
16991741 effect->num_params = numParams;
1742+ #if DISTRHO_PLUGIN_WANT_PROGRAMS
1743+ effect->num_programs = sPlugin ->getProgramCount ();
1744+ #else
17001745 effect->num_programs = 1 ;
1746+ #endif
17011747 effect->num_inputs = DISTRHO_PLUGIN_NUM_INPUTS;
17021748 effect->num_outputs = DISTRHO_PLUGIN_NUM_OUTPUTS;
17031749
0 commit comments