tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

agc_manager_direct_unittest.cc (97777B)


      1 /*
      2 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "modules/audio_processing/agc/agc_manager_direct.h"
     12 
     13 #include <algorithm>
     14 #include <cmath>
     15 #include <cstddef>
     16 #include <cstdint>
     17 #include <fstream>
     18 #include <ios>
     19 #include <limits>
     20 #include <memory>
     21 #include <optional>
     22 #include <string>
     23 #include <tuple>
     24 #include <vector>
     25 
     26 #include "api/audio/audio_processing.h"
     27 #include "api/environment/environment.h"
     28 #include "api/environment/environment_factory.h"
     29 #include "modules/audio_processing/agc/agc.h"
     30 #include "modules/audio_processing/agc/gain_control.h"
     31 #include "modules/audio_processing/agc/mock_agc.h"
     32 #include "modules/audio_processing/audio_buffer.h"
     33 #include "rtc_base/checks.h"
     34 #include "rtc_base/numerics/safe_minmax.h"
     35 #include "rtc_base/strings/string_builder.h"
     36 #include "test/create_test_field_trials.h"
     37 #include "test/gmock.h"
     38 #include "test/gtest.h"
     39 #include "test/testsupport/file_utils.h"
     40 
     41 using ::testing::_;
     42 using ::testing::AtLeast;
     43 using ::testing::DoAll;
     44 using ::testing::Return;
     45 using ::testing::SetArgPointee;
     46 
     47 namespace webrtc {
     48 namespace {
     49 
     50 constexpr int kSampleRateHz = 32000;
     51 constexpr int kNumChannels = 1;
     52 constexpr int kInitialInputVolume = 128;
     53 constexpr int kClippedMin = 165;  // Arbitrary, but different from the default.
     54 constexpr float kAboveClippedThreshold = 0.2f;
     55 constexpr int kMinMicLevel = 12;
     56 constexpr int kClippedLevelStep = 15;
     57 constexpr float kClippedRatioThreshold = 0.1f;
     58 constexpr int kClippedWaitFrames = 300;
     59 constexpr float kLowSpeechProbability = 0.1f;
     60 constexpr float kHighSpeechProbability = 0.7f;
     61 constexpr float kSpeechLevelDbfs = -25.0f;
     62 
     63 constexpr float kMinSample = std::numeric_limits<int16_t>::min();
     64 constexpr float kMaxSample = std::numeric_limits<int16_t>::max();
     65 
     66 using AnalogAgcConfig =
     67    AudioProcessing::Config::GainController1::AnalogGainController;
     68 using ClippingPredictorConfig = AudioProcessing::Config::GainController1::
     69    AnalogGainController::ClippingPredictor;
     70 constexpr AnalogAgcConfig kDefaultAnalogConfig{};
     71 
     72 class MockGainControl : public GainControl {
     73 public:
     74  ~MockGainControl() override {}
     75  MOCK_METHOD(int, set_stream_analog_level, (int level), (override));
     76  MOCK_METHOD(int, stream_analog_level, (), (const, override));
     77  MOCK_METHOD(int, set_mode, (Mode mode), (override));
     78  MOCK_METHOD(Mode, mode, (), (const, override));
     79  MOCK_METHOD(int, set_target_level_dbfs, (int level), (override));
     80  MOCK_METHOD(int, target_level_dbfs, (), (const, override));
     81  MOCK_METHOD(int, set_compression_gain_db, (int gain), (override));
     82  MOCK_METHOD(int, compression_gain_db, (), (const, override));
     83  MOCK_METHOD(int, enable_limiter, (bool enable), (override));
     84  MOCK_METHOD(bool, is_limiter_enabled, (), (const, override));
     85  MOCK_METHOD(int,
     86              set_analog_level_limits,
     87              (int minimum, int maximum),
     88              (override));
     89  MOCK_METHOD(int, analog_level_minimum, (), (const, override));
     90  MOCK_METHOD(int, analog_level_maximum, (), (const, override));
     91  MOCK_METHOD(bool, stream_is_saturated, (), (const, override));
     92 };
     93 
     94 // Construction parameters that tests may explicitely specify.
     95 struct AgcManagerDirectTestParams {
     96  std::string field_trials;
     97  int clipped_level_min = kClippedMin;
     98  bool enable_digital_adaptive = false;
     99  int clipped_level_step = kClippedLevelStep;
    100  float clipped_ratio_threshold = kClippedRatioThreshold;
    101  int clipped_wait_frames = kClippedWaitFrames;
    102  AnalogAgcConfig::ClippingPredictor clipping_predictor;
    103 };
    104 
    105 std::unique_ptr<AgcManagerDirect> CreateAgcManagerDirect(
    106    AgcManagerDirectTestParams p = {}) {
    107  auto manager = std::make_unique<AgcManagerDirect>(
    108      CreateEnvironment(CreateTestFieldTrialsPtr(p.field_trials)), kNumChannels,
    109      AnalogAgcConfig{.startup_min_volume = kInitialInputVolume,
    110                      .clipped_level_min = p.clipped_level_min,
    111                      .enable_digital_adaptive = p.enable_digital_adaptive,
    112                      .clipped_level_step = p.clipped_level_step,
    113                      .clipped_ratio_threshold = p.clipped_ratio_threshold,
    114                      .clipped_wait_frames = p.clipped_wait_frames,
    115                      .clipping_predictor = p.clipping_predictor});
    116  manager->Initialize();
    117  manager->set_stream_analog_level(kInitialInputVolume);
    118  return manager;
    119 }
    120 
    121 // Deprecated.
    122 // TODO(bugs.webrtc.org/7494): Delete this helper, use
    123 // `AgcManagerDirectTestHelper::CallAgcSequence()` instead.
    124 // Calls `AnalyzePreProcess()` on `manager` `num_calls` times. `peak_ratio` is a
    125 // value in [0, 1] which determines the amplitude of the samples (1 maps to full
    126 // scale). The first half of the calls is made on frames which are half filled
    127 // with zeros in order to simulate a signal with different crest factors.
    128 void CallPreProcessAudioBuffer(int num_calls,
    129                               float peak_ratio,
    130                               AgcManagerDirect& manager) {
    131  RTC_DCHECK_LE(peak_ratio, 1.0f);
    132  AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
    133                           kNumChannels, kSampleRateHz, kNumChannels);
    134  const int num_channels = audio_buffer.num_channels();
    135  const int num_frames = audio_buffer.num_frames();
    136 
    137  // Make half of the calls with half zeroed frames.
    138  for (int ch = 0; ch < num_channels; ++ch) {
    139    // 50% of the samples in one frame are zero.
    140    for (int i = 0; i < num_frames; i += 2) {
    141      audio_buffer.channels()[ch][i] = peak_ratio * 32767.0f;
    142      audio_buffer.channels()[ch][i + 1] = 0.0f;
    143    }
    144  }
    145  for (int n = 0; n < num_calls / 2; ++n) {
    146    manager.AnalyzePreProcess(audio_buffer);
    147  }
    148 
    149  // Make the remaining half of the calls with frames whose samples are all set.
    150  for (int ch = 0; ch < num_channels; ++ch) {
    151    for (int i = 0; i < num_frames; ++i) {
    152      audio_buffer.channels()[ch][i] = peak_ratio * 32767.0f;
    153    }
    154  }
    155  for (int n = 0; n < num_calls - num_calls / 2; ++n) {
    156    manager.AnalyzePreProcess(audio_buffer);
    157  }
    158 }
    159 
    160 constexpr char kMinMicLevelFieldTrial[] =
    161    "WebRTC-Audio-2ndAgcMinMicLevelExperiment";
    162 
    163 std::string GetAgcMinMicLevelExperimentFieldTrial(const std::string& value) {
    164  char field_trial_buffer[64];
    165  SimpleStringBuilder builder(field_trial_buffer);
    166  builder << kMinMicLevelFieldTrial << "/" << value << "/";
    167  return builder.str();
    168 }
    169 
    170 std::string GetAgcMinMicLevelExperimentFieldTrialEnabled(
    171    int enabled_value,
    172    const std::string& suffix = "") {
    173  RTC_DCHECK_GE(enabled_value, 0);
    174  RTC_DCHECK_LE(enabled_value, 255);
    175  char field_trial_buffer[64];
    176  SimpleStringBuilder builder(field_trial_buffer);
    177  builder << kMinMicLevelFieldTrial << "/Enabled-" << enabled_value << suffix
    178          << "/";
    179  return builder.str();
    180 }
    181 
    182 std::string GetAgcMinMicLevelExperimentFieldTrial(
    183    std::optional<int> min_mic_level) {
    184  if (min_mic_level.has_value()) {
    185    return GetAgcMinMicLevelExperimentFieldTrialEnabled(*min_mic_level);
    186  }
    187  return GetAgcMinMicLevelExperimentFieldTrial("Disabled");
    188 }
    189 
    190 // (Over)writes `samples_value` for the samples in `audio_buffer`.
    191 // When `clipped_ratio`, a value in [0, 1], is greater than 0, the corresponding
    192 // fraction of the frame is set to a full scale value to simulate clipping.
    193 void WriteAudioBufferSamples(float samples_value,
    194                             float clipped_ratio,
    195                             AudioBuffer& audio_buffer) {
    196  RTC_DCHECK_GE(samples_value, kMinSample);
    197  RTC_DCHECK_LE(samples_value, kMaxSample);
    198  RTC_DCHECK_GE(clipped_ratio, 0.0f);
    199  RTC_DCHECK_LE(clipped_ratio, 1.0f);
    200  int num_channels = audio_buffer.num_channels();
    201  int num_samples = audio_buffer.num_frames();
    202  int num_clipping_samples = clipped_ratio * num_samples;
    203  for (int ch = 0; ch < num_channels; ++ch) {
    204    int i = 0;
    205    for (; i < num_clipping_samples; ++i) {
    206      audio_buffer.channels()[ch][i] = 32767.0f;
    207    }
    208    for (; i < num_samples; ++i) {
    209      audio_buffer.channels()[ch][i] = samples_value;
    210    }
    211  }
    212 }
    213 
    214 // Deprecated.
    215 // TODO(bugs.webrtc.org/7494): Delete this helper, use
    216 // `AgcManagerDirectTestHelper::CallAgcSequence()` instead.
    217 void CallPreProcessAndProcess(int num_calls,
    218                              const AudioBuffer& audio_buffer,
    219                              std::optional<float> speech_probability_override,
    220                              std::optional<float> speech_level_override,
    221                              AgcManagerDirect& manager) {
    222  for (int n = 0; n < num_calls; ++n) {
    223    manager.AnalyzePreProcess(audio_buffer);
    224    manager.Process(audio_buffer, speech_probability_override,
    225                    speech_level_override);
    226  }
    227 }
    228 
    229 // Reads a given number of 10 ms chunks from a PCM file and feeds them to
    230 // `AgcManagerDirect`.
    231 class SpeechSamplesReader {
    232 private:
    233  // Recording properties.
    234  static constexpr int kPcmSampleRateHz = 16000;
    235  static constexpr int kPcmNumChannels = 1;
    236  static constexpr int kPcmBytesPerSamples = sizeof(int16_t);
    237 
    238 public:
    239  SpeechSamplesReader()
    240      : is_(test::ResourcePath("audio_processing/agc/agc_audio", "pcm"),
    241            std::ios::binary | std::ios::ate),
    242        audio_buffer_(kPcmSampleRateHz,
    243                      kPcmNumChannels,
    244                      kPcmSampleRateHz,
    245                      kPcmNumChannels,
    246                      kPcmSampleRateHz,
    247                      kPcmNumChannels),
    248        buffer_(audio_buffer_.num_frames()),
    249        buffer_num_bytes_(buffer_.size() * kPcmBytesPerSamples) {
    250    RTC_CHECK(is_);
    251  }
    252 
    253  // Reads `num_frames` 10 ms frames from the beginning of the PCM file, applies
    254  // `gain_db` and feeds the frames into `agc` by calling `AnalyzePreProcess()`
    255  // and `Process()` for each frame. Reads the number of 10 ms frames available
    256  // in the PCM file if `num_frames` is too large - i.e., does not loop.
    257  void Feed(int num_frames, int gain_db, AgcManagerDirect& agc) {
    258    float gain = std::pow(10.0f, gain_db / 20.0f);  // From dB to linear gain.
    259    is_.seekg(0,
    260              std::ifstream::beg);  // Start from the beginning of the PCM file.
    261 
    262    // Read and feed frames.
    263    for (int i = 0; i < num_frames; ++i) {
    264      is_.read(reinterpret_cast<char*>(buffer_.data()), buffer_num_bytes_);
    265      if (is_.gcount() < buffer_num_bytes_) {
    266        // EOF reached. Stop.
    267        break;
    268      }
    269      // Apply gain and copy samples into `audio_buffer_`.
    270      std::transform(buffer_.begin(), buffer_.end(),
    271                     audio_buffer_.channels()[0], [gain](int16_t v) -> float {
    272                       return SafeClamp(static_cast<float>(v) * gain,
    273                                        kMinSample, kMaxSample);
    274                     });
    275 
    276      agc.AnalyzePreProcess(audio_buffer_);
    277      agc.Process(audio_buffer_);
    278    }
    279  }
    280 
    281  // Reads `num_frames` 10 ms frames from the beginning of the PCM file, applies
    282  // `gain_db` and feeds the frames into `agc` by calling `AnalyzePreProcess()`
    283  // and `Process()` for each frame. Reads the number of 10 ms frames available
    284  // in the PCM file if `num_frames` is too large - i.e., does not loop.
    285  // `speech_probability_override` and `speech_level_override` are passed to
    286  // `Process()` where they are used to override the `agc` RMS error if they
    287  // have a value.
    288  void Feed(int num_frames,
    289            int gain_db,
    290            std::optional<float> speech_probability_override,
    291            std::optional<float> speech_level_override,
    292            AgcManagerDirect& agc) {
    293    float gain = std::pow(10.0f, gain_db / 20.0f);  // From dB to linear gain.
    294    is_.seekg(0,
    295              std::ifstream::beg);  // Start from the beginning of the PCM file.
    296 
    297    // Read and feed frames.
    298    for (int i = 0; i < num_frames; ++i) {
    299      is_.read(reinterpret_cast<char*>(buffer_.data()), buffer_num_bytes_);
    300      if (is_.gcount() < buffer_num_bytes_) {
    301        // EOF reached. Stop.
    302        break;
    303      }
    304      // Apply gain and copy samples into `audio_buffer_`.
    305      std::transform(buffer_.begin(), buffer_.end(),
    306                     audio_buffer_.channels()[0], [gain](int16_t v) -> float {
    307                       return SafeClamp(static_cast<float>(v) * gain,
    308                                        kMinSample, kMaxSample);
    309                     });
    310 
    311      agc.AnalyzePreProcess(audio_buffer_);
    312      agc.Process(audio_buffer_, speech_probability_override,
    313                  speech_level_override);
    314    }
    315  }
    316 
    317 private:
    318  std::ifstream is_;
    319  AudioBuffer audio_buffer_;
    320  std::vector<int16_t> buffer_;
    321  const std::streamsize buffer_num_bytes_;
    322 };
    323 
    324 }  // namespace
    325 
    326 // TODO(bugs.webrtc.org/12874): Use constexpr struct with designated
    327 // initializers once fixed.
    328 constexpr AnalogAgcConfig GetAnalogAgcTestConfig() {
    329  AnalogAgcConfig config;
    330  config.enabled = true;
    331  config.startup_min_volume = kInitialInputVolume;
    332  config.clipped_level_min = kClippedMin;
    333  config.enable_digital_adaptive = true;
    334  config.clipped_level_step = kClippedLevelStep;
    335  config.clipped_ratio_threshold = kClippedRatioThreshold;
    336  config.clipped_wait_frames = kClippedWaitFrames;
    337  config.clipping_predictor = kDefaultAnalogConfig.clipping_predictor;
    338  return config;
    339 }
    340 
    341 constexpr AnalogAgcConfig GetDisabledAnalogAgcConfig() {
    342  AnalogAgcConfig config = GetAnalogAgcTestConfig();
    343  config.enabled = false;
    344  return config;
    345 }
    346 
    347 // Helper class that provides an `AgcManagerDirect` instance with an injected
    348 // `Agc` mock, an `AudioBuffer` instance and `CallAgcSequence()`, a helper
    349 // method that runs the `AgcManagerDirect` instance on the `AudioBuffer` one by
    350 // sticking to the API contract.
    351 class AgcManagerDirectTestHelper {
    352 public:
    353  // Ctor. Initializes `audio_buffer` with zeros.
    354  explicit AgcManagerDirectTestHelper(const Environment& env)
    355      : audio_buffer(kSampleRateHz,
    356                     kNumChannels,
    357                     kSampleRateHz,
    358                     kNumChannels,
    359                     kSampleRateHz,
    360                     kNumChannels),
    361        mock_agc(new ::testing::NiceMock<MockAgc>()),
    362        manager(env, GetAnalogAgcTestConfig(), mock_agc) {
    363    manager.Initialize();
    364    manager.SetupDigitalGainControl(mock_gain_control);
    365    WriteAudioBufferSamples(/*samples_value=*/0.0f, /*clipped_ratio=*/0.0f,
    366                            audio_buffer);
    367  }
    368 
    369  // Calls the sequence of `AgcManagerDirect` methods according to the API
    370  // contract, namely:
    371  // - Sets the applied input volume;
    372  // - Uses `audio_buffer` to call `AnalyzePreProcess()` and `Process()`;
    373  // - Sets the digital compression gain, if specified, on the injected
    374  // `mock_agc`. Returns the recommended input volume. The RMS error from
    375  // AGC is replaced by an override value if `speech_probability_override`
    376  // and `speech_level_override` have a value.
    377  int CallAgcSequence(int applied_input_volume,
    378                      std::optional<float> speech_probability_override,
    379                      std::optional<float> speech_level_override) {
    380    manager.set_stream_analog_level(applied_input_volume);
    381    manager.AnalyzePreProcess(audio_buffer);
    382    manager.Process(audio_buffer, speech_probability_override,
    383                    speech_level_override);
    384    std::optional<int> digital_gain = manager.GetDigitalComressionGain();
    385    if (digital_gain) {
    386      mock_gain_control.set_compression_gain_db(*digital_gain);
    387    }
    388    return manager.recommended_analog_level();
    389  }
    390 
    391  // Deprecated.
    392  // TODO(bugs.webrtc.org/7494): Let the caller write `audio_buffer` and use
    393  // `CallAgcSequence()`. The RMS error from AGC is replaced by an override
    394  // value if `speech_probability_override` and `speech_level_override` have
    395  // a value.
    396  void CallProcess(int num_calls,
    397                   std::optional<float> speech_probability_override,
    398                   std::optional<float> speech_level_override) {
    399    for (int i = 0; i < num_calls; ++i) {
    400      EXPECT_CALL(*mock_agc, Process(_)).WillOnce(Return());
    401      manager.Process(audio_buffer, speech_probability_override,
    402                      speech_level_override);
    403      std::optional<int> new_digital_gain = manager.GetDigitalComressionGain();
    404      if (new_digital_gain) {
    405        mock_gain_control.set_compression_gain_db(*new_digital_gain);
    406      }
    407    }
    408  }
    409 
    410  // Deprecated.
    411  // TODO(bugs.webrtc.org/7494): Let the caller write `audio_buffer` and use
    412  // `CallAgcSequence()`.
    413  void CallPreProc(int num_calls, float clipped_ratio) {
    414    RTC_DCHECK_GE(clipped_ratio, 0.0f);
    415    RTC_DCHECK_LE(clipped_ratio, 1.0f);
    416    WriteAudioBufferSamples(/*samples_value=*/0.0f, clipped_ratio,
    417                            audio_buffer);
    418    for (int i = 0; i < num_calls; ++i) {
    419      manager.AnalyzePreProcess(audio_buffer);
    420    }
    421  }
    422 
    423  // Deprecated.
    424  // TODO(bugs.webrtc.org/7494): Let the caller write `audio_buffer` and use
    425  // `CallAgcSequence()`.
    426  void CallPreProcForChangingAudio(int num_calls, float peak_ratio) {
    427    RTC_DCHECK_GE(peak_ratio, 0.0f);
    428    RTC_DCHECK_LE(peak_ratio, 1.0f);
    429    const float samples_value = peak_ratio * 32767.0f;
    430 
    431    // Make half of the calls on a frame where the samples alternate
    432    // `sample_values` and zeros.
    433    WriteAudioBufferSamples(samples_value, /*clipped_ratio=*/0.0f,
    434                            audio_buffer);
    435    for (size_t ch = 0; ch < audio_buffer.num_channels(); ++ch) {
    436      for (size_t k = 1; k < audio_buffer.num_frames(); k += 2) {
    437        audio_buffer.channels()[ch][k] = 0.0f;
    438      }
    439    }
    440    for (int i = 0; i < num_calls / 2; ++i) {
    441      manager.AnalyzePreProcess(audio_buffer);
    442    }
    443 
    444    // Make half of thecalls on a frame where all the samples equal
    445    // `sample_values`.
    446    WriteAudioBufferSamples(samples_value, /*clipped_ratio=*/0.0f,
    447                            audio_buffer);
    448    for (int i = 0; i < num_calls - num_calls / 2; ++i) {
    449      manager.AnalyzePreProcess(audio_buffer);
    450    }
    451  }
    452 
    453  AudioBuffer audio_buffer;
    454  MockAgc* mock_agc;
    455  AgcManagerDirect manager;
    456  MockGainControl mock_gain_control;
    457 };
    458 
    459 class AgcManagerDirectParametrizedTest
    460    : public ::testing::TestWithParam<std::tuple<std::optional<int>, bool>> {
    461 protected:
    462  AgcManagerDirectParametrizedTest()
    463      : env_(CreateEnvironment(CreateTestFieldTrialsPtr(
    464            GetAgcMinMicLevelExperimentFieldTrial(std::get<0>(GetParam()))))) {}
    465 
    466  bool IsMinMicLevelOverridden() const {
    467    return std::get<0>(GetParam()).has_value();
    468  }
    469  int GetMinMicLevel() const {
    470    return std::get<0>(GetParam()).value_or(kMinMicLevel);
    471  }
    472 
    473  bool IsRmsErrorOverridden() const { return std::get<1>(GetParam()); }
    474  std::optional<float> GetOverrideOrEmpty(float value) const {
    475    return IsRmsErrorOverridden() ? std::optional<float>(value) : std::nullopt;
    476  }
    477 
    478  const Environment env_;
    479 };
    480 
    481 INSTANTIATE_TEST_SUITE_P(
    482    ,
    483    AgcManagerDirectParametrizedTest,
    484    ::testing::Combine(testing::Values(std::nullopt, 12, 20), testing::Bool()));
    485 
    486 // Checks that when the analog controller is disabled, no downward adaptation
    487 // takes place.
    488 // TODO(webrtc:7494): Revisit the test after moving the number of override wait
    489 // frames to AMP config. The test passes but internally the gain update timing
    490 // differs.
    491 TEST_P(AgcManagerDirectParametrizedTest,
    492       DisabledAnalogAgcDoesNotAdaptDownwards) {
    493  AgcManagerDirect manager_no_analog_agc(env_, kNumChannels,
    494                                         GetDisabledAnalogAgcConfig());
    495  manager_no_analog_agc.Initialize();
    496  AgcManagerDirect manager_with_analog_agc(env_, kNumChannels,
    497                                           GetAnalogAgcTestConfig());
    498  manager_with_analog_agc.Initialize();
    499 
    500  AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
    501                           kNumChannels, kSampleRateHz, kNumChannels);
    502 
    503  constexpr int kAnalogLevel = 250;
    504  static_assert(kAnalogLevel > kInitialInputVolume, "Increase `kAnalogLevel`.");
    505  manager_no_analog_agc.set_stream_analog_level(kAnalogLevel);
    506  manager_with_analog_agc.set_stream_analog_level(kAnalogLevel);
    507 
    508  // Make a first call with input that doesn't clip in order to let the
    509  // controller read the input volume. That is needed because clipping input
    510  // causes the controller to stay in idle state for
    511  // `AnalogAgcConfig::clipped_wait_frames` frames.
    512  WriteAudioBufferSamples(/*samples_value=*/0.0f, /*clipped_ratio=*/0.0f,
    513                          audio_buffer);
    514  manager_no_analog_agc.AnalyzePreProcess(audio_buffer);
    515  manager_with_analog_agc.AnalyzePreProcess(audio_buffer);
    516  manager_no_analog_agc.Process(audio_buffer,
    517                                GetOverrideOrEmpty(kHighSpeechProbability),
    518                                GetOverrideOrEmpty(-18.0f));
    519  manager_with_analog_agc.Process(audio_buffer,
    520                                  GetOverrideOrEmpty(kHighSpeechProbability),
    521                                  GetOverrideOrEmpty(-18.0f));
    522 
    523  // Feed clipping input to trigger a downward adapation of the analog level.
    524  WriteAudioBufferSamples(/*samples_value=*/0.0f, /*clipped_ratio=*/0.2f,
    525                          audio_buffer);
    526  manager_no_analog_agc.AnalyzePreProcess(audio_buffer);
    527  manager_with_analog_agc.AnalyzePreProcess(audio_buffer);
    528  manager_no_analog_agc.Process(audio_buffer,
    529                                GetOverrideOrEmpty(kHighSpeechProbability),
    530                                GetOverrideOrEmpty(-10.0f));
    531  manager_with_analog_agc.Process(audio_buffer,
    532                                  GetOverrideOrEmpty(kHighSpeechProbability),
    533                                  GetOverrideOrEmpty(-10.0f));
    534 
    535  // Check that no adaptation occurs when the analog controller is disabled
    536  // and make sure that the test triggers a downward adaptation otherwise.
    537  EXPECT_EQ(manager_no_analog_agc.recommended_analog_level(), kAnalogLevel);
    538  ASSERT_LT(manager_with_analog_agc.recommended_analog_level(), kAnalogLevel);
    539 }
    540 
    541 // Checks that when the analog controller is disabled, no upward adaptation
    542 // takes place.
    543 // TODO(webrtc:7494): Revisit the test after moving the number of override wait
    544 // frames to APM config. The test passes but internally the gain update timing
    545 // differs.
    546 TEST_P(AgcManagerDirectParametrizedTest, DisabledAnalogAgcDoesNotAdaptUpwards) {
    547  AgcManagerDirect manager_no_analog_agc(env_, kNumChannels,
    548                                         GetDisabledAnalogAgcConfig());
    549  manager_no_analog_agc.Initialize();
    550  AgcManagerDirect manager_with_analog_agc(env_, kNumChannels,
    551                                           GetAnalogAgcTestConfig());
    552  manager_with_analog_agc.Initialize();
    553 
    554  constexpr int kAnalogLevel = kInitialInputVolume;
    555  manager_no_analog_agc.set_stream_analog_level(kAnalogLevel);
    556  manager_with_analog_agc.set_stream_analog_level(kAnalogLevel);
    557 
    558  // Feed speech with low energy to trigger an upward adapation of the analog
    559  // level.
    560  constexpr int kNumFrames = 125;
    561  constexpr int kGainDb = -20;
    562  SpeechSamplesReader reader;
    563  reader.Feed(kNumFrames, kGainDb, GetOverrideOrEmpty(kHighSpeechProbability),
    564              GetOverrideOrEmpty(-42.0f), manager_no_analog_agc);
    565  reader.Feed(kNumFrames, kGainDb, GetOverrideOrEmpty(kHighSpeechProbability),
    566              GetOverrideOrEmpty(-42.0f), manager_with_analog_agc);
    567 
    568  // Check that no adaptation occurs when the analog controller is disabled
    569  // and make sure that the test triggers an upward adaptation otherwise.
    570  EXPECT_EQ(manager_no_analog_agc.recommended_analog_level(), kAnalogLevel);
    571  ASSERT_GT(manager_with_analog_agc.recommended_analog_level(), kAnalogLevel);
    572 }
    573 
    574 TEST_P(AgcManagerDirectParametrizedTest,
    575       StartupMinVolumeConfigurationIsRespected) {
    576  AgcManagerDirectTestHelper helper(env_);
    577  helper.CallAgcSequence(kInitialInputVolume,
    578                         GetOverrideOrEmpty(kHighSpeechProbability),
    579                         GetOverrideOrEmpty(kSpeechLevelDbfs));
    580  EXPECT_EQ(kInitialInputVolume, helper.manager.recommended_analog_level());
    581 }
    582 
    583 TEST_P(AgcManagerDirectParametrizedTest, MicVolumeResponseToRmsError) {
    584  const auto speech_probability_override =
    585      GetOverrideOrEmpty(kHighSpeechProbability);
    586 
    587  AgcManagerDirectTestHelper helper(env_);
    588  helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
    589                         GetOverrideOrEmpty(kSpeechLevelDbfs));
    590 
    591  // Compressor default; no residual error.
    592  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    593      .WillOnce(DoAll(SetArgPointee<0>(5), Return(true)));
    594  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    595                     GetOverrideOrEmpty(-23.0f));
    596 
    597  // Inside the compressor's window; no change of volume.
    598  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    599      .WillOnce(DoAll(SetArgPointee<0>(10), Return(true)));
    600  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    601                     GetOverrideOrEmpty(-28.0f));
    602 
    603  // Above the compressor's window; volume should be increased.
    604  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    605      .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)));
    606  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    607                     GetOverrideOrEmpty(-29.0f));
    608  EXPECT_EQ(130, helper.manager.recommended_analog_level());
    609 
    610  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    611      .WillOnce(DoAll(SetArgPointee<0>(20), Return(true)));
    612  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    613                     GetOverrideOrEmpty(-38.0f));
    614  EXPECT_EQ(168, helper.manager.recommended_analog_level());
    615 
    616  // Inside the compressor's window; no change of volume.
    617  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    618      .WillOnce(DoAll(SetArgPointee<0>(5), Return(true)));
    619  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    620                     GetOverrideOrEmpty(-23.0f));
    621  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    622      .WillOnce(DoAll(SetArgPointee<0>(0), Return(true)));
    623  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    624                     GetOverrideOrEmpty(-18.0f));
    625 
    626  // Below the compressor's window; volume should be decreased.
    627  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    628      .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
    629  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    630                     GetOverrideOrEmpty(-17.0f));
    631  EXPECT_EQ(167, helper.manager.recommended_analog_level());
    632 
    633  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    634      .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
    635  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    636                     GetOverrideOrEmpty(-17.0f));
    637  EXPECT_EQ(163, helper.manager.recommended_analog_level());
    638 
    639  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    640      .WillOnce(DoAll(SetArgPointee<0>(-9), Return(true)));
    641  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    642                     GetOverrideOrEmpty(-9.0f));
    643  EXPECT_EQ(129, helper.manager.recommended_analog_level());
    644 }
    645 
    646 TEST_P(AgcManagerDirectParametrizedTest, MicVolumeIsLimited) {
    647  const auto speech_probability_override =
    648      GetOverrideOrEmpty(kHighSpeechProbability);
    649 
    650  AgcManagerDirectTestHelper helper(env_);
    651  helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
    652                         GetOverrideOrEmpty(kSpeechLevelDbfs));
    653 
    654  // Maximum upwards change is limited.
    655  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    656      .WillOnce(DoAll(SetArgPointee<0>(30), Return(true)));
    657  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    658                     GetOverrideOrEmpty(-48.0f));
    659  EXPECT_EQ(183, helper.manager.recommended_analog_level());
    660 
    661  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    662      .WillOnce(DoAll(SetArgPointee<0>(30), Return(true)));
    663  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    664                     GetOverrideOrEmpty(-48.0f));
    665  EXPECT_EQ(243, helper.manager.recommended_analog_level());
    666 
    667  // Won't go higher than the maximum.
    668  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    669      .WillOnce(DoAll(SetArgPointee<0>(30), Return(true)));
    670  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    671                     GetOverrideOrEmpty(-48.0f));
    672  EXPECT_EQ(255, helper.manager.recommended_analog_level());
    673 
    674  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    675      .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
    676  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    677                     GetOverrideOrEmpty(-17.0f));
    678  EXPECT_EQ(254, helper.manager.recommended_analog_level());
    679 
    680  // Maximum downwards change is limited.
    681  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    682      .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true)));
    683  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    684                     GetOverrideOrEmpty(22.0f));
    685  EXPECT_EQ(194, helper.manager.recommended_analog_level());
    686 
    687  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    688      .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true)));
    689  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    690                     GetOverrideOrEmpty(22.0f));
    691  EXPECT_EQ(137, helper.manager.recommended_analog_level());
    692 
    693  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    694      .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true)));
    695  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    696                     GetOverrideOrEmpty(22.0f));
    697  EXPECT_EQ(88, helper.manager.recommended_analog_level());
    698 
    699  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    700      .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true)));
    701  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    702                     GetOverrideOrEmpty(22.0f));
    703  EXPECT_EQ(54, helper.manager.recommended_analog_level());
    704 
    705  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    706      .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true)));
    707  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    708                     GetOverrideOrEmpty(22.0f));
    709  EXPECT_EQ(33, helper.manager.recommended_analog_level());
    710 
    711  // Won't go lower than the minimum.
    712  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    713      .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true)));
    714  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    715                     GetOverrideOrEmpty(22.0f));
    716  EXPECT_EQ(std::max(18, GetMinMicLevel()),
    717            helper.manager.recommended_analog_level());
    718 
    719  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    720      .WillOnce(DoAll(SetArgPointee<0>(-40), Return(true)));
    721  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    722                     GetOverrideOrEmpty(22.0f));
    723  EXPECT_EQ(std::max(12, GetMinMicLevel()),
    724            helper.manager.recommended_analog_level());
    725 }
    726 
    727 TEST_P(AgcManagerDirectParametrizedTest, CompressorStepsTowardsTarget) {
    728  constexpr std::optional<float> kNoOverride = std::nullopt;
    729  const auto speech_probability_override =
    730      GetOverrideOrEmpty(kHighSpeechProbability);
    731 
    732  AgcManagerDirectTestHelper helper(env_);
    733  helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
    734                         GetOverrideOrEmpty(kSpeechLevelDbfs));
    735 
    736  // Compressor default; no call to set_compression_gain_db.
    737  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    738      .WillOnce(DoAll(SetArgPointee<0>(5), Return(true)))
    739      .WillRepeatedly(Return(false));
    740  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(_)).Times(0);
    741  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    742                     GetOverrideOrEmpty(-23.0f));
    743  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(_)).Times(0);
    744  // The mock `GetRmsErrorDb()` returns false; mimic this by passing
    745  // std::nullopt as an override.
    746  helper.CallProcess(/*num_calls=*/19, kNoOverride, kNoOverride);
    747 
    748  // Moves slowly upwards.
    749  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    750      .WillOnce(DoAll(SetArgPointee<0>(9), Return(true)))
    751      .WillRepeatedly(Return(false));
    752  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(_)).Times(0);
    753  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    754                     GetOverrideOrEmpty(-27.0f));
    755  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(_)).Times(0);
    756  helper.CallProcess(/*num_calls=*/18, kNoOverride, kNoOverride);
    757  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(8))
    758      .WillOnce(Return(0));
    759  helper.CallProcess(/*num_calls=*/1, kNoOverride, kNoOverride);
    760 
    761  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(_)).Times(0);
    762  helper.CallProcess(/*num_calls=*/19, kNoOverride, kNoOverride);
    763  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(9))
    764      .WillOnce(Return(0));
    765  helper.CallProcess(/*num_calls=*/1, kNoOverride, kNoOverride);
    766 
    767  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(_)).Times(0);
    768  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    769 
    770  // Moves slowly downward, then reverses before reaching the original target.
    771  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    772      .WillOnce(DoAll(SetArgPointee<0>(5), Return(true)))
    773      .WillRepeatedly(Return(false));
    774  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(_)).Times(0);
    775  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    776                     GetOverrideOrEmpty(-23.0f));
    777  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(_)).Times(0);
    778  helper.CallProcess(/*num_calls=*/18, kNoOverride, kNoOverride);
    779  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(8))
    780      .WillOnce(Return(0));
    781  helper.CallProcess(/*num_calls=*/1, kNoOverride, kNoOverride);
    782 
    783  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    784      .WillOnce(DoAll(SetArgPointee<0>(9), Return(true)))
    785      .WillRepeatedly(Return(false));
    786  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(_)).Times(0);
    787  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    788                     GetOverrideOrEmpty(-27.0f));
    789  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(_)).Times(0);
    790  helper.CallProcess(/*num_calls=*/18, kNoOverride, kNoOverride);
    791  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(9))
    792      .WillOnce(Return(0));
    793  helper.CallProcess(/*num_calls=*/1, kNoOverride, kNoOverride);
    794 
    795  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(_)).Times(0);
    796  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    797 }
    798 
    799 TEST_P(AgcManagerDirectParametrizedTest, CompressorErrorIsDeemphasized) {
    800  constexpr std::optional<float> kNoOverride = std::nullopt;
    801  const auto speech_probability_override =
    802      GetOverrideOrEmpty(kHighSpeechProbability);
    803 
    804  AgcManagerDirectTestHelper helper(env_);
    805  helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
    806                         GetOverrideOrEmpty(kSpeechLevelDbfs));
    807 
    808  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    809      .WillOnce(DoAll(SetArgPointee<0>(10), Return(true)))
    810      .WillRepeatedly(Return(false));
    811  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    812                     GetOverrideOrEmpty(-28.0f));
    813  // The mock `GetRmsErrorDb()` returns false; mimic this by passing
    814  // std::nullopt as an override.
    815  helper.CallProcess(/*num_calls=*/18, kNoOverride, kNoOverride);
    816  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(8))
    817      .WillOnce(Return(0));
    818  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    819  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(9))
    820      .WillOnce(Return(0));
    821  helper.CallProcess(/*num_calls=*/1, kNoOverride, kNoOverride);
    822  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(_)).Times(0);
    823  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    824 
    825  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    826      .WillOnce(DoAll(SetArgPointee<0>(0), Return(true)))
    827      .WillRepeatedly(Return(false));
    828  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    829                     GetOverrideOrEmpty(-18.0f));
    830  helper.CallProcess(/*num_calls=*/18, kNoOverride, kNoOverride);
    831  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(8))
    832      .WillOnce(Return(0));
    833  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    834  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(7))
    835      .WillOnce(Return(0));
    836  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    837  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(6))
    838      .WillOnce(Return(0));
    839  helper.CallProcess(/*num_calls=*/1, kNoOverride, kNoOverride);
    840  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(_)).Times(0);
    841  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    842 }
    843 
    844 TEST_P(AgcManagerDirectParametrizedTest, CompressorReachesMaximum) {
    845  constexpr std::optional<float> kNoOverride = std::nullopt;
    846  const auto speech_probability_override =
    847      GetOverrideOrEmpty(kHighSpeechProbability);
    848 
    849  AgcManagerDirectTestHelper helper(env_);
    850  helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
    851                         GetOverrideOrEmpty(kSpeechLevelDbfs));
    852 
    853  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    854      .WillOnce(DoAll(SetArgPointee<0>(10), Return(true)))
    855      .WillOnce(DoAll(SetArgPointee<0>(10), Return(true)))
    856      .WillOnce(DoAll(SetArgPointee<0>(10), Return(true)))
    857      .WillOnce(DoAll(SetArgPointee<0>(10), Return(true)))
    858      .WillRepeatedly(Return(false));
    859  helper.CallProcess(/*num_calls=*/4, speech_probability_override,
    860                     GetOverrideOrEmpty(-28.0f));
    861  // The mock `GetRmsErrorDb()` returns false; mimic this by passing
    862  // std::nullopt as an override.
    863  helper.CallProcess(/*num_calls=*/15, kNoOverride, kNoOverride);
    864  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(8))
    865      .WillOnce(Return(0));
    866  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    867  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(9))
    868      .WillOnce(Return(0));
    869  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    870  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(10))
    871      .WillOnce(Return(0));
    872  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    873  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(11))
    874      .WillOnce(Return(0));
    875  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    876  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(12))
    877      .WillOnce(Return(0));
    878  helper.CallProcess(/*num_calls=*/1, kNoOverride, kNoOverride);
    879 }
    880 
    881 TEST_P(AgcManagerDirectParametrizedTest, CompressorReachesMinimum) {
    882  constexpr std::optional<float> kNoOverride = std::nullopt;
    883  const auto speech_probability_override =
    884      GetOverrideOrEmpty(kHighSpeechProbability);
    885 
    886  AgcManagerDirectTestHelper helper(env_);
    887  helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
    888                         GetOverrideOrEmpty(kSpeechLevelDbfs));
    889 
    890  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    891      .WillOnce(DoAll(SetArgPointee<0>(0), Return(true)))
    892      .WillOnce(DoAll(SetArgPointee<0>(0), Return(true)))
    893      .WillOnce(DoAll(SetArgPointee<0>(0), Return(true)))
    894      .WillOnce(DoAll(SetArgPointee<0>(0), Return(true)))
    895      .WillRepeatedly(Return(false));
    896  helper.CallProcess(/*num_calls=*/4, speech_probability_override,
    897                     GetOverrideOrEmpty(-18.0f));
    898  // The mock `GetRmsErrorDb()` returns false; mimic this by passing
    899  // std::nullopt as an override.
    900  helper.CallProcess(/*num_calls=*/15, kNoOverride, kNoOverride);
    901  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(6))
    902      .WillOnce(Return(0));
    903  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    904  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(5))
    905      .WillOnce(Return(0));
    906  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    907  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(4))
    908      .WillOnce(Return(0));
    909  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    910  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(3))
    911      .WillOnce(Return(0));
    912  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
    913  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(2))
    914      .WillOnce(Return(0));
    915  helper.CallProcess(/*num_calls=*/1, kNoOverride, kNoOverride);
    916 }
    917 
    918 TEST_P(AgcManagerDirectParametrizedTest, NoActionWhileMuted) {
    919  AgcManagerDirectTestHelper helper(env_);
    920  helper.CallAgcSequence(kInitialInputVolume,
    921                         GetOverrideOrEmpty(kHighSpeechProbability),
    922                         GetOverrideOrEmpty(kSpeechLevelDbfs));
    923 
    924  helper.manager.HandleCaptureOutputUsedChange(false);
    925  helper.manager.Process(helper.audio_buffer,
    926                         GetOverrideOrEmpty(kHighSpeechProbability),
    927                         GetOverrideOrEmpty(kSpeechLevelDbfs));
    928 
    929  std::optional<int> new_digital_gain =
    930      helper.manager.GetDigitalComressionGain();
    931  if (new_digital_gain) {
    932    helper.mock_gain_control.set_compression_gain_db(*new_digital_gain);
    933  }
    934 }
    935 
    936 TEST_P(AgcManagerDirectParametrizedTest, UnmutingChecksVolumeWithoutRaising) {
    937  AgcManagerDirectTestHelper helper(env_);
    938  helper.CallAgcSequence(kInitialInputVolume,
    939                         GetOverrideOrEmpty(kHighSpeechProbability),
    940                         GetOverrideOrEmpty(kSpeechLevelDbfs));
    941 
    942  helper.manager.HandleCaptureOutputUsedChange(false);
    943  helper.manager.HandleCaptureOutputUsedChange(true);
    944 
    945  constexpr int kInputVolume = 127;
    946  helper.manager.set_stream_analog_level(kInputVolume);
    947  EXPECT_CALL(*helper.mock_agc, Reset());
    948 
    949  // SetMicVolume should not be called.
    950  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_)).WillOnce(Return(false));
    951  helper.CallProcess(/*num_calls=*/1,
    952                     GetOverrideOrEmpty(kHighSpeechProbability),
    953                     GetOverrideOrEmpty(kSpeechLevelDbfs));
    954  EXPECT_EQ(127, helper.manager.recommended_analog_level());
    955 }
    956 
    957 TEST_P(AgcManagerDirectParametrizedTest, UnmutingRaisesTooLowVolume) {
    958  AgcManagerDirectTestHelper helper(env_);
    959  helper.CallAgcSequence(kInitialInputVolume,
    960                         GetOverrideOrEmpty(kHighSpeechProbability),
    961                         GetOverrideOrEmpty(kSpeechLevelDbfs));
    962 
    963  helper.manager.HandleCaptureOutputUsedChange(false);
    964  helper.manager.HandleCaptureOutputUsedChange(true);
    965 
    966  constexpr int kInputVolume = 11;
    967  helper.manager.set_stream_analog_level(kInputVolume);
    968  EXPECT_CALL(*helper.mock_agc, Reset());
    969 
    970  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_)).WillOnce(Return(false));
    971  helper.CallProcess(/*num_calls=*/1,
    972                     GetOverrideOrEmpty(kHighSpeechProbability),
    973                     GetOverrideOrEmpty(kSpeechLevelDbfs));
    974  EXPECT_EQ(GetMinMicLevel(), helper.manager.recommended_analog_level());
    975 }
    976 
    977 TEST_P(AgcManagerDirectParametrizedTest,
    978       ManualLevelChangeResultsInNoSetMicCall) {
    979  const auto speech_probability_override =
    980      GetOverrideOrEmpty(kHighSpeechProbability);
    981 
    982  AgcManagerDirectTestHelper helper(env_);
    983  helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
    984                         GetOverrideOrEmpty(kSpeechLevelDbfs));
    985 
    986  // Change outside of compressor's range, which would normally trigger a call
    987  // to `SetMicVolume()`.
    988  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
    989      .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)));
    990 
    991  // When the analog volume changes, the gain controller is reset.
    992  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
    993 
    994  // GetMicVolume returns a value outside of the quantization slack, indicating
    995  // a manual volume change.
    996  ASSERT_NE(helper.manager.recommended_analog_level(), 154);
    997  helper.manager.set_stream_analog_level(154);
    998  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
    999                     GetOverrideOrEmpty(-29.0f));
   1000  EXPECT_EQ(154, helper.manager.recommended_analog_level());
   1001 
   1002  // Do the same thing, except downwards now.
   1003  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1004      .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
   1005  helper.manager.set_stream_analog_level(100);
   1006  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1007  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1008                     GetOverrideOrEmpty(-17.0f));
   1009  EXPECT_EQ(100, helper.manager.recommended_analog_level());
   1010 
   1011  // And finally verify the AGC continues working without a manual change.
   1012  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1013      .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
   1014  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1015                     GetOverrideOrEmpty(-17.0f));
   1016  EXPECT_EQ(99, helper.manager.recommended_analog_level());
   1017 }
   1018 
   1019 TEST_P(AgcManagerDirectParametrizedTest,
   1020       RecoveryAfterManualLevelChangeFromMax) {
   1021  const auto speech_probability_override =
   1022      GetOverrideOrEmpty(kHighSpeechProbability);
   1023 
   1024  AgcManagerDirectTestHelper helper(env_);
   1025  helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
   1026                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1027 
   1028  // Force the mic up to max volume. Takes a few steps due to the residual
   1029  // gain limitation.
   1030  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1031      .WillRepeatedly(DoAll(SetArgPointee<0>(30), Return(true)));
   1032  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1033                     GetOverrideOrEmpty(-48.0f));
   1034  EXPECT_EQ(183, helper.manager.recommended_analog_level());
   1035  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1036                     GetOverrideOrEmpty(-48.0f));
   1037  EXPECT_EQ(243, helper.manager.recommended_analog_level());
   1038  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1039                     GetOverrideOrEmpty(-48.0f));
   1040  EXPECT_EQ(255, helper.manager.recommended_analog_level());
   1041 
   1042  // Manual change does not result in SetMicVolume call.
   1043  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1044      .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
   1045  helper.manager.set_stream_analog_level(50);
   1046  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1047  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1048                     GetOverrideOrEmpty(-17.0f));
   1049  EXPECT_EQ(50, helper.manager.recommended_analog_level());
   1050 
   1051  // Continues working as usual afterwards.
   1052  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1053      .WillOnce(DoAll(SetArgPointee<0>(20), Return(true)));
   1054  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1055                     GetOverrideOrEmpty(-38.0f));
   1056 
   1057  EXPECT_EQ(69, helper.manager.recommended_analog_level());
   1058 }
   1059 
   1060 // Checks that, when the min mic level override is not specified, AGC ramps up
   1061 // towards the minimum mic level after the mic level is manually set below the
   1062 // minimum gain to enforce.
   1063 TEST_P(AgcManagerDirectParametrizedTest,
   1064       RecoveryAfterManualLevelChangeBelowMinWithoutMiMicLevelnOverride) {
   1065  if (IsMinMicLevelOverridden()) {
   1066    GTEST_SKIP() << "Skipped. Min mic level overridden.";
   1067  }
   1068 
   1069  const auto speech_probability_override =
   1070      GetOverrideOrEmpty(kHighSpeechProbability);
   1071 
   1072  AgcManagerDirectTestHelper helper(env_);
   1073  helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
   1074                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1075 
   1076  // Manual change below min, but strictly positive, otherwise AGC won't take
   1077  // any action.
   1078  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1079      .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
   1080  helper.manager.set_stream_analog_level(1);
   1081  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1082  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1083                     GetOverrideOrEmpty(-17.0f));
   1084  EXPECT_EQ(1, helper.manager.recommended_analog_level());
   1085 
   1086  // Continues working as usual afterwards.
   1087  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1088      .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)));
   1089  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1090                     GetOverrideOrEmpty(-29.0f));
   1091  EXPECT_EQ(2, helper.manager.recommended_analog_level());
   1092 
   1093  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1094      .WillOnce(DoAll(SetArgPointee<0>(30), Return(true)));
   1095  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1096                     GetOverrideOrEmpty(-48.0f));
   1097  EXPECT_EQ(11, helper.manager.recommended_analog_level());
   1098 
   1099  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1100      .WillOnce(DoAll(SetArgPointee<0>(20), Return(true)));
   1101  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1102                     GetOverrideOrEmpty(-38.0f));
   1103  EXPECT_EQ(18, helper.manager.recommended_analog_level());
   1104 }
   1105 
   1106 // Checks that, when the min mic level override is specified, AGC immediately
   1107 // applies the minimum mic level after the mic level is manually set below the
   1108 // minimum gain to enforce.
   1109 TEST_P(AgcManagerDirectParametrizedTest,
   1110       RecoveryAfterManualLevelChangeBelowMin) {
   1111  if (!IsMinMicLevelOverridden()) {
   1112    GTEST_SKIP() << "Skipped. Min mic level not overridden.";
   1113  }
   1114 
   1115  const auto speech_probability_override =
   1116      GetOverrideOrEmpty(kHighSpeechProbability);
   1117 
   1118  AgcManagerDirectTestHelper helper(env_);
   1119  helper.CallAgcSequence(kInitialInputVolume, speech_probability_override,
   1120                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1121 
   1122  // Manual change below min, but strictly positive, otherwise
   1123  // AGC won't take any action.
   1124  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1125      .WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
   1126  helper.manager.set_stream_analog_level(1);
   1127  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1128  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1129                     GetOverrideOrEmpty(-17.0f));
   1130  EXPECT_EQ(GetMinMicLevel(), helper.manager.recommended_analog_level());
   1131 }
   1132 
   1133 TEST_P(AgcManagerDirectParametrizedTest, NoClippingHasNoImpact) {
   1134  AgcManagerDirectTestHelper helper(env_);
   1135  helper.CallAgcSequence(kInitialInputVolume,
   1136                         GetOverrideOrEmpty(kHighSpeechProbability),
   1137                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1138 
   1139  helper.CallPreProc(/*num_calls=*/100, /*clipped_ratio=*/0);
   1140  EXPECT_EQ(128, helper.manager.recommended_analog_level());
   1141 }
   1142 
   1143 TEST_P(AgcManagerDirectParametrizedTest, ClippingUnderThresholdHasNoImpact) {
   1144  AgcManagerDirectTestHelper helper(env_);
   1145  helper.CallAgcSequence(kInitialInputVolume,
   1146                         GetOverrideOrEmpty(kHighSpeechProbability),
   1147                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1148 
   1149  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/0.099);
   1150  EXPECT_EQ(128, helper.manager.recommended_analog_level());
   1151 }
   1152 
   1153 TEST_P(AgcManagerDirectParametrizedTest, ClippingLowersVolume) {
   1154  AgcManagerDirectTestHelper helper(env_);
   1155  helper.CallAgcSequence(/*applied_input_volume=*/255,
   1156                         GetOverrideOrEmpty(kHighSpeechProbability),
   1157                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1158 
   1159  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1160  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/0.2);
   1161  EXPECT_EQ(240, helper.manager.recommended_analog_level());
   1162 }
   1163 
   1164 TEST_P(AgcManagerDirectParametrizedTest, WaitingPeriodBetweenClippingChecks) {
   1165  AgcManagerDirectTestHelper helper(env_);
   1166  helper.CallAgcSequence(/*applied_input_volume=*/255,
   1167                         GetOverrideOrEmpty(kHighSpeechProbability),
   1168                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1169 
   1170  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1171  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
   1172  EXPECT_EQ(240, helper.manager.recommended_analog_level());
   1173 
   1174  EXPECT_CALL(*helper.mock_agc, Reset()).Times(0);
   1175  helper.CallPreProc(/*num_calls=*/300,
   1176                     /*clipped_ratio=*/kAboveClippedThreshold);
   1177  EXPECT_EQ(240, helper.manager.recommended_analog_level());
   1178 
   1179  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1180  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
   1181  EXPECT_EQ(225, helper.manager.recommended_analog_level());
   1182 }
   1183 
   1184 TEST_P(AgcManagerDirectParametrizedTest, ClippingLoweringIsLimited) {
   1185  AgcManagerDirectTestHelper helper(env_);
   1186  helper.CallAgcSequence(/*applied_input_volume=*/180,
   1187                         GetOverrideOrEmpty(kHighSpeechProbability),
   1188                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1189 
   1190  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1191  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
   1192  EXPECT_EQ(kClippedMin, helper.manager.recommended_analog_level());
   1193 
   1194  EXPECT_CALL(*helper.mock_agc, Reset()).Times(0);
   1195  helper.CallPreProc(/*num_calls=*/1000,
   1196                     /*clipped_ratio=*/kAboveClippedThreshold);
   1197  EXPECT_EQ(kClippedMin, helper.manager.recommended_analog_level());
   1198 }
   1199 
   1200 TEST_P(AgcManagerDirectParametrizedTest,
   1201       ClippingMaxIsRespectedWhenEqualToLevel) {
   1202  const auto speech_probability_override =
   1203      GetOverrideOrEmpty(kHighSpeechProbability);
   1204 
   1205  AgcManagerDirectTestHelper helper(env_);
   1206  helper.CallAgcSequence(/*applied_input_volume=*/255,
   1207                         speech_probability_override,
   1208                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1209 
   1210  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1211  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
   1212  EXPECT_EQ(240, helper.manager.recommended_analog_level());
   1213 
   1214  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1215      .WillRepeatedly(DoAll(SetArgPointee<0>(30), Return(true)));
   1216  helper.CallProcess(/*num_calls=*/10, speech_probability_override,
   1217                     GetOverrideOrEmpty(-48.0f));
   1218  EXPECT_EQ(240, helper.manager.recommended_analog_level());
   1219 }
   1220 
   1221 TEST_P(AgcManagerDirectParametrizedTest,
   1222       ClippingMaxIsRespectedWhenHigherThanLevel) {
   1223  const auto speech_probability_override =
   1224      GetOverrideOrEmpty(kHighSpeechProbability);
   1225 
   1226  AgcManagerDirectTestHelper helper(env_);
   1227  helper.CallAgcSequence(/*applied_input_volume=*/200,
   1228                         speech_probability_override,
   1229                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1230 
   1231  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1232  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
   1233  EXPECT_EQ(185, helper.manager.recommended_analog_level());
   1234 
   1235  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1236      .WillRepeatedly(DoAll(SetArgPointee<0>(40), Return(true)));
   1237  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1238                     GetOverrideOrEmpty(-58.0f));
   1239  EXPECT_EQ(240, helper.manager.recommended_analog_level());
   1240  helper.CallProcess(/*num_calls=*/10, speech_probability_override,
   1241                     GetOverrideOrEmpty(-58.0f));
   1242  EXPECT_EQ(240, helper.manager.recommended_analog_level());
   1243 }
   1244 
   1245 TEST_P(AgcManagerDirectParametrizedTest,
   1246       MaxCompressionIsIncreasedAfterClipping) {
   1247  constexpr std::optional<float> kNoOverride = std::nullopt;
   1248  const auto speech_probability_override =
   1249      GetOverrideOrEmpty(kHighSpeechProbability);
   1250 
   1251  AgcManagerDirectTestHelper helper(env_);
   1252  helper.CallAgcSequence(/*applied_input_volume=*/210,
   1253                         speech_probability_override,
   1254                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1255 
   1256  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1257  helper.CallPreProc(/*num_calls=*/1, kAboveClippedThreshold);
   1258  EXPECT_EQ(195, helper.manager.recommended_analog_level());
   1259 
   1260  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1261      .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)))
   1262      .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)))
   1263      .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)))
   1264      .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)))
   1265      .WillOnce(DoAll(SetArgPointee<0>(11), Return(true)))
   1266      .WillRepeatedly(Return(false));
   1267  helper.CallProcess(/*num_calls=*/5, speech_probability_override,
   1268                     GetOverrideOrEmpty(-29.0f));
   1269  // The mock `GetRmsErrorDb()` returns false; mimic this by passing
   1270  // std::nullopt as an override.
   1271  helper.CallProcess(/*num_calls=*/14, kNoOverride, kNoOverride);
   1272  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(8))
   1273      .WillOnce(Return(0));
   1274  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
   1275  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(9))
   1276      .WillOnce(Return(0));
   1277  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
   1278  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(10))
   1279      .WillOnce(Return(0));
   1280  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
   1281  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(11))
   1282      .WillOnce(Return(0));
   1283  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
   1284  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(12))
   1285      .WillOnce(Return(0));
   1286  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
   1287  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(13))
   1288      .WillOnce(Return(0));
   1289  helper.CallProcess(/*num_calls=*/1, kNoOverride, kNoOverride);
   1290 
   1291  // Continue clipping until we hit the maximum surplus compression.
   1292  helper.CallPreProc(/*num_calls=*/300,
   1293                     /*clipped_ratio=*/kAboveClippedThreshold);
   1294  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1295  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
   1296  EXPECT_EQ(180, helper.manager.recommended_analog_level());
   1297 
   1298  helper.CallPreProc(/*num_calls=*/300,
   1299                     /*clipped_ratio=*/kAboveClippedThreshold);
   1300  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1301  helper.CallPreProc(1, kAboveClippedThreshold);
   1302  EXPECT_EQ(kClippedMin, helper.manager.recommended_analog_level());
   1303 
   1304  // Current level is now at the minimum, but the maximum allowed level still
   1305  // has more to decrease.
   1306  helper.CallPreProc(/*num_calls=*/300,
   1307                     /*clipped_ratio=*/kAboveClippedThreshold);
   1308  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
   1309 
   1310  helper.CallPreProc(/*num_calls=*/300,
   1311                     /*clipped_ratio=*/kAboveClippedThreshold);
   1312  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
   1313 
   1314  helper.CallPreProc(/*num_calls=*/300,
   1315                     /*clipped_ratio=*/kAboveClippedThreshold);
   1316  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
   1317 
   1318  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1319      .WillOnce(DoAll(SetArgPointee<0>(16), Return(true)))
   1320      .WillOnce(DoAll(SetArgPointee<0>(16), Return(true)))
   1321      .WillOnce(DoAll(SetArgPointee<0>(16), Return(true)))
   1322      .WillOnce(DoAll(SetArgPointee<0>(16), Return(true)))
   1323      .WillRepeatedly(Return(false));
   1324  helper.CallProcess(/*num_calls=*/4, speech_probability_override,
   1325                     GetOverrideOrEmpty(-34.0f));
   1326  helper.CallProcess(/*num_calls=*/15, kNoOverride, kNoOverride);
   1327  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(14))
   1328      .WillOnce(Return(0));
   1329  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
   1330  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(15))
   1331      .WillOnce(Return(0));
   1332  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
   1333  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(16))
   1334      .WillOnce(Return(0));
   1335  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
   1336  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(17))
   1337      .WillOnce(Return(0));
   1338  helper.CallProcess(/*num_calls=*/20, kNoOverride, kNoOverride);
   1339  EXPECT_CALL(helper.mock_gain_control, set_compression_gain_db(18))
   1340      .WillOnce(Return(0));
   1341  helper.CallProcess(/*num_calls=*/1, kNoOverride, kNoOverride);
   1342 }
   1343 
   1344 TEST_P(AgcManagerDirectParametrizedTest, UserCanRaiseVolumeAfterClipping) {
   1345  const auto speech_probability_override =
   1346      GetOverrideOrEmpty(kHighSpeechProbability);
   1347 
   1348  AgcManagerDirectTestHelper helper(env_);
   1349  helper.CallAgcSequence(/*applied_input_volume=*/225,
   1350                         speech_probability_override,
   1351                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1352 
   1353  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1354  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
   1355  EXPECT_EQ(210, helper.manager.recommended_analog_level());
   1356 
   1357  // High enough error to trigger a volume check.
   1358  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1359      .WillOnce(DoAll(SetArgPointee<0>(14), Return(true)));
   1360  // User changed the volume.
   1361  helper.manager.set_stream_analog_level(250);
   1362  EXPECT_CALL(*helper.mock_agc, Reset()).Times(AtLeast(1));
   1363  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1364                     GetOverrideOrEmpty(-32.0f));
   1365  EXPECT_EQ(250, helper.manager.recommended_analog_level());
   1366 
   1367  // Move down...
   1368  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1369      .WillOnce(DoAll(SetArgPointee<0>(-10), Return(true)));
   1370  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1371                     GetOverrideOrEmpty(-8.0f));
   1372  EXPECT_EQ(210, helper.manager.recommended_analog_level());
   1373  // And back up to the new max established by the user.
   1374  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1375      .WillOnce(DoAll(SetArgPointee<0>(40), Return(true)));
   1376  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1377                     GetOverrideOrEmpty(-58.0f));
   1378  EXPECT_EQ(250, helper.manager.recommended_analog_level());
   1379  // Will not move above new maximum.
   1380  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1381      .WillOnce(DoAll(SetArgPointee<0>(30), Return(true)));
   1382  helper.CallProcess(/*num_calls=*/1, speech_probability_override,
   1383                     GetOverrideOrEmpty(-48.0f));
   1384  EXPECT_EQ(250, helper.manager.recommended_analog_level());
   1385 }
   1386 
   1387 TEST_P(AgcManagerDirectParametrizedTest, ClippingDoesNotPullLowVolumeBackUp) {
   1388  AgcManagerDirectTestHelper helper(env_);
   1389  helper.CallAgcSequence(/*applied_input_volume=*/80,
   1390                         GetOverrideOrEmpty(kHighSpeechProbability),
   1391                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1392 
   1393  EXPECT_CALL(*helper.mock_agc, Reset()).Times(0);
   1394  int initial_volume = helper.manager.recommended_analog_level();
   1395  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
   1396  EXPECT_EQ(initial_volume, helper.manager.recommended_analog_level());
   1397 }
   1398 
   1399 TEST_P(AgcManagerDirectParametrizedTest, TakesNoActionOnZeroMicVolume) {
   1400  AgcManagerDirectTestHelper helper(env_);
   1401  helper.CallAgcSequence(kInitialInputVolume,
   1402                         GetOverrideOrEmpty(kHighSpeechProbability),
   1403                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1404 
   1405  EXPECT_CALL(*helper.mock_agc, GetRmsErrorDb(_))
   1406      .WillRepeatedly(DoAll(SetArgPointee<0>(30), Return(true)));
   1407  helper.manager.set_stream_analog_level(0);
   1408  helper.CallProcess(/*num_calls=*/10,
   1409                     GetOverrideOrEmpty(kHighSpeechProbability),
   1410                     GetOverrideOrEmpty(-48.0f));
   1411  EXPECT_EQ(0, helper.manager.recommended_analog_level());
   1412 }
   1413 
   1414 TEST_P(AgcManagerDirectParametrizedTest, ClippingDetectionLowersVolume) {
   1415  AgcManagerDirectTestHelper helper(env_);
   1416  helper.CallAgcSequence(/*applied_input_volume=*/255,
   1417                         GetOverrideOrEmpty(kHighSpeechProbability),
   1418                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1419 
   1420  EXPECT_EQ(255, helper.manager.recommended_analog_level());
   1421  helper.CallPreProcForChangingAudio(/*num_calls=*/100, /*peak_ratio=*/0.99f);
   1422  EXPECT_EQ(255, helper.manager.recommended_analog_level());
   1423  helper.CallPreProcForChangingAudio(/*num_calls=*/100, /*peak_ratio=*/1.0f);
   1424  EXPECT_EQ(240, helper.manager.recommended_analog_level());
   1425 }
   1426 
   1427 TEST_P(AgcManagerDirectParametrizedTest,
   1428       DisabledClippingPredictorDoesNotLowerVolume) {
   1429  AgcManagerDirectTestHelper helper(env_);
   1430  helper.CallAgcSequence(/*applied_input_volume=*/255,
   1431                         GetOverrideOrEmpty(kHighSpeechProbability),
   1432                         GetOverrideOrEmpty(kSpeechLevelDbfs));
   1433 
   1434  EXPECT_FALSE(helper.manager.clipping_predictor_enabled());
   1435  EXPECT_EQ(255, helper.manager.recommended_analog_level());
   1436  helper.CallPreProcForChangingAudio(/*num_calls=*/100, /*peak_ratio=*/0.99f);
   1437  EXPECT_EQ(255, helper.manager.recommended_analog_level());
   1438  helper.CallPreProcForChangingAudio(/*num_calls=*/100, /*peak_ratio=*/0.99f);
   1439  EXPECT_EQ(255, helper.manager.recommended_analog_level());
   1440 }
   1441 
   1442 TEST_P(AgcManagerDirectParametrizedTest, DisableDigitalDisablesDigital) {
   1443  if (IsRmsErrorOverridden()) {
   1444    GTEST_SKIP() << "Skipped. RMS error override does not affect the test.";
   1445  }
   1446 
   1447  auto agc = std::unique_ptr<Agc>(new ::testing::NiceMock<MockAgc>());
   1448  MockGainControl mock_gain_control;
   1449  EXPECT_CALL(mock_gain_control, set_mode(GainControl::kFixedDigital));
   1450  EXPECT_CALL(mock_gain_control, set_target_level_dbfs(0));
   1451  EXPECT_CALL(mock_gain_control, set_compression_gain_db(0));
   1452  EXPECT_CALL(mock_gain_control, enable_limiter(false));
   1453 
   1454  AnalogAgcConfig config;
   1455  config.enable_digital_adaptive = false;
   1456  auto manager = std::make_unique<AgcManagerDirect>(env_, kNumChannels, config);
   1457  manager->Initialize();
   1458  manager->SetupDigitalGainControl(mock_gain_control);
   1459 }
   1460 
   1461 TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentDefault) {
   1462  std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect();
   1463  EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel);
   1464 }
   1465 
   1466 TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentDisabled) {
   1467  for (const std::string& field_trial_suffix : {"", "_20220210"}) {
   1468    std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect(
   1469        {.field_trials = GetAgcMinMicLevelExperimentFieldTrial(
   1470             "Disabled" + field_trial_suffix)});
   1471    EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel);
   1472  }
   1473 }
   1474 
   1475 // Checks that a field-trial parameter outside of the valid range [0,255] is
   1476 // ignored.
   1477 TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentOutOfRangeAbove) {
   1478  std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect(
   1479      {.field_trials = GetAgcMinMicLevelExperimentFieldTrial("Enabled-256")});
   1480  EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel);
   1481 }
   1482 
   1483 // Checks that a field-trial parameter outside of the valid range [0,255] is
   1484 // ignored.
   1485 TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentOutOfRangeBelow) {
   1486  std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect(
   1487      {.field_trials = GetAgcMinMicLevelExperimentFieldTrial("Enabled--1")});
   1488  EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevel);
   1489 }
   1490 
   1491 // Verifies that a valid experiment changes the minimum microphone level. The
   1492 // start volume is larger than the min level and should therefore not be
   1493 // changed.
   1494 TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentEnabled50) {
   1495  constexpr int kMinMicLevelOverride = 50;
   1496  for (const std::string& field_trial_suffix : {"", "_20220210"}) {
   1497    SCOPED_TRACE(field_trial_suffix);
   1498 
   1499    std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect(
   1500        {.field_trials = GetAgcMinMicLevelExperimentFieldTrialEnabled(
   1501             kMinMicLevelOverride, field_trial_suffix)});
   1502 
   1503    EXPECT_EQ(manager->channel_agcs_[0]->min_mic_level(), kMinMicLevelOverride);
   1504  }
   1505 }
   1506 
   1507 // Checks that, when the "WebRTC-Audio-AgcMinMicLevelExperiment" field trial is
   1508 // specified with a valid value, the mic level never gets lowered beyond the
   1509 // override value in the presence of clipping.
   1510 TEST(AgcManagerDirectTest, AgcMinMicLevelExperimentCheckMinLevelWithClipping) {
   1511  constexpr int kMinMicLevelOverride = 250;
   1512 
   1513  // Create and initialize two AGCs by specifying and leaving unspecified the
   1514  // relevant field trial.
   1515  std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect();
   1516  std::unique_ptr<AgcManagerDirect> manager_with_override =
   1517      CreateAgcManagerDirect(
   1518          {.field_trials = GetAgcMinMicLevelExperimentFieldTrialEnabled(
   1519               kMinMicLevelOverride)});
   1520 
   1521  // Create a test input signal which containts 80% of clipped samples.
   1522  AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
   1523                           1);
   1524  WriteAudioBufferSamples(/*samples_value=*/4000.0f, /*clipped_ratio=*/0.8f,
   1525                          audio_buffer);
   1526 
   1527  // Simulate 4 seconds of clipping; it is expected to trigger a downward
   1528  // adjustment of the analog gain.
   1529  CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
   1530                           /*speech_probability_override=*/std::nullopt,
   1531                           /*speech_level_override=*/std::nullopt, *manager);
   1532  CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
   1533                           /*speech_probability_override=*/std::nullopt,
   1534                           /*speech_level_override=*/std::nullopt,
   1535                           *manager_with_override);
   1536 
   1537  // Make sure that an adaptation occurred.
   1538  ASSERT_GT(manager->recommended_analog_level(), 0);
   1539 
   1540  // Check that the test signal triggers a larger downward adaptation for
   1541  // `manager`, which is allowed to reach a lower gain.
   1542  EXPECT_GT(manager_with_override->recommended_analog_level(),
   1543            manager->recommended_analog_level());
   1544  // Check that the gain selected by `manager_with_override` equals the minimum
   1545  // value overridden via field trial.
   1546  EXPECT_EQ(manager_with_override->recommended_analog_level(),
   1547            kMinMicLevelOverride);
   1548 }
   1549 
   1550 // Checks that, when the "WebRTC-Audio-AgcMinMicLevelExperiment" field trial is
   1551 // specified with a valid value, the mic level never gets lowered beyond the
   1552 // override value in the presence of clipping when RMS error override is used.
   1553 // TODO(webrtc:7494): Revisit the test after moving the number of override wait
   1554 // frames to APM config. The test passes but internally the gain update timing
   1555 // differs.
   1556 TEST(AgcManagerDirectTest,
   1557     AgcMinMicLevelExperimentCheckMinLevelWithClippingWithRmsErrorOverride) {
   1558  constexpr int kMinMicLevelOverride = 250;
   1559 
   1560  // Create and initialize two AGCs by specifying and leaving unspecified the
   1561  // relevant field trial.
   1562  std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect();
   1563  std::unique_ptr<AgcManagerDirect> manager_with_override =
   1564      CreateAgcManagerDirect(
   1565          {.field_trials = GetAgcMinMicLevelExperimentFieldTrialEnabled(
   1566               kMinMicLevelOverride)});
   1567 
   1568  // Create a test input signal which containts 80% of clipped samples.
   1569  AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
   1570                           1);
   1571  WriteAudioBufferSamples(/*samples_value=*/4000.0f, /*clipped_ratio=*/0.8f,
   1572                          audio_buffer);
   1573 
   1574  // Simulate 4 seconds of clipping; it is expected to trigger a downward
   1575  // adjustment of the analog gain.
   1576  CallPreProcessAndProcess(
   1577      /*num_calls=*/400, audio_buffer,
   1578      /*speech_probability_override=*/0.7f,
   1579      /*speech_probability_level=*/-18.0f, *manager);
   1580  CallPreProcessAndProcess(
   1581      /*num_calls=*/400, audio_buffer,
   1582      /*speech_probability_override=*/std::optional<float>(0.7f),
   1583      /*speech_probability_level=*/std::optional<float>(-18.0f),
   1584      *manager_with_override);
   1585 
   1586  // Make sure that an adaptation occurred.
   1587  ASSERT_GT(manager->recommended_analog_level(), 0);
   1588 
   1589  // Check that the test signal triggers a larger downward adaptation for
   1590  // `manager`, which is allowed to reach a lower gain.
   1591  EXPECT_GT(manager_with_override->recommended_analog_level(),
   1592            manager->recommended_analog_level());
   1593  // Check that the gain selected by `manager_with_override` equals the minimum
   1594  // value overridden via field trial.
   1595  EXPECT_EQ(manager_with_override->recommended_analog_level(),
   1596            kMinMicLevelOverride);
   1597 }
   1598 
   1599 // Checks that, when the "WebRTC-Audio-AgcMinMicLevelExperiment" field trial is
   1600 // specified with a value lower than the `clipped_level_min`, the behavior of
   1601 // the analog gain controller is the same as that obtained when the field trial
   1602 // is not specified.
   1603 TEST(AgcManagerDirectTest,
   1604     AgcMinMicLevelExperimentCompareMicLevelWithClipping) {
   1605  // Create and initialize two AGCs by specifying and leaving unspecified the
   1606  // relevant field trial.
   1607  // Use a large clipped level step to more quickly decrease the analog gain
   1608  // with clipping.
   1609  std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect({
   1610      .clipped_level_min = kDefaultAnalogConfig.clipped_level_min,
   1611      .enable_digital_adaptive = false,
   1612      .clipped_level_step = 64,
   1613  });
   1614 
   1615  constexpr int kMinMicLevelOverride = 20;
   1616  static_assert(kDefaultAnalogConfig.clipped_level_min >= kMinMicLevelOverride,
   1617                "Use a lower override value.");
   1618  std::unique_ptr<AgcManagerDirect> manager_with_override =
   1619      CreateAgcManagerDirect({
   1620          .field_trials = GetAgcMinMicLevelExperimentFieldTrialEnabled(
   1621              kMinMicLevelOverride),
   1622          .clipped_level_min = kDefaultAnalogConfig.clipped_level_min,
   1623          .enable_digital_adaptive = false,
   1624          .clipped_level_step = 64,
   1625      });
   1626 
   1627  // Create a test input signal which containts 80% of clipped samples.
   1628  AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
   1629                           1);
   1630  WriteAudioBufferSamples(/*samples_value=*/4000.0f, /*clipped_ratio=*/0.8f,
   1631                          audio_buffer);
   1632 
   1633  // Simulate 4 seconds of clipping; it is expected to trigger a downward
   1634  // adjustment of the analog gain.
   1635  CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
   1636                           /*speech_probability_override=*/std::nullopt,
   1637                           /*speech_level_override=*/std::nullopt, *manager);
   1638  CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
   1639                           /*speech_probability_override=*/std::nullopt,
   1640                           /*speech_level_override=*/std::nullopt,
   1641                           *manager_with_override);
   1642 
   1643  // Make sure that an adaptation occurred.
   1644  ASSERT_GT(manager->recommended_analog_level(), 0);
   1645 
   1646  // Check that the selected analog gain is the same for both controllers and
   1647  // that it equals the minimum level reached when clipping is handled. That is
   1648  // expected because the minimum microphone level override is less than the
   1649  // minimum level used when clipping is detected.
   1650  EXPECT_EQ(manager->recommended_analog_level(),
   1651            manager_with_override->recommended_analog_level());
   1652  EXPECT_EQ(manager_with_override->recommended_analog_level(),
   1653            kDefaultAnalogConfig.clipped_level_min);
   1654 }
   1655 
   1656 // Checks that, when the "WebRTC-Audio-AgcMinMicLevelExperiment" field trial is
   1657 // specified with a value lower than the `clipped_level_min`, the behavior of
   1658 // the analog gain controller is the same as that obtained when the field trial
   1659 // is not specified.
   1660 // TODO(webrtc:7494): Revisit the test after moving the number of override wait
   1661 // frames to APM config. The test passes but internally the gain update timing
   1662 // differs.
   1663 TEST(AgcManagerDirectTest,
   1664     AgcMinMicLevelExperimentCompareMicLevelWithClippingWithRmsErrorOverride) {
   1665  // Create and initialize two AGCs by specifying and leaving unspecified the
   1666  // relevant field trial.
   1667  std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect({
   1668      .clipped_level_min = kDefaultAnalogConfig.clipped_level_min,
   1669      .enable_digital_adaptive = false,
   1670      .clipped_level_step = 64,
   1671  });
   1672 
   1673  constexpr int kMinMicLevelOverride = 20;
   1674  static_assert(kDefaultAnalogConfig.clipped_level_min >= kMinMicLevelOverride,
   1675                "Use a lower override value.");
   1676  std::unique_ptr<AgcManagerDirect> manager_with_override =
   1677      CreateAgcManagerDirect({
   1678          .field_trials = GetAgcMinMicLevelExperimentFieldTrialEnabled(
   1679              kMinMicLevelOverride),
   1680          .clipped_level_min = kDefaultAnalogConfig.clipped_level_min,
   1681          .enable_digital_adaptive = false,
   1682          .clipped_level_step = 64,
   1683      });
   1684 
   1685  // Create a test input signal which containts 80% of clipped samples.
   1686  AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
   1687                           1);
   1688  WriteAudioBufferSamples(/*samples_value=*/4000.0f, /*clipped_ratio=*/0.8f,
   1689                          audio_buffer);
   1690 
   1691  CallPreProcessAndProcess(
   1692      /*num_calls=*/400, audio_buffer,
   1693      /*speech_probability_override=*/std::optional<float>(0.7f),
   1694      /*speech_level_override=*/std::optional<float>(-18.0f), *manager);
   1695  CallPreProcessAndProcess(
   1696      /*num_calls=*/400, audio_buffer,
   1697      /*speech_probability_override=*/std::optional<float>(0.7f),
   1698      /*speech_level_override=*/std::optional<float>(-18.0f),
   1699      *manager_with_override);
   1700 
   1701  // Make sure that an adaptation occurred.
   1702  ASSERT_GT(manager->recommended_analog_level(), 0);
   1703 
   1704  // Check that the selected analog gain is the same for both controllers and
   1705  // that it equals the minimum level reached when clipping is handled. That is
   1706  // expected because the minimum microphone level override is less than the
   1707  // minimum level used when clipping is detected.
   1708  EXPECT_EQ(manager->recommended_analog_level(),
   1709            manager_with_override->recommended_analog_level());
   1710  EXPECT_EQ(manager_with_override->recommended_analog_level(),
   1711            kDefaultAnalogConfig.clipped_level_min);
   1712 }
   1713 
   1714 // TODO(bugs.webrtc.org/12774): Test the bahavior of `clipped_level_step`.
   1715 // TODO(bugs.webrtc.org/12774): Test the bahavior of `clipped_ratio_threshold`.
   1716 // TODO(bugs.webrtc.org/12774): Test the bahavior of `clipped_wait_frames`.
   1717 // Verifies that configurable clipping parameters are initialized as intended.
   1718 TEST_P(AgcManagerDirectParametrizedTest, ClippingParametersVerified) {
   1719  if (IsRmsErrorOverridden()) {
   1720    GTEST_SKIP() << "Skipped. RMS error override does not affect the test.";
   1721  }
   1722 
   1723  std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect();
   1724  EXPECT_EQ(manager->clipped_level_step_, kClippedLevelStep);
   1725  EXPECT_EQ(manager->clipped_ratio_threshold_, kClippedRatioThreshold);
   1726  EXPECT_EQ(manager->clipped_wait_frames_, kClippedWaitFrames);
   1727 
   1728  std::unique_ptr<AgcManagerDirect> manager_custom =
   1729      CreateAgcManagerDirect({.clipped_level_step = 10,
   1730                              .clipped_ratio_threshold = 0.2f,
   1731                              .clipped_wait_frames = 50});
   1732  EXPECT_EQ(manager_custom->clipped_level_step_, 10);
   1733  EXPECT_EQ(manager_custom->clipped_ratio_threshold_, 0.2f);
   1734  EXPECT_EQ(manager_custom->clipped_wait_frames_, 50);
   1735 }
   1736 
   1737 TEST_P(AgcManagerDirectParametrizedTest,
   1738       DisableClippingPredictorDisablesClippingPredictor) {
   1739  if (IsRmsErrorOverridden()) {
   1740    GTEST_SKIP() << "Skipped. RMS error override does not affect the test.";
   1741  }
   1742 
   1743  std::unique_ptr<AgcManagerDirect> manager =
   1744      CreateAgcManagerDirect({.clipping_predictor = {.enabled = false}});
   1745 
   1746  EXPECT_FALSE(manager->clipping_predictor_enabled());
   1747  EXPECT_FALSE(manager->use_clipping_predictor_step());
   1748 }
   1749 
   1750 TEST_P(AgcManagerDirectParametrizedTest, ClippingPredictorDisabledByDefault) {
   1751  if (IsRmsErrorOverridden()) {
   1752    GTEST_SKIP() << "Skipped. RMS error override does not affect the test.";
   1753  }
   1754 
   1755  constexpr ClippingPredictorConfig kDefaultConfig;
   1756  EXPECT_FALSE(kDefaultConfig.enabled);
   1757 }
   1758 
   1759 TEST_P(AgcManagerDirectParametrizedTest,
   1760       EnableClippingPredictorEnablesClippingPredictor) {
   1761  if (IsRmsErrorOverridden()) {
   1762    GTEST_SKIP() << "Skipped. RMS error override does not affect the test.";
   1763  }
   1764 
   1765  std::unique_ptr<AgcManagerDirect> manager = CreateAgcManagerDirect(
   1766      {.clipping_predictor = {.enabled = true, .use_predicted_step = true}});
   1767 
   1768  EXPECT_TRUE(manager->clipping_predictor_enabled());
   1769  EXPECT_TRUE(manager->use_clipping_predictor_step());
   1770 }
   1771 
   1772 TEST_P(AgcManagerDirectParametrizedTest,
   1773       DisableClippingPredictorDoesNotLowerVolume) {
   1774  AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
   1775                           kNumChannels, kSampleRateHz, kNumChannels);
   1776 
   1777  AnalogAgcConfig config = GetAnalogAgcTestConfig();
   1778  config.clipping_predictor.enabled = false;
   1779  AgcManagerDirect manager(env_, config, new ::testing::NiceMock<MockAgc>());
   1780  manager.Initialize();
   1781  manager.set_stream_analog_level(/*level=*/255);
   1782  EXPECT_FALSE(manager.clipping_predictor_enabled());
   1783  EXPECT_FALSE(manager.use_clipping_predictor_step());
   1784  EXPECT_EQ(manager.recommended_analog_level(), 255);
   1785  manager.Process(audio_buffer, GetOverrideOrEmpty(kHighSpeechProbability),
   1786                  GetOverrideOrEmpty(kSpeechLevelDbfs));
   1787  CallPreProcessAudioBuffer(/*num_calls=*/10, /*peak_ratio=*/0.99f, manager);
   1788  EXPECT_EQ(manager.recommended_analog_level(), 255);
   1789  CallPreProcessAudioBuffer(/*num_calls=*/300, /*peak_ratio=*/0.99f, manager);
   1790  EXPECT_EQ(manager.recommended_analog_level(), 255);
   1791  CallPreProcessAudioBuffer(/*num_calls=*/10, /*peak_ratio=*/0.99f, manager);
   1792  EXPECT_EQ(manager.recommended_analog_level(), 255);
   1793 }
   1794 
   1795 TEST_P(AgcManagerDirectParametrizedTest,
   1796       UsedClippingPredictionsProduceLowerAnalogLevels) {
   1797  AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
   1798                           kNumChannels, kSampleRateHz, kNumChannels);
   1799 
   1800  AnalogAgcConfig config_with_prediction = GetAnalogAgcTestConfig();
   1801  config_with_prediction.clipping_predictor.enabled = true;
   1802  config_with_prediction.clipping_predictor.use_predicted_step = true;
   1803  AnalogAgcConfig config_without_prediction = GetAnalogAgcTestConfig();
   1804  config_without_prediction.clipping_predictor.enabled = false;
   1805  AgcManagerDirect manager_with_prediction(env_, config_with_prediction,
   1806                                           new ::testing::NiceMock<MockAgc>());
   1807  AgcManagerDirect manager_without_prediction(
   1808      env_, config_without_prediction, new ::testing::NiceMock<MockAgc>());
   1809 
   1810  manager_with_prediction.Initialize();
   1811  manager_without_prediction.Initialize();
   1812 
   1813  constexpr int kInitialLevel = 255;
   1814  constexpr float kClippingPeakRatio = 1.0f;
   1815  constexpr float kCloseToClippingPeakRatio = 0.99f;
   1816  constexpr float kZeroPeakRatio = 0.0f;
   1817  manager_with_prediction.set_stream_analog_level(kInitialLevel);
   1818  manager_without_prediction.set_stream_analog_level(kInitialLevel);
   1819  manager_with_prediction.Process(audio_buffer,
   1820                                  GetOverrideOrEmpty(kHighSpeechProbability),
   1821                                  GetOverrideOrEmpty(kSpeechLevelDbfs));
   1822  manager_without_prediction.Process(audio_buffer,
   1823                                     GetOverrideOrEmpty(kHighSpeechProbability),
   1824                                     GetOverrideOrEmpty(kSpeechLevelDbfs));
   1825  EXPECT_TRUE(manager_with_prediction.clipping_predictor_enabled());
   1826  EXPECT_FALSE(manager_without_prediction.clipping_predictor_enabled());
   1827  EXPECT_TRUE(manager_with_prediction.use_clipping_predictor_step());
   1828  EXPECT_EQ(manager_with_prediction.recommended_analog_level(), kInitialLevel);
   1829  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
   1830            kInitialLevel);
   1831 
   1832  // Expect a change in the analog level when the prediction step is used.
   1833  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
   1834                            manager_with_prediction);
   1835  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
   1836                            manager_without_prediction);
   1837  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
   1838            kInitialLevel - kClippedLevelStep);
   1839  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
   1840            kInitialLevel);
   1841 
   1842  // Expect no change during waiting.
   1843  CallPreProcessAudioBuffer(kClippedWaitFrames, kCloseToClippingPeakRatio,
   1844                            manager_with_prediction);
   1845  CallPreProcessAudioBuffer(kClippedWaitFrames, kCloseToClippingPeakRatio,
   1846                            manager_without_prediction);
   1847  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
   1848            kInitialLevel - kClippedLevelStep);
   1849  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
   1850            kInitialLevel);
   1851 
   1852  // Expect a change when the prediction step is used.
   1853  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
   1854                            manager_with_prediction);
   1855  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
   1856                            manager_without_prediction);
   1857  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
   1858            kInitialLevel - 2 * kClippedLevelStep);
   1859  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
   1860            kInitialLevel);
   1861 
   1862  // Expect no change when clipping is not detected or predicted.
   1863  CallPreProcessAudioBuffer(2 * kClippedWaitFrames, kZeroPeakRatio,
   1864                            manager_with_prediction);
   1865  CallPreProcessAudioBuffer(2 * kClippedWaitFrames, kZeroPeakRatio,
   1866                            manager_without_prediction);
   1867  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
   1868            kInitialLevel - 2 * kClippedLevelStep);
   1869  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
   1870            kInitialLevel);
   1871 
   1872  // Expect a change for clipping frames.
   1873  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
   1874                            manager_with_prediction);
   1875  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
   1876                            manager_without_prediction);
   1877  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
   1878            kInitialLevel - 3 * kClippedLevelStep);
   1879  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
   1880            kInitialLevel - kClippedLevelStep);
   1881 
   1882  // Expect no change during waiting.
   1883  CallPreProcessAudioBuffer(kClippedWaitFrames, kClippingPeakRatio,
   1884                            manager_with_prediction);
   1885  CallPreProcessAudioBuffer(kClippedWaitFrames, kClippingPeakRatio,
   1886                            manager_without_prediction);
   1887  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
   1888            kInitialLevel - 3 * kClippedLevelStep);
   1889  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
   1890            kInitialLevel - kClippedLevelStep);
   1891 
   1892  // Expect a change for clipping frames.
   1893  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
   1894                            manager_with_prediction);
   1895  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
   1896                            manager_without_prediction);
   1897  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
   1898            kInitialLevel - 4 * kClippedLevelStep);
   1899  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
   1900            kInitialLevel - 2 * kClippedLevelStep);
   1901 }
   1902 
   1903 TEST_P(AgcManagerDirectParametrizedTest,
   1904       UnusedClippingPredictionsProduceEqualAnalogLevels) {
   1905  AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
   1906                           kNumChannels, kSampleRateHz, kNumChannels);
   1907 
   1908  AnalogAgcConfig config_with_prediction = GetAnalogAgcTestConfig();
   1909  config_with_prediction.clipping_predictor.enabled = true;
   1910  config_with_prediction.clipping_predictor.use_predicted_step = false;
   1911  AnalogAgcConfig config_without_prediction = GetAnalogAgcTestConfig();
   1912  config_without_prediction.clipping_predictor.enabled = false;
   1913  AgcManagerDirect manager_with_prediction(env_, config_with_prediction,
   1914                                           new ::testing::NiceMock<MockAgc>());
   1915  AgcManagerDirect manager_without_prediction(
   1916      env_, config_without_prediction, new ::testing::NiceMock<MockAgc>());
   1917 
   1918  constexpr int kInitialLevel = 255;
   1919  constexpr float kClippingPeakRatio = 1.0f;
   1920  constexpr float kCloseToClippingPeakRatio = 0.99f;
   1921  constexpr float kZeroPeakRatio = 0.0f;
   1922  manager_with_prediction.Initialize();
   1923  manager_without_prediction.Initialize();
   1924  manager_with_prediction.set_stream_analog_level(kInitialLevel);
   1925  manager_without_prediction.set_stream_analog_level(kInitialLevel);
   1926  manager_with_prediction.Process(audio_buffer,
   1927                                  GetOverrideOrEmpty(kHighSpeechProbability),
   1928                                  GetOverrideOrEmpty(kSpeechLevelDbfs));
   1929  manager_without_prediction.Process(audio_buffer,
   1930                                     GetOverrideOrEmpty(kHighSpeechProbability),
   1931                                     GetOverrideOrEmpty(kSpeechLevelDbfs));
   1932 
   1933  EXPECT_TRUE(manager_with_prediction.clipping_predictor_enabled());
   1934  EXPECT_FALSE(manager_without_prediction.clipping_predictor_enabled());
   1935  EXPECT_FALSE(manager_with_prediction.use_clipping_predictor_step());
   1936  EXPECT_EQ(manager_with_prediction.recommended_analog_level(), kInitialLevel);
   1937  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
   1938            kInitialLevel);
   1939 
   1940  // Expect no change in the analog level for non-clipping frames.
   1941  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
   1942                            manager_with_prediction);
   1943  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
   1944                            manager_without_prediction);
   1945  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
   1946            manager_without_prediction.recommended_analog_level());
   1947 
   1948  // Expect no change for non-clipping frames.
   1949  CallPreProcessAudioBuffer(kClippedWaitFrames, kCloseToClippingPeakRatio,
   1950                            manager_with_prediction);
   1951  CallPreProcessAudioBuffer(kClippedWaitFrames, kCloseToClippingPeakRatio,
   1952                            manager_without_prediction);
   1953  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
   1954            manager_without_prediction.recommended_analog_level());
   1955 
   1956  // Expect no change for non-clipping frames.
   1957  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
   1958                            manager_with_prediction);
   1959  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
   1960                            manager_without_prediction);
   1961  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
   1962            manager_without_prediction.recommended_analog_level());
   1963 
   1964  // Expect no change when clipping is not detected or predicted.
   1965  CallPreProcessAudioBuffer(2 * kClippedWaitFrames, kZeroPeakRatio,
   1966                            manager_with_prediction);
   1967  CallPreProcessAudioBuffer(2 * kClippedWaitFrames, kZeroPeakRatio,
   1968                            manager_without_prediction);
   1969  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
   1970            manager_without_prediction.recommended_analog_level());
   1971 
   1972  // Expect a change for clipping frames.
   1973  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
   1974                            manager_with_prediction);
   1975  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
   1976                            manager_without_prediction);
   1977  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
   1978            manager_without_prediction.recommended_analog_level());
   1979 
   1980  // Expect no change during waiting.
   1981  CallPreProcessAudioBuffer(kClippedWaitFrames, kClippingPeakRatio,
   1982                            manager_with_prediction);
   1983  CallPreProcessAudioBuffer(kClippedWaitFrames, kClippingPeakRatio,
   1984                            manager_without_prediction);
   1985  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
   1986            manager_without_prediction.recommended_analog_level());
   1987 
   1988  // Expect a change for clipping frames.
   1989  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
   1990                            manager_with_prediction);
   1991  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
   1992                            manager_without_prediction);
   1993  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
   1994            manager_without_prediction.recommended_analog_level());
   1995 }
   1996 
   1997 // Checks that passing an empty speech level and probability overrides to
   1998 // `Process()` has the same effect as passing no overrides.
   1999 TEST_P(AgcManagerDirectParametrizedTest, EmptyRmsErrorOverrideHasNoEffect) {
   2000  AgcManagerDirect manager_1(env_, kNumChannels, GetAnalogAgcTestConfig());
   2001  AgcManagerDirect manager_2(env_, kNumChannels, GetAnalogAgcTestConfig());
   2002  manager_1.Initialize();
   2003  manager_2.Initialize();
   2004 
   2005  constexpr int kAnalogLevel = 50;
   2006  manager_1.set_stream_analog_level(kAnalogLevel);
   2007  manager_2.set_stream_analog_level(kAnalogLevel);
   2008 
   2009  // Feed speech with low energy to trigger an upward adapation of the analog
   2010  // level.
   2011  constexpr int kNumFrames = 125;
   2012  constexpr int kGainDb = -20;
   2013  SpeechSamplesReader reader;
   2014 
   2015  // Check the initial input volume.
   2016  ASSERT_EQ(manager_1.recommended_analog_level(), kAnalogLevel);
   2017  ASSERT_EQ(manager_2.recommended_analog_level(), kAnalogLevel);
   2018 
   2019  reader.Feed(kNumFrames, kGainDb, std::nullopt, std::nullopt, manager_1);
   2020  reader.Feed(kNumFrames, kGainDb, manager_2);
   2021 
   2022  // Check that the states are the same and adaptation occurs.
   2023  EXPECT_EQ(manager_1.recommended_analog_level(),
   2024            manager_2.recommended_analog_level());
   2025  ASSERT_GT(manager_1.recommended_analog_level(), kAnalogLevel);
   2026  EXPECT_EQ(manager_1.voice_probability(), manager_2.voice_probability());
   2027  EXPECT_EQ(manager_1.frames_since_clipped_, manager_2.frames_since_clipped_);
   2028 
   2029  // Check that the states of the channel AGCs are the same.
   2030  EXPECT_EQ(manager_1.num_channels(), manager_2.num_channels());
   2031  for (int i = 0; i < manager_1.num_channels(); ++i) {
   2032    EXPECT_EQ(manager_1.channel_agcs_[i]->recommended_analog_level(),
   2033              manager_2.channel_agcs_[i]->recommended_analog_level());
   2034    EXPECT_EQ(manager_1.channel_agcs_[i]->voice_probability(),
   2035              manager_2.channel_agcs_[i]->voice_probability());
   2036  }
   2037 }
   2038 
   2039 // Checks that passing a non-empty speech level and probability overrides to
   2040 // `Process()` has an effect.
   2041 TEST_P(AgcManagerDirectParametrizedTest, NonEmptyRmsErrorOverrideHasEffect) {
   2042  AgcManagerDirect manager_1(env_, kNumChannels, GetAnalogAgcTestConfig());
   2043  AgcManagerDirect manager_2(env_, kNumChannels, GetAnalogAgcTestConfig());
   2044  manager_1.Initialize();
   2045  manager_2.Initialize();
   2046 
   2047  constexpr int kInputVolume = 128;
   2048  manager_1.set_stream_analog_level(kInputVolume);
   2049  manager_2.set_stream_analog_level(kInputVolume);
   2050 
   2051  // Feed speech with low energy to trigger an upward adapation of the input
   2052  // volume.
   2053  constexpr int kNumFrames = 125;
   2054  constexpr int kGainDb = -20;
   2055  SpeechSamplesReader reader;
   2056 
   2057  // Make sure that the feeding samples triggers an adaptation when no override
   2058  // is specified.
   2059  reader.Feed(kNumFrames, kGainDb, manager_1);
   2060  ASSERT_GT(manager_1.recommended_analog_level(), kInputVolume);
   2061 
   2062  // Expect that feeding samples triggers an adaptation when the speech
   2063  // probability and speech level overrides are specified.
   2064  reader.Feed(kNumFrames, kGainDb,
   2065              /*speech_probability_override=*/kHighSpeechProbability,
   2066              /*speech_level_override=*/-45.0f, manager_2);
   2067  EXPECT_GT(manager_2.recommended_analog_level(), kInputVolume);
   2068 
   2069  // The voice probability override does not affect the `voice_probability()`
   2070  // getter.
   2071  EXPECT_EQ(manager_1.voice_probability(), manager_2.voice_probability());
   2072 }
   2073 
   2074 class AgcManagerDirectChannelSampleRateTest
   2075    : public ::testing::TestWithParam<std::tuple<int, int>> {
   2076 protected:
   2077  int GetNumChannels() const { return std::get<0>(GetParam()); }
   2078  int GetSampleRateHz() const { return std::get<1>(GetParam()); }
   2079 };
   2080 
   2081 TEST_P(AgcManagerDirectChannelSampleRateTest, CheckIsAlive) {
   2082  const int num_channels = GetNumChannels();
   2083  const int sample_rate_hz = GetSampleRateHz();
   2084 
   2085  constexpr AnalogAgcConfig kConfig{.enabled = true,
   2086                                    .clipping_predictor{.enabled = true}};
   2087  AgcManagerDirect manager(CreateEnvironment(), num_channels, kConfig);
   2088  manager.Initialize();
   2089  AudioBuffer buffer(sample_rate_hz, num_channels, sample_rate_hz, num_channels,
   2090                     sample_rate_hz, num_channels);
   2091 
   2092  constexpr int kStartupVolume = 100;
   2093  int applied_initial_volume = kStartupVolume;
   2094 
   2095  // Trigger a downward adaptation with clipping.
   2096  WriteAudioBufferSamples(/*samples_value=*/0.0f, /*clipped_ratio=*/0.5f,
   2097                          buffer);
   2098  const int initial_volume1 = applied_initial_volume;
   2099  for (int i = 0; i < 400; ++i) {
   2100    manager.set_stream_analog_level(applied_initial_volume);
   2101    manager.AnalyzePreProcess(buffer);
   2102    manager.Process(buffer, kLowSpeechProbability,
   2103                    /*speech_level_dbfs=*/-20.0f);
   2104    applied_initial_volume = manager.recommended_analog_level();
   2105  }
   2106  ASSERT_LT(manager.recommended_analog_level(), initial_volume1);
   2107 
   2108  // Fill in audio that does not clip.
   2109  WriteAudioBufferSamples(/*samples_value=*/1234.5f, /*clipped_ratio=*/0.0f,
   2110                          buffer);
   2111 
   2112  // Trigger an upward adaptation.
   2113  const int initial_volume2 = manager.recommended_analog_level();
   2114  for (int i = 0; i < kConfig.clipped_wait_frames; ++i) {
   2115    manager.set_stream_analog_level(applied_initial_volume);
   2116    manager.AnalyzePreProcess(buffer);
   2117    manager.Process(buffer, kHighSpeechProbability,
   2118                    /*speech_level_dbfs=*/-65.0f);
   2119    applied_initial_volume = manager.recommended_analog_level();
   2120  }
   2121  EXPECT_GT(manager.recommended_analog_level(), initial_volume2);
   2122 
   2123  // Trigger a downward adaptation.
   2124  const int initial_volume = manager.recommended_analog_level();
   2125  for (int i = 0; i < 100; ++i) {
   2126    manager.set_stream_analog_level(applied_initial_volume);
   2127    manager.AnalyzePreProcess(buffer);
   2128    manager.Process(buffer, kHighSpeechProbability,
   2129                    /*speech_level_dbfs=*/-5.0f);
   2130    applied_initial_volume = manager.recommended_analog_level();
   2131  }
   2132  EXPECT_LT(manager.recommended_analog_level(), initial_volume);
   2133 }
   2134 
   2135 INSTANTIATE_TEST_SUITE_P(
   2136    ,
   2137    AgcManagerDirectChannelSampleRateTest,
   2138    ::testing::Combine(::testing::Values(1, 2, 3, 6),
   2139                       ::testing::Values(8000, 16000, 32000, 48000)));
   2140 
   2141 }  // namespace webrtc