/[svn]/linuxsampler/trunk/src/engines/common/BiquadFilter.h
ViewVC logotype

Contents of /linuxsampler/trunk/src/engines/common/BiquadFilter.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 617 - (show annotations) (download) (as text)
Wed Jun 8 21:00:06 2005 UTC (18 years, 10 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 24402 byte(s)
* hand-crafted assembly optimization code can be disabled with
  './configure --disable-asm' (definitely not recommended)

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 Christian Schoenebeck *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 ***************************************************************************/
23
24 #ifndef __LS_BIQUADFILTER_H__
25 #define __LS_BIQUADFILTER_H__
26
27 #include <math.h>
28
29 #include "../../common/global.h"
30
31 /// ln(2) / 2
32 #define LN_2_2 0.34657359f
33
34 #ifndef LIMIT
35 # define LIMIT(v,l,u) (v < l ? l : (v > u ? u : v))
36 #endif
37
38 namespace LinuxSampler {
39
40 typedef float bq_t;
41
42 /**
43 * Internal parameters of the biquad filter, which are actually the
44 * final parameters of the filter's transfer function. This strucure is
45 * only needed when these parameters should stored outside the
46 * BiquadFilter class, e.g. to save calculation time by sharing them
47 * between multiple filters.
48 */
49 struct biquad_param_t {
50 bq_t b0;
51 bq_t b1;
52 bq_t b2;
53 bq_t a1;
54 bq_t a2;
55 };
56
57 /**
58 * Bi-quadratic filter
59 * (adapted from lisp code by Eli Brandt, http://www.cs.cmu.edu/~eli/)
60 */
61 class BiquadFilter {
62 protected:
63 // following five variables are only used if no external biquad_param_t reference is used
64 bq_t b0;
65 bq_t b1;
66 bq_t b2;
67 bq_t a1;
68 bq_t a2;
69 // following four variables are used to buffer the feedback
70 bq_t x1;
71 bq_t x2;
72 bq_t y1;
73 bq_t y2;
74
75 const static float fbc = 0.98;
76
77 /**
78 * Prevent \a f from going into denormal mode which would slow down
79 * subsequent floating point calculations, we achieve that by setting
80 * \a f to zero when it falls under the denormal threshold value.
81 */
82 inline void KillDenormal(bq_t& f) {
83 // TODO: this is a generic solution for 32bit floats, should be replaced by CPU specific asm code
84 f += 1e-18f;
85 f -= 1e-18f;
86 }
87 public:
88 BiquadFilter() {
89 Reset();
90 }
91
92 void Reset() {
93 x1 = 0.0f;
94 x2 = 0.0f;
95 y1 = 0.0f;
96 y2 = 0.0f;
97 }
98
99 inline bq_t Apply(const bq_t x) {
100 bq_t y;
101
102 y = this->b0 * x + this->b1 * this->x1 + this->b2 * this->x2 +
103 this->a1 * this->y1 + this->a2 * this->y2;
104 KillDenormal(y);
105 this->x2 = this->x1;
106 this->x1 = x;
107 this->y2 = this->y1;
108 this->y1 = y;
109
110 return y;
111 }
112
113 inline bq_t Apply(biquad_param_t* param, const bq_t x) {
114 bq_t y;
115
116 y = param->b0 * x + param->b1 * this->x1 + param->b2 * this->x2 +
117 param->a1 * this->y1 + param->a2 * this->y2;
118 KillDenormal(y);
119 this->x2 = this->x1;
120 this->x1 = x;
121 this->y2 = this->y1;
122 this->y1 = y;
123
124 return y;
125 }
126
127 #if CONFIG_ASM && ARCH_X86
128 // expects to find input in xmm0 (xmm0 stays unmodified) and finally leaves output in xmm6
129 inline void Apply4StepsSSE(biquad_param_t* param) {
130 __asm__ __volatile__ (
131 "movss (%2),%%xmm4 # b0\n\t"
132 "shufps $0x00,%%xmm4,%%xmm4 # copy b0 to other cells\n\t"
133 "mulps %%xmm0,%%xmm4 # xmm4 = x*b0\n\t"
134 "movups (%0),%%xmm2 # load b1,b2,a1,a2\n\t"
135 "movups (%1),%%xmm5 # load x1,x2,y1,y2\n\t"
136 /* sample 0 */
137 "movaps %%xmm5,%%xmm3\n\t"
138 "mulps %%xmm2,%%xmm5 # xmm5 = [b1,b2,a1,a2] * [x1,x2,y1,y2]\n\t"
139 "shufps $0x0a,%%xmm3,%%xmm3 # x2 = x1, y2 = y1\n\t"
140 "movss %%xmm4,%%xmm6\n\t"
141 "addss %%xmm5,%%xmm6\n\t"
142 "shufps $0x39,%%xmm5,%%xmm5\n\t"
143 "addss %%xmm5,%%xmm6\n\t"
144 "shufps $0x39,%%xmm5,%%xmm5\n\t"
145 "addss %%xmm5,%%xmm6\n\t"
146 "shufps $0x39,%%xmm5,%%xmm5\n\t"
147 "addss %%xmm5,%%xmm6 # xmm6 = b0*x + b1*x1 + b2*x2 + a1*y1 + a2*y2\n\t"
148 /* sample 1 */
149 "shufps $0x39,%%xmm4,%%xmm4 # rotate xmm4 down 1 cell\n\t"
150 "movss %%xmm6,%%xmm3 # y1 = y\n\t"
151 "shufps $0x4e,%%xmm3,%%xmm3 # rotate 2 cells\n\t"
152 "movss %%xmm0,%%xmm3 # x1 = x\n\t"
153 "shufps $0x93,%%xmm6,%%xmm6 # rotate output up 1 cell\n\t"
154 "movaps %%xmm3,%%xmm5\n\t"
155 "shufps $0x39,%%xmm0,%%xmm0 # rotate input down 1 cell\n\t"
156 "mulps %%xmm2,%%xmm5 # xmm5 = [b1,b2,a1,a2] * [x1,x2,y1,y2]\n\t"
157 "movss %%xmm5,%%xmm6\n\t"
158 "addss %%xmm4,%%xmm6\n\t"
159 "shufps $0x39,%%xmm5,%%xmm5\n\t"
160 "addss %%xmm5,%%xmm6\n\t"
161 "shufps $0x39,%%xmm5,%%xmm5\n\t"
162 "addss %%xmm5,%%xmm6\n\t"
163 "shufps $0x39,%%xmm5,%%xmm5\n\t"
164 "addss %%xmm5,%%xmm6 # xmm6 = b0*x + b1*x1 + b2*x2 + a1*y1 + a2*y2\n\t"
165 /* sample 2 */
166 "shufps $0x0a,%%xmm3,%%xmm3 # x2 = x1, y2 = y1\n\t"
167 "shufps $0x39,%%xmm4,%%xmm4 # rotate xmm4 down 1 cell\n\t"
168 "movss %%xmm6,%%xmm3 # y1 = y\n\t"
169 "shufps $0x4e,%%xmm3,%%xmm3 # rotate 2 cells\n\t"
170 "movss %%xmm0,%%xmm3 # x1 = x\n\t"
171 "shufps $0x93,%%xmm6,%%xmm6 # rotate output up 1 cell\n\t"
172 "movaps %%xmm3,%%xmm5\n\t"
173 "shufps $0x39,%%xmm0,%%xmm0 # rotate input down 1 cell\n\t"
174 "mulps %%xmm2,%%xmm5 # xmm5 = [b1,b2,a1,a2] * [x1,x2,y1,y2]\n\t"
175 "movss %%xmm5,%%xmm6\n\t"
176 "addss %%xmm4,%%xmm6\n\t"
177 "shufps $0x39,%%xmm5,%%xmm5\n\t"
178 "addss %%xmm5,%%xmm6\n\t"
179 "shufps $0x39,%%xmm5,%%xmm5\n\t"
180 "addss %%xmm5,%%xmm6\n\t"
181 "shufps $0x39,%%xmm5,%%xmm5\n\t"
182 "addss %%xmm5,%%xmm6 # xmm6 = b0*x + b1*x1 + b2*x2 + a1*y1 + a2*y2\n\t"
183 /* sample 3 */
184 "shufps $0x0a,%%xmm3,%%xmm3 # x2 = x1, y2 = y1\n\t"
185 "shufps $0x39,%%xmm4,%%xmm4 # rotate xmm4 down 1 cell\n\t"
186 "movss %%xmm6,%%xmm3 # y1 = y\n\t"
187 "shufps $0x4e,%%xmm3,%%xmm3 # rotate 2 cells\n\t"
188 "movss %%xmm0,%%xmm3 # x1 = x\n\t"
189 "shufps $0x93,%%xmm6,%%xmm6 # rotate output up 1 cell\n\t"
190 "mulps %%xmm3,%%xmm2 # xmm5 = [b1,b2,a1,a2] * [x1,x2,y1,y2]\n\t"
191 "shufps $0x39,%%xmm0,%%xmm0 # rotate input down 1 cell\n\t"
192 "movss %%xmm2,%%xmm6\n\t"
193 "shufps $0x39,%%xmm2,%%xmm2\n\t"
194 "addss %%xmm2,%%xmm6\n\t"
195 "shufps $0x39,%%xmm2,%%xmm2\n\t"
196 "addss %%xmm2,%%xmm6\n\t"
197 "shufps $0x39,%%xmm2,%%xmm2\n\t"
198 "addss %%xmm2,%%xmm6\n\t"
199 "addss %%xmm4,%%xmm6 # xmm6 = b0*x + b1*x1 + b2*x2 + a1*y1 + a2*y2\n\t"
200 /* done */
201 "shufps $0x0a,%%xmm3,%%xmm3 # x2 = x1, y2 = y1\n\t"
202 "movss %%xmm6,%%xmm3 # y1 = y\n\t"
203 "shufps $0x4e,%%xmm3,%%xmm3 # rotate 2 cells\n\t"
204 "movss %%xmm0,%%xmm3 # x1 = x\n\t"
205 "shufps $0x1b,%%xmm6,%%xmm6 # swap output to correct order\n\t"
206 "shufps $0x39,%%xmm0,%%xmm0 # rotate input down 1 cell, to restore original input\n\t"
207 "movups %%xmm3,(%1) # store x1,x2,y1,y2\n\t"
208 : /* no output */
209 : "r" (&param->b1), /* %0 - [b1,b2,a1,a2] */
210 "r" (&x1), /* %1 - [x1,x2,y1,y2] */
211 "r" (&param->b0) /* %2 */
212 );
213 }
214 #endif // CONFIG_ASM && ARCH_X86
215
216 inline bq_t ApplyFB(bq_t x, const bq_t fb) {
217 bq_t y;
218
219 x += this->y1 * fb * 0.98;
220 y = this->b0 * x + this->b1 * this->x1 + this->b2 * this->x2 +
221 this->a1 * this->y1 + this->a2 * this->y2;
222 KillDenormal(y);
223 this->x2 = this->x1;
224 this->x1 = x;
225 this->y2 = this->y1;
226 this->y1 = y;
227
228 return y;
229 }
230
231 inline bq_t ApplyFB(biquad_param_t* param, bq_t x, const bq_t fb) {
232 bq_t y;
233
234 x += this->y1 * fb * 0.98;
235 y = param->b0 * x + param->b1 * this->x1 + param->b2 * this->x2 +
236 param->a1 * this->y1 + param->a2 * this->y2;
237 KillDenormal(y);
238 this->x2 = this->x1;
239 this->x1 = x;
240 this->y2 = this->y1;
241 this->y1 = y;
242
243 return y;
244 }
245
246 #if CONFIG_ASM && ARCH_X86
247 // expects to find input in xmm0 (xmm0 stays unmodified) and finally leaves output in xmm7
248 inline void ApplyFB4StepsSSE(biquad_param_t* param, const bq_t &fb) {
249 float xs, ys;
250 float t0, t1, t2, t3, t4, t5, t6, t7, t8; // temporary stack space
251 __asm__ __volatile__ (
252 /* prepare input */
253 "movss %15,%%xmm5\n\t"
254 "movss %%xmm0,(%14)\n\t"
255 /* sample 0 */
256 "movss %0, %%xmm3\n\t"
257 "movss %1, %%xmm4\n\t"
258 "mulss %%xmm4, %%xmm5\n\t"
259 "movss %%xmm3, %2\n\t"
260 "movss %%xmm5, %16\n\t"
261 "mulss %%xmm3, %%xmm5\n\t"
262 "movss %19, %%xmm2\n\t"
263 "movss %3, %%xmm6\n\t"
264 "movss %21, %%xmm3\n\t"
265 "addss %%xmm5, %%xmm6\n\t"
266 "movss %%xmm2, %%xmm5\n\t"
267 "movss %20, %%xmm4\n\t"
268 "movss %%xmm6, %4\n\t"
269 "mulss %%xmm6, %%xmm5\n\t"
270 "movss %5, %%xmm6\n\t"
271 "movss %%xmm2, %6\n\t"
272 "movss %%xmm4, %7\n\t"
273 "movss %%xmm3, %%xmm2\n\t"
274 "mulss %%xmm6, %%xmm4\n\t"
275 "mulss %8, %%xmm2\n\t"
276 "movss %%xmm3, %9\n\t"
277 "addss %%xmm4, %%xmm5\n\t"
278 "movss %18, %%xmm3\n\t"
279 "movss %17, %%xmm4\n\t"
280 "addss %%xmm2, %%xmm5\n\t"
281 "movss %%xmm4, %10\n\t"
282 "movss %%xmm3, %%xmm2\n\t"
283 "mulss %11, %%xmm4\n\t"
284 "mulss %12, %%xmm2\n\t"
285 "movss %%xmm3, %13\n\t"
286 "addss %%xmm4, %%xmm5\n\t"
287 "movss %11, %%xmm3\n\t"
288 "movss %4, %%xmm4\n\t"
289 "addss %%xmm2, %%xmm5\n\t"
290 :: "m" (y1), /* %0 */
291 "m" (fbc), /* %1 */
292 "m" (t0), /* %2 */
293 "m" (xs), /* %3 */
294 "m" (t7), /* %4 */
295 "m" (x1), /* %5 */
296 "m" (t1), /* %6 */
297 "m" (t2), /* %7 */
298 "m" (x2), /* %8 */
299 "m" (t3), /* %9 */
300 "m" (t4), /* %10 */
301 "m" (t0), /* %11 */
302 "m" (y2), /* %12 */
303 "m" (t5), /* %13 */
304 "r" (&xs), /* %14 */
305 "m" (fb), /* %15 */
306 "m" (ys), /* %16 */
307 "m" (param->a1), /* %17 */
308 "m" (param->a2), /* %18 */
309 "m" (param->b0), /* %19 */
310 "m" (param->b1), /* %20 */
311 "m" (param->b2) /* %21 */
312 );
313 __asm__ __volatile__ (
314 "shufps $0x39,%%xmm0,%%xmm0 # rotate down one cell\n\t"
315 "movss %%xmm5,%%xmm7\n\t"
316 ::
317 );
318 /* sample 1 */
319 __asm__ __volatile__ (
320 "movss %0, %%xmm4\n\t"
321 "movss %%xmm0, %%xmm3\n\t"
322 "mulss %%xmm5, %%xmm4\n\t"
323 "mulss %3, %%xmm6\n\t"
324 "movss %5, %%xmm2\n\t"
325 "addss %%xmm4, %%xmm3\n\t"
326 "mulss %7, %%xmm2\n\t"
327 "movss %6, %%xmm4\n\t"
328 "movss %%xmm3, %8\n\t"
329 "mulss %%xmm3, %%xmm4\n\t"
330 "addss %%xmm2, %%xmm4\n\t"
331 "movss %9, %%xmm3\n\t"
332 "mulss %%xmm5, %%xmm3\n\t"
333 "movss %10, %%xmm2\n\t"
334 "addss %%xmm6, %%xmm4\n\t"
335 "mulss %11, %%xmm2\n\t"
336 "addss %%xmm3, %%xmm4\n\t"
337 "addss %%xmm2, %%xmm4\n\t"
338 :: "m" (ys), /* %0 */
339 "m" (fbc), /* %1 */
340 "m" (xs), /* %2 */
341 "m" (t3), /* %3 */
342 "m" (y2), /* %4 */
343 "m" (t2), /* %5 */
344 "m" (t1), /* %6 */
345 "m" (t7), /* %7 */
346 "m" (t8), /* %8 */
347 "m" (t4), /* %9 */
348 "m" (t5), /* %10 */
349 "m" (t0), /* %11 */
350 "m" (x2), /* %12 */
351 "m" (x1), /* %13 */
352 "m" (y1) /* %14 */
353 );
354 __asm__ __volatile__ (
355 "shufps $0x93,%%xmm7,%%xmm7 # rotate up one cell\n\t"
356 "shufps $0x39,%%xmm0,%%xmm0 # rotate down one cell\n\t"
357 "movss %%xmm4,%%xmm7\n\t"
358 ::
359 );
360 /* sample 2 */
361 __asm__ __volatile__ (
362 "movss %2, %%xmm6\n\t"
363 "movss %3, %%xmm3\n\t"
364 "mulss %%xmm4, %%xmm6\n\t"
365 "movss %4, %%xmm2\n\t"
366 "mulss %9, %%xmm2\n\t"
367 "addss %%xmm0, %%xmm6\n\t"
368 "mulss %7, %%xmm5\n\t"
369 "mulss %%xmm6, %%xmm3\n\t"
370 "addss %%xmm2, %%xmm3\n\t"
371 "movss %5, %%xmm2\n\t"
372 "mulss %8, %%xmm2\n\t"
373 "addss %%xmm2, %%xmm3\n\t"
374 "movss %6, %%xmm2\n\t"
375 "mulss %%xmm4, %%xmm2\n\t"
376 "addss %%xmm5, %%xmm2\n\t"
377 "addss %%xmm2, %%xmm3\n\t"
378 :: "m" (xs), /* %0 */
379 "m" (fb), /* %1 */
380 "m" (ys), /* %2 */
381 "m" (t1), /* %3 */
382 "m" (t2), /* %4 */
383 "m" (t3), /* %5 */
384 "m" (t4), /* %6 */
385 "m" (t5), /* %7 */
386 "m" (t7), /* %8 */
387 "m" (t8), /* %9 */
388 "m" (x1), /* %10 */
389 "m" (x2), /* %11 */
390 "m" (y1), /* %12 */
391 "m" (y2) /* %13 */
392 );
393 __asm__ __volatile__ (
394 "shufps $0x39,%%xmm0,%%xmm0 # rotate down one cell\n\t"
395 "shufps $0x93,%%xmm7,%%xmm7 # rotate up one cell\n\t"
396 "movss %%xmm3,%%xmm7\n\t"
397 ::
398 );
399 /* sample 3 */
400 __asm__ __volatile__ (
401 "movss %1, %%xmm2\n\t"
402 "mulss %7, %%xmm4\n\t"
403 "mulss %%xmm3, %%xmm2\n\t"
404 "movss %3, %%xmm5\n\t"
405 "movss %%xmm6, %11\n\t"
406 "addss %%xmm0, %%xmm2\n\t"
407 "movss %%xmm3, %13\n\t"
408 "mulss %%xmm2, %%xmm5\n\t"
409 "mulss %4, %%xmm6\n\t"
410 "movss %%xmm2, %10\n\t"
411 "addss %%xmm6, %%xmm5\n\t"
412 "movss %5, %%xmm2\n\t"
413 "mulss %9, %%xmm2\n\t"
414 "mulss %6, %%xmm3\n\t"
415 "addss %%xmm2, %%xmm5\n\t"
416 "addss %%xmm3, %%xmm4\n\t"
417 "addss %%xmm4, %%xmm5\n\t"
418 "movss %%xmm5, %12\n\t"
419 :: "m" (xs), /* %0 */
420 "m" (ys), /* %1 */
421 "m" (fbc), /* %2 */
422 "m" (t1), /* %3 */
423 "m" (t2), /* %4 */
424 "m" (t3), /* %5 */
425 "m" (t4), /* %6 */
426 "m" (t5), /* %7 */
427 "m" (t6), /* %8 */
428 "m" (t8), /* %9 */
429 "m" (x1), /* %10 */
430 "m" (x2), /* %11 */
431 "m" (y1), /* %12 */
432 "m" (y2) /* %13 */
433 );
434 __asm__ __volatile__ (
435 "shufps $0x93,%%xmm7,%%xmm7 # rotate up one cell\n\t"
436 "shufps $0x39,%%xmm0,%%xmm0 # rotate down one cell to restore original input\n\t"
437 "movss %%xmm5,%%xmm7\n\t"
438 "shufps $0x1b,%%xmm7,%%xmm7 # swap output to correct order\n\t"
439 ::
440 );
441 }
442 #endif // CONFIG_ASM && ARCH_X86
443 };
444
445 /** @brief Lowpass Filter
446 *
447 * Lowpass filter based on biquad filter implementation.
448 */
449 class LowpassFilter : public BiquadFilter {
450 public:
451 inline LowpassFilter() : BiquadFilter() {}
452
453 inline void SetParameters(bq_t fc, bq_t bw, bq_t fs) {
454 bq_t omega = 2.0 * M_PI * fc / fs;
455 bq_t sn = sin(omega);
456 bq_t cs = cos(omega);
457 bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn);
458
459 const float a0r = 1.0 / (1.0 + alpha);
460 this->b0 = a0r * (1.0 - cs) * 0.5;
461 this->b1 = a0r * (1.0 - cs);
462 this->b2 = a0r * (1.0 - cs) * 0.5;
463 this->a1 = a0r * (2.0 * cs);
464 this->a2 = a0r * (alpha - 1.0);
465 }
466
467 inline void SetParameters(biquad_param_t* param, bq_t fc, bq_t bw, bq_t fs) {
468 bq_t omega = 2.0 * M_PI * fc / fs;
469 bq_t sn = sin(omega);
470 bq_t cs = cos(omega);
471 bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn);
472
473 const float a0r = 1.0 / (1.0 + alpha);
474 param->b0 = a0r * (1.0 - cs) * 0.5;
475 param->b1 = a0r * (1.0 - cs);
476 param->b2 = a0r * (1.0 - cs) * 0.5;
477 param->a1 = a0r * (2.0 * cs);
478 param->a2 = a0r * (alpha - 1.0);
479 }
480 };
481
482 /** @brief Bandpass Filter
483 *
484 * Bandpass filter based on biquad filter implementation.
485 */
486 class BandpassFilter : public BiquadFilter {
487 public:
488 inline BandpassFilter() : BiquadFilter() {}
489
490 inline void SetParameters(bq_t fc, bq_t bw, bq_t fs) {
491 bq_t omega = 2.0 * M_PI * fc / fs;
492 bq_t sn = sin(omega);
493 bq_t cs = cos(omega);
494 bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn);
495
496 const float a0r = 1.0 / (1.0 + alpha);
497 this->b0 = a0r * alpha;
498 this->b1 = 0.0;
499 this->b2 = a0r * -alpha;
500 this->a1 = a0r * (2.0 * cs);
501 this->a2 = a0r * (alpha - 1.0);
502 }
503
504 inline void SetParameters(biquad_param_t* param, bq_t fc, bq_t bw, bq_t fs) {
505 bq_t omega = 2.0 * M_PI * fc / fs;
506 bq_t sn = sin(omega);
507 bq_t cs = cos(omega);
508 bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn);
509
510 const float a0r = 1.0 / (1.0 + alpha);
511 param->b0 = a0r * alpha;
512 param->b1 = 0.0;
513 param->b2 = a0r * -alpha;
514 param->a1 = a0r * (2.0 * cs);
515 param->a2 = a0r * (alpha - 1.0);
516 }
517 };
518
519 /** @brief Highpass Filter
520 *
521 * Highpass filter based on biquad filter implementation.
522 */
523 class HighpassFilter : public BiquadFilter {
524 public:
525 inline HighpassFilter() : BiquadFilter() {}
526
527 inline void SetParameters(bq_t fc, bq_t bw, bq_t fs) {
528 bq_t omega = 2.0 * M_PI * fc / fs;
529 bq_t sn = sin(omega);
530 bq_t cs = cos(omega);
531 bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn);
532
533 const float a0r = 1.0 / (1.0 + alpha);
534 this->b0 = a0r * (1.0 + cs) * 0.5;
535 this->b1 = a0r * -(1.0 + cs);
536 this->b2 = a0r * (1.0 + cs) * 0.5;
537 this->a1 = a0r * (2.0 * cs);
538 this->a2 = a0r * (alpha - 1.0);
539 }
540
541 inline void SetParameters(biquad_param_t* param, bq_t fc, bq_t bw, bq_t fs) {
542 bq_t omega = 2.0 * M_PI * fc / fs;
543 bq_t sn = sin(omega);
544 bq_t cs = cos(omega);
545 bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn);
546
547 const float a0r = 1.0 / (1.0 + alpha);
548 param->b0 = a0r * (1.0 + cs) * 0.5;
549 param->b1 = a0r * -(1.0 + cs);
550 param->b2 = a0r * (1.0 + cs) * 0.5;
551 param->a1 = a0r * (2.0 * cs);
552 param->a2 = a0r * (alpha - 1.0);
553 }
554 };
555
556 } // namespace LinuxSampler
557
558 #endif // __LS_BIQUADFILTER_H__

  ViewVC Help
Powered by ViewVC