00001 #ifndef __TAudioBuffer__
00002 #define __TAudioBuffer__
00003
00004
00005
00006 #include <Basics/CCountedObject.hpp>
00007 #include <MathTools/CMathTools.hpp>
00008 #include <Collections/TAutomaticPointer.hpp>
00009 using Exponent::MathTools::CMathTools;
00010 using Exponent::Basics::CCountedObject;
00011 using Exponent::Collections::TAutomaticPointer;
00012
00013
00014
00015 namespace Exponent
00016 {
00017 namespace Audio
00018 {
00036 template<typename TypeName> class TAudioBuffer : public CCountedObject
00037 {
00039 EXPONENT_CLASS_DECLARATION;
00042
00043
00044 public:
00045
00046
00047
00052 typedef TAutomaticPointer< TAutomaticPointer<TypeName> > TAudioBufferPointer;
00053
00054
00055
00059 TAudioBuffer() : m_buffer(NULL), m_numberOfSamples(0), m_numberOfChannels(0), m_bufferSize(0)
00060 {
00061 NULL_POINTER(m_buffer);
00062 m_numberOfSamples = 0;
00063 m_numberOfChannels = 0;
00064 m_bufferSize = 0;
00065 }
00066
00070 virtual ~TAudioBuffer()
00071 {
00072 this->uninitialise();
00073 }
00074
00075
00076
00077
00084 bool initialise(const unsigned long numberOfSamples, const unsigned long numberOfChannels)
00085 {
00086
00087 if (m_buffer)
00088 {
00089 this->uninitialise();
00090 }
00091
00092
00093 m_numberOfSamples = numberOfSamples;
00094 m_numberOfChannels = numberOfChannels;
00095 m_bufferSize = m_numberOfSamples * m_numberOfChannels;
00096
00097
00098 m_buffer = new TypeName[m_bufferSize];
00099
00100
00101 this->clearBuffer();
00102
00103
00104 return true;
00105 }
00106
00110 void uninitialise()
00111 {
00112
00113 if (m_buffer)
00114 {
00115
00116 FREE_ARRAY_POINTER(m_buffer);
00117
00118
00119 m_numberOfChannels = 0;
00120 m_numberOfSamples = 0;
00121 m_bufferSize = 0;
00122 }
00123 }
00124
00128 void clearBuffer()
00129 {
00130
00131 if (m_buffer)
00132 {
00133 memset(m_buffer, 0, m_bufferSize * sizeof(TypeName));
00134 }
00135 }
00136
00137
00138
00145 const TypeName *operator[](const long index) const
00146 {
00147 return this->getChannel(index);
00148 }
00149
00150
00151
00161 const TypeName *getChannel(const unsigned long index) const
00162 {
00163 if (m_buffer && index < m_numberOfChannels)
00164 {
00165 return &m_buffer[index];
00166 }
00167 return NULL;
00168 }
00169
00179 TypeName *getMutableChannel(const unsigned long index)
00180 {
00181 if (m_buffer && index < m_numberOfChannels)
00182 {
00183 return &m_buffer[index];
00184 }
00185 return NULL;
00186 }
00187
00192 const TypeName *getData() const
00193 {
00194 if (m_buffer)
00195 {
00196 return m_buffer;
00197 }
00198 return NULL;
00199 }
00200
00205 TypeName *getMutableData()
00206 {
00207 if (m_buffer)
00208 {
00209 return m_buffer;
00210 }
00211 return NULL;
00212 }
00213
00214
00215
00220 FORCEINLINE unsigned long getNumberOfChannels() const { return m_numberOfChannels; }
00221
00226 FORCEINLINE unsigned long getNumberOfSamples() const { return m_numberOfSamples; }
00227
00232 FORCEINLINE unsigned long getBufferSize() const { return m_bufferSize; }
00233
00240 FORCEINLINE unsigned long getSampleFrameSize() const { return m_numberOfChannels; }
00241
00242
00243
00249 TypeName getMaximumSample(const unsigned long channel) const
00250 {
00251 if (channel < m_numberOfChannels && m_buffer)
00252 {
00253 TypeName *buffer = &m_buffer[channel];
00254 TypeName maxValue = -2.0;
00255 for (long i = 0; i < m_numberOfSamples; i++)
00256 {
00257 maxValue = CMathTools::fastMaximum(*buffer, maxValue);
00258 buffer += m_numberOfChannels;
00259 }
00260 return maxValue;
00261 }
00262 return (TypeName)0;
00263 }
00264
00270 TypeName getMinimumSample(const unsigned long channel) const
00271 {
00272 if (channel < m_numberOfChannels && m_buffer)
00273 {
00274 TypeName *buffer = &m_buffer[channel];
00275 TypeName minValue = 2.0;
00276 for (long i = 0; i < m_numberOfSamples; i++)
00277 {
00278 minValue = CMathTools::fastMinimum(*buffer, minValue);
00279 buffer += m_numberOfChannels;
00280 }
00281 return minValue;
00282 }
00283 return (TypeName)0;
00284 }
00285
00293 FORCEINLINE TypeName getRMSLevel(const unsigned long channel, const unsigned long numberOfSamples, const unsigned long startSample = 0) const
00294 {
00295 if (channel < m_numberOfChannels && m_buffer && numberOfSamples <= m_numberOfSamples && startSample + numberOfSamples <= m_numberOfSamples)
00296 {
00297 TypeName mean = 0.0;
00298 const TypeName *theChannel = &m_buffer[channel + (this->getSampleFrameSize() * startSample)];
00299
00300
00301 for (unsigned long i = 0; i < numberOfSamples; i++)
00302 {
00303 mean += *theChannel * *theChannel;
00304 theChannel += this->getSampleFrameSize();
00305 }
00306
00307
00308 return sqrt(mean / (TypeName)numberOfSamples);
00309 }
00310 return (TypeName)0;
00311 }
00312
00316 void denormal()
00317 {
00318
00319 if (m_buffer == NULL)
00320 {
00321 return;
00322 }
00323
00324
00325 for (unsigned long i = 0; i < m_bufferSize; i++)
00326 {
00327 m_buffer[i] += (TypeName)1e-15;
00328 }
00329 }
00330
00335 bool mergeChannelsToMono()
00336 {
00337
00338 if (m_buffer == NULL)
00339 {
00340 return false;
00341 }
00342
00343
00344 if (m_numberOfChannels <= 1)
00345 {
00346 return true;
00347 }
00348
00349
00350 const TypeName level = 1.0 / (TypeName)m_numberOfChannels;
00351
00352
00353 TypeName *buffer = new TypeName[m_numberOfSamples];
00354 memset(buffer, 0, m_numberOfSamples * sizeof(TypeName));
00355 TypeName *bufferPointer = &m_buffer[0];
00356
00357
00358 for (unsigned long i = 0; i < m_numberOfSamples; i++)
00359 {
00360 for (unsigned long j = 0; j < m_numberOfChannels; j++)
00361 {
00362 buffer[i] += *bufferPointer++ * level;
00363 }
00364 }
00365
00366
00367 FREE_POINTER(m_buffer);
00368
00369
00370 m_buffer = buffer;
00371
00372
00373 m_numberOfChannels = 1;
00374 m_bufferSize = m_numberOfSamples;
00375
00376
00377 return true;
00378 }
00379
00386 bool copySamples(const TypeName *buffer, const unsigned long numberOfSamples)
00387 {
00388
00389 if (numberOfSamples <= m_numberOfSamples * m_numberOfChannels && m_buffer)
00390 {
00391
00392 memcpy(m_buffer, buffer, numberOfSamples * sizeof(TypeName));
00393
00394
00395 return true;
00396 }
00397
00398
00399 return false;
00400 }
00401
00411 bool mergeChannelToBuffer(float *buffer, const unsigned long startSample, const unsigned long numberOfSamples, const unsigned long channel)
00412 {
00413
00414 const unsigned long length = startSample + numberOfSamples;
00415
00416
00417 if (length <= m_numberOfSamples && channel < m_numberOfChannels && buffer != NULL)
00418 {
00419
00420
00421
00422 const TypeName *audioData = &m_buffer[channel][startSample * m_numberOfChannels];
00423
00424
00425 if (audioData == NULL)
00426 {
00427 return false;
00428 }
00429
00430
00431 for (unsigned long i = 0; i < numberOfSamples; i++)
00432 {
00433 buffer[i] += (float)*audioData;
00434 audioData += m_numberOfChannels;
00435 }
00436
00437
00438 return true;
00439 }
00440
00441
00442 return false;
00443 }
00444
00454 bool mergeChannelToBuffer(double *buffer, const unsigned long startSample, const unsigned long numberOfSamples, const unsigned long channel)
00455 {
00456
00457 const unsigned long length = startSample + numberOfSamples;
00458
00459
00460 if (length <= m_numberOfSamples && channel < m_numberOfChannels && buffer != NULL)
00461 {
00462
00463
00464
00465 const TypeName *audioData = &m_buffer[startSample * m_numberOfChannels];
00466
00467
00468 for (unsigned long i = 0; i < numberOfSamples; i++)
00469 {
00470 buffer[i] += (double)*audioData;
00471 audioData += m_numberOfChannels;
00472 }
00473
00474
00475 return true;
00476 }
00477
00478
00479 return false;
00480 }
00481
00482
00483
00484 protected:
00485
00486
00487
00488 TypeName *m_buffer;
00489 unsigned long m_numberOfSamples;
00490 unsigned long m_numberOfChannels;
00491 unsigned long m_bufferSize;
00493
00494
00495 };
00496
00501 typedef TAudioBuffer<double> TDoublePrecisionAudioBuffer;
00502
00507 typedef TAudioBuffer<float> TSinglePrecisionAudioBuffer;
00508
00510 EXPONENT_TEMPLATE_CLASS_IMPLEMENTATION(TAudioBuffer<TypeName>, TypeName, CCountedObject);
00512 }
00513 }
00514 #endif // End of TAudioBuffer.hpp