Index: webrtc/modules/audio_processing/aec/aec_core.cc |
diff --git a/webrtc/modules/audio_processing/aec/aec_core.cc b/webrtc/modules/audio_processing/aec/aec_core.cc |
index 5da8b136c16f05a42240dce9f944db95730069bd..2d3894078fc70e14841f9ce1f4ddb680475c99a1 100644 |
--- a/webrtc/modules/audio_processing/aec/aec_core.cc |
+++ b/webrtc/modules/audio_processing/aec/aec_core.cc |
@@ -404,53 +404,60 @@ const float WebRtcAec_kMinFarendPSD = 15; |
// |
// In addition to updating the PSDs, also the filter diverge state is |
// determined. |
-static void SmoothedPSD(AecCore* aec, |
+static void SmoothedPSD(int mult, |
+ bool extended_filter_enabled, |
float efw[2][PART_LEN1], |
float dfw[2][PART_LEN1], |
float xfw[2][PART_LEN1], |
+ CoherenceState* coherence_state, |
+ short* filter_divergence_state, |
int* extreme_filter_divergence) { |
// Power estimate smoothing coefficients. |
const float* ptrGCoh = |
- aec->extended_filter_enabled |
- ? WebRtcAec_kExtendedSmoothingCoefficients[aec->mult - 1] |
- : WebRtcAec_kNormalSmoothingCoefficients[aec->mult - 1]; |
+ extended_filter_enabled |
+ ? WebRtcAec_kExtendedSmoothingCoefficients[mult - 1] |
+ : WebRtcAec_kNormalSmoothingCoefficients[mult - 1]; |
int i; |
float sdSum = 0, seSum = 0; |
for (i = 0; i < PART_LEN1; i++) { |
- aec->sd[i] = ptrGCoh[0] * aec->sd[i] + |
- ptrGCoh[1] * (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]); |
- aec->se[i] = ptrGCoh[0] * aec->se[i] + |
- ptrGCoh[1] * (efw[0][i] * efw[0][i] + efw[1][i] * efw[1][i]); |
+ coherence_state->sd[i] = |
+ ptrGCoh[0] * coherence_state->sd[i] + |
+ ptrGCoh[1] * (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]); |
+ coherence_state->se[i] = |
+ ptrGCoh[0] * coherence_state->se[i] + |
+ ptrGCoh[1] * (efw[0][i] * efw[0][i] + efw[1][i] * efw[1][i]); |
// We threshold here to protect against the ill-effects of a zero farend. |
// The threshold is not arbitrarily chosen, but balances protection and |
// adverse interaction with the algorithm's tuning. |
// TODO(bjornv): investigate further why this is so sensitive. |
- aec->sx[i] = ptrGCoh[0] * aec->sx[i] + |
- ptrGCoh[1] * WEBRTC_SPL_MAX( |
- xfw[0][i] * xfw[0][i] + xfw[1][i] * xfw[1][i], |
- WebRtcAec_kMinFarendPSD); |
- |
- aec->sde[i][0] = |
- ptrGCoh[0] * aec->sde[i][0] + |
+ coherence_state->sx[i] = |
+ ptrGCoh[0] * coherence_state->sx[i] + |
+ ptrGCoh[1] * |
+ WEBRTC_SPL_MAX(xfw[0][i] * xfw[0][i] + xfw[1][i] * xfw[1][i], |
+ WebRtcAec_kMinFarendPSD); |
+ |
+ coherence_state->sde[i][0] = |
+ ptrGCoh[0] * coherence_state->sde[i][0] + |
ptrGCoh[1] * (dfw[0][i] * efw[0][i] + dfw[1][i] * efw[1][i]); |
- aec->sde[i][1] = |
- ptrGCoh[0] * aec->sde[i][1] + |
+ coherence_state->sde[i][1] = |
+ ptrGCoh[0] * coherence_state->sde[i][1] + |
ptrGCoh[1] * (dfw[0][i] * efw[1][i] - dfw[1][i] * efw[0][i]); |
- aec->sxd[i][0] = |
- ptrGCoh[0] * aec->sxd[i][0] + |
+ coherence_state->sxd[i][0] = |
+ ptrGCoh[0] * coherence_state->sxd[i][0] + |
ptrGCoh[1] * (dfw[0][i] * xfw[0][i] + dfw[1][i] * xfw[1][i]); |
- aec->sxd[i][1] = |
- ptrGCoh[0] * aec->sxd[i][1] + |
+ coherence_state->sxd[i][1] = |
+ ptrGCoh[0] * coherence_state->sxd[i][1] + |
ptrGCoh[1] * (dfw[0][i] * xfw[1][i] - dfw[1][i] * xfw[0][i]); |
- sdSum += aec->sd[i]; |
- seSum += aec->se[i]; |
+ sdSum += coherence_state->sd[i]; |
+ seSum += coherence_state->se[i]; |
} |
// Divergent filter safeguard update. |
- aec->divergeState = (aec->divergeState ? 1.05f : 1.0f) * seSum > sdSum; |
+ *filter_divergence_state = |
+ (*filter_divergence_state ? 1.05f : 1.0f) * seSum > sdSum; |
// Signal extreme filter divergence if the error is significantly larger |
// than the nearend (13 dB). |
@@ -481,26 +488,30 @@ __inline static void StoreAsComplex(const float* data, |
data_complex[1][PART_LEN] = 0; |
} |
-static void SubbandCoherence(AecCore* aec, |
+static void SubbandCoherence(int mult, |
+ bool extended_filter_enabled, |
float efw[2][PART_LEN1], |
float dfw[2][PART_LEN1], |
float xfw[2][PART_LEN1], |
float* fft, |
float* cohde, |
float* cohxd, |
+ CoherenceState* coherence_state, |
+ short* filter_divergence_state, |
int* extreme_filter_divergence) { |
int i; |
- SmoothedPSD(aec, efw, dfw, xfw, extreme_filter_divergence); |
+ SmoothedPSD(mult, extended_filter_enabled, efw, dfw, xfw, coherence_state, |
+ filter_divergence_state, extreme_filter_divergence); |
// Subband coherence |
for (i = 0; i < PART_LEN1; i++) { |
- cohde[i] = |
- (aec->sde[i][0] * aec->sde[i][0] + aec->sde[i][1] * aec->sde[i][1]) / |
- (aec->sd[i] * aec->se[i] + 1e-10f); |
- cohxd[i] = |
- (aec->sxd[i][0] * aec->sxd[i][0] + aec->sxd[i][1] * aec->sxd[i][1]) / |
- (aec->sx[i] * aec->sd[i] + 1e-10f); |
+ cohde[i] = (coherence_state->sde[i][0] * coherence_state->sde[i][0] + |
+ coherence_state->sde[i][1] * coherence_state->sde[i][1]) / |
+ (coherence_state->sd[i] * coherence_state->se[i] + 1e-10f); |
+ cohxd[i] = (coherence_state->sxd[i][0] * coherence_state->sxd[i][0] + |
+ coherence_state->sxd[i][1] * coherence_state->sxd[i][1]) / |
+ (coherence_state->sx[i] * coherence_state->sd[i] + 1e-10f); |
} |
} |
@@ -1050,7 +1061,9 @@ static void EchoSuppression(AecCore* aec, |
memcpy(xfw, 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->mult, aec->extended_filter_enabled == 1, efw, |
+ dfw, xfw, fft, cohde, cohxd, &aec->coherence_state, |
+ &aec->divergeState, |
&aec->extreme_filter_divergence); |
// Select the microphone signal as output if the filter is deemed to have |
@@ -1666,18 +1679,18 @@ int WebRtcAec_InitAec(AecCore* aec, int sampFreq) { |
// doesn't change the output at all and yields 0.4% overall speedup. |
memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); |
memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); |
- memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1); |
- memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1); |
+ memset(aec->coherence_state.sde, 0, sizeof(complex_t) * PART_LEN1); |
+ memset(aec->coherence_state.sxd, 0, sizeof(complex_t) * PART_LEN1); |
memset(aec->xfwBuf, 0, |
sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); |
- memset(aec->se, 0, sizeof(float) * PART_LEN1); |
+ memset(aec->coherence_state.se, 0, sizeof(float) * PART_LEN1); |
// To prevent numerical instability in the first block. |
for (i = 0; i < PART_LEN1; i++) { |
- aec->sd[i] = 1; |
+ aec->coherence_state.sd[i] = 1; |
} |
for (i = 0; i < PART_LEN1; i++) { |
- aec->sx[i] = 1; |
+ aec->coherence_state.sx[i] = 1; |
} |
memset(aec->hNs, 0, sizeof(aec->hNs)); |