/[svn]/linuxsampler/trunk/src/engines/gig/Filter.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/gig/Filter.h

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

revision 328 by schoenebeck, Sat Dec 25 21:58:58 2004 UTC revision 2175 by persson, Mon Apr 25 08:12:36 2011 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     *   Copyright (C) 2006-2011 Christian Schoenebeck and Andreas Persson     *
8   *                                                                         *   *                                                                         *
9   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
10   *   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 27 
27    
28  #include "../../common/global.h"  #include "../../common/global.h"
29    
30  #if DEBUG_HEADERS  #include <gig.h>
 # warning Filter.h included  
 #endif // DEBUG_HEADERS  
31    
32  #include "../common/BiquadFilter.h"  #include <cmath>
33    
34  // TODO: Gigasampler's "Turbo Lowpass" and "Bandreject" filters not implemented yet  /* TODO: This file contains both generic filters (used by the sfz
35       engine) and gig specific filters. It should probably be split up,
36       and the generic parts should be moved out of the gig directory. */
37    
38    /*
39     * The formulas for the biquad coefficients come from Robert
40     * Bristow-Johnson's Audio EQ Cookbook. The one pole filter formulas
41     * come from a post on musicdsp.org. The one poles, biquads and
42     * cascaded biquads are modeled after output from Dimension LE and SFZ
43     * Player. The gig filters are modeled after output from GigaStudio.
44     */
45    namespace LinuxSampler {
46    
47  #include "../../lib/fileloader/libgig/gig.h"      /**
48         * Filter state and parameters for a biquad filter.
49         */
50        class BiquadFilterData {
51        public:
52            float b0, b1, b2;
53            float a1, a2;
54    
55  #define LSF_BW 0.9          float x1, x2;
56  #define LSF_FB 0.9f          float y1, y2;
57        };
58    
59  namespace LinuxSampler { namespace gig {      /**
60         * Filter state and parameters for cascaded biquad filters and gig
61         * engine filters.
62         */
63        class FilterData : public BiquadFilterData
64        {
65        public:
66            union {
67                // gig filter parameters
68                struct {
69                    float a3;
70                    float x3;
71                    float y3;
72    
73                    float scale;
74                    float b20;
75                    float y21, y22, y23;
76                };
77                // cascaded biquad parameters
78                struct {
79                    BiquadFilterData d2;
80                    BiquadFilterData d3;
81                };
82            };
83        };
84    
85      /**      /**
86       * These are filters similar to the ones from Gigasampler.       * Abstract base class for all filter implementations.
87         */
88        class FilterBase {
89        public:
90            virtual float Apply(FilterData& d, float x) const = 0;
91            virtual void SetParameters(FilterData& d, float fc, float r,
92                                       float fs) const = 0;
93            virtual void Reset(FilterData& d) const = 0;
94        protected:
95            void KillDenormal(float& f) const {
96                f += 1e-18f;
97                f -= 1e-18f;
98            }
99        };
100    
101        /**
102         * One-pole lowpass filter.
103         */
104        class LowpassFilter1p : public FilterBase {
105        public:
106            float Apply(FilterData& d, float x) const {
107                float y = x + d.a1 * (x - d.y1); // d.b0 * x - d.a1 * d.y1;
108                KillDenormal(y);
109                d.y1 = y;
110                return y;
111            }
112    
113            void SetParameters(FilterData& d, float fc, float r, float fs) const {
114                float omega = 2.0 * M_PI * fc / fs;
115                float c     = 2 - cos(omega);
116                d.a1 = -(c - sqrt(c * c - 1));
117                // d.b0 = 1 + d.a1;
118            }
119    
120            void Reset(FilterData& d) const {
121                d.y1 = 0;
122            }
123        };
124    
125        /**
126         * One pole highpass filter.
127         */
128        class HighpassFilter1p : public FilterBase {
129        public:
130            float Apply(FilterData& d, float x) const {
131                // d.b0 * x + d.b1 * d.x1 - d.a1 * d.y1;
132                float y = d.a1 * (-x + d.x1 - d.y1);
133                KillDenormal(y);
134                d.x1 = x;
135                d.y1 = y;
136                return y;
137            }
138    
139            void SetParameters(FilterData& d, float fc, float r, float fs) const {
140                float omega = 2.0 * M_PI * fc / fs;
141                float c     = 2 - cos(omega);
142                d.a1 = -(c - sqrt(c * c - 1));
143                // d.b0 = -d.a1
144                // d.b1 = d.a1
145            }
146    
147            void Reset(FilterData& d) const {
148                d.x1 = 0;
149                d.y1 = 0;
150            }
151        };
152    
153        /**
154         * Base class for biquad filter implementations.
155         */
156        class BiquadFilter : public FilterBase {
157        protected:
158            float ApplyBQ(BiquadFilterData& d, float x) const {
159                float y = d.b0 * x + d.b1 * d.x1 + d.b2 * d.x2 +
160                    d.a1 * d.y1 + d.a2 * d.y2;
161                KillDenormal(y);
162                d.x2 = d.x1;
163                d.x1 = x;
164                d.y2 = d.y1;
165                d.y1 = y;
166                return y;
167            }
168    
169        public:
170            float Apply(FilterData& d, float x) const {
171                return ApplyBQ(d, x);
172            }
173    
174            void Reset(FilterData& d) const {
175                d.x1 = d.x2 = 0;
176                d.y1 = d.y2 = 0;
177            }
178        };
179    
180        /**
181         * Base class for cascaded double biquad filter (four poles).
182         */
183        class DoubleBiquadFilter : public BiquadFilter {
184        public:
185            float Apply(FilterData& d, float x) const {
186                return ApplyBQ(d.d2, BiquadFilter::Apply(d, x));
187            }
188    
189            void Reset(FilterData& d) const {
190                BiquadFilter::Reset(d);
191                d.d2.x1 = d.d2.x2 = 0;
192                d.d2.y1 = d.d2.y2 = 0;
193            }
194        };
195    
196        /**
197         * Base class for cascaded triple biquad filter (six poles).
198         */
199        class TripleBiquadFilter : public DoubleBiquadFilter {
200        public:
201            float Apply(FilterData& d, float x) const {
202                return ApplyBQ(d.d3, DoubleBiquadFilter::Apply(d, x));
203            }
204    
205            void Reset(FilterData& d) const {
206                DoubleBiquadFilter::Reset(d);
207                d.d3.x1 = d.d3.x2 = 0;
208                d.d3.y1 = d.d3.y2 = 0;
209            }
210        };
211    
212    
213        /** @brief Lowpass Filter
214         *
215         * Lowpass filter based on biquad filter implementation.
216         */
217        class LowpassFilter : public BiquadFilter {
218        public:
219            void SetParameters(FilterData& d, float fc, float r, float fs) const {
220                float omega = 2.0 * M_PI * fc / fs;
221                float sn    = sin(omega);
222                float cs    = cos(omega);
223                float alpha = sn * M_SQRT1_2 * exp(-M_LN10 / 20 * r);
224                float a0r = 1.0 / (1.0 + alpha);
225    
226                d.b0 = a0r * (1.0 - cs) * 0.5;
227                d.b1 = a0r * (1.0 - cs);
228                d.b2 = a0r * (1.0 - cs) * 0.5;
229                d.a1 = a0r * (2.0 * cs);
230                d.a2 = a0r * (alpha - 1.0);
231            }
232        };
233    
234        /** @brief Four pole lowpass filter
235         *
236         * Lowpass filter based on two cascaded biquad filters.
237         */
238        class LowpassFilter4p : public DoubleBiquadFilter {
239        public:
240            void SetParameters(FilterData& d, float fc, float r, float fs) const {
241                float omega = 2.0 * M_PI * fc / fs;
242                float sn    = sin(omega);
243                float cs    = cos(omega);
244                float alpha = sn * M_SQRT1_2;
245                float a0r = 1.0 / (1.0 + alpha);
246    
247                d.b0 = a0r * (1.0 - cs) * 0.5;
248                d.b1 = a0r * (1.0 - cs);
249                d.b2 = a0r * (1.0 - cs) * 0.5;
250                d.a1 = a0r * (2.0 * cs);
251                d.a2 = a0r * (alpha - 1.0);
252    
253                alpha *= exp(-M_LN10 / 20 * r);
254                a0r = 1.0 / (1.0 + alpha);
255    
256                d.d2.b0 = a0r * (1.0 - cs) * 0.5;
257                d.d2.b1 = a0r * (1.0 - cs);
258                d.d2.b2 = a0r * (1.0 - cs) * 0.5;
259                d.d2.a1 = a0r * (2.0 * cs);
260                d.d2.a2 = a0r * (alpha - 1.0);
261            }
262        };
263    
264        /** @brief Six pole lowpass filter
265         *
266         * Lowpass filter based on three cascaded biquad filters.
267         */
268        class LowpassFilter6p : public TripleBiquadFilter {
269        public:
270            void SetParameters(FilterData& d, float fc, float r, float fs) const {
271                float omega = 2.0 * M_PI * fc / fs;
272                float sn    = sin(omega);
273                float cs    = cos(omega);
274                float alpha = sn * M_SQRT1_2;
275                float a0r = 1.0 / (1.0 + alpha);
276    
277                d.b0 = d.d2.b0 = a0r * (1.0 - cs) * 0.5;
278                d.b1 = d.d2.b1 = a0r * (1.0 - cs);
279                d.b2 = d.d2.b2 = a0r * (1.0 - cs) * 0.5;
280                d.a1 = d.d2.a1 = a0r * (2.0 * cs);
281                d.a2 = d.d2.a2 = a0r * (alpha - 1.0);
282    
283                alpha *= exp(-M_LN10 / 20 * r);
284                a0r = 1.0 / (1.0 + alpha);
285    
286                d.d3.b0 = a0r * (1.0 - cs) * 0.5;
287                d.d3.b1 = a0r * (1.0 - cs);
288                d.d3.b2 = a0r * (1.0 - cs) * 0.5;
289                d.d3.a1 = a0r * (2.0 * cs);
290                d.d3.a2 = a0r * (alpha - 1.0);
291            }
292        };
293    
294        /** @brief Bandpass filter
295         *
296         * Bandpass filter based on biquad filter implementation.
297         */
298        class BandpassFilter : public BiquadFilter {
299        public:
300            void SetParameters(FilterData& d, float fc, float r, float fs) const {
301                float omega = 2.0 * M_PI * fc / fs;
302                float sn    = sin(omega);
303                float cs    = cos(omega);
304                float alpha = sn * M_SQRT1_2 * exp(-M_LN10 / 20 * r);
305    
306                float a0r = 1.0 / (1.0 + alpha);
307                d.b0 = a0r * alpha;
308                d.b1 = 0.0;
309                d.b2 = a0r * -alpha;
310                d.a1 = a0r * (2.0 * cs);
311                d.a2 = a0r * (alpha - 1.0);
312            }
313        };
314    
315        /** @brief Bandreject filter
316         *
317         * Bandreject filter based on biquad filter implementation.
318         */
319        class BandrejectFilter : public BiquadFilter {
320        public:
321            void SetParameters(FilterData& d, float fc, float r, float fs) const {
322                float omega = 2.0 * M_PI * fc / fs;
323                float sn    = sin(omega);
324                float cs    = cos(omega);
325                float alpha = sn * M_SQRT1_2 * exp(-M_LN10 / 20 * r);
326    
327                float a0r = 1.0 / (1.0 + alpha);
328                d.b0 = a0r;
329                d.b1 = a0r * (-2.0 * cs);
330                d.b2 = a0r;
331                d.a1 = a0r * (2.0 * cs);
332                d.a2 = a0r * (alpha - 1.0);
333            }
334        };
335    
336        /** @brief Highpass filter
337         *
338         * Highpass filter based on biquad filter implementation.
339         */
340        class HighpassFilter : public BiquadFilter {
341        public:
342            void SetParameters(FilterData& d, float fc, float r, float fs) const {
343                float omega = 2.0 * M_PI * fc / fs;
344                float sn    = sin(omega);
345                float cs    = cos(omega);
346                float alpha = sn * M_SQRT1_2 * exp(-M_LN10 / 20 * r);
347    
348                float a0r = 1.0 / (1.0 + alpha);
349                d.b0 = a0r * (1.0 + cs) * 0.5;
350                d.b1 = a0r * -(1.0 + cs);
351                d.b2 = a0r * (1.0 + cs) * 0.5;
352                d.a1 = a0r * (2.0 * cs);
353                d.a2 = a0r * (alpha - 1.0);
354            }
355        };
356    
357        /** @brief Four pole highpass filter
358         *
359         * Highpass filter based on three cascaded biquad filters.
360         */
361        class HighpassFilter4p : public DoubleBiquadFilter {
362        public:
363            void SetParameters(FilterData& d, float fc, float r, float fs) const {
364                float omega = 2.0 * M_PI * fc / fs;
365                float sn    = sin(omega);
366                float cs    = cos(omega);
367                float alpha = sn * M_SQRT1_2;
368    
369                float a0r = 1.0 / (1.0 + alpha);
370                d.b0 = a0r * (1.0 + cs) * 0.5;
371                d.b1 = a0r * -(1.0 + cs);
372                d.b2 = a0r * (1.0 + cs) * 0.5;
373                d.a1 = a0r * (2.0 * cs);
374                d.a2 = a0r * (alpha - 1.0);
375    
376                alpha *= exp(-M_LN10 / 20 * r);
377                a0r = 1.0 / (1.0 + alpha);
378    
379                d.d2.b0 = a0r * (1.0 + cs) * 0.5;
380                d.d2.b1 = a0r * -(1.0 + cs);
381                d.d2.b2 = a0r * (1.0 + cs) * 0.5;
382                d.d2.a1 = a0r * (2.0 * cs);
383                d.d2.a2 = a0r * (alpha - 1.0);
384            }
385        };
386    
387        /** @brief Six pole highpass filter
388         *
389         * Highpass filter based on three cascaded biquad filters.
390         */
391        class HighpassFilter6p : public TripleBiquadFilter {
392        public:
393            void SetParameters(FilterData& d, float fc, float r, float fs) const {
394                float omega = 2.0 * M_PI * fc / fs;
395                float sn    = sin(omega);
396                float cs    = cos(omega);
397                float alpha = sn * M_SQRT1_2;
398    
399                float a0r = 1.0 / (1.0 + alpha);
400                d.b0 = d.d2.b0 = a0r * (1.0 + cs) * 0.5;
401                d.b1 = d.d2.b1 = a0r * -(1.0 + cs);
402                d.b2 = d.d2.b2 = a0r * (1.0 + cs) * 0.5;
403                d.a1 = d.d2.a1 = a0r * (2.0 * cs);
404                d.a2 = d.d2.a2 = a0r * (alpha - 1.0);
405    
406                alpha *= exp(-M_LN10 / 20 * r);
407                a0r = 1.0 / (1.0 + alpha);
408    
409                d.d3.b0 = a0r * (1.0 + cs) * 0.5;
410                d.d3.b1 = a0r * -(1.0 + cs);
411                d.d3.b2 = a0r * (1.0 + cs) * 0.5;
412                d.d3.a1 = a0r * (2.0 * cs);
413                d.d3.a2 = a0r * (alpha - 1.0);
414            }
415        };
416    
417    namespace gig {
418    
419        /**
420         * Base class for the gig engine filters.
421         */
422        class GigFilter : public FilterBase {
423        public:
424            void Reset(FilterData& d) const {
425                d.x1 = d.x2 = d.x3 = 0;
426                d.y1 = d.y2 = d.y3 = 0;
427            }
428        protected:
429            float ApplyA(FilterData& d, float x) const {
430                float y = x - d.a1 * d.y1 - d.a2 * d.y2 - d.a3 * d.y3;
431                KillDenormal(y);
432                d.y3 = d.y2;
433                d.y2 = d.y1;
434                d.y1 = y;
435                return y;
436            }
437        };
438    
439    #define GIG_PARAM_INIT                                                  \
440        float f1 = fc * 0.0075279;                                          \
441        float f2 = f1 - 1 + r * fc * (-5.5389e-5 + 1.1982e-7 * fc);         \
442        float scale = r < 51 ? 1.0f : 1.3762f - 0.0075073f * r
443    
444        class LowpassFilter : public GigFilter {
445        public:
446            float Apply(FilterData& d, float x) const {
447                return ApplyA(d, d.b0 * x);
448            }
449    
450            void SetParameters(FilterData& d, float fc, float r, float fs) const {
451                GIG_PARAM_INIT;
452    
453                float f1_2 = f1 * f1;
454                d.b0 = f1_2 * scale;
455                d.a1 = f2;
456                d.a2 = f1_2 - 1;
457                d.a3 = -f2;
458            }
459        };
460    
461        class BandpassFilter : public GigFilter {
462        public:
463            float Apply(FilterData& d, float x) const {
464                float y = ApplyA(d, d.b0 * x + d.b2 * d.x2);
465                d.x2 = d.x1;
466                d.x1 = x;
467                return y;
468            }
469    
470            void SetParameters(FilterData& d, float fc, float r, float fs) const {
471                GIG_PARAM_INIT;
472    
473                d.b0 = f1 * scale;
474                d.b2 = -d.b0;
475                d.a1 = f2;
476                d.a2 = f1 * f1 - 1;
477                d.a3 = -f2;
478            }
479        };
480    
481        class HighpassFilter : public GigFilter {
482            float Apply(FilterData& d, float x) const {
483                float y = ApplyA(d, -x + d.x1 + d.x2 - d.x3);
484                d.x3 = d.x2;
485                d.x2 = d.x1;
486                d.x1 = x;
487                return y * d.scale;
488            }
489    
490            void SetParameters(FilterData& d, float fc, float r, float fs) const {
491                GIG_PARAM_INIT;
492    
493                d.a1 = f2;
494                d.a2 = f1 * f1 - 1;
495                d.a3 = -f2;
496                d.scale = scale;
497            }
498        };
499    
500        class BandrejectFilter : public GigFilter {
501            float Apply(FilterData& d, float x) const {
502                float y = ApplyA(d, x - d.x1 + d.b2 * d.x2 + d.x3);
503                d.x3 = d.x2;
504                d.x2 = d.x1;
505                d.x1 = x;
506                return y * d.scale;
507            }
508    
509            void SetParameters(FilterData& d, float fc, float r, float fs) const {
510                GIG_PARAM_INIT;
511    
512                d.b2 = f1 * f1 - 1;
513                d.a1 = f2;
514                d.a2 = d.b2;
515                d.a3 = -f2;
516                d.scale = scale;
517            }
518        };
519    
520        class LowpassTurboFilter : public LowpassFilter {
521        public:
522            float Apply(FilterData& d, float x) const {
523                float y = d.b20 * LowpassFilter::Apply(d, x)
524                    - d.a1 * d.y21 - d.a2 * d.y22 - d.a3 * d.y23;
525                KillDenormal(y);
526                d.y23 = d.y22;
527                d.y22 = d.y21;
528                d.y21 = y;
529                return y;
530            }
531    
532            void SetParameters(FilterData& d, float fc, float r, float fs) const {
533                LowpassFilter::SetParameters(d, fc, r, fs);
534                d.b20 = d.b0 * 0.5;
535            }
536        };
537    } //namespace gig
538    
539    
540        /**
541         * Main filter class.
542       */       */
543      class Filter {      class Filter {
544          protected:          protected:
545              BandpassFilter    BasicBPFilter;              static const LowpassFilter1p  lp1p;
546              HighpassFilter    HPFilter;              static const LowpassFilter    lp2p;
547              BandpassFilter    BPFilter;              static const LowpassFilter4p  lp4p;
548              LowpassFilter     LPFilter;              static const LowpassFilter6p  lp6p;
549              BiquadFilter*     pFilter;              static const BandpassFilter   bp2p;
550              bq_t              scale;              static const BandrejectFilter br2p;
551              bq_t              resonance;              static const HighpassFilter1p hp1p;
552              bq_t              cutoff;              static const HighpassFilter   hp2p;
553              ::gig::vcf_type_t Type;              static const HighpassFilter4p hp4p;
554              static const float fFB = LSF_FB;              static const HighpassFilter6p hp6p;
555          public:              /**
556                 * These are filters similar to the ones from Gigasampler.
557                 */
558                static const gig::HighpassFilter     HPFilter;
559                static const gig::BandpassFilter     BPFilter;
560                static const gig::LowpassFilter      LPFilter;
561                static const gig::BandrejectFilter   BRFilter;
562                static const gig::LowpassTurboFilter LPTFilter;
563    
564                FilterData d;
565                const FilterBase* pFilter;
566    
567            public:
568              Filter() {              Filter() {
569                  // set filter type to 'lowpass' by default                  // set filter type to 'lowpass' by default
570                  pFilter = &LPFilter;                  pFilter = &LPFilter;
571                  Type    = ::gig::vcf_type_lowpass;                  pFilter->Reset(d);
572              }              }
573    
574              inline bq_t Cutoff()     { return cutoff; }              enum vcf_type_t {
575                    vcf_type_gig_lowpass = ::gig::vcf_type_lowpass,
576              inline bq_t Resonance()  { return resonance; }                  vcf_type_gig_lowpassturbo = ::gig::vcf_type_lowpassturbo,
577                    vcf_type_gig_bandpass = ::gig::vcf_type_bandpass,
578                    vcf_type_gig_highpass = ::gig::vcf_type_highpass,
579                    vcf_type_gig_bandreject = ::gig::vcf_type_bandreject,
580                    vcf_type_1p_lowpass,
581                    vcf_type_1p_highpass,
582                    vcf_type_2p_lowpass,
583                    vcf_type_2p_highpass,
584                    vcf_type_2p_bandpass,
585                    vcf_type_2p_bandreject,
586                    vcf_type_4p_lowpass,
587                    vcf_type_4p_highpass,
588                    vcf_type_6p_lowpass,
589                    vcf_type_6p_highpass
590                };
591    
592              inline void SetType(::gig::vcf_type_t FilterType) {              void SetType(vcf_type_t FilterType) {
593                  switch (FilterType) {                  switch (FilterType) {
594                      case ::gig::vcf_type_highpass:                      case vcf_type_gig_highpass:
595                          pFilter = &HPFilter;                          pFilter = &HPFilter;
596                          break;                          break;
597                      case ::gig::vcf_type_bandreject: //TODO: not implemented yet                      case vcf_type_gig_bandreject:
598                          Type = ::gig::vcf_type_bandpass;                          pFilter = &BRFilter;
599                      case ::gig::vcf_type_bandpass:                          break;
600                        case vcf_type_gig_bandpass:
601                          pFilter = &BPFilter;                          pFilter = &BPFilter;
602                          break;                          break;
603                      case ::gig::vcf_type_lowpassturbo: //TODO: not implemented yet                      case vcf_type_gig_lowpassturbo:
604                      default:                          pFilter = &LPTFilter;
                         Type = ::gig::vcf_type_lowpass;  
                     case ::gig::vcf_type_lowpass:  
                         pFilter = &LPFilter;  
   
                 }  
                 Type = FilterType;  
             }  
   
             inline void SetParameters(bq_t cutoff, bq_t resonance, bq_t fs) {  
                 BasicBPFilter.SetParameters(cutoff, 0.7, fs);  
                 switch (Type) {  
                     case ::gig::vcf_type_highpass:  
                         HPFilter.SetParameters(cutoff, 1.0 - resonance * LSF_BW, fs);  
605                          break;                          break;
606                      case ::gig::vcf_type_bandpass:                      case vcf_type_1p_lowpass:
607                          BPFilter.SetParameters(cutoff, 1.0 - resonance * LSF_BW, fs);                          pFilter = &lp1p;
608                          break;                          break;
609                      case ::gig::vcf_type_lowpass:                      case vcf_type_1p_highpass:
610                          LPFilter.SetParameters(cutoff, 1.0 - resonance * LSF_BW, fs);                          pFilter = &hp1p;
611                          break;                          break;
612                  }                      case vcf_type_2p_lowpass:
613                  this->scale     = 1.0f - resonance * 0.7f;                          pFilter = &lp2p;
                 this->resonance = resonance;  
                 this->cutoff    = cutoff;  
             }  
   
             inline void SetParameters(biquad_param_t* base, biquad_param_t* main, bq_t cutoff, bq_t resonance, bq_t fs) {  
                 BasicBPFilter.SetParameters(base, cutoff, 0.7, fs);  
                 switch (Type) {  
                     case ::gig::vcf_type_highpass:  
                         HPFilter.SetParameters(main, cutoff, 1.0 - resonance * LSF_BW, fs);  
614                          break;                          break;
615                      case ::gig::vcf_type_bandpass:                      case vcf_type_2p_highpass:
616                          BPFilter.SetParameters(main, cutoff, 1.0 - resonance * LSF_BW, fs);                          pFilter = &hp2p;
617                          break;                          break;
618                      case ::gig::vcf_type_lowpass:                      case vcf_type_2p_bandpass:
619                          LPFilter.SetParameters(main, cutoff, 1.0 - resonance * LSF_BW, fs);                          pFilter = &bp2p;
620                          break;                          break;
621                        case vcf_type_2p_bandreject:
622                            pFilter = &br2p;
623                            break;
624                        case vcf_type_4p_lowpass:
625                            pFilter = &lp4p;
626                            break;
627                        case vcf_type_4p_highpass:
628                            pFilter = &hp4p;
629                            break;
630                        case vcf_type_6p_lowpass:
631                            pFilter = &lp6p;
632                            break;
633                        case vcf_type_6p_highpass:
634                            pFilter = &hp6p;
635                            break;
636                        default:
637                            pFilter = &LPFilter;
638                  }                  }
639                  this->scale     = 1.0f - resonance * 0.7f;                  pFilter->Reset(d);
                 this->resonance = resonance;  
                 this->cutoff    = cutoff;  
             }  
   
             void Reset() {  
                 BasicBPFilter.Reset();  
                 HPFilter.Reset();  
                 BPFilter.Reset();  
                 LPFilter.Reset();  
640              }              }
641    
642              inline bq_t Apply(const bq_t in) {              void SetParameters(float cutoff, float resonance, float fs) {
643                  return pFilter->Apply(in) * this->scale +                  pFilter->SetParameters(d, cutoff, resonance, fs);
                         BasicBPFilter.ApplyFB(in, this->resonance * LSF_FB) * this->resonance;  
644              }              }
645    
646              inline bq_t Apply(biquad_param_t* base, biquad_param_t* main, const bq_t in) {              void Reset() {
647                  return pFilter->Apply(main, in) * this->scale +                  return pFilter->Reset(d);
                         BasicBPFilter.ApplyFB(base, in, this->resonance * LSF_FB) * this->resonance;  
648              }              }
649    
650  #if ARCH_X86              float Apply(float in) {
651              // expects to find input in xmm0 and leaves output in xmm7                  return pFilter->Apply(d, in);
             inline void Apply4StepsSSE(biquad_param_t* base, biquad_param_t* main) {  
                 float fb;  
                 __asm__ __volatile__ (  
                     "movss %0, %%xmm4\n\t"  
                     "mulss %1, %%xmm4      # this->resonance * LSF_FB\n\t"  
                     "movss %%xmm4, %2\n\t"  
                     :: "m" (fFB),       /* %0 */  
                        "m" (resonance), /* %1 */  
                        "m" (fb)         /* %2 */  
                 );  
                 BasicBPFilter.ApplyFB4StepsSSE(base, fb); // leaves output in xmm7  
                 __asm__ __volatile__ (  
                     "movss  %0, %%xmm4\n\t"  
                     "shufps $0, %%xmm4, %%xmm4     # copy to other 3 cells\n\t"  
                     "mulps  %%xmm4, %%xmm7         # ApplyFB() * this->resonance\n\t"  
                     :: "m" (resonance) /* %0 */  
                 );  
                 pFilter->Apply4StepsSSE(main); // leaves output in xmm6  
                 __asm__ __volatile__ (  
                     "movss  %0, %%xmm5\n\t"  
                     "shufps $0, %%xmm5, %%xmm5     # copy to other 3 cells\n\t"  
                     "mulps  %%xmm5, %%xmm6         # Apply() * this->scale\n\t"  
                     "addps  %%xmm6, %%xmm7         # xmm7 = result\n\t"  
                     :: "m" (scale) /* %0 */  
                 );  
652              }              }
 #endif // ARCH_X86  
   
653      };      };
654    
655  }} //namespace LinuxSampler::gig  } //namespace LinuxSampler
656    
657  #endif // __LS_GIG_FILTER_H__  #endif // __LS_GIG_FILTER_H__

Legend:
Removed from v.328  
changed lines
  Added in v.2175

  ViewVC Help
Powered by ViewVC