mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 23:11:41 +00:00
Refactor lfos into separate file
This commit is contained in:
parent
933555f2ce
commit
41717700a5
4 changed files with 105 additions and 62 deletions
|
@ -129,6 +129,7 @@ libfluidsynth_la_SOURCES = \
|
|||
fluid_iir_filter.c \
|
||||
fluid_iir_filter.h \
|
||||
fluid_adsr_env.h \
|
||||
fluid_lfo.h \
|
||||
fluid_filerenderer.c \
|
||||
fluid_aufile.c
|
||||
|
||||
|
|
80
fluidsynth/src/fluid_lfo.h
Normal file
80
fluidsynth/src/fluid_lfo.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUID_LFO_H
|
||||
#define _FLUID_LFO_H
|
||||
|
||||
#include "fluidsynth_priv.h"
|
||||
|
||||
typedef struct _fluid_lfo_t fluid_lfo_t;
|
||||
|
||||
struct _fluid_lfo_t {
|
||||
fluid_real_t val; /* the current value of the LFO */
|
||||
unsigned int delay; /* the delay of the lfo in samples */
|
||||
fluid_real_t incr; /* the lfo frequency is converted to a per-buffer increment */
|
||||
};
|
||||
|
||||
static inline void
|
||||
fluid_lfo_reset(fluid_lfo_t* lfo)
|
||||
{
|
||||
lfo->val = 0.0f;
|
||||
}
|
||||
|
||||
static inline void
|
||||
fluid_lfo_set_incr(fluid_lfo_t* lfo, fluid_real_t incr)
|
||||
{
|
||||
lfo->incr = incr;
|
||||
}
|
||||
|
||||
static inline void
|
||||
fluid_lfo_set_delay(fluid_lfo_t* lfo, unsigned int delay)
|
||||
{
|
||||
lfo->delay = delay;
|
||||
}
|
||||
|
||||
static inline fluid_real_t
|
||||
fluid_lfo_get_val(fluid_lfo_t* lfo)
|
||||
{
|
||||
return lfo->val;
|
||||
}
|
||||
|
||||
static inline void
|
||||
fluid_lfo_calc(fluid_lfo_t* lfo, unsigned int cur_delay)
|
||||
{
|
||||
if (cur_delay < lfo->delay)
|
||||
return;
|
||||
|
||||
lfo->val += lfo->incr;
|
||||
|
||||
if (lfo->val > (fluid_real_t) 1.0)
|
||||
{
|
||||
lfo->incr = -lfo->incr;
|
||||
lfo->val = (fluid_real_t) 2.0 - lfo->val;
|
||||
}
|
||||
else if (lfo->val < (fluid_real_t) -1.0)
|
||||
{
|
||||
lfo->incr = -lfo->incr;
|
||||
lfo->val = (fluid_real_t) -2.0 - lfo->val;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -140,14 +140,14 @@ fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample,
|
|||
/* mod env initialization*/
|
||||
fluid_adsr_env_reset(&voice->modenv);
|
||||
|
||||
/* mod lfo */
|
||||
voice->modlfo_val = 0.0;/* Fixme: Retrieve from any other existing
|
||||
voice on this channel to keep LFOs in
|
||||
unison? */
|
||||
|
||||
/* vib lfo */
|
||||
voice->viblfo_val = 0.0f; /* Fixme: See mod lfo */
|
||||
/* lfo init */
|
||||
/* Fixme: Retrieve from any other existing
|
||||
voice on this channel to keep LFOs in
|
||||
unison? */
|
||||
|
||||
fluid_lfo_reset(&voice->modlfo);
|
||||
fluid_lfo_reset(&voice->viblfo);
|
||||
|
||||
/* Clear sample history in filter */
|
||||
fluid_iir_filter_reset(&voice->resonant_filter);
|
||||
|
||||
|
@ -289,45 +289,12 @@ fluid_voice_write (fluid_voice_t* voice, fluid_real_t *dsp_buf)
|
|||
fluid_adsr_env_calc(&voice->modenv, 0);
|
||||
fluid_check_fpe ("voice_write mod env");
|
||||
|
||||
/******************* mod lfo **********************/
|
||||
/******************* lfo **********************/
|
||||
|
||||
if (voice->ticks >= voice->modlfo_delay)
|
||||
{
|
||||
voice->modlfo_val += voice->modlfo_incr;
|
||||
|
||||
if (voice->modlfo_val > 1.0)
|
||||
{
|
||||
voice->modlfo_incr = -voice->modlfo_incr;
|
||||
voice->modlfo_val = (fluid_real_t) 2.0 - voice->modlfo_val;
|
||||
}
|
||||
else if (voice->modlfo_val < -1.0)
|
||||
{
|
||||
voice->modlfo_incr = -voice->modlfo_incr;
|
||||
voice->modlfo_val = (fluid_real_t) -2.0 - voice->modlfo_val;
|
||||
}
|
||||
}
|
||||
|
||||
fluid_lfo_calc(&voice->modlfo, voice->ticks);
|
||||
fluid_check_fpe ("voice_write mod LFO");
|
||||
|
||||
/******************* vib lfo **********************/
|
||||
|
||||
if (voice->ticks >= voice->viblfo_delay)
|
||||
{
|
||||
voice->viblfo_val += voice->viblfo_incr;
|
||||
|
||||
if (voice->viblfo_val > (fluid_real_t) 1.0)
|
||||
{
|
||||
voice->viblfo_incr = -voice->viblfo_incr;
|
||||
voice->viblfo_val = (fluid_real_t) 2.0 - voice->viblfo_val;
|
||||
}
|
||||
else if (voice->viblfo_val < -1.0)
|
||||
{
|
||||
voice->viblfo_incr = -voice->viblfo_incr;
|
||||
voice->viblfo_val = (fluid_real_t) -2.0 - voice->viblfo_val;
|
||||
}
|
||||
}
|
||||
|
||||
fluid_check_fpe ("voice_write Vib LFO");
|
||||
fluid_lfo_calc(&voice->viblfo, voice->ticks);
|
||||
fluid_check_fpe ("voice_write vib LFO");
|
||||
|
||||
/******************* amplitude **********************/
|
||||
|
||||
|
@ -345,7 +312,7 @@ fluid_voice_write (fluid_voice_t* voice, fluid_real_t *dsp_buf)
|
|||
* A positive modlfo_to_vol should increase volume (negative attenuation).
|
||||
*/
|
||||
target_amp = fluid_atten2amp (voice->attenuation)
|
||||
* fluid_cb2amp (voice->modlfo_val * -voice->modlfo_to_vol)
|
||||
* fluid_cb2amp (fluid_lfo_get_val(&voice->modlfo) * -voice->modlfo_to_vol)
|
||||
* fluid_adsr_env_get_val(&voice->volenv);
|
||||
}
|
||||
else
|
||||
|
@ -355,7 +322,7 @@ fluid_voice_write (fluid_voice_t* voice, fluid_real_t *dsp_buf)
|
|||
|
||||
target_amp = fluid_atten2amp (voice->attenuation)
|
||||
* fluid_cb2amp (960.0f * (1.0f - fluid_adsr_env_get_val(&voice->volenv))
|
||||
+ voice->modlfo_val * -voice->modlfo_to_vol);
|
||||
+ fluid_lfo_get_val(&voice->modlfo) * -voice->modlfo_to_vol);
|
||||
|
||||
/* We turn off a voice, if the volume has dropped low enough. */
|
||||
|
||||
|
@ -408,8 +375,8 @@ fluid_voice_write (fluid_voice_t* voice, fluid_real_t *dsp_buf)
|
|||
* buffer. It is the ratio between the frequencies of original
|
||||
* waveform and output waveform.*/
|
||||
voice->phase_incr = fluid_ct2hz_real
|
||||
(voice->pitch + voice->modlfo_val * voice->modlfo_to_pitch
|
||||
+ voice->viblfo_val * voice->viblfo_to_pitch
|
||||
(voice->pitch + fluid_lfo_get_val(&voice->modlfo) * voice->modlfo_to_pitch
|
||||
+ fluid_lfo_get_val(&voice->viblfo) * voice->viblfo_to_pitch
|
||||
+ fluid_adsr_env_get_val(&voice->modenv) * voice->modenv_to_pitch) / voice->root_pitch_hz;
|
||||
|
||||
fluid_check_fpe ("voice_write phase calculation");
|
||||
|
@ -419,7 +386,7 @@ fluid_voice_write (fluid_voice_t* voice, fluid_real_t *dsp_buf)
|
|||
|
||||
/*************** resonant filter ******************/
|
||||
fluid_iir_filter_calc(&voice->resonant_filter, voice->output_rate,
|
||||
voice->modlfo_val * voice->modlfo_to_fc +
|
||||
fluid_lfo_get_val(&voice->modlfo) * voice->modlfo_to_fc +
|
||||
fluid_adsr_env_get_val(&voice->modenv) * voice->modenv_to_fc);
|
||||
|
||||
/*********************** run the dsp chain ************************
|
||||
|
@ -920,7 +887,7 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
case GEN_MODLFODELAY:
|
||||
x = _GEN(voice, GEN_MODLFODELAY);
|
||||
fluid_clip(x, -12000.0f, 5000.0f);
|
||||
voice->modlfo_delay = (unsigned int) (voice->output_rate * fluid_tc2sec_delay(x));
|
||||
fluid_lfo_set_delay(&voice->modlfo, (unsigned int) (voice->output_rate * fluid_tc2sec_delay(x)));
|
||||
break;
|
||||
|
||||
case GEN_MODLFOFREQ:
|
||||
|
@ -929,7 +896,7 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
*/
|
||||
x = _GEN(voice, GEN_MODLFOFREQ);
|
||||
fluid_clip(x, -16000.0f, 4500.0f);
|
||||
voice->modlfo_incr = (4.0f * FLUID_BUFSIZE * fluid_act2hz(x) / voice->output_rate);
|
||||
fluid_lfo_set_incr(&voice->modlfo, (4.0f * FLUID_BUFSIZE * fluid_act2hz(x) / voice->output_rate));
|
||||
break;
|
||||
|
||||
case GEN_VIBLFOFREQ:
|
||||
|
@ -940,13 +907,13 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
*/
|
||||
x = _GEN(voice, GEN_VIBLFOFREQ);
|
||||
fluid_clip(x, -16000.0f, 4500.0f);
|
||||
voice->viblfo_incr = (4.0f * FLUID_BUFSIZE * fluid_act2hz(x) / voice->output_rate);
|
||||
fluid_lfo_set_incr(&voice->viblfo, (4.0f * FLUID_BUFSIZE * fluid_act2hz(x) / voice->output_rate));
|
||||
break;
|
||||
|
||||
case GEN_VIBLFODELAY:
|
||||
x = _GEN(voice,GEN_VIBLFODELAY);
|
||||
fluid_clip(x, -12000.0f, 5000.0f);
|
||||
voice->viblfo_delay = (unsigned int) (voice->output_rate * fluid_tc2sec_delay(x));
|
||||
fluid_lfo_set_delay(&voice->viblfo, (unsigned int) (voice->output_rate * fluid_tc2sec_delay(x)));
|
||||
break;
|
||||
|
||||
case GEN_VIBLFOTOPITCH:
|
||||
|
@ -1283,7 +1250,7 @@ fluid_voice_noteoff(fluid_voice_t* voice)
|
|||
* for seamless volume transition.
|
||||
*/
|
||||
if (fluid_adsr_env_get_val(&voice->volenv) > 0){
|
||||
fluid_real_t lfo = voice->modlfo_val * -voice->modlfo_to_vol;
|
||||
fluid_real_t lfo = fluid_lfo_get_val(&voice->modlfo) * -voice->modlfo_to_vol;
|
||||
fluid_real_t amp = fluid_adsr_env_get_val(&voice->volenv) * pow (10.0, lfo / -200);
|
||||
fluid_real_t env_value = - ((-200 * log (amp) / log (10.0) - lfo) / 960.0 - 1);
|
||||
fluid_clip (env_value, 0.0, 1.0);
|
||||
|
@ -1767,5 +1734,3 @@ fluid_voice_optimize_sample(fluid_sample_t* s)
|
|||
return FLUID_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "fluid_mod.h"
|
||||
#include "fluid_iir_filter.h"
|
||||
#include "fluid_adsr_env.h"
|
||||
#include "fluid_lfo.h"
|
||||
|
||||
#define NO_CHANNEL 0xff
|
||||
|
||||
|
@ -128,17 +129,13 @@ struct _fluid_voice_t
|
|||
fluid_real_t modenv_to_pitch;
|
||||
|
||||
/* mod lfo */
|
||||
fluid_real_t modlfo_val; /* the value of the modulation LFO */
|
||||
unsigned int modlfo_delay; /* the delay of the lfo in samples */
|
||||
fluid_real_t modlfo_incr; /* the lfo frequency is converted to a per-buffer increment */
|
||||
fluid_lfo_t modlfo;
|
||||
fluid_real_t modlfo_to_fc;
|
||||
fluid_real_t modlfo_to_pitch;
|
||||
fluid_real_t modlfo_to_vol;
|
||||
|
||||
/* vib lfo */
|
||||
fluid_real_t viblfo_val; /* the value of the vibrato LFO */
|
||||
unsigned int viblfo_delay; /* the delay of the lfo in samples */
|
||||
fluid_real_t viblfo_incr; /* the lfo frequency is converted to a per-buffer increment */
|
||||
fluid_lfo_t viblfo;
|
||||
fluid_real_t viblfo_to_pitch;
|
||||
|
||||
fluid_iir_filter_t resonant_filter; /* IIR resonance dsp filter */
|
||||
|
|
Loading…
Reference in a new issue