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 == NULL)
98 return NULL;
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 /* Guard: sin(omega) is zero when freq <= 0 or freq >= srate/2.
110 * The alpha formula divides by sin(omega), so bail out. */
111 if (freq <= 0.0 || freq >= srate / 2.0) {
112 free(b);
113 return NULL;
114 }
115
116 A = pow(10.0, dbGain / 40.0);
117 omega = 2.0 * M_PI * freq / srate;
118 sn = sin(omega);
119 cs = cos(omega);
120 alpha = sn * sinh(M_LN2 / 2.0 * bandwidth * omega / sn);
121 /* beta * sn substitutes for the cookbook's 2*sqrt(A)*alpha in shelf
122 * filters (LSH/HSH). This is mathematically equivalent to fixing the
123 * shelf slope parameter S = 1 (steepest slope without resonance).
124 * Because of this, the 'bandwidth' parameter has no effect on LSH/HSH. */
125 beta = sqrt(A + A); /* = sqrt(2*A) */
126
127 switch (type) {
128
129 /* --- Low-Pass Filter ---
130 * Passes frequencies below 'freq', attenuates higher ones.
131 * Think of it as removing treble from an audio signal. */
132 case LPF:
133 b0 = (1.0 - cs) / 2.0;
134 b1 = 1.0 - cs;
135 b2 = (1.0 - cs) / 2.0;
136 a0 = 1.0 + alpha;
137 a1 = -2.0 * cs;
138 a2 = 1.0 - alpha;
139 break;
140
141 /* --- High-Pass Filter ---
142 * Passes frequencies above 'freq', attenuates lower ones.
143 * Useful for removing low-frequency rumble (wind noise, etc.). */
144 case HPF:
145 b0 = (1.0 + cs) / 2.0;
146 b1 = -(1.0 + cs);
147 b2 = (1.0 + cs) / 2.0;
148 a0 = 1.0 + alpha;
149 a1 = -2.0 * cs;
150 a2 = 1.0 - alpha;
151 break;
152
153 /* --- Band-Pass Filter ---
154 * Passes a range of frequencies centred on 'freq'.
155 * Width is controlled by 'bandwidth' (in octaves). */
156 case BPF:
157 b0 = alpha;
158 b1 = 0.0;
159 b2 = -alpha;
160 a0 = 1.0 + alpha;
161 a1 = -2.0 * cs;
162 a2 = 1.0 - alpha;
163 break;
164
165 /* --- Notch (Band-Reject) Filter ---
166 * Removes a narrow band of frequencies around 'freq'.
167 * Commonly used to eliminate 50/60 Hz mains hum. */
168 case NOTCH:
169 b0 = 1.0;
170 b1 = -2.0 * cs;
171 b2 = 1.0;
172 a0 = 1.0 + alpha;
173 a1 = -2.0 * cs;
174 a2 = 1.0 - alpha;
175 break;
176
177 /* --- Peaking EQ Filter ---
178 * Boosts or cuts a band of frequencies by 'dbGain' dB.
179 * This is the "parametric EQ" knob on a mixing console. */
180 case PEQ:
181 b0 = 1.0 + (alpha * A);
182 b1 = -2.0 * cs;
183 b2 = 1.0 - (alpha * A);
184 a0 = 1.0 + (alpha / A);
185 a1 = -2.0 * cs;
186 a2 = 1.0 - (alpha / A);
187 break;
188
189 /* --- Low Shelf Filter ---
190 * Boosts or cuts all frequencies below 'freq' by 'dbGain' dB.
191 * Like a bass knob on a stereo. */
192 case LSH:
193 b0 = A * ((A + 1.0) - (A - 1.0) * cs + beta * sn);
194 b1 = 2.0 * A * ((A - 1.0) - (A + 1.0) * cs);
195 b2 = A * ((A + 1.0) - (A - 1.0) * cs - beta * sn);
196 a0 = (A + 1.0) + (A - 1.0) * cs + beta * sn;
197 a1 = -2.0 * ((A - 1.0) + (A + 1.0) * cs);
198 a2 = (A + 1.0) + (A - 1.0) * cs - beta * sn;
199 break;
200
201 /* --- High Shelf Filter ---
202 * Boosts or cuts all frequencies above 'freq' by 'dbGain' dB.
203 * Like a treble knob on a stereo. */
204 case HSH:
205 b0 = A * ((A + 1.0) + (A - 1.0) * cs + beta * sn);
206 b1 = -2.0 * A * ((A - 1.0) + (A + 1.0) * cs);
207 b2 = A * ((A + 1.0) + (A - 1.0) * cs - beta * sn);
208 a0 = (A + 1.0) - (A - 1.0) * cs + beta * sn;
209 a1 = 2.0 * ((A - 1.0) - (A + 1.0) * cs);
210 a2 = (A + 1.0) - (A - 1.0) * cs - beta * sn;
211 break;
212
213 default:
214 free(b);
215 return NULL;
216 }
217
218 /* Normalise all coefficients by dividing through by a0.
219 * This means the filter equation becomes:
220 * y[n] = a0*x[n] + a1*x[n-1] + a2*x[n-2] - a3*y[n-1] - a4*y[n-2]
221 * where a0..a4 are the normalised coefficients stored in the struct. */
222 b->a0 = b0 / a0;
223 b->a1 = b1 / a0;
224 b->a2 = b2 / a0;
225 b->a3 = a1 / a0;
226 b->a4 = a2 / a0;
227
228 /* Clear the delay lines (no previous samples yet) */
229 b->x1 = b->x2 = 0.0;
230 b->y1 = b->y2 = 0.0;
231
232 return b;
233}
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