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}
This commit is contained in:
peah
2016-02-13 16:40:47 -08:00
committed by Commit bot
parent 46e2cb8a88
commit be61562bfb
7 changed files with 204 additions and 84 deletions

View File

@ -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",

View File

@ -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',

View File

@ -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<LevelEstimatorImpl> level_estimator;
rtc::scoped_ptr<NoiseSuppressionImpl> noise_suppression;
rtc::scoped_ptr<VoiceDetectionImpl> voice_detection;
rtc::scoped_ptr<GainControlForNewAgc> gain_control_for_new_agc;
rtc::scoped_ptr<GainControlForExperimentalAgc>
gain_control_for_experimental_agc;
// Accessed internally from both render and capture.
rtc::scoped_ptr<TransientSuppressor> 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<int>(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());

View File

@ -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_;

View File

@ -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);
}

View File

@ -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

View File

@ -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_