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