Jamoma API  0.6.0.a19
TTAudioObjectBase.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup dspLibrary
4  *
5  * @brief #TTAudioObjectBase is the Jamoma DSP Audio Object Base Class
6  *
7  * @details
8  *
9  * @authors Tim Place, Nils Peters, Trond Lossius
10  *
11  * @copyright Copyright © 2008 by 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 "TTDSP.h"
18 #include "TTAudioObjectBase.h"
19 #include "TTEnvironment.h"
20 #include "TTUnitTest.h"
21 
22 #define thisTTClass TTAudioObjectBase
23 
25  TTObjectBase(arguments),
26  mMaxNumChannels(0),
27  attrMute(0),
28  inputArray(kTTSym_audiosignalarray,2),
29  outputArray(kTTSym_audiosignalarray,2),
30  startProcessingTime(0.0),
31  accumulatedProcessingTime(0.0),
32  accumulatedProcessingCalls(0.0)
33 {
34  // Convention: 'Public' attribute names begin with a capital letter, 'Private' attribute names begin with a lower case letter
35 // registerAttribute("maxNumChannels", kTypeUInt8, &maxNumChannels, (TTSetterMethod)&TTAudioObjectBase::setMaxNumChannels);
36  addAttributeWithSetter(MaxNumChannels, kTypeUInt16);
37  addAttributeProperty(MaxNumChannels, defaultValue, 1);
38 
42 
47 
48  // Set Defaults...
49 
50  setAttributeValue(kTTSym_sampleRate, ttEnvironment->mSampleRate);
53  setAttributeValue("bypass", NO);
54 }
55 
56 #undef thisTTClass
57 
58 
60 {
61  ;
62 }
63 
64 
66 {
67  TTChannelCount newNumChannels = newValue;
68 
69  if (newNumChannels < 1)
70  newNumChannels = 1;
71 
72  if (newNumChannels != mMaxNumChannels) {
73  TTValue oldMaxNumChannels = mMaxNumChannels;
74 
75  mMaxNumChannels = newNumChannels;
76  sendMessage("updateMaxNumChannels", oldMaxNumChannels, kTTValNONE);
77  }
78  return kTTErrNone;
79 }
80 
81 
83 {
84  TTValue oldSampleRate(sr);
85 
86  sr = newValue;
87  srInv = 1.0/sr;
88  srMill = sr * 0.001;
89  sendMessage("updateSampleRate", oldSampleRate, kTTValNONE);
90  return kTTErrNone;
91 }
92 
93 
95 {
96  for (TTChannelCount i=0; i<outputs->numAudioSignals; i++) {
97  TTAudioSignal& out = outputs->getSignal(i);
98 
99  if (i<inputs->numAudioSignals) {
100  TTAudioSignal& in = inputs->getSignal(i);
101  TTAudioSignal::copy(in, out);
102  }
103  else
104  out.clear();
105  }
106  return kTTErrNone;
107 }
108 
109 
111 {
112  y = x;
113  return kTTErrNone;
114 }
115 
116 
117 
119 {
120  for (TTChannelCount i=0; i<outputs->numAudioSignals; i++)
121  (outputs->getSignal(i)).clear();
122  return kTTErrNone;
123 }
124 
125 
126 
128 {
129  TTAudioSignalPtr in;
130  TTAudioSignalPtr out;
131  TTErr err;
132 
133  TTObjectBaseInstantiate(kTTSym_audiosignal, &in, 1);
134  TTObjectBaseInstantiate(kTTSym_audiosignal, &out, 1);
135 
136  in->allocWithVectorSize(1);
137  out->allocWithVectorSize(1);
138 
139  in->mSampleVectors[0][0] = x;
140  err = process(in, out);
141  y = out->mSampleVectors[0][0];
142 
143  TTObjectBaseRelease(&in);
144  TTObjectBaseRelease(&out);
145 
146  return err;
147 }
148 
149 
151 {
152  processMethod = newProcessMethod;
153  if (!calculateMethod)
155 
156  if (!attrBypass) {
159  }
160  return kTTErrNone;
161 }
162 
163 
165 {
166  calculateMethod = newCalculateMethod;
167  if (!attrBypass)
169  return kTTErrNone;
170 }
171 
172 
174 {
175  attrBypass = value;
176  if (attrBypass) {
179  }
180  else if (attrMute) {
182  }
183  else {
185  if (calculateMethod)
187  else
189  }
190  return kTTErrNone;
191 }
192 
193 
195 {
196  attrMute = value;
197  if (attrBypass) {
199  }
200  else if (attrMute) {
202  }
203  else {
205  }
206  return kTTErrNone;
207 }
208 
209 
211 {
212  TTFloat64 x = input;
213  TTFloat64 y = 0.0;
214  TTErr err;
215 
216  err = calculate(x, y);
217  output = y;
218  return err;
219 }
220 
221 
223 {
224  TTErr err = kTTErrGeneric;
225 
226  if (valid) {
227  lock();
228  err = (this->*currentCalculateMethod)(x, y, NULL);
229  unlock();
230  }
231  return err;
232 }
233 
234 
236 {
237  TTErr err = kTTErrGeneric;
238 
239  if (valid) {
240  TTFloat64 in;
241  TTFloat64 out;
242  TTUInt32 size;
243 
244  lock();
245 
246  // at the moment we are iterating through the values using the same call to the object
247  // however, if the calculation involves the history of previous input or output
248  // then this will not work --
249  // TODO: there needs to be a way to request a calculation of a list on the object if it defines such a method
250 
251  y.clear();
252  size = x.size();
253  for (TTUInt32 i=0; i<size; i++) {
254  in = x[i];
255  err = (this->*currentCalculateMethod)(in, out, NULL);
256  y.append(out);
257  }
258  unlock();
259  }
260  return err;
261 }
262 
263 
265 {
266  TTErr err = kTTErrGeneric;
267 
268  if (valid) {
269  lock();
270  TTAudioSignalArrayPtr(inputArray.instance())->numAudioSignals = 1;
271  TTAudioSignalArrayPtr(inputArray.instance())->setSignal(0, &in);
272  TTAudioSignalArrayPtr(outputArray.instance())->numAudioSignals = 1;
273  TTAudioSignalArrayPtr(outputArray.instance())->setSignal(0, &out);
274  out.setSampleRate(sr);
276  err = (this->*currentProcessMethod)(TTAudioSignalArrayPtr(inputArray.instance()), TTAudioSignalArrayPtr(outputArray.instance()));
277  else {
279  err = (this->*currentProcessMethod)(TTAudioSignalArrayPtr(inputArray.instance()), TTAudioSignalArrayPtr(outputArray.instance()));
282  }
283  unlock();
284  }
285  return err;
286 }
287 
288 
290 {
291  TTErr err = kTTErrGeneric;
292 
293  if (valid) {
294  lock();
295  TTAudioSignalArrayPtr(inputArray.instance())->numAudioSignals = 0;
296  TTAudioSignalArrayPtr(outputArray.instance())->numAudioSignals = 1;
297  TTAudioSignalArrayPtr(outputArray.instance())->setSignal(0, &out);
298  out.setSampleRate(sr);
300  err = (this->*currentProcessMethod)(TTAudioSignalArrayPtr(inputArray.instance()), TTAudioSignalArrayPtr(outputArray.instance()));
301  else{
303  err = (this->*currentProcessMethod)(TTAudioSignalArrayPtr(inputArray.instance()), TTAudioSignalArrayPtr(outputArray.instance()));
306  }
307  unlock();
308  }
309  return err;
310 }
311 
312 
314 {
315  TTErr err = kTTErrGeneric;
316 
317  if (valid) {
318  lock();
319  TTAudioSignalArrayPtr(inputArray.instance())->numAudioSignals = 2;
320  TTAudioSignalArrayPtr(inputArray.instance())->setSignal(0, &in1);
321  TTAudioSignalArrayPtr(inputArray.instance())->setSignal(1, &in2);
322  TTAudioSignalArrayPtr(outputArray.instance())->numAudioSignals = 2;
323  TTAudioSignalArrayPtr(outputArray.instance())->setSignal(0, &out1);
324  TTAudioSignalArrayPtr(outputArray.instance())->setSignal(1, &out2);
325  out1.setSampleRate(sr);
326  out2.setSampleRate(sr);
328  err = (this->*currentProcessMethod)(TTAudioSignalArrayPtr(inputArray.instance()), TTAudioSignalArrayPtr(outputArray.instance()));
329  else{
331  err = (this->*currentProcessMethod)(TTAudioSignalArrayPtr(inputArray.instance()), TTAudioSignalArrayPtr(outputArray.instance()));
334  }
335  unlock();
336  }
337  return err;
338 }
339 
340 
342 {
343  TTErr err = kTTErrGeneric;
344 
345  if (valid) {
346  lock();
347  TTAudioSignalArrayPtr(inputArray.instance())->numAudioSignals = 2;
348  TTAudioSignalArrayPtr(inputArray.instance())->setSignal(0, &in1);
349  TTAudioSignalArrayPtr(inputArray.instance())->setSignal(1, &in2);
350  TTAudioSignalArrayPtr(outputArray.instance())->numAudioSignals = 1;
351  TTAudioSignalArrayPtr(outputArray.instance())->setSignal(0, &out);
352  out.setSampleRate(sr);
354  err = (this->*currentProcessMethod)(TTAudioSignalArrayPtr(inputArray.instance()), TTAudioSignalArrayPtr(outputArray.instance()));
355  else{
357  err = (this->*currentProcessMethod)(TTAudioSignalArrayPtr(inputArray.instance()), TTAudioSignalArrayPtr(outputArray.instance()));
360  }
361  unlock();
362  }
363  return err;
364 }
365 
366 
368 {
369  TTErr err = kTTErrGeneric;
370 
371  if (valid) {
372  lock();
373  outputs->setAllSampleRates(sr);
375  err = (this->*currentProcessMethod)(inputs, outputs);
376  else{
378  err = (this->*currentProcessMethod)(inputs, outputs);
381  }
382  unlock();
383  }
384  return err;
385 }
386 
387 
389 {
391  startProcessingTime = 0.0;
393  return kTTErrNone;
394 }
395 
396 
398 {
400  return kTTErrNone;
401 }
402 
403 
404 #if 0
405 #pragma mark -
406 #pragma mark Utilities
407 #endif
408 
409 // RADIANS CONVERSIONS: cannot make static because of access to a member data element
410 // hz-to-radians conversion
411 TTFloat64 TTAudioObjectBase::hertzToRadians(const TTFloat64 hz) // NOTE: Be sure to set the sr before calling this function
412 {
413  return(hz * kTTTwoPi / sr);
414 }
415 
416 // radians-to-hz conversion
417 TTFloat64 TTAudioObjectBase::radiansToHertz(const TTFloat64 radians) // NOTE: Be sure to set the sr before calling this function
418 {
419  return(radians * sr / kTTTwoPi);
420 }
421 
422 // degrees-to-radians conversion
424 {
425  //return((degrees * kTTPi) / 180.);
426  return (degrees * kTTDegreesToRadians);
427 }
428 
429 // radians-to-degrees conversion
431 {
432  //return((radians * 180.) / kTTPi);
433  return (radians * kTTRadiansToDegrees);
434 }
435 
436 
437 // Decay Time (seconds) to feedback coefficient conversion
439 {
440  TTFloat64 fb;
441 
442  delay = delay * 0.001; // convert delay from milliseconds to seconds
443  if (decay_time < 0) {
444  fb = delay / -decay_time;
445  fb = fb * -60.;
446  fb = pow(10., (fb / 20.));
447  fb *= -1.;
448  }
449  else {
450  fb = delay / decay_time;
451  fb = fb * -60.;
452  fb = pow(10., (fb / 20.));
453  }
454  return(fb);
455 }
456 
457 // return the decay time based on the feedback coefficient
459 {
460  TTFloat64 decay_time;
461 
462  if (feedback > 0) {
463  decay_time = 20. * (log10(feedback));
464  decay_time = -60.0 / decay_time;
465  decay_time = decay_time * (delay);
466  }
467  else if (feedback < 0) {
468  decay_time = 20. * (log10(fabs(feedback)));
469  decay_time = -60.0 / decay_time;
470  decay_time = decay_time * (-delay);
471  }
472  else
473  decay_time = 0;
474 
475  return(decay_time);
476 }
TTErr sendMessage(const TTSymbol name)
TODO: Document this function.
TTErr setMaxNumChannels(const TTValue &newValue)
Setter for the maxNumChannels attribute.
TTErr setSr(const TTValue &newValue)
Setter for the sample-rate attribute.
TTErr(TTObjectBase::* TTSetterMethod)(const TTAttribute &attribute, const TTValue &value)
A type that can be used to store a pointer to a message for an object.
Definition: TTObjectBase.h:78
TTErr unlock()
Unlock the object when thread-safe processing is no longer required.
Definition: TTObjectBase.h:530
TTErr TTObjectBaseRelease(TTObjectBasePtr *anObject)
DEPRECATED.
TTCalculateMethod currentCalculateMethod
This function pointer always points to the current calculate routine.
TTFloat64 accumulatedProcessingCalls
The number of times the process method has been called (for benchmarking)
TTFloat64 degreesToRadians(const TTFloat64 degrees)
Degrees-to-radians conversion.
TTFOUNDATION_EXPORT TTEnvironment * ttEnvironment
The environment object has one instance, which is global in scope.
TTObject inputArray
If the process method is passed a signal, rather than an array of signals, we wrap the signal in this...
TTChannelCount mMaxNumChannels
This is the maximum number of channels that can be guaranteed to work.
TTFloat64 decayToFeedback(const TTFloat64 decay_time, TTFloat64 delay)
Decay Time (seconds) to feedback coefficient conversion.
TTProcessMethod processMethod
This function pointer points to the active (non-bypass) processing routine.
size_type size() const noexcept
Return the number of elements.
TTErr calculate(const TTFloat64 &x, TTFloat64 &y)
Calculate a single sample of output for a single sample of input.
TTFOUNDATION_EXPORT const TTFloat64 kTTTwoPi
Pre-calculated value of pi * 2.
Definition: TTBase.cpp:24
TTFloat64 startProcessingTime
The time at which this object's process method was last invoked (for benchmarking) ...
TTAudioObjectBase is the Jamoma DSP Audio Object Base Class
TTErr setBypass(const TTValue &value)
Bypass the audio processing routine and copy all input samples to the output unchanged.
TTBoolean mBenchmarking
Attribute: Enable benchmarking in TTAudioObject and TTDataObject ?
Definition: TTEnvironment.h:56
Base class for all first-class Jamoma objects.
Definition: TTObjectBase.h:109
TTProcessMethod currentProcessMethod
This function pointer always points to the current processing routine.
TTErr(TTObjectBase::* TTMethod)(const TTSymbol methodName, const TTValue &anInputValue, TTValue &anOutputValue)
A type that can be used to store a pointer to a message for an object.
Definition: TTObjectBase.h:46
TTFloat64 radiansToHertz(const TTFloat64 radians)
Convert radians into Hertz.
TTBoolean attrBypass
Are we bypassing the processMethod?
TTFloat64 accumulatedProcessingTime
The amount of time spent in this object's process method (for benchmarking)
TTErr registerAttribute(const TTSymbol name, const TTDataType type, void *address)
Register an attribute.
Jamoma DSP Library.
TTErr setAttributeValue(const TTSymbol name, TTValue &value)
Set an attribute value for an object.
double TTFloat64
64 bit floating point number
Definition: TTBase.h:188
TTErr muteProcess(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
A muted audio processing method, which simply copies zeroes to the output.
TTBoolean valid
If the object isn't completely built, or is in the process of freeing, this will be false...
Definition: TTObjectBase.h:124
TTObject outputArray
If the process method is passed a signal, rather than an array of signals, we wrap the signal in this...
TTErr registerMessage(const TTSymbol name, TTMethod method)
Register a message with this object.
TTFloat64 TTGetTimeInMicroseconds()
Return the current system time in microseconds.
Definition: TTBase.h:445
16-bit unsigned integer, range is 0 through 65,535.
Definition: TTBase.h:276
TTErr resetBenchmarking()
Reset the benchmarking accumulation used to calculate the results of getProcessingBenchmark().
void append(const T &anElementValueToAppend)
Insert a single TTElement at the end.
Definition: TTValue.h:243
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
TTErr bypassCalculate(const TTFloat64 &x, TTFloat64 &y, TTPtr data)
Produces a result for calls to calculate when the unit is bypassed.
TTAudioObjectBase(const TTValue &arguments)
Constructor.
TTFOUNDATION_EXPORT const TTFloat64 kTTRadiansToDegrees
Factor constant for converting radians to degrees.
Definition: TTBase.cpp:32
TTErr defaultCalculateMethod(const TTFloat64 &x, TTFloat64 &y, TTPtr data)
A default calculate method, which simply calls the process method with 1 channel signals that are 1 s...
TTErr clear()
Zero out all of the sample values in the audio signal.
TTBoolean attrMute
Mute the processMethod.
TTCalculateMethod calculateMethod
This function pointer points to the active (non-bypass) calculate routine.
#define addAttributeProperty(attributeName, propertyName, initialValue)
A convenience macro to be used for registering properties of attributes.
Definition: TTAttribute.h:68
TTErr(TTAudioObjectBase::* TTProcessMethod)(TTAudioSignalArrayPtr in, TTAudioSignalArrayPtr out)
A type that can be used to store a pointer to a process method (which calculates a vector of samples)...
TTErr TTObjectBaseInstantiate(const TTSymbol className, TTObjectBasePtr *returnedObjectPtr, const TTValue arguments)
DEPRECATED.
TTFloat64 hertzToRadians(const TTFloat64 hz)
Convert Hertz to radians.
Boolean (1/0) or (true/false) flag.
Definition: TTBase.h:281
TTErr calculateMessage(TTValueConstRef input, TTValueRef output)
TTErr(TTAudioObjectBase::* TTCalculateMethod)(const TTFloat64 &x, TTFloat64 &y, TTPtr data)
A type that can be used to store a pointer to a calculate method (which calculates a single sample)...
TTErr setCalculate(TTCalculateMethod newCalculateMethod)
Set the sample calculate routine to point to a method that is defined as an arg to this function...
The TTAudioSignal class represents N vectors of audio samples for M channels.
Definition: TTAudioSignal.h:57
TTSampleValue ** mSampleVectors
An array of pointers to the first sample in each vector. Declared Public for fast access...
Definition: TTAudioSignal.h:74
TTErr process(TTAudioSignal &in, TTAudioSignal &out)
Process the input signal, resulting in an output signal.
TTErr setProcess(TTProcessMethod processMethod)
Set the audio processing routine to point to a method that is defined as an arg to this function...
TTErr bypassProcess(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
The default audio processing method, which simply copies a signal through with no modifications...
TTUInt16 TTChannelCount
Data type used when counting the number of channels in multi-channel audio signals and processes...
Definition: TTAudioSignal.h:31
virtual ~TTAudioObjectBase()
Destructor.
TTFloat64 radiansToDegrees(const TTFloat64 radians)
Radians-to-degrees conversion.
A simple container for an array of TTAudioSignal pointers.
void clear()
Clear all values from the vector, leaving with size of 0.
Definition: TTValue.h:131
TTEnvironment is a global object providing information on the environemt.
TTErr setMute(const TTValue &value)
Mute the audio processing routine and zero all output.
Something went wrong, but what exactly is not known. Typically used for context-specific problems...
Definition: TTBase.h:344
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
TTFloat64 feedbackToDecay(const TTFloat64 feedback, const TTFloat64 delay)
Return the decay time based on the feedback coefficient.
std::uint32_t TTUInt32
32 bit unsigned integer
Definition: TTBase.h:178
TTFOUNDATION_EXPORT const TTFloat64 kTTDegreesToRadians
Factor constant for converting degrees to radians.
Definition: TTBase.cpp:33
TTUInt32 mSampleRate
Current sample rate as understood by the environment as a whole.
Definition: TTEnvironment.h:55
TTFloat64 srMill
1/1000 of the current sample rate (samples per millisecond)
TTErr getProcessingBenchmark(TTValueConstRef, TTValueRef v)
Return the average time spent by this object processing audio since the last reset.
#define addAttributeWithSetter(name, type)
A convenience macro to be used by subclasses for registering attributes with a custom setter...
Definition: TTAttribute.h:47
32-bit unsigned integer, range is 0 through 4,294,967,295.
Definition: TTBase.h:278
TTFloat64 srInv
1.0 over the current sample rate (inverse)
TTObjectBase * instance() const
Return a direct pointer to the internal instance.
Definition: TTObject.cpp:105
No Error.
Definition: TTBase.h:343
virtual TTErr test(TTValue &)
Default (empty) template for unit tests.
static TTErr copy(const TTAudioSignal &source, TTAudioSignal &dest, TTChannelCount channelOffset=0)
Copy the audio from one signal into another.
Set this flag if the method you are binding to this message is prototyped to accept no arguments...
Definition: TTObjectBase.h:86
TTErr allocWithVectorSize(const TTUInt16 newVectorSize)
Allocate memory for all channels at the specified vectorsize, if the vectorsize is different from the...
TTErr lock()
Lock the object in order to ensure thread-safe processing.
Definition: TTObjectBase.h:520
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
TTChannelCount numAudioSignals
The number of audio signal pointers which are actually valid.
TTUInt32 sr
Current sample rate being used by this object.