bw_iir1 doc + bw_iir2 limited prewarping freq

This commit is contained in:
Stefano D'Angelo 2025-01-31 08:13:32 +01:00
parent fbd0890017
commit 61afaca400
2 changed files with 110 additions and 13 deletions

View File

@ -23,7 +23,13 @@
* version {{{ 1.0.0 }}}
* requires {{{ bw_common bw_math }}}
* description {{{
* XXX
* Lightweight and fast first-order IIR filter in TDF-II form.
*
* This is not a regular DSP module, as it exposes state and coefficients,
* and it's not appropriate for time-varying operation. If you need that,
* check out [bw_ap1](bw_ap1), [bw_hp1](bw_hp1), [bw_hs1](bw_hs1),
* [bw_lp1](bw_lp1), [bw_ls1](bw_ls1), [bw_mm1](bw_mm1), and
* [bw_one_pole](bw_one_pole).
* }}}
* changelog {{{
* <ul>
@ -62,7 +68,11 @@ static inline void bw_iir1_reset(
float b1,
float a1);
/*! <<<```
* XXX.
* Computes and puts the initial output in `y_0` and the initial state in
* `s_0`, given the initial input `x_0` and coefficients `b0`, `b1`, and
* `b2`.
*
* The given coefficients must describe a stable filter.
*
* #### bw_iir1_reset_multi()
* ```>>> */
@ -75,7 +85,14 @@ static inline void bw_iir1_reset_multi(
float a1,
size_t n_channels);
/*! <<<```
* XXX.
* Computes and puts each of the `n_channels` initial outputs in `y_0` and
* initial states in `s_0`, given the corresponding initial inputs `x_0` and
* coefficients `b0`, `b1`, and `b2`.
*
* `y_0` and/or `s_0` may be `BW_NULL`, in which case the corresponding
* values are not written anywhere.
*
* The given coefficients must describe a stable filter.
*
* #### bw_iir1_process1()
* ```>>> */
@ -87,7 +104,11 @@ static inline void bw_iir1_process1(
float b1,
float a1);
/*! <<<```
* XXX.
* Processes one input sample `x` using coefficients `b0`, `b1`, and `b2`.
* The output sample and next state value are put in `y` and `s`
* respectively.
*
* The given coefficients must describe a stable filter.
*
* #### bw_iir1_process()
* ```>>> */
@ -100,7 +121,11 @@ static inline void bw_iir1_process(
float a1,
size_t n_samples);
/*! <<<```
* XXX
* Processes the first `n_samples` of the input buffer `x` and fills the
* first `n_samples` of the output buffer `y`, while using coefficients `b0`,
* `b1`, and `b2`. The next state value is put in `s`.
*
* The given coefficients must describe a stable filter.
*
* #### bw_iir1_process_multi()
* ```>>> */
@ -114,7 +139,12 @@ static inline void bw_iir1_process_multi(
size_t n_channels,
size_t n_samples);
/*! <<<```
* XXX
* Processes the first `n_samples` of the `n_channels` input buffers `x` and
* fills the first `n_samples` of the `n_channels` output buffers `y`, while
* using coefficients `b0`, `b1`, and `b2`. The next `n_channels` state
* values are put in `s`.
*
* The given coefficients must describe a stable filter.
*
* #### bw_iir1_coeffs_ap1()
* ```>>> */
@ -127,7 +157,16 @@ static inline void bw_iir1_coeffs_ap1(
float * BW_RESTRICT b1,
float * BW_RESTRICT a1);
/*! <<<```
* XXX
* Computes and puts coefficient values in `b0`, `b1`, and `a1` resulting in
* a first-order allpass filter (90° shift at cutoff, approaching 180° shift
* at high frequencies) with unitary gain, using the bilinear transform with
* prewarping.
*
* It takes the `sample_rate` (Hz, must be positive) and the `cutoff`
* frequency (Hz, in [`1e-6f`, `1e12f`]). If `prewarp_freq` is `0`, then the
* prewarping frequency matches `cutoff`, otherwise the value specified by
* `prewarp_freq` (Hz, in [`1e-6f`, `1e12f`], however interally limited to
* avoid instability) is used.
*
* #### bw_iir1_coeffs_hp1()
* ```>>> */
@ -140,7 +179,16 @@ static inline void bw_iir1_coeffs_hp1(
float * BW_RESTRICT b1,
float * BW_RESTRICT a1);
/*! <<<```
* XXX
* Computes and puts coefficient values in `b0`, `b1`, and `a1` resulting in
* a first-order highpass filter (6 dB/oct) with gain asymptotically
* approaching unity as frequency increases, using the bilinear transform
* with prewarping.
*
* It takes the `sample_rate` (Hz, must be positive) and the `cutoff`
* frequency (Hz, in [`1e-6f`, `1e12f`]). If `prewarp_freq` is `0`, then the
* prewarping frequency matches `cutoff`, otherwise the value specified by
* `prewarp_freq` (Hz, in [`1e-6f`, `1e12f`], however interally limited to
* avoid instability) is used.
*
* #### bw_iir1_coeffs_hs1()
* ```>>> */
@ -155,7 +203,17 @@ static inline void bw_iir1_coeffs_hs1(
float * BW_RESTRICT b1,
float * BW_RESTRICT a1);
/*! <<<```
* XXX
* Computes and puts coefficient values in `b0`, `b1`, and `a1` resulting in
* a first-order high shelf filter (6 dB/oct) with unitary DC gain, using the
* bilinear transform with prewarping.
*
* It takes the `sample_rate` (Hz, must be positive), the `cutoff` frequency
* (Hz, in [`1e-6f`, `1e12f`]), and the high-frequency gain `high_gain`,
* either as linear gain (in [1e-30f, 1e30f]) if `high_gain_dB` is `0`, or
* otherwise in dB (in [-600.f, 600.f]). If `prewarp_freq` is `0`, then the
* prewarping frequency matches `cutoff`, otherwise the value specified by
* `prewarp_freq` (Hz, in [`1e-6f`, `1e12f`], however interally limited to
* avoid instability) is used.
*
* #### bw_iir1_coeffs_lp1()
* ```>>> */
@ -168,7 +226,15 @@ static inline void bw_iir1_coeffs_lp1(
float * BW_RESTRICT b1,
float * BW_RESTRICT a1);
/*! <<<```
* XXX
* Computes and puts coefficient values in `b0`, `b1`, and `a1` resulting in
* a first-order lowpass filter (6 dB/oct) with unitary DC gain, using the
* bilinear transform with prewarping.
*
* It takes the `sample_rate` (Hz, must be positive) and the `cutoff`
* frequency (Hz, in [`1e-6f`, `1e12f`]). If `prewarp_freq` is `0`, then the
* prewarping frequency matches `cutoff`, otherwise the value specified by
* `prewarp_freq` (Hz, in [`1e-6f`, `1e12f`], however interally limited to
* avoid instability) is used.
*
* #### bw_iir1_coeffs_ls1()
* ```>>> */
@ -183,7 +249,17 @@ static inline void bw_iir1_coeffs_ls1(
float * BW_RESTRICT b1,
float * BW_RESTRICT a1);
/*! <<<```
* XXX
* Computes and puts coefficient values in `b0`, `b1`, and `a1` resulting in
* a first-order high shelf filter (6 dB/oct) with unitary DC gain, using the
* bilinear transform with prewarping.
*
* It takes the `sample_rate` (Hz, must be positive), the `cutoff` frequency
* (Hz, in [`1e-6f`, `1e12f`]), and the `dc_gain`, either as linear gain
* (in [1e-30f, 1e30f]) if `dc_gain_dB` is `0`, or otherwise in dB (in
* [-600.f, 600.f]). If `prewarp_freq` is `0`, then the prewarping frequency
* matches `cutoff`, otherwise the value specified by `prewarp_freq` (Hz, in
* [`1e-6f`, `1e12f`], however interally limited to avoid instability) is
* used.
*
* #### bw_iir1_coeffs_mm1()
* ```>>> */
@ -198,7 +274,21 @@ static inline void bw_iir1_coeffs_mm1(
float * BW_RESTRICT b1,
float * BW_RESTRICT a1);
/*! <<<```
* XXX
* Computes and puts coefficient values in `b0`, `b1`, and `a1` resulting in
* a first-order filter implementing an approximation of the Laplace-domain
* transfer function
*
* > H(s) = coeff\_x + (2 pi fc coeff\_lp) / (s + 2 pi fc)
*
* where fc is the cutoff frequency, using the bilinear transform with
* prewarping.
*
* It takes the `sample_rate` (Hz, must be positive), the `cutoff` frequency
* (Hz, in [`1e-6f`, `1e12f`]), and output coefficients `coeff_x` and
* `coeff_lp` (both must be finite). If `prewarp_freq` is `0`, then the
* prewarping frequency matches `cutoff`, otherwise the value specified by
* `prewarp_freq` (Hz, in [`1e-6f`, `1e12f`], however interally limited to
* avoid instability) is used.
* }}} */
#if !defined(BW_CXX_NO_EXTERN_C) && defined(__cplusplus)

View File

@ -23,7 +23,13 @@
* version {{{ 1.0.0 }}}
* requires {{{ bw_common bw_math }}}
* description {{{
* XXX
* Lightweight and fast second-order IIR filter (biquad) in TDF-II form.
*
* This is not a regular DSP module, as it exposes state and coefficients,
* and it's not appropriate for time-varying operation. If you need that,
* check out [bw_ap2](bw_ap2), [bw_hs2](bw_hs2), [bw_ls2](bw_ls2),
* [bw_mm2](bw_mm2), [bw_notch](bw_notch), [bw_peak](bw_peak), and
* [bw_svf](bw_svf).
* }}}
* changelog {{{
* <ul>
@ -548,6 +554,7 @@ static inline void bw_iir2_process_multi(
#define BW_IIR2_COEFFS_COMMON \
prewarp_freq = prewarp_at_cutoff ? cutoff : prewarp_freq; \
prewarp_freq = bw_minf(prewarp_freq, 0.499f * sample_rate); \
const float t = bw_tanf(3.141592653589793f * prewarp_freq * bw_rcpf(sample_rate)); \
const float k1 = prewarp_freq * prewarp_freq; \
const float k2 = t * cutoff; \