clap

CLAP Audio Plugin API
Log | Files | Refs | README | LICENSE

commit 090c1d04e0040e4c3463d65019df66c244e952cc
parent 295db37324c7f3568b94eb53541cda0f68268102
Author: Alexandre Bique <bique.alexandre@gmail.com>
Date:   Wed,  7 Jan 2015 00:20:16 +0100

thyns: add parameters for the filter

Diffstat:
Mexamples/thyns/filt.h | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Mexamples/thyns/params.h | 2++
Mexamples/thyns/voice.h | 16+++++++++++++---
3 files changed, 85 insertions(+), 15 deletions(-)

diff --git a/examples/thyns/filt.h b/examples/thyns/filt.h @@ -8,6 +8,13 @@ # include "defs.h" +enum thyns_filt_param_index +{ + THYNS_FILT_PARAM_CUTOFF = 0, + THYNS_FILT_PARAM_RESONANCE, + THYNS_FILT_PARAM_COUNT +}; + struct thyns_filt { uint32_t sr; // sample rate @@ -19,15 +26,67 @@ struct thyns_filt double g; double g_div; - float iceq1; // states in form - float iceq2; // of current - float iceq3; // equivalents - float iceq4; // of capacitors + double iceq1; // states in form + double iceq2; // of current + double iceq3; // equivalents + double iceq4; // of capacitors - float y4; // delayed feedback + double y4; // delayed feedback + + /* parameters */ + union clap_param_value *values[THYNS_FILT_PARAM_COUNT]; }; static inline void +thyns_filt_param_info(uint32_t index, + union clap_param_value value, + const char *prefix, + struct clap_param *param) +{ +#define P(Dst, Args...) snprintf(Dst, sizeof (Dst), Args); + + switch (index) { + case THYNS_FILT_PARAM_CUTOFF: + P(param->id, "%s%s", prefix, "cutoff"); + P(param->name, "%s", "cutoff"); + P(param->desc, "%s", "Filter's cutoff"); + P(param->display, "%f", value.f); + param->type = CLAP_PARAM_FLOAT; + param->is_per_note = true; + param->is_used = true; + param->is_periodic = false; + param->value = value; + param->min.f = 0; + param->max.f = 28000; + param->scale = CLAP_PARAM_LOG; + break; + + case THYNS_FILT_PARAM_RESONANCE: + P(param->id, "%s%s", prefix, "resonance"); + P(param->name, "%s", "resonance"); + P(param->desc, "%s", "Filter's resonance"); + P(param->display, "%f", value.f); + param->type = CLAP_PARAM_FLOAT; + param->is_per_note = true; + param->is_used = true; + param->is_periodic = false; + param->value = value; + param->min.f = 0; + param->max.f = 2; + param->scale = CLAP_PARAM_LINEAR; + break; + } +#undef P +} + +static inline void +thyns_filt_params_init(union clap_param_value *values) +{ + values[THYNS_FILT_PARAM_CUTOFF].f = 10000; + values[THYNS_FILT_PARAM_RESONANCE].f = 0.7; +} + +static inline void thyns_filt_init(struct thyns_filt *filt, uint32_t sr) { memset(filt, 0, sizeof (*filt)); @@ -35,17 +94,16 @@ thyns_filt_init(struct thyns_filt *filt, uint32_t sr) filt->pi_sr = M_PI / sr; } -static inline void -thyns_filt_set_cutoff(struct thyns_filt *filt, double cutoff) +static inline double +thyns_filt_step(struct thyns_filt *filt, + double in, + double cutoff, + double resonance) { filt->g = tan(filt->pi_sr * cutoff); filt->g_div = 1.0 / (1.0 + filt->g); -} -static inline double -thyns_filt_step(struct thyns_filt *filt, double in) -{ - double x0 = in - filt->resonance * filt->y4; + double x0 = in - resonance * filt->y4; double y1 = (filt->g * tanh(x0) + filt->iceq1) * filt->g_div; double y2 = (filt->g * tanh(y1) + filt->iceq2) * filt->g_div; double y3 = (filt->g * tanh(y2) + filt->iceq3) * filt->g_div; diff --git a/examples/thyns/params.h b/examples/thyns/params.h @@ -6,6 +6,7 @@ struct thyns_params union clap_param_value values[0]; union clap_param_value osc1[THYNS_OSC_PARAM_COUNT]; union clap_param_value osc2[THYNS_OSC_PARAM_COUNT]; + union clap_param_value filt[THYNS_FILT_PARAM_COUNT]; }; static void @@ -13,6 +14,7 @@ thyns_params_init(struct thyns_params *params) { thyns_osc_params_init(params->osc1); thyns_osc_params_init(params->osc2); + thyns_filt_params_init(params->filt); } #endif /* !PARAMS_H */ diff --git a/examples/thyns/voice.h b/examples/thyns/voice.h @@ -76,6 +76,11 @@ thyns_voice_params_init(struct thyns_voice *voice, for (int i = 0; i < THYNS_OSC_PARAM_COUNT; ++i) voice->osc2.values[i] = params->values + off + i; off += THYNS_OSC_PARAM_COUNT; + + // filt + for (int i = 0; i < THYNS_FILT_PARAM_COUNT; ++i) + voice->filt.values[i] = params->values + off + i; + off += THYNS_FILT_PARAM_COUNT; } static inline void @@ -94,6 +99,11 @@ thyns_voice_use_param(struct thyns_voice *voice, voice->osc2.values[index - i] = params->values + index; } i += THYNS_OSC_PARAM_COUNT; + + if (index < i + THYNS_FILT_PARAM_COUNT) { + voice->filt.values[index - i] = params->values + index; + } + i += THYNS_FILT_PARAM_COUNT; } static inline void @@ -123,9 +133,9 @@ thyns_voice_step(struct thyns_voice *voice) double osc2 = thyns_osc_step(&voice->osc2); double oscm = osc1 * (1 - voice->osc_mix) + osc2 * voice->osc_mix; double fenv = thyns_env_step(&voice->filt_env) * voice->filt_env_depth; - double cutoff = exp(log(voice->filt.cutoff) + fenv); - thyns_filt_set_cutoff(&voice->filt, cutoff); - double filtered = thyns_filt_step(&voice->filt, oscm); + double cutoff = exp(log(voice->filt.values[THYNS_FILT_PARAM_CUTOFF]->f) + fenv); + double filtered = thyns_filt_step(&voice->filt, oscm, cutoff, + voice->filt.values[THYNS_FILT_PARAM_RESONANCE]->f); double amp = voice->amp * thyns_env_step(&voice->amp_env); return filtered * amp;