AgcManagerDirect: Refine unit tests

Add unit tests `UsedClippingPredictionsProduceLowerAnalogLevels` and
`UnusedClippingPredictionsProduceEqualAnalogLevels`. These tests replace
the existing tests `EnableClippingPredictorLowersVolume` and
`EnableClippingPredictorWithUnusedPredictedStepDoesNotLowerVolume`.

Bug: webrtc:12774
Change-Id: I2f5b726d58d8afb3d3bf39a3c96fa8d3910fa9e0
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/231225
Commit-Queue: Hanna Silen <silen@webrtc.org>
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#34932}
diff --git a/modules/audio_processing/agc/agc_manager_direct.h b/modules/audio_processing/agc/agc_manager_direct.h
index 27569d8..a452ee1 100644
--- a/modules/audio_processing/agc/agc_manager_direct.h
+++ b/modules/audio_processing/agc/agc_manager_direct.h
@@ -106,11 +106,10 @@
                            ClippingParametersVerified);
   FRIEND_TEST_ALL_PREFIXES(AgcManagerDirectStandaloneTest,
                            DisableClippingPredictorDoesNotLowerVolume);
-  FRIEND_TEST_ALL_PREFIXES(
-      AgcManagerDirectStandaloneTest,
-      EnableClippingPredictorWithUnusedPredictedStepDoesNotLowerVolume);
   FRIEND_TEST_ALL_PREFIXES(AgcManagerDirectStandaloneTest,
-                           EnableClippingPredictorLowersVolume);
+                           UsedClippingPredictionsProduceLowerAnalogLevels);
+  FRIEND_TEST_ALL_PREFIXES(AgcManagerDirectStandaloneTest,
+                           UnusedClippingPredictionsProduceEqualAnalogLevels);
 
   // Dependency injection for testing. Don't delete `agc` as the memory is owned
   // by the manager.
