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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 617 - (hide 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 schoenebeck 53 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 schoenebeck 56 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 617 * Copyright (C) 2005 Christian Schoenebeck *
7 schoenebeck 53 * *
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 capela 268 #include <math.h>
28    
29 schoenebeck 328 #include "../../common/global.h"
30    
31 schoenebeck 53 /// 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 schoenebeck 80 * 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 senkov 324 bq_t a1;
54     bq_t a2;
55 schoenebeck 80 };
56    
57     /**
58     * Bi-quadratic filter
59     * (adapted from lisp code by Eli Brandt, http://www.cs.cmu.edu/~eli/)
60     */
61 schoenebeck 53 class BiquadFilter {
62     protected:
63 schoenebeck 80 // following five variables are only used if no external biquad_param_t reference is used
64 schoenebeck 53 bq_t b0;
65     bq_t b1;
66     bq_t b2;
67 senkov 324 bq_t a1;
68     bq_t a2;
69 schoenebeck 80 // following four variables are used to buffer the feedback
70 schoenebeck 53 bq_t x1;
71     bq_t x2;
72     bq_t y1;
73     bq_t y2;
74    
75 schoenebeck 319 const static float fbc = 0.98;
76    
77 schoenebeck 53 /**
78 schoenebeck 80 * 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 schoenebeck 53 // 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 schoenebeck 319 BiquadFilter() {
89     Reset();
90     }
91    
92     void Reset() {
93 schoenebeck 53 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 schoenebeck 80 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 schoenebeck 617 #if CONFIG_ASM && ARCH_X86
128 schoenebeck 319 // 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 schoenebeck 617 #endif // CONFIG_ASM && ARCH_X86
215 schoenebeck 319
216 schoenebeck 53 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 schoenebeck 80
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 schoenebeck 319
246 schoenebeck 617 #if CONFIG_ASM && ARCH_X86
247 schoenebeck 319 // 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 schoenebeck 617 #endif // CONFIG_ASM && ARCH_X86
443 schoenebeck 53 };
444    
445 schoenebeck 563 /** @brief Lowpass Filter
446     *
447     * Lowpass filter based on biquad filter implementation.
448     */
449 schoenebeck 53 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 schoenebeck 80
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 schoenebeck 53 };
481    
482 schoenebeck 563 /** @brief Bandpass Filter
483     *
484     * Bandpass filter based on biquad filter implementation.
485     */
486 schoenebeck 53 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 schoenebeck 80
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 schoenebeck 53 };
518    
519 schoenebeck 563 /** @brief Highpass Filter
520     *
521     * Highpass filter based on biquad filter implementation.
522     */
523 schoenebeck 53 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 schoenebeck 80
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 schoenebeck 53 };
555    
556     } // namespace LinuxSampler
557    
558     #endif // __LS_BIQUADFILTER_H__

  ViewVC Help
Powered by ViewVC