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