Jamoma API  0.6.0.a19
TTAverage.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup dspAnalysisLib
4  *
5  * @brief TTAverage - measuring of averaged and RMS signal energy
6  *
7  * @details
8  *
9  * @authors Nils Peters, Tim Place, Trond Lossius
10  *
11  * @copyright Copyright © 2011, Nils Peters, Tim 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 "TTAverage.h"
18 
19 #define thisTTClass TTAverage
20 #define thisTTClassName "average"
21 #define thisTTClassTags "dspAnalysisLib, audio, analysis, rms, energy, movingAverage"
22 
23 
24 #ifndef TT_PLATFORM_MAC
25 #include <algorithm>
26 #endif
27 
28 
29 TT_AUDIO_CONSTRUCTOR,
30 mMaxInterval(2000),
31 mInterval(100)
32 {
33  TTChannelCount initialMaxNumChannels = arguments;
34 
35  addAttributeWithSetter(Mode, kTypeSymbol); //absolute, bipolar, rms
36  addAttributeWithSetter(MaxInterval, kTypeInt64);
38  addAttributeProperty(Interval, range, TTValue(1, mMaxInterval));
39  addAttributeProperty(Interval, rangeChecking, TT("clip"));
40  addMessage(clear);
41  addUpdates(SampleRate);
42  addUpdates(MaxNumChannels);
43 
44  // Set Defaults
45  setAttributeValue(kTTSym_maxNumChannels, initialMaxNumChannels);
46  setAttributeValue(TT("maxInterval"), 2000);
47  setAttributeValue(TT("mode"), TT("bipolar")); //absolute, bipolar, rms
48  setAttributeValue(TT("interval"), 100); //100 sample window length of moving average window
49  //TODO: add attribute to set interval in ms, rather than in samples
50 
51 }
52 
53 
54 TTAverage::~TTAverage()
55 {
56  ;
57 }
58 
59 
60 TTErr TTAverage::init(TTUInt64 newDelayMaxInSamples)
61 {
62 
63  for (TTDelayBufferIter buffer = mBins.begin(); buffer != mBins.end(); ++buffer) {
64  buffer->resize(mMaxInterval);
65  buffer->clear();
66  }
67  reset();
68 
69 return kTTErrNone;
70 }
71 
72 
74 {
76  mBins.resize(mMaxNumChannels);
77  return init(mMaxInterval);
78 }
79 
81 {
82  for (TTDelayBufferIter buffer = mBins.begin(); buffer != mBins.end(); ++buffer)
83  buffer->setDelay(mInterval);
84 
85 }
86 
87 
89 {
90  for_each(mBins.begin(), mBins.end(), std::mem_fun_ref(&TTDelayBuffer::clear));
91  mAccumulator.assign(mMaxNumChannels, 0.0);
92  return kTTErrNone;
93 }
94 
95 
97 {
98  TTSymbol newMode = aNewMode;
99 
100  if (mMode != newMode) {
101  clear();
102  reset();
103  mMode = newMode;
104  }
105 
106  if (mMode == TT("bipolar"))
108  if (mMode == TT("absolute"))
110  if (mMode == TT("rms"))
112  else {
114  return kTTErrInvalidValue;
115  }
116 }
117 
119 {
120  mInterval = aNewInterval;
122  reset();
123  clear();
124  return kTTErrNone;
125 }
126 
127 TTErr TTAverage::setMaxInterval(const TTValue& aNewMaxInterval)
128 {
129  mMaxInterval = aNewMaxInterval;
130 
131  return init(mMaxInterval);
132 }
133 
134 
135 TTErr TTAverage::updateSampleRate(const TTValue& aNotUsed1, TTValue& aNotUsed2)
136 {
137  //TODO: See header file for details
138  return kTTErrNone;
139 }
140 
141 #if 0
142 #pragma mark -
143 #pragma mark dsp routines
144 #endif
145 
146 
147 // Macro that is used to wrap the various processing methods for one channel as methods processing all channels.
148 #define TTAVERAGE_WRAP_CALCULATE_METHOD(methodName) \
149 TTAudioSignal& in = anInputs->getSignal(0); \
150 TTAudioSignal& out = anOutputs->getSignal(0); \
151 TTUInt16 vs; \
152 TTSampleValue* inSample; \
153 TTSampleValue* outSample; \
154 TTChannelCount numchannels = TTAudioSignal::getMinChannelCount(in, out); \
155 TTPtrSizedInt channel; \
156 TTDelayBufferPtr buffer; \
157 \
158 for (channel=0; channel<numchannels; channel++) { \
159 inSample = in.mSampleVectors[channel]; \
160 outSample = out.mSampleVectors[channel]; \
161 vs = in.getVectorSizeAsInt(); \
162 buffer = &mBins[channel]; \
163 \
164 while (vs--) { \
165 methodName (*inSample, *outSample, buffer, channel); \
166 outSample++; \
167 inSample++; \
168 } \
169 }\
170 return kTTErrNone;
171 
172 
174 {
175  TTDelayBufferPtr buffer = &mBins[aChannel];
176  return calculateAbsoluteValue(anInput, anOutput, buffer, aChannel);
177 }
178 
179 
181 {
182  TTAVERAGE_WRAP_CALCULATE_METHOD(calculateAbsoluteValue);
183 
184 }
185 
186 inline TTErr TTAverage::calculateAbsoluteValue(const TTFloat64& anInput, TTFloat64& anOutput, TTDelayBufferPtr aDelayBuffer, TTPtrSizedInt aChannel)
187 {
188  mAccumulator[aChannel] -= *aDelayBuffer->mReadPointer++;
189  mAccumulator[aChannel] += *aDelayBuffer->mWritePointer++ = fabs(anInput);
190  anOutput = mAccumulator[aChannel] * mIntervalReciprocal;
191 
192  // wrap the pointers in the buffer, if needed
193  if (aDelayBuffer->mWritePointer > aDelayBuffer->tail())
194  aDelayBuffer->mWritePointer = aDelayBuffer->head();
195  if (aDelayBuffer->mReadPointer > aDelayBuffer->tail())
196  aDelayBuffer->mReadPointer = aDelayBuffer->head();
197 
198 
199  return kTTErrNone;
200 }
201 
203 {
204  TTDelayBufferPtr buffer = &mBins[aChannel];
205  return calculateBipolarValue(anInput, anOutput, buffer, aChannel);
206 }
207 
209 {
210  TTAVERAGE_WRAP_CALCULATE_METHOD(calculateBipolarValue);
211 }
212 
213 inline TTErr TTAverage::calculateBipolarValue(const TTFloat64& anInput, TTFloat64& anOutput, TTDelayBufferPtr aDelayBuffer, TTPtrSizedInt aChannel)
214 {
215  mAccumulator[aChannel] -= *aDelayBuffer->mReadPointer++;
216  mAccumulator[aChannel] += *aDelayBuffer->mWritePointer++ = anInput;
217  anOutput = mAccumulator[aChannel] * mIntervalReciprocal;
218 
219  // wrap the pointers in the buffer, if needed
220  if (aDelayBuffer->mWritePointer > aDelayBuffer->tail())
221  aDelayBuffer->mWritePointer = aDelayBuffer->head();
222  if (aDelayBuffer->mReadPointer > aDelayBuffer->tail())
223  aDelayBuffer->mReadPointer = aDelayBuffer->head();
224 
225  return kTTErrNone;
226 }
227 
228 
230 {
231  TTDelayBufferPtr buffer = &mBins[aChannel];
232  return calculateRmsValue(anInput, anOutput, buffer, aChannel);
233 }
234 
236 {
237  TTAVERAGE_WRAP_CALCULATE_METHOD(calculateRmsValue);
238 
239 }
240 
241 inline TTErr TTAverage::calculateRmsValue(const TTFloat64& anInput, TTFloat64& anOutput, TTDelayBufferPtr aDelayBuffer, TTPtrSizedInt aChannel)
242 {
243  mAccumulator[aChannel] -= *aDelayBuffer->mReadPointer++;
244  mAccumulator[aChannel] += *aDelayBuffer->mWritePointer++ = anInput*anInput;
245  anOutput = sqrt(mAccumulator[aChannel] * mIntervalReciprocal);
246 
247  // wrap the pointers in the buffer, if needed
248  if (aDelayBuffer->mWritePointer > aDelayBuffer->tail())
249  aDelayBuffer->mWritePointer = aDelayBuffer->head();
250  if (aDelayBuffer->mReadPointer > aDelayBuffer->tail())
251  aDelayBuffer->mReadPointer = aDelayBuffer->head();
252 
253  return kTTErrNone;
254 }
255 
256 
257 
258 
259 
TTSampleVector mAccumulator
An accumulator used for calculation of running averages.
Definition: TTAverage.h:33
TTErr updateMaxNumChannels(const TTValue &anOldMaxNumChannels, TTValue &aNotUsed)
This method gets called when the inherited maxNumChannels attribute is changed.
Definition: TTAverage.cpp:73
An inappropriate value was specified for an attribute or variable.
Definition: TTBase.h:349
std::uint64_t TTUInt64
64 bit unsigned integer
Definition: TTBase.h:180
TTErr setInterval(const TTValue &aNewInterval)
Set the interval to use when averaging.
Definition: TTAverage.cpp:118
TTChannelCount mMaxNumChannels
This is the maximum number of channels that can be guaranteed to work.
TTSampleValuePtr mWritePointer
"record" pointer for buffer
Definition: TTDelayBuffer.h:32
TTErr clear()
Reset (clear) the history used in the analysis.
Definition: TTAverage.cpp:88
#define setProcessMethod(methodName)
A convenience macro to be used by subclasses for setting the process method.
TTAverage - measuring of averaged and RMS signal energy
TTUInt64 mInterval
The interval to do running averaging over.
Definition: TTAverage.h:31
Symbol type.
Definition: TTBase.h:282
double TTFloat64
64 bit floating point number
Definition: TTBase.h:188
#define TT
This macro is defined as a shortcut for doing a lookup in the symbol table.
Definition: TTSymbol.h:155
TTErr setMode(const TTValue &newValue)
Set the mode attribute that controlles what averaging mode to use.
Definition: TTAverage.cpp:96
TTErr updateSampleRate(const TTValue &aNotUsed1, TTValue &aNotUsed2)
Receives notifications when there are changes to the inherited sr attribute.
Definition: TTAverage.cpp:135
#define addAttributeProperty(attributeName, propertyName, initialValue)
A convenience macro to be used for registering properties of attributes.
Definition: TTAttribute.h:68
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
TTSampleValuePtr mReadPointer
"playback" pointer
Definition: TTDelayBuffer.h:33
TTErr setMaxInterval(const TTValue &aNewMaxInterval)
Set the maximum interval that can be used when averaging.
Definition: TTAverage.cpp:127
TTErr processBipolarAverage(TTAudioSignalArrayPtr anInputs, TTAudioSignalArrayPtr anOutputs)
Audio process method to use when doing bipolar averaging.
Definition: TTAverage.cpp:208
TTErr calculateBipolarValue(const TTFloat64 &anInput, TTFloat64 &anOutput, TTDelayBufferPtr aDelayBuffer, TTPtrSizedInt aChannel)
An inline method for single sample calculation of bipolar average value.
Definition: TTAverage.cpp:213
TTSymbol mMode
Averaging mode, options are absolute, bipolar and rms.
Definition: TTAverage.h:34
TTErr init(TTUInt64 newDelayMaxInSamples)
Internal method - set up the buffer memory.
Definition: TTAverage.cpp:60
TTUInt16 TTChannelCount
Data type used when counting the number of channels in multi-channel audio signals and processes...
Definition: TTAudioSignal.h:31
64-bit signed integer, ragne is −9,223,372,036,854,775,808 through 9,223,372,036,854,775,807
Definition: TTBase.h:279
TTFloat64 mIntervalReciprocal
The inverse of mInterval. Calculated and stored for conviniency and efficiency.
Definition: TTAverage.h:32
TTErr processRmsAverage(TTAudioSignalArrayPtr anInputs, TTAudioSignalArrayPtr anOutputs)
Audio process method to use when doing root-mean-square averaging.
Definition: TTAverage.cpp:235
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
long TTPtrSizedInt
An integer that is the same size as a pointer.
Definition: TTBase.h:240
TTErr processAbsoluteAverage(TTAudioSignalArrayPtr anInputs, TTAudioSignalArrayPtr anOutputs)
Audio process method to use when doing absolute value averaging.
Definition: TTAverage.cpp:180
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
No Error.
Definition: TTBase.h:343
TTErr calculateAbsoluteValue(const TTFloat64 &anInput, TTFloat64 &anOutput, TTDelayBufferPtr aDelayBuffer, TTPtrSizedInt aChannel)
An inline method for single sample calculation of absolute average value.
Definition: TTAverage.cpp:186
void reset()
Internal method - Position the buffer pointers.
Definition: TTAverage.cpp:80
void resize(size_type n)
Change the number of elements.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
TTUInt64 mMaxInterval
The largest possible interval or window to do running averaging over.
Definition: TTAverage.h:30
TTDelayBuffer is a container object that holds some audio in a chunk of memory, with accessors for us...
Definition: TTDelayBuffer.h:27
#define addUpdates(updateName)
An 'update' is a message sent to a subclass instance from its parent class.
Definition: TTMessage.h:44
TTErr calculateRmsValue(const TTFloat64 &anInput, TTFloat64 &anOutput, TTDelayBufferPtr aDelayBuffer, TTPtrSizedInt aChannel)
An inline method for single sample calculation of rms (root mean square) average value.
Definition: TTAverage.cpp:241