From 7ae909929318cb48aebb0d551903269e0c5a6735 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sun, 8 Apr 2018 17:22:57 +0200 Subject: [PATCH] unify rvoice update functions calling conventions by proper typedefing --- src/rvoice/fluid_adsr_env.c | 17 ++-- src/rvoice/fluid_adsr_env.h | 9 +- src/rvoice/fluid_iir_filter.c | 18 ++-- src/rvoice/fluid_iir_filter.h | 10 +- src/rvoice/fluid_lfo.c | 16 +-- src/rvoice/fluid_lfo.h | 4 +- src/rvoice/fluid_rvoice.c | 167 +++++++++++++++++++++---------- src/rvoice/fluid_rvoice.h | 58 +++++------ src/rvoice/fluid_rvoice_event.c | 170 ++++++-------------------------- src/rvoice/fluid_rvoice_event.h | 21 ++-- src/rvoice/fluid_rvoice_mixer.c | 91 ++++++++++------- src/rvoice/fluid_rvoice_mixer.h | 35 +++---- src/synth/fluid_synth.c | 36 +++++-- src/synth/fluid_voice.c | 136 ++++++++++++++----------- src/utils/fluidsynth_priv.h | 16 +++ 15 files changed, 405 insertions(+), 399 deletions(-) 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..0a3a430e 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); } @@ -163,29 +40,40 @@ fluid_rvoice_event_dispatch(fluid_rvoice_event_t* event) * 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_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_ptr(fluid_rvoice_eventhandler_t* handler, - void* method, void* object, void* ptr) +int +fluid_rvoice_eventhandler_push_param(fluid_rvoice_eventhandler_t* handler, fluid_rvoice_function_t method, void* object, fluid_rvoice_param_t param[EVENT_PARAMS]) { fluid_rvoice_event_t local_event; local_event.method = method; local_event.object = object; - local_event.ptr = ptr; + FLUID_MEMCPY(&local_event.param, param, sizeof(*param) * EVENT_PARAMS); + + return fluid_rvoice_eventhandler_push_LOCAL(handler, &local_event); +} + +int +fluid_rvoice_eventhandler_push_ptr(fluid_rvoice_eventhandler_t* handler, + 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.param[0].ptr = ptr; return fluid_rvoice_eventhandler_push_LOCAL(handler, &local_event); } @@ -193,7 +81,7 @@ fluid_rvoice_eventhandler_push_ptr(fluid_rvoice_eventhandler_t* handler, int fluid_rvoice_eventhandler_push5(fluid_rvoice_eventhandler_t* handler, - void* method, void* object, int intparam, + fluid_rvoice_function_t 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) { @@ -201,12 +89,12 @@ fluid_rvoice_eventhandler_push5(fluid_rvoice_eventhandler_t* handler, 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; + local_event.param[0].i = intparam; + local_event.param[1].real = r1; + local_event.param[2].real = r2; + local_event.param[3].real = r3; + local_event.param[4].real = r4; + local_event.param[5].real = r5; return fluid_rvoice_eventhandler_push_LOCAL(handler, &local_event); @@ -225,7 +113,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..8d5ea9d5 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[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 @@ -89,17 +82,21 @@ 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, + 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_rvoice_function_t 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_param(fluid_rvoice_eventhandler_t* handler, + fluid_rvoice_function_t method, void* object, + fluid_rvoice_param_t param[EVENT_PARAMS]); + static FLUID_INLINE void fluid_rvoice_eventhandler_add_rvoice(fluid_rvoice_eventhandler_t* handler, fluid_rvoice_t* rvoice) diff --git a/src/rvoice/fluid_rvoice_mixer.c b/src/rvoice/fluid_rvoice_mixer.c index 52c8e7aa..bcda2d04 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,20 @@ 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; + param[0].real = param[1].real; // FIXME: this is needed for fluid_rvoice_set_output_rate() + 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); + fluid_rvoice_set_output_rate(mixer->rvoices[i], param); #if LADSPA if (mixer->ladspa_fx != NULL) { @@ -612,7 +618,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 +665,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 +685,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 +931,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 4efffc73..85dbb23c 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -536,7 +536,7 @@ 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); @@ -1940,7 +1940,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; } @@ -4159,6 +4160,8 @@ fluid_synth_set_reverb_full(fluid_synth_t* synth, int set, double roomsize, double damping, double width, double level) { int ret; + fluid_rvoice_param_t param[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_REVMODEL_SET_ALL, FLUID_FAILED); @@ -4179,11 +4182,16 @@ 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); + ret = fluid_rvoice_eventhandler_push_param(synth->eventhandler, + fluid_rvoice_mixer_set_reverb_params, + synth->eventhandler->mixer, + param); FLUID_API_RETURN(ret); } @@ -4351,6 +4359,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[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); @@ -4373,10 +4383,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_param(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..c3542f43 100644 --- a/src/synth/fluid_voice.c +++ b/src/synth/fluid_voice.c @@ -48,56 +48,45 @@ 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[EVENT_PARAMS]; \ + fluid_rvoice_eventhandler_push_param(voice->channel->synth->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[EVENT_PARAMS]; \ + param[0].real = rarg; \ + fluid_rvoice_eventhandler_push_param(voice->channel->synth->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[EVENT_PARAMS]; \ + param[0].i = iarg; \ + fluid_rvoice_eventhandler_push_param(voice->channel->synth->eventhandler, proc, obj, param); \ + } while (0) + +#define UPDATE_RVOICE_GENERIC_I2(proc, obj, iarg1, iarg2) \ + do { \ + fluid_rvoice_param_t param[EVENT_PARAMS]; \ + param[0].i = iarg1; \ + param[1].i = iarg2; \ + fluid_rvoice_eventhandler_push_param(voice->channel->synth->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[EVENT_PARAMS]; \ + param[0].i = iarg; \ + param[1].real = rarg; \ + fluid_rvoice_eventhandler_push_param(voice->channel->synth->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) @@ -110,9 +99,19 @@ fluid_voice_update_volenv(fluid_voice_t* voice, 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[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; + + fluid_rvoice_eventhandler_push_param(voice->channel->synth->eventhandler, + fluid_adsr_env_set_data, + &voice->rvoice->envlfo.volenv, + param); } static FLUID_INLINE void @@ -124,9 +123,19 @@ fluid_voice_update_modenv(fluid_voice_t* voice, 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[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; + + fluid_rvoice_eventhandler_push_param(voice->channel->synth->eventhandler, + fluid_adsr_env_set_data, + &voice->rvoice->envlfo.modenv, + param); } static FLUID_INLINE void fluid_voice_sample_unref(fluid_sample_t** sample) @@ -152,6 +161,8 @@ static void fluid_voice_swap_rvoice(fluid_voice_t* voice) static void fluid_voice_initialize_rvoice(fluid_voice_t* voice) { + fluid_rvoice_param_t param[EVENT_PARAMS]; + FLUID_MEMSET(voice->rvoice, 0, sizeof(fluid_rvoice_t)); /* The 'sustain' and 'finished' segments of the volume / modulation @@ -168,8 +179,12 @@ static void fluid_voice_initialize_rvoice(fluid_voice_t* voice) fluid_voice_update_modenv(voice, 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); } /* @@ -276,7 +291,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->channel->synth->eventhandler, fluid_rvoice_set_sample, voice->rvoice, sample); fluid_sample_incr_ref(sample); voice->sample = sample; @@ -301,11 +316,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; } @@ -692,12 +708,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 +745,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 +788,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: @@ -1180,8 +1196,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 +1679,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 +1828,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/utils/fluidsynth_priv.h b/src/utils/fluidsynth_priv.h index 9d39cb67..810a44f3 100644 --- a/src/utils/fluidsynth_priv.h +++ b/src/utils/fluidsynth_priv.h @@ -205,6 +205,22 @@ 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; +typedef union _fluid_rvoice_param_t +{ + void* ptr; + int i; + fluid_real_t real; +} fluid_rvoice_param_t; +typedef void (*fluid_rvoice_function_t)(void* obj, fluid_rvoice_param_t* param); + +enum { EVENT_PARAMS = 6 }; + +/* 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, fluid_rvoice_param_t param[EVENT_PARAMS]) + + /*************************************************************** * * CONSTANTS