diff --git a/modules/audio_processing/agc/agc_manager_direct_unittest.cc b/modules/audio_processing/agc/agc_manager_direct_unittest.cc
index bb284f9..14f9cd7 100644
--- a/modules/audio_processing/agc/agc_manager_direct_unittest.cc
+++ b/modules/audio_processing/agc/agc_manager_direct_unittest.cc
@@ -951,48 +951,177 @@
 }
 
 TEST(AgcManagerDirectStandaloneTest,
-     EnableClippingPredictorWithUnusedPredictedStepDoesNotLowerVolume) {
-  // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed.
-  ClippingPredictorConfig config;
-  config.enabled = true;
-  config.use_predicted_step = false;
-  AgcManagerDirect manager(new ::testing::NiceMock<MockAgc>(), kInitialVolume,
-                           kClippedMin, kSampleRateHz, kClippedLevelStep,
-                           kClippedRatioThreshold, kClippedWaitFrames, config);
-  manager.Initialize();
-  manager.set_stream_analog_level(/*level=*/255);
-  EXPECT_TRUE(manager.clipping_predictor_enabled());
-  EXPECT_FALSE(manager.use_clipping_predictor_step());
-  EXPECT_EQ(manager.stream_analog_level(), 255);
-  manager.Process(nullptr);
-  CallPreProcessAudioBuffer(/*num_calls=*/10, /*peak_ratio=*/0.99f, manager);
-  EXPECT_EQ(manager.stream_analog_level(), 255);
-  CallPreProcessAudioBuffer(/*num_calls=*/300, /*peak_ratio=*/0.99f, manager);
-  EXPECT_EQ(manager.stream_analog_level(), 255);
-  CallPreProcessAudioBuffer(/*num_calls=*/10, /*peak_ratio=*/0.99f, manager);
-  EXPECT_EQ(manager.stream_analog_level(), 255);
+     UsedClippingPredictionsProduceLowerAnalogLevels) {
+  // TODO(bugs.webrtc.org/12874): Use designated initializers once fixed.
+  ClippingPredictorConfig config_with_prediction;
+  config_with_prediction.enabled = true;
+  config_with_prediction.use_predicted_step = true;
+  AgcManagerDirect manager_with_prediction(
+      new ::testing::NiceMock<MockAgc>(), kInitialVolume, kClippedMin,
+      kSampleRateHz, kClippedLevelStep, kClippedRatioThreshold,
+      kClippedWaitFrames, config_with_prediction);
+  ClippingPredictorConfig config_without_prediction;
+  config_without_prediction.enabled = false;
+  AgcManagerDirect manager_without_prediction(
+      new ::testing::NiceMock<MockAgc>(), kInitialVolume, kClippedMin,
+      kSampleRateHz, kClippedLevelStep, kClippedRatioThreshold,
+      kClippedWaitFrames, config_without_prediction);
+  manager_with_prediction.Initialize();
+  manager_without_prediction.Initialize();
+  constexpr int kInitialLevel = 255;
+  constexpr float kClippingPeakRatio = 1.0f;
+  constexpr float kCloseToClippingPeakRatio = 0.99f;
+  constexpr float kZeroPeakRatio = 0.0f;
+  manager_with_prediction.set_stream_analog_level(kInitialLevel);
+  manager_without_prediction.set_stream_analog_level(kInitialLevel);
+  manager_with_prediction.Process(nullptr);
+  manager_without_prediction.Process(nullptr);
+  EXPECT_TRUE(manager_with_prediction.clipping_predictor_enabled());
+  EXPECT_FALSE(manager_without_prediction.clipping_predictor_enabled());
+  EXPECT_TRUE(manager_with_prediction.use_clipping_predictor_step());
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(), kInitialLevel);
+  EXPECT_EQ(manager_without_prediction.stream_analog_level(), kInitialLevel);
+  // Expect a change in the analog level when the prediction step is used.
+  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
+                            manager_with_prediction);
+  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
+                            manager_without_prediction);
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(),
+            kInitialLevel - kClippedLevelStep);
+  EXPECT_EQ(manager_without_prediction.stream_analog_level(), kInitialLevel);
+  // Expect no change during waiting.
+  CallPreProcessAudioBuffer(kClippedWaitFrames, kCloseToClippingPeakRatio,
+                            manager_with_prediction);
+  CallPreProcessAudioBuffer(kClippedWaitFrames, kCloseToClippingPeakRatio,
+                            manager_without_prediction);
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(),
+            kInitialLevel - kClippedLevelStep);
+  EXPECT_EQ(manager_without_prediction.stream_analog_level(), kInitialLevel);
+  // Expect a change when the prediction step is used.
+  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
+                            manager_with_prediction);
+  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
+                            manager_without_prediction);
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(),
+            kInitialLevel - 2 * kClippedLevelStep);
+  EXPECT_EQ(manager_without_prediction.stream_analog_level(), kInitialLevel);
+  // Expect no change when clipping is not detected or predicted.
+  CallPreProcessAudioBuffer(2 * kClippedWaitFrames, kZeroPeakRatio,
+                            manager_with_prediction);
+  CallPreProcessAudioBuffer(2 * kClippedWaitFrames, kZeroPeakRatio,
+                            manager_without_prediction);
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(),
+            kInitialLevel - 2 * kClippedLevelStep);
+  EXPECT_EQ(manager_without_prediction.stream_analog_level(), kInitialLevel);
+  // Expect a change for clipping frames.
+  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
+                            manager_with_prediction);
+  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
+                            manager_without_prediction);
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(),
+            kInitialLevel - 3 * kClippedLevelStep);
+  EXPECT_EQ(manager_without_prediction.stream_analog_level(),
+            kInitialLevel - kClippedLevelStep);
+  // Expect no change during waiting.
+  CallPreProcessAudioBuffer(kClippedWaitFrames, kClippingPeakRatio,
+                            manager_with_prediction);
+  CallPreProcessAudioBuffer(kClippedWaitFrames, kClippingPeakRatio,
+                            manager_without_prediction);
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(),
+            kInitialLevel - 3 * kClippedLevelStep);
+  EXPECT_EQ(manager_without_prediction.stream_analog_level(),
+            kInitialLevel - kClippedLevelStep);
+  // Expect a change for clipping frames.
+  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
+                            manager_with_prediction);
+  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
+                            manager_without_prediction);
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(),
+            kInitialLevel - 4 * kClippedLevelStep);
+  EXPECT_EQ(manager_without_prediction.stream_analog_level(),
+            kInitialLevel - 2 * kClippedLevelStep);
 }
 
