@@ -402,6 +402,11 @@ class PluginVst : public ParameterAndNotesHelper
402
402
std::memset (fProgramName , 0 , sizeof (fProgramName ));
403
403
std::strcpy (fProgramName , " Default" );
404
404
405
+ #if DISTRHO_PLUGIN_WANT_PROGRAMS
406
+ fProgramIndex = 0 ;
407
+ fUserPresetLoaded = false ;
408
+ #endif
409
+
405
410
const uint32_t parameterCount = fPlugin .getParameterCount ();
406
411
407
412
if (parameterCount != 0 )
@@ -478,8 +483,31 @@ class PluginVst : public ParameterAndNotesHelper
478
483
479
484
switch (opcode)
480
485
{
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
+
481
505
case VST_EFFECT_OPCODE_03: // get program
506
+ #if DISTRHO_PLUGIN_WANT_PROGRAMS
507
+ return fProgramIndex ;
508
+ #else
482
509
return 0 ;
510
+ #endif
483
511
484
512
case VST_EFFECT_OPCODE_04: // set program name
485
513
if (char * const programName = (char *)ptr)
@@ -500,7 +528,11 @@ class PluginVst : public ParameterAndNotesHelper
500
528
case VST_EFFECT_OPCODE_1D: // get program name indexed
501
529
if (char * const programName = (char *)ptr)
502
530
{
531
+ #if DISTRHO_PLUGIN_WANT_PROGRAMS
532
+ d_strncpy (programName, fPlugin .getProgramName (index), 24 );
533
+ #else
503
534
d_strncpy (programName, fProgramName , 24 );
535
+ #endif
504
536
return 1 ;
505
537
}
506
538
break ;
@@ -862,6 +894,11 @@ class PluginVst : public ParameterAndNotesHelper
862
894
}
863
895
}
864
896
897
+ # if DISTRHO_PLUGIN_WANT_PROGRAMS
898
+ // mark that we have loaded user preset from host
899
+ fUserPresetLoaded = true ;
900
+ # endif
901
+
865
902
return 1 ;
866
903
}
867
904
#endif // DISTRHO_PLUGIN_WANT_STATE
@@ -1124,6 +1161,11 @@ class PluginVst : public ParameterAndNotesHelper
1124
1161
// Temporary data
1125
1162
char fProgramName [32 ];
1126
1163
1164
+ #if DISTRHO_PLUGIN_WANT_PROGRAMS
1165
+ int fProgramIndex ;
1166
+ bool fUserPresetLoaded ;
1167
+ #endif
1168
+
1127
1169
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
1128
1170
uint32_t fMidiEventCount ;
1129
1171
MidiEvent fMidiEvents [kMaxMidiEvents ];
@@ -1697,7 +1739,11 @@ const vst_effect* VSTPluginMain(const vst_host_callback audioMaster)
1697
1739
1698
1740
// plugin fields
1699
1741
effect->num_params = numParams;
1742
+ #if DISTRHO_PLUGIN_WANT_PROGRAMS
1743
+ effect->num_programs = sPlugin ->getProgramCount ();
1744
+ #else
1700
1745
effect->num_programs = 1 ;
1746
+ #endif
1701
1747
effect->num_inputs = DISTRHO_PLUGIN_NUM_INPUTS;
1702
1748
effect->num_outputs = DISTRHO_PLUGIN_NUM_OUTPUTS;
1703
1749
0 commit comments