Jamoma API  0.6.0.a19
TTAudioObjectBase.h
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 #ifndef __TT_AUDIO_OBJECT_BASE_H__
18 #define __TT_AUDIO_OBJECT_BASE_H__
19 
20 #include "TTObjectBase.h"
21 #include "TTSymbol.h"
22 #include "TTValue.h"
23 #include "TTAudioSignal.h"
24 #include "TTAudioSignalArray.h"
25 
26 
27 // Forward declaration of TTAudioObjectBase for the typedef that follows...
28 class TTAudioObjectBase;
29 class TTAudio;
30 
31 
32 /** A type that can be used to store a pointer to a process method (which calculates a vector of samples).
33  @param in Audio to be processed
34  @param out Processed audio
35  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
36  @ingroup typedefs
37  */
39 
40 
41 /** A type that can be used to store a pointer to a calculate method (which calculates a single sample).
42  @param x A single sample to be processed
43  @param y A single processed sample
44  @param data Additional data to be used by the calculation implementation, such as the channel number for which to compute.
45  @ingroup typedefs
46  */
48 
49 
50 /** A convenience macro to be used by subclasses for setting the process method.
51  @param methodName The name of the method to use for processing audio vectors.
52  */
53 #define setProcessMethod(methodName) setProcess((TTProcessMethod)& thisTTClass ::methodName )
54 
55 
56 /** A convenience macro to be used by subclasses for setting the calculate method.
57  @param methodName The name of the method to use for processing individual audio samples.
58  */
59 #define setCalculateMethod(methodName) setCalculate((TTCalculateMethod)& thisTTClass ::methodName )
60 
61 
62 #define TT_WRAP_CALCULATE_METHOD(methodName) \
63 TTAudioSignal& in = inputs->getSignal(0); \
64 TTAudioSignal& out = outputs->getSignal(0); \
65 TTUInt16 vs; \
66 TTSampleValue* inSample; \
67 TTSampleValue* outSample; \
68 TTChannelCount numchannels = TTAudioSignal::getMinChannelCount(in, out); \
69 TTPtrSizedInt channel; \
70 \
71 for (channel=0; channel<numchannels; channel++) { \
72  inSample = in.mSampleVectors[channel]; \
73  outSample = out.mSampleVectors[channel]; \
74  vs = in.getVectorSizeAsInt(); \
75  \
76  while (vs--) { \
77  methodName (*inSample, *outSample, channel); \
78  outSample++; \
79  inSample++; \
80  } \
81 }\
82 return kTTErrNone;
83 
84 
85 
86 /****************************************************************************************************/
87 // Class Specification
88 
89 /** TTAudioObjectBase is the base class for all audio generating and processing objects in Jamoma DSP.
90  *
91  * @details The theory of operation is that this class handles the public interface to any subclass,
92  * including the main processing method, which calls an appropriate method through a function pointer.
93  * By default, this points to the built-in bypassProcess(). Subclasses then set it to point to their
94  * own process() method(s) as needed.
95  */
96 class TTDSP_EXPORT TTAudioObjectBase : public TTObjectBase {
97 protected:
98  TTUInt32 sr; ///< Current sample rate being used by this object
99  TTFloat64 srInv; ///< 1.0 over the current sample rate (inverse)
100  TTFloat64 srMill; ///< 1/1000 of the current sample rate (samples per millisecond)
101  TTChannelCount mMaxNumChannels; ///< This is the maximum number of channels that can be guaranteed to work
102  TTBoolean unused; ///< Old var that is not used anymore, but we want to keep the struct size the same
103  TTBoolean attrBypass; ///< Are we bypassing the processMethod?
104  TTBoolean attrMute; ///< Mute the processMethod.
105  TTProcessMethod processMethod; ///< This function pointer points to the active (non-bypass) processing routine.
106  TTProcessMethod currentProcessMethod; ///< This function pointer always points to the current processing routine.
107  TTCalculateMethod calculateMethod; ///< This function pointer points to the active (non-bypass) calculate routine.
108  TTCalculateMethod currentCalculateMethod; ///< This function pointer always points to the current calculate routine.
109  TTObject inputArray; ///< If the process method is passed a signal, rather than an array of signals, we wrap the signal in this array.
110  TTObject outputArray; ///< If the process method is passed a signal, rather than an array of signals, we wrap the signal in this array.
111  TTFloat64 startProcessingTime; ///< The time at which this object's process method was last invoked (for benchmarking)
112  TTFloat64 accumulatedProcessingTime; ///< The amount of time spent in this object's process method (for benchmarking)
113  TTFloat64 accumulatedProcessingCalls; ///< The number of times the process method has been called (for benchmarking)
114 
115 
116  /** Set the audio processing routine to point to a method that is defined as an arg to this function.
117  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
118  */
119  TTErr setProcess(TTProcessMethod processMethod);
120 
121 
122  /** Set the sample calculate routine to point to a method that is defined as an arg to this function.
123  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
124  */
125  TTErr setCalculate(TTCalculateMethod newCalculateMethod);
126 
127 
128  /** Bypass the audio processing routine and copy all input samples to the output unchanged.
129  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
130  */
131  TTErr setBypass(const TTValue& value);
132 
133 
134  /** Reset the benchmarking accumulation used to calculate the results of getProcessingBenchmark().
135  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
136  */
137  TTErr resetBenchmarking();
138 
139 
140  /** Return the average time spent by this object processing audio since the last reset.
141  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
142  */
143  TTErr getProcessingBenchmark(TTValueConstRef, TTValueRef v);
144 
145 
146 public:
147 
148  /** Mute the audio processing routine and zero all output.
149  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
150  */
151  TTErr setMute(const TTValue& value);
152 
153 
154  /** Setter for the maxNumChannels attribute.
155  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
156  */
157  TTErr setMaxNumChannels(const TTValue& newValue);
158 
159 
160  /** Increase the maxNumChannels attribute, if neccessary.
161  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
162  */
163  TTErr adaptMaxNumChannels(const TTChannelCount newMaxNumChannels)
164  {
165  if (newMaxNumChannels > mMaxNumChannels)
166  return setAttributeValue(kTTSym_maxNumChannels, newMaxNumChannels);
167  else
168  return kTTErrNone;
169  }
170 
171 
172  /** Setter for the sample-rate attribute.
173  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
174  */
175  TTErr setSr(const TTValue& newValue);
176 
177 
178  /** Convenience method for updating the sample-rate.
179  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
180  */
181  TTErr setSampleRate(const TTUInt32& newSampleRate)
182  {
183  if (newSampleRate && newSampleRate != sr)
184  return setAttributeValue(kTTSym_sampleRate, newSampleRate);
185  else
186  return kTTErrNone;
187  }
188 
189 
190 protected:
191 
192  /** Constructor.
193  @details Requires that the maximum number of channels to be used with this instance is defined.
194  @param arguments Arguments to the constructor.
195  */
196  TTAudioObjectBase(const TTValue& arguments);
197 
198 
199 public:
200 
201  /** Destructor.
202  */
203  virtual ~TTAudioObjectBase();
204 
205 
206  /** Calculate a single sample of output for a single sample of input.
207  @param x The input to the function.
208  @param y The output of the function.
209  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
210  */
211  TTErr calculate(const TTFloat64& x, TTFloat64& y);
212  TTErr calculate(const TTValue& x, TTValue& y);
213 
214 
215  /**
216  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
217  */
218  TTErr calculateMessage(TTValueConstRef input, TTValueRef output);
219 
220 
221  /** Process the input signal, resulting in an output signal. This method wraps the actual process method that will be called.
222  @param in The input signal.
223  @param out The output signal.
224  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
225  */
226  TTErr process(TTAudioSignal& in, TTAudioSignal& out);
227 
228  // Shortcut for when the caller is using pointers
229  TTErr process(TTAudioSignal* in, TTAudioSignal* out)
230  {
231  return process(*in, *out);
232  }
233 
234 
235  /** Process the an output signal only, e.g. for a signal generator. This method wraps the actual process method that will be called.
236  @param in The input signal.
237  @param out The output signal.
238  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
239  */
240  TTErr process(TTAudioSignal& out);
241 
242  // shortcut for when the caller is using pointers
243  TTErr process(TTAudioSignal* out)
244  {
245  return process(*out);
246  }
247 
248 
249  /** Process two input signals, resulting in two output signals.
250  @details This method wraps the actual process method, which may use the extra signal as a sidechain or other input.
251  @param in1 The main input signal.
252  @param in2 A secondary or sidechain input signal.
253  @param in1 The main output signal.
254  @param in2 A secondary or sidechain output signal.
255  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
256  */
257  TTErr process(TTAudioSignal& in1, TTAudioSignal& in2, TTAudioSignal& out1, TTAudioSignal& out2);
258 
259  // Shortcut for when the caller is using pointers
260  TTErr process(TTAudioSignal* in1, TTAudioSignal* in2, TTAudioSignal* out1, TTAudioSignal* out2)
261  {
262  return process(*in1, *in2, *out1, *out2);
263  }
264 
265 
266  /** Process two input signals, resulting in an output signal.
267  @details This method wraps the actual process method that will be called.
268  @param in1 The main input signal.
269  @param in2 A secondary or sidechain input signal.
270  @param out The output signal.
271  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
272  */
273  TTErr process(TTAudioSignal& in1, TTAudioSignal& in2, TTAudioSignal& out);
274 
275  // shortcut for when the caller is using pointers
276  TTErr process(TTAudioSignal* in1, TTAudioSignal* in2, TTAudioSignal* out)
277  {
278  return process(*in1, *in2, *out);
279  }
280 
281  /** Process an array of audio signals.
282  @param inputs The input audio signals to process.
283  @param outputs The resulting processed audio signals.
284  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
285  */
286  TTErr process(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs);
287 
288 
289  TTErr process(TTAudio& inputs, TTAudio& outputs);
290 
291  /** The default audio processing method, which simply copies a signal through with no modifications.
292  @param inputs
293  @param outputs
294  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
295  */
296  TTErr bypassProcess(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs);
297 
298  /** Produces a result for calls to calculate when the unit is bypassed.
299  @param inputs The audio input signals that will be passed through with no further processing.
300  @param outputs The resulting unprocessesed (bypassed) audio signals.
301  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
302  */
303  TTErr bypassCalculate(const TTFloat64& x, TTFloat64& y, TTPtr data);
304 
305  /** A muted audio processing method, which simply copies zeroes to the output.
306  @param inputs The audio input signals to be muted
307  @param outputs The processed (muted) audio signals.
308  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
309  */
310  TTErr muteProcess(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs);
311 
312 
313  /** A default calculate method, which simply calls the process method with 1 channel signals that are 1 sample in length.
314  @details This method is not fast, and if you anticipate the calculate method to be called often, you should write a proper
315  calculate method in the subclass.
316  @param x
317  @param y
318  @param data
319  @return #TTErr error code if the method fails to execute, else #kTTErrNone.
320  */
321  TTErr defaultCalculateMethod(const TTFloat64& x, TTFloat64& y, TTPtr data);
322 
323 
324  // UTILITIES
325 
326  /** Convert Hertz to radians.
327  @details Be sure to set the sr for this object before calling this function.
328  @param hz Frequency expressed in Hz.
329  @return Frequency expressed in radians.
330  */
331  TTFloat64 hertzToRadians(const TTFloat64 hz);
332 
333  /** Convert radians into Hertz.
334  @details Be sure to set the sr for this object before calling this function.
335  @param radians Frequency expressed in radians.
336  @return Frequency expressed in Hz.
337  */
338  TTFloat64 radiansToHertz(const TTFloat64 radians);
339 
340  /** Degrees-to-radians conversion.
341  @param degrees Frequency expressed in degrees.
342  @return Frequency expressed in radians.
343  */
344  TTFloat64 degreesToRadians(const TTFloat64 degrees);
345 
346  /** Radians-to-degrees conversion.
347  @param radians Frequency expressed in radians.
348  @return Frequency expressed in degrees.
349  */
350  TTFloat64 radiansToDegrees(const TTFloat64 radians);
351 
352  /** Decay Time (seconds) to feedback coefficient conversion.
353  @param decay_time -60 dB decay time in seconds.
354  @param delay The delay time of the feedback loop.
355  @return Calculated feedback coefficient.
356  */
357  TTFloat64 decayToFeedback(const TTFloat64 decay_time, TTFloat64 delay);
358 
359  /** Return the decay time based on the feedback coefficient.
360  @param feedback The feedback coefficient.
361  @param delay The delay time of the feedback loop.
362  @return Calculated -60 dB decay time.
363  */
364  TTFloat64 feedbackToDecay(const TTFloat64 feedback, const TTFloat64 delay);
365 
366 
367 
368  /** Default (empty) template for unit tests.
369  @param returnedTestInfo Returned information on the outcome of the unit test(s)
370  @return #kTTErrNone if tests exists and they all pass, else #TTErr error codes depending on the outcome of the test.
371  */
372  virtual TTErr test(TTValue& /*returnedTestInfo*/)
373  {
374  logMessage("No Tests have been written for this class -- please supply a test method.\n");
375  return kTTErrGeneric;
376  }
377 
378 };
379 
380 
381 /** Pointer to a #TTAudioObjectBase.
382  @ingroup typedefs
383  */
385 
386 
387 /** Convert linear amplitude into deciBels.
388  @todo This could probably be using DataspaceLib instead?
389  @param value The linear gain value to convert.
390  @return Converted decibel value.
391  */
393 {
394  if (value >= 0)
395  return(20.0 * (log10(value)));
396  else
397  return 0;
398 }
399 
400 
401 /** Convert decibels into linear ampliude.
402  @todo This could probably be using DataspaceLib instead?
403  @param value The decibel value to convert.
404  @return The converted linear gain value.
405  */
407 {
408  return(pow(10., (value / 20.)));
409 }
410 
411 
412 /** Convert midi into linear amplitude.
413  @todo This could probably be using DataspaceLib instead?
414  @param value The midi gain value to convert.
415  @return The converted linear gain value.
416  */
418 {
419  return pow(value * 0.01, kTTGainMidiPower);
420 }
421 
422 
423 /** Convert linear amplitude into midi.
424  @todo This could probably be using DataspaceLib instead?
425  @param value A linear amplitude to convert.
426  @return The converted midi gain value.
427  */
429 {
430  return 100.0 * pow(value, kTTGainMidiPowerInv);
431 }
432 
433 
434 /** Generate the next prime number higher than the value passed in.
435  @param value The number passed in.
436  @return The next prime number higher than the number passed in.
437  */
438 inline TTUInt32 TTPrime(TTUInt32 value)
439 {
440  long candidate, last, i, isPrime;
441 
442  if (value < 2)
443  candidate = 2;
444  else if (value == 2)
445  candidate = 3;
446  else {
447  candidate = value;
448  if (candidate % 2 == 0) // Test only odd numbers
449  candidate--;
450  do{
451  isPrime = true; // Assume glorious success
452  candidate += 2; // Bump to the next number to test
453  last = TTUInt32(sqrt((TTFloat32)candidate)); // We'll check to see if candidate has any factors, from 2 to last
454  for (i=3; (i <= last) && isPrime; i+=2) { // Loop through odd numbers only
455  if ((candidate % i) == 0)
456  isPrime = false;
457  }
458  }
459  while (!isPrime);
460  }
461  return candidate;
462 }
463 
464 
465 /** An idiosyncratic utility for slightly randomizing a number.
466  Specifically this is used in applications such as randoming delay times for a reverb.
467  @param value The value to randomise
468  @param aSampleRate Current sample rate
469  @return The slightly randomised value
470  */
471 inline TTFloat64 TTDeviate(TTFloat64 value, TTFloat64 aSampleRate = 1.0)
472 { //TODO use Mersedian Twister for rand-generator
473  value += (2.0 * (TTFloat32(rand()) / TTFloat32(RAND_MAX))) - 1.0; // randomize input with +1 to -1 ms
474  value = value * 0.001 * aSampleRate; // convert from ms to samples
475  value = (TTFloat32)TTPrime(TTUInt32(value)); // find the nearest prime number (in samples)
476  value = (value / aSampleRate) * 1000.0; // convert back to ms
477 
478  return value;
479 }
480 
481 
482 #endif // __TT_AUDIO_OBJECT_BASE_H__
TTFloat64 TTDecibelsToLinearGain(TTFloat64 value)
Convert decibels into linear ampliude.
bool TTBoolean
Boolean flag, same as Boolean on the Mac.
Definition: TTBase.h:167
TTFloat64 TTLinearGainToDecibels(const TTFloat64 value)
Convert linear amplitude into deciBels.
The Jamoma Object Base Class.
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)
TTObject inputArray
If the process method is passed a signal, rather than an array of signals, we wrap the signal in this...
TTAudioObjectBase is the base class for all audio generating and processing objects in Jamoma DSP...
TTChannelCount mMaxNumChannels
This is the maximum number of channels that can be guaranteed to work.
TTErr logMessage(TTImmutableCString fmtstring,...)
Log messages scoped to this object instance.
TTProcessMethod processMethod
This function pointer points to the active (non-bypass) processing routine.
Create and use Jamoma object instances.
Definition: TTObject.h:29
TTFloat64 startProcessingTime
The time at which this object's process method was last invoked (for benchmarking) ...
Base class for all first-class Jamoma objects.
Definition: TTObjectBase.h:109
TTProcessMethod currentProcessMethod
This function pointer always points to the current processing routine.
TTBoolean attrBypass
Are we bypassing the processMethod?
TTFloat64 accumulatedProcessingTime
The amount of time spent in this object's process method (for benchmarking)
TTErr setAttributeValue(const TTSymbol name, TTValue &value)
Set an attribute value for an object.
TTFloat64 TTDeviate(TTFloat64 value, TTFloat64 aSampleRate=1.0)
An idiosyncratic utility for slightly randomizing a number.
double TTFloat64
64 bit floating point number
Definition: TTBase.h:188
TTObject outputArray
If the process method is passed a signal, rather than an array of signals, we wrap the signal in this...
TTFloat64 TTLinearGainToMidi(TTFloat64 value)
Convert linear amplitude into midi.
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
TTFOUNDATION_EXPORT const TTFloat64 kTTGainMidiPowerInv
Invverse power constant used when calculating MID gain.
Definition: TTBase.cpp:35
TTAudioObjectBase * TTAudioObjectBasePtr
Pointer to a TTAudioObjectBase.
TTBoolean attrMute
Mute the processMethod.
TTCalculateMethod calculateMethod
This function pointer points to the active (non-bypass) calculate routine.
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)...
float TTFloat32
32 bit floating point number
Definition: TTBase.h:187
TTErr adaptMaxNumChannels(const TTChannelCount newMaxNumChannels)
Increase the maxNumChannels attribute, if neccessary.
Container for an array of TTAudioSignal pointers.
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)...
The TTAudioSignal class represents N vectors of audio samples for M channels.
Definition: TTAudioSignal.h:57
TTBoolean unused
Old var that is not used anymore, but we want to keep the struct size the same.
Represents M channels containing N vectors of audio samples.
TTUInt32 TTPrime(TTUInt32 value)
Generate the next prime number higher than the value passed in.
TTUInt16 TTChannelCount
Data type used when counting the number of channels in multi-channel audio signals and processes...
Definition: TTAudioSignal.h:31
TTFloat64 TTMidiToLinearGain(TTFloat64 value)
Convert midi into linear amplitude.
A simple container for an array of TTAudioSignal pointers.
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
std::uint32_t TTUInt32
32 bit unsigned integer
Definition: TTBase.h:178
TTFloat64 srMill
1/1000 of the current sample rate (samples per millisecond)
TTFloat64 srInv
1.0 over the current sample rate (inverse)
No Error.
Definition: TTBase.h:343
virtual TTErr test(TTValue &)
Default (empty) template for unit tests.
TTFOUNDATION_EXPORT const TTFloat64 kTTGainMidiPower
Power constant used when calculating MID gain.
Definition: TTBase.cpp:34
TTErr setSampleRate(const TTUInt32 &newSampleRate)
Convenience method for updating the sample-rate.
Provides a common way of representing composite values.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
Wrap TTAudioSignal instances for convenience.
Definition: TTAudioObject.h:25
TTUInt32 sr
Current sample rate being used by this object.