aboutsummaryrefslogtreecommitdiff
path: root/webrtc/modules/audio_processing
diff options
context:
space:
mode:
authorpeah <peah@webrtc.org>2015-12-09 11:07:20 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-09 19:07:27 +0000
commitb14f00113ed054a94f406fb58348e2cedf098cc0 (patch)
treec1c9ea2d443efa74474b6718548dafad289b6948 /webrtc/modules/audio_processing
parent434aca8d862a46d0c3b71698a264d0c71d898170 (diff)
downloadwebrtc-b14f00113ed054a94f406fb58348e2cedf098cc0.tar.gz
Some minor (bitexact) AEC echo suppressor refactoring
-Moved filter reset from the echo suppression into the echo subtraction code where it belongs (the echo subtractor should own its filter reset). -Moved the selection between using the microphone sinal and the echo subtractor output down to the lowest level in the EchoSuppression function. This makes sense as that selection was very hidden in an unrelated sub-sub-function call and as the selection is critical for what the AEC outputs. The changes have been tested for bitexactness. BUG=webrtc:5201 Review URL: https://codereview.webrtc.org/1499573003 Cr-Commit-Position: refs/heads/master@{#10956}
Diffstat (limited to 'webrtc/modules/audio_processing')
-rw-r--r--webrtc/modules/audio_processing/aec/aec_core.c42
-rw-r--r--webrtc/modules/audio_processing/aec/aec_core_internal.h7
-rw-r--r--webrtc/modules/audio_processing/aec/aec_core_neon.c19
-rw-r--r--webrtc/modules/audio_processing/aec/aec_core_sse2.c19
4 files changed, 53 insertions, 34 deletions
diff --git a/webrtc/modules/audio_processing/aec/aec_core.c b/webrtc/modules/audio_processing/aec/aec_core.c
index cc8905fc57..41e9ba1cc2 100644
--- a/webrtc/modules/audio_processing/aec/aec_core.c
+++ b/webrtc/modules/audio_processing/aec/aec_core.c
@@ -327,12 +327,13 @@ const float WebRtcAec_kMinFarendPSD = 15;
// - sde : cross-PSD of near-end and residual echo
// - sxd : cross-PSD of near-end and far-end
//
-// In addition to updating the PSDs, also the filter diverge state is determined
-// upon actions are taken.
+// In addition to updating the PSDs, also the filter diverge state is
+// determined.
static void SmoothedPSD(AecCore* aec,
float efw[2][PART_LEN1],
float dfw[2][PART_LEN1],
- float xfw[2][PART_LEN1]) {
+ float xfw[2][PART_LEN1],
+ int* extreme_filter_divergence) {
// Power estimate smoothing coefficients.
const float* ptrGCoh = aec->extended_filter_enabled
? WebRtcAec_kExtendedSmoothingCoefficients[aec->mult - 1]
@@ -373,15 +374,12 @@ static void SmoothedPSD(AecCore* aec,
seSum += aec->se[i];
}
- // Divergent filter safeguard.
+ // Divergent filter safeguard update.
aec->divergeState = (aec->divergeState ? 1.05f : 1.0f) * seSum > sdSum;
- if (aec->divergeState)
- memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1);
-
- // Reset if error is significantly larger than nearend (13 dB).
- if (!aec->extended_filter_enabled && seSum > (19.95f * sdSum))
- memset(aec->wfBuf, 0, sizeof(aec->wfBuf));
+ // Signal extreme filter divergence if the error is significantly larger
+ // than the nearend (13 dB).
+ *extreme_filter_divergence = (seSum > (19.95f * sdSum));
}
// Window time domain data to be used by the fft.
@@ -414,10 +412,11 @@ static void SubbandCoherence(AecCore* aec,
float xfw[2][PART_LEN1],
float* fft,
float* cohde,
- float* cohxd) {
+ float* cohxd,
+ int* extreme_filter_divergence) {
int i;
- SmoothedPSD(aec, efw, dfw, xfw);
+ SmoothedPSD(aec, efw, dfw, xfw, extreme_filter_divergence);
// Subband coherence
for (i = 0; i < PART_LEN1; i++) {
@@ -945,6 +944,14 @@ static void EchoSubtraction(
int i;
memset(s_fft, 0, sizeof(s_fft));
+ // Conditionally reset the echo subtraction filter if the filter has diverged
+ // significantly.
+ if (!aec->extended_filter_enabled &&
+ aec->extreme_filter_divergence) {
+ memset(aec->wfBuf, 0, sizeof(aec->wfBuf));
+ aec->extreme_filter_divergence = 0;
+ }
+
// Produce echo estimate s_fft.
WebRtcAec_FilterFar(num_partitions,
x_fft_buf_block_pos,
@@ -1072,7 +1079,14 @@ static void EchoSuppression(AecCore* aec,
aec->xfwBuf + aec->delayIdx * PART_LEN1,
sizeof(xfw[0][0]) * 2 * PART_LEN1);
- WebRtcAec_SubbandCoherence(aec, efw, dfw, xfw, fft, cohde, cohxd);
+ WebRtcAec_SubbandCoherence(aec, efw, dfw, xfw, fft, cohde, cohxd,
+ &aec->extreme_filter_divergence);
+
+ // Select the microphone signal as output if the filter is deemed to have
+ // diverged.
+ if (aec->divergeState) {
+ memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1);
+ }
hNlXdAvg = 0;
for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) {
@@ -1740,6 +1754,8 @@ int WebRtcAec_InitAec(AecCore* aec, int sampFreq) {
aec->seed = 777;
aec->delayEstCtr = 0;
+ aec->extreme_filter_divergence = 0;
+
// Metrics disabled by default
aec->metricsMode = 0;
InitMetrics(aec);
diff --git a/webrtc/modules/audio_processing/aec/aec_core_internal.h b/webrtc/modules/audio_processing/aec/aec_core_internal.h
index 9ec65991ad..f8cb799ef4 100644
--- a/webrtc/modules/audio_processing/aec/aec_core_internal.h
+++ b/webrtc/modules/audio_processing/aec/aec_core_internal.h
@@ -152,6 +152,10 @@ struct AecCore {
// Runtime selection of number of filter partitions.
int num_partitions;
+ // Flag that extreme filter divergence has been detected by the Echo
+ // Suppressor.
+ int extreme_filter_divergence;
+
#ifdef WEBRTC_AEC_DEBUG_DUMP
// Sequence number of this AEC instance, so that different instances can
// choose different dump file names.
@@ -209,7 +213,8 @@ typedef void (*WebRtcAecSubBandCoherence)(AecCore* aec,
float xfw[2][PART_LEN1],
float* fft,
float* cohde,
- float* cohxd);
+ float* cohxd,
+ int* extreme_filter_divergence);
extern WebRtcAecSubBandCoherence WebRtcAec_SubbandCoherence;
typedef int (*WebRtcAecPartitionDelay)(const AecCore* aec);
diff --git a/webrtc/modules/audio_processing/aec/aec_core_neon.c b/webrtc/modules/audio_processing/aec/aec_core_neon.c
index 84f2d290b1..7898ab2543 100644
--- a/webrtc/modules/audio_processing/aec/aec_core_neon.c
+++ b/webrtc/modules/audio_processing/aec/aec_core_neon.c
@@ -510,7 +510,8 @@ static int PartitionDelayNEON(const AecCore* aec) {
static void SmoothedPSD(AecCore* aec,
float efw[2][PART_LEN1],
float dfw[2][PART_LEN1],
- float xfw[2][PART_LEN1]) {
+ float xfw[2][PART_LEN1],
+ int* extreme_filter_divergence) {
// Power estimate smoothing coefficients.
const float* ptrGCoh = aec->extended_filter_enabled
? WebRtcAec_kExtendedSmoothingCoefficients[aec->mult - 1]
@@ -626,15 +627,12 @@ static void SmoothedPSD(AecCore* aec,
seSum += aec->se[i];
}
- // Divergent filter safeguard.
+ // Divergent filter safeguard update.
aec->divergeState = (aec->divergeState ? 1.05f : 1.0f) * seSum > sdSum;
- if (aec->divergeState)
- memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1);
-
- // Reset if error is significantly larger than nearend (13 dB).
- if (!aec->extended_filter_enabled && seSum > (19.95f * sdSum))
- memset(aec->wfBuf, 0, sizeof(aec->wfBuf));
+ // Signal extreme filter divergence if the error is significantly larger
+ // than the nearend (13 dB).
+ *extreme_filter_divergence = (seSum > (19.95f * sdSum));
}
// Window time domain data to be used by the fft.
@@ -680,10 +678,11 @@ static void SubbandCoherenceNEON(AecCore* aec,
float xfw[2][PART_LEN1],
float* fft,
float* cohde,
- float* cohxd) {
+ float* cohxd,
+ int* extreme_filter_divergence) {
int i;
- SmoothedPSD(aec, efw, dfw, xfw);
+ SmoothedPSD(aec, efw, dfw, xfw, extreme_filter_divergence);
{
const float32x4_t vec_1eminus10 = vdupq_n_f32(1e-10f);
diff --git a/webrtc/modules/audio_processing/aec/aec_core_sse2.c b/webrtc/modules/audio_processing/aec/aec_core_sse2.c
index 8134917787..f897a4c0c7 100644
--- a/webrtc/modules/audio_processing/aec/aec_core_sse2.c
+++ b/webrtc/modules/audio_processing/aec/aec_core_sse2.c
@@ -489,7 +489,8 @@ static int PartitionDelaySSE2(const AecCore* aec) {
static void SmoothedPSD(AecCore* aec,
float efw[2][PART_LEN1],
float dfw[2][PART_LEN1],
- float xfw[2][PART_LEN1]) {
+ float xfw[2][PART_LEN1],
+ int* extreme_filter_divergence) {
// Power estimate smoothing coefficients.
const float* ptrGCoh = aec->extended_filter_enabled
? WebRtcAec_kExtendedSmoothingCoefficients[aec->mult - 1]
@@ -608,15 +609,12 @@ static void SmoothedPSD(AecCore* aec,
seSum += aec->se[i];
}
- // Divergent filter safeguard.
+ // Divergent filter safeguard update.
aec->divergeState = (aec->divergeState ? 1.05f : 1.0f) * seSum > sdSum;
- if (aec->divergeState)
- memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1);
-
- // Reset if error is significantly larger than nearend (13 dB).
- if (!aec->extended_filter_enabled && seSum > (19.95f * sdSum))
- memset(aec->wfBuf, 0, sizeof(aec->wfBuf));
+ // Signal extreme filter divergence if the error is significantly larger
+ // than the nearend (13 dB).
+ *extreme_filter_divergence = (seSum > (19.95f * sdSum));
}
// Window time domain data to be used by the fft.
@@ -666,10 +664,11 @@ static void SubbandCoherenceSSE2(AecCore* aec,
float xfw[2][PART_LEN1],
float* fft,
float* cohde,
- float* cohxd) {
+ float* cohxd,
+ int* extreme_filter_divergence) {
int i;
- SmoothedPSD(aec, efw, dfw, xfw);
+ SmoothedPSD(aec, efw, dfw, xfw, extreme_filter_divergence);
{
const __m128 vec_1eminus10 = _mm_set1_ps(1e-10f);