/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/audio_processing/agc2/input_volume_controller.h"

#include <algorithm>
#include <fstream>
#include <limits>
#include <string>
#include <tuple>
#include <vector>

#include "rtc_base/numerics/safe_minmax.h"
#include "rtc_base/strings/string_builder.h"
#include "test/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

using ::testing::_;
using ::testing::AtLeast;
using ::testing::DoAll;
using ::testing::Return;
using ::testing::SetArgPointee;

namespace webrtc {
namespace {

constexpr int kSampleRateHz = 32000;
constexpr int kNumChannels = 1;
constexpr int kInitialInputVolume = 128;
constexpr int kClippedMin = 165;  // Arbitrary, but different from the default.
constexpr float kAboveClippedThreshold = 0.2f;
constexpr int kMinMicLevel = 12;
constexpr int kClippedLevelStep = 15;
constexpr float kClippedRatioThreshold = 0.1f;
constexpr int kClippedWaitFrames = 300;
constexpr float kHighSpeechProbability = 0.7f;
constexpr float kSpeechLevel = -25.0f;

constexpr float kMinSample = std::numeric_limits<int16_t>::min();
constexpr float kMaxSample = std::numeric_limits<int16_t>::max();

using ClippingPredictorConfig = AudioProcessing::Config::GainController1::
    AnalogGainController::ClippingPredictor;

using InputVolumeControllerConfig = InputVolumeController::Config;

constexpr InputVolumeControllerConfig kDefaultInputVolumeControllerConfig{};
constexpr ClippingPredictorConfig kDefaultClippingPredictorConfig{};

std::unique_ptr<InputVolumeController> CreateInputVolumeController(
    int startup_min_volume,
    int clipped_level_step,
    float clipped_ratio_threshold,
    int clipped_wait_frames,
    bool enable_clipping_predictor = false) {
  InputVolumeControllerConfig config{
      .enabled = true,
      .startup_min_volume = startup_min_volume,
      .clipped_level_min = kClippedMin,
      .clipped_level_step = clipped_level_step,
      .clipped_ratio_threshold = clipped_ratio_threshold,
      .clipped_wait_frames = clipped_wait_frames,
      .enable_clipping_predictor = enable_clipping_predictor,
      .target_range_max_dbfs = -18,
      .target_range_min_dbfs = -30,
  };

  return std::make_unique<InputVolumeController>(/*num_capture_channels=*/1,
                                                 config);
}

// Deprecated.
// TODO(bugs.webrtc.org/7494): Delete this helper, use
// `InputVolumeControllerTestHelper::CallAgcSequence()` instead.
// Calls `AnalyzePreProcess()` on `manager` `num_calls` times. `peak_ratio` is a
// value in [0, 1] which determines the amplitude of the samples (1 maps to full
// scale). The first half of the calls is made on frames which are half filled
// with zeros in order to simulate a signal with different crest factors.
void CallPreProcessAudioBuffer(int num_calls,
                               float peak_ratio,
                               InputVolumeController& manager) {
  RTC_DCHECK_LE(peak_ratio, 1.0f);
  AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
                           kNumChannels, kSampleRateHz, kNumChannels);
  const int num_channels = audio_buffer.num_channels();
  const int num_frames = audio_buffer.num_frames();

  // Make half of the calls with half zeroed frames.
  for (int ch = 0; ch < num_channels; ++ch) {
    // 50% of the samples in one frame are zero.
    for (int i = 0; i < num_frames; i += 2) {
      audio_buffer.channels()[ch][i] = peak_ratio * 32767.0f;
      audio_buffer.channels()[ch][i + 1] = 0.0f;
    }
  }
  for (int n = 0; n < num_calls / 2; ++n) {
    manager.AnalyzePreProcess(audio_buffer);
  }

  // Make the remaining half of the calls with frames whose samples are all set.
  for (int ch = 0; ch < num_channels; ++ch) {
    for (int i = 0; i < num_frames; ++i) {
      audio_buffer.channels()[ch][i] = peak_ratio * 32767.0f;
    }
  }
  for (int n = 0; n < num_calls - num_calls / 2; ++n) {
    manager.AnalyzePreProcess(audio_buffer);
  }
}

constexpr char kMinMicLevelFieldTrial[] =
    "WebRTC-Audio-2ndAgcMinMicLevelExperiment";

std::string GetAgcMinMicLevelExperimentFieldTrial(const std::string& value) {
  char field_trial_buffer[64];
  rtc::SimpleStringBuilder builder(field_trial_buffer);
  builder << kMinMicLevelFieldTrial << "/" << value << "/";
  return builder.str();
}

std::string GetAgcMinMicLevelExperimentFieldTrialEnabled(
    int enabled_value,
    const std::string& suffix = "") {
  RTC_DCHECK_GE(enabled_value, 0);
  RTC_DCHECK_LE(enabled_value, 255);
  char field_trial_buffer[64];
  rtc::SimpleStringBuilder builder(field_trial_buffer);
  builder << kMinMicLevelFieldTrial << "/Enabled-" << enabled_value << suffix
          << "/";
  return builder.str();
}

std::string GetAgcMinMicLevelExperimentFieldTrial(
    absl::optional<int> min_mic_level) {
  if (min_mic_level.has_value()) {
    return GetAgcMinMicLevelExperimentFieldTrialEnabled(*min_mic_level);
  }
  return GetAgcMinMicLevelExperimentFieldTrial("Disabled");
}

// (Over)writes `samples_value` for the samples in `audio_buffer`.
// When `clipped_ratio`, a value in [0, 1], is greater than 0, the corresponding
// fraction of the frame is set to a full scale value to simulate clipping.
void WriteAudioBufferSamples(float samples_value,
                             float clipped_ratio,
                             AudioBuffer& audio_buffer) {
  RTC_DCHECK_GE(samples_value, kMinSample);
  RTC_DCHECK_LE(samples_value, kMaxSample);
  RTC_DCHECK_GE(clipped_ratio, 0.0f);
  RTC_DCHECK_LE(clipped_ratio, 1.0f);
  int num_channels = audio_buffer.num_channels();
  int num_samples = audio_buffer.num_frames();
  int num_clipping_samples = clipped_ratio * num_samples;
  for (int ch = 0; ch < num_channels; ++ch) {
    int i = 0;
    for (; i < num_clipping_samples; ++i) {
      audio_buffer.channels()[ch][i] = 32767.0f;
    }
    for (; i < num_samples; ++i) {
      audio_buffer.channels()[ch][i] = samples_value;
    }
  }
}

// Deprecated.
// TODO(bugs.webrtc.org/7494): Delete this helper, use
// `InputVolumeControllerTestHelper::CallAgcSequence()` instead.
void CallPreProcessAndProcess(int num_calls,
                              const AudioBuffer& audio_buffer,
                              absl::optional<float> speech_probability,
                              absl::optional<float> speech_level,
                              InputVolumeController& manager) {
  for (int n = 0; n < num_calls; ++n) {
    manager.AnalyzePreProcess(audio_buffer);
    manager.Process(speech_probability, speech_level);
  }
}

// Reads a given number of 10 ms chunks from a PCM file and feeds them to
// `InputVolumeController`.
class SpeechSamplesReader {
 private:
  // Recording properties.
  static constexpr int kPcmSampleRateHz = 16000;
  static constexpr int kPcmNumChannels = 1;
  static constexpr int kPcmBytesPerSamples = sizeof(int16_t);

