Jamoma API  0.6.0.a19
TTBuffer.h
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup dspLibrary
4  *
5  * @brief #TTBuffer manages the check-in/out of #TTSampleMatrix pointers.
6  *
7  * @details #TTBuffer acts as a librarian for checking-in and checking-out audio within a chunk of memory. Any object that wishes to read or write samples managed by #TTBuffer must first check-out a pointer to the current #TTSampleMatrix. Once the pointer has been obtained, the object can read and write audio samples by working directly with the corresponding #TTSampleMatrix functions. Upon completion of its work, the object is then responsible for checking-in the pointer back to the #TTBuffer.@n@n
8  * This extra layer of protection prevents problems that can occur during such operations as changing the length in samples, changing number of channels, filling the buffer or loading a sound file. Whenever these key changes are made through #TTBuffer, it first creates a new #TTSampleMatrix and applies changes there. The new #TTSampleMatrix only becomes available for check-out after the changes are completed.@n@n
9  * The advantage of this approach is that during such changes, objects that have checked-out a #TTSampleMatrix pointer can continue using these samples without fear of them being changed before being ready. Only once the object checks-in the current pointer and performs another check-out will it begin using the new set of samples. This can be advantageous in applications such as sampling, wavetables or granular processing.
10  *
11  * @see TTSampleMatrix, TTMatrix, TTAudioSignal
12  *
13  * @authors Timothy Place & Nathan Wolek
14  *
15  * @copyright Copyright © 2012, Timothy Place & Nathan Wolek @n
16  * This code is licensed under the terms of the "New BSD License" @n
17  * http://creativecommons.org/licenses/BSD/
18  */
19 
20 #ifndef __TT_BUFFER_H__
21 #define __TT_BUFFER_H__
22 
23 #include "TTDSP.h"
24 #include "TTSampleMatrix.h"
25 
26 
27 extern TTHashPtr gTTBufferNameMap; // maps names to TTSampleMatrix instances for TTBuffer
28 
29 /** TTBuffer manages the check-in/out of #TTSampleMatrix pointers.
30 
31 #TTBuffer acts as a librarian for checking-in and checking-out audio within a chunk of memory. Any object that wishes to read or write samples managed by #TTBuffer must first check-out a pointer to the current #TTSampleMatrix. Once the pointer has been obtained, the object can read and write audio samples by working directly with the corresponding #TTSampleMatrix functions. Upon completion of its work, the object is then responsible for checking-in the pointer back to the #TTBuffer.
32 
33  @see TTAudioSignal, TTSampleMatrix
34 */
35 class TTDSP_EXPORT TTBuffer : public TTAudioObjectBase {
37 
38 protected:
39 
40  TTSymbol mName; ///< name associated with this buffer
41  TTSampleMatrixPtr mActiveMatrix; ///< pointer to TTSampleMatrix that will be returned via checkOutMatrix()
42  TTSampleMatrixPtr mBecomingActiveMatrix; ///< pointer to TTSampleMatrix that is being prepared internally for a future checkOutMatrix()
43 
44  // internal method used for initializing the TTBuffer and mActiveMatrix for use
45  TTErr init(TTChannelCount channelCount, TTSymbol name);
46 
47  // internal method used for disposing of a no-longer used matrix
48  TTErr chuckMatrix(TTSampleMatrixPtr oldMatrix);
49 
50  // internal methods used for prepping mBecomingActiveMatrix, then swapping it out with mActiveMatrix
51  TTErr prepareBecomingActiveMatrix();
52  TTErr promoteBecomingActiveMatrix();
53 
54 public:
55 
56  // public method to check out the mActiveMatrix
57  TTErr checkOutMatrix(TTSampleMatrixPtr& startUsingThisMatrix);
58  TTErr checkOutMatrixValues(const TTValueRef unusedInput, TTValueRef output);
59 
60  // public method to check in TTSampleMatrix. if it is no longer mActiveMatrix, action is taken.
61  TTErr checkInMatrix(TTSampleMatrixPtr& doneUsingThisMatrix);
62  TTErr checkInMatrixValues(const TTValueRef input, TTValueRef unusedOutput);
63 
64  TTErr getNames(const TTValueRef unusedInput, TTValueRef returnedNames)
65  {
66  return gTTBufferNameMap->getKeys(returnedNames);
67  }
68 
69 
70  TTErr setName(const TTValueRef newName)
71  {
72  TTSymbol name = kTTSymEmpty;
73  TTSymbol oldName = mName;
74  TTValue returnedValue;
75  TTErr err = kTTErrNone;
76 
77  name = newName[0];
78 
79  // if the name is the same, then do nothing
80  if (name == mName)
81  return kTTErrNone;
82 
83  // if the name was left off, then generate a random value
84  if (name == kTTSymEmpty)
85  name = TTSymbol::random();
86 
87  // see if the name is already in the global buffer name map
88  err = gTTBufferNameMap->lookup(name, returnedValue);
89 
90  // if it is already in use by another TTBuffer
91  if (err == kTTErrNone)
92  {
93  return kTTErrInvalidValue;
94  } else { // if it is not, then we can add it
95  gTTBufferNameMap->append(name, TTPtr(this));
96  mName = name;
97  return kTTErrNone;
98  }
99  }
100 
101 
102  /****************************************************************************************************/
103  // TODO: Some will need to be rewritten as BufferPool implementation is fleshed out
104 
105  /*
106  NOTE: Set methods could follow this pattern
107  1) TTObjectInstantiate("samplematrix", (TTObjectPtr*)&mBecomingActiveMatrix, kTTValNONE)
108  2) mBecomingActiveMatrix.adaptTo(mActiveMatrix)
109  3) mBecomingActiveMatrix->setTheWhatever(TTValue arg1)
110  4) if no error...
111  mBecomingIdle = mActiveMatrix
112  mActiveMatrix = mBecomingActiveMatrix
113  5) if mBecomingIdle->getUserCount() = 0 then delete
114  else mBecomingIdle->setBufferPoolStage(kSM_BecomingIdle)
115 
116  In order to ensure that this happens consistently, we use the following macros to wrap methods from TTSampleMatrix as our own
117  */
118 
119  #define TTBUFFER_WRAP_1ARG(methodname) \
120  TTErr methodname (TTValue& arg1) { return mActiveMatrix -> methodname (arg1); }
121  #define TTBUFFER_WRAP_k1ARG(methodname) \
122  TTErr methodname (const TTValue& arg1) { return mActiveMatrix -> methodname (arg1); }
123  #define TTBUFFER_WRAP_WITHSPAWN_k1ARG(methodname) \
124  TTErr methodname (const TTValue& arg1) \
125  { \
126  TTErr err = prepareBecomingActiveMatrix(); \
127  if (!err) \
128  err = mBecomingActiveMatrix -> methodname (arg1); \
129  if (!err) \
130  err = promoteBecomingActiveMatrix(); \
131  return err; \
132  }
133 
134  // Methods of the hosted TTSampleMatrix object
135 
136  TTBUFFER_WRAP_WITHSPAWN_k1ARG( setNumChannels )
137  TTBUFFER_WRAP_1ARG( getNumChannels )
138 
139  TTBUFFER_WRAP_WITHSPAWN_k1ARG( setLengthInSeconds )
140  TTBUFFER_WRAP_1ARG( getLengthInSeconds )
141 
142  TTBUFFER_WRAP_WITHSPAWN_k1ARG( setLengthInSamples )
143  TTBUFFER_WRAP_1ARG( getLengthInSamples )
144 
145  /* NOTE: We do not wrap getValueAtIndex, peek, setValueAtIndex, poke and simliar methods.
146  Objects should work directly with the TTSampleMatrixPtr that they check out for these types of operations.
147  */
148 
149  /** Attribute updater: whenever the sample rate for this buffer is changed, apply to the active TTSampleMatrix immediately. This change is not deferred to next checkout.
150  @return Returns a TTErr error code. */
151  TTErr updateSampleRate(const TTValue& oldSampleRate, TTValue&)
152  {
153  return mActiveMatrix->setAttributeValue(kTTSym_sampleRate, sr);
154  }
155 
156  TTErr fill(const TTValue& value, TTValue& unusedOutput)
157  {
158  TTErr err = prepareBecomingActiveMatrix();
159  if (!err)
160  err = mBecomingActiveMatrix -> fill (value,unusedOutput);
161  if (!err)
162  err = promoteBecomingActiveMatrix();
163  return err;
164  }
165 
166  TTErr load(const TTValue& value, TTValue& unusedOutput)
167  {
168  TTErr err = prepareBecomingActiveMatrix();
169  if (!err)
170  err = mBecomingActiveMatrix -> load (value,unusedOutput);
171  if (!err)
172  err = promoteBecomingActiveMatrix();
173  return err;
174  }
175 
176  TTErr resizeThenLoad(const TTValue& value, TTValue& unusedOutput)
177  {
178  TTErr err = prepareBecomingActiveMatrix();
179  if (!err)
180  err = mBecomingActiveMatrix -> resizeThenLoad(value, unusedOutput);
181  if (!err)
182  err = promoteBecomingActiveMatrix();
183  return err;
184  }
185 
186  TTBUFFER_WRAP_k1ARG( normalize )
187 
188  /****************************************************************************************************/
189 
190 
191  /** Unit testing */
192  virtual TTErr test(TTValue& returnedTestInfo);
193 
194 };
195 
196 typedef TTBuffer* TTBufferPtr;
197 
198 /** Wrap TTBuffer instances for convenience. */
199 class TTAudioBuffer : public TTObject {
200 public:
201  TTAudioBuffer(const TTValue& channelCount, const TTValue& sampleCount):
202  TTObject(kTTSym_buffer, channelCount)
203  {
204  instance()->setLengthInSamples(sampleCount);
205  }
206 
207  TTBufferPtr instance()
208  {
209  return (TTBufferPtr)mObjectInstance;
210  }
211 
212  TTErr fill(const TTValue &value)
213  {
214  TTValue unusedOuput;
215  return instance()->fill(value, unusedOuput);
216  }
217 
218  TTErr load(const TTValue &value)
219  {
220  TTValue unusedOuput;
221  return instance()->load(value, unusedOuput);
222  }
223 
224  TTErr resizeThenLoad(const TTValue &value)
225  {
226  TTValue unusedOutput;
227  return instance()->resizeThenLoad(value, unusedOutput);
228  }
229 
230  TTErr checkOutMatrix(TTSampleMatrixPtr& startUsingThisMatrix)
231  {
232  return instance()->checkOutMatrix(startUsingThisMatrix);
233  }
234 
235  TTErr checkInMatrix(TTSampleMatrixPtr& doneUsingThisMatrix)
236  {
237  return instance()->checkInMatrix(doneUsingThisMatrix);
238  }
239 
240 };
241 
242 #endif // __TT_BUFFER_H__
An inappropriate value was specified for an attribute or variable.
Definition: TTBase.h:349
TTSampleMatrixPtr mBecomingActiveMatrix
pointer to TTSampleMatrix that is being prepared internally for a future checkOutMatrix() ...
Definition: TTBuffer.h:42
TTErr lookup(const TTSymbol key, TTValue &value)
Find the value for the given key.
Definition: TTHash.cpp:76
TTAudioObjectBase is the base class for all audio generating and processing objects in Jamoma DSP...
Wrap TTBuffer instances for convenience.
Definition: TTBuffer.h:199
Create and use Jamoma object instances.
Definition: TTObject.h:29
TTSampleMatrix holds some audio in a chunk of memory.
TTErr getKeys(TTValue &hashKeys)
Get an array of all of the keys for the hash table.
Definition: TTHash.cpp:126
TTBuffer manages the check-in/out of TTSampleMatrix pointers.
Definition: TTBuffer.h:35
Jamoma DSP Library.
TTErr setAttributeValue(const TTSymbol name, TTValue &value)
Set an attribute value for an object.
Maintain a collection of TTValue objects indexed by TTSymbol pointers.
Definition: TTHash.h:36
static TTSymbol random()
Generate a pseudo-random symbol.
Definition: TTSymbol.h:141
Container object that holds some audio in a chunk of memory.
#define TTCLASS_SETUP(className)
TODO Doxygen: need more comments here.
Definition: TTFoundation.h:54
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
TTErr append(const TTSymbol key, const TTValue &value)
Insert an item into the hash table.
Definition: TTHash.cpp:70
TTUInt16 TTChannelCount
Data type used when counting the number of channels in multi-channel audio signals and processes...
Definition: TTAudioSignal.h:31
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
No Error.
Definition: TTBase.h:343
TTSymbol mName
name associated with this buffer
Definition: TTBuffer.h:40
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
TTSampleMatrixPtr mActiveMatrix
pointer to TTSampleMatrix that will be returned via checkOutMatrix()
Definition: TTBuffer.h:41