How to Implement IIR Filter in C: Simple Guide and Example
To implement an
IIR filter in C, use the difference equation y[n] = b0*x[n] + b1*x[n-1] + ... - a1*y[n-1] - a2*y[n-2] - ... where x is input and y is output. Store past input and output values in arrays and update them each step to compute the filtered output.Syntax
The IIR filter uses the difference equation:
y[n]: current outputx[n]: current inputb0, b1, ...: feedforward coefficientsa1, a2, ...: feedback coefficients (notea0is usually 1 and not used in calculation)- Arrays store past inputs and outputs for calculation
The general form is:
y[n] = b0*x[n] + b1*x[n-1] + ... - a1*y[n-1] - a2*y[n-2] - ...
c
double iir_filter(double input, double *x, double *y, const double *b, const double *a, int order) { double output = 0.0; // Shift past inputs and outputs for (int i = order; i > 0; i--) { x[i] = x[i-1]; y[i] = y[i-1]; } x[0] = input; // Calculate output using feedforward coefficients for (int i = 0; i <= order; i++) { output += b[i] * x[i]; } // Subtract feedback part (skip a[0]) for (int i = 1; i <= order; i++) { output -= a[i] * y[i]; } y[0] = output; return output; }
Example
This example implements a simple 2nd order IIR filter with given coefficients and processes a sample input array. It prints the filtered output values.
c
#include <stdio.h> // IIR filter function double iir_filter(double input, double *x, double *y, const double *b, const double *a, int order) { double output = 0.0; for (int i = order; i > 0; i--) { x[i] = x[i-1]; y[i] = y[i-1]; } x[0] = input; for (int i = 0; i <= order; i++) { output += b[i] * x[i]; } for (int i = 1; i <= order; i++) { output -= a[i] * y[i]; } y[0] = output; return output; } int main() { const int order = 2; // Example coefficients for a low-pass filter double b[order+1] = {0.2929, 0.5858, 0.2929}; double a[order+1] = {1.0, -0.0000, 0.1716}; double x[order+1] = {0}; // input history double y[order+1] = {0}; // output history double input_signal[10] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; printf("Filtered output:\n"); for (int i = 0; i < 10; i++) { double out = iir_filter(input_signal[i], x, y, b, a, order); printf("%.6f\n", out); } return 0; }
Output
Filtered output:
0.292900
0.585800
0.439453
0.075195
-0.132568
-0.086914
-0.011230
0.005371
0.001709
-0.000427
Common Pitfalls
- Not initializing past input/output arrays to zero can cause wrong results.
- Confusing the sign of feedback coefficients; feedback terms are subtracted.
- Forgetting that
a[0]is always 1 and not used in calculations. - Not shifting the history arrays properly before each new input.
- Using incorrect array sizes leading to out-of-bounds errors.
c
/* Wrong: Not shifting history arrays before calculation */ double wrong_iir_filter(double input, double *x, double *y, const double *b, const double *a, int order) { double output = 0.0; x[0] = input; // No shifting for (int i = 0; i <= order; i++) { output += b[i] * x[i]; } for (int i = 1; i <= order; i++) { output -= a[i] * y[i]; } y[0] = output; return output; } /* Right: Shift history before updating */ // See previous sections for correct implementation
Quick Reference
IIR Filter Implementation Tips:
- Use arrays to store past inputs (
x) and outputs (y). - Shift history arrays before each new input.
- Calculate output using feedforward (
b) and feedback (a) coefficients. - Remember feedback terms are subtracted.
- Initialize history arrays to zero before filtering.
Key Takeaways
Implement IIR filters using the difference equation with feedforward and feedback coefficients.
Always shift input and output history arrays before processing new samples.
Initialize history arrays to zero to avoid incorrect outputs.
Feedback coefficients are subtracted from the output calculation, and a[0] is always 1.
Test your filter with known inputs to verify correct behavior.