diff options
author | peah <peah@webrtc.org> | 2015-12-09 11:07:20 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-09 19:07:27 +0000 |
commit | b14f00113ed054a94f406fb58348e2cedf098cc0 (patch) | |
tree | c1c9ea2d443efa74474b6718548dafad289b6948 /webrtc/modules/audio_processing | |
parent | 434aca8d862a46d0c3b71698a264d0c71d898170 (diff) | |
download | webrtc-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')
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); |