AEC3: Use minimum ERLE during onsets

This change disables the ERLE estimation of onsets and instead assumes
minimum ERLE. This reduces the risk of echo leaks during onsets. The
estimated ERLE was sometimes incorrect due to:
- Not enough data to train on.
- Platform noise suppression can change the echo-path.

Bug: chromium:119942,webrtc:10341
Change-Id: I1dd1c0f160489e76eb784f07e99af02f44f387ec
Reviewed-on: https://webrtc-review.googlesource.com/c/123782
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Reviewed-by: Jesus de Vicente Pena <devicentepena@webrtc.org>
Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26794}
diff --git a/modules/audio_processing/aec3/BUILD.gn b/modules/audio_processing/aec3/BUILD.gn
index 7fbc405..e8bbe69 100644
--- a/modules/audio_processing/aec3/BUILD.gn
+++ b/modules/audio_processing/aec3/BUILD.gn
@@ -143,6 +143,7 @@
     "../../../rtc_base:safe_minmax",
     "../../../rtc_base/system:arch",
     "../../../system_wrappers:cpu_features_api",
+    "../../../system_wrappers:field_trial",
     "../../../system_wrappers:metrics",
     "../utility:ooura_fft",
     "//third_party/abseil-cpp/absl/types:optional",
diff --git a/modules/audio_processing/aec3/subband_erle_estimator.cc b/modules/audio_processing/aec3/subband_erle_estimator.cc
index 730522d..82f3dab 100644
--- a/modules/audio_processing/aec3/subband_erle_estimator.cc
+++ b/modules/audio_processing/aec3/subband_erle_estimator.cc
@@ -15,6 +15,7 @@
 
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_minmax.h"
+#include "system_wrappers/include/field_trial.h"
 
 namespace webrtc {
 
@@ -33,11 +34,16 @@
   return max_erle;
 }
 
+bool EnableMinErleDuringOnsets() {
+  return !field_trial::IsEnabled("WebRTC-Aec3MinErleDuringOnsetsKillSwitch");
+}
+
 }  // namespace
 
 SubbandErleEstimator::SubbandErleEstimator(const EchoCanceller3Config& config)
     : min_erle_(config.erle.min),
-      max_erle_(SetMaxErleBands(config.erle.max_l, config.erle.max_h)) {
+      max_erle_(SetMaxErleBands(config.erle.max_l, config.erle.max_h)),
+      use_min_erle_during_onsets_(EnableMinErleDuringOnsets()) {
   Reset();
 }
 
@@ -95,10 +101,12 @@
       if (is_erle_updated[k] && !accum_spectra_.low_render_energy_[k]) {
         if (coming_onset_[k]) {
           coming_onset_[k] = false;
-          float alpha = new_erle[k] < erle_onsets_[k] ? 0.3f : 0.15f;
-          erle_onsets_[k] = rtc::SafeClamp(
-              erle_onsets_[k] + alpha * (new_erle[k] - erle_onsets_[k]),
-              min_erle_, max_erle_[k]);
+          if (!use_min_erle_during_onsets_) {
+            float alpha = new_erle[k] < erle_onsets_[k] ? 0.3f : 0.15f;
+            erle_onsets_[k] = rtc::SafeClamp(
+                erle_onsets_[k] + alpha * (new_erle[k] - erle_onsets_[k]),
+                min_erle_, max_erle_[k]);
+          }
         }
         hold_counters_[k] = kBlocksForOnsetDetection;
       }
diff --git a/modules/audio_processing/aec3/subband_erle_estimator.h b/modules/audio_processing/aec3/subband_erle_estimator.h
index c1ad4b5..903c629 100644
--- a/modules/audio_processing/aec3/subband_erle_estimator.h
+++ b/modules/audio_processing/aec3/subband_erle_estimator.h
@@ -66,6 +66,7 @@
 
   const float min_erle_;
   const std::array<float, kFftLengthBy2Plus1> max_erle_;
+  const bool use_min_erle_during_onsets_;
   AccumulatedSpectra accum_spectra_;
   std::array<float, kFftLengthBy2Plus1> erle_;
   std::array<float, kFftLengthBy2Plus1> erle_onsets_;
diff --git a/test/fuzzers/audio_processing_configs_fuzzer.cc b/test/fuzzers/audio_processing_configs_fuzzer.cc
index 333144f..efaeb13 100644
--- a/test/fuzzers/audio_processing_configs_fuzzer.cc
+++ b/test/fuzzers/audio_processing_configs_fuzzer.cc
@@ -28,6 +28,7 @@
 const std::string kFieldTrialNames[] = {
     "WebRTC-Audio-Agc2ForceExtraSaturationMargin",
     "WebRTC-Audio-Agc2ForceInitialSaturationMargin",
+    "WebRTC-Aec3MinErleDuringOnsetsKillSwitch",
 };
 
 std::unique_ptr<AudioProcessing> CreateApm(test::FuzzDataHelper* fuzz_data,