Jamoma API  0.6.0.a19
TTMirrorBandpass10.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup dspFilterLib
4  *
5  * @brief #TTMirror5 is a 10th-order bandpass/notch filter built up from a 2-path allpass structure transformed from the 5th-order #TTMirror5 lowpass filter
6  *
7  * @details
8  *
9  * @authors Timothy Place, Trond Lossius
10  *
11  * @copyright Copyright © 2010, Timothy Place @n
12  * This code is licensed under the terms of the "New BSD License" @n
13  * http://creativecommons.org/licenses/BSD/
14  */
15 
16 
17 #include "TTMirrorBandpass10.h"
18 
19 #define thisTTClass TTMirrorBandpass10
20 #define thisTTClassName "mirror.bandpass.10"
21 #define thisTTClassTags "dspFilterLib, audio, processor, filter, bandpass, notch"
22 
23 #ifdef TT_PLATFORM_WIN
24 #include <Algorithm>
25 #endif
26 
27 TT_AUDIO_CONSTRUCTOR,
28  mF0("allpass.4a"),
29  mF1("allpass.2c"),
30  mF2("allpass.4a"),
31  mBandwidth(1000.0)
32 {
33  TTChannelCount initialMaxNumChannels = arguments;
34 
39  addMessage(clear);
40  addUpdates(MaxNumChannels);
41 
42  setAttributeValue(kTTSym_maxNumChannels, initialMaxNumChannels);
43  setAttributeValue(TT("mode"), TT("bandpass"));
44  setAttributeValue(TT("frequency"), sr/4.0);
45  setAttributeValue(TT("q"), 1.0);
46 }
47 
48 
49 TTMirrorBandpass10::~TTMirrorBandpass10()
50 {
51 }
52 
53 
54 TTErr TTMirrorBandpass10::updateMaxNumChannels(const TTValue& oldMaxNumChannels, TTValue&)
55 {
56  mF0.set(kTTSym_maxNumChannels, mMaxNumChannels);
57  mF1.set(kTTSym_maxNumChannels, mMaxNumChannels);
58  mF2.set(kTTSym_maxNumChannels, mMaxNumChannels);
59  clear();
60  return kTTErrNone;
61 }
62 
63 
64 TTErr TTMirrorBandpass10::clear()
65 {
66  mF0.send(kTTSym_clear);
67  mF1.send(kTTSym_clear);
68  mF2.send(kTTSym_clear);
69  return kTTErrNone;
70 }
71 
72 
73 TTErr TTMirrorBandpass10::setMode(const TTValue& newValue)
74 {
75  TTSymbol newMode = newValue;
76 
77  if (newMode == TT("notch")) {
78  mMode = TT("notch");
79  setCalculateMethod(calculateNotch);
80  setProcessMethod(processNotch);
81  }
82  else { // bandpass
83  mMode = TT("bandpass");
84  setCalculateMethod(calculateBandpass);
85  setProcessMethod(processBandpass);
86  }
87  return kTTErrNone;
88 }
89 
90 
91 TTErr TTMirrorBandpass10::calculateCoefficients(void)
92 {
93  const TTFloat64 f_s = sr;
94  const TTFloat64 f_c = TTClip<TTFloat64>(mFrequency, 0.0, sr/2.0);
95  const TTFloat64 f_bw = mBandwidth;
96  const TTFloat64 theta_fc = kTTTwoPi * (f_c/f_s);
97  const TTFloat64 theta_bw = kTTTwoPi * (f_bw/f_s);
98  const TTFloat64 b = (1 - tan(theta_bw / 2.0)) / (1 + tan(theta_bw / 2.0));
99  const TTFloat64 c = cos(theta_fc);
100  TTFloat64 alpha;
101  TTFloat64 d_0;
102  TTFloat64 d_1;
103  TTFloat64 d_2;
104  TTFloat64 d_3;
105  TTFloat64 d_4;
106  TTFloat64 e_1;
107  TTFloat64 e_2;
108 
109  // Path-0
110 
111  alpha = 0.141348681136137; // these values for alpha give us a -60dB stopband
112  d_0 = 1 + alpha*b*b;
113  d_1 = (-2*c*(1+b)*(1+alpha*b)) / d_0;
114  d_2 = ((1+alpha)*(c*c*(1+b*b)+2*b*(1+c*c))) / d_0; // This equation is wrong in the F.H. Book
115  d_3 = (-2*c*(1+b)*(alpha + b)) / d_0; // This equation is wrong in the Safari-online version of the F.H. Book
116  d_4 = (alpha + b*b) / d_0;
117 
118  mF0.set("d1", d_1);
119  mF0.set("d2", d_2);
120  mF0.set("d3", d_3);
121  mF0.set("d4", d_4);
122 
123  // Path-1
124 
125  e_1 = -c - c*b;
126  e_2 = b;
127 
128  mF1.set(TT("e1"), e_1);
129  mF1.set(TT("e2"), e_2);
130 
131  alpha = 0.589994872274064; // these values for alpha give us a -60dB stopband
132  d_0 = 1 + alpha*b*b;
133  d_1 = (-2*c*(1+b)*(1+alpha*b)) / d_0;
134  d_2 = ((1+alpha)*(c*c*(1+b*b)+2*b*(1+c*c))) / d_0; // This equation is wrong in the F.H. Book
135  d_3 = (-2*c*(1+b)*(alpha + b)) / d_0; // This equation is wrong in the Safari-online version of the F.H. Book
136  d_4 = (alpha + b*b) / d_0;
137 
138  mF2.set("d1", d_1);
139  mF2.set("d2", d_2);
140  mF2.set("d3", d_3);
141  mF2.set("d4", d_4);
142 
143  return kTTErrNone;
144 
145 }
146 
147 
148 TTErr TTMirrorBandpass10::setFrequency(const TTValue& newValue)
149 {
150  mFrequency = newValue;
151  if (mBandwidthSetWithQ)
152  return setQ(mQ);
153  else
154  return calculateCoefficients();
155 }
156 
157 
158 // NOTE: if we also wanted to set bandwidth in octaves,
159 // check this article: http://www.rane.com/note170.html
160 //
161 // Q = (sqrt(2^n) * f_1) / (2^n * f_1 - f_1) , n = number of octaves
162 //
163 // the reverse operation is detailed in the article
164 
165 TTErr TTMirrorBandpass10::setBandwidth(const TTValue& newValue)
166 {
167  mBandwidth = TTClip<TTFloat64>(newValue, 0.0, sr/2.0);
169  mBandwidthSetWithQ = NO;
170  return calculateCoefficients();
171 }
172 
173 
174 TTErr TTMirrorBandpass10::setQ(const TTValue& newValue)
175 {
176  mQ = newValue;
177  TTLimitMin(mQ, 0.0);
179  mBandwidthSetWithQ = YES;
180  return calculateCoefficients();
181 }
182 
183 
184 inline void TTMirrorBandpass10::filterKernel(const TTFloat64& input, TTFloat64& outputPath0, TTFloat64& outputPath1, TTPtrSizedInt channel)
185 {
186  TTFloat64 temp;
187 
188  TTBASE(mF0, TTAllpass4a)->calculateValue(input, outputPath0, channel);
189 
190  TTBASE(mF1, TTAllpass2c)->calculateValue(input, temp, channel);
191  TTBASE(mF2, TTAllpass4a)->calculateValue(temp, outputPath1, channel);
192 }
193 
194 
195 TTErr TTMirrorBandpass10::calculateBandpass(const TTFloat64& x, TTFloat64& y, TTPtrSizedInt channel)
196 {
197  TTFloat64 outputFromPath0;
198  TTFloat64 outputFromPath1;
199 
200  filterKernel(x, outputFromPath0, outputFromPath1, channel);
201  y = (outputFromPath0 + outputFromPath1) * 0.5;
202  return kTTErrNone;
203 }
204 
205 
206 TTErr TTMirrorBandpass10::calculateNotch(const TTFloat64& x, TTFloat64& y, TTPtrSizedInt channel)
207 {
208  TTFloat64 outputFromPath0;
209  TTFloat64 outputFromPath1;
210 
211  filterKernel(x, outputFromPath0, outputFromPath1, channel);
212  y = (outputFromPath0 - outputFromPath1) * 0.5;
213  return kTTErrNone;
214 }
215 
216 
217 TTErr TTMirrorBandpass10::processBandpass(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
218 {
219  TT_WRAP_CALCULATE_METHOD(calculateBandpass);
220 }
221 
222 
223 TTErr TTMirrorBandpass10::processNotch(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
224 {
225  TT_WRAP_CALCULATE_METHOD(calculateNotch);
226 }
227 
TTErr send(const TTSymbol aName)
Send a message to this object with no arguments.
Definition: TTObject.cpp:135
TTChannelCount mMaxNumChannels
This is the maximum number of channels that can be guaranteed to work.
TTAudioObject mF0
filter0 (in the upper path)
TTMirror5 is a 10th-order bandpass/notch filter built up from a 2-path allpass structure transformed ...
TTFOUNDATION_EXPORT const TTFloat64 kTTTwoPi
Pre-calculated value of pi * 2.
Definition: TTBase.cpp:24
#define TTBASE(instance_, class_)
Macro to access the actual C++ class that is contained inside of the TTObject as a pointer...
Definition: TTObject.h:211
#define setProcessMethod(methodName)
A convenience macro to be used by subclasses for setting the process method.
Symbol type.
Definition: TTBase.h:282
double TTFloat64
64 bit floating point number
Definition: TTBase.h:188
#define TT
This macro is defined as a shortcut for doing a lookup in the symbol table.
Definition: TTSymbol.h:155
#define setCalculateMethod(methodName)
A convenience macro to be used by subclasses for setting the calculate method.
TTFloat64 mBandwidth
attribute: in hertz
TTAudioObject mF2
filter2 (in the lower path, second block)
64-bit floating point
Definition: TTBase.h:272
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object.
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
A second-order building-block allpass filter.
Definition: TTAllpass4a.h:28
A second-order building-block allpass filter.
Definition: TTAllpass2c.h:49
TTUInt16 TTChannelCount
Data type used when counting the number of channels in multi-channel audio signals and processes...
Definition: TTAudioSignal.h:31
TTSymbol mMode
attribute: lowpass or highpass
TTFloat64 mQ
attribute: bandwidth expressed as Q
A simple container for an array of TTAudioSignal pointers.
TTAudioObject mF1
filter1 (in the lower path, first block)
long TTPtrSizedInt
An integer that is the same size as a pointer.
Definition: TTBase.h:240
TTBoolean mBandwidthSetWithQ
flag to tell us whether to adjust bandwidth when frequency changes
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
#define addAttributeWithSetter(name, type)
A convenience macro to be used by subclasses for registering attributes with a custom setter...
Definition: TTAttribute.h:47
#define addMessage(name)
A convenience macro to be used by subclasses for registering messages.
Definition: TTMessage.h:19
No Error.
Definition: TTBase.h:343
TTFloat64 mFrequency
attribute: in hertz
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
#define addUpdates(updateName)
An 'update' is a message sent to a subclass instance from its parent class.
Definition: TTMessage.h:44
TTUInt32 sr
Current sample rate being used by this object.