bw_iir1 debbugging code

This commit is contained in:
Stefano D'Angelo 2025-01-28 19:27:08 +01:00
parent a6d52765a6
commit ee327ebe80

View File

@ -253,11 +253,27 @@ static void bw_iir1_reset(
float b0,
float b1,
float a1) {
// -1<a1<1
const float d = bw_rcpf(1.f + a1);
const float k = d * x_0;
*y_0 = k * (b1 + b0);
*s_0 = k * (b1 - a1 * b0);
BW_ASSERT(bw_is_finite(x_0));
BW_ASSERT(y_0 != BW_NULL);
BW_ASSERT(s_0 != BW_NULL);
BW_ASSERT(y_0 != s_0);
BW_ASSERT(bw_is_finite(b0));
BW_ASSERT(bw_is_finite(b1));
BW_ASSERT(bw_is_finite(a1));
BW_ASSERT(-1.f <= a1 <= 1.f);
if (a1 == -1.f) {
*y_0 = 0.f;
*s_0 = 0.f;
} else {
const float d = bw_rcpf(1.f + a1);
const float k = d * x_0;
*y_0 = k * (b1 + b0);
*s_0 = k * (b1 - a1 * b0);
}
BW_ASSERT(bw_is_finite(*y_0));
BW_ASSERT(bw_is_finite(*s_0));
}
static inline void bw_iir1_reset_multi(
@ -268,6 +284,15 @@ static inline void bw_iir1_reset_multi(
float b1,
float a1,
size_t n_channels) {
BW_ASSERT(x_0 != BW_NULL);
BW_ASSERT(bw_has_only_finite(x_0, n_channels));
BW_ASSERT(s_0 == BW_NULL || x_0 != s_0);
BW_ASSERT(y_0 == BW_NULL || s_0 == BW_NULL || y_0 != s_0);
BW_ASSERT(bw_is_finite(b0));
BW_ASSERT(bw_is_finite(b1));
BW_ASSERT(bw_is_finite(a1));
BW_ASSERT(-1.f <= a1 <= 1.f);
if (y_0 != BW_NULL) {
if (s_0 != BW_NULL)
for (size_t i = 0; i < n_channels; i++)
@ -286,6 +311,9 @@ static inline void bw_iir1_reset_multi(
else
{} // no need to do anything
}
BW_ASSERT_DEEP(y_0 != BW_NULL ? bw_has_only_finite(y_0, n_channels) : 1);
BW_ASSERT_DEEP(s_0 != BW_NULL ? bw_has_only_finite(s_0, n_channels) : 1);
}
static inline void bw_iir1_process1(
@ -295,8 +323,21 @@ static inline void bw_iir1_process1(
float b0,
float b1,
float a1) {
BW_ASSERT(bw_is_finite(x));
BW_ASSERT(y != BW_NULL);
BW_ASSERT(s != BW_NULL);
BW_ASSERT(y != s);
BW_ASSERT(bw_is_finite(*s));
BW_ASSERT(bw_is_finite(b0));
BW_ASSERT(bw_is_finite(b1));
BW_ASSERT(bw_is_finite(a1));
BW_ASSERT(-1.f <= a1 <= 1.f);
*y = b0 * x + *s;
*s = b1 * x - a1 * *y;
BW_ASSERT(bw_is_finite(*y));
BW_ASSERT(bw_is_finite(*s));
}
static inline void bw_iir1_process(
@ -307,8 +348,23 @@ static inline void bw_iir1_process(
float b1,
float a1,
size_t n_samples) {
BW_ASSERT(x != BW_NULL);
BW_ASSERT(bw_has_only_finite(x, n_channels));
BW_ASSERT(y != BW_NULL);
BW_ASSERT(s != BW_NULL);
BW_ASSERT(x != s);
BW_ASSERT(y != s);
BW_ASSERT(bw_is_finite(*s));
BW_ASSERT(bw_is_finite(b0));
BW_ASSERT(bw_is_finite(b1));
BW_ASSERT(bw_is_finite(a1));
BW_ASSERT(-1.f <= a1 <= 1.f);
for (size_t i = 0; i < n_samples; i++)
bw_iir1_process1(x[i], y + i, s, b0, b1, a1);
BW_ASSERT_DEEP(bw_has_only_finite(y, n_channels));
BW_ASSERT(bw_is_finite(*s));
}
static inline void bw_iir1_process_multi(
@ -320,13 +376,42 @@ static inline void bw_iir1_process_multi(
float a1,
size_t n_channels,
size_t n_samples) {
BW_ASSERT(x != BW_NULL);
BW_ASSERT(y != BW_NULL);
BW_ASSERT(s != BW_NULL);
#ifndef BW_NO_DEBUG
for (size_t i = 0; i < n_channels; i++) {
BW_ASSERT(x[i] != BW_NULL);
BW_ASSERT_DEEP(bw_has_only_finite(x[i], n_samples));
BW_ASSERT(y[i] != BW_NULL);
}
for (size_t i = 0; i < n_channels; i++)
for (size_t j = i + 1; j < n_channels; j++)
BW_ASSERT(y[i] != y[j]);
for (size_t i = 0; i < n_channels; i++)
for (size_t j = 0; j < n_channels; j++)
BW_ASSERT(i == j || x[i] != y[j]);
for (size_t i = 0; i < n_channels; i++)
BW_ASSERT(bw_is_finite(s[i]));
#endif
BW_ASSERT(bw_is_finite(b0));
BW_ASSERT(bw_is_finite(b1));
BW_ASSERT(bw_is_finite(a1));
BW_ASSERT(-1.f <= a1 <= 1.f);
for (size_t i = 0; i < n_samples; i++)
for (size_t j = 0; j < n_channels; j++)
bw_iir1_process1(x[j][i], y[j] + i, s + j, b0, b1, a1);
#ifndef BW_NO_DEBUG
for (size_t i = 0; i < n_channels; i++)
BW_ASSERT_DEEP(bw_has_only_finite(y[i], n_samples));
#endif
}
#define BW_IIR1_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 k = t * cutoff; \
const float d = bw_rcpf(k + prewarp_freq); \
@ -340,9 +425,26 @@ static inline void bw_iir1_coeffs_ap1(
float * BW_RESTRICT b0,
float * BW_RESTRICT b1,
float * BW_RESTRICT a1) {
BW_ASSERT(bw_is_finite(sample_rate));
BW_ASSERT(sample_rate > 0.f);
BW_ASSERT(bw_is_finite(cutoff));
BW_ASSERT(cutoff >= 1e-6f && cutoff <= 1e12f);
BW_ASSERT(prewarp_at_cutoff ? bw_is_finite(prewarp_freq) : 1);
BW_ASSERT(prewarp_at_cutoff ? prewarp_freq >= 1e-6f && prewarp_freq <= 1e12f : 1);
BW_ASSERT(b0 != BW_NULL);
BW_ASSERT(b1 != BW_NULL);
BW_ASSERT(a1 != BW_NULL);
BW_ASSERT(b0 != b1);
BW_ASSERT(b0 != a1);
BW_ASSERT(b1 != a1);
BW_IIR1_COEFFS_COMMON
*b0 = *a1;
*b1 = 1.f;
BW_ASSERT(bw_is_finite(*b0));
BW_ASSERT(bw_is_finite(*b1));
BW_ASSERT(bw_is_finite(*a1));
}
static inline void bw_iir1_coeffs_hp1(
@ -353,9 +455,26 @@ static inline void bw_iir1_coeffs_hp1(
float * BW_RESTRICT b0,
float * BW_RESTRICT b1,
float * BW_RESTRICT a1) {
BW_ASSERT(bw_is_finite(sample_rate));
BW_ASSERT(sample_rate > 0.f);
BW_ASSERT(bw_is_finite(cutoff));
BW_ASSERT(cutoff >= 1e-6f && cutoff <= 1e12f);
BW_ASSERT(prewarp_at_cutoff ? bw_is_finite(prewarp_freq) : 1);
BW_ASSERT(prewarp_at_cutoff ? prewarp_freq >= 1e-6f && prewarp_freq <= 1e12f : 1);
BW_ASSERT(b0 != BW_NULL);
BW_ASSERT(b1 != BW_NULL);
BW_ASSERT(a1 != BW_NULL);
BW_ASSERT(b0 != b1);
BW_ASSERT(b0 != a1);
BW_ASSERT(b1 != a1);
BW_IIR1_COEFFS_COMMON
*b0 = d * (k - prewarp_freq);
*b1 = -*b0;
BW_ASSERT(bw_is_finite(*b0));
BW_ASSERT(bw_is_finite(*b1));
BW_ASSERT(bw_is_finite(*a1));
}
static inline void bw_iir1_coeffs_hs1_lin(
@ -367,11 +486,31 @@ static inline void bw_iir1_coeffs_hs1_lin(
float * BW_RESTRICT b0,
float * BW_RESTRICT b1,
float * BW_RESTRICT a1) {
BW_ASSERT(bw_is_finite(sample_rate));
BW_ASSERT(sample_rate > 0.f);
BW_ASSERT(bw_is_finite(cutoff));
BW_ASSERT(cutoff > 0.f);
BW_ASSERT(prewarp_at_cutoff ? bw_is_finite(prewarp_freq) : 1);
BW_ASSERT(prewarp_at_cutoff ? prewarp_freq >= 1e-6f && prewarp_freq <= 1e12f : 1);
BW_ASSERT(bw_is_finite(high_gain_lin));
BW_ASSERT(high_gain_lin >= 1e-30f && high_gain_lin <= 1e30f);
BW_ASSERT(cutoff * bw_sqrtf(high_gain_lin) >= 1e-6f && cutoff * bw_sqrtf(high_gain_lin) <= 1e12f);
BW_ASSERT(b0 != BW_NULL);
BW_ASSERT(b1 != BW_NULL);
BW_ASSERT(a1 != BW_NULL);
BW_ASSERT(b0 != b1);
BW_ASSERT(b0 != a1);
BW_ASSERT(b1 != a1);
cutoff = cutoff * bw_sqrtf(high_gain_lin);
BW_IIR1_COEFFS_COMMON
const float k2 = high_gain_lin * prewarp_freq;
*b0 = d * (k + k2);
*b1 = d * (k - k2);
BW_ASSERT(bw_is_finite(*b0));
BW_ASSERT(bw_is_finite(*b1));
BW_ASSERT(bw_is_finite(*a1));
}
static inline void bw_iir1_coeffs_hs1_dB(
@ -383,6 +522,9 @@ static inline void bw_iir1_coeffs_hs1_dB(
float * BW_RESTRICT b0,
float * BW_RESTRICT b1,
float * BW_RESTRICT a1) {
BW_ASSERT(bw_is_finite(high_gain_dB));
BW_ASSERT(high_gain_dB >= -600.f && high_gain_dB <= 600.f);
bw_iir1_coeffs_hs1_lin(sample_rate, cutoff, prewarp_at_cutoff, prewarp_freq, bw_dB2linf(high_gain_dB), b0, b1, a1);
}
@ -394,9 +536,26 @@ static inline void bw_iir1_coeffs_lp1(
float * BW_RESTRICT b0,
float * BW_RESTRICT b1,
float * BW_RESTRICT a1) {
BW_ASSERT(bw_is_finite(sample_rate));
BW_ASSERT(sample_rate > 0.f);
BW_ASSERT(bw_is_finite(cutoff));
BW_ASSERT(cutoff >= 1e-6f && cutoff <= 1e12f);
BW_ASSERT(prewarp_at_cutoff ? bw_is_finite(prewarp_freq) : 1);
BW_ASSERT(prewarp_at_cutoff ? prewarp_freq >= 1e-6f && prewarp_freq <= 1e12f : 1);
BW_ASSERT(b0 != BW_NULL);
BW_ASSERT(b1 != BW_NULL);
BW_ASSERT(a1 != BW_NULL);
BW_ASSERT(b0 != b1);
BW_ASSERT(b0 != a1);
BW_ASSERT(b1 != a1);
BW_IIR1_COEFFS_COMMON
*b0 = d * k;
*b1 = *b0;
BW_ASSERT(bw_is_finite(*b0));
BW_ASSERT(bw_is_finite(*b1));
BW_ASSERT(bw_is_finite(*a1));
}
static inline void bw_iir1_coeffs_ls1_lin(
@ -408,11 +567,31 @@ static inline void bw_iir1_coeffs_ls1_lin(
float * BW_RESTRICT b0,
float * BW_RESTRICT b1,
float * BW_RESTRICT a1) {
BW_ASSERT(bw_is_finite(sample_rate));
BW_ASSERT(sample_rate > 0.f);
BW_ASSERT(bw_is_finite(cutoff));
BW_ASSERT(cutoff > 0.f);
BW_ASSERT(prewarp_at_cutoff ? bw_is_finite(prewarp_freq) : 1);
BW_ASSERT(prewarp_at_cutoff ? prewarp_freq >= 1e-6f && prewarp_freq <= 1e12f : 1);
BW_ASSERT(bw_is_finite(dc_gain_lin));
BW_ASSERT(dc_gain_lin >= 1e-30f && dc_gain_lin <= 1e30f);
BW_ASSERT(cutoff * bw_rcpf(bw_sqrtf(dc_gain_lin)) >= 1e-6f && cutoff * bw_rcpf(bw_sqrtf(dc_gain_lin)) <= 1e12f);
BW_ASSERT(b0 != BW_NULL);
BW_ASSERT(b1 != BW_NULL);
BW_ASSERT(a1 != BW_NULL);
BW_ASSERT(b0 != b1);
BW_ASSERT(b0 != a1);
BW_ASSERT(b1 != a1);
cutoff = cutoff * bw_rcpf(bw_sqrtf(dc_gain_lin));
BW_IIR1_COEFFS_COMMON
const float k2 = dc_gain_lin * k;
*b0 = d * (k2 + prewarp_freq);
*b1 = d * (k2 - prewarp_freq);
BW_ASSERT(bw_is_finite(*b0));
BW_ASSERT(bw_is_finite(*b1));
BW_ASSERT(bw_is_finite(*a1));
}
static inline void bw_iir1_coeffs_ls1_dB(
@ -424,6 +603,9 @@ static inline void bw_iir1_coeffs_ls1_dB(
float * BW_RESTRICT b0,
float * BW_RESTRICT b1,
float * BW_RESTRICT a1) {
BW_ASSERT(bw_is_finite(dc_gain_dB));
BW_ASSERT(dc_gain_dB >= -600.f && dc_gain_dB <= 600.f);
bw_iir1_coeffs_ls1_lin(sample_rate, cutoff, prewarp_at_cutoff, prewarp_freq, bw_dB2linf(dc_gain_dB), b0, b1, a1);
}
@ -437,11 +619,28 @@ static inline void bw_iir1_coeffs_mm1(
float * BW_RESTRICT b0,
float * BW_RESTRICT b1,
float * BW_RESTRICT a1) {
BW_ASSERT(bw_is_finite(sample_rate));
BW_ASSERT(sample_rate > 0.f);
BW_ASSERT(bw_is_finite(cutoff));
BW_ASSERT(cutoff >= 1e-6f && cutoff <= 1e12f);
BW_ASSERT(prewarp_at_cutoff ? bw_is_finite(prewarp_freq) : 1);
BW_ASSERT(prewarp_at_cutoff ? prewarp_freq >= 1e-6f && prewarp_freq <= 1e12f : 1);
BW_ASSERT(b0 != BW_NULL);
BW_ASSERT(b1 != BW_NULL);
BW_ASSERT(a1 != BW_NULL);
BW_ASSERT(b0 != b1);
BW_ASSERT(b0 != a1);
BW_ASSERT(b1 != a1);
BW_IIR1_COEFFS_COMMON
const float k2 = prewarp_freq * coeff_x;
const float k3 = k * (coeff_lp + coeff_x);
*b0 = d * (k3 + k2);
*b1 = d * (k3 - k2);
BW_ASSERT(bw_is_finite(*b0));
BW_ASSERT(bw_is_finite(*b1));
BW_ASSERT(bw_is_finite(*a1));
}
#undef BW_IIR1_COEFFS_COMMON