From be61562bfb7b72a38462c4303c9a205379adeddb Mon Sep 17 00:00:00 2001 From: peah Date: Sat, 13 Feb 2016 16:40:47 -0800 Subject: [PATCH] Moved the GainControlForNewAGC class to be a separate file. Apart from being motivated in order to make the source files shorter this is needed when separating the APM submodules structs into separate files. BUG= Review URL: https://codereview.webrtc.org/1678813002 Cr-Commit-Position: refs/heads/master@{#11611} --- webrtc/modules/audio_processing/BUILD.gn | 2 + .../audio_processing/audio_processing.gypi | 2 + .../audio_processing/audio_processing_impl.cc | 95 +++------------- .../audio_processing/audio_processing_impl.h | 6 +- .../audio_processing_impl_locking_unittest.cc | 9 +- .../gain_control_for_experimental_agc.cc | 104 ++++++++++++++++++ .../gain_control_for_experimental_agc.h | 70 ++++++++++++ 7 files changed, 204 insertions(+), 84 deletions(-) create mode 100644 webrtc/modules/audio_processing/gain_control_for_experimental_agc.cc create mode 100644 webrtc/modules/audio_processing/gain_control_for_experimental_agc.h diff --git a/webrtc/modules/audio_processing/BUILD.gn b/webrtc/modules/audio_processing/BUILD.gn index 13da8d6c49..58347933e5 100644 --- a/webrtc/modules/audio_processing/BUILD.gn +++ b/webrtc/modules/audio_processing/BUILD.gn @@ -68,6 +68,8 @@ source_set("audio_processing") { "echo_cancellation_impl.h", "echo_control_mobile_impl.cc", "echo_control_mobile_impl.h", + "gain_control_for_experimental_agc.cc", + "gain_control_for_experimental_agc.h", "gain_control_impl.cc", "gain_control_impl.h", "high_pass_filter_impl.cc", diff --git a/webrtc/modules/audio_processing/audio_processing.gypi b/webrtc/modules/audio_processing/audio_processing.gypi index c665f5b0e8..eaee6443dd 100644 --- a/webrtc/modules/audio_processing/audio_processing.gypi +++ b/webrtc/modules/audio_processing/audio_processing.gypi @@ -78,6 +78,8 @@ 'echo_cancellation_impl.h', 'echo_control_mobile_impl.cc', 'echo_control_mobile_impl.h', + 'gain_control_for_experimental_agc.cc', + 'gain_control_for_experimental_agc.h', 'gain_control_impl.cc', 'gain_control_impl.h', 'high_pass_filter_impl.cc', diff --git a/webrtc/modules/audio_processing/audio_processing_impl.cc b/webrtc/modules/audio_processing/audio_processing_impl.cc index b3f38f408e..f3856128bb 100644 --- a/webrtc/modules/audio_processing/audio_processing_impl.cc +++ b/webrtc/modules/audio_processing/audio_processing_impl.cc @@ -29,6 +29,7 @@ extern "C" { #include "webrtc/modules/audio_processing/common.h" #include "webrtc/modules/audio_processing/echo_cancellation_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_impl.h" #include "webrtc/modules/audio_processing/high_pass_filter_impl.h" #include "webrtc/modules/audio_processing/intelligibility/intelligibility_enhancer.h" @@ -80,72 +81,6 @@ static bool LayoutHasKeyboard(AudioProcessing::ChannelLayout layout) { // Throughout webrtc, it's assumed that success is represented by zero. static_assert(AudioProcessing::kNoError == 0, "kNoError must be zero"); -// This class has two main functionalities: -// -// 1) It is returned instead of the real GainControl after the new AGC has been -// enabled in order to prevent an outside user from overriding compression -// settings. It doesn't do anything in its implementation, except for -// delegating the const methods and Enable calls to the real GainControl, so -// AGC can still be disabled. -// -// 2) It is injected into AgcManagerDirect and implements volume callbacks for -// getting and setting the volume level. It just caches this value to be used -// in VoiceEngine later. -class GainControlForNewAgc : public GainControl, public VolumeCallbacks { - public: - explicit GainControlForNewAgc(GainControlImpl* gain_control) - : real_gain_control_(gain_control), volume_(0) {} - - // GainControl implementation. - int Enable(bool enable) override { - return real_gain_control_->Enable(enable); - } - bool is_enabled() const override { return real_gain_control_->is_enabled(); } - int set_stream_analog_level(int level) override { - volume_ = level; - return AudioProcessing::kNoError; - } - int stream_analog_level() override { return volume_; } - int set_mode(Mode mode) override { return AudioProcessing::kNoError; } - Mode mode() const override { return GainControl::kAdaptiveAnalog; } - int set_target_level_dbfs(int level) override { - return AudioProcessing::kNoError; - } - int target_level_dbfs() const override { - return real_gain_control_->target_level_dbfs(); - } - int set_compression_gain_db(int gain) override { - return AudioProcessing::kNoError; - } - int compression_gain_db() const override { - return real_gain_control_->compression_gain_db(); - } - int enable_limiter(bool enable) override { return AudioProcessing::kNoError; } - bool is_limiter_enabled() const override { - return real_gain_control_->is_limiter_enabled(); - } - int set_analog_level_limits(int minimum, int maximum) override { - return AudioProcessing::kNoError; - } - int analog_level_minimum() const override { - return real_gain_control_->analog_level_minimum(); - } - int analog_level_maximum() const override { - return real_gain_control_->analog_level_maximum(); - } - bool stream_is_saturated() const override { - return real_gain_control_->stream_is_saturated(); - } - - // VolumeCallbacks implementation. - void SetMicVolume(int volume) override { volume_ = volume; } - int GetMicVolume() override { return volume_; } - - private: - GainControl* real_gain_control_; - int volume_; -}; - struct AudioProcessingImpl::ApmPublicSubmodules { ApmPublicSubmodules() : echo_cancellation(nullptr), @@ -159,7 +94,8 @@ struct AudioProcessingImpl::ApmPublicSubmodules { rtc::scoped_ptr level_estimator; rtc::scoped_ptr noise_suppression; rtc::scoped_ptr voice_detection; - rtc::scoped_ptr gain_control_for_new_agc; + rtc::scoped_ptr + gain_control_for_experimental_agc; // Accessed internally from both render and capture. rtc::scoped_ptr transient_suppressor; @@ -248,8 +184,9 @@ AudioProcessingImpl::AudioProcessingImpl(const Config& config, new NoiseSuppressionImpl(&crit_capture_)); public_submodules_->voice_detection.reset( new VoiceDetectionImpl(&crit_capture_)); - public_submodules_->gain_control_for_new_agc.reset( - new GainControlForNewAgc(public_submodules_->gain_control)); + public_submodules_->gain_control_for_experimental_agc.reset( + new GainControlForExperimentalAgc(public_submodules_->gain_control, + &crit_capture_)); private_submodules_->component_list.push_back( public_submodules_->echo_cancellation); @@ -264,10 +201,10 @@ AudioProcessingImpl::AudioProcessingImpl(const Config& config, AudioProcessingImpl::~AudioProcessingImpl() { // Depends on gain_control_ and - // public_submodules_->gain_control_for_new_agc. + // public_submodules_->gain_control_for_experimental_agc. private_submodules_->agc_manager.reset(); // Depends on gain_control_. - public_submodules_->gain_control_for_new_agc.reset(); + public_submodules_->gain_control_for_experimental_agc.reset(); while (!private_submodules_->component_list.empty()) { ProcessingComponent* component = private_submodules_->component_list.front(); @@ -759,7 +696,7 @@ int AudioProcessingImpl::ProcessStreamLocked() { AudioBuffer* ca = capture_.capture_audio.get(); // For brevity. - if (constants_.use_new_agc && + if (constants_.use_experimental_agc && public_submodules_->gain_control->is_enabled()) { private_submodules_->agc_manager->AnalyzePreProcess( ca->channels()[0], ca->num_channels(), @@ -796,7 +733,7 @@ int AudioProcessingImpl::ProcessStreamLocked() { public_submodules_->echo_control_mobile->ProcessCaptureAudio(ca)); public_submodules_->voice_detection->ProcessCaptureAudio(ca); - if (constants_.use_new_agc && + if (constants_.use_experimental_agc && public_submodules_->gain_control->is_enabled() && (!capture_nonlocked_.beamformer_enabled || private_submodules_->beamformer->is_target_present())) { @@ -998,7 +935,7 @@ int AudioProcessingImpl::ProcessReverseStreamLocked() { RETURN_ON_ERR(public_submodules_->echo_cancellation->ProcessRenderAudio(ra)); RETURN_ON_ERR( public_submodules_->echo_control_mobile->ProcessRenderAudio(ra)); - if (!constants_.use_new_agc) { + if (!constants_.use_experimental_agc) { RETURN_ON_ERR(public_submodules_->gain_control->ProcessRenderAudio(ra)); } @@ -1164,8 +1101,8 @@ EchoControlMobile* AudioProcessingImpl::echo_control_mobile() const { GainControl* AudioProcessingImpl::gain_control() const { // Adding a lock here has no effect as it allows any access to the submodule // from the returned pointer. - if (constants_.use_new_agc) { - return public_submodules_->gain_control_for_new_agc.get(); + if (constants_.use_experimental_agc) { + return public_submodules_->gain_control_for_experimental_agc.get(); } return public_submodules_->gain_control; } @@ -1284,11 +1221,11 @@ bool AudioProcessingImpl::rev_conversion_needed() const { } void AudioProcessingImpl::InitializeExperimentalAgc() { - if (constants_.use_new_agc) { + if (constants_.use_experimental_agc) { if (!private_submodules_->agc_manager.get()) { private_submodules_->agc_manager.reset(new AgcManagerDirect( public_submodules_->gain_control, - public_submodules_->gain_control_for_new_agc.get(), + public_submodules_->gain_control_for_experimental_agc.get(), constants_.agc_startup_min_volume)); } private_submodules_->agc_manager->Initialize(); @@ -1519,7 +1456,7 @@ int AudioProcessingImpl::WriteConfigMessage(bool forced) { static_cast(public_submodules_->gain_control->mode())); config.set_agc_limiter_enabled( public_submodules_->gain_control->is_limiter_enabled()); - config.set_noise_robust_agc_enabled(constants_.use_new_agc); + config.set_noise_robust_agc_enabled(constants_.use_experimental_agc); config.set_hpf_enabled(public_submodules_->high_pass_filter->is_enabled()); diff --git a/webrtc/modules/audio_processing/audio_processing_impl.h b/webrtc/modules/audio_processing/audio_processing_impl.h index a19d3fce55..b3f43fa5b3 100644 --- a/webrtc/modules/audio_processing/audio_processing_impl.h +++ b/webrtc/modules/audio_processing/audio_processing_impl.h @@ -274,14 +274,14 @@ class AudioProcessingImpl : public AudioProcessing { // APM constants. const struct ApmConstants { ApmConstants(int agc_startup_min_volume, - bool use_new_agc, + bool use_experimental_agc, bool intelligibility_enabled) : // Format of processing streams at input/output call sites. agc_startup_min_volume(agc_startup_min_volume), - use_new_agc(use_new_agc), + use_experimental_agc(use_experimental_agc), intelligibility_enabled(intelligibility_enabled) {} int agc_startup_min_volume; - bool use_new_agc; + bool use_experimental_agc; bool intelligibility_enabled; } constants_; diff --git a/webrtc/modules/audio_processing/audio_processing_impl_locking_unittest.cc b/webrtc/modules/audio_processing/audio_processing_impl_locking_unittest.cc index 2e22b2c51e..7ce6a569d1 100644 --- a/webrtc/modules/audio_processing/audio_processing_impl_locking_unittest.cc +++ b/webrtc/modules/audio_processing/audio_processing_impl_locking_unittest.cc @@ -600,7 +600,6 @@ bool StatsProcessor::Process() { (test_config_->aec_type == AecType::BasicWebRtcAecSettingsWithAecMobile)); EXPECT_TRUE(apm_->gain_control()->is_enabled()); - apm_->gain_control()->stream_analog_level(); EXPECT_TRUE(apm_->noise_suppression()->is_enabled()); // The below return values are not testable. @@ -713,9 +712,12 @@ void CaptureProcessor::CallApmCaptureSide() { // Prepare a proper capture side processing API call input. PrepareFrame(); - // Set the stream delay + // Set the stream delay. apm_->set_stream_delay_ms(30); + // Set the analog level. + apm_->gain_control()->set_stream_analog_level(80); + // Call the specified capture side API processing method. int result = AudioProcessing::kNoError; switch (test_config_->capture_api_function) { @@ -738,6 +740,9 @@ void CaptureProcessor::CallApmCaptureSide() { FAIL(); } + // Retrieve the new analog level. + apm_->gain_control()->stream_analog_level(); + // Check the return code for error. ASSERT_EQ(AudioProcessing::kNoError, result); } diff --git a/webrtc/modules/audio_processing/gain_control_for_experimental_agc.cc b/webrtc/modules/audio_processing/gain_control_for_experimental_agc.cc new file mode 100644 index 0000000000..2ef88c03aa --- /dev/null +++ b/webrtc/modules/audio_processing/gain_control_for_experimental_agc.cc @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2016 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. + */ + +#include "webrtc/modules/audio_processing/gain_control_for_experimental_agc.h" + +#include "webrtc/base/checks.h" +#include "webrtc/base/criticalsection.h" +#include "webrtc/modules/audio_processing/include/audio_processing.h" + +namespace webrtc { + +GainControlForExperimentalAgc::GainControlForExperimentalAgc( + GainControl* gain_control, + rtc::CriticalSection* crit_capture) + : real_gain_control_(gain_control), + volume_(0), + crit_capture_(crit_capture) {} + +int GainControlForExperimentalAgc::Enable(bool enable) { + return real_gain_control_->Enable(enable); +} + +bool GainControlForExperimentalAgc::is_enabled() const { + return real_gain_control_->is_enabled(); +} + +int GainControlForExperimentalAgc::set_stream_analog_level(int level) { + rtc::CritScope cs_capture(crit_capture_); + volume_ = level; + return AudioProcessing::kNoError; +} + +int GainControlForExperimentalAgc::stream_analog_level() { + rtc::CritScope cs_capture(crit_capture_); + return volume_; +} + +int GainControlForExperimentalAgc::set_mode(Mode mode) { + return AudioProcessing::kNoError; +} + +GainControl::Mode GainControlForExperimentalAgc::mode() const { + return GainControl::kAdaptiveAnalog; +} + +int GainControlForExperimentalAgc::set_target_level_dbfs(int level) { + return AudioProcessing::kNoError; +} + +int GainControlForExperimentalAgc::target_level_dbfs() const { + return real_gain_control_->target_level_dbfs(); +} + +int GainControlForExperimentalAgc::set_compression_gain_db(int gain) { + return AudioProcessing::kNoError; +} + +int GainControlForExperimentalAgc::compression_gain_db() const { + return real_gain_control_->compression_gain_db(); +} + +int GainControlForExperimentalAgc::enable_limiter(bool enable) { + return AudioProcessing::kNoError; +} + +bool GainControlForExperimentalAgc::is_limiter_enabled() const { + return real_gain_control_->is_limiter_enabled(); +} + +int GainControlForExperimentalAgc::set_analog_level_limits(int minimum, + int maximum) { + return AudioProcessing::kNoError; +} + +int GainControlForExperimentalAgc::analog_level_minimum() const { + return real_gain_control_->analog_level_minimum(); +} + +int GainControlForExperimentalAgc::analog_level_maximum() const { + return real_gain_control_->analog_level_maximum(); +} + +bool GainControlForExperimentalAgc::stream_is_saturated() const { + return real_gain_control_->stream_is_saturated(); +} + +void GainControlForExperimentalAgc::SetMicVolume(int volume) { + rtc::CritScope cs_capture(crit_capture_); + volume_ = volume; +} + +int GainControlForExperimentalAgc::GetMicVolume() { + rtc::CritScope cs_capture(crit_capture_); + return volume_; +} + +} // namespace webrtc diff --git a/webrtc/modules/audio_processing/gain_control_for_experimental_agc.h b/webrtc/modules/audio_processing/gain_control_for_experimental_agc.h new file mode 100644 index 0000000000..4fbd05c685 --- /dev/null +++ b/webrtc/modules/audio_processing/gain_control_for_experimental_agc.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016 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_GAIN_CONTROL_FOR_EXPERIMENTAL_AGC_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_GAIN_CONTROL_FOR_EXPERIMENTAL_AGC_H_ + +#include "webrtc/base/constructormagic.h" +#include "webrtc/base/criticalsection.h" +#include "webrtc/base/thread_checker.h" +#include "webrtc/modules/audio_processing/agc/agc_manager_direct.h" +#include "webrtc/modules/audio_processing/include/audio_processing.h" + +namespace webrtc { + +// This class has two main purposes: +// +// 1) It is returned instead of the real GainControl after the new AGC has been +// enabled in order to prevent an outside user from overriding compression +// settings. It doesn't do anything in its implementation, except for +// delegating the const methods and Enable calls to the real GainControl, so +// AGC can still be disabled. +// +// 2) It is injected into AgcManagerDirect and implements volume callbacks for +// getting and setting the volume level. It just caches this value to be used +// in VoiceEngine later. +class GainControlForExperimentalAgc : public GainControl, + public VolumeCallbacks { + public: + explicit GainControlForExperimentalAgc(GainControl* gain_control, + rtc::CriticalSection* crit_capture); + + // GainControl implementation. + int Enable(bool enable) override; + bool is_enabled() const override; + int set_stream_analog_level(int level) override; + int stream_analog_level() override; + int set_mode(Mode mode) override; + Mode mode() const override; + int set_target_level_dbfs(int level) override; + int target_level_dbfs() const override; + int set_compression_gain_db(int gain) override; + int compression_gain_db() const override; + int enable_limiter(bool enable) override; + bool is_limiter_enabled() const override; + int set_analog_level_limits(int minimum, int maximum) override; + int analog_level_minimum() const override; + int analog_level_maximum() const override; + bool stream_is_saturated() const override; + + // VolumeCallbacks implementation. + void SetMicVolume(int volume) override; + int GetMicVolume() override; + + private: + GainControl* real_gain_control_; + int volume_; + rtc::CriticalSection* crit_capture_; + RTC_DISALLOW_COPY_AND_ASSIGN(GainControlForExperimentalAgc); +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_GAIN_CONTROL_FOR_EXPERIMENTAL_AGC_H_