From f26ed23fd91a0f16feab65ad7940566544d54a64 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 6 Dec 2016 16:59:57 +0100 Subject: a-fluid synth: list all bank/programs --- libs/plugins/a-fluidsynth.lv2/a-fluidsynth.cc | 126 +++++++++++++++++--------- 1 file changed, 83 insertions(+), 43 deletions(-) diff --git a/libs/plugins/a-fluidsynth.lv2/a-fluidsynth.cc b/libs/plugins/a-fluidsynth.lv2/a-fluidsynth.cc index 4a91b31823..bea0bc78d2 100644 --- a/libs/plugins/a-fluidsynth.lv2/a-fluidsynth.cc +++ b/libs/plugins/a-fluidsynth.lv2/a-fluidsynth.cc @@ -20,9 +20,14 @@ #define _GNU_SOURCE #endif -#include +#include +#include +#include +#include +#include + +#include #include -#include #include #define AFS_URN "urn:ardour:a-fluidsynth" @@ -75,6 +80,27 @@ enum { CMD_FREE = 1, }; +struct BankProgram { + BankProgram (const std::string& n, int b, int p) + : name (n) + , bank (b) + , program (p) + {} + + BankProgram (const BankProgram& other) + : name (other.name) + , bank (other.bank) + , program (other.program) + {} + + std::string name; + int bank; + int program; +}; + +typedef std::vector BPList; +typedef std::map BPMap; + typedef struct { /* ports */ const LV2_Atom_Sequence* control; @@ -109,7 +135,9 @@ typedef struct { #ifdef LV2_EXTENDED LV2_Midnam* midnam; + BPMap presets; #endif + pthread_mutex_t bp_lock; /* state */ bool panic; @@ -134,6 +162,12 @@ load_sf2 (AFluidSynth* self, const char* fn) { const int synth_id = fluid_synth_sfload (self->synth, fn, 1); +#ifdef LV2_EXTENDED + pthread_mutex_lock (&self->bp_lock); + self->presets.clear (); + pthread_mutex_unlock (&self->bp_lock); +#endif + if (synth_id == FLUID_FAILED) { return false; } @@ -146,10 +180,23 @@ load_sf2 (AFluidSynth* self, const char* fn) int chn; fluid_preset_t preset; sfont->iteration_start (sfont); - for (chn = 0; sfont->iteration_next (sfont, &preset) && chn < 16; ++chn) { - fluid_synth_program_select (self->synth, chn, synth_id, - preset.get_banknum (&preset), preset.get_num (&preset)); + pthread_mutex_lock (&self->bp_lock); + for (chn = 0; sfont->iteration_next (sfont, &preset); ++chn) { + if (chn < 16) { + fluid_synth_program_select (self->synth, chn, synth_id, + preset.get_banknum (&preset), preset.get_num (&preset)); + } +#ifndef LV2_EXTENDED + else { break ; } +#else + self->presets[preset.get_banknum (&preset)].push_back ( + BankProgram ( + preset.get_name (&preset), + preset.get_banknum (&preset), + preset.get_num (&preset))); +#endif } + pthread_mutex_unlock (&self->bp_lock); if (chn == 0) { return false; @@ -293,6 +340,8 @@ instantiate (const LV2_Descriptor* descriptor, /* initialize plugin state */ + pthread_mutex_init (&self->bp_lock, NULL); + self->presets = BPMap(); self->panic = false; self->inform_ui = false; self->initialized = false; @@ -500,6 +549,7 @@ static void cleanup (LV2_Handle instance) delete_fluid_synth (self->synth); delete_fluid_settings (self->settings); delete_fluid_midi_event (self->fmidi_event); + pthread_mutex_destroy (&self->bp_lock); free (self); } @@ -524,6 +574,7 @@ work (LV2_Handle instance, return LV2_WORKER_ERR_UNKNOWN; } + self->initialized = load_sf2 (self, self->queue_sf2_file_path); if (self->initialized) { @@ -618,20 +669,16 @@ restore (LV2_Handle instance, return LV2_STATE_SUCCESS; } -static char* xml_escape (const char* s) { - // crude, but hey - if (!s) { - return strdup (""); - } - char* tmp; - char* rv = strdup (s); - while ((tmp = strchr(rv, '"'))) { - *tmp = '\''; - } - while ((tmp = strchr(rv, '&'))) { - *tmp = '+'; - } - return rv; +static std::string xml_escape (const std::string& s) +{ + std::string r (s); + std::replace (r.begin (), r.end(), '"', '\''); + size_t pos = 0; + while((pos = r.find ("&", pos)) != std::string::npos) { + r.replace (pos, 1, "&"); + pos += 4; + } + return r; } #ifdef LV2_EXTENDED @@ -642,12 +689,6 @@ mn_file (LV2_Handle instance) char* rv = NULL; char tmp[1024]; - fluid_sfont_t* sfont = NULL; - if (self->initialized && !self->reinit_in_progress) { - sfont = fluid_synth_get_sfont (self->synth, 0); - } - // TODO collect program info during load_sf2(); - rv = (char*) calloc (1, sizeof (char)); #define pf(...) \ @@ -684,27 +725,26 @@ mn_file (LV2_Handle instance) } pf (" \n"); pf (" \n"); - pf (" \n"); - pf (" \n"); - pf (" \n"); - pf (" \n"); - - pf (" \n"); - if (sfont) { - fluid_preset_t preset; - sfont->iteration_start (sfont); - for (int num = 1; sfont->iteration_next (sfont, &preset); ++num) { - if (preset.get_banknum (&preset) != 0) { - continue; + int bn = 1; + pthread_mutex_lock (&self->bp_lock); + const BPMap& ps (self->presets); + pthread_mutex_unlock (&self->bp_lock); + + for (BPMap::const_iterator i = ps.begin (); i != ps.end (); ++i, ++bn) { + pf (" \n", i->first); + if (i->second.size() > 0) { + pf (" \n"); + int n = 0; + for (BPList::const_iterator j = i->second.begin(); j != i->second.end(); ++j, ++n) { + pf (" \n", + n, xml_escape (j->name).c_str(), j->program); } - char* pn = xml_escape (preset.get_name (&preset)); - pf (" \n", - num, pn, preset.get_num (&preset)); - free (pn); + pf (" \n"); } + pf (" \n"); } - pf (" \n"); + pf (" \n"); pf (" \n"); pf (" \n"); @@ -715,12 +755,12 @@ mn_file (LV2_Handle instance) pf (" \n"); pf (" \n"); - pf ( " \n" "" ); + //printf("-----\n%s\n------\n", rv); return rv; } -- cgit v1.2.3