| Index: webrtc/modules/audio_processing/aec3/echo_remover.cc | 
| diff --git a/webrtc/modules/audio_processing/aec3/echo_remover.cc b/webrtc/modules/audio_processing/aec3/echo_remover.cc | 
| index 41e954652a7ec9581cdc8115dee526575961af55..2b28a217510f36de3bc6968d2943b9ff4b605516 100644 | 
| --- a/webrtc/modules/audio_processing/aec3/echo_remover.cc | 
| +++ b/webrtc/modules/audio_processing/aec3/echo_remover.cc | 
| @@ -9,6 +9,7 @@ | 
| */ | 
| #include "webrtc/modules/audio_processing/aec3/echo_remover.h" | 
|  | 
| +#include <math.h> | 
| #include <algorithm> | 
| #include <memory> | 
| #include <numeric> | 
| @@ -24,7 +25,6 @@ | 
| #include "webrtc/modules/audio_processing/aec3/echo_remover_metrics.h" | 
| #include "webrtc/modules/audio_processing/aec3/fft_data.h" | 
| #include "webrtc/modules/audio_processing/aec3/output_selector.h" | 
| -#include "webrtc/modules/audio_processing/aec3/power_echo_model.h" | 
| #include "webrtc/modules/audio_processing/aec3/render_buffer.h" | 
| #include "webrtc/modules/audio_processing/aec3/render_delay_buffer.h" | 
| #include "webrtc/modules/audio_processing/aec3/residual_echo_estimator.h" | 
| @@ -46,11 +46,6 @@ void LinearEchoPower(const FftData& E, | 
| } | 
| } | 
|  | 
| -float BlockPower(const std::array<float, kBlockSize> x) { | 
| -  return std::accumulate(x.begin(), x.end(), 0.f, | 
| -                         [](float a, float b) -> float { return a + b * b; }); | 
| -} | 
| - | 
| // Class for removing the echo from the capture signal. | 
| class EchoRemoverImpl final : public EchoRemover { | 
| public: | 
| @@ -83,8 +78,6 @@ class EchoRemoverImpl final : public EchoRemover { | 
| SuppressionGain suppression_gain_; | 
| ComfortNoiseGenerator cng_; | 
| SuppressionFilter suppression_filter_; | 
| -  PowerEchoModel power_echo_model_; | 
| -  RenderBuffer X_buffer_; | 
| RenderSignalAnalyzer render_signal_analyzer_; | 
| OutputSelector output_selector_; | 
| ResidualEchoEstimator residual_echo_estimator_; | 
| @@ -106,12 +99,7 @@ EchoRemoverImpl::EchoRemoverImpl(int sample_rate_hz) | 
| subtractor_(data_dumper_.get(), optimization_), | 
| suppression_gain_(optimization_), | 
| cng_(optimization_), | 
| -      suppression_filter_(sample_rate_hz_), | 
| -      X_buffer_(optimization_, | 
| -                NumBandsForRate(sample_rate_hz_), | 
| -                std::max(subtractor_.MinFarendBufferLength(), | 
| -                         power_echo_model_.MinFarendBufferLength()), | 
| -                subtractor_.NumBlocksInRenderSums()) { | 
| +      suppression_filter_(sample_rate_hz_) { | 
| RTC_DCHECK(ValidFullBandRate(sample_rate_hz)); | 
| } | 
|  | 
| @@ -134,23 +122,23 @@ void EchoRemoverImpl::ProcessCapture( | 
| const std::vector<float>& x0 = x[0]; | 
| std::vector<float>& y0 = (*y)[0]; | 
|  | 
| -  data_dumper_->DumpWav("aec3_processblock_capture_input", kBlockSize, &y0[0], | 
| +  data_dumper_->DumpWav("aec3_echo_remover_capture_input", kBlockSize, &y0[0], | 
| LowestBandRate(sample_rate_hz_), 1); | 
| -  data_dumper_->DumpWav("aec3_processblock_render_input", kBlockSize, &x0[0], | 
| +  data_dumper_->DumpWav("aec3_echo_remover_render_input", kBlockSize, &x0[0], | 
| LowestBandRate(sample_rate_hz_), 1); | 
|  | 
| aec_state_.UpdateCaptureSaturation(capture_signal_saturation); | 
|  | 
| if (echo_path_variability.AudioPathChanged()) { | 
| subtractor_.HandleEchoPathChange(echo_path_variability); | 
| -    residual_echo_estimator_.HandleEchoPathChange(echo_path_variability); | 
| +    aec_state_.HandleEchoPathChange(echo_path_variability); | 
| } | 
|  | 
| std::array<float, kFftLengthBy2Plus1> Y2; | 
| -  std::array<float, kFftLengthBy2Plus1> S2_power; | 
| std::array<float, kFftLengthBy2Plus1> R2; | 
| std::array<float, kFftLengthBy2Plus1> S2_linear; | 
| std::array<float, kFftLengthBy2Plus1> G; | 
| +  float high_bands_gain; | 
| FftData Y; | 
| FftData comfort_noise; | 
| FftData high_band_comfort_noise; | 
| @@ -159,14 +147,13 @@ void EchoRemoverImpl::ProcessCapture( | 
| auto& E2_main = subtractor_output.E2_main; | 
| auto& E2_shadow = subtractor_output.E2_shadow; | 
| auto& e_main = subtractor_output.e_main; | 
| -  auto& e_shadow = subtractor_output.e_shadow; | 
|  | 
| // Analyze the render signal. | 
| render_signal_analyzer_.Update(render_buffer, aec_state_.FilterDelay()); | 
|  | 
| // Perform linear echo cancellation. | 
| -  subtractor_.Process(render_buffer, y0, render_signal_analyzer_, | 
| -                      aec_state_.SaturatedCapture(), &subtractor_output); | 
| +  subtractor_.Process(render_buffer, y0, render_signal_analyzer_, aec_state_, | 
| +                      &subtractor_output); | 
|  | 
| // Compute spectra. | 
| fft_.ZeroPaddedFft(y0, &Y); | 
| @@ -175,35 +162,29 @@ void EchoRemoverImpl::ProcessCapture( | 
|  | 
| // Update the AEC state information. | 
| aec_state_.Update(subtractor_.FilterFrequencyResponse(), | 
| -                    echo_path_delay_samples, render_buffer, E2_main, E2_shadow, | 
| -                    Y2, x0, echo_path_variability, echo_leakage_detected_); | 
| - | 
| -  // Use the power model to estimate the echo. | 
| -  // TODO(peah): Remove in upcoming CL. | 
| -  // power_echo_model_.EstimateEcho(render_buffer, Y2, aec_state_, &S2_power); | 
| +                    echo_path_delay_samples, render_buffer, E2_main, Y2, x0, | 
| +                    echo_leakage_detected_); | 
|  | 
| // Choose the linear output. | 
| -  output_selector_.FormLinearOutput(e_main, y0); | 
| +  output_selector_.FormLinearOutput(!aec_state_.HeadsetDetected(), e_main, y0); | 
| data_dumper_->DumpWav("aec3_output_linear", kBlockSize, &y0[0], | 
| LowestBandRate(sample_rate_hz_), 1); | 
| const auto& E2 = output_selector_.UseSubtractorOutput() ? E2_main : Y2; | 
|  | 
| // Estimate the residual echo power. | 
| -  residual_echo_estimator_.Estimate( | 
| -      output_selector_.UseSubtractorOutput(), aec_state_, render_buffer, | 
| -      subtractor_.FilterFrequencyResponse(), E2_main, E2_shadow, S2_linear, | 
| -      S2_power, Y2, &R2); | 
| +  residual_echo_estimator_.Estimate(output_selector_.UseSubtractorOutput(), | 
| +                                    aec_state_, render_buffer, S2_linear, Y2, | 
| +                                    &R2); | 
|  | 
| // Estimate the comfort noise. | 
| cng_.Compute(aec_state_, Y2, &comfort_noise, &high_band_comfort_noise); | 
|  | 
| -  // Detect basic doubletalk. | 
| -  const bool doubletalk = BlockPower(e_shadow) < BlockPower(e_main); | 
| - | 
| // A choose and apply echo suppression gain. | 
| suppression_gain_.GetGain(E2, R2, cng_.NoiseSpectrum(), | 
| -                            doubletalk ? 0.001f : 0.0001f, &G); | 
| -  suppression_filter_.ApplyGain(comfort_noise, high_band_comfort_noise, G, y); | 
| +                            aec_state_.SaturatedEcho(), x, y->size(), | 
| +                            &high_bands_gain, &G); | 
| +  suppression_filter_.ApplyGain(comfort_noise, high_band_comfort_noise, G, | 
| +                                high_bands_gain, y); | 
|  | 
| // Update the metrics. | 
| metrics_.Update(aec_state_, cng_.NoiseSpectrum(), G); | 
| @@ -216,21 +197,16 @@ void EchoRemoverImpl::ProcessCapture( | 
| LowestBandRate(sample_rate_hz_), 1); | 
| data_dumper_->DumpRaw("aec3_using_subtractor_output", | 
| output_selector_.UseSubtractorOutput() ? 1 : 0); | 
| -  data_dumper_->DumpRaw("aec3_doubletalk", doubletalk ? 1 : 0); | 
| data_dumper_->DumpRaw("aec3_E2", E2); | 
| data_dumper_->DumpRaw("aec3_E2_main", E2_main); | 
| data_dumper_->DumpRaw("aec3_E2_shadow", E2_shadow); | 
| data_dumper_->DumpRaw("aec3_S2_linear", S2_linear); | 
| -  data_dumper_->DumpRaw("aec3_S2_power", S2_power); | 
| data_dumper_->DumpRaw("aec3_Y2", Y2); | 
| +  data_dumper_->DumpRaw("aec3_X2", render_buffer.Spectrum(0)); | 
| data_dumper_->DumpRaw("aec3_R2", R2); | 
| data_dumper_->DumpRaw("aec3_erle", aec_state_.Erle()); | 
| data_dumper_->DumpRaw("aec3_erl", aec_state_.Erl()); | 
| -  data_dumper_->DumpRaw("aec3_reliable_filter_bands", | 
| -                        aec_state_.BandsWithReliableFilter()); | 
| data_dumper_->DumpRaw("aec3_active_render", aec_state_.ActiveRender()); | 
| -  data_dumper_->DumpRaw("aec3_model_based_aec_feasible", | 
| -                        aec_state_.ModelBasedAecFeasible()); | 
| data_dumper_->DumpRaw("aec3_usable_linear_estimate", | 
| aec_state_.UsableLinearEstimate()); | 
| data_dumper_->DumpRaw( | 
|  |