 public:
  SpeechSamplesReader()
      : is_(test::ResourcePath("audio_processing/agc/agc_audio", "pcm"),
            std::ios::binary | std::ios::ate),
        audio_buffer_(kPcmSampleRateHz,
                      kPcmNumChannels,
                      kPcmSampleRateHz,
                      kPcmNumChannels,
                      kPcmSampleRateHz,
                      kPcmNumChannels),
        buffer_(audio_buffer_.num_frames()),
        buffer_num_bytes_(buffer_.size() * kPcmBytesPerSamples) {
    RTC_CHECK(is_);
  }

  // Reads `num_frames` 10 ms frames from the beginning of the PCM file, applies
  // `gain_db` and feeds the frames into `agc` by calling `AnalyzePreProcess()`
  // and `Process()` for each frame. Reads the number of 10 ms frames available
  // in the PCM file if `num_frames` is too large - i.e., does not loop.
  // `speech_probability` and `speech_level` are passed to
  // `Process()`.
  void Feed(int num_frames,
            int gain_db,
            absl::optional<float> speech_probability,
            absl::optional<float> speech_level,
            InputVolumeController& agc) {
    float gain = std::pow(10.0f, gain_db / 20.0f);  // From dB to linear gain.
    is_.seekg(0, is_.beg);  // Start from the beginning of the PCM file.

    // Read and feed frames.
    for (int i = 0; i < num_frames; ++i) {
      is_.read(reinterpret_cast<char*>(buffer_.data()), buffer_num_bytes_);
      if (is_.gcount() < buffer_num_bytes_) {
        // EOF reached. Stop.
        break;
      }
      // Apply gain and copy samples into `audio_buffer_`.
      std::transform(buffer_.begin(), buffer_.end(),
                     audio_buffer_.channels()[0], [gain](int16_t v) -> float {
                       return rtc::SafeClamp(static_cast<float>(v) * gain,
                                             kMinSample, kMaxSample);
                     });

      agc.AnalyzePreProcess(audio_buffer_);
      agc.Process(speech_probability, speech_level);
    }
  }

 private:
  std::ifstream is_;
  AudioBuffer audio_buffer_;
  std::vector<int16_t> buffer_;
  const std::streamsize buffer_num_bytes_;
};

}  // namespace

// TODO(bugs.webrtc.org/12874): Use constexpr struct with designated
// initializers once fixed.
constexpr InputVolumeControllerConfig GetInputVolumeControllerTestConfig() {
  InputVolumeControllerConfig config{
      .enabled = true,
      .startup_min_volume = kInitialInputVolume,
      .clipped_level_min = kClippedMin,
      .clipped_level_step = kClippedLevelStep,
      .clipped_ratio_threshold = kClippedRatioThreshold,
      .clipped_wait_frames = kClippedWaitFrames,
      .enable_clipping_predictor = kDefaultClippingPredictorConfig.enabled,
      .target_range_max_dbfs = -18,
      .target_range_min_dbfs = -30,
  };
  return config;
}

constexpr InputVolumeControllerConfig GetDisabledInputVolumeControllerConfig() {
  InputVolumeControllerConfig config = GetInputVolumeControllerTestConfig();
  config.enabled = false;
  return config;
}

// Helper class that provides an `InputVolumeController` instance with an
// `AudioBuffer` instance and `CallAgcSequence()`, a helper method that runs the
// `InputVolumeController` instance on the `AudioBuffer` one by sticking to the
// API contract.
class InputVolumeControllerTestHelper {
 public:
  // Ctor. Initializes `audio_buffer` with zeros.
  InputVolumeControllerTestHelper()
      : audio_buffer(kSampleRateHz,
                     kNumChannels,
                     kSampleRateHz,
                     kNumChannels,
                     kSampleRateHz,
                     kNumChannels),
        manager(/*num_capture_channels=*/1,
                GetInputVolumeControllerTestConfig()) {
    manager.Initialize();
    WriteAudioBufferSamples(/*samples_value=*/0.0f, /*clipped_ratio=*/0.0f,
                            audio_buffer);
  }

  // Calls the sequence of `InputVolumeController` methods according to the API
  // contract, namely:
  // - Sets the applied input volume;
  // - Uses `audio_buffer` to call `AnalyzePreProcess()` and `Process()`;
  //  Returns the recommended input volume.
  int CallAgcSequence(int applied_input_volume,
                      absl::optional<float> speech_probability,
                      absl::optional<float> speech_level) {
    manager.set_stream_analog_level(applied_input_volume);
    manager.AnalyzePreProcess(audio_buffer);
    manager.Process(speech_probability, speech_level);

    return manager.recommended_analog_level();
  }

  // Deprecated.
  // TODO(bugs.webrtc.org/7494): Let the caller write `audio_buffer` and use
  // `CallAgcSequence()`.
  void CallProcess(int num_calls,
                   absl::optional<float> speech_probability,
                   absl::optional<float> speech_level) {
    for (int i = 0; i < num_calls; ++i) {
      manager.Process(speech_probability, speech_level);
    }
  }

  // Deprecated.
  // TODO(bugs.webrtc.org/7494): Let the caller write `audio_buffer` and use
  // `CallAgcSequence()`.
  void CallPreProc(int num_calls, float clipped_ratio) {
    RTC_DCHECK_GE(clipped_ratio, 0.0f);
    RTC_DCHECK_LE(clipped_ratio, 1.0f);
    WriteAudioBufferSamples(/*samples_value=*/0.0f, clipped_ratio,
                            audio_buffer);
    for (int i = 0; i < num_calls; ++i) {
      manager.AnalyzePreProcess(audio_buffer);
    }
  }

  // Deprecated.
  // TODO(bugs.webrtc.org/7494): Let the caller write `audio_buffer` and use
  // `CallAgcSequence()`.
  void CallPreProcForChangingAudio(int num_calls, float peak_ratio) {
    RTC_DCHECK_GE(peak_ratio, 0.0f);
    RTC_DCHECK_LE(peak_ratio, 1.0f);
    const float samples_value = peak_ratio * 32767.0f;

    // Make half of the calls on a frame where the samples alternate
    // `sample_values` and zeros.
    WriteAudioBufferSamples(samples_value, /*clipped_ratio=*/0.0f,
                            audio_buffer);
    for (size_t ch = 0; ch < audio_buffer.num_channels(); ++ch) {
      for (size_t k = 1; k < audio_buffer.num_frames(); k += 2) {
        audio_buffer.channels()[ch][k] = 0.0f;
      }
    }
    for (int i = 0; i < num_calls / 2; ++i) {
      manager.AnalyzePreProcess(audio_buffer);
    }

    // Make half of thecalls on a frame where all the samples equal
    // `sample_values`.
    WriteAudioBufferSamples(samples_value, /*clipped_ratio=*/0.0f,
                            audio_buffer);
    for (int i = 0; i < num_calls - num_calls / 2; ++i) {
      manager.AnalyzePreProcess(audio_buffer);
    }
  }

  AudioBuffer audio_buffer;
  InputVolumeController manager;
};

class InputVolumeControllerParametrizedTest
    : public ::testing::TestWithParam<std::tuple<absl::optional<int>, bool>> {
 protected:
  InputVolumeControllerParametrizedTest()
      : field_trials_(
            GetAgcMinMicLevelExperimentFieldTrial(std::get<0>(GetParam()))) {}

  bool IsMinMicLevelOverridden() const {
    return std::get<0>(GetParam()).has_value();
  }
  int GetMinMicLevel() const {
    return std::get<0>(GetParam()).value_or(kMinMicLevel);
  }

  bool RmsErrorHasValue() const { return std::get<1>(GetParam()); }
  absl::optional<float> GetValueOrEmpty(float value) const {
    return RmsErrorHasValue() ? absl::optional<float>(value) : absl::nullopt;
  }

 private:
  test::ScopedFieldTrials field_trials_;
};

INSTANTIATE_TEST_SUITE_P(
    ,
    InputVolumeControllerParametrizedTest,
    ::testing::Combine(testing::Values(absl::nullopt, 12, 20),
                       testing::Values(true)));

// Checks that when the analog controller is disabled, no downward adaptation
// takes place.
// TODO(webrtc:7494): Revisit the test after moving the number of update wait
// frames to AMP config. The test passes but internally the gain update timing
// differs.
TEST_P(InputVolumeControllerParametrizedTest,
       DisabledAnalogAgcDoesNotAdaptDownwards) {
  InputVolumeController manager_no_analog_agc(
      kNumChannels, GetDisabledInputVolumeControllerConfig());
  manager_no_analog_agc.Initialize();
  InputVolumeController manager_with_analog_agc(
      kNumChannels, GetInputVolumeControllerTestConfig());
  manager_with_analog_agc.Initialize();

  AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
                           kNumChannels, kSampleRateHz, kNumChannels);

  constexpr int kInputVolume = 250;
  static_assert(kInputVolume > kInitialInputVolume, "Increase `kInputVolume`.");
  manager_no_analog_agc.set_stream_analog_level(kInputVolume);
  manager_with_analog_agc.set_stream_analog_level(kInputVolume);

  // Make a first call with input that doesn't clip in order to let the
  // controller read the input volume. That is needed because clipping input
  // causes the controller to stay in idle state for
  // `InputVolumeControllerConfig::clipped_wait_frames` frames.
  WriteAudioBufferSamples(/*samples_value=*/0.0f, /*clipping_ratio=*/0.0f,
                          audio_buffer);
  manager_no_analog_agc.AnalyzePreProcess(audio_buffer);
  manager_with_analog_agc.AnalyzePreProcess(audio_buffer);
  manager_no_analog_agc.Process(GetValueOrEmpty(kHighSpeechProbability),
                                GetValueOrEmpty(-18.0f));
  manager_with_analog_agc.Process(GetValueOrEmpty(kHighSpeechProbability),
                                  GetValueOrEmpty(-18.0f));

  // Feed clipping input to trigger a downward adapation of the analog level.
  WriteAudioBufferSamples(/*samples_value=*/0.0f, /*clipping_ratio=*/0.2f,
                          audio_buffer);
  manager_no_analog_agc.AnalyzePreProcess(audio_buffer);
  manager_with_analog_agc.AnalyzePreProcess(audio_buffer);
  manager_no_analog_agc.Process(GetValueOrEmpty(kHighSpeechProbability),
                                GetValueOrEmpty(-10.0f));
  manager_with_analog_agc.Process(GetValueOrEmpty(kHighSpeechProbability),
                                  GetValueOrEmpty(-10.0f));

  // Check that no adaptation occurs when the analog controller is disabled
  // and make sure that the test triggers a downward adaptation otherwise.
  EXPECT_EQ(manager_no_analog_agc.recommended_analog_level(), kInputVolume);
  ASSERT_LT(manager_with_analog_agc.recommended_analog_level(), kInputVolume);
}

// Checks that when the analog controller is disabled, no upward adaptation
// takes place.
// TODO(webrtc:7494): Revisit the test after moving the number of update wait
// frames to APM config. The test passes but internally the gain update timing
// differs.
TEST_P(InputVolumeControllerParametrizedTest,
       DisabledAnalogAgcDoesNotAdaptUpwards) {
  InputVolumeController manager_no_analog_agc(
      kNumChannels, GetDisabledInputVolumeControllerConfig());
  manager_no_analog_agc.Initialize();
  InputVolumeController manager_with_analog_agc(
      kNumChannels, GetInputVolumeControllerTestConfig());
  manager_with_analog_agc.Initialize();

  constexpr int kInputVolume = kInitialInputVolume;
  manager_no_analog_agc.set_stream_analog_level(kInputVolume);
  manager_with_analog_agc.set_stream_analog_level(kInputVolume);

  // Feed speech with low energy to trigger an upward adapation of the analog
  // level.
  constexpr int kNumFrames = 125;
  constexpr int kGainDb = -20;
  SpeechSamplesReader reader;
  reader.Feed(kNumFrames, kGainDb, GetValueOrEmpty(kHighSpeechProbability),
              GetValueOrEmpty(-42.0f), manager_no_analog_agc);
  reader.Feed(kNumFrames, kGainDb, GetValueOrEmpty(kHighSpeechProbability),
              GetValueOrEmpty(-42.0f), manager_with_analog_agc);

  // Check that no adaptation occurs when the analog controller is disabled
  // and make sure that the test triggers an upward adaptation otherwise.
  EXPECT_EQ(manager_no_analog_agc.recommended_analog_level(), kInputVolume);
  ASSERT_GT(manager_with_analog_agc.recommended_analog_level(), kInputVolume);
}