-TEST(AgcManagerDirectStandaloneTest, EnableClippingPredictorLowersVolume) {
-  // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed.
-  ClippingPredictorConfig config;
-  config.enabled = true;
-  config.use_predicted_step = true;
-  AgcManagerDirect manager(new ::testing::NiceMock<MockAgc>(), kInitialVolume,
-                           kClippedMin, kSampleRateHz, kClippedLevelStep,
-                           kClippedRatioThreshold, kClippedWaitFrames, config);
-  manager.Initialize();
-  manager.set_stream_analog_level(/*level=*/255);
-  EXPECT_TRUE(manager.clipping_predictor_enabled());
-  EXPECT_TRUE(manager.use_clipping_predictor_step());
-  EXPECT_EQ(manager.stream_analog_level(), 255);
-  manager.Process(nullptr);
-  CallPreProcessAudioBuffer(/*num_calls=*/10, /*peak_ratio=*/0.99f, manager);
-  EXPECT_EQ(manager.stream_analog_level(), 240);
-  CallPreProcessAudioBuffer(/*num_calls=*/300, /*peak_ratio=*/0.99f, manager);
-  EXPECT_EQ(manager.stream_analog_level(), 240);
-  CallPreProcessAudioBuffer(/*num_calls=*/10, /*peak_ratio=*/0.99f, manager);
-  EXPECT_EQ(manager.stream_analog_level(), 225);
+TEST(AgcManagerDirectStandaloneTest,
+     UnusedClippingPredictionsProduceEqualAnalogLevels) {
+  // TODO(bugs.webrtc.org/12874): Use designated initializers once fixed.
+  ClippingPredictorConfig config_with_prediction;
+  config_with_prediction.enabled = true;
+  config_with_prediction.use_predicted_step = false;
+  AgcManagerDirect manager_with_prediction(
+      new ::testing::NiceMock<MockAgc>(), kInitialVolume, kClippedMin,
+      kSampleRateHz, kClippedLevelStep, kClippedRatioThreshold,
+      kClippedWaitFrames, config_with_prediction);
+  ClippingPredictorConfig config_without_prediction;
+  config_without_prediction.enabled = false;
+  AgcManagerDirect manager_without_prediction(
+      new ::testing::NiceMock<MockAgc>(), kInitialVolume, kClippedMin,
+      kSampleRateHz, kClippedLevelStep, kClippedRatioThreshold,
+      kClippedWaitFrames, config_without_prediction);
+  constexpr int kInitialLevel = 255;
+  constexpr float kClippingPeakRatio = 1.0f;
+  constexpr float kCloseToClippingPeakRatio = 0.99f;
+  constexpr float kZeroPeakRatio = 0.0f;
+  manager_with_prediction.Initialize();
+  manager_without_prediction.Initialize();
+  manager_with_prediction.set_stream_analog_level(kInitialLevel);
+  manager_without_prediction.set_stream_analog_level(kInitialLevel);
+  manager_with_prediction.Process(nullptr);
+  manager_without_prediction.Process(nullptr);
+  EXPECT_TRUE(manager_with_prediction.clipping_predictor_enabled());
+  EXPECT_FALSE(manager_without_prediction.clipping_predictor_enabled());
+  EXPECT_FALSE(manager_with_prediction.use_clipping_predictor_step());
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(), kInitialLevel);
+  EXPECT_EQ(manager_without_prediction.stream_analog_level(), kInitialLevel);
+  // Expect no change in the analog level for non-clipping frames.
+  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
+                            manager_with_prediction);
+  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
+                            manager_without_prediction);
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(),
+            manager_without_prediction.stream_analog_level());
+  // Expect no change for non-clipping frames.
+  CallPreProcessAudioBuffer(kClippedWaitFrames, kCloseToClippingPeakRatio,
+                            manager_with_prediction);
+  CallPreProcessAudioBuffer(kClippedWaitFrames, kCloseToClippingPeakRatio,
+                            manager_without_prediction);
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(),
+            manager_without_prediction.stream_analog_level());
+  // Expect no change for non-clipping frames.
+  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
+                            manager_with_prediction);
+  CallPreProcessAudioBuffer(/*num_calls=*/10, kCloseToClippingPeakRatio,
+                            manager_without_prediction);
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(),
+            manager_without_prediction.stream_analog_level());
+  // Expect no change when clipping is not detected or predicted.
+  CallPreProcessAudioBuffer(2 * kClippedWaitFrames, kZeroPeakRatio,
+                            manager_with_prediction);
+  CallPreProcessAudioBuffer(2 * kClippedWaitFrames, kZeroPeakRatio,
+                            manager_without_prediction);
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(),
+            manager_without_prediction.stream_analog_level());
+  // Expect a change for clipping frames.
+  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
+                            manager_with_prediction);
+  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
+                            manager_without_prediction);
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(),
+            manager_without_prediction.stream_analog_level());
+  // Expect no change during waiting.
+  CallPreProcessAudioBuffer(kClippedWaitFrames, kClippingPeakRatio,
+                            manager_with_prediction);
+  CallPreProcessAudioBuffer(kClippedWaitFrames, kClippingPeakRatio,
+                            manager_without_prediction);
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(),
+            manager_without_prediction.stream_analog_level());
+  // Expect a change for clipping frames.
+  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
+                            manager_with_prediction);
+  CallPreProcessAudioBuffer(/*num_calls=*/1, kClippingPeakRatio,
+                            manager_without_prediction);
+  EXPECT_EQ(manager_with_prediction.stream_analog_level(),
+            manager_without_prediction.stream_analog_level());
 }
 
 }  // namespace webrtc