From debaa442ed0317e215706c8c7d91c880e6bd6051 Mon Sep 17 00:00:00 2001 From: peah Date: Wed, 3 May 2017 05:39:09 -0700 Subject: [PATCH] Corrected the behavior in AEC3 during buffer overruns and underruns This CL corrects the behavior in AEC3 during buffer overruns and underruns in three ways. 1) When there is no render signal available (due to a buffering issues, a zero block is inserted instead of the previous render block. This avoids the same block being repeatedly inserted when there are many back-to-back calls. 2) The internal counters in the main adaptive filter gain are also reset when the filter is reset. 3) The internal counters in the shadow adaptive filter gain are reset when the filter is reset. BUG=chromium:717920,webrtc:7559 Review-Url: https://codereview.webrtc.org/2862533002 Cr-Commit-Position: refs/heads/master@{#17991} --- .../aec3/main_filter_update_gain.cc | 5 +++- .../aec3/render_delay_buffer.cc | 25 +++++++++++++------ .../aec3/shadow_filter_update_gain.cc | 7 ++++++ .../aec3/shadow_filter_update_gain.h | 5 ++++ .../audio_processing/aec3/subtractor.cc | 1 + 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/webrtc/modules/audio_processing/aec3/main_filter_update_gain.cc b/webrtc/modules/audio_processing/aec3/main_filter_update_gain.cc index 9cfb08bdb0..3c4959c11c 100644 --- a/webrtc/modules/audio_processing/aec3/main_filter_update_gain.cc +++ b/webrtc/modules/audio_processing/aec3/main_filter_update_gain.cc @@ -22,6 +22,7 @@ namespace webrtc { namespace { constexpr float kHErrorInitial = 10000.f; +constexpr int kPoorExcitationCounterInitial = 1000; } // namespace @@ -30,7 +31,7 @@ int MainFilterUpdateGain::instance_count_ = 0; MainFilterUpdateGain::MainFilterUpdateGain() : data_dumper_( new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))), - poor_excitation_counter_(1000) { + poor_excitation_counter_(kPoorExcitationCounterInitial) { H_error_.fill(kHErrorInitial); } @@ -38,6 +39,8 @@ MainFilterUpdateGain::~MainFilterUpdateGain() {} void MainFilterUpdateGain::HandleEchoPathChange() { H_error_.fill(kHErrorInitial); + poor_excitation_counter_ = kPoorExcitationCounterInitial; + call_counter_ = 0; } void MainFilterUpdateGain::Compute( diff --git a/webrtc/modules/audio_processing/aec3/render_delay_buffer.cc b/webrtc/modules/audio_processing/aec3/render_delay_buffer.cc index 6e6766ab4d..12dae1b8b4 100644 --- a/webrtc/modules/audio_processing/aec3/render_delay_buffer.cc +++ b/webrtc/modules/audio_processing/aec3/render_delay_buffer.cc @@ -97,6 +97,7 @@ class RenderDelayBufferImpl final : public RenderDelayBuffer { DownsampledRenderBuffer downsampled_render_buffer_; DecimatorBy4 render_decimator_; ApiCallJitterBuffer api_call_jitter_buffer_; + const std::vector> zero_block_; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderDelayBufferImpl); }; @@ -107,7 +108,8 @@ RenderDelayBufferImpl::RenderDelayBufferImpl(size_t num_bands) num_bands, std::max(kResidualEchoPowerRenderWindowSize, kAdaptiveFilterLength), std::vector(1, kAdaptiveFilterLength)), - api_call_jitter_buffer_(num_bands) { + api_call_jitter_buffer_(num_bands), + zero_block_(num_bands, std::vector(kBlockSize, 0.f)) { buffer_.fill(std::vector>( num_bands, std::vector(kBlockSize, 0.f))); @@ -147,12 +149,11 @@ bool RenderDelayBufferImpl::Insert( bool RenderDelayBufferImpl::UpdateBuffers() { bool underrun = true; - // Update the buffers with a new block if such is available, otherwise repeat - // the previous block. + // Update the buffers with a new block if such is available, otherwise insert + // a block of silence. if (api_call_jitter_buffer_.Size() > 0) { last_insert_index_ = (last_insert_index_ + 1) % buffer_.size(); api_call_jitter_buffer_.Remove(&buffer_[last_insert_index_]); - underrun = false; } @@ -162,14 +163,22 @@ bool RenderDelayBufferImpl::UpdateBuffers() { downsampled_render_buffer_.buffer.size(); std::array render_downsampled; - render_decimator_.Decimate(buffer_[last_insert_index_][0], - render_downsampled); + if (underrun) { + render_decimator_.Decimate(zero_block_[0], render_downsampled); + } else { + render_decimator_.Decimate(buffer_[last_insert_index_][0], + render_downsampled); + } std::copy(render_downsampled.rbegin(), render_downsampled.rend(), downsampled_render_buffer_.buffer.begin() + downsampled_render_buffer_.position); - fft_buffer_.Insert( - buffer_[(last_insert_index_ - delay_ + buffer_.size()) % buffer_.size()]); + if (underrun) { + fft_buffer_.Insert(zero_block_); + } else { + fft_buffer_.Insert(buffer_[(last_insert_index_ - delay_ + buffer_.size()) % + buffer_.size()]); + } return !underrun; } diff --git a/webrtc/modules/audio_processing/aec3/shadow_filter_update_gain.cc b/webrtc/modules/audio_processing/aec3/shadow_filter_update_gain.cc index 85bc11fb0d..61a1f575b1 100644 --- a/webrtc/modules/audio_processing/aec3/shadow_filter_update_gain.cc +++ b/webrtc/modules/audio_processing/aec3/shadow_filter_update_gain.cc @@ -17,6 +17,13 @@ namespace webrtc { +void ShadowFilterUpdateGain::HandleEchoPathChange() { + // TODO(peah): Check whether this counter should instead be initialized to a + // large value. + poor_signal_excitation_counter_ = 0; + call_counter_ = 0; +} + void ShadowFilterUpdateGain::Compute( const RenderBuffer& render_buffer, const RenderSignalAnalyzer& render_signal_analyzer, diff --git a/webrtc/modules/audio_processing/aec3/shadow_filter_update_gain.h b/webrtc/modules/audio_processing/aec3/shadow_filter_update_gain.h index a67b8fb636..72218b6608 100644 --- a/webrtc/modules/audio_processing/aec3/shadow_filter_update_gain.h +++ b/webrtc/modules/audio_processing/aec3/shadow_filter_update_gain.h @@ -21,6 +21,9 @@ namespace webrtc { // Provides functionality for computing the fixed gain for the shadow filter. class ShadowFilterUpdateGain { public: + // Takes action in the case of a known echo path change. + void HandleEchoPathChange(); + // Computes the gain. void Compute(const RenderBuffer& render_buffer, const RenderSignalAnalyzer& render_signal_analyzer, @@ -30,6 +33,8 @@ class ShadowFilterUpdateGain { FftData* G); private: + // TODO(peah): Check whether this counter should instead be initialized to a + // large value. size_t poor_signal_excitation_counter_ = 0; size_t call_counter_ = 0; }; diff --git a/webrtc/modules/audio_processing/aec3/subtractor.cc b/webrtc/modules/audio_processing/aec3/subtractor.cc index 4b462238e2..3897d947e1 100644 --- a/webrtc/modules/audio_processing/aec3/subtractor.cc +++ b/webrtc/modules/audio_processing/aec3/subtractor.cc @@ -55,6 +55,7 @@ void Subtractor::HandleEchoPathChange( main_filter_.HandleEchoPathChange(); shadow_filter_.HandleEchoPathChange(); G_main_.HandleEchoPathChange(); + G_shadow_.HandleEchoPathChange(); } }