Working on audio echo cancellation

This commit is contained in:
Philip Rosedale 2013-05-18 12:33:21 -07:00
parent c43847946c
commit d9cc07cf17
3 changed files with 31 additions and 21 deletions

View file

@ -1662,7 +1662,7 @@ void Application::displayOverlay() {
#ifndef _WIN32 #ifndef _WIN32
_audio.render(_glWidget->width(), _glWidget->height()); _audio.render(_glWidget->width(), _glWidget->height());
_audioScope.render(20, _glWidget->height() - 200); _audioScope.render(20, _glWidget->height() - 200);
//_audio.renderEchoCompare(); // PER: Will turn back on to further test echo _audio.renderEchoCompare(); // PER: Will turn back on to further test echo
#endif #endif
//noiseTest(_glWidget->width(), _glWidget->height()); //noiseTest(_glWidget->width(), _glWidget->height());

View file

@ -99,12 +99,21 @@ int audioCallback (const void* inputBuffer,
parentAudio->_scope->addSamples(2, outputRight, PACKET_LENGTH_SAMPLES_PER_CHANNEL); parentAudio->_scope->addSamples(2, outputRight, PACKET_LENGTH_SAMPLES_PER_CHANNEL);
// if needed, add input/output data to echo analysis buffers // if needed, add input/output data to echo analysis buffers
if (parentAudio->_isGatheringEchoFrames) { if (parentAudio->_echoInputFrameCountdown > 0) {
memcpy(parentAudio->_echoInputSamples, inputLeft, if (--parentAudio->_echoInputFrameCountdown == 0) {
memcpy(parentAudio->_echoInputSamples, inputLeft,
PACKET_LENGTH_SAMPLES_PER_CHANNEL * sizeof(int16_t)); PACKET_LENGTH_SAMPLES_PER_CHANNEL * sizeof(int16_t));
parentAudio->_echoInputFrameCountdown = 0;
printLog("got input\n");
}
}
if (parentAudio->_isGatheringEchoOutputFrames) {
memcpy(parentAudio->_echoOutputSamples, outputLeft, memcpy(parentAudio->_echoOutputSamples, outputLeft,
PACKET_LENGTH_SAMPLES_PER_CHANNEL * sizeof(int16_t)); PACKET_LENGTH_SAMPLES_PER_CHANNEL * sizeof(int16_t));
parentAudio->addedPingFrame(); parentAudio->_isGatheringEchoOutputFrames = false;
parentAudio->_echoInputFrameCountdown = 2;
printLog("got output\n");
} }
if (inputLeft != NULL) { if (inputLeft != NULL) {
@ -273,7 +282,10 @@ int audioCallback (const void* inputBuffer,
for (int s = 0; s < PACKET_LENGTH_SAMPLES_PER_CHANNEL; s++) { for (int s = 0; s < PACKET_LENGTH_SAMPLES_PER_CHANNEL; s++) {
outputLeft[s] = outputRight[s] = (int16_t)(sinf((float) s / PING_PITCH) * PING_VOLUME); outputLeft[s] = outputRight[s] = (int16_t)(sinf((float) s / PING_PITCH) * PING_VOLUME);
} }
parentAudio->_isGatheringEchoFrames = true; printLog("Send echo ping\n");
parentAudio->_isSendingEchoPing = false;
parentAudio->_isGatheringEchoOutputFrames = true;
} }
gettimeofday(&parentAudio->_lastCallbackTime, NULL); gettimeofday(&parentAudio->_lastCallbackTime, NULL);
return paContinue; return paContinue;
@ -293,6 +305,9 @@ Audio::Audio(Oscilloscope* scope) :
_scope(scope), _scope(scope),
_averagedLatency(0.0), _averagedLatency(0.0),
_measuredJitter(0), _measuredJitter(0),
_jitterBufferLengthMsecs(12.0),
_jitterBufferSamples(_jitterBufferLengthMsecs *
NUM_AUDIO_CHANNELS * (SAMPLE_RATE / 1000.0)),
_wasStarved(0), _wasStarved(0),
_lastInputLoudness(0), _lastInputLoudness(0),
_mixerLoopbackFlag(false), _mixerLoopbackFlag(false),
@ -303,8 +318,8 @@ Audio::Audio(Oscilloscope* scope) :
_packetsReceivedThisPlayback(0), _packetsReceivedThisPlayback(0),
_shouldStartEcho(false), _shouldStartEcho(false),
_isSendingEchoPing(false), _isSendingEchoPing(false),
_echoPingFrameCount(0), _echoInputFrameCountdown(0),
_isGatheringEchoFrames(false) _isGatheringEchoOutputFrames(false)
{ {
outputPortAudioError(Pa_Initialize()); outputPortAudioError(Pa_Initialize());
outputPortAudioError(Pa_OpenDefaultStream(&_stream, outputPortAudioError(Pa_OpenDefaultStream(&_stream,
@ -376,20 +391,11 @@ void Audio::addProceduralSounds(int16_t* inputBuffer, int numSamples) {
void Audio::startEchoTest() { void Audio::startEchoTest() {
_shouldStartEcho = true; _shouldStartEcho = true;
_echoPingFrameCount = 0;
_isSendingEchoPing = true; _isSendingEchoPing = true;
_isGatheringEchoFrames = false; _isGatheringEchoOutputFrames = false;
} }
void Audio::addedPingFrame() {
const int ECHO_PING_FRAMES = 1;
_echoPingFrameCount++;
if (_echoPingFrameCount == ECHO_PING_FRAMES) {
_isGatheringEchoFrames = false;
_isSendingEchoPing = false;
//startEchoTest();
}
}
void Audio::analyzeEcho(int16_t* inputBuffer, int16_t* outputBuffer, int numSamples) { void Audio::analyzeEcho(int16_t* inputBuffer, int16_t* outputBuffer, int numSamples) {
// Compare output and input streams, looking for evidence of correlation needing echo cancellation // Compare output and input streams, looking for evidence of correlation needing echo cancellation
// //

View file

@ -38,7 +38,6 @@ public:
void addReceivedAudioToBuffer(unsigned char* receivedData, int receivedBytes); void addReceivedAudioToBuffer(unsigned char* receivedData, int receivedBytes);
void startEchoTest(); void startEchoTest();
void addedPingFrame();
void renderEchoCompare(); void renderEchoCompare();
private: private:
@ -49,6 +48,8 @@ private:
timeval _lastReceiveTime; timeval _lastReceiveTime;
float _averagedLatency; float _averagedLatency;
float _measuredJitter; float _measuredJitter;
float _jitterBufferLengthMsecs;
short _jitterBufferSamples;
int _wasStarved; int _wasStarved;
float _lastInputLoudness; float _lastInputLoudness;
bool _mixerLoopbackFlag; bool _mixerLoopbackFlag;
@ -57,12 +58,15 @@ private:
int _totalPacketsReceived; int _totalPacketsReceived;
timeval _firstPlaybackTime; timeval _firstPlaybackTime;
int _packetsReceivedThisPlayback; int _packetsReceivedThisPlayback;
// Echo Analysis
bool _shouldStartEcho; bool _shouldStartEcho;
bool _isSendingEchoPing; bool _isSendingEchoPing;
int _echoPingFrameCount;
int16_t* _echoInputSamples; int16_t* _echoInputSamples;
int16_t* _echoOutputSamples; int16_t* _echoOutputSamples;
bool _isGatheringEchoFrames; int _echoInputFrameCountdown;
bool _isGatheringEchoOutputFrames;
// give access to AudioData class from audioCallback // give access to AudioData class from audioCallback
friend int audioCallback (const void*, void*, unsigned long, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void*); friend int audioCallback (const void*, void*, unsigned long, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void*);