diff --git a/sflphone-common/src/audio/echocancel.cpp b/sflphone-common/src/audio/echocancel.cpp index c3c2ae4d68c20efc4e3fe5b924ef778692986af5..1eeb7b96c8916b3d17153b5f5aa13b9fc9c5023c 100644 --- a/sflphone-common/src/audio/echocancel.cpp +++ b/sflphone-common/src/audio/echocancel.cpp @@ -87,7 +87,9 @@ EchoCancel::EchoCancel(int smplRate, int frameLength) : _samplingRate(smplRate), memset(_delayLineAmplify, 0, MAX_DELAY_LINE_AMPL*sizeof(float)); _amplDelayIndexIn = 0; - _amplDelayIndexOut = 0;; + _amplDelayIndexOut = 0; + + _correlationSize = _spkrAdaptSize; } @@ -300,8 +302,39 @@ void EchoCancel::updateEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrDat if(_spkrHistCnt >= _historyLength) _spkrHistCnt = 0; + // if adaptation done, stop here + if(_adaptDone) + return; + + // start learning only if there is data played through speaker + if(!_adaptStarted) { + if(spkrLvl > MIN_SIG_LEVEL) + _adaptStarted = true; + else + return; + } - + if(_spkrAdaptCnt < _spkrAdaptSize) + _spkrAdaptArray[_spkrAdaptCnt++] = spkrLvl; + + if(_micAdaptCnt < _micAdaptSize) + _micAdaptArray[_micAdaptCnt++] = micLvl; + + // perform correlation if spkr size is reached + if(_adaptCnt > _spkrAdaptSize) { + int k = _adaptCnt - _spkrAdaptSize; + _correlationArray[k] = performCorrelation(_spkrAdaptArray, _micAdaptArray+k, _correlationSize); + } + + _adaptCnt++; + + // if we captured a full echo + if(_adaptCnt == _micAdaptSize) { + _debug("EchoCancel: Echo path adaptation completed"); + _adaptDone = true; + _amplDelayIndexOut = getMaximumIndex(_correlationArray, _correlationSize); + } + } @@ -374,3 +407,31 @@ void EchoCancel::decreaseFactor() { if(_amplFactor < 0.0) _amplFactor = 0.0; } + + +int EchoCancel::performCorrelation(int *data1, int *data2, int size) { + + int correlation = 0; + while(size) { + size--; + correlation += data1[size] * data2[size]; + } + return correlation; +} + + +int EchoCancel::getMaximumIndex(int *data, int size) { + + int index = size; + int max = data[size-1]; + + while(size) { + size--; + if(data[size] > max) { + index = size; + max = data[size]; + } + } + + return index; +} diff --git a/sflphone-common/src/audio/echocancel.h b/sflphone-common/src/audio/echocancel.h index c559e6a6f6095bb9f7393af8be64109a3c4c91c3..204aab32622c13dec5922715bfdb22f342527f91 100644 --- a/sflphone-common/src/audio/echocancel.h +++ b/sflphone-common/src/audio/echocancel.h @@ -138,6 +138,10 @@ class EchoCancel : public Algorithm { */ void decreaseFactor(); + int performCorrelation(int *data1, int *data2, int size); + + int getMaximumIndex(int *data, int size); + /** * Internal buffer for mic data synchronization */