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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 268 by capela, Thu Oct 7 22:20:20 2004 UTC revision 685 by persson, Tue Jul 5 19:30:37 2005 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   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  *   *   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  *   *   it under the terms of the GNU General Public License as published by  *
# Line 25  Line 26 
26    
27  #include <math.h>  #include <math.h>
28    
29    #include "../../common/global.h"
30    
31  /// ln(2) / 2  /// ln(2) / 2
32  #define LN_2_2                  0.34657359f  #define LN_2_2                  0.34657359f
33    
# Line 44  namespace LinuxSampler { Line 47  namespace LinuxSampler {
47       * between multiple filters.       * between multiple filters.
48       */       */
49      struct biquad_param_t {      struct biquad_param_t {
         bq_t a1;  
         bq_t a2;  
50          bq_t b0;          bq_t b0;
51          bq_t b1;          bq_t b1;
52          bq_t b2;          bq_t b2;
53            bq_t a1;
54            bq_t a2;
55      };      };
56    
57      /**      /**
# Line 58  namespace LinuxSampler { Line 61  namespace LinuxSampler {
61      class BiquadFilter {      class BiquadFilter {
62          protected:          protected:
63              // following five variables are only used if no external biquad_param_t reference is used              // following five variables are only used if no external biquad_param_t reference is used
             bq_t a1;  
             bq_t a2;  
64              bq_t b0;              bq_t b0;
65              bq_t b1;              bq_t b1;
66              bq_t b2;              bq_t b2;
67                bq_t a1;
68                bq_t a2;
69              // following four variables are used to buffer the feedback              // following four variables are used to buffer the feedback
70              bq_t x1;              bq_t x1;
71              bq_t x2;              bq_t x2;
72              bq_t y1;              bq_t y1;
73              bq_t y2;              bq_t y2;
74    
75    #if __GNUC__ >= 4
76                float fbc;
77    #else
78                const static float fbc = 0.98;
79    #endif
80    
81              /**              /**
82               * Prevent \a f from going into denormal mode which would slow down               * Prevent \a f from going into denormal mode which would slow down
83               * subsequent floating point calculations, we achieve that by setting               * subsequent floating point calculations, we achieve that by setting
# Line 80  namespace LinuxSampler { Line 89  namespace LinuxSampler {
89                  f -= 1e-18f;                  f -= 1e-18f;
90              }              }
91          public:          public:
92              inline BiquadFilter() {              BiquadFilter() {
93                    Reset();
94    #if __GNUC__ >= 4
95                    fbc = 0.98f;
96    #endif
97                }
98    
99                void Reset() {
100                  x1 = 0.0f;                  x1 = 0.0f;
101                  x2 = 0.0f;                  x2 = 0.0f;
102                  y1 = 0.0f;                  y1 = 0.0f;
# Line 115  namespace LinuxSampler { Line 131  namespace LinuxSampler {
131                  return y;                  return y;
132              }              }
133    
134    #if CONFIG_ASM && ARCH_X86
135                // expects to find input in xmm0 (xmm0 stays unmodified) and finally leaves output in xmm6
136                inline void Apply4StepsSSE(biquad_param_t* param) {
137                    __asm__ __volatile__ (
138                        "movss (%2),%%xmm4                # b0\n\t"
139                        "shufps   $0x00,%%xmm4,%%xmm4     # copy b0 to other cells\n\t"
140                        "mulps  %%xmm0,%%xmm4             # xmm4 = x*b0\n\t"
141                        "movups (%0),%%xmm2               # load b1,b2,a1,a2\n\t"
142                        "movups (%1),%%xmm5               # load x1,x2,y1,y2\n\t"
143                        /* sample 0 */
144                        "movaps %%xmm5,%%xmm3\n\t"
145                        "mulps  %%xmm2,%%xmm5             # xmm5 = [b1,b2,a1,a2] * [x1,x2,y1,y2]\n\t"
146                        "shufps $0x0a,%%xmm3,%%xmm3       # x2 = x1, y2 = y1\n\t"
147                        "movss  %%xmm4,%%xmm6\n\t"
148                        "addss  %%xmm5,%%xmm6\n\t"
149                        "shufps $0x39,%%xmm5,%%xmm5\n\t"
150                        "addss  %%xmm5,%%xmm6\n\t"
151                        "shufps $0x39,%%xmm5,%%xmm5\n\t"
152                        "addss  %%xmm5,%%xmm6\n\t"
153                        "shufps $0x39,%%xmm5,%%xmm5\n\t"
154                        "addss  %%xmm5,%%xmm6             # xmm6 = b0*x + b1*x1 + b2*x2 + a1*y1 + a2*y2\n\t"
155                        /* sample 1 */
156                        "shufps $0x39,%%xmm4,%%xmm4       # rotate xmm4 down 1 cell\n\t"
157                        "movss  %%xmm6,%%xmm3             # y1 = y\n\t"
158                        "shufps $0x4e,%%xmm3,%%xmm3       # rotate 2 cells\n\t"
159                        "movss  %%xmm0,%%xmm3             # x1 = x\n\t"
160                        "shufps $0x93,%%xmm6,%%xmm6       # rotate output up 1 cell\n\t"
161                        "movaps %%xmm3,%%xmm5\n\t"
162                        "shufps $0x39,%%xmm0,%%xmm0       # rotate input down 1 cell\n\t"
163                        "mulps  %%xmm2,%%xmm5             # xmm5 = [b1,b2,a1,a2] * [x1,x2,y1,y2]\n\t"
164                        "movss  %%xmm5,%%xmm6\n\t"
165                        "addss  %%xmm4,%%xmm6\n\t"
166                        "shufps $0x39,%%xmm5,%%xmm5\n\t"
167                        "addss  %%xmm5,%%xmm6\n\t"
168                        "shufps $0x39,%%xmm5,%%xmm5\n\t"
169                        "addss  %%xmm5,%%xmm6\n\t"
170                        "shufps $0x39,%%xmm5,%%xmm5\n\t"
171                        "addss  %%xmm5,%%xmm6             # xmm6 = b0*x + b1*x1 + b2*x2 + a1*y1 + a2*y2\n\t"
172                        /* sample 2 */
173                        "shufps $0x0a,%%xmm3,%%xmm3       # x2 = x1, y2 = y1\n\t"
174                        "shufps $0x39,%%xmm4,%%xmm4       # rotate xmm4 down 1 cell\n\t"
175                        "movss  %%xmm6,%%xmm3             # y1 = y\n\t"
176                        "shufps $0x4e,%%xmm3,%%xmm3       # rotate 2 cells\n\t"
177                        "movss  %%xmm0,%%xmm3             # x1 = x\n\t"
178                        "shufps $0x93,%%xmm6,%%xmm6       # rotate output up 1 cell\n\t"
179                        "movaps %%xmm3,%%xmm5\n\t"
180                        "shufps $0x39,%%xmm0,%%xmm0       # rotate input down 1 cell\n\t"
181                        "mulps  %%xmm2,%%xmm5             # xmm5 = [b1,b2,a1,a2] * [x1,x2,y1,y2]\n\t"
182                        "movss  %%xmm5,%%xmm6\n\t"
183                        "addss  %%xmm4,%%xmm6\n\t"
184                        "shufps $0x39,%%xmm5,%%xmm5\n\t"
185                        "addss  %%xmm5,%%xmm6\n\t"
186                        "shufps $0x39,%%xmm5,%%xmm5\n\t"
187                        "addss  %%xmm5,%%xmm6\n\t"
188                        "shufps $0x39,%%xmm5,%%xmm5\n\t"
189                        "addss  %%xmm5,%%xmm6             # xmm6 = b0*x + b1*x1 + b2*x2 + a1*y1 + a2*y2\n\t"
190                        /* sample 3 */
191                        "shufps $0x0a,%%xmm3,%%xmm3       # x2 = x1, y2 = y1\n\t"
192                        "shufps $0x39,%%xmm4,%%xmm4       # rotate xmm4 down 1 cell\n\t"
193                        "movss  %%xmm6,%%xmm3             # y1 = y\n\t"
194                        "shufps $0x4e,%%xmm3,%%xmm3       # rotate 2 cells\n\t"
195                        "movss  %%xmm0,%%xmm3             # x1 = x\n\t"
196                        "shufps $0x93,%%xmm6,%%xmm6       # rotate output up 1 cell\n\t"
197                        "mulps  %%xmm3,%%xmm2             # xmm5 = [b1,b2,a1,a2] * [x1,x2,y1,y2]\n\t"
198                        "shufps $0x39,%%xmm0,%%xmm0       # rotate input down 1 cell\n\t"
199                        "movss  %%xmm2,%%xmm6\n\t"
200                        "shufps $0x39,%%xmm2,%%xmm2\n\t"
201                        "addss  %%xmm2,%%xmm6\n\t"
202                        "shufps $0x39,%%xmm2,%%xmm2\n\t"
203                        "addss  %%xmm2,%%xmm6\n\t"
204                        "shufps $0x39,%%xmm2,%%xmm2\n\t"
205                        "addss  %%xmm2,%%xmm6\n\t"
206                        "addss  %%xmm4,%%xmm6             # xmm6 = b0*x + b1*x1 + b2*x2 + a1*y1 + a2*y2\n\t"
207                        /* done */
208                        "shufps $0x0a,%%xmm3,%%xmm3       # x2 = x1, y2 = y1\n\t"
209                        "movss  %%xmm6,%%xmm3             # y1 = y\n\t"
210                        "shufps $0x4e,%%xmm3,%%xmm3       # rotate 2 cells\n\t"
211                        "movss  %%xmm0,%%xmm3             # x1 = x\n\t"
212                        "shufps $0x1b,%%xmm6,%%xmm6       # swap output to correct order\n\t"
213                        "shufps $0x39,%%xmm0,%%xmm0       # rotate input down 1 cell, to restore original input\n\t"
214                        "movups %%xmm3,(%1)               # store x1,x2,y1,y2\n\t"
215                        : /* no output */
216                        : "r" (&param->b1), /* %0 - [b1,b2,a1,a2] */
217                          "r" (&x1),        /* %1 - [x1,x2,y1,y2] */
218                          "r" (&param->b0)  /* %2 */
219                    );
220                }
221    #endif // CONFIG_ASM && ARCH_X86
222    
223              inline bq_t ApplyFB(bq_t x, const bq_t fb) {              inline bq_t ApplyFB(bq_t x, const bq_t fb) {
224                  bq_t y;                  bq_t y;
225    
# Line 144  namespace LinuxSampler { Line 249  namespace LinuxSampler {
249    
250                  return y;                  return y;
251              }              }
252    
253    #if CONFIG_ASM && ARCH_X86
254                // expects to find input in xmm0 (xmm0 stays unmodified) and finally leaves output in xmm7
255                inline void ApplyFB4StepsSSE(biquad_param_t* param, const bq_t &fb) {
256                    float xs, ys;
257                    float t0, t1, t2, t3, t4, t5, t6, t7, t8; // temporary stack space
258                    __asm__ __volatile__ (
259                        /* prepare input */
260                        "movss  %15,%%xmm5\n\t"
261                        "movss  %%xmm0,(%14)\n\t"
262                        /* sample 0 */
263                        "movss   %0, %%xmm3\n\t"
264                        "movss   %1, %%xmm4\n\t"
265                        "mulss   %%xmm4, %%xmm5\n\t"
266                        "movss   %%xmm3, %2\n\t"
267                        "movss   %%xmm5, %16\n\t"
268                        "mulss   %%xmm3, %%xmm5\n\t"
269                        "movss   %19, %%xmm2\n\t"
270                        "movss   %3, %%xmm6\n\t"
271                        "movss   %21, %%xmm3\n\t"
272                        "addss   %%xmm5, %%xmm6\n\t"
273                        "movss  %%xmm2, %%xmm5\n\t"
274                        "movss   %20, %%xmm4\n\t"
275                        "movss   %%xmm6, %4\n\t"
276                        "mulss   %%xmm6, %%xmm5\n\t"
277                        "movss   %5, %%xmm6\n\t"
278                        "movss   %%xmm2, %6\n\t"
279                        "movss   %%xmm4, %7\n\t"
280                        "movss   %%xmm3, %%xmm2\n\t"
281                        "mulss   %%xmm6, %%xmm4\n\t"
282                        "mulss   %8, %%xmm2\n\t"
283                        "movss   %%xmm3, %9\n\t"
284                        "addss   %%xmm4, %%xmm5\n\t"
285                        "movss   %18, %%xmm3\n\t"
286                        "movss   %17, %%xmm4\n\t"
287                        "addss   %%xmm2, %%xmm5\n\t"
288                        "movss   %%xmm4, %10\n\t"
289                        "movss   %%xmm3, %%xmm2\n\t"
290                        "mulss   %11, %%xmm4\n\t"
291                        "mulss   %12, %%xmm2\n\t"
292                        "movss   %%xmm3, %13\n\t"
293                        "addss   %%xmm4, %%xmm5\n\t"
294                        "movss   %11, %%xmm3\n\t"
295                        "movss   %4, %%xmm4\n\t"
296                        "addss   %%xmm2, %%xmm5\n\t"
297                        :: "m" (y1),  /* %0 */
298                           "m" (fbc), /* %1 */
299                           "m" (t0),  /* %2 */
300                           "m" (xs),  /* %3 */
301                           "m" (t7),  /* %4 */
302                           "m" (x1),  /* %5 */
303                           "m" (t1),  /* %6 */
304                           "m" (t2),  /* %7 */
305                           "m" (x2),  /* %8 */
306                           "m" (t3),  /* %9 */
307                           "m" (t4),  /* %10 */
308                           "m" (t0),  /* %11 */
309                           "m" (y2),  /* %12 */
310                           "m" (t5),  /* %13 */
311                           "r" (&xs),  /* %14 */
312                           "m" (fb),   /* %15 */
313                           "m" (ys),   /* %16 */
314                           "m" (param->a1), /* %17 */
315                           "m" (param->a2), /* %18 */
316                           "m" (param->b0), /* %19 */
317                           "m" (param->b1), /* %20 */
318                           "m" (param->b2) /* %21 */
319                    );
320                    __asm__ __volatile__ (
321                        "shufps $0x39,%%xmm0,%%xmm0  # rotate down one cell\n\t"
322                        "movss  %%xmm5,%%xmm7\n\t"
323                        ::
324                    );
325                    /* sample 1 */
326                    __asm__ __volatile__ (
327                        "movss   %0, %%xmm4\n\t"
328                        "movss   %%xmm0, %%xmm3\n\t"
329                        "mulss   %%xmm5, %%xmm4\n\t"
330                        "mulss   %3, %%xmm6\n\t"
331                        "movss   %5, %%xmm2\n\t"
332                        "addss   %%xmm4, %%xmm3\n\t"
333                        "mulss   %7, %%xmm2\n\t"
334                        "movss   %6, %%xmm4\n\t"
335                        "movss   %%xmm3, %8\n\t"
336                        "mulss   %%xmm3, %%xmm4\n\t"
337                        "addss   %%xmm2, %%xmm4\n\t"
338                        "movss   %9, %%xmm3\n\t"
339                        "mulss   %%xmm5, %%xmm3\n\t"
340                        "movss   %10, %%xmm2\n\t"
341                        "addss   %%xmm6, %%xmm4\n\t"
342                        "mulss   %11, %%xmm2\n\t"
343                        "addss   %%xmm3, %%xmm4\n\t"
344                        "addss   %%xmm2, %%xmm4\n\t"
345                        :: "m" (ys),  /* %0 */
346                           "m" (fbc), /* %1 */
347                           "m" (xs),  /* %2 */
348                           "m" (t3),  /* %3 */
349                           "m" (y2),  /* %4 */
350                           "m" (t2),  /* %5 */
351                           "m" (t1),  /* %6 */
352                           "m" (t7),  /* %7 */
353                           "m" (t8),  /* %8 */
354                           "m" (t4),  /* %9 */
355                           "m" (t5),  /* %10 */
356                           "m" (t0),  /* %11 */
357                           "m" (x2),  /* %12 */
358                           "m" (x1),  /* %13 */
359                           "m" (y1)   /* %14 */
360                    );
361                    __asm__ __volatile__ (
362                        "shufps $0x93,%%xmm7,%%xmm7  # rotate up one cell\n\t"
363                        "shufps $0x39,%%xmm0,%%xmm0  # rotate down one cell\n\t"
364                        "movss  %%xmm4,%%xmm7\n\t"
365                        ::
366                    );
367                    /* sample 2 */
368                    __asm__ __volatile__ (
369                        "movss   %2, %%xmm6\n\t"
370                        "movss   %3, %%xmm3\n\t"
371                        "mulss   %%xmm4, %%xmm6\n\t"
372                        "movss   %4, %%xmm2\n\t"
373                        "mulss   %9, %%xmm2\n\t"
374                        "addss   %%xmm0, %%xmm6\n\t"
375                        "mulss   %7, %%xmm5\n\t"
376                        "mulss   %%xmm6, %%xmm3\n\t"
377                        "addss   %%xmm2, %%xmm3\n\t"
378                        "movss   %5, %%xmm2\n\t"
379                        "mulss   %8, %%xmm2\n\t"
380                        "addss   %%xmm2, %%xmm3\n\t"
381                        "movss   %6, %%xmm2\n\t"
382                        "mulss   %%xmm4, %%xmm2\n\t"
383                        "addss   %%xmm5, %%xmm2\n\t"
384                        "addss   %%xmm2, %%xmm3\n\t"
385                        :: "m" (xs),  /* %0 */
386                           "m" (fb),  /* %1 */
387                           "m" (ys), /* %2 */
388                           "m" (t1),  /* %3 */
389                           "m" (t2),  /* %4 */
390                           "m" (t3),  /* %5 */
391                           "m" (t4),  /* %6 */
392                           "m" (t5),  /* %7 */
393                           "m" (t7),  /* %8 */
394                           "m" (t8),  /* %9 */
395                           "m" (x1),  /* %10 */
396                           "m" (x2),  /* %11 */
397                           "m" (y1),  /* %12 */
398                           "m" (y2)   /* %13 */
399                    );
400                    __asm__ __volatile__ (
401                        "shufps $0x39,%%xmm0,%%xmm0  # rotate down one cell\n\t"
402                        "shufps $0x93,%%xmm7,%%xmm7  # rotate up one cell\n\t"
403                        "movss  %%xmm3,%%xmm7\n\t"
404                        ::
405                    );
406                    /* sample 3 */
407                    __asm__ __volatile__ (
408                        "movss   %1, %%xmm2\n\t"
409                        "mulss   %7, %%xmm4\n\t"
410                        "mulss   %%xmm3, %%xmm2\n\t"
411                        "movss   %3, %%xmm5\n\t"
412                        "movss   %%xmm6, %11\n\t"
413                        "addss   %%xmm0, %%xmm2\n\t"
414                        "movss   %%xmm3, %13\n\t"
415                        "mulss   %%xmm2, %%xmm5\n\t"
416                        "mulss   %4, %%xmm6\n\t"
417                        "movss   %%xmm2, %10\n\t"
418                        "addss   %%xmm6, %%xmm5\n\t"
419                        "movss   %5, %%xmm2\n\t"
420                        "mulss   %9, %%xmm2\n\t"
421                        "mulss   %6, %%xmm3\n\t"
422                        "addss   %%xmm2, %%xmm5\n\t"
423                        "addss   %%xmm3, %%xmm4\n\t"
424                        "addss   %%xmm4, %%xmm5\n\t"
425                        "movss   %%xmm5, %12\n\t"
426                        :: "m" (xs),  /* %0 */
427                           "m" (ys),  /* %1 */
428                           "m" (fbc), /* %2 */
429                           "m" (t1),  /* %3 */
430                           "m" (t2),  /* %4 */
431                           "m" (t3),  /* %5 */
432                           "m" (t4),  /* %6 */
433                           "m" (t5),  /* %7 */
434                           "m" (t6),  /* %8 */
435                           "m" (t8),  /* %9 */
436                           "m" (x1),  /* %10 */
437                           "m" (x2),  /* %11 */
438                           "m" (y1),  /* %12 */
439                           "m" (y2)   /* %13 */
440                    );
441                    __asm__ __volatile__ (
442                        "shufps $0x93,%%xmm7,%%xmm7  # rotate up one cell\n\t"
443                        "shufps $0x39,%%xmm0,%%xmm0  # rotate down one cell to restore original input\n\t"
444                        "movss  %%xmm5,%%xmm7\n\t"
445                        "shufps $0x1b,%%xmm7,%%xmm7  # swap output to correct order\n\t"
446                        ::
447                    );
448                }
449    #endif // CONFIG_ASM && ARCH_X86
450      };      };
451    
452        /** @brief Lowpass Filter
453         *
454         * Lowpass filter based on biquad filter implementation.
455         */
456      class LowpassFilter : public BiquadFilter {      class LowpassFilter : public BiquadFilter {
457          public:          public:
458              inline LowpassFilter() : BiquadFilter() {}              inline LowpassFilter() : BiquadFilter() {}
# Line 179  namespace LinuxSampler { Line 486  namespace LinuxSampler {
486              }              }
487      };      };
488    
489        /** @brief Bandpass Filter
490         *
491         * Bandpass filter based on biquad filter implementation.
492         */
493      class BandpassFilter : public BiquadFilter {      class BandpassFilter : public BiquadFilter {
494          public:          public:
495              inline BandpassFilter() : BiquadFilter() {}              inline BandpassFilter() : BiquadFilter() {}
# Line 212  namespace LinuxSampler { Line 523  namespace LinuxSampler {
523              }              }
524      };      };
525    
526        /** @brief Highpass Filter
527         *
528         * Highpass filter based on biquad filter implementation.
529         */
530      class HighpassFilter : public BiquadFilter {      class HighpassFilter : public BiquadFilter {
531          public:          public:
532              inline HighpassFilter() : BiquadFilter() {}              inline HighpassFilter() : BiquadFilter() {}

Legend:
Removed from v.268  
changed lines
  Added in v.685

  ViewVC Help
Powered by ViewVC