CSL  6.0
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,
47  PEAKING,
48  ALL_PASS
49 } FilterType;
50 #else
51  #define BW_LOW_PASS 0
52  #define BW_HIGH_PASS 1
53  #define BW_BAND_PASS 2
54  #define BW_BAND_STOP 3
55  #define BW_LOW_SHELF 4
56  #define BW_HIGH_SHELF 5
57  #define PEAKING 6
58  #define ALL_PASS 7
59  typedef int FilterType;
60 #endif
61 
62 /// Declare the pointer to freq/bw buffers (if used) and current scale/offset values
63 
64 #define DECLARE_FILTER_CONTROLS \
65  Port * freqPort = mInputs[CSL_FILTER_FREQUENCY]; \
66  Port * bwPort = mInputs[CSL_FILTER_AMOUNT]
67 
68 /// Load the freq/bw-related values at the start
69 
70 #define LOAD_FILTER_CONTROLS \
71  if (freqPort) Controllable::pullInput(freqPort, numFrames); \
72  if (bwPort) Controllable::pullInput(bwPort, numFrames)
73 
74 /// FrequencyAmount -- mix-in class with frequency and amount (BW) control inputs (may be constants or
75 /// generators). amount (probably 0..1) is a generalised placeholder for bandwidth, resonance or radius,
76 /// according to filter type or could equally be used as a kind of x,y location in the frequency domain
77 
78 class FrequencyAmount : public virtual Controllable {
79 public:
80  FrequencyAmount(); ///< Constructors
81 /* FrequencyAmount(float frequency, float amount = 1.f); ///< also specify bandwidth/radius/resonance etc.
82  FrequencyAmount(UnitGenerator & frequency, float amount = 1.f);
83  FrequencyAmount(UnitGenerator & frequency, UnitGenerator & amount);
84 */ ~FrequencyAmount(); ///< Destructor
85 
86  // accessors
87  void setFrequency(UnitGenerator & frequency); ///< set the receiver's frequency to a UGen or a float
88  void setFrequency(float frequency);
89  float getFrequency();
90 
91  void setAmount(UnitGenerator & amount); ///< set the receiver's amount to a UGen or a float
92  void setAmount(float amount);
93 };
94 
95 ///
96 /// Filter: the canonical-form n-pole/m-zero filter class
97 ///
98 
99 class Filter : public Effect, public Scalable, public FrequencyAmount {
100 
101 public:
102  Filter();
103  Filter(unsigned num_b, unsigned num_a = 1);
104  Filter(UnitGenerator & in, unsigned num_b = 1, unsigned num_a = 1);
105  Filter(UnitGenerator & in, SampleBuffer bCoeffs, SampleBuffer aCoeffs, unsigned num_b, unsigned num_a);
106  ~Filter();
107 
108  void clear(void); ///< clears the input/output buffers
109  virtual void setupCoeffs() { }; ///< to be overloaded by subclasses
110  /// supply the coefficients directly
111  void setupCoeffs(SampleBuffer bCoeffs, SampleBuffer aCoeffs, unsigned num_b, unsigned num_a );
112 
113  virtual void nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (CException);
114 
115  void dump(); ///< log information about myself
116 
117 protected:
118  void init(unsigned a, unsigned b); ///< shared initialization function
119 
120  float mBCoeff[FILTER_MAX_COEFFICIENTS]; ///< array of numerator coeffs
121  float mACoeff[FILTER_MAX_COEFFICIENTS]; ///< array of denominator coeffs
122  unsigned mBNum; ///< number of coeffs in b
123  unsigned mANum; ///< number of coeffs in a
124  Buffer * mPrevInputs; ///< arrays of past input and output samples
126  float mFrame; ///< to keep hold of sample rate for calculating coeffs
127 };
128 
129 /// Butterworth IIR (2nd order recursive) filter.
130 ///
131 /// This operates upon a buffer of frames of amplitude samples by applying the following equation
132 /// 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.
133 /// It has constructors that can calculate the coefficients from a given cutoff frequency.
134 ///
135 /// Note that the bandwidth is ignored for HPF & LPF filters
136 
137 class Butter : public Filter {
138 
139 public:
140  // constructors / destructor
141  Butter ();
142  Butter (FilterType type, float cutoff);
143  Butter (FilterType type, float center, float bandwidth);
144  Butter (UnitGenerator & in, FilterType type, float cutoff);
145  Butter (UnitGenerator & in, FilterType type, UnitGenerator & cutoff);
146  Butter (UnitGenerator & in, FilterType type, float center, float bandwidth);
147  Butter (UnitGenerator & in, FilterType type, UnitGenerator & center, UnitGenerator & bandwidth);
148  // Filtering
149  void setupCoeffs();
150 
151 protected:
152  int mFilterType; // flag as to what kind of filter I am
153 
154 };
155 
156 /// General-purpose Biquad IIR (2nd order recursive) filter.
157 /// This is simplified and optimized, but doesn't support dynamic or scalable controls.
158 /// It uses inst vars rather than arrays for the coefficients.
159 /// NB: peak gain (dB) is used only for the peak and shelf types)
160 
161 class Biquad : public Filter {
162 public: // constructors / destructor
163  Biquad ();
164  Biquad (FilterType type, float freq, float Q, float dB = 0.0f);
165  Biquad (UnitGenerator & in, FilterType type, float freq, float Q, float dB = 0.0f);
166  // this version is optimized
167  void nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (CException);
168  // Filtering
169  void setQ(float q);
170  void setFrq(float f);
171  void incrFrq(float f);
172  void setBoost(float d);
173  void incrBoost(float d);
174 
175 protected:
176  int mFilterType; ///< flag as to what kind of filter I am
177  float Fc, dB, Q; ///< ctr frq (Hz), peak (dB), Q(uality) factor
178  float a0, a1, a2, b1, b2; ///< coefficients
179  float z1, z2; ///< past outputs
180  void setupCoeffs();
181 };
182 
183 /// Formant Filter with zeros at +-z and complex conjugate poles at +-omega.
184 /// setupCoeffs() looks at the member var called normalize;
185 /// if normalize is true, the filter zeros are placed at z = 1, z = -1, and the coefficients
186 /// are then normalized to produce a constant unity peak gain. The resulting filter
187 /// frequency response has a resonance at the given frequency. The closer the poles
188 /// are to the unit-circle (radius close to one), the narrower the resulting resonance width.
189 
190 class Formant : public Filter {
191 
192 public:
193  /// constructors & destructor
194  Formant (UnitGenerator & in, float center_freq, float radius);
195  Formant (UnitGenerator & in, UnitGenerator & center_freq, float radius);
196  ~Formant(void) { };
197 
198  /// Filtering methods
199  void setupCoeffs();
200  void setNormalize(bool normalize);
201 
202 protected:
204 };
205 
206 /// Notch Filter with poles at +-z and complex conjugate zeros at +-omega.
207 
208 class Notch : public Filter {
209 
210 public:
211  /// constructors & destructor
212  Notch (UnitGenerator & in, float center_freq, float radius);
213  Notch (UnitGenerator & in, UnitGenerator & center_freq, float radius);
214  ~Notch(void) { };
215  // Filtering
216  void setupCoeffs ();
217 
218 };
219 
220 /// Allpass Filter with a pole and a zero at equal frequency and straddling the unit circle.
221 /// Allows all freqs to pass through but messes with phases.
222 ///
223 /// Note that the Amount parameter of FrequencyAmount is ignored.
224 
225 class Allpass : public Filter {
226 
227 public:
228  // constructors / destructor
229  Allpass (UnitGenerator & in, float coeff);
230  Allpass (UnitGenerator & in, UnitGenerator & coeff);
231  ~Allpass(void) { };
232  // Filtering
233  void setupCoeffs();
234 
235 protected:
237  float mCoeff;
239 };
240 
241 /// Moog-style resonant VCF class
242 
243 class Moog : public Filter {
244 
245 public:
246  // constructors / destructor
247  Moog (UnitGenerator & in);
248  Moog (UnitGenerator & in, UnitGenerator & cutoff);
249  Moog (UnitGenerator & in, UnitGenerator & cutoff, UnitGenerator & resonance);
250  Moog (UnitGenerator & in, float cutoff);
251  Moog (UnitGenerator & in, float cutoff, float resonance);
252  ~Moog (void) { };
253  // Filtering
254  void setupCoeffs ();
255 
256  void nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (CException);
257 
258 protected:
259  float k, p, r; // coefficients
260  float x, oldx;
261  float y1, y2, y3, y4, oldy1, oldy2, oldy3;
262  bool debugging;
263 };
264 
265 }
266 
267 #endif
sample * SampleBuffer
1-channel buffer data type, vector of (sample)
Definition: CSL_Types.h:194
Buffer * mPrevInputs
arrays of past input and output samples
Definition: Filters.h:124
float a0
Definition: Filters.h:178
unsigned mBNum
number of coeffs in b
Definition: Filters.h:122
virtual void setupCoeffs()
Definition: Filters.h:109
float x
Definition: Filters.h:260
float mBCoeff[FILTER_MAX_COEFFICIENTS]
array of numerator coeffs
Definition: Filters.h:120
Buffer * mPrevOutputs
Definition: Filters.h:125
void setupCoeffs()
Definition: Filters.cpp:402
~Formant(void)
Definition: Filters.h:196
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Definition: Accessor.h:17
Effect – mix-in for classes that have unit generators as inputs (like filters).
Definition: CSL_Core.h:466
void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
really compute the next buffer given an offset base channel; this is called by nextBuffer, possibly multiple times
Definition: Filters.cpp:521
~Allpass(void)
Definition: Filters.h:231
void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
really compute the next buffer given an offset base channel; this is called by nextBuffer, possibly multiple times
Definition: Filters.cpp:666
float a2
Definition: Filters.h:178
Notch(UnitGenerator &in, float center_freq, float radius)
constructors & destructor
Definition: Filters.cpp:584
float mCoeff
Definition: Filters.h:237
float mFrame
to keep hold of sample rate for calculating coeffs
Definition: Filters.h:126
float z1
Definition: Filters.h:179
float p
Definition: Filters.h:259
void setupCoeffs()
Definition: Filters.cpp:625
#define PEAKING
Definition: Filters.h:57
void setupCoeffs()
Definition: Filters.cpp:249
Formant(UnitGenerator &in, float center_freq, float radius)
constructors & destructor
Definition: Filters.cpp:542
void setBoost(float d)
Definition: Filters.cpp:511
void incrBoost(float d)
Definition: Filters.cpp:516
void setAmount(UnitGenerator &amount)
set the receiver's amount to a UGen or a float
Definition: Filters.cpp:45
float y2
Definition: Filters.h:261
int mFilterType
Definition: Filters.h:152
#define BW_LOW_SHELF
Definition: Filters.h:55
#define BW_HIGH_SHELF
Definition: Filters.h:56
void incrFrq(float f)
Definition: Filters.cpp:506
Filter: the canonical-form n-pole/m-zero filter class.
Definition: Filters.h:99
float Q
ctr frq (Hz), peak (dB), Q(uality) factor
Definition: Filters.h:177
float oldx
Definition: Filters.h:260
float Fc
Definition: Filters.h:177
void setQ(float q)
Definition: Filters.cpp:496
#define ALL_PASS
Definition: Filters.h:58
float dB
Definition: Filters.h:177
Notch Filter with poles at +-z and complex conjugate zeros at +-omega.
Definition: Filters.h:208
~Moog(void)
Definition: Filters.h:252
Controllable – superclass of the mix-ins that add control or signal inputs. This holds onto a map of...
Definition: CSL_Core.h:371
#define BW_LOW_PASS
Definition: Filters.h:51
~FrequencyAmount()
Destructor.
Definition: Filters.cpp:23
void dump()
log information about myself
Definition: Filters.cpp:169
Scalable – mix-in class with scale and offset control inputs (may be constants or generators)...
Definition: CSL_Core.h:403
Buffer mCoeffBuffer
Definition: Filters.h:238
Allpass Filter with a pole and a zero at equal frequency and straddling the unit circle. Allows all freqs to pass through but messes with phases.
Definition: Filters.h:225
~Notch(void)
Definition: Filters.h:214
int mFilterType
flag as to what kind of filter I am
Definition: Filters.h:176
#define BW_BAND_PASS
Definition: Filters.h:53
General-purpose Biquad IIR (2nd order recursive) filter. This is simplified and optimized, but doesn't support dynamic or scalable controls. It uses inst vars rather than arrays for the coefficients. NB: peak gain (dB) is used only for the peak and shelf types)
Definition: Filters.h:161
#define FILTER_MAX_COEFFICIENTS
Filters.h – CSL filter classes.
Definition: Filters.h:32
float a1
Definition: Filters.h:178
float k
Definition: Filters.h:259
float y1
Definition: Filters.h:261
float b2
coefficients
Definition: Filters.h:178
FrequencyAmount()
Constructors.
Definition: Filters.cpp:17
bool debugging
Definition: Filters.h:262
void setupCoeffs()
Definition: Filters.cpp:597
#define BW_HIGH_PASS
Definition: Filters.h:52
void setFrq(float f)
Definition: Filters.cpp:501
unsigned mANum
number of coeffs in a
Definition: Filters.h:123
float getFrequency()
Definition: Filters.cpp:41
float oldy3
Definition: Filters.h:261
Filter()
Generic Filter class with scalable order and generic next_buffer method that implememnts the canonica...
Definition: Filters.cpp:64
float b1
Definition: Filters.h:178
float y3
Definition: Filters.h:261
void setFrequency(UnitGenerator &frequency)
set the receiver's frequency to a UGen or a float
Definition: Filters.cpp:27
Formant Filter with zeros at +-z and complex conjugate poles at +-omega. setupCoeffs() looks at the m...
Definition: Filters.h:190
Butterworth IIR (2nd order recursive) filter.
Definition: Filters.h:137
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
Definition: CSL_Core.h:106
int FilterType
Definition: Filters.h:59
UnitGenerator * mCoeffUGen
Definition: Filters.h:236
Moog-style resonant VCF class.
Definition: Filters.h:243
float oldy2
Definition: Filters.h:261
~Filter()
Filter destructor frees temp memory.
Definition: Filters.cpp:98
float z2
past outputs
Definition: Filters.h:179
float r
Definition: Filters.h:259
#define BW_BAND_STOP
Definition: Filters.h:54
float oldy1
Definition: Filters.h:261
forward declaration
Definition: CSL_Core.h:241
Allpass(UnitGenerator &in, float coeff)
Definition: Filters.cpp:611
float mACoeff[FILTER_MAX_COEFFICIENTS]
array of denominator coeffs
Definition: Filters.h:121
virtual void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
really compute the next buffer given an offset base channel; this is called by nextBuffer, possibly multiple times
Definition: Filters.cpp:105
bool mNormalize
Definition: Filters.h:203
void clear(void)
clears the input/output buffers
Definition: Filters.cpp:163
void init(unsigned a, unsigned b)
shared initialization function
Definition: Filters.cpp:84
FrequencyAmount – mix-in class with frequency and amount (BW) control inputs (may be constants or ge...
Definition: Filters.h:78
void setupCoeffs()
Definition: Filters.cpp:701
void setNormalize(bool normalize)
Definition: Filters.cpp:558
float y4
Definition: Filters.h:261
Butter()
Butterworth IIR (2nd order recursive) filter. This operates upon a buffer of frames of amplitude samp...
Definition: Filters.cpp:193
Base class of CSL exceptions (written upper-case). Has a string message.
void setupCoeffs()
Filtering methods.
Definition: Filters.cpp:566
Moog(UnitGenerator &in)
Definition: Filters.cpp:634