Butterworth: use 2nd order components

When building a high-order Butterworth filter, split into 2nd-order
components, not 4th-order. Instability due to quantization effects has been
observed on real data even with double-precision floating point.
This commit is contained in:
Laurence Withers 2012-03-16 10:55:21 +00:00
parent 00b6427cca
commit 26456a3080
1 changed files with 8 additions and 3 deletions

View File

@ -103,8 +103,13 @@ iir_parser_raw(struct iir_filter_t** fi, const char* desc)
* The maximum order in any single Butterworth-type filter. If the given order * The maximum order in any single Butterworth-type filter. If the given order
* exceeds this, we split the resulting filter up into multiple sets of * exceeds this, we split the resulting filter up into multiple sets of
* coefficients of this order or less. * coefficients of this order or less.
*
* This is required since IIR filters, even with double-precision floating
* point numbers, are particularly susceptible to quantization errors. In
* practice, anything with a steeper roll-off than 2nd order can go unstable
* when presented with real input data.
*/ */
#define IIR_PARSER_BW_MAX_ORDER (4) #define IIR_PARSER_BW_MAX_ORDER (2)
@ -176,7 +181,7 @@ iir_parser_bw_aux2(struct iir_filter_t** fi,
} }
iir_coeff_free(coeff); iir_coeff_free(coeff);
if(!order) return 0; if(!order) return 0;
/* add a <4th order segment */ /* add a <2nd order segment */
} }
coeff = bw(order, gain, corner); coeff = bw(order, gain, corner);
@ -214,7 +219,7 @@ iir_parser_bw_aux3(struct iir_filter_t** fi,
} }
iir_coeff_free(coeff); iir_coeff_free(coeff);
if(!order) return 0; if(!order) return 0;
/* add a <4th order segment */ /* add a <2nd order segment */
} }
coeff = bw(order, gain, c1, c2); coeff = bw(order, gain, c1, c2);