From 96b951c593a2665cc8688d60343dc225f62f4e99 Mon Sep 17 00:00:00 2001 From: peah Date: Tue, 22 Aug 2017 10:26:07 -0700 Subject: [PATCH] Make AEC3 recover more quickly for lost capture data This CL ensures that AEC3 recovers more quickly when capture data is lost in such a manner that the echo path, as seen by AEC3, becomes noncausal due to the AEC3 buffer misalignment caused by the data loss. The CL adds the assumption of a minimum echo path delay of 5 blocks and makes the hysteresis in the delay selection one-sided. BUG=chromium:757796, webrtc:8131 Review-Url: https://codereview.webrtc.org/2998223002 Cr-Commit-Position: refs/heads/master@{#19454} --- .../audio_processing/aec3/aec3_common.h | 1 + .../audio_processing/aec3/block_processor.cc | 25 ++++++++++++------- .../aec3/render_delay_controller.cc | 4 +-- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/webrtc/modules/audio_processing/aec3/aec3_common.h b/webrtc/modules/audio_processing/aec3/aec3_common.h index b78118353b..bf62c0e649 100644 --- a/webrtc/modules/audio_processing/aec3/aec3_common.h +++ b/webrtc/modules/audio_processing/aec3/aec3_common.h @@ -63,6 +63,7 @@ constexpr size_t kDownsampledRenderBufferSize = constexpr size_t kRenderDelayBufferSize = (3 * kDownsampledRenderBufferSize) / (4 * kSubBlockSize); +constexpr size_t kMinEchoPathDelayBlocks = 5; constexpr size_t kMaxApiCallsJitterBlocks = 30; constexpr size_t kRenderTransferQueueSize = kMaxApiCallsJitterBlocks / 2; static_assert(2 * kRenderTransferQueueSize >= kMaxApiCallsJitterBlocks, diff --git a/webrtc/modules/audio_processing/aec3/block_processor.cc b/webrtc/modules/audio_processing/aec3/block_processor.cc index 3a32f3c80b..52bc4ef1a3 100644 --- a/webrtc/modules/audio_processing/aec3/block_processor.cc +++ b/webrtc/modules/audio_processing/aec3/block_processor.cc @@ -112,20 +112,27 @@ void BlockProcessorImpl::ProcessCapture( const size_t old_delay = render_buffer_->Delay(); const size_t new_delay = delay_controller_->GetDelay( render_buffer_->GetDownsampledRenderBuffer(), (*capture_block)[0]); - render_buffer_->SetDelay(new_delay); - const size_t achieved_delay = render_buffer_->Delay(); - // Inform the delay controller of the actually set delay to allow it to - // properly react to a non-feasible delay. - delay_controller_->SetDelay(achieved_delay); + bool delay_change; + if (new_delay >= kMinEchoPathDelayBlocks) { + render_buffer_->SetDelay(new_delay); + const size_t achieved_delay = render_buffer_->Delay(); + delay_change = old_delay != achieved_delay || old_delay != new_delay || + render_buffer_overrun_occurred_; + + // Inform the delay controller of the actually set delay to allow it to + // properly react to a non-feasible delay. + delay_controller_->SetDelay(achieved_delay); + } else { + delay_controller_->Reset(); + render_buffer_->Reset(); + delay_change = true; + } // Remove the echo from the capture signal. echo_remover_->ProcessCapture( delay_controller_->AlignmentHeadroomSamples(), - EchoPathVariability(echo_path_gain_change, - old_delay != achieved_delay || - old_delay != new_delay || - render_buffer_overrun_occurred_), + EchoPathVariability(echo_path_gain_change, delay_change), capture_signal_saturation, render_buffer_->GetRenderBuffer(), capture_block); diff --git a/webrtc/modules/audio_processing/aec3/render_delay_controller.cc b/webrtc/modules/audio_processing/aec3/render_delay_controller.cc index 06074e2cdb..a88540e21f 100644 --- a/webrtc/modules/audio_processing/aec3/render_delay_controller.cc +++ b/webrtc/modules/audio_processing/aec3/render_delay_controller.cc @@ -59,7 +59,7 @@ size_t ComputeNewBufferDelay(size_t current_delay, size_t new_delay = std::max(echo_path_delay_blocks - kDelayHeadroomBlocks, 0); // Add hysteresis. - if (new_delay == current_delay + 1 || new_delay + 1 == current_delay) { + if (new_delay == current_delay + 1) { new_delay = current_delay; } @@ -78,7 +78,7 @@ RenderDelayControllerImpl::RenderDelayControllerImpl(int sample_rate_hz) RenderDelayControllerImpl::~RenderDelayControllerImpl() = default; void RenderDelayControllerImpl::Reset() { - delay_ = 0; + delay_ = kMinEchoPathDelayBlocks; blocks_since_last_delay_estimate_ = 300000; echo_path_delay_samples_ = 0; align_call_counter_ = 0;