From d84b3d1f3d8ad6b1e1f2667e2d2d48cf5ca59227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=85hgren?= Date: Fri, 12 Jan 2018 14:47:11 +0100 Subject: [PATCH] Generalized the hysteresis behavior in the AEC3 delay estimator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This CL generalizes the hysteresis behavior on the AEC3 delay estimator to be two-sided and easier to configure. Bug: webrtc:8671 Change-Id: Ife21c1511416e32eb3618c81178deefe332ac1e8 Reviewed-on: https://webrtc-review.googlesource.com/39267 Reviewed-by: Gustaf Ullberg Commit-Queue: Per Ã…hgren Cr-Commit-Position: refs/heads/master@{#21604} --- .../aec3/render_delay_controller.cc | 34 +++++++++++++++---- .../include/audio_processing.h | 3 ++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/modules/audio_processing/aec3/render_delay_controller.cc b/modules/audio_processing/aec3/render_delay_controller.cc index dfc47f4b23..16a447730d 100644 --- a/modules/audio_processing/aec3/render_delay_controller.cc +++ b/modules/audio_processing/aec3/render_delay_controller.cc @@ -39,6 +39,9 @@ class RenderDelayControllerImpl final : public RenderDelayController { private: static int instance_count_; std::unique_ptr data_dumper_; + const int delay_headroom_blocks_; + const int hysteresis_limit_1_blocks_; + const int hysteresis_limit_2_blocks_; rtc::Optional delay_; EchoPathDelayEstimator delay_estimator_; size_t align_call_counter_ = 0; @@ -48,19 +51,30 @@ class RenderDelayControllerImpl final : public RenderDelayController { RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderDelayControllerImpl); }; -size_t ComputeNewBufferDelay(rtc::Optional current_delay, +size_t ComputeNewBufferDelay(const rtc::Optional& current_delay, + int delay_headroom_blocks, + int hysteresis_limit_1_blocks, + int hysteresis_limit_2_blocks, size_t delay_samples) { // The below division is not exact and the truncation is intended. const int echo_path_delay_blocks = delay_samples >> kBlockSizeLog2; - constexpr int kDelayHeadroomBlocks = 1; // Compute the buffer delay increase required to achieve the desired latency. - size_t new_delay = std::max(echo_path_delay_blocks - kDelayHeadroomBlocks, 0); + size_t new_delay = + std::max(echo_path_delay_blocks - delay_headroom_blocks, 0); // Add hysteresis. if (current_delay) { - if (new_delay == *current_delay + 1) { - new_delay = *current_delay; + if (new_delay > *current_delay) { + if (new_delay <= *current_delay + hysteresis_limit_1_blocks) { + new_delay = *current_delay; + } + } else if (new_delay < *current_delay) { + size_t hysteresis_limit = std::max( + static_cast(*current_delay) - hysteresis_limit_2_blocks, 0); + if (new_delay >= hysteresis_limit) { + new_delay = *current_delay; + } } } @@ -75,6 +89,12 @@ RenderDelayControllerImpl::RenderDelayControllerImpl( int sample_rate_hz) : data_dumper_( new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))), + delay_headroom_blocks_( + static_cast(config.delay.delay_headroom_blocks)), + hysteresis_limit_1_blocks_( + static_cast(config.delay.hysteresis_limit_1_blocks)), + hysteresis_limit_2_blocks_( + static_cast(config.delay.hysteresis_limit_2_blocks)), delay_estimator_(data_dumper_.get(), config), delay_buf_(kBlockSize * non_causal_offset, 0.f) { RTC_DCHECK(ValidFullBandRate(sample_rate_hz)); @@ -120,7 +140,9 @@ rtc::Optional RenderDelayControllerImpl::GetDelay( if (delay_samples) { // Compute and set new render delay buffer delay. if (align_call_counter_ > kNumBlocksPerSecond) { - delay_ = ComputeNewBufferDelay(delay_, static_cast(*delay_samples)); + delay_ = ComputeNewBufferDelay( + delay_, delay_headroom_blocks_, hysteresis_limit_1_blocks_, + hysteresis_limit_2_blocks_, static_cast(*delay_samples)); } metrics_.Update(static_cast(*delay_samples), delay_ ? *delay_ : 0); diff --git a/modules/audio_processing/include/audio_processing.h b/modules/audio_processing/include/audio_processing.h index 8951b8cda8..6f7cda0da1 100644 --- a/modules/audio_processing/include/audio_processing.h +++ b/modules/audio_processing/include/audio_processing.h @@ -1238,6 +1238,9 @@ struct EchoCanceller3Config { size_t num_filters = 4; size_t api_call_jitter_blocks = 26; size_t min_echo_path_delay_blocks = 5; + size_t delay_headroom_blocks = 1; + size_t hysteresis_limit_1_blocks = 1; + size_t hysteresis_limit_2_blocks = 0; } delay; struct Filter {