AEC3: Avoid using filter output in suppression gain computation in non-linear mode

As non-linear mode uses a suppressed version of y (not e) as output, this change
uses Y2, rather than E2, as nearend spectrum when computing the suppression gains.
E2 is still used in linear mode.

This change also affects how the minimum suppression gains are calculated. The
minimum gain is now min_echo_power / weighted_residual_echo.

Bug: webrtc:10550
Change-Id: I2904c5a09dd64b06bf25eb5a37c18dab50297794
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/133023
Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org>
Reviewed-by: Per Ã…hgren <peah@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27629}
diff --git a/modules/audio_processing/aec3/echo_remover.cc b/modules/audio_processing/aec3/echo_remover.cc
index cb24248..493916c 100644
--- a/modules/audio_processing/aec3/echo_remover.cc
+++ b/modules/audio_processing/aec3/echo_remover.cc
@@ -290,15 +290,22 @@
   // Estimate the comfort noise.
   cng_.Compute(aec_state_, Y2, &comfort_noise, &high_band_comfort_noise);
 
-  // Compute and apply the suppression gain.
+  // Suppressor echo estimate.
   const auto& echo_spectrum =
       aec_state_.UsableLinearEstimate() ? S2_linear : R2;
 
-  std::array<float, kFftLengthBy2Plus1> E2_bounded;
-  std::transform(E2.begin(), E2.end(), Y2.begin(), E2_bounded.begin(),
-                 [](float a, float b) { return std::min(a, b); });
+  // Suppressor nearend estimate.
+  std::array<float, kFftLengthBy2Plus1> nearend_spectrum_bounded;
+  if (aec_state_.UsableLinearEstimate()) {
+    std::transform(E2.begin(), E2.end(), Y2.begin(),
+                   nearend_spectrum_bounded.begin(),
+                   [](float a, float b) { return std::min(a, b); });
+  }
+  auto& nearend_spectrum =
+      aec_state_.UsableLinearEstimate() ? nearend_spectrum_bounded : Y2;
 
