/*
 *  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 <cmath>
#include <cstdint>
#include <fstream>
#include <ios>
#include <limits>
#include <memory>
#include <optional>
#include <tuple>
#include <vector>

#include "api/audio/audio_processing.h"
#include "modules/audio_processing/audio_buffer.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_minmax.h"
#include "system_wrappers/include/metrics.h"
#include "test/create_test_environment.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 kDefaultInitialInputVolume = 128;
constexpr int kClippedMin = 165;  // Arbitrary, but different from the default.
constexpr float kAboveClippedThreshold = 0.2f;
constexpr int kClippedLevelStep = 15;
constexpr float kClippedRatioThreshold = 0.1f;
constexpr int kClippedWaitFrames = 300;
constexpr float kHighSpeechProbability = 0.7f;
constexpr float kLowSpeechProbability = 0.1f;
constexpr float kSpeechLevel = -25.0f;
constexpr float kSpeechRatioThreshold = 0.8f;

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 ClippingPredictorConfig kDefaultClippingPredictorConfig{};

std::unique_ptr<InputVolumeController> CreateInputVolumeController(
    int clipped_level_step = kClippedLevelStep,
    float clipped_ratio_threshold = kClippedRatioThreshold,
    int clipped_wait_frames = kClippedWaitFrames,
    bool enable_clipping_predictor = false,
    int update_input_volume_wait_frames = 0) {
  InputVolumeControllerConfig config{
      .min_input_volume = 20,
      .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,
      .update_input_volume_wait_frames = update_input_volume_wait_frames,
      .speech_probability_threshold = 0.5f,
      .speech_ratio_threshold = kSpeechRatioThreshold,
  };

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

// (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;
    }
  }
}

// (Over)writes samples in `audio_buffer`. Alternates samples `samples_value`
// and zero.
void WriteAlternatingAudioBufferSamples(float samples_value,
                                        AudioBuffer& audio_buffer) {
  RTC_DCHECK_GE(samples_value, kMinSample);
  RTC_DCHECK_LE(samples_value, kMaxSample);
  const int num_channels = audio_buffer.num_channels();
  const int num_frames = audio_buffer.num_frames();
  for (int ch = 0; ch < num_channels; ++ch) {
    for (int i = 0; i < num_frames; i += 2) {
      audio_buffer.channels()[ch][i] = samples_value;
      audio_buffer.channels()[ch][i + 1] = 0.0f;
    }
  }
}

// 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 `controller` by calling
  // `AnalyzeInputAudio()` and `RecommendInputVolume()` 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_dbfs`
  // are passed to `RecommendInputVolume()`.
  int Feed(int num_frames,
           int applied_input_volume,
           int gain_db,
           float speech_probability,
           std::optional<float> speech_level_dbfs,
           InputVolumeController& controller) {
    RTC_DCHECK(controller.capture_output_used());

    float gain = std::pow(10.0f, gain_db / 20.0f);  // From dB to linear gain.
    is_.seekg(0,
              std::ifstream::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 SafeClamp(static_cast<float>(v) * gain,
                                        kMinSample, kMaxSample);
                     });
      controller.AnalyzeInputAudio(applied_input_volume, audio_buffer_);
      const auto recommended_input_volume = controller.RecommendInputVolume(
          speech_probability, speech_level_dbfs);

      // Expect no errors: Applied volume set for every frame;
      // `RecommendInputVolume()` returns a non-empty value.
      EXPECT_TRUE(recommended_input_volume.has_value());

      applied_input_volume = *recommended_input_volume;
    }
    return applied_input_volume;
  }

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

// Runs the MonoInputVolumeControl processing sequence following the API
// contract. Returns the updated recommended input volume.
float UpdateRecommendedInputVolume(MonoInputVolumeController& mono_controller,
                                   int applied_input_volume,
                                   float speech_probability,
                                   std::optional<float> rms_error_dbfs) {
  mono_controller.set_stream_analog_level(applied_input_volume);
  EXPECT_EQ(mono_controller.recommended_analog_level(), applied_input_volume);
  mono_controller.Process(rms_error_dbfs, speech_probability);
  return mono_controller.recommended_analog_level();
}

}  // namespace

// TODO(bugs.webrtc.org/12874): Use constexpr struct with designated
// initializers once fixed.
constexpr InputVolumeControllerConfig GetInputVolumeControllerTestConfig() {
  InputVolumeControllerConfig config{
      .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,
      .update_input_volume_wait_frames = 0,
      .speech_probability_threshold = 0.5f,
      .speech_ratio_threshold = 1.0f,
  };
  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.
  // TODO(bugs.webrtc.org/7494): Remove the default argument.
  InputVolumeControllerTestHelper(const InputVolumeController::Config& config =
                                      GetInputVolumeControllerTestConfig())
      : audio_buffer(kSampleRateHz,
                     kNumChannels,
                     kSampleRateHz,
                     kNumChannels,
                     kSampleRateHz,
                     kNumChannels),
        controller(/*num_capture_channels=*/1,
                   config,
                   CreateTestEnvironment().field_trials()) {
    controller.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 `AnalyzeInputAudio()` and
  // `RecommendInputVolume()`;
  //  Returns the recommended input volume.
  std::optional<int> CallAgcSequence(int applied_input_volume,
                                     float speech_probability,
                                     std::optional<float> speech_level_dbfs,
                                     int num_calls = 1) {
    RTC_DCHECK_GE(num_calls, 1);
    std::optional<int> volume = applied_input_volume;
    for (int i = 0; i < num_calls; ++i) {
      // Repeat the initial volume if `RecommendInputVolume()` doesn't return a
      // value.
      controller.AnalyzeInputAudio(volume.value_or(applied_input_volume),
                                   audio_buffer);
      volume = controller.RecommendInputVolume(speech_probability,
                                               speech_level_dbfs);

      // Allow deviation from the API contract: `RecommendInputVolume()` doesn't
      // return a recommended input volume.
      if (volume.has_value()) {
        EXPECT_EQ(*volume, controller.recommended_input_volume());
      }
    }
    return volume;
  }

  // Deprecated.
  // TODO(bugs.webrtc.org/7494): Let the caller write `audio_buffer` and use
  // `CallAgcSequence()`.
  int CallRecommendInputVolume(int num_calls,
                               int initial_volume,
                               float speech_probability,
                               std::optional<float> speech_level_dbfs) {
    RTC_DCHECK(controller.capture_output_used());

    // Create non-clipping audio for `AnalyzeInputAudio()`.
    WriteAlternatingAudioBufferSamples(0.1f * kMaxSample, audio_buffer);
    int volume = initial_volume;
    for (int i = 0; i < num_calls; ++i) {
      controller.AnalyzeInputAudio(volume, audio_buffer);
      const auto recommended_input_volume = controller.RecommendInputVolume(
          speech_probability, speech_level_dbfs);

      // Expect no errors: Applied volume set for every frame;
      // `RecommendInputVolume()` returns a non-empty value.
      EXPECT_TRUE(recommended_input_volume.has_value());

      volume = *recommended_input_volume;
    }
    return volume;
  }

  // Deprecated.
  // TODO(bugs.webrtc.org/7494): Let the caller write `audio_buffer` and use
  // `CallAgcSequence()`.
  void CallAnalyzeInputAudio(int num_calls, float clipped_ratio) {
    RTC_DCHECK(controller.capture_output_used());

    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) {
      controller.AnalyzeInputAudio(controller.recommended_input_volume(),
                                   audio_buffer);
    }
  }

  AudioBuffer audio_buffer;
  InputVolumeController controller;
};

class InputVolumeControllerChannelSampleRateTest
    : public ::testing::TestWithParam<std::tuple<int, int>> {
 protected:
  int GetNumChannels() const { return std::get<0>(GetParam()); }
  int GetSampleRateHz() const { return std::get<1>(GetParam()); }
};

TEST_P(InputVolumeControllerChannelSampleRateTest, CheckIsAlive) {
  const int num_channels = GetNumChannels();
  const int sample_rate_hz = GetSampleRateHz();

  constexpr InputVolumeController::Config kConfig{.enable_clipping_predictor =
                                                      true};
  InputVolumeController controller(num_channels, kConfig,
                                   CreateTestEnvironment().field_trials());
  controller.Initialize();
  AudioBuffer buffer(sample_rate_hz, num_channels, sample_rate_hz, num_channels,
                     sample_rate_hz, num_channels);

  constexpr int kStartupVolume = 100;
  int applied_initial_volume = kStartupVolume;

  // Trigger a downward adaptation with clipping.
  constexpr int kLevelWithinTargetDbfs =
      (kConfig.target_range_min_dbfs + kConfig.target_range_max_dbfs) / 2;
  WriteAlternatingAudioBufferSamples(/*samples_value=*/kMaxSample, buffer);
  const int initial_volume1 = applied_initial_volume;
  for (int i = 0; i < 400; ++i) {
    controller.AnalyzeInputAudio(applied_initial_volume, buffer);
    auto recommended_input_volume = controller.RecommendInputVolume(
        kLowSpeechProbability,
        /*speech_level_dbfs=*/kLevelWithinTargetDbfs);
    ASSERT_TRUE(recommended_input_volume.has_value());
    applied_initial_volume = *recommended_input_volume;
  }
  ASSERT_LT(controller.recommended_input_volume(), initial_volume1);

  // Fill in audio that does not clip.
  WriteAlternatingAudioBufferSamples(/*samples_value=*/1234.5f, buffer);

  // Trigger an upward adaptation.
  const int initial_volume2 = controller.recommended_input_volume();
  for (int i = 0; i < kConfig.clipped_wait_frames; ++i) {
    controller.AnalyzeInputAudio(applied_initial_volume, buffer);
    auto recommended_input_volume = controller.RecommendInputVolume(
        kHighSpeechProbability,
        /*speech_level_dbfs=*/kConfig.target_range_min_dbfs - 5);
    ASSERT_TRUE(recommended_input_volume.has_value());
    applied_initial_volume = *recommended_input_volume;
  }
  EXPECT_GT(controller.recommended_input_volume(), initial_volume2);

  // Trigger a downward adaptation.
  const int initial_volume = controller.recommended_input_volume();
  for (int i = 0; i < kConfig.update_input_volume_wait_frames; ++i) {
    controller.AnalyzeInputAudio(applied_initial_volume, buffer);
    auto recommended_input_volume = controller.RecommendInputVolume(
        kHighSpeechProbability,
        /*speech_level_dbfs=*/kConfig.target_range_max_dbfs + 5);
    ASSERT_TRUE(recommended_input_volume.has_value());
    applied_initial_volume = *recommended_input_volume;
  }
  EXPECT_LT(controller.recommended_input_volume(), initial_volume);
}

INSTANTIATE_TEST_SUITE_P(
    ,
    InputVolumeControllerChannelSampleRateTest,
    ::testing::Combine(::testing::Values(1, 2, 3, 6),
                       ::testing::Values(8000, 16000, 32000, 48000)));

class InputVolumeControllerParametrizedTest
    : public ::testing::TestWithParam<int> {};

TEST_P(InputVolumeControllerParametrizedTest,
       StartupMinVolumeConfigurationRespectedWhenAppliedInputVolumeAboveMin) {
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = GetParam()});

  EXPECT_EQ(*helper.CallAgcSequence(/*applied_input_volume=*/128,
                                    /*speech_probability=*/0.9f,
                                    /*speech_level_dbfs=*/-80),
            128);
}

TEST_P(
    InputVolumeControllerParametrizedTest,
    StartupMinVolumeConfigurationRespectedWhenAppliedInputVolumeMaybeBelowMin) {
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = GetParam()});

  EXPECT_GE(*helper.CallAgcSequence(/*applied_input_volume=*/10,
                                    /*speech_probability=*/0.9f,
                                    /*speech_level_dbfs=*/-80),
            10);
}

TEST_P(InputVolumeControllerParametrizedTest,
       StartupMinVolumeRespectedWhenAppliedVolumeNonZero) {
  const int kMinInputVolume = GetParam();
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = kMinInputVolume,
                  .target_range_min_dbfs = -30,
                  .update_input_volume_wait_frames = 1,
                  .speech_probability_threshold = 0.5f,
                  .speech_ratio_threshold = 0.5f});

  // Volume change possible; speech level below the digital gain window.
  int volume = *helper.CallAgcSequence(/*applied_input_volume=*/1,
                                       /*speech_probability=*/0.9f,
                                       /*speech_level_dbfs=*/-80);

  EXPECT_EQ(volume, kMinInputVolume);
}

TEST_P(InputVolumeControllerParametrizedTest,
       MinVolumeRepeatedlyRespectedWhenAppliedVolumeNonZero) {
  const int kMinInputVolume = GetParam();
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = kMinInputVolume,
                  .target_range_min_dbfs = -30,
                  .update_input_volume_wait_frames = 1,
                  .speech_probability_threshold = 0.5f,
                  .speech_ratio_threshold = 0.5f});

  // Volume change possible; speech level below the digital gain window.
  for (int i = 0; i < 100; ++i) {
    const int volume = *helper.CallAgcSequence(/*applied_input_volume=*/1,
                                               /*speech_probability=*/0.9f,
                                               /*speech_level_dbfs=*/-80);
    EXPECT_GE(volume, kMinInputVolume);
  }
}

TEST_P(InputVolumeControllerParametrizedTest,
       StartupMinVolumeRespectedOnceWhenAppliedVolumeZero) {
  const int kMinInputVolume = GetParam();
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = kMinInputVolume,
                  .target_range_min_dbfs = -30,
                  .update_input_volume_wait_frames = 1,
                  .speech_probability_threshold = 0.5f,
                  .speech_ratio_threshold = 0.5f});

  int volume = *helper.CallAgcSequence(/*applied_input_volume=*/0,
                                       /*speech_probability=*/0.9f,
                                       /*speech_level_dbfs=*/-80);

  EXPECT_EQ(volume, kMinInputVolume);

  // No change of volume regardless of a speech level below the digital gain
  // window; applied volume is zero.
  volume = *helper.CallAgcSequence(/*applied_input_volume=*/0,
                                   /*speech_probability=*/0.9f,
                                   /*speech_level_dbfs=*/-80);

  EXPECT_EQ(volume, 0);
}

TEST_P(InputVolumeControllerParametrizedTest, MicVolumeResponseToRmsError) {
  InputVolumeControllerConfig config = GetInputVolumeControllerTestConfig();
  config.min_input_volume = GetParam();
  InputVolumeControllerTestHelper helper(config);
  int volume = *helper.CallAgcSequence(kDefaultInitialInputVolume,
                                       kHighSpeechProbability, kSpeechLevel);

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

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

  // Above the digital gain's  window; volume should be increased.
  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, -29.0f);
  EXPECT_EQ(volume, 128);

  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, -38.0f);
  EXPECT_EQ(volume, 156);

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

  // Below the digial gain's window; volume should be decreased.
  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, -17.0f);
  EXPECT_EQ(volume, 155);

  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, -17.0f);
  EXPECT_EQ(volume, 151);

  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, -9.0f);
  EXPECT_EQ(volume, 119);
}

TEST_P(InputVolumeControllerParametrizedTest, MicVolumeIsLimited) {
  InputVolumeControllerConfig config = GetInputVolumeControllerTestConfig();
  const int min_input_volume = GetParam();
  config.min_input_volume = min_input_volume;
  InputVolumeControllerTestHelper helper(config);
  int volume = *helper.CallAgcSequence(kDefaultInitialInputVolume,
                                       kHighSpeechProbability, kSpeechLevel);

  // Maximum upwards change is limited.
  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, -48.0f);
  EXPECT_EQ(volume, 183);

  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, -48.0f);
  EXPECT_EQ(volume, 243);

  // Won't go higher than the maximum.
  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, -48.0f);
  EXPECT_EQ(volume, 255);

  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, -17.0f);
  EXPECT_EQ(volume, 254);

  // Maximum downwards change is limited.
  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, 22.0f);
  EXPECT_EQ(volume, 194);

  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, 22.0f);
  EXPECT_EQ(volume, 137);

  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, 22.0f);
  EXPECT_EQ(volume, 88);

  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, 22.0f);
  EXPECT_EQ(volume, 54);

  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, 22.0f);
  EXPECT_EQ(volume, 33);

  // Won't go lower than the minimum.
  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, 22.0f);
  EXPECT_EQ(volume, std::max(18, min_input_volume));

  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, 22.0f);
  EXPECT_EQ(volume, std::max(12, min_input_volume));
}

TEST_P(InputVolumeControllerParametrizedTest, NoActionWhileMuted) {
  InputVolumeControllerTestHelper helper_1(
      /*config=*/{.min_input_volume = GetParam()});
  InputVolumeControllerTestHelper helper_2(
      /*config=*/{.min_input_volume = GetParam()});

  int volume_1 = *helper_1.CallAgcSequence(/*applied_input_volume=*/255,
                                           kHighSpeechProbability, kSpeechLevel,
                                           /*num_calls=*/1);
  int volume_2 = *helper_2.CallAgcSequence(/*applied_input_volume=*/255,
                                           kHighSpeechProbability, kSpeechLevel,
                                           /*num_calls=*/1);

  EXPECT_EQ(volume_1, 255);
  EXPECT_EQ(volume_2, 255);

  helper_2.controller.HandleCaptureOutputUsedChange(false);

  WriteAlternatingAudioBufferSamples(kMaxSample, helper_1.audio_buffer);
  WriteAlternatingAudioBufferSamples(kMaxSample, helper_2.audio_buffer);

  volume_1 =
      *helper_1.CallAgcSequence(volume_1, kHighSpeechProbability, kSpeechLevel,
                                /*num_calls=*/1);
  volume_2 =
      *helper_2.CallAgcSequence(volume_2, kHighSpeechProbability, kSpeechLevel,
                                /*num_calls=*/1);

  EXPECT_LT(volume_1, 255);
  EXPECT_EQ(volume_2, 255);
}

TEST_P(InputVolumeControllerParametrizedTest,
       UnmutingChecksVolumeWithoutRaising) {
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = GetParam()});
  helper.CallAgcSequence(kDefaultInitialInputVolume, kHighSpeechProbability,
                         kSpeechLevel);

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

  constexpr int kInputVolume = 127;

  // SetMicVolume should not be called.
  EXPECT_EQ(
      helper.CallRecommendInputVolume(/*num_calls=*/1, kInputVolume,
                                      kHighSpeechProbability, kSpeechLevel),
      kInputVolume);
}

TEST_P(InputVolumeControllerParametrizedTest, UnmutingRaisesTooLowVolume) {
  const int min_input_volume = GetParam();
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = min_input_volume});
  helper.CallAgcSequence(kDefaultInitialInputVolume, kHighSpeechProbability,
                         kSpeechLevel);

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

  constexpr int kInputVolume = 11;

  EXPECT_EQ(
      helper.CallRecommendInputVolume(/*num_calls=*/1, kInputVolume,
                                      kHighSpeechProbability, kSpeechLevel),
      min_input_volume);
}

TEST_P(InputVolumeControllerParametrizedTest,
       ManualLevelChangeResultsInNoSetMicCall) {
  InputVolumeControllerConfig config = GetInputVolumeControllerTestConfig();
  config.min_input_volume = GetParam();
  InputVolumeControllerTestHelper helper(config);
  int volume = *helper.CallAgcSequence(kDefaultInitialInputVolume,
                                       kHighSpeechProbability, kSpeechLevel);

  // GetMicVolume returns a value outside of the quantization slack, indicating
  // a manual volume change.
  ASSERT_NE(volume, 154);
  volume = helper.CallRecommendInputVolume(
      /*num_calls=*/1, /*initial_volume=*/154, kHighSpeechProbability, -29.0f);
  EXPECT_EQ(volume, 154);

  // Do the same thing, except downwards now.
  volume = helper.CallRecommendInputVolume(
      /*num_calls=*/1, /*initial_volume=*/100, kHighSpeechProbability, -17.0f);
  EXPECT_EQ(volume, 100);

  // And finally verify the AGC continues working without a manual change.
  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, -17.0f);
  EXPECT_EQ(volume, 99);
}

TEST_P(InputVolumeControllerParametrizedTest,
       RecoveryAfterManualLevelChangeFromMax) {
  InputVolumeControllerConfig config = GetInputVolumeControllerTestConfig();
  config.min_input_volume = GetParam();
  InputVolumeControllerTestHelper helper(config);
  int volume = *helper.CallAgcSequence(kDefaultInitialInputVolume,
                                       kHighSpeechProbability, kSpeechLevel);

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

  // Manual change does not result in SetMicVolume call.
  volume = helper.CallRecommendInputVolume(
      /*num_calls=*/1, /*initial_volume=*/50, kHighSpeechProbability, -17.0f);
  EXPECT_EQ(helper.controller.recommended_input_volume(), 50);

  // Continues working as usual afterwards.
  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, -38.0f);

  EXPECT_EQ(volume, 65);
}

// Checks that the minimum input volume is enforced during the upward adjustment
// of the input volume.
TEST_P(InputVolumeControllerParametrizedTest,
       EnforceMinInputVolumeDuringUpwardsAdjustment) {
  const int min_input_volume = GetParam();
  InputVolumeControllerConfig config = GetInputVolumeControllerTestConfig();
  config.min_input_volume = min_input_volume;
  InputVolumeControllerTestHelper helper(config);
  int volume = *helper.CallAgcSequence(kDefaultInitialInputVolume,
                                       kHighSpeechProbability, kSpeechLevel);

  // Manual change below min, but strictly positive, otherwise no action will be
  // taken.
  volume = helper.CallRecommendInputVolume(
      /*num_calls=*/1, /*initial_volume=*/1, kHighSpeechProbability, -17.0f);

  // Trigger an upward adjustment of the input volume.
  EXPECT_EQ(volume, min_input_volume);
  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, -29.0f);
  EXPECT_EQ(volume, min_input_volume);
  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, -30.0f);
  EXPECT_EQ(volume, min_input_volume);

  // After a number of consistently low speech level observations, the input
  // volume is eventually raised above the minimum.
  volume = helper.CallRecommendInputVolume(/*num_calls=*/10, volume,
                                           kHighSpeechProbability, -38.0f);
  EXPECT_GT(volume, min_input_volume);
}

// 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) {
  const int min_input_volume = GetParam();
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = min_input_volume});
  int volume = *helper.CallAgcSequence(kDefaultInitialInputVolume,
                                       kHighSpeechProbability, kSpeechLevel);

  // Manual change below min, but strictly positive, otherwise
  // AGC won't take any action.
  volume = helper.CallRecommendInputVolume(
      /*num_calls=*/1, /*initial_volume=*/1, kHighSpeechProbability, -17.0f);
  EXPECT_EQ(volume, min_input_volume);
}

TEST_P(InputVolumeControllerParametrizedTest, NoClippingHasNoImpact) {
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = GetParam()});
  helper.CallAgcSequence(kDefaultInitialInputVolume, kHighSpeechProbability,
                         kSpeechLevel);

  helper.CallAnalyzeInputAudio(/*num_calls=*/100, /*clipped_ratio=*/0);
  EXPECT_EQ(helper.controller.recommended_input_volume(), 128);
}

TEST_P(InputVolumeControllerParametrizedTest,
       ClippingUnderThresholdHasNoImpact) {
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = GetParam()});
  helper.CallAgcSequence(kDefaultInitialInputVolume, kHighSpeechProbability,
                         kSpeechLevel);

  helper.CallAnalyzeInputAudio(/*num_calls=*/1, /*clipped_ratio=*/0.099);
  EXPECT_EQ(helper.controller.recommended_input_volume(), 128);
}

TEST_P(InputVolumeControllerParametrizedTest, ClippingLowersVolume) {
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = GetParam()});
  helper.CallAgcSequence(/*applied_input_volume=*/255, kHighSpeechProbability,
                         kSpeechLevel);

  helper.CallAnalyzeInputAudio(/*num_calls=*/1, /*clipped_ratio=*/0.2);
  EXPECT_EQ(helper.controller.recommended_input_volume(), 240);
}

TEST_P(InputVolumeControllerParametrizedTest,
       WaitingPeriodBetweenClippingChecks) {
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = GetParam()});
  helper.CallAgcSequence(/*applied_input_volume=*/255, kHighSpeechProbability,
                         kSpeechLevel);

  helper.CallAnalyzeInputAudio(/*num_calls=*/1,
                               /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(helper.controller.recommended_input_volume(), 240);

  helper.CallAnalyzeInputAudio(/*num_calls=*/300,
                               /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(helper.controller.recommended_input_volume(), 240);

  helper.CallAnalyzeInputAudio(/*num_calls=*/1,
                               /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(helper.controller.recommended_input_volume(), 225);
}

TEST_P(InputVolumeControllerParametrizedTest, ClippingLoweringIsLimited) {
  InputVolumeControllerConfig config = GetInputVolumeControllerTestConfig();
  config.min_input_volume = GetParam();
  InputVolumeControllerTestHelper helper(config);
  helper.CallAgcSequence(/*applied_input_volume=*/180, kHighSpeechProbability,
                         kSpeechLevel);

  helper.CallAnalyzeInputAudio(/*num_calls=*/1,
                               /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(helper.controller.recommended_input_volume(), kClippedMin);

  helper.CallAnalyzeInputAudio(/*num_calls=*/1000,
                               /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(helper.controller.recommended_input_volume(), kClippedMin);
}

TEST_P(InputVolumeControllerParametrizedTest,
       ClippingMaxIsRespectedWhenEqualToLevel) {
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = GetParam()});
  helper.CallAgcSequence(/*applied_input_volume=*/255, kHighSpeechProbability,
                         kSpeechLevel);

  helper.CallAnalyzeInputAudio(/*num_calls=*/1,
                               /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(helper.controller.recommended_input_volume(), 240);

  helper.CallRecommendInputVolume(/*num_calls=*/10, /*initial_volume=*/240,
                                  kHighSpeechProbability, -48.0f);
  EXPECT_EQ(helper.controller.recommended_input_volume(), 240);
}

TEST_P(InputVolumeControllerParametrizedTest,
       ClippingMaxIsRespectedWhenHigherThanLevel) {
  InputVolumeControllerConfig config = GetInputVolumeControllerTestConfig();
  config.min_input_volume = GetParam();
  InputVolumeControllerTestHelper helper(config);
  helper.CallAgcSequence(/*applied_input_volume=*/200, kHighSpeechProbability,
                         kSpeechLevel);

  helper.CallAnalyzeInputAudio(/*num_calls=*/1,
                               /*clipped_ratio=*/kAboveClippedThreshold);
  int volume = helper.controller.recommended_input_volume();
  EXPECT_EQ(volume, 185);

  volume = helper.CallRecommendInputVolume(/*num_calls=*/1, volume,
                                           kHighSpeechProbability, -58.0f);
  EXPECT_EQ(volume, 240);
  volume = helper.CallRecommendInputVolume(/*num_calls=*/10, volume,
                                           kHighSpeechProbability, -58.0f);
  EXPECT_EQ(volume, 240);
}

TEST_P(InputVolumeControllerParametrizedTest, UserCanRaiseVolumeAfterClipping) {
  InputVolumeControllerConfig config = GetInputVolumeControllerTestConfig();
  config.min_input_volume = GetParam();
  InputVolumeControllerTestHelper helper(config);
  helper.CallAgcSequence(/*applied_input_volume=*/225, kHighSpeechProbability,
                         kSpeechLevel);

  helper.CallAnalyzeInputAudio(/*num_calls=*/1,
                               /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(helper.controller.recommended_input_volume(), 210);

  // User changed the volume.
  int volume = helper.CallRecommendInputVolume(
      /*num_calls=*/1, /*initial_volume-*/ 250, kHighSpeechProbability, -32.0f);
  EXPECT_EQ(volume, 250);

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

TEST_P(InputVolumeControllerParametrizedTest,
       ClippingDoesNotPullLowVolumeBackUp) {
  InputVolumeControllerConfig config = GetInputVolumeControllerTestConfig();
  config.min_input_volume = GetParam();
  InputVolumeControllerTestHelper helper(config);
  helper.CallAgcSequence(/*applied_input_volume=*/80, kHighSpeechProbability,
                         kSpeechLevel);

  int initial_volume = helper.controller.recommended_input_volume();
  helper.CallAnalyzeInputAudio(/*num_calls=*/1,
                               /*clipped_ratio=*/kAboveClippedThreshold);
  EXPECT_EQ(helper.controller.recommended_input_volume(), initial_volume);
}

TEST_P(InputVolumeControllerParametrizedTest, TakesNoActionOnZeroMicVolume) {
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = GetParam()});
  helper.CallAgcSequence(kDefaultInitialInputVolume, kHighSpeechProbability,
                         kSpeechLevel);

  EXPECT_EQ(
      helper.CallRecommendInputVolume(/*num_calls=*/10, /*initial_volume=*/0,
                                      kHighSpeechProbability, -48.0f),
      0);
}

TEST_P(InputVolumeControllerParametrizedTest, ClippingDetectionLowersVolume) {
  InputVolumeControllerConfig config = GetInputVolumeControllerTestConfig();
  config.min_input_volume = GetParam();
  InputVolumeControllerTestHelper helper(config);
  int volume = *helper.CallAgcSequence(/*applied_input_volume=*/255,
                                       kHighSpeechProbability, kSpeechLevel,
                                       /*num_calls=*/1);

  EXPECT_EQ(volume, 255);

  WriteAlternatingAudioBufferSamples(0.99f * kMaxSample, helper.audio_buffer);
  volume = *helper.CallAgcSequence(volume, kHighSpeechProbability, kSpeechLevel,
                                   /*num_calls=*/100);

  EXPECT_EQ(volume, 255);

  WriteAlternatingAudioBufferSamples(kMaxSample, helper.audio_buffer);
  volume = *helper.CallAgcSequence(volume, kHighSpeechProbability, kSpeechLevel,
                                   /*num_calls=*/100);

  EXPECT_EQ(volume, 240);
}

// 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) {
  std::unique_ptr<InputVolumeController> controller =
      CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
                                  kClippedWaitFrames);
  controller->Initialize();
  EXPECT_EQ(controller->clipped_level_step_, kClippedLevelStep);
  EXPECT_EQ(controller->clipped_ratio_threshold_, kClippedRatioThreshold);
  EXPECT_EQ(controller->clipped_wait_frames_, kClippedWaitFrames);
  std::unique_ptr<InputVolumeController> controller_custom =
      CreateInputVolumeController(/*clipped_level_step=*/10,
                                  /*clipped_ratio_threshold=*/0.2f,
                                  /*clipped_wait_frames=*/50);
  controller_custom->Initialize();
  EXPECT_EQ(controller_custom->clipped_level_step_, 10);
  EXPECT_EQ(controller_custom->clipped_ratio_threshold_, 0.2f);
  EXPECT_EQ(controller_custom->clipped_wait_frames_, 50);
}

TEST_P(InputVolumeControllerParametrizedTest,
       DisableClippingPredictorDisablesClippingPredictor) {
  std::unique_ptr<InputVolumeController> controller =
      CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
                                  kClippedWaitFrames,
                                  /*enable_clipping_predictor=*/false);
  controller->Initialize();

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

TEST_P(InputVolumeControllerParametrizedTest,
       EnableClippingPredictorEnablesClippingPredictor) {
  std::unique_ptr<InputVolumeController> controller =
      CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
                                  kClippedWaitFrames,
                                  /*enable_clipping_predictor=*/true);
  controller->Initialize();

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

TEST_P(InputVolumeControllerParametrizedTest,
       DisableClippingPredictorDoesNotLowerVolume) {
  int volume = 255;
  InputVolumeControllerConfig config = GetInputVolumeControllerTestConfig();
  config.enable_clipping_predictor = false;
  auto helper = InputVolumeControllerTestHelper(config);
  helper.controller.Initialize();

  EXPECT_FALSE(helper.controller.clipping_predictor_enabled());
  EXPECT_FALSE(helper.controller.use_clipping_predictor_step());

  // Expect no change if clipping prediction is enabled.
  for (int j = 0; j < 31; ++j) {
    WriteAlternatingAudioBufferSamples(0.99f * kMaxSample, helper.audio_buffer);
    volume =
        *helper.CallAgcSequence(volume, kLowSpeechProbability, kSpeechLevel,
                                /*num_calls=*/5);

    WriteAudioBufferSamples(0.99f * kMaxSample, /*clipped_ratio=*/0.0f,
                            helper.audio_buffer);
    volume =
        *helper.CallAgcSequence(volume, kLowSpeechProbability, kSpeechLevel,
                                /*num_calls=*/5);

    EXPECT_EQ(volume, 255);
  }
}

// TODO(bugs.webrtc.org/7494): Split into several smaller tests.
TEST_P(InputVolumeControllerParametrizedTest,
       UsedClippingPredictionsProduceLowerAnalogLevels) {
  constexpr int kInitialLevel = 255;
  constexpr float kCloseToClippingPeakRatio = 0.99f;
  int volume_1 = kInitialLevel;
  int volume_2 = kInitialLevel;

  // Create two helpers, one with clipping prediction and one without.
  auto config_1 = GetInputVolumeControllerTestConfig();
  auto config_2 = GetInputVolumeControllerTestConfig();
  config_1.enable_clipping_predictor = true;
  config_2.enable_clipping_predictor = false;
  auto helper_1 = InputVolumeControllerTestHelper(config_1);
  auto helper_2 = InputVolumeControllerTestHelper(config_2);
  helper_1.controller.Initialize();
  helper_2.controller.Initialize();

  EXPECT_TRUE(helper_1.controller.clipping_predictor_enabled());
  EXPECT_FALSE(helper_2.controller.clipping_predictor_enabled());
  EXPECT_TRUE(helper_1.controller.use_clipping_predictor_step());

  // Expect a change if clipping prediction is enabled.
  WriteAlternatingAudioBufferSamples(kCloseToClippingPeakRatio * kMaxSample,
                                     helper_1.audio_buffer);
  WriteAlternatingAudioBufferSamples(kCloseToClippingPeakRatio * kMaxSample,
                                     helper_2.audio_buffer);
  volume_1 = *helper_1.CallAgcSequence(volume_1, kLowSpeechProbability,
                                       kSpeechLevel, 5);
  volume_2 = *helper_2.CallAgcSequence(volume_2, kLowSpeechProbability,
                                       kSpeechLevel, 5);

  WriteAudioBufferSamples(kCloseToClippingPeakRatio * kMaxSample,
                          /*clipped_ratio=*/0.0f, helper_1.audio_buffer);
  WriteAudioBufferSamples(kCloseToClippingPeakRatio * kMaxSample,
                          /*clipped_ratio=*/0.0f, helper_2.audio_buffer);
  volume_1 = *helper_1.CallAgcSequence(volume_1, kLowSpeechProbability,
                                       kSpeechLevel, 5);
  volume_2 = *helper_2.CallAgcSequence(volume_2, kLowSpeechProbability,
                                       kSpeechLevel, 5);

  EXPECT_EQ(volume_1, kInitialLevel - kClippedLevelStep);
  EXPECT_EQ(volume_2, kInitialLevel);

  // Expect no change during waiting.
  for (int i = 0; i < kClippedWaitFrames / 10; ++i) {
    WriteAlternatingAudioBufferSamples(kCloseToClippingPeakRatio * kMaxSample,
                                       helper_1.audio_buffer);
    WriteAlternatingAudioBufferSamples(kCloseToClippingPeakRatio * kMaxSample,
                                       helper_2.audio_buffer);
    volume_1 = *helper_1.CallAgcSequence(volume_1, kLowSpeechProbability,
                                         kSpeechLevel, 5);
    volume_2 = *helper_2.CallAgcSequence(volume_2, kLowSpeechProbability,
                                         kSpeechLevel, 5);

    WriteAudioBufferSamples(kCloseToClippingPeakRatio * kMaxSample,
                            /*clipped_ratio=*/0.0f, helper_1.audio_buffer);
    WriteAudioBufferSamples(kCloseToClippingPeakRatio * kMaxSample,
                            /*clipped_ratio=*/0.0f, helper_2.audio_buffer);
    volume_1 = *helper_1.CallAgcSequence(volume_1, kLowSpeechProbability,
                                         kSpeechLevel, 5);
    volume_2 = *helper_2.CallAgcSequence(volume_2, kLowSpeechProbability,
                                         kSpeechLevel, 5);

    EXPECT_EQ(volume_1, kInitialLevel - kClippedLevelStep);
    EXPECT_EQ(volume_2, kInitialLevel);
  }

  // Expect a change when the prediction step is used.
  WriteAlternatingAudioBufferSamples(kCloseToClippingPeakRatio * kMaxSample,
                                     helper_1.audio_buffer);
  WriteAlternatingAudioBufferSamples(kCloseToClippingPeakRatio * kMaxSample,
                                     helper_2.audio_buffer);
  volume_1 = *helper_1.CallAgcSequence(volume_1, kLowSpeechProbability,
                                       kSpeechLevel, 5);
  volume_2 = *helper_2.CallAgcSequence(volume_2, kLowSpeechProbability,
                                       kSpeechLevel, 5);

  WriteAudioBufferSamples(kCloseToClippingPeakRatio * kMaxSample,
                          /*clipped_ratio=*/0.0f, helper_1.audio_buffer);
  WriteAudioBufferSamples(kCloseToClippingPeakRatio * kMaxSample,
                          /*clipped_ratio=*/0.0f, helper_2.audio_buffer);
  volume_1 = *helper_1.CallAgcSequence(volume_1, kLowSpeechProbability,
                                       kSpeechLevel, 5);
  volume_2 = *helper_2.CallAgcSequence(volume_2, kLowSpeechProbability,
                                       kSpeechLevel, 5);

  EXPECT_EQ(volume_1, kInitialLevel - 2 * kClippedLevelStep);
  EXPECT_EQ(volume_2, kInitialLevel);

  // Expect no change when clipping is not detected or predicted.
  for (int i = 0; i < 2 * kClippedWaitFrames / 10; ++i) {
    WriteAlternatingAudioBufferSamples(/*samples_value=*/0.0f,
                                       helper_1.audio_buffer);
    WriteAlternatingAudioBufferSamples(/*samples_value=*/0.0f,
                                       helper_2.audio_buffer);
    volume_1 = *helper_1.CallAgcSequence(volume_1, kLowSpeechProbability,
                                         kSpeechLevel, 5);
    volume_2 = *helper_2.CallAgcSequence(volume_2, kLowSpeechProbability,
                                         kSpeechLevel, 5);

    WriteAudioBufferSamples(/*samples_value=*/0.0f, /*clipped_ratio=*/0.0f,
                            helper_1.audio_buffer);
    WriteAudioBufferSamples(/*samples_value=*/0.0f, /*clipped_ratio=*/0.0f,
                            helper_2.audio_buffer);
    volume_1 = *helper_1.CallAgcSequence(volume_1, kLowSpeechProbability,
                                         kSpeechLevel, 5);
    volume_2 = *helper_2.CallAgcSequence(volume_2, kLowSpeechProbability,
                                         kSpeechLevel, 5);
  }

  EXPECT_EQ(volume_1, kInitialLevel - 2 * kClippedLevelStep);
  EXPECT_EQ(volume_2, kInitialLevel);

  // Expect a change for clipping frames.
  WriteAlternatingAudioBufferSamples(kMaxSample, helper_1.audio_buffer);
  WriteAlternatingAudioBufferSamples(kMaxSample, helper_2.audio_buffer);
  volume_1 = *helper_1.CallAgcSequence(volume_1, kLowSpeechProbability,
                                       kSpeechLevel, 1);
  volume_2 = *helper_2.CallAgcSequence(volume_2, kLowSpeechProbability,
                                       kSpeechLevel, 1);

  EXPECT_EQ(volume_1, kInitialLevel - 3 * kClippedLevelStep);
  EXPECT_EQ(volume_2, kInitialLevel - kClippedLevelStep);

  // Expect no change during waiting.
  for (int i = 0; i < kClippedWaitFrames / 10; ++i) {
    WriteAlternatingAudioBufferSamples(kMaxSample, helper_1.audio_buffer);
    WriteAlternatingAudioBufferSamples(kMaxSample, helper_2.audio_buffer);
    volume_1 = *helper_1.CallAgcSequence(volume_1, kLowSpeechProbability,
                                         kSpeechLevel, 5);
    volume_2 = *helper_2.CallAgcSequence(volume_2, kLowSpeechProbability,
                                         kSpeechLevel, 5);

    WriteAudioBufferSamples(kMaxSample, /*clipped_ratio=*/1.0f,
                            helper_1.audio_buffer);
    WriteAudioBufferSamples(kMaxSample, /*clipped_ratio=*/1.0f,
                            helper_2.audio_buffer);
    volume_1 = *helper_1.CallAgcSequence(volume_1, kLowSpeechProbability,
                                         kSpeechLevel, 5);
    volume_2 = *helper_2.CallAgcSequence(volume_2, kLowSpeechProbability,
                                         kSpeechLevel, 5);
  }

  EXPECT_EQ(volume_1, kInitialLevel - 3 * kClippedLevelStep);
  EXPECT_EQ(volume_2, kInitialLevel - kClippedLevelStep);

  // Expect a change for clipping frames.
  WriteAlternatingAudioBufferSamples(kMaxSample, helper_1.audio_buffer);
  WriteAlternatingAudioBufferSamples(kMaxSample, helper_2.audio_buffer);
  volume_1 = *helper_1.CallAgcSequence(volume_1, kLowSpeechProbability,
                                       kSpeechLevel, 1);
  volume_2 = *helper_2.CallAgcSequence(volume_2, kLowSpeechProbability,
                                       kSpeechLevel, 1);

  EXPECT_EQ(volume_1, kInitialLevel - 4 * kClippedLevelStep);
  EXPECT_EQ(volume_2, kInitialLevel - 2 * kClippedLevelStep);
}

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

  // Feed speech with low energy that would trigger an upward adapation of
  // the analog level if an speech level was not low and the RMS level empty.
  constexpr int kNumFrames = 125;
  constexpr int kGainDb = -20;
  SpeechSamplesReader reader;
  int volume = reader.Feed(kNumFrames, kDefaultInitialInputVolume, kGainDb,
                           kLowSpeechProbability, std::nullopt, controller);

  // Check that no adaptation occurs.
  ASSERT_EQ(volume, kDefaultInitialInputVolume);
}

// Checks that the recommended input volume is not updated unless enough
// frames have been processed after the previous update.
TEST(InputVolumeControllerTest, UpdateInputVolumeWaitFramesIsEffective) {
  constexpr int kInputVolume = kDefaultInitialInputVolume;
  std::unique_ptr<InputVolumeController> controller_wait_0 =
      CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
                                  kClippedWaitFrames,
                                  /*enable_clipping_predictor=*/false,
                                  /*update_input_volume_wait_frames=*/0);
  std::unique_ptr<InputVolumeController> controller_wait_100 =
      CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
                                  kClippedWaitFrames,
                                  /*enable_clipping_predictor=*/false,
                                  /*update_input_volume_wait_frames=*/100);
  controller_wait_0->Initialize();
  controller_wait_100->Initialize();

  SpeechSamplesReader reader_1;
  SpeechSamplesReader reader_2;
  int volume_wait_0 = reader_1.Feed(
      /*num_frames=*/99, kInputVolume, /*gain_db=*/0, kHighSpeechProbability,
      /*speech_level_dbfs=*/-42.0f, *controller_wait_0);
  int volume_wait_100 = reader_2.Feed(
      /*num_frames=*/99, kInputVolume, /*gain_db=*/0, kHighSpeechProbability,
      /*speech_level_dbfs=*/-42.0f, *controller_wait_100);

  // Check that adaptation only occurs if enough frames have been processed.
  ASSERT_GT(volume_wait_0, kInputVolume);
  ASSERT_EQ(volume_wait_100, kInputVolume);

  volume_wait_0 =
      reader_1.Feed(/*num_frames=*/1, volume_wait_0,
                    /*gain_db=*/0, kHighSpeechProbability,
                    /*speech_level_dbfs=*/-42.0f, *controller_wait_0);
  volume_wait_100 =
      reader_2.Feed(/*num_frames=*/1, volume_wait_100,
                    /*gain_db=*/0, kHighSpeechProbability,
                    /*speech_level_dbfs=*/-42.0f, *controller_wait_100);

  // Check that adaptation only occurs when enough frames have been processed.
  ASSERT_GT(volume_wait_0, kInputVolume);
  ASSERT_GT(volume_wait_100, kInputVolume);
}

INSTANTIATE_TEST_SUITE_P(,
                         InputVolumeControllerParametrizedTest,
                         ::testing::Values(12, 20));

TEST(InputVolumeControllerTest,
     MinInputVolumeEnforcedWithClippingWhenAboveClippedLevelMin) {
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = 80, .clipped_level_min = 70});

  // Trigger a downward adjustment caused by clipping input. Use a low speech
  // probability to limit the volume changes to clipping handling.
  WriteAudioBufferSamples(/*samples_value=*/4000.0f, /*clipped_ratio=*/0.8f,
                          helper.audio_buffer);
  constexpr int kNumCalls = 800;
  helper.CallAgcSequence(/*applied_input_volume=*/100, kLowSpeechProbability,
                         /*speech_level_dbfs=*/-18.0f, kNumCalls);

  EXPECT_EQ(helper.controller.recommended_input_volume(), 80);
}

TEST(InputVolumeControllerTest,
     ClippedlevelMinEnforcedWithClippingWhenAboveMinInputVolume) {
  InputVolumeControllerTestHelper helper(
      /*config=*/{.min_input_volume = 70, .clipped_level_min = 80});

  // Trigger a downward adjustment caused by clipping input. Use a low speech
  // probability to limit the volume changes to clipping handling.
  WriteAudioBufferSamples(/*samples_value=*/4000.0f, /*clipped_ratio=*/0.8f,
                          helper.audio_buffer);
  constexpr int kNumCalls = 800;
  helper.CallAgcSequence(/*applied_input_volume=*/100, kLowSpeechProbability,
                         /*speech_level_dbfs=*/-18.0f, kNumCalls);

  EXPECT_EQ(helper.controller.recommended_input_volume(), 80);
}

TEST(InputVolumeControllerTest, SpeechRatioThresholdIsEffective) {
  constexpr int kInputVolume = kDefaultInitialInputVolume;
  // Create two input volume controllers with 10 frames between volume updates
  // and the minimum speech ratio of 0.8 and speech probability threshold 0.5.
  std::unique_ptr<InputVolumeController> controller_1 =
      CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
                                  kClippedWaitFrames,
                                  /*enable_clipping_predictor=*/false,
                                  /*update_input_volume_wait_frames=*/10);
  std::unique_ptr<InputVolumeController> controller_2 =
      CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
                                  kClippedWaitFrames,
                                  /*enable_clipping_predictor=*/false,
                                  /*update_input_volume_wait_frames=*/10);
  controller_1->Initialize();
  controller_2->Initialize();

  SpeechSamplesReader reader_1;
  SpeechSamplesReader reader_2;

  int volume_1 = reader_1.Feed(/*num_frames=*/1, kInputVolume, /*gain_db=*/0,
                               /*speech_probability=*/0.7f,
                               /*speech_level_dbfs=*/-42.0f, *controller_1);
  int volume_2 = reader_2.Feed(/*num_frames=*/1, kInputVolume, /*gain_db=*/0,
                               /*speech_probability=*/0.4f,
                               /*speech_level_dbfs=*/-42.0f, *controller_2);

  ASSERT_EQ(volume_1, kInputVolume);
  ASSERT_EQ(volume_2, kInputVolume);

  volume_1 = reader_1.Feed(/*num_frames=*/2, volume_1, /*gain_db=*/0,
                           /*speech_probability=*/0.4f,
                           /*speech_level_dbfs=*/-42.0f, *controller_1);
  volume_2 = reader_2.Feed(/*num_frames=*/2, volume_2, /*gain_db=*/0,
                           /*speech_probability=*/0.4f,
                           /*speech_level_dbfs=*/-42.0f, *controller_2);

  ASSERT_EQ(volume_1, kInputVolume);
  ASSERT_EQ(volume_2, kInputVolume);

  volume_1 = reader_1.Feed(
      /*num_frames=*/7, volume_1, /*gain_db=*/0,
      /*speech_probability=*/0.7f, /*speech_level_dbfs=*/-42.0f, *controller_1);
  volume_2 = reader_2.Feed(
      /*num_frames=*/7, volume_2, /*gain_db=*/0,
      /*speech_probability=*/0.7f, /*speech_level_dbfs=*/-42.0f, *controller_2);

  ASSERT_GT(volume_1, kInputVolume);
  ASSERT_EQ(volume_2, kInputVolume);
}

TEST(InputVolumeControllerTest, SpeechProbabilityThresholdIsEffective) {
  constexpr int kInputVolume = kDefaultInitialInputVolume;
  // Create two input volume controllers with the exact same settings and
  // 10 frames between volume updates.
  std::unique_ptr<InputVolumeController> controller_1 =
      CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
                                  kClippedWaitFrames,
                                  /*enable_clipping_predictor=*/false,
                                  /*update_input_volume_wait_frames=*/10);
  std::unique_ptr<InputVolumeController> controller_2 =
      CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
                                  kClippedWaitFrames,
                                  /*enable_clipping_predictor=*/false,
                                  /*update_input_volume_wait_frames=*/10);
  controller_1->Initialize();
  controller_2->Initialize();

  SpeechSamplesReader reader_1;
  SpeechSamplesReader reader_2;

  // Process with two sets of inputs: Use `reader_1` to process inputs
  // that make the volume to be adjusted after enough frames have been
  // processsed and `reader_2` to process inputs that won't make the volume
  // to be adjusted.
  int volume_1 = reader_1.Feed(/*num_frames=*/1, kInputVolume, /*gain_db=*/0,
                               /*speech_probability=*/0.5f,
                               /*speech_level_dbfs=*/-42.0f, *controller_1);
  int volume_2 = reader_2.Feed(/*num_frames=*/1, kInputVolume, /*gain_db=*/0,
                               /*speech_probability=*/0.49f,
                               /*speech_level_dbfs=*/-42.0f, *controller_2);

  ASSERT_EQ(volume_1, kInputVolume);
  ASSERT_EQ(volume_2, kInputVolume);

  reader_1.Feed(/*num_frames=*/2, volume_1, /*gain_db=*/0,
                /*speech_probability=*/0.49f, /*speech_level_dbfs=*/-42.0f,
                *controller_1);
  reader_2.Feed(/*num_frames=*/2, volume_2, /*gain_db=*/0,
                /*speech_probability=*/0.49f, /*speech_level_dbfs=*/-42.0f,
                *controller_2);

  ASSERT_EQ(volume_1, kInputVolume);
  ASSERT_EQ(volume_2, kInputVolume);

  volume_1 = reader_1.Feed(
      /*num_frames=*/7, volume_1, /*gain_db=*/0,
      /*speech_probability=*/0.5f, /*speech_level_dbfs=*/-42.0f, *controller_1);
  volume_2 = reader_2.Feed(
      /*num_frames=*/7, volume_2, /*gain_db=*/0,
      /*speech_probability=*/0.5f, /*speech_level_dbfs=*/-42.0f, *controller_2);

  ASSERT_GT(volume_1, kInputVolume);
  ASSERT_EQ(volume_2, kInputVolume);
}

TEST(InputVolumeControllerTest,
     DoNotLogRecommendedInputVolumeOnChangeToMatchTarget) {
  metrics::Reset();

  SpeechSamplesReader reader;
  auto controller = CreateInputVolumeController();
  controller->Initialize();
  // Trigger a downward volume change by inputting audio that clips. Pass a
  // speech level that falls in the target range to make sure that the
  // adaptation is not made to match the target range.
  constexpr int kStartupVolume = 255;
  const int volume = reader.Feed(/*num_frames=*/14, kStartupVolume,
                                 /*gain_db=*/50, kHighSpeechProbability,
                                 /*speech_level_dbfs=*/-20.0f, *controller);
  ASSERT_LT(volume, kStartupVolume);
  EXPECT_METRIC_THAT(
      metrics::Samples(
          "WebRTC.Audio.Apm.RecommendedInputVolume.OnChangeToMatchTarget"),
      ::testing::IsEmpty());
}

TEST(InputVolumeControllerTest,
     LogRecommendedInputVolumeOnUpwardChangeToMatchTarget) {
  metrics::Reset();

  SpeechSamplesReader reader;
  auto controller = CreateInputVolumeController();
  controller->Initialize();
  constexpr int kStartupVolume = 100;
  // Trigger an upward volume change by inputting audio that does not clip and
  // by passing a speech level below the target range.
  const int volume = reader.Feed(/*num_frames=*/14, kStartupVolume,
                                 /*gain_db=*/-6, kHighSpeechProbability,
                                 /*speech_level_dbfs=*/-50.0f, *controller);
  ASSERT_GT(volume, kStartupVolume);
  EXPECT_METRIC_THAT(
      metrics::Samples(
          "WebRTC.Audio.Apm.RecommendedInputVolume.OnChangeToMatchTarget"),
      ::testing::Not(::testing::IsEmpty()));
}

TEST(InputVolumeControllerTest,
     LogRecommendedInputVolumeOnDownwardChangeToMatchTarget) {
  metrics::Reset();

  SpeechSamplesReader reader;
  auto controller = CreateInputVolumeController();
  controller->Initialize();
  constexpr int kStartupVolume = 100;
  // Trigger a downward volume change by inputting audio that does not clip and
  // by passing a speech level above the target range.
  const int volume = reader.Feed(/*num_frames=*/14, kStartupVolume,
                                 /*gain_db=*/-6, kHighSpeechProbability,
                                 /*speech_level_dbfs=*/-5.0f, *controller);
  ASSERT_LT(volume, kStartupVolume);
  EXPECT_METRIC_THAT(
      metrics::Samples(
          "WebRTC.Audio.Apm.RecommendedInputVolume.OnChangeToMatchTarget"),
      ::testing::Not(::testing::IsEmpty()));
}

TEST(MonoInputVolumeControllerTest, CheckHandleClippingLowersVolume) {
  constexpr int kInitialInputVolume = 100;
  constexpr int kInputVolumeStep = 29;
  MonoInputVolumeController mono_controller(
      /*clipped_level_min=*/70,
      /*min_mic_level=*/32,
      /*update_input_volume_wait_frames=*/3, kHighSpeechProbability,
      kSpeechRatioThreshold);
  mono_controller.Initialize();

  UpdateRecommendedInputVolume(mono_controller, kInitialInputVolume,
                               kLowSpeechProbability,
                               /*rms_error_dbfs*/ -10.0f);

  mono_controller.HandleClipping(kInputVolumeStep);

  EXPECT_EQ(mono_controller.recommended_analog_level(),
            kInitialInputVolume - kInputVolumeStep);
}

TEST(MonoInputVolumeControllerTest,
     CheckProcessNegativeRmsErrorDecreasesInputVolume) {
  constexpr int kInitialInputVolume = 100;
  MonoInputVolumeController mono_controller(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/32,
      /*update_input_volume_wait_frames=*/3, kHighSpeechProbability,
      kSpeechRatioThreshold);
  mono_controller.Initialize();

  int volume = UpdateRecommendedInputVolume(
      mono_controller, kInitialInputVolume, kHighSpeechProbability, -10.0f);
  volume = UpdateRecommendedInputVolume(mono_controller, volume,
                                        kHighSpeechProbability, -10.0f);
  volume = UpdateRecommendedInputVolume(mono_controller, volume,
                                        kHighSpeechProbability, -10.0f);

  EXPECT_LT(volume, kInitialInputVolume);
}

TEST(MonoInputVolumeControllerTest,
     CheckProcessPositiveRmsErrorIncreasesInputVolume) {
  constexpr int kInitialInputVolume = 100;
  MonoInputVolumeController mono_controller(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/32,
      /*update_input_volume_wait_frames=*/3, kHighSpeechProbability,
      kSpeechRatioThreshold);
  mono_controller.Initialize();

  int volume = UpdateRecommendedInputVolume(
      mono_controller, kInitialInputVolume, kHighSpeechProbability, 10.0f);
  volume = UpdateRecommendedInputVolume(mono_controller, volume,
                                        kHighSpeechProbability, 10.0f);
  volume = UpdateRecommendedInputVolume(mono_controller, volume,
                                        kHighSpeechProbability, 10.0f);

  EXPECT_GT(volume, kInitialInputVolume);
}

TEST(MonoInputVolumeControllerTest,
     CheckProcessNegativeRmsErrorDecreasesInputVolumeWithLimit) {
  constexpr int kInitialInputVolume = 100;
  MonoInputVolumeController mono_controller_1(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/32,
      /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
      kSpeechRatioThreshold);
  MonoInputVolumeController mono_controller_2(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/32,
      /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
      kSpeechRatioThreshold);
  MonoInputVolumeController mono_controller_3(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/32,
      /*update_input_volume_wait_frames=*/2,
      /*speech_probability_threshold=*/0.7,
      /*speech_ratio_threshold=*/0.8);
  mono_controller_1.Initialize();
  mono_controller_2.Initialize();
  mono_controller_3.Initialize();

  // Process RMS errors in the range
  // [`-kMaxResidualGainChange`, `kMaxResidualGainChange`].
  int volume_1 = UpdateRecommendedInputVolume(
      mono_controller_1, kInitialInputVolume, kHighSpeechProbability, -14.0f);
  volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
                                          kHighSpeechProbability, -14.0f);
  // Process RMS errors outside the range
  // [`-kMaxResidualGainChange`, `kMaxResidualGainChange`].
  int volume_2 = UpdateRecommendedInputVolume(
      mono_controller_2, kInitialInputVolume, kHighSpeechProbability, -15.0f);
  int volume_3 = UpdateRecommendedInputVolume(
      mono_controller_3, kInitialInputVolume, kHighSpeechProbability, -30.0f);
  volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
                                          kHighSpeechProbability, -15.0f);
  volume_3 = UpdateRecommendedInputVolume(mono_controller_3, volume_3,
                                          kHighSpeechProbability, -30.0f);

  EXPECT_LT(volume_1, kInitialInputVolume);
  EXPECT_LT(volume_2, volume_1);
  EXPECT_EQ(volume_2, volume_3);
}

TEST(MonoInputVolumeControllerTest,
     CheckProcessPositiveRmsErrorIncreasesInputVolumeWithLimit) {
  constexpr int kInitialInputVolume = 100;
  MonoInputVolumeController mono_controller_1(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/32,
      /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
      kSpeechRatioThreshold);
  MonoInputVolumeController mono_controller_2(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/32,
      /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
      kSpeechRatioThreshold);
  MonoInputVolumeController mono_controller_3(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/32,
      /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
      kSpeechRatioThreshold);
  mono_controller_1.Initialize();
  mono_controller_2.Initialize();
  mono_controller_3.Initialize();

  // Process RMS errors in the range
  // [`-kMaxResidualGainChange`, `kMaxResidualGainChange`].
  int volume_1 = UpdateRecommendedInputVolume(
      mono_controller_1, kInitialInputVolume, kHighSpeechProbability, 14.0f);
  volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
                                          kHighSpeechProbability, 14.0f);
  // Process RMS errors outside the range
  // [`-kMaxResidualGainChange`, `kMaxResidualGainChange`].
  int volume_2 = UpdateRecommendedInputVolume(
      mono_controller_2, kInitialInputVolume, kHighSpeechProbability, 15.0f);
  int volume_3 = UpdateRecommendedInputVolume(
      mono_controller_3, kInitialInputVolume, kHighSpeechProbability, 30.0f);
  volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
                                          kHighSpeechProbability, 15.0f);
  volume_3 = UpdateRecommendedInputVolume(mono_controller_3, volume_3,
                                          kHighSpeechProbability, 30.0f);

  EXPECT_GT(volume_1, kInitialInputVolume);
  EXPECT_GT(volume_2, volume_1);
  EXPECT_EQ(volume_2, volume_3);
}

TEST(MonoInputVolumeControllerTest,
     CheckProcessRmsErrorDecreasesInputVolumeRepeatedly) {
  constexpr int kInitialInputVolume = 100;
  MonoInputVolumeController mono_controller(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/32,
      /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
      kSpeechRatioThreshold);
  mono_controller.Initialize();

  int volume_before = UpdateRecommendedInputVolume(
      mono_controller, kInitialInputVolume, kHighSpeechProbability, -10.0f);
  volume_before = UpdateRecommendedInputVolume(mono_controller, volume_before,
                                               kHighSpeechProbability, -10.0f);

  EXPECT_LT(volume_before, kInitialInputVolume);

  int volume_after = UpdateRecommendedInputVolume(
      mono_controller, volume_before, kHighSpeechProbability, -10.0f);
  volume_after = UpdateRecommendedInputVolume(mono_controller, volume_after,
                                              kHighSpeechProbability, -10.0f);

  EXPECT_LT(volume_after, volume_before);
}

TEST(MonoInputVolumeControllerTest,
     CheckProcessPositiveRmsErrorIncreasesInputVolumeRepeatedly) {
  constexpr int kInitialInputVolume = 100;
  MonoInputVolumeController mono_controller(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/32,
      /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
      kSpeechRatioThreshold);
  mono_controller.Initialize();

  int volume_before = UpdateRecommendedInputVolume(
      mono_controller, kInitialInputVolume, kHighSpeechProbability, 10.0f);
  volume_before = UpdateRecommendedInputVolume(mono_controller, volume_before,
                                               kHighSpeechProbability, 10.0f);

  EXPECT_GT(volume_before, kInitialInputVolume);

  int volume_after = UpdateRecommendedInputVolume(
      mono_controller, volume_before, kHighSpeechProbability, 10.0f);
  volume_after = UpdateRecommendedInputVolume(mono_controller, volume_after,
                                              kHighSpeechProbability, 10.0f);

  EXPECT_GT(volume_after, volume_before);
}

TEST(MonoInputVolumeControllerTest, CheckClippedLevelMinIsEffective) {
  constexpr int kInitialInputVolume = 100;
  constexpr int kClippedLevelMin = 70;
  MonoInputVolumeController mono_controller_1(
      kClippedLevelMin,
      /*min_mic_level=*/84,
      /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
      kSpeechRatioThreshold);
  MonoInputVolumeController mono_controller_2(
      kClippedLevelMin,
      /*min_mic_level=*/84,
      /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
      kSpeechRatioThreshold);
  mono_controller_1.Initialize();
  mono_controller_2.Initialize();

  // Process one frame to reset the state for `HandleClipping()`.
  EXPECT_EQ(UpdateRecommendedInputVolume(mono_controller_1, kInitialInputVolume,
                                         kLowSpeechProbability, -10.0f),
            kInitialInputVolume);
  EXPECT_EQ(UpdateRecommendedInputVolume(mono_controller_2, kInitialInputVolume,
                                         kLowSpeechProbability, -10.0f),
            kInitialInputVolume);

  mono_controller_1.HandleClipping(29);
  mono_controller_2.HandleClipping(31);

  EXPECT_EQ(mono_controller_2.recommended_analog_level(), kClippedLevelMin);
  EXPECT_LT(mono_controller_2.recommended_analog_level(),
            mono_controller_1.recommended_analog_level());
}

TEST(MonoInputVolumeControllerTest, CheckMinMicLevelIsEffective) {
  constexpr int kInitialInputVolume = 100;
  constexpr int kMinMicLevel = 64;
  MonoInputVolumeController mono_controller_1(
      /*clipped_level_min=*/64, kMinMicLevel,
      /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
      kSpeechRatioThreshold);
  MonoInputVolumeController mono_controller_2(
      /*clipped_level_min=*/64, kMinMicLevel,
      /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
      kSpeechRatioThreshold);
  mono_controller_1.Initialize();
  mono_controller_2.Initialize();

  int volume_1 = UpdateRecommendedInputVolume(
      mono_controller_1, kInitialInputVolume, kHighSpeechProbability, -10.0f);
  int volume_2 = UpdateRecommendedInputVolume(
      mono_controller_2, kInitialInputVolume, kHighSpeechProbability, -10.0f);

  EXPECT_EQ(volume_1, kInitialInputVolume);
  EXPECT_EQ(volume_2, kInitialInputVolume);

  volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
                                          kHighSpeechProbability, -10.0f);
  volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
                                          kHighSpeechProbability, -30.0f);

  EXPECT_LT(volume_1, kInitialInputVolume);
  EXPECT_LT(volume_2, volume_1);
  EXPECT_EQ(volume_2, kMinMicLevel);
}

TEST(MonoInputVolumeControllerTest,
     CheckUpdateInputVolumeWaitFramesIsEffective) {
  constexpr int kInitialInputVolume = 100;
  MonoInputVolumeController mono_controller_1(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/84,
      /*update_input_volume_wait_frames=*/1, kHighSpeechProbability,
      kSpeechRatioThreshold);
  MonoInputVolumeController mono_controller_2(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/84,
      /*update_input_volume_wait_frames=*/3, kHighSpeechProbability,
      kSpeechRatioThreshold);
  mono_controller_1.Initialize();
  mono_controller_2.Initialize();

  int volume_1 = UpdateRecommendedInputVolume(
      mono_controller_1, kInitialInputVolume, kHighSpeechProbability, -10.0f);
  int volume_2 = UpdateRecommendedInputVolume(
      mono_controller_2, kInitialInputVolume, kHighSpeechProbability, -10.0f);

  EXPECT_EQ(volume_1, kInitialInputVolume);
  EXPECT_EQ(volume_2, kInitialInputVolume);

  volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
                                          kHighSpeechProbability, -10.0f);
  volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
                                          kHighSpeechProbability, -10.0f);

  EXPECT_LT(volume_1, kInitialInputVolume);
  EXPECT_EQ(volume_2, kInitialInputVolume);

  volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
                                          kHighSpeechProbability, -10.0f);

  EXPECT_LT(volume_2, kInitialInputVolume);
}

TEST(MonoInputVolumeControllerTest,
     CheckSpeechProbabilityThresholdIsEffective) {
  constexpr int kInitialInputVolume = 100;
  constexpr float kSpeechProbabilityThreshold = 0.8f;
  MonoInputVolumeController mono_controller_1(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/84,
      /*update_input_volume_wait_frames=*/2, kSpeechProbabilityThreshold,
      kSpeechRatioThreshold);
  MonoInputVolumeController mono_controller_2(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/84,
      /*update_input_volume_wait_frames=*/2, kSpeechProbabilityThreshold,
      kSpeechRatioThreshold);
  mono_controller_1.Initialize();
  mono_controller_2.Initialize();

  int volume_1 =
      UpdateRecommendedInputVolume(mono_controller_1, kInitialInputVolume,
                                   kSpeechProbabilityThreshold, -10.0f);
  int volume_2 =
      UpdateRecommendedInputVolume(mono_controller_2, kInitialInputVolume,
                                   kSpeechProbabilityThreshold, -10.0f);

  EXPECT_EQ(volume_1, kInitialInputVolume);
  EXPECT_EQ(volume_2, kInitialInputVolume);

  volume_1 = UpdateRecommendedInputVolume(
      mono_controller_1, volume_1, kSpeechProbabilityThreshold - 0.1f, -10.0f);
  volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
                                          kSpeechProbabilityThreshold, -10.0f);

  EXPECT_EQ(volume_1, kInitialInputVolume);
  EXPECT_LT(volume_2, volume_1);
}

TEST(MonoInputVolumeControllerTest, CheckSpeechRatioThresholdIsEffective) {
  constexpr int kInitialInputVolume = 100;
  MonoInputVolumeController mono_controller_1(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/84,
      /*update_input_volume_wait_frames=*/4, kHighSpeechProbability,
      /*speech_ratio_threshold=*/0.75f);
  MonoInputVolumeController mono_controller_2(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/84,
      /*update_input_volume_wait_frames=*/4, kHighSpeechProbability,
      /*speech_ratio_threshold=*/0.75f);
  mono_controller_1.Initialize();
  mono_controller_2.Initialize();

  int volume_1 = UpdateRecommendedInputVolume(
      mono_controller_1, kInitialInputVolume, kHighSpeechProbability, -10.0f);
  int volume_2 = UpdateRecommendedInputVolume(
      mono_controller_2, kInitialInputVolume, kHighSpeechProbability, -10.0f);

  volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
                                          kHighSpeechProbability, -10.0f);
  volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
                                          kHighSpeechProbability, -10.0f);

  volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
                                          kLowSpeechProbability, -10.0f);
  volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
                                          kLowSpeechProbability, -10.0f);

  EXPECT_EQ(volume_1, kInitialInputVolume);
  EXPECT_EQ(volume_2, kInitialInputVolume);

  volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
                                          kLowSpeechProbability, -10.0f);
  volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
                                          kHighSpeechProbability, -10.0f);

  EXPECT_EQ(volume_1, kInitialInputVolume);
  EXPECT_LT(volume_2, volume_1);
}

TEST(MonoInputVolumeControllerTest,
     CheckProcessEmptyRmsErrorDoesNotLowerVolume) {
  constexpr int kInitialInputVolume = 100;
  MonoInputVolumeController mono_controller_1(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/84,
      /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
      kSpeechRatioThreshold);
  MonoInputVolumeController mono_controller_2(
      /*clipped_level_min=*/64,
      /*min_mic_level=*/84,
      /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
      kSpeechRatioThreshold);
  mono_controller_1.Initialize();
  mono_controller_2.Initialize();

  int volume_1 = UpdateRecommendedInputVolume(
      mono_controller_1, kInitialInputVolume, kHighSpeechProbability, -10.0f);
  int volume_2 = UpdateRecommendedInputVolume(
      mono_controller_2, kInitialInputVolume, kHighSpeechProbability, -10.0f);

  EXPECT_EQ(volume_1, kInitialInputVolume);
  EXPECT_EQ(volume_2, kInitialInputVolume);

  volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
                                          kHighSpeechProbability, std::nullopt);
  volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
                                          kHighSpeechProbability, -10.0f);

  EXPECT_EQ(volume_1, kInitialInputVolume);
  EXPECT_LT(volume_2, volume_1);
}

}  // namespace webrtc
