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}
This commit is contained in:
@ -306,7 +306,7 @@ TEST(AdaptiveFirFilter, FilterSize) {
|
||||
// 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(),
|
||||
|
@ -220,8 +220,14 @@ TEST(MainFilterUpdateGain, GainCausesFilterToConverge) {
|
||||
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 @@ TEST(MainFilterUpdateGain, GainCausesFilterToConverge) {
|
||||
// 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 @@ TEST(MainFilterUpdateGain, DecreasingGain) {
|
||||
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 @@ TEST(MainFilterUpdateGain, DecreasingGain) {
|
||||
|
||||
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
|
||||
|
@ -157,8 +157,14 @@ TEST(ShadowFilterUpdateGain, GainCausesFilterToConverge) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +164,13 @@ TEST(Subtractor, Convergence) {
|
||||
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 @@ TEST(Subtractor, NonConvergenceOnUncorrelatedSignals) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1162,12 +1162,12 @@ struct EchoCanceller3Config {
|
||||
|
||||
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 {
|
||||
|
Reference in New Issue
Block a user