diff --git a/modules/audio_processing/agc/BUILD.gn b/modules/audio_processing/agc/BUILD.gn index f5bb27217a..754b807879 100644 --- a/modules/audio_processing/agc/BUILD.gn +++ b/modules/audio_processing/agc/BUILD.gn @@ -25,7 +25,9 @@ rtc_library("agc") { "..:audio_buffer", "..:audio_frame_view", "../../../api:array_view", + "../../../api:field_trials_view", "../../../api/audio:audio_processing", + "../../../api/environment", "../../../common_audio", "../../../common_audio:common_audio_c", "../../../rtc_base:checks", @@ -106,13 +108,15 @@ if (rtc_include_tests) { ":level_estimation", "..:mocks", "../../../api:array_view", + "../../../api:field_trials", + "../../../api/environment", + "../../../api/environment:environment_factory", "../../../rtc_base:checks", "../../../rtc_base:random", "../../../rtc_base:safe_conversions", "../../../rtc_base:safe_minmax", "../../../rtc_base:stringutils", "../../../system_wrappers:metrics", - "../../../test:field_trial", "../../../test:fileutils", "../../../test:test_support", "//testing/gtest", diff --git a/modules/audio_processing/agc/agc_manager_direct.cc b/modules/audio_processing/agc/agc_manager_direct.cc index 763dd9ace6..0f2469df5c 100644 --- a/modules/audio_processing/agc/agc_manager_direct.cc +++ b/modules/audio_processing/agc/agc_manager_direct.cc @@ -14,6 +14,8 @@ #include #include "api/array_view.h" +#include "api/environment/environment.h" +#include "api/field_trials_view.h" #include "common_audio/include/audio_util.h" #include "modules/audio_processing/agc/gain_control.h" #include "modules/audio_processing/agc2/gain_map_internal.h" @@ -22,7 +24,6 @@ #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/numerics/safe_minmax.h" -#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/metrics.h" namespace webrtc { @@ -69,14 +70,13 @@ using AnalogAgcConfig = // string. Returns an unspecified value if the field trial is not specified, if // disabled or if it cannot be parsed. Example: // 'WebRTC-Audio-2ndAgcMinMicLevelExperiment/Enabled-80' => returns 80. -std::optional GetMinMicLevelOverride() { +std::optional GetMinMicLevelOverride(const FieldTrialsView& field_trials) { constexpr char kMinMicLevelFieldTrial[] = "WebRTC-Audio-2ndAgcMinMicLevelExperiment"; - if (!webrtc::field_trial::IsEnabled(kMinMicLevelFieldTrial)) { + if (!field_trials.IsEnabled(kMinMicLevelFieldTrial)) { return std::nullopt; } - const auto field_trial_string = - webrtc::field_trial::FindFullName(kMinMicLevelFieldTrial); + const auto field_trial_string = field_trials.Lookup(kMinMicLevelFieldTrial); int min_mic_level = -1; sscanf(field_trial_string.c_str(), "Enabled-%d", &min_mic_level); if (min_mic_level >= 0 && min_mic_level <= 255) { @@ -447,19 +447,21 @@ void MonoAgc::UpdateCompressor() { std::atomic AgcManagerDirect::instance_counter_(0); AgcManagerDirect::AgcManagerDirect( + const Environment& env, const AudioProcessing::Config::GainController1::AnalogGainController& analog_config, Agc* agc) - : AgcManagerDirect(/*num_capture_channels=*/1, analog_config) { + : AgcManagerDirect(env, /*num_capture_channels=*/1, analog_config) { RTC_DCHECK(channel_agcs_[0]); RTC_DCHECK(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) : 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)), num_capture_channels_(num_capture_channels), disable_digital_adaptive_(!analog_config.enable_digital_adaptive), diff --git a/modules/audio_processing/agc/agc_manager_direct.h b/modules/audio_processing/agc/agc_manager_direct.h index db2d27ba09..78dfa87094 100644 --- a/modules/audio_processing/agc/agc_manager_direct.h +++ b/modules/audio_processing/agc/agc_manager_direct.h @@ -17,6 +17,7 @@ #include "api/array_view.h" #include "api/audio/audio_processing.h" +#include "api/environment/environment.h" #include "modules/audio_processing/agc/agc.h" #include "modules/audio_processing/agc2/clipping_predictor.h" #include "modules/audio_processing/audio_buffer.h" @@ -42,6 +43,7 @@ class AgcManagerDirect final { // passed to `AnalyzePreProcess()` and `Process()`. Clamps // `analog_config.startup_min_level` in the [12, 255] range. AgcManagerDirect( + const Environment& env, int num_capture_channels, const AudioProcessing::Config::GainController1::AnalogGainController& analog_config); @@ -142,6 +144,7 @@ class AgcManagerDirect final { // Ctor that creates a single channel AGC and by injecting `agc`. // `agc` will be owned by this class; hence, do not delete it. AgcManagerDirect( + const Environment& env, const AudioProcessing::Config::GainController1::AnalogGainController& analog_config, Agc* agc); diff --git a/modules/audio_processing/agc/agc_manager_direct_unittest.cc b/modules/audio_processing/agc/agc_manager_direct_unittest.cc index 3b6ae72f14..d5b87bdde4 100644 --- a/modules/audio_processing/agc/agc_manager_direct_unittest.cc +++ b/modules/audio_processing/agc/agc_manager_direct_unittest.cc @@ -15,12 +15,14 @@ #include #include +#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/mock_agc.h" #include "modules/audio_processing/include/mock_audio_processing.h" #include "rtc_base/numerics/safe_minmax.h" #include "rtc_base/strings/string_builder.h" -#include "test/field_trial.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/testsupport/file_utils.h" @@ -78,24 +80,32 @@ class MockGainControl : public GainControl { MOCK_METHOD(bool, stream_is_saturated, (), (const, override)); }; -// TODO(bugs.webrtc.org/12874): Remove and use designated initializers once -// fixed. +// Construction parameters that tests may explicitely specify. +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 CreateAgcManagerDirect( - int startup_min_volume, - int clipped_level_step, - float clipped_ratio_threshold, - int clipped_wait_frames, - const ClippingPredictorConfig& clipping_predictor_config = - kDefaultAnalogConfig.clipping_predictor) { - AnalogAgcConfig config; - config.startup_min_volume = startup_min_volume; - config.clipped_level_min = kClippedMin; - config.enable_digital_adaptive = false; - config.clipped_level_step = clipped_level_step; - config.clipped_ratio_threshold = clipped_ratio_threshold; - config.clipped_wait_frames = clipped_wait_frames; - config.clipping_predictor = clipping_predictor_config; - return std::make_unique(/*num_capture_channels=*/1, config); + AgcManagerDirectTestParams p = {}) { + auto manager = std::make_unique( + CreateEnvironment(FieldTrials::CreateNoGlobal(p.field_trials)), + kNumChannels, + AnalogAgcConfig{.startup_min_volume = kInitialInputVolume, + .clipped_level_min = p.clipped_level_min, + .enable_digital_adaptive = p.enable_digital_adaptive, + .clipped_level_step = p.clipped_level_step, + .clipped_ratio_threshold = p.clipped_ratio_threshold, + .clipped_wait_frames = p.clipped_wait_frames, + .clipping_predictor = p.clipping_predictor}); + manager->Initialize(); + manager->set_stream_analog_level(kInitialInputVolume); + return manager; } // Deprecated. @@ -329,7 +339,7 @@ constexpr AnalogAgcConfig GetDisabledAnalogAgcConfig() { class AgcManagerDirectTestHelper { public: // Ctor. Initializes `audio_buffer` with zeros. - AgcManagerDirectTestHelper() + explicit AgcManagerDirectTestHelper(const Environment& env) : audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz, @@ -337,7 +347,7 @@ class AgcManagerDirectTestHelper { kSampleRateHz, kNumChannels), mock_agc(new ::testing::NiceMock()), - manager(GetAnalogAgcTestConfig(), mock_agc) { + manager(env, GetAnalogAgcTestConfig(), mock_agc) { manager.Initialize(); manager.SetupDigitalGainControl(mock_gain_control); WriteAudioBufferSamples(/*samples_value=*/0.0f, /*clipped_ratio=*/0.0f, @@ -438,8 +448,8 @@ class AgcManagerDirectParametrizedTest : public ::testing::TestWithParam, bool>> { protected: AgcManagerDirectParametrizedTest() - : field_trials_( - GetAgcMinMicLevelExperimentFieldTrial(std::get<0>(GetParam()))) {} + : env_(CreateEnvironment(FieldTrials::CreateNoGlobal( + GetAgcMinMicLevelExperimentFieldTrial(std::get<0>(GetParam()))))) {} bool IsMinMicLevelOverridden() const { return std::get<0>(GetParam()).has_value(); @@ -453,8 +463,7 @@ class AgcManagerDirectParametrizedTest return IsRmsErrorOverridden() ? std::optional(value) : std::nullopt; } - private: - test::ScopedFieldTrials field_trials_; + const Environment env_; }; INSTANTIATE_TEST_SUITE_P( @@ -469,10 +478,10 @@ INSTANTIATE_TEST_SUITE_P( // differs. TEST_P(AgcManagerDirectParametrizedTest, DisabledAnalogAgcDoesNotAdaptDownwards) { - AgcManagerDirect manager_no_analog_agc(kNumChannels, + AgcManagerDirect manager_no_analog_agc(env_, kNumChannels, GetDisabledAnalogAgcConfig()); manager_no_analog_agc.Initialize(); - AgcManagerDirect manager_with_analog_agc(kNumChannels, + AgcManagerDirect manager_with_analog_agc(env_, kNumChannels, GetAnalogAgcTestConfig()); 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 // differs. TEST_P(AgcManagerDirectParametrizedTest, DisabledAnalogAgcDoesNotAdaptUpwards) { - AgcManagerDirect manager_no_analog_agc(kNumChannels, + AgcManagerDirect manager_no_analog_agc(env_, kNumChannels, GetDisabledAnalogAgcConfig()); manager_no_analog_agc.Initialize(); - AgcManagerDirect manager_with_analog_agc(kNumChannels, + AgcManagerDirect manager_with_analog_agc(env_, kNumChannels, GetAnalogAgcTestConfig()); manager_with_analog_agc.Initialize(); @@ -552,7 +561,7 @@ TEST_P(AgcManagerDirectParametrizedTest, DisabledAnalogAgcDoesNotAdaptUpwards) { TEST_P(AgcManagerDirectParametrizedTest, StartupMinVolumeConfigurationIsRespected) { - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -563,7 +572,7 @@ TEST_P(AgcManagerDirectParametrizedTest, MicVolumeResponseToRmsError) { const auto speech_probability_override = GetOverrideOrEmpty(kHighSpeechProbability); - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -626,7 +635,7 @@ TEST_P(AgcManagerDirectParametrizedTest, MicVolumeIsLimited) { const auto speech_probability_override = GetOverrideOrEmpty(kHighSpeechProbability); - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -708,7 +717,7 @@ TEST_P(AgcManagerDirectParametrizedTest, CompressorStepsTowardsTarget) { const auto speech_probability_override = GetOverrideOrEmpty(kHighSpeechProbability); - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -780,7 +789,7 @@ TEST_P(AgcManagerDirectParametrizedTest, CompressorErrorIsDeemphasized) { const auto speech_probability_override = GetOverrideOrEmpty(kHighSpeechProbability); - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -825,7 +834,7 @@ TEST_P(AgcManagerDirectParametrizedTest, CompressorReachesMaximum) { const auto speech_probability_override = GetOverrideOrEmpty(kHighSpeechProbability); - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -862,7 +871,7 @@ TEST_P(AgcManagerDirectParametrizedTest, CompressorReachesMinimum) { const auto speech_probability_override = GetOverrideOrEmpty(kHighSpeechProbability); - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -895,7 +904,7 @@ TEST_P(AgcManagerDirectParametrizedTest, CompressorReachesMinimum) { } TEST_P(AgcManagerDirectParametrizedTest, NoActionWhileMuted) { - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -913,7 +922,7 @@ TEST_P(AgcManagerDirectParametrizedTest, NoActionWhileMuted) { } TEST_P(AgcManagerDirectParametrizedTest, UnmutingChecksVolumeWithoutRaising) { - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -934,7 +943,7 @@ TEST_P(AgcManagerDirectParametrizedTest, UnmutingChecksVolumeWithoutRaising) { } TEST_P(AgcManagerDirectParametrizedTest, UnmutingRaisesTooLowVolume) { - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -958,7 +967,7 @@ TEST_P(AgcManagerDirectParametrizedTest, const auto speech_probability_override = GetOverrideOrEmpty(kHighSpeechProbability); - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1000,7 +1009,7 @@ TEST_P(AgcManagerDirectParametrizedTest, const auto speech_probability_override = GetOverrideOrEmpty(kHighSpeechProbability); - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1048,7 +1057,7 @@ TEST_P(AgcManagerDirectParametrizedTest, const auto speech_probability_override = GetOverrideOrEmpty(kHighSpeechProbability); - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1094,7 +1103,7 @@ TEST_P(AgcManagerDirectParametrizedTest, const auto speech_probability_override = GetOverrideOrEmpty(kHighSpeechProbability); - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, speech_probability_override, GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1110,7 +1119,7 @@ TEST_P(AgcManagerDirectParametrizedTest, } TEST_P(AgcManagerDirectParametrizedTest, NoClippingHasNoImpact) { - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1120,7 +1129,7 @@ TEST_P(AgcManagerDirectParametrizedTest, NoClippingHasNoImpact) { } TEST_P(AgcManagerDirectParametrizedTest, ClippingUnderThresholdHasNoImpact) { - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1130,7 +1139,7 @@ TEST_P(AgcManagerDirectParametrizedTest, ClippingUnderThresholdHasNoImpact) { } TEST_P(AgcManagerDirectParametrizedTest, ClippingLowersVolume) { - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(/*applied_input_volume=*/255, GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1141,7 +1150,7 @@ TEST_P(AgcManagerDirectParametrizedTest, ClippingLowersVolume) { } TEST_P(AgcManagerDirectParametrizedTest, WaitingPeriodBetweenClippingChecks) { - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(/*applied_input_volume=*/255, GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1161,7 +1170,7 @@ TEST_P(AgcManagerDirectParametrizedTest, WaitingPeriodBetweenClippingChecks) { } TEST_P(AgcManagerDirectParametrizedTest, ClippingLoweringIsLimited) { - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(/*applied_input_volume=*/180, GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1181,7 +1190,7 @@ TEST_P(AgcManagerDirectParametrizedTest, const auto speech_probability_override = GetOverrideOrEmpty(kHighSpeechProbability); - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(/*applied_input_volume=*/255, speech_probability_override, GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1202,7 +1211,7 @@ TEST_P(AgcManagerDirectParametrizedTest, const auto speech_probability_override = GetOverrideOrEmpty(kHighSpeechProbability); - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(/*applied_input_volume=*/200, speech_probability_override, GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1227,7 +1236,7 @@ TEST_P(AgcManagerDirectParametrizedTest, const auto speech_probability_override = GetOverrideOrEmpty(kHighSpeechProbability); - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(/*applied_input_volume=*/210, speech_probability_override, GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1324,7 +1333,7 @@ TEST_P(AgcManagerDirectParametrizedTest, UserCanRaiseVolumeAfterClipping) { const auto speech_probability_override = GetOverrideOrEmpty(kHighSpeechProbability); - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(/*applied_input_volume=*/225, speech_probability_override, GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1364,7 +1373,7 @@ TEST_P(AgcManagerDirectParametrizedTest, UserCanRaiseVolumeAfterClipping) { } TEST_P(AgcManagerDirectParametrizedTest, ClippingDoesNotPullLowVolumeBackUp) { - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(/*applied_input_volume=*/80, GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1376,7 +1385,7 @@ TEST_P(AgcManagerDirectParametrizedTest, ClippingDoesNotPullLowVolumeBackUp) { } TEST_P(AgcManagerDirectParametrizedTest, TakesNoActionOnZeroMicVolume) { - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(kInitialInputVolume, GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1391,7 +1400,7 @@ TEST_P(AgcManagerDirectParametrizedTest, TakesNoActionOnZeroMicVolume) { } TEST_P(AgcManagerDirectParametrizedTest, ClippingDetectionLowersVolume) { - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(/*applied_input_volume=*/255, GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1405,7 +1414,7 @@ TEST_P(AgcManagerDirectParametrizedTest, ClippingDetectionLowersVolume) { TEST_P(AgcManagerDirectParametrizedTest, DisabledClippingPredictorDoesNotLowerVolume) { - AgcManagerDirectTestHelper helper; + AgcManagerDirectTestHelper helper(env_); helper.CallAgcSequence(/*applied_input_volume=*/255, GetOverrideOrEmpty(kHighSpeechProbability), GetOverrideOrEmpty(kSpeechLevelDbfs)); @@ -1432,25 +1441,21 @@ TEST_P(AgcManagerDirectParametrizedTest, DisableDigitalDisablesDigital) { AnalogAgcConfig config; config.enable_digital_adaptive = false; - auto manager = std::make_unique(kNumChannels, config); + auto manager = std::make_unique(env_, kNumChannels, config); manager->Initialize(); manager->SetupDigitalGainControl(mock_gain_control); } TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentDefault) { - std::unique_ptr manager = - CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep, - kClippedRatioThreshold, kClippedWaitFrames); + std::unique_ptr manager = CreateAgcManagerDirect(); EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel); } TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentDisabled) { for (const std::string& field_trial_suffix : {"", "_20220210"}) { - test::ScopedFieldTrials field_trial( - GetAgcMinMicLevelExperimentFieldTrial("Disabled" + field_trial_suffix)); - std::unique_ptr manager = - CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep, - kClippedRatioThreshold, kClippedWaitFrames); + std::unique_ptr manager = CreateAgcManagerDirect( + {.field_trials = GetAgcMinMicLevelExperimentFieldTrial( + "Disabled" + field_trial_suffix)}); 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 // ignored. TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentOutOfRangeAbove) { - test::ScopedFieldTrials field_trial( - GetAgcMinMicLevelExperimentFieldTrial("Enabled-256")); - std::unique_ptr manager = - CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep, - kClippedRatioThreshold, kClippedWaitFrames); + std::unique_ptr manager = CreateAgcManagerDirect( + {.field_trials = GetAgcMinMicLevelExperimentFieldTrial("Enabled-256")}); EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel); } // Checks that a field-trial parameter outside of the valid range [0,255] is // ignored. TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentOutOfRangeBelow) { - test::ScopedFieldTrials field_trial( - GetAgcMinMicLevelExperimentFieldTrial("Enabled--1")); - std::unique_ptr manager = - CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep, - kClippedRatioThreshold, kClippedWaitFrames); + std::unique_ptr manager = CreateAgcManagerDirect( + {.field_trials = GetAgcMinMicLevelExperimentFieldTrial("Enabled--1")}); EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel); } @@ -1484,12 +1483,11 @@ TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentEnabled50) { constexpr int kMinMicLevelOverride = 50; for (const std::string& field_trial_suffix : {"", "_20220210"}) { SCOPED_TRACE(field_trial_suffix); - test::ScopedFieldTrials field_trial( - GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride, - field_trial_suffix)); - std::unique_ptr manager = - CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep, - kClippedRatioThreshold, kClippedWaitFrames); + + std::unique_ptr manager = CreateAgcManagerDirect( + {.field_trials = GetAgcMinMicLevelExperimentFieldTrialEnabled( + kMinMicLevelOverride, field_trial_suffix)}); + 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 // relevant field trial. - const auto factory = []() { - std::unique_ptr manager = - CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep, - kClippedRatioThreshold, kClippedWaitFrames); - manager->Initialize(); - manager->set_stream_analog_level(kInitialInputVolume); - return manager; - }; - std::unique_ptr manager = factory(); - std::unique_ptr manager_with_override; - { - test::ScopedFieldTrials field_trial( - GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride)); - manager_with_override = factory(); - } + std::unique_ptr manager = CreateAgcManagerDirect(); + std::unique_ptr manager_with_override = + CreateAgcManagerDirect( + {.field_trials = GetAgcMinMicLevelExperimentFieldTrialEnabled( + kMinMicLevelOverride)}); // Create a test input signal which containts 80% of clipped samples. 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 // relevant field trial. - const auto factory = []() { - std::unique_ptr manager = - CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep, - kClippedRatioThreshold, kClippedWaitFrames); - manager->Initialize(); - manager->set_stream_analog_level(kInitialInputVolume); - return manager; - }; - std::unique_ptr manager = factory(); - std::unique_ptr manager_with_override; - { - test::ScopedFieldTrials field_trial( - GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride)); - manager_with_override = factory(); - } + std::unique_ptr manager = CreateAgcManagerDirect(); + std::unique_ptr manager_with_override = + CreateAgcManagerDirect( + {.field_trials = GetAgcMinMicLevelExperimentFieldTrialEnabled( + kMinMicLevelOverride)}); // Create a test input signal which containts 80% of clipped samples. AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz, @@ -1614,32 +1592,25 @@ TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentCompareMicLevelWithClipping) { // Create and initialize two AGCs by specifying and leaving unspecified the // relevant field trial. - const auto factory = []() { - // Use a large clipped level step to more quickly decrease the analog gain - // with clipping. - AnalogAgcConfig config = kDefaultAnalogConfig; - 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(/*num_capture_channels=*/1, config); - controller->Initialize(); - controller->set_stream_analog_level(kInitialInputVolume); - return controller; - }; - std::unique_ptr manager = factory(); - std::unique_ptr manager_with_override; - { - constexpr int kMinMicLevelOverride = 20; - static_assert( - kDefaultAnalogConfig.clipped_level_min >= kMinMicLevelOverride, - "Use a lower override value."); - test::ScopedFieldTrials field_trial( - GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride)); - manager_with_override = factory(); - } + // Use a large clipped level step to more quickly decrease the analog gain + // with clipping. + std::unique_ptr manager = CreateAgcManagerDirect({ + .clipped_level_min = kDefaultAnalogConfig.clipped_level_min, + .enable_digital_adaptive = false, + .clipped_level_step = 64, + }); + + constexpr int kMinMicLevelOverride = 20; + static_assert(kDefaultAnalogConfig.clipped_level_min >= kMinMicLevelOverride, + "Use a lower override value."); + std::unique_ptr manager_with_override = + CreateAgcManagerDirect({ + .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. AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz, @@ -1681,32 +1652,23 @@ TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentCompareMicLevelWithClippingWithRmsErrorOverride) { // Create and initialize two AGCs by specifying and leaving unspecified the // relevant field trial. - const auto factory = []() { - // Use a large clipped level step to more quickly decrease the analog gain - // with clipping. - AnalogAgcConfig config = kDefaultAnalogConfig; - 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(/*num_capture_channels=*/1, config); - controller->Initialize(); - controller->set_stream_analog_level(kInitialInputVolume); - return controller; - }; - std::unique_ptr manager = factory(); - std::unique_ptr manager_with_override; - { - constexpr int kMinMicLevelOverride = 20; - static_assert( - kDefaultAnalogConfig.clipped_level_min >= kMinMicLevelOverride, - "Use a lower override value."); - test::ScopedFieldTrials field_trial( - GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride)); - manager_with_override = factory(); - } + std::unique_ptr manager = CreateAgcManagerDirect({ + .clipped_level_min = kDefaultAnalogConfig.clipped_level_min, + .enable_digital_adaptive = false, + .clipped_level_step = 64, + }); + + constexpr int kMinMicLevelOverride = 20; + static_assert(kDefaultAnalogConfig.clipped_level_min >= kMinMicLevelOverride, + "Use a lower override value."); + std::unique_ptr manager_with_override = + CreateAgcManagerDirect({ + .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. 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."; } - std::unique_ptr manager = - CreateAgcManagerDirect(kInitialInputVolume, kClippedLevelStep, - kClippedRatioThreshold, kClippedWaitFrames); - manager->Initialize(); + std::unique_ptr manager = CreateAgcManagerDirect(); EXPECT_EQ(manager->clipped_level_step_, kClippedLevelStep); EXPECT_EQ(manager->clipped_ratio_threshold_, kClippedRatioThreshold); EXPECT_EQ(manager->clipped_wait_frames_, kClippedWaitFrames); + std::unique_ptr manager_custom = - CreateAgcManagerDirect(kInitialInputVolume, - /*clipped_level_step=*/10, - /*clipped_ratio_threshold=*/0.2f, - /*clipped_wait_frames=*/50); - manager_custom->Initialize(); + CreateAgcManagerDirect({.clipped_level_step = 10, + .clipped_ratio_threshold = 0.2f, + .clipped_wait_frames = 50}); EXPECT_EQ(manager_custom->clipped_level_step_, 10); EXPECT_EQ(manager_custom->clipped_ratio_threshold_, 0.2f); 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."; } - // TODO(bugs.webrtc.org/12874): Use designated initializers once fixed. - ClippingPredictorConfig config; - config.enabled = false; + std::unique_ptr manager = + CreateAgcManagerDirect({.clipping_predictor = {.enabled = false}}); - std::unique_ptr manager = CreateAgcManagerDirect( - kInitialInputVolume, kClippedLevelStep, kClippedRatioThreshold, - kClippedWaitFrames, config); - manager->Initialize(); EXPECT_FALSE(manager->clipping_predictor_enabled()); 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."; } - // TODO(bugs.webrtc.org/12874): Use designated initializers once fixed. - ClippingPredictorConfig config; - config.enabled = true; - config.use_predicted_step = true; - std::unique_ptr manager = CreateAgcManagerDirect( - kInitialInputVolume, kClippedLevelStep, kClippedRatioThreshold, - kClippedWaitFrames, config); - manager->Initialize(); + {.clipping_predictor = {.enabled = true, .use_predicted_step = true}}); + EXPECT_TRUE(manager->clipping_predictor_enabled()); EXPECT_TRUE(manager->use_clipping_predictor_step()); } @@ -1817,7 +1764,7 @@ TEST_P(AgcManagerDirectParametrizedTest, AnalogAgcConfig config = GetAnalogAgcTestConfig(); config.clipping_predictor.enabled = false; - AgcManagerDirect manager(config, new ::testing::NiceMock()); + AgcManagerDirect manager(env_, config, new ::testing::NiceMock()); manager.Initialize(); manager.set_stream_analog_level(/*level=*/255); EXPECT_FALSE(manager.clipping_predictor_enabled()); @@ -1843,10 +1790,10 @@ TEST_P(AgcManagerDirectParametrizedTest, config_with_prediction.clipping_predictor.use_predicted_step = true; AnalogAgcConfig config_without_prediction = GetAnalogAgcTestConfig(); 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()); AgcManagerDirect manager_without_prediction( - config_without_prediction, new ::testing::NiceMock()); + env_, config_without_prediction, new ::testing::NiceMock()); manager_with_prediction.Initialize(); manager_without_prediction.Initialize(); @@ -1951,10 +1898,10 @@ TEST_P(AgcManagerDirectParametrizedTest, config_with_prediction.clipping_predictor.use_predicted_step = false; AnalogAgcConfig config_without_prediction = GetAnalogAgcTestConfig(); 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()); AgcManagerDirect manager_without_prediction( - config_without_prediction, new ::testing::NiceMock()); + env_, config_without_prediction, new ::testing::NiceMock()); constexpr int kInitialLevel = 255; constexpr float kClippingPeakRatio = 1.0f; @@ -2038,8 +1985,8 @@ TEST_P(AgcManagerDirectParametrizedTest, // Checks that passing an empty speech level and probability overrides to // `Process()` has the same effect as passing no overrides. TEST_P(AgcManagerDirectParametrizedTest, EmptyRmsErrorOverrideHasNoEffect) { - AgcManagerDirect manager_1(kNumChannels, GetAnalogAgcTestConfig()); - AgcManagerDirect manager_2(kNumChannels, GetAnalogAgcTestConfig()); + AgcManagerDirect manager_1(env_, kNumChannels, GetAnalogAgcTestConfig()); + AgcManagerDirect manager_2(env_, kNumChannels, GetAnalogAgcTestConfig()); manager_1.Initialize(); manager_2.Initialize(); @@ -2080,8 +2027,8 @@ TEST_P(AgcManagerDirectParametrizedTest, EmptyRmsErrorOverrideHasNoEffect) { // Checks that passing a non-empty speech level and probability overrides to // `Process()` has an effect. TEST_P(AgcManagerDirectParametrizedTest, NonEmptyRmsErrorOverrideHasEffect) { - AgcManagerDirect manager_1(kNumChannels, GetAnalogAgcTestConfig()); - AgcManagerDirect manager_2(kNumChannels, GetAnalogAgcTestConfig()); + AgcManagerDirect manager_1(env_, kNumChannels, GetAnalogAgcTestConfig()); + AgcManagerDirect manager_2(env_, kNumChannels, GetAnalogAgcTestConfig()); manager_1.Initialize(); manager_2.Initialize(); @@ -2125,7 +2072,7 @@ TEST_P(AgcManagerDirectChannelSampleRateTest, CheckIsAlive) { constexpr AnalogAgcConfig kConfig{.enabled = true, .clipping_predictor{.enabled = true}}; - AgcManagerDirect manager(num_channels, kConfig); + AgcManagerDirect manager(CreateEnvironment(), num_channels, kConfig); manager.Initialize(); AudioBuffer buffer(sample_rate_hz, num_channels, sample_rate_hz, num_channels, sample_rate_hz, num_channels); diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc index fe72b39c57..45b1c8299c 100644 --- a/modules/audio_processing/audio_processing_impl.cc +++ b/modules/audio_processing/audio_processing_impl.cc @@ -2017,8 +2017,9 @@ void AudioProcessingImpl::InitializeGainController1() { if (re_creation) { stream_analog_level = submodules_.agc_manager->recommended_analog_level(); } - submodules_.agc_manager.reset(new AgcManagerDirect( - num_proc_channels(), config_.gain_controller1.analog_gain_controller)); + submodules_.agc_manager = std::make_unique( + env_, num_proc_channels(), + config_.gain_controller1.analog_gain_controller); if (re_creation) { submodules_.agc_manager->set_stream_analog_level(stream_analog_level); }