Skip to content
Snippets Groups Projects
Commit 945a0391 authored by Alexandre Savard's avatar Alexandre Savard
Browse files

[#1966] Add echo canceller adaptation variables and buffers

parent 69e13254
No related branches found
No related tags found
No related merge requests found
...@@ -32,7 +32,17 @@ EchoCancel::EchoCancel(int smplRate, int frameLength) : _samplingRate(smplRate), ...@@ -32,7 +32,17 @@ EchoCancel::EchoCancel(int smplRate, int frameLength) : _samplingRate(smplRate),
_spkrHistCnt(0), _spkrHistCnt(0),
_micHistCnt(0), _micHistCnt(0),
_amplFactor(0.0), _amplFactor(0.0),
_lastAmplFactor(0.0) _lastAmplFactor(0.0),
_amplDelayIndexIn(0),
_amplDelayIndexOut(0),
_adaptDone(false),
_adaptStarted(false),
_adaptCnt(0),
_spkrAdaptCnt(0),
_micAdaptCnt(0),
_spkrAdaptSize(SPKR_ADAPT_SIZE),
_micAdaptSize(MIC_ADAPT_SIZE),
_correlationSize(0)
{ {
_debug("EchoCancel: Instantiate echo canceller"); _debug("EchoCancel: Instantiate echo canceller");
...@@ -48,6 +58,7 @@ EchoCancel::EchoCancel(int smplRate, int frameLength) : _samplingRate(smplRate), ...@@ -48,6 +58,7 @@ EchoCancel::EchoCancel(int smplRate, int frameLength) : _samplingRate(smplRate),
_micData->createReadPointer(); _micData->createReadPointer();
_spkrData->createReadPointer(); _spkrData->createReadPointer();
// variable used to sync mic and spkr
_spkrStoped = true; _spkrStoped = true;
_smplPerFrame = (_samplingRate * _frameLength) / MS_PER_SEC; _smplPerFrame = (_samplingRate * _frameLength) / MS_PER_SEC;
...@@ -55,6 +66,7 @@ EchoCancel::EchoCancel(int smplRate, int frameLength) : _samplingRate(smplRate), ...@@ -55,6 +66,7 @@ EchoCancel::EchoCancel(int smplRate, int frameLength) : _samplingRate(smplRate),
_historyLength = ECHO_LENGTH / SEGMENT_LENGTH; _historyLength = ECHO_LENGTH / SEGMENT_LENGTH;
_nbSegmentPerFrame = _frameLength / SEGMENT_LENGTH; _nbSegmentPerFrame = _frameLength / SEGMENT_LENGTH;
_noiseState = speex_preprocess_state_init(_smplPerFrame, _samplingRate); _noiseState = speex_preprocess_state_init(_smplPerFrame, _samplingRate);
int i=1; int i=1;
speex_preprocess_ctl(_noiseState, SPEEX_PREPROCESS_SET_DENOISE, &i); speex_preprocess_ctl(_noiseState, SPEEX_PREPROCESS_SET_DENOISE, &i);
...@@ -72,10 +84,10 @@ EchoCancel::EchoCancel(int smplRate, int frameLength) : _samplingRate(smplRate), ...@@ -72,10 +84,10 @@ EchoCancel::EchoCancel(int smplRate, int frameLength) : _samplingRate(smplRate),
memset(_avgSpkrLevelHist, 0, BUFF_SIZE*sizeof(int)); memset(_avgSpkrLevelHist, 0, BUFF_SIZE*sizeof(int));
memset(_avgMicLevelHist, 0, BUFF_SIZE*sizeof(int)); memset(_avgMicLevelHist, 0, BUFF_SIZE*sizeof(int));
memset(_delayedAmplify, 0, MAX_DELAY*sizeof(float)); memset(_delayLineAmplify, 0, MAX_DELAY_LINE_AMPL*sizeof(float));
_amplIndexIn = 0; _amplDelayIndexIn = 0;
_amplIndexOut = DELAY_AMPLIFY / SEGMENT_LENGTH; _amplDelayIndexOut = 0;;
} }
...@@ -122,10 +134,10 @@ void EchoCancel::reset() ...@@ -122,10 +134,10 @@ void EchoCancel::reset()
_historyLength = ECHO_LENGTH / SEGMENT_LENGTH; _historyLength = ECHO_LENGTH / SEGMENT_LENGTH;
_nbSegmentPerFrame = _frameLength / SEGMENT_LENGTH; _nbSegmentPerFrame = _frameLength / SEGMENT_LENGTH;
memset(_delayedAmplify, 0, MAX_DELAY*sizeof(float)); memset(_delayLineAmplify, 0, MAX_DELAY_LINE_AMPL*sizeof(float));
_amplIndexIn = 0; _amplDelayIndexIn = 0;
_amplIndexOut = DELAY_AMPLIFY / SEGMENT_LENGTH; _amplDelayIndexOut = DELAY_AMPLIFY / SEGMENT_LENGTH;
_micData->flushAll(); _micData->flushAll();
_spkrData->flushAll(); _spkrData->flushAll();
...@@ -146,12 +158,6 @@ void EchoCancel::reset() ...@@ -146,12 +158,6 @@ void EchoCancel::reset()
f=.0; f=.0;
speex_preprocess_ctl(_noiseState, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f); speex_preprocess_ctl(_noiseState, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);
/*
std::cout << "EchoCancel: _smplPerFrame " << _smplPerFrame
<< ", _smplPerSeg " << _smplPerSeg
<< ", _historyLength " << _historyLength
<< ", _nbSegmentPerFrame " << _nbSegmentPerFrame << std::endl;
*/
_spkrStoped = true; _spkrStoped = true;
} }
...@@ -169,11 +175,6 @@ void EchoCancel::putData(SFLDataFormat *inputData, int nbBytes) ...@@ -169,11 +175,6 @@ void EchoCancel::putData(SFLDataFormat *inputData, int nbBytes)
// Put data in speaker ring buffer // Put data in speaker ring buffer
_spkrData->Put(inputData, nbBytes); _spkrData->Put(inputData, nbBytes);
// std::cout << "EchoCancel: spkrDataAvail " << _spkrData->AvailForGet() << std::endl;
// In case we use libspeex internal buffer
// (require capture and playback stream to be synchronized)
// speex_echo_playback(_echoState, inputData);
} }
void EchoCancel::process(SFLDataFormat *data, int nbBytes) {} void EchoCancel::process(SFLDataFormat *data, int nbBytes) {}
...@@ -199,23 +200,16 @@ int EchoCancel::process(SFLDataFormat *inputData, SFLDataFormat *outputData, int ...@@ -199,23 +200,16 @@ int EchoCancel::process(SFLDataFormat *inputData, SFLDataFormat *outputData, int
int spkrAvail = _spkrData->AvailForGet(); int spkrAvail = _spkrData->AvailForGet();
int micAvail = _micData->AvailForGet(); int micAvail = _micData->AvailForGet();
// std::cout << "Process echo: spkrAvail " << spkrAvail << ", micAvail " << micAvail << ", byteSize " << byteSize << std::endl;
// Init number of frame processed // Init number of frame processed
int nbFrame = 0; int nbFrame = 0;
// Get data from mic and speaker internal buffer // Get data from mic and speaker internal buffer
while((spkrAvail >= byteSize) && (micAvail >= byteSize)) { while((spkrAvail >= byteSize) && (micAvail >= byteSize)) {
// std::cout << "perform echocancel" << std::endl;
// get synchronized data // get synchronized data
_spkrData->Get(_tmpSpkr, byteSize); _spkrData->Get(_tmpSpkr, byteSize);
_micData->Get(_tmpMic, byteSize); _micData->Get(_tmpMic, byteSize);
// micFile->write ((const char *)_tmpMic, byteSize);
// spkrFile->write ((const char *)_tmpSpkr, byteSize);
// Processed echo cancellation // Processed echo cancellation
performEchoCancel(_tmpMic, _tmpSpkr, _tmpOut); performEchoCancel(_tmpMic, _tmpSpkr, _tmpOut);
...@@ -229,8 +223,6 @@ int EchoCancel::process(SFLDataFormat *inputData, SFLDataFormat *outputData, int ...@@ -229,8 +223,6 @@ int EchoCancel::process(SFLDataFormat *inputData, SFLDataFormat *outputData, int
spkrAvail = _spkrData->AvailForGet(); spkrAvail = _spkrData->AvailForGet();
micAvail = _micData->AvailForGet(); micAvail = _micData->AvailForGet();
// std::cout << "Process echo remaining: spkrAvail " << spkrAvail << ", micAvail " << micAvail << std::endl;
// increment nb of frame processed // increment nb of frame processed
++nbFrame; ++nbFrame;
} }
...@@ -247,13 +239,6 @@ void EchoCancel::setSamplingRate(int smplRate) { ...@@ -247,13 +239,6 @@ void EchoCancel::setSamplingRate(int smplRate) {
if (smplRate != _samplingRate) { if (smplRate != _samplingRate) {
_samplingRate = smplRate; _samplingRate = smplRate;
/*
if(smplRate == 16000)
_frameLength = 10;
else
_frameLength = 20;
*/
reset(); reset();
} }
} }
...@@ -293,8 +278,6 @@ void EchoCancel::performEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrDa ...@@ -293,8 +278,6 @@ void EchoCancel::performEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrDa
_lastAmplFactor = _amplFactor; _lastAmplFactor = _amplFactor;
// std::cout << "Amplitude: " << amplify << ", spkrLevel: " << _spkrLevel << ", micLevel: " << _micLevel << std::endl;
amplifySignal(micData+(k*_smplPerSeg), outputData+(k*_smplPerSeg), amplify); amplifySignal(micData+(k*_smplPerSeg), outputData+(k*_smplPerSeg), amplify);
} }
...@@ -317,6 +300,8 @@ void EchoCancel::updateEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrDat ...@@ -317,6 +300,8 @@ void EchoCancel::updateEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrDat
if(_spkrHistCnt >= _historyLength) if(_spkrHistCnt >= _historyLength)
_spkrHistCnt = 0; _spkrHistCnt = 0;
} }
...@@ -355,17 +340,17 @@ void EchoCancel::amplifySignal(SFLDataFormat *micData, SFLDataFormat *outputData ...@@ -355,17 +340,17 @@ void EchoCancel::amplifySignal(SFLDataFormat *micData, SFLDataFormat *outputData
// Use delayed amplification factor due to sound card latency // Use delayed amplification factor due to sound card latency
for(int i = 0; i < _smplPerSeg; i++) { for(int i = 0; i < _smplPerSeg; i++) {
outputData[i] = (SFLDataFormat)(((float)micData[i])*_delayedAmplify[_amplIndexOut]); outputData[i] = (SFLDataFormat)(((float)micData[i])*_delayLineAmplify[_amplDelayIndexOut]);
} }
_amplIndexOut++; _amplDelayIndexOut++;
_delayedAmplify[_amplIndexIn++] = amplify; _delayLineAmplify[_amplDelayIndexIn++] = amplify;
if(_amplIndexOut >= MAX_DELAY) if(_amplDelayIndexOut >= MAX_DELAY_LINE_AMPL)
_amplIndexOut = 0; _amplDelayIndexOut = 0;
if(_amplIndexIn >= MAX_DELAY) if(_amplDelayIndexIn >= MAX_DELAY_LINE_AMPL)
_amplIndexIn = 0; _amplDelayIndexIn = 0;
} }
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
#define DELAY_AMPLIFY 60 #define DELAY_AMPLIFY 60
// maximum in segment size (segment are SEGMENT_LENGTH long) // maximum in segment size (segment are SEGMENT_LENGTH long)
#define MAX_DELAY 10 #define MAX_DELAY_LINE_AMPL 100
// Internal buffer size // Internal buffer size
#define BUFF_SIZE 10000 #define BUFF_SIZE 10000
...@@ -50,6 +50,9 @@ ...@@ -50,6 +50,9 @@
#define DEFAULT_FRAME_LENGTH 20 #define DEFAULT_FRAME_LENGTH 20
#define MIC_ADAPT_SIZE 100
#define SPKR_ADAPT_SIZE 50
class EchoCancel : public Algorithm { class EchoCancel : public Algorithm {
public: public:
...@@ -228,13 +231,44 @@ class EchoCancel : public Algorithm { ...@@ -228,13 +231,44 @@ class EchoCancel : public Algorithm {
/** /**
* Linear gain factor buffer to adjust to system's latency * Linear gain factor buffer to adjust to system's latency
*/ */
float _delayedAmplify[MAX_DELAY]; float _delayLineAmplify[MAX_DELAY_LINE_AMPL];
/** /**
* read/write for mic gain delay * read/write for mic gain delay
*/ */
int _amplIndexIn; int _amplDelayIndexIn;
int _amplIndexOut; int _amplDelayIndexOut;
/**
* State variable to determine if adaptation must be performed
*/
bool _adaptDone;
/**
* State variable to specify if adaptation is started
*/
bool _adaptStarted;
/**
* Adaptation index
*/
int _adaptCnt;
int _spkrAdaptCnt;
int _micAdaptCnt;
int _spkrAdaptSize;
int _micAdaptSize;
int _spkrAdaptArray[BUFF_SIZE];
int _micAdaptArray[BUFF_SIZE];
int _correlationSize;
int _correlationArray[BUFF_SIZE];
/* /*
ofstream *micFile; ofstream *micFile;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment