From 336ae88aafeccf9fa0d9e68f0235ee7d7e7a6deb Mon Sep 17 00:00:00 2001 From: derselbst Date: Thu, 7 Sep 2017 10:45:46 +0200 Subject: [PATCH] new public API to manipulate default modulators patch by @mawe42 --- include/fluidsynth/synth.h | 13 ++++++ src/synth/fluid_synth.c | 90 +++++++++++++++++++++++++++++++++----- src/synth/fluid_synth.h | 2 + 3 files changed, 95 insertions(+), 10 deletions(-) diff --git a/include/fluidsynth/synth.h b/include/fluidsynth/synth.h index bee64d4c..ad37f1de 100644 --- a/include/fluidsynth/synth.h +++ b/include/fluidsynth/synth.h @@ -260,6 +260,19 @@ FLUIDSYNTH_API double fluid_synth_get_cpu_load(fluid_synth_t* synth); FLUIDSYNTH_API char* fluid_synth_error(fluid_synth_t* synth); +/* Default modulators */ + +/** + * Enum used with fluid_synth_add_default_mod() to specify how to handle duplicate modulators. + */ +enum fluid_synth_add_mod { + FLUID_SYNTH_OVERWRITE, /**< Overwrite any existing matching modulator */ + FLUID_SYNTH_ADD, /**< Add (sum) modulator amounts */ +}; + +FLUIDSYNTH_API int fluid_synth_add_default_mod(fluid_synth_t* synth, fluid_mod_t* mod, int mode); + + /* * Synthesizer plugin * diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index c44baf88..859f519c 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -670,6 +670,21 @@ new_fluid_synth(fluid_settings_t *settings) if (synth->eventhandler == NULL) goto error_recovery; + /* Setup the list of default modulators. + * Needs to happen after eventhandler has been set up, as fluid_synth_enter_api is called in the process */ + synth->default_mod = NULL; + fluid_synth_add_default_mod(synth, &default_vel2att_mod, FLUID_SYNTH_ADD); + fluid_synth_add_default_mod(synth, &default_vel2filter_mod, FLUID_SYNTH_ADD); + fluid_synth_add_default_mod(synth, &default_at2viblfo_mod, FLUID_SYNTH_ADD); + fluid_synth_add_default_mod(synth, &default_mod2viblfo_mod, FLUID_SYNTH_ADD); + fluid_synth_add_default_mod(synth, &default_att_mod, FLUID_SYNTH_ADD); + fluid_synth_add_default_mod(synth, &default_pan_mod, FLUID_SYNTH_ADD); + fluid_synth_add_default_mod(synth, &default_expr_mod, FLUID_SYNTH_ADD); + fluid_synth_add_default_mod(synth, &default_reverb_mod, FLUID_SYNTH_ADD); + fluid_synth_add_default_mod(synth, &default_chorus_mod, FLUID_SYNTH_ADD); + fluid_synth_add_default_mod(synth, &default_pitch_bend_mod, FLUID_SYNTH_ADD); + + #ifdef LADSPA /* Create and initialize the Fx unit.*/ synth->LADSPA_FxUnit = new_fluid_LADSPA_FxUnit(synth); @@ -782,6 +797,8 @@ delete_fluid_synth(fluid_synth_t* synth) fluid_list_t *list; fluid_sfont_info_t* sfont_info; fluid_sfloader_t* loader; + fluid_mod_t* default_mod; + fluid_mod_t* mod; if (synth == NULL) { return FLUID_OK; @@ -887,6 +904,14 @@ delete_fluid_synth(fluid_synth_t* synth) FLUID_FREE(synth->LADSPA_FxUnit); #endif + /* delete all default modulators */ + default_mod = synth->default_mod; + while (default_mod != NULL) { + mod = default_mod; + default_mod = mod->next; + fluid_mod_delete(mod); + } + fluid_rec_mutex_destroy(synth->mutex); FLUID_FREE(synth); @@ -1048,6 +1073,55 @@ fluid_synth_damp_voices_by_sostenuto_LOCAL(fluid_synth_t* synth, int chan) return FLUID_OK; } +/** + * Adds a default modulator to the synth. + * @param synth FluidSynth instance + * @param mod Modulator info (values copied, passed in object can be freed again immediately) + * @param mode Determines how to handle an existing identical modulator + * #FLUID_SYNTH_ADD to add (offset) the modulator amounts, + * #FLUID_SYNTH_OVERWRITE to replace the modulator, + * @return FLUID_OK on success, FLUID_FAILED otherwise + */ +int +fluid_synth_add_default_mod(fluid_synth_t* synth, fluid_mod_t* mod, int mode) +{ + fluid_mod_t* default_mod; + fluid_mod_t* last_mod = NULL; + fluid_mod_t* new_mod; + + fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); + fluid_synth_api_enter(synth); + + default_mod = synth->default_mod; + + while (default_mod != NULL) { + if (fluid_mod_test_identity(default_mod, mod)) { + if (mode == FLUID_SYNTH_ADD) + default_mod->amount += mod->amount; + else // FLUID_SYNTH_OVERWRITE + default_mod->amount = mod->amount; + FLUID_API_RETURN(FLUID_OK); + } + last_mod = default_mod; + default_mod = default_mod->next; + } + + /* Add a new modulator (no existing modulator to add / overwrite). */ + new_mod = fluid_mod_new(); + if (new_mod == NULL) + FLUID_API_RETURN(FLUID_FAILED); + + fluid_mod_clone(new_mod, mod); + new_mod->next = NULL; + + if (last_mod == NULL) + synth->default_mod = new_mod; + else + last_mod->next = new_mod; + + FLUID_API_RETURN(FLUID_OK); +} + /** * Send a MIDI controller event on a MIDI channel. @@ -3064,6 +3138,7 @@ fluid_synth_alloc_voice(fluid_synth_t* synth, fluid_sample_t* sample, int chan, int i, k; fluid_voice_t* voice = NULL; fluid_channel_t* channel = NULL; + fluid_mod_t* default_mod; unsigned int ticks; fluid_return_val_if_fail (sample != NULL, NULL); @@ -3116,16 +3191,11 @@ fluid_synth_alloc_voice(fluid_synth_t* synth, fluid_sample_t* sample, int chan, } /* add the default modulators to the synthesis process. */ - fluid_voice_add_mod(voice, &default_vel2att_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.1 */ - fluid_voice_add_mod(voice, &default_vel2filter_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.2 */ - fluid_voice_add_mod(voice, &default_at2viblfo_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.3 */ - fluid_voice_add_mod(voice, &default_mod2viblfo_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.4 */ - fluid_voice_add_mod(voice, &default_att_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.5 */ - fluid_voice_add_mod(voice, &default_pan_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.6 */ - fluid_voice_add_mod(voice, &default_expr_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.7 */ - fluid_voice_add_mod(voice, &default_reverb_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.8 */ - fluid_voice_add_mod(voice, &default_chorus_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.9 */ - fluid_voice_add_mod(voice, &default_pitch_bend_mod, FLUID_VOICE_DEFAULT); /* SF2.01 $8.4.10 */ + default_mod = synth->default_mod; + while (default_mod != NULL) { + fluid_voice_add_mod(voice, default_mod, FLUID_VOICE_DEFAULT); + default_mod = default_mod->next; + } FLUID_API_RETURN(voice); } diff --git a/src/synth/fluid_synth.h b/src/synth/fluid_synth.h index 4bcc361e..1eeec177 100644 --- a/src/synth/fluid_synth.h +++ b/src/synth/fluid_synth.h @@ -169,6 +169,8 @@ struct _fluid_synth_t int cores; /**< Number of CPU cores (1 by default) */ + fluid_mod_t* default_mod; /**< the (dynamic) list of default modulators */ + #ifdef LADSPA fluid_LADSPA_FxUnit_t* LADSPA_FxUnit; /**< Effects unit for LADSPA support */ #endif