- Main Page
- Namespaces
- Classes
- Files
- Directories
- Related Pages

- File List
- File Members

# 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