From a2f4261b7a8530b6ab532afe90cd7e9d5af0c6b8 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 13 Jan 2010 17:05:00 +0000 Subject: [PATCH] Split filter off to separate file Put voice initialization in one place --- CMakeLists.txt | 2 ++ engine.c | 7 ++++--- filter.c | 33 +++++++++++++++++++++++++++++++++ filter.h | 16 ++++++++++++++++ psyn.c | 1 + rng.h | 10 ++++++++++ voice.c | 39 +++++++++++++++++++++++---------------- voice.h | 5 +++-- 8 files changed, 92 insertions(+), 21 deletions(-) create mode 100644 filter.c create mode 100644 filter.h create mode 100644 rng.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 84d3f13..99b7e0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,8 @@ SET(SOURCES engine.h env.c env.h + filter.c + filter.h osc.c osc.h psyn.c diff --git a/engine.c b/engine.c index 4c4de16..a3c0a12 100644 --- a/engine.c +++ b/engine.c @@ -4,6 +4,7 @@ #include #include "env.h" #include "osc.h" +#include "filter.h" #include "voice.h" #include "engine.h" #include "psyn.h" @@ -54,15 +55,15 @@ void engine_startvoice(struct engine_t *engine, uint8_t note, uint8_t velocity) for (i = 0; i < NUM_POLYPHONY; i++, v++) { if (v->playing) continue; + /* Constant voice parameters */ v->playing = true; v->sample = 0; v->released = 0; v->note = note; v->velocity = velocity / 127.0; - osc_setfreq(&v->osc[0], _freqs[note]); - osc_setfreq(&v->osc[1], _freqs[note] * 2); - osc_setfreq(&v->osc[2], _freqs[note] * 5); + /* Voice parameters which determine sound */ + voice_init(v, _freqs[note]); return; } diff --git a/filter.c b/filter.c new file mode 100644 index 0000000..bc655da --- /dev/null +++ b/filter.c @@ -0,0 +1,33 @@ +#include +#include "filter.h" +#include "psyn.h" + +void filter_init_rc(struct filter_t *filter, double R, double C) +{ + filter->k = 1.0 / (R * C) / _sample_rate; + filter->r = 1.0; +} + +void filter_init_freq(struct filter_t *filter, double freq) +{ + filter->k = (2.0 * M_PI * freq) / _sample_rate; + filter->r = 1.0; +} + +void filter_run_lp(struct filter_t *filter, double left, double right) +{ + filter->v_l += filter->k * (left - filter->last_out_l); + filter->v_r += filter->k * (right - filter->last_out_r); + filter->last_out_l = filter->v_l; + filter->last_out_r = filter->v_r; + filter->v_l *= filter->r; + filter->v_r *= filter->r; +} + +void filter_run_hp(struct filter_t *filter, double left, double right) +{ + filter->last_out_l = filter->k * (filter->last_out_l + left - filter->last_in_l); + filter->last_out_r = filter->k * (filter->last_out_r + right - filter->last_in_r); + filter->last_in_l = left; + filter->last_in_r = right; +} diff --git a/filter.h b/filter.h new file mode 100644 index 0000000..34d2976 --- /dev/null +++ b/filter.h @@ -0,0 +1,16 @@ + +struct filter_t { + double k; + double r; + double v_l; + double v_r; + double last_in_l; + double last_in_r; + double last_out_l; + double last_out_r; +}; + +void filter_init_rc(struct filter_t *filter, double R, double C); +void filter_init_freq(struct filter_t *filter, double freq); +void filter_run_lp(struct filter_t *filter, double left, double right); +void filter_run_hp(struct filter_t *filter, double left, double right); diff --git a/psyn.c b/psyn.c index 8f12d3d..bec9c99 100644 --- a/psyn.c +++ b/psyn.c @@ -6,6 +6,7 @@ #include "lv2_event_helpers.h" #include "lv2_uri_map.h" #include "osc.h" +#include "filter.h" #include "voice.h" #include "engine.h" #include "psyn.h" diff --git a/rng.h b/rng.h new file mode 100644 index 0000000..dce2057 --- /dev/null +++ b/rng.h @@ -0,0 +1,10 @@ + +static inline double rng() +{ + static double b = 19.1919191919191919191919; + + b += 19.0; + b *= b; + b -= (int)b; + return (b - 0.5) * 2.0; +} diff --git a/voice.c b/voice.c index 60b9c02..d230aac 100644 --- a/voice.c +++ b/voice.c @@ -4,8 +4,22 @@ #include #include "osc.h" #include "env.h" +#include "filter.h" #include "voice.h" #include "psyn.h" +#include "rng.h" + +void voice_init(struct voice_t *voice, double freq) +{ +// filter_init_rc(&voice->fil[0], 1000.0, 0.000000047); +// filter_init_rc(&voice->fil[1], 47000.0, 0.000000047); + filter_init_freq(&voice->fil[0], 2000.0); + filter_init_freq(&voice->fil[1], 150.0); + + osc_setfreq(&voice->osc[0], freq); + osc_setfreq(&voice->osc[1], freq * 1.2); + osc_setfreq(&voice->osc[2], freq * 5); +} static inline void voice_tick(struct voice_t *voice) { @@ -17,17 +31,6 @@ static inline void voice_tick(struct voice_t *voice) voice->sample++; } -static double _R = 4700.0; -static double _C = 0.000000047; - -static inline void voice_filter(struct voice_t *voice, float l, float r) -{ - double k = 1.0 / (_R * _C) / _sample_rate; - - voice->last_l += k * (l - voice->last_l); - voice->last_r += k * (r - voice->last_r); -} - void voice_run(struct voice_t *voice, uint32_t samples, float *left, float *right) { // uint32_t pos; @@ -47,8 +50,8 @@ void voice_run(struct voice_t *voice, uint32_t samples, float *left, float *righ amplitude *= voice->velocity; - l = amplitude * voice->osc[0].saw; - r = amplitude * voice->osc[0].saw; + l = amplitude * voice->osc[0].sin * (1.0 + rng() * 0.25); + r = amplitude * voice->osc[0].sin * (1.0 + rng() * 0.25); amplitude = env_getamplitude(&_env2, voice->sample, voice->released) * voice->velocity * voice->velocity * 1.5; @@ -57,9 +60,13 @@ void voice_run(struct voice_t *voice, uint32_t samples, float *left, float *righ r += amplitude * voice->osc[1].tri * (1.0 + voice->osc[2].sin * 0.25); } - voice_filter(voice, l, r); + *left += l; + *right += r; - *left += voice->last_l; - *right += voice->last_r; +// filter_run_lp(&voice->fil[0], l, r); +// filter_run_hp(&voice->fil[1], voice->fil[0].last_out_l, voice->fil[0].last_out_r); + +// *left += voice->fil[0].last_out_l; +// *right += voice->fil[0].last_out_r; // } } diff --git a/voice.h b/voice.h index ad6f179..fe113d9 100644 --- a/voice.h +++ b/voice.h @@ -1,4 +1,5 @@ #define VOICE_OSCILLATORS 4 +#define VOICE_FILTERS 2 struct voice_t { @@ -10,8 +11,8 @@ struct voice_t double velocity; struct osc_t osc[VOICE_OSCILLATORS]; - double last_l; - double last_r; + struct filter_t fil[VOICE_FILTERS]; }; +void voice_init(struct voice_t *voice, double freq); void voice_run(struct voice_t *voice, uint32_t samples, float *left, float *right);