1 #ifndef INCLUDED_AUDIOFX_FILTER_H
2 #define INCLUDED_AUDIOFX_FILTER_H
3 
4 #include <deque>
5 #include <string>
6 #include <vector>
7 
8 #include "audiofx.h"
9 #include "samplebuffer_iterators.h"
10 
11 /**
12  * Virtual base for filter effects.
13  * @author Kai Vehmanen
14  */
15 class EFFECT_FILTER : public EFFECT_BASE {
16 
17  public:
18   virtual ~EFFECT_FILTER(void);
19 };
20 
21 /**
22  * Base class for butterworth filter effects.
23  *
24  * Based on SPKit Butterworth algorithms.
25  * (for more info, see http://www.music.helsinki.fi/research/spkit)
26  */
27 class EFFECT_BW_FILTER : public EFFECT_FILTER {
28 
29 private:
30 
31   SAMPLE_SPECS::sample_t outputSample;
32   SAMPLE_ITERATOR_CHANNELS i;
33 
34   std::vector<std::vector<SAMPLE_SPECS::sample_t> > sin;
35   std::vector<std::vector<SAMPLE_SPECS::sample_t> > sout;
36 
37   void init_values(void);
38 
39  protected:
40 
41   std::vector<SAMPLE_SPECS::sample_t> a;
42   std::vector<SAMPLE_SPECS::sample_t> b;
43 
44 public:
45 
46   void process_notused(SAMPLE_BUFFER* sbuf);
47   virtual void init(SAMPLE_BUFFER *insample);
48   virtual void process(void);
49 
50   virtual EFFECT_BW_FILTER* clone(void) const = 0;
51 
52   //  EFFECT_BW_FILTER(void) : sin(2), sout(2), a(3), b(2) {
53 
EFFECT_BW_FILTER(void)54   EFFECT_BW_FILTER(void) : a(3), b(2) {
55     init_values();
56   }
57 };
58 
59 /**
60  * Bandpass filter
61  *
62  * Based on SPKit Butterworth algorithms
63  * (for more info, see http://www.music.helsinki.fi/research/spkit)
64  */
65 class EFFECT_BANDPASS: public EFFECT_BW_FILTER {
66 
67 private:
68 
69   parameter_t center;
70   parameter_t width;
71 
72   parameter_t C;
73   parameter_t D;
74 
75 public:
76 
name(void)77   virtual std::string name(void) const { return("Bandpass filter"); }
parameter_names(void)78   virtual std::string parameter_names(void) const { return("center-freq,width"); }
79 
80   virtual void set_parameter(int param, parameter_t value);
81   virtual parameter_t get_parameter(int param) const;
82 
clone(void)83   EFFECT_BANDPASS* clone(void) const  { return new EFFECT_BANDPASS(*this); }
new_expr(void)84   EFFECT_BANDPASS* new_expr(void) const { return new EFFECT_BANDPASS(); }
85   EFFECT_BANDPASS (parameter_t centerf = 1000.0, parameter_t width = 1000.0);
86 };
87 
88 /**
89  * Bandreject filter
90  *
91  * Based on SPKit Butterworth algorithms
92  * (for more info, see http://www.music.helsinki.fi/research/spkit)
93  */
94 class EFFECT_BANDREJECT: public EFFECT_BW_FILTER {
95 
96 private:
97 
98   parameter_t center;
99   parameter_t width;
100 
101   parameter_t C;
102   parameter_t D;
103 
104 public:
105 
name(void)106   virtual std::string name(void) const { return("Bandreject filter"); }
parameter_names(void)107   virtual std::string parameter_names(void) const { return("center-freq,width"); }
108 
109   virtual void set_parameter(int param, parameter_t value);
110   virtual parameter_t get_parameter(int param) const;
111 
clone(void)112   EFFECT_BANDREJECT* clone(void) const { return new EFFECT_BANDREJECT(*this); }
new_expr(void)113   EFFECT_BANDREJECT* new_expr(void) const { return new EFFECT_BANDREJECT(); }
114   EFFECT_BANDREJECT (parameter_t centerf = 1000.0, parameter_t width = 1000.0);
115 };
116 
117 /**
118  * Highpass filter
119  *
120  * Based on SPKit Butterworth algorithms
121  * (for more info, see http://www.music.helsinki.fi/research/spkit)
122  */
123 class EFFECT_HIGHPASS : public EFFECT_BW_FILTER {
124 
125  private:
126 
127   parameter_t cutOffFreq;
128   parameter_t C;
129 
130 public:
131 
name(void)132   virtual std::string name(void) const { return("Highpass filter"); }
parameter_names(void)133   virtual std::string parameter_names(void) const { return("cutoff-freq"); }
134 
135   virtual void set_parameter(int param, parameter_t value);
136   virtual parameter_t get_parameter(int param) const;
137 
clone(void)138   EFFECT_HIGHPASS* clone(void) const { return new EFFECT_HIGHPASS(*this); }
new_expr(void)139   EFFECT_HIGHPASS* new_expr(void) const { return new EFFECT_HIGHPASS(); }
140   EFFECT_HIGHPASS (parameter_t cutoff = 1000.0);
141 };
142 
143 /**
144  * Allpass filter
145  */
146 class EFFECT_ALLPASS_FILTER : public EFFECT_FILTER {
147 
148   std::vector<std::deque<SAMPLE_SPECS::sample_t> > inbuf, outbuf;
149   SAMPLE_ITERATOR_CHANNELS i;
150 
151   parameter_t feedback_gain;
152   parameter_t D;
153 
154 public:
155 
name(void)156   virtual std::string name(void) const { return("Allpass filter"); }
parameter_names(void)157   virtual std::string parameter_names(void) const { return("delay-samples,feedback-%"); }
158 
159   virtual void set_parameter(int param, parameter_t value);
160   virtual parameter_t get_parameter(int param) const;
161 
162   virtual void init(SAMPLE_BUFFER *insample);
163   virtual void process(void);
164 
clone(void)165   EFFECT_ALLPASS_FILTER* clone(void) const { return new EFFECT_ALLPASS_FILTER(*this); }
new_expr(void)166   EFFECT_ALLPASS_FILTER* new_expr(void) const { return new EFFECT_ALLPASS_FILTER(); }
167   EFFECT_ALLPASS_FILTER (void);
168 };
169 
170 
171 /**
172  * Comb filter
173  *
174  * The basic theory behind this can be found from Ken Steiglitz's book
175  * "A digital signal processing primer", page 103.
176  */
177 class EFFECT_COMB_FILTER : public EFFECT_FILTER {
178 
179   std::vector<std::deque<SAMPLE_SPECS::sample_t> > buffer;
180   std::vector<SAMPLE_SPECS::sample_t> temp;
181   SAMPLE_ITERATOR_CHANNELS i;
182 
183   parameter_t C;
184   parameter_t D;
185 
186 public:
187 
name(void)188   virtual std::string name(void) const { return("Comb filter"); }
parameter_names(void)189   virtual std::string parameter_names(void) const { return("delay-samples,radius"); }
190 
191   virtual void set_parameter(int param, parameter_t value);
192   virtual parameter_t get_parameter(int param) const;
193 
194   virtual void init(SAMPLE_BUFFER *insample);
195   virtual void process(void);
196 
clone(void)197   EFFECT_COMB_FILTER* clone(void) const { return new EFFECT_COMB_FILTER(*this); }
new_expr(void)198   EFFECT_COMB_FILTER* new_expr(void) const { return new EFFECT_COMB_FILTER(); }
199   EFFECT_COMB_FILTER (int delay_in_samples = 1, parameter_t constant = 1.0);
200 };
201 
202 /**
203  * Inverse comb filter
204  *
205  * The basic theory behind this can be found from Ken Steiglitz's book
206  * "A digital signal processing primer", page 77.
207  */
208 class EFFECT_INVERSE_COMB_FILTER : public EFFECT_FILTER {
209 
210   std::vector<parameter_t> laskuri;
211   std::vector<std::deque<SAMPLE_SPECS::sample_t> > buffer;
212   std::vector<SAMPLE_SPECS::sample_t> temp;
213   SAMPLE_ITERATOR_CHANNELS i;
214 
215   parameter_t C;
216   parameter_t D;
217 
218 public:
219 
name(void)220   virtual std::string name(void) const { return("Inverse comb filter"); }
parameter_names(void)221   virtual std::string parameter_names(void) const { return("delay-samples,radius"); }
222 
223   virtual void set_parameter(int param, parameter_t value);
224   virtual parameter_t get_parameter(int param) const;
225 
226   virtual void init(SAMPLE_BUFFER *insample);
227   virtual void process(void);
228 
clone(void)229   EFFECT_INVERSE_COMB_FILTER* clone(void) const { return new EFFECT_INVERSE_COMB_FILTER(*this); }
new_expr(void)230   EFFECT_INVERSE_COMB_FILTER* new_expr(void) const { return new EFFECT_INVERSE_COMB_FILTER(); }
231   EFFECT_INVERSE_COMB_FILTER (int delay_in_samples = 10, parameter_t constant = 1.0);
232 };
233 
234 /**
235  * Lowpass filter
236  *
237  * Based on SPKit Butterworth algorithms
238  * (for more info, see http://www.music.helsinki.fi/research/spkit)
239  */
240 class EFFECT_LOWPASS: public EFFECT_BW_FILTER {
241 
242 private:
243 
244   parameter_t cutOffFreq;
245 
246   parameter_t C;
247 
248 public:
249 
name(void)250   virtual std::string name(void) const { return("Lowpass filter"); }
parameter_names(void)251   virtual std::string parameter_names(void) const { return("cutoff-freq"); }
252 
253   virtual void set_parameter(int param, parameter_t value);
254   virtual parameter_t get_parameter(int param) const;
255 
256   void set_cutoff(parameter_t value, long int srate);
257 
clone(void)258   EFFECT_LOWPASS* clone(void) const { return new EFFECT_LOWPASS(*this); }
new_expr(void)259   EFFECT_LOWPASS* new_expr(void) const { return new EFFECT_LOWPASS(); }
260   EFFECT_LOWPASS (parameter_t cutoff = 1000.0);
261 };
262 
263 /**
264  * A simple lowpass filter
265  *
266  *   Algorithm:  1nd order filter.
267  *   From Fugue source code:
268  *
269  *    output[N] = input[N] * A + input[N-1] * B
270  *
271  *    A = 2.0 * pi * center
272  *    B = exp(-A / frequency)
273  */
274 class EFFECT_LOWPASS_SIMPLE : public EFFECT_FILTER {
275 
276 private:
277 
278   parameter_t cutOffFreq;
279   parameter_t A, B;
280   std::vector<SAMPLE_SPECS::sample_t> outhist, tempin, temphist;
281   SAMPLE_ITERATOR_CHANNELS i;
282 
283 public:
284 
name(void)285   virtual std::string name(void) const { return("Simple lowpass filter"); }
parameter_names(void)286   virtual std::string parameter_names(void) const { return("cutoff-freq"); }
287 
288   virtual void init(SAMPLE_BUFFER *insample);
289   virtual void process(void);
290 
291   virtual void set_parameter(int param, parameter_t value);
292   virtual parameter_t get_parameter(int param) const;
293 
clone(void)294   EFFECT_LOWPASS_SIMPLE* clone(void) const { return new EFFECT_LOWPASS_SIMPLE(*this); }
new_expr(void)295   EFFECT_LOWPASS_SIMPLE* new_expr(void) const { return new EFFECT_LOWPASS_SIMPLE(); }
296   EFFECT_LOWPASS_SIMPLE (parameter_t cutoff = 1000.0);
297 };
298 
299 /**
300  * Resonant bandpass filter
301  */
302 class EFFECT_RESONANT_BANDPASS : public EFFECT_FILTER {
303 
304 private:
305 
306   std::vector<SAMPLE_SPECS::sample_t> outhist1, outhist2;
307 
308   parameter_t center;
309   parameter_t width;
310 
311   parameter_t a, b, c, R;
312   parameter_t pole_angle;
313 
314   SAMPLE_ITERATOR_CHANNELS i;
315 
316 public:
317 
name(void)318   virtual std::string name(void) const { return("Resonant bandpass filter"); }
parameter_names(void)319   virtual std::string parameter_names(void) const { return("center-freq,width"); }
320 
321   virtual void set_parameter(int param, parameter_t value);
322   virtual parameter_t get_parameter(int param) const;
323 
324   virtual void init(SAMPLE_BUFFER *insample);
325   virtual void process(void);
326 
clone(void)327   EFFECT_RESONANT_BANDPASS* clone(void) const { return new EFFECT_RESONANT_BANDPASS(*this); }
new_expr(void)328   EFFECT_RESONANT_BANDPASS* new_expr(void) const { return new EFFECT_RESONANT_BANDPASS(); }
329   EFFECT_RESONANT_BANDPASS (parameter_t centerf = 1000.0, parameter_t width = 1000.0);
330 };
331 
332 /**
333  * Resonant lowpass filter
334  *
335  * Algorithm is based on a sample filter-routine (iir_filter) posted to comp.dsp.
336  */
337 class EFFECT_RESONANT_LOWPASS : public EFFECT_FILTER {
338 
339   SAMPLE_ITERATOR_CHANNELS i;
340 
341   std::vector<SAMPLE_SPECS::sample_t> outhist0, outhist1, outhist2, outhist3;
342   std::vector<SAMPLE_SPECS::sample_t> newhist0, newhist1;
343 
344   class TRIPLE_COEFS {
345   public:
346     parameter_t a0, a1, a2;       // numerator coefficients
347     parameter_t b0, b1, b2;       // denominator coefficients
348   };
349 
350   class FILTER_COEFS {
351   public:
352     parameter_t A, B, C, D;       // filter coefficients
353   };
354 
355   std::vector<TRIPLE_COEFS> ProtoCoef;         // Filter prototype coefficients,
356                                           // for each filter section
357   std::vector<FILTER_COEFS> Coef;
358 
359   parameter_t cutoff, Q, gain, gain_orig;
360   parameter_t pi;
361   parameter_t laskuri;
362 
363   parameter_t ad, bd, wp;      // for szxform()
364 
365   void szxform(int section);
366   void refresh_values(void);
367 
368 public:
369 
name(void)370   virtual std::string name(void) const { return("Resonant lowpass filter"); }
parameter_names(void)371   virtual std::string parameter_names(void) const { return("cutoff-freq,resonance,gain"); }
372 
373   virtual void set_parameter(int param, parameter_t value);
374   virtual parameter_t get_parameter(int param) const;
375 
376   virtual void init(SAMPLE_BUFFER *insample);
377   virtual void process(void);
378 
clone(void)379   EFFECT_RESONANT_LOWPASS* clone(void) const { return new EFFECT_RESONANT_LOWPASS(*this); }
new_expr(void)380   EFFECT_RESONANT_LOWPASS* new_expr(void) const { return new EFFECT_RESONANT_LOWPASS(); }
381   EFFECT_RESONANT_LOWPASS (parameter_t cutoff = 1000.0,
382 			   parameter_t resonance = 1.0,
383 			   parameter_t gain = 1.0);
384 };
385 
386 /**
387  * Resonating bandpass filter
388  *
389  * Based on a second order all-pole (IIR) band-pass filter from SPKit
390  * (for more info, see: http://www.music.helsinki.fi/research/spkit)
391  */
392 class EFFECT_RESONATOR : public EFFECT_FILTER {
393 
394 private:
395 
396   SAMPLE_ITERATOR_CHANNELS i;
397 
398   parameter_t center;
399   parameter_t width;
400 
401   std::vector<SAMPLE_SPECS::sample_t> cona;
402   std::vector<SAMPLE_SPECS::sample_t> conb;
403 
404   std::vector<SAMPLE_SPECS::sample_t> saout0, saout1;
405 
406 public:
407 
name(void)408   virtual std::string name(void) const { return("Resonator filter"); }
parameter_names(void)409   virtual std::string parameter_names(void) const { return("center-freq,width"); }
410 
411   virtual void set_parameter(int param, parameter_t value);
412   virtual parameter_t get_parameter(int param) const;
413 
414   virtual void init(SAMPLE_BUFFER *insample);
415   virtual void process(void);
416 
clone(void)417   EFFECT_RESONATOR* clone(void) const { return new EFFECT_RESONATOR(*this); }
new_expr(void)418   EFFECT_RESONATOR* new_expr(void) const { return new EFFECT_RESONATOR(); }
419   EFFECT_RESONATOR (parameter_t center = 1000.0, parameter_t width = 1000.0);
420 };
421 
422 #endif
423