Jamoma API  0.6.0.a19
TTBuffer.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup dspLibrary
4  *
5  * @brief Audio buffer that manages multiple SampleMatrices.
6  *
7  * @see TTSampleMatrix, TTMatrix, TTAudioSignal
8  *
9  * @authors Timothy Place & Nathan Wolek
10  *
11  * @copyright Copyright © 2012, Timothy Place & Nathan Wolek @n
12  * This code is licensed under the terms of the "New BSD License" @n
13  * http://creativecommons.org/licenses/BSD/
14  */
15 
16 #include "TTBuffer.h"
17 #include "TTSampleMatrix.h"
18 
19 #define thisTTClass TTBuffer
20 #define thisTTClassName "buffer"
21 #define thisTTClassTags "dspLibrary, audio, buffer"
22 
23 
24 TTHashPtr gTTBufferNameMap = NULL;
25 // TODO: we likely need second hash table to track all SampleMatrices for status and destructor
26 
27 TTObjectBasePtr TTBuffer::instantiate(TTSymbol name, const TTValue arguments)
28 {
29  return new TTBuffer(arguments);
30 }
31 
32 
33 extern "C" void TTBuffer::registerClass()
34 {
35  TTClassRegister("buffer", thisTTClassTags, TTBuffer::instantiate);
36 }
37 
38 
39 TTBuffer::TTBuffer(const TTValue& arguments) :
40  TTAudioObjectBase(arguments),
41  mActiveMatrix(NULL),
42  mBecomingActiveMatrix(NULL)
43 {
44  // By convention, the first argument for a TTAudioObjectBase is the number of channels
45  // So we'll maintain that here, and then use the second argument for the name of the buffer
46 
47  TTChannelCount channelCount = 1;
48  TTSymbol name = TTSymbol::random();
49 
50  if (arguments.size() > 0) {
51  channelCount = arguments[0]; // TODO: should we limit range? what should zero mean?
52  if (arguments.size() > 1)
53  name = arguments[1];
54  }
55 
56  addMessageWithArguments(getNames);
58 
62 
63  addMessage(normalize);
66  registerMessage("checkOutMatrix", (TTMethod)&TTBuffer::checkOutMatrixValues);
67  registerMessage("checkInMatrix", (TTMethod)&TTBuffer::checkInMatrixValues);
68 
69  addUpdates(SampleRate);
70 
71  // initialize
72  init(channelCount, name);
73 
74 }
75 
76 
77 TTBuffer::~TTBuffer()
78 {
79  chuckMatrix(mActiveMatrix);
81  // TODO: what happens to matrices that are checked out, but no longer active?
82 }
83 
84 
85 // internal method used for initializing the TTBuffer and mActiveMatrix for use
86 TTErr TTBuffer::init(TTChannelCount channelCount, TTSymbol name)
87 {
88  TTErr err = kTTErrNone;
89 
90  if (!gTTBufferNameMap)
91  gTTBufferNameMap = new TTHash;
92 
93  setAttributeValue("name", name);
94 
95  err = TTObjectBaseInstantiate("samplematrix", (TTObjectBasePtr*)&mActiveMatrix, kTTValNONE);
96  if (!err)
97  {
98  mActiveMatrix->setAttributeValue(kTTSym_sampleRate, this->sr);
99  mActiveMatrix->setAttributeValue("numChannels", channelCount);
101  }
102 
103  return err;
104 }
105 
106 // internal method used for disposing of a no-longer used matrix
107 TTErr TTBuffer::chuckMatrix(TTSampleMatrixPtr oldMatrix)
108 {
109  if (oldMatrix->getUserCount() < 1)
110  {
111  return TTObjectBaseRelease(TTObjectBaseHandle(&oldMatrix));
112  } else {
113  return kTTErrFreeFailed;
114  }
115 
116 }
117 
118 
119 // internal methods used for prepping mBecomingActiveMatrix, then swapping it out with mActiveMatrix
120 TTErr TTBuffer::prepareBecomingActiveMatrix()
121 {
122  // set to generic error first
123  TTErr err = kTTErrGeneric;
124 
125  // check that there isn't already another mBecomingActiveMatrix in progress
126  if (mBecomingActiveMatrix == NULL)
127  {
128  // if so, then we first we try to instatiate a new TTSampleMatrix
129  // and if it succeeds, it will override the generic error above
130  err = TTObjectBaseInstantiate("samplematrix", (TTObjectBasePtr*)&mBecomingActiveMatrix, kTTValNONE);
131  }
132 
133  // only if there is still no error at this point, we set up this other stuff
134  if (!err)
135  {
136  mBecomingActiveMatrix->adaptTo(mActiveMatrix); // start with something like the mActiveMatrix
138  } else {
139  // if there is an error, send a log message
140  TTLogError("TTBuffer failed to prepare new SampleMatrix");
141  }
142 
143  // report if everything worked
144  return err;
145 }
146 
147 TTErr TTBuffer::promoteBecomingActiveMatrix()
148 {
149  // TODO: i think there is a real need for mutex locking here
150 
151  // tell the mActiveMatrix it is on the way out
153 
154  // attempt to chuckMatrix, because if the mUserCount is 0 it will NEVER call checkInMatrix
155  if (mActiveMatrix->getUserCount() < 1) chuckMatrix(mActiveMatrix);
156 
157  // tell the mBecomingActiveMatrix it is on the way in
159 
160  // update the mActiveMatrix pointer
162 
163  // set to NULL for the next time prepareBecomingActiveMatrix() is called
164  mBecomingActiveMatrix = NULL;
165 
166  // no real chance of an error, yet
167  return kTTErrNone;
168 }
169 
170 
171 TTErr TTBuffer::checkOutMatrix(TTSampleMatrixPtr& startUsingThisMatrix)
172 {
173  // add one to the tally of users
175 
176  // then give out the pointer to the current mActiveMatrix
177  startUsingThisMatrix = mActiveMatrix;
178 
179  // no real chance of an error, yet
180  return kTTErrNone;
181 }
182 
183 TTErr TTBuffer::checkOutMatrixValues(const TTValueRef unusedInput, TTValueRef output)
184 {
185  TTSampleMatrixPtr startUsingThisMatrix = NULL;
186 
187  if (checkOutMatrix(startUsingThisMatrix) == kTTErrNone)
188  {
189 
190  TTObjectBasePtr startUsingThisObject = TTObjectBasePtr(TTPtr(startUsingThisMatrix));
191 
192  output.clear();
193  output.append(startUsingThisObject);
194 
195  return kTTErrNone;
196 
197  } else {
198  return kTTErrGeneric;
199  }
200 }
201 
202 TTErr TTBuffer::checkInMatrix(TTSampleMatrixPtr& doneUsingThisMatrix)
203 {
204  // sub one from the tally of users
205  doneUsingThisMatrix->decrementUserCount();
206 
207  // if this is no longer the current mActiveMatrix, then...
208  if(doneUsingThisMatrix->isBufferPoolStage(kSM_BecomingIdle))
209  {
210  // the next method checks the user count, so we don't have to
211  // but maybe we should so that meaningful errors can be reported?
212  chuckMatrix(doneUsingThisMatrix);
213  }
214 
215  // we set the pointer to NULL so that users have to check it out again
216  doneUsingThisMatrix = NULL;
217 
218  // no real chance of an error, yet
219  return kTTErrNone;
220 }
221 
222 TTErr TTBuffer::checkInMatrixValues(const TTValueRef input, const TTValueRef unusedOutput)
223 {
224  TTObject doneUsingThisObject = input[0];
225 
226  // let's make sure input is a samplematrix first
227  if (doneUsingThisObject.name() != TT("samplematrix"))
228  {
229  // if no: return an error
230  return kTTErrInvalidValue;
231  } else {
232  // if yes: get a generic TTPtr, then cast to TTSampleMatrixPtr
233  TTSampleMatrixPtr doneUsingThisMatrix = (TTSampleMatrixPtr)doneUsingThisObject.instance();
234  return checkInMatrix(doneUsingThisMatrix);
235  }
236 
237 }
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 TTObjectBaseRelease(TTObjectBasePtr *anObject)
DEPRECATED.
TTErr decrementUserCount()
Decrease the user count by one.
Couldn't free memory.
Definition: TTBase.h:346
TTAudioObjectBase is the base class for all audio generating and processing objects in Jamoma DSP...
Create and use Jamoma object instances.
Definition: TTObject.h:29
64-bit unsigned integer, range is 0 through 18,446,744,073,709,551,615.
Definition: TTBase.h:280
size_type size() const noexcept
Return the number of elements.
no longer active, but waiting for remaining users to check in
TTSampleMatrix holds some audio in a chunk of memory.
TTBuffer manages the check-in/out of TTSampleMatrix pointers.
Definition: TTBuffer.h:35
Base class for all first-class Jamoma objects.
Definition: TTObjectBase.h:109
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
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
Symbol type.
Definition: TTBase.h:282
static TTSymbol random()
Generate a pseudo-random symbol.
Definition: TTSymbol.h:141
TTErr registerMessage(const TTSymbol name, TTMethod method)
Register a message with this object.
16-bit unsigned integer, range is 0 through 65,535.
Definition: TTBase.h:276
#define TT
This macro is defined as a shortcut for doing a lookup in the symbol table.
Definition: TTSymbol.h:155
void append(const T &anElementValueToAppend)
Insert a single TTElement at the end.
Definition: TTValue.h:243
TTErr adaptTo(const TTSampleMatrix &anotherMatrix)
Set dimensions, element count, datatype, etc.
Container object that holds some audio in a chunk of memory.
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
64-bit floating point
Definition: TTBase.h:272
TTSymbol name() const
Return the name of this class.
Definition: TTObject.cpp:129
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
TTErr incrementUserCount()
Increase the user count by one.
TTUInt16 getUserCount()
Report the current user count.
void TTFOUNDATION_EXPORT TTLogError(TTImmutableCString message,...)
Platform and host independent method for posting errors.
Definition: TTBase.cpp:572
TTErr TTObjectBaseInstantiate(const TTSymbol className, TTObjectBasePtr *returnedObjectPtr, const TTValue arguments)
DEPRECATED.
in use and pointer to this TTSampleMatrix will be given to users at check out
#define addMessageWithArguments(name)
A convenience macro to be used by subclasses for registering messages.
Definition: TTMessage.h:27
TTUInt16 TTChannelCount
Data type used when counting the number of channels in multi-channel audio signals and processes...
Definition: TTAudioSignal.h:31
void clear()
Clear all values from the vector, leaving with size of 0.
Definition: TTValue.h:131
TTBoolean isBufferPoolStage(TTBufferPoolStageEnum testValue)
Test to see if current bufferPoolStage matches a test value.
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
#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
TTObjectBase * instance() const
Return a direct pointer to the internal instance.
Definition: TTObject.cpp:105
No Error.
Definition: TTBase.h:343
TTBuffer manages the check-in/out of TTSampleMatrix pointers.
TTErr setBufferPoolStage(TTBufferPoolStageEnum newValue)
Set the current bufferPoolStage to a new value.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
being prepared for active stage by resizing or file loading operation
TTSampleMatrixPtr mActiveMatrix
pointer to TTSampleMatrix that will be returned via checkOutMatrix()
Definition: TTBuffer.h:41
#define addUpdates(updateName)
An 'update' is a message sent to a subclass instance from its parent class.
Definition: TTMessage.h:44
#define addAttributeWithGetterAndSetter(name, type)
A convenience macro to be used by subclasses for registering attributes with a custom getter and sett...
Definition: TTAttribute.h:57
TTUInt32 sr
Current sample rate being used by this object.