AEC3: Adding a reset of the ERLE estimator after going out from the initial state.

Bug: webrtc:9685
Change-Id: Ifc6019811c3d90df91df07e68f1d04cb39cb3545
Reviewed-on: https://webrtc-review.googlesource.com/96661
Reviewed-by: Per Åhgren <peah@webrtc.org>
Commit-Queue: Jesus de Vicente Pena <devicentepena@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24484}
diff --git a/modules/audio_processing/aec3/aec_state.cc b/modules/audio_processing/aec3/aec_state.cc
index a3fd679..62232ac1 100644
--- a/modules/audio_processing/aec3/aec_state.cc
+++ b/modules/audio_processing/aec3/aec_state.cc
@@ -235,6 +235,9 @@
   }
 
   // Update the ERL and ERLE measures.
+  if (reset_erle_after_echo_path_changes_ && transition_triggered_) {
+    erle_estimator_.Reset();
+  }
   if (blocks_since_reset_ >= 2 * kNumBlocksPerSecond) {
     const auto& X2 = render_buffer.Spectrum(filter_delay_blocks_);
     erle_estimator_.Update(X2, Y2, E2_main, converged_filter,
@@ -267,6 +270,7 @@
   }
 
   // Flag whether the initial state is still active.
+  bool prev_initial_state = initial_state_;
   if (use_short_initial_state_) {
     initial_state_ = blocks_with_proper_filter_adaptation_ <
                      config_.filter.initial_state_seconds * kNumBlocksPerSecond;
@@ -274,6 +278,7 @@
     initial_state_ =
         blocks_with_proper_filter_adaptation_ < 5 * kNumBlocksPerSecond;
   }
+  transition_triggered_ = !initial_state_ && prev_initial_state;
 
   // Update counters for the filter divergence and convergence.
   diverged_blocks_ = diverged_filter ? diverged_blocks_ + 1 : 0;
@@ -382,7 +387,7 @@
   data_dumper_->DumpRaw("aec3_consistent_filter",
                         filter_analyzer_.Consistent());
   data_dumper_->DumpRaw("aec3_suppression_gain_limit", SuppressionGainLimit());
-  data_dumper_->DumpRaw("aec3_initial_state", InitialState());
+  data_dumper_->DumpRaw("aec3_initial_state", initial_state_);
   data_dumper_->DumpRaw("aec3_capture_saturation", SaturatedCapture());
   data_dumper_->DumpRaw("aec3_echo_saturation", echo_saturation_);
   data_dumper_->DumpRaw("aec3_converged_filter", converged_filter);
diff --git a/modules/audio_processing/aec3/aec_state.h b/modules/audio_processing/aec3/aec_state.h
index 772ed90..ea30daf 100644
--- a/modules/audio_processing/aec3/aec_state.h
+++ b/modules/audio_processing/aec3/aec_state.h
@@ -140,8 +140,9 @@
     return filter_has_had_time_to_converge_;
   }
 
-  // Returns whether the filter adaptation is still in the initial state.
-  bool InitialState() const { return initial_state_; }
+  // Returns whether the transition for going out of the initial stated has
+  // been triggered.
+  bool TransitionTriggered() const { return transition_triggered_; }
 
   // Updates the aec state.
   void Update(const absl::optional<DelayEstimate>& external_delay,
@@ -197,6 +198,7 @@
   std::vector<float> max_render_;
   bool filter_has_had_time_to_converge_ = false;
   bool initial_state_ = true;
+  bool transition_triggered_ = false;
   const float gain_rampup_increase_;
   SuppressionGainUpperLimiter suppression_gain_limiter_;
   FilterAnalyzer filter_analyzer_;
diff --git a/modules/audio_processing/aec3/echo_remover.cc b/modules/audio_processing/aec3/echo_remover.cc
index b916880..e52bc62 100644
--- a/modules/audio_processing/aec3/echo_remover.cc
+++ b/modules/audio_processing/aec3/echo_remover.cc
@@ -141,7 +141,6 @@
   bool echo_leakage_detected_ = false;
   AecState aec_state_;
   EchoRemoverMetrics metrics_;
-  bool initial_state_ = true;
   std::array<float, kFftLengthBy2> e_old_;
   std::array<float, kFftLengthBy2> x_old_;
   std::array<float, kFftLengthBy2> y_old_;
@@ -233,7 +232,6 @@
     if (echo_path_variability.delay_change !=
         EchoPathVariability::DelayAdjustment::kNone) {
       suppression_gain_.SetInitialState(true);
-      initial_state_ = true;
     }
   }
   if (gain_change_hangover_ > 0) {
@@ -257,10 +255,9 @@
                                  aec_state_.FilterDelayBlocks());
 
   // Perform linear echo cancellation.
-  if (initial_state_ && !aec_state_.InitialState()) {
+  if (aec_state_.TransitionTriggered()) {
     subtractor_.ExitInitialState();
     suppression_gain_.SetInitialState(false);
-    initial_state_ = false;
   }
 
   // If the delay is known, use the echo subtractor.
@@ -357,9 +354,9 @@
   RTC_DCHECK_EQ(subtractor_output.e_shadow.size(), output.size());
   bool use_main_output = true;
   if (use_shadow_filter_output_) {
-    // As the output of the main adaptive filter generally should be better than
-    // the shadow filter output, add a margin and threshold for when choosing
-    // the shadow filter output.
+    // As the output of the main adaptive filter generally should be better
+    // than the shadow filter output, add a margin and threshold for when
+    // choosing the shadow filter output.
     if (subtractor_output.e2_shadow < 0.9f * subtractor_output.e2_main &&
         subtractor_output.y2 > 30.f * 30.f * kBlockSize &&
         (subtractor_output.s2_main > 60.f * 60.f * kBlockSize ||