fixed bw_svf prewarp-related instability bug
This commit is contained in:
parent
2d101a315e
commit
468f66453b
2
TODO
2
TODO
@ -43,7 +43,7 @@ code:
|
|||||||
* bw_math: review types
|
* bw_math: review types
|
||||||
* src inside distortions? w/ control from outside?
|
* src inside distortions? w/ control from outside?
|
||||||
* bw_fuzz gain compensation?
|
* bw_fuzz gain compensation?
|
||||||
* check initial conditions (especially distorsions)
|
* remove union value = {.f = v};? (std c++ latest)
|
||||||
|
|
||||||
build system:
|
build system:
|
||||||
* make makefiles handle paths with spaces etc
|
* make makefiles handle paths with spaces etc
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
* module_type {{{ dsp }}}
|
* module_type {{{ dsp }}}
|
||||||
* version {{{ 0.4.0 }}}
|
* version {{{ 0.5.0 }}}
|
||||||
* requires {{{ bw_config bw_common bw_math bw_one_pole }}}
|
* requires {{{ bw_config bw_common bw_math bw_one_pole }}}
|
||||||
* description {{{
|
* description {{{
|
||||||
* State variable filter (2nd order, 12 dB/oct) model with separated lowpass,
|
* State variable filter (2nd order, 12 dB/oct) model with separated lowpass,
|
||||||
@ -28,6 +28,11 @@
|
|||||||
* }}}
|
* }}}
|
||||||
* changelog {{{
|
* changelog {{{
|
||||||
<ul>
|
<ul>
|
||||||
|
* <li>Version <strong>0.5.0</strong>:
|
||||||
|
* <ul>
|
||||||
|
* <li>Fixed prewarping-related stability bug.</li>
|
||||||
|
* </ul>
|
||||||
|
* </li>
|
||||||
* <li>Version <strong>0.4.0</strong>:
|
* <li>Version <strong>0.4.0</strong>:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Added initial input value to
|
* <li>Added initial input value to
|
||||||
@ -197,8 +202,9 @@ struct _bw_svf_coeffs {
|
|||||||
float prewarp_k;
|
float prewarp_k;
|
||||||
float t;
|
float t;
|
||||||
float kf;
|
float kf;
|
||||||
|
float kbl;
|
||||||
float k;
|
float k;
|
||||||
float kt;
|
float hp_hb;
|
||||||
float hp_x;
|
float hp_x;
|
||||||
|
|
||||||
// Parameters
|
// Parameters
|
||||||
@ -232,24 +238,30 @@ static inline void bw_svf_set_sample_rate(bw_svf_coeffs *BW_RESTRICT coeffs, flo
|
|||||||
|
|
||||||
static inline void _bw_svf_do_update_coeffs(bw_svf_coeffs *BW_RESTRICT coeffs, char force) {
|
static inline void _bw_svf_do_update_coeffs(bw_svf_coeffs *BW_RESTRICT coeffs, char force) {
|
||||||
const float prewarp_freq = coeffs->prewarp_freq + coeffs->prewarp_k * (coeffs->cutoff - coeffs->prewarp_freq);
|
const float prewarp_freq = coeffs->prewarp_freq + coeffs->prewarp_k * (coeffs->cutoff - coeffs->prewarp_freq);
|
||||||
|
float cutoff_cur = bw_one_pole_get_y_z1(&coeffs->smooth_cutoff_state);
|
||||||
float prewarp_freq_cur = bw_one_pole_get_y_z1(&coeffs->smooth_prewarp_freq_state);
|
float prewarp_freq_cur = bw_one_pole_get_y_z1(&coeffs->smooth_prewarp_freq_state);
|
||||||
float Q_cur = bw_one_pole_get_y_z1(&coeffs->smooth_Q_state);
|
float Q_cur = bw_one_pole_get_y_z1(&coeffs->smooth_Q_state);
|
||||||
|
const char cutoff_changed = force || coeffs->cutoff != cutoff_cur;
|
||||||
const char prewarp_freq_changed = force || prewarp_freq != prewarp_freq_cur;
|
const char prewarp_freq_changed = force || prewarp_freq != prewarp_freq_cur;
|
||||||
const char Q_changed = force || coeffs->Q != Q_cur;
|
const char Q_changed = force || coeffs->Q != Q_cur;
|
||||||
if (prewarp_freq_changed || Q_changed) {
|
if (cutoff_changed || prewarp_freq_changed || Q_changed) {
|
||||||
if (prewarp_freq_changed) {
|
if (cutoff_changed || prewarp_freq_changed) {
|
||||||
prewarp_freq_cur = bw_one_pole_process1_sticky_rel(&coeffs->smooth_coeffs, &coeffs->smooth_prewarp_freq_state, prewarp_freq);
|
if (cutoff_changed)
|
||||||
coeffs->t = bw_tanf_3(coeffs->t_k * prewarp_freq_cur);
|
cutoff_cur = bw_one_pole_process1_sticky_rel(&coeffs->smooth_coeffs, &coeffs->smooth_cutoff_state, coeffs->cutoff);
|
||||||
coeffs->kf = coeffs->t * bw_rcpf_2(prewarp_freq_cur);
|
if (prewarp_freq_changed) {
|
||||||
|
prewarp_freq_cur = bw_one_pole_process1_sticky_rel(&coeffs->smooth_coeffs, &coeffs->smooth_prewarp_freq_state, prewarp_freq);
|
||||||
|
coeffs->t = bw_tanf_3(coeffs->t_k * prewarp_freq_cur);
|
||||||
|
coeffs->kf = coeffs->t * bw_rcpf_2(prewarp_freq_cur);
|
||||||
|
}
|
||||||
|
coeffs->kbl = coeffs->kf * cutoff_cur;
|
||||||
}
|
}
|
||||||
if (Q_changed) {
|
if (Q_changed) {
|
||||||
Q_cur = bw_one_pole_process1_sticky_abs(&coeffs->smooth_coeffs, &coeffs->smooth_Q_state, coeffs->Q);
|
Q_cur = bw_one_pole_process1_sticky_abs(&coeffs->smooth_coeffs, &coeffs->smooth_Q_state, coeffs->Q);
|
||||||
coeffs->k = bw_rcpf_2(Q_cur);
|
coeffs->k = bw_rcpf_2(Q_cur);
|
||||||
}
|
}
|
||||||
coeffs->kt = coeffs->k + coeffs->t;
|
coeffs->hp_hb = coeffs->k + coeffs->kbl;
|
||||||
coeffs->hp_x = bw_rcpf_2(1.f + coeffs->t * coeffs->kt);
|
coeffs->hp_x = bw_rcpf_2(1.f + coeffs->kbl * coeffs->hp_hb);
|
||||||
}
|
}
|
||||||
bw_one_pole_process1(&coeffs->smooth_coeffs, &coeffs->smooth_cutoff_state, coeffs->cutoff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bw_svf_reset_coeffs(bw_svf_coeffs *BW_RESTRICT coeffs) {
|
static inline void bw_svf_reset_coeffs(bw_svf_coeffs *BW_RESTRICT coeffs) {
|
||||||
@ -278,9 +290,9 @@ static inline void bw_svf_process1(const bw_svf_coeffs *BW_RESTRICT coeffs, bw_s
|
|||||||
const float kk = coeffs->kf * state->cutoff_z1;
|
const float kk = coeffs->kf * state->cutoff_z1;
|
||||||
const float lp_xz1 = state->lp_z1 - kk * state->bp_z1;
|
const float lp_xz1 = state->lp_z1 - kk * state->bp_z1;
|
||||||
const float bp_xz1 = state->bp_z1 - kk * state->hp_z1;
|
const float bp_xz1 = state->bp_z1 - kk * state->hp_z1;
|
||||||
*y_hp = coeffs->hp_x * (x + coeffs->kt * bp_xz1 - lp_xz1);
|
*y_hp = coeffs->hp_x * (x + coeffs->hp_hb * bp_xz1 - lp_xz1);
|
||||||
*y_bp = bp_xz1 - coeffs->t * *y_hp;
|
*y_bp = bp_xz1 - coeffs->kbl * *y_hp;
|
||||||
*y_lp = lp_xz1 - coeffs->t * *y_bp;
|
*y_lp = lp_xz1 - coeffs->kbl * *y_bp;
|
||||||
state->hp_z1 = *y_hp;
|
state->hp_z1 = *y_hp;
|
||||||
state->lp_z1 = *y_lp;
|
state->lp_z1 = *y_lp;
|
||||||
state->bp_z1 = *y_bp;
|
state->bp_z1 = *y_bp;
|
||||||
|
Loading…
Reference in New Issue
Block a user