From f3028e173d7ab071144bbae84532e736214ce79a Mon Sep 17 00:00:00 2001 From: Stefano D'Angelo Date: Sat, 26 Nov 2022 18:16:28 +0100 Subject: [PATCH] better use of one pole reset state in bw_svf and better omega approx --- include/bw_math.h | 17 +++++++++++++++++ include/bw_svf.h | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/bw_math.h b/include/bw_math.h index 3d928d8..a2b18fc 100644 --- a/include/bw_math.h +++ b/include/bw_math.h @@ -353,6 +353,14 @@ static inline float bw_omega_3log(float x); * more negative input. * >>> */ +/*! ... + * #### bw_omega_3lognr() + * ```>>> */ +static inline float bw_omega_3lognr(float x); +/*! <<<``` + * ... + * >>> */ + /*! ... * #### bw_sqrtf_2() * ```>>> */ @@ -540,6 +548,15 @@ static inline float bw_omega_3log(float x) { return x <= x2 ? d + x * (c + x * (b + x * a)) : x - bw_logf_3(x); } +static inline float bw_omega_3lognr(float x) { + // omega(x) ~ x with relative error smaller than epsilon (2^-23) for x > 1.6e8) + // (need to avoid big arguments for bw_rcpf_2()) + if (x > 1.6e8f) + return x; + float y = bw_omega_3log(x); + return y - (y - bw_expf_3(x - y)) * bw_rcpf_2(y + 1.f); +} + static inline float bw_sqrtf_2(float x) { _bw_floatint v = {.f = x}; v.u = ((v.u - 0x3f82a127) >> 1) + 0x3f7d8fc7; diff --git a/include/bw_svf.h b/include/bw_svf.h index dfd7395..32a48fd 100644 --- a/include/bw_svf.h +++ b/include/bw_svf.h @@ -166,6 +166,7 @@ static inline void bw_svf_init(bw_svf_coeffs *BW_RESTRICT coeffs) { static inline void bw_svf_set_sample_rate(bw_svf_coeffs *BW_RESTRICT coeffs, float sample_rate) { bw_one_pole_set_sample_rate(&coeffs->smooth_coeffs, sample_rate); + bw_one_pole_reset_coeffs(&coeffs->smooth_coeffs); coeffs->t_k = 3.141592653589793f / sample_rate; } @@ -191,7 +192,6 @@ static inline void _bw_svf_do_update_coeffs(bw_svf_coeffs *BW_RESTRICT coeffs, c } static inline void bw_svf_reset_coeffs(bw_svf_coeffs *BW_RESTRICT coeffs) { - bw_one_pole_reset_coeffs(&coeffs->smooth_coeffs); bw_one_pole_reset_state(&coeffs->smooth_coeffs, &coeffs->smooth_cutoff_state, coeffs->cutoff); bw_one_pole_reset_state(&coeffs->smooth_coeffs, &coeffs->smooth_Q_state, coeffs->Q); _bw_svf_do_update_coeffs(coeffs, 1);