-  suppression_gain_.GetGain(E2, E2_bounded, echo_spectrum, R2,
+  // Compute and apply the suppression gain.
+  suppression_gain_.GetGain(nearend_spectrum, echo_spectrum, R2,
                             cng_.NoiseSpectrum(), render_signal_analyzer_,
                             aec_state_, x, &high_bands_gain, &G);
 
diff --git a/modules/audio_processing/aec3/suppression_gain.cc b/modules/audio_processing/aec3/suppression_gain.cc
index 935980f..b741a71 100644
--- a/modules/audio_processing/aec3/suppression_gain.cc
+++ b/modules/audio_processing/aec3/suppression_gain.cc
@@ -197,7 +197,6 @@
 // Compute the minimum gain as the attenuating gain to put the signal just
 // above the zero sample values.
 void SuppressionGain::GetMinGain(
-    rtc::ArrayView<const float> suppressor_input,
     rtc::ArrayView<const float> weighted_residual_echo,
     bool low_noise_render,
     bool saturated_echo,
@@ -207,10 +206,10 @@
         low_noise_render ? config_.echo_audibility.low_render_limit
                          : config_.echo_audibility.normal_render_limit;
 
-    for (size_t k = 0; k < suppressor_input.size(); ++k) {
-      const float denom =
-          std::min(suppressor_input[k], weighted_residual_echo[k]);
-      min_gain[k] = denom > 0.f ? min_echo_power / denom : 1.f;
+    for (size_t k = 0; k < min_gain.size(); ++k) {
+      min_gain[k] = weighted_residual_echo[k] > 0.f
+                        ? min_echo_power / weighted_residual_echo[k]
+                        : 1.f;
       min_gain[k] = std::min(min_gain[k], 1.f);
     }
     for (size_t k = 0; k < 6; ++k) {
@@ -259,8 +258,8 @@
   WeightEchoForAudibility(config_, residual_echo, weighted_residual_echo);
 
   std::array<float, kFftLengthBy2Plus1> min_gain;
-  GetMinGain(suppressor_input, weighted_residual_echo, low_noise_render,
-             saturated_echo, min_gain);
+  GetMinGain(weighted_residual_echo, low_noise_render, saturated_echo,
+             min_gain);
 
   std::array<float, kFftLengthBy2Plus1> max_gain;
   GetMaxGain(max_gain);
@@ -311,7 +310,6 @@
 SuppressionGain::~SuppressionGain() = default;
 
 void SuppressionGain::GetGain(
-    const std::array<float, kFftLengthBy2Plus1>& suppressor_input_spectrum,
     const std::array<float, kFftLengthBy2Plus1>& nearend_spectrum,
     const std::array<float, kFftLengthBy2Plus1>& echo_spectrum,
     const std::array<float, kFftLengthBy2Plus1>& residual_echo_spectrum,
@@ -340,9 +338,8 @@
 
   // Compute gain for the lower band.
   bool low_noise_render = low_render_detector_.Detect(render);
-  LowerBandGain(low_noise_render, aec_state, suppressor_input_spectrum,
-                nearend_average, residual_echo_spectrum, comfort_noise_spectrum,
-                low_band_gain);
+  LowerBandGain(low_noise_render, aec_state, nearend_spectrum, nearend_average,
+                residual_echo_spectrum, comfort_noise_spectrum, low_band_gain);
 
   // Compute the gain for the upper bands.
   const absl::optional<int> narrow_peak_band =
diff --git a/modules/audio_processing/aec3/suppression_gain.h b/modules/audio_processing/aec3/suppression_gain.h
index 317f43c..2b34dbe 100644
--- a/modules/audio_processing/aec3/suppression_gain.h
+++ b/modules/audio_processing/aec3/suppression_gain.h
@@ -35,7 +35,6 @@
                   int sample_rate_hz);
   ~SuppressionGain();
   void GetGain(
-      const std::array<float, kFftLengthBy2Plus1>& suppressor_input_spectrum,
       const std::array<float, kFftLengthBy2Plus1>& nearend_spectrum,
       const std::array<float, kFftLengthBy2Plus1>& echo_spectrum,
       const std::array<float, kFftLengthBy2Plus1>& residual_echo_spectrum,
@@ -76,8 +75,7 @@
       const std::array<float, kFftLengthBy2Plus1>& comfort_noise,
       std::array<float, kFftLengthBy2Plus1>* gain);
 
-  void GetMinGain(rtc::ArrayView<const float> suppressor_input,
-                  rtc::ArrayView<const float> weighted_residual_echo,
+  void GetMinGain(rtc::ArrayView<const float> weighted_residual_echo,
                   bool low_noise_render,
                   bool saturated_echo,
                   rtc::ArrayView<float> min_gain) const;
diff --git a/modules/audio_processing/aec3/suppression_gain_unittest.cc b/modules/audio_processing/aec3/suppression_gain_unittest.cc
index fc721fe..b110e0a 100644
--- a/modules/audio_processing/aec3/suppression_gain_unittest.cc
+++ b/modules/audio_processing/aec3/suppression_gain_unittest.cc
@@ -45,7 +45,7 @@
   AecState aec_state(EchoCanceller3Config{});
   EXPECT_DEATH(
       SuppressionGain(EchoCanceller3Config{}, DetectOptimization(), 16000)
-          .GetGain(E2, E2, S2, R2, N2,
+          .GetGain(E2, S2, R2, N2,
                    RenderSignalAnalyzer((EchoCanceller3Config{})), aec_state,
                    std::vector<std::vector<float>>(
                        3, std::vector<float>(kBlockSize, 0.f)),
@@ -100,7 +100,7 @@
                      subtractor.FilterImpulseResponse(),
                      *render_delay_buffer->GetRenderBuffer(), E2, Y2, output,
                      y);
-    suppression_gain.GetGain(E2, E2, S2, R2, N2, analyzer, aec_state, x,
+    suppression_gain.GetGain(E2, S2, R2, N2, analyzer, aec_state, x,
                              &high_bands_gain, &g);
   }
   std::for_each(g.begin(), g.end(),
@@ -118,7 +118,7 @@
                      subtractor.FilterImpulseResponse(),
                      *render_delay_buffer->GetRenderBuffer(), E2, Y2, output,
                      y);
-    suppression_gain.GetGain(E2, E2, S2, R2, N2, analyzer, aec_state, x,
+    suppression_gain.GetGain(E2, S2, R2, N2, analyzer, aec_state, x,
                              &high_bands_gain, &g);
   }
   std::for_each(g.begin(), g.end(),
@@ -129,7 +129,7 @@
   R2.fill(10000000000000.f);
 
   for (int k = 0; k < 10; ++k) {
-    suppression_gain.GetGain(E2, E2, S2, R2, N2, analyzer, aec_state, x,
+    suppression_gain.GetGain(E2, S2, R2, N2, analyzer, aec_state, x,
                              &high_bands_gain, &g);
   }
   std::for_each(g.begin(), g.end(),
diff --git a/resources/audio_processing/output_data_float.pb.sha1 b/resources/audio_processing/output_data_float.pb.sha1
index 907ebfd..e9c065b 100644
--- a/resources/audio_processing/output_data_float.pb.sha1
+++ b/resources/audio_processing/output_data_float.pb.sha1
@@ -1 +1 @@
-169276fe22bbeb1c06e0ed1a9df8149c5dbf8f80
\ No newline at end of file
+bc19d9e9fd9503cad02f3b0c21cbd63ed3c5f22c
\ No newline at end of file