From b5adc9e4cb999902a5b3677fea3db66897effcc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=85hgren?= Date: Mon, 15 Jan 2018 13:20:20 +0100 Subject: [PATCH] Use the best of the shadow and main filter characteristics in AEC3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:8746 Change-Id: If40a3ac936dcc4f55ce0943c5228a9891160e752 Reviewed-on: https://webrtc-review.googlesource.com/39509 Commit-Queue: Per Ã…hgren Reviewed-by: Gustaf Ullberg Cr-Commit-Position: refs/heads/master@{#21621} --- modules/audio_processing/aec3/subtractor.cc | 37 +++++++++++++-------- modules/audio_processing/aec3/subtractor.h | 15 ++++++--- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/modules/audio_processing/aec3/subtractor.cc b/modules/audio_processing/aec3/subtractor.cc index 6fbef9e222..e3b4f87c0f 100644 --- a/modules/audio_processing/aec3/subtractor.cc +++ b/modules/audio_processing/aec3/subtractor.cc @@ -97,11 +97,11 @@ void Subtractor::HandleEchoPathChange( G_shadow_.HandleEchoPathChange(); G_main_.SetConfig(config_.filter.main_initial); G_shadow_.SetConfig(config_.filter.shadow_initial); + main_filter_converged_ = false; + shadow_filter_converged_ = false; main_filter_.SetSizePartitions(config_.filter.main_initial.length_blocks); shadow_filter_.SetSizePartitions( config_.filter.shadow_initial.length_blocks); - - converged_filter_ = false; }; // TODO(peah): Add delay-change specific reset behavior. @@ -147,8 +147,6 @@ void Subtractor::Process(const RenderBuffer& render_buffer, bool main_saturation = false; PredictionError(fft_, S, y, &e_main, &output->s_main, &main_saturation); fft_.ZeroPaddedFft(e_main, Aec3Fft::Window::kHanning, &E_main); - fft_.ZeroPaddedFft(e_main, Aec3Fft::Window::kRectangular, - &E_main_nonwindowed); // Form the output of the shadow filter. shadow_filter_.Filter(render_buffer, &S); @@ -156,23 +154,36 @@ void Subtractor::Process(const RenderBuffer& render_buffer, PredictionError(fft_, S, y, &e_shadow, nullptr, &shadow_saturation); fft_.ZeroPaddedFft(e_shadow, Aec3Fft::Window::kHanning, &E_shadow); - if (!converged_filter_) { + if (!(main_filter_converged_ || shadow_filter_converged_)) { const auto sum_of_squares = [](float a, float b) { return a + b * b; }; - const float e2_main = - std::accumulate(e_main.begin(), e_main.end(), 0.f, sum_of_squares); - const float e2_shadow = - std::accumulate(e_shadow.begin(), e_shadow.end(), 0.f, sum_of_squares); const float y2 = std::accumulate(y.begin(), y.end(), 0.f, sum_of_squares); - if (y2 > kBlockSize * 50.f * 50.f) { - converged_filter_ = (e2_main > 0.3 * y2 || e2_shadow > 0.1 * y2); + if (!main_filter_converged_) { + const float e2_main = + std::accumulate(e_main.begin(), e_main.end(), 0.f, sum_of_squares); + main_filter_converged_ = e2_main > 0.1 * y2; + } + + if (!shadow_filter_converged_) { + const float e2_shadow = std::accumulate(e_shadow.begin(), e_shadow.end(), + 0.f, sum_of_squares); + shadow_filter_converged_ = e2_shadow > 0.1 * y2; } } // Compute spectra for future use. - E_main.Spectrum(optimization_, output->E2_main); - E_main_nonwindowed.Spectrum(optimization_, output->E2_main_nonwindowed); E_shadow.Spectrum(optimization_, output->E2_shadow); + E_main.Spectrum(optimization_, output->E2_main); + + if (main_filter_converged_ || !shadow_filter_converged_) { + fft_.ZeroPaddedFft(e_main, Aec3Fft::Window::kRectangular, + &E_main_nonwindowed); + E_main_nonwindowed.Spectrum(optimization_, output->E2_main_nonwindowed); + } else { + fft_.ZeroPaddedFft(e_shadow, Aec3Fft::Window::kRectangular, + &E_main_nonwindowed); + E_main_nonwindowed.Spectrum(optimization_, output->E2_main_nonwindowed); + } // Update the main filter. std::array X2; diff --git a/modules/audio_processing/aec3/subtractor.h b/modules/audio_processing/aec3/subtractor.h index b267abf721..b3c8506c81 100644 --- a/modules/audio_processing/aec3/subtractor.h +++ b/modules/audio_processing/aec3/subtractor.h @@ -53,15 +53,21 @@ class Subtractor { // Returns the block-wise frequency response for the main adaptive filter. const std::vector>& FilterFrequencyResponse() const { - return main_filter_.FilterFrequencyResponse(); + return main_filter_converged_ || (!shadow_filter_converged_) + ? main_filter_.FilterFrequencyResponse() + : shadow_filter_.FilterFrequencyResponse(); } // Returns the estimate of the impulse response for the main adaptive filter. const std::vector& FilterImpulseResponse() const { - return main_filter_.FilterImpulseResponse(); + return main_filter_converged_ || (!shadow_filter_converged_) + ? main_filter_.FilterImpulseResponse() + : shadow_filter_.FilterImpulseResponse(); } - bool ConvergedFilter() const { return converged_filter_; } + bool ConvergedFilter() const { + return main_filter_converged_ || shadow_filter_converged_; + } private: const Aec3Fft fft_; @@ -72,7 +78,8 @@ class Subtractor { AdaptiveFirFilter shadow_filter_; MainFilterUpdateGain G_main_; ShadowFilterUpdateGain G_shadow_; - bool converged_filter_ = false; + bool main_filter_converged_ = false; + bool shadow_filter_converged_ = false; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Subtractor); };