AEC3: Configuration parameter for disabling linear filter

The configuration parameter filter.use_linear_filter can be used to
disable the linear filtering. Disabling the linear filter is equivalent
to runing in non-linear mode.

Bug: b/130016532
Change-Id: I8ffdf474822888b9915444bba6cc1c25ec1efe5a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132552
Reviewed-by: Per Ã…hgren <peah@webrtc.org>
Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27566}
diff --git a/api/audio/echo_canceller3_config.h b/api/audio/echo_canceller3_config.h
index c19226e..d8e6f24 100644
--- a/api/audio/echo_canceller3_config.h
+++ b/api/audio/echo_canceller3_config.h
@@ -76,6 +76,7 @@
     float initial_state_seconds = 2.5f;
     bool conservative_initial_phase = false;
     bool enable_shadow_filter_output_usage = true;
+    bool use_linear_filter = true;
   } filter;
 
   struct Erle {
diff --git a/api/audio/echo_canceller3_config_json.cc b/api/audio/echo_canceller3_config_json.cc
index 07c4e52..9c4824c 100644
--- a/api/audio/echo_canceller3_config_json.cc
+++ b/api/audio/echo_canceller3_config_json.cc
@@ -167,6 +167,9 @@
       ReadParam(subsection, "converged",
                 &cfg.delay.delay_selection_thresholds.converged);
     }
+
+    ReadParam(section, "use_external_delay_estimator",
+              &cfg.delay.use_external_delay_estimator);
   }
 
   if (rtc::GetValueFromJsonObject(aec3_root, "filter", &section)) {
@@ -182,6 +185,7 @@
               &cfg.filter.conservative_initial_phase);
     ReadParam(section, "enable_shadow_filter_output_usage",
               &cfg.filter.enable_shadow_filter_output_usage);
+    ReadParam(section, "use_linear_filter", &cfg.filter.use_linear_filter);
   }
 
   if (rtc::GetValueFromJsonObject(aec3_root, "erle", &section)) {
diff --git a/modules/audio_processing/aec3/aec_state.cc b/modules/audio_processing/aec3/aec_state.cc
index 99791a7..6a5b6e5 100644
--- a/modules/audio_processing/aec3/aec_state.cc
+++ b/modules/audio_processing/aec3/aec_state.cc
@@ -118,7 +118,9 @@
 
   // Estimate the direct path delay of the filter.
   delay_state_.Update(filter_analyzer_, external_delay,
-                      strong_not_saturated_render_blocks_);
+                      config_.filter.use_linear_filter
+                          ? strong_not_saturated_render_blocks_
+                          : 0);
 
   const std::vector<float>& aligned_render_block =
       render_buffer.Block(-delay_state_.DirectPathFilterDelay())[0];
diff --git a/modules/audio_processing/aec3/aec_state.h b/modules/audio_processing/aec3/aec_state.h
index e323b2c..1887492 100644
--- a/modules/audio_processing/aec3/aec_state.h
+++ b/modules/audio_processing/aec3/aec_state.h
@@ -45,12 +45,14 @@
   // Returns whether the echo subtractor can be used to determine the residual
   // echo.
   bool UsableLinearEstimate() const {
-    return filter_quality_state_.LinearFilterUsable();
+    return filter_quality_state_.LinearFilterUsable() &&
+           config_.filter.use_linear_filter;
   }
 
   // Returns whether the echo subtractor output should be used as output.
   bool UseLinearFilterOutput() const {
-    return filter_quality_state_.LinearFilterUsable();
+    return filter_quality_state_.LinearFilterUsable() &&
+           config_.filter.use_linear_filter;
   }
 
   // Returns the estimated echo path gain.