TEST_P(InputVolumeControllerParametrizedTest,
       StartupMinVolumeConfigurationIsRespected) {
  InputVolumeControllerTestHelper helper;

  helper.CallAgcSequence(kInitialInputVolume,
                         GetValueOrEmpty(kHighSpeechProbability),
                         GetValueOrEmpty(kSpeechLevel));

  EXPECT_EQ(kInitialInputVolume, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest, MicVolumeResponseToRmsError) {
  const auto speech_probability = GetValueOrEmpty(kHighSpeechProbability);

  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(kInitialInputVolume, speech_probability,
                         GetValueOrEmpty(kSpeechLevel));

  // Inside the digital gain's window; no change of volume.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-23.0f));

  // Inside the digital gain's window; no change of volume.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-28.0f));

  // Above the digital gain's  window; volume should be increased.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-29.0f));
  EXPECT_EQ(128, helper.manager.recommended_analog_level());

  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-38.0f));
  EXPECT_EQ(156, helper.manager.recommended_analog_level());

  // Inside the digital gain's window; no change of volume.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-23.0f));
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-18.0f));

  // Below the digial gain's window; volume should be decreased.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-17.0f));
  EXPECT_EQ(155, helper.manager.recommended_analog_level());

  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-17.0f));
  EXPECT_EQ(151, helper.manager.recommended_analog_level());

  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-9.0f));
  EXPECT_EQ(119, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest, MicVolumeIsLimited) {
  const auto speech_probability = GetValueOrEmpty(kHighSpeechProbability);

  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(kInitialInputVolume, speech_probability,
                         GetValueOrEmpty(kSpeechLevel));

  // Maximum upwards change is limited.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-48.0f));
  EXPECT_EQ(183, helper.manager.recommended_analog_level());

  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-48.0f));
  EXPECT_EQ(243, helper.manager.recommended_analog_level());

  // Won't go higher than the maximum.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-48.0f));
  EXPECT_EQ(255, helper.manager.recommended_analog_level());

  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-17.0f));
  EXPECT_EQ(254, helper.manager.recommended_analog_level());

  // Maximum downwards change is limited.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(22.0f));
  EXPECT_EQ(194, helper.manager.recommended_analog_level());

  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(22.0f));
  EXPECT_EQ(137, helper.manager.recommended_analog_level());

  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(22.0f));
  EXPECT_EQ(88, helper.manager.recommended_analog_level());

  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(22.0f));
  EXPECT_EQ(54, helper.manager.recommended_analog_level());

  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(22.0f));
  EXPECT_EQ(33, helper.manager.recommended_analog_level());

  // Won't go lower than the minimum.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(22.0f));
  EXPECT_EQ(std::max(18, GetMinMicLevel()),
            helper.manager.recommended_analog_level());

  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(22.0f));
  EXPECT_EQ(std::max(12, GetMinMicLevel()),
            helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest, NoActionWhileMuted) {
  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(kInitialInputVolume,
                         GetValueOrEmpty(kHighSpeechProbability),
                         GetValueOrEmpty(kSpeechLevel));

  helper.manager.HandleCaptureOutputUsedChange(false);
  helper.manager.Process(GetValueOrEmpty(kHighSpeechProbability),
                         GetValueOrEmpty(kSpeechLevel));
}

TEST_P(InputVolumeControllerParametrizedTest,
       UnmutingChecksVolumeWithoutRaising) {
  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(kInitialInputVolume,
                         GetValueOrEmpty(kHighSpeechProbability),
                         GetValueOrEmpty(kSpeechLevel));

  helper.manager.HandleCaptureOutputUsedChange(false);
  helper.manager.HandleCaptureOutputUsedChange(true);

  constexpr int kInputVolume = 127;
  helper.manager.set_stream_analog_level(kInputVolume);

  // SetMicVolume should not be called.
  helper.CallProcess(/*num_calls=*/1, GetValueOrEmpty(kHighSpeechProbability),
                     GetValueOrEmpty(kSpeechLevel));
  EXPECT_EQ(127, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest, UnmutingRaisesTooLowVolume) {
  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(kInitialInputVolume,
                         GetValueOrEmpty(kHighSpeechProbability),
                         GetValueOrEmpty(kSpeechLevel));

  helper.manager.HandleCaptureOutputUsedChange(false);
  helper.manager.HandleCaptureOutputUsedChange(true);

  constexpr int kInputVolume = 11;
  helper.manager.set_stream_analog_level(kInputVolume);

  helper.CallProcess(/*num_calls=*/1, GetValueOrEmpty(kHighSpeechProbability),
                     GetValueOrEmpty(kSpeechLevel));
  EXPECT_EQ(GetMinMicLevel(), helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest,
       ManualLevelChangeResultsInNoSetMicCall) {
  const auto speech_probability = GetValueOrEmpty(kHighSpeechProbability);

  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(kInitialInputVolume, speech_probability,
                         GetValueOrEmpty(kSpeechLevel));

  // GetMicVolume returns a value outside of the quantization slack, indicating
  // a manual volume change.
  ASSERT_NE(helper.manager.recommended_analog_level(), 154);
  helper.manager.set_stream_analog_level(154);
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-29.0f));
  EXPECT_EQ(154, helper.manager.recommended_analog_level());

  // Do the same thing, except downwards now.
  helper.manager.set_stream_analog_level(100);
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-17.0f));
  EXPECT_EQ(100, helper.manager.recommended_analog_level());

  // And finally verify the AGC continues working without a manual change.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-17.0f));
  EXPECT_EQ(99, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest,
       RecoveryAfterManualLevelChangeFromMax) {
  const auto speech_probability = GetValueOrEmpty(kHighSpeechProbability);

  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(kInitialInputVolume, speech_probability,
                         GetValueOrEmpty(kSpeechLevel));

  // Force the mic up to max volume. Takes a few steps due to the residual
  // gain limitation.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-48.0f));
  EXPECT_EQ(183, helper.manager.recommended_analog_level());
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-48.0f));
  EXPECT_EQ(243, helper.manager.recommended_analog_level());
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-48.0f));
  EXPECT_EQ(255, helper.manager.recommended_analog_level());

  // Manual change does not result in SetMicVolume call.
  helper.manager.set_stream_analog_level(50);
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-17.0f));
  EXPECT_EQ(50, helper.manager.recommended_analog_level());

  // Continues working as usual afterwards.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-38.0f));

  EXPECT_EQ(65, helper.manager.recommended_analog_level());
}

// Checks that, when the min mic level override is not specified, AGC ramps up
// towards the minimum mic level after the mic level is manually set below the
// minimum gain to enforce.
TEST_P(InputVolumeControllerParametrizedTest,
       RecoveryAfterManualLevelChangeBelowMinWithoutMinMicLevelOverride) {
  if (IsMinMicLevelOverridden()) {
    GTEST_SKIP() << "Skipped. Min mic level overridden.";
  }

  const auto speech_probability = GetValueOrEmpty(kHighSpeechProbability);

  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(kInitialInputVolume, speech_probability,
                         GetValueOrEmpty(kSpeechLevel));

  // Manual change below min, but strictly positive, otherwise AGC won't take
  // any action.
  helper.manager.set_stream_analog_level(1);
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-17.0f));
  EXPECT_EQ(1, helper.manager.recommended_analog_level());

  // Continues working as usual afterwards.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-29.0f));
  EXPECT_EQ(1, helper.manager.recommended_analog_level());

  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-48.0f));
  EXPECT_EQ(10, helper.manager.recommended_analog_level());

  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-38.0f));
  EXPECT_EQ(16, helper.manager.recommended_analog_level());
}

// Checks that, when the min mic level override is specified, AGC immediately
// applies the minimum mic level after the mic level is manually set below the
// minimum gain to enforce.
TEST_P(InputVolumeControllerParametrizedTest,
       RecoveryAfterManualLevelChangeBelowMin) {
  if (!IsMinMicLevelOverridden()) {
    GTEST_SKIP() << "Skipped. Min mic level not overridden.";
  }

  const auto speech_probability = GetValueOrEmpty(kHighSpeechProbability);

  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(kInitialInputVolume, speech_probability,
                         GetValueOrEmpty(kSpeechLevel));

  // Manual change below min, but strictly positive, otherwise
  // AGC won't take any action.
  helper.manager.set_stream_analog_level(1);
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-17.0f));
  EXPECT_EQ(GetMinMicLevel(), helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest, NoClippingHasNoImpact) {
  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(kInitialInputVolume,
                         GetValueOrEmpty(kHighSpeechProbability),
                         GetValueOrEmpty(kSpeechLevel));

  helper.CallPreProc(/*num_calls=*/100, /*clipped_ratio=*/0);
  EXPECT_EQ(128, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest,
       ClippingUnderThresholdHasNoImpact) {
  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(kInitialInputVolume,
                         GetValueOrEmpty(kHighSpeechProbability),
                         GetValueOrEmpty(kSpeechLevel));

  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/0.099);
  EXPECT_EQ(128, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest, ClippingLowersVolume) {
  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(/*applied_input_volume=*/255,
                         GetValueOrEmpty(kHighSpeechProbability),
                         GetValueOrEmpty(kSpeechLevel));

  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/0.2);
  EXPECT_EQ(240, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest,
       WaitingPeriodBetweenClippingChecks) {
  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(/*applied_input_volume=*/255,
                         GetValueOrEmpty(kHighSpeechProbability),
                         GetValueOrEmpty(kSpeechLevel));

  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(240, helper.manager.recommended_analog_level());

  helper.CallPreProc(/*num_calls=*/300,
                     /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(240, helper.manager.recommended_analog_level());

  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(225, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest, ClippingLoweringIsLimited) {
  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(/*applied_input_volume=*/180,
                         GetValueOrEmpty(kHighSpeechProbability),
                         GetValueOrEmpty(kSpeechLevel));

  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(kClippedMin, helper.manager.recommended_analog_level());

  helper.CallPreProc(/*num_calls=*/1000,
                     /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(kClippedMin, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest,
       ClippingMaxIsRespectedWhenEqualToLevel) {
  const auto speech_probability = GetValueOrEmpty(kHighSpeechProbability);

  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(/*applied_input_volume=*/255, speech_probability,
                         GetValueOrEmpty(kSpeechLevel));

  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(240, helper.manager.recommended_analog_level());

  helper.CallProcess(/*num_calls=*/10, speech_probability,
                     GetValueOrEmpty(-48.0f));
  EXPECT_EQ(240, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest,
       ClippingMaxIsRespectedWhenHigherThanLevel) {
  const auto speech_probability = GetValueOrEmpty(kHighSpeechProbability);

  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(/*applied_input_volume=*/200, speech_probability,
                         GetValueOrEmpty(kSpeechLevel));

  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(185, helper.manager.recommended_analog_level());

  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-58.0f));
  EXPECT_EQ(240, helper.manager.recommended_analog_level());
  helper.CallProcess(/*num_calls=*/10, speech_probability,
                     GetValueOrEmpty(-58.0f));
  EXPECT_EQ(240, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest, UserCanRaiseVolumeAfterClipping) {
  const auto speech_probability = GetValueOrEmpty(kHighSpeechProbability);

  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(/*applied_input_volume=*/225, speech_probability,
                         GetValueOrEmpty(kSpeechLevel));

  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(210, helper.manager.recommended_analog_level());

  // User changed the volume.
  helper.manager.set_stream_analog_level(250);
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-32.0f));
  EXPECT_EQ(250, helper.manager.recommended_analog_level());

  // Move down...
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-8.0f));
  EXPECT_EQ(210, helper.manager.recommended_analog_level());
  // And back up to the new max established by the user.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-58.0f));
  EXPECT_EQ(250, helper.manager.recommended_analog_level());
  // Will not move above new maximum.
  helper.CallProcess(/*num_calls=*/1, speech_probability,
                     GetValueOrEmpty(-48.0f));
  EXPECT_EQ(250, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest,
       ClippingDoesNotPullLowVolumeBackUp) {
  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(/*applied_input_volume=*/80,
                         GetValueOrEmpty(kHighSpeechProbability),
                         GetValueOrEmpty(kSpeechLevel));

  int initial_volume = helper.manager.recommended_analog_level();
  helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(initial_volume, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest, TakesNoActionOnZeroMicVolume) {
  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(kInitialInputVolume,
                         GetValueOrEmpty(kHighSpeechProbability),
                         GetValueOrEmpty(kSpeechLevel));

  helper.manager.set_stream_analog_level(0);
  helper.CallProcess(/*num_calls=*/10, GetValueOrEmpty(kHighSpeechProbability),
                     GetValueOrEmpty(-48.0f));
  EXPECT_EQ(0, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest, ClippingDetectionLowersVolume) {
  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(/*applied_input_volume=*/255,
                         GetValueOrEmpty(kHighSpeechProbability),
                         GetValueOrEmpty(kSpeechLevel));

  EXPECT_EQ(255, helper.manager.recommended_analog_level());
  helper.CallPreProcForChangingAudio(/*num_calls=*/100, /*peak_ratio=*/0.99f);
  EXPECT_EQ(255, helper.manager.recommended_analog_level());
  helper.CallPreProcForChangingAudio(/*num_calls=*/100, /*peak_ratio=*/1.0f);
  EXPECT_EQ(240, helper.manager.recommended_analog_level());
}

TEST_P(InputVolumeControllerParametrizedTest,
       DisabledClippingPredictorDoesNotLowerVolume) {
  InputVolumeControllerTestHelper helper;
  helper.CallAgcSequence(/*applied_input_volume=*/255,
                         GetValueOrEmpty(kHighSpeechProbability),
                         GetValueOrEmpty(kSpeechLevel));

  EXPECT_FALSE(helper.manager.clipping_predictor_enabled());
  EXPECT_EQ(255, helper.manager.recommended_analog_level());
  helper.CallPreProcForChangingAudio(/*num_calls=*/100, /*peak_ratio=*/0.99f);
  EXPECT_EQ(255, helper.manager.recommended_analog_level());
  helper.CallPreProcForChangingAudio(/*num_calls=*/100, /*peak_ratio=*/0.99f);
  EXPECT_EQ(255, helper.manager.recommended_analog_level());
}

TEST(InputVolumeControllerTest, AgcMinMicLevelExperimentDefault) {
  std::unique_ptr<InputVolumeController> manager =
      CreateInputVolumeController(kInitialInputVolume, kClippedLevelStep,
                                  kClippedRatioThreshold, kClippedWaitFrames);
  EXPECT_EQ(manager->channel_controllers_[0]->min_mic_level(), kMinMicLevel);
}

TEST(InputVolumeControllerTest, AgcMinMicLevelExperimentDisabled) {
  for (const std::string& field_trial_suffix : {"", "_20220210"}) {
    test::ScopedFieldTrials field_trial(
        GetAgcMinMicLevelExperimentFieldTrial("Disabled" + field_trial_suffix));
    std::unique_ptr<InputVolumeController> manager =
        CreateInputVolumeController(kInitialInputVolume, kClippedLevelStep,
                                    kClippedRatioThreshold, kClippedWaitFrames);

    EXPECT_EQ(manager->channel_controllers_[0]->min_mic_level(), kMinMicLevel);
  }
}

// Checks that a field-trial parameter outside of the valid range [0,255] is
// ignored.
TEST(InputVolumeControllerTest, AgcMinMicLevelExperimentOutOfRangeAbove) {
  test::ScopedFieldTrials field_trial(
      GetAgcMinMicLevelExperimentFieldTrial("Enabled-256"));
  std::unique_ptr<InputVolumeController> manager =
      CreateInputVolumeController(kInitialInputVolume, kClippedLevelStep,
                                  kClippedRatioThreshold, kClippedWaitFrames);
  EXPECT_EQ(manager->channel_controllers_[0]->min_mic_level(), kMinMicLevel);
}

// Checks that a field-trial parameter outside of the valid range [0,255] is
// ignored.
TEST(InputVolumeControllerTest, AgcMinMicLevelExperimentOutOfRangeBelow) {
  test::ScopedFieldTrials field_trial(
      GetAgcMinMicLevelExperimentFieldTrial("Enabled--1"));
  std::unique_ptr<InputVolumeController> manager =
      CreateInputVolumeController(kInitialInputVolume, kClippedLevelStep,
                                  kClippedRatioThreshold, kClippedWaitFrames);
  EXPECT_EQ(manager->channel_controllers_[0]->min_mic_level(), kMinMicLevel);
}

// Verifies that a valid experiment changes the minimum microphone level. The
// start volume is larger than the min level and should therefore not be
// changed.
TEST(InputVolumeControllerTest, AgcMinMicLevelExperimentEnabled50) {
  constexpr int kMinMicLevelOverride = 50;
  for (const std::string& field_trial_suffix : {"", "_20220210"}) {
    SCOPED_TRACE(field_trial_suffix);
    test::ScopedFieldTrials field_trial(
        GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride,
                                                     field_trial_suffix));
    std::unique_ptr<InputVolumeController> manager =
        CreateInputVolumeController(kInitialInputVolume, kClippedLevelStep,
                                    kClippedRatioThreshold, kClippedWaitFrames);

    EXPECT_EQ(manager->channel_controllers_[0]->min_mic_level(),
              kMinMicLevelOverride);
  }
}

// Checks that, when the "WebRTC-Audio-AgcMinMicLevelExperiment" field trial is
// specified with a valid value, the mic level never gets lowered beyond the
// override value in the presence of clipping.
TEST(InputVolumeControllerTest,
     AgcMinMicLevelExperimentCheckMinLevelWithClipping) {
  constexpr int kMinMicLevelOverride = 250;

  // Create and initialize two AGCs by specifying and leaving unspecified the
  // relevant field trial.
  const auto factory = []() {
    std::unique_ptr<InputVolumeController> manager =
        CreateInputVolumeController(kInitialInputVolume, kClippedLevelStep,
                                    kClippedRatioThreshold, kClippedWaitFrames);
    manager->Initialize();
    manager->set_stream_analog_level(kInitialInputVolume);
    return manager;
  };
  std::unique_ptr<InputVolumeController> manager = factory();
  std::unique_ptr<InputVolumeController> manager_with_rms;
  {
    test::ScopedFieldTrials field_trial(
        GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride));
    manager_with_rms = factory();
  }

  // Create a test input signal which containts 80% of clipped samples.
  AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
                           1);
  WriteAudioBufferSamples(/*samples_value=*/4000.0f, /*clipped_ratio=*/0.8f,
                          audio_buffer);

  // Simulate 4 seconds of clipping; it is expected to trigger a downward
  // adjustment of the analog gain.
  CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
                           /*speech_probability=*/absl::nullopt,
                           /*speech_level=*/absl::nullopt, *manager);
  CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
                           /*speech_probability=*/absl::nullopt,
                           /*speech_level=*/absl::nullopt, *manager_with_rms);

  // Make sure that an adaptation occurred.
  ASSERT_GT(manager->recommended_analog_level(), 0);

  // Check that the test signal triggers a larger downward adaptation for
  // `manager`, which is allowed to reach a lower gain.
  EXPECT_GT(manager_with_rms->recommended_analog_level(),
            manager->recommended_analog_level());
  // Check that the gain selected by `manager_with_rms` equals the minimum
  // value overridden via field trial.
  EXPECT_EQ(manager_with_rms->recommended_analog_level(), kMinMicLevelOverride);
}

// Checks that, when the "WebRTC-Audio-AgcMinMicLevelExperiment" field trial is
// specified with a valid value, the mic level never gets lowered beyond the
// override value in the presence of clipping when RMS error is not empty.
// TODO(webrtc:7494): Revisit the test after moving the number of update wait
// frames to APM config. The test passes but internally the gain update timing
// differs.
TEST(InputVolumeControllerTest,
     AgcMinMicLevelExperimentCheckMinLevelWithClippingWithRmsError) {
  constexpr int kMinMicLevelOverride = 250;

  // Create and initialize two AGCs by specifying and leaving unspecified the
  // relevant field trial.
  const auto factory = []() {
    std::unique_ptr<InputVolumeController> manager =
        CreateInputVolumeController(kInitialInputVolume, kClippedLevelStep,
                                    kClippedRatioThreshold, kClippedWaitFrames);
    manager->Initialize();
    manager->set_stream_analog_level(kInitialInputVolume);
    return manager;
  };
  std::unique_ptr<InputVolumeController> manager = factory();
  std::unique_ptr<InputVolumeController> manager_with_rms;
  {
    test::ScopedFieldTrials field_trial(
        GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride));
    manager_with_rms = factory();
  }

  // Create a test input signal which containts 80% of clipped samples.
  AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
                           1);
  WriteAudioBufferSamples(/*samples_value=*/4000.0f, /*clipped_ratio=*/0.8f,
                          audio_buffer);

  // Simulate 4 seconds of clipping; it is expected to trigger a downward
  // adjustment of the analog gain.
  CallPreProcessAndProcess(
      /*num_calls=*/400, audio_buffer,
      /*speech_probability=*/0.7f,
      /*speech_level=*/-18.0f, *manager);
  CallPreProcessAndProcess(
      /*num_calls=*/400, audio_buffer,
      /*speech_probability=*/0.7f,
      /*speech_level=*/-18.0f, *manager_with_rms);

  // Make sure that an adaptation occurred.
  ASSERT_GT(manager->recommended_analog_level(), 0);

  // Check that the test signal triggers a larger downward adaptation for
  // `manager`, which is allowed to reach a lower gain.
  EXPECT_GT(manager_with_rms->recommended_analog_level(),
            manager->recommended_analog_level());
  // Check that the gain selected by `manager_with_rms` equals the minimum
  // value overridden via field trial.
  EXPECT_EQ(manager_with_rms->recommended_analog_level(), kMinMicLevelOverride);
}

// Checks that, when the "WebRTC-Audio-AgcMinMicLevelExperiment" field trial is
// specified with a value lower than the `clipped_level_min`, the behavior of
// the analog gain controller is the same as that obtained when the field trial
// is not specified.
TEST(InputVolumeControllerTest,
     AgcMinMicLevelExperimentCompareMicLevelWithClipping) {
  // Create and initialize two AGCs by specifying and leaving unspecified the
  // relevant field trial.
  const auto factory = []() {
    // Use a large clipped level step to more quickly decrease the analog gain
    // with clipping.
    InputVolumeControllerConfig config = kDefaultInputVolumeControllerConfig;
    config.enabled = true;
    config.startup_min_volume = kInitialInputVolume;
    config.clipped_level_step = 64;
    config.clipped_ratio_threshold = kClippedRatioThreshold;
    config.clipped_wait_frames = kClippedWaitFrames;
    auto controller = std::make_unique<InputVolumeController>(
        /*num_capture_channels=*/1, config);
    controller->Initialize();
    controller->set_stream_analog_level(kInitialInputVolume);
    return controller;
  };
  std::unique_ptr<InputVolumeController> manager = factory();
  std::unique_ptr<InputVolumeController> manager_with_rms;
  {
    constexpr int kMinMicLevelOverride = 20;
    static_assert(kDefaultInputVolumeControllerConfig.clipped_level_min >=
                      kMinMicLevelOverride,
                  "Use a lower override value.");
    test::ScopedFieldTrials field_trial(
        GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride));
    manager_with_rms = factory();
  }

  // Create a test input signal which containts 80% of clipped samples.
  AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
                           1);
  WriteAudioBufferSamples(/*samples_value=*/4000.0f, /*clipped_ratio=*/0.8f,
                          audio_buffer);

  // Simulate 4 seconds of clipping; it is expected to trigger a downward
  // adjustment of the analog gain.
  CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
                           /*speech_probability=*/absl::nullopt,
                           /*speech_level=*/absl::nullopt, *manager);
  CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
                           /*speech_probability=*/absl::nullopt,
                           /*speech_level=*/absl::nullopt, *manager_with_rms);

  // Make sure that an adaptation occurred.
  ASSERT_GT(manager->recommended_analog_level(), 0);

  // Check that the selected analog gain is the same for both controllers and
  // that it equals the minimum level reached when clipping is handled. That is
  // expected because the minimum microphone level override is less than the
  // minimum level used when clipping is detected.
  EXPECT_EQ(manager->recommended_analog_level(),
            manager_with_rms->recommended_analog_level());
  EXPECT_EQ(manager_with_rms->recommended_analog_level(),
            kDefaultInputVolumeControllerConfig.clipped_level_min);
}

// Checks that, when the "WebRTC-Audio-AgcMinMicLevelExperiment" field trial is
// specified with a value lower than the `clipped_level_min`, the behavior of
// the analog gain controller is the same as that obtained when the field trial
// is not specified.
// TODO(webrtc:7494): Revisit the test after moving the number of update wait
// frames to APM config. The test passes but internally the gain update timing
// differs.
TEST(InputVolumeControllerTest,
     AgcMinMicLevelExperimentCompareMicLevelWithClippingWithRmsError) {
  // Create and initialize two AGCs by specifying and leaving unspecified the
  // relevant field trial.
  const auto factory = []() {
    // Use a large clipped level step to more quickly decrease the analog gain
    // with clipping.
    InputVolumeControllerConfig config = kDefaultInputVolumeControllerConfig;
    config.enabled = true;
    config.startup_min_volume = kInitialInputVolume;
    config.clipped_level_step = 64;
    config.clipped_ratio_threshold = kClippedRatioThreshold;
    config.clipped_wait_frames = kClippedWaitFrames;
    auto controller = std::make_unique<InputVolumeController>(
        /*num_capture_channels=*/1, config);
    controller->Initialize();
    controller->set_stream_analog_level(kInitialInputVolume);
    return controller;
  };
  std::unique_ptr<InputVolumeController> manager = factory();
  std::unique_ptr<InputVolumeController> manager_with_rms;
  {
    constexpr int kMinMicLevelOverride = 20;
    static_assert(kDefaultInputVolumeControllerConfig.clipped_level_min >=
                      kMinMicLevelOverride,
                  "Use a lower override value.");
    test::ScopedFieldTrials field_trial(
        GetAgcMinMicLevelExperimentFieldTrialEnabled(kMinMicLevelOverride));
    manager_with_rms = factory();
  }

  // Create a test input signal which containts 80% of clipped samples.
  AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
                           1);
  WriteAudioBufferSamples(/*samples_value=*/4000.0f, /*clipped_ratio=*/0.8f,
                          audio_buffer);

  CallPreProcessAndProcess(
      /*num_calls=*/400, audio_buffer,
      /*speech_probability=*/0.7f,
      /*speech_level=*/-18.0f, *manager);
  CallPreProcessAndProcess(
      /*num_calls=*/400, audio_buffer,
      /*speech_probability=*/0.7f,
      /*speech_level=*/-18.0f, *manager_with_rms);

  // Make sure that an adaptation occurred.
  ASSERT_GT(manager->recommended_analog_level(), 0);

  // Check that the selected analog gain is the same for both controllers and
  // that it equals the minimum level reached when clipping is handled. That is
  // expected because the minimum microphone level override is less than the
  // minimum level used when clipping is detected.
  EXPECT_EQ(manager->recommended_analog_level(),
            manager_with_rms->recommended_analog_level());
  EXPECT_EQ(manager_with_rms->recommended_analog_level(),
            kDefaultInputVolumeControllerConfig.clipped_level_min);
}

// TODO(bugs.webrtc.org/12774): Test the bahavior of `clipped_level_step`.
// TODO(bugs.webrtc.org/12774): Test the bahavior of `clipped_ratio_threshold`.
// TODO(bugs.webrtc.org/12774): Test the bahavior of `clipped_wait_frames`.
// Verifies that configurable clipping parameters are initialized as intended.
TEST_P(InputVolumeControllerParametrizedTest, ClippingParametersVerified) {
  if (RmsErrorHasValue()) {
    GTEST_SKIP() << "Skipped. RMS error does not affect the test.";
  }

  std::unique_ptr<InputVolumeController> manager =
      CreateInputVolumeController(kInitialInputVolume, kClippedLevelStep,
                                  kClippedRatioThreshold, kClippedWaitFrames);
  manager->Initialize();
  EXPECT_EQ(manager->clipped_level_step_, kClippedLevelStep);
  EXPECT_EQ(manager->clipped_ratio_threshold_, kClippedRatioThreshold);
  EXPECT_EQ(manager->clipped_wait_frames_, kClippedWaitFrames);
  std::unique_ptr<InputVolumeController> manager_custom =
      CreateInputVolumeController(kInitialInputVolume,
                                  /*clipped_level_step=*/10,
                                  /*clipped_ratio_threshold=*/0.2f,
                                  /*clipped_wait_frames=*/50);
  manager_custom->Initialize();
  EXPECT_EQ(manager_custom->clipped_level_step_, 10);
  EXPECT_EQ(manager_custom->clipped_ratio_threshold_, 0.2f);
  EXPECT_EQ(manager_custom->clipped_wait_frames_, 50);
}

TEST_P(InputVolumeControllerParametrizedTest,
       DisableClippingPredictorDisablesClippingPredictor) {
  if (RmsErrorHasValue()) {
    GTEST_SKIP() << "Skipped. RMS error does not affect the test.";
  }

  std::unique_ptr<InputVolumeController> manager = CreateInputVolumeController(
      kInitialInputVolume, kClippedLevelStep, kClippedRatioThreshold,
      kClippedWaitFrames, /*enable_clipping_predictor=*/false);
  manager->Initialize();

  EXPECT_FALSE(manager->clipping_predictor_enabled());
  EXPECT_FALSE(manager->use_clipping_predictor_step());
}

TEST_P(InputVolumeControllerParametrizedTest,
       ClippingPredictorDisabledByDefault) {
  if (RmsErrorHasValue()) {
    GTEST_SKIP() << "Skipped. RMS error does not affect the test.";
  }

  constexpr ClippingPredictorConfig kDefaultConfig;
  EXPECT_FALSE(kDefaultConfig.enabled);
}

TEST_P(InputVolumeControllerParametrizedTest,
       EnableClippingPredictorEnablesClippingPredictor) {
  if (RmsErrorHasValue()) {
    GTEST_SKIP() << "Skipped. RMS error does not affect the test.";
  }

  std::unique_ptr<InputVolumeController> manager = CreateInputVolumeController(
      kInitialInputVolume, kClippedLevelStep, kClippedRatioThreshold,
      kClippedWaitFrames, /*enable_clipping_predictor=*/true);
  manager->Initialize();

  EXPECT_TRUE(manager->clipping_predictor_enabled());
  EXPECT_TRUE(manager->use_clipping_predictor_step());
}

TEST_P(InputVolumeControllerParametrizedTest,
       DisableClippingPredictorDoesNotLowerVolume) {
  AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
                           kNumChannels, kSampleRateHz, kNumChannels);

  InputVolumeControllerConfig config = GetInputVolumeControllerTestConfig();
  config.enable_clipping_predictor = false;
  InputVolumeController manager(/*num_capture_channels=*/1, config);
  manager.Initialize();
  manager.set_stream_analog_level(/*level=*/255);
  EXPECT_FALSE(manager.clipping_predictor_enabled());
  EXPECT_FALSE(manager.use_clipping_predictor_step());
  EXPECT_EQ(manager.recommended_analog_level(), 255);
  manager.Process(GetValueOrEmpty(kHighSpeechProbability),
                  GetValueOrEmpty(kSpeechLevel));
  CallPreProcessAudioBuffer(/*num_calls=*/10, /*peak_ratio=*/0.99f, manager);
  EXPECT_EQ(manager.recommended_analog_level(), 255);
  CallPreProcessAudioBuffer(/*num_calls=*/300, /*peak_ratio=*/0.99f, manager);
  EXPECT_EQ(manager.recommended_analog_level(), 255);
  CallPreProcessAudioBuffer(/*num_calls=*/10, /*peak_ratio=*/0.99f, manager);
  EXPECT_EQ(manager.recommended_analog_level(), 255);
}

TEST_P(InputVolumeControllerParametrizedTest,
       UsedClippingPredictionsProduceLowerAnalogLevels) {
  AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
                           kNumChannels, kSampleRateHz, kNumChannels);

  InputVolumeControllerConfig config_with_prediction =
      GetInputVolumeControllerTestConfig();
  config_with_prediction.enable_clipping_predictor = true;

  InputVolumeControllerConfig config_without_prediction =
      GetInputVolumeControllerTestConfig();

  config_without_prediction.enable_clipping_predictor = false;
  InputVolumeController manager_without_prediction(/*num_capture_channels=*/1,
                                                   config_without_prediction);
  InputVolumeController manager_with_prediction(/*num_capture_channels=*/1,
                                                config_with_prediction);

  manager_with_prediction.Initialize();
  manager_without_prediction.Initialize();

  constexpr int kInitialLevel = 255;
  constexpr float kClippingPeakRatio = 1.0f;
  constexpr float kCloseToClippingPeakRatio = 0.99f;
  constexpr float kZeroPeakRatio = 0.0f;
  manager_with_prediction.set_stream_analog_level(kInitialLevel);
  manager_without_prediction.set_stream_analog_level(kInitialLevel);

  manager_with_prediction.Process(GetValueOrEmpty(kHighSpeechProbability),
                                  GetValueOrEmpty(kSpeechLevel));
  manager_without_prediction.Process(GetValueOrEmpty(kHighSpeechProbability),
                                     GetValueOrEmpty(kSpeechLevel));

  EXPECT_TRUE(manager_with_prediction.clipping_predictor_enabled());
  EXPECT_FALSE(manager_without_prediction.clipping_predictor_enabled());
  EXPECT_TRUE(manager_with_prediction.use_clipping_predictor_step());
  EXPECT_EQ(manager_with_prediction.recommended_analog_level(), kInitialLevel);
  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
            kInitialLevel);

  // Expect a change in the analog level when the prediction step is used.
  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
                            manager_with_prediction);
  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
                            manager_without_prediction);
  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
            kInitialLevel - kClippedLevelStep);
  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
            kInitialLevel);

  // Expect no change during waiting.
  CallPreProcessAudioBuffer(kClippedWaitFrames, kCloseToClippingPeakRatio,
                            manager_with_prediction);
  CallPreProcessAudioBuffer(kClippedWaitFrames, kCloseToClippingPeakRatio,
                            manager_without_prediction);
  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
            kInitialLevel - kClippedLevelStep);
  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
            kInitialLevel);

  // Expect a change when the prediction step is used.
  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
                            manager_with_prediction);
  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
                            manager_without_prediction);
  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
            kInitialLevel - 2 * kClippedLevelStep);
  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
            kInitialLevel);

  // Expect no change when clipping is not detected or predicted.
  CallPreProcessAudioBuffer(2 * kClippedWaitFrames, kZeroPeakRatio,
                            manager_with_prediction);
  CallPreProcessAudioBuffer(2 * kClippedWaitFrames, kZeroPeakRatio,
                            manager_without_prediction);
  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
            kInitialLevel - 2 * kClippedLevelStep);
  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
            kInitialLevel);

  // Expect a change for clipping frames.
  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
                            manager_with_prediction);
  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
                            manager_without_prediction);
  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
            kInitialLevel - 3 * kClippedLevelStep);
  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
            kInitialLevel - kClippedLevelStep);

  // Expect no change during waiting.
  CallPreProcessAudioBuffer(kClippedWaitFrames, kClippingPeakRatio,
                            manager_with_prediction);
  CallPreProcessAudioBuffer(kClippedWaitFrames, kClippingPeakRatio,
                            manager_without_prediction);
  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
            kInitialLevel - 3 * kClippedLevelStep);
  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
            kInitialLevel - kClippedLevelStep);

  // Expect a change for clipping frames.
  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
                            manager_with_prediction);
  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
                            manager_without_prediction);
  EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
            kInitialLevel - 4 * kClippedLevelStep);
  EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
            kInitialLevel - 2 * kClippedLevelStep);
}

// Checks that passing an empty speech level has no effect on the input volume.
TEST_P(InputVolumeControllerParametrizedTest, EmptyRmsErrorHasNoEffect) {
  InputVolumeController manager(kNumChannels,
                                GetInputVolumeControllerTestConfig());
  manager.Initialize();

  constexpr int kInputVolume = kInitialInputVolume;
  manager.set_stream_analog_level(kInputVolume);

  // Feed speech with low energy that would trigger an upward adapation of
  // the analog level if an speech level and RMS values were not empty.
  constexpr int kNumFrames = 125;
  constexpr int kGainDb = -20;
  SpeechSamplesReader reader;
  reader.Feed(kNumFrames, kGainDb, absl::nullopt, absl::nullopt, manager);

  // Check that no adaptation occurs.
  ASSERT_EQ(manager.recommended_analog_level(), kInputVolume);
}

}  // namespace webrtc
