xref: /aosp_15_r20/external/webrtc/modules/audio_processing/agc2/input_volume_controller_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/audio_processing/agc2/input_volume_controller.h"
12 
13 #include <algorithm>
14 #include <fstream>
15 #include <limits>
16 #include <string>
17 #include <vector>
18 
19 #include "rtc_base/numerics/safe_minmax.h"
20 #include "rtc_base/strings/string_builder.h"
21 #include "test/field_trial.h"
22 #include "test/gmock.h"
23 #include "test/gtest.h"
24 #include "test/testsupport/file_utils.h"
25 
26 using ::testing::_;
27 using ::testing::AtLeast;
28 using ::testing::DoAll;
29 using ::testing::Return;
30 using ::testing::SetArgPointee;
31 
32 namespace webrtc {
33 namespace {
34 
35 constexpr int kSampleRateHz = 32000;
36 constexpr int kNumChannels = 1;
37 constexpr int kInitialInputVolume = 128;
38 constexpr int kClippedMin = 165;  // Arbitrary, but different from the default.
39 constexpr float kAboveClippedThreshold = 0.2f;
40 constexpr int kMinMicLevel = 12;
41 constexpr int kClippedLevelStep = 15;
42 constexpr float kClippedRatioThreshold = 0.1f;
43 constexpr int kClippedWaitFrames = 300;
44 constexpr float kHighSpeechProbability = 0.7f;
45 constexpr float kLowSpeechProbability = 0.1f;
46 constexpr float kSpeechLevel = -25.0f;
47 constexpr float kSpeechProbabilityThreshold = 0.5f;
48 constexpr float kSpeechRatioThreshold = 0.8f;
49 
50 constexpr float kMinSample = std::numeric_limits<int16_t>::min();
51 constexpr float kMaxSample = std::numeric_limits<int16_t>::max();
52 
53 using ClippingPredictorConfig = AudioProcessing::Config::GainController1::
54     AnalogGainController::ClippingPredictor;
55 
56 using InputVolumeControllerConfig = InputVolumeController::Config;
57 
58 constexpr InputVolumeControllerConfig kDefaultInputVolumeControllerConfig{};
59 constexpr ClippingPredictorConfig kDefaultClippingPredictorConfig{};
60 
CreateInputVolumeController(int clipped_level_step,float clipped_ratio_threshold,int clipped_wait_frames,bool enable_clipping_predictor=false,int update_input_volume_wait_frames=0)61 std::unique_ptr<InputVolumeController> CreateInputVolumeController(
62     int clipped_level_step,
63     float clipped_ratio_threshold,
64     int clipped_wait_frames,
65     bool enable_clipping_predictor = false,
66     int update_input_volume_wait_frames = 0) {
67   InputVolumeControllerConfig config{
68       .clipped_level_min = kClippedMin,
69       .clipped_level_step = clipped_level_step,
70       .clipped_ratio_threshold = clipped_ratio_threshold,
71       .clipped_wait_frames = clipped_wait_frames,
72       .enable_clipping_predictor = enable_clipping_predictor,
73       .target_range_max_dbfs = -18,
74       .target_range_min_dbfs = -30,
75       .update_input_volume_wait_frames = update_input_volume_wait_frames,
76       .speech_probability_threshold = kSpeechProbabilityThreshold,
77       .speech_ratio_threshold = kSpeechRatioThreshold,
78   };
79 
80   return std::make_unique<InputVolumeController>(/*num_capture_channels=*/1,
81                                                  config);
82 }
83 
84 // Deprecated.
85 // TODO(bugs.webrtc.org/7494): Delete this helper, use
86 // `InputVolumeControllerTestHelper::CallAgcSequence()` instead.
87 // Calls `AnalyzePreProcess()` on `controller` `num_calls` times. `peak_ratio`
88 // is a value in [0, 1] which determines the amplitude of the samples (1 maps to
89 // full scale). The first half of the calls is made on frames which are half
90 // filled with zeros in order to simulate a signal with different crest factors.
CallPreProcessAudioBuffer(int num_calls,float peak_ratio,InputVolumeController & controller)91 void CallPreProcessAudioBuffer(int num_calls,
92                                float peak_ratio,
93                                InputVolumeController& controller) {
94   RTC_DCHECK_LE(peak_ratio, 1.0f);
95   AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
96                            kNumChannels, kSampleRateHz, kNumChannels);
97   const int num_channels = audio_buffer.num_channels();
98   const int num_frames = audio_buffer.num_frames();
99 
100   // Make half of the calls with half zeroed frames.
101   for (int ch = 0; ch < num_channels; ++ch) {
102     // 50% of the samples in one frame are zero.
103     for (int i = 0; i < num_frames; i += 2) {
104       audio_buffer.channels()[ch][i] = peak_ratio * 32767.0f;
105       audio_buffer.channels()[ch][i + 1] = 0.0f;
106     }
107   }
108   for (int n = 0; n < num_calls / 2; ++n) {
109     controller.AnalyzePreProcess(audio_buffer);
110   }
111 
112   // Make the remaining half of the calls with frames whose samples are all set.
113   for (int ch = 0; ch < num_channels; ++ch) {
114     for (int i = 0; i < num_frames; ++i) {
115       audio_buffer.channels()[ch][i] = peak_ratio * 32767.0f;
116     }
117   }
118   for (int n = 0; n < num_calls - num_calls / 2; ++n) {
119     controller.AnalyzePreProcess(audio_buffer);
120   }
121 }
122 
123 constexpr char kMinInputVolumeFieldTrial[] = "WebRTC-Audio-Agc2-MinInputVolume";
124 
GetAgcMinInputVolumeFieldTrial(const std::string & value)125 std::string GetAgcMinInputVolumeFieldTrial(const std::string& value) {
126   char field_trial_buffer[64];
127   rtc::SimpleStringBuilder builder(field_trial_buffer);
128   builder << kMinInputVolumeFieldTrial << "/" << value << "/";
129   return builder.str();
130 }
131 
GetAgcMinInputVolumeFieldTrialEnabled(int enabled_value,const std::string & suffix="")132 std::string GetAgcMinInputVolumeFieldTrialEnabled(
133     int enabled_value,
134     const std::string& suffix = "") {
135   RTC_DCHECK_GE(enabled_value, 0);
136   RTC_DCHECK_LE(enabled_value, 255);
137   char field_trial_buffer[64];
138   rtc::SimpleStringBuilder builder(field_trial_buffer);
139   builder << kMinInputVolumeFieldTrial << "/Enabled-" << enabled_value << suffix
140           << "/";
141   return builder.str();
142 }
143 
GetAgcMinInputVolumeFieldTrial(absl::optional<int> volume)144 std::string GetAgcMinInputVolumeFieldTrial(absl::optional<int> volume) {
145   if (volume.has_value()) {
146     return GetAgcMinInputVolumeFieldTrialEnabled(*volume);
147   }
148   return GetAgcMinInputVolumeFieldTrial("Disabled");
149 }
150 
151 // (Over)writes `samples_value` for the samples in `audio_buffer`.
152 // When `clipped_ratio`, a value in [0, 1], is greater than 0, the corresponding
153 // fraction of the frame is set to a full scale value to simulate clipping.
WriteAudioBufferSamples(float samples_value,float clipped_ratio,AudioBuffer & audio_buffer)154 void WriteAudioBufferSamples(float samples_value,
155                              float clipped_ratio,
156                              AudioBuffer& audio_buffer) {
157   RTC_DCHECK_GE(samples_value, kMinSample);
158   RTC_DCHECK_LE(samples_value, kMaxSample);
159   RTC_DCHECK_GE(clipped_ratio, 0.0f);
160   RTC_DCHECK_LE(clipped_ratio, 1.0f);
161   int num_channels = audio_buffer.num_channels();
162   int num_samples = audio_buffer.num_frames();
163   int num_clipping_samples = clipped_ratio * num_samples;
164   for (int ch = 0; ch < num_channels; ++ch) {
165     int i = 0;
166     for (; i < num_clipping_samples; ++i) {
167       audio_buffer.channels()[ch][i] = 32767.0f;
168     }
169     for (; i < num_samples; ++i) {
170       audio_buffer.channels()[ch][i] = samples_value;
171     }
172   }
173 }
174 
175 // Deprecated.
176 // TODO(bugs.webrtc.org/7494): Delete this helper, use
177 // `InputVolumeControllerTestHelper::CallAgcSequence()` instead.
CallPreProcessAndProcess(int num_calls,const AudioBuffer & audio_buffer,float speech_probability,absl::optional<float> speech_level,InputVolumeController & controller)178 void CallPreProcessAndProcess(int num_calls,
179                               const AudioBuffer& audio_buffer,
180                               float speech_probability,
181                               absl::optional<float> speech_level,
182                               InputVolumeController& controller) {
183   for (int n = 0; n < num_calls; ++n) {
184     controller.AnalyzePreProcess(audio_buffer);
185     controller.Process(speech_probability, speech_level);
186   }
187 }
188 
189 // Reads a given number of 10 ms chunks from a PCM file and feeds them to
190 // `InputVolumeController`.
191 class SpeechSamplesReader {
192  private:
193   // Recording properties.
194   static constexpr int kPcmSampleRateHz = 16000;
195   static constexpr int kPcmNumChannels = 1;
196   static constexpr int kPcmBytesPerSamples = sizeof(int16_t);
197 
198  public:
SpeechSamplesReader()199   SpeechSamplesReader()
200       : is_(test::ResourcePath("audio_processing/agc/agc_audio", "pcm"),
201             std::ios::binary | std::ios::ate),
202         audio_buffer_(kPcmSampleRateHz,
203                       kPcmNumChannels,
204                       kPcmSampleRateHz,
205                       kPcmNumChannels,
206                       kPcmSampleRateHz,
207                       kPcmNumChannels),
208         buffer_(audio_buffer_.num_frames()),
209         buffer_num_bytes_(buffer_.size() * kPcmBytesPerSamples) {
210     RTC_CHECK(is_);
211   }
212 
213   // Reads `num_frames` 10 ms frames from the beginning of the PCM file, applies
214   // `gain_db` and feeds the frames into `controller` by calling
215   // `AnalyzePreProcess()` and `Process()` for each frame. Reads the number of
216   // 10 ms frames available in the PCM file if `num_frames` is too large - i.e.,
217   // does not loop. `speech_probability` and `speech_level` are passed to
218   // `Process()`.
Feed(int num_frames,int gain_db,float speech_probability,absl::optional<float> speech_level,InputVolumeController & controller)219   void Feed(int num_frames,
220             int gain_db,
221             float speech_probability,
222             absl::optional<float> speech_level,
223             InputVolumeController& controller) {
224     float gain = std::pow(10.0f, gain_db / 20.0f);  // From dB to linear gain.
225     is_.seekg(0, is_.beg);  // Start from the beginning of the PCM file.
226 
227     // Read and feed frames.
228     for (int i = 0; i < num_frames; ++i) {
229       is_.read(reinterpret_cast<char*>(buffer_.data()), buffer_num_bytes_);
230       if (is_.gcount() < buffer_num_bytes_) {
231         // EOF reached. Stop.
232         break;
233       }
234       // Apply gain and copy samples into `audio_buffer_`.
235       std::transform(buffer_.begin(), buffer_.end(),
236                      audio_buffer_.channels()[0], [gain](int16_t v) -> float {
237                        return rtc::SafeClamp(static_cast<float>(v) * gain,
238                                              kMinSample, kMaxSample);
239                      });
240 
241       controller.AnalyzePreProcess(audio_buffer_);
242       controller.Process(speech_probability, speech_level);
243     }
244   }
245 
246  private:
247   std::ifstream is_;
248   AudioBuffer audio_buffer_;
249   std::vector<int16_t> buffer_;
250   const std::streamsize buffer_num_bytes_;
251 };
252 
253 // Runs the MonoInputVolumeControl processing sequence following the API
254 // contract. Returns the updated recommended input volume.
UpdateRecommendedInputVolume(MonoInputVolumeController & controller,int applied_input_volume,float speech_probability,const absl::optional<float> rms_error_dbfs)255 float UpdateRecommendedInputVolume(MonoInputVolumeController& controller,
256                                    int applied_input_volume,
257                                    float speech_probability,
258                                    const absl::optional<float> rms_error_dbfs) {
259   controller.set_stream_analog_level(applied_input_volume);
260   EXPECT_EQ(controller.recommended_analog_level(), applied_input_volume);
261   controller.Process(rms_error_dbfs, speech_probability);
262   return controller.recommended_analog_level();
263 }
264 
265 }  // namespace
266 
267 // TODO(bugs.webrtc.org/12874): Use constexpr struct with designated
268 // initializers once fixed.
GetInputVolumeControllerTestConfig()269 constexpr InputVolumeControllerConfig GetInputVolumeControllerTestConfig() {
270   InputVolumeControllerConfig config{
271       .clipped_level_min = kClippedMin,
272       .clipped_level_step = kClippedLevelStep,
273       .clipped_ratio_threshold = kClippedRatioThreshold,
274       .clipped_wait_frames = kClippedWaitFrames,
275       .enable_clipping_predictor = kDefaultClippingPredictorConfig.enabled,
276       .target_range_max_dbfs = -18,
277       .target_range_min_dbfs = -30,
278       .update_input_volume_wait_frames = 0,
279       .speech_probability_threshold = 0.5f,
280       .speech_ratio_threshold = 1.0f,
281   };
282   return config;
283 }
284 
285 // Helper class that provides an `InputVolumeController` instance with an
286 // `AudioBuffer` instance and `CallAgcSequence()`, a helper method that runs the
287 // `InputVolumeController` instance on the `AudioBuffer` one by sticking to the
288 // API contract.
289 class InputVolumeControllerTestHelper {
290  public:
291   // Ctor. Initializes `audio_buffer` with zeros.
InputVolumeControllerTestHelper()292   InputVolumeControllerTestHelper()
293       : audio_buffer(kSampleRateHz,
294                      kNumChannels,
295                      kSampleRateHz,
296                      kNumChannels,
297                      kSampleRateHz,
298                      kNumChannels),
299         controller(/*num_capture_channels=*/1,
300                    GetInputVolumeControllerTestConfig()) {
301     controller.Initialize();
302     WriteAudioBufferSamples(/*samples_value=*/0.0f, /*clipped_ratio=*/0.0f,
303                             audio_buffer);
304   }
305 
306   // Calls the sequence of `InputVolumeController` methods according to the API
307   // contract, namely:
308   // - Sets the applied input volume;
309   // - Uses `audio_buffer` to call `AnalyzePreProcess()` and `Process()`;
310   //  Returns the recommended input volume.
CallAgcSequence(int applied_input_volume,float speech_probability,absl::optional<float> speech_level)311   int CallAgcSequence(int applied_input_volume,
312                       float speech_probability,
313                       absl::optional<float> speech_level) {
314     controller.set_stream_analog_level(applied_input_volume);
315     controller.AnalyzePreProcess(audio_buffer);
316     controller.Process(speech_probability, speech_level);
317 
318     return controller.recommended_analog_level();
319   }
320 
321   // Deprecated.
322   // TODO(bugs.webrtc.org/7494): Let the caller write `audio_buffer` and use
323   // `CallAgcSequence()`.
CallProcess(int num_calls,float speech_probability,absl::optional<float> speech_level)324   void CallProcess(int num_calls,
325                    float speech_probability,
326                    absl::optional<float> speech_level) {
327     for (int i = 0; i < num_calls; ++i) {
328       controller.Process(speech_probability, speech_level);
329     }
330   }
331 
332   // Deprecated.
333   // TODO(bugs.webrtc.org/7494): Let the caller write `audio_buffer` and use
334   // `CallAgcSequence()`.
CallPreProc(int num_calls,float clipped_ratio)335   void CallPreProc(int num_calls, float clipped_ratio) {
336     RTC_DCHECK_GE(clipped_ratio, 0.0f);
337     RTC_DCHECK_LE(clipped_ratio, 1.0f);
338     WriteAudioBufferSamples(/*samples_value=*/0.0f, clipped_ratio,
339                             audio_buffer);
340     for (int i = 0; i < num_calls; ++i) {
341       controller.AnalyzePreProcess(audio_buffer);
342     }
343   }
344 
345   // Deprecated.
346   // TODO(bugs.webrtc.org/7494): Let the caller write `audio_buffer` and use
347   // `CallAgcSequence()`.
CallPreProcForChangingAudio(int num_calls,float peak_ratio)348   void CallPreProcForChangingAudio(int num_calls, float peak_ratio) {
349     RTC_DCHECK_GE(peak_ratio, 0.0f);
350     RTC_DCHECK_LE(peak_ratio, 1.0f);
351     const float samples_value = peak_ratio * 32767.0f;
352 
353     // Make half of the calls on a frame where the samples alternate
354     // `sample_values` and zeros.
355     WriteAudioBufferSamples(samples_value, /*clipped_ratio=*/0.0f,
356                             audio_buffer);
357     for (size_t ch = 0; ch < audio_buffer.num_channels(); ++ch) {
358       for (size_t k = 1; k < audio_buffer.num_frames(); k += 2) {
359         audio_buffer.channels()[ch][k] = 0.0f;
360       }
361     }
362     for (int i = 0; i < num_calls / 2; ++i) {
363       controller.AnalyzePreProcess(audio_buffer);
364     }
365 
366     // Make half of thecalls on a frame where all the samples equal
367     // `sample_values`.
368     WriteAudioBufferSamples(samples_value, /*clipped_ratio=*/0.0f,
369                             audio_buffer);
370     for (int i = 0; i < num_calls - num_calls / 2; ++i) {
371       controller.AnalyzePreProcess(audio_buffer);
372     }
373   }
374 
375   AudioBuffer audio_buffer;
376   InputVolumeController controller;
377 };
378 
379 class InputVolumeControllerParametrizedTest
380     : public ::testing::TestWithParam<absl::optional<int>> {
381  protected:
InputVolumeControllerParametrizedTest()382   InputVolumeControllerParametrizedTest()
383       : field_trials_(GetAgcMinInputVolumeFieldTrial(GetParam())) {}
384 
GetMinInputVolume() const385   int GetMinInputVolume() const { return GetParam().value_or(kMinMicLevel); }
386 
387  private:
388   test::ScopedFieldTrials field_trials_;
389 };
390 
391 INSTANTIATE_TEST_SUITE_P(,
392                          InputVolumeControllerParametrizedTest,
393                          ::testing::Values(absl::nullopt, 12, 20));
394 
TEST_P(InputVolumeControllerParametrizedTest,StartupMinVolumeConfigurationIsRespected)395 TEST_P(InputVolumeControllerParametrizedTest,
396        StartupMinVolumeConfigurationIsRespected) {
397   InputVolumeControllerTestHelper helper;
398 
399   helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
400                          kSpeechLevel);
401 
402   EXPECT_EQ(kInitialInputVolume, helper.controller.recommended_analog_level());
403 }
404 
TEST_P(InputVolumeControllerParametrizedTest,MicVolumeResponseToRmsError)405 TEST_P(InputVolumeControllerParametrizedTest, MicVolumeResponseToRmsError) {
406   InputVolumeControllerTestHelper helper;
407   helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
408                          kSpeechLevel);
409 
410   // Inside the digital gain's window; no change of volume.
411   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -23.0f);
412 
413   // Inside the digital gain's window; no change of volume.
414   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -28.0f);
415 
416   // Above the digital gain's  window; volume should be increased.
417   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -29.0f);
418   EXPECT_EQ(helper.controller.recommended_analog_level(), 128);
419 
420   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -38.0f);
421   EXPECT_EQ(helper.controller.recommended_analog_level(), 156);
422 
423   // Inside the digital gain's window; no change of volume.
424   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -23.0f);
425   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -18.0f);
426 
427   // Below the digial gain's window; volume should be decreased.
428   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
429   EXPECT_EQ(helper.controller.recommended_analog_level(), 155);
430 
431   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
432   EXPECT_EQ(helper.controller.recommended_analog_level(), 151);
433 
434   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -9.0f);
435   EXPECT_EQ(helper.controller.recommended_analog_level(), 119);
436 }
437 
TEST_P(InputVolumeControllerParametrizedTest,MicVolumeIsLimited)438 TEST_P(InputVolumeControllerParametrizedTest, MicVolumeIsLimited) {
439   InputVolumeControllerTestHelper helper;
440   helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
441                          kSpeechLevel);
442 
443   // Maximum upwards change is limited.
444   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
445   EXPECT_EQ(helper.controller.recommended_analog_level(), 183);
446 
447   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
448   EXPECT_EQ(helper.controller.recommended_analog_level(), 243);
449 
450   // Won't go higher than the maximum.
451   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
452   EXPECT_EQ(helper.controller.recommended_analog_level(), 255);
453 
454   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
455   EXPECT_EQ(helper.controller.recommended_analog_level(), 254);
456 
457   // Maximum downwards change is limited.
458   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
459   EXPECT_EQ(helper.controller.recommended_analog_level(), 194);
460 
461   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
462   EXPECT_EQ(helper.controller.recommended_analog_level(), 137);
463 
464   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
465   EXPECT_EQ(helper.controller.recommended_analog_level(), 88);
466 
467   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
468   EXPECT_EQ(helper.controller.recommended_analog_level(), 54);
469 
470   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
471   EXPECT_EQ(helper.controller.recommended_analog_level(), 33);
472 
473   // Won't go lower than the minimum.
474   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
475   EXPECT_EQ(helper.controller.recommended_analog_level(),
476             std::max(18, GetMinInputVolume()));
477 
478   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
479   EXPECT_EQ(helper.controller.recommended_analog_level(),
480             std::max(12, GetMinInputVolume()));
481 }
482 
TEST_P(InputVolumeControllerParametrizedTest,NoActionWhileMuted)483 TEST_P(InputVolumeControllerParametrizedTest, NoActionWhileMuted) {
484   InputVolumeControllerTestHelper helper;
485   helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
486                          kSpeechLevel);
487 
488   helper.controller.HandleCaptureOutputUsedChange(false);
489   helper.controller.Process(kHighSpeechProbability, kSpeechLevel);
490 }
491 
TEST_P(InputVolumeControllerParametrizedTest,UnmutingChecksVolumeWithoutRaising)492 TEST_P(InputVolumeControllerParametrizedTest,
493        UnmutingChecksVolumeWithoutRaising) {
494   InputVolumeControllerTestHelper helper;
495   helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
496                          kSpeechLevel);
497 
498   helper.controller.HandleCaptureOutputUsedChange(false);
499   helper.controller.HandleCaptureOutputUsedChange(true);
500 
501   constexpr int kInputVolume = 127;
502   helper.controller.set_stream_analog_level(kInputVolume);
503 
504   // SetMicVolume should not be called.
505   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, kSpeechLevel);
506   EXPECT_EQ(helper.controller.recommended_analog_level(), 127);
507 }
508 
TEST_P(InputVolumeControllerParametrizedTest,UnmutingRaisesTooLowVolume)509 TEST_P(InputVolumeControllerParametrizedTest, UnmutingRaisesTooLowVolume) {
510   InputVolumeControllerTestHelper helper;
511   helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
512                          kSpeechLevel);
513 
514   helper.controller.HandleCaptureOutputUsedChange(false);
515   helper.controller.HandleCaptureOutputUsedChange(true);
516 
517   constexpr int kInputVolume = 11;
518   helper.controller.set_stream_analog_level(kInputVolume);
519 
520   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, kSpeechLevel);
521   EXPECT_EQ(helper.controller.recommended_analog_level(), GetMinInputVolume());
522 }
523 
TEST_P(InputVolumeControllerParametrizedTest,ManualLevelChangeResultsInNoSetMicCall)524 TEST_P(InputVolumeControllerParametrizedTest,
525        ManualLevelChangeResultsInNoSetMicCall) {
526   InputVolumeControllerTestHelper helper;
527   helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
528                          kSpeechLevel);
529 
530   // GetMicVolume returns a value outside of the quantization slack, indicating
531   // a manual volume change.
532   ASSERT_NE(helper.controller.recommended_analog_level(), 154);
533   helper.controller.set_stream_analog_level(154);
534   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -29.0f);
535   EXPECT_EQ(helper.controller.recommended_analog_level(), 154);
536 
537   // Do the same thing, except downwards now.
538   helper.controller.set_stream_analog_level(100);
539   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
540   EXPECT_EQ(helper.controller.recommended_analog_level(), 100);
541 
542   // And finally verify the AGC continues working without a manual change.
543   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
544   EXPECT_EQ(helper.controller.recommended_analog_level(), 99);
545 }
546 
TEST_P(InputVolumeControllerParametrizedTest,RecoveryAfterManualLevelChangeFromMax)547 TEST_P(InputVolumeControllerParametrizedTest,
548        RecoveryAfterManualLevelChangeFromMax) {
549   InputVolumeControllerTestHelper helper;
550   helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
551                          kSpeechLevel);
552 
553   // Force the mic up to max volume. Takes a few steps due to the residual
554   // gain limitation.
555   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
556   EXPECT_EQ(helper.controller.recommended_analog_level(), 183);
557   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
558   EXPECT_EQ(helper.controller.recommended_analog_level(), 243);
559   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
560   EXPECT_EQ(helper.controller.recommended_analog_level(), 255);
561 
562   // Manual change does not result in SetMicVolume call.
563   helper.controller.set_stream_analog_level(50);
564   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
565   EXPECT_EQ(helper.controller.recommended_analog_level(), 50);
566 
567   // Continues working as usual afterwards.
568   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -38.0f);
569 
570   EXPECT_EQ(helper.controller.recommended_analog_level(), 65);
571 }
572 
573 // Checks that the minimum input volume is enforced during the upward adjustment
574 // of the input volume.
TEST_P(InputVolumeControllerParametrizedTest,EnforceMinInputVolumeDuringUpwardsAdjustment)575 TEST_P(InputVolumeControllerParametrizedTest,
576        EnforceMinInputVolumeDuringUpwardsAdjustment) {
577   InputVolumeControllerTestHelper helper;
578   helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
579                          kSpeechLevel);
580 
581   // Manual change below min, but strictly positive, otherwise no action will be
582   // taken.
583   helper.controller.set_stream_analog_level(1);
584   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
585 
586   // Trigger an upward adjustment of the input volume.
587   EXPECT_EQ(helper.controller.recommended_analog_level(), GetMinInputVolume());
588   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -29.0f);
589   EXPECT_EQ(helper.controller.recommended_analog_level(), GetMinInputVolume());
590   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
591   EXPECT_EQ(helper.controller.recommended_analog_level(), GetMinInputVolume());
592 
593   // After a number of consistently low speech level observations, the input
594   // volume is eventually raised above the minimum.
595   helper.CallProcess(/*num_calls=*/10, kHighSpeechProbability, -38.0f);
596   EXPECT_GT(helper.controller.recommended_analog_level(), GetMinInputVolume());
597 }
598 
599 // Checks that, when the min mic level override is specified, AGC immediately
600 // applies the minimum mic level after the mic level is manually set below the
601 // minimum gain to enforce.
TEST_P(InputVolumeControllerParametrizedTest,RecoveryAfterManualLevelChangeBelowMin)602 TEST_P(InputVolumeControllerParametrizedTest,
603        RecoveryAfterManualLevelChangeBelowMin) {
604   InputVolumeControllerTestHelper helper;
605   helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
606                          kSpeechLevel);
607 
608   // Manual change below min, but strictly positive, otherwise
609   // AGC won't take any action.
610   helper.controller.set_stream_analog_level(1);
611   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
612   EXPECT_EQ(GetMinInputVolume(), helper.controller.recommended_analog_level());
613 }
614 
TEST_P(InputVolumeControllerParametrizedTest,NoClippingHasNoImpact)615 TEST_P(InputVolumeControllerParametrizedTest, NoClippingHasNoImpact) {
616   InputVolumeControllerTestHelper helper;
617   helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
618                          kSpeechLevel);
619 
620   helper.CallPreProc(/*num_calls=*/100, /*clipped_ratio=*/0);
621   EXPECT_EQ(helper.controller.recommended_analog_level(), 128);
622 }
623 
TEST_P(InputVolumeControllerParametrizedTest,ClippingUnderThresholdHasNoImpact)624 TEST_P(InputVolumeControllerParametrizedTest,
625        ClippingUnderThresholdHasNoImpact) {
626   InputVolumeControllerTestHelper helper;
627   helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
628                          kSpeechLevel);
629 
630   helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/0.099);
631   EXPECT_EQ(helper.controller.recommended_analog_level(), 128);
632 }
633 
TEST_P(InputVolumeControllerParametrizedTest,ClippingLowersVolume)634 TEST_P(InputVolumeControllerParametrizedTest, ClippingLowersVolume) {
635   InputVolumeControllerTestHelper helper;
636   helper.CallAgcSequence(/*applied_input_volume=*/255, kHighSpeechProbability,
637                          kSpeechLevel);
638 
639   helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/0.2);
640   EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
641 }
642 
TEST_P(InputVolumeControllerParametrizedTest,WaitingPeriodBetweenClippingChecks)643 TEST_P(InputVolumeControllerParametrizedTest,
644        WaitingPeriodBetweenClippingChecks) {
645   InputVolumeControllerTestHelper helper;
646   helper.CallAgcSequence(/*applied_input_volume=*/255, kHighSpeechProbability,
647                          kSpeechLevel);
648 
649   helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
650   EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
651 
652   helper.CallPreProc(/*num_calls=*/300,
653                      /*clipped_ratio=*/kAboveClippedThreshold);
654   EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
655 
656   helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
657   EXPECT_EQ(helper.controller.recommended_analog_level(), 225);
658 }
659 
TEST_P(InputVolumeControllerParametrizedTest,ClippingLoweringIsLimited)660 TEST_P(InputVolumeControllerParametrizedTest, ClippingLoweringIsLimited) {
661   InputVolumeControllerTestHelper helper;
662   helper.CallAgcSequence(/*applied_input_volume=*/180, kHighSpeechProbability,
663                          kSpeechLevel);
664 
665   helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
666   EXPECT_EQ(helper.controller.recommended_analog_level(), kClippedMin);
667 
668   helper.CallPreProc(/*num_calls=*/1000,
669                      /*clipped_ratio=*/kAboveClippedThreshold);
670   EXPECT_EQ(helper.controller.recommended_analog_level(), kClippedMin);
671 }
672 
TEST_P(InputVolumeControllerParametrizedTest,ClippingMaxIsRespectedWhenEqualToLevel)673 TEST_P(InputVolumeControllerParametrizedTest,
674        ClippingMaxIsRespectedWhenEqualToLevel) {
675   InputVolumeControllerTestHelper helper;
676   helper.CallAgcSequence(/*applied_input_volume=*/255, kHighSpeechProbability,
677                          kSpeechLevel);
678 
679   helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
680   EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
681 
682   helper.CallProcess(/*num_calls=*/10, kHighSpeechProbability, -48.0f);
683   EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
684 }
685 
TEST_P(InputVolumeControllerParametrizedTest,ClippingMaxIsRespectedWhenHigherThanLevel)686 TEST_P(InputVolumeControllerParametrizedTest,
687        ClippingMaxIsRespectedWhenHigherThanLevel) {
688   InputVolumeControllerTestHelper helper;
689   helper.CallAgcSequence(/*applied_input_volume=*/200, kHighSpeechProbability,
690                          kSpeechLevel);
691 
692   helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
693   EXPECT_EQ(helper.controller.recommended_analog_level(), 185);
694 
695   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -58.0f);
696   EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
697   helper.CallProcess(/*num_calls=*/10, kHighSpeechProbability, -58.0f);
698   EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
699 }
700 
TEST_P(InputVolumeControllerParametrizedTest,UserCanRaiseVolumeAfterClipping)701 TEST_P(InputVolumeControllerParametrizedTest, UserCanRaiseVolumeAfterClipping) {
702   InputVolumeControllerTestHelper helper;
703   helper.CallAgcSequence(/*applied_input_volume=*/225, kHighSpeechProbability,
704                          kSpeechLevel);
705 
706   helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
707   EXPECT_EQ(helper.controller.recommended_analog_level(), 210);
708 
709   // User changed the volume.
710   helper.controller.set_stream_analog_level(250);
711   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -32.0f);
712   EXPECT_EQ(helper.controller.recommended_analog_level(), 250);
713 
714   // Move down...
715   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -8.0f);
716   EXPECT_EQ(helper.controller.recommended_analog_level(), 210);
717   // And back up to the new max established by the user.
718   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -58.0f);
719   EXPECT_EQ(helper.controller.recommended_analog_level(), 250);
720   // Will not move above new maximum.
721   helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
722   EXPECT_EQ(helper.controller.recommended_analog_level(), 250);
723 }
724 
TEST_P(InputVolumeControllerParametrizedTest,ClippingDoesNotPullLowVolumeBackUp)725 TEST_P(InputVolumeControllerParametrizedTest,
726        ClippingDoesNotPullLowVolumeBackUp) {
727   InputVolumeControllerTestHelper helper;
728   helper.CallAgcSequence(/*applied_input_volume=*/80, kHighSpeechProbability,
729                          kSpeechLevel);
730 
731   int initial_volume = helper.controller.recommended_analog_level();
732   helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
733   EXPECT_EQ(initial_volume, helper.controller.recommended_analog_level());
734 }
735 
TEST_P(InputVolumeControllerParametrizedTest,TakesNoActionOnZeroMicVolume)736 TEST_P(InputVolumeControllerParametrizedTest, TakesNoActionOnZeroMicVolume) {
737   InputVolumeControllerTestHelper helper;
738   helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
739                          kSpeechLevel);
740 
741   helper.controller.set_stream_analog_level(0);
742   helper.CallProcess(/*num_calls=*/10, kHighSpeechProbability, -48.0f);
743   EXPECT_EQ(helper.controller.recommended_analog_level(), 0);
744 }
745 
TEST_P(InputVolumeControllerParametrizedTest,ClippingDetectionLowersVolume)746 TEST_P(InputVolumeControllerParametrizedTest, ClippingDetectionLowersVolume) {
747   InputVolumeControllerTestHelper helper;
748   helper.CallAgcSequence(/*applied_input_volume=*/255, kHighSpeechProbability,
749                          kSpeechLevel);
750 
751   EXPECT_EQ(helper.controller.recommended_analog_level(), 255);
752   helper.CallPreProcForChangingAudio(/*num_calls=*/100, /*peak_ratio=*/0.99f);
753   EXPECT_EQ(helper.controller.recommended_analog_level(), 255);
754   helper.CallPreProcForChangingAudio(/*num_calls=*/100, /*peak_ratio=*/1.0f);
755   EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
756 }
757 
TEST_P(InputVolumeControllerParametrizedTest,DisabledClippingPredictorDoesNotLowerVolume)758 TEST_P(InputVolumeControllerParametrizedTest,
759        DisabledClippingPredictorDoesNotLowerVolume) {
760   InputVolumeControllerTestHelper helper;
761   helper.CallAgcSequence(/*applied_input_volume=*/255, kHighSpeechProbability,
762                          kSpeechLevel);
763 
764   EXPECT_FALSE(helper.controller.clipping_predictor_enabled());
765   EXPECT_EQ(helper.controller.recommended_analog_level(), 255);
766   helper.CallPreProcForChangingAudio(/*num_calls=*/100, /*peak_ratio=*/0.99f);
767   EXPECT_EQ(helper.controller.recommended_analog_level(), 255);
768   helper.CallPreProcForChangingAudio(/*num_calls=*/100, /*peak_ratio=*/0.99f);
769   EXPECT_EQ(helper.controller.recommended_analog_level(), 255);
770 }
771 
TEST(InputVolumeControllerTest,MinInputVolumeDefault)772 TEST(InputVolumeControllerTest, MinInputVolumeDefault) {
773   std::unique_ptr<InputVolumeController> controller =
774       CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
775                                   kClippedWaitFrames);
776   EXPECT_EQ(controller->channel_controllers_[0]->min_input_volume(),
777             kMinMicLevel);
778 }
779 
TEST(InputVolumeControllerTest,MinInputVolumeDisabled)780 TEST(InputVolumeControllerTest, MinInputVolumeDisabled) {
781   for (const std::string& field_trial_suffix : {"", "_20220210"}) {
782     test::ScopedFieldTrials field_trial(
783         GetAgcMinInputVolumeFieldTrial("Disabled" + field_trial_suffix));
784     std::unique_ptr<InputVolumeController> controller =
785         CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
786                                     kClippedWaitFrames);
787 
788     EXPECT_EQ(controller->channel_controllers_[0]->min_input_volume(),
789               kMinMicLevel);
790   }
791 }
792 
793 // Checks that a field-trial parameter outside of the valid range [0,255] is
794 // ignored.
TEST(InputVolumeControllerTest,MinInputVolumeOutOfRangeAbove)795 TEST(InputVolumeControllerTest, MinInputVolumeOutOfRangeAbove) {
796   test::ScopedFieldTrials field_trial(
797       GetAgcMinInputVolumeFieldTrial("Enabled-256"));
798   std::unique_ptr<InputVolumeController> controller =
799       CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
800                                   kClippedWaitFrames);
801   EXPECT_EQ(controller->channel_controllers_[0]->min_input_volume(),
802             kMinMicLevel);
803 }
804 
805 // Checks that a field-trial parameter outside of the valid range [0,255] is
806 // ignored.
TEST(InputVolumeControllerTest,MinInputVolumeOutOfRangeBelow)807 TEST(InputVolumeControllerTest, MinInputVolumeOutOfRangeBelow) {
808   test::ScopedFieldTrials field_trial(
809       GetAgcMinInputVolumeFieldTrial("Enabled--1"));
810   std::unique_ptr<InputVolumeController> controller =
811       CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
812                                   kClippedWaitFrames);
813   EXPECT_EQ(controller->channel_controllers_[0]->min_input_volume(),
814             kMinMicLevel);
815 }
816 
817 // Verifies that a valid experiment changes the minimum microphone level. The
818 // start volume is larger than the min level and should therefore not be
819 // changed.
TEST(InputVolumeControllerTest,MinInputVolumeEnabled50)820 TEST(InputVolumeControllerTest, MinInputVolumeEnabled50) {
821   constexpr int kMinInputVolume = 50;
822   for (const std::string& field_trial_suffix : {"", "_20220210"}) {
823     SCOPED_TRACE(field_trial_suffix);
824     test::ScopedFieldTrials field_trial(GetAgcMinInputVolumeFieldTrialEnabled(
825         kMinInputVolume, field_trial_suffix));
826     std::unique_ptr<InputVolumeController> controller =
827         CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
828                                     kClippedWaitFrames);
829 
830     EXPECT_EQ(controller->channel_controllers_[0]->min_input_volume(),
831               kMinInputVolume);
832   }
833 }
834 
835 // Checks that, when the "WebRTC-Audio-Agc2-MinInputVolume" field trial is
836 // specified with a valid value, the mic level never gets lowered beyond the
837 // override value in the presence of clipping.
TEST(InputVolumeControllerTest,MinInputVolumeCheckMinLevelWithClipping)838 TEST(InputVolumeControllerTest, MinInputVolumeCheckMinLevelWithClipping) {
839   constexpr int kMinInputVolume = 250;
840 
841   // Create and initialize two AGCs by specifying and leaving unspecified the
842   // relevant field trial.
843   const auto factory = []() {
844     std::unique_ptr<InputVolumeController> controller =
845         CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
846                                     kClippedWaitFrames);
847     controller->Initialize();
848     controller->set_stream_analog_level(kInitialInputVolume);
849     return controller;
850   };
851   std::unique_ptr<InputVolumeController> controller = factory();
852   std::unique_ptr<InputVolumeController> manager_with_override;
853   {
854     test::ScopedFieldTrials field_trial(
855         GetAgcMinInputVolumeFieldTrialEnabled(kMinInputVolume));
856     manager_with_override = factory();
857   }
858 
859   // Create a test input signal which containts 80% of clipped samples.
860   AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
861                            1);
862   WriteAudioBufferSamples(/*samples_value=*/4000.0f, /*clipped_ratio=*/0.8f,
863                           audio_buffer);
864 
865   // Simulate 4 seconds of clipping; it is expected to trigger a downward
866   // adjustment of the analog gain. Use low speech probability to limit the
867   // volume changes to clipping handling.
868   CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
869                            kLowSpeechProbability, /*speech_level=*/-42.0f,
870                            *controller);
871   CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
872                            kLowSpeechProbability, /*speech_level=*/-42.0f,
873                            *manager_with_override);
874 
875   // Make sure that an adaptation occurred.
876   ASSERT_GT(controller->recommended_analog_level(), 0);
877 
878   // Check that the test signal triggers a larger downward adaptation for
879   // `controller`, which is allowed to reach a lower gain.
880   EXPECT_GT(manager_with_override->recommended_analog_level(),
881             controller->recommended_analog_level());
882   // Check that the gain selected by `manager_with_override` equals the
883   // minimum value overridden via field trial.
884   EXPECT_EQ(manager_with_override->recommended_analog_level(), kMinInputVolume);
885 }
886 
887 // Checks that, when the "WebRTC-Audio-Agc2-MinInputVolume" field trial is
888 // specified with a valid value, the mic level never gets lowered beyond the
889 // override value in the presence of clipping when RMS error is not empty.
890 // TODO(webrtc:7494): Revisit the test after moving the number of update wait
891 // frames to APM config. The test passes but internally the gain update timing
892 // differs.
TEST(InputVolumeControllerTest,MinInputVolumeCheckMinLevelWithClippingWithRmsError)893 TEST(InputVolumeControllerTest,
894      MinInputVolumeCheckMinLevelWithClippingWithRmsError) {
895   constexpr int kMinInputVolume = 250;
896 
897   // Create and initialize two AGCs by specifying and leaving unspecified the
898   // relevant field trial.
899   const auto factory = []() {
900     std::unique_ptr<InputVolumeController> controller =
901         CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
902                                     kClippedWaitFrames);
903     controller->Initialize();
904     controller->set_stream_analog_level(kInitialInputVolume);
905     return controller;
906   };
907   std::unique_ptr<InputVolumeController> controller = factory();
908   std::unique_ptr<InputVolumeController> manager_with_override;
909   {
910     test::ScopedFieldTrials field_trial(
911         GetAgcMinInputVolumeFieldTrialEnabled(kMinInputVolume));
912     manager_with_override = factory();
913   }
914 
915   // Create a test input signal which containts 80% of clipped samples.
916   AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
917                            1);
918   WriteAudioBufferSamples(/*samples_value=*/4000.0f, /*clipped_ratio=*/0.8f,
919                           audio_buffer);
920 
921   // Simulate 4 seconds of clipping; it is expected to trigger a downward
922   // adjustment of the analog gain.
923   CallPreProcessAndProcess(
924       /*num_calls=*/400, audio_buffer, kHighSpeechProbability,
925       /*speech_level=*/-18.0f, *controller);
926   CallPreProcessAndProcess(
927       /*num_calls=*/400, audio_buffer, kHighSpeechProbability,
928       /*speech_level=*/-18.0f, *manager_with_override);
929 
930   // Make sure that an adaptation occurred.
931   ASSERT_GT(controller->recommended_analog_level(), 0);
932 
933   // Check that the test signal triggers a larger downward adaptation for
934   // `controller`, which is allowed to reach a lower gain.
935   EXPECT_GT(manager_with_override->recommended_analog_level(),
936             controller->recommended_analog_level());
937   // Check that the gain selected by `manager_with_override` equals the minimum
938   // value overridden via field trial.
939   EXPECT_EQ(manager_with_override->recommended_analog_level(), kMinInputVolume);
940 }
941 
942 // Checks that, when the "WebRTC-Audio-Agc2-MinInputVolume" field trial is
943 // specified with a value lower than the `clipped_level_min`, the behavior of
944 // the analog gain controller is the same as that obtained when the field trial
945 // is not specified.
TEST(InputVolumeControllerTest,MinInputVolumeCompareMicLevelWithClipping)946 TEST(InputVolumeControllerTest, MinInputVolumeCompareMicLevelWithClipping) {
947   // Create and initialize two AGCs by specifying and leaving unspecified the
948   // relevant field trial.
949   const auto factory = []() {
950     // Use a large clipped level step to more quickly decrease the analog gain
951     // with clipping.
952     InputVolumeControllerConfig config = kDefaultInputVolumeControllerConfig;
953     config.clipped_level_step = 64;
954     config.clipped_ratio_threshold = kClippedRatioThreshold;
955     config.clipped_wait_frames = kClippedWaitFrames;
956     auto controller = std::make_unique<InputVolumeController>(
957         /*num_capture_channels=*/1, config);
958     controller->Initialize();
959     controller->set_stream_analog_level(kInitialInputVolume);
960     return controller;
961   };
962   std::unique_ptr<InputVolumeController> controller = factory();
963   std::unique_ptr<InputVolumeController> manager_with_override;
964   {
965     constexpr int kMinInputVolume = 20;
966     static_assert(kDefaultInputVolumeControllerConfig.clipped_level_min >=
967                       kMinInputVolume,
968                   "Use a lower override value.");
969     test::ScopedFieldTrials field_trial(
970         GetAgcMinInputVolumeFieldTrialEnabled(kMinInputVolume));
971     manager_with_override = factory();
972   }
973 
974   // Create a test input signal which containts 80% of clipped samples.
975   AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
976                            1);
977   WriteAudioBufferSamples(/*samples_value=*/4000.0f, /*clipped_ratio=*/0.8f,
978                           audio_buffer);
979 
980   // Simulate 4 seconds of clipping; it is expected to trigger a downward
981   // adjustment of the analog gain. Use low speech probability to limit the
982   // volume changes to clipping handling.
983   CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
984                            kLowSpeechProbability, /*speech_level=*/-18,
985                            *controller);
986   CallPreProcessAndProcess(/*num_calls=*/400, audio_buffer,
987                            kLowSpeechProbability, /*speech_level=*/-18,
988                            *manager_with_override);
989 
990   // Make sure that an adaptation occurred.
991   ASSERT_GT(controller->recommended_analog_level(), 0);
992 
993   // Check that the selected analog gain is the same for both controllers and
994   // that it equals the minimum level reached when clipping is handled. That is
995   // expected because the minimum microphone level override is less than the
996   // minimum level used when clipping is detected.
997   EXPECT_EQ(controller->recommended_analog_level(),
998             manager_with_override->recommended_analog_level());
999   EXPECT_EQ(manager_with_override->recommended_analog_level(),
1000             kDefaultInputVolumeControllerConfig.clipped_level_min);
1001 }
1002 
1003 // Checks that, when the "WebRTC-Audio-Agc2-MinInputVolume" field trial is
1004 // specified with a value lower than the `clipped_level_min`, the behavior of
1005 // the analog gain controller is the same as that obtained when the field trial
1006 // is not specified.
1007 // TODO(webrtc:7494): Revisit the test after moving the number of update wait
1008 // frames to APM config. The test passes but internally the gain update timing
1009 // differs.
TEST(InputVolumeControllerTest,MinInputVolumeCompareMicLevelWithClippingWithRmsError)1010 TEST(InputVolumeControllerTest,
1011      MinInputVolumeCompareMicLevelWithClippingWithRmsError) {
1012   // Create and initialize two AGCs by specifying and leaving unspecified the
1013   // relevant field trial.
1014   const auto factory = []() {
1015     // Use a large clipped level step to more quickly decrease the analog gain
1016     // with clipping.
1017     InputVolumeControllerConfig config = kDefaultInputVolumeControllerConfig;
1018     config.clipped_level_step = 64;
1019     config.clipped_ratio_threshold = kClippedRatioThreshold;
1020     config.clipped_wait_frames = kClippedWaitFrames;
1021     auto controller = std::make_unique<InputVolumeController>(
1022         /*num_capture_channels=*/1, config);
1023     controller->Initialize();
1024     controller->set_stream_analog_level(kInitialInputVolume);
1025     return controller;
1026   };
1027   std::unique_ptr<InputVolumeController> controller = factory();
1028   std::unique_ptr<InputVolumeController> manager_with_override;
1029   {
1030     constexpr int kMinInputVolume = 20;
1031     static_assert(kDefaultInputVolumeControllerConfig.clipped_level_min >=
1032                       kMinInputVolume,
1033                   "Use a lower override value.");
1034     test::ScopedFieldTrials field_trial(
1035         GetAgcMinInputVolumeFieldTrialEnabled(kMinInputVolume));
1036     manager_with_override = factory();
1037   }
1038 
1039   // Create a test input signal which containts 80% of clipped samples.
1040   AudioBuffer audio_buffer(kSampleRateHz, 1, kSampleRateHz, 1, kSampleRateHz,
1041                            1);
1042   WriteAudioBufferSamples(/*samples_value=*/4000.0f, /*clipped_ratio=*/0.8f,
1043                           audio_buffer);
1044 
1045   CallPreProcessAndProcess(
1046       /*num_calls=*/400, audio_buffer,
1047       /*speech_probability=*/0.7f,
1048       /*speech_level=*/-18.0f, *controller);
1049   CallPreProcessAndProcess(
1050       /*num_calls=*/400, audio_buffer,
1051       /*speech_probability=*/0.7f,
1052       /*speech_level=*/-18.0f, *manager_with_override);
1053 
1054   // Make sure that an adaptation occurred.
1055   ASSERT_GT(controller->recommended_analog_level(), 0);
1056 
1057   // Check that the selected analog gain is the same for both controllers and
1058   // that it equals the minimum level reached when clipping is handled. That is
1059   // expected because the minimum microphone level override is less than the
1060   // minimum level used when clipping is detected.
1061   EXPECT_EQ(controller->recommended_analog_level(),
1062             manager_with_override->recommended_analog_level());
1063   EXPECT_EQ(manager_with_override->recommended_analog_level(),
1064             kDefaultInputVolumeControllerConfig.clipped_level_min);
1065 }
1066 
1067 // TODO(bugs.webrtc.org/12774): Test the bahavior of `clipped_level_step`.
1068 // TODO(bugs.webrtc.org/12774): Test the bahavior of `clipped_ratio_threshold`.
1069 // TODO(bugs.webrtc.org/12774): Test the bahavior of `clipped_wait_frames`.
1070 // Verifies that configurable clipping parameters are initialized as intended.
TEST_P(InputVolumeControllerParametrizedTest,ClippingParametersVerified)1071 TEST_P(InputVolumeControllerParametrizedTest, ClippingParametersVerified) {
1072   std::unique_ptr<InputVolumeController> controller =
1073       CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
1074                                   kClippedWaitFrames);
1075   controller->Initialize();
1076   EXPECT_EQ(controller->clipped_level_step_, kClippedLevelStep);
1077   EXPECT_EQ(controller->clipped_ratio_threshold_, kClippedRatioThreshold);
1078   EXPECT_EQ(controller->clipped_wait_frames_, kClippedWaitFrames);
1079   std::unique_ptr<InputVolumeController> manager_custom =
1080       CreateInputVolumeController(/*clipped_level_step=*/10,
1081                                   /*clipped_ratio_threshold=*/0.2f,
1082                                   /*clipped_wait_frames=*/50);
1083   manager_custom->Initialize();
1084   EXPECT_EQ(manager_custom->clipped_level_step_, 10);
1085   EXPECT_EQ(manager_custom->clipped_ratio_threshold_, 0.2f);
1086   EXPECT_EQ(manager_custom->clipped_wait_frames_, 50);
1087 }
1088 
TEST_P(InputVolumeControllerParametrizedTest,DisableClippingPredictorDisablesClippingPredictor)1089 TEST_P(InputVolumeControllerParametrizedTest,
1090        DisableClippingPredictorDisablesClippingPredictor) {
1091   std::unique_ptr<InputVolumeController> controller =
1092       CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
1093                                   kClippedWaitFrames,
1094                                   /*enable_clipping_predictor=*/false);
1095   controller->Initialize();
1096 
1097   EXPECT_FALSE(controller->clipping_predictor_enabled());
1098   EXPECT_FALSE(controller->use_clipping_predictor_step());
1099 }
1100 
TEST_P(InputVolumeControllerParametrizedTest,EnableClippingPredictorEnablesClippingPredictor)1101 TEST_P(InputVolumeControllerParametrizedTest,
1102        EnableClippingPredictorEnablesClippingPredictor) {
1103   std::unique_ptr<InputVolumeController> controller =
1104       CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
1105                                   kClippedWaitFrames,
1106                                   /*enable_clipping_predictor=*/true);
1107   controller->Initialize();
1108 
1109   EXPECT_TRUE(controller->clipping_predictor_enabled());
1110   EXPECT_TRUE(controller->use_clipping_predictor_step());
1111 }
1112 
TEST_P(InputVolumeControllerParametrizedTest,DisableClippingPredictorDoesNotLowerVolume)1113 TEST_P(InputVolumeControllerParametrizedTest,
1114        DisableClippingPredictorDoesNotLowerVolume) {
1115   AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
1116                            kNumChannels, kSampleRateHz, kNumChannels);
1117 
1118   InputVolumeControllerConfig config = GetInputVolumeControllerTestConfig();
1119   config.enable_clipping_predictor = false;
1120   InputVolumeController controller(/*num_capture_channels=*/1, config);
1121   controller.Initialize();
1122   controller.set_stream_analog_level(/*level=*/255);
1123   EXPECT_FALSE(controller.clipping_predictor_enabled());
1124   EXPECT_FALSE(controller.use_clipping_predictor_step());
1125   EXPECT_EQ(controller.recommended_analog_level(), 255);
1126   controller.Process(kHighSpeechProbability, kSpeechLevel);
1127   CallPreProcessAudioBuffer(/*num_calls=*/10, /*peak_ratio=*/0.99f, controller);
1128   EXPECT_EQ(controller.recommended_analog_level(), 255);
1129   CallPreProcessAudioBuffer(/*num_calls=*/300, /*peak_ratio=*/0.99f,
1130                             controller);
1131   EXPECT_EQ(controller.recommended_analog_level(), 255);
1132   CallPreProcessAudioBuffer(/*num_calls=*/10, /*peak_ratio=*/0.99f, controller);
1133   EXPECT_EQ(controller.recommended_analog_level(), 255);
1134 }
1135 
TEST_P(InputVolumeControllerParametrizedTest,UsedClippingPredictionsProduceLowerAnalogLevels)1136 TEST_P(InputVolumeControllerParametrizedTest,
1137        UsedClippingPredictionsProduceLowerAnalogLevels) {
1138   AudioBuffer audio_buffer(kSampleRateHz, kNumChannels, kSampleRateHz,
1139                            kNumChannels, kSampleRateHz, kNumChannels);
1140 
1141   InputVolumeControllerConfig config_with_prediction =
1142       GetInputVolumeControllerTestConfig();
1143   config_with_prediction.enable_clipping_predictor = true;
1144 
1145   InputVolumeControllerConfig config_without_prediction =
1146       GetInputVolumeControllerTestConfig();
1147 
1148   config_without_prediction.enable_clipping_predictor = false;
1149   InputVolumeController manager_without_prediction(/*num_capture_channels=*/1,
1150                                                    config_without_prediction);
1151   InputVolumeController manager_with_prediction(/*num_capture_channels=*/1,
1152                                                 config_with_prediction);
1153 
1154   manager_with_prediction.Initialize();
1155   manager_without_prediction.Initialize();
1156 
1157   constexpr int kInitialLevel = 255;
1158   constexpr float kClippingPeakRatio = 1.0f;
1159   constexpr float kCloseToClippingPeakRatio = 0.99f;
1160   constexpr float kZeroPeakRatio = 0.0f;
1161   manager_with_prediction.set_stream_analog_level(kInitialLevel);
1162   manager_without_prediction.set_stream_analog_level(kInitialLevel);
1163 
1164   manager_with_prediction.Process(kHighSpeechProbability, kSpeechLevel);
1165   manager_without_prediction.Process(kHighSpeechProbability, kSpeechLevel);
1166 
1167   EXPECT_TRUE(manager_with_prediction.clipping_predictor_enabled());
1168   EXPECT_FALSE(manager_without_prediction.clipping_predictor_enabled());
1169   EXPECT_TRUE(manager_with_prediction.use_clipping_predictor_step());
1170   EXPECT_EQ(manager_with_prediction.recommended_analog_level(), kInitialLevel);
1171   EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
1172             kInitialLevel);
1173 
1174   // Expect a change in the analog level when the prediction step is used.
1175   CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
1176                             manager_with_prediction);
1177   CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
1178                             manager_without_prediction);
1179   EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
1180             kInitialLevel - kClippedLevelStep);
1181   EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
1182             kInitialLevel);
1183 
1184   // Expect no change during waiting.
1185   CallPreProcessAudioBuffer(kClippedWaitFrames, kCloseToClippingPeakRatio,
1186                             manager_with_prediction);
1187   CallPreProcessAudioBuffer(kClippedWaitFrames, kCloseToClippingPeakRatio,
1188                             manager_without_prediction);
1189   EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
1190             kInitialLevel - kClippedLevelStep);
1191   EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
1192             kInitialLevel);
1193 
1194   // Expect a change when the prediction step is used.
1195   CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
1196                             manager_with_prediction);
1197   CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
1198                             manager_without_prediction);
1199   EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
1200             kInitialLevel - 2 * kClippedLevelStep);
1201   EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
1202             kInitialLevel);
1203 
1204   // Expect no change when clipping is not detected or predicted.
1205   CallPreProcessAudioBuffer(2 * kClippedWaitFrames, kZeroPeakRatio,
1206                             manager_with_prediction);
1207   CallPreProcessAudioBuffer(2 * kClippedWaitFrames, kZeroPeakRatio,
1208                             manager_without_prediction);
1209   EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
1210             kInitialLevel - 2 * kClippedLevelStep);
1211   EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
1212             kInitialLevel);
1213 
1214   // Expect a change for clipping frames.
1215   CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
1216                             manager_with_prediction);
1217   CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
1218                             manager_without_prediction);
1219   EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
1220             kInitialLevel - 3 * kClippedLevelStep);
1221   EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
1222             kInitialLevel - kClippedLevelStep);
1223 
1224   // Expect no change during waiting.
1225   CallPreProcessAudioBuffer(kClippedWaitFrames, kClippingPeakRatio,
1226                             manager_with_prediction);
1227   CallPreProcessAudioBuffer(kClippedWaitFrames, kClippingPeakRatio,
1228                             manager_without_prediction);
1229   EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
1230             kInitialLevel - 3 * kClippedLevelStep);
1231   EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
1232             kInitialLevel - kClippedLevelStep);
1233 
1234   // Expect a change for clipping frames.
1235   CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
1236                             manager_with_prediction);
1237   CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
1238                             manager_without_prediction);
1239   EXPECT_EQ(manager_with_prediction.recommended_analog_level(),
1240             kInitialLevel - 4 * kClippedLevelStep);
1241   EXPECT_EQ(manager_without_prediction.recommended_analog_level(),
1242             kInitialLevel - 2 * kClippedLevelStep);
1243 }
1244 
1245 // Checks that passing an empty speech level has no effect on the input volume.
TEST_P(InputVolumeControllerParametrizedTest,EmptyRmsErrorHasNoEffect)1246 TEST_P(InputVolumeControllerParametrizedTest, EmptyRmsErrorHasNoEffect) {
1247   InputVolumeController controller(kNumChannels,
1248                                    GetInputVolumeControllerTestConfig());
1249   controller.Initialize();
1250 
1251   constexpr int kInputVolume = kInitialInputVolume;
1252   controller.set_stream_analog_level(kInputVolume);
1253 
1254   // Feed speech with low energy that would trigger an upward adapation of
1255   // the analog level if an speech level was not low and the RMS level empty.
1256   constexpr int kNumFrames = 125;
1257   constexpr int kGainDb = -20;
1258   SpeechSamplesReader reader;
1259   reader.Feed(kNumFrames, kGainDb, kLowSpeechProbability, absl::nullopt,
1260               controller);
1261 
1262   // Check that no adaptation occurs.
1263   ASSERT_EQ(controller.recommended_analog_level(), kInputVolume);
1264 }
1265 
1266 // Checks that the recommended input volume is not updated unless enough
1267 // frames have been processed after the previous update.
TEST(InputVolumeControllerTest,UpdateInputVolumeWaitFramesIsEffective)1268 TEST(InputVolumeControllerTest, UpdateInputVolumeWaitFramesIsEffective) {
1269   constexpr int kInputVolume = kInitialInputVolume;
1270   std::unique_ptr<InputVolumeController> controller_wait_0 =
1271       CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
1272                                   kClippedWaitFrames,
1273                                   /*enable_clipping_predictor=*/false,
1274                                   /*update_input_volume_wait_frames=*/0);
1275   std::unique_ptr<InputVolumeController> controller_wait_100 =
1276       CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
1277                                   kClippedWaitFrames,
1278                                   /*enable_clipping_predictor=*/false,
1279                                   /*update_input_volume_wait_frames=*/100);
1280   controller_wait_0->Initialize();
1281   controller_wait_100->Initialize();
1282   controller_wait_0->set_stream_analog_level(kInputVolume);
1283   controller_wait_100->set_stream_analog_level(kInputVolume);
1284 
1285   SpeechSamplesReader reader_1;
1286   SpeechSamplesReader reader_2;
1287   reader_1.Feed(/*num_frames=*/99, /*gain_db=*/0, kHighSpeechProbability,
1288                 /*speech_level=*/-42.0f, *controller_wait_0);
1289   reader_2.Feed(/*num_frames=*/99, /*gain_db=*/0, kHighSpeechProbability,
1290                 /*speech_level=*/-42.0f, *controller_wait_100);
1291 
1292   // Check that adaptation only occurs if enough frames have been processed.
1293   ASSERT_GT(controller_wait_0->recommended_analog_level(), kInputVolume);
1294   ASSERT_EQ(controller_wait_100->recommended_analog_level(), kInputVolume);
1295 
1296   reader_1.Feed(/*num_frames=*/1, /*gain_db=*/0, kHighSpeechProbability,
1297                 /*speech_level=*/-42.0f, *controller_wait_0);
1298   reader_2.Feed(/*num_frames=*/1, /*gain_db=*/0, kHighSpeechProbability,
1299                 /*speech_level=*/-42.0f, *controller_wait_100);
1300 
1301   // Check that adaptation only occurs when enough frames have been processed.
1302   ASSERT_GT(controller_wait_0->recommended_analog_level(), kInputVolume);
1303   ASSERT_GT(controller_wait_100->recommended_analog_level(), kInputVolume);
1304 }
1305 
TEST(InputVolumeControllerTest,SpeechRatioThresholdIsEffective)1306 TEST(InputVolumeControllerTest, SpeechRatioThresholdIsEffective) {
1307   constexpr int kInputVolume = kInitialInputVolume;
1308   // Create two input volume controllers with 10 frames between volume updates
1309   // and the minimum speech ratio of 0.8 and speech probability threshold 0.5.
1310   std::unique_ptr<InputVolumeController> controller_1 =
1311       CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
1312                                   kClippedWaitFrames,
1313                                   /*enable_clipping_predictor=*/false,
1314                                   /*update_input_volume_wait_frames=*/10);
1315   std::unique_ptr<InputVolumeController> controller_2 =
1316       CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
1317                                   kClippedWaitFrames,
1318                                   /*enable_clipping_predictor=*/false,
1319                                   /*update_input_volume_wait_frames=*/10);
1320   controller_1->Initialize();
1321   controller_2->Initialize();
1322   controller_1->set_stream_analog_level(kInputVolume);
1323   controller_2->set_stream_analog_level(kInputVolume);
1324 
1325   SpeechSamplesReader reader_1;
1326   SpeechSamplesReader reader_2;
1327 
1328   reader_1.Feed(/*num_frames=*/1, /*gain_db=*/0,
1329                 /*speech_probability=*/0.7f, /*speech_level=*/-42.0f,
1330                 *controller_1);
1331   reader_2.Feed(/*num_frames=*/1, /*gain_db=*/0,
1332                 /*speech_probability=*/0.4f, /*speech_level=*/-42.0f,
1333                 *controller_2);
1334 
1335   ASSERT_EQ(controller_1->recommended_analog_level(), kInputVolume);
1336   ASSERT_EQ(controller_2->recommended_analog_level(), kInputVolume);
1337 
1338   reader_1.Feed(/*num_frames=*/2, /*gain_db=*/0,
1339                 /*speech_probability=*/0.4f, /*speech_level=*/-42.0f,
1340                 *controller_1);
1341   reader_2.Feed(/*num_frames=*/2, /*gain_db=*/0,
1342                 /*speech_probability=*/0.4f, /*speech_level=*/-42.0f,
1343                 *controller_2);
1344 
1345   ASSERT_EQ(controller_1->recommended_analog_level(), kInputVolume);
1346   ASSERT_EQ(controller_2->recommended_analog_level(), kInputVolume);
1347 
1348   reader_1.Feed(/*num_frames=*/7, /*gain_db=*/0,
1349                 /*speech_probability=*/0.7f, /*speech_level=*/-42.0f,
1350                 *controller_1);
1351   reader_2.Feed(/*num_frames=*/7, /*gain_db=*/0,
1352                 /*speech_probability=*/0.7f, /*speech_level=*/-42.0f,
1353                 *controller_2);
1354 
1355   ASSERT_GT(controller_1->recommended_analog_level(), kInputVolume);
1356   ASSERT_EQ(controller_2->recommended_analog_level(), kInputVolume);
1357 }
1358 
TEST(InputVolumeControllerTest,SpeechProbabilityThresholdIsEffective)1359 TEST(InputVolumeControllerTest, SpeechProbabilityThresholdIsEffective) {
1360   constexpr int kInputVolume = kInitialInputVolume;
1361   // Create two input volume controllers with the exact same settings and
1362   // 10 frames between volume updates.
1363   std::unique_ptr<InputVolumeController> controller_1 =
1364       CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
1365                                   kClippedWaitFrames,
1366                                   /*enable_clipping_predictor=*/false,
1367                                   /*update_input_volume_wait_frames=*/10);
1368   std::unique_ptr<InputVolumeController> controller_2 =
1369       CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
1370                                   kClippedWaitFrames,
1371                                   /*enable_clipping_predictor=*/false,
1372                                   /*update_input_volume_wait_frames=*/10);
1373   controller_1->Initialize();
1374   controller_2->Initialize();
1375   controller_1->set_stream_analog_level(kInputVolume);
1376   controller_2->set_stream_analog_level(kInputVolume);
1377 
1378   SpeechSamplesReader reader_1;
1379   SpeechSamplesReader reader_2;
1380 
1381   // Process with two sets of inputs: Use `reader_1` to process inputs
1382   // that make the volume to be adjusted after enough frames have been
1383   // processsed and `reader_2` to process inputs that won't make the volume
1384   // to be adjusted.
1385   reader_1.Feed(/*num_frames=*/1, /*gain_db=*/0,
1386                 /*speech_probability=*/0.5f, /*speech_level=*/-42.0f,
1387                 *controller_1);
1388   reader_2.Feed(/*num_frames=*/1, /*gain_db=*/0,
1389                 /*speech_probability=*/0.49f, /*speech_level=*/-42.0f,
1390                 *controller_2);
1391 
1392   ASSERT_EQ(controller_1->recommended_analog_level(), kInputVolume);
1393   ASSERT_EQ(controller_2->recommended_analog_level(), kInputVolume);
1394 
1395   reader_1.Feed(/*num_frames=*/2, /*gain_db=*/0,
1396                 /*speech_probability=*/0.49f, /*speech_level=*/-42.0f,
1397                 *controller_1);
1398   reader_2.Feed(/*num_frames=*/2, /*gain_db=*/0,
1399                 /*speech_probability=*/0.49f, /*speech_level=*/-42.0f,
1400                 *controller_2);
1401 
1402   ASSERT_EQ(controller_1->recommended_analog_level(), kInputVolume);
1403   ASSERT_EQ(controller_2->recommended_analog_level(), kInputVolume);
1404 
1405   reader_1.Feed(/*num_frames=*/7, /*gain_db=*/0,
1406                 /*speech_probability=*/0.5f, /*speech_level=*/-42.0f,
1407                 *controller_1);
1408   reader_2.Feed(/*num_frames=*/7, /*gain_db=*/0,
1409                 /*speech_probability=*/0.5f, /*speech_level=*/-42.0f,
1410                 *controller_2);
1411 
1412   ASSERT_GT(controller_1->recommended_analog_level(), kInputVolume);
1413   ASSERT_EQ(controller_2->recommended_analog_level(), kInputVolume);
1414 }
1415 
TEST(MonoInputVolumeControllerTest,CheckHandleClippingLowersVolume)1416 TEST(MonoInputVolumeControllerTest, CheckHandleClippingLowersVolume) {
1417   constexpr int kInitialInputVolume = 100;
1418   constexpr int kInputVolumeStep = 29;
1419   MonoInputVolumeController mono_controller(
1420       /*clipped_level_min=*/70,
1421       /*min_mic_level=*/32,
1422       /*update_input_volume_wait_frames=*/3, kHighSpeechProbability,
1423       kSpeechRatioThreshold);
1424   mono_controller.Initialize();
1425 
1426   UpdateRecommendedInputVolume(mono_controller, kInitialInputVolume,
1427                                kLowSpeechProbability,
1428                                /*rms_error_dbfs*/ -10.0f);
1429 
1430   mono_controller.HandleClipping(kInputVolumeStep);
1431 
1432   EXPECT_EQ(mono_controller.recommended_analog_level(),
1433             kInitialInputVolume - kInputVolumeStep);
1434 }
1435 
TEST(MonoInputVolumeControllerTest,CheckProcessNegativeRmsErrorDecreasesInputVolume)1436 TEST(MonoInputVolumeControllerTest,
1437      CheckProcessNegativeRmsErrorDecreasesInputVolume) {
1438   constexpr int kInitialInputVolume = 100;
1439   MonoInputVolumeController mono_controller(
1440       /*clipped_level_min=*/64,
1441       /*min_mic_level=*/32,
1442       /*update_input_volume_wait_frames=*/3, kHighSpeechProbability,
1443       kSpeechRatioThreshold);
1444   mono_controller.Initialize();
1445 
1446   int volume = UpdateRecommendedInputVolume(
1447       mono_controller, kInitialInputVolume, kHighSpeechProbability, -10.0f);
1448   volume = UpdateRecommendedInputVolume(mono_controller, volume,
1449                                         kHighSpeechProbability, -10.0f);
1450   volume = UpdateRecommendedInputVolume(mono_controller, volume,
1451                                         kHighSpeechProbability, -10.0f);
1452 
1453   EXPECT_LT(volume, kInitialInputVolume);
1454 }
1455 
TEST(MonoInputVolumeControllerTest,CheckProcessPositiveRmsErrorIncreasesInputVolume)1456 TEST(MonoInputVolumeControllerTest,
1457      CheckProcessPositiveRmsErrorIncreasesInputVolume) {
1458   constexpr int kInitialInputVolume = 100;
1459   MonoInputVolumeController mono_controller(
1460       /*clipped_level_min=*/64,
1461       /*min_mic_level=*/32,
1462       /*update_input_volume_wait_frames=*/3, kHighSpeechProbability,
1463       kSpeechRatioThreshold);
1464   mono_controller.Initialize();
1465 
1466   int volume = UpdateRecommendedInputVolume(
1467       mono_controller, kInitialInputVolume, kHighSpeechProbability, 10.0f);
1468   volume = UpdateRecommendedInputVolume(mono_controller, volume,
1469                                         kHighSpeechProbability, 10.0f);
1470   volume = UpdateRecommendedInputVolume(mono_controller, volume,
1471                                         kHighSpeechProbability, 10.0f);
1472 
1473   EXPECT_GT(volume, kInitialInputVolume);
1474 }
1475 
TEST(MonoInputVolumeControllerTest,CheckProcessNegativeRmsErrorDecreasesInputVolumeWithLimit)1476 TEST(MonoInputVolumeControllerTest,
1477      CheckProcessNegativeRmsErrorDecreasesInputVolumeWithLimit) {
1478   constexpr int kInitialInputVolume = 100;
1479   MonoInputVolumeController mono_controller_1(
1480       /*clipped_level_min=*/64,
1481       /*min_mic_level=*/32,
1482       /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
1483       kSpeechRatioThreshold);
1484   MonoInputVolumeController mono_controller_2(
1485       /*clipped_level_min=*/64,
1486       /*min_mic_level=*/32,
1487       /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
1488       kSpeechRatioThreshold);
1489   MonoInputVolumeController mono_controller_3(
1490       /*clipped_level_min=*/64,
1491       /*min_mic_level=*/32,
1492       /*update_input_volume_wait_frames=*/2,
1493       /*speech_probability_threshold=*/0.7,
1494       /*speech_ratio_threshold=*/0.8);
1495   mono_controller_1.Initialize();
1496   mono_controller_2.Initialize();
1497   mono_controller_3.Initialize();
1498 
1499   // Process RMS errors in the range
1500   // [`-kMaxResidualGainChange`, `kMaxResidualGainChange`].
1501   int volume_1 = UpdateRecommendedInputVolume(
1502       mono_controller_1, kInitialInputVolume, kHighSpeechProbability, -14.0f);
1503   volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
1504                                           kHighSpeechProbability, -14.0f);
1505   // Process RMS errors outside the range
1506   // [`-kMaxResidualGainChange`, `kMaxResidualGainChange`].
1507   int volume_2 = UpdateRecommendedInputVolume(
1508       mono_controller_2, kInitialInputVolume, kHighSpeechProbability, -15.0f);
1509   int volume_3 = UpdateRecommendedInputVolume(
1510       mono_controller_3, kInitialInputVolume, kHighSpeechProbability, -30.0f);
1511   volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
1512                                           kHighSpeechProbability, -15.0f);
1513   volume_3 = UpdateRecommendedInputVolume(mono_controller_3, volume_3,
1514                                           kHighSpeechProbability, -30.0f);
1515 
1516   EXPECT_LT(volume_1, kInitialInputVolume);
1517   EXPECT_LT(volume_2, volume_1);
1518   EXPECT_EQ(volume_2, volume_3);
1519 }
1520 
TEST(MonoInputVolumeControllerTest,CheckProcessPositiveRmsErrorIncreasesInputVolumeWithLimit)1521 TEST(MonoInputVolumeControllerTest,
1522      CheckProcessPositiveRmsErrorIncreasesInputVolumeWithLimit) {
1523   constexpr int kInitialInputVolume = 100;
1524   MonoInputVolumeController mono_controller_1(
1525       /*clipped_level_min=*/64,
1526       /*min_mic_level=*/32,
1527       /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
1528       kSpeechRatioThreshold);
1529   MonoInputVolumeController mono_controller_2(
1530       /*clipped_level_min=*/64,
1531       /*min_mic_level=*/32,
1532       /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
1533       kSpeechRatioThreshold);
1534   MonoInputVolumeController mono_controller_3(
1535       /*clipped_level_min=*/64,
1536       /*min_mic_level=*/32,
1537       /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
1538       kSpeechRatioThreshold);
1539   mono_controller_1.Initialize();
1540   mono_controller_2.Initialize();
1541   mono_controller_3.Initialize();
1542 
1543   // Process RMS errors in the range
1544   // [`-kMaxResidualGainChange`, `kMaxResidualGainChange`].
1545   int volume_1 = UpdateRecommendedInputVolume(
1546       mono_controller_1, kInitialInputVolume, kHighSpeechProbability, 14.0f);
1547   volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
1548                                           kHighSpeechProbability, 14.0f);
1549   // Process RMS errors outside the range
1550   // [`-kMaxResidualGainChange`, `kMaxResidualGainChange`].
1551   int volume_2 = UpdateRecommendedInputVolume(
1552       mono_controller_2, kInitialInputVolume, kHighSpeechProbability, 15.0f);
1553   int volume_3 = UpdateRecommendedInputVolume(
1554       mono_controller_3, kInitialInputVolume, kHighSpeechProbability, 30.0f);
1555   volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
1556                                           kHighSpeechProbability, 15.0f);
1557   volume_3 = UpdateRecommendedInputVolume(mono_controller_3, volume_3,
1558                                           kHighSpeechProbability, 30.0f);
1559 
1560   EXPECT_GT(volume_1, kInitialInputVolume);
1561   EXPECT_GT(volume_2, volume_1);
1562   EXPECT_EQ(volume_2, volume_3);
1563 }
1564 
TEST(MonoInputVolumeControllerTest,CheckProcessRmsErrorDecreasesInputVolumeRepeatedly)1565 TEST(MonoInputVolumeControllerTest,
1566      CheckProcessRmsErrorDecreasesInputVolumeRepeatedly) {
1567   constexpr int kInitialInputVolume = 100;
1568   MonoInputVolumeController mono_controller(
1569       /*clipped_level_min=*/64,
1570       /*min_mic_level=*/32,
1571       /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
1572       kSpeechRatioThreshold);
1573   mono_controller.Initialize();
1574 
1575   int volume_before = UpdateRecommendedInputVolume(
1576       mono_controller, kInitialInputVolume, kHighSpeechProbability, -10.0f);
1577   volume_before = UpdateRecommendedInputVolume(mono_controller, volume_before,
1578                                                kHighSpeechProbability, -10.0f);
1579 
1580   EXPECT_LT(volume_before, kInitialInputVolume);
1581 
1582   int volume_after = UpdateRecommendedInputVolume(
1583       mono_controller, volume_before, kHighSpeechProbability, -10.0f);
1584   volume_after = UpdateRecommendedInputVolume(mono_controller, volume_after,
1585                                               kHighSpeechProbability, -10.0f);
1586 
1587   EXPECT_LT(volume_after, volume_before);
1588 }
1589 
TEST(MonoInputVolumeControllerTest,CheckProcessPositiveRmsErrorIncreasesInputVolumeRepeatedly)1590 TEST(MonoInputVolumeControllerTest,
1591      CheckProcessPositiveRmsErrorIncreasesInputVolumeRepeatedly) {
1592   constexpr int kInitialInputVolume = 100;
1593   MonoInputVolumeController mono_controller(
1594       /*clipped_level_min=*/64,
1595       /*min_mic_level=*/32,
1596       /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
1597       kSpeechRatioThreshold);
1598   mono_controller.Initialize();
1599 
1600   int volume_before = UpdateRecommendedInputVolume(
1601       mono_controller, kInitialInputVolume, kHighSpeechProbability, 10.0f);
1602   volume_before = UpdateRecommendedInputVolume(mono_controller, volume_before,
1603                                                kHighSpeechProbability, 10.0f);
1604 
1605   EXPECT_GT(volume_before, kInitialInputVolume);
1606 
1607   int volume_after = UpdateRecommendedInputVolume(
1608       mono_controller, volume_before, kHighSpeechProbability, 10.0f);
1609   volume_after = UpdateRecommendedInputVolume(mono_controller, volume_after,
1610                                               kHighSpeechProbability, 10.0f);
1611 
1612   EXPECT_GT(volume_after, volume_before);
1613 }
1614 
TEST(MonoInputVolumeControllerTest,CheckClippedLevelMinIsEffective)1615 TEST(MonoInputVolumeControllerTest, CheckClippedLevelMinIsEffective) {
1616   constexpr int kInitialInputVolume = 100;
1617   constexpr int kClippedLevelMin = 70;
1618   MonoInputVolumeController mono_controller_1(
1619       kClippedLevelMin,
1620       /*min_mic_level=*/84,
1621       /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
1622       kSpeechRatioThreshold);
1623   MonoInputVolumeController mono_controller_2(
1624       kClippedLevelMin,
1625       /*min_mic_level=*/84,
1626       /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
1627       kSpeechRatioThreshold);
1628   mono_controller_1.Initialize();
1629   mono_controller_2.Initialize();
1630 
1631   // Process one frame to reset the state for `HandleClipping()`.
1632   EXPECT_EQ(UpdateRecommendedInputVolume(mono_controller_1, kInitialInputVolume,
1633                                          kLowSpeechProbability, -10.0f),
1634             kInitialInputVolume);
1635   EXPECT_EQ(UpdateRecommendedInputVolume(mono_controller_2, kInitialInputVolume,
1636                                          kLowSpeechProbability, -10.0f),
1637             kInitialInputVolume);
1638 
1639   mono_controller_1.HandleClipping(29);
1640   mono_controller_2.HandleClipping(31);
1641 
1642   EXPECT_EQ(mono_controller_2.recommended_analog_level(), kClippedLevelMin);
1643   EXPECT_LT(mono_controller_2.recommended_analog_level(),
1644             mono_controller_1.recommended_analog_level());
1645 }
1646 
TEST(MonoInputVolumeControllerTest,CheckMinMicLevelIsEffective)1647 TEST(MonoInputVolumeControllerTest, CheckMinMicLevelIsEffective) {
1648   constexpr int kInitialInputVolume = 100;
1649   constexpr int kMinMicLevel = 64;
1650   MonoInputVolumeController mono_controller_1(
1651       /*clipped_level_min=*/64, kMinMicLevel,
1652       /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
1653       kSpeechRatioThreshold);
1654   MonoInputVolumeController mono_controller_2(
1655       /*clipped_level_min=*/64, kMinMicLevel,
1656       /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
1657       kSpeechRatioThreshold);
1658   mono_controller_1.Initialize();
1659   mono_controller_2.Initialize();
1660 
1661   int volume_1 = UpdateRecommendedInputVolume(
1662       mono_controller_1, kInitialInputVolume, kHighSpeechProbability, -10.0f);
1663   int volume_2 = UpdateRecommendedInputVolume(
1664       mono_controller_2, kInitialInputVolume, kHighSpeechProbability, -10.0f);
1665 
1666   EXPECT_EQ(volume_1, kInitialInputVolume);
1667   EXPECT_EQ(volume_2, kInitialInputVolume);
1668 
1669   volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
1670                                           kHighSpeechProbability, -10.0f);
1671   volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
1672                                           kHighSpeechProbability, -30.0f);
1673 
1674   EXPECT_LT(volume_1, kInitialInputVolume);
1675   EXPECT_LT(volume_2, volume_1);
1676   EXPECT_EQ(volume_2, kMinMicLevel);
1677 }
1678 
TEST(MonoInputVolumeControllerTest,CheckUpdateInputVolumeWaitFramesIsEffective)1679 TEST(MonoInputVolumeControllerTest,
1680      CheckUpdateInputVolumeWaitFramesIsEffective) {
1681   constexpr int kInitialInputVolume = 100;
1682   MonoInputVolumeController mono_controller_1(
1683       /*clipped_level_min=*/64,
1684       /*min_mic_level=*/84,
1685       /*update_input_volume_wait_frames=*/1, kHighSpeechProbability,
1686       kSpeechRatioThreshold);
1687   MonoInputVolumeController mono_controller_2(
1688       /*clipped_level_min=*/64,
1689       /*min_mic_level=*/84,
1690       /*update_input_volume_wait_frames=*/3, kHighSpeechProbability,
1691       kSpeechRatioThreshold);
1692   mono_controller_1.Initialize();
1693   mono_controller_2.Initialize();
1694 
1695   int volume_1 = UpdateRecommendedInputVolume(
1696       mono_controller_1, kInitialInputVolume, kHighSpeechProbability, -10.0f);
1697   int volume_2 = UpdateRecommendedInputVolume(
1698       mono_controller_2, kInitialInputVolume, kHighSpeechProbability, -10.0f);
1699 
1700   EXPECT_EQ(volume_1, kInitialInputVolume);
1701   EXPECT_EQ(volume_2, kInitialInputVolume);
1702 
1703   volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
1704                                           kHighSpeechProbability, -10.0f);
1705   volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
1706                                           kHighSpeechProbability, -10.0f);
1707 
1708   EXPECT_LT(volume_1, kInitialInputVolume);
1709   EXPECT_EQ(volume_2, kInitialInputVolume);
1710 
1711   volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
1712                                           kHighSpeechProbability, -10.0f);
1713 
1714   EXPECT_LT(volume_2, kInitialInputVolume);
1715 }
1716 
TEST(MonoInputVolumeControllerTest,CheckSpeechProbabilityThresholdIsEffective)1717 TEST(MonoInputVolumeControllerTest,
1718      CheckSpeechProbabilityThresholdIsEffective) {
1719   constexpr int kInitialInputVolume = 100;
1720   constexpr float kSpeechProbabilityThreshold = 0.8f;
1721   MonoInputVolumeController mono_controller_1(
1722       /*clipped_level_min=*/64,
1723       /*min_mic_level=*/84,
1724       /*update_input_volume_wait_frames=*/2, kSpeechProbabilityThreshold,
1725       kSpeechRatioThreshold);
1726   MonoInputVolumeController mono_controller_2(
1727       /*clipped_level_min=*/64,
1728       /*min_mic_level=*/84,
1729       /*update_input_volume_wait_frames=*/2, kSpeechProbabilityThreshold,
1730       kSpeechRatioThreshold);
1731   mono_controller_1.Initialize();
1732   mono_controller_2.Initialize();
1733 
1734   int volume_1 =
1735       UpdateRecommendedInputVolume(mono_controller_1, kInitialInputVolume,
1736                                    kSpeechProbabilityThreshold, -10.0f);
1737   int volume_2 =
1738       UpdateRecommendedInputVolume(mono_controller_2, kInitialInputVolume,
1739                                    kSpeechProbabilityThreshold, -10.0f);
1740 
1741   EXPECT_EQ(volume_1, kInitialInputVolume);
1742   EXPECT_EQ(volume_2, kInitialInputVolume);
1743 
1744   volume_1 = UpdateRecommendedInputVolume(
1745       mono_controller_1, volume_1, kSpeechProbabilityThreshold - 0.1f, -10.0f);
1746   volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
1747                                           kSpeechProbabilityThreshold, -10.0f);
1748 
1749   EXPECT_EQ(volume_1, kInitialInputVolume);
1750   EXPECT_LT(volume_2, volume_1);
1751 }
1752 
TEST(MonoInputVolumeControllerTest,CheckSpeechRatioThresholdIsEffective)1753 TEST(MonoInputVolumeControllerTest, CheckSpeechRatioThresholdIsEffective) {
1754   constexpr int kInitialInputVolume = 100;
1755   MonoInputVolumeController mono_controller_1(
1756       /*clipped_level_min=*/64,
1757       /*min_mic_level=*/84,
1758       /*update_input_volume_wait_frames=*/4, kHighSpeechProbability,
1759       /*speech_ratio_threshold=*/0.75f);
1760   MonoInputVolumeController mono_controller_2(
1761       /*clipped_level_min=*/64,
1762       /*min_mic_level=*/84,
1763       /*update_input_volume_wait_frames=*/4, kHighSpeechProbability,
1764       /*speech_ratio_threshold=*/0.75f);
1765   mono_controller_1.Initialize();
1766   mono_controller_2.Initialize();
1767 
1768   int volume_1 = UpdateRecommendedInputVolume(
1769       mono_controller_1, kInitialInputVolume, kHighSpeechProbability, -10.0f);
1770   int volume_2 = UpdateRecommendedInputVolume(
1771       mono_controller_2, kInitialInputVolume, kHighSpeechProbability, -10.0f);
1772 
1773   volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
1774                                           kHighSpeechProbability, -10.0f);
1775   volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
1776                                           kHighSpeechProbability, -10.0f);
1777 
1778   volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
1779                                           kLowSpeechProbability, -10.0f);
1780   volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
1781                                           kLowSpeechProbability, -10.0f);
1782 
1783   EXPECT_EQ(volume_1, kInitialInputVolume);
1784   EXPECT_EQ(volume_2, kInitialInputVolume);
1785 
1786   volume_1 = UpdateRecommendedInputVolume(mono_controller_1, volume_1,
1787                                           kLowSpeechProbability, -10.0f);
1788   volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
1789                                           kHighSpeechProbability, -10.0f);
1790 
1791   EXPECT_EQ(volume_1, kInitialInputVolume);
1792   EXPECT_LT(volume_2, volume_1);
1793 }
1794 
TEST(MonoInputVolumeControllerTest,CheckProcessEmptyRmsErrorDoesNotLowerVolume)1795 TEST(MonoInputVolumeControllerTest,
1796      CheckProcessEmptyRmsErrorDoesNotLowerVolume) {
1797   constexpr int kInitialInputVolume = 100;
1798   MonoInputVolumeController mono_controller_1(
1799       /*clipped_level_min=*/64,
1800       /*min_mic_level=*/84,
1801       /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
1802       kSpeechRatioThreshold);
1803   MonoInputVolumeController mono_controller_2(
1804       /*clipped_level_min=*/64,
1805       /*min_mic_level=*/84,
1806       /*update_input_volume_wait_frames=*/2, kHighSpeechProbability,
1807       kSpeechRatioThreshold);
1808   mono_controller_1.Initialize();
1809   mono_controller_2.Initialize();
1810 
1811   int volume_1 = UpdateRecommendedInputVolume(
1812       mono_controller_1, kInitialInputVolume, kHighSpeechProbability, -10.0f);
1813   int volume_2 = UpdateRecommendedInputVolume(
1814       mono_controller_2, kInitialInputVolume, kHighSpeechProbability, -10.0f);
1815 
1816   EXPECT_EQ(volume_1, kInitialInputVolume);
1817   EXPECT_EQ(volume_2, kInitialInputVolume);
1818 
1819   volume_1 = UpdateRecommendedInputVolume(
1820       mono_controller_1, volume_1, kHighSpeechProbability, absl::nullopt);
1821   volume_2 = UpdateRecommendedInputVolume(mono_controller_2, volume_2,
1822                                           kHighSpeechProbability, -10.0f);
1823 
1824   EXPECT_EQ(volume_1, kInitialInputVolume);
1825   EXPECT_LT(volume_2, volume_1);
1826 }
1827 
1828 }  // namespace webrtc
1829