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}
This commit is contained in:
peah
2015-12-09 11:07:20 -08:00
committed by Commit bot
parent 434aca8d86
commit b14f00113e
4 changed files with 53 additions and 34 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);