Jamoma API  0.6.0.a19
TTSvf.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup dspFilterLib
4  *
5  * @brief #TTSvf is a state variable filter object
6  *
7  * @details
8  *
9  * @authors Timothy Place, Trond Lossius
10  *
11  * @copyright Copyright © 2008, 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 "TTSvf.h"
18 
19 #define thisTTClass TTSvf
20 #define thisTTClassName "svf"
21 #define thisTTClassTags "dspFilterLib, audio, processor, filter, lowpass, highpass, bandpass, notch"
22 
23 
24 TT_AUDIO_CONSTRUCTOR
25 {
26  // register attributes
28  addAttributeProperty(Frequency, range, TTValue(2.0, 20000.0));
29  addAttributeProperty(Frequency, rangeChecking, TT("clip"));
30 
32  addAttributeProperty(Resonance, range, TTValue(0.001, 100.0));
33  addAttributeProperty(Resonance, rangeChecking, TT("clip"));
34 
36 
37  // register methods
38  addMessage(clear);
39  addUpdates(MaxNumChannels);
40  addUpdates(SampleRate);
41 
42  // Set Defaults...
43  setAttributeValue(kTTSym_maxNumChannels, arguments); // This attribute is inherited
44  setAttributeValue(TT("mode"), TT("lowpass"));
45  setAttributeValue(TT("frequency"), 1000.0);
46  setAttributeValue(TT("resonance"), 1.0);
47 }
48 
49 
50 TTSvf::~TTSvf()
51 {
52  ;
53 }
54 
55 
56 TTErr TTSvf::updateMaxNumChannels(const TTValue& oldMaxNumChannels, TTValue&)
57 {
58  mLowpass_output.resize(mMaxNumChannels);
59  mHighpass_output.resize(mMaxNumChannels);
60  mBandpass_output.resize(mMaxNumChannels);
61  mNotch_output.resize(mMaxNumChannels);
62  mPeak_output.resize(mMaxNumChannels);
63  clear();
64  return kTTErrNone;
65 }
66 
67 
68 TTErr TTSvf::updateSampleRate(const TTValue& oldSampleRate, TTValue&)
69 {
71  return setFrequency(v);
72 }
73 
74 
76 {
77  mLowpass_output.assign(mMaxNumChannels, 0.0);
78  mHighpass_output.assign(mMaxNumChannels, 0.0);
79  mBandpass_output.assign(mMaxNumChannels, 0.0);
80  mNotch_output.assign(mMaxNumChannels, 0.0);
81  mPeak_output.assign(mMaxNumChannels, 0.0);
82  return kTTErrNone;
83 }
84 
85 
86 TTErr TTSvf::setMode(const TTValue& newValue)
87 {
88  TTSymbol newMode = newValue;
89 
90  if (newMode == TT("lowpass")) {
92  setCalculateMethod(calculateLowpass);
93  }
94  else if (newMode == TT("highpass")) {
95  setProcessMethod(processHighpass);
96  setCalculateMethod(calculateHighpass);
97  }
98 else if (newMode == TT("bandpass")) {
99  setProcessMethod(processBandpass);
100  setCalculateMethod(calculateBandpass);
101  }
102 else if (newMode == TT("notch")) {
103  setProcessMethod(processNotch);
104  setCalculateMethod(calculateNotch);
105  }
106 else if (newMode == TT("peak")) {
107  setProcessMethod(processPeak);
108  setCalculateMethod(calculatePeak);
109  }
110  else {
111  logError("bad mode specified for TTSvf: %s", newMode.c_str());
112  return kTTErrInvalidValue;
113  }
114 
115  mMode = newMode;
116  return kTTErrNone;
117 }
118 
119 
120 TTErr TTSvf::setFrequency(const TTValue& newValue)
121 {
122  mFrequency = newValue;
123  mF = 2.0 * sin(kTTHalfPi * mFrequency / sr ); // equivalent to mF = 2.0 * sin(kTTPi * mFrequency / double(sr * 2));
124  if (mF > 0.25)
125  mF = 0.25;
126  calculateCoefficients();
127  return kTTErrNone;
128 }
129 
130 
131 TTErr TTSvf::setResonance(const TTValue& newValue)
132 {
133  mResonance = newValue;
134  mR = mResonance * 0.1;
135  calculateCoefficients();
136  return kTTErrNone;
137 }
138 
139 
140 void TTSvf::calculateCoefficients()
141 {
142  TTFloat64 temp1 = 2.0 / mF - mF * 0.5;
143  TTFloat64 temp2 = 2.0 * (1.0 - pow(mR, 0.25));
144 
145  TTLimitMax(temp1, 2.0);
146 
147  if (temp1 < temp2)
148  mDamp = temp1;
149  else
150  mDamp = temp2;
151 }
152 
153 
155 {
156  // UNROLLED (oversampling) FOR LOOP FOR SPEED
157  mNotch_output[channel] = value - mDamp * mBandpass_output[channel];
158  TTZeroDenormal(mNotch_output[channel]);
159 
160  mLowpass_output[channel] += TTAntiDenormal(mFrequency * mBandpass_output[channel]);
161 
162  mHighpass_output[channel] = mNotch_output[channel] - mLowpass_output[channel];
163  TTZeroDenormal(mHighpass_output[channel]);
164 
165  mBandpass_output[channel] = mFrequency * mHighpass_output[channel] + mBandpass_output[channel];
166  TTZeroDenormal(mBandpass_output[channel]);
167 
168  mNotch_output[channel] = value - mDamp * mBandpass_output[channel];
169  TTZeroDenormal(mNotch_output[channel]);
170 
171  mLowpass_output[channel] += TTAntiDenormal(mFrequency * mBandpass_output[channel]);
172 
173  mHighpass_output[channel] = mNotch_output[channel] - mLowpass_output[channel];
174  TTZeroDenormal(mHighpass_output[channel]);
175 
176  mBandpass_output[channel] = mFrequency * mHighpass_output[channel] + mBandpass_output[channel];
177  TTZeroDenormal(mBandpass_output[channel]);
178 }
179 
180 
181 inline TTErr TTSvf::calculateLowpass(const TTFloat64& x, TTFloat64& y, TTPtrSizedInt channel)
182 {
183  tick(x, channel);
184  y = 0.5 * mLowpass_output[channel];
185  return kTTErrNone;
186 }
187 
188 
190 {
191  TT_WRAP_CALCULATE_METHOD(calculateLowpass);
192 }
193 
194 
195 
196 inline TTErr TTSvf::calculateHighpass(const TTFloat64& x, TTFloat64& y, TTPtrSizedInt channel)
197 {
198  tick(x, channel);
199  y = 0.5 * mHighpass_output[channel];
200  return kTTErrNone;
201 }
202 
203 
204 TTErr TTSvf::processHighpass(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
205 {
206  TT_WRAP_CALCULATE_METHOD(calculateHighpass);
207 }
208 
209 
210 
211 inline TTErr TTSvf::calculateBandpass(const TTFloat64& x, TTFloat64& y, TTPtrSizedInt channel)
212 {
213  tick(x, channel);
214  y = 0.5 * mBandpass_output[channel];
215  return kTTErrNone;
216 }
217 
218 
219 TTErr TTSvf::processBandpass(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
220 {
221  TT_WRAP_CALCULATE_METHOD(calculateBandpass);
222 }
223 
224 
225 
226 inline TTErr TTSvf::calculateNotch(const TTFloat64& x, TTFloat64& y, TTPtrSizedInt channel)
227 {
228  tick(x, channel);
229  y = 0.5 * mNotch_output[channel];
230  return kTTErrNone;
231 }
232 
233 
234 TTErr TTSvf::processNotch(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
235 {
236  TT_WRAP_CALCULATE_METHOD(calculateNotch);
237 }
238 
239 
240 
241 
242 inline TTErr TTSvf::calculatePeak(const TTFloat64& x, TTFloat64& y, TTPtrSizedInt channel)
243 {
244  tick(x, channel);
245  y = 0.5 * (mLowpass_output[channel] - mHighpass_output[channel]);
246  return kTTErrNone;
247 }
248 
249 
250 TTErr TTSvf::processPeak(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
251 {
252  TT_WRAP_CALCULATE_METHOD(calculatePeak);
253 }
An inappropriate value was specified for an attribute or variable.
Definition: TTBase.h:349
TTChannelCount mMaxNumChannels
This is the maximum number of channels that can be guaranteed to work.
TTErr processLowpass(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
Audio processing methods.
Definition: TTSvf.cpp:189
TTSymbol mMode
lowpass, highpass, bandpass, notch, or peak
Definition: TTSvf.h:37
TTErr logError(TTImmutableCString fmtstring,...)
Log errors scoped to this object instance.
TTErr clear()
This algorithm uses an IIR filter, meaning that it relies on feedback.
Definition: TTSvf.cpp:75
#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
TTSvf is a state variable filter object
void tick(TTSampleValue value, TTChannelCount channel)
Performs the actual SVF calculations.
Definition: TTSvf.cpp:154
#define setCalculateMethod(methodName)
A convenience macro to be used by subclasses for setting the calculate method.
64-bit floating point
Definition: TTBase.h:272
#define addAttributeProperty(attributeName, propertyName, initialValue)
A convenience macro to be used for registering properties of attributes.
Definition: TTAttribute.h:68
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
const char * c_str() const
Return a pointer to the internal string as a C-string.
Definition: TTSymbol.h:77
TTUInt16 TTChannelCount
Data type used when counting the number of channels in multi-channel audio signals and processes...
Definition: TTAudioSignal.h:31
TTFloat64 mFrequency
filter cutoff frequency
Definition: TTSvf.h:35
A simple container for an array of TTAudioSignal pointers.
long TTPtrSizedInt
An integer that is the same size as a pointer.
Definition: TTBase.h:240
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
TTFOUNDATION_EXPORT const TTFloat64 kTTHalfPi
Pre-calculated value of pi/2.
Definition: TTBase.cpp:28
#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 TTSampleValue
A value representing a single audio sample.
Definition: TTBase.h:230
TTFloat64 mResonance
filter resonance – range is best between 1.0 and 16.0
Definition: TTSvf.h:36
[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.