AGC2: retuning and large refactoring

- Bug fix: the desired initial gain quickly dropped to 0 dB hence
  starting a call with a too low level
- New tuning to make AGC2 more robust to VAD mistakes
- Smarter max gain increase speed: to deal with an increased threshold
  of adjacent speech frames, the gain applier temporarily allows a
  faster gain increase to deal with a longer time spent waiting for
  enough speech frames in a row to be observed
- Saturation protector isolated from `AdaptiveModeLevelEstimator` to
  simplify the unit tests for the latter (non bit-exact change)
- AGC2 adaptive digital config: unnecessary params deprecated
- Code readability improvements
- Data dumps clean-up and better naming

Bug: webrtc:7494
Change-Id: I4e36059bdf2566cc2a7e1a7e95b7430ba9ae9844
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/215140
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Reviewed-by: Jesus de Vicente Pena <devicentepena@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33736}
diff --git a/modules/audio_processing/gain_controller2_unittest.cc b/modules/audio_processing/gain_controller2_unittest.cc
index 274c821..815d58e 100644
--- a/modules/audio_processing/gain_controller2_unittest.cc
+++ b/modules/audio_processing/gain_controller2_unittest.cc
@@ -11,6 +11,7 @@
 #include "modules/audio_processing/gain_controller2.h"
 
 #include <algorithm>
+#include <cmath>
 #include <memory>
 
 #include "api/array_view.h"
@@ -68,7 +69,8 @@
   return agc2;
 }
 
-float GainAfterProcessingFile(GainController2* gain_controller) {
+float GainDbAfterProcessingFile(GainController2& gain_controller,
+                                int max_duration_ms) {
   // Set up an AudioBuffer to be filled from the speech file.
   constexpr size_t kStereo = 2u;
   const StreamConfig capture_config(AudioProcessing::kSampleRate48kHz, kStereo,
@@ -82,24 +84,29 @@
   std::vector<float> capture_input(capture_config.num_frames() *
                                    capture_config.num_channels());
 
-  // The file should contain at least this many frames. Every iteration, we put
-  // a frame through the gain controller.
-  const int kNumFramesToProcess = 100;
-  for (int frame_no = 0; frame_no < kNumFramesToProcess; ++frame_no) {
+  // Process the input file which must be long enough to cover
+  // `max_duration_ms`.
+  RTC_DCHECK_GT(max_duration_ms, 0);
+  const int num_frames = rtc::CheckedDivExact(max_duration_ms, 10);
+  for (int i = 0; i < num_frames; ++i) {
     ReadFloatSamplesFromStereoFile(capture_config.num_frames(),
                                    capture_config.num_channels(), &capture_file,
                                    capture_input);
-
     test::CopyVectorToAudioBuffer(capture_config, capture_input, &ab);
-    gain_controller->Process(&ab);
+    gain_controller.Process(&ab);
   }
 
-  // Send in a last frame with values constant 1 (It's low enough to detect high
-  // gain, and for ease of computation). The applied gain is the result.
+  // Send in a last frame with minimum dBFS level.
   constexpr float sample_value = 1.f;
   SetAudioBufferSamples(sample_value, &ab);
-  gain_controller->Process(&ab);
-  return ab.channels()[0][0];
+  gain_controller.Process(&ab);
+  // Measure the RMS level after processing.
+  float rms = 0.0f;
+  for (size_t i = 0; i < capture_config.num_frames(); ++i) {
+    rms += ab.channels()[0][i] * ab.channels()[0][i];
+  }
+  // Return the applied gain in dB.
+  return 20.0f * std::log10(std::sqrt(rms / capture_config.num_frames()));
 }
 
 }  // namespace
@@ -324,34 +331,20 @@
                                48000,
                                true)));
 
-TEST(GainController2, UsageSaturationMargin) {
+// Checks that the gain applied at the end of a PCM samples file is close to the
+// expected value.
+TEST(GainController2, CheckGainAdaptiveDigital) {
+  constexpr float kExpectedGainDb = 4.3f;
+  constexpr float kToleranceDb = 0.5f;
   GainController2 gain_controller2;
   gain_controller2.Initialize(AudioProcessing::kSampleRate48kHz);
-
   AudioProcessing::Config::GainController2 config;
-  // Check that samples are not amplified as much when extra margin is
-  // high. They should not be amplified at all, but only after convergence. GC2
-  // starts with a gain, and it takes time until it's down to 0 dB.
   config.fixed_digital.gain_db = 0.f;
   config.adaptive_digital.enabled = true;
-  config.adaptive_digital.extra_saturation_margin_db = 50.f;
   gain_controller2.ApplyConfig(config);
-
-  EXPECT_LT(GainAfterProcessingFile(&gain_controller2), 2.f);
-}
-
-TEST(GainController2, UsageNoSaturationMargin) {
-  GainController2 gain_controller2;
-  gain_controller2.Initialize(AudioProcessing::kSampleRate48kHz);
-
-  AudioProcessing::Config::GainController2 config;
-  // Check that some gain is applied if there is no margin.
-  config.fixed_digital.gain_db = 0.f;
-  config.adaptive_digital.enabled = true;
-  config.adaptive_digital.extra_saturation_margin_db = 0.f;
-  gain_controller2.ApplyConfig(config);
-
-  EXPECT_GT(GainAfterProcessingFile(&gain_controller2), 1.9f);
+  EXPECT_NEAR(
+      GainDbAfterProcessingFile(gain_controller2, /*max_duration_ms=*/2000),
+      kExpectedGainDb, kToleranceDb);
 }
 
 }  // namespace test