Merge "Issue 3370834: No Echo canceler for SIP"
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user