AEC3: Loosen the echo removal requirements in conservative mode

This CL lowers the margins in the AEC3 conservative mode to increase
the transparency when there are audio buffer issues, and during call
startup.

In particular, this CL adjusts the parameters and thresholds to
-Make the requirements for filter divergence more strict, to minimize
the transparency loss during minor filter divergence.
-Decrease the echo power uncertainty used during initial filter
convergence, to increase transparency after audio buffer issues.
-Deactivate the enforcement of conservative suppressor gain after
audio buffer.

Bug: webrtc:9641,chromium:875611
Change-Id: Ie171bb411f17a1e8661c291118debd334f65c74f
Reviewed-on: https://webrtc-review.googlesource.com/94776
Commit-Queue: Per Åhgren <peah@webrtc.org>
Reviewed-by: Jesus de Vicente Pena <devicentepena@webrtc.org>
Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24333}
This commit is contained in:
Per Åhgren
2018-08-19 11:12:00 +02:00
committed by Commit Bot
parent 57b7b67b60
commit 6204adf2ed
6 changed files with 91 additions and 2 deletions

View File

@ -72,6 +72,41 @@ bool TreatTransparentModeAsNonlinear() {
"WebRTC-Aec3TreatTransparentModeAsNonlinearKillSwitch");
}
bool LowUncertaintyBeforeConvergence() {
return !field_trial::IsEnabled(
"WebRTC-Aec3LowUncertaintyBeforeConvergenceKillSwitch");
}
bool MediumUncertaintyBeforeConvergence() {
return !field_trial::IsEnabled(
"WebRTC-Aec3MediumUncertaintyBeforeConvergenceKillSwitch");
}
bool EarlyEntryToConvergedMode() {
return !field_trial::IsEnabled(
"WebRTC-Aec3EarlyEntryToConvergedModeKillSwitch");
}
bool ConservativeFilterDivergence() {
return !field_trial::IsEnabled(
"WebRTC-Aec3ConservativeFilterDivergenceKillSwitch");
}
bool UseEarlyLimiterDeactivation() {
return !field_trial::IsEnabled(
"WebRTC-Aec3EarlyLimiterDeactivationKillSwitch");
}
float UncertaintyBeforeConvergence() {
if (LowUncertaintyBeforeConvergence()) {
return 1.f;
} else if (MediumUncertaintyBeforeConvergence()) {
return 4.f;
} else {
return 10.f;
}
}
float ComputeGainRampupIncrease(const EchoCanceller3Config& config) {
const auto& c = config.echo_removal_control.gain_rampup;
return powf(1.f / c.first_non_zero_gain, 1.f / c.non_zero_gain_blocks);
@ -103,6 +138,10 @@ AecState::AecState(const EchoCanceller3Config& config)
EnableUncertaintyUntilSufficientAdapted()),
transparent_mode_enforces_nonlinear_mode_(
TreatTransparentModeAsNonlinear()),
uncertainty_before_convergence_(UncertaintyBeforeConvergence()),
early_entry_to_converged_mode_(EarlyEntryToConvergedMode()),
conservative_filter_divergence_(ConservativeFilterDivergence()),
early_limiter_deactivation_(UseEarlyLimiterDeactivation()),
erle_estimator_(config.erle.min, config.erle.max_l, config.erle.max_h),
max_render_(config_.filter.main.length_blocks, 0.f),
gain_rampup_increase_(ComputeGainRampupIncrease(config_)),
@ -201,6 +240,9 @@ void AecState::Update(
// an initial echo burst.
suppression_gain_limiter_.Update(render_buffer.GetRenderActivity(),
transparent_mode_);
if (converged_filter && early_limiter_deactivation_) {
suppression_gain_limiter_.Deactivate();
}
if (UseStationaryProperties()) {
// Update the echo audibility evaluator.
@ -231,6 +273,10 @@ void AecState::Update(
blocks_with_proper_filter_adaptation_ >= 1.5f * kNumBlocksPerSecond;
}
if (converged_filter && early_entry_to_converged_mode_) {
filter_has_had_time_to_converge_ = true;
}
if (!filter_should_have_converged_) {
filter_should_have_converged_ =
blocks_with_proper_filter_adaptation_ > 6 * kNumBlocksPerSecond;
@ -335,7 +381,14 @@ void AecState::Update(
}
use_linear_filter_output_ = usable_linear_estimate_ && !TransparentMode();
diverged_linear_filter_ = diverged_filter;
if (conservative_filter_divergence_) {
diverged_linear_filter_ =
subtractor_output_analyzer_.SeverelyDivergedFilter() &&
active_render_block;
} else {
diverged_linear_filter_ = diverged_filter;
}
const bool stationary_block =
use_stationary_properties_ && echo_audibility_.IsBlockStationary();

View File

@ -80,7 +80,7 @@ class AecState {
if (!filter_has_had_time_to_converge_ &&
use_uncertainty_until_sufficiently_adapted_) {
return 10.f;
return uncertainty_before_convergence_;
}
return absl::nullopt;
}
@ -182,6 +182,10 @@ class AecState {
const bool no_alignment_required_for_linear_mode_;
const bool use_uncertainty_until_sufficiently_adapted_;
const bool transparent_mode_enforces_nonlinear_mode_;
const float uncertainty_before_convergence_;
const bool early_entry_to_converged_mode_;
const bool conservative_filter_divergence_;
const bool early_limiter_deactivation_;
ErlEstimator erl_estimator_;
ErleEstimator erle_estimator_;
size_t capture_block_counter_ = 0;

View File

@ -54,9 +54,18 @@ bool EnableShadowFilterJumpstart() {
return !field_trial::IsEnabled("WebRTC-Aec3ShadowFilterJumpstartKillSwitch");
}
bool EnableUnityInitialRampupGain() {
return field_trial::IsEnabled("WebRTC-Aec3EnableUnityInitialRampupGain");
}
bool EnableUnityNonZeroRampupGain() {
return field_trial::IsEnabled("WebRTC-Aec3EnableUnityNonZeroRampupGain");
}
// Method for adjusting config parameter dependencies..
EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config) {
EchoCanceller3Config adjusted_cfg = config;
const EchoCanceller3Config default_cfg;
if (!EnableReverbModelling()) {
adjusted_cfg.ep_strength.default_len = 0.f;
@ -126,6 +135,18 @@ EchoCanceller3Config AdjustConfig(const EchoCanceller3Config& config) {
adjusted_cfg.filter.main.error_floor = 0.001f;
}
if (EnableUnityInitialRampupGain() &&
adjusted_cfg.echo_removal_control.gain_rampup.initial_gain ==
default_cfg.echo_removal_control.gain_rampup.initial_gain) {
adjusted_cfg.echo_removal_control.gain_rampup.initial_gain = 1.f;
}
if (EnableUnityNonZeroRampupGain() &&
adjusted_cfg.echo_removal_control.gain_rampup.first_non_zero_gain ==
default_cfg.echo_removal_control.gain_rampup.first_non_zero_gain) {
adjusted_cfg.echo_removal_control.gain_rampup.first_non_zero_gain = 1.f;
}
return adjusted_cfg;
}

View File

@ -40,12 +40,15 @@ void SubtractorOutputAnalyzer::Update(
float min_e2 =
strict_divergence_check_ ? std::min(e2_main, e2_shadow) : e2_main;
filter_diverged_ = min_e2 > 1.5f * y2 && y2 > 30.f * 30.f * kBlockSize;
filter_severely_diverged_ =
min_e2 > 1.5f * y2 && y2 > 200.f * 200.f * kBlockSize;
}
void SubtractorOutputAnalyzer::HandleEchoPathChange() {
shadow_filter_converged_ = false;
main_filter_converged_ = false;
filter_diverged_ = false;
filter_severely_diverged_ = false;
}
} // namespace webrtc

View File

@ -30,6 +30,7 @@ class SubtractorOutputAnalyzer {
}
bool DivergedFilter() const { return filter_diverged_; }
bool SeverelyDivergedFilter() const { return filter_severely_diverged_; }
// Handle echo path change.
void HandleEchoPathChange();
@ -39,6 +40,7 @@ class SubtractorOutputAnalyzer {
bool shadow_filter_converged_ = false;
bool main_filter_converged_ = false;
bool filter_diverged_ = false;
bool filter_severely_diverged_ = false;
};
} // namespace webrtc

View File

@ -35,6 +35,12 @@ class SuppressionGainUpperLimiter {
// Return whether the suppressor gain limit is active.
bool IsActive() const { return (realignment_counter_ > 0); }
// Inactivate limiter.
void Deactivate() {
realignment_counter_ = 0;
suppressor_gain_limit_ = 1.f;
}
private:
const EchoCanceller3Config::EchoRemovalControl::GainRampup rampup_config_;
const float gain_rampup_increase_;