From cb1b55612c44948c837575ebb22768f4a5510625 Mon Sep 17 00:00:00 2001 From: Sam Zackrisson Date: Fri, 28 Sep 2018 14:15:09 +0200 Subject: [PATCH] Use low cut filtering whenever NS or AEC are enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These submodules implicitly rely on low cut filtering being enabled. This CL clarifies a distinction: High pass filtering is a feature that users can enable, according to the WebRTC standard. Low cut filtering is a processing effect that is applied when any of the following is active: - high pass filter - noise suppression - builtin echo cancellation Bug: webrtc:9535 Change-Id: I9474276fb11354ea3b01e65a0699f6c29263770b Reviewed-on: https://webrtc-review.googlesource.com/102600 Reviewed-by: Per Ã…hgren Commit-Queue: Sam Zackrisson Cr-Commit-Position: refs/heads/master@{#24892} --- .../audio_processing/audio_processing_impl.cc | 15 +++++++---- .../audio_processing/audio_processing_impl.h | 5 ++-- .../audio_processing_unittest.cc | 25 ++----------------- 3 files changed, 15 insertions(+), 30 deletions(-) diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc index 0772936f63..ac28096108 100644 --- a/modules/audio_processing/audio_processing_impl.cc +++ b/modules/audio_processing/audio_processing_impl.cc @@ -154,7 +154,7 @@ AudioProcessingImpl::ApmSubmoduleStates::ApmSubmoduleStates( capture_analyzer_enabled_(capture_analyzer_enabled) {} bool AudioProcessingImpl::ApmSubmoduleStates::Update( - bool low_cut_filter_enabled, + bool high_pass_filter_enabled, bool echo_canceller_enabled, bool mobile_echo_controller_enabled, bool residual_echo_detector_enabled, @@ -167,7 +167,7 @@ bool AudioProcessingImpl::ApmSubmoduleStates::Update( bool level_estimator_enabled, bool transient_suppressor_enabled) { bool changed = false; - changed |= (low_cut_filter_enabled != low_cut_filter_enabled_); + changed |= (high_pass_filter_enabled != high_pass_filter_enabled_); changed |= (echo_canceller_enabled != echo_canceller_enabled_); changed |= (mobile_echo_controller_enabled != mobile_echo_controller_enabled_); @@ -185,7 +185,7 @@ bool AudioProcessingImpl::ApmSubmoduleStates::Update( (voice_activity_detector_enabled != voice_activity_detector_enabled_); changed |= (transient_suppressor_enabled != transient_suppressor_enabled_); if (changed) { - low_cut_filter_enabled_ = low_cut_filter_enabled; + high_pass_filter_enabled_ = high_pass_filter_enabled; echo_canceller_enabled_ = echo_canceller_enabled; mobile_echo_controller_enabled_ = mobile_echo_controller_enabled; residual_echo_detector_enabled_ = residual_echo_detector_enabled; @@ -211,7 +211,7 @@ bool AudioProcessingImpl::ApmSubmoduleStates::CaptureMultiBandSubModulesActive() bool AudioProcessingImpl::ApmSubmoduleStates::CaptureMultiBandProcessingActive() const { - return low_cut_filter_enabled_ || echo_canceller_enabled_ || + return high_pass_filter_enabled_ || echo_canceller_enabled_ || mobile_echo_controller_enabled_ || noise_suppressor_enabled_ || adaptive_gain_controller_enabled_ || echo_controller_enabled_; } @@ -243,6 +243,11 @@ bool AudioProcessingImpl::ApmSubmoduleStates::RenderMultiBandProcessingActive() return false; } +bool AudioProcessingImpl::ApmSubmoduleStates::LowCutFilteringRequired() const { + return high_pass_filter_enabled_ || echo_canceller_enabled_ || + mobile_echo_controller_enabled_ || noise_suppressor_enabled_; +} + struct AudioProcessingImpl::ApmPublicSubmodules { ApmPublicSubmodules() {} // Accessed externally of APM without any lock acquired. @@ -1792,7 +1797,7 @@ void AudioProcessingImpl::InitializeTransient() { } void AudioProcessingImpl::InitializeLowCutFilter() { - if (config_.high_pass_filter.enabled) { + if (submodule_states_.LowCutFilteringRequired()) { private_submodules_->low_cut_filter.reset( new LowCutFilter(num_proc_channels(), proc_sample_rate_hz())); } else { diff --git a/modules/audio_processing/audio_processing_impl.h b/modules/audio_processing/audio_processing_impl.h index 808e3f907a..781f954107 100644 --- a/modules/audio_processing/audio_processing_impl.h +++ b/modules/audio_processing/audio_processing_impl.h @@ -178,7 +178,7 @@ class AudioProcessingImpl : public AudioProcessing { bool render_pre_processor_enabled, bool capture_analyzer_enabled); // Updates the submodule state and returns true if it has changed. - bool Update(bool low_cut_filter_enabled, + bool Update(bool high_pass_filter_enabled, bool echo_canceller_enabled, bool mobile_echo_controller_enabled, bool residual_echo_detector_enabled, @@ -197,12 +197,13 @@ class AudioProcessingImpl : public AudioProcessing { bool RenderMultiBandSubModulesActive() const; bool RenderFullBandProcessingActive() const; bool RenderMultiBandProcessingActive() const; + bool LowCutFilteringRequired() const; private: const bool capture_post_processor_enabled_ = false; const bool render_pre_processor_enabled_ = false; const bool capture_analyzer_enabled_ = false; - bool low_cut_filter_enabled_ = false; + bool high_pass_filter_enabled_ = false; bool echo_canceller_enabled_ = false; bool mobile_echo_controller_enabled_ = false; bool residual_echo_detector_enabled_ = false; diff --git a/modules/audio_processing/audio_processing_unittest.cc b/modules/audio_processing/audio_processing_unittest.cc index adee5a9c89..3f0decc957 100644 --- a/modules/audio_processing/audio_processing_unittest.cc +++ b/modules/audio_processing/audio_processing_unittest.cc @@ -1410,33 +1410,12 @@ TEST_F(ApmTest, SplittingFilter) { EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false)); EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false)); - // 5. Not using super-wb. - frame_->samples_per_channel_ = 160; - frame_->num_channels_ = 2; - frame_->sample_rate_hz_ = 16000; - // Enable AEC, which would require the filter in super-wb. We rely on the - // first few frames of data being unaffected by the AEC. - // TODO(andrew): This test, and the one below, rely rather tenuously on the - // behavior of the AEC. Think of something more robust. + // Check the test is valid. We should have distortion from the filter + // when AEC is enabled (which won't affect the audio). AudioProcessing::Config apm_config = apm_->GetConfig(); apm_config.echo_canceller.enabled = true; apm_config.echo_canceller.mobile_mode = false; apm_->ApplyConfig(apm_config); - // Make sure we have extended filter enabled. This makes sure nothing is - // touched until we have a farend frame. - Config config; - config.Set(new ExtendedFilter(true)); - apm_->SetExtraOptions(config); - SetFrameTo(frame_, 1000); - frame_copy.CopyFrom(*frame_); - EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0)); - EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_)); - EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0)); - EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_)); - EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy)); - - // Check the test is valid. We should have distortion from the filter - // when AEC is enabled (which won't affect the audio). frame_->samples_per_channel_ = 320; frame_->num_channels_ = 2; frame_->sample_rate_hz_ = 32000;