CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

Filters.h
Go to the documentation of this file.
1 ///
2 /// Filters.h -- CSL filter classes.
3 ///
4 /// The base Filter class can perform the generic filter equation based upon a set of feedback
5 /// and feedforward coefficients. Subclasses of Filter implement the setupCoeffs method to build
6 /// these coefficients according to different algorithms.
7 /// The subclasses here mostly inherit from the FrequencyAmount controllable, which specifies a
8 /// center frequency and an 'amount' which may variously be resonance, radius, bandwidth etc
9 /// according to the algorithm.
10 ///
11 /// OK so for example Butter class has a CenterFrequency port and a Bandwidth port,
12 /// but pull_controls must be calling Controllables to do the pullInput()
13 ///
14 /// Or, a generic filter that can take a multichannel UGen for each of aCoeffs and bCoeffs (i.e.
15 /// multichannel ports), and other filter classes that wrap this and have Frequency and Bandwidth ports etc.
16 /// This reduces the calls to setupCoeffs, because they'd actually be part of the nextBuffer instead
17 ///
18 /// The reason is that the Scalable type approach & macros can't be extended to filter otherwise.
19 /// ALSO, there are no similar macros for Effect; how should this work?
20 ///
21 /// OK, the way he had it working here is filtering in place, i.e. no internal buffer,
22 /// but if I inherit from Effect, I do have an internal buffer; this means the first thing to do is
23 /// memcopy the input to the output, then pounce on that; or do the in-place stuff in the Effect port
24 /// and finally copy to output, say with scale & offset performed there.
25 ///
26 /// See the copyright notice and acknowledgment of authors in the file COPYRIGHT
27 ///
28
29 #ifndef CSL_Filters_H
30 #define CSL_Filters_H
31
32 #define FILTER_MAX_COEFFICIENTS (16) // seems reasonable?
33
34 #include "CSL_Core.h"
35
36 namespace csl {
37
38 #ifdef CSL_ENUMS
39
40 typedef enum {
41 BW_LOW_PASS = 0,
42 BW_HIGH_PASS,
43 BW_BAND_PASS,
44 BW_BAND_STOP
45 } ButterworthType;
46 #else
47 #define BW_LOW_PASS 0
48 #define BW_HIGH_PASS 1
49 #define BW_BAND_PASS 2
50 #define BW_BAND_STOP 3
51 typedef int ButterworthType;
52 #endif
53
54 /// Declare the pointer to freq/bw buffers (if used) and current scale/offset values
55
56 #define DECLARE_FILTER_CONTROLS \
57 Port * freqPort = mInputs[CSL_FILTER_FREQUENCY]; \
58 Port * bwPort = mInputs[CSL_FILTER_AMOUNT]
59
60 /// Load the freq/bw-related values at the start
61
62 #define LOAD_FILTER_CONTROLS \
63 if (freqPort) Controllable::pullInput(freqPort, numFrames); \
64 if (bwPort) Controllable::pullInput(bwPort, numFrames)
65
66 /// FrequencyAmount -- mix-in class with frequency and amount (BW) control inputs (may be constants or
67 /// generators). amount (probably 0..1) is a generalised placeholder for bandwidth, resonance or radius,
68 /// according to filter type or could equally be used as a kind of x,y location in the frequency domain
69
70 class FrequencyAmount : public virtual Controllable {
71 public:
72 FrequencyAmount(); ///< Constructors
73 /* FrequencyAmount(float frequency, float amount = 1.f); ///< also specify bandwidth/radius/resonance etc.
74 FrequencyAmount(UnitGenerator & frequency, float amount = 1.f);
75 FrequencyAmount(UnitGenerator & frequency, UnitGenerator & amount);
76 */ ~FrequencyAmount(); ///< Destructor
77
78 // accessors
79 void setFrequency(UnitGenerator & frequency); ///< set the receiver's frequency to a UGen or a float
80 void setFrequency(float frequency);
81 float getFrequency();
82
83 void setAmount(UnitGenerator & amount); ///< set the receiver's amount to a UGen or a float
84 void setAmount(float amount);
85 };
86
87 ///
88 /// Filter: the canonical-form n-pole/m-zero filter class
89 ///
90
91 class Filter : public Effect, public Scalable, public FrequencyAmount {
92
93 public:
94 Filter();
95 Filter(unsigned num_b, unsigned num_a = 1);
96 Filter(UnitGenerator & in, unsigned num_b = 1, unsigned num_a = 1);
97 Filter(UnitGenerator & in, SampleBuffer bCoeffs, SampleBuffer aCoeffs, unsigned num_b, unsigned num_a);
98 ~Filter();
99
100 void clear(void); ///< clears the input/output buffers
101 virtual void setupCoeffs() { }; ///< to be overloaded by subclasses
102 /// supply the coefficients directly
103 void setupCoeffs(SampleBuffer bCoeffs, SampleBuffer aCoeffs, unsigned num_b, unsigned num_a );
104
105 virtual void nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (CException);
106
107 void dump(); ///< log information about myself
108
109 protected:
110 void init(unsigned a, unsigned b); ///< shared initialization function
111
112 float mBCoeff[FILTER_MAX_COEFFICIENTS]; ///< array of numerator coeffs
113 float mACoeff[FILTER_MAX_COEFFICIENTS]; ///< array of denominator coeffs
114 unsigned mBNum; ///< number of coeffs in b
115 unsigned mANum; ///< number of coeffs in a
116 Buffer * mPrevInputs; ///< arrays of past input and output samples
117 Buffer * mPrevOutputs;
118 float mFrame; ///< to keep hold of sample rate for calculating coeffs
119 };
120
121 /// Butterworth IIR (2nd order recursive) filter.
122 /// This operates upon a buffer of frames of amplitude samples by applying the following equation
123 /// y(n) = a0*x(n) + a1*x(n-1) + a2*x(n-2) - b1*y(n-1) - b2*y(n-2) where x is an amplitude sample.
124 /// It has constructors that can calculate the coefficients from a given cutoff frequency.
125
126 class Butter : public Filter {
127
128 public:
129 // constructors / destructor
130 Butter ();
131 Butter (ButterworthType type, float cutoff);
132 Butter (ButterworthType type, float center, float bandwidth);
133 Butter (UnitGenerator & in, ButterworthType type, float cutoff);
134 Butter (UnitGenerator & in, ButterworthType type, UnitGenerator & cutoff);
135 Butter (UnitGenerator & in, ButterworthType type, float center, float bandwidth);
136 Butter (UnitGenerator & in, ButterworthType type, UnitGenerator & center, UnitGenerator & bandwidth);
137 // Filtering
138 void setupCoeffs ();
139
140 protected:
141 int mFilterType; // flag as to what kind of filter I am
142
143 };
144
145 /// Formant Filter with zeros at +-z and complex conjugate poles at +-omega.
146 /// setupCoeffs() looks at the member var called normalize;
147 /// if normalize is true, the filter zeros are placed at z = 1, z = -1, and the coefficients
148 /// are then normalized to produce a constant unity peak gain. The resulting filter
149 /// frequency response has a resonance at the given frequency. The closer the poles
150 /// are to the unit-circle (radius close to one), the narrower the resulting resonance width.
151
152 class Formant : public Filter {
153
154 public:
155 /// constructors & destructor
156 Formant (UnitGenerator & in, float center_freq, float radius);
157 Formant (UnitGenerator & in, UnitGenerator & center_freq, float radius);
158 ~Formant(void) { };
159
160 /// Filtering methods
161 void setupCoeffs();
162 void setNormalize(bool normalize);
163
164 protected:
165 bool mNormalize;
166 };
167
168 /// Notch Filter with poles at +-z and complex conjugate zeros at +-omega.
169
170 class Notch : public Filter {
171
172 public:
173 /// constructors & destructor
174 Notch (UnitGenerator & in, float center_freq, float radius);
175 Notch (UnitGenerator & in, UnitGenerator & center_freq, float radius);
176 ~Notch(void) { };
177 // Filtering
178 void setupCoeffs ();
179
180 };
181
182 /// Allpass Filter with a pole and a zero at equal frequency and straddling the unit circle.
183 /// Allows all freqs to pass through but messes with phases.
184 /// Note that the Amount parameter of FrequencyAmount is ignored.
185
186 class Allpass : public Filter {
187
188 public:
189 // constructors / destructor
190 Allpass (UnitGenerator & in, float coeff);
191 Allpass (UnitGenerator & in, UnitGenerator & coeff);
192 ~Allpass(void) { };
193 // Filtering
194 void setupCoeffs();
195
196 protected:
197 UnitGenerator * mCoeffUGen;
198 float mCoeff;
199 Buffer mCoeffBuffer;
200 };
201
202 /// Moog VCF class
203
204 class Moog : public Filter {
205
206 public:
207 // constructors / destructor
208 Moog (UnitGenerator & in);
209 Moog (UnitGenerator & in, UnitGenerator & cutoff);
210 Moog (UnitGenerator & in, UnitGenerator & cutoff, UnitGenerator & resonance);
211 Moog (UnitGenerator & in, float cutoff);
212 Moog (UnitGenerator & in, float cutoff, float resonance);
213 ~Moog (void) { };
214 // Filtering
215 void setupCoeffs ();
216
217 void nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (CException);
218
219 protected:
220 float k, p, r; // coefficients
221 float x, oldx;
222 float y1, y2, y3, y4, oldy1, oldy2, oldy3;
223 bool debugging;
224 };
225
226 }
227
228 #endif