RTP: integrate the echo canceller from speex.
Currently the filter_length is set to one second.
Will change that when we have a better idea.
Change-Id: Ia942a8fff00b096de8ff0049a448816ea9a68068
diff --git a/voip/jni/rtp/Android.mk b/voip/jni/rtp/Android.mk
index a364355..3bd85aa 100644
--- a/voip/jni/rtp/Android.mk
+++ b/voip/jni/rtp/Android.mk
@@ -32,10 +32,11 @@
libutils \
libmedia
-LOCAL_STATIC_LIBRARIES :=
+LOCAL_STATIC_LIBRARIES := libspeex
LOCAL_C_INCLUDES += \
- $(JNI_H_INCLUDE)
+ $(JNI_H_INCLUDE) \
+ external/speex/include
LOCAL_CFLAGS += -fvisibility=hidden
diff --git a/voip/jni/rtp/AudioGroup.cpp b/voip/jni/rtp/AudioGroup.cpp
index bb45a9a..b5a4e22 100644
--- a/voip/jni/rtp/AudioGroup.cpp
+++ b/voip/jni/rtp/AudioGroup.cpp
@@ -40,6 +40,8 @@
#include <media/AudioTrack.h>
#include <media/mediarecorder.h>
+#include <speex/speex_echo.h>
+
#include "jni.h"
#include "JNIHelp.h"
@@ -445,6 +447,8 @@
int mDeviceSocket;
AudioTrack mTrack;
AudioRecord mRecord;
+
+ SpeexEchoState *mEchoState;
bool networkLoop();
bool deviceLoop();
@@ -506,6 +510,7 @@
mEventQueue = -1;
mDtmfEvent = -1;
mDeviceSocket = -1;
+ mEchoState = NULL;
mNetworkThread = new NetworkThread(this);
mDeviceThread = new DeviceThread(this);
}
@@ -518,6 +523,9 @@
mRecord.stop();
close(mEventQueue);
close(mDeviceSocket);
+ if (mEchoState) {
+ speex_echo_state_destroy(mEchoState);
+ }
while (mChain) {
AudioStream *next = mChain->mNext;
delete mChain;
@@ -566,7 +574,8 @@
}
LOGD("latency: output %d, input %d", mTrack.latency(), mRecord.latency());
- // TODO: initialize echo canceler here.
+ // Initialize echo canceller.
+ mEchoState = speex_echo_state_init(sampleCount, sampleRate);
// Create device socket.
int pair[2];
@@ -633,6 +642,7 @@
if (mode == MUTED) {
mRecord.stop();
} else {
+ speex_echo_state_reset(mEchoState);
mRecord.start();
}
@@ -793,7 +803,7 @@
status_t status = mRecord.obtainBuffer(&buffer, 1);
if (status == NO_ERROR) {
- int count = (buffer.frameCount < toRead) ?
+ int count = ((int)buffer.frameCount < toRead) ?
buffer.frameCount : toRead;
memcpy(&input[mSampleCount - toRead], buffer.i8, count * 2);
toRead -= count;
@@ -817,8 +827,9 @@
if (mMode == NORMAL) {
send(mDeviceSocket, input, sizeof(input), MSG_DONTWAIT);
} else {
- // TODO: Echo canceller runs here.
- send(mDeviceSocket, input, sizeof(input), MSG_DONTWAIT);
+ int16_t result[mSampleCount];
+ speex_echo_cancellation(mEchoState, input, output, result);
+ send(mDeviceSocket, result, sizeof(result), MSG_DONTWAIT);
}
}
return true;