From 040f87f934f5e1d2ecd12436b984479e3c2dac71 Mon Sep 17 00:00:00 2001 From: Gustaf Ullberg Date: Tue, 9 Oct 2018 15:02:39 +0200 Subject: [PATCH] AEC3: Allow a more stable filter during double-talk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a new attempt to reduce the filter divergence during double-talk without regressing in clock-drift scenarios. - The error_floor in decreased to allow for slow adaptation when the filter performs well. - The leakage_diverged is increased to allow for fast adaptation when the shadow filter performs better. - A new parameter, error_ceil, was added to stop the filter from adapting too fast. Bug: webrtc:9746,chromium:883264 Change-Id: Ie2868d2388b48412a192a004ec13f9eff34517b8 Reviewed-on: https://webrtc-review.googlesource.com/c/100460 Commit-Queue: Gustaf Ullberg Reviewed-by: Per Ã…hgren Cr-Commit-Position: refs/heads/master@{#25063} --- api/audio/echo_canceller3_config.h | 6 ++++-- modules/audio_processing/aec3/echo_canceller3.cc | 11 +++++++++++ .../audio_processing/aec3/main_filter_update_gain.cc | 8 +++++++- .../test/audio_processing_simulator.cc | 7 +++++-- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/api/audio/echo_canceller3_config.h b/api/audio/echo_canceller3_config.h index 49bc895ff3..dec9e06d74 100644 --- a/api/audio/echo_canceller3_config.h +++ b/api/audio/echo_canceller3_config.h @@ -46,6 +46,7 @@ struct EchoCanceller3Config { float leakage_converged; float leakage_diverged; float error_floor; + float error_ceil; float noise_gate; }; @@ -55,10 +56,11 @@ struct EchoCanceller3Config { float noise_gate; }; - MainConfiguration main = {13, 0.00005f, 0.01f, 0.1f, 20075344.f}; + MainConfiguration main = {13, 0.00005f, 0.05f, 0.001f, 2.f, 20075344.f}; ShadowConfiguration shadow = {13, 0.7f, 20075344.f}; - MainConfiguration main_initial = {12, 0.005f, 0.5f, 0.001f, 20075344.f}; + MainConfiguration main_initial = {12, 0.005f, 0.5f, + 0.001f, 2.f, 20075344.f}; ShadowConfiguration shadow_initial = {12, 0.9f, 20075344.f}; size_t config_change_duration_blocks = 250; diff --git a/modules/audio_processing/aec3/echo_canceller3.cc b/modules/audio_processing/aec3/echo_canceller3.cc index b2f9229683..e331c1887b 100644 --- a/modules/audio_processing/aec3/echo_canceller3.cc +++ b/modules/audio_processing/aec3/echo_canceller3.cc @@ -66,6 +66,10 @@ bool EnableLongReverb() { return field_trial::IsEnabled("WebRTC-Aec3ShortReverbKillSwitch"); } +bool EnableNewFilterParams() { + return !field_trial::IsEnabled("WebRTC-Aec3NewFilterParamsKillSwitch"); +} + // Method for adjusting config parameter dependencies.. EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config) { EchoCanceller3Config adjusted_cfg = config; @@ -139,6 +143,13 @@ EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config) { adjusted_cfg.filter.main.error_floor = 0.001f; } + if (!EnableNewFilterParams()) { + adjusted_cfg.filter.main.leakage_diverged = 0.01f; + adjusted_cfg.filter.main.error_floor = 0.1f; + adjusted_cfg.filter.main.error_ceil = 1E10f; + adjusted_cfg.filter.main_initial.error_ceil = 1E10f; + } + if (EnableUnityInitialRampupGain() && adjusted_cfg.echo_removal_control.gain_rampup.initial_gain == default_cfg.echo_removal_control.gain_rampup.initial_gain) { diff --git a/modules/audio_processing/aec3/main_filter_update_gain.cc b/modules/audio_processing/aec3/main_filter_update_gain.cc index 4f48cd4748..ec5347e634 100644 --- a/modules/audio_processing/aec3/main_filter_update_gain.cc +++ b/modules/audio_processing/aec3/main_filter_update_gain.cc @@ -127,7 +127,10 @@ void MainFilterUpdateGain::Compute( H_error_increase.begin(), std::multiplies()); std::transform(H_error_.begin(), H_error_.end(), H_error_increase.begin(), H_error_.begin(), [&](float a, float b) { - return std::max(a + b, current_config_.error_floor); + float error = a + b; + error = std::max(error, current_config_.error_floor); + error = std::min(error, current_config_.error_ceil); + return error; }); data_dumper_->DumpRaw("aec3_main_gain_H_error", H_error_); @@ -153,6 +156,9 @@ void MainFilterUpdateGain::UpdateCurrentConfig() { current_config_.error_floor = average(old_target_config_.error_floor, target_config_.error_floor, change_factor); + current_config_.error_ceil = + average(old_target_config_.error_ceil, target_config_.error_ceil, + change_factor); current_config_.noise_gate = average(old_target_config_.noise_gate, target_config_.noise_gate, change_factor); diff --git a/modules/audio_processing/test/audio_processing_simulator.cc b/modules/audio_processing/test/audio_processing_simulator.cc index 65f3c87497..0e06a9adee 100644 --- a/modules/audio_processing/test/audio_processing_simulator.cc +++ b/modules/audio_processing/test/audio_processing_simulator.cc @@ -77,6 +77,7 @@ void PrintAec3ParameterValues(const EchoCanceller3Config& cfg) { std::cout << cfg.filter.main.leakage_converged << ","; std::cout << cfg.filter.main.leakage_diverged << ","; std::cout << cfg.filter.main.error_floor << ","; + std::cout << cfg.filter.main.error_ceil << ","; std::cout << cfg.filter.main.noise_gate; std::cout << "],"; @@ -91,6 +92,7 @@ void PrintAec3ParameterValues(const EchoCanceller3Config& cfg) { std::cout << cfg.filter.main_initial.leakage_converged << ","; std::cout << cfg.filter.main_initial.leakage_diverged << ","; std::cout << cfg.filter.main_initial.error_floor << ","; + std::cout << cfg.filter.main_initial.error_ceil << ","; std::cout << cfg.filter.main_initial.noise_gate; std::cout << "],"; @@ -353,7 +355,7 @@ class Aec3ParametersParser { if (rtc::GetValueFromJsonObject(root, param_name, &json_array)) { std::vector v; rtc::JsonArrayToDoubleVector(json_array, &v); - if (v.size() != 5) { + if (v.size() != 6) { std::cout << "Incorrect array size for " << param_name << std::endl; RTC_CHECK(false); } @@ -361,7 +363,8 @@ class Aec3ParametersParser { param->leakage_converged = static_cast(v[1]); param->leakage_diverged = static_cast(v[2]); param->error_floor = static_cast(v[3]); - param->noise_gate = static_cast(v[4]); + param->error_ceil = static_cast(v[4]); + param->noise_gate = static_cast(v[5]); } }