This CL introduces the new functionality for setting

the APM parameters to the high-pass filter.

The introduction will be done in three steps:
1) This CL which introduces the new scheme and
 changes the code in webrtcvoiceengine.cc to use it.
2) Introduce the scheme into upstream code.
3) Remove the HighPassFilter interface in APM.

BUG=webrtc::6220, webrtc::6296, webrtc::6297, webrtc::6181, webrtc::5298

Review-Url: https://codereview.webrtc.org/2415403002
Cr-Commit-Position: refs/heads/master@{#15197}
This commit is contained in:
peah
2016-11-22 07:24:52 -08:00
committed by Commit bot
parent 30a12fbbb9
commit 8271d04009
17 changed files with 191 additions and 172 deletions

View File

@ -825,14 +825,6 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) {
} }
} }
if (options.highpass_filter) {
LOG(LS_INFO) << "High pass filter enabled? " << *options.highpass_filter;
if (voep->EnableHighPassFilter(*options.highpass_filter) == -1) {
LOG_RTCERR1(SetHighpassFilterStatus, *options.highpass_filter);
return false;
}
}
if (options.stereo_swapping) { if (options.stereo_swapping) {
LOG(LS_INFO) << "Stereo swapping enabled? " << *options.stereo_swapping; LOG(LS_INFO) << "Stereo swapping enabled? " << *options.stereo_swapping;
voep->EnableStereoChannelSwapping(*options.stereo_swapping); voep->EnableStereoChannelSwapping(*options.stereo_swapping);
@ -920,6 +912,10 @@ bool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) {
} }
} }
if (options.highpass_filter) {
apm_config_.high_pass_filter.enabled = *options.highpass_filter;
}
apm()->SetExtraOptions(config); apm()->SetExtraOptions(config);
apm()->ApplyConfig(apm_config_); apm()->ApplyConfig(apm_config_);

View File

@ -89,6 +89,10 @@ class WebRtcVoiceEngine final : public webrtc::TraceCallback {
// Stops AEC dump. // Stops AEC dump.
void StopAecDump(); void StopAecDump();
const webrtc::AudioProcessing::Config& GetApmConfigForTest() const {
return apm_config_;
}
private: private:
// Every option that is "set" will be applied. Every option not "set" will be // Every option that is "set" will be applied. Every option not "set" will be
// ignored. This allows us to selectively turn on and off different options // ignored. This allows us to selectively turn on and off different options

View File

@ -571,6 +571,10 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
} }
} }
bool IsHighPassFilterEnabled() {
return engine_->GetApmConfigForTest().high_pass_filter.enabled;
}
protected: protected:
StrictMock<webrtc::test::MockAudioDeviceModule> adm_; StrictMock<webrtc::test::MockAudioDeviceModule> adm_;
StrictMock<webrtc::test::MockAudioProcessing> apm_; StrictMock<webrtc::test::MockAudioProcessing> apm_;
@ -2793,7 +2797,6 @@ TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
webrtc::AgcConfig agc_config; webrtc::AgcConfig agc_config;
bool ns_enabled; bool ns_enabled;
webrtc::NsModes ns_mode; webrtc::NsModes ns_mode;
bool highpass_filter_enabled;
bool stereo_swapping_enabled; bool stereo_swapping_enabled;
bool typing_detection_enabled; bool typing_detection_enabled;
voe_.GetEcStatus(ec_enabled, ec_mode); voe_.GetEcStatus(ec_enabled, ec_mode);
@ -2801,7 +2804,6 @@ TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
voe_.GetAgcStatus(agc_enabled, agc_mode); voe_.GetAgcStatus(agc_enabled, agc_mode);
voe_.GetAgcConfig(agc_config); voe_.GetAgcConfig(agc_config);
voe_.GetNsStatus(ns_enabled, ns_mode); voe_.GetNsStatus(ns_enabled, ns_mode);
highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled(); stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
voe_.GetTypingDetectionStatus(typing_detection_enabled); voe_.GetTypingDetectionStatus(typing_detection_enabled);
EXPECT_TRUE(ec_enabled); EXPECT_TRUE(ec_enabled);
@ -2810,7 +2812,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
EXPECT_TRUE(agc_enabled); EXPECT_TRUE(agc_enabled);
EXPECT_EQ(0, agc_config.targetLeveldBOv); EXPECT_EQ(0, agc_config.targetLeveldBOv);
EXPECT_TRUE(ns_enabled); EXPECT_TRUE(ns_enabled);
EXPECT_TRUE(highpass_filter_enabled); EXPECT_TRUE(IsHighPassFilterEnabled());
EXPECT_FALSE(stereo_swapping_enabled); EXPECT_FALSE(stereo_swapping_enabled);
EXPECT_TRUE(typing_detection_enabled); EXPECT_TRUE(typing_detection_enabled);
EXPECT_EQ(ec_mode, webrtc::kEcConference); EXPECT_EQ(ec_mode, webrtc::kEcConference);
@ -2826,7 +2828,6 @@ TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
voe_.GetAgcStatus(agc_enabled, agc_mode); voe_.GetAgcStatus(agc_enabled, agc_mode);
voe_.GetAgcConfig(agc_config); voe_.GetAgcConfig(agc_config);
voe_.GetNsStatus(ns_enabled, ns_mode); voe_.GetNsStatus(ns_enabled, ns_mode);
highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled(); stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
voe_.GetTypingDetectionStatus(typing_detection_enabled); voe_.GetTypingDetectionStatus(typing_detection_enabled);
EXPECT_TRUE(ec_enabled); EXPECT_TRUE(ec_enabled);
@ -2835,7 +2836,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
EXPECT_TRUE(agc_enabled); EXPECT_TRUE(agc_enabled);
EXPECT_EQ(0, agc_config.targetLeveldBOv); EXPECT_EQ(0, agc_config.targetLeveldBOv);
EXPECT_TRUE(ns_enabled); EXPECT_TRUE(ns_enabled);
EXPECT_TRUE(highpass_filter_enabled); EXPECT_TRUE(IsHighPassFilterEnabled());
EXPECT_FALSE(stereo_swapping_enabled); EXPECT_FALSE(stereo_swapping_enabled);
EXPECT_TRUE(typing_detection_enabled); EXPECT_TRUE(typing_detection_enabled);
EXPECT_EQ(ec_mode, webrtc::kEcConference); EXPECT_EQ(ec_mode, webrtc::kEcConference);
@ -2858,7 +2859,6 @@ TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
voe_.GetAgcStatus(agc_enabled, agc_mode); voe_.GetAgcStatus(agc_enabled, agc_mode);
voe_.GetAgcConfig(agc_config); voe_.GetAgcConfig(agc_config);
voe_.GetNsStatus(ns_enabled, ns_mode); voe_.GetNsStatus(ns_enabled, ns_mode);
highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled(); stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
voe_.GetTypingDetectionStatus(typing_detection_enabled); voe_.GetTypingDetectionStatus(typing_detection_enabled);
EXPECT_TRUE(ec_enabled); EXPECT_TRUE(ec_enabled);
@ -2866,7 +2866,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
EXPECT_TRUE(agc_enabled); EXPECT_TRUE(agc_enabled);
EXPECT_EQ(0, agc_config.targetLeveldBOv); EXPECT_EQ(0, agc_config.targetLeveldBOv);
EXPECT_TRUE(ns_enabled); EXPECT_TRUE(ns_enabled);
EXPECT_TRUE(highpass_filter_enabled); EXPECT_TRUE(IsHighPassFilterEnabled());
EXPECT_FALSE(stereo_swapping_enabled); EXPECT_FALSE(stereo_swapping_enabled);
EXPECT_TRUE(typing_detection_enabled); EXPECT_TRUE(typing_detection_enabled);
EXPECT_EQ(ec_mode, webrtc::kEcConference); EXPECT_EQ(ec_mode, webrtc::kEcConference);
@ -2919,11 +2919,10 @@ TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true); send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
SetSendParameters(send_parameters_); SetSendParameters(send_parameters_);
voe_.GetNsStatus(ns_enabled, ns_mode); voe_.GetNsStatus(ns_enabled, ns_mode);
highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled(); stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
voe_.GetTypingDetectionStatus(typing_detection_enabled); voe_.GetTypingDetectionStatus(typing_detection_enabled);
EXPECT_FALSE(ns_enabled); EXPECT_FALSE(ns_enabled);
EXPECT_FALSE(highpass_filter_enabled); EXPECT_FALSE(IsHighPassFilterEnabled());
EXPECT_FALSE(typing_detection_enabled); EXPECT_FALSE(typing_detection_enabled);
EXPECT_TRUE(stereo_swapping_enabled); EXPECT_TRUE(stereo_swapping_enabled);
@ -2946,20 +2945,18 @@ TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
webrtc::AgcModes agc_mode; webrtc::AgcModes agc_mode;
bool ns_enabled; bool ns_enabled;
webrtc::NsModes ns_mode; webrtc::NsModes ns_mode;
bool highpass_filter_enabled;
bool stereo_swapping_enabled; bool stereo_swapping_enabled;
bool typing_detection_enabled; bool typing_detection_enabled;
voe_.GetEcStatus(ec_enabled, ec_mode); voe_.GetEcStatus(ec_enabled, ec_mode);
voe_.GetAgcStatus(agc_enabled, agc_mode); voe_.GetAgcStatus(agc_enabled, agc_mode);
voe_.GetNsStatus(ns_enabled, ns_mode); voe_.GetNsStatus(ns_enabled, ns_mode);
highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled(); stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
voe_.GetTypingDetectionStatus(typing_detection_enabled); voe_.GetTypingDetectionStatus(typing_detection_enabled);
EXPECT_TRUE(ec_enabled); EXPECT_TRUE(ec_enabled);
EXPECT_TRUE(agc_enabled); EXPECT_TRUE(agc_enabled);
EXPECT_TRUE(ns_enabled); EXPECT_TRUE(ns_enabled);
EXPECT_TRUE(highpass_filter_enabled); EXPECT_TRUE(IsHighPassFilterEnabled());
EXPECT_TRUE(typing_detection_enabled); EXPECT_TRUE(typing_detection_enabled);
EXPECT_FALSE(stereo_swapping_enabled); EXPECT_FALSE(stereo_swapping_enabled);
} }

