Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(782)

Unified Diff: webrtc/modules/audio_processing/aec/aec_core.cc

Issue 1887003002: Added support in the AEC for refined filter adaptation. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Changes in response to reviewer comments. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 4b5abedd5aa7694172fe773438fcc0822dc08ee9..f13cf94c2bc1cbe66f0e0ec84a79ca2a10434661 100644
--- a/webrtc/modules/audio_processing/aec/aec_core.cc
+++ b/webrtc/modules/audio_processing/aec/aec_core.cc
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <string.h>
+#include "webrtc/base/checks.h"
extern "C" {
#include "webrtc/common_audio/ring_buffer.h"
}
@@ -238,15 +239,10 @@ static void FilterFar(int num_partitions,
}
}
-static void ScaleErrorSignal(int extended_filter_enabled,
- float normal_mu,
- float normal_error_threshold,
+static void ScaleErrorSignal(float mu,
+ float error_threshold,
float x_pow[PART_LEN1],
float ef[2][PART_LEN1]) {
- const float mu = extended_filter_enabled ? kExtendedMu : normal_mu;
- const float error_threshold = extended_filter_enabled
- ? kExtendedErrorThreshold
- : normal_error_threshold;
int i;
float abs_ef;
for (i = 0; i < (PART_LEN1); i++) {
@@ -936,11 +932,38 @@ static int SignalBasedDelayCorrection(AecCore* self) {
return delay_correction;
}
+static void RegressorPower(int num_partitions,
+ int latest_added_partition,
+ float x_fft_buf[2]
+ [kExtendedNumPartitions * PART_LEN1],
+ float x_pow[PART_LEN1]) {
+ RTC_DCHECK_LT(latest_added_partition, num_partitions);
+ memset(x_pow, 0, PART_LEN1 * sizeof(x_pow[0]));
+
+ int partition = latest_added_partition;
+ int x_fft_buf_position = partition * PART_LEN1;
+ for (int i = 0; i < num_partitions; ++i) {
+ for (int bin = 0; bin < PART_LEN1; ++bin) {
+ float re = x_fft_buf[0][x_fft_buf_position];
+ float im = x_fft_buf[1][x_fft_buf_position];
+ x_pow[bin] += re * re + im * im;
+ ++x_fft_buf_position;
+ }
+
+ ++partition;
+ if (partition == num_partitions) {
+ partition = 0;
+ RTC_DCHECK_EQ(num_partitions * PART_LEN1, x_fft_buf_position);
+ x_fft_buf_position = 0;
+ }
+ }
+}
+
static void EchoSubtraction(AecCore* aec,
int num_partitions,
int extended_filter_enabled,
- float normal_mu,
- float normal_error_threshold,
+ float filter_step_size,
+ float error_threshold,
float* x_fft,
int* x_fft_buf_block_pos,
float x_fft_buf[2]
@@ -1001,8 +1024,7 @@ static void EchoSubtraction(AecCore* aec,
sizeof(e_fft[0][0]) * PART_LEN1 * 2);
// Scale error signal inversely with far power.
- WebRtcAec_ScaleErrorSignal(extended_filter_enabled, normal_mu,
- normal_error_threshold, x_pow, e_fft);
+ WebRtcAec_ScaleErrorSignal(filter_step_size, error_threshold, x_pow, e_fft);
WebRtcAec_FilterAdaptation(num_partitions, *x_fft_buf_block_pos, x_fft_buf,
e_fft, h_fft_buf);
memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN);
@@ -1315,18 +1337,31 @@ static void ProcessBlock(AecCore* aec) {
memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2);
Fft(fft, df);
- // Power smoothing
- for (i = 0; i < PART_LEN1; i++) {
- far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) +
- (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]);
- aec->xPow[i] =
- gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum;
- // Calculate absolute spectra
- abs_far_spectrum[i] = sqrtf(far_spectrum);
+ // Power smoothing.
+ if (aec->refined_adaptive_filter_enabled) {
+ for (i = 0; i < PART_LEN1; ++i) {
+ far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) +
+ (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]);
+ // Calculate the magnitude spectrum.
+ abs_far_spectrum[i] = sqrtf(far_spectrum);
+ }
+ RegressorPower(aec->num_partitions, aec->xfBufBlockPos, aec->xfBuf,
+ aec->xPow);
+ } else {
+ for (i = 0; i < PART_LEN1; ++i) {
+ far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) +
+ (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]);
+ aec->xPow[i] =
+ gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum;
+ // Calculate the magnitude spectrum.
+ abs_far_spectrum[i] = sqrtf(far_spectrum);
+ }
+ }
+ for (i = 0; i < PART_LEN1; ++i) {
near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i];
aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum;
- // Calculate absolute spectra
+ // Calculate the magnitude spectrum.
abs_near_spectrum[i] = sqrtf(near_spectrum);
}
@@ -1379,7 +1414,7 @@ static void ProcessBlock(AecCore* aec) {
// Perform echo subtraction.
EchoSubtraction(aec, aec->num_partitions, aec->extended_filter_enabled,
- aec->normal_mu, aec->normal_error_threshold, &x_fft[0][0],
+ aec->filter_step_size, aec->error_threshold, &x_fft[0][0],
&aec->xfBufBlockPos, aec->xfBuf, nearend_ptr, aec->xPow,
aec->wfBuf, echo_subtractor_output);
@@ -1485,6 +1520,7 @@ AecCore* WebRtcAec_CreateAec() {
#endif
aec->extended_filter_enabled = 0;
aec->aec3_enabled = 0;
+ aec->refined_adaptive_filter_enabled = false;
// Assembly optimization
WebRtcAec_FilterFar = FilterFar;
@@ -1548,18 +1584,53 @@ void WebRtcAec_FreeAec(AecCore* aec) {
delete aec;
}
+static void SetAdaptiveFilterStepSize(AecCore* aec) {
+ // Extended filter adaptation parameter.
+ // TODO(ajm): No narrowband tuning yet.
+ const float kExtendedMu = 0.4f;
+
+ if (aec->refined_adaptive_filter_enabled) {
+ aec->filter_step_size = 0.05f;
+ } else {
+ if (aec->extended_filter_enabled) {
+ aec->filter_step_size = kExtendedMu;
+ } else {
+ if (aec->sampFreq == 8000) {
+ aec->filter_step_size = 0.6f;
+ } else {
+ aec->filter_step_size = 0.5f;
+ }
+ }
+ }
+}
+
+static void SetErrorThreshold(AecCore* aec) {
+ // Extended filter adaptation parameter.
+ // TODO(ajm): No narrowband tuning yet.
+ static const float kExtendedErrorThreshold = 1.0e-6f;
+
+ if (aec->extended_filter_enabled) {
+ aec->error_threshold = kExtendedErrorThreshold;
+ } else {
+ if (aec->sampFreq == 8000) {
+ aec->error_threshold = 2e-6f;
+ } else {
+ aec->error_threshold = 1.5e-6f;
+ }
+ }
+}
+
int WebRtcAec_InitAec(AecCore* aec, int sampFreq) {
int i;
aec->sampFreq = sampFreq;
+ SetAdaptiveFilterStepSize(aec);
+ SetErrorThreshold(aec);
+
if (sampFreq == 8000) {
- aec->normal_mu = 0.6f;
- aec->normal_error_threshold = 2e-6f;
aec->num_bands = 1;
} else {
- aec->normal_mu = 0.5f;
- aec->normal_error_threshold = 1.5e-6f;
aec->num_bands = (size_t)(sampFreq / 16000);
}
@@ -1930,9 +2001,20 @@ int WebRtcAec_aec3_enabled(AecCore* self) {
return self->aec3_enabled;
}
+void WebRtcAec_enable_refined_adaptive_filter(AecCore* self, bool enable) {
+ self->refined_adaptive_filter_enabled = enable;
+ SetAdaptiveFilterStepSize(self);
+ SetErrorThreshold(self);
+}
+
+bool WebRtcAec_refined_adaptive_filter_enabled(const AecCore* self) {
+ return self->refined_adaptive_filter_enabled;
+}
void WebRtcAec_enable_extended_filter(AecCore* self, int enable) {
self->extended_filter_enabled = enable;
+ SetAdaptiveFilterStepSize(self);
+ SetErrorThreshold(self);
self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions;
// Update the delay estimator with filter length. See InitAEC() for details.
WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2);
« no previous file with comments | « webrtc/modules/audio_processing/aec/aec_core.h ('k') | webrtc/modules/audio_processing/aec/aec_core_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698