From 05d8ee1b3e39eaf7d5d31e824ada9a1611415d48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=85hgren?= Date: Thu, 7 Jun 2018 15:59:59 +0200 Subject: [PATCH] AEC3: Delay stabilization after a delay change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This CL ensures that the linear-filter based refined delay is chosen to match the delay that was detected by the delay estimator during the time it takes for the linear filter to converge. Bug: webrtc:9371,chromium:850451 Change-Id: Ib9cf532df0577ceca10a260d9d2deba5306f88bb Reviewed-on: https://webrtc-review.googlesource.com/81682 Commit-Queue: Per Ã…hgren Reviewed-by: Gustaf Ullberg Cr-Commit-Position: refs/heads/master@{#23537} --- modules/audio_processing/aec3/aec_state.cc | 17 +++++++++++++++++ modules/audio_processing/aec3/aec_state.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/modules/audio_processing/aec3/aec_state.cc b/modules/audio_processing/aec3/aec_state.cc index f35818564e..516f6abc3f 100644 --- a/modules/audio_processing/aec3/aec_state.cc +++ b/modules/audio_processing/aec3/aec_state.cc @@ -33,6 +33,11 @@ bool EnableStationaryRenderImprovements() { "WebRTC-Aec3StationaryRenderImprovementsKillSwitch"); } +bool EnableEnforcingDelayAfterRealignment() { + return !field_trial::IsEnabled( + "WebRTC-Aec3EnforceDelayAfterRealignmentKillSwitch"); +} + 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); @@ -53,6 +58,7 @@ AecState::AecState(const EchoCanceller3Config& config) use_stationary_properties_( EnableStationaryRenderImprovements() && config_.echo_audibility.use_stationary_properties), + enforce_delay_after_realignment_(EnableEnforcingDelayAfterRealignment()), erle_estimator_(config.erle.min, config.erle.max_l, config.erle.max_h), max_render_(config_.filter.main.length_blocks, 0.f), reverb_decay_(fabsf(config_.ep_strength.default_len)), @@ -122,6 +128,17 @@ void AecState::Update( // Analyze the filter and compute the delays. filter_analyzer_.Update(adaptive_filter_impulse_response, render_buffer); filter_delay_blocks_ = filter_analyzer_.DelayBlocks(); + if (enforce_delay_after_realignment_) { + if (external_delay && + (!external_delay_ || external_delay_->delay != external_delay->delay)) { + frames_since_external_delay_change_ = 0; + external_delay_ = external_delay; + } + if (blocks_with_proper_filter_adaptation_ < 2 * kNumBlocksPerSecond && + external_delay_) { + filter_delay_blocks_ = config_.delay.delay_headroom_blocks; + } + } if (filter_analyzer_.Consistent()) { internal_delay_ = filter_analyzer_.DelayBlocks(); diff --git a/modules/audio_processing/aec3/aec_state.h b/modules/audio_processing/aec3/aec_state.h index 4765e84384..d513a4084d 100644 --- a/modules/audio_processing/aec3/aec_state.h +++ b/modules/audio_processing/aec3/aec_state.h @@ -148,6 +148,7 @@ class AecState { const EchoCanceller3Config config_; const bool allow_transparent_mode_; const bool use_stationary_properties_; + const bool enforce_delay_after_realignment_; ErlEstimator erl_estimator_; ErleEstimator erle_estimator_; size_t capture_block_counter_ = 0; @@ -187,6 +188,8 @@ class AecState { bool converged_filter_seen_ = false; bool consistent_filter_seen_ = false; bool external_delay_seen_ = false; + rtc::Optional external_delay_; + size_t frames_since_external_delay_change_ = 0; size_t converged_filter_count_ = 0; bool finite_erl_ = false; size_t active_blocks_since_converged_filter_ = 0;