View File

@ -600,9 +600,9 @@ if (rtc_include_tests) {
"audio_processing/echo_detector/mean_variance_estimator_unittest.cc", "audio_processing/echo_detector/mean_variance_estimator_unittest.cc",
"audio_processing/echo_detector/normalized_covariance_estimator_unittest.cc", "audio_processing/echo_detector/normalized_covariance_estimator_unittest.cc",
"audio_processing/gain_control_unittest.cc", "audio_processing/gain_control_unittest.cc",
"audio_processing/high_pass_filter_unittest.cc",
"audio_processing/level_controller/level_controller_unittest.cc", "audio_processing/level_controller/level_controller_unittest.cc",
"audio_processing/level_estimator_unittest.cc", "audio_processing/level_estimator_unittest.cc",
"audio_processing/low_cut_filter_unittest.cc",
"audio_processing/noise_suppression_unittest.cc", "audio_processing/noise_suppression_unittest.cc",
"audio_processing/residual_echo_detector_unittest.cc", "audio_processing/residual_echo_detector_unittest.cc",
"audio_processing/test/bitexactness_tools.cc", "audio_processing/test/bitexactness_tools.cc",

View File

@ -71,8 +71,6 @@ rtc_static_library("audio_processing") {
"gain_control_for_experimental_agc.h", "gain_control_for_experimental_agc.h",
"gain_control_impl.cc", "gain_control_impl.cc",
"gain_control_impl.h", "gain_control_impl.h",
"high_pass_filter_impl.cc",
"high_pass_filter_impl.h",
"include/audio_processing.cc", "include/audio_processing.cc",
"include/audio_processing.h", "include/audio_processing.h",
"include/config.cc", "include/config.cc",
@ -102,6 +100,8 @@ rtc_static_library("audio_processing") {
"level_estimator_impl.h", "level_estimator_impl.h",
"logging/apm_data_dumper.cc", "logging/apm_data_dumper.cc",
"logging/apm_data_dumper.h", "logging/apm_data_dumper.h",
"low_cut_filter.cc",
"low_cut_filter.h",
"noise_suppression_impl.cc", "noise_suppression_impl.cc",
"noise_suppression_impl.h", "noise_suppression_impl.h",
"render_queue_item_verifier.h", "render_queue_item_verifier.h",

View File

@ -28,12 +28,12 @@
#include "webrtc/modules/audio_processing/echo_control_mobile_impl.h" #include "webrtc/modules/audio_processing/echo_control_mobile_impl.h"
#include "webrtc/modules/audio_processing/gain_control_for_experimental_agc.h" #include "webrtc/modules/audio_processing/gain_control_for_experimental_agc.h"
#include "webrtc/modules/audio_processing/gain_control_impl.h" #include "webrtc/modules/audio_processing/gain_control_impl.h"
#include "webrtc/modules/audio_processing/high_pass_filter_impl.h"
#if WEBRTC_INTELLIGIBILITY_ENHANCER #if WEBRTC_INTELLIGIBILITY_ENHANCER
#include "webrtc/modules/audio_processing/intelligibility/intelligibility_enhancer.h" #include "webrtc/modules/audio_processing/intelligibility/intelligibility_enhancer.h"
#endif #endif
#include "webrtc/modules/audio_processing/level_controller/level_controller.h" #include "webrtc/modules/audio_processing/level_controller/level_controller.h"
#include "webrtc/modules/audio_processing/level_estimator_impl.h" #include "webrtc/modules/audio_processing/level_estimator_impl.h"
#include "webrtc/modules/audio_processing/low_cut_filter.h"
#include "webrtc/modules/audio_processing/noise_suppression_impl.h" #include "webrtc/modules/audio_processing/noise_suppression_impl.h"
#include "webrtc/modules/audio_processing/residual_echo_detector.h" #include "webrtc/modules/audio_processing/residual_echo_detector.h"
#include "webrtc/modules/audio_processing/transient/transient_suppressor.h" #include "webrtc/modules/audio_processing/transient/transient_suppressor.h"
@ -127,6 +127,29 @@ static const size_t kMaxAllowedValuesOfSamplesPerFrame = 160;
// reverse and forward call numbers. // reverse and forward call numbers.
static const size_t kMaxNumFramesToBuffer = 100; static const size_t kMaxNumFramesToBuffer = 100;
class HighPassFilterImpl : public HighPassFilter {
public:
explicit HighPassFilterImpl(AudioProcessingImpl* apm) : apm_(apm) {}
~HighPassFilterImpl() override = default;
// HighPassFilter implementation.
int Enable(bool enable) override {
apm_->MutateConfig([enable](AudioProcessing::Config* config) {
config->high_pass_filter.enabled = enable;
});
return AudioProcessing::kNoError;
}
bool is_enabled() const override {
return apm_->GetConfig().high_pass_filter.enabled;
}
private:
AudioProcessingImpl* apm_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(HighPassFilterImpl);
};
} // namespace } // namespace
// Throughout webrtc, it's assumed that success is represented by zero. // Throughout webrtc, it's assumed that success is represented by zero.
@ -135,7 +158,7 @@ static_assert(AudioProcessing::kNoError == 0, "kNoError must be zero");
AudioProcessingImpl::ApmSubmoduleStates::ApmSubmoduleStates() {} AudioProcessingImpl::ApmSubmoduleStates::ApmSubmoduleStates() {}
bool AudioProcessingImpl::ApmSubmoduleStates::Update( bool AudioProcessingImpl::ApmSubmoduleStates::Update(
bool high_pass_filter_enabled, bool low_cut_filter_enabled,
bool echo_canceller_enabled, bool echo_canceller_enabled,
bool mobile_echo_controller_enabled, bool mobile_echo_controller_enabled,
bool residual_echo_detector_enabled, bool residual_echo_detector_enabled,
@ -148,7 +171,7 @@ bool AudioProcessingImpl::ApmSubmoduleStates::Update(
bool level_estimator_enabled, bool level_estimator_enabled,
bool transient_suppressor_enabled) { bool transient_suppressor_enabled) {
bool changed = false; bool changed = false;
changed |= (high_pass_filter_enabled != high_pass_filter_enabled_); changed |= (low_cut_filter_enabled != low_cut_filter_enabled_);
changed |= (echo_canceller_enabled != echo_canceller_enabled_); changed |= (echo_canceller_enabled != echo_canceller_enabled_);
changed |= changed |=
(mobile_echo_controller_enabled != mobile_echo_controller_enabled_); (mobile_echo_controller_enabled != mobile_echo_controller_enabled_);
@ -166,7 +189,7 @@ bool AudioProcessingImpl::ApmSubmoduleStates::Update(
(voice_activity_detector_enabled != voice_activity_detector_enabled_); (voice_activity_detector_enabled != voice_activity_detector_enabled_);
changed |= (transient_suppressor_enabled != transient_suppressor_enabled_); changed |= (transient_suppressor_enabled != transient_suppressor_enabled_);
if (changed) { if (changed) {
high_pass_filter_enabled_ = high_pass_filter_enabled; low_cut_filter_enabled_ = low_cut_filter_enabled;
echo_canceller_enabled_ = echo_canceller_enabled; echo_canceller_enabled_ = echo_canceller_enabled;
mobile_echo_controller_enabled_ = mobile_echo_controller_enabled; mobile_echo_controller_enabled_ = mobile_echo_controller_enabled;
residual_echo_detector_enabled_ = residual_echo_detector_enabled; residual_echo_detector_enabled_ = residual_echo_detector_enabled;
@ -199,7 +222,7 @@ bool AudioProcessingImpl::ApmSubmoduleStates::CaptureMultiBandSubModulesActive()
bool AudioProcessingImpl::ApmSubmoduleStates::CaptureMultiBandProcessingActive() bool AudioProcessingImpl::ApmSubmoduleStates::CaptureMultiBandProcessingActive()
const { const {
return high_pass_filter_enabled_ || echo_canceller_enabled_ || return low_cut_filter_enabled_ || echo_canceller_enabled_ ||
mobile_echo_controller_enabled_ || noise_suppressor_enabled_ || mobile_echo_controller_enabled_ || noise_suppressor_enabled_ ||
beamformer_enabled_ || adaptive_gain_controller_enabled_; beamformer_enabled_ || adaptive_gain_controller_enabled_;
} }
@ -226,7 +249,6 @@ struct AudioProcessingImpl::ApmPublicSubmodules {
std::unique_ptr<EchoCancellationImpl> echo_cancellation; std::unique_ptr<EchoCancellationImpl> echo_cancellation;
std::unique_ptr<EchoControlMobileImpl> echo_control_mobile; std::unique_ptr<EchoControlMobileImpl> echo_control_mobile;
std::unique_ptr<GainControlImpl> gain_control; std::unique_ptr<GainControlImpl> gain_control;
std::unique_ptr<HighPassFilterImpl> high_pass_filter;
std::unique_ptr<LevelEstimatorImpl> level_estimator; std::unique_ptr<LevelEstimatorImpl> level_estimator;
std::unique_ptr<NoiseSuppressionImpl> noise_suppression; std::unique_ptr<NoiseSuppressionImpl> noise_suppression;
std::unique_ptr<VoiceDetectionImpl> voice_detection; std::unique_ptr<VoiceDetectionImpl> voice_detection;
@ -246,6 +268,7 @@ struct AudioProcessingImpl::ApmPrivateSubmodules {
// Accessed internally from capture or during initialization // Accessed internally from capture or during initialization
std::unique_ptr<NonlinearBeamformer> beamformer; std::unique_ptr<NonlinearBeamformer> beamformer;
std::unique_ptr<AgcManagerDirect> agc_manager; std::unique_ptr<AgcManagerDirect> agc_manager;
std::unique_ptr<LowCutFilter> low_cut_filter;
std::unique_ptr<LevelController> level_controller; std::unique_ptr<LevelController> level_controller;
std::unique_ptr<ResidualEchoDetector> residual_echo_detector; std::unique_ptr<ResidualEchoDetector> residual_echo_detector;
}; };
@ -275,7 +298,8 @@ AudioProcessingImpl::AudioProcessingImpl(const webrtc::Config& config)
AudioProcessingImpl::AudioProcessingImpl(const webrtc::Config& config, AudioProcessingImpl::AudioProcessingImpl(const webrtc::Config& config,
NonlinearBeamformer* beamformer) NonlinearBeamformer* beamformer)
: public_submodules_(new ApmPublicSubmodules()), : high_pass_filter_impl_(new HighPassFilterImpl(this)),
public_submodules_(new ApmPublicSubmodules()),
private_submodules_(new ApmPrivateSubmodules(beamformer)), private_submodules_(new ApmPrivateSubmodules(beamformer)),
constants_(config.Get<ExperimentalAgc>().startup_min_volume, constants_(config.Get<ExperimentalAgc>().startup_min_volume,
#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
@ -302,8 +326,6 @@ AudioProcessingImpl::AudioProcessingImpl(const webrtc::Config& config,
new EchoControlMobileImpl(&crit_render_, &crit_capture_)); new EchoControlMobileImpl(&crit_render_, &crit_capture_));
public_submodules_->gain_control.reset( public_submodules_->gain_control.reset(
new GainControlImpl(&crit_capture_, &crit_capture_)); new GainControlImpl(&crit_capture_, &crit_capture_));
public_submodules_->high_pass_filter.reset(
new HighPassFilterImpl(&crit_capture_));
public_submodules_->level_estimator.reset( public_submodules_->level_estimator.reset(
new LevelEstimatorImpl(&crit_capture_)); new LevelEstimatorImpl(&crit_capture_));
public_submodules_->noise_suppression.reset( public_submodules_->noise_suppression.reset(
@ -478,8 +500,7 @@ int AudioProcessingImpl::InitializeLocked() {
#if WEBRTC_INTELLIGIBILITY_ENHANCER #if WEBRTC_INTELLIGIBILITY_ENHANCER
InitializeIntelligibility(); InitializeIntelligibility();
#endif #endif
public_submodules_->high_pass_filter->Initialize(num_proc_channels(), InitializeLowCutFilter();
proc_sample_rate_hz());
public_submodules_->noise_suppression->Initialize(num_proc_channels(), public_submodules_->noise_suppression->Initialize(num_proc_channels(),
proc_sample_rate_hz()); proc_sample_rate_hz());
public_submodules_->voice_detection->Initialize(proc_split_sample_rate_hz()); public_submodules_->voice_detection->Initialize(proc_split_sample_rate_hz());
@ -602,6 +623,11 @@ void AudioProcessingImpl::ApplyConfig(const AudioProcessing::Config& config) {
<< capture_nonlocked_.level_controller_enabled; << capture_nonlocked_.level_controller_enabled;
private_submodules_->level_controller->ApplyConfig(config_.level_controller); private_submodules_->level_controller->ApplyConfig(config_.level_controller);
InitializeLowCutFilter();
LOG(LS_INFO) << "Highpass filter activated: "
<< config_.high_pass_filter.enabled;
} }
void AudioProcessingImpl::SetExtraOptions(const webrtc::Config& config) { void AudioProcessingImpl::SetExtraOptions(const webrtc::Config& config) {
@ -1089,7 +1115,9 @@ int AudioProcessingImpl::ProcessCaptureStreamLocked() {
capture_buffer->set_num_channels(1); capture_buffer->set_num_channels(1);
} }
public_submodules_->high_pass_filter->ProcessCaptureAudio(capture_buffer); if (private_submodules_->low_cut_filter) {
private_submodules_->low_cut_filter->Process(capture_buffer);
}
RETURN_ON_ERR( RETURN_ON_ERR(
public_submodules_->gain_control->AnalyzeCaptureAudio(capture_buffer)); public_submodules_->gain_control->AnalyzeCaptureAudio(capture_buffer));
public_submodules_->noise_suppression->AnalyzeCaptureAudio(capture_buffer); public_submodules_->noise_suppression->AnalyzeCaptureAudio(capture_buffer);
@ -1523,7 +1551,7 @@ GainControl* AudioProcessingImpl::gain_control() const {
} }
HighPassFilter* AudioProcessingImpl::high_pass_filter() const { HighPassFilter* AudioProcessingImpl::high_pass_filter() const {
return public_submodules_->high_pass_filter.get(); return high_pass_filter_impl_.get();
} }
LevelEstimator* AudioProcessingImpl::level_estimator() const { LevelEstimator* AudioProcessingImpl::level_estimator() const {
@ -1538,9 +1566,23 @@ VoiceDetection* AudioProcessingImpl::voice_detection() const {
return public_submodules_->voice_detection.get(); return public_submodules_->voice_detection.get();
} }
void AudioProcessingImpl::MutateConfig(
rtc::FunctionView<void(AudioProcessing::Config*)> mutator) {
rtc::CritScope cs_render(&crit_render_);
rtc::CritScope cs_capture(&crit_capture_);
mutator(&config_);
ApplyConfig(config_);
}
AudioProcessing::Config AudioProcessingImpl::GetConfig() const {
rtc::CritScope cs_render(&crit_render_);
rtc::CritScope cs_capture(&crit_capture_);
return config_;
}
bool AudioProcessingImpl::UpdateActiveSubmoduleStates() { bool AudioProcessingImpl::UpdateActiveSubmoduleStates() {
return submodule_states_.Update( return submodule_states_.Update(
public_submodules_->high_pass_filter->is_enabled(), config_.high_pass_filter.enabled,
public_submodules_->echo_cancellation->is_enabled(), public_submodules_->echo_cancellation->is_enabled(),
public_submodules_->echo_control_mobile->is_enabled(), public_submodules_->echo_control_mobile->is_enabled(),
config_.residual_echo_detector.enabled, config_.residual_echo_detector.enabled,
@ -1589,6 +1631,15 @@ void AudioProcessingImpl::InitializeIntelligibility() {
#endif #endif
} }
void AudioProcessingImpl::InitializeLowCutFilter() {
if (config_.high_pass_filter.enabled) {
private_submodules_->low_cut_filter.reset(
new LowCutFilter(num_proc_channels(), proc_sample_rate_hz()));
} else {
private_submodules_->low_cut_filter.reset();
}
}
void AudioProcessingImpl::InitializeLevelController() { void AudioProcessingImpl::InitializeLevelController() {
private_submodules_->level_controller->Initialize(proc_sample_rate_hz()); private_submodules_->level_controller->Initialize(proc_sample_rate_hz());
} }
@ -1772,7 +1823,7 @@ int AudioProcessingImpl::WriteConfigMessage(bool forced) {
public_submodules_->gain_control->is_limiter_enabled()); public_submodules_->gain_control->is_limiter_enabled());
config.set_noise_robust_agc_enabled(constants_.use_experimental_agc); config.set_noise_robust_agc_enabled(constants_.use_experimental_agc);
config.set_hpf_enabled(public_submodules_->high_pass_filter->is_enabled()); config.set_hpf_enabled(config_.high_pass_filter.enabled);
config.set_ns_enabled(public_submodules_->noise_suppression->is_enabled()); config.set_ns_enabled(public_submodules_->noise_suppression->is_enabled());
config.set_ns_level( config.set_ns_level(

View File

@ -17,6 +17,7 @@
#include <vector> #include <vector>
#include "webrtc/base/criticalsection.h" #include "webrtc/base/criticalsection.h"
#include "webrtc/base/function_view.h"
#include "webrtc/base/gtest_prod_util.h" #include "webrtc/base/gtest_prod_util.h"
#include "webrtc/base/ignore_wundef.h" #include "webrtc/base/ignore_wundef.h"
#include "webrtc/base/swap_queue.h" #include "webrtc/base/swap_queue.h"
@ -126,11 +127,16 @@ class AudioProcessingImpl : public AudioProcessing {
EchoCancellation* echo_cancellation() const override; EchoCancellation* echo_cancellation() const override;
EchoControlMobile* echo_control_mobile() const override; EchoControlMobile* echo_control_mobile() const override;
GainControl* gain_control() const override; GainControl* gain_control() const override;
// TODO(peah): Deprecate this API call.
HighPassFilter* high_pass_filter() const override; HighPassFilter* high_pass_filter() const override;
LevelEstimator* level_estimator() const override; LevelEstimator* level_estimator() const override;
NoiseSuppression* noise_suppression() const override; NoiseSuppression* noise_suppression() const override;
VoiceDetection* voice_detection() const override; VoiceDetection* voice_detection() const override;
// TODO(peah): Remove these two methods once the new API allows that.
void MutateConfig(rtc::FunctionView<void(AudioProcessing::Config*)> mutator);
AudioProcessing::Config GetConfig() const;
protected: protected:
// Overridden in a mock. // Overridden in a mock.
virtual int InitializeLocked() virtual int InitializeLocked()
@ -145,11 +151,14 @@ class AudioProcessingImpl : public AudioProcessing {
struct ApmPublicSubmodules; struct ApmPublicSubmodules;
struct ApmPrivateSubmodules; struct ApmPrivateSubmodules;
// Submodule interface implementations.
std::unique_ptr<HighPassFilter> high_pass_filter_impl_;
class ApmSubmoduleStates { class ApmSubmoduleStates {
public: public:
ApmSubmoduleStates(); ApmSubmoduleStates();
// Updates the submodule state and returns true if it has changed. // Updates the submodule state and returns true if it has changed.
bool Update(bool high_pass_filter_enabled, bool Update(bool low_cut_filter_enabled,
bool echo_canceller_enabled, bool echo_canceller_enabled,
bool mobile_echo_controller_enabled, bool mobile_echo_controller_enabled,
bool residual_echo_detector_enabled, bool residual_echo_detector_enabled,
@ -167,7 +176,7 @@ class AudioProcessingImpl : public AudioProcessing {
bool RenderMultiBandProcessingActive() const; bool RenderMultiBandProcessingActive() const;
private: private:
bool high_pass_filter_enabled_ = false; bool low_cut_filter_enabled_ = false;
bool echo_canceller_enabled_ = false; bool echo_canceller_enabled_ = false;
bool mobile_echo_controller_enabled_ = false; bool mobile_echo_controller_enabled_ = false;
bool residual_echo_detector_enabled_ = false; bool residual_echo_detector_enabled_ = false;
@ -240,6 +249,7 @@ class AudioProcessingImpl : public AudioProcessing {
void InitializeLevelController() EXCLUSIVE_LOCKS_REQUIRED(crit_capture_); void InitializeLevelController() EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
void InitializeResidualEchoDetector() void InitializeResidualEchoDetector()
EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_); EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
void InitializeLowCutFilter() EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
void EmptyQueuedRenderAudio(); void EmptyQueuedRenderAudio();
void AllocateRenderQueue() void AllocateRenderQueue()

View File

@ -185,7 +185,10 @@ void EnableAllAPComponents(AudioProcessing* ap) {
EXPECT_NOERR(ap->gain_control()->Enable(true)); EXPECT_NOERR(ap->gain_control()->Enable(true));
#endif #endif
EXPECT_NOERR(ap->high_pass_filter()->Enable(true)); AudioProcessing::Config apm_config;
apm_config.high_pass_filter.enabled = true;
ap->ApplyConfig(apm_config);
EXPECT_NOERR(ap->level_estimator()->Enable(true)); EXPECT_NOERR(ap->level_estimator()->Enable(true));
EXPECT_NOERR(ap->noise_suppression()->Enable(true)); EXPECT_NOERR(ap->noise_suppression()->Enable(true));
@ -1391,10 +1394,11 @@ TEST_F(ApmTest, NoiseSuppression) {
TEST_F(ApmTest, HighPassFilter) { TEST_F(ApmTest, HighPassFilter) {
// Turn HP filter on/off // Turn HP filter on/off
EXPECT_EQ(apm_->kNoError, apm_->high_pass_filter()->Enable(true)); AudioProcessing::Config apm_config;
EXPECT_TRUE(apm_->high_pass_filter()->is_enabled()); apm_config.high_pass_filter.enabled = true;
EXPECT_EQ(apm_->kNoError, apm_->high_pass_filter()->Enable(false)); apm_->ApplyConfig(apm_config);
EXPECT_FALSE(apm_->high_pass_filter()->is_enabled()); apm_config.high_pass_filter.enabled = false;
apm_->ApplyConfig(apm_config);
} }
TEST_F(ApmTest, LevelEstimator) { TEST_F(ApmTest, LevelEstimator) {

View File

@ -1,47 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_HIGH_PASS_FILTER_IMPL_H_
#define WEBRTC_MODULES_AUDIO_PROCESSING_HIGH_PASS_FILTER_IMPL_H_
#include <memory>
#include <vector>
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/modules/audio_processing/include/audio_processing.h"
namespace webrtc {
class AudioBuffer;
class HighPassFilterImpl : public HighPassFilter {
public:
explicit HighPassFilterImpl(rtc::CriticalSection* crit);
~HighPassFilterImpl() override;
// TODO(peah): Fold into ctor, once public API is removed.
void Initialize(size_t channels, int sample_rate_hz);
void ProcessCaptureAudio(AudioBuffer* audio);
// HighPassFilter implementation.
int Enable(bool enable) override;
bool is_enabled() const override;
private:
class BiquadFilter;
rtc::CriticalSection* const crit_ = nullptr;
bool enabled_ GUARDED_BY(crit_) = false;
std::vector<std::unique_ptr<BiquadFilter>> filters_ GUARDED_BY(crit_);
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(HighPassFilterImpl);
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_HIGH_PASS_FILTER_IMPL_H_

View File

@ -199,10 +199,9 @@ struct Intelligibility {
// //
// AudioProcessing::Config config; // AudioProcessing::Config config;
// config.level_controller.enabled = true; // config.level_controller.enabled = true;
// config.high_pass_filter.enabled = true;
// apm->ApplyConfig(config) // apm->ApplyConfig(config)
// //
// apm->high_pass_filter()->Enable(true);
//
// apm->echo_cancellation()->enable_drift_compensation(false); // apm->echo_cancellation()->enable_drift_compensation(false);
// apm->echo_cancellation()->Enable(true); // apm->echo_cancellation()->Enable(true);
// //
@ -265,6 +264,10 @@ class AudioProcessing {
bool enabled = true; bool enabled = true;
#endif #endif
} residual_echo_detector; } residual_echo_detector;
struct HighPassFilter {
bool enabled = false;
} high_pass_filter;
}; };
// TODO(mgraczyk): Remove once all methods that use ChannelLayout are gone. // TODO(mgraczyk): Remove once all methods that use ChannelLayout are gone.
@ -554,6 +557,7 @@ class AudioProcessing {
virtual EchoCancellation* echo_cancellation() const = 0; virtual EchoCancellation* echo_cancellation() const = 0;
virtual EchoControlMobile* echo_control_mobile() const = 0; virtual EchoControlMobile* echo_control_mobile() const = 0;
virtual GainControl* gain_control() const = 0; virtual GainControl* gain_control() const = 0;
// TODO(peah): Deprecate this API call.
virtual HighPassFilter* high_pass_filter() const = 0; virtual HighPassFilter* high_pass_filter() const = 0;
virtual LevelEstimator* level_estimator() const = 0; virtual LevelEstimator* level_estimator() const = 0;
virtual NoiseSuppression* noise_suppression() const = 0; virtual NoiseSuppression* noise_suppression() const = 0;
@ -960,7 +964,7 @@ class GainControl {
protected: protected:
virtual ~GainControl() {} virtual ~GainControl() {}
}; };
// TODO(peah): Remove this interface.
// A filtering component which removes DC offset and low-frequency noise. // A filtering component which removes DC offset and low-frequency noise.
// Recommended to be enabled on the client-side. // Recommended to be enabled on the client-side.
class HighPassFilter { class HighPassFilter {
@ -968,7 +972,6 @@ class HighPassFilter {
virtual int Enable(bool enable) = 0; virtual int Enable(bool enable) = 0;
virtual bool is_enabled() const = 0; virtual bool is_enabled() const = 0;
protected:
virtual ~HighPassFilter() {} virtual ~HighPassFilter() {}
}; };

View File

@ -225,8 +225,7 @@ void RunTogetherWithApm(std::string test_description,
ASSERT_EQ(AudioProcessing::kNoError, ASSERT_EQ(AudioProcessing::kNoError,
apm->echo_control_mobile()->Enable(false)); apm->echo_control_mobile()->Enable(false));
} }
ASSERT_EQ(AudioProcessing::kNoError, apm_config.high_pass_filter.enabled = include_default_apm_processing;
apm->high_pass_filter()->Enable(include_default_apm_processing));
ASSERT_EQ(AudioProcessing::kNoError, ASSERT_EQ(AudioProcessing::kNoError,
apm->noise_suppression()->Enable(include_default_apm_processing)); apm->noise_suppression()->Enable(include_default_apm_processing));
ASSERT_EQ(AudioProcessing::kNoError, ASSERT_EQ(AudioProcessing::kNoError,

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "webrtc/modules/audio_processing/high_pass_filter_impl.h" #include "webrtc/modules/audio_processing/low_cut_filter.h"
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/modules/audio_processing/audio_buffer.h" #include "webrtc/modules/audio_processing/audio_buffer.h"
@ -20,16 +20,12 @@ const int16_t kFilterCoefficients8kHz[5] = {3798, -7596, 3798, 7807, -3733};
const int16_t kFilterCoefficients[5] = {4012, -8024, 4012, 8002, -3913}; const int16_t kFilterCoefficients[5] = {4012, -8024, 4012, 8002, -3913};
} // namespace } // namespace
class HighPassFilterImpl::BiquadFilter { class LowCutFilter::BiquadFilter {
public: public:
explicit BiquadFilter(int sample_rate_hz) : explicit BiquadFilter(int sample_rate_hz)
ba_(sample_rate_hz == AudioProcessing::kSampleRate8kHz ? : ba_(sample_rate_hz == AudioProcessing::kSampleRate8kHz
kFilterCoefficients8kHz : kFilterCoefficients) ? kFilterCoefficients8kHz
{ : kFilterCoefficients) {
Reset();
}
void Reset() {
std::memset(x_, 0, sizeof(x_)); std::memset(x_, 0, sizeof(x_));
std::memset(y_, 0, sizeof(y_)); std::memset(y_, 0, sizeof(y_));
} }
@ -44,11 +40,11 @@ class HighPassFilterImpl::BiquadFilter {
// y[i] = b[0] * x[i] + b[1] * x[i-1] + b[2] * x[i-2] // y[i] = b[0] * x[i] + b[1] * x[i-1] + b[2] * x[i-2]
// + -a[1] * y[i-1] + -a[2] * y[i-2]; // + -a[1] * y[i-1] + -a[2] * y[i-2];
tmp_int32 = y[1] * ba[3]; // -a[1] * y[i-1] (low part) tmp_int32 = y[1] * ba[3]; // -a[1] * y[i-1] (low part)
tmp_int32 += y[3] * ba[4]; // -a[2] * y[i-2] (low part) tmp_int32 += y[3] * ba[4]; // -a[2] * y[i-2] (low part)
tmp_int32 = (tmp_int32 >> 15); tmp_int32 = (tmp_int32 >> 15);
tmp_int32 += y[0] * ba[3]; // -a[1] * y[i-1] (high part) tmp_int32 += y[0] * ba[3]; // -a[1] * y[i-1] (high part)
tmp_int32 += y[2] * ba[4]; // -a[2] * y[i-2] (high part) tmp_int32 += y[2] * ba[4]; // -a[2] * y[i-2] (high part)
tmp_int32 = (tmp_int32 << 1); tmp_int32 = (tmp_int32 << 1);
tmp_int32 += data[i] * ba[0]; // b[0] * x[0] tmp_int32 += data[i] * ba[0]; // b[0] * x[0]
@ -70,8 +66,7 @@ class HighPassFilterImpl::BiquadFilter {
tmp_int32 += 2048; tmp_int32 += 2048;
// Saturate (to 2^27) so that the HP filtered signal does not overflow. // Saturate (to 2^27) so that the HP filtered signal does not overflow.
tmp_int32 = WEBRTC_SPL_SAT(static_cast<int32_t>(134217727), tmp_int32 = WEBRTC_SPL_SAT(static_cast<int32_t>(134217727), tmp_int32,
tmp_int32,
static_cast<int32_t>(-134217728)); static_cast<int32_t>(-134217728));
// Convert back to Q0 and use rounding. // Convert back to Q0 and use rounding.
@ -85,29 +80,17 @@ class HighPassFilterImpl::BiquadFilter {
int16_t y_[4]; int16_t y_[4];
}; };
HighPassFilterImpl::HighPassFilterImpl(rtc::CriticalSection* crit) LowCutFilter::LowCutFilter(size_t channels, int sample_rate_hz) {
: crit_(crit) { filters_.resize(channels);
RTC_DCHECK(crit_);
}
HighPassFilterImpl::~HighPassFilterImpl() {}
void HighPassFilterImpl::Initialize(size_t channels, int sample_rate_hz) {
std::vector<std::unique_ptr<BiquadFilter>> new_filters(channels);
for (size_t i = 0; i < channels; i++) { for (size_t i = 0; i < channels; i++) {
new_filters[i].reset(new BiquadFilter(sample_rate_hz)); filters_[i].reset(new BiquadFilter(sample_rate_hz));
} }
rtc::CritScope cs(crit_);
filters_.swap(new_filters);
} }
void HighPassFilterImpl::ProcessCaptureAudio(AudioBuffer* audio) { LowCutFilter::~LowCutFilter() {}
RTC_DCHECK(audio);
rtc::CritScope cs(crit_);
if (!enabled_) {
return;
}
void LowCutFilter::Process(AudioBuffer* audio) {
RTC_DCHECK(audio);
RTC_DCHECK_GE(160u, audio->num_frames_per_band()); RTC_DCHECK_GE(160u, audio->num_frames_per_band());
RTC_DCHECK_EQ(filters_.size(), audio->num_channels()); RTC_DCHECK_EQ(filters_.size(), audio->num_channels());
for (size_t i = 0; i < filters_.size(); i++) { for (size_t i = 0; i < filters_.size(); i++) {
@ -116,19 +99,4 @@ void HighPassFilterImpl::ProcessCaptureAudio(AudioBuffer* audio) {
} }
} }
int HighPassFilterImpl::Enable(bool enable) {
rtc::CritScope cs(crit_);
if (!enabled_ && enable) {
for (auto& filter : filters_) {
filter->Reset();
}
}
enabled_ = enable;
return AudioProcessing::kNoError;
}
bool HighPassFilterImpl::is_enabled() const {
rtc::CritScope cs(crit_);
return enabled_;
}
} // namespace webrtc } // namespace webrtc

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_LOW_CUT_FILTER_H_
#define WEBRTC_MODULES_AUDIO_PROCESSING_LOW_CUT_FILTER_H_
#include <memory>
#include <vector>
#include "webrtc/base/constructormagic.h"
namespace webrtc {
class AudioBuffer;
class LowCutFilter {
public:
LowCutFilter(size_t channels, int sample_rate_hz);
~LowCutFilter();
void Process(AudioBuffer* audio);
private:
class BiquadFilter;
std::vector<std::unique_ptr<BiquadFilter>> filters_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(LowCutFilter);
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_LOW_CUT_FILTER_H_

View File

@ -11,7 +11,7 @@
#include "webrtc/base/array_view.h" #include "webrtc/base/array_view.h"
#include "webrtc/modules/audio_processing/audio_buffer.h" #include "webrtc/modules/audio_processing/audio_buffer.h"
#include "webrtc/modules/audio_processing/high_pass_filter_impl.h" #include "webrtc/modules/audio_processing/low_cut_filter.h"
#include "webrtc/modules/audio_processing/test/audio_buffer_tools.h" #include "webrtc/modules/audio_processing/test/audio_buffer_tools.h"
#include "webrtc/modules/audio_processing/test/bitexactness_tools.h" #include "webrtc/modules/audio_processing/test/bitexactness_tools.h"
#include "webrtc/test/gtest.h" #include "webrtc/test/gtest.h"
@ -22,14 +22,14 @@ namespace {
// Process one frame of data and produce the output. // Process one frame of data and produce the output.
std::vector<float> ProcessOneFrame(const std::vector<float>& frame_input, std::vector<float> ProcessOneFrame(const std::vector<float>& frame_input,
const StreamConfig& stream_config, const StreamConfig& stream_config,
HighPassFilterImpl* high_pass_filter) { LowCutFilter* low_cut_filter) {
AudioBuffer audio_buffer( AudioBuffer audio_buffer(
stream_config.num_frames(), stream_config.num_channels(), stream_config.num_frames(), stream_config.num_channels(),
stream_config.num_frames(), stream_config.num_channels(), stream_config.num_frames(), stream_config.num_channels(),
stream_config.num_frames()); stream_config.num_frames());
test::CopyVectorToAudioBuffer(stream_config, frame_input, &audio_buffer); test::CopyVectorToAudioBuffer(stream_config, frame_input, &audio_buffer);
high_pass_filter->ProcessCaptureAudio(&audio_buffer); low_cut_filter->Process(&audio_buffer);
std::vector<float> frame_output; std::vector<float> frame_output;
test::ExtractVectorFromAudioBuffer(stream_config, &audio_buffer, test::ExtractVectorFromAudioBuffer(stream_config, &audio_buffer,
&frame_output); &frame_output);
@ -43,11 +43,7 @@ void RunBitexactnessTest(int sample_rate,
const std::vector<float>& input, const std::vector<float>& input,
const std::vector<float>& reference) { const std::vector<float>& reference) {
const StreamConfig stream_config(sample_rate, num_channels, false); const StreamConfig stream_config(sample_rate, num_channels, false);
rtc::CriticalSection crit; LowCutFilter low_cut_filter(num_channels, sample_rate);
HighPassFilterImpl high_pass_filter(&crit);
high_pass_filter.Initialize(num_channels, sample_rate);
high_pass_filter.Enable(true);
std::vector<float> output; std::vector<float> output;
const size_t num_frames_to_process = const size_t num_frames_to_process =
@ -62,7 +58,7 @@ void RunBitexactnessTest(int sample_rate,
stream_config.num_frames() * stream_config.num_channels() * stream_config.num_frames() * stream_config.num_channels() *
(frame_no + 1)); (frame_no + 1));
output = ProcessOneFrame(frame_input, stream_config, &high_pass_filter); output = ProcessOneFrame(frame_input, stream_config, &low_cut_filter);
} }
// Form vector to compare the reference to. Only the last frame processed // Form vector to compare the reference to. Only the last frame processed
@ -98,7 +94,7 @@ std::vector<float> CreateVector(const rtc::ArrayView<const float>& array_view) {
} }
} // namespace } // namespace
TEST(HighPassFilterBitExactnessTest, Mono8kHzInitial) { TEST(LowCutFilterBitExactnessTest, Mono8kHzInitial) {
const float kReferenceInput[] = { const float kReferenceInput[] = {
0.153442f, -0.436920f, -0.057602f, -0.141767f, 0.108608f, 0.116834f, 0.153442f, -0.436920f, -0.057602f, -0.141767f, 0.108608f, 0.116834f,
0.114979f, -0.103151f, -0.169925f, -0.167180f, 0.242024f, -0.525426f, 0.114979f, -0.103151f, -0.169925f, -0.167180f, 0.242024f, -0.525426f,
@ -124,7 +120,7 @@ TEST(HighPassFilterBitExactnessTest, Mono8kHzInitial) {
CreateVector(rtc::ArrayView<const float>(kReference))); CreateVector(rtc::ArrayView<const float>(kReference)));
} }
TEST(HighPassFilterBitExactnessTest, Mono8kHzConverged) { TEST(LowCutFilterBitExactnessTest, Mono8kHzConverged) {
const float kReferenceInput[] = { const float kReferenceInput[] = {
0.153442f, -0.436920f, -0.057602f, -0.141767f, 0.108608f, 0.116834f, 0.153442f, -0.436920f, -0.057602f, -0.141767f, 0.108608f, 0.116834f,
0.114979f, -0.103151f, -0.169925f, -0.167180f, 0.242024f, -0.525426f, 0.114979f, -0.103151f, -0.169925f, -0.167180f, 0.242024f, -0.525426f,
@ -176,7 +172,7 @@ TEST(HighPassFilterBitExactnessTest, Mono8kHzConverged) {
CreateVector(rtc::ArrayView<const float>(kReference))); CreateVector(rtc::ArrayView<const float>(kReference)));
} }
TEST(HighPassFilterBitExactnessTest, Stereo8kHzInitial) { TEST(LowCutFilterBitExactnessTest, Stereo8kHzInitial) {
const float kReferenceInput[] = { const float kReferenceInput[] = {
0.790847f, 0.165037f, 0.165494f, 0.709852f, -0.930269f, 0.770840f, 0.790847f, 0.165037f, 0.165494f, 0.709852f, -0.930269f, 0.770840f,
-0.184538f, -0.927236f, 0.492296f, -0.690342f, -0.712183f, 0.211918f, -0.184538f, -0.927236f, 0.492296f, -0.690342f, -0.712183f, 0.211918f,
@ -217,7 +213,7 @@ TEST(HighPassFilterBitExactnessTest, Stereo8kHzInitial) {
CreateVector(rtc::ArrayView<const float>(kReference))); CreateVector(rtc::ArrayView<const float>(kReference)));
} }
TEST(HighPassFilterBitExactnessTest, Stereo8kHzConverged) { TEST(LowCutFilterBitExactnessTest, Stereo8kHzConverged) {
const float kReferenceInput[] = { const float kReferenceInput[] = {
-0.502095f, -0.227154f, -0.137133f, 0.661773f, 0.649294f, -0.094003f, -0.502095f, -0.227154f, -0.137133f, 0.661773f, 0.649294f, -0.094003f,
-0.238880f, 0.851737f, 0.481687f, 0.475266f, 0.893832f, 0.020199f, -0.238880f, 0.851737f, 0.481687f, 0.475266f, 0.893832f, 0.020199f,
@ -311,7 +307,7 @@ TEST(HighPassFilterBitExactnessTest, Stereo8kHzConverged) {
CreateVector(rtc::ArrayView<const float>(kReference))); CreateVector(rtc::ArrayView<const float>(kReference)));
} }
TEST(HighPassFilterBitExactnessTest, Mono16kHzInitial) { TEST(LowCutFilterBitExactnessTest, Mono16kHzInitial) {
const float kReferenceInput[] = { const float kReferenceInput[] = {
0.150254f, 0.512488f, -0.631245f, 0.240938f, 0.089080f, -0.365440f, 0.150254f, 0.512488f, -0.631245f, 0.240938f, 0.089080f, -0.365440f,
-0.121169f, 0.095748f, 1.000000f, 0.773932f, -0.377232f, 0.848124f, -0.121169f, 0.095748f, 1.000000f, 0.773932f, -0.377232f, 0.848124f,
@ -350,7 +346,7 @@ TEST(HighPassFilterBitExactnessTest, Mono16kHzInitial) {
CreateVector(rtc::ArrayView<const float>(kReference))); CreateVector(rtc::ArrayView<const float>(kReference)));
} }
TEST(HighPassFilterBitExactnessTest, Mono16kHzConverged) { TEST(LowCutFilterBitExactnessTest, Mono16kHzConverged) {
const float kReferenceInput[] = { const float kReferenceInput[] = {
0.150254f, 0.512488f, -0.631245f, 0.240938f, 0.089080f, -0.365440f, 0.150254f, 0.512488f, -0.631245f, 0.240938f, 0.089080f, -0.365440f,
-0.121169f, 0.095748f, 1.000000f, 0.773932f, -0.377232f, 0.848124f, -0.121169f, 0.095748f, 1.000000f, 0.773932f, -0.377232f, 0.848124f,
@ -442,7 +438,7 @@ TEST(HighPassFilterBitExactnessTest, Mono16kHzConverged) {
CreateVector(rtc::ArrayView<const float>(kReference))); CreateVector(rtc::ArrayView<const float>(kReference)));
} }
TEST(HighPassFilterBitExactnessTest, Stereo16kHzInitial) { TEST(LowCutFilterBitExactnessTest, Stereo16kHzInitial) {
const float kReferenceInput[] = { const float kReferenceInput[] = {
0.087390f, -0.370759f, -0.235918f, 0.583079f, 0.678359f, 0.360473f, 0.087390f, -0.370759f, -0.235918f, 0.583079f, 0.678359f, 0.360473f,
-0.166156f, 0.285780f, -0.571837f, 0.234542f, 0.350382f, 0.202047f, -0.166156f, 0.285780f, -0.571837f, 0.234542f, 0.350382f, 0.202047f,
@ -510,7 +506,7 @@ TEST(HighPassFilterBitExactnessTest, Stereo16kHzInitial) {
CreateVector(rtc::ArrayView<const float>(kReference))); CreateVector(rtc::ArrayView<const float>(kReference)));
} }
TEST(HighPassFilterBitExactnessTest, Stereo16kHzConverged) { TEST(LowCutFilterBitExactnessTest, Stereo16kHzConverged) {
const float kReferenceInput[] = { const float kReferenceInput[] = {
-0.145875f, 0.910744f, 0.448494f, 0.161783f, 0.080516f, 0.410882f, -0.145875f, 0.910744f, 0.448494f, 0.161783f, 0.080516f, 0.410882f,
-0.989942f, 0.565032f, 0.853719f, -0.983409f, 0.649257f, 0.534672f, -0.989942f, 0.565032f, 0.853719f, -0.983409f, 0.649257f, 0.534672f,

View File

@ -403,8 +403,7 @@ void AecDumpBasedSimulator::HandleMessage(
if (msg.has_hpf_enabled() || settings_.use_hpf) { if (msg.has_hpf_enabled() || settings_.use_hpf) {
bool enable = settings_.use_hpf ? *settings_.use_hpf : msg.hpf_enabled(); bool enable = settings_.use_hpf ? *settings_.use_hpf : msg.hpf_enabled();
RTC_CHECK_EQ(AudioProcessing::kNoError, apm_config.high_pass_filter.enabled = enable;
ap_->high_pass_filter()->Enable(enable));
if (settings_.use_verbose_logging) { if (settings_.use_verbose_logging) {
std::cout << " hpf_enabled: " << (enable ? "true" : "false") std::cout << " hpf_enabled: " << (enable ? "true" : "false")
<< std::endl; << std::endl;

View File

@ -273,6 +273,10 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
if (settings_.use_lc) { if (settings_.use_lc) {
apm_config.level_controller.enabled = *settings_.use_lc; apm_config.level_controller.enabled = *settings_.use_lc;
} }
if (settings_.use_hpf) {
apm_config.high_pass_filter.enabled = *settings_.use_hpf;
}
if (settings_.use_refined_adaptive_filter) { if (settings_.use_refined_adaptive_filter) {
config.Set<RefinedAdaptiveFilter>( config.Set<RefinedAdaptiveFilter>(
new RefinedAdaptiveFilter(*settings_.use_refined_adaptive_filter)); new RefinedAdaptiveFilter(*settings_.use_refined_adaptive_filter));
@ -302,10 +306,6 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
RTC_CHECK_EQ(AudioProcessing::kNoError, RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->gain_control()->Enable(*settings_.use_agc)); ap_->gain_control()->Enable(*settings_.use_agc));
} }
if (settings_.use_hpf) {
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->high_pass_filter()->Enable(*settings_.use_hpf));
}
if (settings_.use_ns) { if (settings_.use_ns) {
RTC_CHECK_EQ(AudioProcessing::kNoError, RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->noise_suppression()->Enable(*settings_.use_ns)); ap_->noise_suppression()->Enable(*settings_.use_ns));

View File

@ -199,6 +199,8 @@ void DebugDumpReplayer::MaybeRecreateApm(const audioproc::Config& msg) {
} }
void DebugDumpReplayer::ConfigureApm(const audioproc::Config& msg) { void DebugDumpReplayer::ConfigureApm(const audioproc::Config& msg) {
AudioProcessing::Config apm_config;
// AEC configs. // AEC configs.
RTC_CHECK(msg.has_aec_enabled()); RTC_CHECK(msg.has_aec_enabled());
RTC_CHECK_EQ(AudioProcessing::kNoError, RTC_CHECK_EQ(AudioProcessing::kNoError,
@ -247,8 +249,7 @@ void DebugDumpReplayer::ConfigureApm(const audioproc::Config& msg) {
// HPF configs. // HPF configs.
RTC_CHECK(msg.has_hpf_enabled()); RTC_CHECK(msg.has_hpf_enabled());
RTC_CHECK_EQ(AudioProcessing::kNoError, apm_config.high_pass_filter.enabled = msg.hpf_enabled();
apm_->high_pass_filter()->Enable(msg.hpf_enabled()));
// NS configs. // NS configs.
RTC_CHECK(msg.has_ns_enabled()); RTC_CHECK(msg.has_ns_enabled());
@ -259,6 +260,8 @@ void DebugDumpReplayer::ConfigureApm(const audioproc::Config& msg) {
RTC_CHECK_EQ(AudioProcessing::kNoError, RTC_CHECK_EQ(AudioProcessing::kNoError,
apm_->noise_suppression()->set_level( apm_->noise_suppression()->set_level(
static_cast<NoiseSuppression::Level>(msg.ns_level()))); static_cast<NoiseSuppression::Level>(msg.ns_level())));
apm_->ApplyConfig(apm_config);
} }
void DebugDumpReplayer::LoadNextMessage() { void DebugDumpReplayer::LoadNextMessage() {