Remove AudioProcessing::gain_control() getter

This change also resolves a bug in audioproc_f:
The implicit ApplyConfig calls to enable gain control settings in
aec_dump_simulator.cc:377-406 [1] are overwritten by the ApplyConfig
call on line 500 using a config from line 292.

Compared to a ToT build including a fix for that bug, these changes
are bitexact on a large number of aecdumps.

[1] https://cs.chromium.org/chromium/src/third_party/webrtc/modules/audio_processing/test/aec_dump_based_simulator.cc?l=377&rcl=8bbf9e2c6e40feb8efcbf276b43945a14d651e9b

Bug: webrtc:9878
Change-Id: Id427d34e838c999d996d58193977ac2a9198edd6
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/156463
Commit-Queue: Sam Zackrisson <saza@webrtc.org>
Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29481}
This commit is contained in:
Sam Zackrisson 2019-10-15 10:10:26 +02:00 committed by Commit Bot
parent eb90e6ffe3
commit 41478c7c1b
25 changed files with 233 additions and 625 deletions

View File

@ -291,8 +291,8 @@ rtc_static_library("rtc_audio_video") {
"../modules/audio_device:audio_device_impl",
"../modules/audio_mixer:audio_mixer_impl",
"../modules/audio_processing:api",
"../modules/audio_processing:gain_control_interface",
"../modules/audio_processing/aec_dump",
"../modules/audio_processing/agc:gain_control_interface",
"../modules/video_coding",
"../modules/video_coding:video_codec_interface",
"../modules/video_coding:video_coding_utility",

View File

@ -49,7 +49,6 @@ rtc_source_set("api") {
":audio_generator_interface",
":audio_processing_statistics",
":config",
":gain_control_interface",
"../../api:scoped_refptr",
"../../api/audio:aec3_config",
"../../api/audio:echo_control",
@ -58,6 +57,7 @@ rtc_source_set("api") {
"../../rtc_base:rtc_base_approved",
"../../rtc_base/system:arch",
"../../rtc_base/system:rtc_export",
"agc:gain_control_interface",
"//third_party/abseil-cpp/absl/types:optional",
]
}
@ -170,8 +170,6 @@ rtc_static_library("audio_processing") {
":audio_processing_c",
":audio_processing_statistics",
":config",
":gain_control_config_proxy",
":gain_control_interface",
":high_pass_filter",
":noise_suppression_proxy",
"../../api:array_view",
@ -197,6 +195,7 @@ rtc_static_library("audio_processing") {
"aecm:aecm_core",
"agc",
"agc:agc_legacy_c",
"agc:gain_control_interface",
"agc2:adaptive_digital",
"agc2:fixed_digital",
"agc2:gain_applier",
@ -223,25 +222,6 @@ rtc_static_library("audio_processing") {
]
}
rtc_source_set("gain_control_interface") {
sources = [
"include/gain_control.h",
]
}
rtc_source_set("gain_control_config_proxy") {
sources = [
"gain_control_config_proxy.cc",
"gain_control_config_proxy.h",
]
deps = [
":api",
":gain_control_interface",
"../../rtc_base:criticalsection",
"../../rtc_base:macromagic",
]
}
rtc_source_set("noise_suppression_proxy") {
sources = [
"noise_suppression_proxy.cc",
@ -434,7 +414,6 @@ if (rtc_include_tests) {
"config_unittest.cc",
"echo_cancellation_impl_unittest.cc",
"echo_control_mobile_unittest.cc",
"gain_control_config_proxy_unittest.cc",
"gain_controller2_unittest.cc",
"splitting_filter_unittest.cc",
"test/fake_recording_device_unittest.cc",
@ -459,7 +438,6 @@ if (rtc_include_tests) {
":audioproc_test_utils",
":config",
":file_audio_generator_unittests",
":gain_control_config_proxy",
":high_pass_filter",
":mocks",
"../../api:array_view",

View File

@ -8,6 +8,12 @@
import("../../../webrtc.gni")
rtc_source_set("gain_control_interface") {
sources = [
"gain_control.h",
]
}
rtc_source_set("agc") {
sources = [
"agc_manager_direct.cc",
@ -15,10 +21,10 @@ rtc_source_set("agc") {
]
configs += [ "..:apm_debug_dump" ]
deps = [
":gain_control_interface",
":gain_map",
":level_estimation",
"..:apm_logging",
"..:gain_control_interface",
"../../../common_audio",
"../../../common_audio:common_audio_c",
"../../../rtc_base:checks",
@ -100,6 +106,7 @@ if (rtc_include_tests) {
deps = [
":agc",
":gain_control_interface",
":level_estimation",
"..:mocks",
"../../../test:fileutils",

View File

@ -18,9 +18,9 @@
#endif
#include "common_audio/include/audio_util.h"
#include "modules/audio_processing/agc/gain_control.h"
#include "modules/audio_processing/agc/gain_map_internal.h"
#include "modules/audio_processing/agc2/adaptive_mode_level_estimator_agc.h"
#include "modules/audio_processing/include/gain_control.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_minmax.h"

View File

@ -10,6 +10,7 @@
#include "modules/audio_processing/agc/agc_manager_direct.h"
#include "modules/audio_processing/agc/gain_control.h"
#include "modules/audio_processing/agc/mock_agc.h"
#include "modules/audio_processing/include/mock_audio_processing.h"
#include "test/gmock.h"
@ -31,6 +32,27 @@ const int kInitialVolume = 128;
constexpr int kClippedMin = 165; // Arbitrary, but different from the default.
const float kAboveClippedThreshold = 0.2f;
class MockGainControl : public GainControl {
public:
virtual ~MockGainControl() {}
MOCK_METHOD1(Enable, int(bool enable));
MOCK_CONST_METHOD0(is_enabled, bool());
MOCK_METHOD1(set_stream_analog_level, int(int level));
MOCK_CONST_METHOD0(stream_analog_level, int());
MOCK_METHOD1(set_mode, int(Mode mode));
MOCK_CONST_METHOD0(mode, Mode());
MOCK_METHOD1(set_target_level_dbfs, int(int level));
MOCK_CONST_METHOD0(target_level_dbfs, int());
MOCK_METHOD1(set_compression_gain_db, int(int gain));
MOCK_CONST_METHOD0(compression_gain_db, int());
MOCK_METHOD1(enable_limiter, int(bool enable));
MOCK_CONST_METHOD0(is_limiter_enabled, bool());
MOCK_METHOD2(set_analog_level_limits, int(int minimum, int maximum));
MOCK_CONST_METHOD0(analog_level_minimum, int());
MOCK_CONST_METHOD0(analog_level_maximum, int());
MOCK_CONST_METHOD0(stream_is_saturated, bool());
};
class TestVolumeCallbacks : public VolumeCallbacks {
public:
TestVolumeCallbacks() : volume_(0) {}
@ -89,7 +111,7 @@ class AgcManagerDirectTest : public ::testing::Test {
}
MockAgc* agc_;
test::MockGainControl gctrl_;
MockGainControl gctrl_;
TestVolumeCallbacks volume_;
AgcManagerDirect manager_;
};
@ -684,7 +706,7 @@ TEST_F(AgcManagerDirectTest, TakesNoActionOnZeroMicVolume) {
TEST(AgcManagerDirectStandaloneTest, DisableDigitalDisablesDigital) {
auto agc = std::unique_ptr<Agc>(new ::testing::NiceMock<MockAgc>());
test::MockGainControl gctrl;
MockGainControl gctrl;
TestVolumeCallbacks volume;
AgcManagerDirect manager(agc.release(), &gctrl, &volume, kInitialVolume,

View File

@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MODULES_AUDIO_PROCESSING_INCLUDE_GAIN_CONTROL_H_
#define MODULES_AUDIO_PROCESSING_INCLUDE_GAIN_CONTROL_H_
#ifndef MODULES_AUDIO_PROCESSING_AGC_GAIN_CONTROL_H_
#define MODULES_AUDIO_PROCESSING_AGC_GAIN_CONTROL_H_
namespace webrtc {
@ -105,4 +105,4 @@ class GainControl {
};
} // namespace webrtc
#endif // MODULES_AUDIO_PROCESSING_INCLUDE_GAIN_CONTROL_H_
#endif // MODULES_AUDIO_PROCESSING_AGC_GAIN_CONTROL_H_

View File

@ -28,7 +28,6 @@
#include "modules/audio_processing/common.h"
#include "modules/audio_processing/echo_cancellation_impl.h"
#include "modules/audio_processing/echo_control_mobile_impl.h"
#include "modules/audio_processing/gain_control_config_proxy.h"
#include "modules/audio_processing/gain_control_for_experimental_agc.h"
#include "modules/audio_processing/gain_control_impl.h"
#include "modules/audio_processing/gain_controller2.h"
@ -263,7 +262,6 @@ struct AudioProcessingImpl::ApmPublicSubmodules {
std::unique_ptr<GainControlImpl> gain_control;
std::unique_ptr<GainControlForExperimentalAgc>
gain_control_for_experimental_agc;
std::unique_ptr<GainControlConfigProxy> gain_control_config_proxy;
// Accessed internally from both render and capture.
std::unique_ptr<TransientSuppressor> transient_suppressor;
@ -412,8 +410,6 @@ AudioProcessingImpl::AudioProcessingImpl(
public_submodules_->gain_control_for_experimental_agc.reset(
new GainControlForExperimentalAgc(
public_submodules_->gain_control.get()));
public_submodules_->gain_control_config_proxy.reset(
new GainControlConfigProxy(&crit_capture_, this, agc1()));
// If no echo detector is injected, use the ResidualEchoDetector.
if (!private_submodules_->echo_detector) {
@ -1828,10 +1824,6 @@ AudioProcessingStats AudioProcessingImpl::GetStatistics(
return stats;
}
GainControl* AudioProcessingImpl::gain_control() const {
return public_submodules_->gain_control_config_proxy.get();
}
NoiseSuppression* AudioProcessingImpl::noise_suppression() const {
return public_submodules_->noise_suppression_proxy.get();
}

View File

@ -16,6 +16,7 @@
#include <vector>
#include "api/function_view.h"
#include "modules/audio_processing/agc/gain_control.h"
#include "modules/audio_processing/audio_buffer.h"
#include "modules/audio_processing/include/aec_dump.h"
#include "modules/audio_processing/include/audio_processing.h"
@ -119,7 +120,6 @@ class AudioProcessingImpl : public AudioProcessing {
// would offer no protection (the submodules are
// created only once in a single-treaded manner
// during APM creation).
GainControl* gain_control() const override;
NoiseSuppression* noise_suppression() const override;
// TODO(peah): Remove MutateConfig once the new API allows that.

View File

@ -535,17 +535,14 @@ bool AudioProcessingImplLockTest::MaybeEndTest() {
void AudioProcessingImplLockTest::SetUp() {
test_config_ = static_cast<TestConfig>(GetParam());
ASSERT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
ASSERT_EQ(apm_->kNoError,
apm_->gain_control()->set_mode(GainControl::kAdaptiveDigital));
ASSERT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
AudioProcessing::Config apm_config = apm_->GetConfig();
apm_config.echo_canceller.enabled =
(test_config_.aec_type != AecType::AecTurnedOff);
apm_config.echo_canceller.mobile_mode =
(test_config_.aec_type == AecType::BasicWebRtcAecSettingsWithAecMobile);
apm_config.gain_controller1.enabled = true;
apm_config.gain_controller1.mode =
AudioProcessing::Config::GainController1::kAdaptiveDigital;
apm_config.noise_suppression.enabled = true;
apm_config.voice_detection.enabled = true;
apm_config.level_estimation.enabled = true;
@ -590,7 +587,7 @@ void StatsProcessor::Process() {
} else {
EXPECT_FALSE(apm_config.echo_canceller.enabled);
}
EXPECT_TRUE(apm_->gain_control()->is_enabled());
EXPECT_TRUE(apm_config.gain_controller1.enabled);
EXPECT_TRUE(apm_config.noise_suppression.enabled);
// The below return values are not testable.
@ -697,7 +694,7 @@ void CaptureProcessor::CallApmCaptureSide() {
apm_->set_stream_delay_ms(30);
// Set the analog level.
apm_->gain_control()->set_stream_analog_level(80);
apm_->set_stream_analog_level(80);
// Call the specified capture side API processing method.
int result = AudioProcessing::kNoError;
@ -722,7 +719,7 @@ void CaptureProcessor::CallApmCaptureSide() {
}
// Retrieve the new analog level.
apm_->gain_control()->stream_analog_level();
apm_->recommended_stream_analog_level();
// Check the return code for error.
ASSERT_EQ(AudioProcessing::kNoError, result);

View File

@ -221,9 +221,9 @@ TEST(AudioProcessingImplTest,
AudioProcessingBuilder()
.SetEchoControlFactory(std::move(echo_control_factory))
.Create());
apm->gain_control()->Enable(false); // Disable AGC.
apm->gain_control()->set_mode(GainControl::Mode::kFixedDigital);
// Disable AGC.
webrtc::AudioProcessing::Config apm_config;
apm_config.gain_controller1.enabled = false;
apm_config.gain_controller2.enabled = false;
apm_config.pre_amplifier.enabled = true;
apm_config.pre_amplifier.fixed_gain_factor = 1.f;
@ -264,9 +264,11 @@ TEST(AudioProcessingImplTest,
AudioProcessingBuilder()
.SetEchoControlFactory(std::move(echo_control_factory))
.Create());
apm->gain_control()->Enable(true); // Enable AGC.
apm->gain_control()->set_mode(GainControl::Mode::kAdaptiveAnalog);
webrtc::AudioProcessing::Config apm_config;
// Enable AGC1.
apm_config.gain_controller1.enabled = true;
apm_config.gain_controller1.mode =
AudioProcessing::Config::GainController1::kAdaptiveAnalog;
apm_config.gain_controller2.enabled = false;
apm_config.pre_amplifier.enabled = false;
apm->ApplyConfig(apm_config);
@ -280,14 +282,14 @@ TEST(AudioProcessingImplTest,
MockEchoControl* echo_control_mock = echo_control_factory_ptr->GetNext();
const int initial_analog_gain = apm->gain_control()->stream_analog_level();
const int initial_analog_gain = apm->recommended_stream_analog_level();
EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
EXPECT_CALL(*echo_control_mock, ProcessCapture(NotNull(), false)).Times(1);
apm->ProcessStream(&frame);
// Force an analog gain change if it did not happen.
if (initial_analog_gain == apm->gain_control()->stream_analog_level()) {
apm->gain_control()->set_stream_analog_level(initial_analog_gain + 1);
if (initial_analog_gain == apm->recommended_stream_analog_level()) {
apm->set_stream_analog_level(initial_analog_gain + 1);
}
EXPECT_CALL(*echo_control_mock, AnalyzeCapture(testing::_)).Times(1);
@ -305,8 +307,11 @@ TEST(AudioProcessingImplTest, EchoControllerObservesPlayoutVolumeChange) {
AudioProcessingBuilder()
.SetEchoControlFactory(std::move(echo_control_factory))
.Create());
apm->gain_control()->Enable(false); // Disable AGC.
apm->gain_control()->set_mode(GainControl::Mode::kFixedDigital);
// Disable AGC.
webrtc::AudioProcessing::Config apm_config;
apm_config.gain_controller1.enabled = false;
apm_config.gain_controller2.enabled = false;
apm->ApplyConfig(apm_config);
AudioFrame frame;
constexpr int16_t kAudioLevel = 10000;

View File

@ -446,14 +446,13 @@ class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
void SetUp() override {
// Lambda function for setting the default APM runtime settings for desktop.
auto set_default_desktop_apm_runtime_settings = [](AudioProcessing* apm) {
ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
ASSERT_EQ(apm->kNoError,
apm->gain_control()->set_mode(GainControl::kAdaptiveDigital));
ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
AudioProcessing::Config apm_config = apm->GetConfig();
apm_config.echo_canceller.enabled = true;
apm_config.echo_canceller.mobile_mode = false;
apm_config.gain_controller1.enabled = true;
apm_config.gain_controller1.mode =
AudioProcessing::Config::GainController1::kAdaptiveDigital;
apm_config.level_estimation.enabled = true;
apm_config.voice_detection.enabled = true;
apm->ApplyConfig(apm_config);
@ -461,14 +460,13 @@ class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
// Lambda function for setting the default APM runtime settings for mobile.
auto set_default_mobile_apm_runtime_settings = [](AudioProcessing* apm) {
ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
ASSERT_EQ(apm->kNoError,
apm->gain_control()->set_mode(GainControl::kAdaptiveDigital));
ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
AudioProcessing::Config apm_config = apm->GetConfig();
apm_config.echo_canceller.enabled = true;
apm_config.echo_canceller.mobile_mode = true;
apm_config.gain_controller1.mode =
AudioProcessing::Config::GainController1::kAdaptiveDigital;
apm_config.level_estimation.enabled = true;
apm_config.level_estimation.enabled = true;
apm_config.voice_detection.enabled = true;
apm->ApplyConfig(apm_config);
@ -477,13 +475,10 @@ class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
// Lambda function for turning off all of the APM runtime settings
// submodules.
auto turn_off_default_apm_runtime_settings = [](AudioProcessing* apm) {
ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(false));
ASSERT_EQ(apm->kNoError,
apm->gain_control()->set_mode(GainControl::kAdaptiveDigital));
ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(false));
ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(false));
AudioProcessing::Config apm_config = apm->GetConfig();
apm_config.echo_canceller.enabled = false;
apm_config.gain_controller1.enabled = false;
apm_config.level_estimation.enabled = false;
apm_config.voice_detection.enabled = false;
apm->ApplyConfig(apm_config);

View File

@ -560,7 +560,7 @@ void ApmTest::ReadFrameWithRewind(FILE* file, AudioFrame* frame) {
void ApmTest::ProcessWithDefaultStreamParameters(AudioFrame* frame) {
EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->set_stream_analog_level(127));
apm_->set_stream_analog_level(127);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame));
}
@ -678,22 +678,24 @@ void ApmTest::StreamParametersTest(Format format) {
EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
// -- Missing AGC level --
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
AudioProcessing::Config apm_config = apm_->GetConfig();
apm_config.gain_controller1.enabled = true;
apm_->ApplyConfig(apm_config);
EXPECT_EQ(apm_->kStreamParameterNotSetError, ProcessStreamChooser(format));
// Resets after successful ProcessStream().
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->set_stream_analog_level(127));
apm_->set_stream_analog_level(127);
EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
EXPECT_EQ(apm_->kStreamParameterNotSetError, ProcessStreamChooser(format));
// Other stream parameters set correctly.
AudioProcessing::Config apm_config = apm_->GetConfig();
apm_config.echo_canceller.enabled = true;
apm_config.echo_canceller.mobile_mode = false;
apm_->ApplyConfig(apm_config);
EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
EXPECT_EQ(apm_->kStreamParameterNotSetError, ProcessStreamChooser(format));
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
apm_config.gain_controller1.enabled = false;
apm_->ApplyConfig(apm_config);
// -- Missing delay --
EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
@ -705,10 +707,12 @@ void ApmTest::StreamParametersTest(Format format) {
EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
// Other stream parameters set correctly.
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->set_stream_analog_level(127));
apm_config.gain_controller1.enabled = true;
apm_->ApplyConfig(apm_config);
apm_->set_stream_analog_level(127);
EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
apm_config.gain_controller1.enabled = false;
apm_->ApplyConfig(apm_config);
// -- No stream parameters --
EXPECT_EQ(apm_->kNoError, AnalyzeReverseStreamChooser(format));
@ -716,7 +720,7 @@ void ApmTest::StreamParametersTest(Format format) {
// -- All there --
EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->set_stream_analog_level(127));
apm_->set_stream_analog_level(127);
EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
}
@ -839,117 +843,129 @@ TEST_F(ApmTest, SampleRatesInt) {
}
TEST_F(ApmTest, GainControl) {
AudioProcessing::Config config = apm_->GetConfig();
config.gain_controller1.enabled = false;
apm_->ApplyConfig(config);
config.gain_controller1.enabled = true;
apm_->ApplyConfig(config);
// Testing gain modes
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_mode(apm_->gain_control()->mode()));
GainControl::Mode mode[] = {GainControl::kAdaptiveAnalog,
GainControl::kAdaptiveDigital,
GainControl::kFixedDigital};
for (size_t i = 0; i < arraysize(mode); i++) {
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->set_mode(mode[i]));
EXPECT_EQ(mode[i], apm_->gain_control()->mode());
for (auto mode :
{AudioProcessing::Config::GainController1::kAdaptiveDigital,
AudioProcessing::Config::GainController1::kFixedDigital,
AudioProcessing::Config::GainController1::kAdaptiveAnalog}) {
config.gain_controller1.mode = mode;
apm_->ApplyConfig(config);
apm_->set_stream_analog_level(100);
EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(kFloatFormat));
}
// Testing target levels
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->set_target_level_dbfs(
apm_->gain_control()->target_level_dbfs()));
int level_dbfs[] = {0, 6, 31};
for (size_t i = 0; i < arraysize(level_dbfs); i++) {
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_target_level_dbfs(level_dbfs[i]));
EXPECT_EQ(level_dbfs[i], apm_->gain_control()->target_level_dbfs());
// Testing target levels
for (int target_level_dbfs : {0, 15, 31}) {
config.gain_controller1.target_level_dbfs = target_level_dbfs;
apm_->ApplyConfig(config);
apm_->set_stream_analog_level(100);
EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(kFloatFormat));
}
// Testing compression gains
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->set_compression_gain_db(
apm_->gain_control()->compression_gain_db()));
int gain_db[] = {0, 10, 90};
for (size_t i = 0; i < arraysize(gain_db); i++) {
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_compression_gain_db(gain_db[i]));
ProcessStreamChooser(kFloatFormat);
EXPECT_EQ(gain_db[i], apm_->gain_control()->compression_gain_db());
for (int compression_gain_db : {0, 10, 90}) {
config.gain_controller1.compression_gain_db = compression_gain_db;
apm_->ApplyConfig(config);
apm_->set_stream_analog_level(100);
EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(kFloatFormat));
}
// Testing limiter off/on
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->enable_limiter(false));
EXPECT_FALSE(apm_->gain_control()->is_limiter_enabled());
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->enable_limiter(true));
EXPECT_TRUE(apm_->gain_control()->is_limiter_enabled());
for (bool enable : {false, true}) {
config.gain_controller1.enable_limiter = enable;
apm_->ApplyConfig(config);
apm_->set_stream_analog_level(100);
EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(kFloatFormat));
}
// Testing level limits
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->set_analog_level_limits(
apm_->gain_control()->analog_level_minimum(),
apm_->gain_control()->analog_level_maximum()));
int min_level[] = {0, 255, 1024};
for (size_t i = 0; i < arraysize(min_level); i++) {
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->set_analog_level_limits(
min_level[i], 1024));
EXPECT_EQ(min_level[i], apm_->gain_control()->analog_level_minimum());
std::array<int, 4> kMinLevels = {0, 0, 255, 65000};
std::array<int, 4> kMaxLevels = {255, 1024, 65535, 65535};
for (size_t i = 0; i < kMinLevels.size(); ++i) {
int min_level = kMinLevels[i];
int max_level = kMaxLevels[i];
config.gain_controller1.analog_level_minimum = min_level;
config.gain_controller1.analog_level_maximum = max_level;
apm_->ApplyConfig(config);
apm_->set_stream_analog_level((min_level + max_level) / 2);
EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(kFloatFormat));
}
int max_level[] = {0, 1024, 65535};
for (size_t i = 0; i < arraysize(min_level); i++) {
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_analog_level_limits(0, max_level[i]));
EXPECT_EQ(max_level[i], apm_->gain_control()->analog_level_maximum());
}
// TODO(ajm): stream_is_saturated() and stream_analog_level()
// Turn AGC off
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
EXPECT_FALSE(apm_->gain_control()->is_enabled());
}
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
TEST_F(ApmTest, GainControlDiesOnTooLowTargetLevelDbfs) {
EXPECT_DEATH(apm_->gain_control()->set_target_level_dbfs(-1), "");
auto config = apm_->GetConfig();
config.gain_controller1.target_level_dbfs = -1;
EXPECT_DEATH(apm_->ApplyConfig(config), "");
}
TEST_F(ApmTest, GainControlDiesOnTooHighTargetLevelDbfs) {
EXPECT_DEATH(apm_->gain_control()->set_target_level_dbfs(32), "");
auto config = apm_->GetConfig();
config.gain_controller1.target_level_dbfs = 32;
EXPECT_DEATH(apm_->ApplyConfig(config), "");
}
TEST_F(ApmTest, GainControlDiesOnTooLowCompressionGainDb) {
EXPECT_DEATH(apm_->gain_control()->set_compression_gain_db(-1), "");
auto config = apm_->GetConfig();
config.gain_controller1.compression_gain_db = -1;
EXPECT_DEATH(apm_->ApplyConfig(config), "");
}
TEST_F(ApmTest, GainControlDiesOnTooHighCompressionGainDb) {
EXPECT_DEATH(apm_->gain_control()->set_compression_gain_db(91), "");
auto config = apm_->GetConfig();
config.gain_controller1.compression_gain_db = 91;
EXPECT_DEATH(apm_->ApplyConfig(config), "");
}
TEST_F(ApmTest, GainControlDiesOnTooLowAnalogLevelLowerLimit) {
EXPECT_DEATH(apm_->gain_control()->set_analog_level_limits(-1, 512), "");
auto config = apm_->GetConfig();
config.gain_controller1.analog_level_minimum = -1;
EXPECT_DEATH(apm_->ApplyConfig(config), "");
}
TEST_F(ApmTest, GainControlDiesOnTooHighAnalogLevelUpperLimit) {
EXPECT_DEATH(apm_->gain_control()->set_analog_level_limits(512, 65536), "");
auto config = apm_->GetConfig();
config.gain_controller1.analog_level_maximum = 65536;
EXPECT_DEATH(apm_->ApplyConfig(config), "");
}
TEST_F(ApmTest, GainControlDiesOnInvertedAnalogLevelLimits) {
EXPECT_DEATH(apm_->gain_control()->set_analog_level_limits(512, 255), "");
auto config = apm_->GetConfig();
config.gain_controller1.analog_level_minimum = 512;
config.gain_controller1.analog_level_maximum = 255;
EXPECT_DEATH(apm_->ApplyConfig(config), "");
}
TEST_F(ApmTest, ApmDiesOnTooLowAnalogLevel) {
apm_->gain_control()->set_analog_level_limits(255, 512);
auto config = apm_->GetConfig();
config.gain_controller1.analog_level_minimum = 255;
config.gain_controller1.analog_level_maximum = 512;
apm_->ApplyConfig(config);
EXPECT_DEATH(apm_->set_stream_analog_level(254), "");
}
TEST_F(ApmTest, ApmDiesOnTooHighAnalogLevel) {
apm_->gain_control()->set_analog_level_limits(255, 512);
auto config = apm_->GetConfig();
config.gain_controller1.analog_level_minimum = 255;
config.gain_controller1.analog_level_maximum = 512;
apm_->ApplyConfig(config);
EXPECT_DEATH(apm_->set_stream_analog_level(513), "");
}
#endif
void ApmTest::RunQuantizedVolumeDoesNotGetStuckTest(int sample_rate) {
Init(sample_rate, sample_rate, sample_rate, 2, 2, 2, false);
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
auto config = apm_->GetConfig();
config.gain_controller1.enabled = true;
config.gain_controller1.mode =
AudioProcessing::Config::GainController1::kAdaptiveAnalog;
apm_->ApplyConfig(config);
int out_analog_level = 0;
for (int i = 0; i < 2000; ++i) {
@ -958,10 +974,9 @@ void ApmTest::RunQuantizedVolumeDoesNotGetStuckTest(int sample_rate) {
ScaleFrame(frame_, 0.25);
// Always pass in the same volume.
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_stream_analog_level(100));
apm_->set_stream_analog_level(100);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
out_analog_level = apm_->gain_control()->stream_analog_level();
out_analog_level = apm_->recommended_stream_analog_level();
}
// Ensure the AGC is still able to reach the maximum.
@ -978,9 +993,11 @@ TEST_F(ApmTest, QuantizedVolumeDoesNotGetStuck) {
void ApmTest::RunManualVolumeChangeIsPossibleTest(int sample_rate) {
Init(sample_rate, sample_rate, sample_rate, 2, 2, 2, false);
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
auto config = apm_->GetConfig();
config.gain_controller1.enabled = true;
config.gain_controller1.mode =
AudioProcessing::Config::GainController1::kAdaptiveAnalog;
apm_->ApplyConfig(config);
int out_analog_level = 100;
for (int i = 0; i < 1000; ++i) {
@ -988,10 +1005,9 @@ void ApmTest::RunManualVolumeChangeIsPossibleTest(int sample_rate) {
// Ensure the audio is at a low level, so the AGC will try to increase it.
ScaleFrame(frame_, 0.25);
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_stream_analog_level(out_analog_level));
apm_->set_stream_analog_level(out_analog_level);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
out_analog_level = apm_->gain_control()->stream_analog_level();
out_analog_level = apm_->recommended_stream_analog_level();
}
// Ensure the volume was raised.
@ -1004,10 +1020,9 @@ void ApmTest::RunManualVolumeChangeIsPossibleTest(int sample_rate) {
ReadFrameWithRewind(near_file_, frame_);
ScaleFrame(frame_, 0.25);
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_stream_analog_level(out_analog_level));
apm_->set_stream_analog_level(out_analog_level);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
out_analog_level = apm_->gain_control()->stream_analog_level();
out_analog_level = apm_->recommended_stream_analog_level();
// Check that AGC respected the manually adjusted volume.
EXPECT_LT(out_analog_level, highest_level_reached);
}
@ -1051,9 +1066,9 @@ TEST_F(ApmTest, AllProcessingDisabledByDefault) {
AudioProcessing::Config config = apm_->GetConfig();
EXPECT_FALSE(config.echo_canceller.enabled);
EXPECT_FALSE(config.high_pass_filter.enabled);
EXPECT_FALSE(config.gain_controller1.enabled);
EXPECT_FALSE(config.level_estimation.enabled);
EXPECT_FALSE(config.voice_detection.enabled);
EXPECT_FALSE(apm_->gain_control()->is_enabled());
EXPECT_FALSE(apm_->noise_suppression()->is_enabled());
}
@ -1125,10 +1140,9 @@ TEST_F(ApmTest, IdenticalInputChannelsResultInIdenticalOutputChannels) {
frame_->vad_activity_ = AudioFrame::kVadUnknown;
ASSERT_EQ(kNoErr, apm_->set_stream_delay_ms(0));
ASSERT_EQ(kNoErr,
apm_->gain_control()->set_stream_analog_level(analog_level));
apm_->set_stream_analog_level(analog_level);
ASSERT_EQ(kNoErr, apm_->ProcessStream(frame_));
analog_level = apm_->gain_control()->stream_analog_level();
analog_level = apm_->recommended_stream_analog_level();
VerifyChannelsAreEqual(frame_->data(), frame_->samples_per_channel_);
}
@ -1258,7 +1272,7 @@ void ApmTest::ProcessDebugDump(const std::string& in_filename,
// ProcessStream could have changed this for the output frame.
frame_->num_channels_ = apm_->num_input_channels();
EXPECT_NOERR(apm_->gain_control()->set_stream_analog_level(msg.level()));
apm_->set_stream_analog_level(msg.level());
EXPECT_NOERR(apm_->set_stream_delay_ms(msg.delay()));
if (msg.has_keypress()) {
apm_->set_stream_key_pressed(msg.keypress());
@ -1485,7 +1499,6 @@ TEST_F(ApmTest, Process) {
int frame_count = 0;
int has_voice_count = 0;
int is_saturated_count = 0;
int analog_level = 127;
int analog_level_average = 0;
int max_output_average = 0;
@ -1501,8 +1514,7 @@ TEST_F(ApmTest, Process) {
frame_->vad_activity_ = AudioFrame::kVadUnknown;
EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
EXPECT_EQ(apm_->kNoError,
apm_->gain_control()->set_stream_analog_level(analog_level));
apm_->set_stream_analog_level(analog_level);
EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
@ -1512,11 +1524,8 @@ TEST_F(ApmTest, Process) {
max_output_average += MaxAudioFrame(*frame_);
analog_level = apm_->gain_control()->stream_analog_level();
analog_level = apm_->recommended_stream_analog_level();
analog_level_average += analog_level;
if (apm_->gain_control()->stream_is_saturated()) {
is_saturated_count++;
}
AudioProcessingStats stats =
apm_->GetStatistics(/*has_remote_tracks=*/false);
EXPECT_TRUE(stats.voice_detected);
@ -1602,7 +1611,6 @@ TEST_F(ApmTest, Process) {
#endif
EXPECT_NEAR(test->has_voice_count(),
has_voice_count - kHasVoiceCountOffset, kHasVoiceCountNear);
EXPECT_NEAR(test->is_saturated_count(), is_saturated_count, kIntNear);
EXPECT_NEAR(test->analog_level_average(), analog_level_average, kIntNear);
EXPECT_NEAR(test->max_output_average(),
@ -1616,7 +1624,6 @@ TEST_F(ApmTest, Process) {
#endif
} else {
test->set_has_voice_count(has_voice_count);
test->set_is_saturated_count(is_saturated_count);
test->set_analog_level_average(analog_level_average);
test->set_max_output_average(max_output_average);
@ -1828,7 +1835,7 @@ class AudioProcessingTest
processing_config.reverse_output_stream(), rev_out_cb.channels()));
EXPECT_NOERR(ap->set_stream_delay_ms(0));
EXPECT_NOERR(ap->gain_control()->set_stream_analog_level(analog_level));
ap->set_stream_analog_level(analog_level);
EXPECT_NOERR(ap->ProcessStream(
fwd_cb.channels(), fwd_cb.num_frames(), input_rate,
@ -1852,7 +1859,7 @@ class AudioProcessingTest
ASSERT_EQ(rev_out_length, fwrite(float_data.get(), sizeof(float_data[0]),
rev_out_length, rev_out_file));
analog_level = ap->gain_control()->stream_analog_level();
analog_level = ap->recommended_stream_analog_level();
}
fclose(far_file);
fclose(near_file);
@ -2421,11 +2428,11 @@ std::unique_ptr<AudioProcessing> CreateApm(bool mobile_aec) {
AudioProcessing::Config apm_config;
apm_config.residual_echo_detector.enabled = true;
apm_config.high_pass_filter.enabled = false;
apm_config.gain_controller1.enabled = false;
apm_config.gain_controller2.enabled = false;
apm_config.echo_canceller.enabled = true;
apm_config.echo_canceller.mobile_mode = mobile_aec;
apm->ApplyConfig(apm_config);
EXPECT_EQ(apm->gain_control()->Enable(false), 0);
EXPECT_EQ(apm->noise_suppression()->Enable(false), 0);
return apm;
}

View File

@ -1,132 +0,0 @@
/*
* Copyright (c) 2019 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 "modules/audio_processing/gain_control_config_proxy.h"
namespace webrtc {
namespace {
AudioProcessing::Config::GainController1::Mode InterfaceModeToConfigMode(
GainControl::Mode agc_mode) {
using AgcConfig = AudioProcessing::Config::GainController1;
switch (agc_mode) {
case GainControl::kAdaptiveAnalog:
return AgcConfig::kAdaptiveAnalog;
case GainControl::kAdaptiveDigital:
return AgcConfig::kAdaptiveDigital;
case GainControl::kFixedDigital:
return AgcConfig::kFixedDigital;
}
}
} // namespace
GainControlConfigProxy::GainControlConfigProxy(
rtc::CriticalSection* crit_capture,
AudioProcessing* apm,
GainControl* agc)
: crit_capture_(crit_capture), apm_(apm), agc_(agc) {
RTC_DCHECK(apm);
RTC_DCHECK(agc);
RTC_DCHECK(crit_capture);
}
GainControlConfigProxy::~GainControlConfigProxy() = default;
int GainControlConfigProxy::set_stream_analog_level(int level) {
apm_->set_stream_analog_level(level);
return AudioProcessing::kNoError;
}
int GainControlConfigProxy::stream_analog_level() const {
return apm_->recommended_stream_analog_level();
}
int GainControlConfigProxy::Enable(bool enable) {
auto apm_config = apm_->GetConfig();
apm_config.gain_controller1.enabled = enable;
apm_->ApplyConfig(apm_config);
return AudioProcessing::kNoError;
}
int GainControlConfigProxy::set_mode(Mode mode) {
auto config = apm_->GetConfig();
config.gain_controller1.mode = InterfaceModeToConfigMode(mode);
apm_->ApplyConfig(config);
return AudioProcessing::kNoError;
}
int GainControlConfigProxy::set_target_level_dbfs(int level) {
auto config = apm_->GetConfig();
config.gain_controller1.target_level_dbfs = level;
apm_->ApplyConfig(config);
return AudioProcessing::kNoError;
}
int GainControlConfigProxy::set_compression_gain_db(int gain) {
apm_->SetRuntimeSetting(
AudioProcessing::RuntimeSetting::CreateCompressionGainDb(gain));
return AudioProcessing::kNoError;
}
int GainControlConfigProxy::enable_limiter(bool enable) {
auto config = apm_->GetConfig();
config.gain_controller1.enable_limiter = enable;
apm_->ApplyConfig(config);
return AudioProcessing::kNoError;
}
int GainControlConfigProxy::set_analog_level_limits(int minimum, int maximum) {
auto config = apm_->GetConfig();
config.gain_controller1.analog_level_minimum = minimum;
config.gain_controller1.analog_level_maximum = maximum;
apm_->ApplyConfig(config);
return AudioProcessing::kNoError;
}
bool GainControlConfigProxy::is_limiter_enabled() const {
rtc::CritScope cs_capture(crit_capture_);
return agc_->is_limiter_enabled();
}
int GainControlConfigProxy::compression_gain_db() const {
rtc::CritScope cs_capture(crit_capture_);
return agc_->compression_gain_db();
}
bool GainControlConfigProxy::is_enabled() const {
rtc::CritScope cs_capture(crit_capture_);
return agc_->is_enabled();
}
GainControl::Mode GainControlConfigProxy::mode() const {
rtc::CritScope cs_capture(crit_capture_);
return agc_->mode();
}
int GainControlConfigProxy::target_level_dbfs() const {
rtc::CritScope cs_capture(crit_capture_);
return agc_->target_level_dbfs();
}
int GainControlConfigProxy::analog_level_minimum() const {
rtc::CritScope cs_capture(crit_capture_);
return agc_->analog_level_minimum();
}
int GainControlConfigProxy::analog_level_maximum() const {
rtc::CritScope cs_capture(crit_capture_);
return agc_->analog_level_maximum();
}
bool GainControlConfigProxy::stream_is_saturated() const {
rtc::CritScope cs_capture(crit_capture_);
return agc_->stream_is_saturated();
}
} // namespace webrtc

View File

@ -1,62 +0,0 @@
/*
* Copyright (c) 2019 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 MODULES_AUDIO_PROCESSING_GAIN_CONTROL_CONFIG_PROXY_H_
#define MODULES_AUDIO_PROCESSING_GAIN_CONTROL_CONFIG_PROXY_H_
#include "modules/audio_processing/include/audio_processing.h"
#include "modules/audio_processing/include/gain_control.h"
#include "rtc_base/critical_section.h"
#include "rtc_base/thread_annotations.h"
namespace webrtc {
// This class forwards all gain control configuration to the audio processing
// module, for compatibility with AudioProcessing::Config.
class GainControlConfigProxy : public GainControl {
public:
GainControlConfigProxy(rtc::CriticalSection* crit_capture,
AudioProcessing* apm,
GainControl* agc);
GainControlConfigProxy(const GainControlConfigProxy&) = delete;
GainControlConfigProxy& operator=(const GainControlConfigProxy&) = delete;
~GainControlConfigProxy() override;
private:
// GainControl API during processing.
int set_stream_analog_level(int level) override;
int stream_analog_level() const override;
// GainControl config setters.
int Enable(bool enable) override;
int set_mode(Mode mode) override;
int set_target_level_dbfs(int level) override;
int set_compression_gain_db(int gain) override;
int enable_limiter(bool enable) override;
int set_analog_level_limits(int minimum, int maximum) override;
// GainControl config getters.
bool is_enabled() const override;
bool is_limiter_enabled() const override;
int compression_gain_db() const override;
int target_level_dbfs() const override;
int analog_level_minimum() const override;
int analog_level_maximum() const override;
bool stream_is_saturated() const override;
Mode mode() const override;
rtc::CriticalSection* crit_capture_ = nullptr;
AudioProcessing* apm_ = nullptr;
GainControl* agc_ RTC_GUARDED_BY(crit_capture_) = nullptr;
};
} // namespace webrtc
#endif // MODULES_AUDIO_PROCESSING_GAIN_CONTROL_CONFIG_PROXY_H_

View File

@ -1,163 +0,0 @@
/*
* Copyright (c) 2019 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 "modules/audio_processing/gain_control_config_proxy.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "modules/audio_processing/include/mock_audio_processing.h"
#include "rtc_base/critical_section.h"
#include "rtc_base/ref_counted_object.h"
#include "test/gtest.h"
namespace webrtc {
class GainControlConfigProxyTest : public ::testing::Test {
protected:
GainControlConfigProxyTest()
: apm_(new rtc::RefCountedObject<
::testing::StrictMock<test::MockAudioProcessing>>()),
agc_(),
proxy_(&lock_, apm_, &agc_) {
EXPECT_CALL(*apm_, GetConfig())
.WillRepeatedly(::testing::ReturnPointee(&apm_config_));
EXPECT_CALL(*apm_, ApplyConfig(::testing::_))
.WillRepeatedly(::testing::SaveArg<0>(&apm_config_));
}
GainControl* proxy() { return &proxy_; }
rtc::scoped_refptr<testing::StrictMock<test::MockAudioProcessing>> apm_;
::testing::StrictMock<test::MockGainControl> agc_;
AudioProcessing::Config apm_config_;
private:
rtc::CriticalSection lock_;
GainControlConfigProxy proxy_;
};
// GainControl API during processing.
TEST_F(GainControlConfigProxyTest, SetStreamAnalogLevel) {
EXPECT_CALL(*apm_, set_stream_analog_level(100));
proxy()->set_stream_analog_level(100);
}
TEST_F(GainControlConfigProxyTest, StreamAnalogLevel) {
EXPECT_CALL(*apm_, recommended_stream_analog_level())
.WillOnce(::testing::Return(100));
EXPECT_EQ(100, proxy()->stream_analog_level());
}
// GainControl config setters.
TEST_F(GainControlConfigProxyTest, SetEnable) {
proxy()->Enable(true);
EXPECT_TRUE(apm_config_.gain_controller1.enabled);
proxy()->Enable(false);
EXPECT_FALSE(apm_config_.gain_controller1.enabled);
}
TEST_F(GainControlConfigProxyTest, SetMode) {
proxy()->set_mode(GainControl::Mode::kAdaptiveAnalog);
EXPECT_EQ(apm_config_.gain_controller1.kAdaptiveAnalog,
apm_config_.gain_controller1.mode);
proxy()->set_mode(GainControl::Mode::kAdaptiveDigital);
EXPECT_EQ(apm_config_.gain_controller1.kAdaptiveDigital,
apm_config_.gain_controller1.mode);
proxy()->set_mode(GainControl::Mode::kFixedDigital);
EXPECT_EQ(apm_config_.gain_controller1.kFixedDigital,
apm_config_.gain_controller1.mode);
}
TEST_F(GainControlConfigProxyTest, SetTargetLevelDbfs) {
proxy()->set_target_level_dbfs(17);
EXPECT_EQ(17, apm_config_.gain_controller1.target_level_dbfs);
}
TEST_F(GainControlConfigProxyTest, SetCompressionGainDb) {
AudioProcessing::RuntimeSetting setting;
EXPECT_CALL(*apm_, SetRuntimeSetting(::testing::_))
.WillOnce(::testing::SaveArg<0>(&setting));
proxy()->set_compression_gain_db(17);
EXPECT_EQ(AudioProcessing::RuntimeSetting::Type::kCaptureCompressionGain,
setting.type());
float value;
setting.GetFloat(&value);
EXPECT_EQ(17, static_cast<int>(value + .5f));
}
TEST_F(GainControlConfigProxyTest, SetEnableLimiter) {
proxy()->enable_limiter(true);
EXPECT_TRUE(apm_config_.gain_controller1.enable_limiter);
proxy()->enable_limiter(false);
EXPECT_FALSE(apm_config_.gain_controller1.enable_limiter);
}
TEST_F(GainControlConfigProxyTest, SetAnalogLevelLimits) {
proxy()->set_analog_level_limits(100, 300);
EXPECT_EQ(100, apm_config_.gain_controller1.analog_level_minimum);
EXPECT_EQ(300, apm_config_.gain_controller1.analog_level_maximum);
}
TEST_F(GainControlConfigProxyTest, GetEnabled) {
EXPECT_CALL(agc_, is_enabled())
.WillOnce(::testing::Return(true))
.WillOnce(::testing::Return(false));
EXPECT_TRUE(proxy()->is_enabled());
EXPECT_FALSE(proxy()->is_enabled());
}
TEST_F(GainControlConfigProxyTest, GetLimiterEnabled) {
EXPECT_CALL(agc_, is_enabled())
.WillOnce(::testing::Return(true))
.WillOnce(::testing::Return(false));
EXPECT_TRUE(proxy()->is_enabled());
EXPECT_FALSE(proxy()->is_enabled());
}
TEST_F(GainControlConfigProxyTest, GetCompressionGainDb) {
EXPECT_CALL(agc_, compression_gain_db()).WillOnce(::testing::Return(17));
EXPECT_EQ(17, proxy()->compression_gain_db());
}
TEST_F(GainControlConfigProxyTest, GetTargetLevelDbfs) {
EXPECT_CALL(agc_, target_level_dbfs()).WillOnce(::testing::Return(17));
EXPECT_EQ(17, proxy()->target_level_dbfs());
}
TEST_F(GainControlConfigProxyTest, GetAnalogLevelMinimum) {
EXPECT_CALL(agc_, analog_level_minimum()).WillOnce(::testing::Return(17));
EXPECT_EQ(17, proxy()->analog_level_minimum());
}
TEST_F(GainControlConfigProxyTest, GetAnalogLevelMaximum) {
EXPECT_CALL(agc_, analog_level_maximum()).WillOnce(::testing::Return(17));
EXPECT_EQ(17, proxy()->analog_level_maximum());
}
TEST_F(GainControlConfigProxyTest, GetStreamIsSaturated) {
EXPECT_CALL(agc_, stream_is_saturated())
.WillOnce(::testing::Return(true))
.WillOnce(::testing::Return(false));
EXPECT_TRUE(proxy()->stream_is_saturated());
EXPECT_FALSE(proxy()->stream_is_saturated());
}
TEST_F(GainControlConfigProxyTest, GetMode) {
EXPECT_CALL(agc_, mode())
.WillOnce(::testing::Return(GainControl::Mode::kAdaptiveAnalog))
.WillOnce(::testing::Return(GainControl::Mode::kAdaptiveDigital))
.WillOnce(::testing::Return(GainControl::Mode::kFixedDigital));
EXPECT_EQ(GainControl::Mode::kAdaptiveAnalog, proxy()->mode());
EXPECT_EQ(GainControl::Mode::kAdaptiveDigital, proxy()->mode());
EXPECT_EQ(GainControl::Mode::kFixedDigital, proxy()->mode());
}
} // namespace webrtc

View File

@ -12,7 +12,7 @@
#define MODULES_AUDIO_PROCESSING_GAIN_CONTROL_FOR_EXPERIMENTAL_AGC_H_
#include "modules/audio_processing/agc/agc_manager_direct.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "modules/audio_processing/agc/gain_control.h"
#include "rtc_base/thread_checker.h"
namespace webrtc {

View File

@ -19,7 +19,7 @@
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "modules/audio_processing/include/gain_control.h"
#include "modules/audio_processing/agc/gain_control.h"
#include "rtc_base/constructor_magic.h"
namespace webrtc {

View File

@ -30,7 +30,6 @@
#include "modules/audio_processing/include/audio_generator.h"
#include "modules/audio_processing/include/audio_processing_statistics.h"
#include "modules/audio_processing/include/config.h"
#include "modules/audio_processing/include/gain_control.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/deprecation.h"
#include "rtc_base/ref_count.h"
@ -48,7 +47,6 @@ class StreamConfig;
class ProcessingConfig;
class EchoDetector;
class GainControl;
class NoiseSuppression;
class CustomAudioAnalyzer;
class CustomProcessing;
@ -190,19 +188,24 @@ struct ExperimentalNs {
// AudioProcessing::Config config;
// config.echo_canceller.enabled = true;
// config.echo_canceller.mobile_mode = false;
// config.high_pass_filter.enabled = true;
//
// config.gain_controller1.enabled = true;
// config.gain_controller1.mode =
// AudioProcessing::Config::GainController1::kAdaptiveAnalog;
// config.gain_controller1.analog_level_minimum = 0;
// config.gain_controller1.analog_level_maximum = 255;
//
// config.gain_controller2.enabled = true;
//
// config.high_pass_filter.enabled = true;
//
// config.voice_detection.enabled = true;
//
// apm->ApplyConfig(config)
//
// apm->noise_reduction()->set_level(kHighSuppression);
// apm->noise_reduction()->Enable(true);
//
// apm->gain_control()->set_analog_level_limits(0, 255);
// apm->gain_control()->set_mode(kAdaptiveAnalog);
// apm->gain_control()->Enable(true);
//
// apm->voice_detection()->Enable(true);
//
// // Start a voice call...
//
// // ... Render frame arrives bound for the audio HAL ...
@ -211,12 +214,12 @@ struct ExperimentalNs {
// // ... Capture frame arrives from the audio HAL ...
// // Call required set_stream_ functions.
// apm->set_stream_delay_ms(delay_ms);
// apm->gain_control()->set_stream_analog_level(analog_level);
// apm->set_stream_analog_level(analog_level);
//
// apm->ProcessStream(capture_frame);
//
// // Call required stream_ functions.
// analog_level = apm->gain_control()->stream_analog_level();
// analog_level = apm->recommended_stream_analog_level();
// has_voice = apm->stream_has_voice();
//
// // Repeate render and capture processing for the duration of the call...
@ -683,7 +686,6 @@ class RTC_EXPORT AudioProcessing : public rtc::RefCountInterface {
// These provide access to the component interfaces and should never return
// NULL. The pointers will be valid for the lifetime of the APM instance.
// The memory for these objects is entirely managed internally.
virtual GainControl* gain_control() const = 0;
virtual NoiseSuppression* noise_suppression() const = 0;
// Returns the last applied configuration.

View File

@ -22,27 +22,6 @@
namespace webrtc {
namespace test {
class MockGainControl : public GainControl {
public:
virtual ~MockGainControl() {}
MOCK_METHOD1(Enable, int(bool enable));
MOCK_CONST_METHOD0(is_enabled, bool());
MOCK_METHOD1(set_stream_analog_level, int(int level));
MOCK_CONST_METHOD0(stream_analog_level, int());
MOCK_METHOD1(set_mode, int(Mode mode));
MOCK_CONST_METHOD0(mode, Mode());
MOCK_METHOD1(set_target_level_dbfs, int(int level));
MOCK_CONST_METHOD0(target_level_dbfs, int());
MOCK_METHOD1(set_compression_gain_db, int(int gain));
MOCK_CONST_METHOD0(compression_gain_db, int());
MOCK_METHOD1(enable_limiter, int(bool enable));
MOCK_CONST_METHOD0(is_limiter_enabled, bool());
MOCK_METHOD2(set_analog_level_limits, int(int minimum, int maximum));
MOCK_CONST_METHOD0(analog_level_minimum, int());
MOCK_CONST_METHOD0(analog_level_maximum, int());
MOCK_CONST_METHOD0(stream_is_saturated, bool());
};
class MockNoiseSuppression : public NoiseSuppression {
public:
virtual ~MockNoiseSuppression() {}
@ -87,8 +66,7 @@ class MockEchoControl : public EchoControl {
class MockAudioProcessing : public ::testing::NiceMock<AudioProcessing> {
public:
MockAudioProcessing()
: gain_control_(new ::testing::NiceMock<MockGainControl>()),
noise_suppression_(new ::testing::NiceMock<MockNoiseSuppression>()) {}
: noise_suppression_(new ::testing::NiceMock<MockNoiseSuppression>()) {}
virtual ~MockAudioProcessing() {}
@ -154,7 +132,6 @@ class MockAudioProcessing : public ::testing::NiceMock<AudioProcessing> {
MOCK_METHOD0(UpdateHistogramsOnCallEnd, void());
MOCK_CONST_METHOD1(GetStatistics, AudioProcessingStats(bool));
virtual MockGainControl* gain_control() const { return gain_control_.get(); }
virtual MockNoiseSuppression* noise_suppression() const {
return noise_suppression_.get();
}
@ -162,7 +139,6 @@ class MockAudioProcessing : public ::testing::NiceMock<AudioProcessing> {
MOCK_CONST_METHOD0(GetConfig, AudioProcessing::Config());
private:
std::unique_ptr<MockGainControl> gain_control_;
std::unique_ptr<MockNoiseSuppression> noise_suppression_;
};

View File

@ -376,8 +376,7 @@ void AecDumpBasedSimulator::HandleMessage(
if (msg.has_agc_enabled() || settings_.use_agc) {
bool enable = settings_.use_agc ? *settings_.use_agc : msg.agc_enabled();
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->gain_control()->Enable(enable));
apm_config.gain_controller1.enabled = enable;
if (settings_.use_verbose_logging) {
std::cout << " agc_enabled: " << (enable ? "true" : "false")
<< std::endl;
@ -386,9 +385,9 @@ void AecDumpBasedSimulator::HandleMessage(
if (msg.has_agc_mode() || settings_.agc_mode) {
int mode = settings_.agc_mode ? *settings_.agc_mode : msg.agc_mode();
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->gain_control()->set_mode(
static_cast<webrtc::GainControl::Mode>(mode)));
apm_config.gain_controller1.mode =
static_cast<webrtc::AudioProcessing::Config::GainController1::Mode>(
mode);
if (settings_.use_verbose_logging) {
std::cout << " agc_mode: " << mode << std::endl;
}
@ -397,8 +396,7 @@ void AecDumpBasedSimulator::HandleMessage(
if (msg.has_agc_limiter_enabled() || settings_.use_agc_limiter) {
bool enable = settings_.use_agc_limiter ? *settings_.use_agc_limiter
: msg.agc_limiter_enabled();
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->gain_control()->enable_limiter(enable));
apm_config.gain_controller1.enable_limiter = enable;
if (settings_.use_verbose_logging) {
std::cout << " agc_limiter_enabled: " << (enable ? "true" : "false")
<< std::endl;

View File

@ -188,15 +188,12 @@ void AudioProcessingSimulator::ProcessStream(bool fixed_interface) {
}
// Notify the current mic level to AGC.
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->gain_control()->set_stream_analog_level(
fake_recording_device_.MicLevel()));
ap_->set_stream_analog_level(fake_recording_device_.MicLevel());
} else {
// Notify the current mic level to AGC.
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->gain_control()->set_stream_analog_level(
settings_.aec_dump_input_filename ? aec_dump_mic_level_
: analog_mic_level_));
ap_->set_stream_analog_level(settings_.aec_dump_input_filename
? aec_dump_mic_level_
: analog_mic_level_);
}
// Process the current audio frame.
@ -218,7 +215,7 @@ void AudioProcessingSimulator::ProcessStream(bool fixed_interface) {
// Store the mic level suggested by AGC.
// Note that when the analog gain is simulated and an AEC dump is used as
// input, |analog_mic_level_| will not be used with set_stream_analog_level().
analog_mic_level_ = ap_->gain_control()->stream_analog_level();
analog_mic_level_ = ap_->recommended_stream_analog_level();
if (settings_.simulate_mic_gain) {
fake_recording_device_.SetMicLevel(analog_mic_level_);
}
@ -463,6 +460,25 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
apm_config.voice_detection.enabled = *settings_.use_vad;
}
if (settings_.use_agc) {
apm_config.gain_controller1.enabled = *settings_.use_agc;
}
if (settings_.agc_mode) {
apm_config.gain_controller1.mode =
static_cast<webrtc::AudioProcessing::Config::GainController1::Mode>(
*settings_.agc_mode);
}
if (settings_.use_agc_limiter) {
apm_config.gain_controller1.enable_limiter = *settings_.use_agc_limiter;
}
if (settings_.agc_target_level) {
apm_config.gain_controller1.target_level_dbfs = *settings_.agc_target_level;
}
if (settings_.agc_compression_gain) {
apm_config.gain_controller1.compression_gain_db =
*settings_.agc_compression_gain;
}
if (settings_.use_refined_adaptive_filter) {
config.Set<RefinedAdaptiveFilter>(
new RefinedAdaptiveFilter(*settings_.use_refined_adaptive_filter));
@ -498,34 +514,10 @@ void AudioProcessingSimulator::CreateAudioProcessor() {
ap_->ApplyConfig(apm_config);
if (settings_.use_agc) {
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->gain_control()->Enable(*settings_.use_agc));
}
if (settings_.use_ns) {
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->noise_suppression()->Enable(*settings_.use_ns));
}
if (settings_.use_agc_limiter) {
RTC_CHECK_EQ(AudioProcessing::kNoError, ap_->gain_control()->enable_limiter(
*settings_.use_agc_limiter));
}
if (settings_.agc_target_level) {
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->gain_control()->set_target_level_dbfs(
*settings_.agc_target_level));
}
if (settings_.agc_compression_gain) {
RTC_CHECK_EQ(AudioProcessing::kNoError,
ap_->gain_control()->set_compression_gain_db(
*settings_.agc_compression_gain));
}
if (settings_.agc_mode) {
RTC_CHECK_EQ(
AudioProcessing::kNoError,
ap_->gain_control()->set_mode(
static_cast<webrtc::GainControl::Mode>(*settings_.agc_mode)));
}
if (settings_.ns_level) {
RTC_CHECK_EQ(
AudioProcessing::kNoError,

View File

@ -57,7 +57,6 @@ struct SimulationSettings {
absl::optional<bool> use_hpf;
absl::optional<bool> use_ns;
absl::optional<bool> use_ts;
absl::optional<bool> use_ie;
absl::optional<bool> use_vad;
absl::optional<bool> use_le;
absl::optional<bool> use_all;

View File

@ -338,7 +338,6 @@ SimulationSettings CreateSettings() {
if (absl::GetFlag(FLAGS_all_default)) {
settings.use_le = true;
settings.use_vad = true;
settings.use_ie = false;
settings.use_ts = true;
settings.use_ns = true;
settings.use_hpf = true;

View File

@ -119,8 +119,7 @@ void DebugDumpReplayer::OnStreamEvent(const audioproc::Stream& msg) {
// APM should have been created.
RTC_CHECK(apm_.get());
RTC_CHECK_EQ(AudioProcessing::kNoError,
apm_->gain_control()->set_stream_analog_level(msg.level()));
apm_->set_stream_analog_level(msg.level());
RTC_CHECK_EQ(AudioProcessing::kNoError,
apm_->set_stream_delay_ms(msg.delay()));
@ -237,21 +236,17 @@ void DebugDumpReplayer::ConfigureApm(const audioproc::Config& msg) {
static_cast<AudioProcessing::Config::NoiseSuppression::Level>(
msg.ns_level());
apm_->ApplyConfig(apm_config);
// AGC configs.
RTC_CHECK(msg.has_agc_enabled());
RTC_CHECK_EQ(AudioProcessing::kNoError,
apm_->gain_control()->Enable(msg.agc_enabled()));
RTC_CHECK(msg.has_agc_mode());
RTC_CHECK_EQ(AudioProcessing::kNoError,
apm_->gain_control()->set_mode(
static_cast<GainControl::Mode>(msg.agc_mode())));
RTC_CHECK(msg.has_agc_limiter_enabled());
RTC_CHECK_EQ(AudioProcessing::kNoError,
apm_->gain_control()->enable_limiter(msg.agc_limiter_enabled()));
apm_config.gain_controller1.enabled = msg.agc_enabled();
apm_config.gain_controller1.mode =
static_cast<AudioProcessing::Config::GainController1::Mode>(
msg.agc_mode());
apm_config.gain_controller1.enable_limiter = msg.agc_limiter_enabled();
apm_->ApplyConfig(apm_config);
}
void DebugDumpReplayer::LoadNextMessage() {

View File

@ -529,8 +529,9 @@ TEST_F(DebugDumpTest, MAYBE_ToggleAgc) {
generator.StartRecording();
generator.Process(100);
GainControl* agc = generator.apm()->gain_control();
EXPECT_EQ(AudioProcessing::kNoError, agc->Enable(!agc->is_enabled()));
AudioProcessing::Config apm_config = generator.apm()->GetConfig();
apm_config.gain_controller1.enabled = !apm_config.gain_controller1.enabled;
generator.apm()->ApplyConfig(apm_config);
generator.Process(100);
generator.StopRecording();