unify rvoice update functions calling conventions

by proper typedefing
This commit is contained in:
derselbst 2018-04-08 17:22:57 +02:00
parent 189433a757
commit 7ae9099293
15 changed files with 405 additions and 399 deletions

View file

@ -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;

View file

@ -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)

View file

@ -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)

View file

@ -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);

View file

@ -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;
}

View file

@ -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)

View file

@ -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);
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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)

View file

@ -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) {

View file

@ -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

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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