diff --git a/src/rvoice/fluid_adsr_env.c b/src/rvoice/fluid_adsr_env.c index 5362405f..0d3d7b60 100644 --- a/src/rvoice/fluid_adsr_env.c +++ b/src/rvoice/fluid_adsr_env.c @@ -20,15 +20,16 @@ #include "fluid_adsr_env.h" -void -fluid_adsr_env_set_data(fluid_adsr_env_t* env, - fluid_adsr_env_section_t section, - unsigned int count, - fluid_real_t coeff, - fluid_real_t increment, - fluid_real_t min, - fluid_real_t max) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_adsr_env_set_data) { + fluid_adsr_env_t* env = obj; + fluid_adsr_env_section_t section = param[0].i; + unsigned int count = param[1].i; + fluid_real_t coeff = param[2].real; + fluid_real_t increment = param[3].real; + fluid_real_t min = param[4].real; + fluid_real_t max = param[5].real; + env->data[section].count = count; env->data[section].coeff = coeff; env->data[section].increment = increment; diff --git a/src/rvoice/fluid_adsr_env.h b/src/rvoice/fluid_adsr_env.h index 1a5a4c22..abb267d4 100644 --- a/src/rvoice/fluid_adsr_env.h +++ b/src/rvoice/fluid_adsr_env.h @@ -104,14 +104,7 @@ fluid_adsr_env_calc(fluid_adsr_env_t* env, int is_volenv) /* This one cannot be inlined since it is referenced in the event queue */ -void -fluid_adsr_env_set_data(fluid_adsr_env_t* env, - fluid_adsr_env_section_t section, - unsigned int count, - fluid_real_t coeff, - fluid_real_t increment, - fluid_real_t min, - fluid_real_t max); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_adsr_env_set_data); static FLUID_INLINE void fluid_adsr_env_reset(fluid_adsr_env_t* env) diff --git a/src/rvoice/fluid_iir_filter.c b/src/rvoice/fluid_iir_filter.c index bd488be5..95ea5b69 100644 --- a/src/rvoice/fluid_iir_filter.c +++ b/src/rvoice/fluid_iir_filter.c @@ -138,8 +138,12 @@ fluid_iir_filter_apply(fluid_iir_filter_t* iir_filter, } -void fluid_iir_filter_init(fluid_iir_filter_t* iir_filter, enum fluid_iir_filter_type type, enum fluid_iir_filter_flags flags) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_iir_filter_init) { + fluid_iir_filter_t* iir_filter = obj; + enum fluid_iir_filter_type type = param[0].i; + enum fluid_iir_filter_flags flags = param[1].i; + iir_filter->type = type; iir_filter->flags = flags; if(type != FLUID_IIR_DISABLED) @@ -158,10 +162,11 @@ fluid_iir_filter_reset(fluid_iir_filter_t* iir_filter) iir_filter->filter_startup = 1; } -void -fluid_iir_filter_set_fres(fluid_iir_filter_t* iir_filter, - fluid_real_t fres) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_iir_filter_set_fres) { + fluid_iir_filter_t* iir_filter = obj; + fluid_real_t fres = param[0].real; + iir_filter->fres = fres; iir_filter->last_fres = -1.; } @@ -197,9 +202,10 @@ static fluid_real_t fluid_iir_filter_q_from_dB(fluid_real_t q_dB) return pow(10.0f, q_dB / 20.0f); } -void -fluid_iir_filter_set_q(fluid_iir_filter_t* iir_filter, fluid_real_t q) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_iir_filter_set_q) { + fluid_iir_filter_t* iir_filter = obj; + fluid_real_t q = param[0].real; int flags = iir_filter->flags; if(flags & FLUID_IIR_Q_ZERO_OFF && q<=0.0) diff --git a/src/rvoice/fluid_iir_filter.h b/src/rvoice/fluid_iir_filter.h index d1af2a0e..23268848 100644 --- a/src/rvoice/fluid_iir_filter.h +++ b/src/rvoice/fluid_iir_filter.h @@ -25,19 +25,15 @@ typedef struct _fluid_iir_filter_t fluid_iir_filter_t; - -void fluid_iir_filter_init(fluid_iir_filter_t* iir_filter, enum fluid_iir_filter_type, enum fluid_iir_filter_flags flags); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_iir_filter_init); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_iir_filter_set_fres); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_iir_filter_set_q); void fluid_iir_filter_apply(fluid_iir_filter_t* iir_filter, fluid_real_t *dsp_buf, int dsp_buf_count); void fluid_iir_filter_reset(fluid_iir_filter_t* iir_filter); -void fluid_iir_filter_set_q(fluid_iir_filter_t* iir_filter, fluid_real_t q); - -void fluid_iir_filter_set_fres(fluid_iir_filter_t* iir_filter, - fluid_real_t fres); - void fluid_iir_filter_calc(fluid_iir_filter_t* iir_filter, fluid_real_t output_rate, fluid_real_t fres_mod); diff --git a/src/rvoice/fluid_lfo.c b/src/rvoice/fluid_lfo.c index ff178e00..a6d2f6ff 100644 --- a/src/rvoice/fluid_lfo.c +++ b/src/rvoice/fluid_lfo.c @@ -1,13 +1,17 @@ #include "fluid_lfo.h" -void -fluid_lfo_set_incr(fluid_lfo_t* lfo, fluid_real_t increment) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_lfo_set_incr) { - lfo->increment = increment; + fluid_lfo_t* lfo = obj; + fluid_real_t increment = param[0].real; + + lfo->increment = increment; } -void -fluid_lfo_set_delay(fluid_lfo_t* lfo, unsigned int delay) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_lfo_set_delay) { - lfo->delay = delay; + fluid_lfo_t* lfo = obj; + unsigned int delay = param[0].i; + + lfo->delay = delay; } diff --git a/src/rvoice/fluid_lfo.h b/src/rvoice/fluid_lfo.h index 7916e9eb..7f2906a0 100644 --- a/src/rvoice/fluid_lfo.h +++ b/src/rvoice/fluid_lfo.h @@ -38,8 +38,8 @@ fluid_lfo_reset(fluid_lfo_t* lfo) } // These two cannot be inlined since they're used by event_dispatch -void fluid_lfo_set_incr(fluid_lfo_t* lfo, fluid_real_t increment); -void fluid_lfo_set_delay(fluid_lfo_t* lfo, unsigned int delay); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_lfo_set_incr); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_lfo_set_delay); static FLUID_INLINE fluid_real_t fluid_lfo_get_val(fluid_lfo_t* lfo) diff --git a/src/rvoice/fluid_rvoice.c b/src/rvoice/fluid_rvoice.c index 7dccded0..0c3e2c03 100644 --- a/src/rvoice/fluid_rvoice.c +++ b/src/rvoice/fluid_rvoice.c @@ -22,6 +22,9 @@ #include "fluid_conv.h" #include "fluid_sys.h" + +static void fluid_rvoice_noteoff_LOCAL(fluid_rvoice_t* voice, unsigned int min_ticks); + /** * @return -1 if voice has finished, 0 if it's currently quiet, 1 otherwise */ @@ -158,7 +161,7 @@ fluid_rvoice_check_sample_sanity(fluid_rvoice_t* voice) /* Zero length? */ if (voice->dsp.start == voice->dsp.end){ - fluid_rvoice_voiceoff(voice); + fluid_rvoice_voiceoff(voice, NULL); return; } @@ -282,7 +285,7 @@ fluid_rvoice_write (fluid_rvoice_t* voice, fluid_real_t *dsp_buf) if (voice->envlfo.noteoff_ticks != 0 && voice->envlfo.ticks >= voice->envlfo.noteoff_ticks) { - fluid_rvoice_noteoff(voice, 0); + fluid_rvoice_noteoff_LOCAL(voice, 0); } voice->envlfo.ticks += FLUID_BUFSIZE; @@ -475,28 +478,33 @@ fluid_rvoice_buffers_check_bufnum(fluid_rvoice_buffers_t* buffers, unsigned int } -void -fluid_rvoice_buffers_set_amp(fluid_rvoice_buffers_t* buffers, - unsigned int bufnum, fluid_real_t value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_buffers_set_amp) { + fluid_rvoice_buffers_t* buffers = obj; + unsigned int bufnum = param[0].i; + fluid_real_t value = param[1].real; + if (fluid_rvoice_buffers_check_bufnum(buffers, bufnum) != FLUID_OK) return; buffers->bufs[bufnum].amp = value; } -void -fluid_rvoice_buffers_set_mapping(fluid_rvoice_buffers_t* buffers, - unsigned int bufnum, int mapping) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_buffers_set_mapping) { + fluid_rvoice_buffers_t* buffers = obj; + unsigned int bufnum = param[0].i; + int mapping = param[1].i; + if (fluid_rvoice_buffers_check_bufnum(buffers, bufnum) != FLUID_OK) return; buffers->bufs[bufnum].mapping = mapping; } -void -fluid_rvoice_reset(fluid_rvoice_t* voice) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_reset) { + fluid_rvoice_t* voice = obj; + voice->dsp.has_looped = 0; voice->envlfo.ticks = 0; voice->envlfo.noteoff_ticks = 0; @@ -530,9 +538,16 @@ fluid_rvoice_reset(fluid_rvoice_t* voice) voice->dsp.check_sample_sanity_flag |= FLUID_SAMPLESANITY_STARTUP; } +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_noteoff) +{ + fluid_rvoice_t* rvoice = obj; + unsigned int min_ticks = param[0].i; + + fluid_rvoice_noteoff_LOCAL(rvoice, min_ticks); +} -void -fluid_rvoice_noteoff(fluid_rvoice_t* voice, unsigned int min_ticks) +static void +fluid_rvoice_noteoff_LOCAL(fluid_rvoice_t* voice, unsigned int min_ticks) { if (min_ticks > voice->envlfo.ticks) { /* Delay noteoff */ @@ -600,9 +615,9 @@ static FLUID_INLINE void fluid_rvoice_local_retrigger_attack (fluid_rvoice_t* vo * see fluid_synth_noteon_mono_legato_multi_retrigger() * @param voice the synthesis voice to be updated */ -void -fluid_rvoice_multi_retrigger_attack (fluid_rvoice_t* voice) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_multi_retrigger_attack) { + fluid_rvoice_t* voice = obj; int section = fluid_adsr_env_get_section(&voice->envlfo.volenv); /*------------------------------------------------------------------------- Section skip for volume envelope @@ -645,9 +660,12 @@ fluid_rvoice_multi_retrigger_attack (fluid_rvoice_t* voice) * pitchoffset is accumulated in current dsp pitchoffset. * 2) And to get constant portamento duration, dsp pitch increment is updated. */ -void fluid_rvoice_set_portamento(fluid_rvoice_t * voice, unsigned int countinc, - fluid_real_t pitchoffset) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_portamento) { + fluid_rvoice_t * voice = obj; + unsigned int countinc = param[0].i; + fluid_real_t pitchoffset = param[1].real; + if (countinc) { voice->dsp.pitchoffset += pitchoffset; @@ -657,82 +675,110 @@ void fluid_rvoice_set_portamento(fluid_rvoice_t * voice, unsigned int countinc, dsp.pitchoffset will be incremented by dsp pitchinc. */ } -void -fluid_rvoice_set_output_rate(fluid_rvoice_t* voice, fluid_real_t value) + +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_output_rate) { + fluid_rvoice_t* voice = obj; + fluid_real_t value = param[0].real; + voice->dsp.output_rate = value; } -void -fluid_rvoice_set_interp_method(fluid_rvoice_t* voice, int value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_interp_method) { + fluid_rvoice_t* voice = obj; + int value = param[0].i; + voice->dsp.interp_method = value; } -void -fluid_rvoice_set_root_pitch_hz(fluid_rvoice_t* voice, fluid_real_t value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_root_pitch_hz) { + fluid_rvoice_t* voice = obj; + fluid_real_t value = param[0].real; + voice->dsp.root_pitch_hz = value; } -void -fluid_rvoice_set_pitch(fluid_rvoice_t* voice, fluid_real_t value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_pitch) { + fluid_rvoice_t* voice = obj; + fluid_real_t value = param[0].real; + voice->dsp.pitch = value; } -void -fluid_rvoice_set_attenuation(fluid_rvoice_t* voice, fluid_real_t value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_attenuation) { + fluid_rvoice_t* voice = obj; + fluid_real_t value = param[0].real; + voice->dsp.prev_attenuation = voice->dsp.attenuation; voice->dsp.attenuation = value; } -void -fluid_rvoice_set_min_attenuation_cB(fluid_rvoice_t* voice, fluid_real_t value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_min_attenuation_cB) { + fluid_rvoice_t* voice = obj; + fluid_real_t value = param[0].real; + voice->dsp.min_attenuation_cB = value; } -void -fluid_rvoice_set_viblfo_to_pitch(fluid_rvoice_t* voice, fluid_real_t value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_viblfo_to_pitch) { + fluid_rvoice_t* voice = obj; + fluid_real_t value = param[0].real; + voice->envlfo.viblfo_to_pitch = value; } -void fluid_rvoice_set_modlfo_to_pitch(fluid_rvoice_t* voice, fluid_real_t value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_pitch) { + fluid_rvoice_t* voice = obj; + fluid_real_t value = param[0].real; + voice->envlfo.modlfo_to_pitch = value; } -void -fluid_rvoice_set_modlfo_to_vol(fluid_rvoice_t* voice, fluid_real_t value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_vol) { + fluid_rvoice_t* voice = obj; + fluid_real_t value = param[0].real; + voice->envlfo.modlfo_to_vol = value; } -void -fluid_rvoice_set_modlfo_to_fc(fluid_rvoice_t* voice, fluid_real_t value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_fc) { + fluid_rvoice_t* voice = obj; + fluid_real_t value = param[0].real; + voice->envlfo.modlfo_to_fc = value; } -void -fluid_rvoice_set_modenv_to_fc(fluid_rvoice_t* voice, fluid_real_t value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modenv_to_fc) { + fluid_rvoice_t* voice = obj; + fluid_real_t value = param[0].real; + voice->envlfo.modenv_to_fc = value; } -void -fluid_rvoice_set_modenv_to_pitch(fluid_rvoice_t* voice, fluid_real_t value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modenv_to_pitch) { + fluid_rvoice_t* voice = obj; + fluid_real_t value = param[0].real; + voice->envlfo.modenv_to_pitch = value; } -void -fluid_rvoice_set_synth_gain(fluid_rvoice_t* voice, fluid_real_t value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_synth_gain) { + fluid_rvoice_t* voice = obj; + fluid_real_t value = param[0].real; + voice->dsp.synth_gain = value; /* For a looped sample, this value will be overwritten as soon as the @@ -744,52 +790,67 @@ fluid_rvoice_set_synth_gain(fluid_rvoice_t* voice, fluid_real_t value) voice->dsp.check_sample_sanity_flag |= FLUID_SAMPLESANITY_CHECK; } -void -fluid_rvoice_set_start(fluid_rvoice_t* voice, int value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_start) { + fluid_rvoice_t* voice = obj; + int value = param[0].i; + voice->dsp.start = value; voice->dsp.check_sample_sanity_flag |= FLUID_SAMPLESANITY_CHECK; } -void -fluid_rvoice_set_end(fluid_rvoice_t* voice, int value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_end) { + fluid_rvoice_t* voice = obj; + int value = param[0].i; + voice->dsp.end = value; voice->dsp.check_sample_sanity_flag |= FLUID_SAMPLESANITY_CHECK; } -void -fluid_rvoice_set_loopstart(fluid_rvoice_t* voice, int value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_loopstart) { + fluid_rvoice_t* voice = obj; + int value = param[0].i; + voice->dsp.loopstart = value; voice->dsp.check_sample_sanity_flag |= FLUID_SAMPLESANITY_CHECK; } -void fluid_rvoice_set_loopend(fluid_rvoice_t* voice, int value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_loopend) { + fluid_rvoice_t* voice = obj; + int value = param[0].i; + voice->dsp.loopend = value; voice->dsp.check_sample_sanity_flag |= FLUID_SAMPLESANITY_CHECK; } -void fluid_rvoice_set_samplemode(fluid_rvoice_t* voice, enum fluid_loop value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_samplemode) { + fluid_rvoice_t* voice = obj; + enum fluid_loop value = param[0].i; + voice->dsp.samplemode = value; voice->dsp.check_sample_sanity_flag |= FLUID_SAMPLESANITY_CHECK; } -void -fluid_rvoice_set_sample(fluid_rvoice_t* voice, fluid_sample_t* value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_sample) { + fluid_rvoice_t* voice = obj; + fluid_sample_t* value = param[0].ptr; + voice->dsp.sample = value; if (value) { voice->dsp.check_sample_sanity_flag |= FLUID_SAMPLESANITY_STARTUP; } } -void -fluid_rvoice_voiceoff(fluid_rvoice_t* voice) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_voiceoff) { + fluid_rvoice_t* voice = obj; + fluid_adsr_env_set_section(&voice->envlfo.volenv, FLUID_VOICE_ENVFINISHED); fluid_adsr_env_set_section(&voice->envlfo.modenv, FLUID_VOICE_ENVFINISHED); } diff --git a/src/rvoice/fluid_rvoice.h b/src/rvoice/fluid_rvoice.h index 88e1ddf4..9518be00 100644 --- a/src/rvoice/fluid_rvoice.h +++ b/src/rvoice/fluid_rvoice.h @@ -167,40 +167,36 @@ int fluid_rvoice_write(fluid_rvoice_t* voice, fluid_real_t *dsp_buf); void fluid_rvoice_buffers_mix(fluid_rvoice_buffers_t* buffers, fluid_real_t* dsp_buf, int samplecount, fluid_real_t** dest_bufs, int dest_bufcount); -void fluid_rvoice_buffers_set_amp(fluid_rvoice_buffers_t* buffers, - unsigned int bufnum, fluid_real_t value); -void fluid_rvoice_buffers_set_mapping(fluid_rvoice_buffers_t* buffers, - unsigned int bufnum, int mapping); -/* Dynamic update functions */ -void fluid_rvoice_set_portamento(fluid_rvoice_t * voice, unsigned int countinc, - fluid_real_t pitchoffset); -void fluid_rvoice_multi_retrigger_attack(fluid_rvoice_t* voice); -void fluid_rvoice_noteoff(fluid_rvoice_t* voice, unsigned int min_ticks); -void fluid_rvoice_voiceoff(fluid_rvoice_t* voice); -void fluid_rvoice_reset(fluid_rvoice_t* voice); -void fluid_rvoice_set_output_rate(fluid_rvoice_t* voice, fluid_real_t output_rate); -void fluid_rvoice_set_interp_method(fluid_rvoice_t* voice, int interp_method); -void fluid_rvoice_set_root_pitch_hz(fluid_rvoice_t* voice, fluid_real_t root_pitch_hz); -void fluid_rvoice_set_pitch(fluid_rvoice_t* voice, fluid_real_t value); -void fluid_rvoice_set_synth_gain(fluid_rvoice_t* voice, fluid_real_t value); -void fluid_rvoice_set_attenuation(fluid_rvoice_t* voice, fluid_real_t value); -void fluid_rvoice_set_min_attenuation_cB(fluid_rvoice_t* voice, fluid_real_t value); -void fluid_rvoice_set_viblfo_to_pitch(fluid_rvoice_t* voice, fluid_real_t value); -void fluid_rvoice_set_modlfo_to_pitch(fluid_rvoice_t* voice, fluid_real_t value); -void fluid_rvoice_set_modlfo_to_vol(fluid_rvoice_t* voice, fluid_real_t value); -void fluid_rvoice_set_modlfo_to_fc(fluid_rvoice_t* voice, fluid_real_t value); -void fluid_rvoice_set_modenv_to_fc(fluid_rvoice_t* voice, fluid_real_t value); -void fluid_rvoice_set_modenv_to_pitch(fluid_rvoice_t* voice, fluid_real_t value); -void fluid_rvoice_set_start(fluid_rvoice_t* voice, int value); -void fluid_rvoice_set_end(fluid_rvoice_t* voice, int value); -void fluid_rvoice_set_loopstart(fluid_rvoice_t* voice, int value); -void fluid_rvoice_set_loopend(fluid_rvoice_t* voice, int value); -void fluid_rvoice_set_sample(fluid_rvoice_t* voice, fluid_sample_t* value); -void fluid_rvoice_set_samplemode(fluid_rvoice_t* voice, enum fluid_loop value); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_buffers_set_amp); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_buffers_set_mapping); + +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_noteoff); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_voiceoff); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_reset); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_multi_retrigger_attack); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_portamento); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_output_rate); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_interp_method); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_root_pitch_hz); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_pitch); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_attenuation); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_min_attenuation_cB); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_viblfo_to_pitch); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_pitch); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_vol); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_fc); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modenv_to_fc); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modenv_to_pitch); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_synth_gain); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_start); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_end); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_loopstart); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_loopend); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_samplemode); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_sample); /* defined in fluid_rvoice_dsp.c */ - void fluid_rvoice_dsp_config (void); int fluid_rvoice_dsp_interpolate_none (fluid_rvoice_dsp_t *voice); int fluid_rvoice_dsp_interpolate_linear (fluid_rvoice_dsp_t *voice); diff --git a/src/rvoice/fluid_rvoice_event.c b/src/rvoice/fluid_rvoice_event.c index e4b9da31..6723574c 100644 --- a/src/rvoice/fluid_rvoice_event.c +++ b/src/rvoice/fluid_rvoice_event.c @@ -24,136 +24,13 @@ #include "fluid_iir_filter.h" #include "fluid_lfo.h" #include "fluid_adsr_env.h" -/* Calling proc without data parameters */ -#define EVENTFUNC_0(proc, type) \ - if (event->method == proc) { \ - proc((type) event->object); \ - return; } - -/* Calling proc passing only one real data parameter */ -#define EVENTFUNC_R1(proc, type) \ - if (event->method == proc) { \ - if(event->intparam != 0) { FLUID_LOG(FLUID_DBG, "IR-mismatch"); } \ - proc((type) event->object, event->realparams[0]); \ - return; } - -/* Calling proc passing pointer parameter */ -#define EVENTFUNC_PTR(proc, type, type2) \ - if (event->method == proc) { \ - proc((type) event->object, (type2) event->ptr); \ - return; } - -/* Calling proc passing only int parameter */ -#define EVENTFUNC_I1(proc, type) \ - if (event->method == proc) { \ - if(event->realparams[0] != 0.0f) { FLUID_LOG(FLUID_DBG, "IR-mismatch"); } \ - proc((type) event->object, event->intparam); \ - return; } - -/* Calling proc passing: int,int data parameters */ -#define EVENTFUNC_II(proc, type) \ - if (event->method == proc) { \ - proc((type) event->object, event->intparam, (int) event->realparams[0]); \ - return; } - -/* Calling proc passing: int,real data parameters */ -#define EVENTFUNC_IR(proc, type) \ - if (event->method == proc) { \ - proc((type) event->object, event->intparam, event->realparams[0]); \ - return; } - -/* Calling proc passing: int,real,real,real,real,real data parameters */ -#define EVENTFUNC_ALL(proc, type) \ - if (event->method == proc) { \ - proc((type) event->object, event->intparam, event->realparams[0], \ - event->realparams[1], event->realparams[2], event->realparams[3], \ - event->realparams[4]); \ - return; } - -/* Calling proc passing: int,int,real,real,real,int data parameters */ -#define EVENTFUNC_IIR3I(proc, type) \ - if (event->method == proc) { \ - proc((type) event->object, event->intparam, (int)event->realparams[0], \ - event->realparams[1], event->realparams[2], event->realparams[3], \ - (int)event->realparams[4]); \ - return; } - -/* Calling proc passing: int,int,real,real,real,real data parameters */ -#define EVENTFUNC_IIR4(proc, type) \ - if (event->method == proc) { \ - proc((type) event->object, event->intparam, (int)event->realparams[0], \ - event->realparams[1], event->realparams[2], event->realparams[3], \ - event->realparams[4]); \ - return; } - -/* Calling proc passing: int,real,real,real,real data parameters */ -#define EVENTFUNC_R4(proc, type) \ - if (event->method == proc) { \ - proc((type) event->object, event->intparam, event->realparams[0], \ - event->realparams[1], event->realparams[2], event->realparams[3]); \ - return; } - static int fluid_rvoice_eventhandler_push_LOCAL(fluid_rvoice_eventhandler_t* handler, const fluid_rvoice_event_t* src_event); -void +static FLUID_INLINE void fluid_rvoice_event_dispatch(fluid_rvoice_event_t* event) { - EVENTFUNC_PTR(fluid_rvoice_mixer_add_voice, fluid_rvoice_mixer_t*, fluid_rvoice_t*); - EVENTFUNC_I1(fluid_rvoice_noteoff, fluid_rvoice_t*); - EVENTFUNC_0(fluid_rvoice_voiceoff, fluid_rvoice_t*); - EVENTFUNC_0(fluid_rvoice_reset, fluid_rvoice_t*); - - EVENTFUNC_0(fluid_rvoice_multi_retrigger_attack, fluid_rvoice_t*); - EVENTFUNC_IR(fluid_rvoice_set_portamento, fluid_rvoice_t*); - - EVENTFUNC_IIR4(fluid_adsr_env_set_data, fluid_adsr_env_t*); - - EVENTFUNC_I1(fluid_lfo_set_delay, fluid_lfo_t*); - EVENTFUNC_R1(fluid_lfo_set_incr, fluid_lfo_t*); - - EVENTFUNC_II(fluid_iir_filter_init, fluid_iir_filter_t*); - EVENTFUNC_R1(fluid_iir_filter_set_fres, fluid_iir_filter_t*); - EVENTFUNC_R1(fluid_iir_filter_set_q, fluid_iir_filter_t*); - - EVENTFUNC_II(fluid_rvoice_buffers_set_mapping, fluid_rvoice_buffers_t*); - EVENTFUNC_IR(fluid_rvoice_buffers_set_amp, fluid_rvoice_buffers_t*); - - EVENTFUNC_R1(fluid_rvoice_set_modenv_to_pitch, fluid_rvoice_t*); - EVENTFUNC_R1(fluid_rvoice_set_output_rate, fluid_rvoice_t*); - EVENTFUNC_R1(fluid_rvoice_set_root_pitch_hz, fluid_rvoice_t*); - EVENTFUNC_R1(fluid_rvoice_set_synth_gain, fluid_rvoice_t*); - EVENTFUNC_R1(fluid_rvoice_set_pitch, fluid_rvoice_t*); - EVENTFUNC_R1(fluid_rvoice_set_attenuation, fluid_rvoice_t*); - EVENTFUNC_R1(fluid_rvoice_set_min_attenuation_cB, fluid_rvoice_t*); - EVENTFUNC_R1(fluid_rvoice_set_viblfo_to_pitch, fluid_rvoice_t*); - EVENTFUNC_R1(fluid_rvoice_set_modlfo_to_pitch, fluid_rvoice_t*); - EVENTFUNC_R1(fluid_rvoice_set_modlfo_to_vol, fluid_rvoice_t*); - EVENTFUNC_R1(fluid_rvoice_set_modlfo_to_fc, fluid_rvoice_t*); - EVENTFUNC_R1(fluid_rvoice_set_modenv_to_fc, fluid_rvoice_t*); - EVENTFUNC_R1(fluid_rvoice_set_modenv_to_pitch, fluid_rvoice_t*); - EVENTFUNC_I1(fluid_rvoice_set_interp_method, fluid_rvoice_t*); - EVENTFUNC_I1(fluid_rvoice_set_start, fluid_rvoice_t*); - EVENTFUNC_I1(fluid_rvoice_set_end, fluid_rvoice_t*); - EVENTFUNC_I1(fluid_rvoice_set_loopstart, fluid_rvoice_t*); - EVENTFUNC_I1(fluid_rvoice_set_loopend, fluid_rvoice_t*); - EVENTFUNC_I1(fluid_rvoice_set_samplemode, fluid_rvoice_t*); - EVENTFUNC_PTR(fluid_rvoice_set_sample, fluid_rvoice_t*, fluid_sample_t*); - - EVENTFUNC_R1(fluid_rvoice_mixer_set_samplerate, fluid_rvoice_mixer_t*); - EVENTFUNC_I1(fluid_rvoice_mixer_set_polyphony, fluid_rvoice_mixer_t*); - EVENTFUNC_I1(fluid_rvoice_mixer_set_reverb_enabled, fluid_rvoice_mixer_t*); - EVENTFUNC_I1(fluid_rvoice_mixer_set_chorus_enabled, fluid_rvoice_mixer_t*); - EVENTFUNC_I1(fluid_rvoice_mixer_set_mix_fx, fluid_rvoice_mixer_t*); - EVENTFUNC_0(fluid_rvoice_mixer_reset_fx, fluid_rvoice_mixer_t*); - EVENTFUNC_0(fluid_rvoice_mixer_reset_reverb, fluid_rvoice_mixer_t*); - EVENTFUNC_0(fluid_rvoice_mixer_reset_chorus, fluid_rvoice_mixer_t*); - EVENTFUNC_II(fluid_rvoice_mixer_set_threads, fluid_rvoice_mixer_t*); - - EVENTFUNC_IIR3I(fluid_rvoice_mixer_set_chorus_params, fluid_rvoice_mixer_t*); - EVENTFUNC_R4(fluid_rvoice_mixer_set_reverb_params, fluid_rvoice_mixer_t*); - - FLUID_LOG(FLUID_ERR, "fluid_rvoice_event_dispatch: Unknown method %p to dispatch!", event->method); + event->method(event->object, event->param); } @@ -162,56 +39,45 @@ fluid_rvoice_event_dispatch(fluid_rvoice_event_t* event) * use push for all events, then use flush to commit them to the * queue. If threadsafe is false, all events are processed immediately. */ int -fluid_rvoice_eventhandler_push(fluid_rvoice_eventhandler_t* handler, - void* method, void* object, int intparam, +fluid_rvoice_eventhandler_push_int_real(fluid_rvoice_eventhandler_t* handler, + fluid_rvoice_function_t method, void* object, int intparam, fluid_real_t realparam) { fluid_rvoice_event_t local_event; local_event.method = method; local_event.object = object; - local_event.intparam = intparam; - local_event.realparams[0] = realparam; + local_event.param[0].i = intparam; + local_event.param[1].real = realparam; return fluid_rvoice_eventhandler_push_LOCAL(handler, &local_event); } +int +fluid_rvoice_eventhandler_push(fluid_rvoice_eventhandler_t* handler, fluid_rvoice_function_t method, void* object, fluid_rvoice_param_t param[MAX_EVENT_PARAMS]) +{ + fluid_rvoice_event_t local_event; + + local_event.method = method; + local_event.object = object; + FLUID_MEMCPY(&local_event.param, param, sizeof(*param) * MAX_EVENT_PARAMS); + + return fluid_rvoice_eventhandler_push_LOCAL(handler, &local_event); +} int fluid_rvoice_eventhandler_push_ptr(fluid_rvoice_eventhandler_t* handler, - void* method, void* object, void* ptr) + fluid_rvoice_function_t method, void* object, void* ptr) { fluid_rvoice_event_t local_event; local_event.method = method; local_event.object = object; - local_event.ptr = ptr; + local_event.param[0].ptr = ptr; return fluid_rvoice_eventhandler_push_LOCAL(handler, &local_event); } - -int -fluid_rvoice_eventhandler_push5(fluid_rvoice_eventhandler_t* handler, - void* method, void* object, int intparam, - fluid_real_t r1, fluid_real_t r2, - fluid_real_t r3, fluid_real_t r4, fluid_real_t r5) -{ - fluid_rvoice_event_t local_event; - - local_event.method = method; - local_event.object = object; - local_event.intparam = intparam; - local_event.realparams[0] = r1; - local_event.realparams[1] = r2; - local_event.realparams[2] = r3; - local_event.realparams[3] = r4; - local_event.realparams[4] = r5; - - return fluid_rvoice_eventhandler_push_LOCAL(handler, &local_event); - -} - static int fluid_rvoice_eventhandler_push_LOCAL(fluid_rvoice_eventhandler_t* handler, const fluid_rvoice_event_t* src_event) { fluid_rvoice_event_t* event; @@ -225,7 +91,7 @@ static int fluid_rvoice_eventhandler_push_LOCAL(fluid_rvoice_eventhandler_t* han return FLUID_FAILED; // Buffer full... } - memcpy(event, src_event, sizeof(*event)); + FLUID_MEMCPY(event, src_event, sizeof(*event)); return FLUID_OK; } diff --git a/src/rvoice/fluid_rvoice_event.h b/src/rvoice/fluid_rvoice_event.h index 0c56cbc1..b72e63d5 100644 --- a/src/rvoice/fluid_rvoice_event.h +++ b/src/rvoice/fluid_rvoice_event.h @@ -26,22 +26,15 @@ #include "fluid_rvoice_mixer.h" #include "fluid_ringbuffer.h" -#define EVENT_REAL_PARAMS (5) - typedef struct _fluid_rvoice_event_t fluid_rvoice_event_t; typedef struct _fluid_rvoice_eventhandler_t fluid_rvoice_eventhandler_t; struct _fluid_rvoice_event_t { - void* method; + fluid_rvoice_function_t method; void* object; - void* ptr; - int intparam; - fluid_real_t realparams[EVENT_REAL_PARAMS]; + fluid_rvoice_param_t param[MAX_EVENT_PARAMS]; }; -void fluid_rvoice_event_dispatch(fluid_rvoice_event_t* event); - - /* * Bridge between the renderer thread and the midi state thread. * fluid_rvoice_eventhandler_fetch_all() can be called in parallell @@ -88,17 +81,16 @@ fluid_rvoice_eventhandler_get_finished_voice(fluid_rvoice_eventhandler_t* handle } -int fluid_rvoice_eventhandler_push(fluid_rvoice_eventhandler_t* handler, - void* method, void* object, int intparam, +int fluid_rvoice_eventhandler_push_int_real(fluid_rvoice_eventhandler_t* handler, + fluid_rvoice_function_t method, void* object, int intparam, fluid_real_t realparam); int fluid_rvoice_eventhandler_push_ptr(fluid_rvoice_eventhandler_t* handler, - void* method, void* object, void* ptr); + fluid_rvoice_function_t method, void* object, void* ptr); -int fluid_rvoice_eventhandler_push5(fluid_rvoice_eventhandler_t* handler, - void* method, void* object, int intparam, - fluid_real_t r1, fluid_real_t r2, - fluid_real_t r3, fluid_real_t r4, fluid_real_t r5); +int fluid_rvoice_eventhandler_push(fluid_rvoice_eventhandler_t* handler, + fluid_rvoice_function_t method, void* object, + fluid_rvoice_param_t param[MAX_EVENT_PARAMS]); static FLUID_INLINE void fluid_rvoice_eventhandler_add_rvoice(fluid_rvoice_eventhandler_t* handler, diff --git a/src/rvoice/fluid_rvoice_mixer.c b/src/rvoice/fluid_rvoice_mixer.c index 52c8e7aa..2ac07f90 100644 --- a/src/rvoice/fluid_rvoice_mixer.c +++ b/src/rvoice/fluid_rvoice_mixer.c @@ -311,14 +311,15 @@ static int fluid_mixer_buffers_replace_voice(fluid_mixer_buffers_t* buffers, } */ -int -fluid_rvoice_mixer_add_voice(fluid_rvoice_mixer_t* mixer, fluid_rvoice_t* voice) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_add_voice) { int i; + fluid_rvoice_mixer_t* mixer = obj; + fluid_rvoice_t* voice = param[0].ptr; if (mixer->active_voices < mixer->polyphony) { mixer->rvoices[mixer->active_voices++] = voice; - return FLUID_OK; + return; // success } /* See if any voices just finished, if so, take its place. @@ -326,18 +327,18 @@ fluid_rvoice_mixer_add_voice(fluid_rvoice_mixer_t* mixer, fluid_rvoice_t* voice) for (i=0; i < mixer->active_voices; i++) { if (mixer->rvoices[i] == voice) { FLUID_LOG(FLUID_ERR, "Internal error: Trying to replace an existing rvoice in fluid_rvoice_mixer_add_voice?!"); - return FLUID_FAILED; + return; } if (mixer->rvoices[i]->envlfo.volenv.section == FLUID_VOICE_ENVFINISHED) { fluid_finish_rvoice(&mixer->buffers, mixer->rvoices[i]); mixer->rvoices[i] = voice; - return FLUID_OK; + return; // success } } /* This should never happen */ FLUID_LOG(FLUID_ERR, "Trying to exceed polyphony in fluid_rvoice_mixer_add_voice"); - return FLUID_FAILED; + return; } static int @@ -359,21 +360,23 @@ fluid_mixer_buffers_update_polyphony(fluid_mixer_buffers_t* buffers, int value) * Update polyphony - max number of voices (NOTE: not hard real-time capable) * @return FLUID_OK or FLUID_FAILED */ -int -fluid_rvoice_mixer_set_polyphony(fluid_rvoice_mixer_t* handler, int value) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_polyphony) { void* newptr; + fluid_rvoice_mixer_t* handler = obj; + int value = param[0].i; + if (handler->active_voices > value) - return FLUID_FAILED; + return /*FLUID_FAILED*/; newptr = FLUID_REALLOC(handler->rvoices, value * sizeof(fluid_rvoice_t*)); if (newptr == NULL) - return FLUID_FAILED; + return /*FLUID_FAILED*/; handler->rvoices = newptr; if (fluid_mixer_buffers_update_polyphony(&handler->buffers, value) == FLUID_FAILED) - return FLUID_FAILED; + return /*FLUID_FAILED*/; #ifdef ENABLE_MIXER_THREADS { @@ -381,12 +384,12 @@ fluid_rvoice_mixer_set_polyphony(fluid_rvoice_mixer_t* handler, int value) for (i=0; i < handler->thread_count; i++) if (fluid_mixer_buffers_update_polyphony(&handler->threads[i], value) == FLUID_FAILED) - return FLUID_FAILED; + return /*FLUID_FAILED*/; } #endif handler->polyphony = value; - return FLUID_OK; + return /*FLUID_OK*/; } @@ -497,17 +500,18 @@ fluid_mixer_buffers_init(fluid_mixer_buffers_t* buffers, fluid_rvoice_mixer_t* m /** * Note: Not hard real-time capable (calls malloc) */ -void -fluid_rvoice_mixer_set_samplerate(fluid_rvoice_mixer_t* mixer, fluid_real_t samplerate) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_samplerate) { - int i; + fluid_rvoice_mixer_t* mixer = obj; + fluid_real_t samplerate = param[1].real; // becausee fluid_synth_update_mixer() puts real into arg2 + if (mixer->fx.chorus) delete_fluid_chorus(mixer->fx.chorus); + mixer->fx.chorus = new_fluid_chorus(samplerate); if (mixer->fx.reverb) fluid_revmodel_samplerate_change(mixer->fx.reverb, samplerate); - for (i=0; i < mixer->active_voices; i++) - fluid_rvoice_set_output_rate(mixer->rvoices[i], samplerate); + #if LADSPA if (mixer->ladspa_fx != NULL) { @@ -612,7 +616,6 @@ void delete_fluid_rvoice_mixer(fluid_rvoice_mixer_t* mixer) { fluid_return_if_fail(mixer != NULL); - fluid_rvoice_mixer_set_threads(mixer, 0, 0); #ifdef ENABLE_MIXER_THREADS if (mixer->thread_ready) delete_fluid_cond(mixer->thread_ready); @@ -660,13 +663,18 @@ void fluid_rvoice_mixer_set_ladspa(fluid_rvoice_mixer_t* mixer, } #endif -void fluid_rvoice_mixer_set_reverb_enabled(fluid_rvoice_mixer_t* mixer, int on) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_reverb_enabled) { + fluid_rvoice_mixer_t* mixer = obj; + int on = param[0].i; + mixer->fx.with_reverb = on; } -void fluid_rvoice_mixer_set_chorus_enabled(fluid_rvoice_mixer_t* mixer, int on) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_chorus_enabled) { + fluid_rvoice_mixer_t* mixer = obj; + int on = param[0].i; mixer->fx.with_chorus = on; } @@ -675,32 +683,40 @@ void fluid_rvoice_mixer_set_mix_fx(fluid_rvoice_mixer_t* mixer, int on) mixer->fx.mix_fx_to_out = on; } -void fluid_rvoice_mixer_set_chorus_params(fluid_rvoice_mixer_t* mixer, int set, - int nr, fluid_real_t level, fluid_real_t speed, - fluid_real_t depth_ms, int type) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_chorus_params) { + fluid_rvoice_mixer_t* mixer = obj; + int set = param[0].i; + int nr = param[1].i; + fluid_real_t level = param[2].real; + fluid_real_t speed = param[3].real; + fluid_real_t depth_ms = param[4].real; + int type = param[5].i; + fluid_chorus_set(mixer->fx.chorus, set, nr, level, speed, depth_ms, type); } -void fluid_rvoice_mixer_set_reverb_params(fluid_rvoice_mixer_t* mixer, int set, - fluid_real_t roomsize, fluid_real_t damping, - fluid_real_t width, fluid_real_t level) + +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_reverb_params) { + fluid_rvoice_mixer_t* mixer = obj; + int set = param[0].i; + fluid_real_t roomsize = param[1].real; + fluid_real_t damping = param[2].real; + fluid_real_t width = param[3].real; + fluid_real_t level = param[4].real; + fluid_revmodel_set(mixer->fx.reverb, set, roomsize, damping, width, level); } -void fluid_rvoice_mixer_reset_fx(fluid_rvoice_mixer_t* mixer) -{ - fluid_revmodel_reset(mixer->fx.reverb); - fluid_chorus_reset(mixer->fx.chorus); -} - -void fluid_rvoice_mixer_reset_reverb(fluid_rvoice_mixer_t* mixer) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_reset_reverb) { + fluid_rvoice_mixer_t* mixer = obj; fluid_revmodel_reset(mixer->fx.reverb); } -void fluid_rvoice_mixer_reset_chorus(fluid_rvoice_mixer_t* mixer) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_reset_chorus) { + fluid_rvoice_mixer_t* mixer = obj; fluid_chorus_reset(mixer->fx.chorus); } @@ -913,13 +929,14 @@ fluid_render_loop_multithread(fluid_rvoice_mixer_t* mixer) * @param thread_count Number of extra mixer threads for multi-core rendering * @param prio_level real-time prio level for the extra mixer threads */ -void -fluid_rvoice_mixer_set_threads(fluid_rvoice_mixer_t* mixer, int thread_count, - int prio_level) +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_threads) { #ifdef ENABLE_MIXER_THREADS char name[16]; int i; + fluid_rvoice_mixer_t* mixer = obj; + int thread_count = param[0].i; + int prio_level = param[1].real; // Kill all existing threads first if (mixer->thread_count) { diff --git a/src/rvoice/fluid_rvoice_mixer.h b/src/rvoice/fluid_rvoice_mixer.h index 2fa3ec26..2245d74a 100644 --- a/src/rvoice/fluid_rvoice_mixer.h +++ b/src/rvoice/fluid_rvoice_mixer.h @@ -51,26 +51,23 @@ fluid_rvoice_mixer_t* new_fluid_rvoice_mixer(int buf_count, int fx_buf_count, void delete_fluid_rvoice_mixer(fluid_rvoice_mixer_t*); -void fluid_rvoice_mixer_set_samplerate(fluid_rvoice_mixer_t* mixer, fluid_real_t samplerate); -void fluid_rvoice_mixer_set_reverb_enabled(fluid_rvoice_mixer_t* mixer, int on); -void fluid_rvoice_mixer_set_chorus_enabled(fluid_rvoice_mixer_t* mixer, int on); -void fluid_rvoice_mixer_set_mix_fx(fluid_rvoice_mixer_t* mixer, int on); -int fluid_rvoice_mixer_set_polyphony(fluid_rvoice_mixer_t* handler, int value); -int fluid_rvoice_mixer_add_voice(fluid_rvoice_mixer_t* mixer, fluid_rvoice_t* voice); -void fluid_rvoice_mixer_set_chorus_params(fluid_rvoice_mixer_t* mixer, int set, - int nr, fluid_real_t level, fluid_real_t speed, - fluid_real_t depth_ms, int type); -void fluid_rvoice_mixer_set_reverb_params(fluid_rvoice_mixer_t* mixer, int set, - fluid_real_t roomsize, fluid_real_t damping, - fluid_real_t width, fluid_real_t level); -void fluid_rvoice_mixer_reset_fx(fluid_rvoice_mixer_t* mixer); -void fluid_rvoice_mixer_reset_reverb(fluid_rvoice_mixer_t* mixer); -void fluid_rvoice_mixer_reset_chorus(fluid_rvoice_mixer_t* mixer); -void fluid_rvoice_mixer_set_threads(fluid_rvoice_mixer_t* mixer, int thread_count, - int prio_level); - -#ifdef LADSPA +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_add_voice); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_samplerate); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_polyphony); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_chorus_enabled); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_reverb_enabled); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_chorus_params); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_reverb_params); + +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_reset_reverb); +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_reset_chorus); + +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_threads); + + +void fluid_rvoice_mixer_set_mix_fx(fluid_rvoice_mixer_t* mixer, int on); +#ifdef LADSPA void fluid_rvoice_mixer_set_ladspa(fluid_rvoice_mixer_t* mixer, fluid_ladspa_fx_t *ladspa_fx, int audio_groups); #endif diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index 33f74428..44e3ecfa 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -131,6 +131,9 @@ static void fluid_synth_handle_important_channels(void *data, const char *name, static void fluid_synth_reset_basic_channel_LOCAL(fluid_synth_t* synth, int chan, int nbr_chan); static int fluid_synth_check_next_basic_channel(fluid_synth_t* synth, int basicchan, int mode, int val); static void fluid_synth_set_basic_channel_LOCAL(fluid_synth_t* synth, int basicchan, int mode, int val); +static int fluid_synth_set_reverb_full_LOCAL(fluid_synth_t* synth, int set, double roomsize, + double damping, double width, double level); + /*************************************************************** * @@ -536,16 +539,23 @@ void delete_fluid_sample_timer(fluid_synth_t* synth, fluid_sample_timer_t* timer */ static FLUID_INLINE void -fluid_synth_update_mixer(fluid_synth_t* synth, void* method, int intparam, +fluid_synth_update_mixer(fluid_synth_t* synth, fluid_rvoice_function_t method, int intparam, fluid_real_t realparam) { fluid_return_if_fail(synth != NULL && synth->eventhandler != NULL); fluid_return_if_fail(synth->eventhandler->mixer != NULL); - fluid_rvoice_eventhandler_push(synth->eventhandler, method, + fluid_rvoice_eventhandler_push_int_real(synth->eventhandler, method, synth->eventhandler->mixer, intparam, realparam); } +static FLUID_INLINE unsigned int fluid_synth_get_min_note_length_LOCAL(fluid_synth_t* synth) +{ + int i; + fluid_settings_getint(synth->settings, "synth.min-note-length", &i); + return (unsigned int) (i*synth->sample_rate/1000.0f); +} + /** * Create new FluidSynth instance. * @param settings Configuration parameters to use (used directly). @@ -760,7 +770,7 @@ new_fluid_synth(fluid_settings_t *settings) goto error_recovery; } for (i = 0; i < synth->nvoice; i++) { - synth->voice[i] = new_fluid_voice(synth->sample_rate); + synth->voice[i] = new_fluid_voice(synth->eventhandler, synth->sample_rate); if (synth->voice[i] == NULL) { goto error_recovery; } @@ -773,7 +783,9 @@ new_fluid_synth(fluid_settings_t *settings) fluid_synth_set_basic_channel_LOCAL(synth, 0, FLUID_CHANNEL_MODE_OMNION_POLY, synth->midi_channels); - fluid_synth_set_sample_rate(synth, synth->sample_rate); + synth->min_note_length_ticks = fluid_synth_get_min_note_length_LOCAL(synth); + + fluid_synth_update_mixer(synth, fluid_rvoice_mixer_set_polyphony, synth->polyphony, 0.0f); fluid_synth_set_reverb_on(synth, synth->with_reverb); @@ -783,18 +795,13 @@ new_fluid_synth(fluid_settings_t *settings) synth->curmax = 0; synth->dither_index = 0; - synth->reverb_roomsize = FLUID_REVERB_DEFAULT_ROOMSIZE; - synth->reverb_damping = FLUID_REVERB_DEFAULT_DAMP; - synth->reverb_width = FLUID_REVERB_DEFAULT_WIDTH; - synth->reverb_level = FLUID_REVERB_DEFAULT_LEVEL; - - fluid_rvoice_eventhandler_push5(synth->eventhandler, - fluid_rvoice_mixer_set_reverb_params, - synth->eventhandler->mixer, - FLUID_REVMODEL_SET_ALL, synth->reverb_roomsize, - synth->reverb_damping, synth->reverb_width, - synth->reverb_level, 0.0f); - + fluid_synth_set_reverb_full_LOCAL(synth, + FLUID_REVMODEL_SET_ALL, + FLUID_REVERB_DEFAULT_ROOMSIZE, + FLUID_REVERB_DEFAULT_DAMP, + FLUID_REVERB_DEFAULT_WIDTH, + FLUID_REVERB_DEFAULT_LEVEL); + /* Initialize multi-core variables if multiple cores enabled */ if (synth->cores > 1) { @@ -1940,7 +1947,8 @@ fluid_synth_system_reset_LOCAL(fluid_synth_t* synth) fluid_synth_set_basic_channel(synth, 0, FLUID_CHANNEL_MODE_OMNION_POLY, synth->midi_channels); - fluid_synth_update_mixer(synth, fluid_rvoice_mixer_reset_fx, 0, 0.0f); + fluid_synth_update_mixer(synth, fluid_rvoice_mixer_reset_reverb, 0, 0.0f); + fluid_synth_update_mixer(synth, fluid_rvoice_mixer_reset_chorus, 0, 0.0f); return FLUID_OK; } @@ -2583,6 +2591,7 @@ fluid_synth_handle_sample_rate(void *data, const char* name, double value) fluid_synth_set_sample_rate(synth, (float) value); } + /** * Set sample rate of the synth. * @note This function is currently experimental and should only be @@ -2600,8 +2609,7 @@ fluid_synth_set_sample_rate(fluid_synth_t* synth, float sample_rate) fluid_clip (sample_rate, 8000.0f, 96000.0f); synth->sample_rate = sample_rate; - fluid_settings_getint(synth->settings, "synth.min-note-length", &i); - synth->min_note_length_ticks = (unsigned int) (i*synth->sample_rate/1000.0f); + synth->min_note_length_ticks = fluid_synth_get_min_note_length_LOCAL(synth); for (i=0; i < synth->polyphony; i++) fluid_voice_set_output_rate(synth->voice[i], sample_rate); @@ -2715,7 +2723,7 @@ fluid_synth_update_polyphony_LOCAL(fluid_synth_t* synth, int new_polyphony) return FLUID_FAILED; synth->voice = new_voices; for (i = synth->nvoice; i < new_polyphony; i++) { - synth->voice[i] = new_fluid_voice(synth->sample_rate); + synth->voice[i] = new_fluid_voice(synth->eventhandler, synth->sample_rate); if (synth->voice[i] == NULL) return FLUID_FAILED; @@ -4141,6 +4149,7 @@ fluid_synth_set_reverb_full(fluid_synth_t* synth, int set, double roomsize, double damping, double width, double level) { int ret; + fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); /* if non of the flags is set, fail */ fluid_return_val_if_fail (set & FLUID_REVMODEL_SET_ALL, FLUID_FAILED); @@ -4148,7 +4157,17 @@ fluid_synth_set_reverb_full(fluid_synth_t* synth, int set, double roomsize, /* Synth shadow values are set here so that they will be returned if querried */ fluid_synth_api_enter(synth); + ret = fluid_synth_set_reverb_full_LOCAL(synth, set, roomsize, damping, width, level); + FLUID_API_RETURN(ret); +} +static int +fluid_synth_set_reverb_full_LOCAL(fluid_synth_t* synth, int set, double roomsize, + double damping, double width, double level) +{ + int ret; + fluid_rvoice_param_t param[MAX_EVENT_PARAMS]; + if (set & FLUID_REVMODEL_SET_ROOMSIZE) synth->reverb_roomsize = roomsize; @@ -4161,13 +4180,17 @@ fluid_synth_set_reverb_full(fluid_synth_t* synth, int set, double roomsize, if (set & FLUID_REVMODEL_SET_LEVEL) synth->reverb_level = level; + param[0].i = set; + param[1].real = roomsize; + param[2].real = damping; + param[3].real = width; + param[4].real = level; /* finally enqueue an rvoice event to the mixer to actual update reverb */ - ret = fluid_rvoice_eventhandler_push5(synth->eventhandler, - fluid_rvoice_mixer_set_reverb_params, - synth->eventhandler->mixer, set, - roomsize, damping, width, level, 0.0f); - - FLUID_API_RETURN(ret); + ret = fluid_rvoice_eventhandler_push(synth->eventhandler, + fluid_rvoice_mixer_set_reverb_params, + synth->eventhandler->mixer, + param); + return ret; } /** @@ -4333,6 +4356,8 @@ fluid_synth_set_chorus_full(fluid_synth_t* synth, int set, int nr, double level, double speed, double depth_ms, int type) { int ret; + fluid_rvoice_param_t param[MAX_EVENT_PARAMS]; + fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); /* if non of the flags is set, fail */ fluid_return_val_if_fail (set & FLUID_CHORUS_SET_ALL, FLUID_FAILED); @@ -4355,10 +4380,16 @@ fluid_synth_set_chorus_full(fluid_synth_t* synth, int set, int nr, double level, if (set & FLUID_CHORUS_SET_TYPE) synth->chorus_type = type; - ret = fluid_rvoice_eventhandler_push5(synth->eventhandler, - fluid_rvoice_mixer_set_chorus_params, - synth->eventhandler->mixer, set, - nr, level, speed, depth_ms, type); + param[0].i = set; + param[1].i = nr; + param[2].real = level; + param[3].real = speed; + param[4].real = depth_ms; + param[5].i = type; + ret = fluid_rvoice_eventhandler_push(synth->eventhandler, + fluid_rvoice_mixer_set_chorus_params, + synth->eventhandler->mixer, + param); FLUID_API_RETURN(ret); } diff --git a/src/synth/fluid_voice.c b/src/synth/fluid_voice.c index 6c09667b..c073391b 100644 --- a/src/synth/fluid_voice.c +++ b/src/synth/fluid_voice.c @@ -48,85 +48,110 @@ fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t* voice); #define UPDATE_RVOICE0(proc) \ do { \ - if (voice->can_access_rvoice) proc(voice->rvoice); \ - else fluid_rvoice_eventhandler_push(voice->channel->synth->eventhandler, \ - proc, voice->rvoice, 0, 0.0f); \ + fluid_rvoice_param_t param[MAX_EVENT_PARAMS]; \ + fluid_rvoice_eventhandler_push(voice->eventhandler, proc, voice->rvoice, param); \ } while (0) -#define UPDATE_RVOICE_PTR(proc, obj) \ - do { \ - if (voice->can_access_rvoice) proc(voice->rvoice, obj); \ - else fluid_rvoice_eventhandler_push_ptr(voice->channel->synth->eventhandler, \ - proc, voice->rvoice, obj); \ - } while (0) - - #define UPDATE_RVOICE_GENERIC_R1(proc, obj, rarg) \ do { \ - if (voice->can_access_rvoice) proc(obj, rarg); \ - else fluid_rvoice_eventhandler_push(voice->channel->synth->eventhandler, \ - proc, obj, 0, rarg); \ + fluid_rvoice_param_t param[MAX_EVENT_PARAMS]; \ + param[0].real = rarg; \ + fluid_rvoice_eventhandler_push(voice->eventhandler, proc, obj, param); \ } while (0) #define UPDATE_RVOICE_GENERIC_I1(proc, obj, iarg) \ do { \ - if (voice->can_access_rvoice) proc(obj, iarg); \ - else fluid_rvoice_eventhandler_push(voice->channel->synth->eventhandler, \ - proc, obj, iarg, 0.0f); \ + fluid_rvoice_param_t param[MAX_EVENT_PARAMS]; \ + param[0].i = iarg; \ + fluid_rvoice_eventhandler_push(voice->eventhandler, proc, obj, param); \ + } while (0) + +#define UPDATE_RVOICE_GENERIC_I2(proc, obj, iarg1, iarg2) \ + do { \ + fluid_rvoice_param_t param[MAX_EVENT_PARAMS]; \ + param[0].i = iarg1; \ + param[1].i = iarg2; \ + fluid_rvoice_eventhandler_push(voice->eventhandler, proc, obj, param); \ } while (0) #define UPDATE_RVOICE_GENERIC_IR(proc, obj, iarg, rarg) \ do { \ - if (voice->can_access_rvoice) proc(obj, iarg, rarg); \ - else fluid_rvoice_eventhandler_push(voice->channel->synth->eventhandler, \ - proc, obj, iarg, rarg); \ - } while (0) - -#define UPDATE_RVOICE_GENERIC_ALL(proc, obj, iarg, r1, r2, r3, r4, r5) \ - do { \ - if (voice->can_access_rvoice) proc(obj, iarg, r1, r2, r3, r4, r5); \ - else fluid_rvoice_eventhandler_push5(voice->channel->synth->eventhandler, \ - proc, obj, iarg, r1, r2, r3, r4, r5); \ + fluid_rvoice_param_t param[MAX_EVENT_PARAMS]; \ + param[0].i = iarg; \ + param[1].real = rarg; \ + fluid_rvoice_eventhandler_push(voice->eventhandler, proc, obj, param); \ } while (0) #define UPDATE_RVOICE_R1(proc, arg1) UPDATE_RVOICE_GENERIC_R1(proc, voice->rvoice, arg1) #define UPDATE_RVOICE_I1(proc, arg1) UPDATE_RVOICE_GENERIC_I1(proc, voice->rvoice, arg1) -#define UPDATE_RVOICE_FILTER1(proc, arg1) UPDATE_RVOICE_GENERIC_R1(proc, &voice->rvoice->resonant_filter, arg1) -#define UPDATE_RVOICE_CUSTOM_FILTER1(proc, arg1) UPDATE_RVOICE_GENERIC_R1(proc, &voice->rvoice->resonant_custom_filter, arg1) -#define UPDATE_RVOICE_CUSTOM_FILTER_I2(proc, arg1, arg2) UPDATE_RVOICE_GENERIC_IR(proc, &voice->rvoice->resonant_custom_filter, arg1, arg2) -#define UPDATE_RVOICE2(proc, iarg, rarg) UPDATE_RVOICE_GENERIC_IR(proc, voice->rvoice, iarg, rarg) -#define UPDATE_RVOICE_BUFFERS2(proc, iarg, rarg) UPDATE_RVOICE_GENERIC_IR(proc, &voice->rvoice->buffers, iarg, rarg) +#define UPDATE_RVOICE_BUFFERS_AMP(proc, iarg, rarg) UPDATE_RVOICE_GENERIC_IR(proc, &voice->rvoice->buffers, iarg, rarg) #define UPDATE_RVOICE_ENVLFO_R1(proc, envp, rarg) UPDATE_RVOICE_GENERIC_R1(proc, &voice->rvoice->envlfo.envp, rarg) #define UPDATE_RVOICE_ENVLFO_I1(proc, envp, iarg) UPDATE_RVOICE_GENERIC_I1(proc, &voice->rvoice->envlfo.envp, iarg) static FLUID_INLINE void -fluid_voice_update_volenv(fluid_voice_t* voice, - fluid_adsr_env_section_t section, +fluid_voice_update_volenv(fluid_voice_t* voice, + int enqueue, + fluid_adsr_env_section_t section, unsigned int count, fluid_real_t coeff, fluid_real_t increment, fluid_real_t min, fluid_real_t max) { - UPDATE_RVOICE_GENERIC_ALL(fluid_adsr_env_set_data, - &voice->rvoice->envlfo.volenv, section, count, - coeff, increment, min, max); + fluid_rvoice_param_t param[MAX_EVENT_PARAMS]; + + param[0].i = section; + param[1].i = count; + param[2].real = coeff; + param[3].real = increment; + param[4].real = min; + param[5].real = max; + + if(enqueue) + { + fluid_rvoice_eventhandler_push(voice->eventhandler, + fluid_adsr_env_set_data, + &voice->rvoice->envlfo.volenv, + param); + } + else + { + fluid_adsr_env_set_data(&voice->rvoice->envlfo.volenv, param); + } } static FLUID_INLINE void -fluid_voice_update_modenv(fluid_voice_t* voice, - fluid_adsr_env_section_t section, +fluid_voice_update_modenv(fluid_voice_t* voice, + int enqueue, + fluid_adsr_env_section_t section, unsigned int count, fluid_real_t coeff, fluid_real_t increment, fluid_real_t min, fluid_real_t max) { - UPDATE_RVOICE_GENERIC_ALL(fluid_adsr_env_set_data, - &voice->rvoice->envlfo.modenv, section, count, - coeff, increment, min, max); + fluid_rvoice_param_t param[MAX_EVENT_PARAMS]; + + param[0].i = section; + param[1].i = count; + param[2].real = coeff; + param[3].real = increment; + param[4].real = min; + param[5].real = max; + + if(enqueue) + { + fluid_rvoice_eventhandler_push(voice->eventhandler, + fluid_adsr_env_set_data, + &voice->rvoice->envlfo.modenv, + param); + } + else + { + fluid_adsr_env_set_data(&voice->rvoice->envlfo.modenv, param); + } } static FLUID_INLINE void fluid_voice_sample_unref(fluid_sample_t** sample) @@ -150,8 +175,10 @@ static void fluid_voice_swap_rvoice(fluid_voice_t* voice) voice->can_access_overflow_rvoice = ctemp; } -static void fluid_voice_initialize_rvoice(fluid_voice_t* voice) +static void fluid_voice_initialize_rvoice(fluid_voice_t* voice, fluid_real_t output_rate) { + fluid_rvoice_param_t param[MAX_EVENT_PARAMS]; + FLUID_MEMSET(voice->rvoice, 0, sizeof(fluid_rvoice_t)); /* The 'sustain' and 'finished' segments of the volume / modulation @@ -159,24 +186,31 @@ static void fluid_voice_initialize_rvoice(fluid_voice_t* voice) * or generator. Therefore it is enough to initialize them once * during the lifetime of the synth. */ - fluid_voice_update_volenv(voice, FLUID_VOICE_ENVSUSTAIN, + fluid_voice_update_volenv(voice, FALSE, FLUID_VOICE_ENVSUSTAIN, 0xffffffff, 1.0f, 0.0f, -1.0f, 2.0f); - fluid_voice_update_volenv(voice, FLUID_VOICE_ENVFINISHED, + fluid_voice_update_volenv(voice, FALSE, FLUID_VOICE_ENVFINISHED, 0xffffffff, 0.0f, 0.0f, -1.0f, 1.0f); - fluid_voice_update_modenv(voice, FLUID_VOICE_ENVSUSTAIN, + fluid_voice_update_modenv(voice, FALSE, FLUID_VOICE_ENVSUSTAIN, 0xffffffff, 1.0f, 0.0f, -1.0f, 2.0f); - fluid_voice_update_modenv(voice, FLUID_VOICE_ENVFINISHED, + fluid_voice_update_modenv(voice, FALSE, FLUID_VOICE_ENVFINISHED, 0xffffffff, 0.0f, 0.0f, -1.0f, 1.0f); - fluid_iir_filter_init(&voice->rvoice->resonant_filter, FLUID_IIR_LOWPASS, 0); - fluid_iir_filter_init(&voice->rvoice->resonant_custom_filter, FLUID_IIR_DISABLED, 0); + param[0].i = FLUID_IIR_LOWPASS; + param[1].i = 0; + fluid_iir_filter_init(&voice->rvoice->resonant_filter, param); + + param[0].i = FLUID_IIR_DISABLED; + fluid_iir_filter_init(&voice->rvoice->resonant_custom_filter, param); + + param[0].real = output_rate; + fluid_rvoice_set_output_rate(voice->rvoice, param); } /* * new_fluid_voice */ fluid_voice_t* -new_fluid_voice(fluid_real_t output_rate) +new_fluid_voice(fluid_rvoice_eventhandler_t* handler, fluid_real_t output_rate) { fluid_voice_t* voice; voice = FLUID_NEW(fluid_voice_t); @@ -184,12 +218,15 @@ new_fluid_voice(fluid_real_t output_rate) FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } + + voice->can_access_rvoice = TRUE; + voice->can_access_overflow_rvoice = TRUE; + voice->rvoice = FLUID_NEW(fluid_rvoice_t); voice->overflow_rvoice = FLUID_NEW(fluid_rvoice_t); if (voice->rvoice == NULL || voice->overflow_rvoice == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); - FLUID_FREE(voice->rvoice); - FLUID_FREE(voice); + delete_fluid_voice(voice); return NULL; } @@ -197,17 +234,15 @@ new_fluid_voice(fluid_real_t output_rate) voice->chan = NO_CHANNEL; voice->key = 0; voice->vel = 0; + voice->eventhandler = handler; voice->channel = NULL; voice->sample = NULL; + voice->output_rate = output_rate; /* Initialize both the rvoice and overflow_rvoice */ - voice->can_access_rvoice = TRUE; - voice->can_access_overflow_rvoice = TRUE; - fluid_voice_initialize_rvoice(voice); + fluid_voice_initialize_rvoice(voice, output_rate); fluid_voice_swap_rvoice(voice); - fluid_voice_initialize_rvoice(voice); - - fluid_voice_set_output_rate(voice, output_rate); + fluid_voice_initialize_rvoice(voice, output_rate); return voice; } @@ -276,7 +311,7 @@ fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample, unloading of the soundfont while this voice is playing, once for us and once for the rvoice. */ fluid_sample_incr_ref(sample); - UPDATE_RVOICE_PTR(fluid_rvoice_set_sample, sample); + fluid_rvoice_eventhandler_push_ptr(voice->eventhandler, fluid_rvoice_set_sample, voice->rvoice, sample); fluid_sample_incr_ref(sample); voice->sample = sample; @@ -301,11 +336,12 @@ fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample, /* Set up buffer mapping, should be done more flexible in the future. */ i = channel->synth->audio_groups; - UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_mapping, 2, i*2 + SYNTH_REVERB_CHANNEL); - UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_mapping, 3, i*2 + SYNTH_CHORUS_CHANNEL); + UPDATE_RVOICE_GENERIC_I2(fluid_rvoice_buffers_set_mapping, &voice->rvoice->buffers, 2, i*2 + SYNTH_REVERB_CHANNEL); + UPDATE_RVOICE_GENERIC_I2(fluid_rvoice_buffers_set_mapping, &voice->rvoice->buffers, 3, i*2 + SYNTH_CHORUS_CHANNEL); + i = 2 * (voice->chan % i); - UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_mapping, 0, i); - UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_mapping, 1, i+1); + UPDATE_RVOICE_GENERIC_I2(fluid_rvoice_buffers_set_mapping, &voice->rvoice->buffers, 0, i); + UPDATE_RVOICE_GENERIC_I2(fluid_rvoice_buffers_set_mapping, &voice->rvoice->buffers, 1, i+1); return FLUID_OK; } @@ -315,20 +351,15 @@ fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample, * Update sample rate. * @note If the voice is active, it will be turned off. */ -int +void fluid_voice_set_output_rate(fluid_voice_t* voice, fluid_real_t value) { if (fluid_voice_is_playing(voice)) fluid_voice_off(voice); voice->output_rate = value; - UPDATE_RVOICE_R1(fluid_rvoice_set_output_rate, value); - /* Update the other rvoice as well */ - fluid_voice_swap_rvoice(voice); - UPDATE_RVOICE_R1(fluid_rvoice_set_output_rate, value); - fluid_voice_swap_rvoice(voice); - - return FLUID_FAILED; + UPDATE_RVOICE_GENERIC_R1(fluid_rvoice_set_output_rate, voice->rvoice, value); + UPDATE_RVOICE_GENERIC_R1(fluid_rvoice_set_output_rate, voice->overflow_rvoice, value); } @@ -692,12 +723,12 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen) voice->balance = fluid_voice_gen_value(voice, GEN_CUSTOM_BALANCE); /* left amp */ - UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 0, + UPDATE_RVOICE_BUFFERS_AMP(fluid_rvoice_buffers_set_amp, 0, fluid_voice_calculate_gain_amplitude(voice, fluid_pan(voice->pan, 1) * fluid_balance(voice->balance, 1))); /* right amp */ - UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 1, + UPDATE_RVOICE_BUFFERS_AMP(fluid_rvoice_buffers_set_amp, 1, fluid_voice_calculate_gain_amplitude(voice, fluid_pan(voice->pan, 0) * fluid_balance(voice->balance, 0))); break; @@ -729,14 +760,14 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen) /* The generator unit is 'tenths of a percent'. */ voice->reverb_send = x / 1000.0f; fluid_clip(voice->reverb_send, 0.0, 1.0); - UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 2, fluid_voice_calculate_gain_amplitude(voice, voice->reverb_send)); + UPDATE_RVOICE_BUFFERS_AMP(fluid_rvoice_buffers_set_amp, 2, fluid_voice_calculate_gain_amplitude(voice, voice->reverb_send)); break; case GEN_CHORUSSEND: /* The generator unit is 'tenths of a percent'. */ voice->chorus_send = x / 1000.0f; fluid_clip(voice->chorus_send, 0.0, 1.0); - UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 3, fluid_voice_calculate_gain_amplitude(voice, voice->chorus_send)); + UPDATE_RVOICE_BUFFERS_AMP(fluid_rvoice_buffers_set_amp, 3, fluid_voice_calculate_gain_amplitude(voice, voice->chorus_send)); break; case GEN_OVERRIDEROOTKEY: @@ -772,20 +803,20 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen) * modulation. The allowed range is tested in the 'fluid_ct2hz' * function [PH,20021214] */ - UPDATE_RVOICE_FILTER1(fluid_iir_filter_set_fres, x); + UPDATE_RVOICE_GENERIC_R1(fluid_iir_filter_set_fres, &voice->rvoice->resonant_filter, x); break; case GEN_FILTERQ: - UPDATE_RVOICE_FILTER1(fluid_iir_filter_set_q, x); + UPDATE_RVOICE_GENERIC_R1(fluid_iir_filter_set_q, &voice->rvoice->resonant_filter, x); break; /* same as the two above, only for the custom filter */ case GEN_CUSTOM_FILTERFC: - UPDATE_RVOICE_CUSTOM_FILTER1(fluid_iir_filter_set_fres, x); + UPDATE_RVOICE_GENERIC_R1(fluid_iir_filter_set_fres, &voice->rvoice->resonant_custom_filter, x); break; case GEN_CUSTOM_FILTERQ: - UPDATE_RVOICE_CUSTOM_FILTER1(fluid_iir_filter_set_q, x); + UPDATE_RVOICE_GENERIC_R1(fluid_iir_filter_set_q, &voice->rvoice->resonant_custom_filter, x); break; case GEN_MODLFOTOPITCH: @@ -968,21 +999,21 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen) case GEN_VOLENVDELAY: /* SF2.01 section 8.1.3 # 33 */ fluid_clip(x, -12000.0f, 5000.0f); count = NUM_BUFFERS_DELAY(x); - fluid_voice_update_volenv(voice, FLUID_VOICE_ENVDELAY, + fluid_voice_update_volenv(voice, TRUE, FLUID_VOICE_ENVDELAY, count, 0.0f, 0.0f, -1.0f, 1.0f); break; case GEN_VOLENVATTACK: /* SF2.01 section 8.1.3 # 34 */ fluid_clip(x, -12000.0f, 8000.0f); count = 1 + NUM_BUFFERS_ATTACK(x); - fluid_voice_update_volenv(voice, FLUID_VOICE_ENVATTACK, + fluid_voice_update_volenv(voice, TRUE, FLUID_VOICE_ENVATTACK, count, 1.0f, 1.0f / count, -1.0f, 1.0f); break; case GEN_VOLENVHOLD: /* SF2.01 section 8.1.3 # 35 */ case GEN_KEYTOVOLENVHOLD: /* SF2.01 section 8.1.3 # 39 */ count = calculate_hold_decay_buffers(voice, GEN_VOLENVHOLD, GEN_KEYTOVOLENVHOLD, 0); /* 0 means: hold */ - fluid_voice_update_volenv(voice, FLUID_VOICE_ENVHOLD, + fluid_voice_update_volenv(voice, TRUE, FLUID_VOICE_ENVHOLD, count, 1.0f, 0.0f, -1.0f, 2.0f); break; @@ -992,35 +1023,35 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen) x = 1.0f - 0.001f * fluid_voice_gen_value(voice, GEN_VOLENVSUSTAIN); fluid_clip(x , 0.0f, 1.0f); count = calculate_hold_decay_buffers(voice, GEN_VOLENVDECAY, GEN_KEYTOVOLENVDECAY, 1); /* 1 for decay */ - fluid_voice_update_volenv(voice, FLUID_VOICE_ENVDECAY, + fluid_voice_update_volenv(voice, TRUE, FLUID_VOICE_ENVDECAY, count, 1.0f, count ? -1.0f / count : 0.0f, x, 2.0f); break; case GEN_VOLENVRELEASE: /* SF2.01 section 8.1.3 # 38 */ fluid_clip(x, FLUID_MIN_VOLENVRELEASE, 8000.0f); count = 1 + NUM_BUFFERS_RELEASE(x); - fluid_voice_update_volenv(voice, FLUID_VOICE_ENVRELEASE, + fluid_voice_update_volenv(voice, TRUE, FLUID_VOICE_ENVRELEASE, count, 1.0f, -1.0f / count, 0.0f, 1.0f); break; /* Modulation envelope */ case GEN_MODENVDELAY: /* SF2.01 section 8.1.3 # 25 */ fluid_clip(x, -12000.0f, 5000.0f); - fluid_voice_update_modenv(voice, FLUID_VOICE_ENVDELAY, + fluid_voice_update_modenv(voice, TRUE, FLUID_VOICE_ENVDELAY, NUM_BUFFERS_DELAY(x), 0.0f, 0.0f, -1.0f, 1.0f); break; case GEN_MODENVATTACK: /* SF2.01 section 8.1.3 # 26 */ fluid_clip(x, -12000.0f, 8000.0f); count = 1 + NUM_BUFFERS_ATTACK(x); - fluid_voice_update_modenv(voice, FLUID_VOICE_ENVATTACK, + fluid_voice_update_modenv(voice, TRUE, FLUID_VOICE_ENVATTACK, count, 1.0f, 1.0f / count, -1.0f, 1.0f); break; case GEN_MODENVHOLD: /* SF2.01 section 8.1.3 # 27 */ case GEN_KEYTOMODENVHOLD: /* SF2.01 section 8.1.3 # 31 */ count = calculate_hold_decay_buffers(voice, GEN_MODENVHOLD, GEN_KEYTOMODENVHOLD, 0); /* 1 means: hold */ - fluid_voice_update_modenv(voice, FLUID_VOICE_ENVHOLD, + fluid_voice_update_modenv(voice, TRUE, FLUID_VOICE_ENVHOLD, count, 1.0f, 0.0f, -1.0f, 2.0f); break; @@ -1030,14 +1061,14 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen) count = calculate_hold_decay_buffers(voice, GEN_MODENVDECAY, GEN_KEYTOMODENVDECAY, 1); /* 1 for decay */ x = 1.0f - 0.001f * fluid_voice_gen_value(voice, GEN_MODENVSUSTAIN); fluid_clip(x, 0.0f, 1.0f); - fluid_voice_update_modenv(voice, FLUID_VOICE_ENVDECAY, + fluid_voice_update_modenv(voice, TRUE, FLUID_VOICE_ENVDECAY, count, 1.0f, count ? -1.0f / count : 0.0f, x, 2.0f); break; case GEN_MODENVRELEASE: /* SF 2.01 section 8.1.3 # 30 */ fluid_clip(x, -12000.0f, 8000.0f); count = 1 + NUM_BUFFERS_RELEASE(x); - fluid_voice_update_modenv(voice, FLUID_VOICE_ENVRELEASE, + fluid_voice_update_modenv(voice, TRUE, FLUID_VOICE_ENVRELEASE, count, 1.0f, -1.0f / count, 0.0f, 2.0f); break; @@ -1180,8 +1211,8 @@ void fluid_voice_update_portamento (fluid_voice_t* voice, int fromkey,int tokey) (fluid_real_t)fluid_channel_portamentotime(channel)) / (fluid_real_t)FLUID_BUFSIZE +0.5); - /* Sends portamento parameters to the voice dsp */ - UPDATE_RVOICE2(fluid_rvoice_set_portamento, countinc, pitchoffset); + /* Send portamento parameters to the voice dsp */ + UPDATE_RVOICE_GENERIC_IR(fluid_rvoice_set_portamento, voice->rvoice, countinc, pitchoffset); } /*---------------------------------------------------------------*/ @@ -1663,10 +1694,10 @@ int fluid_voice_set_gain(fluid_voice_t* voice, fluid_real_t gain) chorus = fluid_voice_calculate_gain_amplitude(voice, voice->chorus_send); UPDATE_RVOICE_R1(fluid_rvoice_set_synth_gain, gain); - UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 0, left); - UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 1, right); - UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 2, reverb); - UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 3, chorus); + UPDATE_RVOICE_BUFFERS_AMP(fluid_rvoice_buffers_set_amp, 0, left); + UPDATE_RVOICE_BUFFERS_AMP(fluid_rvoice_buffers_set_amp, 1, right); + UPDATE_RVOICE_BUFFERS_AMP(fluid_rvoice_buffers_set_amp, 2, reverb); + UPDATE_RVOICE_BUFFERS_AMP(fluid_rvoice_buffers_set_amp, 3, chorus); return FLUID_OK; } @@ -1812,6 +1843,6 @@ fluid_voice_get_overflow_prio(fluid_voice_t* voice, void fluid_voice_set_custom_filter(fluid_voice_t* voice, enum fluid_iir_filter_type type, enum fluid_iir_filter_flags flags) { - UPDATE_RVOICE_CUSTOM_FILTER_I2(fluid_iir_filter_init, type, flags); + UPDATE_RVOICE_GENERIC_I2(fluid_iir_filter_init, &voice->rvoice->resonant_custom_filter, type, flags); } diff --git a/src/synth/fluid_voice.h b/src/synth/fluid_voice.h index bda95cc8..93d51973 100644 --- a/src/synth/fluid_voice.h +++ b/src/synth/fluid_voice.h @@ -29,6 +29,7 @@ #include "fluid_adsr_env.h" #include "fluid_lfo.h" #include "fluid_rvoice.h" +#include "fluid_rvoice_event.h" #include "fluid_sys.h" #define NO_CHANNEL 0xff @@ -69,6 +70,7 @@ struct _fluid_voice_t unsigned char key; /* the key of the noteon event, quick access for noteoff */ unsigned char vel; /* the velocity of the noteon event */ fluid_channel_t* channel; + fluid_rvoice_eventhandler_t* eventhandler; fluid_gen_t gen[GEN_LAST]; fluid_mod_t mod[FLUID_NUM_MOD]; int mod_count; @@ -114,7 +116,7 @@ struct _fluid_voice_t }; -fluid_voice_t* new_fluid_voice(fluid_real_t output_rate); +fluid_voice_t* new_fluid_voice(fluid_rvoice_eventhandler_t* handler, fluid_real_t output_rate); void delete_fluid_voice(fluid_voice_t* voice); void fluid_voice_start(fluid_voice_t* voice); @@ -135,7 +137,7 @@ int fluid_voice_set_param(fluid_voice_t* voice, int gen, fluid_real_t value, int /** Set the gain. */ int fluid_voice_set_gain(fluid_voice_t* voice, fluid_real_t gain); -int fluid_voice_set_output_rate(fluid_voice_t* voice, fluid_real_t value); +void fluid_voice_set_output_rate(fluid_voice_t* voice, fluid_real_t value); /** Update all the synthesis parameters, which depend on generator diff --git a/src/utils/fluidsynth_priv.h b/src/utils/fluidsynth_priv.h index 9d39cb67..544e713a 100644 --- a/src/utils/fluidsynth_priv.h +++ b/src/utils/fluidsynth_priv.h @@ -205,6 +205,23 @@ typedef struct _fluid_server_socket_t fluid_server_socket_t; typedef struct _fluid_sample_timer_t fluid_sample_timer_t; typedef struct _fluid_zone_range_t fluid_zone_range_t; +/* Declare rvoice related typedefs here instead of fluid_rvoice.h, as it's needed + * in fluid_lfo.c and fluid_adsr.c as well */ +typedef union _fluid_rvoice_param_t +{ + void* ptr; + int i; + fluid_real_t real; +} fluid_rvoice_param_t; +enum { MAX_EVENT_PARAMS = 6 }; /**< Maximum number of #fluid_rvoice_param_t to be passed to an #fluid_rvoice_function_t */ +typedef void (*fluid_rvoice_function_t)(void* obj, const fluid_rvoice_param_t param[MAX_EVENT_PARAMS]); + +/* Macro for declaring an rvoice event function (#fluid_rvoice_function_t). The functions may only access + * those params that were previously set in fluid_voice.c + */ +#define DECLARE_FLUID_RVOICE_FUNCTION(name) void name(void* obj, const fluid_rvoice_param_t param[MAX_EVENT_PARAMS]) + + /*************************************************************** * * CONSTANTS