/[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 2377 - (show annotations) (download) (as text)
Thu Oct 4 18:16:26 2012 UTC (11 years, 5 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 24734 byte(s)
* Various "const" and "restrict" optimizations.

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

  ViewVC Help
Powered by ViewVC