From 55c680e6fd3a70c4cd4f5d03dc3e418fa173ea9d Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Sat, 14 Feb 2009 00:46:58 +0000 Subject: [PATCH] speed optimizations --- src/client.cpp | 106 +++++++++++++++++++++-------------------------- src/client.h | 71 +++++++++++++++---------------- src/global.h | 6 +-- src/resample.cpp | 90 ++++++++++++++++++++++------------------ src/resample.h | 24 +++++------ src/util.cpp | 38 ++++++++++++----- src/util.h | 23 ++++++---- 7 files changed, 186 insertions(+), 172 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index 889a6187..e9a7c49d 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -27,7 +27,8 @@ /* Implementation *************************************************************/ CClient::CClient ( const quint16 iPortNumber ) : bRun ( false ), - iSndCrdBlockSizeSam ( MIN_SND_CRD_BLOCK_SIZE_SAMPLES ), + iSndCrdMonoBlockSizeSam ( MIN_SND_CRD_BLOCK_SIZE_SAMPLES ), + iSndCrdStereoBlockSizeSam ( 2 * MIN_SND_CRD_BLOCK_SIZE_SAMPLES ), Sound ( MIN_SND_CRD_BLOCK_SIZE_SAMPLES * 2 /* stereo */ ), Socket ( &Channel, iPortNumber ), iAudioInFader ( AUD_FADER_IN_MAX / 2 ), @@ -172,30 +173,27 @@ void CClient::OnProtocolStatus ( bool bOk ) void CClient::Init() { // set block size (in samples) - iBlockSizeSam = MIN_BLOCK_SIZE_SAMPLES; + iMonoBlockSizeSam = MIN_BLOCK_SIZE_SAMPLES; + iStereoBlockSizeSam = 2 * MIN_BLOCK_SIZE_SAMPLES; - vecsAudioSndCrd.Init ( iSndCrdBlockSizeSam * 2 ); // stereo - vecdAudioSndCrdL.Init ( iSndCrdBlockSizeSam ); - vecdAudioSndCrdR.Init ( iSndCrdBlockSizeSam ); + vecsAudioSndCrd.Init ( iSndCrdStereoBlockSizeSam ); + vecdAudioSndCrd.Init ( iSndCrdStereoBlockSizeSam ); - vecdAudioL.Init ( iBlockSizeSam ); - vecdAudioR.Init ( iBlockSizeSam ); + vecdAudio.Init ( iStereoBlockSizeSam ); Sound.InitRecording(); Sound.InitPlayback(); // resample objects are always initialized with the input block size // record - ResampleObjDownL.Init ( iSndCrdBlockSizeSam, SND_CRD_SAMPLE_RATE, SYSTEM_SAMPLE_RATE ); - ResampleObjDownR.Init ( iSndCrdBlockSizeSam, SND_CRD_SAMPLE_RATE, SYSTEM_SAMPLE_RATE ); + ResampleObjDown.Init ( iSndCrdMonoBlockSizeSam, SND_CRD_SAMPLE_RATE, SYSTEM_SAMPLE_RATE ); // playback - ResampleObjUpL.Init ( iBlockSizeSam, SYSTEM_SAMPLE_RATE, SND_CRD_SAMPLE_RATE ); - ResampleObjUpR.Init ( iBlockSizeSam, SYSTEM_SAMPLE_RATE, SND_CRD_SAMPLE_RATE ); + ResampleObjUp.Init ( iMonoBlockSizeSam, SYSTEM_SAMPLE_RATE, SND_CRD_SAMPLE_RATE ); // init network buffers - vecsNetwork.Init ( iBlockSizeSam ); - vecdNetwData.Init ( iBlockSizeSam ); + vecsNetwork.Init ( iMonoBlockSizeSam ); + vecdNetwData.Init ( iMonoBlockSizeSam ); // init moving average buffer for response time evaluation RespTimeMoAvBuf.Init ( LEN_MOV_AV_RESPONSE ); @@ -208,7 +206,7 @@ void CClient::Init() void CClient::run() { - int i, iInCnt; + int i, j; // Set thread priority (The working thread should have a higher // priority than the GUI) @@ -242,7 +240,7 @@ void CClient::run() } - // runtime phase ------------------------------------------------------------ + // runtime phase ----------------------------------------------------------- // enable channel Channel.SetEnable ( true ); @@ -261,21 +259,17 @@ void CClient::run() PostWinMessage ( MS_SOUND_IN, MUL_COL_LED_GREEN ); } - // copy data from one stereo buffer in two separate buffers - iInCnt = 0; - for ( i = 0; i < iSndCrdBlockSizeSam; i++ ) + // convert data from short to double + for ( i = 0; i < iSndCrdStereoBlockSizeSam; i++ ) { - vecdAudioSndCrdL[i] = (double) vecsAudioSndCrd[iInCnt++]; - vecdAudioSndCrdR[i] = (double) vecsAudioSndCrd[iInCnt++]; + vecdAudioSndCrd[i] = (double) vecsAudioSndCrd[i]; } // resample data for each channel seaparately - ResampleObjDownL.Resample ( vecdAudioSndCrdL, vecdAudioL ); - ResampleObjDownR.Resample ( vecdAudioSndCrdR, vecdAudioR ); + ResampleObjDown.Resample ( vecdAudioSndCrd, vecdAudio ); - // update signal level meters - SignalLevelMeterL.Update ( vecdAudioL ); - SignalLevelMeterR.Update ( vecdAudioR ); + // update stereo signal level meter + SignalLevelMeter.Update ( vecdAudio ); // add reverberation effect if activated if ( iReverbLevel != 0 ) @@ -285,44 +279,47 @@ void CClient::run() if ( bReverbOnLeftChan ) { - for ( i = 0; i < iBlockSizeSam; i++ ) + for ( i = 0; i < iStereoBlockSizeSam; i += 2 ) { // left channel - vecdAudioL[i] += - dRevLev * AudioReverb.ProcessSample ( vecdAudioL[i] ); + vecdAudio[i] += + dRevLev * AudioReverb.ProcessSample ( vecdAudio[i] ); } } else { - for ( i = 0; i < iBlockSizeSam; i++ ) + for ( i = 1; i < iStereoBlockSizeSam; i += 2 ) { // right channel - vecdAudioR[i] += - dRevLev * AudioReverb.ProcessSample ( vecdAudioR[i] ); + vecdAudio[i] += + dRevLev * AudioReverb.ProcessSample ( vecdAudio[i] ); } } } // mix both signals depending on the fading setting - const int iMiddleOfFader = AUD_FADER_IN_MAX / 2; + const int iMiddleOfFader = AUD_FADER_IN_MAX / 2; const double dAttFact = (double) ( iMiddleOfFader - abs ( iMiddleOfFader - iAudioInFader ) ) / iMiddleOfFader; - for ( i = 0; i < iBlockSizeSam; i++ ) + if ( iAudioInFader > iMiddleOfFader ) { - double dMixedSignal; - - if ( iAudioInFader > iMiddleOfFader ) + for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 ) { - dMixedSignal = vecdAudioL[i] + dAttFact * vecdAudioR[i]; + // attenuation on right channel + vecsNetwork[i] = + Double2Short ( vecdAudio[j] + dAttFact * vecdAudio[j + 1] ); } - else + } + else + { + for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 ) { - dMixedSignal = vecdAudioR[i] + dAttFact * vecdAudioL[i]; + // attenuation on left channel + vecsNetwork[i] = + Double2Short ( vecdAudio[j + 1] + dAttFact * vecdAudio[j] ); } - - vecsNetwork[i] = Double2Short ( dMixedSignal ); } // send it through the network @@ -344,7 +341,7 @@ void CClient::run() // fid=fopen('v.dat','r');x=fread(fid,'int16');fclose(fid); static FILE* pFileDelay = fopen("v.dat", "wb"); short sData[2]; -for (i = 0; i < iBlockSizeSam; i++) +for (i = 0; i < iMonoBlockSizeSam; i++) { sData[0] = (short) vecdNetwData[i]; fwrite(&sData, size_t(2), size_t(1), pFileDelay); @@ -356,30 +353,24 @@ fflush(pFileDelay); if ( Channel.IsConnected() ) { // write mono input signal in both sound-card channels - for ( i = 0; i < iBlockSizeSam; i++ ) + for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 ) { - vecdAudioL[i] = vecdAudioR[i] = vecdNetwData[i]; + vecdAudio[j] = vecdAudio[j + 1] = vecdNetwData[i]; } } else { // if not connected, clear data - for ( i = 0; i < iBlockSizeSam; i++ ) - { - vecdAudioL[i] = vecdAudioR[i] = 0.0; - } + vecdAudio.Reset ( 0.0 ); } - // resample data for each channel separately - ResampleObjUpL.Resample ( vecdAudioL, vecdAudioSndCrdL ); - ResampleObjUpR.Resample ( vecdAudioR, vecdAudioSndCrdR ); + // resample data + ResampleObjUp.Resample ( vecdAudio, vecdAudioSndCrd ); - // copy data from one stereo buffer in two separate buffers - iInCnt = 0; - for ( i = 0; i < iSndCrdBlockSizeSam; i++ ) + // convert data from double to short type + for ( i = 0; i < iSndCrdStereoBlockSizeSam; i++ ) { - vecsAudioSndCrd[iInCnt++] = Double2Short ( vecdAudioSndCrdL[i] ); - vecsAudioSndCrd[iInCnt++] = Double2Short ( vecdAudioSndCrdR[i] ); + vecsAudioSndCrd[i] = Double2Short ( vecdAudioSndCrd[i] ); } // play the new block @@ -404,8 +395,7 @@ fflush(pFileDelay); Sound.Close(); // reset current signal level and LEDs - SignalLevelMeterL.Reset(); - SignalLevelMeterR.Reset(); + SignalLevelMeter.Reset(); PostWinMessage ( MS_RESET_ALL, 0 ); } diff --git a/src/client.h b/src/client.h index 7153f3f6..f8ad6ed6 100755 --- a/src/client.h +++ b/src/client.h @@ -68,8 +68,8 @@ public: bool Stop(); bool IsRunning() { return bRun; } bool SetServerAddr ( QString strNAddr ); - double MicLevelL() { return SignalLevelMeterL.MicLevel(); } - double MicLevelR() { return SignalLevelMeterR.MicLevel(); } + double MicLevelL() { return SignalLevelMeter.MicLevelLeft(); } + double MicLevelR() { return SignalLevelMeter.MicLevelRight(); } bool IsConnected() { return Channel.IsConnected(); } /* We want to return the standard deviation. For that we need to calculate @@ -143,59 +143,54 @@ public: // settings - QString strIPAddress; - QString strName; + QString strIPAddress; + QString strName; protected: - virtual void run(); - void UpdateTimeResponseMeasurement(); - void UpdateSocketBufferSize(); + virtual void run(); + void UpdateTimeResponseMeasurement(); + void UpdateSocketBufferSize(); // only one channel is needed for client application - CChannel Channel; - bool bDoAutoSockBufSize; + CChannel Channel; + bool bDoAutoSockBufSize; - CSocket Socket; - CSound Sound; - CSignalLevelMeter SignalLevelMeterL; - CSignalLevelMeter SignalLevelMeterR; + CSocket Socket; + CSound Sound; + CStereoSignalLevelMeter SignalLevelMeter; - bool bRun; - CVector vecdNetwData; + bool bRun; + CVector vecdNetwData; - int iAudioInFader; - bool bReverbOnLeftChan; - int iReverbLevel; - CAudioReverb AudioReverb; + int iAudioInFader; + bool bReverbOnLeftChan; + int iReverbLevel; + CAudioReverb AudioReverb; - int iSndCrdBlockSizeSam; - int iBlockSizeSam; + int iSndCrdMonoBlockSizeSam; + int iSndCrdStereoBlockSizeSam; + int iMonoBlockSizeSam; + int iStereoBlockSizeSam; - int iNetwBufSizeFactIn; + int iNetwBufSizeFactIn; - bool bOpenChatOnNewMessage; + bool bOpenChatOnNewMessage; - CVector vecsAudioSndCrd; - CVector vecdAudioSndCrdL; - CVector vecdAudioSndCrdR; - - CVector vecdAudioL; - CVector vecdAudioR; - - CVector vecsNetwork; + CVector vecsAudioSndCrd; + CVector vecdAudioSndCrd; + CVector vecdAudio; + CVector vecsNetwork; // resample objects - CAudioResample ResampleObjDownL; // left channel - CAudioResample ResampleObjDownR; // right channel - CAudioResample ResampleObjUpL; // left channel - CAudioResample ResampleObjUpR; // right channel + CStereoAudioResample ResampleObjDown; + CStereoAudioResample ResampleObjUp; // for ping measurement and standard deviation of audio interface - CPreciseTime PreciseTime; + CPreciseTime PreciseTime; // debugging, evaluating - CMovingAv RespTimeMoAvBuf; - int TimeLastBlock; + CMovingAv RespTimeMoAvBuf; + int TimeLastBlock; public slots: void OnSendProtMessage ( CVector vecMessage ); diff --git a/src/global.h b/src/global.h index 5ed13fdf..da51a1ba 100755 --- a/src/global.h +++ b/src/global.h @@ -1,5 +1,5 @@ /******************************************************************************\ - * Copyright (c) 2004-2008 + * Copyright (c) 2004-2009 * * Author(s): * Volker Fischer @@ -92,10 +92,6 @@ // (just search for the tag in the entire code) #define MAX_NUM_CHANNELS 6 // max number channels for server -// sample rate offset estimation algorithm -// time interval for sample rate offset estimation -#define TIME_INT_SAM_OFFS_EST 60 // s - // length of the moving average buffer for response time measurement #define TIME_MOV_AV_RESPONSE 30 // seconds #define LEN_MOV_AV_RESPONSE ( TIME_MOV_AV_RESPONSE * 1000 / MIN_BLOCK_DURATION_MS ) diff --git a/src/resample.cpp b/src/resample.cpp index 950506a9..ee8b0be9 100755 --- a/src/resample.cpp +++ b/src/resample.cpp @@ -86,7 +86,7 @@ int CResample::Resample ( CVector& vecdInput, // convolution double dy1 = 0.0; double dy2 = 0.0; - for (int i = 0; i < NUM_TAPS_PER_PHASE1; i++) + for ( int i = 0; i < NUM_TAPS_PER_PHASE1; i++ ) { dy1 += fResTaps1[ip1 * INTERP_DECIM_I_D1 + i] * vecdIntBuff[in1 - i]; dy2 += fResTaps1[ip2 * INTERP_DECIM_I_D1 + i] * vecdIntBuff[in2 - i]; @@ -134,10 +134,10 @@ void CResample::Init ( const int iNewInputBlockSize ) /******************************************************************************\ -* Audio Resampler * +* Stereo Audio Resampler * \******************************************************************************/ -void CAudioResample::Resample ( CVector& vecdInput, - CVector& vecdOutput ) +void CStereoAudioResample::Resample ( CVector& vecdInput, + CVector& vecdOutput ) { int j; @@ -148,50 +148,58 @@ void CAudioResample::Resample ( CVector& vecdInput, } else { + const int iTwoTimesNumTaps = 2 * iNumTaps; + /* move old data from the end to the history part of the buffer and add new data (shift register) */ // shift old values - int iMovLen = iInputBlockSize; - for ( j = 0; j < iNumTaps; j++ ) + int iMovLen = iStereoInputBlockSize; + for ( j = 0; j < iTwoTimesNumTaps; j++ ) { vecdIntBuff[j] = vecdIntBuff[iMovLen++]; } // add new block of data - int iBlockEnd = iNumTaps; - for ( j = 0; j < iInputBlockSize; j++ ) + int iBlockEnd = iTwoTimesNumTaps; + for ( j = 0; j < iStereoInputBlockSize; j++ ) { vecdIntBuff[iBlockEnd++] = vecdInput[j]; } // main loop - for ( j = 0; j < iOutputBlockSize; j++ ) + for ( j = 0; j < iMonoOutputBlockSize; j++ ) { // calculate filter phase const int ip = (int) ( j * iI / dRation ) % iI; - // sample position in input vector - const int in = (int) ( j / dRation ) + iNumTaps - 1; + // sample position in stereo input vector + const int in = 2 * ( (int) ( j / dRation ) + iNumTaps - 1 ); // convolution - double dy = 0.0; + double dyL = 0.0; + double dyR = 0.0; for ( int i = 0; i < iNumTaps; i++ ) { - dy += pFiltTaps[ip + i * iI] * vecdIntBuff[in - i]; + const double dCurFiltTap = pFiltTaps[ip + i * iI]; + const int iCurSamplePos = in - 2 * i; + + dyL += dCurFiltTap * vecdIntBuff[iCurSamplePos]; + dyR += dCurFiltTap * vecdIntBuff[iCurSamplePos + 1]; } - vecdOutput[j] = dy; + vecdOutput[2 * j] = dyL; + vecdOutput[2 * j + 1] = dyR; } } } -void CAudioResample::Init ( const int iNewInputBlockSize, - const int iFrom, - const int iTo ) +void CStereoAudioResample::Init ( const int iNewMonoInputBlockSize, + const int iFrom, + const int iTo ) { - dRation = ( (double) iTo ) / iFrom; - iInputBlockSize = iNewInputBlockSize; - iOutputBlockSize = (int) ( iInputBlockSize * dRation ); + dRation = ( (double) iTo ) / iFrom; + iStereoInputBlockSize = 2 * iNewMonoInputBlockSize; + iMonoOutputBlockSize = (int) ( iNewMonoInputBlockSize * dRation ); // set correct parameters if ( iFrom == SND_CRD_SAMPLE_RATE ) // downsampling case @@ -205,22 +213,22 @@ void CAudioResample::Init ( const int iNewInputBlockSize, break; case ( SND_CRD_SAMPLE_RATE * 7 / 12 ): // 48 kHz to 28 kHz - pFiltTaps = fResTaps12_7; - iNumTaps = INTERP_I_12_7 * NUM_TAPS_PER_PHASE12_7; - iI = DECIM_D_12_7; + pFiltTaps = fResTaps12_7; + iNumTaps = INTERP_I_12_7 * NUM_TAPS_PER_PHASE12_7; + iI = DECIM_D_12_7; break; case ( SND_CRD_SAMPLE_RATE * 2 / 3 ): // 48 kHz to 32 kHz - pFiltTaps = fResTaps3_2; - iNumTaps = INTERP_I_3_2 * NUM_TAPS_PER_PHASE3_2; - iI = DECIM_D_3_2; + pFiltTaps = fResTaps3_2; + iNumTaps = INTERP_I_3_2 * NUM_TAPS_PER_PHASE3_2; + iI = DECIM_D_3_2; break; case SND_CRD_SAMPLE_RATE: // 48 kHz to 48 kHz // no resampling needed - pFiltTaps = NULL; - iNumTaps = 0; - iI = 1; + pFiltTaps = NULL; + iNumTaps = 0; + iI = 1; break; default: @@ -234,21 +242,21 @@ void CAudioResample::Init ( const int iNewInputBlockSize, switch ( iFrom ) { case ( SND_CRD_SAMPLE_RATE / 2 ): // 24 kHz to 48 kHz - pFiltTaps = fResTaps2; - iNumTaps = DECIM_D_2 * NUM_TAPS_PER_PHASE2; - iI = INTERP_I_2; + pFiltTaps = fResTaps2; + iNumTaps = DECIM_D_2 * NUM_TAPS_PER_PHASE2; + iI = INTERP_I_2; break; case ( SND_CRD_SAMPLE_RATE * 7 / 12 ): // 28 kHz to 48 kHz - pFiltTaps = fResTaps12_7; - iNumTaps = DECIM_D_12_7 * NUM_TAPS_PER_PHASE12_7; - iI = INTERP_I_12_7; + pFiltTaps = fResTaps12_7; + iNumTaps = DECIM_D_12_7 * NUM_TAPS_PER_PHASE12_7; + iI = INTERP_I_12_7; break; case ( SND_CRD_SAMPLE_RATE * 2 / 3 ): // 32 kHz to 48 kHz - pFiltTaps = fResTaps3_2; - iNumTaps = DECIM_D_3_2 * NUM_TAPS_PER_PHASE3_2; - iI = INTERP_I_3_2; + pFiltTaps = fResTaps3_2; + iNumTaps = DECIM_D_3_2 * NUM_TAPS_PER_PHASE3_2; + iI = INTERP_I_3_2; break; default: @@ -258,6 +266,8 @@ void CAudioResample::Init ( const int iNewInputBlockSize, } } - // allocate memory for internal buffer, clear sample history - vecdIntBuff.Init ( iInputBlockSize + iNumTaps, 0.0 ); + // allocate memory for internal buffer, clear sample history (we have + // to consider stereo data here -> two times the number of taps of + // additional memory is required) + vecdIntBuff.Init ( iStereoInputBlockSize + 2 * iNumTaps, 0.0 ); } diff --git a/src/resample.h b/src/resample.h index 50b68b14..8ae54c32 100755 --- a/src/resample.h +++ b/src/resample.h @@ -52,27 +52,27 @@ protected: int iInputBlockSize; }; -class CAudioResample +class CStereoAudioResample { public: - CAudioResample() {} - virtual ~CAudioResample() {} + CStereoAudioResample() {} + virtual ~CStereoAudioResample() {} - void Init ( const int iNewInputBlockSize, const int iFrom, const int iTo ); + void Init ( const int iNewMonoInputBlockSize, const int iFrom, const int iTo ); void Resample ( CVector& vecdInput, CVector& vecdOutput ); protected: - double dRation; + double dRation; - CVector vecdIntBuff; - int iHistorySize; + CVector vecdIntBuff; + int iHistorySize; - int iInputBlockSize; - int iOutputBlockSize; + int iStereoInputBlockSize; + int iMonoOutputBlockSize; - float* pFiltTaps; - int iNumTaps; - int iI; + float* pFiltTaps; + int iNumTaps; + int iI; }; diff --git a/src/util.cpp b/src/util.cpp index 4916157e..34bc6aae 100755 --- a/src/util.cpp +++ b/src/util.cpp @@ -27,10 +27,10 @@ /* Implementation *************************************************************/ // Input level meter implementation -------------------------------------------- -void CSignalLevelMeter::Update ( CVector& vecdAudio ) +void CStereoSignalLevelMeter::Update ( CVector& vecdAudio ) { - // get the vector size - const int iVecSize = vecdAudio.Size(); + // get the stereo vector size + const int iStereoVecSize = vecdAudio.Size(); // Get maximum of current block // @@ -43,15 +43,29 @@ void CSignalLevelMeter::Update ( CVector& vecdAudio ) // special cases but for the average music signals the following code // should give good results. // - double dMax = 0.0; - for ( int i = 0; i < iVecSize; i += 3 ) + double dMaxL = 0.0; + double dMaxR = 0.0; + for ( int i = 0; i < iStereoVecSize; i += 6 ) // 2 * 3 = 6 -> stereo { - if ( dMax < vecdAudio[i] ) + // left channel + if ( dMaxL < vecdAudio[i] ) { - dMax = vecdAudio[i]; + dMaxL = vecdAudio[i]; + } + + // right channel + if ( dMaxR < vecdAudio[i + 1] ) + { + dMaxR = vecdAudio[i + 1]; } } + dCurLevelL = UpdateCurLevel ( dCurLevelL, dMaxL ); + dCurLevelR = UpdateCurLevel ( dCurLevelR, dMaxR ); +} + +double CStereoSignalLevelMeter::UpdateCurLevel ( double dCurLevel, const double& dMax ) +{ // decrease max with time if ( dCurLevel >= METER_FLY_BACK ) { @@ -66,13 +80,17 @@ void CSignalLevelMeter::Update ( CVector& vecdAudio ) // update current level -> only use maximum if ( dMax > dCurLevel ) { - dCurLevel = dMax; + return dMax; + } + else + { + return dCurLevel; } } -double CSignalLevelMeter::MicLevel() +double CStereoSignalLevelMeter::CalcLogResult ( const double& dLinearLevel ) { - const double dNormMicLevel = dCurLevel / _MAXSHORT; + const double dNormMicLevel = dLinearLevel / _MAXSHORT; // logarithmic measure if ( dNormMicLevel > 0 ) diff --git a/src/util.h b/src/util.h index a4d88191..dcc320a9 100755 --- a/src/util.h +++ b/src/util.h @@ -356,19 +356,24 @@ public slots: /* Other Classes **************************************************************/ -// Signal Level Meter ---------------------------------------------------------- -class CSignalLevelMeter +// Stereo Signal Level Meter --------------------------------------------------- +class CStereoSignalLevelMeter { public: - CSignalLevelMeter() : dCurLevel ( 0.0 ) {} - virtual ~CSignalLevelMeter() {} + CStereoSignalLevelMeter() { Reset(); } + virtual ~CStereoSignalLevelMeter() {} - void Update ( CVector& vecdAudio ); - double MicLevel(); - void Reset() { dCurLevel = 0.0; } + void Update ( CVector& vecdAudio ); + double MicLevelLeft() { return CalcLogResult ( dCurLevelL ); } + double MicLevelRight() { return CalcLogResult ( dCurLevelR ); } + void Reset() { dCurLevelL = 0.0; dCurLevelR = 0.0; } protected: - double dCurLevel; + double CalcLogResult ( const double& dLinearLevel ); + double UpdateCurLevel ( double dCurLevel, const double& dMax ); + + double dCurLevelL; + double dCurLevelR; }; class CHostAddress @@ -409,7 +414,7 @@ class CAudioReverb public: CAudioReverb ( const double rT60 = (double) 5.0 ); - void Clear(); + void Clear(); double ProcessSample ( const double input ); protected: