CAudioBuffer.hpp

Go to the documentation of this file.
00001 #ifndef __CAudioBuffer__
00002 #define __CAudioBuffer__
00003 
00004 //  ===========================================================================
00005 
00006 #include <Basics/CCountedObject.hpp>
00007 #include <Exceptions/CException.hpp>
00008 #include <MathTools/CMathTools.hpp>
00009 
00010 //  ===========================================================================
00011 
00012 using Exponent::Basics::CCountedObject;
00013 using Exponent::Exceptions::CException;
00014 using Exponent::MathTools::CMathTools;
00015 
00016 //  ===========================================================================
00017 
00018 namespace Exponent
00019 {
00020     namespace Audio
00021     {
00046         class CAudioBuffer : public CCountedObject
00047         {
00049             EXPONENT_CLASS_DECLARATION;
00052 //  ===========================================================================
00053 
00054         public:
00055 
00056 //  ===========================================================================
00057 
00058             const static double CAUDIO_BUFFER_DENORMAL;     
00060 //  ===========================================================================
00061 
00066             enum EStereoChannels
00067             {
00068                 e_left = 0,     
00069                 e_right,        
00071                 e_mono = 1,     
00072                 e_stereo,       
00073             };
00074 
00075 //  ===========================================================================
00076 
00081             CAudioBuffer(const long bufferSize);
00082 
00086             CAudioBuffer();
00087 
00091             virtual ~CAudioBuffer();
00092 
00093 //  ===========================================================================
00094 
00099             double **getMutableAudioData() const { return m_waveData; }
00100 
00105             const double **getAudioData() const { return (const double **)&m_waveData[0]; }
00106 
00112             FORCEINLINE double *getChannel(const long channel) { return m_waveData[channel]; }
00113 
00120             FORCEINLINE double getSample(const long channel, const long index) { return m_waveData[channel][index]; }
00121 
00122 //  ===========================================================================
00123 
00128             void initialise(const long bufferSize);
00129 
00133             void uninitialise();
00134 
00139             void reInitialise(const long bufferSize);
00140 
00141 //  ===========================================================================
00142 
00146             void FORCEINLINE clearWaveForm()
00147             {
00148                 const size_t size = m_bufferSize * sizeof(double);
00149                 memset(m_waveData[0], 0, size);
00150                 memset(m_waveData[1], 0, size);
00151             }
00152 
00153 //  ===========================================================================
00154 
00158             void FORCEINLINE mergeChannels()
00159             {
00160                 for (long i = 0; i < m_bufferSize; i++)
00161                 {
00162                     m_waveData[0][i] = m_waveData[1][i] = ((m_waveData[0][i] * 0.5) + (m_waveData[1][i] * 0.5));
00163                 }
00164             }
00165 
00171             void FORCEINLINE mergeWithBuffer(CAudioBuffer *buffer)
00172             {
00173                 if (buffer->getBufferSize() != m_bufferSize)
00174                 {
00175                     throw CException("Buffer sizes do not match", "CAudioBuffer::mergeWithBuffer(CAudioBuffer *)");
00176                 }
00177 
00178                 double *left   = m_waveData[0];
00179                 double *right  = m_waveData[1];
00180                 double *leftF  = buffer->getChannel(e_left);
00181                 double *rightF = buffer->getChannel(e_right);
00182 
00183                 for (long i = 0; i < m_bufferSize; i++)
00184                 {
00185                     left[i]  += leftF[i];
00186                     right[i] += rightF[i];
00187                 }
00188             }
00189 
00190 //  ===========================================================================
00191 
00197             void FORCEINLINE accumulateInToFloatData(float **output, const long numberOfSamples)
00198             {
00199                 double *left  = m_waveData[0];
00200                 double *right = m_waveData[1];
00201                 float *leftF  = output[0];
00202                 float *rightF = output[1];
00203 
00204                 for (long i = 0; i < numberOfSamples; i++)
00205                 {
00206                     leftF[i]  += (float)left[i];
00207                     rightF[i] += (float)right[i];
00208                 }
00209             }
00210 
00217             void FORCEINLINE mergeToBuffer(double *output, const long numberOfSamples)
00218             {
00219                 if (output == NULL)
00220                 {
00221                     throw CException("Output buffer is NULL", "CAudioBuffer::mergeToBuffer(double *, const long)");
00222                 }
00223 
00224                 double *left  = m_waveData[0];
00225                 double *right = m_waveData[1];
00226 
00227                 for (long i = 0; i < numberOfSamples; i++)
00228                 {
00229                     output[i] = (left[i] * 0.5) + (right[i] * 0.5);
00230                 }
00231             }
00232 
00233 //  ===========================================================================
00234 
00239             long getBufferSize() const { return m_bufferSize; }
00240 
00241 //  ===========================================================================
00242 
00248             void FORCEINLINE setFromAudioBuffer(CAudioBuffer *buffer)
00249             {
00250                 if (buffer->getBufferSize() != m_bufferSize)
00251                 {
00252                     throw CException("Buffer sizes do not match", "CAudioBuffer::setFromAudioBuffer(CAudioBuffer *)");
00253                 }
00254 
00255                 memcpy(m_waveData[0], buffer->getChannel(e_left),  m_bufferSize * sizeof(double));
00256                 memcpy(m_waveData[1], buffer->getChannel(e_right), m_bufferSize * sizeof(double));
00257             }
00258 
00264             void FORCEINLINE setWaveDataFromFloatData(float **waveData, const long numberOfSamples)
00265             {
00266                 double *left  = m_waveData[0];
00267                 double *right = m_waveData[1];
00268 
00269                 float *leftF  = waveData[0];
00270                 float *rightF = waveData[1];
00271 
00272                 for (long i = 0; i < numberOfSamples; i++)
00273                 {
00274                     left[i]  = (double)leftF[i];
00275                     right[i] = (double)rightF[i];
00276                 }
00277             }
00278 
00284             void FORCEINLINE setWaveDataFromFloatDataAndDenormal(float **waveData, const long numberOfSamples)
00285             {
00286                 double *left  = m_waveData[0];
00287                 double *right = m_waveData[1];
00288 
00289                 float *leftF  = waveData[0];
00290                 float *rightF = waveData[1];
00291 
00292                 for (long i = 0; i < numberOfSamples; i++)
00293                 {
00294                     left[i]  = (double)leftF[i]  + CAUDIO_BUFFER_DENORMAL;
00295                     right[i] = (double)rightF[i] + CAUDIO_BUFFER_DENORMAL;
00296                 }
00297             }
00298 
00304             void FORCEINLINE copyToFloatBufferFromWaveData(float **waveData, const long numberOfSamples)
00305             {
00306                 double *left  = m_waveData[0];
00307                 double *right = m_waveData[1];
00308 
00309                 float *leftF  = waveData[0];
00310                 float *rightF = waveData[1];
00311 
00312                 for (long i = 0; i < numberOfSamples; i++)
00313                 {
00314                     leftF[i]  = (float)left[i];
00315                     rightF[i] = (float)right[i];
00316                 }
00317             }
00318 
00319 //  ===========================================================================
00320 
00325             void FORCEINLINE denormal(const long numberOfSamples)
00326             {
00327                 double *left  = m_waveData[0];
00328                 double *right = m_waveData[1];
00329                 for (long i = 0; i < numberOfSamples; i++)
00330                 {
00331                     left[i]  += CAUDIO_BUFFER_DENORMAL;
00332                     right[i] += CAUDIO_BUFFER_DENORMAL;
00333                 }
00334             }
00335 
00340             void FORCEINLINE changeGain(const double volume)
00341             {
00342                 double *left  = m_waveData[0];
00343                 double *right = m_waveData[1];
00344                 for (long i = 0; i < m_bufferSize; i++)
00345                 {
00346                     left[i]  *= volume;
00347                     right[i] *= volume;
00348                 }
00349             }
00350 
00356             void getMaxSamples(double &left, double &right);
00357 
00362             void FORCEINLINE applyTanhLimiting()
00363             {
00364                 double *left  = m_waveData[0];
00365                 double *right = m_waveData[1];
00366                 for (long i = 0; i < m_bufferSize; i++)
00367                 {
00368                     left[i]  = CMathTools::tanhApproximation(left[i]);
00369                     right[i] = CMathTools::tanhApproximation(right[i]);
00370                 }
00371             }
00372 
00379             FORCEINLINE static double computeRMS(const double *buffer, const long numberOfSamplesToProcess)
00380             {
00381                 // Compute the squares
00382                 double mean1 = 0.0, mean2 = 0.0, mean3 = 0.0, mean4 = 0.0;
00383                 for (long i = 0; i < numberOfSamplesToProcess - 4; i+=4)
00384                 {
00385                     mean1 += buffer[i]     * buffer[i];
00386                     mean2 += buffer[i + 1] * buffer[i + 1];
00387                     mean3 += buffer[i + 2] * buffer[i + 2];
00388                     mean4 += buffer[i + 3] * buffer[i + 3];
00389                 }
00390                 /*for (long i = 0; i < numberOfSamplesToProcess; i++)
00391                 {
00392                     mean += buffer[i] * buffer[i];
00393                 }*/
00394                 return sqrt((mean1 + mean2 + mean3 + mean4) / numberOfSamplesToProcess);
00395 
00396                 // Compute the mean
00397                 //mean /= numberOfSamplesToProcess;
00398 
00399                 // Return the RMS
00400                 //return sqrt(mean);
00401             }
00402 
00409             FORCEINLINE static double computeRMS(const float *buffer, const long numberOfSamplesToProcess)
00410             {
00411                 // Compute the squares
00412                 double mean = 0.0;
00413                 for (long i = 0; i < numberOfSamplesToProcess; i++)
00414                 {
00415                     mean += (double)(buffer[i] * buffer[i]);
00416                 }
00417 
00418                 // Compute the mean
00419                 mean /= numberOfSamplesToProcess;
00420 
00421                 // Return the RMS
00422                 return sqrt(mean);
00423             }
00424 
00425 //  ===========================================================================
00426 
00427         protected:
00428 
00429 //  ===========================================================================
00430 
00431             double **m_waveData;        
00432             long m_bufferSize;          
00433         };
00434     }
00435 }
00436 
00437 #endif  // End of CAudioBuffer.hpp

Infinity API - CAudioBuffer.hpp Source File generated on 7 Mar 2007