Updated the behavior for the filter adaptation in echo canceller 3
This CL adjusts the filter adaptation behavior to better handle
reverberant environments and environments with poor SNR.
It furthermore updates the unittests to handle the reduced adaptation
speed.
Bug: webrtc:8661
Change-Id: I5f1b5a4a34b333bd6c643ed3727899d0838dbf90
Reviewed-on: https://webrtc-review.googlesource.com/34184
Reviewed-by: Gustaf Ullberg <gustaf@webrtc.org>
Commit-Queue: Per Åhgren <peah@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21323}
diff --git a/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc b/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc
index 47566c2..f26d511 100644
--- a/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc
+++ b/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc
@@ -306,7 +306,7 @@
// Verifies that the filter is being able to properly filter a signal and to
// adapt its coefficients.
TEST(AdaptiveFirFilter, FilterAndAdapt) {
- constexpr size_t kNumBlocksToProcess = 500;
+ constexpr size_t kNumBlocksToProcess = 1000;
ApmDataDumper data_dumper(42);
EchoCanceller3Config config;
AdaptiveFirFilter filter(config.filter.length_blocks, DetectOptimization(),
diff --git a/modules/audio_processing/aec3/main_filter_update_gain_unittest.cc b/modules/audio_processing/aec3/main_filter_update_gain_unittest.cc
index fb088a3..ad5e740 100644
--- a/modules/audio_processing/aec3/main_filter_update_gain_unittest.cc
+++ b/modules/audio_processing/aec3/main_filter_update_gain_unittest.cc
@@ -220,8 +220,14 @@
false, &e, &y, &G);
// Verify that the main filter is able to perform well.
- EXPECT_LT(1000 * std::inner_product(e.begin(), e.end(), e.begin(), 0.f),
- std::inner_product(y.begin(), y.end(), y.begin(), 0.f));
+ // Use different criteria to take overmodelling into account.
+ if (filter_length_blocks == 12) {
+ EXPECT_LT(1000 * std::inner_product(e.begin(), e.end(), e.begin(), 0.f),
+ std::inner_product(y.begin(), y.end(), y.begin(), 0.f));
+ } else {
+ EXPECT_LT(std::inner_product(e.begin(), e.end(), e.begin(), 0.f),
+ std::inner_product(y.begin(), y.end(), y.begin(), 0.f));
+ }
}
}
}
@@ -229,8 +235,6 @@
// Verifies that the magnitude of the gain on average decreases for a
// persistently exciting signal.
TEST(MainFilterUpdateGain, DecreasingGain) {
- for (size_t filter_length_blocks : {12, 20, 30}) {
- SCOPED_TRACE(ProduceDebugText(filter_length_blocks));
std::vector<int> blocks_with_echo_path_changes;
std::vector<int> blocks_with_saturation;
@@ -243,15 +247,12 @@
std::array<float, kFftLengthBy2Plus1> G_b_power;
std::array<float, kFftLengthBy2Plus1> G_c_power;
- RunFilterUpdateTest(100, 65, filter_length_blocks,
- blocks_with_echo_path_changes, blocks_with_saturation,
- false, &e, &y, &G_a);
- RunFilterUpdateTest(300, 65, filter_length_blocks,
- blocks_with_echo_path_changes, blocks_with_saturation,
- false, &e, &y, &G_b);
- RunFilterUpdateTest(600, 65, filter_length_blocks,
- blocks_with_echo_path_changes, blocks_with_saturation,
- false, &e, &y, &G_c);
+ RunFilterUpdateTest(100, 65, 12, blocks_with_echo_path_changes,
+ blocks_with_saturation, false, &e, &y, &G_a);
+ RunFilterUpdateTest(300, 65, 12, blocks_with_echo_path_changes,
+ blocks_with_saturation, false, &e, &y, &G_b);
+ RunFilterUpdateTest(600, 65, 12, blocks_with_echo_path_changes,
+ blocks_with_saturation, false, &e, &y, &G_c);
G_a.Spectrum(Aec3Optimization::kNone, G_a_power);
G_b.Spectrum(Aec3Optimization::kNone, G_b_power);
@@ -262,7 +263,6 @@
EXPECT_GT(std::accumulate(G_b_power.begin(), G_b_power.end(), 0.),
std::accumulate(G_c_power.begin(), G_c_power.end(), 0.));
- }
}
// Verifies that the gain is zero when there is saturation and that the internal
diff --git a/modules/audio_processing/aec3/shadow_filter_update_gain_unittest.cc b/modules/audio_processing/aec3/shadow_filter_update_gain_unittest.cc
index 4c7f76e..6692dbb 100644
--- a/modules/audio_processing/aec3/shadow_filter_update_gain_unittest.cc
+++ b/modules/audio_processing/aec3/shadow_filter_update_gain_unittest.cc
@@ -157,8 +157,14 @@
blocks_with_saturation, &e, &y, &G);
// Verify that the main filter is able to perform well.
- EXPECT_LT(1000 * std::inner_product(e.begin(), e.end(), e.begin(), 0.f),
- std::inner_product(y.begin(), y.end(), y.begin(), 0.f));
+ // Use different criteria to take overmodelling into account.
+ if (filter_length_blocks == 12) {
+ EXPECT_LT(1000 * std::inner_product(e.begin(), e.end(), e.begin(), 0.f),
+ std::inner_product(y.begin(), y.end(), y.begin(), 0.f));
+ } else {
+ EXPECT_LT(std::inner_product(e.begin(), e.end(), e.begin(), 0.f),
+ std::inner_product(y.begin(), y.end(), y.begin(), 0.f));
+ }
}
}
}
diff --git a/modules/audio_processing/aec3/subtractor_unittest.cc b/modules/audio_processing/aec3/subtractor_unittest.cc
index 42801fe..daf74fd 100644
--- a/modules/audio_processing/aec3/subtractor_unittest.cc
+++ b/modules/audio_processing/aec3/subtractor_unittest.cc
@@ -164,7 +164,13 @@
float echo_to_nearend_power =
RunSubtractorTest(300, delay_samples, filter_length_blocks, false,
blocks_with_echo_path_changes);
- EXPECT_GT(0.1f, echo_to_nearend_power);
+
+ // Use different criteria to take overmodelling into account.
+ if (filter_length_blocks == 12) {
+ EXPECT_GT(0.1f, echo_to_nearend_power);
+ } else {
+ EXPECT_GT(1.f, echo_to_nearend_power);
+ }
}
}
}
@@ -177,9 +183,9 @@
SCOPED_TRACE(ProduceDebugText(delay_samples, filter_length_blocks));
float echo_to_nearend_power =
- RunSubtractorTest(100, delay_samples, filter_length_blocks, true,
+ RunSubtractorTest(300, delay_samples, filter_length_blocks, true,
blocks_with_echo_path_changes);
- EXPECT_NEAR(1.f, echo_to_nearend_power, 0.05);
+ EXPECT_NEAR(1.f, echo_to_nearend_power, 0.1);
}
}
}
diff --git a/modules/audio_processing/include/audio_processing.h b/modules/audio_processing/include/audio_processing.h
index 28990b8..3b8d2c4 100644
--- a/modules/audio_processing/include/audio_processing.h
+++ b/modules/audio_processing/include/audio_processing.h
@@ -1162,12 +1162,12 @@
struct Filter {
size_t length_blocks = 12;
- float shadow_rate = 0.5f;
- float leakage_converged = 0.01f;
- float leakage_diverged = 1.f / 60.f;
- float error_floor = 0.1f;
- float main_noise_gate = 220075344.f;
- float shadow_noise_gate = 220075344.f;
+ float shadow_rate = 0.1f;
+ float leakage_converged = 0.005f;
+ float leakage_diverged = 0.05f;
+ float error_floor = 0.001f;
+ float main_noise_gate = 20075344.f;
+ float shadow_noise_gate = 20075344.f;
} filter;
struct Erle {