diff --git a/examples/common/web/web.mk b/examples/common/web/web.mk
index b1af648..785bedd 100644
--- a/examples/common/web/web.mk
+++ b/examples/common/web/web.mk
@@ -26,7 +26,9 @@ LDFLAGS := \
ifdef SYNTH
LDFLAGS += \
-Wl,--export=wrapper_note_on \
- -Wl,--export=wrapper_note_off
+ -Wl,--export=wrapper_note_off \
+ -Wl,--export=wrapper_pitch_bend \
+ -Wl,--export=wrapper_mod_wheel
INDEX := ${ROOT_DIR}/../../common/web/index-synth.html
else
diff --git a/examples/fx_eq_3band/src/bw_example_fx_eq_3band.c b/examples/fx_eq_3band/src/bw_example_fx_eq_3band.c
index 197cdf5..863ee29 100644
--- a/examples/fx_eq_3band/src/bw_example_fx_eq_3band.c
+++ b/examples/fx_eq_3band/src/bw_example_fx_eq_3band.c
@@ -32,13 +32,13 @@
enum {
p_ls_cutoff,
p_ls_gain,
- p_ls_slope,
+ p_ls_Q,
p_peak_cutoff,
p_peak_gain,
p_peak_bw,
p_hs_cutoff,
p_hs_gain,
- p_hs_slope,
+ p_hs_Q,
p_n
};
@@ -62,8 +62,6 @@ bw_example_fx_eq_3band bw_example_fx_eq_3band_new() {
bw_ls2_init(&instance->ls2_coeffs);
bw_peak_init(&instance->peak_coeffs);
bw_hs2_init(&instance->hs2_coeffs);
- bw_ls2_set_use_slope(&instance->ls2_coeffs, 0);
- bw_hs2_set_use_slope(&instance->hs2_coeffs, 0);
return instance;
}
@@ -101,7 +99,8 @@ void bw_example_fx_eq_3band_set_parameter(bw_example_fx_eq_3band instance, int i
case p_ls_gain:
bw_ls2_set_dc_gain_dB(&instance->ls2_coeffs, -20.f + 40.f * value);
break;
- case p_ls_slope:
+ case p_ls_Q:
+ bw_ls2_set_Q(&instance->ls2_coeffs, 0.5f + 4.5f * value);
break;
case p_peak_cutoff:
bw_peak_set_cutoff(&instance->peak_coeffs, 20.f + (20e3f - 20.f) * value * value * value);
@@ -118,7 +117,8 @@ void bw_example_fx_eq_3band_set_parameter(bw_example_fx_eq_3band instance, int i
case p_hs_gain:
bw_hs2_set_high_gain_dB(&instance->hs2_coeffs, -20.f + 40.f * value);
break;
- case p_hs_slope:
+ case p_hs_Q:
+ bw_hs2_set_Q(&instance->hs2_coeffs, 0.5f + 4.5f * value);
break;
}
}
diff --git a/examples/fx_eq_3band/src/config.h b/examples/fx_eq_3band/src/config.h
index 38acad5..eb090ea 100644
--- a/examples/fx_eq_3band/src/config.h
+++ b/examples/fx_eq_3band/src/config.h
@@ -71,13 +71,13 @@ static struct config_io_bus config_buses_out[NUM_BUSES_OUT] = {
static struct config_parameter config_parameters[NUM_PARAMETERS] = {
{ "Low shelf cutoff", "LS cutoff", "Hz", 0, 0, 0, 0.2f },
{ "Low shelf gain", "LS gain", "dB", 0, 0, 0, 0.5f },
- { "Low shelf slope", "LS slope", "", 0, 0, 0, 0.f },
+ { "Low shelf Q", "LS Q", "", 0, 0, 0, 0.f },
{ "Peak cutoff", "Peak cutoff", "Hz", 0, 0, 0, 0.5f },
{ "Peak gain", "Peak gain", "dB", 0, 0, 0, 0.5f },
{ "Peak bandiwdth", "Peak BW", "", 0, 0, 0, 1.f },
{ "High shelf cutoff", "HS cutoff", "Hz", 0, 0, 0, 0.8f },
{ "High shelf gain", "HS gain", "dB", 0, 0, 0, 0.5f },
- { "High shelf slope", "HS slope", "", 0, 0, 0, 0.f }
+ { "High shelf Q", "HS Q", "", 0, 0, 0, 0.f }
};
// Internal API
diff --git a/examples/fx_eq_3band/web/config.js b/examples/fx_eq_3band/web/config.js
index bbaac50..93db7f1 100644
--- a/examples/fx_eq_3band/web/config.js
+++ b/examples/fx_eq_3band/web/config.js
@@ -41,7 +41,7 @@ var parameters = [
defaultValue: 0.5
},
{
- name: "Low shelf slope",
+ name: "Low shelf Q",
output: false,
defaultValue: 0.0
},
@@ -71,7 +71,7 @@ var parameters = [
defaultValue: 0.5
},
{
- name: "High shelf slope",
+ name: "High shelf Q",
output: false,
defaultValue: 0.0
}
diff --git a/examples/synth_mono/src/bw_example_synth_mono.c b/examples/synth_mono/src/bw_example_synth_mono.c
index fca2f09..59d47e1 100644
--- a/examples/synth_mono/src/bw_example_synth_mono.c
+++ b/examples/synth_mono/src/bw_example_synth_mono.c
@@ -294,7 +294,8 @@ void bw_example_synth_mono_process(bw_example_synth_mono instance, const float**
if (instance->params[p_noise_color] >= 0.5f)
bw_pink_filt_process(&instance->pink_filt_coeffs, &instance->pink_filt_state, instance->buf[0], instance->buf[0], n);
else
- bw_pink_filt_reset_state(&instance->pink_filt_coeffs, &instance->pink_filt_state);
+ bw_pink_filt_reset_state(&instance->pink_filt_coeffs, &instance->pink_filt_state); // FIXME: calling this here is sloppy coding
+ bw_buf_scale(instance->buf[0], instance->buf[0], 5.f, n);
for (int j = 0; j < n; j++)
instance->buf[1][j] = instance->mod_wheel * (out[j] + instance->params[p_mod_mix] * (instance->buf[0][j] - out[j]));
@@ -338,8 +339,8 @@ void bw_example_synth_mono_process(bw_example_synth_mono instance, const float**
bw_osc_filt_process(&instance->osc_filt_state, out, out, n);
const float k = instance->params[p_noise_color] >= 0.5f
- ? 3.f * bw_noise_gen_get_scaling_k(&instance->noise_gen_coeffs) * bw_pink_filt_get_scaling_k(&instance->pink_filt_coeffs)
- : 0.01f * bw_noise_gen_get_scaling_k(&instance->noise_gen_coeffs);
+ ? 6.f * bw_noise_gen_get_scaling_k(&instance->noise_gen_coeffs) * bw_pink_filt_get_scaling_k(&instance->pink_filt_coeffs)
+ : 0.1f * bw_noise_gen_get_scaling_k(&instance->noise_gen_coeffs);
bw_buf_scale(instance->buf[0], instance->buf[0], k, n);
bw_buf_mix(out, out, instance->buf[0], n);
diff --git a/include/bw_hs2.h b/include/bw_hs2.h
index 6d45960..70daaf1 100644
--- a/include/bw_hs2.h
+++ b/include/bw_hs2.h
@@ -26,12 +26,6 @@
* }}}
* description {{{
* Second-order high shelf filter (12 dB/oct) with unitary DC gain.
- *
- * The quality factor can be either directly controlled via the Q parameter
- * or indirectly through the slope parameter, which indicates the "shelf
- * slope" as defined in the "Cookbook formulae for audio EQ biquad filter
- * coefficients" by Robert Bristow-Johnson. The use_slope parameter allows
- * you to choose which parameterization to use.
* }}}
* changelog {{{
*
@@ -152,23 +146,6 @@ static inline void bw_hs2_set_high_gain_dB(bw_hs2_coeffs *BW_RESTRICT coeffs, fl
* `coeffs`.
*
* Default value: `-INFINITY`.
- *
- * #### bw_hs2_set_slope()
- * ```>>> */
-static inline void bw_hs2_set_slope(bw_hs2_coeffs *BW_RESTRICT coeffs, float value);
-/*! <<<```
- * Sets the shelf slope `value` in `coeffs`.
- *
- * Default value: `0.5f`.
- *
- * #### bw_hs2_set_use_slope()
- * ```>>> */
-static inline void bw_hs2_set_use_slope(bw_hs2_coeffs *BW_RESTRICT coeffs, char value);
-/*! <<<```
- * Sets whether the quality factor should be controlled via the slope
- * parameter (`value` non-`0`) or via the Q parameter (`0`).
- *
- * Default value: non-`0` (use slope parameter).
* }}} */
/*** Implementation ***/
@@ -191,9 +168,6 @@ struct _bw_hs2_coeffs {
// Parameters
float high_gain;
float cutoff;
- float Q;
- float slope;
- char use_slope;
int param_changed;
};
@@ -203,17 +177,12 @@ struct _bw_hs2_state {
#define _BW_HS2_PARAM_HIGH_GAIN 1
#define _BW_HS2_PARAM_CUTOFF (1<<1)
-#define _BW_HS2_PARAM_Q (1<<2)
-#define _BW_HS2_PARAM_SLOPE (1<<3)
static inline void bw_hs2_init(bw_hs2_coeffs *BW_RESTRICT coeffs) {
bw_mm2_init(&coeffs->mm2_coeffs);
bw_mm2_set_prewarp_at_cutoff(&coeffs->mm2_coeffs, 0);
coeffs->high_gain = 1.f;
coeffs->cutoff = 1e3f;
- coeffs->Q = 0.5f;
- coeffs->slope = 0.5f;
- coeffs->use_slope = 1;
}
static inline void bw_hs2_set_sample_rate(bw_hs2_coeffs *BW_RESTRICT coeffs, float sample_rate) {
@@ -222,29 +191,17 @@ static inline void bw_hs2_set_sample_rate(bw_hs2_coeffs *BW_RESTRICT coeffs, flo
static inline void _bw_hs2_update_mm2_params(bw_hs2_coeffs *BW_RESTRICT coeffs) {
if (coeffs->param_changed) {
- if (coeffs->param_changed & (_BW_HS2_PARAM_HIGH_GAIN | _BW_HS2_PARAM_CUTOFF)) {
- if (coeffs->param_changed & _BW_HS2_PARAM_HIGH_GAIN) {
- coeffs->sg = bw_sqrtf_2(coeffs->high_gain);
- coeffs->isg = bw_rcpf_2(coeffs->sg);
- coeffs->ssg = bw_sqrtf_2(coeffs->sg);
- bw_mm2_set_coeff_x(&coeffs->mm2_coeffs, coeffs->sg);
- bw_mm2_set_coeff_lp(&coeffs->mm2_coeffs, 1.f - coeffs->sg);
- bw_mm2_set_coeff_hp(&coeffs->mm2_coeffs, coeffs->high_gain - coeffs->sg);
- }
- if (coeffs->param_changed & _BW_HS2_PARAM_CUTOFF)
- bw_mm2_set_prewarp_freq(&coeffs->mm2_coeffs, coeffs->cutoff);
- bw_mm2_set_cutoff(&coeffs->mm2_coeffs, coeffs->cutoff * coeffs->ssg);
- }
- if (coeffs->use_slope) {
- if (coeffs->param_changed & (_BW_HS2_PARAM_HIGH_GAIN | _BW_HS2_PARAM_SLOPE)) {
- const float k = coeffs->sg + coeffs->isg;
- bw_mm2_set_Q(&coeffs->mm2_coeffs, bw_sqrtf_2(coeffs->slope * bw_rcpf_2(coeffs->slope + coeffs->slope + k - k * coeffs->slope)));
- }
- }
- else {
- if (coeffs->param_changed & _BW_HS2_PARAM_Q)
- bw_mm2_set_Q(&coeffs->mm2_coeffs, coeffs->Q);
+ if (coeffs->param_changed & _BW_HS2_PARAM_HIGH_GAIN) {
+ coeffs->sg = bw_sqrtf_2(coeffs->high_gain);
+ coeffs->isg = bw_rcpf_2(coeffs->sg);
+ coeffs->ssg = bw_sqrtf_2(coeffs->sg);
+ bw_mm2_set_coeff_x(&coeffs->mm2_coeffs, coeffs->sg);
+ bw_mm2_set_coeff_lp(&coeffs->mm2_coeffs, 1.f - coeffs->sg);
+ bw_mm2_set_coeff_hp(&coeffs->mm2_coeffs, coeffs->high_gain - coeffs->sg);
}
+ if (coeffs->param_changed & _BW_HS2_PARAM_CUTOFF)
+ bw_mm2_set_prewarp_freq(&coeffs->mm2_coeffs, coeffs->cutoff);
+ bw_mm2_set_cutoff(&coeffs->mm2_coeffs, coeffs->cutoff * coeffs->ssg);
coeffs->param_changed = 0;
}
}
@@ -288,10 +245,7 @@ static inline void bw_hs2_set_cutoff(bw_hs2_coeffs *BW_RESTRICT coeffs, float va
}
static inline void bw_hs2_set_Q(bw_hs2_coeffs *BW_RESTRICT coeffs, float value) {
- if (coeffs->Q != value) {
- coeffs->Q = value;
- coeffs->param_changed |= _BW_HS2_PARAM_Q;
- }
+ bw_mm2_set_Q(&coeffs->mm2_coeffs, value);
}
static inline void bw_hs2_set_high_gain_lin(bw_hs2_coeffs *BW_RESTRICT coeffs, float value) {
@@ -305,24 +259,8 @@ static inline void bw_hs2_set_high_gain_dB(bw_hs2_coeffs *BW_RESTRICT coeffs, fl
bw_hs2_set_high_gain_lin(coeffs, bw_dB2linf_3(value));
}
-static inline void bw_hs2_set_slope(bw_hs2_coeffs *BW_RESTRICT coeffs, float value) {
- if (coeffs->slope != value) {
- coeffs->slope = value;
- coeffs->param_changed |= _BW_HS2_PARAM_SLOPE;
- }
-}
-
-static inline void bw_hs2_set_use_slope(bw_hs2_coeffs *BW_RESTRICT coeffs, char value) {
- if ((coeffs->use_slope && !value) || (!coeffs->use_slope && value)) {
- coeffs->use_slope = value;
- coeffs->param_changed |= _BW_HS2_PARAM_Q | _BW_HS2_PARAM_SLOPE;
- }
-}
-
#undef _BW_HS2_PARAM_HIGH_GAIN
#undef _BW_HS2_PARAM_CUTOFF
-#undef _BW_HS2_PARAM_Q
-#undef _BW_HS2_PARAM_SLOPE
#ifdef __cplusplus
}
diff --git a/include/bw_ls2.h b/include/bw_ls2.h
index 85e50b9..d7e67cf 100644
--- a/include/bw_ls2.h
+++ b/include/bw_ls2.h
@@ -27,12 +27,6 @@
* description {{{
* Second-order low shelf filter (12 dB/oct) with gain asymptotically
* approaching unity as frequency increases.
- *
- * The quality factor can be either directly controlled via the Q parameter
- * or indirectly through the slope parameter, which indicates the "shelf
- * slope" as defined in the "Cookbook formulae for audio EQ biquad filter
- * coefficients" by Robert Bristow-Johnson. The use_slope parameter allows
- * you to choose which parameterization to use.
* }}}
* changelog {{{
*
@@ -151,23 +145,6 @@ static inline void bw_ls2_set_dc_gain_dB(bw_ls2_coeffs *BW_RESTRICT coeffs, floa
* Sets the dc gain parameter to the given `value` (dB) in `coeffs`.
*
* Default value: `-INFINITY`.
- *
- * #### bw_ls2_set_slope()
- * ```>>> */
-static inline void bw_ls2_set_slope(bw_ls2_coeffs *BW_RESTRICT coeffs, float value);
-/*! <<<```
- * Sets the shelf slope `value` in `coeffs`.
- *
- * Default value: `0.5f`.
- *
- * #### bw_ls2_set_use_slope()
- * ```>>> */
-static inline void bw_ls2_set_use_slope(bw_ls2_coeffs *BW_RESTRICT coeffs, char value);
-/*! <<<```
- * Sets whether the quality factor should be controlled via the slope
- * parameter (`value` non-`0`) or via the Q parameter (`0`).
- *
- * Default value: non-`0` (use slope parameter).
* }}} */
/*** Implementation ***/
@@ -190,9 +167,6 @@ struct _bw_ls2_coeffs {
// Parameters
float dc_gain;
float cutoff;
- float Q;
- float slope;
- char use_slope;
int param_changed;
};
@@ -202,17 +176,12 @@ struct _bw_ls2_state {
#define _BW_LS2_PARAM_DC_GAIN 1
#define _BW_LS2_PARAM_CUTOFF (1<<1)
-#define _BW_LS2_PARAM_Q (1<<2)
-#define _BW_LS2_PARAM_SLOPE (1<<3)
static inline void bw_ls2_init(bw_ls2_coeffs *BW_RESTRICT coeffs) {
bw_mm2_init(&coeffs->mm2_coeffs);
bw_mm2_set_prewarp_at_cutoff(&coeffs->mm2_coeffs, 0);
coeffs->dc_gain = 1.f;
coeffs->cutoff = 1e3f;
- coeffs->Q = 0.5f;
- coeffs->slope = 0.5f;
- coeffs->use_slope = 1;
}
static inline void bw_ls2_set_sample_rate(bw_ls2_coeffs *BW_RESTRICT coeffs, float sample_rate) {
@@ -221,29 +190,17 @@ static inline void bw_ls2_set_sample_rate(bw_ls2_coeffs *BW_RESTRICT coeffs, flo
static inline void _bw_ls2_update_mm2_params(bw_ls2_coeffs *BW_RESTRICT coeffs) {
if (coeffs->param_changed) {
- if (coeffs->param_changed & (_BW_LS2_PARAM_DC_GAIN | _BW_LS2_PARAM_CUTOFF)) {
- if (coeffs->param_changed & _BW_LS2_PARAM_DC_GAIN) {
- coeffs->sg = bw_sqrtf_2(coeffs->dc_gain);
- coeffs->isg = bw_rcpf_2(coeffs->sg);
- coeffs->issg = bw_sqrtf_2(coeffs->isg);
- bw_mm2_set_coeff_x(&coeffs->mm2_coeffs, coeffs->sg);
- bw_mm2_set_coeff_lp(&coeffs->mm2_coeffs, coeffs->dc_gain - coeffs->sg);
- bw_mm2_set_coeff_hp(&coeffs->mm2_coeffs, 1.f - coeffs->sg);
- }
- if (coeffs->param_changed & _BW_LS2_PARAM_CUTOFF)
- bw_mm2_set_prewarp_freq(&coeffs->mm2_coeffs, coeffs->cutoff);
- bw_mm2_set_cutoff(&coeffs->mm2_coeffs, coeffs->cutoff * coeffs->issg);
- }
- if (coeffs->use_slope) {
- if (coeffs->param_changed & (_BW_LS2_PARAM_DC_GAIN | _BW_LS2_PARAM_SLOPE)) {
- const float k = coeffs->sg + coeffs->isg;
- bw_mm2_set_Q(&coeffs->mm2_coeffs, bw_sqrtf_2(coeffs->slope * bw_rcpf_2(coeffs->slope + coeffs->slope + k - k * coeffs->slope)));
- }
- }
- else {
- if (coeffs->param_changed & _BW_LS2_PARAM_Q)
- bw_mm2_set_Q(&coeffs->mm2_coeffs, coeffs->Q);
+ if (coeffs->param_changed & _BW_LS2_PARAM_DC_GAIN) {
+ coeffs->sg = bw_sqrtf_2(coeffs->dc_gain);
+ coeffs->isg = bw_rcpf_2(coeffs->sg);
+ coeffs->issg = bw_sqrtf_2(coeffs->isg);
+ bw_mm2_set_coeff_x(&coeffs->mm2_coeffs, coeffs->sg);
+ bw_mm2_set_coeff_lp(&coeffs->mm2_coeffs, coeffs->dc_gain - coeffs->sg);
+ bw_mm2_set_coeff_hp(&coeffs->mm2_coeffs, 1.f - coeffs->sg);
}
+ if (coeffs->param_changed & _BW_LS2_PARAM_CUTOFF)
+ bw_mm2_set_prewarp_freq(&coeffs->mm2_coeffs, coeffs->cutoff);
+ bw_mm2_set_cutoff(&coeffs->mm2_coeffs, coeffs->cutoff * coeffs->issg);
coeffs->param_changed = 0;
}
}
@@ -287,10 +244,7 @@ static inline void bw_ls2_set_cutoff(bw_ls2_coeffs *BW_RESTRICT coeffs, float va
}
static inline void bw_ls2_set_Q(bw_ls2_coeffs *BW_RESTRICT coeffs, float value) {
- if (coeffs->Q != value) {
- coeffs->Q = value;
- coeffs->param_changed |= _BW_LS2_PARAM_Q;
- }
+ bw_mm2_set_Q(&coeffs->mm2_coeffs, value);
}
static inline void bw_ls2_set_dc_gain_lin(bw_ls2_coeffs *BW_RESTRICT coeffs, float value) {
@@ -304,24 +258,8 @@ static inline void bw_ls2_set_dc_gain_dB(bw_ls2_coeffs *BW_RESTRICT coeffs, floa
bw_ls2_set_dc_gain_lin(coeffs, bw_dB2linf_3(value));
}
-static inline void bw_ls2_set_slope(bw_ls2_coeffs *BW_RESTRICT coeffs, float value) {
- if (coeffs->slope != value) {
- coeffs->slope = value;
- coeffs->param_changed |= _BW_LS2_PARAM_SLOPE;
- }
-}
-
-static inline void bw_ls2_set_use_slope(bw_ls2_coeffs *BW_RESTRICT coeffs, char value) {
- if ((coeffs->use_slope && !value) || (!coeffs->use_slope && value)) {
- coeffs->use_slope = value;
- coeffs->param_changed |= _BW_LS2_PARAM_Q | _BW_LS2_PARAM_SLOPE;
- }
-}
-
#undef _BW_LS2_PARAM_DC_GAIN
#undef _BW_LS2_PARAM_CUTOFF
-#undef _BW_LS2_PARAM_Q
-#undef _BW_LS2_PARAM_SLOPE
#ifdef __cplusplus
}
diff --git a/include/bw_math.h b/include/bw_math.h
index aa21eca..71842fd 100644
--- a/include/bw_math.h
+++ b/include/bw_math.h
@@ -1,7 +1,7 @@
/*
* Brickworks
*
- * Copyright (C) 2021, 2022 Orastron Srl unipersonale
+ * Copyright (C) 2021-2023 Orastron Srl unipersonale
*
* Brickworks is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/include/bw_peak.h b/include/bw_peak.h
index 3d8b810..37a4f28 100644
--- a/include/bw_peak.h
+++ b/include/bw_peak.h
@@ -162,7 +162,7 @@ static inline void bw_peak_set_bandwidth(bw_peak_coeffs *BW_RESTRICT coeffs, flo
*
* Default value: `0.5f`.
*
- * #### bw_peak_set_use_slope()
+ * #### bw_peak_set_use_bandwidth()
* ```>>> */
static inline void bw_peak_set_use_bandwidth(bw_peak_coeffs *BW_RESTRICT coeffs, char value);
/*! <<<```