@@ -490,18 +490,54 @@ Processor::MidiProgram* Processor::getMidiProgram (int program) const
490490 return ret;
491491}
492492
493+ Array<Processor::MidiProgramInfo> Processor::getMidiPrograms () const
494+ {
495+ Array<MidiProgramInfo> result;
496+
497+ if (useGlobalMidiPrograms ())
498+ {
499+ PluginDescription desc;
500+ getPluginDescription (desc);
501+ const auto uids = desc.createIdentifierString ();
502+ if (uids.isEmpty ())
503+ return result;
504+
505+ const auto dir = DataPath::defaultGlobalMidiProgramsDir ();
506+ for (const auto & file : dir.findChildFiles (File::findFiles, false , uids + " _*.eln" ))
507+ {
508+ // Filenames are "<uids>_<NNN>.eln"; parse the trailing program index.
509+ const auto index = file.getFileNameWithoutExtension ()
510+ .fromLastOccurrenceOf (" _" , false , false )
511+ .getIntValue ();
512+ if (isPositiveAndBelow (index, 128 ))
513+ {
514+ String name (" Global " );
515+ name << (index + 1 );
516+ result.add ({ index, name });
517+ }
518+ }
519+ }
520+ else
521+ {
522+ // Only include programs that actually have saved state. Reading a
523+ // program name elsewhere can find-or-create empty placeholder entries.
524+ for (auto * const p : midiPrograms)
525+ if (p->state .getSize () > 0 )
526+ result.add ({ p->program , p->name });
527+ }
528+
529+ std::sort (result.begin (), result.end (), [] (const MidiProgramInfo& a, const MidiProgramInfo& b) {
530+ return a.program < b.program ;
531+ });
532+
533+ return result;
534+ }
535+
493536void Processor::MidiProgramLoader::handleAsyncUpdate ()
494537{
495538 const File programFile = node.getMidiProgramFile ();
496539 const bool globalPrograms = node.useGlobalMidiPrograms ();
497540 const auto requestedProgram = node.getMidiProgram ();
498- #if 0
499- if (node.lastMidiProgram.get() == requestedProgram)
500- {
501- DBG("[element] same program, not loading.");
502- return;
503- }
504- #endif
505541
506542 if (globalPrograms)
507543 {
0 commit comments