diff options
Diffstat (limited to 'voip/jni')
-rw-r--r-- | voip/jni/rtp/Android.mk | 3 | ||||
-rw-r--r-- | voip/jni/rtp/AudioGroup.cpp | 81 |
2 files changed, 66 insertions, 18 deletions
diff --git a/voip/jni/rtp/Android.mk b/voip/jni/rtp/Android.mk index 47ed658..0815294 100644 --- a/voip/jni/rtp/Android.mk +++ b/voip/jni/rtp/Android.mk @@ -49,7 +49,8 @@ LOCAL_C_INCLUDES += \ frameworks/base/media/libstagefright/codecs/amrnb/enc/include \ frameworks/base/media/libstagefright/codecs/amrnb/enc/src \ frameworks/base/media/libstagefright/codecs/amrnb/dec/include \ - frameworks/base/media/libstagefright/codecs/amrnb/dec/src + frameworks/base/media/libstagefright/codecs/amrnb/dec/src \ + system/media/audio_effects/include LOCAL_CFLAGS += -fvisibility=hidden diff --git a/voip/jni/rtp/AudioGroup.cpp b/voip/jni/rtp/AudioGroup.cpp index 85ed1c8..529b425 100644 --- a/voip/jni/rtp/AudioGroup.cpp +++ b/voip/jni/rtp/AudioGroup.cpp @@ -40,7 +40,8 @@ #include <media/AudioRecord.h> #include <media/AudioTrack.h> #include <media/mediarecorder.h> - +#include <media/AudioEffect.h> +#include <audio_effects/effect_aec.h> #include <system/audio.h> #include "jni.h" @@ -481,6 +482,7 @@ public: bool sendDtmf(int event); bool add(AudioStream *stream); bool remove(int socket); + bool platformHasAec() { return mPlatformHasAec; } private: enum { @@ -491,6 +493,8 @@ private: LAST_MODE = 3, }; + bool checkPlatformAec(); + AudioStream *mChain; int mEventQueue; volatile int mDtmfEvent; @@ -499,6 +503,7 @@ private: int mSampleRate; int mSampleCount; int mDeviceSocket; + bool mPlatformHasAec; class NetworkThread : public Thread { @@ -550,6 +555,7 @@ AudioGroup::AudioGroup() mDeviceSocket = -1; mNetworkThread = new NetworkThread(this); mDeviceThread = new DeviceThread(this); + mPlatformHasAec = checkPlatformAec(); } AudioGroup::~AudioGroup() @@ -630,10 +636,6 @@ bool AudioGroup::setMode(int mode) if (mode == NORMAL && !strcmp(value, "herring")) { mode = ECHO_SUPPRESSION; } - if (mode == ECHO_SUPPRESSION && AudioSystem::getParameters( - 0, String8("ec_supported")) == "ec_supported=yes") { - mode = NORMAL; - } if (mMode == mode) { return true; } @@ -759,6 +761,25 @@ bool AudioGroup::NetworkThread::threadLoop() return true; } +bool AudioGroup::checkPlatformAec() +{ + effect_descriptor_t fxDesc; + uint32_t numFx; + + if (AudioEffect::queryNumberEffects(&numFx) != NO_ERROR) { + return false; + } + for (uint32_t i = 0; i < numFx; i++) { + if (AudioEffect::queryEffect(i, &fxDesc) != NO_ERROR) { + continue; + } + if (memcmp(&fxDesc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) { + return true; + } + } + return false; +} + bool AudioGroup::DeviceThread::threadLoop() { int mode = mGroup->mMode; @@ -798,10 +819,6 @@ bool AudioGroup::DeviceThread::threadLoop() } LOGD("latency: output %d, input %d", track.latency(), record.latency()); - // Initialize echo canceler. - EchoSuppressor echo(sampleCount, - (track.latency() + record.latency()) * sampleRate / 1000); - // Give device socket a reasonable buffer size. setsockopt(deviceSocket, SOL_SOCKET, SO_RCVBUF, &output, sizeof(output)); setsockopt(deviceSocket, SOL_SOCKET, SO_SNDBUF, &output, sizeof(output)); @@ -810,6 +827,33 @@ bool AudioGroup::DeviceThread::threadLoop() char c; while (recv(deviceSocket, &c, 1, MSG_DONTWAIT) == 1); + // check if platform supports echo cancellation and do not active local echo suppression in + // this case + EchoSuppressor *echo = NULL; + AudioEffect *aec = NULL; + if (mode == ECHO_SUPPRESSION) { + if (mGroup->platformHasAec()) { + aec = new AudioEffect(FX_IID_AEC, + NULL, + 0, + 0, + 0, + record.getSessionId(), + record.getInput()); + status_t status = aec->initCheck(); + if (status == NO_ERROR || status == ALREADY_EXISTS) { + aec->setEnabled(true); + } else { + delete aec; + aec = NULL; + } + } + // Create local echo suppressor if platform AEC cannot be used. + if (aec == NULL) { + echo = new EchoSuppressor(sampleCount, + (track.latency() + record.latency()) * sampleRate / 1000); + } + } // Start AudioRecord before AudioTrack. This prevents AudioTrack from being // disabled due to buffer underrun while waiting for AudioRecord. if (mode != MUTED) { @@ -843,7 +887,7 @@ bool AudioGroup::DeviceThread::threadLoop() track.releaseBuffer(&buffer); } else if (status != TIMED_OUT && status != WOULD_BLOCK) { LOGE("cannot write to AudioTrack"); - return true; + goto exit; } } @@ -859,7 +903,7 @@ bool AudioGroup::DeviceThread::threadLoop() record.releaseBuffer(&buffer); } else if (status != TIMED_OUT && status != WOULD_BLOCK) { LOGE("cannot read from AudioRecord"); - return true; + goto exit; } } } @@ -870,15 +914,18 @@ bool AudioGroup::DeviceThread::threadLoop() } if (mode != MUTED) { - if (mode == NORMAL) { - send(deviceSocket, input, sizeof(input), MSG_DONTWAIT); - } else { - echo.run(output, input); - send(deviceSocket, input, sizeof(input), MSG_DONTWAIT); + if (echo != NULL) { + LOGV("echo->run()"); + echo->run(output, input); } + send(deviceSocket, input, sizeof(input), MSG_DONTWAIT); } } - return false; + +exit: + delete echo; + delete aec; + return true; } //------------------------------------------------------------------------------ |