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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 877 - (show annotations) (download) (as text)
Sun Jun 25 13:54:17 2006 UTC (17 years, 9 months ago) by persson
File MIME type: text/x-c++hdr
File size: 6967 byte(s)
* new filter implementation, which is more accurate and supports all
  filter types including bandreject and lowpass turbo

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 Christian Schoenebeck *
7 * Copyright (C) 2006 Christian Schoenebeck and Andreas Persson *
8 * *
9 * 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 *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the Free Software *
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
22 * MA 02111-1307 USA *
23 ***************************************************************************/
24
25 #ifndef __LS_GIG_FILTER_H__
26 #define __LS_GIG_FILTER_H__
27
28 #include "../../common/global.h"
29
30 #include <gig.h>
31
32 namespace LinuxSampler { namespace gig {
33
34 class FilterBase {
35 public:
36 virtual float Apply(float x) = 0;
37 virtual void SetParameters(float f1, float f2, float scale) = 0;
38 virtual ~FilterBase() {}
39
40 virtual void Reset() {
41 y1 = y2 = y3 = x1 = x2 = x3 = 0;
42 }
43
44 private:
45 float y1, y2, y3;
46
47 protected:
48 float a1, a2, a3, x1, x2, x3;
49
50 void KillDenormal(float& f) {
51 f += 1e-18f;
52 f -= 1e-18f;
53 }
54
55 float ApplyA(float x) {
56 float y = x - a1 * y1 - a2 * y2 - a3 * y3;
57 KillDenormal(y);
58 y3 = y2;
59 y2 = y1;
60 y1 = y;
61 return y;
62 }
63 };
64
65 class LowpassFilter : public FilterBase {
66 protected:
67 float b0;
68 public:
69 float Apply(float x) {
70 return ApplyA(b0 * x);
71 }
72
73 void SetParameters(float f1, float f2, float scale) {
74 float f1_2 = f1 * f1;
75 b0 = f1_2 * scale;
76 a1 = f2;
77 a2 = f1_2 - 1;
78 a3 = -f2;
79 }
80 };
81
82 class BandpassFilter : public FilterBase {
83 float b0, b2;
84 public:
85 float Apply(float x) {
86 float y = ApplyA(b0 * x + b2 * x2);
87 x2 = x1;
88 x1 = x;
89 return y;
90 }
91
92 void SetParameters(float f1, float f2, float scale) {
93 b0 = f1 * scale;
94 b2 = -b0;
95 a1 = f2;
96 a2 = f1 * f1 - 1;
97 a3 = -f2;
98 }
99 };
100
101 class HighpassFilter : public FilterBase {
102 float scale;
103 public:
104 float Apply(float x) {
105 float y = ApplyA(-x + x1 + x2 - x3);
106 x3 = x2;
107 x2 = x1;
108 x1 = x;
109 return y * scale;
110 }
111
112 void SetParameters(float f1, float f2, float scale) {
113 a1 = f2;
114 a2 = f1 * f1 - 1;
115 a3 = -f2;
116 this->scale = scale;
117 }
118 };
119
120 class BandrejectFilter : public FilterBase {
121 float scale, b2;
122 public:
123 float Apply(float x) {
124 float y = ApplyA(x - x1 + b2 * x2 + x3);
125 x3 = x2;
126 x2 = x1;
127 x1 = x;
128 return y * scale;
129 }
130
131 void SetParameters(float f1, float f2, float scale) {
132 b2 = f1 * f1 - 1;
133 a1 = f2;
134 a2 = b2;
135 a3 = -f2;
136 this->scale = scale;
137 }
138 };
139
140 class LowpassTurboFilter : public LowpassFilter {
141 float b20, y21, y22, y23;
142 public:
143 float Apply(float x) {
144 float y = b20 * LowpassFilter::Apply(x)
145 - a1 * y21 - a2 * y22 - a3 * y23;
146 KillDenormal(y);
147 y23 = y22;
148 y22 = y21;
149 y21 = y;
150
151 return y;
152 }
153
154 void SetParameters(float f1, float f2, float scale) {
155 LowpassFilter::SetParameters(f1, f2, scale);
156 b20 = b0 * 0.5;
157 }
158
159 void Reset() {
160 LowpassFilter::Reset();
161 y21 = y22 = y23 = 0;
162 }
163 };
164
165 /**
166 * These are filters similar to the ones from Gigasampler.
167 */
168 class Filter {
169 protected:
170 HighpassFilter HPFilter;
171 BandpassFilter BPFilter;
172 LowpassFilter LPFilter;
173 BandrejectFilter BRFilter;
174 LowpassTurboFilter LPTFilter;
175 FilterBase* pFilter;
176
177 public:
178 Filter() {
179 // set filter type to 'lowpass' by default
180 pFilter = &LPFilter;
181 }
182
183 void SetType(::gig::vcf_type_t FilterType) {
184 switch (FilterType) {
185 case ::gig::vcf_type_highpass:
186 pFilter = &HPFilter;
187 break;
188 case ::gig::vcf_type_bandreject:
189 pFilter = &BRFilter;
190 break;
191 case ::gig::vcf_type_bandpass:
192 pFilter = &BPFilter;
193 break;
194 case ::gig::vcf_type_lowpassturbo:
195 pFilter = &LPTFilter;
196 break;
197 default:
198 pFilter = &LPFilter;
199 }
200 }
201
202 void SetParameters(float cutoff, float resonance, float fs) {
203 float f1 = cutoff * 0.0075279;
204 float f2 = f1 - 1 + resonance * cutoff * (-5.5389e-5 + 1.1982e-7 * cutoff);
205 float scale = resonance < 51 ? 1.0f : 1.3762f - 0.0075073f * resonance;
206 pFilter->SetParameters(f1, f2, scale);
207 }
208
209 void Reset() {
210 HPFilter.Reset();
211 BPFilter.Reset();
212 LPFilter.Reset();
213 BRFilter.Reset();
214 LPTFilter.Reset();
215 }
216
217 float Apply(float in) {
218 return pFilter->Apply(in);
219 }
220 };
221
222 }} //namespace LinuxSampler::gig
223
224 #endif // __LS_GIG_FILTER_H__

  ViewVC Help
Powered by ViewVC