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),
_spkrHistCnt(0),
_micHistCnt(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");
......@@ -48,6 +58,7 @@ EchoCancel::EchoCancel(int smplRate, int frameLength) : _samplingRate(smplRate),
_micData->createReadPointer();
_spkrData->createReadPointer();
// variable used to sync mic and spkr
_spkrStoped = true;
_smplPerFrame = (_samplingRate * _frameLength) / MS_PER_SEC;
......@@ -55,6 +66,7 @@ EchoCancel::EchoCancel(int smplRate, int frameLength) : _samplingRate(smplRate),
_historyLength = ECHO_LENGTH / SEGMENT_LENGTH;
_nbSegmentPerFrame = _frameLength / SEGMENT_LENGTH;
_noiseState = speex_preprocess_state_init(_smplPerFrame, _samplingRate);
int i=1;
speex_preprocess_ctl(_noiseState, SPEEX_PREPROCESS_SET_DENOISE, &i);
......@@ -72,10 +84,10 @@ EchoCancel::EchoCancel(int smplRate, int frameLength) : _samplingRate(smplRate),
memset(_avgSpkrLevelHist, 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;
_amplIndexOut = DELAY_AMPLIFY / SEGMENT_LENGTH;
_amplDelayIndexIn = 0;
_amplDelayIndexOut = 0;;
}
......@@ -122,10 +134,10 @@ void EchoCancel::reset()
_historyLength = ECHO_LENGTH / SEGMENT_LENGTH;
_nbSegmentPerFrame = _frameLength / SEGMENT_LENGTH;
memset(_delayedAmplify, 0, MAX_DELAY*sizeof(float));
memset(_delayLineAmplify, 0, MAX_DELAY_LINE_AMPL*sizeof(float));
_amplIndexIn = 0;
_amplIndexOut = DELAY_AMPLIFY / SEGMENT_LENGTH;
_amplDelayIndexIn = 0;
_amplDelayIndexOut = DELAY_AMPLIFY / SEGMENT_LENGTH;
_micData->flushAll();
_spkrData->flushAll();
......@@ -146,12 +158,6 @@ void EchoCancel::reset()
f=.0;
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;
}
......@@ -169,11 +175,6 @@ void EchoCancel::putData(SFLDataFormat *inputData, int nbBytes)
// Put data in speaker ring buffer
_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) {}
......@@ -199,23 +200,16 @@ int EchoCancel::process(SFLDataFormat *inputData, SFLDataFormat *outputData, int
int spkrAvail = _spkrData->AvailForGet();
int micAvail = _micData->AvailForGet();
// std::cout << "Process echo: spkrAvail " << spkrAvail << ", micAvail " << micAvail << ", byteSize " << byteSize << std::endl;
// Init number of frame processed
int nbFrame = 0;
// Get data from mic and speaker internal buffer
while((spkrAvail >= byteSize) && (micAvail >= byteSize)) {
// std::cout << "perform echocancel" << std::endl;
// get synchronized data
_spkrData->Get(_tmpSpkr, byteSize);
_micData->Get(_tmpMic, byteSize);
// micFile->write ((const char *)_tmpMic, byteSize);
// spkrFile->write ((const char *)_tmpSpkr, byteSize);
// Processed echo cancellation
performEchoCancel(_tmpMic, _tmpSpkr, _tmpOut);
......@@ -229,8 +223,6 @@ int EchoCancel::process(SFLDataFormat *inputData, SFLDataFormat *outputData, int
spkrAvail = _spkrData->AvailForGet();
micAvail = _micData->AvailForGet();
// std::cout << "Process echo remaining: spkrAvail " << spkrAvail << ", micAvail " << micAvail << std::endl;
// increment nb of frame processed
++nbFrame;
}
......@@ -247,13 +239,6 @@ void EchoCancel::setSamplingRate(int smplRate) {
if (smplRate != _samplingRate) {
_samplingRate = smplRate;
/*
if(smplRate == 16000)
_frameLength = 10;
else
_frameLength = 20;
*/
reset();
}
}
......@@ -293,8 +278,6 @@ void EchoCancel::performEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrDa
_lastAmplFactor = _amplFactor;
// std::cout << "Amplitude: " << amplify << ", spkrLevel: " << _spkrLevel << ", micLevel: " << _micLevel << std::endl;
amplifySignal(micData+(k*_smplPerSeg), outputData+(k*_smplPerSeg), amplify);
}
......@@ -317,6 +300,8 @@ void EchoCancel::updateEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrDat
if(_spkrHistCnt >= _historyLength)
_spkrHistCnt = 0;
}
......@@ -355,17 +340,17 @@ void EchoCancel::amplifySignal(SFLDataFormat *micData, SFLDataFormat *outputData
// Use delayed amplification factor due to sound card latency
for(int i = 0; i < _smplPerSeg; i++) {
outputData[i] = (SFLDataFormat)(((float)micData[i])*_delayedAmplify[_amplIndexOut]);
outputData[i] = (SFLDataFormat)(((float)micData[i])*_delayLineAmplify[_amplDelayIndexOut]);
}
_amplIndexOut++;
_delayedAmplify[_amplIndexIn++] = amplify;
_amplDelayIndexOut++;
_delayLineAmplify[_amplDelayIndexIn++] = amplify;
if(_amplIndexOut >= MAX_DELAY)
_amplIndexOut = 0;
if(_amplDelayIndexOut >= MAX_DELAY_LINE_AMPL)
_amplDelayIndexOut = 0;
if(_amplIndexIn >= MAX_DELAY)
_amplIndexIn = 0;
if(_amplDelayIndexIn >= MAX_DELAY_LINE_AMPL)
_amplDelayIndexIn = 0;
}
......
......@@ -41,7 +41,7 @@
#define DELAY_AMPLIFY 60
// maximum in segment size (segment are SEGMENT_LENGTH long)
#define MAX_DELAY 10
#define MAX_DELAY_LINE_AMPL 100
// Internal buffer size
#define BUFF_SIZE 10000
......@@ -50,6 +50,9 @@
#define DEFAULT_FRAME_LENGTH 20
#define MIC_ADAPT_SIZE 100
#define SPKR_ADAPT_SIZE 50
class EchoCancel : public Algorithm {
public:
......@@ -228,13 +231,44 @@ class EchoCancel : public Algorithm {
/**
* 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
*/
int _amplIndexIn;
int _amplIndexOut;
int _amplDelayIndexIn;
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;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment