diff --git a/src/bindings/fluid_ladspa.c b/src/bindings/fluid_ladspa.c index 6dcfff77..df2d2980 100644 --- a/src/bindings/fluid_ladspa.c +++ b/src/bindings/fluid_ladspa.c @@ -34,6 +34,8 @@ #define LADSPA_API_ENTER(_fx) (fluid_rec_mutex_lock((_fx)->api_mutex)) +#define LADSPA_API_EXIT(_fx) (fluid_rec_mutex_unlock((_fx)->api_mutex)) + #define LADSPA_API_RETURN(_fx, _ret) \ fluid_rec_mutex_unlock((_fx)->api_mutex); \ return (_ret); @@ -88,7 +90,7 @@ fluid_ladspa_fx_t *new_fluid_ladspa_fx(fluid_synth_t *synth) fx->state = FLUID_LADSPA_INACTIVE; - fx->sample_rate = synth->sample_rate; + fx->sample_rate = (unsigned long)synth->sample_rate; fx->audio_groups = synth->audio_groups; fx->effects_channels = synth->effects_channels; @@ -159,6 +161,43 @@ void delete_fluid_ladspa_fx(fluid_ladspa_fx_t *fx) FLUID_FREE(fx); }; +/** + * Set the sample rate of the LADSPA effects. + * + * Resets the LADSPA effects if the sample rate is different from the + * previous sample rate. + * + * @param fx LADSPA fx instance + * @param sample_rate new sample rate + */ +void fluid_ladspa_set_sample_rate(fluid_ladspa_fx_t *fx, fluid_synth_t *synth) +{ + unsigned long new_sample_rate = (unsigned long)synth->sample_rate; + + LADSPA_API_ENTER(fx); + + if (fx->sample_rate == new_sample_rate) + { + LADSPA_API_EXIT(fx); + return; + } + + if (fluid_ladspa_is_active(fx)) + { + if (fluid_ladspa_deactivate(fx, synth) != FLUID_OK) + { + FLUID_LOG(FLUID_ERR, "Failed to deactivate LADSPA, unable to change sample rate"); + LADSPA_API_EXIT(fx); + return; + } + } + + clear_ladspa(fx); + fx->sample_rate = new_sample_rate; + + LADSPA_API_EXIT(fx); +} + /** * Check if the LADSPA engine is in use by FluidSynth. * diff --git a/src/bindings/fluid_ladspa.h b/src/bindings/fluid_ladspa.h index c0b4f971..5fb41579 100644 --- a/src/bindings/fluid_ladspa.h +++ b/src/bindings/fluid_ladspa.h @@ -94,7 +94,7 @@ typedef struct _fluid_ladspa_node_t typedef struct _fluid_ladspa_fx_t { - int sample_rate; + unsigned long sample_rate; int audio_groups; int effects_channels; @@ -124,6 +124,7 @@ typedef struct _fluid_ladspa_fx_t fluid_ladspa_fx_t *new_fluid_ladspa_fx(fluid_synth_t *synth); void delete_fluid_ladspa_fx(fluid_ladspa_fx_t *fx); +void fluid_ladspa_set_sample_rate(fluid_ladspa_fx_t *fx, fluid_synth_t *synth); int fluid_ladspa_is_active(fluid_ladspa_fx_t *fx); int fluid_ladspa_activate(fluid_ladspa_fx_t *fx, fluid_synth_t *synth); diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index 329bfe9a..6f8c481d 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -2350,7 +2350,7 @@ fluid_synth_update_presets(fluid_synth_t* synth) } } -/* Handler for synth.gain setting. */ +/* Handler for synth.sample-rate setting. */ static int fluid_synth_update_sample_rate(fluid_synth_t* synth, char* name, double value) { @@ -2383,6 +2383,16 @@ fluid_synth_set_sample_rate(fluid_synth_t* synth, float sample_rate) fluid_synth_update_mixer(synth, fluid_rvoice_mixer_set_samplerate, 0, sample_rate); fluid_synth_api_exit(synth); + +#ifdef LADSPA + /* Signal sample rate change to LADSPA effects. Called after releasing the + * synth api, as LADSPA might need to wait for rvoice mixer to deactivate + * the effects unit first. */ + if (synth->ladspa_fx != NULL) + { + fluid_ladspa_set_sample_rate(synth->ladspa_fx, synth); + } +#endif }