miniDSP
A small C library for audio DSP
Loading...
Searching...
No Matches
biquad.c
Go to the documentation of this file.
1
33#include "biquad.h"
34
49smp_type BiQuad(smp_type sample, biquad *b)
50{
51 smp_type result;
52
53 /* Apply the difference equation */
54 result = b->a0 * sample
55 + b->a1 * b->x1
56 + b->a2 * b->x2
57 - b->a3 * b->y1
58 - b->a4 * b->y2;
59
60 /* Shift the input delay line */
61 b->x2 = b->x1;
62 b->x1 = sample;
63
64 /* Shift the output delay line */
65 b->y2 = b->y1;
66 b->y1 = result;
67
68 return result;
69}
70
88biquad *BiQuad_new(int type, smp_type dbGain,
89 smp_type freq, smp_type srate,
90 smp_type bandwidth)
91{
92 biquad *b;
93 smp_type A, omega, sn, cs, alpha, beta;
94 smp_type a0, a1, a2, b0, b1, b2;
95
96 b = malloc(sizeof(biquad));
97 if (b == nullptr)
98 return nullptr;
99
100 /* --- Compute intermediate variables ---
101 *
102 * A = linear amplitude from dB gain (used by PEQ and shelf filters)
103 * omega = angular frequency of the centre/corner in radians per sample
104 * sn = sin(omega)
105 * cs = cos(omega)
106 * alpha = controls the bandwidth (Q factor)
107 * beta = helper for shelf filter coefficients
108 */
109 A = pow(10.0, dbGain / 40.0);
110 omega = 2.0 * M_PI * freq / srate;
111 sn = sin(omega);
112 cs = cos(omega);
113 alpha = sn * sinh(M_LN2 / 2.0 * bandwidth * omega / sn);
114 /* beta * sn substitutes for the cookbook's 2*sqrt(A)*alpha in shelf
115 * filters (LSH/HSH). This is mathematically equivalent to fixing the
116 * shelf slope parameter S = 1 (steepest slope without resonance).
117 * Because of this, the 'bandwidth' parameter has no effect on LSH/HSH. */
118 beta = sqrt(A + A); /* = sqrt(2*A) */
119
120 switch (type) {
121
122 /* --- Low-Pass Filter ---
123 * Passes frequencies below 'freq', attenuates higher ones.
124 * Think of it as removing treble from an audio signal. */
125 case LPF:
126 b0 = (1.0 - cs) / 2.0;
127 b1 = 1.0 - cs;
128 b2 = (1.0 - cs) / 2.0;
129 a0 = 1.0 + alpha;
130 a1 = -2.0 * cs;
131 a2 = 1.0 - alpha;
132 break;
133
134 /* --- High-Pass Filter ---
135 * Passes frequencies above 'freq', attenuates lower ones.
136 * Useful for removing low-frequency rumble (wind noise, etc.). */
137 case HPF:
138 b0 = (1.0 + cs) / 2.0;
139 b1 = -(1.0 + cs);
140 b2 = (1.0 + cs) / 2.0;
141 a0 = 1.0 + alpha;
142 a1 = -2.0 * cs;
143 a2 = 1.0 - alpha;
144 break;
145
146 /* --- Band-Pass Filter ---
147 * Passes a range of frequencies centred on 'freq'.
148 * Width is controlled by 'bandwidth' (in octaves). */
149 case BPF:
150 b0 = alpha;
151 b1 = 0.0;
152 b2 = -alpha;
153 a0 = 1.0 + alpha;
154 a1 = -2.0 * cs;
155 a2 = 1.0 - alpha;
156 break;
157
158 /* --- Notch (Band-Reject) Filter ---
159 * Removes a narrow band of frequencies around 'freq'.
160 * Commonly used to eliminate 50/60 Hz mains hum. */
161 case NOTCH:
162 b0 = 1.0;
163 b1 = -2.0 * cs;
164 b2 = 1.0;
165 a0 = 1.0 + alpha;
166 a1 = -2.0 * cs;
167 a2 = 1.0 - alpha;
168 break;
169
170 /* --- Peaking EQ Filter ---
171 * Boosts or cuts a band of frequencies by 'dbGain' dB.
172 * This is the "parametric EQ" knob on a mixing console. */
173 case PEQ:
174 b0 = 1.0 + (alpha * A);
175 b1 = -2.0 * cs;
176 b2 = 1.0 - (alpha * A);
177 a0 = 1.0 + (alpha / A);
178 a1 = -2.0 * cs;
179 a2 = 1.0 - (alpha / A);
180 break;
181
182 /* --- Low Shelf Filter ---
183 * Boosts or cuts all frequencies below 'freq' by 'dbGain' dB.
184 * Like a bass knob on a stereo. */
185 case LSH:
186 b0 = A * ((A + 1.0) - (A - 1.0) * cs + beta * sn);
187 b1 = 2.0 * A * ((A - 1.0) - (A + 1.0) * cs);
188 b2 = A * ((A + 1.0) - (A - 1.0) * cs - beta * sn);
189 a0 = (A + 1.0) + (A - 1.0) * cs + beta * sn;
190 a1 = -2.0 * ((A - 1.0) + (A + 1.0) * cs);
191 a2 = (A + 1.0) + (A - 1.0) * cs - beta * sn;
192 break;
193
194 /* --- High Shelf Filter ---
195 * Boosts or cuts all frequencies above 'freq' by 'dbGain' dB.
196 * Like a treble knob on a stereo. */
197 case HSH:
198 b0 = A * ((A + 1.0) + (A - 1.0) * cs + beta * sn);
199 b1 = -2.0 * A * ((A - 1.0) + (A + 1.0) * cs);
200 b2 = A * ((A + 1.0) + (A - 1.0) * cs - beta * sn);
201 a0 = (A + 1.0) - (A - 1.0) * cs + beta * sn;
202 a1 = 2.0 * ((A - 1.0) - (A + 1.0) * cs);
203 a2 = (A + 1.0) - (A - 1.0) * cs - beta * sn;
204 break;
205
206 default:
207 free(b);
208 return nullptr;
209 }
210
211 /* Normalise all coefficients by dividing through by a0.
212 * This means the filter equation becomes:
213 * y[n] = a0*x[n] + a1*x[n-1] + a2*x[n-2] - a3*y[n-1] - a4*y[n-2]
214 * where a0..a4 are the normalised coefficients stored in the struct. */
215 b->a0 = b0 / a0;
216 b->a1 = b1 / a0;
217 b->a2 = b2 / a0;
218 b->a3 = a1 / a0;
219 b->a4 = a2 / a0;
220
221 /* Clear the delay lines (no previous samples yet) */
222 b->x1 = b->x2 = 0.0;
223 b->y1 = b->y2 = 0.0;
224
225 return b;
226}
smp_type BiQuad(smp_type sample, biquad *b)
Process one input sample through the biquad filter.
Definition biquad.c:49
biquad * BiQuad_new(int type, smp_type dbGain, smp_type freq, smp_type srate, smp_type bandwidth)
Create a new biquad filter with the specified characteristics.
Definition biquad.c:88
Biquad (second-order IIR) filter interface.
State and coefficients for a single biquad filter section.
Definition biquad.h:47