Jamoma API  0.6.0.a19
TTAudioSignal.h
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup dspLibrary
4  *
5  * @brief Represents M channels containing N vectors of audio samples.
6  *
7  * @details TODO: put more info here
8  *
9  * @authors Tim Place
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_SIGNAL_H__
18 #define __TT_AUDIO_SIGNAL_H__
19 
20 #include "TTFoundation.h"
21 #include "TTObjectBase.h"
22 #include "TTSymbol.h"
23 #include "TTValue.h"
24 
25 
26 // Typedefs
27 
28 /** Data type used when counting the number of channels in multi-channel audio signals and processes.
29  @ingroup typedefs
30  */
32 
33 
34 
35 // Constants
36 
37 /** @ingroup consts
38  The maximum number of audio channels that Jamoma DSP (and AudioGraph) is able to deal with.
39  @details This depends on the #TTChannelCount type used to store the number of channels.
40 
41  */
42 TTDSP_EXPORT extern const TTChannelCount kTTMaxChannelsPossible;
43 
44 
45 
46 /****************************************************************************************************/
47 // Class Specification
48 
49 /** The TTAudioSignal class represents N vectors of audio samples for M channels.
50 
51  All of the members are made public so that direct access to members can be used for
52  speed in cases where efficiency is of the utmost importance.
53 
54  Where speed is less critical, the preferred method of work with audio signals is the same as for other objects:
55  use the dynamic message passing interface.
56 */
57 class TTDSP_EXPORT TTAudioSignal : public TTDataObjectBase {
59 
60 private:
61  enum{
62  kExternallyOwned = 0,
63  kLocallyOwned = 1
64  };
65 
66  TTBoolean mIsLocallyOwned;
67  TTChannelCount mMaxNumChannels; ///< The number of audio channels for which memory has been allocated.
68  TTUInt16 mVectorSize; ///< Vector Size for this signal. Every channel in a signal must have the same vector-size.
69  TTChannelCount mNumChannels; ///< The number of audio channels that have valid sample values stored in them.
70  TTUInt8 mBitdepth; ///< Currently supported bitdepths are 32 and 64. This is set by the setVector() method.
71  TTUInt32 mSampleRate; ///< Audio signal metadata, defined in Hertz or set to 0 if not available.
72 
73 public:
74  TTSampleValue** mSampleVectors; ///< An array of pointers to the first sample in each vector. Declared Public for fast access.
75 
76  /** Copy constructor. */
77  TTAudioSignal(const TTAudioSignal& original);
78 
79 private:
80  /** Internal method for freeing the vectors. */
81  void chuck();
82 
83 public:
84  /** Attribute accessor. */
85  TTErr setMaxNumChannels(const TTValue& newMaxNumChannels);
86 
87 
88  void setSampleRate(const TTUInt32& newSampleRate)
89  {
90  mSampleRate = newSampleRate;
91  }
92 
93  TTUInt32 getSampleRate()
94  {
95  return mSampleRate;
96  }
97 
98  //! [doxygenAppendixC_methodExample]
99  /** Assigns a vector of sample values to a channel in this signal.
100  @details The vector member of this class simply holds a pointer, not a copy of the data. This makes the
101  operation of this method (and others) fast, but also means that care should be taken to ensure
102  that the data being pointed to by this signal is valid, and does not become invalid during the
103  lifetime of the signal.
104 
105  It is the responsibility of the user of this method to ensure that the sample-rate and vector-size
106  are also set correctly.
107  @param channel The channel number (zero-based) to assign the vector to.
108  @param vectorSize The number of samples in the vector.
109  @param newVector A pointer to the first sample in a vector of samples.
110  @result An error code.
111  */
112  TTErr setVector(const TTChannelCount channel, const TTUInt16 vectorSize, const TTSampleValuePtr newVector);
113  //! [doxygenAppendixC_methodExample]
114 // TTErr setVector64(const TTValue& v, TTValue&); // A version of the above used by the message passing interface.
115  TTErr setVector64Copy(const TTChannelCount channel, const TTUInt16 vectorSize, const TTSampleValuePtr newVector);
116  /** This version handles vector assignments from 32-bit vectors.
117  */
118  TTErr setVector(const TTChannelCount channel, const TTUInt16 vectorSize, const TTFloat32* newVector);
119 // TTErr setVector32(const TTValue& v, TTValue&); // A version of the above used by the message passing interface.
120 
121  TTFloat64 getSample64(const TTChannelCount channel, const TTUInt16 sampleNumber)
122  {
123  return mSampleVectors[channel][sampleNumber];
124  }
125 
126  TTFloat32 getSample(const TTChannelCount channel, const TTUInt16 sampleNumber)
127  {
128  return ((TTFloat32)mSampleVectors[channel][sampleNumber]);
129  }
130 
131 
132  TTErr getVector(const TTChannelCount channel, const TTUInt16 vectorSize, TTSampleValue* returnedVector);
133 // TTErr getVector64(TTValue&, TTValue& v); // A version of the above used by the message passing interface.
134  TTErr getVectorCopy(const TTChannelCount channel, const TTUInt16 theVectorSize, TTSampleValue* returnedVector); // version of getVector that copies
135 
136  TTErr getVector(const TTChannelCount channel, const TTUInt16 vectorSize, TTFloat32* returnedVector);
137 // TTErr getVector32(TTValue&, TTValue& v); // A version of the above used by the message passing interface.
138 
139 protected:
140  TTErr setVectorSize(const TTValue& newVectorSize)
141  {
142  mVectorSize = newVectorSize;
143  return kTTErrNone;
144  }
145 
146 public:
147  TTErr setVectorSizeWithInt(const TTUInt16 newVectorSize)
148  {
149  mVectorSize = newVectorSize;
150  return kTTErrNone;
151  }
152 
153  TTUInt16 getVectorSizeAsInt() const
154  {
155  return mVectorSize;
156  }
157 
158  TTErr changeVectorSize(const TTUInt16 newVectorSize)
159  {
160  if (mIsLocallyOwned)
161  allocWithVectorSize(newVectorSize);
162  else
163  mVectorSize = newVectorSize;
164  return kTTErrNone;
165  }
166 
167 
168  TTErr setNumChannels(const TTValue& newNumChannels)
169  {
170  mNumChannels = TTClip<TTChannelCount>(newNumChannels, 0, mMaxNumChannels);
171  return kTTErrNone;
172  }
173 
174  TTErr setNumChannelsWithInt(const TTChannelCount newNumChannels)
175  {
176  mNumChannels = TTClip<TTChannelCount>(newNumChannels, 0, mMaxNumChannels);
177  return kTTErrNone;
178  }
179 
180 
181  TTChannelCount getNumChannelsAsInt() const
182  {
183  return mNumChannels;
184  }
185 
186  TTChannelCount getMaxNumChannelsAsInt();
187 
188 
189  TTBoolean getIsLocallyOwned()
190  {
191  return mIsLocallyOwned;
192  }
193 
194  /** Allocate memory for all channels at the current vectorsize.
195  */
196  TTErr alloc();
197 
198 
199  /** Allocate memory for a given number of channels, setting MaxChannelCount, at the current vector size.
200  Unlike other alloc() routines, the existing contents of the audio channels is preserved.
201 
202  DOES NOT TAKE INTO ACCOUNT THE 'LOCALLY OWNED' ATTRIBUTE BEING SET TO FALSE!
203  COULD CAUSE MEM CORRUPTION IF USED ON EXTERNAL REFERENCES!
204  */
205  TTErr allocWithNewChannelCount(TTChannelCount newChannelCount);
206 
207 
208  /** Allocate memory for all channels at the specified vectorsize,
209  if the vectorsize is different from the current state.
210  */
211  TTErr allocWithVectorSize(const TTUInt16 newVectorSize);
212  TTErr allocWithNewVectorSize(const TTValue& newVectorSize, TTValue&);
213 
214 
215  /** Zero out all of the sample values in the audio signal.
216  @return An error code. */
218  {
219  if (!mSampleVectors)
220  return kTTErrGeneric;
221 
222  // Ideally, we could do this:
223  // memset(mSampleVectors, 0, sizeof(TTSampleValue) * mVectorSize * mNumChannels);
224  // But, at the moment, we implement a vector of vectors rather than a block of memory that we index as a single chunk.
225  // So we have to iterate like this:
226 
227  for (TTUInt32 channel=0; channel<mNumChannels; channel++)
228  memset(mSampleVectors[channel], 0, sizeof(TTSampleValue) * mVectorSize);
229 
230  return kTTErrNone;
231  }
232 
233 
234  TTErr fill(TTFloat64 aFillValue)
235  {
236  if (!mSampleVectors)
237  return kTTErrGeneric;
238 
239  // Ideally, we could do this:
240  // memset(mSampleVectors, 0, sizeof(TTSampleValue) * mVectorSize * mNumChannels);
241  // But, at the moment, we implement a vector of vectors rather than a block of memory that we index as a single chunk.
242  // So we have to iterate like this:
243 
244  for (TTChannelCount channel=0; channel<mNumChannels; channel++) {
245  for (int n=0; n<mVectorSize; n++)
246  mSampleVectors[channel][n] = aFillValue;
247  }
248 
249  return kTTErrNone;
250  }
251 
252 
253  /** Reference the audio from one signal in another. */
254  static TTErr reference(const TTAudioSignal& source, TTAudioSignal& dest);
255 
256  /** Copy the audio from one signal into another. */
257  static TTErr copy(const TTAudioSignal& source, TTAudioSignal& dest, TTChannelCount channelOffset=0);
258 
259  /** Copy the audio from one signal into another, but not taking care to zero channels that aren't used. */
260  static TTErr copyDirty(const TTAudioSignal& source, TTAudioSignal& dest, TTChannelCount channelOffset=0);
261 
262  /** Copy the audio from one signal into another. */
263  static TTErr copySubset(const TTAudioSignal& source, TTAudioSignal& dest, TTChannelCount startingChannel=0, TTChannelCount endingChannel=0);
264 
265 
266 
267 
268  /** Use this class method to determine the least number of channels the two signals have in common.
269  * In cases where a processAudio method expects to have a matching number of audio inputs and outputs,
270  * this method can be used to compare the two signals and return the number of channels for which
271  * it is safe to assume that the number of inputs and outputs are the same.
272  * @param signal1 The first of the two signals to be compared.
273  * @param signal2 The second of the two signals to be compared.
274  * @return The number of channels that are valid for both signal1 and signal2. */
275  //static TTChannelCount getMinChannelCount(const TTAudioSignal& signal1, const TTAudioSignal& signal2);
276 
277  static TTChannelCount getMinChannelCount(const TTAudioSignal& signal1, const TTAudioSignal& signal2)
278  {
279  if (signal1.mNumChannels > signal2.mNumChannels)
280  return signal2.mNumChannels;
281  else
282  return signal1.mNumChannels;
283  }
284 
285  /** Use this class method to determine the least number of channels the specified signals have in common.
286  In cases where a processAudio method expects to have a matching number of audio inputs and outputs,
287  this method can be used to compare the two signals and return the number of channels for which
288  it is safe to assume that the number of inputs and outputs are the same.
289  @param signal1 The first of three signals to be compared.
290  @param signal2 The second of three signals to be compared.
291  @param signal3 The third of three signals to be compared.
292  @return The number of channels that are valid for all signals. */
293  //static TTChanelCount getMinChannelCount(const TTAudioSignal& signal1, const TTAudioSignal& signal2, const TTAudioSignal& signal3);
294 
295  static TTChannelCount getMinChannelCount(const TTAudioSignal& signal1, const TTAudioSignal& signal2, const TTAudioSignal& signal3)
296  {
297  TTChannelCount numChannels = signal1.mNumChannels;
298 
299  if (signal2.mNumChannels < numChannels)
300  numChannels = signal2.mNumChannels;
301  if (signal3.mNumChannels < numChannels)
302  numChannels = signal3.mNumChannels;
303 
304  return numChannels;
305  }
306 
307  static TTChannelCount getMaxChannelCount(const TTAudioSignal& signal1, const TTAudioSignal& signal2);
308  static TTChannelCount getMaxChannelCount(const TTAudioSignal& signal1, const TTAudioSignal& signal2, const TTAudioSignal& signal3);
309 
310  /** Use this class method to determine the number of channels of an input or output signal.
311  * This can be useful in circumstances where input and output signals are not necsessarily expected
312  * or required to have the same number of channels.
313  * @param signal The signal that we want to investigate.
314  * @return The number of channels of the signal. */
315  static TTChannelCount getNumChannels(const TTAudioSignal& signal);
316 
317 
318  /** Sum another audio signal's samples with this audio signal's samples.
319  */
320  TTAudioSignal& operator += (const TTAudioSignal& rightHandValue)
321  {
322  short vs;
323  TTSampleValue* inSample;
324  TTSampleValue* outSample;
325  short channelCount = getMaxChannelCount(*this, rightHandValue);
326  short channel;
327 
328  if (channelCount > mMaxNumChannels)
329  allocWithNewChannelCount(channelCount);
330  else
331  mNumChannels = channelCount;
332  if (channelCount > rightHandValue.mMaxNumChannels)
333  channelCount = rightHandValue.mMaxNumChannels;
334 
335  for (channel=0; channel<channelCount; channel++) {
336  inSample = rightHandValue.mSampleVectors[channel];
337  outSample = mSampleVectors[channel];
338 
339  if (mVectorSize > rightHandValue.mVectorSize)
340  vs = rightHandValue.mVectorSize;
341  else
342  vs = mVectorSize;
343 
344  while (vs--) {
345  (*outSample) = (*outSample) + (*inSample);
346  outSample++;
347  inSample++;
348  }
349  }
350  return *this;
351  }
352 
353 
354  /** Assign another audio signal's samples and channel/vector configuration with this audio signal's samples. */
355  TTAudioSignal& operator = (const TTAudioSignal& rightHandValue)
356  {
357  if (rightHandValue.mMaxNumChannels > mMaxNumChannels)
358  setMaxNumChannels(rightHandValue.mMaxNumChannels);
359  mNumChannels = rightHandValue.mNumChannels;
360  mSampleRate = rightHandValue.mSampleRate;
361 
362  setVectorSizeWithInt(rightHandValue.mVectorSize);
363  if (mIsLocallyOwned)
364  alloc();
365 
366  TTAudioSignal::copy(rightHandValue, *this);
367  return *this;
368  }
369 
370 };
371 
372 
374 
375 
376 #endif // __TT_AUDIO_SIGNAL_H__
377 
bool TTBoolean
Boolean flag, same as Boolean on the Mac.
Definition: TTBase.h:167
std::uint16_t TTUInt16
16 bit unsigned integer
Definition: TTBase.h:176
The Jamoma Object Base Class.
TTDataObjectBase is the base class for all data generating and processing objects.
double TTFloat64
64 bit floating point number
Definition: TTBase.h:188
#define TTCLASS_SETUP(className)
TODO Doxygen: need more comments here.
Definition: TTFoundation.h:54
TTDSP_EXPORT const TTChannelCount kTTMaxChannelsPossible
The maximum number of audio channels that Jamoma DSP (and AudioGraph) is able to deal with...
Definition: TTDSP.cpp:21
TTErr clear()
Zero out all of the sample values in the audio signal.
float TTFloat32
32 bit floating point number
Definition: TTBase.h:187
static TTChannelCount getMinChannelCount(const TTAudioSignal &signal1, const TTAudioSignal &signal2)
Use this class method to determine the least number of channels the two signals have in common...
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
TTUInt16 TTChannelCount
Data type used when counting the number of channels in multi-channel audio signals and processes...
Definition: TTAudioSignal.h:31
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
No Error.
Definition: TTBase.h:343
static TTErr copy(const TTAudioSignal &source, TTAudioSignal &dest, TTChannelCount channelOffset=0)
Copy the audio from one signal into another.
static TTChannelCount getMinChannelCount(const TTAudioSignal &signal1, const TTAudioSignal &signal2, const TTAudioSignal &signal3)
Use this class method to determine the least number of channels the specified signals have in common...
Provides a common way of representing composite values.
TTFloat64 TTSampleValue
A value representing a single audio sample.
Definition: TTBase.h:230
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
unsigned char TTUInt8
8 bit unsigned integer (char)
Definition: TTBase.h:174