Propagate field trials into AgcManagerDirect

Bug: webrtc:369904700
Change-Id: I8389627f46494f825bcdcb59022ddfa992f74639
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/372381
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43722}
This commit is contained in:
Danil Chapovalov 2024-12-20 16:14:22 +01:00 committed by WebRTC LUCI CQ
parent 83861d5649
commit bf4c1bcd94
5 changed files with 164 additions and 207 deletions

View File

@ -25,7 +25,9 @@ rtc_library("agc") {
"..:audio_buffer", "..:audio_buffer",
"..:audio_frame_view", "..:audio_frame_view",
"../../../api:array_view", "../../../api:array_view",
"../../../api:field_trials_view",
"../../../api/audio:audio_processing", "../../../api/audio:audio_processing",
"../../../api/environment",
"../../../common_audio", "../../../common_audio",
"../../../common_audio:common_audio_c", "../../../common_audio:common_audio_c",
"../../../rtc_base:checks", "../../../rtc_base:checks",
@ -106,13 +108,15 @@ if (rtc_include_tests) {
":level_estimation", ":level_estimation",
"..:mocks", "..:mocks",
"../../../api:array_view", "../../../api:array_view",
"../../../api:field_trials",
"../../../api/environment",
"../../../api/environment:environment_factory",
"../../../rtc_base:checks", "../../../rtc_base:checks",
"../../../rtc_base:random", "../../../rtc_base:random",
"../../../rtc_base:safe_conversions", "../../../rtc_base:safe_conversions",
"../../../rtc_base:safe_minmax", "../../../rtc_base:safe_minmax",
"../../../rtc_base:stringutils", "../../../rtc_base:stringutils",
"../../../system_wrappers:metrics", "../../../system_wrappers:metrics",
"../../../test:field_trial",
"../../../test:fileutils", "../../../test:fileutils",
"../../../test:test_support", "../../../test:test_support",
"//testing/gtest", "//testing/gtest",

View File

@ -14,6 +14,8 @@
#include <cmath> #include <cmath>
#include "api/array_view.h" #include "api/array_view.h"
#include "api/environment/environment.h"
#include "api/field_trials_view.h"
#include "common_audio/include/audio_util.h" #include "common_audio/include/audio_util.h"
#include "modules/audio_processing/agc/gain_control.h" #include "modules/audio_processing/agc/gain_control.h"
#include "modules/audio_processing/agc2/gain_map_internal.h" #include "modules/audio_processing/agc2/gain_map_internal.h"
@ -22,7 +24,6 @@
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_minmax.h" #include "rtc_base/numerics/safe_minmax.h"
#include "system_wrappers/include/field_trial.h"
#include "system_wrappers/include/metrics.h" #include "system_wrappers/include/metrics.h"
namespace webrtc { namespace webrtc {
@ -69,14 +70,13 @@ using AnalogAgcConfig =
// string. Returns an unspecified value if the field trial is not specified, if // string. Returns an unspecified value if the field trial is not specified, if
// disabled or if it cannot be parsed. Example: // disabled or if it cannot be parsed. Example:
// 'WebRTC-Audio-2ndAgcMinMicLevelExperiment/Enabled-80' => returns 80. // 'WebRTC-Audio-2ndAgcMinMicLevelExperiment/Enabled-80' => returns 80.
std::optional<int> GetMinMicLevelOverride() { std::optional<int> GetMinMicLevelOverride(const FieldTrialsView& field_trials) {
constexpr char kMinMicLevelFieldTrial[] = constexpr char kMinMicLevelFieldTrial[] =
"WebRTC-Audio-2ndAgcMinMicLevelExperiment"; "WebRTC-Audio-2ndAgcMinMicLevelExperiment";
if (!webrtc::field_trial::IsEnabled(kMinMicLevelFieldTrial)) { if (!field_trials.IsEnabled(kMinMicLevelFieldTrial)) {
return std::nullopt; return std::nullopt;
} }
const auto field_trial_string = const auto field_trial_string = field_trials.Lookup(kMinMicLevelFieldTrial);
webrtc::field_trial::FindFullName(kMinMicLevelFieldTrial);
int min_mic_level = -1; int min_mic_level = -1;
sscanf(field_trial_string.c_str(), "Enabled-%d", &min_mic_level); sscanf(field_trial_string.c_str(), "Enabled-%d", &min_mic_level);
if (min_mic_level >= 0 && min_mic_level <= 255) { if (min_mic_level >= 0 && min_mic_level <= 255) {
@ -447,19 +447,21 @@ void MonoAgc::UpdateCompressor() {
std::atomic<int> AgcManagerDirect::instance_counter_(0); std::atomic<int> AgcManagerDirect::instance_counter_(0);
AgcManagerDirect::AgcManagerDirect( AgcManagerDirect::AgcManagerDirect(
const Environment& env,
const AudioProcessing::Config::GainController1::AnalogGainController& const AudioProcessing::Config::GainController1::AnalogGainController&
analog_config, analog_config,
Agc* agc) Agc* agc)
: AgcManagerDirect(/*num_capture_channels=*/1, analog_config) { : AgcManagerDirect(env, /*num_capture_channels=*/1, analog_config) {
RTC_DCHECK(channel_agcs_[0]); RTC_DCHECK(channel_agcs_[0]);
RTC_DCHECK(agc); RTC_DCHECK(agc);
channel_agcs_[0]->set_agc(agc); channel_agcs_[0]->set_agc(agc);
} }
AgcManagerDirect::AgcManagerDirect(int num_capture_channels, AgcManagerDirect::AgcManagerDirect(const Environment& env,
int num_capture_channels,
const AnalogAgcConfig& analog_config) const AnalogAgcConfig& analog_config)
: analog_controller_enabled_(analog_config.enabled), : analog_controller_enabled_(analog_config.enabled),
min_mic_level_override_(GetMinMicLevelOverride()), min_mic_level_override_(GetMinMicLevelOverride(env.field_trials())),
data_dumper_(new ApmDataDumper(instance_counter_.fetch_add(1) + 1)), data_dumper_(new ApmDataDumper(instance_counter_.fetch_add(1) + 1)),
num_capture_channels_(num_capture_channels), num_capture_channels_(num_capture_channels),
disable_digital_adaptive_(!analog_config.enable_digital_adaptive), disable_digital_adaptive_(!analog_config.enable_digital_adaptive),

View File

@ -17,6 +17,7 @@
#include "api/array_view.h" #include "api/array_view.h"
#include "api/audio/audio_processing.h" #include "api/audio/audio_processing.h"
#include "api/environment/environment.h"
#include "modules/audio_processing/agc/agc.h" #include "modules/audio_processing/agc/agc.h"
#include "modules/audio_processing/agc2/clipping_predictor.h" #include "modules/audio_processing/agc2/clipping_predictor.h"
#include "modules/audio_processing/audio_buffer.h" #include "modules/audio_processing/audio_buffer.h"
@ -42,6 +43,7 @@ class AgcManagerDirect final {
// passed to `AnalyzePreProcess()` and `Process()`. Clamps // passed to `AnalyzePreProcess()` and `Process()`. Clamps
// `analog_config.startup_min_level` in the [12, 255] range. // `analog_config.startup_min_level` in the [12, 255] range.
AgcManagerDirect( AgcManagerDirect(
const Environment& env,
int num_capture_channels, int num_capture_channels,
const AudioProcessing::Config::GainController1::AnalogGainController& const AudioProcessing::Config::GainController1::AnalogGainController&
analog_config); analog_config);
@ -142,6 +144,7 @@ class AgcManagerDirect final {
// Ctor that creates a single channel AGC and by injecting `agc`. // Ctor that creates a single channel AGC and by injecting `agc`.
// `agc` will be owned by this class; hence, do not delete it. // `agc` will be owned by this class; hence, do not delete it.
AgcManagerDirect( AgcManagerDirect(
const Environment& env,
const AudioProcessing::Config::GainController1::AnalogGainController& const AudioProcessing::Config::GainController1::AnalogGainController&
analog_config, analog_config,
Agc* agc); Agc* agc);

View File

@ -15,12 +15,14 @@
#include <tuple> #include <tuple>
#include <vector> #include <vector>
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/field_trials.h"
#include "modules/audio_processing/agc/gain_control.h" #include "modules/audio_processing/agc/gain_control.h"
#include "modules/audio_processing/agc/mock_agc.h" #include "modules/audio_processing/agc/mock_agc.h"
#include "modules/audio_processing/include/mock_audio_processing.h" #include "modules/audio_processing/include/mock_audio_processing.h"
#include "rtc_base/numerics/safe_minmax.h" #include "rtc_base/numerics/safe_minmax.h"
#include "rtc_base/strings/string_builder.h" #include "rtc_base/strings/string_builder.h"
#include "test/field_trial.h"
#include "test/gmock.h" #include "test/gmock.h"
#include "test/gtest.h" #include "test/gtest.h"
#include "test/testsupport/file_utils.h" #include "test/testsupport/file_utils.h"
@ -78,24 +80,32 @@ class MockGainControl : public GainControl {
MOCK_METHOD(bool, stream_is_saturated, (), (const, override)); MOCK_METHOD(bool, stream_is_saturated, (), (const, override));
}; };
// TODO(bugs.webrtc.org/12874): Remove and use designated initializers once // Construction parameters that tests may explicitely specify.
// fixed. struct AgcManagerDirectTestParams {
std::string field_trials;
int clipped_level_min = kClippedMin;
bool enable_digital_adaptive = false;
int clipped_level_step = kClippedLevelStep;
float clipped_ratio_threshold = kClippedRatioThreshold;
int clipped_wait_frames = kClippedWaitFrames;
AnalogAgcConfig::ClippingPredictor clipping_predictor;
};
std::unique_ptr<AgcManagerDirect> CreateAgcManagerDirect( std::unique_ptr<AgcManagerDirect> CreateAgcManagerDirect(
int startup_min_volume, AgcManagerDirectTestParams p = {}) {
int clipped_level_step, auto manager = std::make_unique<AgcManagerDirect>(
float clipped_ratio_threshold, CreateEnvironment(FieldTrials::CreateNoGlobal(p.field_trials)),
int clipped_wait_frames, kNumChannels,
const ClippingPredictorConfig& clipping_predictor_config = AnalogAgcConfig{.startup_min_volume = kInitialInputVolume,
kDefaultAnalogConfig.clipping_predictor) { .clipped_level_min = p.clipped_level_min,
AnalogAgcConfig config; .enable_digital_adaptive = p.enable_digital_adaptive,
config.startup_min_volume = startup_min_volume; .clipped_level_step = p.clipped_level_step,
config.clipped_level_min = kClippedMin; .clipped_ratio_threshold = p.clipped_ratio_threshold,
config.enable_digital_adaptive = false; .clipped_wait_frames = p.clipped_wait_frames,
config.clipped_level_step = clipped_level_step; .clipping_predictor = p.clipping_predictor});
config.clipped_ratio_threshold = clipped_ratio_threshold; manager->Initialize();
config.clipped_wait_frames = clipped_wait_frames; manager->set_stream_analog_level(kInitialInputVolume);
config.clipping_predictor = clipping_predictor_config; return manager;
return std::make_unique<AgcManagerDirect>(/*num_capture_channels=*/1, config);
} }
// Deprecated. // Deprecated.
@ -329,7 +339,7 @@ constexpr AnalogAgcConfig GetDisabledAnalogAgcConfig() {
class AgcManagerDirectTestHelper { class AgcManagerDirectTestHelper {
public: public:
// Ctor. Initializes `audio_buffer` with zeros. // Ctor. Initializes `audio_buffer` with zeros.
AgcManagerDirectTestHelper() explicit AgcManagerDirectTestHelper(const Environment& env)
: audio_buffer(kSampleRateHz, : audio_buffer(kSampleRateHz,
kNumChannels, kNumChannels,
kSampleRateHz, kSampleRateHz,
@ -337,7 +347,7 @@ class AgcManagerDirectTestHelper {
kSampleRateHz, kSampleRateHz,
kNumChannels), kNumChannels),
mock_agc(new ::testing::NiceMock<MockAgc>()), mock_agc(new ::testing::NiceMock<MockAgc>()),
manager(GetAnalogAgcTestConfig(), mock_agc) { manager(env, GetAnalogAgcTestConfig(), mock_agc) {
manager.Initialize(); manager.Initialize();
manager.SetupDigitalGainControl(mock_gain_control); manager.SetupDigitalGainControl(mock_gain_control);
WriteAudioBufferSamples(/*samples_value=*/0.0f, /*clipped_ratio=*/0.0f, WriteAudioBufferSamples(/*samples_value=*/0.0f, /*clipped_ratio=*/0.0f,
@ -438,8 +448,8 @@ class AgcManagerDirectParametrizedTest
: public ::testing::TestWithParam<std::tuple<std::optional<int>, bool>> { : public ::testing::TestWithParam<std::tuple<std::optional<int>, bool>> {
protected: protected:
AgcManagerDirectParametrizedTest() AgcManagerDirectParametrizedTest()
: field_trials_( : env_(CreateEnvironment(FieldTrials::CreateNoGlobal(
GetAgcMinMicLevelExperimentFieldTrial(std::get<0>(GetParam()))) {} GetAgcMinMicLevelExperimentFieldTrial(std::get<0>(GetParam()))))) {}
bool IsMinMicLevelOverridden() const { bool IsMinMicLevelOverridden() const {
return std::get<0>(GetParam()).has_value(); return std::get<0>(GetParam()).has_value();
@ -453,8 +463,7 @@ class AgcManagerDirectParametrizedTest
return IsRmsErrorOverridden() ? std::optional<float>(value) : std::nullopt; return IsRmsErrorOverridden() ? std::optional<float>(value) : std::nullopt;
} }
private: const Environment env_;
test::ScopedFieldTrials field_trials_;
}; };
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
@ -469,10 +478,10 @@ INSTANTIATE_TEST_SUITE_P(
// differs. // differs.
TEST_P(AgcManagerDirectParametrizedTest, TEST_P(AgcManagerDirectParametrizedTest,
DisabledAnalogAgcDoesNotAdaptDownwards) { DisabledAnalogAgcDoesNotAdaptDownwards) {
AgcManagerDirect manager_no_analog_agc(kNumChannels, AgcManagerDirect manager_no_analog_agc(env_, kNumChannels,
GetDisabledAnalogAgcConfig()); GetDisabledAnalogAgcConfig());
manager_no_analog_agc.Initialize(); manager_no_analog_agc.Initialize();
AgcManagerDirect manager_with_analog_agc(kNumChannels, AgcManagerDirect manager_with_analog_agc(env_, kNumChannels,
GetAnalogAgcTestConfig()); GetAnalogAgcTestConfig());
manager_with_analog_agc.Initialize(); manager_with_analog_agc.Initialize();
@ -523,10 +532,10 @@ TEST_P(AgcManagerDirectParametrizedTest,
// frames to APM config. The test passes but internally the gain update timing // frames to APM config. The test passes but internally the gain update timing
// differs. // differs.
TEST_P(AgcManagerDirectParametrizedTest, DisabledAnalogAgcDoesNotAdaptUpwards) { TEST_P(AgcManagerDirectParametrizedTest, DisabledAnalogAgcDoesNotAdaptUpwards) {
AgcManagerDirect manager_no_analog_agc(kNumChannels, AgcManagerDirect manager_no_analog_agc(env_, kNumChannels,
GetDisabledAnalogAgcConfig()); GetDisabledAnalogAgcConfig());
manager_no_analog_agc.Initialize(); manager_no_analog_agc.Initialize();
AgcManagerDirect manager_with_analog_agc(kNumChannels, AgcManagerDirect manager_with_analog_agc(env_, kNumChannels,
GetAnalogAgcTestConfig()); GetAnalogAgcTestConfig());
manager_with_analog_agc.Initialize(); manager_with_analog_agc.Initialize();
@ -552,7 +561,7 @@ TEST_P(AgcManagerDirectParametrizedTest, DisabledAnalogAgcDoesNotAdaptUpwards) {
TEST_P(AgcManagerDirectParametrizedTest, TEST_P(AgcManagerDirectParametrizedTest,
StartupMinVolumeConfigurationIsRespected) { StartupMinVolumeConfigurationIsRespected) {
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, helper.CallAgcSequence(kInitialInputVolume,
GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kHighSpeechProbability),
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -563,7 +572,7 @@ TEST_P(AgcManagerDirectParametrizedTest, MicVolumeResponseToRmsError) {
const auto speech_probability_override = const auto speech_probability_override =
GetOverrideOrEmpty(kHighSpeechProbability); GetOverrideOrEmpty(kHighSpeechProbability);
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -626,7 +635,7 @@ TEST_P(AgcManagerDirectParametrizedTest, MicVolumeIsLimited) {
const auto speech_probability_override = const auto speech_probability_override =
GetOverrideOrEmpty(kHighSpeechProbability); GetOverrideOrEmpty(kHighSpeechProbability);
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -708,7 +717,7 @@ TEST_P(AgcManagerDirectParametrizedTest, CompressorStepsTowardsTarget) {
const auto speech_probability_override = const auto speech_probability_override =
GetOverrideOrEmpty(kHighSpeechProbability); GetOverrideOrEmpty(kHighSpeechProbability);
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -780,7 +789,7 @@ TEST_P(AgcManagerDirectParametrizedTest, CompressorErrorIsDeemphasized) {
const auto speech_probability_override = const auto speech_probability_override =
GetOverrideOrEmpty(kHighSpeechProbability); GetOverrideOrEmpty(kHighSpeechProbability);
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -825,7 +834,7 @@ TEST_P(AgcManagerDirectParametrizedTest, CompressorReachesMaximum) {
const auto speech_probability_override = const auto speech_probability_override =
GetOverrideOrEmpty(kHighSpeechProbability); GetOverrideOrEmpty(kHighSpeechProbability);
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -862,7 +871,7 @@ TEST_P(AgcManagerDirectParametrizedTest, CompressorReachesMinimum) {
const auto speech_probability_override = const auto speech_probability_override =
GetOverrideOrEmpty(kHighSpeechProbability); GetOverrideOrEmpty(kHighSpeechProbability);
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -895,7 +904,7 @@ TEST_P(AgcManagerDirectParametrizedTest, CompressorReachesMinimum) {
} }
TEST_P(AgcManagerDirectParametrizedTest, NoActionWhileMuted) { TEST_P(AgcManagerDirectParametrizedTest, NoActionWhileMuted) {
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, helper.CallAgcSequence(kInitialInputVolume,
GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kHighSpeechProbability),
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -913,7 +922,7 @@ TEST_P(AgcManagerDirectParametrizedTest, NoActionWhileMuted) {
} }
TEST_P(AgcManagerDirectParametrizedTest, UnmutingChecksVolumeWithoutRaising) { TEST_P(AgcManagerDirectParametrizedTest, UnmutingChecksVolumeWithoutRaising) {
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, helper.CallAgcSequence(kInitialInputVolume,
GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kHighSpeechProbability),
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -934,7 +943,7 @@ TEST_P(AgcManagerDirectParametrizedTest, UnmutingChecksVolumeWithoutRaising) {
} }
TEST_P(AgcManagerDirectParametrizedTest, UnmutingRaisesTooLowVolume) { TEST_P(AgcManagerDirectParametrizedTest, UnmutingRaisesTooLowVolume) {
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, helper.CallAgcSequence(kInitialInputVolume,
GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kHighSpeechProbability),
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -958,7 +967,7 @@ TEST_P(AgcManagerDirectParametrizedTest,
const auto speech_probability_override = const auto speech_probability_override =
GetOverrideOrEmpty(kHighSpeechProbability); GetOverrideOrEmpty(kHighSpeechProbability);
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1000,7 +1009,7 @@ TEST_P(AgcManagerDirectParametrizedTest,
const auto speech_probability_override = const auto speech_probability_override =
GetOverrideOrEmpty(kHighSpeechProbability); GetOverrideOrEmpty(kHighSpeechProbability);
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1048,7 +1057,7 @@ TEST_P(AgcManagerDirectParametrizedTest,
const auto speech_probability_override = const auto speech_probability_override =
GetOverrideOrEmpty(kHighSpeechProbability); GetOverrideOrEmpty(kHighSpeechProbability);
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1094,7 +1103,7 @@ TEST_P(AgcManagerDirectParametrizedTest,
const auto speech_probability_override = const auto speech_probability_override =
GetOverrideOrEmpty(kHighSpeechProbability); GetOverrideOrEmpty(kHighSpeechProbability);
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1110,7 +1119,7 @@ TEST_P(AgcManagerDirectParametrizedTest,
} }
TEST_P(AgcManagerDirectParametrizedTest, NoClippingHasNoImpact) { TEST_P(AgcManagerDirectParametrizedTest, NoClippingHasNoImpact) {
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, helper.CallAgcSequence(kInitialInputVolume,
GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kHighSpeechProbability),
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1120,7 +1129,7 @@ TEST_P(AgcManagerDirectParametrizedTest, NoClippingHasNoImpact) {
} }
TEST_P(AgcManagerDirectParametrizedTest, ClippingUnderThresholdHasNoImpact) { TEST_P(AgcManagerDirectParametrizedTest, ClippingUnderThresholdHasNoImpact) {
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, helper.CallAgcSequence(kInitialInputVolume,
GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kHighSpeechProbability),
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1130,7 +1139,7 @@ TEST_P(AgcManagerDirectParametrizedTest, ClippingUnderThresholdHasNoImpact) {
} }
TEST_P(AgcManagerDirectParametrizedTest, ClippingLowersVolume) { TEST_P(AgcManagerDirectParametrizedTest, ClippingLowersVolume) {
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(/*applied_input_volume=*/255, helper.CallAgcSequence(/*applied_input_volume=*/255,
GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kHighSpeechProbability),
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1141,7 +1150,7 @@ TEST_P(AgcManagerDirectParametrizedTest, ClippingLowersVolume) {
} }
TEST_P(AgcManagerDirectParametrizedTest, WaitingPeriodBetweenClippingChecks) { TEST_P(AgcManagerDirectParametrizedTest, WaitingPeriodBetweenClippingChecks) {
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(/*applied_input_volume=*/255, helper.CallAgcSequence(/*applied_input_volume=*/255,
GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kHighSpeechProbability),
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1161,7 +1170,7 @@ TEST_P(AgcManagerDirectParametrizedTest, WaitingPeriodBetweenClippingChecks) {
} }
TEST_P(AgcManagerDirectParametrizedTest, ClippingLoweringIsLimited) { TEST_P(AgcManagerDirectParametrizedTest, ClippingLoweringIsLimited) {
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(/*applied_input_volume=*/180, helper.CallAgcSequence(/*applied_input_volume=*/180,
GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kHighSpeechProbability),
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1181,7 +1190,7 @@ TEST_P(AgcManagerDirectParametrizedTest,
const auto speech_probability_override = const auto speech_probability_override =
GetOverrideOrEmpty(kHighSpeechProbability); GetOverrideOrEmpty(kHighSpeechProbability);
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(/*applied_input_volume=*/255, helper.CallAgcSequence(/*applied_input_volume=*/255,
speech_probability_override, speech_probability_override,
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1202,7 +1211,7 @@ TEST_P(AgcManagerDirectParametrizedTest,
const auto speech_probability_override = const auto speech_probability_override =
GetOverrideOrEmpty(kHighSpeechProbability); GetOverrideOrEmpty(kHighSpeechProbability);
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(/*applied_input_volume=*/200, helper.CallAgcSequence(/*applied_input_volume=*/200,
speech_probability_override, speech_probability_override,
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1227,7 +1236,7 @@ TEST_P(AgcManagerDirectParametrizedTest,
const auto speech_probability_override = const auto speech_probability_override =
GetOverrideOrEmpty(kHighSpeechProbability); GetOverrideOrEmpty(kHighSpeechProbability);
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(/*applied_input_volume=*/210, helper.CallAgcSequence(/*applied_input_volume=*/210,
speech_probability_override, speech_probability_override,
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1324,7 +1333,7 @@ TEST_P(AgcManagerDirectParametrizedTest, UserCanRaiseVolumeAfterClipping) {
const auto speech_probability_override = const auto speech_probability_override =
GetOverrideOrEmpty(kHighSpeechProbability); GetOverrideOrEmpty(kHighSpeechProbability);
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(/*applied_input_volume=*/225, helper.CallAgcSequence(/*applied_input_volume=*/225,
speech_probability_override, speech_probability_override,
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1364,7 +1373,7 @@ TEST_P(AgcManagerDirectParametrizedTest, UserCanRaiseVolumeAfterClipping) {
} }
TEST_P(AgcManagerDirectParametrizedTest, ClippingDoesNotPullLowVolumeBackUp) { TEST_P(AgcManagerDirectParametrizedTest, ClippingDoesNotPullLowVolumeBackUp) {
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(/*applied_input_volume=*/80, helper.CallAgcSequence(/*applied_input_volume=*/80,
GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kHighSpeechProbability),
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1376,7 +1385,7 @@ TEST_P(AgcManagerDirectParametrizedTest, ClippingDoesNotPullLowVolumeBackUp) {
} }
TEST_P(AgcManagerDirectParametrizedTest, TakesNoActionOnZeroMicVolume) { TEST_P(AgcManagerDirectParametrizedTest, TakesNoActionOnZeroMicVolume) {
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(kInitialInputVolume, helper.CallAgcSequence(kInitialInputVolume,
GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kHighSpeechProbability),
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1391,7 +1400,7 @@ TEST_P(AgcManagerDirectParametrizedTest, TakesNoActionOnZeroMicVolume) {
} }
TEST_P(AgcManagerDirectParametrizedTest, ClippingDetectionLowersVolume) { TEST_P(AgcManagerDirectParametrizedTest, ClippingDetectionLowersVolume) {
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(/*applied_input_volume=*/255, helper.CallAgcSequence(/*applied_input_volume=*/255,
GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kHighSpeechProbability),
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1405,7 +1414,7 @@ TEST_P(AgcManagerDirectParametrizedTest, ClippingDetectionLowersVolume) {
TEST_P(AgcManagerDirectParametrizedTest, TEST_P(AgcManagerDirectParametrizedTest,
DisabledClippingPredictorDoesNotLowerVolume) { DisabledClippingPredictorDoesNotLowerVolume) {
AgcManagerDirectTestHelper helper; AgcManagerDirectTestHelper helper(env_);
helper.CallAgcSequence(/*applied_input_volume=*/255, helper.CallAgcSequence(/*applied_input_volume=*/255,
GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kHighSpeechProbability),
GetOverrideOrEmpty(kSpeechLevelDbfs)); GetOverrideOrEmpty(kSpeechLevelDbfs));
@ -1432,25 +1441,21 @@ TEST_P(AgcManagerDirectParametrizedTest, DisableDigitalDisablesDigital) {
AnalogAgcConfig config; AnalogAgcConfig config;
config.enable_digital_adaptive = false; config.enable_digital_adaptive = false;
auto manager = std::make_unique<AgcManagerDirect>(kNumChannels, config); auto manager = std::make_unique<AgcManagerDirect>(env_, kNumChannels, config);
manager->Initialize(); manager->Initialize();
manager->SetupDigitalGainControl(mock_gain_control); manager->SetupDigitalGainControl(mock_gain_control);
} }
TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentDefault) { TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentDefault) {
std::unique_ptr<AgcManagerDirect> manager = std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect();
CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep,
kClippedRatioThreshold, kClippedWaitFrames);
EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel); EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel);
} }
TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentDisabled) { TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentDisabled) {
for (const std::string& field_trial_suffix : {"", "_20220210"}) { for (const std::string& field_trial_suffix : {"", "_20220210"}) {
test::ScopedFieldTrials field_trial( std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect(
GetAgcMinMicLevelExperimentFieldTrial("Disabled" + field_trial_suffix)); {.field_trials = GetAgcMinMicLevelExperimentFieldTrial(
std::unique_ptr<AgcManagerDirect> manager = "Disabled" + field_trial_suffix)});
CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep,
kClippedRatioThreshold, kClippedWaitFrames);
EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel); EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel);
} }
} }
@ -1458,22 +1463,16 @@ TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentDisabled) {
// Checks that a field-trial parameter outside of the valid range [0,255] is // Checks that a field-trial parameter outside of the valid range [0,255] is
// ignored. // ignored.
TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentOutOfRangeAbove) { TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentOutOfRangeAbove) {
test::ScopedFieldTrials field_trial( std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect(
GetAgcMinMicLevelExperimentFieldTrial("Enabled-256")); {.field_trials = GetAgcMinMicLevelExperimentFieldTrial("Enabled-256")});
std::unique_ptr<AgcManagerDirect> manager =
CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep,
kClippedRatioThreshold, kClippedWaitFrames);
EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel); EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel);
} }
// Checks that a field-trial parameter outside of the valid range [0,255] is // Checks that a field-trial parameter outside of the valid range [0,255] is
// ignored. // ignored.
TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentOutOfRangeBelow) { TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentOutOfRangeBelow) {
test::ScopedFieldTrials field_trial( std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect(
GetAgcMinMicLevelExperimentFieldTrial("Enabled--1")); {.field_trials = GetAgcMinMicLevelExperimentFieldTrial("Enabled--1")});
std::unique_ptr<AgcManagerDirect> manager =
CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep,
kClippedRatioThreshold, kClippedWaitFrames);
EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel); EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel);
} }
@ -1484,12 +1483,11 @@ TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentEnabled50) {
constexpr int kMinMicLevelOverride = 50; constexpr int kMinMicLevelOverride = 50;
for (const std::string& field_trial_suffix : {"", "_20220210"}) { for (const std::string& field_trial_suffix : {"", "_20220210"}) {
SCOPED_TRACE(field_trial_suffix); SCOPED_TRACE(field_trial_suffix);
test::ScopedFieldTrials field_trial(
GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride, std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect(
field_trial_suffix)); {.field_trials = GetAgcMinMicLevelExperimentFieldTrialEnabled(
std::unique_ptr<AgcManagerDirect> manager = kMinMicLevelOverride, field_trial_suffix)});
CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep,
kClippedRatioThreshold, kClippedWaitFrames);
EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevelOverride); EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevelOverride);
} }
} }
@ -1502,21 +1500,11 @@ TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentCheckMinLevelWithClipping) {
// Create and initialize two AGCs by specifying and leaving unspecified the // Create and initialize two AGCs by specifying and leaving unspecified the
// relevant field trial. // relevant field trial.
const auto factory = []() { std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect();
std::unique_ptr<AgcManagerDirect> manager = std::unique_ptr<AgcManagerDirect> manager_with_override =
CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep, CreateAgcManagerDirect(
kClippedRatioThreshold, kClippedWaitFrames); {.field_trials = GetAgcMinMicLevelExperimentFieldTrialEnabled(
manager->Initialize(); kMinMicLevelOverride)});
manager->set_stream_analog_level(kInitialInputVolume);
return manager;
};
std::unique_ptr<AgcManagerDirect> manager = factory();
std::unique_ptr<AgcManagerDirect> manager_with_override;
{
test::ScopedFieldTrials field_trial(
GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride));
manager_with_override = factory();
}
// Create a test input signal which containts 80% of clipped samples. // Create a test input signal which containts 80% of clipped samples.
AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz, AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
@ -1559,21 +1547,11 @@ TEST(AgcManagerDirectTest,
// Create and initialize two AGCs by specifying and leaving unspecified the // Create and initialize two AGCs by specifying and leaving unspecified the
// relevant field trial. // relevant field trial.
const auto factory = []() { std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect();
std::unique_ptr<AgcManagerDirect> manager = std::unique_ptr<AgcManagerDirect> manager_with_override =
CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep, CreateAgcManagerDirect(
kClippedRatioThreshold, kClippedWaitFrames); {.field_trials = GetAgcMinMicLevelExperimentFieldTrialEnabled(
manager->Initialize(); kMinMicLevelOverride)});
manager->set_stream_analog_level(kInitialInputVolume);
return manager;
};
std::unique_ptr<AgcManagerDirect> manager = factory();
std::unique_ptr<AgcManagerDirect> manager_with_override;
{
test::ScopedFieldTrials field_trial(
GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride));
manager_with_override = factory();
}
// Create a test input signal which containts 80% of clipped samples. // Create a test input signal which containts 80% of clipped samples.
AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz, AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
@ -1614,32 +1592,25 @@ TEST(AgcManagerDirectTest,
AgcMinMicLevelExperimentCompareMicLevelWithClipping) { AgcMinMicLevelExperimentCompareMicLevelWithClipping) {
// Create and initialize two AGCs by specifying and leaving unspecified the // Create and initialize two AGCs by specifying and leaving unspecified the
// relevant field trial. // relevant field trial.
const auto factory = []() {
// Use a large clipped level step to more quickly decrease the analog gain // Use a large clipped level step to more quickly decrease the analog gain
// with clipping. // with clipping.
AnalogAgcConfig config = kDefaultAnalogConfig; std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect({
config.startup_min_volume = kInitialInputVolume; .clipped_level_min = kDefaultAnalogConfig.clipped_level_min,
config.enable_digital_adaptive = false; .enable_digital_adaptive = false,
config.clipped_level_step = 64; .clipped_level_step = 64,
config.clipped_ratio_threshold = kClippedRatioThreshold; });
config.clipped_wait_frames = kClippedWaitFrames;
auto controller =
std::make_unique<AgcManagerDirect>(/*num_capture_channels=*/1, config);
controller->Initialize();
controller->set_stream_analog_level(kInitialInputVolume);
return controller;
};
std::unique_ptr<AgcManagerDirect> manager = factory();
std::unique_ptr<AgcManagerDirect> manager_with_override;
{
constexpr int kMinMicLevelOverride = 20; constexpr int kMinMicLevelOverride = 20;
static_assert( static_assert(kDefaultAnalogConfig.clipped_level_min >= kMinMicLevelOverride,
kDefaultAnalogConfig.clipped_level_min >= kMinMicLevelOverride,
"Use a lower override value."); "Use a lower override value.");
test::ScopedFieldTrials field_trial( std::unique_ptr<AgcManagerDirect> manager_with_override =
GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride)); CreateAgcManagerDirect({
manager_with_override = factory(); .field_trials = GetAgcMinMicLevelExperimentFieldTrialEnabled(
} kMinMicLevelOverride),
.clipped_level_min = kDefaultAnalogConfig.clipped_level_min,
.enable_digital_adaptive = false,
.clipped_level_step = 64,
});
// Create a test input signal which containts 80% of clipped samples. // Create a test input signal which containts 80% of clipped samples.
AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz, AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
@ -1681,32 +1652,23 @@ TEST(AgcManagerDirectTest,
AgcMinMicLevelExperimentCompareMicLevelWithClippingWithRmsErrorOverride) { AgcMinMicLevelExperimentCompareMicLevelWithClippingWithRmsErrorOverride) {
// Create and initialize two AGCs by specifying and leaving unspecified the // Create and initialize two AGCs by specifying and leaving unspecified the
// relevant field trial. // relevant field trial.
const auto factory = []() { std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect({
// Use a large clipped level step to more quickly decrease the analog gain .clipped_level_min = kDefaultAnalogConfig.clipped_level_min,
// with clipping. .enable_digital_adaptive = false,
AnalogAgcConfig config = kDefaultAnalogConfig; .clipped_level_step = 64,
config.startup_min_volume = kInitialInputVolume; });
config.enable_digital_adaptive = false;
config.clipped_level_step = 64;
config.clipped_ratio_threshold = kClippedRatioThreshold;
config.clipped_wait_frames = kClippedWaitFrames;
auto controller =
std::make_unique<AgcManagerDirect>(/*num_capture_channels=*/1, config);
controller->Initialize();
controller->set_stream_analog_level(kInitialInputVolume);
return controller;
};
std::unique_ptr<AgcManagerDirect> manager = factory();
std::unique_ptr<AgcManagerDirect> manager_with_override;
{
constexpr int kMinMicLevelOverride = 20; constexpr int kMinMicLevelOverride = 20;
static_assert( static_assert(kDefaultAnalogConfig.clipped_level_min >= kMinMicLevelOverride,
kDefaultAnalogConfig.clipped_level_min >= kMinMicLevelOverride,
"Use a lower override value."); "Use a lower override value.");
test::ScopedFieldTrials field_trial( std::unique_ptr<AgcManagerDirect> manager_with_override =
GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride)); CreateAgcManagerDirect({
manager_with_override = factory(); .field_trials = GetAgcMinMicLevelExperimentFieldTrialEnabled(
} kMinMicLevelOverride),
.clipped_level_min = kDefaultAnalogConfig.clipped_level_min,
.enable_digital_adaptive = false,
.clipped_level_step = 64,
});
// Create a test input signal which containts 80% of clipped samples. // Create a test input signal which containts 80% of clipped samples.
AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz, AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
@ -1746,19 +1708,15 @@ TEST_P(AgcManagerDirectParametrizedTest, ClippingParametersVerified) {
GTEST_SKIP() << "Skipped. RMS error override does not affect the test."; GTEST_SKIP() << "Skipped. RMS error override does not affect the test.";
} }
std::unique_ptr<AgcManagerDirect> manager = std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect();
CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep,
kClippedRatioThreshold, kClippedWaitFrames);
manager->Initialize();
EXPECT_EQ(manager->clipped_level_step_, kClippedLevelStep); EXPECT_EQ(manager->clipped_level_step_, kClippedLevelStep);
EXPECT_EQ(manager->clipped_ratio_threshold_, kClippedRatioThreshold); EXPECT_EQ(manager->clipped_ratio_threshold_, kClippedRatioThreshold);
EXPECT_EQ(manager->clipped_wait_frames_, kClippedWaitFrames); EXPECT_EQ(manager->clipped_wait_frames_, kClippedWaitFrames);
std::unique_ptr<AgcManagerDirect> manager_custom = std::unique_ptr<AgcManagerDirect> manager_custom =
CreateAgcManagerDirect(kInitialInputVolume, CreateAgcManagerDirect({.clipped_level_step = 10,
/*clipped_level_step=*/10, .clipped_ratio_threshold = 0.2f,
/*clipped_ratio_threshold=*/0.2f, .clipped_wait_frames = 50});
/*clipped_wait_frames=*/50);
manager_custom->Initialize();
EXPECT_EQ(manager_custom->clipped_level_step_, 10); EXPECT_EQ(manager_custom->clipped_level_step_, 10);
EXPECT_EQ(manager_custom->clipped_ratio_threshold_, 0.2f); EXPECT_EQ(manager_custom->clipped_ratio_threshold_, 0.2f);
EXPECT_EQ(manager_custom->clipped_wait_frames_, 50); EXPECT_EQ(manager_custom->clipped_wait_frames_, 50);
@ -1770,14 +1728,9 @@ TEST_P(AgcManagerDirectParametrizedTest,
GTEST_SKIP() << "Skipped. RMS error override does not affect the test."; GTEST_SKIP() << "Skipped. RMS error override does not affect the test.";
} }
// TODO(bugs.webrtc.org/12874): Use designated initializers once fixed. std::unique_ptr<AgcManagerDirect> manager =
ClippingPredictorConfig config; CreateAgcManagerDirect({.clipping_predictor = {.enabled = false}});
config.enabled = false;
std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect(
kInitialInputVolume, kClippedLevelStep, kClippedRatioThreshold,
kClippedWaitFrames, config);
manager->Initialize();
EXPECT_FALSE(manager->clipping_predictor_enabled()); EXPECT_FALSE(manager->clipping_predictor_enabled());
EXPECT_FALSE(manager->use_clipping_predictor_step()); EXPECT_FALSE(manager->use_clipping_predictor_step());
} }
@ -1797,15 +1750,9 @@ TEST_P(AgcManagerDirectParametrizedTest,
GTEST_SKIP() << "Skipped. RMS error override does not affect the test."; GTEST_SKIP() << "Skipped. RMS error override does not affect the test.";
} }
// TODO(bugs.webrtc.org/12874): Use designated initializers once fixed.
ClippingPredictorConfig config;
config.enabled = true;
config.use_predicted_step = true;
std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect( std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect(
kInitialInputVolume, kClippedLevelStep, kClippedRatioThreshold, {.clipping_predictor = {.enabled = true, .use_predicted_step = true}});
kClippedWaitFrames, config);
manager->Initialize();
EXPECT_TRUE(manager->clipping_predictor_enabled()); EXPECT_TRUE(manager->clipping_predictor_enabled());
EXPECT_TRUE(manager->use_clipping_predictor_step()); EXPECT_TRUE(manager->use_clipping_predictor_step());
} }
@ -1817,7 +1764,7 @@ TEST_P(AgcManagerDirectParametrizedTest,
AnalogAgcConfig config = GetAnalogAgcTestConfig(); AnalogAgcConfig config = GetAnalogAgcTestConfig();
config.clipping_predictor.enabled = false; config.clipping_predictor.enabled = false;
AgcManagerDirect manager(config, new ::testing::NiceMock<MockAgc>()); AgcManagerDirect manager(env_, config, new ::testing::NiceMock<MockAgc>());
manager.Initialize(); manager.Initialize();
manager.set_stream_analog_level(/*level=*/255); manager.set_stream_analog_level(/*level=*/255);
EXPECT_FALSE(manager.clipping_predictor_enabled()); EXPECT_FALSE(manager.clipping_predictor_enabled());
@ -1843,10 +1790,10 @@ TEST_P(AgcManagerDirectParametrizedTest,
config_with_prediction.clipping_predictor.use_predicted_step = true; config_with_prediction.clipping_predictor.use_predicted_step = true;
AnalogAgcConfig config_without_prediction = GetAnalogAgcTestConfig(); AnalogAgcConfig config_without_prediction = GetAnalogAgcTestConfig();
config_without_prediction.clipping_predictor.enabled = false; config_without_prediction.clipping_predictor.enabled = false;
AgcManagerDirect manager_with_prediction(config_with_prediction, AgcManagerDirect manager_with_prediction(env_, config_with_prediction,
new ::testing::NiceMock<MockAgc>()); new ::testing::NiceMock<MockAgc>());
AgcManagerDirect manager_without_prediction( AgcManagerDirect manager_without_prediction(
config_without_prediction, new ::testing::NiceMock<MockAgc>()); env_, config_without_prediction, new ::testing::NiceMock<MockAgc>());
manager_with_prediction.Initialize(); manager_with_prediction.Initialize();
manager_without_prediction.Initialize(); manager_without_prediction.Initialize();
@ -1951,10 +1898,10 @@ TEST_P(AgcManagerDirectParametrizedTest,
config_with_prediction.clipping_predictor.use_predicted_step = false; config_with_prediction.clipping_predictor.use_predicted_step = false;
AnalogAgcConfig config_without_prediction = GetAnalogAgcTestConfig(); AnalogAgcConfig config_without_prediction = GetAnalogAgcTestConfig();
config_without_prediction.clipping_predictor.enabled = false; config_without_prediction.clipping_predictor.enabled = false;
AgcManagerDirect manager_with_prediction(config_with_prediction, AgcManagerDirect manager_with_prediction(env_, config_with_prediction,
new ::testing::NiceMock<MockAgc>()); new ::testing::NiceMock<MockAgc>());
AgcManagerDirect manager_without_prediction( AgcManagerDirect manager_without_prediction(
config_without_prediction, new ::testing::NiceMock<MockAgc>()); env_, config_without_prediction, new ::testing::NiceMock<MockAgc>());
constexpr int kInitialLevel = 255; constexpr int kInitialLevel = 255;
constexpr float kClippingPeakRatio = 1.0f; constexpr float kClippingPeakRatio = 1.0f;
@ -2038,8 +1985,8 @@ TEST_P(AgcManagerDirectParametrizedTest,
// Checks that passing an empty speech level and probability overrides to // Checks that passing an empty speech level and probability overrides to
// `Process()` has the same effect as passing no overrides. // `Process()` has the same effect as passing no overrides.
TEST_P(AgcManagerDirectParametrizedTest, EmptyRmsErrorOverrideHasNoEffect) { TEST_P(AgcManagerDirectParametrizedTest, EmptyRmsErrorOverrideHasNoEffect) {
AgcManagerDirect manager_1(kNumChannels, GetAnalogAgcTestConfig()); AgcManagerDirect manager_1(env_, kNumChannels, GetAnalogAgcTestConfig());
AgcManagerDirect manager_2(kNumChannels, GetAnalogAgcTestConfig()); AgcManagerDirect manager_2(env_, kNumChannels, GetAnalogAgcTestConfig());
manager_1.Initialize(); manager_1.Initialize();
manager_2.Initialize(); manager_2.Initialize();
@ -2080,8 +2027,8 @@ TEST_P(AgcManagerDirectParametrizedTest, EmptyRmsErrorOverrideHasNoEffect) {
// Checks that passing a non-empty speech level and probability overrides to // Checks that passing a non-empty speech level and probability overrides to
// `Process()` has an effect. // `Process()` has an effect.
TEST_P(AgcManagerDirectParametrizedTest, NonEmptyRmsErrorOverrideHasEffect) { TEST_P(AgcManagerDirectParametrizedTest, NonEmptyRmsErrorOverrideHasEffect) {
AgcManagerDirect manager_1(kNumChannels, GetAnalogAgcTestConfig()); AgcManagerDirect manager_1(env_, kNumChannels, GetAnalogAgcTestConfig());
AgcManagerDirect manager_2(kNumChannels, GetAnalogAgcTestConfig()); AgcManagerDirect manager_2(env_, kNumChannels, GetAnalogAgcTestConfig());
manager_1.Initialize(); manager_1.Initialize();
manager_2.Initialize(); manager_2.Initialize();
@ -2125,7 +2072,7 @@ TEST_P(AgcManagerDirectChannelSampleRateTest, CheckIsAlive) {
constexpr AnalogAgcConfig kConfig{.enabled = true, constexpr AnalogAgcConfig kConfig{.enabled = true,
.clipping_predictor{.enabled = true}}; .clipping_predictor{.enabled = true}};
AgcManagerDirect manager(num_channels, kConfig); AgcManagerDirect manager(CreateEnvironment(), num_channels, kConfig);
manager.Initialize(); manager.Initialize();
AudioBuffer buffer(sample_rate_hz, num_channels, sample_rate_hz, num_channels, AudioBuffer buffer(sample_rate_hz, num_channels, sample_rate_hz, num_channels,
sample_rate_hz, num_channels); sample_rate_hz, num_channels);

View File

@ -2017,8 +2017,9 @@ void AudioProcessingImpl::InitializeGainController1() {
if (re_creation) { if (re_creation) {
stream_analog_level = submodules_.agc_manager->recommended_analog_level(); stream_analog_level = submodules_.agc_manager->recommended_analog_level();
} }
submodules_.agc_manager.reset(new AgcManagerDirect( submodules_.agc_manager = std::make_unique<AgcManagerDirect>(
num_proc_channels(), config_.gain_controller1.analog_gain_controller)); env_, num_proc_channels(),
config_.gain_controller1.analog_gain_controller);
if (re_creation) { if (re_creation) {
submodules_.agc_manager->set_stream_analog_level(stream_analog_level); submodules_.agc_manager->set_stream_analog_level(stream_analog_level);
} }