Remove deprecated legacy AEC code

This CL removes the deprecated legacy AEC code.

Note that this CL should not be landed before the M80 release has been cut.

Bug: webrtc:11165
Change-Id: I59ee94526e62f702bb9fa9fa2d38c4e48f44753c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/161238
Commit-Queue: Per Åhgren <peah@webrtc.org>
Reviewed-by: Gustaf Ullberg <gustaf@webrtc.org>
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30036}
diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn
index a0f6124..f347b04 100644
--- a/modules/audio_processing/BUILD.gn
+++ b/modules/audio_processing/BUILD.gn
@@ -11,13 +11,6 @@
   import("//third_party/protobuf/proto_library.gni")
 }
 
-declare_args() {
-  # Disables the usual mode where we trust the reported system delay
-  # values the AEC receives. The corresponding define is set appropriately
-  # in the code, but it can be force-enabled here for testing.
-  aec_untrusted_delay_for_testing = false
-}
-
 config("apm_debug_dump") {
   if (apm_debug_dump) {
     defines = [ "WEBRTC_APM_DEBUG_DUMP=1" ]
@@ -112,8 +105,6 @@
     "audio_processing_impl.cc",
     "audio_processing_impl.h",
     "common.h",
-    "echo_cancellation_impl.cc",
-    "echo_cancellation_impl.h",
     "echo_control_mobile_impl.cc",
     "echo_control_mobile_impl.h",
     "echo_detector/circular_buffer.cc",
@@ -187,8 +178,6 @@
     "../../system_wrappers:cpu_features_api",
     "../../system_wrappers:field_trial",
     "../../system_wrappers:metrics",
-    "aec",
-    "aec:aec_core",
     "aec3",
     "aecm:aecm_core",
     "agc",
@@ -202,10 +191,6 @@
     "//third_party/abseil-cpp/absl/types:optional",
   ]
 
-  if (aec_untrusted_delay_for_testing) {
-    defines += [ "WEBRTC_UNTRUSTED_DELAY" ]
-  }
-
   if (rtc_prefer_fixed_point) {
     defines += [ "WEBRTC_NS_FIXED" ]
   } else {
@@ -400,7 +385,6 @@
       "audio_buffer_unittest.cc",
       "audio_frame_view_unittest.cc",
       "config_unittest.cc",
-      "echo_cancellation_impl_unittest.cc",
       "echo_control_mobile_unittest.cc",
       "gain_controller2_unittest.cc",
       "splitting_filter_unittest.cc",
@@ -451,8 +435,6 @@
       "../../test:rtc_expect_death",
       "../../test:test_support",
       "../audio_coding:neteq_input_audio_tools",
-      "aec:aec_core",
-      "aec:aec_unittests",
       "aec_dump:mock_aec_dump_unittests",
       "agc:agc_unittests",
       "agc2:adaptive_digital_unittests",
@@ -463,7 +445,6 @@
       "agc2:test_utils",
       "agc2/rnn_vad:unittests",
       "test/conversational_speech:unittest",
-      "utility:block_mean_calculator_unittest",
       "utility:legacy_delay_estimator_unittest",
       "utility:pffft_wrapper_unittest",
       "vad:vad_unittests",
@@ -499,7 +480,6 @@
         "audio_processing_impl_locking_unittest.cc",
         "audio_processing_impl_unittest.cc",
         "audio_processing_unittest.cc",
-        "echo_cancellation_bit_exact_unittest.cc",
         "echo_control_mobile_bit_exact_unittest.cc",
         "echo_detector/circular_buffer_unittest.cc",
         "echo_detector/mean_variance_estimator_unittest.cc",
diff --git a/modules/audio_processing/aec/BUILD.gn b/modules/audio_processing/aec/BUILD.gn
deleted file mode 100644
index 472ed17..0000000
--- a/modules/audio_processing/aec/BUILD.gn
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
-#
-# Use of this source code is governed by a BSD-style license
-# that can be found in the LICENSE file in the root of the source
-# tree. An additional intellectual property rights grant can be found
-# in the file PATENTS.  All contributing project authors may
-# be found in the AUTHORS file in the root of the source tree.
-
-import("../../../webrtc.gni")
-
-rtc_library("aec") {
-  configs += [ "..:apm_debug_dump" ]
-  sources = [
-    "aec_resampler.cc",
-    "aec_resampler.h",
-    "echo_cancellation.cc",
-    "echo_cancellation.h",
-  ]
-  deps = [
-    ":aec_core",
-    "..:apm_logging",
-    "../../../common_audio:common_audio_c",
-    "../../../rtc_base:checks",
-    "../../../rtc_base:rtc_base_approved",
-  ]
-}
-
-rtc_library("aec_core") {
-  configs += [ "..:apm_debug_dump" ]
-  sources = [
-    "aec_common.h",
-    "aec_core.cc",
-    "aec_core.h",
-    "aec_core_optimized_methods.h",
-  ]
-  deps = [
-    "..:apm_logging",
-    "../../../common_audio:common_audio_c",
-    "../../../rtc_base:checks",
-    "../../../rtc_base:rtc_base_approved",
-    "../../../rtc_base/system:arch",
-    "../../../system_wrappers:cpu_features_api",
-    "../../../system_wrappers:metrics",
-    "../utility:block_mean_calculator",
-    "../utility:legacy_delay_estimator",
-    "../utility:ooura_fft",
-  ]
-  cflags = []
-
-  if (current_cpu == "x86" || current_cpu == "x64") {
-    sources += [ "aec_core_sse2.cc" ]
-    if (is_posix || is_fuchsia) {
-      cflags += [ "-msse2" ]
-    }
-  }
-
-  if (rtc_build_with_neon) {
-    sources += [ "aec_core_neon.cc" ]
-
-    if (current_cpu != "arm64") {
-      # Enable compilation for the NEON instruction set.
-      suppressed_configs += [ "//build/config/compiler:compiler_arm_fpu" ]
-      cflags += [ "-mfpu=neon" ]
-    }
-
-    deps += [ "../../../common_audio" ]
-  }
-
-  if (current_cpu == "mipsel" && mips_float_abi == "hard") {
-    sources += [ "aec_core_mips.cc" ]
-  }
-}
-
-if (rtc_include_tests) {
-  rtc_library("aec_unittests") {
-    testonly = true
-
-    sources = [
-      "echo_cancellation_unittest.cc",
-      "system_delay_unittest.cc",
-    ]
-    deps = [
-      ":aec",
-      ":aec_core",
-      "../../../rtc_base:checks",
-      "../../../rtc_base:rtc_base_approved",
-      "../../../test:test_support",
-      "//testing/gtest",
-    ]
-  }
-}
diff --git a/modules/audio_processing/aec/aec_common.h b/modules/audio_processing/aec/aec_common.h
deleted file mode 100644
index ac1f339..0000000
--- a/modules/audio_processing/aec/aec_common.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef MODULES_AUDIO_PROCESSING_AEC_AEC_COMMON_H_
-#define MODULES_AUDIO_PROCESSING_AEC_AEC_COMMON_H_
-
-#ifdef _MSC_VER /* visual c++ */
-#define ALIGN16_BEG __declspec(align(16))
-#define ALIGN16_END
-#else /* gcc or icc */
-#define ALIGN16_BEG
-#define ALIGN16_END __attribute__((aligned(16)))
-#endif
-
-#ifdef __cplusplus
-namespace webrtc {
-#endif
-
-extern ALIGN16_BEG const float ALIGN16_END WebRtcAec_sqrtHanning[65];
-extern ALIGN16_BEG const float ALIGN16_END WebRtcAec_weightCurve[65];
-extern ALIGN16_BEG const float ALIGN16_END WebRtcAec_overDriveCurve[65];
-extern const float WebRtcAec_kExtendedSmoothingCoefficients[2][2];
-extern const float WebRtcAec_kNormalSmoothingCoefficients[2][2];
-extern const float WebRtcAec_kMinFarendPSD;
-
-#ifdef __cplusplus
-}  // namespace webrtc
-#endif
-
-#endif  // MODULES_AUDIO_PROCESSING_AEC_AEC_COMMON_H_
diff --git a/modules/audio_processing/aec/aec_core.cc b/modules/audio_processing/aec/aec_core.cc
deleted file mode 100644
index d8ba926..0000000
--- a/modules/audio_processing/aec/aec_core.cc
+++ /dev/null
@@ -1,2012 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-/*
- * The core AEC algorithm, which is presented with time-aligned signals.
- */
-
-#include "modules/audio_processing/aec/aec_core.h"
-
-#include <math.h>
-#include <stddef.h>  // size_t
-#include <stdlib.h>
-#include <string.h>
-
-#include <algorithm>
-#include <cmath>
-
-#include "rtc_base/checks.h"
-
-extern "C" {
-#include "common_audio/ring_buffer.h"
-}
-#include "common_audio/signal_processing/include/signal_processing_library.h"
-#include "modules/audio_processing/aec/aec_common.h"
-#include "modules/audio_processing/aec/aec_core_optimized_methods.h"
-#include "modules/audio_processing/logging/apm_data_dumper.h"
-#include "modules/audio_processing/utility/delay_estimator_wrapper.h"
-#include "rtc_base/system/arch.h"
-#include "system_wrappers/include/cpu_features_wrapper.h"
-#include "system_wrappers/include/metrics.h"
-
-namespace webrtc {
-// Buffer size (samples)
-static const size_t kBufferSizeBlocks = 250;  // 1 second of audio in 16 kHz.
-
-// Metrics
-static const size_t kSubCountLen = 4;
-static const size_t kCountLen = 50;
-static const int kDelayMetricsAggregationWindow = 1250;  // 5 seconds at 16 kHz.
-
-// Divergence metric is based on audio level, which gets updated every
-// |kSubCountLen + 1| * PART_LEN samples. Divergence metric takes the statistics
-// of |kDivergentFilterFractionAggregationWindowSize| audio levels. The
-// following value corresponds to 1 second at 16 kHz.
-static const int kDivergentFilterFractionAggregationWindowSize = 50;
-
-// Quantities to control H band scaling for SWB input
-static const float cnScaleHband = 0.4f;  // scale for comfort noise in H band.
-// Initial bin for averaging nlp gain in low band
-static const int freqAvgIc = PART_LEN / 2;
-
-// Matlab code to produce table:
-// win = sqrt(hanning(63)); win = [0 ; win(1:32)];
-// fprintf(1, '\t%.14f, %.14f, %.14f,\n', win);
-ALIGN16_BEG const float ALIGN16_END WebRtcAec_sqrtHanning[65] = {
-    0.00000000000000f, 0.02454122852291f, 0.04906767432742f, 0.07356456359967f,
-    0.09801714032956f, 0.12241067519922f, 0.14673047445536f, 0.17096188876030f,
-    0.19509032201613f, 0.21910124015687f, 0.24298017990326f, 0.26671275747490f,
-    0.29028467725446f, 0.31368174039889f, 0.33688985339222f, 0.35989503653499f,
-    0.38268343236509f, 0.40524131400499f, 0.42755509343028f, 0.44961132965461f,
-    0.47139673682600f, 0.49289819222978f, 0.51410274419322f, 0.53499761988710f,
-    0.55557023301960f, 0.57580819141785f, 0.59569930449243f, 0.61523159058063f,
-    0.63439328416365f, 0.65317284295378f, 0.67155895484702f, 0.68954054473707f,
-    0.70710678118655f, 0.72424708295147f, 0.74095112535496f, 0.75720884650648f,
-    0.77301045336274f, 0.78834642762661f, 0.80320753148064f, 0.81758481315158f,
-    0.83146961230255f, 0.84485356524971f, 0.85772861000027f, 0.87008699110871f,
-    0.88192126434835f, 0.89322430119552f, 0.90398929312344f, 0.91420975570353f,
-    0.92387953251129f, 0.93299279883474f, 0.94154406518302f, 0.94952818059304f,
-    0.95694033573221f, 0.96377606579544f, 0.97003125319454f, 0.97570213003853f,
-    0.98078528040323f, 0.98527764238894f, 0.98917650996478f, 0.99247953459871f,
-    0.99518472667220f, 0.99729045667869f, 0.99879545620517f, 0.99969881869620f,
-    1.00000000000000f};
-
-// Matlab code to produce table:
-// weightCurve = [0 ; 0.3 * sqrt(linspace(0,1,64))' + 0.1];
-// fprintf(1, '\t%.4f, %.4f, %.4f, %.4f, %.4f, %.4f,\n', weightCurve);
-ALIGN16_BEG const float ALIGN16_END WebRtcAec_weightCurve[65] = {
-    0.0000f, 0.1000f, 0.1378f, 0.1535f, 0.1655f, 0.1756f, 0.1845f, 0.1926f,
-    0.2000f, 0.2069f, 0.2134f, 0.2195f, 0.2254f, 0.2309f, 0.2363f, 0.2414f,
-    0.2464f, 0.2512f, 0.2558f, 0.2604f, 0.2648f, 0.2690f, 0.2732f, 0.2773f,
-    0.2813f, 0.2852f, 0.2890f, 0.2927f, 0.2964f, 0.3000f, 0.3035f, 0.3070f,
-    0.3104f, 0.3138f, 0.3171f, 0.3204f, 0.3236f, 0.3268f, 0.3299f, 0.3330f,
-    0.3360f, 0.3390f, 0.3420f, 0.3449f, 0.3478f, 0.3507f, 0.3535f, 0.3563f,
-    0.3591f, 0.3619f, 0.3646f, 0.3673f, 0.3699f, 0.3726f, 0.3752f, 0.3777f,
-    0.3803f, 0.3828f, 0.3854f, 0.3878f, 0.3903f, 0.3928f, 0.3952f, 0.3976f,
-    0.4000f};
-
-// Matlab code to produce table:
-// overDriveCurve = [sqrt(linspace(0,1,65))' + 1];
-// fprintf(1, '\t%.4f, %.4f, %.4f, %.4f, %.4f, %.4f,\n', overDriveCurve);
-ALIGN16_BEG const float ALIGN16_END WebRtcAec_overDriveCurve[65] = {
-    1.0000f, 1.1250f, 1.1768f, 1.2165f, 1.2500f, 1.2795f, 1.3062f, 1.3307f,
-    1.3536f, 1.3750f, 1.3953f, 1.4146f, 1.4330f, 1.4507f, 1.4677f, 1.4841f,
-    1.5000f, 1.5154f, 1.5303f, 1.5449f, 1.5590f, 1.5728f, 1.5863f, 1.5995f,
-    1.6124f, 1.6250f, 1.6374f, 1.6495f, 1.6614f, 1.6731f, 1.6847f, 1.6960f,
-    1.7071f, 1.7181f, 1.7289f, 1.7395f, 1.7500f, 1.7603f, 1.7706f, 1.7806f,
-    1.7906f, 1.8004f, 1.8101f, 1.8197f, 1.8292f, 1.8385f, 1.8478f, 1.8570f,
-    1.8660f, 1.8750f, 1.8839f, 1.8927f, 1.9014f, 1.9100f, 1.9186f, 1.9270f,
-    1.9354f, 1.9437f, 1.9520f, 1.9601f, 1.9682f, 1.9763f, 1.9843f, 1.9922f,
-    2.0000f};
-
-// Delay Agnostic AEC parameters, still under development and may change.
-static const float kDelayQualityThresholdMax = 0.07f;
-static const float kDelayQualityThresholdMin = 0.01f;
-static const int kInitialShiftOffset = 5;
-#if !defined(WEBRTC_ANDROID)
-static const int kDelayCorrectionStart = 1500;  // 10 ms chunks
-#endif
-
-// Target suppression levels for nlp modes.
-// log{0.001, 0.00001, 0.00000001}
-static const float kTargetSupp[3] = {-6.9f, -11.5f, -18.4f};
-
-// Two sets of parameters, one for the extended filter mode.
-static const float kExtendedMinOverDrive[3] = {3.0f, 6.0f, 15.0f};
-static const float kNormalMinOverDrive[3] = {1.0f, 2.0f, 5.0f};
-const float WebRtcAec_kExtendedSmoothingCoefficients[2][2] = {{0.9f, 0.1f},
-                                                              {0.92f, 0.08f}};
-const float WebRtcAec_kNormalSmoothingCoefficients[2][2] = {{0.9f, 0.1f},
-                                                            {0.93f, 0.07f}};
-
-// Number of partitions forming the NLP's "preferred" bands.
-enum { kPrefBandSize = 24 };
-
-WebRtcAecFilterFar WebRtcAec_FilterFar;
-WebRtcAecScaleErrorSignal WebRtcAec_ScaleErrorSignal;
-WebRtcAecFilterAdaptation WebRtcAec_FilterAdaptation;
-WebRtcAecOverdrive WebRtcAec_Overdrive;
-WebRtcAecSuppress WebRtcAec_Suppress;
-WebRtcAecComputeCoherence WebRtcAec_ComputeCoherence;
-WebRtcAecUpdateCoherenceSpectra WebRtcAec_UpdateCoherenceSpectra;
-WebRtcAecStoreAsComplex WebRtcAec_StoreAsComplex;
-WebRtcAecPartitionDelay WebRtcAec_PartitionDelay;
-WebRtcAecWindowData WebRtcAec_WindowData;
-
-__inline static float MulRe(float aRe, float aIm, float bRe, float bIm) {
-  return aRe * bRe - aIm * bIm;
-}
-
-__inline static float MulIm(float aRe, float aIm, float bRe, float bIm) {
-  return aRe * bIm + aIm * bRe;
-}
-
-// TODO(minyue): Due to a legacy bug, |framelevel| and |averagelevel| use a
-// window, of which the length is 1 unit longer than indicated. Remove "+1" when
-// the code is refactored.
-PowerLevel::PowerLevel()
-    : framelevel(kSubCountLen + 1), averagelevel(kCountLen + 1) {}
-
-Aec2BlockBuffer::Aec2BlockBuffer() {
-  buffer_ = WebRtc_CreateBuffer(kBufferSizeBlocks, sizeof(float) * PART_LEN);
-  RTC_CHECK(buffer_);
-  ReInit();
-}
-
-Aec2BlockBuffer::~Aec2BlockBuffer() {
-  WebRtc_FreeBuffer(buffer_);
-}
-
-void Aec2BlockBuffer::ReInit() {
-  WebRtc_InitBuffer(buffer_);
-}
-
-void Aec2BlockBuffer::Insert(const float block[PART_LEN]) {
-  WebRtc_WriteBuffer(buffer_, block, 1);
-}
-
-void Aec2BlockBuffer::ExtractExtendedBlock(float extended_block[PART_LEN2]) {
-  float* block_ptr = NULL;
-  RTC_DCHECK_LT(0, AvaliableSpace());
-
-  // Extract the previous block.
-  WebRtc_MoveReadPtr(buffer_, -1);
-  size_t read_elements = WebRtc_ReadBuffer(
-      buffer_, reinterpret_cast<void**>(&block_ptr), &extended_block[0], 1);
-  if (read_elements == 0u) {
-    std::fill_n(&extended_block[0], PART_LEN, 0.0f);
-  } else if (block_ptr != &extended_block[0]) {
-    memcpy(&extended_block[0], block_ptr, PART_LEN * sizeof(float));
-  }
-
-  // Extract the current block.
-  read_elements =
-      WebRtc_ReadBuffer(buffer_, reinterpret_cast<void**>(&block_ptr),
-                        &extended_block[PART_LEN], 1);
-  if (read_elements == 0u) {
-    std::fill_n(&extended_block[PART_LEN], PART_LEN, 0.0f);
-  } else if (block_ptr != &extended_block[PART_LEN]) {
-    memcpy(&extended_block[PART_LEN], block_ptr, PART_LEN * sizeof(float));
-  }
-}
-
-int Aec2BlockBuffer::AdjustSize(int buffer_size_decrease) {
-  return WebRtc_MoveReadPtr(buffer_, buffer_size_decrease);
-}
-
-size_t Aec2BlockBuffer::Size() {
-  return static_cast<int>(WebRtc_available_read(buffer_));
-}
-
-size_t Aec2BlockBuffer::AvaliableSpace() {
-  return WebRtc_available_write(buffer_);
-}
-
-DivergentFilterFraction::DivergentFilterFraction()
-    : count_(0), occurrence_(0), fraction_(-1.0) {}
-
-void DivergentFilterFraction::Reset() {
-  Clear();
-  fraction_ = -1.0;
-}
-
-void DivergentFilterFraction::AddObservation(const PowerLevel& nearlevel,
-                                             const PowerLevel& linoutlevel,
-                                             const PowerLevel& nlpoutlevel) {
-  const float near_level = nearlevel.framelevel.GetLatestMean();
-  const float level_increase =
-      linoutlevel.framelevel.GetLatestMean() - near_level;
-  const bool output_signal_active =
-      nlpoutlevel.framelevel.GetLatestMean() > 40.0 * nlpoutlevel.minlevel;
-  // Level increase should be, in principle, negative, when the filter
-  // does not diverge. Here we allow some margin (0.01 * near end level) and
-  // numerical error (1.0). We count divergence only when the AEC output
-  // signal is active.
-  if (output_signal_active && level_increase > std::max(0.01 * near_level, 1.0))
-    occurrence_++;
-  ++count_;
-  if (count_ == kDivergentFilterFractionAggregationWindowSize) {
-    fraction_ = static_cast<float>(occurrence_) /
-                kDivergentFilterFractionAggregationWindowSize;
-    Clear();
-  }
-}
-
-float DivergentFilterFraction::GetLatestFraction() const {
-  return fraction_;
-}
-
-void DivergentFilterFraction::Clear() {
-  count_ = 0;
-  occurrence_ = 0;
-}
-
-// TODO(minyue): Moving some initialization from WebRtcAec_CreateAec() to ctor.
-AecCore::AecCore(int instance_index)
-    : data_dumper(new ApmDataDumper(instance_index)) {}
-
-AecCore::~AecCore() {}
-
-static int CmpFloat(const void* a, const void* b) {
-  const float* da = (const float*)a;
-  const float* db = (const float*)b;
-
-  return (*da > *db) - (*da < *db);
-}
-
-static void FilterFar(int num_partitions,
-                      int x_fft_buf_block_pos,
-                      float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-                      float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-                      float y_fft[2][PART_LEN1]) {
-  int i;
-  for (i = 0; i < num_partitions; i++) {
-    int j;
-    int xPos = (i + x_fft_buf_block_pos) * PART_LEN1;
-    int pos = i * PART_LEN1;
-    // Check for wrap
-    if (i + x_fft_buf_block_pos >= num_partitions) {
-      xPos -= num_partitions * (PART_LEN1);
-    }
-
-    for (j = 0; j < PART_LEN1; j++) {
-      y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j],
-                           h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]);
-      y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j],
-                           h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]);
-    }
-  }
-}
-
-static void ScaleErrorSignal(float mu,
-                             float error_threshold,
-                             float x_pow[PART_LEN1],
-                             float ef[2][PART_LEN1]) {
-  int i;
-  float abs_ef;
-  for (i = 0; i < (PART_LEN1); i++) {
-    ef[0][i] /= (x_pow[i] + 1e-10f);
-    ef[1][i] /= (x_pow[i] + 1e-10f);
-    abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]);
-
-    if (abs_ef > error_threshold) {
-      abs_ef = error_threshold / (abs_ef + 1e-10f);
-      ef[0][i] *= abs_ef;
-      ef[1][i] *= abs_ef;
-    }
-
-    // Stepsize factor
-    ef[0][i] *= mu;
-    ef[1][i] *= mu;
-  }
-}
-
-static void FilterAdaptation(
-    const OouraFft& ooura_fft,
-    int num_partitions,
-    int x_fft_buf_block_pos,
-    float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float e_fft[2][PART_LEN1],
-    float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) {
-  int i, j;
-  float fft[PART_LEN2];
-  for (i = 0; i < num_partitions; i++) {
-    int xPos = (i + x_fft_buf_block_pos) * (PART_LEN1);
-    int pos;
-    // Check for wrap
-    if (i + x_fft_buf_block_pos >= num_partitions) {
-      xPos -= num_partitions * PART_LEN1;
-    }
-
-    pos = i * PART_LEN1;
-
-    for (j = 0; j < PART_LEN; j++) {
-      fft[2 * j] = MulRe(x_fft_buf[0][xPos + j], -x_fft_buf[1][xPos + j],
-                         e_fft[0][j], e_fft[1][j]);
-      fft[2 * j + 1] = MulIm(x_fft_buf[0][xPos + j], -x_fft_buf[1][xPos + j],
-                             e_fft[0][j], e_fft[1][j]);
-    }
-    fft[1] =
-        MulRe(x_fft_buf[0][xPos + PART_LEN], -x_fft_buf[1][xPos + PART_LEN],
-              e_fft[0][PART_LEN], e_fft[1][PART_LEN]);
-
-    ooura_fft.InverseFft(fft);
-    memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN);
-
-    // fft scaling
-    {
-      float scale = 2.0f / PART_LEN2;
-      for (j = 0; j < PART_LEN; j++) {
-        fft[j] *= scale;
-      }
-    }
-    ooura_fft.Fft(fft);
-
-    h_fft_buf[0][pos] += fft[0];
-    h_fft_buf[0][pos + PART_LEN] += fft[1];
-
-    for (j = 1; j < PART_LEN; j++) {
-      h_fft_buf[0][pos + j] += fft[2 * j];
-      h_fft_buf[1][pos + j] += fft[2 * j + 1];
-    }
-  }
-}
-
-static void Overdrive(float overdrive_scaling,
-                      const float hNlFb,
-                      float hNl[PART_LEN1]) {
-  for (int i = 0; i < PART_LEN1; ++i) {
-    // Weight subbands
-    if (hNl[i] > hNlFb) {
-      hNl[i] = WebRtcAec_weightCurve[i] * hNlFb +
-               (1 - WebRtcAec_weightCurve[i]) * hNl[i];
-    }
-    hNl[i] = powf(hNl[i], overdrive_scaling * WebRtcAec_overDriveCurve[i]);
-  }
-}
-
-static void Suppress(const float hNl[PART_LEN1], float efw[2][PART_LEN1]) {
-  for (int i = 0; i < PART_LEN1; ++i) {
-    // Suppress error signal
-    efw[0][i] *= hNl[i];
-    efw[1][i] *= hNl[i];
-
-    // Ooura fft returns incorrect sign on imaginary component. It matters here
-    // because we are making an additive change with comfort noise.
-    efw[1][i] *= -1;
-  }
-}
-
-static int PartitionDelay(
-    int num_partitions,
-    float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) {
-  // Measures the energy in each filter partition and returns the partition with
-  // highest energy.
-  // TODO(bjornv): Spread computational cost by computing one partition per
-  // block?
-  float wfEnMax = 0;
-  int i;
-  int delay = 0;
-
-  for (i = 0; i < num_partitions; i++) {
-    int j;
-    int pos = i * PART_LEN1;
-    float wfEn = 0;
-    for (j = 0; j < PART_LEN1; j++) {
-      wfEn += h_fft_buf[0][pos + j] * h_fft_buf[0][pos + j] +
-              h_fft_buf[1][pos + j] * h_fft_buf[1][pos + j];
-    }
-
-    if (wfEn > wfEnMax) {
-      wfEnMax = wfEn;
-      delay = i;
-    }
-  }
-  return delay;
-}
-
-// Update metric with 10 * log10(numerator / denominator).
-static void UpdateLogRatioMetric(Stats* metric,
-                                 float numerator,
-                                 float denominator) {
-  RTC_DCHECK(metric);
-  RTC_CHECK(numerator >= 0);
-  RTC_CHECK(denominator >= 0);
-
-  const float log_numerator = std::log10(numerator + 1e-10f);
-  const float log_denominator = std::log10(denominator + 1e-10f);
-  metric->instant = 10.0f * (log_numerator - log_denominator);
-
-  // Max.
-  if (metric->instant > metric->max)
-    metric->max = metric->instant;
-
-  // Min.
-  if (metric->instant < metric->min)
-    metric->min = metric->instant;
-
-  // Average.
-  metric->counter++;
-  // This is to protect overflow, which should almost never happen.
-  RTC_CHECK_NE(0, metric->counter);
-  metric->sum += metric->instant;
-  metric->average = metric->sum / metric->counter;
-
-  // Upper mean.
-  if (metric->instant > metric->average) {
-    metric->hicounter++;
-    // This is to protect overflow, which should almost never happen.
-    RTC_CHECK_NE(0, metric->hicounter);
-    metric->hisum += metric->instant;
-    metric->himean = metric->hisum / metric->hicounter;
-  }
-}
-
-// Threshold to protect against the ill-effects of a zero far-end.
-const float WebRtcAec_kMinFarendPSD = 15;
-
-// Updates the following smoothed Power Spectral Densities (PSD):
-//  - sd  : near-end
-//  - se  : residual echo
-//  - sx  : far-end
-//  - sde : cross-PSD of near-end and residual echo
-//  - sxd : cross-PSD of near-end and far-end
-//
-// In addition to updating the PSDs, also the filter diverge state is
-// determined.
-static void UpdateCoherenceSpectra(int mult,
-                                   bool extended_filter_enabled,
-                                   float efw[2][PART_LEN1],
-                                   float dfw[2][PART_LEN1],
-                                   float xfw[2][PART_LEN1],
-                                   CoherenceState* coherence_state,
-                                   short* filter_divergence_state,
-                                   int* extreme_filter_divergence) {
-  // Power estimate smoothing coefficients.
-  const float* ptrGCoh =
-      extended_filter_enabled
-          ? WebRtcAec_kExtendedSmoothingCoefficients[mult - 1]
-          : WebRtcAec_kNormalSmoothingCoefficients[mult - 1];
-  int i;
-  float sdSum = 0, seSum = 0;
-
-  for (i = 0; i < PART_LEN1; i++) {
-    coherence_state->sd[i] =
-        ptrGCoh[0] * coherence_state->sd[i] +
-        ptrGCoh[1] * (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]);
-    coherence_state->se[i] =
-        ptrGCoh[0] * coherence_state->se[i] +
-        ptrGCoh[1] * (efw[0][i] * efw[0][i] + efw[1][i] * efw[1][i]);
-    // We threshold here to protect against the ill-effects of a zero farend.
-    // The threshold is not arbitrarily chosen, but balances protection and
-    // adverse interaction with the algorithm's tuning.
-    // TODO(bjornv): investigate further why this is so sensitive.
-    coherence_state->sx[i] =
-        ptrGCoh[0] * coherence_state->sx[i] +
-        ptrGCoh[1] *
-            WEBRTC_SPL_MAX(xfw[0][i] * xfw[0][i] + xfw[1][i] * xfw[1][i],
-                           WebRtcAec_kMinFarendPSD);
-
-    coherence_state->sde[i][0] =
-        ptrGCoh[0] * coherence_state->sde[i][0] +
-        ptrGCoh[1] * (dfw[0][i] * efw[0][i] + dfw[1][i] * efw[1][i]);
-    coherence_state->sde[i][1] =
-        ptrGCoh[0] * coherence_state->sde[i][1] +
-        ptrGCoh[1] * (dfw[0][i] * efw[1][i] - dfw[1][i] * efw[0][i]);
-
-    coherence_state->sxd[i][0] =
-        ptrGCoh[0] * coherence_state->sxd[i][0] +
-        ptrGCoh[1] * (dfw[0][i] * xfw[0][i] + dfw[1][i] * xfw[1][i]);
-    coherence_state->sxd[i][1] =
-        ptrGCoh[0] * coherence_state->sxd[i][1] +
-        ptrGCoh[1] * (dfw[0][i] * xfw[1][i] - dfw[1][i] * xfw[0][i]);
-
-    sdSum += coherence_state->sd[i];
-    seSum += coherence_state->se[i];
-  }
-
-  // Divergent filter safeguard update.
-  *filter_divergence_state =
-      (*filter_divergence_state ? 1.05f : 1.0f) * seSum > sdSum;
-
-  // Signal extreme filter divergence if the error is significantly larger
-  // than the nearend (13 dB).
-  *extreme_filter_divergence = (seSum > (19.95f * sdSum));
-}
-
-// Window time domain data to be used by the fft.
-__inline static void WindowData(float* x_windowed, const float* x) {
-  int i;
-  for (i = 0; i < PART_LEN; i++) {
-    x_windowed[i] = x[i] * WebRtcAec_sqrtHanning[i];
-    x_windowed[PART_LEN + i] =
-        x[PART_LEN + i] * WebRtcAec_sqrtHanning[PART_LEN - i];
-  }
-}
-
-// Puts fft output data into a complex valued array.
-__inline static void StoreAsComplex(const float* data,
-                                    float data_complex[2][PART_LEN1]) {
-  int i;
-  data_complex[0][0] = data[0];
-  data_complex[1][0] = 0;
-  for (i = 1; i < PART_LEN; i++) {
-    data_complex[0][i] = data[2 * i];
-    data_complex[1][i] = data[2 * i + 1];
-  }
-  data_complex[0][PART_LEN] = data[1];
-  data_complex[1][PART_LEN] = 0;
-}
-
-static void ComputeCoherence(const CoherenceState* coherence_state,
-                             float* cohde,
-                             float* cohxd) {
-  // Subband coherence
-  for (int i = 0; i < PART_LEN1; i++) {
-    cohde[i] = (coherence_state->sde[i][0] * coherence_state->sde[i][0] +
-                coherence_state->sde[i][1] * coherence_state->sde[i][1]) /
-               (coherence_state->sd[i] * coherence_state->se[i] + 1e-10f);
-    cohxd[i] = (coherence_state->sxd[i][0] * coherence_state->sxd[i][0] +
-                coherence_state->sxd[i][1] * coherence_state->sxd[i][1]) /
-               (coherence_state->sx[i] * coherence_state->sd[i] + 1e-10f);
-  }
-}
-
-static void GetHighbandGain(const float* lambda, float* nlpGainHband) {
-  int i;
-
-  *nlpGainHband = 0.0f;
-  for (i = freqAvgIc; i < PART_LEN1 - 1; i++) {
-    *nlpGainHband += lambda[i];
-  }
-  *nlpGainHband /= static_cast<float>(PART_LEN1 - 1 - freqAvgIc);
-}
-
-static void GenerateComplexNoise(uint32_t* seed, float noise[2][PART_LEN1]) {
-  const float kPi2 = 6.28318530717959f;
-  int16_t randW16[PART_LEN];
-  WebRtcSpl_RandUArray(randW16, PART_LEN, seed);
-
-  noise[0][0] = 0;
-  noise[1][0] = 0;
-  for (size_t i = 1; i < PART_LEN1; i++) {
-    float tmp = kPi2 * randW16[i - 1] / 32768.f;
-    noise[0][i] = cosf(tmp);
-    noise[1][i] = -sinf(tmp);
-  }
-  noise[1][PART_LEN] = 0;
-}
-
-static void ComfortNoise(bool generate_high_frequency_noise,
-                         uint32_t* seed,
-                         float e_fft[2][PART_LEN1],
-                         float high_frequency_comfort_noise[2][PART_LEN1],
-                         const float* noise_spectrum,
-                         const float* suppressor_gain) {
-  float complex_noise[2][PART_LEN1];
-
-  GenerateComplexNoise(seed, complex_noise);
-
-  // Shape, scale and add comfort noise.
-  for (int i = 1; i < PART_LEN1; ++i) {
-    float noise_scaling =
-        sqrtf(WEBRTC_SPL_MAX(1 - suppressor_gain[i] * suppressor_gain[i], 0)) *
-        sqrtf(noise_spectrum[i]);
-    e_fft[0][i] += noise_scaling * complex_noise[0][i];
-    e_fft[1][i] += noise_scaling * complex_noise[1][i];
-  }
-
-  // Form comfort noise for higher frequencies.
-  if (generate_high_frequency_noise) {
-    // Compute average noise power and nlp gain over the second half of freq
-    // spectrum (i.e., 4->8khz).
-    int start_avg_band = PART_LEN1 / 2;
-    float upper_bands_noise_power = 0.f;
-    float upper_bands_suppressor_gain = 0.f;
-    for (int i = start_avg_band; i < PART_LEN1; ++i) {
-      upper_bands_noise_power += sqrtf(noise_spectrum[i]);
-      upper_bands_suppressor_gain +=
-          sqrtf(WEBRTC_SPL_MAX(1 - suppressor_gain[i] * suppressor_gain[i], 0));
-    }
-    upper_bands_noise_power /= (PART_LEN1 - start_avg_band);
-    upper_bands_suppressor_gain /= (PART_LEN1 - start_avg_band);
-
-    // Shape, scale and add comfort noise.
-    float noise_scaling = upper_bands_suppressor_gain * upper_bands_noise_power;
-    high_frequency_comfort_noise[0][0] = 0;
-    high_frequency_comfort_noise[1][0] = 0;
-    for (int i = 1; i < PART_LEN1; ++i) {
-      high_frequency_comfort_noise[0][i] = noise_scaling * complex_noise[0][i];
-      high_frequency_comfort_noise[1][i] = noise_scaling * complex_noise[1][i];
-    }
-    high_frequency_comfort_noise[1][PART_LEN] = 0;
-  } else {
-    memset(high_frequency_comfort_noise, 0,
-           2 * PART_LEN1 * sizeof(high_frequency_comfort_noise[0][0]));
-  }
-}
-
-static void InitLevel(PowerLevel* level) {
-  const float kBigFloat = 1E17f;
-  level->averagelevel.Reset();
-  level->framelevel.Reset();
-  level->minlevel = kBigFloat;
-}
-
-static void InitStats(Stats* stats) {
-  stats->instant = kOffsetLevel;
-  stats->average = kOffsetLevel;
-  stats->max = kOffsetLevel;
-  stats->min = kOffsetLevel * (-1);
-  stats->sum = 0;
-  stats->hisum = 0;
-  stats->himean = kOffsetLevel;
-  stats->counter = 0;
-  stats->hicounter = 0;
-}
-
-static void InitMetrics(AecCore* self) {
-  self->stateCounter = 0;
-  InitLevel(&self->farlevel);
-  InitLevel(&self->nearlevel);
-  InitLevel(&self->linoutlevel);
-  InitLevel(&self->nlpoutlevel);
-
-  InitStats(&self->erl);
-  InitStats(&self->erle);
-  InitStats(&self->aNlp);
-  InitStats(&self->rerl);
-
-  self->divergent_filter_fraction.Reset();
-}
-
-static float CalculatePower(const float* in, size_t num_samples) {
-  size_t k;
-  float energy = 0.0f;
-
-  for (k = 0; k < num_samples; ++k) {
-    energy += in[k] * in[k];
-  }
-  return energy / num_samples;
-}
-
-static void UpdateLevel(PowerLevel* level, float power) {
-  level->framelevel.AddValue(power);
-  if (level->framelevel.EndOfBlock()) {
-    const float new_frame_level = level->framelevel.GetLatestMean();
-    if (new_frame_level > 0) {
-      if (new_frame_level < level->minlevel) {
-        level->minlevel = new_frame_level;  // New minimum.
-      } else {
-        level->minlevel *= (1 + 0.001f);  // Small increase.
-      }
-    }
-    level->averagelevel.AddValue(new_frame_level);
-  }
-}
-
-static void UpdateMetrics(AecCore* aec) {
-  const float actThresholdNoisy = 8.0f;
-  const float actThresholdClean = 40.0f;
-
-  const float noisyPower = 300000.0f;
-
-  float actThreshold;
-
-  if (aec->echoState) {  // Check if echo is likely present
-    aec->stateCounter++;
-  }
-
-  if (aec->linoutlevel.framelevel.EndOfBlock()) {
-    aec->divergent_filter_fraction.AddObservation(
-        aec->nearlevel, aec->linoutlevel, aec->nlpoutlevel);
-  }
-
-  if (aec->farlevel.averagelevel.EndOfBlock()) {
-    if (aec->farlevel.minlevel < noisyPower) {
-      actThreshold = actThresholdClean;
-    } else {
-      actThreshold = actThresholdNoisy;
-    }
-
-    const float far_average_level = aec->farlevel.averagelevel.GetLatestMean();
-
-    // The last condition is to let estimation be made in active far-end
-    // segments only.
-    if ((aec->stateCounter > (0.5f * kCountLen * kSubCountLen)) &&
-        (aec->farlevel.framelevel.EndOfBlock()) &&
-        (far_average_level > (actThreshold * aec->farlevel.minlevel))) {
-      // ERL: error return loss.
-      const float near_average_level =
-          aec->nearlevel.averagelevel.GetLatestMean();
-      UpdateLogRatioMetric(&aec->erl, far_average_level, near_average_level);
-
-      // A_NLP: error return loss enhanced before the nonlinear suppression.
-      const float linout_average_level =
-          aec->linoutlevel.averagelevel.GetLatestMean();
-      UpdateLogRatioMetric(&aec->aNlp, near_average_level,
-                           linout_average_level);
-
-      // ERLE: error return loss enhanced.
-      const float nlpout_average_level =
-          aec->nlpoutlevel.averagelevel.GetLatestMean();
-      UpdateLogRatioMetric(&aec->erle, near_average_level,
-                           nlpout_average_level);
-    }
-
-    aec->stateCounter = 0;
-  }
-}
-
-static void UpdateDelayMetrics(AecCore* self) {
-  int i = 0;
-  int delay_values = 0;
-  int median = 0;
-  int lookahead = WebRtc_lookahead(self->delay_estimator);
-  const int kMsPerBlock = PART_LEN / (self->mult * 8);
-  int64_t l1_norm = 0;
-
-  if (self->num_delay_values == 0) {
-    // We have no new delay value data. Even though -1 is a valid |median| in
-    // the sense that we allow negative values, it will practically never be
-    // used since multiples of |kMsPerBlock| will always be returned.
-    // We therefore use -1 to indicate in the logs that the delay estimator was
-    // not able to estimate the delay.
-    self->delay_median = -1;
-    self->delay_std = -1;
-    self->fraction_poor_delays = -1;
-    return;
-  }
-
-  // Start value for median count down.
-  delay_values = self->num_delay_values >> 1;
-  // Get median of delay values since last update.
-  for (i = 0; i < kHistorySizeBlocks; i++) {
-    delay_values -= self->delay_histogram[i];
-    if (delay_values < 0) {
-      median = i;
-      break;
-    }
-  }
-  // Account for lookahead.
-  self->delay_median = (median - lookahead) * kMsPerBlock;
-
-  // Calculate the L1 norm, with median value as central moment.
-  for (i = 0; i < kHistorySizeBlocks; i++) {
-    l1_norm += abs(i - median) * self->delay_histogram[i];
-  }
-  self->delay_std = static_cast<int>((l1_norm + self->num_delay_values / 2) /
-                                     self->num_delay_values) *
-                    kMsPerBlock;
-
-  // Determine fraction of delays that are out of bounds, that is, either
-  // negative (anti-causal system) or larger than the AEC filter length.
-  {
-    int num_delays_out_of_bounds = self->num_delay_values;
-    const int histogram_length =
-        sizeof(self->delay_histogram) / sizeof(self->delay_histogram[0]);
-    for (i = lookahead; i < lookahead + self->num_partitions; ++i) {
-      if (i < histogram_length)
-        num_delays_out_of_bounds -= self->delay_histogram[i];
-    }
-    self->fraction_poor_delays =
-        static_cast<float>(num_delays_out_of_bounds) / self->num_delay_values;
-  }
-
-  // Reset histogram.
-  memset(self->delay_histogram, 0, sizeof(self->delay_histogram));
-  self->num_delay_values = 0;
-}
-
-static void ScaledInverseFft(const OouraFft& ooura_fft,
-                             float freq_data[2][PART_LEN1],
-                             float time_data[PART_LEN2],
-                             float scale,
-                             int conjugate) {
-  int i;
-  const float normalization = scale / static_cast<float>(PART_LEN2);
-  const float sign = (conjugate ? -1 : 1);
-  time_data[0] = freq_data[0][0] * normalization;
-  time_data[1] = freq_data[0][PART_LEN] * normalization;
-  for (i = 1; i < PART_LEN; i++) {
-    time_data[2 * i] = freq_data[0][i] * normalization;
-    time_data[2 * i + 1] = sign * freq_data[1][i] * normalization;
-  }
-  ooura_fft.InverseFft(time_data);
-}
-
-static void Fft(const OouraFft& ooura_fft,
-                float time_data[PART_LEN2],
-                float freq_data[2][PART_LEN1]) {
-  int i;
-  ooura_fft.Fft(time_data);
-
-  // Reorder fft output data.
-  freq_data[1][0] = 0;
-  freq_data[1][PART_LEN] = 0;
-  freq_data[0][0] = time_data[0];
-  freq_data[0][PART_LEN] = time_data[1];
-  for (i = 1; i < PART_LEN; i++) {
-    freq_data[0][i] = time_data[2 * i];
-    freq_data[1][i] = time_data[2 * i + 1];
-  }
-}
-
-static int SignalBasedDelayCorrection(AecCore* self) {
-  int delay_correction = 0;
-  int last_delay = -2;
-  RTC_DCHECK(self);
-#if !defined(WEBRTC_ANDROID)
-  // On desktops, turn on correction after |kDelayCorrectionStart| frames.  This
-  // is to let the delay estimation get a chance to converge.  Also, if the
-  // playout audio volume is low (or even muted) the delay estimation can return
-  // a very large delay, which will break the AEC if it is applied.
-  if (self->frame_count < kDelayCorrectionStart) {
-    self->data_dumper->DumpRaw("aec_da_reported_delay", 1, &last_delay);
-    return 0;
-  }
-#endif
-
-  // 1. Check for non-negative delay estimate.  Note that the estimates we get
-  //    from the delay estimation are not compensated for lookahead.  Hence, a
-  //    negative |last_delay| is an invalid one.
-  // 2. Verify that there is a delay change.  In addition, only allow a change
-  //    if the delay is outside a certain region taking the AEC filter length
-  //    into account.
-  // TODO(bjornv): Investigate if we can remove the non-zero delay change check.
-  // 3. Only allow delay correction if the delay estimation quality exceeds
-  //    |delay_quality_threshold|.
-  // 4. Finally, verify that the proposed |delay_correction| is feasible by
-  //    comparing with the size of the far-end buffer.
-  last_delay = WebRtc_last_delay(self->delay_estimator);
-  self->data_dumper->DumpRaw("aec_da_reported_delay", 1, &last_delay);
-  if ((last_delay >= 0) && (last_delay != self->previous_delay) &&
-      (WebRtc_last_delay_quality(self->delay_estimator) >
-       self->delay_quality_threshold)) {
-    int delay = last_delay - WebRtc_lookahead(self->delay_estimator);
-    // Allow for a slack in the actual delay, defined by a |lower_bound| and an
-    // |upper_bound|.  The adaptive echo cancellation filter is currently
-    // |num_partitions| (of 64 samples) long.  If the delay estimate is negative
-    // or at least 3/4 of the filter length we open up for correction.
-    const int lower_bound = 0;
-    const int upper_bound = self->num_partitions * 3 / 4;
-    const int do_correction = delay <= lower_bound || delay > upper_bound;
-    if (do_correction == 1) {
-      int available_read = self->farend_block_buffer_.Size();
-      // With |shift_offset| we gradually rely on the delay estimates.  For
-      // positive delays we reduce the correction by |shift_offset| to lower the
-      // risk of pushing the AEC into a non causal state.  For negative delays
-      // we rely on the values up to a rounding error, hence compensate by 1
-      // element to make sure to push the delay into the causal region.
-      delay_correction = -delay;
-      delay_correction += delay > self->shift_offset ? self->shift_offset : 1;
-      self->shift_offset--;
-      self->shift_offset = (self->shift_offset <= 1 ? 1 : self->shift_offset);
-      if (delay_correction > available_read - self->mult - 1) {
-        // There is not enough data in the buffer to perform this shift.  Hence,
-        // we do not rely on the delay estimate and do nothing.
-        delay_correction = 0;
-      } else {
-        self->previous_delay = last_delay;
-        ++self->delay_correction_count;
-      }
-    }
-  }
-  // Update the |delay_quality_threshold| once we have our first delay
-  // correction.
-  if (self->delay_correction_count > 0) {
-    float delay_quality = WebRtc_last_delay_quality(self->delay_estimator);
-    delay_quality =
-        (delay_quality > kDelayQualityThresholdMax ? kDelayQualityThresholdMax
-                                                   : delay_quality);
-    self->delay_quality_threshold =
-        (delay_quality > self->delay_quality_threshold
-             ? delay_quality
-             : self->delay_quality_threshold);
-  }
-  self->data_dumper->DumpRaw("aec_da_delay_correction", 1, &delay_correction);
-
-  return delay_correction;
-}
-
-static void RegressorPower(
-    int num_partitions,
-    int latest_added_partition,
-    float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float x_pow[PART_LEN1]) {
-  RTC_DCHECK_LT(latest_added_partition, num_partitions);
-  memset(x_pow, 0, PART_LEN1 * sizeof(x_pow[0]));
-
-  int partition = latest_added_partition;
-  int x_fft_buf_position = partition * PART_LEN1;
-  for (int i = 0; i < num_partitions; ++i) {
-    for (int bin = 0; bin < PART_LEN1; ++bin) {
-      float re = x_fft_buf[0][x_fft_buf_position];
-      float im = x_fft_buf[1][x_fft_buf_position];
-      x_pow[bin] += re * re + im * im;
-      ++x_fft_buf_position;
-    }
-
-    ++partition;
-    if (partition == num_partitions) {
-      partition = 0;
-      RTC_DCHECK_EQ(num_partitions * PART_LEN1, x_fft_buf_position);
-      x_fft_buf_position = 0;
-    }
-  }
-}
-
-static void EchoSubtraction(
-    const OouraFft& ooura_fft,
-    int num_partitions,
-    int extended_filter_enabled,
-    int* extreme_filter_divergence,
-    float filter_step_size,
-    float error_threshold,
-    float* x_fft,
-    int* x_fft_buf_block_pos,
-    float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float* const y,
-    float x_pow[PART_LEN1],
-    float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float echo_subtractor_output[PART_LEN]) {
-  float s_fft[2][PART_LEN1];
-  float e_extended[PART_LEN2];
-  float s_extended[PART_LEN2];
-  float* s;
-  float e[PART_LEN];
-  float e_fft[2][PART_LEN1];
-  int i;
-
-  // Update the x_fft_buf block position.
-  (*x_fft_buf_block_pos)--;
-  if ((*x_fft_buf_block_pos) == -1) {
-    *x_fft_buf_block_pos = num_partitions - 1;
-  }
-
-  // Buffer x_fft.
-  memcpy(x_fft_buf[0] + (*x_fft_buf_block_pos) * PART_LEN1, x_fft,
-         sizeof(float) * PART_LEN1);
-  memcpy(x_fft_buf[1] + (*x_fft_buf_block_pos) * PART_LEN1, &x_fft[PART_LEN1],
-         sizeof(float) * PART_LEN1);
-
-  memset(s_fft, 0, sizeof(s_fft));
-
-  // Conditionally reset the echo subtraction filter if the filter has diverged
-  // significantly.
-  if (!extended_filter_enabled && *extreme_filter_divergence) {
-    memset(h_fft_buf, 0,
-           2 * kExtendedNumPartitions * PART_LEN1 * sizeof(h_fft_buf[0][0]));
-    *extreme_filter_divergence = 0;
-  }
-
-  // Produce echo estimate s_fft.
-  WebRtcAec_FilterFar(num_partitions, *x_fft_buf_block_pos, x_fft_buf,
-                      h_fft_buf, s_fft);
-
-  // Compute the time-domain echo estimate s.
-  ScaledInverseFft(ooura_fft, s_fft, s_extended, 2.0f, 0);
-  s = &s_extended[PART_LEN];
-
-  // Compute the time-domain echo prediction error.
-  for (i = 0; i < PART_LEN; ++i) {
-    e[i] = y[i] - s[i];
-  }
-
-  // Compute the frequency domain echo prediction error.
-  memset(e_extended, 0, sizeof(float) * PART_LEN);
-  memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN);
-  Fft(ooura_fft, e_extended, e_fft);
-
-  // Scale error signal inversely with far power.
-  WebRtcAec_ScaleErrorSignal(filter_step_size, error_threshold, x_pow, e_fft);
-  WebRtcAec_FilterAdaptation(ooura_fft, num_partitions, *x_fft_buf_block_pos,
-                             x_fft_buf, e_fft, h_fft_buf);
-  memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN);
-}
-
-static void FormSuppressionGain(AecCore* aec,
-                                float cohde[PART_LEN1],
-                                float cohxd[PART_LEN1],
-                                float hNl[PART_LEN1]) {
-  float hNlDeAvg, hNlXdAvg;
-  float hNlPref[kPrefBandSize];
-  float hNlFb = 0, hNlFbLow = 0;
-  const int prefBandSize = kPrefBandSize / aec->mult;
-  const float prefBandQuant = 0.75f, prefBandQuantLow = 0.5f;
-  const int minPrefBand = 4 / aec->mult;
-  // Power estimate smoothing coefficients.
-  const float* min_overdrive = aec->extended_filter_enabled
-                                   ? kExtendedMinOverDrive
-                                   : kNormalMinOverDrive;
-
-  hNlXdAvg = 0;
-  for (int i = minPrefBand; i < prefBandSize + minPrefBand; ++i) {
-    hNlXdAvg += cohxd[i];
-  }
-  hNlXdAvg /= prefBandSize;
-  hNlXdAvg = 1 - hNlXdAvg;
-
-  hNlDeAvg = 0;
-  for (int i = minPrefBand; i < prefBandSize + minPrefBand; ++i) {
-    hNlDeAvg += cohde[i];
-  }
-  hNlDeAvg /= prefBandSize;
-
-  if (hNlXdAvg < 0.75f && hNlXdAvg < aec->hNlXdAvgMin) {
-    aec->hNlXdAvgMin = hNlXdAvg;
-  }
-
-  if (hNlDeAvg > 0.98f && hNlXdAvg > 0.9f) {
-    aec->stNearState = 1;
-  } else if (hNlDeAvg < 0.95f || hNlXdAvg < 0.8f) {
-    aec->stNearState = 0;
-  }
-
-  if (aec->hNlXdAvgMin == 1) {
-    aec->echoState = 0;
-    aec->overDrive = min_overdrive[aec->nlp_mode];
-
-    if (aec->stNearState == 1) {
-      memcpy(hNl, cohde, sizeof(hNl[0]) * PART_LEN1);
-      hNlFb = hNlDeAvg;
-      hNlFbLow = hNlDeAvg;
-    } else {
-      for (int i = 0; i < PART_LEN1; ++i) {
-        hNl[i] = 1 - cohxd[i];
-        hNl[i] = std::max(hNl[i], 0.f);
-      }
-      hNlFb = hNlXdAvg;
-      hNlFbLow = hNlXdAvg;
-    }
-  } else {
-    if (aec->stNearState == 1) {
-      aec->echoState = 0;
-      memcpy(hNl, cohde, sizeof(hNl[0]) * PART_LEN1);
-      hNlFb = hNlDeAvg;
-      hNlFbLow = hNlDeAvg;
-    } else {
-      aec->echoState = 1;
-      for (int i = 0; i < PART_LEN1; ++i) {
-        hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]);
-        hNl[i] = std::max(hNl[i], 0.f);
-      }
-
-      // Select an order statistic from the preferred bands.
-      // TODO(peah): Using quicksort now, but a selection algorithm may be
-      // preferred.
-      memcpy(hNlPref, &hNl[minPrefBand], sizeof(float) * prefBandSize);
-      qsort(hNlPref, prefBandSize, sizeof(float), CmpFloat);
-      hNlFb = hNlPref[static_cast<int>(
-          std::floor(prefBandQuant * (prefBandSize - 1)))];
-      hNlFbLow = hNlPref[static_cast<int>(
-          std::floor(prefBandQuantLow * (prefBandSize - 1)))];
-    }
-  }
-
-  // Track the local filter minimum to determine suppression overdrive.
-  if (hNlFbLow < 0.6f && hNlFbLow < aec->hNlFbLocalMin) {
-    aec->hNlFbLocalMin = hNlFbLow;
-    aec->hNlFbMin = hNlFbLow;
-    aec->hNlNewMin = 1;
-    aec->hNlMinCtr = 0;
-  }
-  aec->hNlFbLocalMin =
-      WEBRTC_SPL_MIN(aec->hNlFbLocalMin + 0.0008f / aec->mult, 1);
-  aec->hNlXdAvgMin = WEBRTC_SPL_MIN(aec->hNlXdAvgMin + 0.0006f / aec->mult, 1);
-
-  if (aec->hNlNewMin == 1) {
-    aec->hNlMinCtr++;
-  }
-  if (aec->hNlMinCtr == 2) {
-    aec->hNlNewMin = 0;
-    aec->hNlMinCtr = 0;
-    aec->overDrive = WEBRTC_SPL_MAX(
-        kTargetSupp[aec->nlp_mode] /
-            static_cast<float>(std::log(aec->hNlFbMin + 1e-10f) + 1e-10f),
-        min_overdrive[aec->nlp_mode]);
-  }
-
-  // Smooth the overdrive.
-  if (aec->overDrive < aec->overdrive_scaling) {
-    aec->overdrive_scaling =
-        0.99f * aec->overdrive_scaling + 0.01f * aec->overDrive;
-  } else {
-    aec->overdrive_scaling =
-        0.9f * aec->overdrive_scaling + 0.1f * aec->overDrive;
-  }
-
-  // Apply the overdrive.
-  WebRtcAec_Overdrive(aec->overdrive_scaling, hNlFb, hNl);
-}
-
-static void EchoSuppression(const OouraFft& ooura_fft,
-                            AecCore* aec,
-                            float* nearend_extended_block_lowest_band,
-                            float farend_extended_block[PART_LEN2],
-                            float* echo_subtractor_output,
-                            float output[NUM_HIGH_BANDS_MAX + 1][PART_LEN]) {
-  float efw[2][PART_LEN1];
-  float xfw[2][PART_LEN1];
-  float dfw[2][PART_LEN1];
-  float comfortNoiseHband[2][PART_LEN1];
-  float fft[PART_LEN2];
-  float nlpGainHband;
-  int i;
-  size_t j;
-
-  // Coherence and non-linear filter
-  float cohde[PART_LEN1], cohxd[PART_LEN1];
-  float hNl[PART_LEN1];
-
-  // Filter energy
-  const int delayEstInterval = 10 * aec->mult;
-
-  float* xfw_ptr = NULL;
-
-  // Update eBuf with echo subtractor output.
-  memcpy(aec->eBuf + PART_LEN, echo_subtractor_output,
-         sizeof(float) * PART_LEN);
-
-  // Analysis filter banks for the echo suppressor.
-  // Windowed near-end ffts.
-  WindowData(fft, nearend_extended_block_lowest_band);
-  ooura_fft.Fft(fft);
-  StoreAsComplex(fft, dfw);
-
-  // Windowed echo suppressor output ffts.
-  WindowData(fft, aec->eBuf);
-  ooura_fft.Fft(fft);
-  StoreAsComplex(fft, efw);
-
-  // NLP
-
-  // Convert far-end partition to the frequency domain with windowing.
-  WindowData(fft, farend_extended_block);
-  Fft(ooura_fft, fft, xfw);
-  xfw_ptr = &xfw[0][0];
-
-  // Buffer far.
-  memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1);
-
-  aec->delayEstCtr++;
-  if (aec->delayEstCtr == delayEstInterval) {
-    aec->delayEstCtr = 0;
-    aec->delayIdx = WebRtcAec_PartitionDelay(aec->num_partitions, aec->wfBuf);
-  }
-
-  aec->data_dumper->DumpRaw("aec_nlp_delay", 1, &aec->delayIdx);
-
-  // Use delayed far.
-  memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1,
-         sizeof(xfw[0][0]) * 2 * PART_LEN1);
-
-  WebRtcAec_UpdateCoherenceSpectra(aec->mult, aec->extended_filter_enabled == 1,
-                                   efw, dfw, xfw, &aec->coherence_state,
-                                   &aec->divergeState,
-                                   &aec->extreme_filter_divergence);
-
-  WebRtcAec_ComputeCoherence(&aec->coherence_state, cohde, cohxd);
-
-  // Select the microphone signal as output if the filter is deemed to have
-  // diverged.
-  if (aec->divergeState) {
-    memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1);
-  }
-
-  FormSuppressionGain(aec, cohde, cohxd, hNl);
-
-  aec->data_dumper->DumpRaw("aec_nlp_gain", PART_LEN1, hNl);
-
-  WebRtcAec_Suppress(hNl, efw);
-
-  // Add comfort noise.
-  ComfortNoise(aec->num_bands > 1, &aec->seed, efw, comfortNoiseHband,
-               aec->noisePow, hNl);
-
-  // Inverse error fft.
-  ScaledInverseFft(ooura_fft, efw, fft, 2.0f, 1);
-
-  // Overlap and add to obtain output.
-  for (i = 0; i < PART_LEN; i++) {
-    output[0][i] = (fft[i] * WebRtcAec_sqrtHanning[i] +
-                    aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]);
-
-    // Saturate output to keep it in the allowed range.
-    output[0][i] = WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, output[0][i],
-                                  WEBRTC_SPL_WORD16_MIN);
-  }
-  memcpy(aec->outBuf, &fft[PART_LEN], PART_LEN * sizeof(aec->outBuf[0]));
-
-  // For H band
-  if (aec->num_bands > 1) {
-    // H band gain
-    // average nlp over low band: average over second half of freq spectrum
-    // (4->8khz)
-    GetHighbandGain(hNl, &nlpGainHband);
-
-    // Inverse comfort_noise
-    ScaledInverseFft(ooura_fft, comfortNoiseHband, fft, 2.0f, 0);
-
-    // compute gain factor
-    for (j = 1; j < aec->num_bands; ++j) {
-      for (i = 0; i < PART_LEN; i++) {
-        output[j][i] = aec->previous_nearend_block[j][i] * nlpGainHband;
-      }
-    }
-
-    // Add some comfort noise where Hband is attenuated.
-    for (i = 0; i < PART_LEN; i++) {
-      output[1][i] += cnScaleHband * fft[i];
-    }
-
-    // Saturate output to keep it in the allowed range.
-    for (j = 1; j < aec->num_bands; ++j) {
-      for (i = 0; i < PART_LEN; i++) {
-        output[j][i] = WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, output[j][i],
-                                      WEBRTC_SPL_WORD16_MIN);
-      }
-    }
-  }
-
-  // Copy the current block to the old position.
-  memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN);
-
-  memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf,
-          sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1);
-}
-
-static void ProcessNearendBlock(
-    AecCore* aec,
-    float farend_extended_block_lowest_band[PART_LEN2],
-    float nearend_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN],
-    float output_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN]) {
-  size_t i;
-
-  float fft[PART_LEN2];
-  float nearend_extended_block_lowest_band[PART_LEN2];
-  float farend_fft[2][PART_LEN1];
-  float nearend_fft[2][PART_LEN1];
-  float far_spectrum = 0.0f;
-  float near_spectrum = 0.0f;
-  float abs_far_spectrum[PART_LEN1];
-  float abs_near_spectrum[PART_LEN1];
-
-  const float gPow[2] = {0.9f, 0.1f};
-
-  // Noise estimate constants.
-  const int noiseInitBlocks = 500 * aec->mult;
-  const float step = 0.1f;
-  const float ramp = 1.0002f;
-  const float gInitNoise[2] = {0.999f, 0.001f};
-
-  float echo_subtractor_output[PART_LEN];
-
-  aec->data_dumper->DumpWav("aec_far", PART_LEN,
-                            &farend_extended_block_lowest_band[PART_LEN],
-                            std::min(aec->sampFreq, 16000), 1);
-  aec->data_dumper->DumpWav("aec_near", PART_LEN, &nearend_block[0][0],
-                            std::min(aec->sampFreq, 16000), 1);
-
-  if (aec->metricsMode == 1) {
-    // Update power levels
-    UpdateLevel(
-        &aec->farlevel,
-        CalculatePower(&farend_extended_block_lowest_band[PART_LEN], PART_LEN));
-    UpdateLevel(&aec->nearlevel,
-                CalculatePower(&nearend_block[0][0], PART_LEN));
-  }
-
-  // Convert far-end signal to the frequency domain.
-  memcpy(fft, farend_extended_block_lowest_band, sizeof(float) * PART_LEN2);
-  Fft(aec->ooura_fft, fft, farend_fft);
-
-  // Form extended nearend frame.
-  memcpy(&nearend_extended_block_lowest_band[0],
-         &aec->previous_nearend_block[0][0], sizeof(float) * PART_LEN);
-  memcpy(&nearend_extended_block_lowest_band[PART_LEN], &nearend_block[0][0],
-         sizeof(float) * PART_LEN);
-
-  // Convert near-end signal to the frequency domain.
-  memcpy(fft, nearend_extended_block_lowest_band, sizeof(float) * PART_LEN2);
-  Fft(aec->ooura_fft, fft, nearend_fft);
-
-  // Power smoothing.
-  if (aec->refined_adaptive_filter_enabled) {
-    for (i = 0; i < PART_LEN1; ++i) {
-      far_spectrum = farend_fft[0][i] * farend_fft[0][i] +
-                     farend_fft[1][i] * farend_fft[1][i];
-      // Calculate the magnitude spectrum.
-      abs_far_spectrum[i] = sqrtf(far_spectrum);
-    }
-    RegressorPower(aec->num_partitions, aec->xfBufBlockPos, aec->xfBuf,
-                   aec->xPow);
-  } else {
-    for (i = 0; i < PART_LEN1; ++i) {
-      far_spectrum = farend_fft[0][i] * farend_fft[0][i] +
-                     farend_fft[1][i] * farend_fft[1][i];
-      aec->xPow[i] =
-          gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum;
-      // Calculate the magnitude spectrum.
-      abs_far_spectrum[i] = sqrtf(far_spectrum);
-    }
-  }
-
-  for (i = 0; i < PART_LEN1; ++i) {
-    near_spectrum = nearend_fft[0][i] * nearend_fft[0][i] +
-                    nearend_fft[1][i] * nearend_fft[1][i];
-    aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum;
-    // Calculate the magnitude spectrum.
-    abs_near_spectrum[i] = sqrtf(near_spectrum);
-  }
-
-  // Estimate noise power. Wait until dPow is more stable.
-  if (aec->noiseEstCtr > 50) {
-    for (i = 0; i < PART_LEN1; i++) {
-      if (aec->dPow[i] < aec->dMinPow[i]) {
-        aec->dMinPow[i] =
-            (aec->dPow[i] + step * (aec->dMinPow[i] - aec->dPow[i])) * ramp;
-      } else {
-        aec->dMinPow[i] *= ramp;
-      }
-    }
-  }
-
-  // Smooth increasing noise power from zero at the start,
-  // to avoid a sudden burst of comfort noise.
-  if (aec->noiseEstCtr < noiseInitBlocks) {
-    aec->noiseEstCtr++;
-    for (i = 0; i < PART_LEN1; i++) {
-      if (aec->dMinPow[i] > aec->dInitMinPow[i]) {
-        aec->dInitMinPow[i] = gInitNoise[0] * aec->dInitMinPow[i] +
-                              gInitNoise[1] * aec->dMinPow[i];
-      } else {
-        aec->dInitMinPow[i] = aec->dMinPow[i];
-      }
-    }
-    aec->noisePow = aec->dInitMinPow;
-  } else {
-    aec->noisePow = aec->dMinPow;
-  }
-
-  // Block wise delay estimation used for logging
-  if (aec->delay_logging_enabled) {
-    if (WebRtc_AddFarSpectrumFloat(aec->delay_estimator_farend,
-                                   abs_far_spectrum, PART_LEN1) == 0) {
-      int delay_estimate = WebRtc_DelayEstimatorProcessFloat(
-          aec->delay_estimator, abs_near_spectrum, PART_LEN1);
-      if (delay_estimate >= 0) {
-        // Update delay estimate buffer.
-        aec->delay_histogram[delay_estimate]++;
-        aec->num_delay_values++;
-      }
-      if (aec->delay_metrics_delivered == 1 &&
-          aec->num_delay_values >= kDelayMetricsAggregationWindow) {
-        UpdateDelayMetrics(aec);
-      }
-    }
-  }
-
-  // Perform echo subtraction.
-  EchoSubtraction(
-      aec->ooura_fft, aec->num_partitions, aec->extended_filter_enabled,
-      &aec->extreme_filter_divergence, aec->filter_step_size,
-      aec->error_threshold, &farend_fft[0][0], &aec->xfBufBlockPos, aec->xfBuf,
-      &nearend_block[0][0], aec->xPow, aec->wfBuf, echo_subtractor_output);
-  aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions,
-                            &aec->wfBuf[0][0]);
-  aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions,
-                            &aec->wfBuf[1][0]);
-
-  aec->data_dumper->DumpWav("aec_out_linear", PART_LEN, echo_subtractor_output,
-                            std::min(aec->sampFreq, 16000), 1);
-
-  if (aec->metricsMode == 1) {
-    UpdateLevel(&aec->linoutlevel,
-                CalculatePower(echo_subtractor_output, PART_LEN));
-  }
-
-  // Perform echo suppression.
-  EchoSuppression(aec->ooura_fft, aec, nearend_extended_block_lowest_band,
-                  farend_extended_block_lowest_band, echo_subtractor_output,
-                  output_block);
-
-  if (aec->metricsMode == 1) {
-    UpdateLevel(&aec->nlpoutlevel,
-                CalculatePower(&output_block[0][0], PART_LEN));
-    UpdateMetrics(aec);
-  }
-
-  // Store the nearend signal until the next frame.
-  for (i = 0; i < aec->num_bands; ++i) {
-    memcpy(&aec->previous_nearend_block[i][0], &nearend_block[i][0],
-           sizeof(float) * PART_LEN);
-  }
-
-  aec->data_dumper->DumpWav("aec_out", PART_LEN, &output_block[0][0],
-                            std::min(aec->sampFreq, 16000), 1);
-}
-
-AecCore* WebRtcAec_CreateAec(int instance_count) {
-  AecCore* aec = new AecCore(instance_count);
-
-  if (!aec) {
-    return NULL;
-  }
-  aec->nearend_buffer_size = 0;
-  memset(&aec->nearend_buffer[0], 0, sizeof(aec->nearend_buffer));
-  // Start the output buffer with zeros to be able to produce
-  // a full output frame in the first frame.
-  aec->output_buffer_size = PART_LEN - (FRAME_LEN - PART_LEN);
-  memset(&aec->output_buffer[0], 0, sizeof(aec->output_buffer));
-
-  aec->delay_estimator_farend =
-      WebRtc_CreateDelayEstimatorFarend(PART_LEN1, kHistorySizeBlocks);
-  if (aec->delay_estimator_farend == NULL) {
-    WebRtcAec_FreeAec(aec);
-    return NULL;
-  }
-  // We create the delay_estimator with the same amount of maximum lookahead as
-  // the delay history size (kHistorySizeBlocks) for symmetry reasons.
-  aec->delay_estimator = WebRtc_CreateDelayEstimator(
-      aec->delay_estimator_farend, kHistorySizeBlocks);
-  if (aec->delay_estimator == NULL) {
-    WebRtcAec_FreeAec(aec);
-    return NULL;
-  }
-#ifdef WEBRTC_ANDROID
-  aec->delay_agnostic_enabled = 1;  // DA-AEC enabled by default.
-  // DA-AEC assumes the system is causal from the beginning and will self adjust
-  // the lookahead when shifting is required.
-  WebRtc_set_lookahead(aec->delay_estimator, 0);
-#else
-  aec->delay_agnostic_enabled = 0;
-  WebRtc_set_lookahead(aec->delay_estimator, kLookaheadBlocks);
-#endif
-  aec->extended_filter_enabled = 0;
-  aec->refined_adaptive_filter_enabled = false;
-
-  // Assembly optimization
-  WebRtcAec_FilterFar = FilterFar;
-  WebRtcAec_ScaleErrorSignal = ScaleErrorSignal;
-  WebRtcAec_FilterAdaptation = FilterAdaptation;
-  WebRtcAec_Overdrive = Overdrive;
-  WebRtcAec_Suppress = Suppress;
-  WebRtcAec_ComputeCoherence = ComputeCoherence;
-  WebRtcAec_UpdateCoherenceSpectra = UpdateCoherenceSpectra;
-  WebRtcAec_StoreAsComplex = StoreAsComplex;
-  WebRtcAec_PartitionDelay = PartitionDelay;
-  WebRtcAec_WindowData = WindowData;
-
-#if defined(WEBRTC_ARCH_X86_FAMILY)
-  if (WebRtc_GetCPUInfo(kSSE2)) {
-    WebRtcAec_InitAec_SSE2();
-  }
-#endif
-
-#if defined(MIPS_FPU_LE)
-  WebRtcAec_InitAec_mips();
-#endif
-
-#if defined(WEBRTC_HAS_NEON)
-  WebRtcAec_InitAec_neon();
-#endif
-
-  return aec;
-}
-
-void WebRtcAec_FreeAec(AecCore* aec) {
-  if (aec == NULL) {
-    return;
-  }
-
-  WebRtc_FreeDelayEstimator(aec->delay_estimator);
-  WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend);
-
-  delete aec;
-}
-
-static void SetAdaptiveFilterStepSize(AecCore* aec) {
-  // Extended filter adaptation parameter.
-  // TODO(ajm): No narrowband tuning yet.
-  const float kExtendedMu = 0.4f;
-
-  if (aec->refined_adaptive_filter_enabled) {
-    aec->filter_step_size = 0.05f;
-  } else {
-    if (aec->extended_filter_enabled) {
-      aec->filter_step_size = kExtendedMu;
-    } else {
-      if (aec->sampFreq == 8000) {
-        aec->filter_step_size = 0.6f;
-      } else {
-        aec->filter_step_size = 0.5f;
-      }
-    }
-  }
-}
-
-static void SetErrorThreshold(AecCore* aec) {
-  // Extended filter adaptation parameter.
-  // TODO(ajm): No narrowband tuning yet.
-  static const float kExtendedErrorThreshold = 1.0e-6f;
-
-  if (aec->extended_filter_enabled) {
-    aec->error_threshold = kExtendedErrorThreshold;
-  } else {
-    if (aec->sampFreq == 8000) {
-      aec->error_threshold = 2e-6f;
-    } else {
-      aec->error_threshold = 1.5e-6f;
-    }
-  }
-}
-
-int WebRtcAec_InitAec(AecCore* aec, int sampFreq) {
-  int i;
-  aec->data_dumper->InitiateNewSetOfRecordings();
-
-  aec->sampFreq = sampFreq;
-
-  SetAdaptiveFilterStepSize(aec);
-  SetErrorThreshold(aec);
-
-  if (sampFreq == 8000) {
-    aec->num_bands = 1;
-  } else {
-    aec->num_bands = (size_t)(sampFreq / 16000);
-  }
-
-  // Start the output buffer with zeros to be able to produce
-  // a full output frame in the first frame.
-  aec->output_buffer_size = PART_LEN - (FRAME_LEN - PART_LEN);
-  memset(&aec->output_buffer[0], 0, sizeof(aec->output_buffer));
-  aec->nearend_buffer_size = 0;
-  memset(&aec->nearend_buffer[0], 0, sizeof(aec->nearend_buffer));
-
-  // Initialize far-end buffer.
-  aec->farend_block_buffer_.ReInit();
-
-  aec->system_delay = 0;
-
-  if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) {
-    return -1;
-  }
-  if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) {
-    return -1;
-  }
-  aec->delay_logging_enabled = 0;
-  aec->delay_metrics_delivered = 0;
-  memset(aec->delay_histogram, 0, sizeof(aec->delay_histogram));
-  aec->num_delay_values = 0;
-  aec->delay_median = -1;
-  aec->delay_std = -1;
-  aec->fraction_poor_delays = -1.0f;
-
-  aec->previous_delay = -2;  // (-2): Uninitialized.
-  aec->delay_correction_count = 0;
-  aec->shift_offset = kInitialShiftOffset;
-  aec->delay_quality_threshold = kDelayQualityThresholdMin;
-
-  aec->num_partitions = kNormalNumPartitions;
-
-  // Update the delay estimator with filter length.  We use half the
-  // |num_partitions| to take the echo path into account.  In practice we say
-  // that the echo has a duration of maximum half |num_partitions|, which is not
-  // true, but serves as a crude measure.
-  WebRtc_set_allowed_offset(aec->delay_estimator, aec->num_partitions / 2);
-  // TODO(bjornv): I currently hard coded the enable.  Once we've established
-  // that AECM has no performance regression, robust_validation will be enabled
-  // all the time and the APIs to turn it on/off will be removed.  Hence, remove
-  // this line then.
-  WebRtc_enable_robust_validation(aec->delay_estimator, 1);
-  aec->frame_count = 0;
-
-  // Default target suppression mode.
-  aec->nlp_mode = 1;
-
-  // Sampling frequency multiplier w.r.t. 8 kHz.
-  // In case of multiple bands we process the lower band in 16 kHz, hence the
-  // multiplier is always 2.
-  if (aec->num_bands > 1) {
-    aec->mult = 2;
-  } else {
-    aec->mult = static_cast<int16_t>(aec->sampFreq) / 8000;
-  }
-
-  aec->farBufWritePos = 0;
-  aec->farBufReadPos = 0;
-
-  aec->inSamples = 0;
-  aec->outSamples = 0;
-  aec->knownDelay = 0;
-
-  // Initialize buffers
-  memset(aec->previous_nearend_block, 0, sizeof(aec->previous_nearend_block));
-  memset(aec->eBuf, 0, sizeof(aec->eBuf));
-
-  memset(aec->xPow, 0, sizeof(aec->xPow));
-  memset(aec->dPow, 0, sizeof(aec->dPow));
-  memset(aec->dInitMinPow, 0, sizeof(aec->dInitMinPow));
-  aec->noisePow = aec->dInitMinPow;
-  aec->noiseEstCtr = 0;
-
-  // Initial comfort noise power
-  for (i = 0; i < PART_LEN1; i++) {
-    aec->dMinPow[i] = 1.0e6f;
-  }
-
-  // Holds the last block written to
-  aec->xfBufBlockPos = 0;
-  // TODO(peah): Investigate need for these initializations. Deleting them
-  // doesn't change the output at all and yields 0.4% overall speedup.
-  memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
-  memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
-  memset(aec->coherence_state.sde, 0, sizeof(complex_t) * PART_LEN1);
-  memset(aec->coherence_state.sxd, 0, sizeof(complex_t) * PART_LEN1);
-  memset(aec->xfwBuf, 0,
-         sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
-  memset(aec->coherence_state.se, 0, sizeof(float) * PART_LEN1);
-
-  // To prevent numerical instability in the first block.
-  for (i = 0; i < PART_LEN1; i++) {
-    aec->coherence_state.sd[i] = 1;
-  }
-  for (i = 0; i < PART_LEN1; i++) {
-    aec->coherence_state.sx[i] = 1;
-  }
-
-  memset(aec->hNs, 0, sizeof(aec->hNs));
-  memset(aec->outBuf, 0, sizeof(float) * PART_LEN);
-
-  aec->hNlFbMin = 1;
-  aec->hNlFbLocalMin = 1;
-  aec->hNlXdAvgMin = 1;
-  aec->hNlNewMin = 0;
-  aec->hNlMinCtr = 0;
-  aec->overDrive = 2;
-  aec->overdrive_scaling = 2;
-  aec->delayIdx = 0;
-  aec->stNearState = 0;
-  aec->echoState = 0;
-  aec->divergeState = 0;
-
-  aec->seed = 777;
-  aec->delayEstCtr = 0;
-
-  aec->extreme_filter_divergence = 0;
-
-  // Metrics disabled by default
-  aec->metricsMode = 0;
-  InitMetrics(aec);
-
-  return 0;
-}
-
-void WebRtcAec_BufferFarendBlock(AecCore* aec, const float* farend) {
-  // Check if the buffer is full, and in that case flush the oldest data.
-  if (aec->farend_block_buffer_.AvaliableSpace() < 1) {
-    aec->farend_block_buffer_.AdjustSize(1);
-  }
-  aec->farend_block_buffer_.Insert(farend);
-}
-
-int WebRtcAec_AdjustFarendBufferSizeAndSystemDelay(AecCore* aec,
-                                                   int buffer_size_decrease) {
-  int achieved_buffer_size_decrease =
-      aec->farend_block_buffer_.AdjustSize(buffer_size_decrease);
-  aec->system_delay -= achieved_buffer_size_decrease * PART_LEN;
-  return achieved_buffer_size_decrease;
-}
-
-void FormNearendBlock(
-    size_t nearend_start_index,
-    size_t num_bands,
-    const float* const* nearend_frame,
-    size_t num_samples_from_nearend_frame,
-    const float nearend_buffer[NUM_HIGH_BANDS_MAX + 1]
-                              [PART_LEN - (FRAME_LEN - PART_LEN)],
-    float nearend_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN]) {
-  RTC_DCHECK_LE(num_samples_from_nearend_frame, PART_LEN);
-  const int num_samples_from_buffer = PART_LEN - num_samples_from_nearend_frame;
-
-  if (num_samples_from_buffer > 0) {
-    for (size_t i = 0; i < num_bands; ++i) {
-      memcpy(&nearend_block[i][0], &nearend_buffer[i][0],
-             num_samples_from_buffer * sizeof(float));
-    }
-  }
-
-  for (size_t i = 0; i < num_bands; ++i) {
-    memcpy(&nearend_block[i][num_samples_from_buffer],
-           &nearend_frame[i][nearend_start_index],
-           num_samples_from_nearend_frame * sizeof(float));
-  }
-}
-
-void BufferNearendFrame(
-    size_t nearend_start_index,
-    size_t num_bands,
-    const float* const* nearend_frame,
-    size_t num_samples_to_buffer,
-    float nearend_buffer[NUM_HIGH_BANDS_MAX + 1]
-                        [PART_LEN - (FRAME_LEN - PART_LEN)]) {
-  for (size_t i = 0; i < num_bands; ++i) {
-    memcpy(&nearend_buffer[i][0],
-           &nearend_frame[i][nearend_start_index + FRAME_LEN -
-                             num_samples_to_buffer],
-           num_samples_to_buffer * sizeof(float));
-  }
-}
-
-void BufferOutputBlock(
-    size_t num_bands,
-    const float output_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN],
-    size_t* output_buffer_size,
-    float output_buffer[NUM_HIGH_BANDS_MAX + 1][2 * PART_LEN]) {
-  for (size_t i = 0; i < num_bands; ++i) {
-    memcpy(&output_buffer[i][*output_buffer_size], &output_block[i][0],
-           PART_LEN * sizeof(float));
-  }
-  (*output_buffer_size) += PART_LEN;
-}
-
-void FormOutputFrame(size_t output_start_index,
-                     size_t num_bands,
-                     size_t* output_buffer_size,
-                     float output_buffer[NUM_HIGH_BANDS_MAX + 1][2 * PART_LEN],
-                     float* const* output_frame) {
-  RTC_DCHECK_LE(FRAME_LEN, *output_buffer_size);
-  for (size_t i = 0; i < num_bands; ++i) {
-    memcpy(&output_frame[i][output_start_index], &output_buffer[i][0],
-           FRAME_LEN * sizeof(float));
-  }
-  (*output_buffer_size) -= FRAME_LEN;
-  if (*output_buffer_size > 0) {
-    RTC_DCHECK_GE(2 * PART_LEN - FRAME_LEN, (*output_buffer_size));
-    for (size_t i = 0; i < num_bands; ++i) {
-      memcpy(&output_buffer[i][0], &output_buffer[i][FRAME_LEN],
-             (*output_buffer_size) * sizeof(float));
-    }
-  }
-}
-
-void WebRtcAec_ProcessFrames(AecCore* aec,
-                             const float* const* nearend,
-                             size_t num_bands,
-                             size_t num_samples,
-                             int knownDelay,
-                             float* const* out) {
-  RTC_DCHECK(num_samples == 80 || num_samples == 160);
-
-  aec->frame_count++;
-  // For each frame the process is as follows:
-  // 1) If the system_delay indicates on being too small for processing a
-  //    frame we stuff the buffer with enough data for 10 ms.
-  // 2 a) Adjust the buffer to the system delay, by moving the read pointer.
-  //   b) Apply signal based delay correction, if we have detected poor AEC
-  //    performance.
-  // 3) TODO(bjornv): Investigate if we need to add this:
-  //    If we can't move read pointer due to buffer size limitations we
-  //    flush/stuff the buffer.
-  // 4) Process as many partitions as possible.
-  // 5) Update the |system_delay| with respect to a full frame of FRAME_LEN
-  //    samples. Even though we will have data left to process (we work with
-  //    partitions) we consider updating a whole frame, since that's the
-  //    amount of data we input and output in audio_processing.
-  // 6) Update the outputs.
-
-  // The AEC has two different delay estimation algorithms built in.  The
-  // first relies on delay input values from the user and the amount of
-  // shifted buffer elements is controlled by |knownDelay|.  This delay will
-  // give a guess on how much we need to shift far-end buffers to align with
-  // the near-end signal.  The other delay estimation algorithm uses the
-  // far- and near-end signals to find the offset between them.  This one
-  // (called "signal delay") is then used to fine tune the alignment, or
-  // simply compensate for errors in the system based one.
-  // Note that the two algorithms operate independently.  Currently, we only
-  // allow one algorithm to be turned on.
-
-  RTC_DCHECK_EQ(aec->num_bands, num_bands);
-
-  for (size_t j = 0; j < num_samples; j += FRAME_LEN) {
-    // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we
-    // have enough far-end data for that by stuffing the buffer if the
-    // |system_delay| indicates others.
-    if (aec->system_delay < FRAME_LEN) {
-      // We don't have enough data so we rewind 10 ms.
-      WebRtcAec_AdjustFarendBufferSizeAndSystemDelay(aec, -(aec->mult + 1));
-    }
-
-    if (!aec->delay_agnostic_enabled) {
-      // 2 a) Compensate for a possible change in the system delay.
-
-      // TODO(bjornv): Investigate how we should round the delay difference;
-      // right now we know that incoming |knownDelay| is underestimated when
-      // it's less than |aec->knownDelay|. We therefore, round (-32) in that
-      // direction. In the other direction, we don't have this situation, but
-      // might flush one partition too little. This can cause non-causality,
-      // which should be investigated. Maybe, allow for a non-symmetric
-      // rounding, like -16.
-      int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN;
-      int moved_elements = aec->farend_block_buffer_.AdjustSize(move_elements);
-      aec->knownDelay -= moved_elements * PART_LEN;
-    } else {
-      // 2 b) Apply signal based delay correction.
-      int move_elements = SignalBasedDelayCorrection(aec);
-      int moved_elements = aec->farend_block_buffer_.AdjustSize(move_elements);
-      int far_near_buffer_diff =
-          aec->farend_block_buffer_.Size() -
-          (aec->nearend_buffer_size + FRAME_LEN) / PART_LEN;
-      WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements);
-      WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend,
-                                           moved_elements);
-      // If we rely on reported system delay values only, a buffer underrun here
-      // can never occur since we've taken care of that in 1) above.  Here, we
-      // apply signal based delay correction and can therefore end up with
-      // buffer underruns since the delay estimation can be wrong.  We therefore
-      // stuff the buffer with enough elements if needed.
-      if (far_near_buffer_diff < 0) {
-        WebRtcAec_AdjustFarendBufferSizeAndSystemDelay(aec,
-                                                       far_near_buffer_diff);
-      }
-    }
-
-    static_assert(
-        16 == (FRAME_LEN - PART_LEN),
-        "These constants need to be properly related for this code to work");
-    float output_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN];
-    float nearend_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN];
-    float farend_extended_block_lowest_band[PART_LEN2];
-
-    // Form and process a block of nearend samples, buffer the output block of
-    // samples.
-    aec->farend_block_buffer_.ExtractExtendedBlock(
-        farend_extended_block_lowest_band);
-    FormNearendBlock(j, num_bands, nearend, PART_LEN - aec->nearend_buffer_size,
-                     aec->nearend_buffer, nearend_block);
-    ProcessNearendBlock(aec, farend_extended_block_lowest_band, nearend_block,
-                        output_block);
-    BufferOutputBlock(num_bands, output_block, &aec->output_buffer_size,
-                      aec->output_buffer);
-
-    if ((FRAME_LEN - PART_LEN + aec->nearend_buffer_size) == PART_LEN) {
-      // When possible (every fourth frame) form and process a second block of
-      // nearend samples, buffer the output block of samples.
-      aec->farend_block_buffer_.ExtractExtendedBlock(
-          farend_extended_block_lowest_band);
-      FormNearendBlock(j + FRAME_LEN - PART_LEN, num_bands, nearend, PART_LEN,
-                       aec->nearend_buffer, nearend_block);
-      ProcessNearendBlock(aec, farend_extended_block_lowest_band, nearend_block,
-                          output_block);
-      BufferOutputBlock(num_bands, output_block, &aec->output_buffer_size,
-                        aec->output_buffer);
-
-      // Reset the buffer size as there are no samples left in the nearend input
-      // to buffer.
-      aec->nearend_buffer_size = 0;
-    } else {
-      // Buffer the remaining samples in the nearend input.
-      aec->nearend_buffer_size += FRAME_LEN - PART_LEN;
-      BufferNearendFrame(j, num_bands, nearend, aec->nearend_buffer_size,
-                         aec->nearend_buffer);
-    }
-
-    // 5) Update system delay with respect to the entire frame.
-    aec->system_delay -= FRAME_LEN;
-
-    // 6) Form the output frame.
-    FormOutputFrame(j, num_bands, &aec->output_buffer_size, aec->output_buffer,
-                    out);
-  }
-}
-
-int WebRtcAec_GetDelayMetricsCore(AecCore* self,
-                                  int* median,
-                                  int* std,
-                                  float* fraction_poor_delays) {
-  RTC_DCHECK(self);
-  RTC_DCHECK(median);
-  RTC_DCHECK(std);
-
-  if (self->delay_logging_enabled == 0) {
-    // Logging disabled.
-    return -1;
-  }
-
-  if (self->delay_metrics_delivered == 0) {
-    UpdateDelayMetrics(self);
-    self->delay_metrics_delivered = 1;
-  }
-  *median = self->delay_median;
-  *std = self->delay_std;
-  *fraction_poor_delays = self->fraction_poor_delays;
-
-  return 0;
-}
-
-int WebRtcAec_echo_state(AecCore* self) {
-  return self->echoState;
-}
-
-void WebRtcAec_GetEchoStats(AecCore* self,
-                            Stats* erl,
-                            Stats* erle,
-                            Stats* a_nlp,
-                            float* divergent_filter_fraction) {
-  RTC_DCHECK(erl);
-  RTC_DCHECK(erle);
-  RTC_DCHECK(a_nlp);
-  *erl = self->erl;
-  *erle = self->erle;
-  *a_nlp = self->aNlp;
-  *divergent_filter_fraction =
-      self->divergent_filter_fraction.GetLatestFraction();
-}
-
-void WebRtcAec_SetConfigCore(AecCore* self,
-                             int nlp_mode,
-                             int metrics_mode,
-                             int delay_logging) {
-  RTC_DCHECK_GE(nlp_mode, 0);
-  RTC_DCHECK_LT(nlp_mode, 3);
-  self->nlp_mode = nlp_mode;
-  self->metricsMode = metrics_mode;
-  if (self->metricsMode) {
-    InitMetrics(self);
-  }
-  // Turn on delay logging if it is either set explicitly or if delay agnostic
-  // AEC is enabled (which requires delay estimates).
-  self->delay_logging_enabled = delay_logging || self->delay_agnostic_enabled;
-  if (self->delay_logging_enabled) {
-    memset(self->delay_histogram, 0, sizeof(self->delay_histogram));
-  }
-}
-
-void WebRtcAec_enable_delay_agnostic(AecCore* self, int enable) {
-  self->delay_agnostic_enabled = enable;
-}
-
-int WebRtcAec_delay_agnostic_enabled(AecCore* self) {
-  return self->delay_agnostic_enabled;
-}
-
-void WebRtcAec_enable_refined_adaptive_filter(AecCore* self, bool enable) {
-  self->refined_adaptive_filter_enabled = enable;
-  SetAdaptiveFilterStepSize(self);
-  SetErrorThreshold(self);
-}
-
-bool WebRtcAec_refined_adaptive_filter_enabled(const AecCore* self) {
-  return self->refined_adaptive_filter_enabled;
-}
-
-void WebRtcAec_enable_extended_filter(AecCore* self, int enable) {
-  self->extended_filter_enabled = enable;
-  SetAdaptiveFilterStepSize(self);
-  SetErrorThreshold(self);
-  self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions;
-  // Update the delay estimator with filter length.  See InitAEC() for details.
-  WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2);
-}
-
-int WebRtcAec_extended_filter_enabled(AecCore* self) {
-  return self->extended_filter_enabled;
-}
-
-int WebRtcAec_system_delay(AecCore* self) {
-  return self->system_delay;
-}
-
-void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
-  RTC_DCHECK_GE(delay, 0);
-  self->system_delay = delay;
-}
-}  // namespace webrtc
diff --git a/modules/audio_processing/aec/aec_core.h b/modules/audio_processing/aec/aec_core.h
deleted file mode 100644
index 659b6a1..0000000
--- a/modules/audio_processing/aec/aec_core.h
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-/*
- * Specifies the interface for the AEC core.
- */
-
-#ifndef MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_H_
-#define MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_H_
-
-#include <stddef.h>
-
-#include <memory>
-
-extern "C" {
-#include "common_audio/ring_buffer.h"
-}
-#include "modules/audio_processing/aec/aec_common.h"
-#include "modules/audio_processing/utility/block_mean_calculator.h"
-#include "modules/audio_processing/utility/ooura_fft.h"
-#include "rtc_base/constructor_magic.h"
-
-namespace webrtc {
-
-#define FRAME_LEN 80
-#define PART_LEN 64               // Length of partition
-#define PART_LEN1 (PART_LEN + 1)  // Unique fft coefficients
-#define PART_LEN2 (PART_LEN * 2)  // Length of partition * 2
-#define NUM_HIGH_BANDS_MAX 2      // Max number of high bands
-
-class ApmDataDumper;
-
-typedef float complex_t[2];
-// For performance reasons, some arrays of complex numbers are replaced by twice
-// as long arrays of float, all the real parts followed by all the imaginary
-// ones (complex_t[SIZE] -> float[2][SIZE]). This allows SIMD optimizations and
-// is better than two arrays (one for the real parts and one for the imaginary
-// parts) as this other way would require two pointers instead of one and cause
-// extra register spilling. This also allows the offsets to be calculated at
-// compile time.
-
-// Metrics
-enum { kOffsetLevel = -100 };
-
-typedef struct Stats {
-  float instant;
-  float average;
-  float min;
-  float max;
-  float sum;
-  float hisum;
-  float himean;
-  size_t counter;
-  size_t hicounter;
-} Stats;
-
-// Number of partitions for the extended filter mode. The first one is an enum
-// to be used in array declarations, as it represents the maximum filter length.
-enum { kExtendedNumPartitions = 32 };
-static const int kNormalNumPartitions = 12;
-
-// Delay estimator constants, used for logging and delay compensation if
-// if reported delays are disabled.
-enum { kLookaheadBlocks = 15 };
-enum {
-  // 500 ms for 16 kHz which is equivalent with the limit of reported delays.
-  kHistorySizeBlocks = 125
-};
-
-typedef struct PowerLevel {
-  PowerLevel();
-
-  BlockMeanCalculator framelevel;
-  BlockMeanCalculator averagelevel;
-  float minlevel;
-} PowerLevel;
-
-class Aec2BlockBuffer {
- public:
-  Aec2BlockBuffer();
-  ~Aec2BlockBuffer();
-  void ReInit();
-  void Insert(const float block[PART_LEN]);
-  void ExtractExtendedBlock(float extended_block[PART_LEN]);
-  int AdjustSize(int buffer_size_decrease);
-  size_t Size();
-  size_t AvaliableSpace();
-
- private:
-  RingBuffer* buffer_;
-};
-
-class DivergentFilterFraction {
- public:
-  DivergentFilterFraction();
-
-  // Reset.
-  void Reset();
-
-  void AddObservation(const PowerLevel& nearlevel,
-                      const PowerLevel& linoutlevel,
-                      const PowerLevel& nlpoutlevel);
-
-  // Return the latest fraction.
-  float GetLatestFraction() const;
-
- private:
-  // Clear all values added.
-  void Clear();
-
-  size_t count_;
-  size_t occurrence_;
-  float fraction_;
-
-  RTC_DISALLOW_COPY_AND_ASSIGN(DivergentFilterFraction);
-};
-
-typedef struct CoherenceState {
-  complex_t sde[PART_LEN1];  // cross-psd of nearend and error
-  complex_t sxd[PART_LEN1];  // cross-psd of farend and nearend
-  float sx[PART_LEN1], sd[PART_LEN1], se[PART_LEN1];  // far, near, error psd
-} CoherenceState;
-
-struct AecCore {
-  explicit AecCore(int instance_index);
-  ~AecCore();
-
-  std::unique_ptr<ApmDataDumper> data_dumper;
-  const OouraFft ooura_fft;
-
-  CoherenceState coherence_state;
-
-  int farBufWritePos, farBufReadPos;
-
-  int knownDelay;
-  int inSamples, outSamples;
-  int delayEstCtr;
-
-  // Nearend buffer used for changing from FRAME_LEN to PART_LEN sample block
-  // sizes. The buffer stores all the incoming bands and for each band a maximum
-  // of PART_LEN - (FRAME_LEN - PART_LEN) values need to be buffered in order to
-  // change the block size from FRAME_LEN to PART_LEN.
-  float nearend_buffer[NUM_HIGH_BANDS_MAX + 1]
-                      [PART_LEN - (FRAME_LEN - PART_LEN)];
-  size_t nearend_buffer_size;
-  float output_buffer[NUM_HIGH_BANDS_MAX + 1][2 * PART_LEN];
-  size_t output_buffer_size;
-
-  float eBuf[PART_LEN2];  // error
-
-  float previous_nearend_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN];
-
-  float xPow[PART_LEN1];
-  float dPow[PART_LEN1];
-  float dMinPow[PART_LEN1];
-  float dInitMinPow[PART_LEN1];
-  float* noisePow;
-
-  float xfBuf[2][kExtendedNumPartitions * PART_LEN1];  // farend fft buffer
-  float wfBuf[2][kExtendedNumPartitions * PART_LEN1];  // filter fft
-  // Farend windowed fft buffer.
-  complex_t xfwBuf[kExtendedNumPartitions * PART_LEN1];
-
-  float hNs[PART_LEN1];
-  float hNlFbMin, hNlFbLocalMin;
-  float hNlXdAvgMin;
-  int hNlNewMin, hNlMinCtr;
-  float overDrive;
-  float overdrive_scaling;
-  int nlp_mode;
-  float outBuf[PART_LEN];
-  int delayIdx;
-
-  short stNearState, echoState;
-  short divergeState;
-
-  int xfBufBlockPos;
-
-  Aec2BlockBuffer farend_block_buffer_;
-
-  int system_delay;  // Current system delay buffered in AEC.
-
-  int mult;  // sampling frequency multiple
-  int sampFreq = 16000;
-  size_t num_bands;
-  uint32_t seed;
-
-  float filter_step_size;  // stepsize
-  float error_threshold;   // error threshold
-
-  int noiseEstCtr;
-
-  PowerLevel farlevel;
-  PowerLevel nearlevel;
-  PowerLevel linoutlevel;
-  PowerLevel nlpoutlevel;
-
-  int metricsMode;
-  int stateCounter;
-  Stats erl;
-  Stats erle;
-  Stats aNlp;
-  Stats rerl;
-  DivergentFilterFraction divergent_filter_fraction;
-
-  // Quantities to control H band scaling for SWB input
-  int freq_avg_ic;       // initial bin for averaging nlp gain
-  int flag_Hband_cn;     // for comfort noise
-  float cn_scale_Hband;  // scale for comfort noise in H band
-
-  int delay_metrics_delivered;
-  int delay_histogram[kHistorySizeBlocks];
-  int num_delay_values;
-  int delay_median;
-  int delay_std;
-  float fraction_poor_delays;
-  int delay_logging_enabled;
-  void* delay_estimator_farend;
-  void* delay_estimator;
-  // Variables associated with delay correction through signal based delay
-  // estimation feedback.
-  int previous_delay;
-  int delay_correction_count;
-  int shift_offset;
-  float delay_quality_threshold;
-  int frame_count;
-
-  // 0 = delay agnostic mode (signal based delay correction) disabled.
-  // Otherwise enabled.
-  int delay_agnostic_enabled;
-  // 1 = extended filter mode enabled, 0 = disabled.
-  int extended_filter_enabled;
-  // 1 = refined filter adaptation aec mode enabled, 0 = disabled.
-  bool refined_adaptive_filter_enabled;
-
-  // Runtime selection of number of filter partitions.
-  int num_partitions;
-
-  // Flag that extreme filter divergence has been detected by the Echo
-  // Suppressor.
-  int extreme_filter_divergence;
-};
-
-AecCore* WebRtcAec_CreateAec(int instance_count);  // Returns NULL on error.
-void WebRtcAec_FreeAec(AecCore* aec);
-int WebRtcAec_InitAec(AecCore* aec, int sampFreq);
-void WebRtcAec_InitAec_SSE2(void);
-#if defined(MIPS_FPU_LE)
-void WebRtcAec_InitAec_mips(void);
-#endif
-#if defined(WEBRTC_HAS_NEON)
-void WebRtcAec_InitAec_neon(void);
-#endif
-
-void WebRtcAec_BufferFarendBlock(AecCore* aec, const float* farend);
-void WebRtcAec_ProcessFrames(AecCore* aec,
-                             const float* const* nearend,
-                             size_t num_bands,
-                             size_t num_samples,
-                             int knownDelay,
-                             float* const* out);
-
-// A helper function to call adjust the farend buffer size.
-// Returns the number of elements the size was decreased with, and adjusts
-// |system_delay| by the corresponding amount in ms.
-int WebRtcAec_AdjustFarendBufferSizeAndSystemDelay(AecCore* aec,
-                                                   int size_decrease);
-
-// Calculates the median, standard deviation and amount of poor values among the
-// delay estimates aggregated up to the first call to the function. After that
-// first call the metrics are aggregated and updated every second. With poor
-// values we mean values that most likely will cause the AEC to perform poorly.
-// TODO(bjornv): Consider changing tests and tools to handle constant
-// constant aggregation window throughout the session instead.
-int WebRtcAec_GetDelayMetricsCore(AecCore* self,
-                                  int* median,
-                                  int* std,
-                                  float* fraction_poor_delays);
-
-// Returns the echo state (1: echo, 0: no echo).
-int WebRtcAec_echo_state(AecCore* self);
-
-// Gets statistics of the echo metrics ERL, ERLE, A_NLP.
-void WebRtcAec_GetEchoStats(AecCore* self,
-                            Stats* erl,
-                            Stats* erle,
-                            Stats* a_nlp,
-                            float* divergent_filter_fraction);
-
-// Sets local configuration modes.
-void WebRtcAec_SetConfigCore(AecCore* self,
-                             int nlp_mode,
-                             int metrics_mode,
-                             int delay_logging);
-
-// Non-zero enables, zero disables.
-void WebRtcAec_enable_delay_agnostic(AecCore* self, int enable);
-
-// Returns non-zero if delay agnostic (i.e., signal based delay estimation) is
-// enabled and zero if disabled.
-int WebRtcAec_delay_agnostic_enabled(AecCore* self);
-
-// Turns on/off the refined adaptive filter feature.
-void WebRtcAec_enable_refined_adaptive_filter(AecCore* self, bool enable);
-
-// Returns whether the refined adaptive filter is enabled.
-bool WebRtcAec_refined_adaptive_filter(const AecCore* self);
-
-// Enables or disables extended filter mode. Non-zero enables, zero disables.
-void WebRtcAec_enable_extended_filter(AecCore* self, int enable);
-
-// Returns non-zero if extended filter mode is enabled and zero if disabled.
-int WebRtcAec_extended_filter_enabled(AecCore* self);
-
-// Returns the current |system_delay|, i.e., the buffered difference between
-// far-end and near-end.
-int WebRtcAec_system_delay(AecCore* self);
-
-// Sets the |system_delay| to |value|.  Note that if the value is changed
-// improperly, there can be a performance regression.  So it should be used with
-// care.
-void WebRtcAec_SetSystemDelay(AecCore* self, int delay);
-
-}  // namespace webrtc
-
-#endif  // MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_H_
diff --git a/modules/audio_processing/aec/aec_core_mips.cc b/modules/audio_processing/aec/aec_core_mips.cc
deleted file mode 100644
index 2b388a7..0000000
--- a/modules/audio_processing/aec/aec_core_mips.cc
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-/*
- * The core AEC algorithm, which is presented with time-aligned signals.
- */
-
-#include <math.h>
-
-#include "modules/audio_processing/aec/aec_core.h"
-
-extern "C" {
-#include "common_audio/signal_processing/include/signal_processing_library.h"
-}
-#include "modules/audio_processing/aec/aec_core_optimized_methods.h"
-#include "modules/audio_processing/utility/ooura_fft.h"
-
-namespace webrtc {
-
-extern const float WebRtcAec_weightCurve[65];
-extern const float WebRtcAec_overDriveCurve[65];
-
-void WebRtcAec_FilterFar_mips(
-    int num_partitions,
-    int x_fft_buf_block_pos,
-    float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float y_fft[2][PART_LEN1]) {
-  int i;
-  for (i = 0; i < num_partitions; i++) {
-    int xPos = (i + x_fft_buf_block_pos) * PART_LEN1;
-    int pos = i * PART_LEN1;
-    // Check for wrap
-    if (i + x_fft_buf_block_pos >= num_partitions) {
-      xPos -= num_partitions * (PART_LEN1);
-    }
-    float* yf0 = y_fft[0];
-    float* yf1 = y_fft[1];
-    float* aRe = x_fft_buf[0] + xPos;
-    float* aIm = x_fft_buf[1] + xPos;
-    float* bRe = h_fft_buf[0] + pos;
-    float* bIm = h_fft_buf[1] + pos;
-    float f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13;
-    int len = PART_LEN1 >> 1;
-
-    __asm __volatile(
-        ".set       push                                                \n\t"
-        ".set       noreorder                                           \n\t"
-        "1:                                                             \n\t"
-        "lwc1       %[f0],      0(%[aRe])                               \n\t"
-        "lwc1       %[f1],      0(%[bRe])                               \n\t"
-        "lwc1       %[f2],      0(%[bIm])                               \n\t"
-        "lwc1       %[f3],      0(%[aIm])                               \n\t"
-        "lwc1       %[f4],      4(%[aRe])                               \n\t"
-        "lwc1       %[f5],      4(%[bRe])                               \n\t"
-        "lwc1       %[f6],      4(%[bIm])                               \n\t"
-        "mul.s      %[f8],      %[f0],          %[f1]                   \n\t"
-        "mul.s      %[f0],      %[f0],          %[f2]                   \n\t"
-        "mul.s      %[f9],      %[f4],          %[f5]                   \n\t"
-        "mul.s      %[f4],      %[f4],          %[f6]                   \n\t"
-        "lwc1       %[f7],      4(%[aIm])                               \n\t"
-#if !defined(MIPS32_R2_LE)
-        "mul.s      %[f12],     %[f2],          %[f3]                   \n\t"
-        "mul.s      %[f1],      %[f3],          %[f1]                   \n\t"
-        "mul.s      %[f11],     %[f6],          %[f7]                   \n\t"
-        "addiu      %[aRe],     %[aRe],         8                       \n\t"
-        "addiu      %[aIm],     %[aIm],         8                       \n\t"
-        "addiu      %[len],     %[len],         -1                      \n\t"
-        "sub.s      %[f8],      %[f8],          %[f12]                  \n\t"
-        "mul.s      %[f12],     %[f7],          %[f5]                   \n\t"
-        "lwc1       %[f2],      0(%[yf0])                               \n\t"
-        "add.s      %[f1],      %[f0],          %[f1]                   \n\t"
-        "lwc1       %[f3],      0(%[yf1])                               \n\t"
-        "sub.s      %[f9],      %[f9],          %[f11]                  \n\t"
-        "lwc1       %[f6],      4(%[yf0])                               \n\t"
-        "add.s      %[f4],      %[f4],          %[f12]                  \n\t"
-#else   // #if !defined(MIPS32_R2_LE)
-        "addiu      %[aRe],     %[aRe],         8                       \n\t"
-        "addiu      %[aIm],     %[aIm],         8                       \n\t"
-        "addiu      %[len],     %[len],         -1                      \n\t"
-        "nmsub.s    %[f8],      %[f8],          %[f2],      %[f3]       \n\t"
-        "lwc1       %[f2],      0(%[yf0])                               \n\t"
-        "madd.s     %[f1],      %[f0],          %[f3],      %[f1]       \n\t"
-        "lwc1       %[f3],      0(%[yf1])                               \n\t"
-        "nmsub.s    %[f9],      %[f9],          %[f6],      %[f7]       \n\t"
-        "lwc1       %[f6],      4(%[yf0])                               \n\t"
-        "madd.s     %[f4],      %[f4],          %[f7],      %[f5]       \n\t"
-#endif  // #if !defined(MIPS32_R2_LE)
-        "lwc1       %[f5],      4(%[yf1])                               \n\t"
-        "add.s      %[f2],      %[f2],          %[f8]                   \n\t"
-        "addiu      %[bRe],     %[bRe],         8                       \n\t"
-        "addiu      %[bIm],     %[bIm],         8                       \n\t"
-        "add.s      %[f3],      %[f3],          %[f1]                   \n\t"
-        "add.s      %[f6],      %[f6],          %[f9]                   \n\t"
-        "add.s      %[f5],      %[f5],          %[f4]                   \n\t"
-        "swc1       %[f2],      0(%[yf0])                               \n\t"
-        "swc1       %[f3],      0(%[yf1])                               \n\t"
-        "swc1       %[f6],      4(%[yf0])                               \n\t"
-        "swc1       %[f5],      4(%[yf1])                               \n\t"
-        "addiu      %[yf0],     %[yf0],         8                       \n\t"
-        "bgtz       %[len],     1b                                      \n\t"
-        " addiu     %[yf1],     %[yf1],         8                       \n\t"
-        "lwc1       %[f0],      0(%[aRe])                               \n\t"
-        "lwc1       %[f1],      0(%[bRe])                               \n\t"
-        "lwc1       %[f2],      0(%[bIm])                               \n\t"
-        "lwc1       %[f3],      0(%[aIm])                               \n\t"
-        "mul.s      %[f8],      %[f0],          %[f1]                   \n\t"
-        "mul.s      %[f0],      %[f0],          %[f2]                   \n\t"
-#if !defined(MIPS32_R2_LE)
-        "mul.s      %[f12],     %[f2],          %[f3]                   \n\t"
-        "mul.s      %[f1],      %[f3],          %[f1]                   \n\t"
-        "sub.s      %[f8],      %[f8],          %[f12]                  \n\t"
-        "lwc1       %[f2],      0(%[yf0])                               \n\t"
-        "add.s      %[f1],      %[f0],          %[f1]                   \n\t"
-        "lwc1       %[f3],      0(%[yf1])                               \n\t"
-#else   // #if !defined(MIPS32_R2_LE)
-        "nmsub.s    %[f8],      %[f8],          %[f2],      %[f3]       \n\t"
-        "lwc1       %[f2],      0(%[yf0])                               \n\t"
-        "madd.s     %[f1],      %[f0],          %[f3],      %[f1]       \n\t"
-        "lwc1       %[f3],      0(%[yf1])                               \n\t"
-#endif  // #if !defined(MIPS32_R2_LE)
-        "add.s      %[f2],      %[f2],          %[f8]                   \n\t"
-        "add.s      %[f3],      %[f3],          %[f1]                   \n\t"
-        "swc1       %[f2],      0(%[yf0])                               \n\t"
-        "swc1       %[f3],      0(%[yf1])                               \n\t"
-        ".set       pop                                                 \n\t"
-        : [f0] "=&f"(f0), [f1] "=&f"(f1), [f2] "=&f"(f2), [f3] "=&f"(f3),
-          [f4] "=&f"(f4), [f5] "=&f"(f5), [f6] "=&f"(f6), [f7] "=&f"(f7),
-          [f8] "=&f"(f8), [f9] "=&f"(f9), [f10] "=&f"(f10), [f11] "=&f"(f11),
-          [f12] "=&f"(f12), [f13] "=&f"(f13), [aRe] "+r"(aRe), [aIm] "+r"(aIm),
-          [bRe] "+r"(bRe), [bIm] "+r"(bIm), [yf0] "+r"(yf0), [yf1] "+r"(yf1),
-          [len] "+r"(len)
-        :
-        : "memory");
-  }
-}
-
-void WebRtcAec_FilterAdaptation_mips(
-    const OouraFft& ooura_fft,
-    int num_partitions,
-    int x_fft_buf_block_pos,
-    float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float e_fft[2][PART_LEN1],
-    float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) {
-  float fft[PART_LEN2];
-  int i;
-  for (i = 0; i < num_partitions; i++) {
-    int xPos = (i + x_fft_buf_block_pos) * (PART_LEN1);
-    int pos;
-    // Check for wrap
-    if (i + x_fft_buf_block_pos >= num_partitions) {
-      xPos -= num_partitions * PART_LEN1;
-    }
-
-    pos = i * PART_LEN1;
-    float* aRe = x_fft_buf[0] + xPos;
-    float* aIm = x_fft_buf[1] + xPos;
-    float* bRe = e_fft[0];
-    float* bIm = e_fft[1];
-    float* fft_tmp;
-
-    float f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12;
-    int len = PART_LEN >> 1;
-
-    __asm __volatile(
-        ".set       push                                                \n\t"
-        ".set       noreorder                                           \n\t"
-        "addiu      %[fft_tmp], %[fft],         0                       \n\t"
-        "1:                                                             \n\t"
-        "lwc1       %[f0],      0(%[aRe])                               \n\t"
-        "lwc1       %[f1],      0(%[bRe])                               \n\t"
-        "lwc1       %[f2],      0(%[bIm])                               \n\t"
-        "lwc1       %[f4],      4(%[aRe])                               \n\t"
-        "lwc1       %[f5],      4(%[bRe])                               \n\t"
-        "lwc1       %[f6],      4(%[bIm])                               \n\t"
-        "addiu      %[aRe],     %[aRe],         8                       \n\t"
-        "addiu      %[bRe],     %[bRe],         8                       \n\t"
-        "mul.s      %[f8],      %[f0],          %[f1]                   \n\t"
-        "mul.s      %[f0],      %[f0],          %[f2]                   \n\t"
-        "lwc1       %[f3],      0(%[aIm])                               \n\t"
-        "mul.s      %[f9],      %[f4],          %[f5]                   \n\t"
-        "lwc1       %[f7],      4(%[aIm])                               \n\t"
-        "mul.s      %[f4],      %[f4],          %[f6]                   \n\t"
-#if !defined(MIPS32_R2_LE)
-        "mul.s      %[f10],     %[f3],          %[f2]                   \n\t"
-        "mul.s      %[f1],      %[f3],          %[f1]                   \n\t"
-        "mul.s      %[f11],     %[f7],          %[f6]                   \n\t"
-        "mul.s      %[f5],      %[f7],          %[f5]                   \n\t"
-        "addiu      %[aIm],     %[aIm],         8                       \n\t"
-        "addiu      %[bIm],     %[bIm],         8                       \n\t"
-        "addiu      %[len],     %[len],         -1                      \n\t"
-        "add.s      %[f8],      %[f8],          %[f10]                  \n\t"
-        "sub.s      %[f1],      %[f0],          %[f1]                   \n\t"
-        "add.s      %[f9],      %[f9],          %[f11]                  \n\t"
-        "sub.s      %[f5],      %[f4],          %[f5]                   \n\t"
-#else   // #if !defined(MIPS32_R2_LE)
-        "addiu      %[aIm],     %[aIm],         8                       \n\t"
-        "addiu      %[bIm],     %[bIm],         8                       \n\t"
-        "addiu      %[len],     %[len],         -1                      \n\t"
-        "madd.s     %[f8],      %[f8],          %[f3],      %[f2]       \n\t"
-        "nmsub.s    %[f1],      %[f0],          %[f3],      %[f1]       \n\t"
-        "madd.s     %[f9],      %[f9],          %[f7],      %[f6]       \n\t"
-        "nmsub.s    %[f5],      %[f4],          %[f7],      %[f5]       \n\t"
-#endif  // #if !defined(MIPS32_R2_LE)
-        "swc1       %[f8],      0(%[fft_tmp])                           \n\t"
-        "swc1       %[f1],      4(%[fft_tmp])                           \n\t"
-        "swc1       %[f9],      8(%[fft_tmp])                           \n\t"
-        "swc1       %[f5],      12(%[fft_tmp])                          \n\t"
-        "bgtz       %[len],     1b                                      \n\t"
-        " addiu     %[fft_tmp], %[fft_tmp],     16                      \n\t"
-        "lwc1       %[f0],      0(%[aRe])                               \n\t"
-        "lwc1       %[f1],      0(%[bRe])                               \n\t"
-        "lwc1       %[f2],      0(%[bIm])                               \n\t"
-        "lwc1       %[f3],      0(%[aIm])                               \n\t"
-        "mul.s      %[f8],      %[f0],          %[f1]                   \n\t"
-#if !defined(MIPS32_R2_LE)
-        "mul.s      %[f10],     %[f3],          %[f2]                   \n\t"
-        "add.s      %[f8],      %[f8],          %[f10]                  \n\t"
-#else   // #if !defined(MIPS32_R2_LE)
-        "madd.s     %[f8],      %[f8],          %[f3],      %[f2]       \n\t"
-#endif  // #if !defined(MIPS32_R2_LE)
-        "swc1       %[f8],      4(%[fft])                               \n\t"
-        ".set       pop                                                 \n\t"
-        : [f0] "=&f"(f0), [f1] "=&f"(f1), [f2] "=&f"(f2), [f3] "=&f"(f3),
-          [f4] "=&f"(f4), [f5] "=&f"(f5), [f6] "=&f"(f6), [f7] "=&f"(f7),
-          [f8] "=&f"(f8), [f9] "=&f"(f9), [f10] "=&f"(f10), [f11] "=&f"(f11),
-          [f12] "=&f"(f12), [aRe] "+r"(aRe), [aIm] "+r"(aIm), [bRe] "+r"(bRe),
-          [bIm] "+r"(bIm), [fft_tmp] "=&r"(fft_tmp), [len] "+r"(len)
-        : [fft] "r"(fft)
-        : "memory");
-
-    ooura_fft.InverseFft(fft);
-    memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN);
-
-    // fft scaling
-    {
-      float scale = 2.0f / PART_LEN2;
-      __asm __volatile(
-          ".set     push                                    \n\t"
-          ".set     noreorder                               \n\t"
-          "addiu    %[fft_tmp], %[fft],        0            \n\t"
-          "addiu    %[len],     $zero,         8            \n\t"
-          "1:                                               \n\t"
-          "addiu    %[len],     %[len],        -1           \n\t"
-          "lwc1     %[f0],      0(%[fft_tmp])               \n\t"
-          "lwc1     %[f1],      4(%[fft_tmp])               \n\t"
-          "lwc1     %[f2],      8(%[fft_tmp])               \n\t"
-          "lwc1     %[f3],      12(%[fft_tmp])              \n\t"
-          "mul.s    %[f0],      %[f0],         %[scale]     \n\t"
-          "mul.s    %[f1],      %[f1],         %[scale]     \n\t"
-          "mul.s    %[f2],      %[f2],         %[scale]     \n\t"
-          "mul.s    %[f3],      %[f3],         %[scale]     \n\t"
-          "lwc1     %[f4],      16(%[fft_tmp])              \n\t"
-          "lwc1     %[f5],      20(%[fft_tmp])              \n\t"
-          "lwc1     %[f6],      24(%[fft_tmp])              \n\t"
-          "lwc1     %[f7],      28(%[fft_tmp])              \n\t"
-          "mul.s    %[f4],      %[f4],         %[scale]     \n\t"
-          "mul.s    %[f5],      %[f5],         %[scale]     \n\t"
-          "mul.s    %[f6],      %[f6],         %[scale]     \n\t"
-          "mul.s    %[f7],      %[f7],         %[scale]     \n\t"
-          "swc1     %[f0],      0(%[fft_tmp])               \n\t"
-          "swc1     %[f1],      4(%[fft_tmp])               \n\t"
-          "swc1     %[f2],      8(%[fft_tmp])               \n\t"
-          "swc1     %[f3],      12(%[fft_tmp])              \n\t"
-          "swc1     %[f4],      16(%[fft_tmp])              \n\t"
-          "swc1     %[f5],      20(%[fft_tmp])              \n\t"
-          "swc1     %[f6],      24(%[fft_tmp])              \n\t"
-          "swc1     %[f7],      28(%[fft_tmp])              \n\t"
-          "bgtz     %[len],     1b                          \n\t"
-          " addiu   %[fft_tmp], %[fft_tmp],    32           \n\t"
-          ".set     pop                                     \n\t"
-          : [f0] "=&f"(f0), [f1] "=&f"(f1), [f2] "=&f"(f2), [f3] "=&f"(f3),
-            [f4] "=&f"(f4), [f5] "=&f"(f5), [f6] "=&f"(f6), [f7] "=&f"(f7),
-            [len] "=&r"(len), [fft_tmp] "=&r"(fft_tmp)
-          : [scale] "f"(scale), [fft] "r"(fft)
-          : "memory");
-    }
-    ooura_fft.Fft(fft);
-    aRe = h_fft_buf[0] + pos;
-    aIm = h_fft_buf[1] + pos;
-    __asm __volatile(
-        ".set     push                                    \n\t"
-        ".set     noreorder                               \n\t"
-        "addiu    %[fft_tmp], %[fft],        0            \n\t"
-        "addiu    %[len],     $zero,         31           \n\t"
-        "lwc1     %[f0],      0(%[aRe])                   \n\t"
-        "lwc1     %[f1],      0(%[fft_tmp])               \n\t"
-        "lwc1     %[f2],      256(%[aRe])                 \n\t"
-        "lwc1     %[f3],      4(%[fft_tmp])               \n\t"
-        "lwc1     %[f4],      4(%[aRe])                   \n\t"
-        "lwc1     %[f5],      8(%[fft_tmp])               \n\t"
-        "lwc1     %[f6],      4(%[aIm])                   \n\t"
-        "lwc1     %[f7],      12(%[fft_tmp])              \n\t"
-        "add.s    %[f0],      %[f0],         %[f1]        \n\t"
-        "add.s    %[f2],      %[f2],         %[f3]        \n\t"
-        "add.s    %[f4],      %[f4],         %[f5]        \n\t"
-        "add.s    %[f6],      %[f6],         %[f7]        \n\t"
-        "addiu    %[fft_tmp], %[fft_tmp],    16           \n\t"
-        "swc1     %[f0],      0(%[aRe])                   \n\t"
-        "swc1     %[f2],      256(%[aRe])                 \n\t"
-        "swc1     %[f4],      4(%[aRe])                   \n\t"
-        "addiu    %[aRe],     %[aRe],        8            \n\t"
-        "swc1     %[f6],      4(%[aIm])                   \n\t"
-        "addiu    %[aIm],     %[aIm],        8            \n\t"
-        "1:                                               \n\t"
-        "lwc1     %[f0],      0(%[aRe])                   \n\t"
-        "lwc1     %[f1],      0(%[fft_tmp])               \n\t"
-        "lwc1     %[f2],      0(%[aIm])                   \n\t"
-        "lwc1     %[f3],      4(%[fft_tmp])               \n\t"
-        "lwc1     %[f4],      4(%[aRe])                   \n\t"
-        "lwc1     %[f5],      8(%[fft_tmp])               \n\t"
-        "lwc1     %[f6],      4(%[aIm])                   \n\t"
-        "lwc1     %[f7],      12(%[fft_tmp])              \n\t"
-        "add.s    %[f0],      %[f0],         %[f1]        \n\t"
-        "add.s    %[f2],      %[f2],         %[f3]        \n\t"
-        "add.s    %[f4],      %[f4],         %[f5]        \n\t"
-        "add.s    %[f6],      %[f6],         %[f7]        \n\t"
-        "addiu    %[len],     %[len],        -1           \n\t"
-        "addiu    %[fft_tmp], %[fft_tmp],    16           \n\t"
-        "swc1     %[f0],      0(%[aRe])                   \n\t"
-        "swc1     %[f2],      0(%[aIm])                   \n\t"
-        "swc1     %[f4],      4(%[aRe])                   \n\t"
-        "addiu    %[aRe],     %[aRe],        8            \n\t"
-        "swc1     %[f6],      4(%[aIm])                   \n\t"
-        "bgtz     %[len],     1b                          \n\t"
-        " addiu   %[aIm],     %[aIm],        8            \n\t"
-        ".set     pop                                     \n\t"
-        : [f0] "=&f"(f0), [f1] "=&f"(f1), [f2] "=&f"(f2), [f3] "=&f"(f3),
-          [f4] "=&f"(f4), [f5] "=&f"(f5), [f6] "=&f"(f6), [f7] "=&f"(f7),
-          [len] "=&r"(len), [fft_tmp] "=&r"(fft_tmp), [aRe] "+r"(aRe),
-          [aIm] "+r"(aIm)
-        : [fft] "r"(fft)
-        : "memory");
-  }
-}
-
-void WebRtcAec_Overdrive_mips(float overdrive_scaling,
-                              float hNlFb,
-                              float hNl[PART_LEN1]) {
-  const float one = 1.0;
-  float* p_hNl;
-  const float* p_WebRtcAec_wC;
-  float temp1, temp2, temp3, temp4;
-
-  p_hNl = &hNl[0];
-  p_WebRtcAec_wC = &WebRtcAec_weightCurve[0];
-
-  for (int i = 0; i < PART_LEN1; ++i) {
-    // Weight subbands
-    __asm __volatile(
-        ".set      push                                              \n\t"
-        ".set      noreorder                                         \n\t"
-        "lwc1      %[temp1],    0(%[p_hNl])                          \n\t"
-        "lwc1      %[temp2],    0(%[p_wC])                           \n\t"
-        "c.lt.s    %[hNlFb],    %[temp1]                             \n\t"
-        "bc1f      1f                                                \n\t"
-        " mul.s    %[temp3],    %[temp2],     %[hNlFb]               \n\t"
-        "sub.s     %[temp4],    %[one],       %[temp2]               \n\t"
-#if !defined(MIPS32_R2_LE)
-        "mul.s     %[temp1],    %[temp1],     %[temp4]               \n\t"
-        "add.s     %[temp1],    %[temp3],     %[temp1]               \n\t"
-#else   // #if !defined(MIPS32_R2_LE)
-        "madd.s    %[temp1],    %[temp3],     %[temp1],   %[temp4]   \n\t"
-#endif  // #if !defined(MIPS32_R2_LE)
-        "swc1      %[temp1],    0(%[p_hNl])                          \n\t"
-        "1:                                                           \n\t"
-        "addiu     %[p_wC],     %[p_wC],      4                      \n\t"
-        ".set      pop                                               \n\t"
-        : [temp1] "=&f"(temp1), [temp2] "=&f"(temp2), [temp3] "=&f"(temp3),
-          [temp4] "=&f"(temp4), [p_wC] "+r"(p_WebRtcAec_wC)
-        : [hNlFb] "f"(hNlFb), [one] "f"(one), [p_hNl] "r"(p_hNl)
-        : "memory");
-
-    hNl[i] = powf(hNl[i], overdrive_scaling * WebRtcAec_overDriveCurve[i]);
-  }
-}
-
-void WebRtcAec_Suppress_mips(const float hNl[PART_LEN1],
-                             float efw[2][PART_LEN1]) {
-  const float* p_hNl;
-  float* p_efw0;
-  float* p_efw1;
-  float temp1, temp2, temp3, temp4;
-
-  p_hNl = &hNl[0];
-  p_efw0 = &efw[0][0];
-  p_efw1 = &efw[1][0];
-
-  for (int i = 0; i < PART_LEN1; ++i) {
-    __asm __volatile(
-        "lwc1      %[temp1],    0(%[p_hNl])              \n\t"
-        "lwc1      %[temp3],    0(%[p_efw1])             \n\t"
-        "lwc1      %[temp2],    0(%[p_efw0])             \n\t"
-        "addiu     %[p_hNl],    %[p_hNl],     4          \n\t"
-        "mul.s     %[temp3],    %[temp3],     %[temp1]   \n\t"
-        "mul.s     %[temp2],    %[temp2],     %[temp1]   \n\t"
-        "addiu     %[p_efw0],   %[p_efw0],    4          \n\t"
-        "addiu     %[p_efw1],   %[p_efw1],    4          \n\t"
-        "neg.s     %[temp4],    %[temp3]                 \n\t"
-        "swc1      %[temp2],    -4(%[p_efw0])            \n\t"
-        "swc1      %[temp4],    -4(%[p_efw1])            \n\t"
-        : [temp1] "=&f"(temp1), [temp2] "=&f"(temp2), [temp3] "=&f"(temp3),
-          [temp4] "=&f"(temp4), [p_efw0] "+r"(p_efw0), [p_efw1] "+r"(p_efw1),
-          [p_hNl] "+r"(p_hNl)
-        :
-        : "memory");
-  }
-}
-
-void WebRtcAec_ScaleErrorSignal_mips(float mu,
-                                     float error_threshold,
-                                     float x_pow[PART_LEN1],
-                                     float ef[2][PART_LEN1]) {
-  int len = (PART_LEN1);
-  float* ef0 = ef[0];
-  float* ef1 = ef[1];
-  float fac1 = 1e-10f;
-  float err_th2 = error_threshold * error_threshold;
-  float f0, f1, f2;
-#if !defined(MIPS32_R2_LE)
-  float f3;
-#endif
-
-  __asm __volatile(
-      ".set       push                                   \n\t"
-      ".set       noreorder                              \n\t"
-      "1:                                                \n\t"
-      "lwc1       %[f0],     0(%[x_pow])                 \n\t"
-      "lwc1       %[f1],     0(%[ef0])                   \n\t"
-      "lwc1       %[f2],     0(%[ef1])                   \n\t"
-      "add.s      %[f0],     %[f0],       %[fac1]        \n\t"
-      "div.s      %[f1],     %[f1],       %[f0]          \n\t"
-      "div.s      %[f2],     %[f2],       %[f0]          \n\t"
-      "mul.s      %[f0],     %[f1],       %[f1]          \n\t"
-#if defined(MIPS32_R2_LE)
-      "madd.s     %[f0],     %[f0],       %[f2],   %[f2] \n\t"
-#else
-      "mul.s      %[f3],     %[f2],       %[f2]          \n\t"
-      "add.s      %[f0],     %[f0],       %[f3]          \n\t"
-#endif
-      "c.le.s     %[f0],     %[err_th2]                  \n\t"
-      "nop                                               \n\t"
-      "bc1t       2f                                     \n\t"
-      " nop                                              \n\t"
-      "sqrt.s     %[f0],     %[f0]                       \n\t"
-      "add.s      %[f0],     %[f0],       %[fac1]        \n\t"
-      "div.s      %[f0],     %[err_th],   %[f0]          \n\t"
-      "mul.s      %[f1],     %[f1],       %[f0]          \n\t"
-      "mul.s      %[f2],     %[f2],       %[f0]          \n\t"
-      "2:                                                \n\t"
-      "mul.s      %[f1],     %[f1],       %[mu]          \n\t"
-      "mul.s      %[f2],     %[f2],       %[mu]          \n\t"
-      "swc1       %[f1],     0(%[ef0])                   \n\t"
-      "swc1       %[f2],     0(%[ef1])                   \n\t"
-      "addiu      %[len],    %[len],      -1             \n\t"
-      "addiu      %[x_pow],  %[x_pow],    4              \n\t"
-      "addiu      %[ef0],    %[ef0],      4              \n\t"
-      "bgtz       %[len],    1b                          \n\t"
-      " addiu     %[ef1],    %[ef1],      4              \n\t"
-      ".set       pop                                    \n\t"
-      : [f0] "=&f"(f0), [f1] "=&f"(f1), [f2] "=&f"(f2),
-#if !defined(MIPS32_R2_LE)
-        [f3] "=&f"(f3),
-#endif
-        [x_pow] "+r"(x_pow), [ef0] "+r"(ef0), [ef1] "+r"(ef1), [len] "+r"(len)
-      : [fac1] "f"(fac1), [err_th2] "f"(err_th2), [mu] "f"(mu),
-        [err_th] "f"(error_threshold)
-      : "memory");
-}
-
-void WebRtcAec_InitAec_mips(void) {
-  WebRtcAec_FilterFar = WebRtcAec_FilterFar_mips;
-  WebRtcAec_FilterAdaptation = WebRtcAec_FilterAdaptation_mips;
-  WebRtcAec_ScaleErrorSignal = WebRtcAec_ScaleErrorSignal_mips;
-  WebRtcAec_Overdrive = WebRtcAec_Overdrive_mips;
-  WebRtcAec_Suppress = WebRtcAec_Suppress_mips;
-}
-}  // namespace webrtc
diff --git a/modules/audio_processing/aec/aec_core_neon.cc b/modules/audio_processing/aec/aec_core_neon.cc
deleted file mode 100644
index 072bd17..0000000
--- a/modules/audio_processing/aec/aec_core_neon.cc
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-/*
- * The core AEC algorithm, neon version of speed-critical functions.
- *
- * Based on aec_core_sse2.c.
- */
-
-#include <arm_neon.h>
-#include <math.h>
-#include <string.h>  // memset
-
-extern "C" {
-#include "common_audio/signal_processing/include/signal_processing_library.h"
-}
-#include "modules/audio_processing/aec/aec_common.h"
-#include "modules/audio_processing/aec/aec_core_optimized_methods.h"
-#include "modules/audio_processing/utility/ooura_fft.h"
-
-namespace webrtc {
-
-enum { kShiftExponentIntoTopMantissa = 8 };
-enum { kFloatExponentShift = 23 };
-
-__inline static float MulRe(float aRe, float aIm, float bRe, float bIm) {
-  return aRe * bRe - aIm * bIm;
-}
-
-__inline static float MulIm(float aRe, float aIm, float bRe, float bIm) {
-  return aRe * bIm + aIm * bRe;
-}
-
-static void FilterFarNEON(
-    int num_partitions,
-    int x_fft_buf_block_pos,
-    float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float y_fft[2][PART_LEN1]) {
-  int i;
-  for (i = 0; i < num_partitions; i++) {
-    int j;
-    int xPos = (i + x_fft_buf_block_pos) * PART_LEN1;
-    int pos = i * PART_LEN1;
-    // Check for wrap
-    if (i + x_fft_buf_block_pos >= num_partitions) {
-      xPos -= num_partitions * PART_LEN1;
-    }
-
-    // vectorized code (four at once)
-    for (j = 0; j + 3 < PART_LEN1; j += 4) {
-      const float32x4_t x_fft_buf_re = vld1q_f32(&x_fft_buf[0][xPos + j]);
-      const float32x4_t x_fft_buf_im = vld1q_f32(&x_fft_buf[1][xPos + j]);
-      const float32x4_t h_fft_buf_re = vld1q_f32(&h_fft_buf[0][pos + j]);
-      const float32x4_t h_fft_buf_im = vld1q_f32(&h_fft_buf[1][pos + j]);
-      const float32x4_t y_fft_re = vld1q_f32(&y_fft[0][j]);
-      const float32x4_t y_fft_im = vld1q_f32(&y_fft[1][j]);
-      const float32x4_t a = vmulq_f32(x_fft_buf_re, h_fft_buf_re);
-      const float32x4_t e = vmlsq_f32(a, x_fft_buf_im, h_fft_buf_im);
-      const float32x4_t c = vmulq_f32(x_fft_buf_re, h_fft_buf_im);
-      const float32x4_t f = vmlaq_f32(c, x_fft_buf_im, h_fft_buf_re);
-      const float32x4_t g = vaddq_f32(y_fft_re, e);
-      const float32x4_t h = vaddq_f32(y_fft_im, f);
-      vst1q_f32(&y_fft[0][j], g);
-      vst1q_f32(&y_fft[1][j], h);
-    }
-    // scalar code for the remaining items.
-    for (; j < PART_LEN1; j++) {
-      y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j],
-                           h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]);
-      y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j],
-                           h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]);
-    }
-  }
-}
-
-// ARM64's arm_neon.h has already defined vdivq_f32 vsqrtq_f32.
-#if !defined(WEBRTC_ARCH_ARM64)
-static float32x4_t vdivq_f32(float32x4_t a, float32x4_t b) {
-  int i;
-  float32x4_t x = vrecpeq_f32(b);
-  // from arm documentation
-  // The Newton-Raphson iteration:
-  //     x[n+1] = x[n] * (2 - d * x[n])
-  // converges to (1/d) if x0 is the result of VRECPE applied to d.
-  //
-  // Note: The precision did not improve after 2 iterations.
-  for (i = 0; i < 2; i++) {
-    x = vmulq_f32(vrecpsq_f32(b, x), x);
-  }
-  // a/b = a*(1/b)
-  return vmulq_f32(a, x);
-}
-
-static float32x4_t vsqrtq_f32(float32x4_t s) {
-  int i;
-  float32x4_t x = vrsqrteq_f32(s);
-
-  // Code to handle sqrt(0).
-  // If the input to sqrtf() is zero, a zero will be returned.
-  // If the input to vrsqrteq_f32() is zero, positive infinity is returned.
-  const uint32x4_t vec_p_inf = vdupq_n_u32(0x7F800000);
-  // check for divide by zero
-  const uint32x4_t div_by_zero = vceqq_u32(vec_p_inf, vreinterpretq_u32_f32(x));
-  // zero out the positive infinity results
-  x = vreinterpretq_f32_u32(
-      vandq_u32(vmvnq_u32(div_by_zero), vreinterpretq_u32_f32(x)));
-  // from arm documentation
-  // The Newton-Raphson iteration:
-  //     x[n+1] = x[n] * (3 - d * (x[n] * x[n])) / 2)
-  // converges to (1/√d) if x0 is the result of VRSQRTE applied to d.
-  //
-  // Note: The precision did not improve after 2 iterations.
-  for (i = 0; i < 2; i++) {
-    x = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x, x), s), x);
-  }
-  // sqrt(s) = s * 1/sqrt(s)
-  return vmulq_f32(s, x);
-}
-#endif  // WEBRTC_ARCH_ARM64
-
-static void ScaleErrorSignalNEON(float mu,
-                                 float error_threshold,
-                                 float x_pow[PART_LEN1],
-                                 float ef[2][PART_LEN1]) {
-  const float32x4_t k1e_10f = vdupq_n_f32(1e-10f);
-  const float32x4_t kMu = vmovq_n_f32(mu);
-  const float32x4_t kThresh = vmovq_n_f32(error_threshold);
-  int i;
-  // vectorized code (four at once)
-  for (i = 0; i + 3 < PART_LEN1; i += 4) {
-    const float32x4_t x_pow_local = vld1q_f32(&x_pow[i]);
-    const float32x4_t ef_re_base = vld1q_f32(&ef[0][i]);
-    const float32x4_t ef_im_base = vld1q_f32(&ef[1][i]);
-    const float32x4_t xPowPlus = vaddq_f32(x_pow_local, k1e_10f);
-    float32x4_t ef_re = vdivq_f32(ef_re_base, xPowPlus);
-    float32x4_t ef_im = vdivq_f32(ef_im_base, xPowPlus);
-    const float32x4_t ef_re2 = vmulq_f32(ef_re, ef_re);
-    const float32x4_t ef_sum2 = vmlaq_f32(ef_re2, ef_im, ef_im);
-    const float32x4_t absEf = vsqrtq_f32(ef_sum2);
-    const uint32x4_t bigger = vcgtq_f32(absEf, kThresh);
-    const float32x4_t absEfPlus = vaddq_f32(absEf, k1e_10f);
-    const float32x4_t absEfInv = vdivq_f32(kThresh, absEfPlus);
-    uint32x4_t ef_re_if = vreinterpretq_u32_f32(vmulq_f32(ef_re, absEfInv));
-    uint32x4_t ef_im_if = vreinterpretq_u32_f32(vmulq_f32(ef_im, absEfInv));
-    uint32x4_t ef_re_u32 =
-        vandq_u32(vmvnq_u32(bigger), vreinterpretq_u32_f32(ef_re));
-    uint32x4_t ef_im_u32 =
-        vandq_u32(vmvnq_u32(bigger), vreinterpretq_u32_f32(ef_im));
-    ef_re_if = vandq_u32(bigger, ef_re_if);
-    ef_im_if = vandq_u32(bigger, ef_im_if);
-    ef_re_u32 = vorrq_u32(ef_re_u32, ef_re_if);
-    ef_im_u32 = vorrq_u32(ef_im_u32, ef_im_if);
-    ef_re = vmulq_f32(vreinterpretq_f32_u32(ef_re_u32), kMu);
-    ef_im = vmulq_f32(vreinterpretq_f32_u32(ef_im_u32), kMu);
-    vst1q_f32(&ef[0][i], ef_re);
-    vst1q_f32(&ef[1][i], ef_im);
-  }
-  // scalar code for the remaining items.
-  for (; i < PART_LEN1; i++) {
-    float abs_ef;
-    ef[0][i] /= (x_pow[i] + 1e-10f);
-    ef[1][i] /= (x_pow[i] + 1e-10f);
-    abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]);
-
-    if (abs_ef > error_threshold) {
-      abs_ef = error_threshold / (abs_ef + 1e-10f);
-      ef[0][i] *= abs_ef;
-      ef[1][i] *= abs_ef;
-    }
-
-    // Stepsize factor
-    ef[0][i] *= mu;
-    ef[1][i] *= mu;
-  }
-}
-
-static void FilterAdaptationNEON(
-    const OouraFft& ooura_fft,
-    int num_partitions,
-    int x_fft_buf_block_pos,
-    float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float e_fft[2][PART_LEN1],
-    float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) {
-  float fft[PART_LEN2];
-  int i;
-  for (i = 0; i < num_partitions; i++) {
-    int xPos = (i + x_fft_buf_block_pos) * PART_LEN1;
-    int pos = i * PART_LEN1;
-    int j;
-    // Check for wrap
-    if (i + x_fft_buf_block_pos >= num_partitions) {
-      xPos -= num_partitions * PART_LEN1;
-    }
-
-    // Process the whole array...
-    for (j = 0; j < PART_LEN; j += 4) {
-      // Load x_fft_buf and e_fft.
-      const float32x4_t x_fft_buf_re = vld1q_f32(&x_fft_buf[0][xPos + j]);
-      const float32x4_t x_fft_buf_im = vld1q_f32(&x_fft_buf[1][xPos + j]);
-      const float32x4_t e_fft_re = vld1q_f32(&e_fft[0][j]);
-      const float32x4_t e_fft_im = vld1q_f32(&e_fft[1][j]);
-      // Calculate the product of conjugate(x_fft_buf) by e_fft.
-      //   re(conjugate(a) * b) = aRe * bRe + aIm * bIm
-      //   im(conjugate(a) * b)=  aRe * bIm - aIm * bRe
-      const float32x4_t a = vmulq_f32(x_fft_buf_re, e_fft_re);
-      const float32x4_t e = vmlaq_f32(a, x_fft_buf_im, e_fft_im);
-      const float32x4_t c = vmulq_f32(x_fft_buf_re, e_fft_im);
-      const float32x4_t f = vmlsq_f32(c, x_fft_buf_im, e_fft_re);
-      // Interleave real and imaginary parts.
-      const float32x4x2_t g_n_h = vzipq_f32(e, f);
-      // Store
-      vst1q_f32(&fft[2 * j + 0], g_n_h.val[0]);
-      vst1q_f32(&fft[2 * j + 4], g_n_h.val[1]);
-    }
-    // ... and fixup the first imaginary entry.
-    fft[1] =
-        MulRe(x_fft_buf[0][xPos + PART_LEN], -x_fft_buf[1][xPos + PART_LEN],
-              e_fft[0][PART_LEN], e_fft[1][PART_LEN]);
-
-    ooura_fft.InverseFft(fft);
-    memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN);
-
-    // fft scaling
-    {
-      const float scale = 2.0f / PART_LEN2;
-      const float32x4_t scale_ps = vmovq_n_f32(scale);
-      for (j = 0; j < PART_LEN; j += 4) {
-        const float32x4_t fft_ps = vld1q_f32(&fft[j]);
-        const float32x4_t fft_scale = vmulq_f32(fft_ps, scale_ps);
-        vst1q_f32(&fft[j], fft_scale);
-      }
-    }
-    ooura_fft.Fft(fft);
-
-    {
-      const float wt1 = h_fft_buf[1][pos];
-      h_fft_buf[0][pos + PART_LEN] += fft[1];
-      for (j = 0; j < PART_LEN; j += 4) {
-        float32x4_t wtBuf_re = vld1q_f32(&h_fft_buf[0][pos + j]);
-        float32x4_t wtBuf_im = vld1q_f32(&h_fft_buf[1][pos + j]);
-        const float32x4_t fft0 = vld1q_f32(&fft[2 * j + 0]);
-        const float32x4_t fft4 = vld1q_f32(&fft[2 * j + 4]);
-        const float32x4x2_t fft_re_im = vuzpq_f32(fft0, fft4);
-        wtBuf_re = vaddq_f32(wtBuf_re, fft_re_im.val[0]);
-        wtBuf_im = vaddq_f32(wtBuf_im, fft_re_im.val[1]);
-
-        vst1q_f32(&h_fft_buf[0][pos + j], wtBuf_re);
-        vst1q_f32(&h_fft_buf[1][pos + j], wtBuf_im);
-      }
-      h_fft_buf[1][pos] = wt1;
-    }
-  }
-}
-
-static float32x4_t vpowq_f32(float32x4_t a, float32x4_t b) {
-  // a^b = exp2(b * log2(a))
-  //   exp2(x) and log2(x) are calculated using polynomial approximations.
-  float32x4_t log2_a, b_log2_a, a_exp_b;
-
-  // Calculate log2(x), x = a.
-  {
-    // To calculate log2(x), we decompose x like this:
-    //   x = y * 2^n
-    //     n is an integer
-    //     y is in the [1.0, 2.0) range
-    //
-    //   log2(x) = log2(y) + n
-    //     n       can be evaluated by playing with float representation.
-    //     log2(y) in a small range can be approximated, this code uses an order
-    //             five polynomial approximation. The coefficients have been
-    //             estimated with the Remez algorithm and the resulting
-    //             polynomial has a maximum relative error of 0.00086%.
-
-    // Compute n.
-    //    This is done by masking the exponent, shifting it into the top bit of
-    //    the mantissa, putting eight into the biased exponent (to shift/
-    //    compensate the fact that the exponent has been shifted in the top/
-    //    fractional part and finally getting rid of the implicit leading one
-    //    from the mantissa by substracting it out.
-    const uint32x4_t vec_float_exponent_mask = vdupq_n_u32(0x7F800000);
-    const uint32x4_t vec_eight_biased_exponent = vdupq_n_u32(0x43800000);
-    const uint32x4_t vec_implicit_leading_one = vdupq_n_u32(0x43BF8000);
-    const uint32x4_t two_n =
-        vandq_u32(vreinterpretq_u32_f32(a), vec_float_exponent_mask);
-    const uint32x4_t n_1 = vshrq_n_u32(two_n, kShiftExponentIntoTopMantissa);
-    const uint32x4_t n_0 = vorrq_u32(n_1, vec_eight_biased_exponent);
-    const float32x4_t n =
-        vsubq_f32(vreinterpretq_f32_u32(n_0),
-                  vreinterpretq_f32_u32(vec_implicit_leading_one));
-    // Compute y.
-    const uint32x4_t vec_mantissa_mask = vdupq_n_u32(0x007FFFFF);
-    const uint32x4_t vec_zero_biased_exponent_is_one = vdupq_n_u32(0x3F800000);
-    const uint32x4_t mantissa =
-        vandq_u32(vreinterpretq_u32_f32(a), vec_mantissa_mask);
-    const float32x4_t y = vreinterpretq_f32_u32(
-        vorrq_u32(mantissa, vec_zero_biased_exponent_is_one));
-    // Approximate log2(y) ~= (y - 1) * pol5(y).
-    //    pol5(y) = C5 * y^5 + C4 * y^4 + C3 * y^3 + C2 * y^2 + C1 * y + C0
-    const float32x4_t C5 = vdupq_n_f32(-3.4436006e-2f);
-    const float32x4_t C4 = vdupq_n_f32(3.1821337e-1f);
-    const float32x4_t C3 = vdupq_n_f32(-1.2315303f);
-    const float32x4_t C2 = vdupq_n_f32(2.5988452f);
-    const float32x4_t C1 = vdupq_n_f32(-3.3241990f);
-    const float32x4_t C0 = vdupq_n_f32(3.1157899f);
-    float32x4_t pol5_y = C5;
-    pol5_y = vmlaq_f32(C4, y, pol5_y);
-    pol5_y = vmlaq_f32(C3, y, pol5_y);
-    pol5_y = vmlaq_f32(C2, y, pol5_y);
-    pol5_y = vmlaq_f32(C1, y, pol5_y);
-    pol5_y = vmlaq_f32(C0, y, pol5_y);
-    const float32x4_t y_minus_one =
-        vsubq_f32(y, vreinterpretq_f32_u32(vec_zero_biased_exponent_is_one));
-    const float32x4_t log2_y = vmulq_f32(y_minus_one, pol5_y);
-
-    // Combine parts.
-    log2_a = vaddq_f32(n, log2_y);
-  }
-
-  // b * log2(a)
-  b_log2_a = vmulq_f32(b, log2_a);
-
-  // Calculate exp2(x), x = b * log2(a).
-  {
-    // To calculate 2^x, we decompose x like this:
-    //   x = n + y
-    //     n is an integer, the value of x - 0.5 rounded down, therefore
-    //     y is in the [0.5, 1.5) range
-    //
-    //   2^x = 2^n * 2^y
-    //     2^n can be evaluated by playing with float representation.
-    //     2^y in a small range can be approximated, this code uses an order two
-    //         polynomial approximation. The coefficients have been estimated
-    //         with the Remez algorithm and the resulting polynomial has a
-    //         maximum relative error of 0.17%.
-    // To avoid over/underflow, we reduce the range of input to ]-127, 129].
-    const float32x4_t max_input = vdupq_n_f32(129.f);
-    const float32x4_t min_input = vdupq_n_f32(-126.99999f);
-    const float32x4_t x_min = vminq_f32(b_log2_a, max_input);
-    const float32x4_t x_max = vmaxq_f32(x_min, min_input);
-    // Compute n.
-    const float32x4_t half = vdupq_n_f32(0.5f);
-    const float32x4_t x_minus_half = vsubq_f32(x_max, half);
-    const int32x4_t x_minus_half_floor = vcvtq_s32_f32(x_minus_half);
-
-    // Compute 2^n.
-    const int32x4_t float_exponent_bias = vdupq_n_s32(127);
-    const int32x4_t two_n_exponent =
-        vaddq_s32(x_minus_half_floor, float_exponent_bias);
-    const float32x4_t two_n =
-        vreinterpretq_f32_s32(vshlq_n_s32(two_n_exponent, kFloatExponentShift));
-    // Compute y.
-    const float32x4_t y = vsubq_f32(x_max, vcvtq_f32_s32(x_minus_half_floor));
-
-    // Approximate 2^y ~= C2 * y^2 + C1 * y + C0.
-    const float32x4_t C2 = vdupq_n_f32(3.3718944e-1f);
-    const float32x4_t C1 = vdupq_n_f32(6.5763628e-1f);
-    const float32x4_t C0 = vdupq_n_f32(1.0017247f);
-    float32x4_t exp2_y = C2;
-    exp2_y = vmlaq_f32(C1, y, exp2_y);
-    exp2_y = vmlaq_f32(C0, y, exp2_y);
-
-    // Combine parts.
-    a_exp_b = vmulq_f32(exp2_y, two_n);
-  }
-
-  return a_exp_b;
-}
-
-static void OverdriveNEON(float overdrive_scaling,
-                          float hNlFb,
-                          float hNl[PART_LEN1]) {
-  int i;
-  const float32x4_t vec_hNlFb = vmovq_n_f32(hNlFb);
-  const float32x4_t vec_one = vdupq_n_f32(1.0f);
-  const float32x4_t vec_overdrive_scaling = vmovq_n_f32(overdrive_scaling);
-
-  // vectorized code (four at once)
-  for (i = 0; i + 3 < PART_LEN1; i += 4) {
-    // Weight subbands
-    float32x4_t vec_hNl = vld1q_f32(&hNl[i]);
-    const float32x4_t vec_weightCurve = vld1q_f32(&WebRtcAec_weightCurve[i]);
-    const uint32x4_t bigger = vcgtq_f32(vec_hNl, vec_hNlFb);
-    const float32x4_t vec_weightCurve_hNlFb =
-        vmulq_f32(vec_weightCurve, vec_hNlFb);
-    const float32x4_t vec_one_weightCurve = vsubq_f32(vec_one, vec_weightCurve);
-    const float32x4_t vec_one_weightCurve_hNl =
-        vmulq_f32(vec_one_weightCurve, vec_hNl);
-    const uint32x4_t vec_if0 =
-        vandq_u32(vmvnq_u32(bigger), vreinterpretq_u32_f32(vec_hNl));
-    const float32x4_t vec_one_weightCurve_add =
-        vaddq_f32(vec_weightCurve_hNlFb, vec_one_weightCurve_hNl);
-    const uint32x4_t vec_if1 =
-        vandq_u32(bigger, vreinterpretq_u32_f32(vec_one_weightCurve_add));
-
-    vec_hNl = vreinterpretq_f32_u32(vorrq_u32(vec_if0, vec_if1));
-
-    const float32x4_t vec_overDriveCurve =
-        vld1q_f32(&WebRtcAec_overDriveCurve[i]);
-    const float32x4_t vec_overDriveSm_overDriveCurve =
-        vmulq_f32(vec_overdrive_scaling, vec_overDriveCurve);
-    vec_hNl = vpowq_f32(vec_hNl, vec_overDriveSm_overDriveCurve);
-    vst1q_f32(&hNl[i], vec_hNl);
-  }
-
-  // scalar code for the remaining items.
-  for (; i < PART_LEN1; i++) {
-    // Weight subbands
-    if (hNl[i] > hNlFb) {
-      hNl[i] = WebRtcAec_weightCurve[i] * hNlFb +
-               (1 - WebRtcAec_weightCurve[i]) * hNl[i];
-    }
-
-    hNl[i] = powf(hNl[i], overdrive_scaling * WebRtcAec_overDriveCurve[i]);
-  }
-}
-
-static void SuppressNEON(const float hNl[PART_LEN1], float efw[2][PART_LEN1]) {
-  int i;
-  const float32x4_t vec_minus_one = vdupq_n_f32(-1.0f);
-  // vectorized code (four at once)
-  for (i = 0; i + 3 < PART_LEN1; i += 4) {
-    float32x4_t vec_hNl = vld1q_f32(&hNl[i]);
-    float32x4_t vec_efw_re = vld1q_f32(&efw[0][i]);
-    float32x4_t vec_efw_im = vld1q_f32(&efw[1][i]);
-    vec_efw_re = vmulq_f32(vec_efw_re, vec_hNl);
-    vec_efw_im = vmulq_f32(vec_efw_im, vec_hNl);
-
-    // Ooura fft returns incorrect sign on imaginary component. It matters
-    // here because we are making an additive change with comfort noise.
-    vec_efw_im = vmulq_f32(vec_efw_im, vec_minus_one);
-    vst1q_f32(&efw[0][i], vec_efw_re);
-    vst1q_f32(&efw[1][i], vec_efw_im);
-  }
-
-  // scalar code for the remaining items.
-  for (; i < PART_LEN1; i++) {
-    efw[0][i] *= hNl[i];
-    efw[1][i] *= hNl[i];
-
-    // Ooura fft returns incorrect sign on imaginary component. It matters
-    // here because we are making an additive change with comfort noise.
-    efw[1][i] *= -1;
-  }
-}
-
-static int PartitionDelayNEON(
-    int num_partitions,
-    float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) {
-  // Measures the energy in each filter partition and returns the partition with
-  // highest energy.
-  // TODO(bjornv): Spread computational cost by computing one partition per
-  // block?
-  float wfEnMax = 0;
-  int i;
-  int delay = 0;
-
-  for (i = 0; i < num_partitions; i++) {
-    int j;
-    int pos = i * PART_LEN1;
-    float wfEn = 0;
-    float32x4_t vec_wfEn = vdupq_n_f32(0.0f);
-    // vectorized code (four at once)
-    for (j = 0; j + 3 < PART_LEN1; j += 4) {
-      const float32x4_t vec_wfBuf0 = vld1q_f32(&h_fft_buf[0][pos + j]);
-      const float32x4_t vec_wfBuf1 = vld1q_f32(&h_fft_buf[1][pos + j]);
-      vec_wfEn = vmlaq_f32(vec_wfEn, vec_wfBuf0, vec_wfBuf0);
-      vec_wfEn = vmlaq_f32(vec_wfEn, vec_wfBuf1, vec_wfBuf1);
-    }
-    {
-      float32x2_t vec_total;
-      // A B C D
-      vec_total = vpadd_f32(vget_low_f32(vec_wfEn), vget_high_f32(vec_wfEn));
-      // A+B C+D
-      vec_total = vpadd_f32(vec_total, vec_total);
-      // A+B+C+D A+B+C+D
-      wfEn = vget_lane_f32(vec_total, 0);
-    }
-
-    // scalar code for the remaining items.
-    for (; j < PART_LEN1; j++) {
-      wfEn += h_fft_buf[0][pos + j] * h_fft_buf[0][pos + j] +
-              h_fft_buf[1][pos + j] * h_fft_buf[1][pos + j];
-    }
-
-    if (wfEn > wfEnMax) {
-      wfEnMax = wfEn;
-      delay = i;
-    }
-  }
-  return delay;
-}
-
-// Updates the following smoothed  Power Spectral Densities (PSD):
-//  - sd  : near-end
-//  - se  : residual echo
-//  - sx  : far-end
-//  - sde : cross-PSD of near-end and residual echo
-//  - sxd : cross-PSD of near-end and far-end
-//
-// In addition to updating the PSDs, also the filter diverge state is determined
-// upon actions are taken.
-static void UpdateCoherenceSpectraNEON(int mult,
-                                       bool extended_filter_enabled,
-                                       float efw[2][PART_LEN1],
-                                       float dfw[2][PART_LEN1],
-                                       float xfw[2][PART_LEN1],
-                                       CoherenceState* coherence_state,
-                                       short* filter_divergence_state,
-                                       int* extreme_filter_divergence) {
-  // Power estimate smoothing coefficients.
-  const float* ptrGCoh =
-      extended_filter_enabled
-          ? WebRtcAec_kExtendedSmoothingCoefficients[mult - 1]
-          : WebRtcAec_kNormalSmoothingCoefficients[mult - 1];
-  int i;
-  float sdSum = 0, seSum = 0;
-  const float32x4_t vec_15 = vdupq_n_f32(WebRtcAec_kMinFarendPSD);
-  float32x4_t vec_sdSum = vdupq_n_f32(0.0f);
-  float32x4_t vec_seSum = vdupq_n_f32(0.0f);
-
-  for (i = 0; i + 3 < PART_LEN1; i += 4) {
-    const float32x4_t vec_dfw0 = vld1q_f32(&dfw[0][i]);
-    const float32x4_t vec_dfw1 = vld1q_f32(&dfw[1][i]);
-    const float32x4_t vec_efw0 = vld1q_f32(&efw[0][i]);
-    const float32x4_t vec_efw1 = vld1q_f32(&efw[1][i]);
-    const float32x4_t vec_xfw0 = vld1q_f32(&xfw[0][i]);
-    const float32x4_t vec_xfw1 = vld1q_f32(&xfw[1][i]);
-    float32x4_t vec_sd =
-        vmulq_n_f32(vld1q_f32(&coherence_state->sd[i]), ptrGCoh[0]);
-    float32x4_t vec_se =
-        vmulq_n_f32(vld1q_f32(&coherence_state->se[i]), ptrGCoh[0]);
-    float32x4_t vec_sx =
-        vmulq_n_f32(vld1q_f32(&coherence_state->sx[i]), ptrGCoh[0]);
-    float32x4_t vec_dfw_sumsq = vmulq_f32(vec_dfw0, vec_dfw0);
-    float32x4_t vec_efw_sumsq = vmulq_f32(vec_efw0, vec_efw0);
-    float32x4_t vec_xfw_sumsq = vmulq_f32(vec_xfw0, vec_xfw0);
-
-    vec_dfw_sumsq = vmlaq_f32(vec_dfw_sumsq, vec_dfw1, vec_dfw1);
-    vec_efw_sumsq = vmlaq_f32(vec_efw_sumsq, vec_efw1, vec_efw1);
-    vec_xfw_sumsq = vmlaq_f32(vec_xfw_sumsq, vec_xfw1, vec_xfw1);
-    vec_xfw_sumsq = vmaxq_f32(vec_xfw_sumsq, vec_15);
-    vec_sd = vmlaq_n_f32(vec_sd, vec_dfw_sumsq, ptrGCoh[1]);
-    vec_se = vmlaq_n_f32(vec_se, vec_efw_sumsq, ptrGCoh[1]);
-    vec_sx = vmlaq_n_f32(vec_sx, vec_xfw_sumsq, ptrGCoh[1]);
-
-    vst1q_f32(&coherence_state->sd[i], vec_sd);
-    vst1q_f32(&coherence_state->se[i], vec_se);
-    vst1q_f32(&coherence_state->sx[i], vec_sx);
-
-    {
-      float32x4x2_t vec_sde = vld2q_f32(&coherence_state->sde[i][0]);
-      float32x4_t vec_dfwefw0011 = vmulq_f32(vec_dfw0, vec_efw0);
-      float32x4_t vec_dfwefw0110 = vmulq_f32(vec_dfw0, vec_efw1);
-      vec_sde.val[0] = vmulq_n_f32(vec_sde.val[0], ptrGCoh[0]);
-      vec_sde.val[1] = vmulq_n_f32(vec_sde.val[1], ptrGCoh[0]);
-      vec_dfwefw0011 = vmlaq_f32(vec_dfwefw0011, vec_dfw1, vec_efw1);
-      vec_dfwefw0110 = vmlsq_f32(vec_dfwefw0110, vec_dfw1, vec_efw0);
-      vec_sde.val[0] = vmlaq_n_f32(vec_sde.val[0], vec_dfwefw0011, ptrGCoh[1]);
-      vec_sde.val[1] = vmlaq_n_f32(vec_sde.val[1], vec_dfwefw0110, ptrGCoh[1]);
-      vst2q_f32(&coherence_state->sde[i][0], vec_sde);
-    }
-
-    {
-      float32x4x2_t vec_sxd = vld2q_f32(&coherence_state->sxd[i][0]);
-      float32x4_t vec_dfwxfw0011 = vmulq_f32(vec_dfw0, vec_xfw0);
-      float32x4_t vec_dfwxfw0110 = vmulq_f32(vec_dfw0, vec_xfw1);
-      vec_sxd.val[0] = vmulq_n_f32(vec_sxd.val[0], ptrGCoh[0]);
-      vec_sxd.val[1] = vmulq_n_f32(vec_sxd.val[1], ptrGCoh[0]);
-      vec_dfwxfw0011 = vmlaq_f32(vec_dfwxfw0011, vec_dfw1, vec_xfw1);
-      vec_dfwxfw0110 = vmlsq_f32(vec_dfwxfw0110, vec_dfw1, vec_xfw0);
-      vec_sxd.val[0] = vmlaq_n_f32(vec_sxd.val[0], vec_dfwxfw0011, ptrGCoh[1]);
-      vec_sxd.val[1] = vmlaq_n_f32(vec_sxd.val[1], vec_dfwxfw0110, ptrGCoh[1]);
-      vst2q_f32(&coherence_state->sxd[i][0], vec_sxd);
-    }
-
-    vec_sdSum = vaddq_f32(vec_sdSum, vec_sd);
-    vec_seSum = vaddq_f32(vec_seSum, vec_se);
-  }
-  {
-    float32x2_t vec_sdSum_total;
-    float32x2_t vec_seSum_total;
-    // A B C D
-    vec_sdSum_total =
-        vpadd_f32(vget_low_f32(vec_sdSum), vget_high_f32(vec_sdSum));
-    vec_seSum_total =
-        vpadd_f32(vget_low_f32(vec_seSum), vget_high_f32(vec_seSum));
-    // A+B C+D
-    vec_sdSum_total = vpadd_f32(vec_sdSum_total, vec_sdSum_total);
-    vec_seSum_total = vpadd_f32(vec_seSum_total, vec_seSum_total);
-    // A+B+C+D A+B+C+D
-    sdSum = vget_lane_f32(vec_sdSum_total, 0);
-    seSum = vget_lane_f32(vec_seSum_total, 0);
-  }
-
-  // scalar code for the remaining items.
-  for (; i < PART_LEN1; i++) {
-    coherence_state->sd[i] =
-        ptrGCoh[0] * coherence_state->sd[i] +
-        ptrGCoh[1] * (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]);
-    coherence_state->se[i] =
-        ptrGCoh[0] * coherence_state->se[i] +
-        ptrGCoh[1] * (efw[0][i] * efw[0][i] + efw[1][i] * efw[1][i]);
-    // We threshold here to protect against the ill-effects of a zero farend.
-    // The threshold is not arbitrarily chosen, but balances protection and
-    // adverse interaction with the algorithm's tuning.
-    // TODO(bjornv): investigate further why this is so sensitive.
-    coherence_state->sx[i] =
-        ptrGCoh[0] * coherence_state->sx[i] +
-        ptrGCoh[1] *
-            WEBRTC_SPL_MAX(xfw[0][i] * xfw[0][i] + xfw[1][i] * xfw[1][i],
-                           WebRtcAec_kMinFarendPSD);
-
-    coherence_state->sde[i][0] =
-        ptrGCoh[0] * coherence_state->sde[i][0] +
-        ptrGCoh[1] * (dfw[0][i] * efw[0][i] + dfw[1][i] * efw[1][i]);
-    coherence_state->sde[i][1] =
-        ptrGCoh[0] * coherence_state->sde[i][1] +
-        ptrGCoh[1] * (dfw[0][i] * efw[1][i] - dfw[1][i] * efw[0][i]);
-
-    coherence_state->sxd[i][0] =
-        ptrGCoh[0] * coherence_state->sxd[i][0] +
-        ptrGCoh[1] * (dfw[0][i] * xfw[0][i] + dfw[1][i] * xfw[1][i]);
-    coherence_state->sxd[i][1] =
-        ptrGCoh[0] * coherence_state->sxd[i][1] +
-        ptrGCoh[1] * (dfw[0][i] * xfw[1][i] - dfw[1][i] * xfw[0][i]);
-
-    sdSum += coherence_state->sd[i];
-    seSum += coherence_state->se[i];
-  }
-
-  // Divergent filter safeguard update.
-  *filter_divergence_state =
-      (*filter_divergence_state ? 1.05f : 1.0f) * seSum > sdSum;
-
-  // Signal extreme filter divergence if the error is significantly larger
-  // than the nearend (13 dB).
-  *extreme_filter_divergence = (seSum > (19.95f * sdSum));
-}
-
-// Window time domain data to be used by the fft.
-static void WindowDataNEON(float* x_windowed, const float* x) {
-  int i;
-  for (i = 0; i < PART_LEN; i += 4) {
-    const float32x4_t vec_Buf1 = vld1q_f32(&x[i]);
-    const float32x4_t vec_Buf2 = vld1q_f32(&x[PART_LEN + i]);
-    const float32x4_t vec_sqrtHanning = vld1q_f32(&WebRtcAec_sqrtHanning[i]);
-    // A B C D
-    float32x4_t vec_sqrtHanning_rev =
-        vld1q_f32(&WebRtcAec_sqrtHanning[PART_LEN - i - 3]);
-    // B A D C
-    vec_sqrtHanning_rev = vrev64q_f32(vec_sqrtHanning_rev);
-    // D C B A
-    vec_sqrtHanning_rev = vcombine_f32(vget_high_f32(vec_sqrtHanning_rev),
-                                       vget_low_f32(vec_sqrtHanning_rev));
-    vst1q_f32(&x_windowed[i], vmulq_f32(vec_Buf1, vec_sqrtHanning));
-    vst1q_f32(&x_windowed[PART_LEN + i],
-              vmulq_f32(vec_Buf2, vec_sqrtHanning_rev));
-  }
-}
-
-// Puts fft output data into a complex valued array.
-static void StoreAsComplexNEON(const float* data,
-                               float data_complex[2][PART_LEN1]) {
-  int i;
-  for (i = 0; i < PART_LEN; i += 4) {
-    const float32x4x2_t vec_data = vld2q_f32(&data[2 * i]);
-    vst1q_f32(&data_complex[0][i], vec_data.val[0]);
-    vst1q_f32(&data_complex[1][i], vec_data.val[1]);
-  }
-  // fix beginning/end values
-  data_complex[1][0] = 0;
-  data_complex[1][PART_LEN] = 0;
-  data_complex[0][0] = data[0];
-  data_complex[0][PART_LEN] = data[1];
-}
-
-static void ComputeCoherenceNEON(const CoherenceState* coherence_state,
-                                 float* cohde,
-                                 float* cohxd) {
-  int i;
-
-  {
-    const float32x4_t vec_1eminus10 = vdupq_n_f32(1e-10f);
-
-    // Subband coherence
-    for (i = 0; i + 3 < PART_LEN1; i += 4) {
-      const float32x4_t vec_sd = vld1q_f32(&coherence_state->sd[i]);
-      const float32x4_t vec_se = vld1q_f32(&coherence_state->se[i]);
-      const float32x4_t vec_sx = vld1q_f32(&coherence_state->sx[i]);
-      const float32x4_t vec_sdse = vmlaq_f32(vec_1eminus10, vec_sd, vec_se);
-      const float32x4_t vec_sdsx = vmlaq_f32(vec_1eminus10, vec_sd, vec_sx);
-      float32x4x2_t vec_sde = vld2q_f32(&coherence_state->sde[i][0]);
-      float32x4x2_t vec_sxd = vld2q_f32(&coherence_state->sxd[i][0]);
-      float32x4_t vec_cohde = vmulq_f32(vec_sde.val[0], vec_sde.val[0]);
-      float32x4_t vec_cohxd = vmulq_f32(vec_sxd.val[0], vec_sxd.val[0]);
-      vec_cohde = vmlaq_f32(vec_cohde, vec_sde.val[1], vec_sde.val[1]);
-      vec_cohde = vdivq_f32(vec_cohde, vec_sdse);
-      vec_cohxd = vmlaq_f32(vec_cohxd, vec_sxd.val[1], vec_sxd.val[1]);
-      vec_cohxd = vdivq_f32(vec_cohxd, vec_sdsx);
-
-      vst1q_f32(&cohde[i], vec_cohde);
-      vst1q_f32(&cohxd[i], vec_cohxd);
-    }
-  }
-  // scalar code for the remaining items.
-  for (; i < PART_LEN1; i++) {
-    cohde[i] = (coherence_state->sde[i][0] * coherence_state->sde[i][0] +
-                coherence_state->sde[i][1] * coherence_state->sde[i][1]) /
-               (coherence_state->sd[i] * coherence_state->se[i] + 1e-10f);
-    cohxd[i] = (coherence_state->sxd[i][0] * coherence_state->sxd[i][0] +
-                coherence_state->sxd[i][1] * coherence_state->sxd[i][1]) /
-               (coherence_state->sx[i] * coherence_state->sd[i] + 1e-10f);
-  }
-}
-
-void WebRtcAec_InitAec_neon(void) {
-  WebRtcAec_FilterFar = FilterFarNEON;
-  WebRtcAec_ScaleErrorSignal = ScaleErrorSignalNEON;
-  WebRtcAec_FilterAdaptation = FilterAdaptationNEON;
-  WebRtcAec_Overdrive = OverdriveNEON;
-  WebRtcAec_Suppress = SuppressNEON;
-  WebRtcAec_ComputeCoherence = ComputeCoherenceNEON;
-  WebRtcAec_UpdateCoherenceSpectra = UpdateCoherenceSpectraNEON;
-  WebRtcAec_StoreAsComplex = StoreAsComplexNEON;
-  WebRtcAec_PartitionDelay = PartitionDelayNEON;
-  WebRtcAec_WindowData = WindowDataNEON;
-}
-}  // namespace webrtc
diff --git a/modules/audio_processing/aec/aec_core_optimized_methods.h b/modules/audio_processing/aec/aec_core_optimized_methods.h
deleted file mode 100644
index 03c027d..0000000
--- a/modules/audio_processing/aec/aec_core_optimized_methods.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_OPTIMIZED_METHODS_H_
-#define MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_OPTIMIZED_METHODS_H_
-
-#include <memory>
-
-#include "modules/audio_processing/aec/aec_core.h"
-
-namespace webrtc {
-
-typedef void (*WebRtcAecFilterFar)(
-    int num_partitions,
-    int x_fft_buf_block_pos,
-    float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float y_fft[2][PART_LEN1]);
-extern WebRtcAecFilterFar WebRtcAec_FilterFar;
-typedef void (*WebRtcAecScaleErrorSignal)(float mu,
-                                          float error_threshold,
-                                          float x_pow[PART_LEN1],
-                                          float ef[2][PART_LEN1]);
-extern WebRtcAecScaleErrorSignal WebRtcAec_ScaleErrorSignal;
-typedef void (*WebRtcAecFilterAdaptation)(
-    const OouraFft& ooura_fft,
-    int num_partitions,
-    int x_fft_buf_block_pos,
-    float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float e_fft[2][PART_LEN1],
-    float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]);
-extern WebRtcAecFilterAdaptation WebRtcAec_FilterAdaptation;
-
-typedef void (*WebRtcAecOverdrive)(float overdrive_scaling,
-                                   const float hNlFb,
-                                   float hNl[PART_LEN1]);
-extern WebRtcAecOverdrive WebRtcAec_Overdrive;
-
-typedef void (*WebRtcAecSuppress)(const float hNl[PART_LEN1],
-                                  float efw[2][PART_LEN1]);
-extern WebRtcAecSuppress WebRtcAec_Suppress;
-
-typedef void (*WebRtcAecComputeCoherence)(const CoherenceState* coherence_state,
-                                          float* cohde,
-                                          float* cohxd);
-extern WebRtcAecComputeCoherence WebRtcAec_ComputeCoherence;
-
-typedef void (*WebRtcAecUpdateCoherenceSpectra)(int mult,
-                                                bool extended_filter_enabled,
-                                                float efw[2][PART_LEN1],
-                                                float dfw[2][PART_LEN1],
-                                                float xfw[2][PART_LEN1],
-                                                CoherenceState* coherence_state,
-                                                short* filter_divergence_state,
-                                                int* extreme_filter_divergence);
-extern WebRtcAecUpdateCoherenceSpectra WebRtcAec_UpdateCoherenceSpectra;
-
-typedef int (*WebRtcAecPartitionDelay)(
-    int num_partitions,
-    float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]);
-extern WebRtcAecPartitionDelay WebRtcAec_PartitionDelay;
-
-typedef void (*WebRtcAecStoreAsComplex)(const float* data,
-                                        float data_complex[2][PART_LEN1]);
-extern WebRtcAecStoreAsComplex WebRtcAec_StoreAsComplex;
-
-typedef void (*WebRtcAecWindowData)(float* x_windowed, const float* x);
-extern WebRtcAecWindowData WebRtcAec_WindowData;
-
-}  // namespace webrtc
-
-#endif  // MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_OPTIMIZED_METHODS_H_
diff --git a/modules/audio_processing/aec/aec_core_sse2.cc b/modules/audio_processing/aec/aec_core_sse2.cc
deleted file mode 100644
index ede04dd..0000000
--- a/modules/audio_processing/aec/aec_core_sse2.cc
+++ /dev/null
@@ -1,749 +0,0 @@
-/*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-/*
- * The core AEC algorithm, SSE2 version of speed-critical functions.
- */
-
-#include <emmintrin.h>
-#include <math.h>
-#include <string.h>  // memset
-
-extern "C" {
-#include "common_audio/signal_processing/include/signal_processing_library.h"
-}
-#include "modules/audio_processing/aec/aec_common.h"
-#include "modules/audio_processing/aec/aec_core_optimized_methods.h"
-#include "modules/audio_processing/utility/ooura_fft.h"
-
-namespace webrtc {
-
-__inline static float MulRe(float aRe, float aIm, float bRe, float bIm) {
-  return aRe * bRe - aIm * bIm;
-}
-
-__inline static float MulIm(float aRe, float aIm, float bRe, float bIm) {
-  return aRe * bIm + aIm * bRe;
-}
-
-static void FilterFarSSE2(
-    int num_partitions,
-    int x_fft_buf_block_pos,
-    float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float y_fft[2][PART_LEN1]) {
-  int i;
-  for (i = 0; i < num_partitions; i++) {
-    int j;
-    int xPos = (i + x_fft_buf_block_pos) * PART_LEN1;
-    int pos = i * PART_LEN1;
-    // Check for wrap
-    if (i + x_fft_buf_block_pos >= num_partitions) {
-      xPos -= num_partitions * (PART_LEN1);
-    }
-
-    // vectorized code (four at once)
-    for (j = 0; j + 3 < PART_LEN1; j += 4) {
-      const __m128 x_fft_buf_re = _mm_loadu_ps(&x_fft_buf[0][xPos + j]);
-      const __m128 x_fft_buf_im = _mm_loadu_ps(&x_fft_buf[1][xPos + j]);
-      const __m128 h_fft_buf_re = _mm_loadu_ps(&h_fft_buf[0][pos + j]);
-      const __m128 h_fft_buf_im = _mm_loadu_ps(&h_fft_buf[1][pos + j]);
-      const __m128 y_fft_re = _mm_loadu_ps(&y_fft[0][j]);
-      const __m128 y_fft_im = _mm_loadu_ps(&y_fft[1][j]);
-      const __m128 a = _mm_mul_ps(x_fft_buf_re, h_fft_buf_re);
-      const __m128 b = _mm_mul_ps(x_fft_buf_im, h_fft_buf_im);
-      const __m128 c = _mm_mul_ps(x_fft_buf_re, h_fft_buf_im);
-      const __m128 d = _mm_mul_ps(x_fft_buf_im, h_fft_buf_re);
-      const __m128 e = _mm_sub_ps(a, b);
-      const __m128 f = _mm_add_ps(c, d);
-      const __m128 g = _mm_add_ps(y_fft_re, e);
-      const __m128 h = _mm_add_ps(y_fft_im, f);
-      _mm_storeu_ps(&y_fft[0][j], g);
-      _mm_storeu_ps(&y_fft[1][j], h);
-    }
-    // scalar code for the remaining items.
-    for (; j < PART_LEN1; j++) {
-      y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j],
-                           h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]);
-      y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j],
-                           h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]);
-    }
-  }
-}
-
-static void ScaleErrorSignalSSE2(float mu,
-                                 float error_threshold,
-                                 float x_pow[PART_LEN1],
-                                 float ef[2][PART_LEN1]) {
-  const __m128 k1e_10f = _mm_set1_ps(1e-10f);
-  const __m128 kMu = _mm_set1_ps(mu);
-  const __m128 kThresh = _mm_set1_ps(error_threshold);
-
-  int i;
-  // vectorized code (four at once)
-  for (i = 0; i + 3 < PART_LEN1; i += 4) {
-    const __m128 x_pow_local = _mm_loadu_ps(&x_pow[i]);
-    const __m128 ef_re_base = _mm_loadu_ps(&ef[0][i]);
-    const __m128 ef_im_base = _mm_loadu_ps(&ef[1][i]);
-
-    const __m128 xPowPlus = _mm_add_ps(x_pow_local, k1e_10f);
-    __m128 ef_re = _mm_div_ps(ef_re_base, xPowPlus);
-    __m128 ef_im = _mm_div_ps(ef_im_base, xPowPlus);
-    const __m128 ef_re2 = _mm_mul_ps(ef_re, ef_re);
-    const __m128 ef_im2 = _mm_mul_ps(ef_im, ef_im);
-    const __m128 ef_sum2 = _mm_add_ps(ef_re2, ef_im2);
-    const __m128 absEf = _mm_sqrt_ps(ef_sum2);
-    const __m128 bigger = _mm_cmpgt_ps(absEf, kThresh);
-    __m128 absEfPlus = _mm_add_ps(absEf, k1e_10f);
-    const __m128 absEfInv = _mm_div_ps(kThresh, absEfPlus);
-    __m128 ef_re_if = _mm_mul_ps(ef_re, absEfInv);
-    __m128 ef_im_if = _mm_mul_ps(ef_im, absEfInv);
-    ef_re_if = _mm_and_ps(bigger, ef_re_if);
-    ef_im_if = _mm_and_ps(bigger, ef_im_if);
-    ef_re = _mm_andnot_ps(bigger, ef_re);
-    ef_im = _mm_andnot_ps(bigger, ef_im);
-    ef_re = _mm_or_ps(ef_re, ef_re_if);
-    ef_im = _mm_or_ps(ef_im, ef_im_if);
-    ef_re = _mm_mul_ps(ef_re, kMu);
-    ef_im = _mm_mul_ps(ef_im, kMu);
-
-    _mm_storeu_ps(&ef[0][i], ef_re);
-    _mm_storeu_ps(&ef[1][i], ef_im);
-  }
-  // scalar code for the remaining items.
-  {
-    for (; i < (PART_LEN1); i++) {
-      float abs_ef;
-      ef[0][i] /= (x_pow[i] + 1e-10f);
-      ef[1][i] /= (x_pow[i] + 1e-10f);
-      abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]);
-
-      if (abs_ef > error_threshold) {
-        abs_ef = error_threshold / (abs_ef + 1e-10f);
-        ef[0][i] *= abs_ef;
-        ef[1][i] *= abs_ef;
-      }
-
-      // Stepsize factor
-      ef[0][i] *= mu;
-      ef[1][i] *= mu;
-    }
-  }
-}
-
-static void FilterAdaptationSSE2(
-    const OouraFft& ooura_fft,
-    int num_partitions,
-    int x_fft_buf_block_pos,
-    float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
-    float e_fft[2][PART_LEN1],
-    float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) {
-  float fft[PART_LEN2];
-  int i, j;
-  for (i = 0; i < num_partitions; i++) {
-    int xPos = (i + x_fft_buf_block_pos) * (PART_LEN1);
-    int pos = i * PART_LEN1;
-    // Check for wrap
-    if (i + x_fft_buf_block_pos >= num_partitions) {
-      xPos -= num_partitions * PART_LEN1;
-    }
-
-    // Process the whole array...
-    for (j = 0; j < PART_LEN; j += 4) {
-      // Load x_fft_buf and e_fft.
-      const __m128 x_fft_buf_re = _mm_loadu_ps(&x_fft_buf[0][xPos + j]);
-      const __m128 x_fft_buf_im = _mm_loadu_ps(&x_fft_buf[1][xPos + j]);
-      const __m128 e_fft_re = _mm_loadu_ps(&e_fft[0][j]);
-      const __m128 e_fft_im = _mm_loadu_ps(&e_fft[1][j]);
-      // Calculate the product of conjugate(x_fft_buf) by e_fft.
-      //   re(conjugate(a) * b) = aRe * bRe + aIm * bIm
-      //   im(conjugate(a) * b)=  aRe * bIm - aIm * bRe
-      const __m128 a = _mm_mul_ps(x_fft_buf_re, e_fft_re);
-      const __m128 b = _mm_mul_ps(x_fft_buf_im, e_fft_im);
-      const __m128 c = _mm_mul_ps(x_fft_buf_re, e_fft_im);
-      const __m128 d = _mm_mul_ps(x_fft_buf_im, e_fft_re);
-      const __m128 e = _mm_add_ps(a, b);
-      const __m128 f = _mm_sub_ps(c, d);
-      // Interleave real and imaginary parts.
-      const __m128 g = _mm_unpacklo_ps(e, f);
-      const __m128 h = _mm_unpackhi_ps(e, f);
-      // Store
-      _mm_storeu_ps(&fft[2 * j + 0], g);
-      _mm_storeu_ps(&fft[2 * j + 4], h);
-    }
-    // ... and fixup the first imaginary entry.
-    fft[1] =
-        MulRe(x_fft_buf[0][xPos + PART_LEN], -x_fft_buf[1][xPos + PART_LEN],
-              e_fft[0][PART_LEN], e_fft[1][PART_LEN]);
-
-    ooura_fft.InverseFft(fft);
-    memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN);
-
-    // fft scaling
-    {
-      float scale = 2.0f / PART_LEN2;
-      const __m128 scale_ps = _mm_load_ps1(&scale);
-      for (j = 0; j < PART_LEN; j += 4) {
-        const __m128 fft_ps = _mm_loadu_ps(&fft[j]);
-        const __m128 fft_scale = _mm_mul_ps(fft_ps, scale_ps);
-        _mm_storeu_ps(&fft[j], fft_scale);
-      }
-    }
-    ooura_fft.Fft(fft);
-
-    {
-      float wt1 = h_fft_buf[1][pos];
-      h_fft_buf[0][pos + PART_LEN] += fft[1];
-      for (j = 0; j < PART_LEN; j += 4) {
-        __m128 wtBuf_re = _mm_loadu_ps(&h_fft_buf[0][pos + j]);
-        __m128 wtBuf_im = _mm_loadu_ps(&h_fft_buf[1][pos + j]);
-        const __m128 fft0 = _mm_loadu_ps(&fft[2 * j + 0]);
-        const __m128 fft4 = _mm_loadu_ps(&fft[2 * j + 4]);
-        const __m128 fft_re =
-            _mm_shuffle_ps(fft0, fft4, _MM_SHUFFLE(2, 0, 2, 0));
-        const __m128 fft_im =
-            _mm_shuffle_ps(fft0, fft4, _MM_SHUFFLE(3, 1, 3, 1));
-        wtBuf_re = _mm_add_ps(wtBuf_re, fft_re);
-        wtBuf_im = _mm_add_ps(wtBuf_im, fft_im);
-        _mm_storeu_ps(&h_fft_buf[0][pos + j], wtBuf_re);
-        _mm_storeu_ps(&h_fft_buf[1][pos + j], wtBuf_im);
-      }
-      h_fft_buf[1][pos] = wt1;
-    }
-  }
-}
-
-static __m128 mm_pow_ps(__m128 a, __m128 b) {
-  // a^b = exp2(b * log2(a))
-  //   exp2(x) and log2(x) are calculated using polynomial approximations.
-  __m128 log2_a, b_log2_a, a_exp_b;
-
-  // Calculate log2(x), x = a.
-  {
-    // To calculate log2(x), we decompose x like this:
-    //   x = y * 2^n
-    //     n is an integer
-    //     y is in the [1.0, 2.0) range
-    //
-    //   log2(x) = log2(y) + n
-    //     n       can be evaluated by playing with float representation.
-    //     log2(y) in a small range can be approximated, this code uses an order
-    //             five polynomial approximation. The coefficients have been
-    //             estimated with the Remez algorithm and the resulting
-    //             polynomial has a maximum relative error of 0.00086%.
-
-    // Compute n.
-    //    This is done by masking the exponent, shifting it into the top bit of
-    //    the mantissa, putting eight into the biased exponent (to shift/
-    //    compensate the fact that the exponent has been shifted in the top/
-    //    fractional part and finally getting rid of the implicit leading one
-    //    from the mantissa by substracting it out.
-    static const ALIGN16_BEG int float_exponent_mask[4] ALIGN16_END = {
-        0x7F800000, 0x7F800000, 0x7F800000, 0x7F800000};
-    static const ALIGN16_BEG int eight_biased_exponent[4] ALIGN16_END = {
-        0x43800000, 0x43800000, 0x43800000, 0x43800000};
-    static const ALIGN16_BEG int implicit_leading_one[4] ALIGN16_END = {
-        0x43BF8000, 0x43BF8000, 0x43BF8000, 0x43BF8000};
-    static const int shift_exponent_into_top_mantissa = 8;
-    const __m128 two_n =
-        _mm_and_ps(a, *(reinterpret_cast<const __m128*>(float_exponent_mask)));
-    const __m128 n_1 = _mm_castsi128_ps(_mm_srli_epi32(
-        _mm_castps_si128(two_n), shift_exponent_into_top_mantissa));
-    const __m128 n_0 = _mm_or_ps(
-        n_1, *(reinterpret_cast<const __m128*>(eight_biased_exponent)));
-    const __m128 n = _mm_sub_ps(
-        n_0, *(reinterpret_cast<const __m128*>(implicit_leading_one)));
-
-    // Compute y.
-    static const ALIGN16_BEG int mantissa_mask[4] ALIGN16_END = {
-        0x007FFFFF, 0x007FFFFF, 0x007FFFFF, 0x007FFFFF};
-    static const ALIGN16_BEG int zero_biased_exponent_is_one[4] ALIGN16_END = {
-        0x3F800000, 0x3F800000, 0x3F800000, 0x3F800000};
-    const __m128 mantissa =
-        _mm_and_ps(a, *(reinterpret_cast<const __m128*>(mantissa_mask)));
-    const __m128 y = _mm_or_ps(
-        mantissa,
-        *(reinterpret_cast<const __m128*>(zero_biased_exponent_is_one)));
-
-    // Approximate log2(y) ~= (y - 1) * pol5(y).
-    //    pol5(y) = C5 * y^5 + C4 * y^4 + C3 * y^3 + C2 * y^2 + C1 * y + C0
-    static const ALIGN16_BEG float ALIGN16_END C5[4] = {
-        -3.4436006e-2f, -3.4436006e-2f, -3.4436006e-2f, -3.4436006e-2f};
-    static const ALIGN16_BEG float ALIGN16_END C4[4] = {
-        3.1821337e-1f, 3.1821337e-1f, 3.1821337e-1f, 3.1821337e-1f};
-    static const ALIGN16_BEG float ALIGN16_END C3[4] = {
-        -1.2315303f, -1.2315303f, -1.2315303f, -1.2315303f};
-    static const ALIGN16_BEG float ALIGN16_END C2[4] = {2.5988452f, 2.5988452f,
-                                                        2.5988452f, 2.5988452f};
-    static const ALIGN16_BEG float ALIGN16_END C1[4] = {
-        -3.3241990f, -3.3241990f, -3.3241990f, -3.3241990f};
-    static const ALIGN16_BEG float ALIGN16_END C0[4] = {3.1157899f, 3.1157899f,
-                                                        3.1157899f, 3.1157899f};
-    const __m128 pol5_y_0 =
-        _mm_mul_ps(y, *(reinterpret_cast<const __m128*>(C5)));
-    const __m128 pol5_y_1 =
-        _mm_add_ps(pol5_y_0, *(reinterpret_cast<const __m128*>(C4)));
-    const __m128 pol5_y_2 = _mm_mul_ps(pol5_y_1, y);
-    const __m128 pol5_y_3 =
-        _mm_add_ps(pol5_y_2, *(reinterpret_cast<const __m128*>(C3)));
-    const __m128 pol5_y_4 = _mm_mul_ps(pol5_y_3, y);
-    const __m128 pol5_y_5 =
-        _mm_add_ps(pol5_y_4, *(reinterpret_cast<const __m128*>(C2)));
-    const __m128 pol5_y_6 = _mm_mul_ps(pol5_y_5, y);
-    const __m128 pol5_y_7 =
-        _mm_add_ps(pol5_y_6, *(reinterpret_cast<const __m128*>(C1)));
-    const __m128 pol5_y_8 = _mm_mul_ps(pol5_y_7, y);
-    const __m128 pol5_y =
-        _mm_add_ps(pol5_y_8, *(reinterpret_cast<const __m128*>(C0)));
-    const __m128 y_minus_one = _mm_sub_ps(
-        y, *(reinterpret_cast<const __m128*>(zero_biased_exponent_is_one)));
-    const __m128 log2_y = _mm_mul_ps(y_minus_one, pol5_y);
-
-    // Combine parts.
-    log2_a = _mm_add_ps(n, log2_y);
-  }
-
-  // b * log2(a)
-  b_log2_a = _mm_mul_ps(b, log2_a);
-
-  // Calculate exp2(x), x = b * log2(a).
-  {
-    // To calculate 2^x, we decompose x like this:
-    //   x = n + y
-    //     n is an integer, the value of x - 0.5 rounded down, therefore
-    //     y is in the [0.5, 1.5) range
-    //
-    //   2^x = 2^n * 2^y
-    //     2^n can be evaluated by playing with float representation.
-    //     2^y in a small range can be approximated, this code uses an order two
-    //         polynomial approximation. The coefficients have been estimated
-    //         with the Remez algorithm and the resulting polynomial has a
-    //         maximum relative error of 0.17%.
-
-    // To avoid over/underflow, we reduce the range of input to ]-127, 129].
-    static const ALIGN16_BEG float max_input[4] ALIGN16_END = {129.f, 129.f,
-                                                               129.f, 129.f};
-    static const ALIGN16_BEG float min_input[4] ALIGN16_END = {
-        -126.99999f, -126.99999f, -126.99999f, -126.99999f};
-    const __m128 x_min =
-        _mm_min_ps(b_log2_a, *(reinterpret_cast<const __m128*>(max_input)));
-    const __m128 x_max =
-        _mm_max_ps(x_min, *(reinterpret_cast<const __m128*>(min_input)));
-    // Compute n.
-    static const ALIGN16_BEG float half[4] ALIGN16_END = {0.5f, 0.5f, 0.5f,
-                                                          0.5f};
-    const __m128 x_minus_half =
-        _mm_sub_ps(x_max, *(reinterpret_cast<const __m128*>(half)));
-    const __m128i x_minus_half_floor = _mm_cvtps_epi32(x_minus_half);
-    // Compute 2^n.
-    static const ALIGN16_BEG int float_exponent_bias[4] ALIGN16_END = {
-        127, 127, 127, 127};
-    static const int float_exponent_shift = 23;
-    const __m128i two_n_exponent =
-        _mm_add_epi32(x_minus_half_floor,
-                      *(reinterpret_cast<const __m128i*>(float_exponent_bias)));
-    const __m128 two_n =
-        _mm_castsi128_ps(_mm_slli_epi32(two_n_exponent, float_exponent_shift));
-    // Compute y.
-    const __m128 y = _mm_sub_ps(x_max, _mm_cvtepi32_ps(x_minus_half_floor));
-    // Approximate 2^y ~= C2 * y^2 + C1 * y + C0.
-    static const ALIGN16_BEG float C2[4] ALIGN16_END = {
-        3.3718944e-1f, 3.3718944e-1f, 3.3718944e-1f, 3.3718944e-1f};
-    static const ALIGN16_BEG float C1[4] ALIGN16_END = {
-        6.5763628e-1f, 6.5763628e-1f, 6.5763628e-1f, 6.5763628e-1f};
-    static const ALIGN16_BEG float C0[4] ALIGN16_END = {1.0017247f, 1.0017247f,
-                                                        1.0017247f, 1.0017247f};
-    const __m128 exp2_y_0 =
-        _mm_mul_ps(y, *(reinterpret_cast<const __m128*>(C2)));
-    const __m128 exp2_y_1 =
-        _mm_add_ps(exp2_y_0, *(reinterpret_cast<const __m128*>(C1)));
-    const __m128 exp2_y_2 = _mm_mul_ps(exp2_y_1, y);
-    const __m128 exp2_y =
-        _mm_add_ps(exp2_y_2, *(reinterpret_cast<const __m128*>(C0)));
-
-    // Combine parts.
-    a_exp_b = _mm_mul_ps(exp2_y, two_n);
-  }
-  return a_exp_b;
-}
-
-static void OverdriveSSE2(float overdrive_scaling,
-                          float hNlFb,
-                          float hNl[PART_LEN1]) {
-  int i;
-  const __m128 vec_hNlFb = _mm_set1_ps(hNlFb);
-  const __m128 vec_one = _mm_set1_ps(1.0f);
-  const __m128 vec_overdrive_scaling = _mm_set1_ps(overdrive_scaling);
-  // vectorized code (four at once)
-  for (i = 0; i + 3 < PART_LEN1; i += 4) {
-    // Weight subbands
-    __m128 vec_hNl = _mm_loadu_ps(&hNl[i]);
-    const __m128 vec_weightCurve = _mm_loadu_ps(&WebRtcAec_weightCurve[i]);
-    const __m128 bigger = _mm_cmpgt_ps(vec_hNl, vec_hNlFb);
-    const __m128 vec_weightCurve_hNlFb = _mm_mul_ps(vec_weightCurve, vec_hNlFb);
-    const __m128 vec_one_weightCurve = _mm_sub_ps(vec_one, vec_weightCurve);
-    const __m128 vec_one_weightCurve_hNl =
-        _mm_mul_ps(vec_one_weightCurve, vec_hNl);
-    const __m128 vec_if0 = _mm_andnot_ps(bigger, vec_hNl);
-    const __m128 vec_if1 = _mm_and_ps(
-        bigger, _mm_add_ps(vec_weightCurve_hNlFb, vec_one_weightCurve_hNl));
-    vec_hNl = _mm_or_ps(vec_if0, vec_if1);
-
-    const __m128 vec_overDriveCurve =
-        _mm_loadu_ps(&WebRtcAec_overDriveCurve[i]);
-    const __m128 vec_overDriveSm_overDriveCurve =
-        _mm_mul_ps(vec_overdrive_scaling, vec_overDriveCurve);
-    vec_hNl = mm_pow_ps(vec_hNl, vec_overDriveSm_overDriveCurve);
-    _mm_storeu_ps(&hNl[i], vec_hNl);
-  }
-  // scalar code for the remaining items.
-  for (; i < PART_LEN1; i++) {
-    // Weight subbands
-    if (hNl[i] > hNlFb) {
-      hNl[i] = WebRtcAec_weightCurve[i] * hNlFb +
-               (1 - WebRtcAec_weightCurve[i]) * hNl[i];
-    }
-    hNl[i] = powf(hNl[i], overdrive_scaling * WebRtcAec_overDriveCurve[i]);
-  }
-}
-
-static void SuppressSSE2(const float hNl[PART_LEN1], float efw[2][PART_LEN1]) {
-  int i;
-  const __m128 vec_minus_one = _mm_set1_ps(-1.0f);
-  // vectorized code (four at once)
-  for (i = 0; i + 3 < PART_LEN1; i += 4) {
-    // Suppress error signal
-    __m128 vec_hNl = _mm_loadu_ps(&hNl[i]);
-    __m128 vec_efw_re = _mm_loadu_ps(&efw[0][i]);
-    __m128 vec_efw_im = _mm_loadu_ps(&efw[1][i]);
-    vec_efw_re = _mm_mul_ps(vec_efw_re, vec_hNl);
-    vec_efw_im = _mm_mul_ps(vec_efw_im, vec_hNl);
-
-    // Ooura fft returns incorrect sign on imaginary component. It matters
-    // here because we are making an additive change with comfort noise.
-    vec_efw_im = _mm_mul_ps(vec_efw_im, vec_minus_one);
-    _mm_storeu_ps(&efw[0][i], vec_efw_re);
-    _mm_storeu_ps(&efw[1][i], vec_efw_im);
-  }
-  // scalar code for the remaining items.
-  for (; i < PART_LEN1; i++) {
-    // Suppress error signal
-    efw[0][i] *= hNl[i];
-    efw[1][i] *= hNl[i];
-
-    // Ooura fft returns incorrect sign on imaginary component. It matters
-    // here because we are making an additive change with comfort noise.
-    efw[1][i] *= -1;
-  }
-}
-
-__inline static void _mm_add_ps_4x1(__m128 sum, float* dst) {
-  // A+B C+D
-  sum = _mm_add_ps(sum, _mm_shuffle_ps(sum, sum, _MM_SHUFFLE(0, 0, 3, 2)));
-  // A+B+C+D A+B+C+D
-  sum = _mm_add_ps(sum, _mm_shuffle_ps(sum, sum, _MM_SHUFFLE(1, 1, 1, 1)));
-  _mm_store_ss(dst, sum);
-}
-
-static int PartitionDelaySSE2(
-    int num_partitions,
-    float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) {
-  // Measures the energy in each filter partition and returns the partition with
-  // highest energy.
-  // TODO(bjornv): Spread computational cost by computing one partition per
-  // block?
-  float wfEnMax = 0;
-  int i;
-  int delay = 0;
-
-  for (i = 0; i < num_partitions; i++) {
-    int j;
-    int pos = i * PART_LEN1;
-    float wfEn = 0;
-    __m128 vec_wfEn = _mm_set1_ps(0.0f);
-    // vectorized code (four at once)
-    for (j = 0; j + 3 < PART_LEN1; j += 4) {
-      const __m128 vec_wfBuf0 = _mm_loadu_ps(&h_fft_buf[0][pos + j]);
-      const __m128 vec_wfBuf1 = _mm_loadu_ps(&h_fft_buf[1][pos + j]);
-      vec_wfEn = _mm_add_ps(vec_wfEn, _mm_mul_ps(vec_wfBuf0, vec_wfBuf0));
-      vec_wfEn = _mm_add_ps(vec_wfEn, _mm_mul_ps(vec_wfBuf1, vec_wfBuf1));
-    }
-    _mm_add_ps_4x1(vec_wfEn, &wfEn);
-
-    // scalar code for the remaining items.
-    for (; j < PART_LEN1; j++) {
-      wfEn += h_fft_buf[0][pos + j] * h_fft_buf[0][pos + j] +
-              h_fft_buf[1][pos + j] * h_fft_buf[1][pos + j];
-    }
-
-    if (wfEn > wfEnMax) {
-      wfEnMax = wfEn;
-      delay = i;
-    }
-  }
-  return delay;
-}
-
-// Updates the following smoothed  Power Spectral Densities (PSD):
-//  - sd  : near-end
-//  - se  : residual echo
-//  - sx  : far-end
-//  - sde : cross-PSD of near-end and residual echo
-//  - sxd : cross-PSD of near-end and far-end
-//
-// In addition to updating the PSDs, also the filter diverge state is determined
-// upon actions are taken.
-static void UpdateCoherenceSpectraSSE2(int mult,
-                                       bool extended_filter_enabled,
-                                       float efw[2][PART_LEN1],
-                                       float dfw[2][PART_LEN1],
-                                       float xfw[2][PART_LEN1],
-                                       CoherenceState* coherence_state,
-                                       short* filter_divergence_state,
-                                       int* extreme_filter_divergence) {
-  // Power estimate smoothing coefficients.
-  const float* ptrGCoh =
-      extended_filter_enabled
-          ? WebRtcAec_kExtendedSmoothingCoefficients[mult - 1]
-          : WebRtcAec_kNormalSmoothingCoefficients[mult - 1];
-  int i;
-  float sdSum = 0, seSum = 0;
-  const __m128 vec_15 = _mm_set1_ps(WebRtcAec_kMinFarendPSD);
-  const __m128 vec_GCoh0 = _mm_set1_ps(ptrGCoh[0]);
-  const __m128 vec_GCoh1 = _mm_set1_ps(ptrGCoh[1]);
-  __m128 vec_sdSum = _mm_set1_ps(0.0f);
-  __m128 vec_seSum = _mm_set1_ps(0.0f);
-
-  for (i = 0; i + 3 < PART_LEN1; i += 4) {
-    const __m128 vec_dfw0 = _mm_loadu_ps(&dfw[0][i]);
-    const __m128 vec_dfw1 = _mm_loadu_ps(&dfw[1][i]);
-    const __m128 vec_efw0 = _mm_loadu_ps(&efw[0][i]);
-    const __m128 vec_efw1 = _mm_loadu_ps(&efw[1][i]);
-    const __m128 vec_xfw0 = _mm_loadu_ps(&xfw[0][i]);
-    const __m128 vec_xfw1 = _mm_loadu_ps(&xfw[1][i]);
-    __m128 vec_sd =
-        _mm_mul_ps(_mm_loadu_ps(&coherence_state->sd[i]), vec_GCoh0);
-    __m128 vec_se =
-        _mm_mul_ps(_mm_loadu_ps(&coherence_state->se[i]), vec_GCoh0);
-    __m128 vec_sx =
-        _mm_mul_ps(_mm_loadu_ps(&coherence_state->sx[i]), vec_GCoh0);
-    __m128 vec_dfw_sumsq = _mm_mul_ps(vec_dfw0, vec_dfw0);
-    __m128 vec_efw_sumsq = _mm_mul_ps(vec_efw0, vec_efw0);
-    __m128 vec_xfw_sumsq = _mm_mul_ps(vec_xfw0, vec_xfw0);
-    vec_dfw_sumsq = _mm_add_ps(vec_dfw_sumsq, _mm_mul_ps(vec_dfw1, vec_dfw1));
-    vec_efw_sumsq = _mm_add_ps(vec_efw_sumsq, _mm_mul_ps(vec_efw1, vec_efw1));
-    vec_xfw_sumsq = _mm_add_ps(vec_xfw_sumsq, _mm_mul_ps(vec_xfw1, vec_xfw1));
-    vec_xfw_sumsq = _mm_max_ps(vec_xfw_sumsq, vec_15);
-    vec_sd = _mm_add_ps(vec_sd, _mm_mul_ps(vec_dfw_sumsq, vec_GCoh1));
-    vec_se = _mm_add_ps(vec_se, _mm_mul_ps(vec_efw_sumsq, vec_GCoh1));
-    vec_sx = _mm_add_ps(vec_sx, _mm_mul_ps(vec_xfw_sumsq, vec_GCoh1));
-    _mm_storeu_ps(&coherence_state->sd[i], vec_sd);
-    _mm_storeu_ps(&coherence_state->se[i], vec_se);
-    _mm_storeu_ps(&coherence_state->sx[i], vec_sx);
-
-    {
-      const __m128 vec_3210 = _mm_loadu_ps(&coherence_state->sde[i][0]);
-      const __m128 vec_7654 = _mm_loadu_ps(&coherence_state->sde[i + 2][0]);
-      __m128 vec_a =
-          _mm_shuffle_ps(vec_3210, vec_7654, _MM_SHUFFLE(2, 0, 2, 0));
-      __m128 vec_b =
-          _mm_shuffle_ps(vec_3210, vec_7654, _MM_SHUFFLE(3, 1, 3, 1));
-      __m128 vec_dfwefw0011 = _mm_mul_ps(vec_dfw0, vec_efw0);
-      __m128 vec_dfwefw0110 = _mm_mul_ps(vec_dfw0, vec_efw1);
-      vec_a = _mm_mul_ps(vec_a, vec_GCoh0);
-      vec_b = _mm_mul_ps(vec_b, vec_GCoh0);
-      vec_dfwefw0011 =
-          _mm_add_ps(vec_dfwefw0011, _mm_mul_ps(vec_dfw1, vec_efw1));
-      vec_dfwefw0110 =
-          _mm_sub_ps(vec_dfwefw0110, _mm_mul_ps(vec_dfw1, vec_efw0));
-      vec_a = _mm_add_ps(vec_a, _mm_mul_ps(vec_dfwefw0011, vec_GCoh1));
-      vec_b = _mm_add_ps(vec_b, _mm_mul_ps(vec_dfwefw0110, vec_GCoh1));
-      _mm_storeu_ps(&coherence_state->sde[i][0], _mm_unpacklo_ps(vec_a, vec_b));
-      _mm_storeu_ps(&coherence_state->sde[i + 2][0],
-                    _mm_unpackhi_ps(vec_a, vec_b));
-    }
-
-    {
-      const __m128 vec_3210 = _mm_loadu_ps(&coherence_state->sxd[i][0]);
-      const __m128 vec_7654 = _mm_loadu_ps(&coherence_state->sxd[i + 2][0]);
-      __m128 vec_a =
-          _mm_shuffle_ps(vec_3210, vec_7654, _MM_SHUFFLE(2, 0, 2, 0));
-      __m128 vec_b =
-          _mm_shuffle_ps(vec_3210, vec_7654, _MM_SHUFFLE(3, 1, 3, 1));
-      __m128 vec_dfwxfw0011 = _mm_mul_ps(vec_dfw0, vec_xfw0);
-      __m128 vec_dfwxfw0110 = _mm_mul_ps(vec_dfw0, vec_xfw1);
-      vec_a = _mm_mul_ps(vec_a, vec_GCoh0);
-      vec_b = _mm_mul_ps(vec_b, vec_GCoh0);
-      vec_dfwxfw0011 =
-          _mm_add_ps(vec_dfwxfw0011, _mm_mul_ps(vec_dfw1, vec_xfw1));
-      vec_dfwxfw0110 =
-          _mm_sub_ps(vec_dfwxfw0110, _mm_mul_ps(vec_dfw1, vec_xfw0));
-      vec_a = _mm_add_ps(vec_a, _mm_mul_ps(vec_dfwxfw0011, vec_GCoh1));
-      vec_b = _mm_add_ps(vec_b, _mm_mul_ps(vec_dfwxfw0110, vec_GCoh1));
-      _mm_storeu_ps(&coherence_state->sxd[i][0], _mm_unpacklo_ps(vec_a, vec_b));
-      _mm_storeu_ps(&coherence_state->sxd[i + 2][0],
-                    _mm_unpackhi_ps(vec_a, vec_b));
-    }
-
-    vec_sdSum = _mm_add_ps(vec_sdSum, vec_sd);
-    vec_seSum = _mm_add_ps(vec_seSum, vec_se);
-  }
-
-  _mm_add_ps_4x1(vec_sdSum, &sdSum);
-  _mm_add_ps_4x1(vec_seSum, &seSum);
-
-  for (; i < PART_LEN1; i++) {
-    coherence_state->sd[i] =
-        ptrGCoh[0] * coherence_state->sd[i] +
-        ptrGCoh[1] * (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]);
-    coherence_state->se[i] =
-        ptrGCoh[0] * coherence_state->se[i] +
-        ptrGCoh[1] * (efw[0][i] * efw[0][i] + efw[1][i] * efw[1][i]);
-    // We threshold here to protect against the ill-effects of a zero farend.
-    // The threshold is not arbitrarily chosen, but balances protection and
-    // adverse interaction with the algorithm's tuning.
-    // TODO(bjornv): investigate further why this is so sensitive.
-    coherence_state->sx[i] =
-        ptrGCoh[0] * coherence_state->sx[i] +
-        ptrGCoh[1] *
-            WEBRTC_SPL_MAX(xfw[0][i] * xfw[0][i] + xfw[1][i] * xfw[1][i],
-                           WebRtcAec_kMinFarendPSD);
-
-    coherence_state->sde[i][0] =
-        ptrGCoh[0] * coherence_state->sde[i][0] +
-        ptrGCoh[1] * (dfw[0][i] * efw[0][i] + dfw[1][i] * efw[1][i]);
-    coherence_state->sde[i][1] =
-        ptrGCoh[0] * coherence_state->sde[i][1] +
-        ptrGCoh[1] * (dfw[0][i] * efw[1][i] - dfw[1][i] * efw[0][i]);
-
-    coherence_state->sxd[i][0] =
-        ptrGCoh[0] * coherence_state->sxd[i][0] +
-        ptrGCoh[1] * (dfw[0][i] * xfw[0][i] + dfw[1][i] * xfw[1][i]);
-    coherence_state->sxd[i][1] =
-        ptrGCoh[0] * coherence_state->sxd[i][1] +
-        ptrGCoh[1] * (dfw[0][i] * xfw[1][i] - dfw[1][i] * xfw[0][i]);
-
-    sdSum += coherence_state->sd[i];
-    seSum += coherence_state->se[i];
-  }
-
-  // Divergent filter safeguard update.
-  *filter_divergence_state =
-      (*filter_divergence_state ? 1.05f : 1.0f) * seSum > sdSum;
-
-  // Signal extreme filter divergence if the error is significantly larger
-  // than the nearend (13 dB).
-  *extreme_filter_divergence = (seSum > (19.95f * sdSum));
-}
-
-// Window time domain data to be used by the fft.
-static void WindowDataSSE2(float* x_windowed, const float* x) {
-  int i;
-  for (i = 0; i < PART_LEN; i += 4) {
-    const __m128 vec_Buf1 = _mm_loadu_ps(&x[i]);
-    const __m128 vec_Buf2 = _mm_loadu_ps(&x[PART_LEN + i]);
-    const __m128 vec_sqrtHanning = _mm_load_ps(&WebRtcAec_sqrtHanning[i]);
-    // A B C D
-    __m128 vec_sqrtHanning_rev =
-        _mm_loadu_ps(&WebRtcAec_sqrtHanning[PART_LEN - i - 3]);
-    // D C B A
-    vec_sqrtHanning_rev = _mm_shuffle_ps(
-        vec_sqrtHanning_rev, vec_sqrtHanning_rev, _MM_SHUFFLE(0, 1, 2, 3));
-    _mm_storeu_ps(&x_windowed[i], _mm_mul_ps(vec_Buf1, vec_sqrtHanning));
-    _mm_storeu_ps(&x_windowed[PART_LEN + i],
-                  _mm_mul_ps(vec_Buf2, vec_sqrtHanning_rev));
-  }
-}
-
-// Puts fft output data into a complex valued array.
-static void StoreAsComplexSSE2(const float* data,
-                               float data_complex[2][PART_LEN1]) {
-  int i;
-  for (i = 0; i < PART_LEN; i += 4) {
-    const __m128 vec_fft0 = _mm_loadu_ps(&data[2 * i]);
-    const __m128 vec_fft4 = _mm_loadu_ps(&data[2 * i + 4]);
-    const __m128 vec_a =
-        _mm_shuffle_ps(vec_fft0, vec_fft4, _MM_SHUFFLE(2, 0, 2, 0));
-    const __m128 vec_b =
-        _mm_shuffle_ps(vec_fft0, vec_fft4, _MM_SHUFFLE(3, 1, 3, 1));
-    _mm_storeu_ps(&data_complex[0][i], vec_a);
-    _mm_storeu_ps(&data_complex[1][i], vec_b);
-  }
-  // fix beginning/end values
-  data_complex[1][0] = 0;
-  data_complex[1][PART_LEN] = 0;
-  data_complex[0][0] = data[0];
-  data_complex[0][PART_LEN] = data[1];
-}
-
-static void ComputeCoherenceSSE2(const CoherenceState* coherence_state,
-                                 float* cohde,
-                                 float* cohxd) {
-  int i;
-
-  {
-    const __m128 vec_1eminus10 = _mm_set1_ps(1e-10f);
-
-    // Subband coherence
-    for (i = 0; i + 3 < PART_LEN1; i += 4) {
-      const __m128 vec_sd = _mm_loadu_ps(&coherence_state->sd[i]);
-      const __m128 vec_se = _mm_loadu_ps(&coherence_state->se[i]);
-      const __m128 vec_sx = _mm_loadu_ps(&coherence_state->sx[i]);
-      const __m128 vec_sdse =
-          _mm_add_ps(vec_1eminus10, _mm_mul_ps(vec_sd, vec_se));
-      const __m128 vec_sdsx =
-          _mm_add_ps(vec_1eminus10, _mm_mul_ps(vec_sd, vec_sx));
-      const __m128 vec_sde_3210 = _mm_loadu_ps(&coherence_state->sde[i][0]);
-      const __m128 vec_sde_7654 = _mm_loadu_ps(&coherence_state->sde[i + 2][0]);
-      const __m128 vec_sxd_3210 = _mm_loadu_ps(&coherence_state->sxd[i][0]);
-      const __m128 vec_sxd_7654 = _mm_loadu_ps(&coherence_state->sxd[i + 2][0]);
-      const __m128 vec_sde_0 =
-          _mm_shuffle_ps(vec_sde_3210, vec_sde_7654, _MM_SHUFFLE(2, 0, 2, 0));
-      const __m128 vec_sde_1 =
-          _mm_shuffle_ps(vec_sde_3210, vec_sde_7654, _MM_SHUFFLE(3, 1, 3, 1));
-      const __m128 vec_sxd_0 =
-          _mm_shuffle_ps(vec_sxd_3210, vec_sxd_7654, _MM_SHUFFLE(2, 0, 2, 0));
-      const __m128 vec_sxd_1 =
-          _mm_shuffle_ps(vec_sxd_3210, vec_sxd_7654, _MM_SHUFFLE(3, 1, 3, 1));
-      __m128 vec_cohde = _mm_mul_ps(vec_sde_0, vec_sde_0);
-      __m128 vec_cohxd = _mm_mul_ps(vec_sxd_0, vec_sxd_0);
-      vec_cohde = _mm_add_ps(vec_cohde, _mm_mul_ps(vec_sde_1, vec_sde_1));
-      vec_cohde = _mm_div_ps(vec_cohde, vec_sdse);
-      vec_cohxd = _mm_add_ps(vec_cohxd, _mm_mul_ps(vec_sxd_1, vec_sxd_1));
-      vec_cohxd = _mm_div_ps(vec_cohxd, vec_sdsx);
-      _mm_storeu_ps(&cohde[i], vec_cohde);
-      _mm_storeu_ps(&cohxd[i], vec_cohxd);
-    }
-
-    // scalar code for the remaining items.
-    for (; i < PART_LEN1; i++) {
-      cohde[i] = (coherence_state->sde[i][0] * coherence_state->sde[i][0] +
-                  coherence_state->sde[i][1] * coherence_state->sde[i][1]) /
-                 (coherence_state->sd[i] * coherence_state->se[i] + 1e-10f);
-      cohxd[i] = (coherence_state->sxd[i][0] * coherence_state->sxd[i][0] +
-                  coherence_state->sxd[i][1] * coherence_state->sxd[i][1]) /
-                 (coherence_state->sx[i] * coherence_state->sd[i] + 1e-10f);
-    }
-  }
-}
-
-void WebRtcAec_InitAec_SSE2(void) {
-  WebRtcAec_FilterFar = FilterFarSSE2;
-  WebRtcAec_ScaleErrorSignal = ScaleErrorSignalSSE2;
-  WebRtcAec_FilterAdaptation = FilterAdaptationSSE2;
-  WebRtcAec_Overdrive = OverdriveSSE2;
-  WebRtcAec_Suppress = SuppressSSE2;
-  WebRtcAec_ComputeCoherence = ComputeCoherenceSSE2;
-  WebRtcAec_UpdateCoherenceSpectra = UpdateCoherenceSpectraSSE2;
-  WebRtcAec_StoreAsComplex = StoreAsComplexSSE2;
-  WebRtcAec_PartitionDelay = PartitionDelaySSE2;
-  WebRtcAec_WindowData = WindowDataSSE2;
-}
-}  // namespace webrtc
diff --git a/modules/audio_processing/aec/aec_resampler.cc b/modules/audio_processing/aec/aec_resampler.cc
deleted file mode 100644
index 210c2be..0000000
--- a/modules/audio_processing/aec/aec_resampler.cc
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-/* Resamples a signal to an arbitrary rate. Used by the AEC to compensate for
- * clock skew by resampling the farend signal.
- */
-
-#include "modules/audio_processing/aec/aec_resampler.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "modules/audio_processing/aec/aec_core.h"
-#include "rtc_base/checks.h"
-
-namespace webrtc {
-
-enum { kEstimateLengthFrames = 400 };
-
-typedef struct {
-  float buffer[kResamplerBufferSize];
-  float position;
-
-  int deviceSampleRateHz;
-  int skewData[kEstimateLengthFrames];
-  int skewDataIndex;
-  float skewEstimate;
-} AecResampler;
-
-static int EstimateSkew(const int* rawSkew,
-                        int size,
-                        int deviceSampleRateHz,
-                        float* skewEst);
-
-void* WebRtcAec_CreateResampler() {
-  return malloc(sizeof(AecResampler));
-}
-
-int WebRtcAec_InitResampler(void* resampInst, int deviceSampleRateHz) {
-  AecResampler* obj = static_cast<AecResampler*>(resampInst);
-  memset(obj->buffer, 0, sizeof(obj->buffer));
-  obj->position = 0.0;
-
-  obj->deviceSampleRateHz = deviceSampleRateHz;
-  memset(obj->skewData, 0, sizeof(obj->skewData));
-  obj->skewDataIndex = 0;
-  obj->skewEstimate = 0.0;
-
-  return 0;
-}
-
-void WebRtcAec_FreeResampler(void* resampInst) {
-  AecResampler* obj = static_cast<AecResampler*>(resampInst);
-  free(obj);
-}
-
-void WebRtcAec_ResampleLinear(void* resampInst,
-                              const float* inspeech,
-                              size_t size,
-                              float skew,
-                              float* outspeech,
-                              size_t* size_out) {
-  AecResampler* obj = static_cast<AecResampler*>(resampInst);
-
-  float* y;
-  float be, tnew;
-  size_t tn, mm;
-
-  RTC_DCHECK_LE(size, 2 * FRAME_LEN);
-  RTC_DCHECK(resampInst);
-  RTC_DCHECK(inspeech);
-  RTC_DCHECK(outspeech);
-  RTC_DCHECK(size_out);
-
-  // Add new frame data in lookahead
-  memcpy(&obj->buffer[FRAME_LEN + kResamplingDelay], inspeech,
-         size * sizeof(inspeech[0]));
-
-  // Sample rate ratio
-  be = 1 + skew;
-
-  // Loop over input frame
-  mm = 0;
-  y = &obj->buffer[FRAME_LEN];  // Point at current frame
-
-  tnew = be * mm + obj->position;
-  tn = (size_t)tnew;
-
-  while (tn < size) {
-    // Interpolation
-    outspeech[mm] = y[tn] + (tnew - tn) * (y[tn + 1] - y[tn]);
-    mm++;
-
-    tnew = be * mm + obj->position;
-    tn = static_cast<int>(tnew);
-  }
-
-  *size_out = mm;
-  obj->position += (*size_out) * be - size;
-
-  // Shift buffer
-  memmove(obj->buffer, &obj->buffer[size],
-          (kResamplerBufferSize - size) * sizeof(obj->buffer[0]));
-}
-
-int WebRtcAec_GetSkew(void* resampInst, int rawSkew, float* skewEst) {
-  AecResampler* obj = static_cast<AecResampler*>(resampInst);
-  int err = 0;
-
-  if (obj->skewDataIndex < kEstimateLengthFrames) {
-    obj->skewData[obj->skewDataIndex] = rawSkew;
-    obj->skewDataIndex++;
-  } else if (obj->skewDataIndex == kEstimateLengthFrames) {
-    err = EstimateSkew(obj->skewData, kEstimateLengthFrames,
-                       obj->deviceSampleRateHz, skewEst);
-    obj->skewEstimate = *skewEst;
-    obj->skewDataIndex++;
-  } else {
-    *skewEst = obj->skewEstimate;
-  }
-
-  return err;
-}
-
-int EstimateSkew(const int* rawSkew,
-                 int size,
-                 int deviceSampleRateHz,
-                 float* skewEst) {
-  const int absLimitOuter = static_cast<int>(0.04f * deviceSampleRateHz);
-  const int absLimitInner = static_cast<int>(0.0025f * deviceSampleRateHz);
-  int i = 0;
-  int n = 0;
-  float rawAvg = 0;
-  float err = 0;
-  float rawAbsDev = 0;
-  int upperLimit = 0;
-  int lowerLimit = 0;
-  float cumSum = 0;
-  float x = 0;
-  float x2 = 0;
-  float y = 0;
-  float xy = 0;
-  float xAvg = 0;
-  float denom = 0;
-  float skew = 0;
-
-  *skewEst = 0;  // Set in case of error below.
-  for (i = 0; i < size; i++) {
-    if ((rawSkew[i] < absLimitOuter && rawSkew[i] > -absLimitOuter)) {
-      n++;
-      rawAvg += rawSkew[i];
-    }
-  }
-
-  if (n == 0) {
-    return -1;
-  }
-  RTC_DCHECK_GT(n, 0);
-  rawAvg /= n;
-
-  for (i = 0; i < size; i++) {
-    if ((rawSkew[i] < absLimitOuter && rawSkew[i] > -absLimitOuter)) {
-      err = rawSkew[i] - rawAvg;
-      rawAbsDev += err >= 0 ? err : -err;
-    }
-  }
-  RTC_DCHECK_GT(n, 0);
-  rawAbsDev /= n;
-  upperLimit = static_cast<int>(rawAvg + 5 * rawAbsDev + 1);  // +1 for ceiling.
-  lowerLimit = static_cast<int>(rawAvg - 5 * rawAbsDev - 1);  // -1 for floor.
-
-  n = 0;
-  for (i = 0; i < size; i++) {
-    if ((rawSkew[i] < absLimitInner && rawSkew[i] > -absLimitInner) ||
-        (rawSkew[i] < upperLimit && rawSkew[i] > lowerLimit)) {
-      n++;
-      cumSum += rawSkew[i];
-      x += n;
-      x2 += n * n;
-      y += cumSum;
-      xy += n * cumSum;
-    }
-  }
-
-  if (n == 0) {
-    return -1;
-  }
-  RTC_DCHECK_GT(n, 0);
-  xAvg = x / n;
-  denom = x2 - xAvg * x;
-
-  if (denom != 0) {
-    skew = (xy - xAvg * y) / denom;
-  }
-
-  *skewEst = skew;
-  return 0;
-}
-}  // namespace webrtc
diff --git a/modules/audio_processing/aec/aec_resampler.h b/modules/audio_processing/aec/aec_resampler.h
deleted file mode 100644
index a112c43..0000000
--- a/modules/audio_processing/aec/aec_resampler.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef MODULES_AUDIO_PROCESSING_AEC_AEC_RESAMPLER_H_
-#define MODULES_AUDIO_PROCESSING_AEC_AEC_RESAMPLER_H_
-
-#include <stddef.h>
-
-#include "modules/audio_processing/aec/aec_core.h"
-
-namespace webrtc {
-
-enum { kResamplingDelay = 1 };
-enum { kResamplerBufferSize = FRAME_LEN * 4 };
-
-// Unless otherwise specified, functions return 0 on success and -1 on error.
-void* WebRtcAec_CreateResampler();  // Returns NULL on error.
-int WebRtcAec_InitResampler(void* resampInst, int deviceSampleRateHz);
-void WebRtcAec_FreeResampler(void* resampInst);
-
-// Estimates skew from raw measurement.
-int WebRtcAec_GetSkew(void* resampInst, int rawSkew, float* skewEst);
-
-// Resamples input using linear interpolation.
-void WebRtcAec_ResampleLinear(void* resampInst,
-                              const float* inspeech,
-                              size_t size,
-                              float skew,
-                              float* outspeech,
-                              size_t* size_out);
-
-}  // namespace webrtc
-
-#endif  // MODULES_AUDIO_PROCESSING_AEC_AEC_RESAMPLER_H_
diff --git a/modules/audio_processing/aec/echo_cancellation.cc b/modules/audio_processing/aec/echo_cancellation.cc
deleted file mode 100644
index fd1aec4..0000000
--- a/modules/audio_processing/aec/echo_cancellation.cc
+++ /dev/null
@@ -1,864 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-/*
- * Contains the API functions for the AEC.
- */
-#include "modules/audio_processing/aec/echo_cancellation.h"
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-extern "C" {
-#include "common_audio/ring_buffer.h"
-#include "common_audio/signal_processing/include/signal_processing_library.h"
-}
-#include "modules/audio_processing/aec/aec_core.h"
-#include "modules/audio_processing/aec/aec_resampler.h"
-#include "modules/audio_processing/logging/apm_data_dumper.h"
-
-namespace webrtc {
-
-Aec::Aec() = default;
-Aec::~Aec() = default;
-
-// Measured delays [ms]
-// Device                Chrome  GTP
-// MacBook Air           10
-// MacBook Retina        10      100
-// MacPro                30?
-//
-// Win7 Desktop          70      80?
-// Win7 T430s            110
-// Win8 T420s            70
-//
-// Daisy                 50
-// Pixel (w/ preproc?)           240
-// Pixel (w/o preproc?)  110     110
-
-// The extended filter mode gives us the flexibility to ignore the system's
-// reported delays. We do this for platforms which we believe provide results
-// which are incompatible with the AEC's expectations. Based on measurements
-// (some provided above) we set a conservative (i.e. lower than measured)
-// fixed delay.
-//
-// WEBRTC_UNTRUSTED_DELAY will only have an impact when |extended_filter_mode|
-// is enabled. See the note along with |DelayCorrection| in
-// echo_cancellation_impl.h for more details on the mode.
-//
-// Justification:
-// Chromium/Mac: Here, the true latency is so low (~10-20 ms), that it plays
-// havoc with the AEC's buffering. To avoid this, we set a fixed delay of 20 ms
-// and then compensate by rewinding by 10 ms (in wideband) through
-// kDelayDiffOffsetSamples. This trick does not seem to work for larger rewind
-// values, but fortunately this is sufficient.
-//
-// Chromium/Linux(ChromeOS): The values we get on this platform don't correspond
-// well to reality. The variance doesn't match the AEC's buffer changes, and the
-// bulk values tend to be too low. However, the range across different hardware
-// appears to be too large to choose a single value.
-//
-// GTP/Linux(ChromeOS): TBD, but for the moment we will trust the values.
-#if defined(WEBRTC_CHROMIUM_BUILD) && defined(WEBRTC_MAC)
-#define WEBRTC_UNTRUSTED_DELAY
-#endif
-
-#if defined(WEBRTC_UNTRUSTED_DELAY) && defined(WEBRTC_MAC)
-static const int kDelayDiffOffsetSamples = -160;
-#else
-// Not enabled for now.
-static const int kDelayDiffOffsetSamples = 0;
-#endif
-
-#if defined(WEBRTC_MAC)
-static const int kFixedDelayMs = 20;
-#else
-static const int kFixedDelayMs = 50;
-#endif
-#if !defined(WEBRTC_UNTRUSTED_DELAY)
-static const int kMinTrustedDelayMs = 20;
-#endif
-static const int kMaxTrustedDelayMs = 500;
-
-// Maximum length of resampled signal. Must be an integer multiple of frames
-// (ceil(1/(1 + MIN_SKEW)*2) + 1)*FRAME_LEN
-// The factor of 2 handles wb, and the + 1 is as a safety margin
-// TODO(bjornv): Replace with kResamplerBufferSize
-#define MAX_RESAMP_LEN (5 * FRAME_LEN)
-
-static const int kMaxBufSizeStart = 62;  // In partitions
-static const int sampMsNb = 8;           // samples per ms in nb
-static const int initCheck = 42;
-
-int Aec::instance_count = 0;
-
-// Estimates delay to set the position of the far-end buffer read pointer
-// (controlled by knownDelay)
-static void EstBufDelayNormal(Aec* aecInst);
-static void EstBufDelayExtended(Aec* aecInst);
-static int ProcessNormal(Aec* aecInst,
-                         const float* const* nearend,
-                         size_t num_bands,
-                         float* const* out,
-                         size_t num_samples,
-                         int16_t reported_delay_ms,
-                         int32_t skew);
-static void ProcessExtended(Aec* aecInst,
-                            const float* const* nearend,
-                            size_t num_bands,
-                            float* const* out,
-                            size_t num_samples,
-                            int16_t reported_delay_ms,
-                            int32_t skew);
-
-void* WebRtcAec_Create() {
-  Aec* aecpc = new Aec();
-
-  if (!aecpc) {
-    return NULL;
-  }
-  aecpc->data_dumper.reset(new ApmDataDumper(aecpc->instance_count));
-
-  aecpc->aec = WebRtcAec_CreateAec(aecpc->instance_count);
-  if (!aecpc->aec) {
-    WebRtcAec_Free(aecpc);
-    return NULL;
-  }
-  aecpc->resampler = WebRtcAec_CreateResampler();
-  if (!aecpc->resampler) {
-    WebRtcAec_Free(aecpc);
-    return NULL;
-  }
-  // Create far-end pre-buffer. The buffer size has to be large enough for
-  // largest possible drift compensation (kResamplerBufferSize) + "almost" an
-  // FFT buffer (PART_LEN2 - 1).
-  aecpc->far_pre_buf =
-      WebRtc_CreateBuffer(PART_LEN2 + kResamplerBufferSize, sizeof(float));
-  if (!aecpc->far_pre_buf) {
-    WebRtcAec_Free(aecpc);
-    return NULL;
-  }
-
-  aecpc->initFlag = 0;
-
-  aecpc->instance_count++;
-  return aecpc;
-}
-
-void WebRtcAec_Free(void* aecInst) {
-  Aec* aecpc = reinterpret_cast<Aec*>(aecInst);
-
-  if (aecpc == NULL) {
-    return;
-  }
-
-  WebRtc_FreeBuffer(aecpc->far_pre_buf);
-
-  WebRtcAec_FreeAec(aecpc->aec);
-  WebRtcAec_FreeResampler(aecpc->resampler);
-  delete aecpc;
-}
-
-int32_t WebRtcAec_Init(void* aecInst, int32_t sampFreq, int32_t scSampFreq) {
-  Aec* aecpc = reinterpret_cast<Aec*>(aecInst);
-  aecpc->data_dumper->InitiateNewSetOfRecordings();
-  AecConfig aecConfig;
-
-  if (sampFreq != 8000 && sampFreq != 16000 && sampFreq != 32000 &&
-      sampFreq != 48000) {
-    return AEC_BAD_PARAMETER_ERROR;
-  }
-  aecpc->sampFreq = sampFreq;
-
-  if (scSampFreq < 1 || scSampFreq > 96000) {
-    return AEC_BAD_PARAMETER_ERROR;
-  }
-  aecpc->scSampFreq = scSampFreq;
-
-  // Initialize echo canceller core
-  if (WebRtcAec_InitAec(aecpc->aec, aecpc->sampFreq) == -1) {
-    return AEC_UNSPECIFIED_ERROR;
-  }
-
-  if (WebRtcAec_InitResampler(aecpc->resampler, aecpc->scSampFreq) == -1) {
-    return AEC_UNSPECIFIED_ERROR;
-  }
-
-  WebRtc_InitBuffer(aecpc->far_pre_buf);
-  WebRtc_MoveReadPtr(aecpc->far_pre_buf, -PART_LEN);  // Start overlap.
-
-  aecpc->initFlag = initCheck;  // indicates that initialization has been done
-
-  if (aecpc->sampFreq == 32000 || aecpc->sampFreq == 48000) {
-    aecpc->splitSampFreq = 16000;
-  } else {
-    aecpc->splitSampFreq = sampFreq;
-  }
-
-  aecpc->delayCtr = 0;
-  aecpc->sampFactor = (aecpc->scSampFreq * 1.0f) / aecpc->splitSampFreq;
-  // Sampling frequency multiplier (SWB is processed as 160 frame size).
-  aecpc->rate_factor = aecpc->splitSampFreq / 8000;
-
-  aecpc->sum = 0;
-  aecpc->counter = 0;
-  aecpc->checkBuffSize = 1;
-  aecpc->firstVal = 0;
-
-  // We skip the startup_phase completely (setting to 0) if DA-AEC is enabled,
-  // but not extended_filter mode.
-  aecpc->startup_phase = WebRtcAec_extended_filter_enabled(aecpc->aec) ||
-                         !WebRtcAec_delay_agnostic_enabled(aecpc->aec);
-  aecpc->bufSizeStart = 0;
-  aecpc->checkBufSizeCtr = 0;
-  aecpc->msInSndCardBuf = 0;
-  aecpc->filtDelay = -1;  // -1 indicates an initialized state.
-  aecpc->timeForDelayChange = 0;
-  aecpc->knownDelay = 0;
-  aecpc->lastDelayDiff = 0;
-
-  aecpc->skewFrCtr = 0;
-  aecpc->resample = kAecFalse;
-  aecpc->highSkewCtr = 0;
-  aecpc->skew = 0;
-
-  aecpc->farend_started = 0;
-
-  // Default settings.
-  aecConfig.nlpMode = kAecNlpModerate;
-  aecConfig.skewMode = kAecFalse;
-  aecConfig.metricsMode = kAecFalse;
-  aecConfig.delay_logging = kAecFalse;
-
-  if (WebRtcAec_set_config(aecpc, aecConfig) == -1) {
-    return AEC_UNSPECIFIED_ERROR;
-  }
-
-  return 0;
-}
-
-// Returns any error that is caused when buffering the
-// far-end signal.
-int32_t WebRtcAec_GetBufferFarendError(void* aecInst,
-                                       const float* farend,
-                                       size_t nrOfSamples) {
-  Aec* aecpc = reinterpret_cast<Aec*>(aecInst);
-
-  if (!farend)
-    return AEC_NULL_POINTER_ERROR;
-
-  if (aecpc->initFlag != initCheck)
-    return AEC_UNINITIALIZED_ERROR;
-
-  // number of samples == 160 for SWB input
-  if (nrOfSamples != 80 && nrOfSamples != 160)
-    return AEC_BAD_PARAMETER_ERROR;
-
-  return 0;
-}
-
-// only buffer L band for farend
-int32_t WebRtcAec_BufferFarend(void* aecInst,
-                               const float* farend,
-                               size_t nrOfSamples) {
-  Aec* aecpc = reinterpret_cast<Aec*>(aecInst);
-  size_t newNrOfSamples = nrOfSamples;
-  float new_farend[MAX_RESAMP_LEN];
-  const float* farend_ptr = farend;
-
-  // Get any error caused by buffering the farend signal.
-  int32_t error_code =
-      WebRtcAec_GetBufferFarendError(aecInst, farend, nrOfSamples);
-
-  if (error_code != 0)
-    return error_code;
-
-  if (aecpc->skewMode == kAecTrue && aecpc->resample == kAecTrue) {
-    // Resample and get a new number of samples
-    WebRtcAec_ResampleLinear(aecpc->resampler, farend, nrOfSamples, aecpc->skew,
-                             new_farend, &newNrOfSamples);
-    farend_ptr = new_farend;
-  }
-
-  aecpc->farend_started = 1;
-  WebRtcAec_SetSystemDelay(aecpc->aec, WebRtcAec_system_delay(aecpc->aec) +
-                                           static_cast<int>(newNrOfSamples));
-
-  // Write the time-domain data to |far_pre_buf|.
-  WebRtc_WriteBuffer(aecpc->far_pre_buf, farend_ptr, newNrOfSamples);
-
-  // TODO(minyue): reduce to |PART_LEN| samples for each buffering.
-  while (WebRtc_available_read(aecpc->far_pre_buf) >= PART_LEN2) {
-    // We have enough data to pass to the FFT, hence read PART_LEN2 samples.
-    {
-      float* ptmp = NULL;
-      float tmp[PART_LEN2];
-      WebRtc_ReadBuffer(aecpc->far_pre_buf, reinterpret_cast<void**>(&ptmp),
-                        tmp, PART_LEN2);
-      WebRtcAec_BufferFarendBlock(aecpc->aec, &ptmp[PART_LEN]);
-    }
-
-    // Rewind |far_pre_buf| PART_LEN samples for overlap before continuing.
-    WebRtc_MoveReadPtr(aecpc->far_pre_buf, -PART_LEN);
-  }
-
-  return 0;
-}
-
-int32_t WebRtcAec_Process(void* aecInst,
-                          const float* const* nearend,
-                          size_t num_bands,
-                          float* const* out,
-                          size_t nrOfSamples,
-                          int16_t msInSndCardBuf,
-                          int32_t skew) {
-  Aec* aecpc = reinterpret_cast<Aec*>(aecInst);
-  int32_t retVal = 0;
-
-  if (out == NULL) {
-    return AEC_NULL_POINTER_ERROR;
-  }
-
-  if (aecpc->initFlag != initCheck) {
-    return AEC_UNINITIALIZED_ERROR;
-  }
-
-  // number of samples == 160 for SWB input
-  if (nrOfSamples != 80 && nrOfSamples != 160) {
-    return AEC_BAD_PARAMETER_ERROR;
-  }
-
-  if (msInSndCardBuf < 0) {
-    msInSndCardBuf = 0;
-    retVal = AEC_BAD_PARAMETER_WARNING;
-  } else if (msInSndCardBuf > kMaxTrustedDelayMs) {
-    // The clamping is now done in ProcessExtended/Normal().
-    retVal = AEC_BAD_PARAMETER_WARNING;
-  }
-
-  // This returns the value of aec->extended_filter_enabled.
-  if (WebRtcAec_extended_filter_enabled(aecpc->aec)) {
-    ProcessExtended(aecpc, nearend, num_bands, out, nrOfSamples, msInSndCardBuf,
-                    skew);
-  } else {
-    retVal = ProcessNormal(aecpc, nearend, num_bands, out, nrOfSamples,
-                           msInSndCardBuf, skew);
-  }
-
-  int far_buf_size_samples = WebRtcAec_system_delay(aecpc->aec);
-  aecpc->data_dumper->DumpRaw("aec_system_delay", 1, &far_buf_size_samples);
-  aecpc->data_dumper->DumpRaw("aec_known_delay", 1, &aecpc->knownDelay);
-
-  return retVal;
-}
-
-int WebRtcAec_set_config(void* handle, AecConfig config) {
-  Aec* self = reinterpret_cast<Aec*>(handle);
-  if (self->initFlag != initCheck) {
-    return AEC_UNINITIALIZED_ERROR;
-  }
-
-  if (config.skewMode != kAecFalse && config.skewMode != kAecTrue) {
-    return AEC_BAD_PARAMETER_ERROR;
-  }
-  self->skewMode = config.skewMode;
-
-  if (config.nlpMode != kAecNlpConservative &&
-      config.nlpMode != kAecNlpModerate &&
-      config.nlpMode != kAecNlpAggressive) {
-    return AEC_BAD_PARAMETER_ERROR;
-  }
-
-  if (config.metricsMode != kAecFalse && config.metricsMode != kAecTrue) {
-    return AEC_BAD_PARAMETER_ERROR;
-  }
-
-  if (config.delay_logging != kAecFalse && config.delay_logging != kAecTrue) {
-    return AEC_BAD_PARAMETER_ERROR;
-  }
-
-  WebRtcAec_SetConfigCore(self->aec, config.nlpMode, config.metricsMode,
-                          config.delay_logging);
-  return 0;
-}
-
-int WebRtcAec_get_echo_status(void* handle, int* status) {
-  Aec* self = reinterpret_cast<Aec*>(handle);
-  if (status == NULL) {
-    return AEC_NULL_POINTER_ERROR;
-  }
-  if (self->initFlag != initCheck) {
-    return AEC_UNINITIALIZED_ERROR;
-  }
-
-  *status = WebRtcAec_echo_state(self->aec);
-
-  return 0;
-}
-
-int WebRtcAec_GetMetrics(void* handle, AecMetrics* metrics) {
-  const float kUpWeight = 0.7f;
-  float dtmp;
-  int stmp;
-  Aec* self = reinterpret_cast<Aec*>(handle);
-  Stats erl;
-  Stats erle;
-  Stats a_nlp;
-
-  if (handle == NULL) {
-    return -1;
-  }
-  if (metrics == NULL) {
-    return AEC_NULL_POINTER_ERROR;
-  }
-  if (self->initFlag != initCheck) {
-    return AEC_UNINITIALIZED_ERROR;
-  }
-
-  WebRtcAec_GetEchoStats(self->aec, &erl, &erle, &a_nlp,
-                         &metrics->divergent_filter_fraction);
-
-  // ERL
-  metrics->erl.instant = static_cast<int>(erl.instant);
-
-  if ((erl.himean > kOffsetLevel) && (erl.average > kOffsetLevel)) {
-    // Use a mix between regular average and upper part average.
-    dtmp = kUpWeight * erl.himean + (1 - kUpWeight) * erl.average;
-    metrics->erl.average = static_cast<int>(dtmp);
-  } else {
-    metrics->erl.average = kOffsetLevel;
-  }
-
-  metrics->erl.max = static_cast<int>(erl.max);
-
-  if (erl.min < (kOffsetLevel * (-1))) {
-    metrics->erl.min = static_cast<int>(erl.min);
-  } else {
-    metrics->erl.min = kOffsetLevel;
-  }
-
-  // ERLE
-  metrics->erle.instant = static_cast<int>(erle.instant);
-
-  if ((erle.himean > kOffsetLevel) && (erle.average > kOffsetLevel)) {
-    // Use a mix between regular average and upper part average.
-    dtmp = kUpWeight * erle.himean + (1 - kUpWeight) * erle.average;
-    metrics->erle.average = static_cast<int>(dtmp);
-  } else {
-    metrics->erle.average = kOffsetLevel;
-  }
-
-  metrics->erle.max = static_cast<int>(erle.max);
-
-  if (erle.min < (kOffsetLevel * (-1))) {
-    metrics->erle.min = static_cast<int>(erle.min);
-  } else {
-    metrics->erle.min = kOffsetLevel;
-  }
-
-  // RERL
-  if ((metrics->erl.average > kOffsetLevel) &&
-      (metrics->erle.average > kOffsetLevel)) {
-    stmp = metrics->erl.average + metrics->erle.average;
-  } else {
-    stmp = kOffsetLevel;
-  }
-  metrics->rerl.average = stmp;
-
-  // No other statistics needed, but returned for completeness.
-  metrics->rerl.instant = stmp;
-  metrics->rerl.max = stmp;
-  metrics->rerl.min = stmp;
-
-  // A_NLP
-  metrics->aNlp.instant = static_cast<int>(a_nlp.instant);
-
-  if ((a_nlp.himean > kOffsetLevel) && (a_nlp.average > kOffsetLevel)) {
-    // Use a mix between regular average and upper part average.
-    dtmp = kUpWeight * a_nlp.himean + (1 - kUpWeight) * a_nlp.average;
-    metrics->aNlp.average = static_cast<int>(dtmp);
-  } else {
-    metrics->aNlp.average = kOffsetLevel;
-  }
-
-  metrics->aNlp.max = static_cast<int>(a_nlp.max);
-
-  if (a_nlp.min < (kOffsetLevel * (-1))) {
-    metrics->aNlp.min = static_cast<int>(a_nlp.min);
-  } else {
-    metrics->aNlp.min = kOffsetLevel;
-  }
-
-  return 0;
-}
-
-int WebRtcAec_GetDelayMetrics(void* handle,
-                              int* median,
-                              int* std,
-                              float* fraction_poor_delays) {
-  Aec* self = reinterpret_cast<Aec*>(handle);
-  if (median == NULL) {
-    return AEC_NULL_POINTER_ERROR;
-  }
-  if (std == NULL) {
-    return AEC_NULL_POINTER_ERROR;
-  }
-  if (self->initFlag != initCheck) {
-    return AEC_UNINITIALIZED_ERROR;
-  }
-  if (WebRtcAec_GetDelayMetricsCore(self->aec, median, std,
-                                    fraction_poor_delays) == -1) {
-    // Logging disabled.
-    return AEC_UNSUPPORTED_FUNCTION_ERROR;
-  }
-
-  return 0;
-}
-
-AecCore* WebRtcAec_aec_core(void* handle) {
-  if (!handle) {
-    return NULL;
-  }
-  return reinterpret_cast<Aec*>(handle)->aec;
-}
-
-static int ProcessNormal(Aec* aecInst,
-                         const float* const* nearend,
-                         size_t num_bands,
-                         float* const* out,
-                         size_t num_samples,
-                         int16_t reported_delay_ms,
-                         int32_t skew) {
-  int retVal = 0;
-  size_t i;
-  size_t nBlocks10ms;
-  // Limit resampling to doubling/halving of signal
-  const float minSkewEst = -0.5f;
-  const float maxSkewEst = 1.0f;
-
-  reported_delay_ms = reported_delay_ms > kMaxTrustedDelayMs
-                          ? kMaxTrustedDelayMs
-                          : reported_delay_ms;
-  // TODO(andrew): we need to investigate if this +10 is really wanted.
-  reported_delay_ms += 10;
-  aecInst->msInSndCardBuf = reported_delay_ms;
-
-  if (aecInst->skewMode == kAecTrue) {
-    if (aecInst->skewFrCtr < 25) {
-      aecInst->skewFrCtr++;
-    } else {
-      retVal = WebRtcAec_GetSkew(aecInst->resampler, skew, &aecInst->skew);
-      if (retVal == -1) {
-        aecInst->skew = 0;
-        retVal = AEC_BAD_PARAMETER_WARNING;
-      }
-
-      aecInst->skew /= aecInst->sampFactor * num_samples;
-
-      if (aecInst->skew < 1.0e-3 && aecInst->skew > -1.0e-3) {
-        aecInst->resample = kAecFalse;
-      } else {
-        aecInst->resample = kAecTrue;
-      }
-
-      if (aecInst->skew < minSkewEst) {
-        aecInst->skew = minSkewEst;
-      } else if (aecInst->skew > maxSkewEst) {
-        aecInst->skew = maxSkewEst;
-      }
-
-      aecInst->data_dumper->DumpRaw("aec_skew", 1, &aecInst->skew);
-    }
-  }
-
-  nBlocks10ms = num_samples / (FRAME_LEN * aecInst->rate_factor);
-
-  if (aecInst->startup_phase) {
-    for (i = 0; i < num_bands; ++i) {
-      // Only needed if they don't already point to the same place.
-      if (nearend[i] != out[i]) {
-        memcpy(out[i], nearend[i], sizeof(nearend[i][0]) * num_samples);
-      }
-    }
-
-    // The AEC is in the start up mode
-    // AEC is disabled until the system delay is OK
-
-    // Mechanism to ensure that the system delay is reasonably stable.
-    if (aecInst->checkBuffSize) {
-      aecInst->checkBufSizeCtr++;
-      // Before we fill up the far-end buffer we require the system delay
-      // to be stable (+/-8 ms) compared to the first value. This
-      // comparison is made during the following 6 consecutive 10 ms
-      // blocks. If it seems to be stable then we start to fill up the
-      // far-end buffer.
-      if (aecInst->counter == 0) {
-        aecInst->firstVal = aecInst->msInSndCardBuf;
-        aecInst->sum = 0;
-      }
-
-      if (abs(aecInst->firstVal - aecInst->msInSndCardBuf) <
-          WEBRTC_SPL_MAX(0.2 * aecInst->msInSndCardBuf, sampMsNb)) {
-        aecInst->sum += aecInst->msInSndCardBuf;
-        aecInst->counter++;
-      } else {
-        aecInst->counter = 0;
-      }
-
-      if (aecInst->counter * nBlocks10ms >= 6) {
-        // The far-end buffer size is determined in partitions of
-        // PART_LEN samples. Use 75% of the average value of the system
-        // delay as buffer size to start with.
-        aecInst->bufSizeStart =
-            WEBRTC_SPL_MIN((3 * aecInst->sum * aecInst->rate_factor * 8) /
-                               (4 * aecInst->counter * PART_LEN),
-                           kMaxBufSizeStart);
-        // Buffer size has now been determined.
-        aecInst->checkBuffSize = 0;
-      }
-
-      if (aecInst->checkBufSizeCtr * nBlocks10ms > 50) {
-        // For really bad systems, don't disable the echo canceller for
-        // more than 0.5 sec.
-        aecInst->bufSizeStart = WEBRTC_SPL_MIN(
-            (aecInst->msInSndCardBuf * aecInst->rate_factor * 3) / 40,
-            kMaxBufSizeStart);
-        aecInst->checkBuffSize = 0;
-      }
-    }
-
-    // If |checkBuffSize| changed in the if-statement above.
-    if (!aecInst->checkBuffSize) {
-      // The system delay is now reasonably stable (or has been unstable
-      // for too long). When the far-end buffer is filled with
-      // approximately the same amount of data as reported by the system
-      // we end the startup phase.
-      int overhead_elements = WebRtcAec_system_delay(aecInst->aec) / PART_LEN -
-                              aecInst->bufSizeStart;
-      if (overhead_elements == 0) {
-        // Enable the AEC
-        aecInst->startup_phase = 0;
-      } else if (overhead_elements > 0) {
-        // TODO(bjornv): Do we need a check on how much we actually
-        // moved the read pointer? It should always be possible to move
-        // the pointer |overhead_elements| since we have only added data
-        // to the buffer and no delay compensation nor AEC processing
-        // has been done.
-        WebRtcAec_AdjustFarendBufferSizeAndSystemDelay(aecInst->aec,
-                                                       overhead_elements);
-
-        // Enable the AEC
-        aecInst->startup_phase = 0;
-      }
-    }
-  } else {
-    // AEC is enabled.
-    EstBufDelayNormal(aecInst);
-
-    // Call the AEC.
-    // TODO(bjornv): Re-structure such that we don't have to pass
-    // |aecInst->knownDelay| as input. Change name to something like
-    // |system_buffer_diff|.
-    WebRtcAec_ProcessFrames(aecInst->aec, nearend, num_bands, num_samples,
-                            aecInst->knownDelay, out);
-  }
-
-  return retVal;
-}
-
-static void ProcessExtended(Aec* self,
-                            const float* const* nearend,
-                            size_t num_bands,
-                            float* const* out,
-                            size_t num_samples,
-                            int16_t reported_delay_ms,
-                            int32_t skew) {
-  size_t i;
-  const int delay_diff_offset = kDelayDiffOffsetSamples;
-  RTC_DCHECK(num_samples == 80 || num_samples == 160);
-#if defined(WEBRTC_UNTRUSTED_DELAY)
-  reported_delay_ms = kFixedDelayMs;
-#else
-  // This is the usual mode where we trust the reported system delay values.
-  // Due to the longer filter, we no longer add 10 ms to the reported delay
-  // to reduce chance of non-causality. Instead we apply a minimum here to avoid
-  // issues with the read pointer jumping around needlessly.
-  reported_delay_ms = reported_delay_ms < kMinTrustedDelayMs
-                          ? kMinTrustedDelayMs
-                          : reported_delay_ms;
-  // If the reported delay appears to be bogus, we attempt to recover by using
-  // the measured fixed delay values. We use >= here because higher layers
-  // may already clamp to this maximum value, and we would otherwise not
-  // detect it here.
-  reported_delay_ms = reported_delay_ms >= kMaxTrustedDelayMs
-                          ? kFixedDelayMs
-                          : reported_delay_ms;
-#endif
-  self->msInSndCardBuf = reported_delay_ms;
-
-  if (!self->farend_started) {
-    for (i = 0; i < num_bands; ++i) {
-      // Only needed if they don't already point to the same place.
-      if (nearend[i] != out[i]) {
-        memcpy(out[i], nearend[i], sizeof(nearend[i][0]) * num_samples);
-      }
-    }
-    return;
-  }
-  if (self->startup_phase) {
-    // In the extended mode, there isn't a startup "phase", just a special
-    // action on the first frame. In the trusted delay case, we'll take the
-    // current reported delay, unless it's less then our conservative
-    // measurement.
-    int startup_size_ms =
-        reported_delay_ms < kFixedDelayMs ? kFixedDelayMs : reported_delay_ms;
-#if defined(WEBRTC_ANDROID)
-    int target_delay = startup_size_ms * self->rate_factor * 8;
-#else
-    // To avoid putting the AEC in a non-causal state we're being slightly
-    // conservative and scale by 2. On Android we use a fixed delay and
-    // therefore there is no need to scale the target_delay.
-    int target_delay = startup_size_ms * self->rate_factor * 8 / 2;
-#endif
-    int overhead_elements =
-        (WebRtcAec_system_delay(self->aec) - target_delay) / PART_LEN;
-    WebRtcAec_AdjustFarendBufferSizeAndSystemDelay(self->aec,
-                                                   overhead_elements);
-    self->startup_phase = 0;
-  }
-
-  EstBufDelayExtended(self);
-
-  {
-    // |delay_diff_offset| gives us the option to manually rewind the delay on
-    // very low delay platforms which can't be expressed purely through
-    // |reported_delay_ms|.
-    const int adjusted_known_delay =
-        WEBRTC_SPL_MAX(0, self->knownDelay + delay_diff_offset);
-
-    WebRtcAec_ProcessFrames(self->aec, nearend, num_bands, num_samples,
-                            adjusted_known_delay, out);
-  }
-}
-
-static void EstBufDelayNormal(Aec* aecInst) {
-  int nSampSndCard = aecInst->msInSndCardBuf * sampMsNb * aecInst->rate_factor;
-  int current_delay = nSampSndCard - WebRtcAec_system_delay(aecInst->aec);
-  int delay_difference = 0;
-
-  // Before we proceed with the delay estimate filtering we:
-  // 1) Compensate for the frame that will be read.
-  // 2) Compensate for drift resampling.
-  // 3) Compensate for non-causality if needed, since the estimated delay can't
-  //    be negative.
-
-  // 1) Compensating for the frame(s) that will be read/processed.
-  current_delay += FRAME_LEN * aecInst->rate_factor;
-
-  // 2) Account for resampling frame delay.
-  if (aecInst->skewMode == kAecTrue && aecInst->resample == kAecTrue) {
-    current_delay -= kResamplingDelay;
-  }
-
-  // 3) Compensate for non-causality, if needed, by flushing one block.
-  if (current_delay < PART_LEN) {
-    current_delay +=
-        WebRtcAec_AdjustFarendBufferSizeAndSystemDelay(aecInst->aec, 1) *
-        PART_LEN;
-  }
-
-  // We use -1 to signal an initialized state in the "extended" implementation;
-  // compensate for that.
-  aecInst->filtDelay = aecInst->filtDelay < 0 ? 0 : aecInst->filtDelay;
-  aecInst->filtDelay = WEBRTC_SPL_MAX(
-      0, static_cast<int16_t>(0.8 * aecInst->filtDelay + 0.2 * current_delay));
-
-  delay_difference = aecInst->filtDelay - aecInst->knownDelay;
-  if (delay_difference > 224) {
-    if (aecInst->lastDelayDiff < 96) {
-      aecInst->timeForDelayChange = 0;
-    } else {
-      aecInst->timeForDelayChange++;
-    }
-  } else if (delay_difference < 96 && aecInst->knownDelay > 0) {
-    if (aecInst->lastDelayDiff > 224) {
-      aecInst->timeForDelayChange = 0;
-    } else {
-      aecInst->timeForDelayChange++;
-    }
-  } else {
-    aecInst->timeForDelayChange = 0;
-  }
-  aecInst->lastDelayDiff = delay_difference;
-
-  if (aecInst->timeForDelayChange > 25) {
-    aecInst->knownDelay = WEBRTC_SPL_MAX((int)aecInst->filtDelay - 160, 0);
-  }
-}
-
-static void EstBufDelayExtended(Aec* aecInst) {
-  int reported_delay =
-      aecInst->msInSndCardBuf * sampMsNb * aecInst->rate_factor;
-  int current_delay = reported_delay - WebRtcAec_system_delay(aecInst->aec);
-  int delay_difference = 0;
-
-  // Before we proceed with the delay estimate filtering we:
-  // 1) Compensate for the frame that will be read.
-  // 2) Compensate for drift resampling.
-  // 3) Compensate for non-causality if needed, since the estimated delay can't
-  //    be negative.
-
-  // 1) Compensating for the frame(s) that will be read/processed.
-  current_delay += FRAME_LEN * aecInst->rate_factor;
-
-  // 2) Account for resampling frame delay.
-  if (aecInst->skewMode == kAecTrue && aecInst->resample == kAecTrue) {
-    current_delay -= kResamplingDelay;
-  }
-
-  // 3) Compensate for non-causality, if needed, by flushing two blocks.
-  if (current_delay < PART_LEN) {
-    current_delay +=
-        WebRtcAec_AdjustFarendBufferSizeAndSystemDelay(aecInst->aec, 2) *
-        PART_LEN;
-  }
-
-  if (aecInst->filtDelay == -1) {
-    aecInst->filtDelay = WEBRTC_SPL_MAX(0, 0.5 * current_delay);
-  } else {
-    aecInst->filtDelay = WEBRTC_SPL_MAX(
-        0,
-        static_cast<int16_t>(0.95 * aecInst->filtDelay + 0.05 * current_delay));
-  }
-
-  delay_difference = aecInst->filtDelay - aecInst->knownDelay;
-  if (delay_difference > 384) {
-    if (aecInst->lastDelayDiff < 128) {
-      aecInst->timeForDelayChange = 0;
-    } else {
-      aecInst->timeForDelayChange++;
-    }
-  } else if (delay_difference < 128 && aecInst->knownDelay > 0) {
-    if (aecInst->lastDelayDiff > 384) {
-      aecInst->timeForDelayChange = 0;
-    } else {
-      aecInst->timeForDelayChange++;
-    }
-  } else {
-    aecInst->timeForDelayChange = 0;
-  }
-  aecInst->lastDelayDiff = delay_difference;
-
-  if (aecInst->timeForDelayChange > 25) {
-    aecInst->knownDelay = WEBRTC_SPL_MAX((int)aecInst->filtDelay - 256, 0);
-  }
-}
-}  // namespace webrtc
diff --git a/modules/audio_processing/aec/echo_cancellation.h b/modules/audio_processing/aec/echo_cancellation.h
deleted file mode 100644
index 62dc0f0..0000000
--- a/modules/audio_processing/aec/echo_cancellation.h
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef MODULES_AUDIO_PROCESSING_AEC_ECHO_CANCELLATION_H_
-#define MODULES_AUDIO_PROCESSING_AEC_ECHO_CANCELLATION_H_
-
-#include <stddef.h>
-
-#include <memory>
-
-extern "C" {
-#include "common_audio/ring_buffer.h"
-}
-#include "modules/audio_processing/aec/aec_core.h"
-
-namespace webrtc {
-
-// Errors
-#define AEC_UNSPECIFIED_ERROR 12000
-#define AEC_UNSUPPORTED_FUNCTION_ERROR 12001
-#define AEC_UNINITIALIZED_ERROR 12002
-#define AEC_NULL_POINTER_ERROR 12003
-#define AEC_BAD_PARAMETER_ERROR 12004
-
-// Warnings
-#define AEC_BAD_PARAMETER_WARNING 12050
-
-enum { kAecNlpConservative = 0, kAecNlpModerate, kAecNlpAggressive };
-
-enum { kAecFalse = 0, kAecTrue };
-
-typedef struct {
-  int16_t nlpMode;      // default kAecNlpModerate
-  int16_t skewMode;     // default kAecFalse
-  int16_t metricsMode;  // default kAecFalse
-  int delay_logging;    // default kAecFalse
-  // float realSkew;
-} AecConfig;
-
-typedef struct {
-  int instant;
-  int average;
-  int max;
-  int min;
-} AecLevel;
-
-typedef struct {
-  AecLevel rerl;
-  AecLevel erl;
-  AecLevel erle;
-  AecLevel aNlp;
-  float divergent_filter_fraction;
-} AecMetrics;
-
-struct AecCore;
-
-class ApmDataDumper;
-
-typedef struct Aec {
-  Aec();
-  ~Aec();
-
-  std::unique_ptr<ApmDataDumper> data_dumper;
-
-  int delayCtr;
-  int sampFreq;
-  int splitSampFreq;
-  int scSampFreq;
-  float sampFactor;  // scSampRate / sampFreq
-  short skewMode;
-  int bufSizeStart;
-  int knownDelay;
-  int rate_factor;
-
-  short initFlag;  // indicates if AEC has been initialized
-
-  // Variables used for averaging far end buffer size
-  short counter;
-  int sum;
-  short firstVal;
-  short checkBufSizeCtr;
-
-  // Variables used for delay shifts
-  short msInSndCardBuf;
-  short filtDelay;  // Filtered delay estimate.
-  int timeForDelayChange;
-  int startup_phase;
-  int checkBuffSize;
-  short lastDelayDiff;
-
-  // Structures
-  void* resampler;
-
-  int skewFrCtr;
-  int resample;  // if the skew is small enough we don't resample
-  int highSkewCtr;
-  float skew;
-
-  RingBuffer* far_pre_buf;  // Time domain far-end pre-buffer.
-
-  int farend_started;
-
-  // Aec instance counter.
-  static int instance_count;
-  AecCore* aec;
-} Aec;
-
-/*
- * Allocates the memory needed by the AEC. The memory needs to be initialized
- * separately using the WebRtcAec_Init() function. Returns a pointer to the
- * object or NULL on error.
- */
-void* WebRtcAec_Create();
-
-/*
- * This function releases the memory allocated by WebRtcAec_Create().
- *
- * Inputs                       Description
- * -------------------------------------------------------------------
- * void*        aecInst         Pointer to the AEC instance
- */
-void WebRtcAec_Free(void* aecInst);
-
-/*
- * Initializes an AEC instance.
- *
- * Inputs                       Description
- * -------------------------------------------------------------------
- * void*          aecInst       Pointer to the AEC instance
- * int32_t        sampFreq      Sampling frequency of data
- * int32_t        scSampFreq    Soundcard sampling frequency
- *
- * Outputs                      Description
- * -------------------------------------------------------------------
- * int32_t        return        0: OK
- *                             -1: error
- */
-int32_t WebRtcAec_Init(void* aecInst, int32_t sampFreq, int32_t scSampFreq);
-
-/*
- * Inserts an 80 or 160 sample block of data into the farend buffer.
- *
- * Inputs                       Description
- * -------------------------------------------------------------------
- * void*          aecInst       Pointer to the AEC instance
- * const float*   farend        In buffer containing one frame of
- *                              farend signal for L band
- * int16_t        nrOfSamples   Number of samples in farend buffer
- *
- * Outputs                      Description
- * -------------------------------------------------------------------
- * int32_t        return        0: OK
- *                              12000-12050: error code
- */
-int32_t WebRtcAec_BufferFarend(void* aecInst,
-                               const float* farend,
-                               size_t nrOfSamples);
-
-/*
- * Reports any errors that would arise if buffering a farend buffer
- *
- * Inputs                       Description
- * -------------------------------------------------------------------
- * void*          aecInst       Pointer to the AEC instance
- * const float*   farend        In buffer containing one frame of
- *                              farend signal for L band
- * int16_t        nrOfSamples   Number of samples in farend buffer
- *
- * Outputs                      Description
- * -------------------------------------------------------------------
- * int32_t        return        0: OK
- *                              12000-12050: error code
- */
-int32_t WebRtcAec_GetBufferFarendError(void* aecInst,
-                                       const float* farend,
-                                       size_t nrOfSamples);
-
-/*
- * Runs the echo canceller on an 80 or 160 sample blocks of data.
- *
- * Inputs                       Description
- * -------------------------------------------------------------------
- * void*         aecInst        Pointer to the AEC instance
- * float* const* nearend        In buffer containing one frame of
- *                              nearend+echo signal for each band
- * int           num_bands      Number of bands in nearend buffer
- * int16_t       nrOfSamples    Number of samples in nearend buffer
- * int16_t       msInSndCardBuf Delay estimate for sound card and
- *                              system buffers
- * int16_t       skew           Difference between number of samples played
- *                              and recorded at the soundcard (for clock skew
- *                              compensation)
- *
- * Outputs                      Description
- * -------------------------------------------------------------------
- * float* const* out            Out buffer, one frame of processed nearend
- *                              for each band
- * int32_t       return         0: OK
- *                              12000-12050: error code
- */
-int32_t WebRtcAec_Process(void* aecInst,
-                          const float* const* nearend,
-                          size_t num_bands,
-                          float* const* out,
-                          size_t nrOfSamples,
-                          int16_t msInSndCardBuf,
-                          int32_t skew);
-
-/*
- * This function enables the user to set certain parameters on-the-fly.
- *
- * Inputs                       Description
- * -------------------------------------------------------------------
- * void*          handle        Pointer to the AEC instance
- * AecConfig      config        Config instance that contains all
- *                              properties to be set
- *
- * Outputs                      Description
- * -------------------------------------------------------------------
- * int            return        0: OK
- *                              12000-12050: error code
- */
-int WebRtcAec_set_config(void* handle, AecConfig config);
-
-/*
- * Gets the current echo status of the nearend signal.
- *
- * Inputs                       Description
- * -------------------------------------------------------------------
- * void*          handle        Pointer to the AEC instance
- *
- * Outputs                      Description
- * -------------------------------------------------------------------
- * int*           status        0: Almost certainly nearend single-talk
- *                              1: Might not be neared single-talk
- * int            return        0: OK
- *                              12000-12050: error code
- */
-int WebRtcAec_get_echo_status(void* handle, int* status);
-
-/*
- * Gets the current echo metrics for the session.
- *
- * Inputs                       Description
- * -------------------------------------------------------------------
- * void*          handle        Pointer to the AEC instance
- *
- * Outputs                      Description
- * -------------------------------------------------------------------
- * AecMetrics*    metrics       Struct which will be filled out with the
- *                              current echo metrics.
- * int            return        0: OK
- *                              12000-12050: error code
- */
-int WebRtcAec_GetMetrics(void* handle, AecMetrics* metrics);
-
-/*
- * Gets the current delay metrics for the session.
- *
- * Inputs                       Description
- * -------------------------------------------------------------------
- * void*   handle               Pointer to the AEC instance
- *
- * Outputs                      Description
- * -------------------------------------------------------------------
- * int*    median               Delay median value.
- * int*    std                  Delay standard deviation.
- * float*  fraction_poor_delays Fraction of the delay estimates that may
- *                              cause the AEC to perform poorly.
- *
- * int            return        0: OK
- *                              12000-12050: error code
- */
-int WebRtcAec_GetDelayMetrics(void* handle,
-                              int* median,
-                              int* std,
-                              float* fraction_poor_delays);
-
-// Returns a pointer to the low level AEC handle.
-//
-// Input:
-//  - handle                    : Pointer to the AEC instance.
-//
-// Return value:
-//  - AecCore pointer           : NULL for error.
-//
-struct AecCore* WebRtcAec_aec_core(void* handle);
-
-}  // namespace webrtc
-
-#endif  // MODULES_AUDIO_PROCESSING_AEC_ECHO_CANCELLATION_H_
diff --git a/modules/audio_processing/aec/echo_cancellation_unittest.cc b/modules/audio_processing/aec/echo_cancellation_unittest.cc
deleted file mode 100644
index b9c89fd..0000000
--- a/modules/audio_processing/aec/echo_cancellation_unittest.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-// TODO(bjornv): Make this a comprehensive test.
-
-#include "modules/audio_processing/aec/echo_cancellation.h"
-
-#include <stdlib.h>
-#include <time.h>
-
-#include "modules/audio_processing/aec/aec_core.h"
-#include "rtc_base/checks.h"
-#include "test/gtest.h"
-
-namespace webrtc {
-
-TEST(EchoCancellationTest, CreateAndFreeHasExpectedBehavior) {
-  void* handle = WebRtcAec_Create();
-  ASSERT_TRUE(handle);
-  WebRtcAec_Free(nullptr);
-  WebRtcAec_Free(handle);
-}
-
-TEST(EchoCancellationTest, ApplyAecCoreHandle) {
-  void* handle = WebRtcAec_Create();
-  ASSERT_TRUE(handle);
-  EXPECT_TRUE(WebRtcAec_aec_core(NULL) == NULL);
-  AecCore* aec_core = WebRtcAec_aec_core(handle);
-  EXPECT_TRUE(aec_core != NULL);
-  // A simple test to verify that we can set and get a value from the lower
-  // level |aec_core| handle.
-  int delay = 111;
-  WebRtcAec_SetSystemDelay(aec_core, delay);
-  EXPECT_EQ(delay, WebRtcAec_system_delay(aec_core));
-  WebRtcAec_Free(handle);
-}
-
-}  // namespace webrtc
diff --git a/modules/audio_processing/aec/system_delay_unittest.cc b/modules/audio_processing/aec/system_delay_unittest.cc
deleted file mode 100644
index 9c57e8b..0000000
--- a/modules/audio_processing/aec/system_delay_unittest.cc
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "modules/audio_processing/aec/aec_core.h"
-#include "modules/audio_processing/aec/echo_cancellation.h"
-#include "rtc_base/numerics/safe_conversions.h"
-#include "test/gtest.h"
-namespace webrtc {
-namespace {
-
-class SystemDelayTest : public ::testing::Test {
- protected:
-  SystemDelayTest();
-  void SetUp() override;
-  void TearDown() override;
-
-  // Initialization of AEC handle with respect to |sample_rate_hz|. Since the
-  // device sample rate is unimportant we set that value to 48000 Hz.
-  void Init(int sample_rate_hz);
-
-  // Makes one render call and one capture call in that specific order.
-  void RenderAndCapture(int device_buffer_ms);
-
-  // Fills up the far-end buffer with respect to the default device buffer size.
-  size_t BufferFillUp();
-
-  // Runs and verifies the behavior in a stable startup procedure.
-  void RunStableStartup();
-
-  // Maps buffer size in ms into samples, taking the unprocessed frame into
-  // account.
-  int MapBufferSizeToSamples(int size_in_ms, bool extended_filter);
-
-  void* handle_;
-  Aec* self_;
-  size_t samples_per_frame_;
-  // Dummy input/output speech data.
-  static const int kSamplesPerChunk = 160;
-  float far_[kSamplesPerChunk];
-  float near_[kSamplesPerChunk];
-  float out_[kSamplesPerChunk];
-  const float* near_ptr_;
-  float* out_ptr_;
-};
-
-SystemDelayTest::SystemDelayTest()
-    : handle_(NULL), self_(NULL), samples_per_frame_(0) {
-  // Dummy input data are set with more or less arbitrary non-zero values.
-  for (int i = 0; i < kSamplesPerChunk; i++) {
-    far_[i] = 257.0;
-    near_[i] = 514.0;
-  }
-  memset(out_, 0, sizeof(out_));
-  near_ptr_ = near_;
-  out_ptr_ = out_;
-}
-
-void SystemDelayTest::SetUp() {
-  handle_ = WebRtcAec_Create();
-  ASSERT_TRUE(handle_);
-  self_ = reinterpret_cast<Aec*>(handle_);
-}
-
-void SystemDelayTest::TearDown() {
-  // Free AEC
-  WebRtcAec_Free(handle_);
-  handle_ = NULL;
-}
-
-// In SWB mode nothing is added to the buffer handling with respect to
-// functionality compared to WB. We therefore only verify behavior in NB and WB.
-static const int kSampleRateHz[] = {8000, 16000};
-static const size_t kNumSampleRates =
-    sizeof(kSampleRateHz) / sizeof(*kSampleRateHz);
-
-// Default audio device buffer size used.
-static const int kDeviceBufMs = 100;
-
-// Requirement for a stable device convergence time in ms. Should converge in
-// less than |kStableConvergenceMs|.
-static const int kStableConvergenceMs = 100;
-
-// Maximum convergence time in ms. This means that we should leave the startup
-// phase after |kMaxConvergenceMs| independent of device buffer stability
-// conditions.
-static const int kMaxConvergenceMs = 500;
-
-void SystemDelayTest::Init(int sample_rate_hz) {
-  // Initialize AEC
-  EXPECT_EQ(0, WebRtcAec_Init(handle_, sample_rate_hz, 48000));
-  EXPECT_EQ(0, WebRtcAec_system_delay(self_->aec));
-
-  // One frame equals 10 ms of data.
-  samples_per_frame_ = static_cast<size_t>(sample_rate_hz / 100);
-}
-
-void SystemDelayTest::RenderAndCapture(int device_buffer_ms) {
-  EXPECT_EQ(0, WebRtcAec_BufferFarend(handle_, far_, samples_per_frame_));
-  EXPECT_EQ(0, WebRtcAec_Process(handle_, &near_ptr_, 1, &out_ptr_,
-                                 samples_per_frame_, device_buffer_ms, 0));
-}
-
-size_t SystemDelayTest::BufferFillUp() {
-  // To make sure we have a full buffer when we verify stability we first fill
-  // up the far-end buffer with the same amount as we will report in through
-  // Process().
-  size_t buffer_size = 0;
-  for (int i = 0; i < kDeviceBufMs / 10; i++) {
-    EXPECT_EQ(0, WebRtcAec_BufferFarend(handle_, far_, samples_per_frame_));
-    buffer_size += samples_per_frame_;
-    EXPECT_EQ(static_cast<int>(buffer_size),
-              WebRtcAec_system_delay(self_->aec));
-  }
-  return buffer_size;
-}
-
-void SystemDelayTest::RunStableStartup() {
-  // To make sure we have a full buffer when we verify stability we first fill
-  // up the far-end buffer with the same amount as we will report in through
-  // Process().
-  size_t buffer_size = BufferFillUp();
-
-  if (WebRtcAec_delay_agnostic_enabled(self_->aec) == 1) {
-    // In extended_filter mode we set the buffer size after the first processed
-    // 10 ms chunk. Hence, we don't need to wait for the reported system delay
-    // values to become stable.
-    RenderAndCapture(kDeviceBufMs);
-    buffer_size += samples_per_frame_;
-    EXPECT_EQ(0, self_->startup_phase);
-  } else {
-    // A stable device should be accepted and put in a regular process mode
-    // within |kStableConvergenceMs|.
-    int process_time_ms = 0;
-    for (; process_time_ms < kStableConvergenceMs; process_time_ms += 10) {
-      RenderAndCapture(kDeviceBufMs);
-      buffer_size += samples_per_frame_;
-      if (self_->startup_phase == 0) {
-        // We have left the startup phase.
-        break;
-      }
-    }
-    // Verify convergence time.
-    EXPECT_GT(kStableConvergenceMs, process_time_ms);
-  }
-  // Verify that the buffer has been flushed.
-  EXPECT_GE(static_cast<int>(buffer_size), WebRtcAec_system_delay(self_->aec));
-}
-
-int SystemDelayTest::MapBufferSizeToSamples(int size_in_ms,
-                                            bool extended_filter) {
-  // If extended_filter is disabled we add an extra 10 ms for the unprocessed
-  // frame. That is simply how the algorithm is constructed.
-  return static_cast<int>((size_in_ms + (extended_filter ? 0 : 10)) *
-                          samples_per_frame_ / 10);
-}
-
-// The tests should meet basic requirements and not be adjusted to what is
-// actually implemented. If we don't get good code coverage this way we either
-// lack in tests or have unnecessary code.
-// General requirements:
-// 1) If we add far-end data the system delay should be increased with the same
-//    amount we add.
-// 2) If the far-end buffer is full we should flush the oldest data to make room
-//    for the new. In this case the system delay is unaffected.
-// 3) There should exist a startup phase in which the buffer size is to be
-//    determined. In this phase no cancellation should be performed.
-// 4) Under stable conditions (small variations in device buffer sizes) the AEC
-//    should determine an appropriate local buffer size within
-//    |kStableConvergenceMs| ms.
-// 5) Under unstable conditions the AEC should make a decision within
-//    |kMaxConvergenceMs| ms.
-// 6) If the local buffer runs out of data we should stuff the buffer with older
-//    frames.
-// 7) The system delay should within |kMaxConvergenceMs| ms heal from
-//    disturbances like drift, data glitches, toggling events and outliers.
-// 8) The system delay should never become negative.
-
-TEST_F(SystemDelayTest, CorrectIncreaseWhenBufferFarend) {
-  // When we add data to the AEC buffer the internal system delay should be
-  // incremented with the same amount as the size of data.
-  // This process should be independent of DA-AEC and extended_filter mode.
-  for (int extended_filter = 0; extended_filter <= 1; ++extended_filter) {
-    WebRtcAec_enable_extended_filter(self_->aec, extended_filter);
-    EXPECT_EQ(extended_filter, WebRtcAec_extended_filter_enabled(self_->aec));
-    for (int da_aec = 0; da_aec <= 1; ++da_aec) {
-      WebRtcAec_enable_delay_agnostic(self_->aec, da_aec);
-      EXPECT_EQ(da_aec, WebRtcAec_delay_agnostic_enabled(self_->aec));
-      for (size_t i = 0; i < kNumSampleRates; i++) {
-        Init(kSampleRateHz[i]);
-        // Loop through a couple of calls to make sure the system delay
-        // increments correctly.
-        for (int j = 1; j <= 5; j++) {
-          EXPECT_EQ(0,
-                    WebRtcAec_BufferFarend(handle_, far_, samples_per_frame_));
-          EXPECT_EQ(static_cast<int>(j * samples_per_frame_),
-                    WebRtcAec_system_delay(self_->aec));
-        }
-      }
-    }
-  }
-}
-
-// TODO(bjornv): Add a test to verify behavior if the far-end buffer is full
-// when adding new data.
-
-TEST_F(SystemDelayTest, CorrectDelayAfterStableStartup) {
-  // We run the system in a stable startup. After that we verify that the system
-  // delay meets the requirements.
-  // This process should be independent of DA-AEC and extended_filter mode.
-  for (int extended_filter = 0; extended_filter <= 1; ++extended_filter) {
-    WebRtcAec_enable_extended_filter(self_->aec, extended_filter);
-    EXPECT_EQ(extended_filter, WebRtcAec_extended_filter_enabled(self_->aec));
-    for (int da_aec = 0; da_aec <= 1; ++da_aec) {
-      WebRtcAec_enable_delay_agnostic(self_->aec, da_aec);
-      EXPECT_EQ(da_aec, WebRtcAec_delay_agnostic_enabled(self_->aec));
-      for (size_t i = 0; i < kNumSampleRates; i++) {
-        Init(kSampleRateHz[i]);
-        RunStableStartup();
-
-        // Verify system delay with respect to requirements, i.e., the
-        // |system_delay| is in the interval [75%, 100%] of what's reported on
-        // the average.
-        // In extended_filter mode we target 50% and measure after one processed
-        // 10 ms chunk.
-        int average_reported_delay =
-            static_cast<int>(kDeviceBufMs * samples_per_frame_ / 10);
-        EXPECT_GE(average_reported_delay, WebRtcAec_system_delay(self_->aec));
-        int lower_bound = WebRtcAec_extended_filter_enabled(self_->aec)
-                              ? (average_reported_delay / 2 -
-                                 rtc::checked_cast<int>(samples_per_frame_))
-                              : average_reported_delay * 3 / 4;
-        EXPECT_LE(lower_bound, WebRtcAec_system_delay(self_->aec));
-      }
-    }
-  }
-}
-
-TEST_F(SystemDelayTest, CorrectDelayAfterUnstableStartup) {
-  // This test does not apply in extended_filter mode, since we only use the
-  // the first 10 ms chunk to determine a reasonable buffer size. Neither does
-  // it apply if DA-AEC is on because that overrides the startup procedure.
-  WebRtcAec_enable_extended_filter(self_->aec, 0);
-  EXPECT_EQ(0, WebRtcAec_extended_filter_enabled(self_->aec));
-  WebRtcAec_enable_delay_agnostic(self_->aec, 0);
-  EXPECT_EQ(0, WebRtcAec_delay_agnostic_enabled(self_->aec));
-
-  // In an unstable system we would start processing after |kMaxConvergenceMs|.
-  // On the last frame the AEC buffer is adjusted to 60% of the last reported
-  // device buffer size.
-  // We construct an unstable system by altering the device buffer size between
-  // two values |kDeviceBufMs| +- 25 ms.
-  for (size_t i = 0; i < kNumSampleRates; i++) {
-    Init(kSampleRateHz[i]);
-
-    // To make sure we have a full buffer when we verify stability we first fill
-    // up the far-end buffer with the same amount as we will report in on the
-    // average through Process().
-    size_t buffer_size = BufferFillUp();
-
-    int buffer_offset_ms = 25;
-    int reported_delay_ms = 0;
-    int process_time_ms = 0;
-    for (; process_time_ms <= kMaxConvergenceMs; process_time_ms += 10) {
-      reported_delay_ms = kDeviceBufMs + buffer_offset_ms;
-      RenderAndCapture(reported_delay_ms);
-      buffer_size += samples_per_frame_;
-      buffer_offset_ms = -buffer_offset_ms;
-      if (self_->startup_phase == 0) {
-        // We have left the startup phase.
-        break;
-      }
-    }
-    // Verify convergence time.
-    EXPECT_GE(kMaxConvergenceMs, process_time_ms);
-    // Verify that the buffer has been flushed.
-    EXPECT_GE(static_cast<int>(buffer_size),
-              WebRtcAec_system_delay(self_->aec));
-
-    // Verify system delay with respect to requirements, i.e., the
-    // |system_delay| is in the interval [60%, 100%] of what's last reported.
-    EXPECT_GE(static_cast<int>(reported_delay_ms * samples_per_frame_ / 10),
-              WebRtcAec_system_delay(self_->aec));
-    EXPECT_LE(
-        static_cast<int>(reported_delay_ms * samples_per_frame_ / 10 * 3 / 5),
-        WebRtcAec_system_delay(self_->aec));
-  }
-}
-
-TEST_F(SystemDelayTest, CorrectDelayAfterStableBufferBuildUp) {
-  // This test does not apply in extended_filter mode, since we only use the
-  // the first 10 ms chunk to determine a reasonable buffer size. Neither does
-  // it apply if DA-AEC is on because that overrides the startup procedure.
-  WebRtcAec_enable_extended_filter(self_->aec, 0);
-  EXPECT_EQ(0, WebRtcAec_extended_filter_enabled(self_->aec));
-  WebRtcAec_enable_delay_agnostic(self_->aec, 0);
-  EXPECT_EQ(0, WebRtcAec_delay_agnostic_enabled(self_->aec));
-
-  // In this test we start by establishing the device buffer size during stable
-  // conditions, but with an empty internal far-end buffer. Once that is done we
-  // verify that the system delay is increased correctly until we have reach an
-  // internal buffer size of 75% of what's been reported.
-  for (size_t i = 0; i < kNumSampleRates; i++) {
-    Init(kSampleRateHz[i]);
-
-    // We assume that running |kStableConvergenceMs| calls will put the
-    // algorithm in a state where the device buffer size has been determined. We
-    // can make that assumption since we have a separate stability test.
-    int process_time_ms = 0;
-    for (; process_time_ms < kStableConvergenceMs; process_time_ms += 10) {
-      EXPECT_EQ(0, WebRtcAec_Process(handle_, &near_ptr_, 1, &out_ptr_,
-                                     samples_per_frame_, kDeviceBufMs, 0));
-    }
-    // Verify that a buffer size has been established.
-    EXPECT_EQ(0, self_->checkBuffSize);
-
-    // We now have established the required buffer size. Let us verify that we
-    // fill up before leaving the startup phase for normal processing.
-    size_t buffer_size = 0;
-    size_t target_buffer_size = kDeviceBufMs * samples_per_frame_ / 10 * 3 / 4;
-    process_time_ms = 0;
-    for (; process_time_ms <= kMaxConvergenceMs; process_time_ms += 10) {
-      RenderAndCapture(kDeviceBufMs);
-      buffer_size += samples_per_frame_;
-      if (self_->startup_phase == 0) {
-        // We have left the startup phase.
-        break;
-      }
-    }
-    // Verify convergence time.
-    EXPECT_GT(kMaxConvergenceMs, process_time_ms);
-    // Verify that the buffer has reached the desired size.
-    EXPECT_LE(static_cast<int>(target_buffer_size),
-              WebRtcAec_system_delay(self_->aec));
-
-    // Verify normal behavior (system delay is kept constant) after startup by
-    // running a couple of calls to BufferFarend() and Process().
-    for (int j = 0; j < 6; j++) {
-      int system_delay_before_calls = WebRtcAec_system_delay(self_->aec);
-      RenderAndCapture(kDeviceBufMs);
-      EXPECT_EQ(system_delay_before_calls, WebRtcAec_system_delay(self_->aec));
-    }
-  }
-}
-
-TEST_F(SystemDelayTest, CorrectDelayWhenBufferUnderrun) {
-  // Here we test a buffer under run scenario. If we keep on calling
-  // WebRtcAec_Process() we will finally run out of data, but should
-  // automatically stuff the buffer. We verify this behavior by checking if the
-  // system delay goes negative.
-  // This process should be independent of DA-AEC and extended_filter mode.
-  for (int extended_filter = 0; extended_filter <= 1; ++extended_filter) {
-    WebRtcAec_enable_extended_filter(self_->aec, extended_filter);
-    EXPECT_EQ(extended_filter, WebRtcAec_extended_filter_enabled(self_->aec));
-    for (int da_aec = 0; da_aec <= 1; ++da_aec) {
-      WebRtcAec_enable_delay_agnostic(self_->aec, da_aec);
-      EXPECT_EQ(da_aec, WebRtcAec_delay_agnostic_enabled(self_->aec));
-      for (size_t i = 0; i < kNumSampleRates; i++) {
-        Init(kSampleRateHz[i]);
-        RunStableStartup();
-
-        // The AEC has now left the Startup phase. We now have at most
-        // |kStableConvergenceMs| in the buffer. Keep on calling Process() until
-        // we run out of data and verify that the system delay is non-negative.
-        for (int j = 0; j <= kStableConvergenceMs; j += 10) {
-          EXPECT_EQ(0, WebRtcAec_Process(handle_, &near_ptr_, 1, &out_ptr_,
-                                         samples_per_frame_, kDeviceBufMs, 0));
-          EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
-        }
-      }
-    }
-  }
-}
-
-TEST_F(SystemDelayTest, CorrectDelayDuringDrift) {
-  // This drift test should verify that the system delay is never exceeding the
-  // device buffer. The drift is simulated by decreasing the reported device
-  // buffer size by 1 ms every 100 ms. If the device buffer size goes below 30
-  // ms we jump (add) 10 ms to give a repeated pattern.
-
-  // This process should be independent of DA-AEC and extended_filter mode.
-  for (int extended_filter = 0; extended_filter <= 1; ++extended_filter) {
-    WebRtcAec_enable_extended_filter(self_->aec, extended_filter);
-    EXPECT_EQ(extended_filter, WebRtcAec_extended_filter_enabled(self_->aec));
-    for (int da_aec = 0; da_aec <= 1; ++da_aec) {
-      WebRtcAec_enable_delay_agnostic(self_->aec, da_aec);
-      EXPECT_EQ(da_aec, WebRtcAec_delay_agnostic_enabled(self_->aec));
-      for (size_t i = 0; i < kNumSampleRates; i++) {
-        Init(kSampleRateHz[i]);
-        RunStableStartup();
-
-        // We have left the startup phase and proceed with normal processing.
-        int jump = 0;
-        for (int j = 0; j < 1000; j++) {
-          // Drift = -1 ms per 100 ms of data.
-          int device_buf_ms = kDeviceBufMs - (j / 10) + jump;
-          int device_buf =
-              MapBufferSizeToSamples(device_buf_ms, extended_filter == 1);
-
-          if (device_buf_ms < 30) {
-            // Add 10 ms data, taking affect next frame.
-            jump += 10;
-          }
-          RenderAndCapture(device_buf_ms);
-
-          // Verify that the system delay does not exceed the device buffer.
-          EXPECT_GE(device_buf, WebRtcAec_system_delay(self_->aec));
-
-          // Verify that the system delay is non-negative.
-          EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
-        }
-      }
-    }
-  }
-}
-
-TEST_F(SystemDelayTest, ShouldRecoverAfterGlitch) {
-  // This glitch test should verify that the system delay recovers if there is
-  // a glitch in data. The data glitch is constructed as 200 ms of buffering
-  // after which the stable procedure continues. The glitch is never reported by
-  // the device.
-  // The system is said to be in a non-causal state if the difference between
-  // the device buffer and system delay is less than a block (64 samples).
-
-  // This process should be independent of DA-AEC and extended_filter mode.
-  for (int extended_filter = 0; extended_filter <= 1; ++extended_filter) {
-    WebRtcAec_enable_extended_filter(self_->aec, extended_filter);
-    EXPECT_EQ(extended_filter, WebRtcAec_extended_filter_enabled(self_->aec));
-    for (int da_aec = 0; da_aec <= 1; ++da_aec) {
-      WebRtcAec_enable_delay_agnostic(self_->aec, da_aec);
-      EXPECT_EQ(da_aec, WebRtcAec_delay_agnostic_enabled(self_->aec));
-      for (size_t i = 0; i < kNumSampleRates; i++) {
-        Init(kSampleRateHz[i]);
-        RunStableStartup();
-        int device_buf =
-            MapBufferSizeToSamples(kDeviceBufMs, extended_filter == 1);
-        // Glitch state.
-        for (int j = 0; j < 20; j++) {
-          EXPECT_EQ(0,
-                    WebRtcAec_BufferFarend(handle_, far_, samples_per_frame_));
-          // No need to verify system delay, since that is done in a separate
-          // test.
-        }
-        // Verify that we are in a non-causal state, i.e.,
-        // |system_delay| > |device_buf|.
-        EXPECT_LT(device_buf, WebRtcAec_system_delay(self_->aec));
-
-        // Recover state. Should recover at least 4 ms of data per 10 ms, hence
-        // a glitch of 200 ms will take at most 200 * 10 / 4 = 500 ms to recover
-        // from.
-        bool non_causal = true;  // We are currently in a non-causal state.
-        for (int j = 0; j < 50; j++) {
-          int system_delay_before = WebRtcAec_system_delay(self_->aec);
-          RenderAndCapture(kDeviceBufMs);
-          int system_delay_after = WebRtcAec_system_delay(self_->aec);
-          // We have recovered if
-          // |device_buf| - |system_delay_after| >= PART_LEN (1 block).
-          // During recovery, |system_delay_after| < |system_delay_before|,
-          // otherwise they are equal.
-          if (non_causal) {
-            EXPECT_LT(system_delay_after, system_delay_before);
-            if (device_buf - system_delay_after >= PART_LEN) {
-              non_causal = false;
-            }
-          } else {
-            EXPECT_EQ(system_delay_before, system_delay_after);
-          }
-          // Verify that the system delay is non-negative.
-          EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
-        }
-        // Check that we have recovered.
-        EXPECT_FALSE(non_causal);
-      }
-    }
-  }
-}
-
-TEST_F(SystemDelayTest, UnaffectedWhenSpuriousDeviceBufferValues) {
-  // This test does not apply in extended_filter mode, since we only use the
-  // the first 10 ms chunk to determine a reasonable buffer size.
-  const int extended_filter = 0;
-  WebRtcAec_enable_extended_filter(self_->aec, extended_filter);
-  EXPECT_EQ(extended_filter, WebRtcAec_extended_filter_enabled(self_->aec));
-
-  // Should be DA-AEC independent.
-  for (int da_aec = 0; da_aec <= 1; ++da_aec) {
-    WebRtcAec_enable_delay_agnostic(self_->aec, da_aec);
-    EXPECT_EQ(da_aec, WebRtcAec_delay_agnostic_enabled(self_->aec));
-    // This spurious device buffer data test aims at verifying that the system
-    // delay is unaffected by large outliers.
-    // The system is said to be in a non-causal state if the difference between
-    // the device buffer and system delay is less than a block (64 samples).
-    for (size_t i = 0; i < kNumSampleRates; i++) {
-      Init(kSampleRateHz[i]);
-      RunStableStartup();
-      int device_buf =
-          MapBufferSizeToSamples(kDeviceBufMs, extended_filter == 1);
-
-      // Normal state. We are currently not in a non-causal state.
-      bool non_causal = false;
-
-      // Run 1 s and replace device buffer size with 500 ms every 100 ms.
-      for (int j = 0; j < 100; j++) {
-        int system_delay_before_calls = WebRtcAec_system_delay(self_->aec);
-        int device_buf_ms = j % 10 == 0 ? 500 : kDeviceBufMs;
-        RenderAndCapture(device_buf_ms);
-
-        // Check for non-causality.
-        if (device_buf - WebRtcAec_system_delay(self_->aec) < PART_LEN) {
-          non_causal = true;
-        }
-        EXPECT_FALSE(non_causal);
-        EXPECT_EQ(system_delay_before_calls,
-                  WebRtcAec_system_delay(self_->aec));
-
-        // Verify that the system delay is non-negative.
-        EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
-      }
-    }
-  }
-}
-
-TEST_F(SystemDelayTest, CorrectImpactWhenTogglingDeviceBufferValues) {
-  // This test aims at verifying that the system delay is "unaffected" by
-  // toggling values reported by the device.
-  // The test is constructed such that every other device buffer value is zero
-  // and then 2 * |kDeviceBufMs|, hence the size is constant on the average. The
-  // zero values will force us into a non-causal state and thereby lowering the
-  // system delay until we basically run out of data. Once that happens the
-  // buffer will be stuffed.
-  // TODO(bjornv): This test will have a better impact if we verified that the
-  // delay estimate goes up when the system delay goes down to meet the average
-  // device buffer size.
-
-  // This test does not apply if DA-AEC is enabled and extended_filter mode
-  // disabled.
-  for (int extended_filter = 0; extended_filter <= 1; ++extended_filter) {
-    WebRtcAec_enable_extended_filter(self_->aec, extended_filter);
-    EXPECT_EQ(extended_filter, WebRtcAec_extended_filter_enabled(self_->aec));
-    for (int da_aec = 0; da_aec <= 1; ++da_aec) {
-      WebRtcAec_enable_delay_agnostic(self_->aec, da_aec);
-      EXPECT_EQ(da_aec, WebRtcAec_delay_agnostic_enabled(self_->aec));
-      if (extended_filter == 0 && da_aec == 1) {
-        continue;
-      }
-      for (size_t i = 0; i < kNumSampleRates; i++) {
-        Init(kSampleRateHz[i]);
-        RunStableStartup();
-        const int device_buf =
-            MapBufferSizeToSamples(kDeviceBufMs, extended_filter == 1);
-
-        // Normal state. We are currently not in a non-causal state.
-        bool non_causal = false;
-
-        // Loop through 100 frames (both render and capture), which equals 1 s
-        // of data. Every odd frame we set the device buffer size to
-        // 2 * |kDeviceBufMs| and even frames we set the device buffer size to
-        // zero.
-        for (int j = 0; j < 100; j++) {
-          int system_delay_before_calls = WebRtcAec_system_delay(self_->aec);
-          int device_buf_ms = 2 * (j % 2) * kDeviceBufMs;
-          RenderAndCapture(device_buf_ms);
-
-          // Check for non-causality, compared with the average device buffer
-          // size.
-          non_causal |= (device_buf - WebRtcAec_system_delay(self_->aec) < 64);
-          EXPECT_GE(system_delay_before_calls,
-                    WebRtcAec_system_delay(self_->aec));
-
-          // Verify that the system delay is non-negative.
-          EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
-        }
-        // Verify we are not in a non-causal state.
-        EXPECT_FALSE(non_causal);
-      }
-    }
-  }
-}
-
-}  // namespace
-}  // namespace webrtc
diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc
index 97a8379..4d9cdb4 100644
--- a/modules/audio_processing/audio_processing_impl.cc
+++ b/modules/audio_processing/audio_processing_impl.cc
@@ -155,7 +155,6 @@
 
 bool AudioProcessingImpl::SubmoduleStates::Update(
     bool high_pass_filter_enabled,
-    bool echo_canceller_enabled,
     bool mobile_echo_controller_enabled,
     bool residual_echo_detector_enabled,
     bool noise_suppressor_enabled,
@@ -167,7 +166,6 @@
     bool transient_suppressor_enabled) {
   bool changed = false;
   changed |= (high_pass_filter_enabled != high_pass_filter_enabled_);
-  changed |= (echo_canceller_enabled != echo_canceller_enabled_);
   changed |=
       (mobile_echo_controller_enabled != mobile_echo_controller_enabled_);
   changed |=
@@ -182,7 +180,6 @@
   changed |= (transient_suppressor_enabled != transient_suppressor_enabled_);
   if (changed) {
     high_pass_filter_enabled_ = high_pass_filter_enabled;
-    echo_canceller_enabled_ = echo_canceller_enabled;
     mobile_echo_controller_enabled_ = mobile_echo_controller_enabled;
     residual_echo_detector_enabled_ = residual_echo_detector_enabled;
     noise_suppressor_enabled_ = noise_suppressor_enabled;
@@ -212,9 +209,8 @@
 
 bool AudioProcessingImpl::SubmoduleStates::CaptureMultiBandProcessingActive(
     bool ec_processing_active) const {
-  return high_pass_filter_enabled_ || echo_canceller_enabled_ ||
-         mobile_echo_controller_enabled_ || noise_suppressor_enabled_ ||
-         adaptive_gain_controller_enabled_ ||
+  return high_pass_filter_enabled_ || mobile_echo_controller_enabled_ ||
+         noise_suppressor_enabled_ || adaptive_gain_controller_enabled_ ||
          (echo_controller_enabled_ && ec_processing_active);
 }
 
@@ -230,9 +226,8 @@
 
 bool AudioProcessingImpl::SubmoduleStates::RenderMultiBandSubModulesActive()
     const {
-  return RenderMultiBandProcessingActive() || echo_canceller_enabled_ ||
-         mobile_echo_controller_enabled_ || adaptive_gain_controller_enabled_ ||
-         echo_controller_enabled_;
+  return RenderMultiBandProcessingActive() || mobile_echo_controller_enabled_ ||
+         adaptive_gain_controller_enabled_ || echo_controller_enabled_;
 }
 
 bool AudioProcessingImpl::SubmoduleStates::RenderFullBandProcessingActive()
@@ -246,8 +241,8 @@
 }
 
 bool AudioProcessingImpl::SubmoduleStates::HighPassFilteringRequired() const {
-  return high_pass_filter_enabled_ || echo_canceller_enabled_ ||
-         mobile_echo_controller_enabled_ || noise_suppressor_enabled_;
+  return high_pass_filter_enabled_ || mobile_echo_controller_enabled_ ||
+         noise_suppressor_enabled_;
 }
 
 AudioProcessingBuilder::AudioProcessingBuilder() = default;
@@ -638,12 +633,7 @@
 
   const bool aec_config_changed =
       config_.echo_canceller.enabled != config.echo_canceller.enabled ||
-      config_.echo_canceller.use_legacy_aec !=
-          config.echo_canceller.use_legacy_aec ||
-      config_.echo_canceller.mobile_mode != config.echo_canceller.mobile_mode ||
-      (config_.echo_canceller.enabled && config.echo_canceller.use_legacy_aec &&
-       config_.echo_canceller.legacy_moderate_suppression_level !=
-           config.echo_canceller.legacy_moderate_suppression_level);
+      config_.echo_canceller.mobile_mode != config.echo_canceller.mobile_mode;
 
   const bool agc1_config_changed =
       config_.gain_controller1.enabled != config.gain_controller1.enabled ||
@@ -668,6 +658,9 @@
 
   config_ = config;
 
+  // Ensure that this deprecated setting is not used by mistake.
+  RTC_DCHECK(!config_.echo_canceller.use_legacy_aec);
+
   if (aec_config_changed) {
     InitializeEchoController();
   }
@@ -737,13 +730,6 @@
   rtc::CritScope cs_render(&crit_render_);
   rtc::CritScope cs_capture(&crit_capture_);
 
-  capture_nonlocked_.use_aec2_extended_filter =
-      config.Get<ExtendedFilter>().enabled;
-  capture_nonlocked_.use_aec2_delay_agnostic =
-      config.Get<DelayAgnostic>().enabled;
-  capture_nonlocked_.use_aec2_refined_adaptive_filter =
-      config.Get<RefinedAdaptiveFilter>().enabled;
-
   if (capture_.transient_suppressor_enabled !=
       config.Get<ExperimentalNs>().enabled) {
     capture_.transient_suppressor_enabled =
@@ -997,23 +983,6 @@
 void AudioProcessingImpl::QueueBandedRenderAudio(AudioBuffer* audio) {
   RTC_DCHECK_GE(160, audio->num_frames_per_band());
 
-  // Insert the samples into the queue.
-  if (submodules_.echo_cancellation) {
-    RTC_DCHECK(aec_render_signal_queue_);
-    EchoCancellationImpl::PackRenderAudioBuffer(audio, num_output_channels(),
-                                                num_reverse_channels(),
-                                                &aec_render_queue_buffer_);
-
-    if (!aec_render_signal_queue_->Insert(&aec_render_queue_buffer_)) {
-      // The data queue is full and needs to be emptied.
-      EmptyQueuedRenderAudio();
-
-      // Retry the insert (should always work).
-      bool result = aec_render_signal_queue_->Insert(&aec_render_queue_buffer_);
-      RTC_DCHECK(result);
-    }
-  }
-
   if (submodules_.echo_control_mobile) {
     EchoControlMobileImpl::PackRenderAudioBuffer(audio, num_output_channels(),
                                                  num_reverse_channels(),
@@ -1110,14 +1079,6 @@
 
 void AudioProcessingImpl::EmptyQueuedRenderAudio() {
   rtc::CritScope cs_capture(&crit_capture_);
-  if (submodules_.echo_cancellation) {
-    RTC_DCHECK(aec_render_signal_queue_);
-    while (aec_render_signal_queue_->Remove(&aec_capture_queue_buffer_)) {
-      submodules_.echo_cancellation->ProcessRenderAudio(
-          aec_capture_queue_buffer_);
-    }
-  }
-
   if (submodules_.echo_control_mobile) {
     RTC_DCHECK(aecm_render_signal_queue_);
     while (aecm_render_signal_queue_->Remove(&aecm_capture_queue_buffer_)) {
@@ -1236,7 +1197,6 @@
   // TODO(peah): Simplify once the public API Enable functions for these
   // are moved to APM.
   RTC_DCHECK_LE(!!submodules_.echo_controller +
-                    !!submodules_.echo_cancellation +
                     !!submodules_.echo_control_mobile,
                 1);
 
@@ -1350,15 +1310,6 @@
       AudioBuffer* linear_aec_buffer = capture_.linear_aec_output.get();
       submodules_.echo_controller->ProcessCapture(
           capture_buffer, linear_aec_buffer, capture_.echo_path_gain_change);
-    } else if (submodules_.echo_cancellation) {
-      // Ensure that the stream delay was set before the call to the
-      // AEC ProcessCaptureAudio function.
-      if (!was_stream_delay_set()) {
-        return AudioProcessing::kStreamParameterNotSetError;
-      }
-
-      RETURN_ON_ERR(submodules_.echo_cancellation->ProcessCaptureAudio(
-          capture_buffer, stream_delay_ms()));
     }
 
     if (submodules_.noise_suppressor) {
@@ -1387,8 +1338,7 @@
   }
   // TODO(peah): Add reporting from AEC3 whether there is echo.
   RETURN_ON_ERR(submodules_.gain_control->ProcessCaptureAudio(
-      capture_buffer, submodules_.echo_cancellation &&
-                          submodules_.echo_cancellation->stream_has_echo()));
+      capture_buffer, /*stream_has_echo*/ false));
 
   if (submodule_states_.CaptureMultiBandProcessingPresent() &&
       SampleRateSupportsMultiBand(
@@ -1754,7 +1704,6 @@
     return capture_.stats;
   }
   AudioProcessingStats stats = capture_.stats;
-  EchoCancellationImpl::Metrics metrics;
   if (submodules_.echo_controller) {
     auto ec_metrics = submodules_.echo_controller->GetMetrics();
     stats.echo_return_loss = ec_metrics.echo_return_loss;
@@ -1788,8 +1737,8 @@
 
 bool AudioProcessingImpl::UpdateActiveSubmoduleStates() {
   return submodule_states_.Update(
-      config_.high_pass_filter.enabled, !!submodules_.echo_cancellation,
-      !!submodules_.echo_control_mobile, config_.residual_echo_detector.enabled,
+      config_.high_pass_filter.enabled, !!submodules_.echo_control_mobile,
+      config_.residual_echo_detector.enabled,
       !!submodules_.legacy_noise_suppressor || !!submodules_.noise_suppressor,
       submodules_.gain_control->is_enabled(), config_.gain_controller2.enabled,
       config_.pre_amplifier.enabled, capture_nonlocked_.echo_controller_enabled,
@@ -1831,8 +1780,7 @@
 void AudioProcessingImpl::InitializeEchoController() {
   bool use_echo_controller =
       echo_control_factory_ ||
-      (config_.echo_canceller.enabled && !config_.echo_canceller.mobile_mode &&
-       !config_.echo_canceller.use_legacy_aec);
+      (config_.echo_canceller.enabled && !config_.echo_canceller.mobile_mode);
 
   if (use_echo_controller) {
     // Create and activate the echo controller.
@@ -1863,8 +1811,6 @@
 
     capture_nonlocked_.echo_controller_enabled = true;
 
-    submodules_.echo_cancellation.reset();
-    aec_render_signal_queue_.reset();
     submodules_.echo_control_mobile.reset();
     aecm_render_signal_queue_.reset();
     return;
@@ -1875,8 +1821,6 @@
   capture_.linear_aec_output.reset();
 
   if (!config_.echo_canceller.enabled) {
-    submodules_.echo_cancellation.reset();
-    aec_render_signal_queue_.reset();
     submodules_.echo_control_mobile.reset();
     aecm_render_signal_queue_.reset();
     return;
@@ -1905,46 +1849,11 @@
     submodules_.echo_control_mobile->Initialize(proc_split_sample_rate_hz(),
                                                 num_reverse_channels(),
                                                 num_output_channels());
-
-    submodules_.echo_cancellation.reset();
-    aec_render_signal_queue_.reset();
     return;
   }
 
   submodules_.echo_control_mobile.reset();
   aecm_render_signal_queue_.reset();
-
-  // Create and activate AEC2.
-  submodules_.echo_cancellation.reset(new EchoCancellationImpl());
-  submodules_.echo_cancellation->SetExtraOptions(
-      capture_nonlocked_.use_aec2_extended_filter,
-      capture_nonlocked_.use_aec2_delay_agnostic,
-      capture_nonlocked_.use_aec2_refined_adaptive_filter);
-
-  size_t element_max_size =
-      std::max(static_cast<size_t>(1),
-               kMaxAllowedValuesOfSamplesPerBand *
-                   EchoCancellationImpl::NumCancellersRequired(
-                       num_output_channels(), num_reverse_channels()));
-
-  std::vector<float> template_queue_element(element_max_size);
-
-  aec_render_signal_queue_.reset(
-      new SwapQueue<std::vector<float>, RenderQueueItemVerifier<float>>(
-          kMaxNumFramesToBuffer, template_queue_element,
-          RenderQueueItemVerifier<float>(element_max_size)));
-
-  aec_render_queue_buffer_.resize(element_max_size);
-  aec_capture_queue_buffer_.resize(element_max_size);
-
-  submodules_.echo_cancellation->Initialize(
-      proc_sample_rate_hz(), num_reverse_channels(), num_output_channels(),
-      num_proc_channels());
-
-  submodules_.echo_cancellation->set_suppression_level(
-      config_.echo_canceller.legacy_moderate_suppression_level
-          ? EchoCancellationImpl::SuppressionLevel::kModerateSuppression
-          : EchoCancellationImpl::SuppressionLevel::kHighSuppression);
 }
 
 void AudioProcessingImpl::InitializeGainController2() {
@@ -2039,10 +1948,6 @@
   }
 
   std::string experiments_description = "";
-  if (submodules_.echo_cancellation) {
-    experiments_description +=
-        submodules_.echo_cancellation->GetExperimentsDescription();
-  }
   // TODO(peah): Add semicolon-separated concatenations of experiment
   // descriptions for other submodules.
   if (constants_.agc_clipped_level_min != kClippedLevelMin) {
@@ -2058,19 +1963,9 @@
   InternalAPMConfig apm_config;
 
   apm_config.aec_enabled = config_.echo_canceller.enabled;
-  apm_config.aec_delay_agnostic_enabled =
-      submodules_.echo_cancellation &&
-      submodules_.echo_cancellation->is_delay_agnostic_enabled();
-  apm_config.aec_drift_compensation_enabled =
-      submodules_.echo_cancellation &&
-      submodules_.echo_cancellation->is_drift_compensation_enabled();
-  apm_config.aec_extended_filter_enabled =
-      submodules_.echo_cancellation &&
-      submodules_.echo_cancellation->is_extended_filter_enabled();
-  apm_config.aec_suppression_level =
-      submodules_.echo_cancellation
-          ? static_cast<int>(submodules_.echo_cancellation->suppression_level())
-          : 0;
+  apm_config.aec_delay_agnostic_enabled = false;
+  apm_config.aec_extended_filter_enabled = false;
+  apm_config.aec_suppression_level = 0;
 
   apm_config.aecm_enabled = !!submodules_.echo_control_mobile;
   apm_config.aecm_comfort_noise_enabled =
@@ -2151,10 +2046,7 @@
   RTC_DCHECK(aec_dump_);
   AecDump::AudioProcessingState audio_proc_state;
   audio_proc_state.delay = capture_nonlocked_.stream_delay_ms;
-  audio_proc_state.drift =
-      submodules_.echo_cancellation
-          ? submodules_.echo_cancellation->stream_drift_samples()
-          : 0;
+  audio_proc_state.drift = 0;
   audio_proc_state.level = recommended_stream_analog_level();
   audio_proc_state.keypress = capture_.key_pressed;
   aec_dump_->AddAudioProcessingState(audio_proc_state);
diff --git a/modules/audio_processing/audio_processing_impl.h b/modules/audio_processing/audio_processing_impl.h
index e5d0573..dcc2fa6 100644
--- a/modules/audio_processing/audio_processing_impl.h
+++ b/modules/audio_processing/audio_processing_impl.h
@@ -20,7 +20,6 @@
 #include "modules/audio_processing/agc/agc_manager_direct.h"
 #include "modules/audio_processing/agc/gain_control.h"
 #include "modules/audio_processing/audio_buffer.h"
-#include "modules/audio_processing/echo_cancellation_impl.h"
 #include "modules/audio_processing/echo_control_mobile_impl.h"
 #include "modules/audio_processing/gain_control_impl.h"
 #include "modules/audio_processing/gain_controller2.h"
@@ -171,7 +170,6 @@
                     bool capture_analyzer_enabled);
     // Updates the submodule state and returns true if it has changed.
     bool Update(bool high_pass_filter_enabled,
-                bool echo_canceller_enabled,
                 bool mobile_echo_controller_enabled,
                 bool residual_echo_detector_enabled,
                 bool noise_suppressor_enabled,
@@ -196,7 +194,6 @@
     const bool render_pre_processor_enabled_ = false;
     const bool capture_analyzer_enabled_ = false;
     bool high_pass_filter_enabled_ = false;
-    bool echo_canceller_enabled_ = false;
     bool mobile_echo_controller_enabled_ = false;
     bool residual_echo_detector_enabled_ = false;
     bool noise_suppressor_enabled_ = false;
@@ -337,7 +334,6 @@
     std::unique_ptr<GainController2> gain_controller2;
     std::unique_ptr<HighPassFilter> high_pass_filter;
     rtc::scoped_refptr<EchoDetector> echo_detector;
-    std::unique_ptr<EchoCancellationImpl> echo_cancellation;
     std::unique_ptr<EchoControl> echo_controller;
     std::unique_ptr<EchoControlMobileImpl> echo_control_mobile;
     std::unique_ptr<NoiseSuppression> legacy_noise_suppressor;
@@ -436,9 +432,6 @@
     int split_rate;
     int stream_delay_ms;
     bool echo_controller_enabled = false;
-    bool use_aec2_extended_filter = false;
-    bool use_aec2_delay_agnostic = false;
-    bool use_aec2_refined_adaptive_filter = false;
   } capture_nonlocked_;
 
   struct ApmRenderState {
@@ -469,8 +462,6 @@
   int capture_rms_interval_counter_ RTC_GUARDED_BY(crit_capture_) = 0;
 
   // Lock protection not needed.
-  std::unique_ptr<SwapQueue<std::vector<float>, RenderQueueItemVerifier<float>>>
-      aec_render_signal_queue_;
   std::unique_ptr<
       SwapQueue<std::vector<int16_t>, RenderQueueItemVerifier<int16_t>>>
       aecm_render_signal_queue_;
diff --git a/modules/audio_processing/audio_processing_impl_locking_unittest.cc b/modules/audio_processing/audio_processing_impl_locking_unittest.cc
index 9aa3f7a..d09e979 100644
--- a/modules/audio_processing/audio_processing_impl_locking_unittest.cc
+++ b/modules/audio_processing/audio_processing_impl_locking_unittest.cc
@@ -551,17 +551,6 @@
   apm_config.voice_detection.enabled = true;
   apm_config.level_estimation.enabled = true;
   apm_->ApplyConfig(apm_config);
-
-  Config config;
-  config.Set<ExtendedFilter>(
-      new ExtendedFilter(test_config_.aec_type ==
-                         AecType::BasicWebRtcAecSettingsWithExtentedFilter));
-
-  config.Set<DelayAgnostic>(
-      new DelayAgnostic(test_config_.aec_type ==
-                        AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec));
-
-  apm_->SetExtraOptions(config);
 }
 
 void AudioProcessingImplLockTest::TearDown() {
diff --git a/modules/audio_processing/audio_processing_performance_unittest.cc b/modules/audio_processing/audio_processing_performance_unittest.cc
index ebb2480..2ed6f17 100644
--- a/modules/audio_processing/audio_processing_performance_unittest.cc
+++ b/modules/audio_processing/audio_processing_performance_unittest.cc
@@ -483,12 +483,6 @@
       apm->ApplyConfig(apm_config);
     };
 
-    // Lambda function for adding default desktop APM settings to a config.
-    auto add_default_desktop_config = [](Config* config) {
-      config->Set<ExtendedFilter>(new ExtendedFilter(true));
-      config->Set<DelayAgnostic>(new DelayAgnostic(true));
-    };
-
     int num_capture_channels = 1;
     switch (simulation_config_.simulation_settings) {
       case SettingsType::kDefaultApmMobile: {
@@ -499,7 +493,6 @@
       }
       case SettingsType::kDefaultApmDesktop: {
         Config config;
-        add_default_desktop_config(&config);
         apm_.reset(AudioProcessingBuilder().Create(config));
         ASSERT_TRUE(!!apm_);
         set_default_desktop_apm_runtime_settings(apm_.get());
@@ -514,8 +507,6 @@
       }
       case SettingsType::kDefaultApmDesktopWithoutDelayAgnostic: {
         Config config;
-        config.Set<ExtendedFilter>(new ExtendedFilter(true));
-        config.Set<DelayAgnostic>(new DelayAgnostic(false));
         apm_.reset(AudioProcessingBuilder().Create(config));
         ASSERT_TRUE(!!apm_);
         set_default_desktop_apm_runtime_settings(apm_.get());
@@ -524,8 +515,6 @@
       }
       case SettingsType::kDefaultApmDesktopWithoutExtendedFilter: {
         Config config;
-        config.Set<ExtendedFilter>(new ExtendedFilter(false));
-        config.Set<DelayAgnostic>(new DelayAgnostic(true));
         apm_.reset(AudioProcessingBuilder().Create(config));
         ASSERT_TRUE(!!apm_);
         set_default_desktop_apm_runtime_settings(apm_.get());
diff --git a/modules/audio_processing/audio_processing_unittest.cc b/modules/audio_processing/audio_processing_unittest.cc
index 8f29a73..0fd07bf 100644
--- a/modules/audio_processing/audio_processing_unittest.cc
+++ b/modules/audio_processing/audio_processing_unittest.cc
@@ -1536,8 +1536,6 @@
 
     Config config;
     config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
-    config.Set<ExtendedFilter>(
-        new ExtendedFilter(test->use_aec_extended_filter()));
     apm_.reset(AudioProcessingBuilder().Create(config));
 
     EnableAllComponents();
diff --git a/modules/audio_processing/echo_cancellation_bit_exact_unittest.cc b/modules/audio_processing/echo_cancellation_bit_exact_unittest.cc
deleted file mode 100644
index c8c665e..0000000
--- a/modules/audio_processing/echo_cancellation_bit_exact_unittest.cc
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-#include <vector>
-
-#include "api/array_view.h"
-#include "modules/audio_processing/audio_buffer.h"
-#include "modules/audio_processing/echo_cancellation_impl.h"
-#include "modules/audio_processing/test/audio_buffer_tools.h"
-#include "modules/audio_processing/test/bitexactness_tools.h"
-#include "test/gtest.h"
-
-namespace webrtc {
-namespace {
-
-const int kNumFramesToProcess = 100;
-
-void SetupComponent(int sample_rate_hz,
-                    EchoCancellationImpl::SuppressionLevel suppression_level,
-                    bool drift_compensation_enabled,
-                    EchoCancellationImpl* echo_canceller) {
-  echo_canceller->Initialize(sample_rate_hz, 1, 1, 1);
-  echo_canceller->set_suppression_level(suppression_level);
-  echo_canceller->enable_drift_compensation(drift_compensation_enabled);
-
-  Config config;
-  config.Set<DelayAgnostic>(new DelayAgnostic(true));
-  config.Set<ExtendedFilter>(new ExtendedFilter(true));
-  echo_canceller->SetExtraOptions(true, true, false);
-}
-
-void ProcessOneFrame(int sample_rate_hz,
-                     int stream_delay_ms,
-                     bool drift_compensation_enabled,
-                     int stream_drift_samples,
-                     AudioBuffer* render_audio_buffer,
-                     AudioBuffer* capture_audio_buffer,
-                     EchoCancellationImpl* echo_canceller) {
-  if (sample_rate_hz > AudioProcessing::kSampleRate16kHz) {
-    render_audio_buffer->SplitIntoFrequencyBands();
-    capture_audio_buffer->SplitIntoFrequencyBands();
-  }
-
-  std::vector<float> render_audio;
-  EchoCancellationImpl::PackRenderAudioBuffer(
-      render_audio_buffer, 1, render_audio_buffer->num_channels(),
-      &render_audio);
-  echo_canceller->ProcessRenderAudio(render_audio);
-
-  if (drift_compensation_enabled) {
-    echo_canceller->set_stream_drift_samples(stream_drift_samples);
-  }
-
-  echo_canceller->ProcessCaptureAudio(capture_audio_buffer, stream_delay_ms);
-
-  if (sample_rate_hz > AudioProcessing::kSampleRate16kHz) {
-    capture_audio_buffer->MergeFrequencyBands();
-  }
-}
-
-void RunBitexactnessTest(
-    int sample_rate_hz,
-    size_t num_channels,
-    int stream_delay_ms,
-    bool drift_compensation_enabled,
-    int stream_drift_samples,
-    EchoCancellationImpl::SuppressionLevel suppression_level,
-    bool stream_has_echo_reference,
-    const rtc::ArrayView<const float>& output_reference) {
-  EchoCancellationImpl echo_canceller;
-  SetupComponent(sample_rate_hz, suppression_level, drift_compensation_enabled,
-                 &echo_canceller);
-
-  const int samples_per_channel = rtc::CheckedDivExact(sample_rate_hz, 100);
-  const StreamConfig render_config(sample_rate_hz, num_channels, false);
-  AudioBuffer render_buffer(
-      render_config.sample_rate_hz(), render_config.num_channels(),
-      render_config.sample_rate_hz(), 1, render_config.sample_rate_hz(), 1);
-  test::InputAudioFile render_file(
-      test::GetApmRenderTestVectorFileName(sample_rate_hz));
-  std::vector<float> render_input(samples_per_channel * num_channels);
-
-  const StreamConfig capture_config(sample_rate_hz, num_channels, false);
-  AudioBuffer capture_buffer(
-      capture_config.sample_rate_hz(), capture_config.num_channels(),
-      capture_config.sample_rate_hz(), 1, capture_config.sample_rate_hz(), 1);
-  test::InputAudioFile capture_file(
-      test::GetApmCaptureTestVectorFileName(sample_rate_hz));
-  std::vector<float> capture_input(samples_per_channel * num_channels);
-
-  for (int frame_no = 0; frame_no < kNumFramesToProcess; ++frame_no) {
-    ReadFloatSamplesFromStereoFile(samples_per_channel, num_channels,
-                                   &render_file, render_input);
-    ReadFloatSamplesFromStereoFile(samples_per_channel, num_channels,
-                                   &capture_file, capture_input);
-
-    test::CopyVectorToAudioBuffer(render_config, render_input, &render_buffer);
-    test::CopyVectorToAudioBuffer(capture_config, capture_input,
-                                  &capture_buffer);
-
-    ProcessOneFrame(sample_rate_hz, stream_delay_ms, drift_compensation_enabled,
-                    stream_drift_samples, &render_buffer, &capture_buffer,
-                    &echo_canceller);
-  }
-
-  // Extract and verify the test results.
-  std::vector<float> capture_output;
-  test::ExtractVectorFromAudioBuffer(capture_config, &capture_buffer,
-                                     &capture_output);
-
-  EXPECT_EQ(stream_has_echo_reference, echo_canceller.stream_has_echo());
-
-  // Compare the output with the reference. Only the first values of the output
-  // from last frame processed are compared in order not having to specify all
-  // preceeding frames as testvectors. As the algorithm being tested has a
-  // memory, testing only the last frame implicitly also tests the preceeding
-  // frames.
-  const float kElementErrorBound = 1.0f / 32768.0f;
-  EXPECT_TRUE(test::VerifyDeinterleavedArray(
-      capture_config.num_frames(), capture_config.num_channels(),
-      output_reference, capture_output, kElementErrorBound));
-}
-
-const bool kStreamHasEchoReference = true;
-
-}  // namespace
-
-// TODO(peah): Activate all these tests for ARM and ARM64 once the issue on the
-// Chromium ARM and ARM64 boths have been identified. This is tracked in the
-// issue https://bugs.chromium.org/p/webrtc/issues/detail?id=5711.
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
-      defined(WEBRTC_ANDROID))
-TEST(EchoCancellationBitExactnessTest,
-     Mono8kHz_HighLevel_NoDrift_StreamDelay0) {
-#else
-TEST(EchoCancellationBitExactnessTest,
-     DISABLED_Mono8kHz_HighLevel_NoDrift_StreamDelay0) {
-#endif
-  const float kOutputReference[] = {-0.000646f, -0.001525f, 0.002688f};
-  RunBitexactnessTest(8000, 1, 0, false, 0,
-                      EchoCancellationImpl::SuppressionLevel::kHighSuppression,
-                      kStreamHasEchoReference, kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
-      defined(WEBRTC_ANDROID))
-TEST(EchoCancellationBitExactnessTest,
-     Mono16kHz_HighLevel_NoDrift_StreamDelay0) {
-#else
-TEST(EchoCancellationBitExactnessTest,
-     DISABLED_Mono16kHz_HighLevel_NoDrift_StreamDelay0) {
-#endif
-  const float kOutputReference[] = {0.000055f, 0.000421f, 0.001149f};
-  RunBitexactnessTest(16000, 1, 0, false, 0,
-                      EchoCancellationImpl::SuppressionLevel::kHighSuppression,
-                      kStreamHasEchoReference, kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
-      defined(WEBRTC_ANDROID))
-TEST(EchoCancellationBitExactnessTest,
-     Mono32kHz_HighLevel_NoDrift_StreamDelay0) {
-#else
-TEST(EchoCancellationBitExactnessTest,
-     DISABLED_Mono32kHz_HighLevel_NoDrift_StreamDelay0) {
-#endif
-  const float kOutputReference[] = {-0.000671f, 0.000061f, -0.000031f};
-  RunBitexactnessTest(32000, 1, 0, false, 0,
-                      EchoCancellationImpl::SuppressionLevel::kHighSuppression,
-                      kStreamHasEchoReference, kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
-      defined(WEBRTC_ANDROID))
-TEST(EchoCancellationBitExactnessTest,
-     Mono48kHz_HighLevel_NoDrift_StreamDelay0) {
-#else
-TEST(EchoCancellationBitExactnessTest,
-     DISABLED_Mono48kHz_HighLevel_NoDrift_StreamDelay0) {
-#endif
-  const float kOutputReference[] = {-0.001403f, -0.001411f, -0.000755f};
-  RunBitexactnessTest(48000, 1, 0, false, 0,
-                      EchoCancellationImpl::SuppressionLevel::kHighSuppression,
-                      kStreamHasEchoReference, kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
-      defined(WEBRTC_ANDROID))
-TEST(EchoCancellationBitExactnessTest,
-     Mono16kHz_LowLevel_NoDrift_StreamDelay0) {
-#else
-TEST(EchoCancellationBitExactnessTest,
-     DISABLED_Mono16kHz_LowLevel_NoDrift_StreamDelay0) {
-#endif
-#if defined(WEBRTC_MAC)
-  const float kOutputReference[] = {-0.000145f, 0.000179f, 0.000917f};
-#else
-  const float kOutputReference[] = {-0.000009f, 0.000363f, 0.001094f};
-#endif
-  RunBitexactnessTest(16000, 1, 0, false, 0,
-                      EchoCancellationImpl::SuppressionLevel::kLowSuppression,
-                      kStreamHasEchoReference, kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
-      defined(WEBRTC_ANDROID))
-TEST(EchoCancellationBitExactnessTest,
-     Mono16kHz_ModerateLevel_NoDrift_StreamDelay0) {
-#else
-TEST(EchoCancellationBitExactnessTest,
-     DISABLED_Mono16kHz_ModerateLevel_NoDrift_StreamDelay0) {
-#endif
-  const float kOutputReference[] = {0.000055f, 0.000421f, 0.001149f};
-  RunBitexactnessTest(
-      16000, 1, 0, false, 0,
-      EchoCancellationImpl::SuppressionLevel::kModerateSuppression,
-      kStreamHasEchoReference, kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
-      defined(WEBRTC_ANDROID))
-TEST(EchoCancellationBitExactnessTest,
-     Mono16kHz_HighLevel_NoDrift_StreamDelay10) {
-#else
-TEST(EchoCancellationBitExactnessTest,
-     DISABLED_Mono16kHz_HighLevel_NoDrift_StreamDelay10) {
-#endif
-  const float kOutputReference[] = {0.000055f, 0.000421f, 0.001149f};
-  RunBitexactnessTest(16000, 1, 10, false, 0,
-                      EchoCancellationImpl::SuppressionLevel::kHighSuppression,
-                      kStreamHasEchoReference, kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
-      defined(WEBRTC_ANDROID))
-TEST(EchoCancellationBitExactnessTest,
-     Mono16kHz_HighLevel_NoDrift_StreamDelay20) {
-#else
-TEST(EchoCancellationBitExactnessTest,
-     DISABLED_Mono16kHz_HighLevel_NoDrift_StreamDelay20) {
-#endif
-  const float kOutputReference[] = {0.000055f, 0.000421f, 0.001149f};
-  RunBitexactnessTest(16000, 1, 20, false, 0,
-                      EchoCancellationImpl::SuppressionLevel::kHighSuppression,
-                      kStreamHasEchoReference, kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
-      defined(WEBRTC_ANDROID))
-TEST(EchoCancellationBitExactnessTest,
-     Mono16kHz_HighLevel_Drift0_StreamDelay0) {
-#else
-TEST(EchoCancellationBitExactnessTest,
-     DISABLED_Mono16kHz_HighLevel_Drift0_StreamDelay0) {
-#endif
-  const float kOutputReference[] = {0.000055f, 0.000421f, 0.001149f};
-  RunBitexactnessTest(16000, 1, 0, true, 0,
-                      EchoCancellationImpl::SuppressionLevel::kHighSuppression,
-                      kStreamHasEchoReference, kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
-      defined(WEBRTC_ANDROID))
-TEST(EchoCancellationBitExactnessTest,
-     Mono16kHz_HighLevel_Drift5_StreamDelay0) {
-#else
-TEST(EchoCancellationBitExactnessTest,
-     DISABLED_Mono16kHz_HighLevel_Drift5_StreamDelay0) {
-#endif
-  const float kOutputReference[] = {0.000055f, 0.000421f, 0.001149f};
-  RunBitexactnessTest(16000, 1, 0, true, 5,
-                      EchoCancellationImpl::SuppressionLevel::kHighSuppression,
-                      kStreamHasEchoReference, kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
-      defined(WEBRTC_ANDROID))
-TEST(EchoCancellationBitExactnessTest,
-     Stereo8kHz_HighLevel_NoDrift_StreamDelay0) {
-#else
-TEST(EchoCancellationBitExactnessTest,
-     DISABLED_Stereo8kHz_HighLevel_NoDrift_StreamDelay0) {
-#endif
-#if defined(WEBRTC_MAC)
-  const float kOutputReference[] = {-0.000392f, -0.001449f, 0.003004f,
-                                    -0.000392f, -0.001449f, 0.003004f};
-#else
-  const float kOutputReference[] = {-0.000464f, -0.001525f, 0.002933f,
-                                    -0.000464f, -0.001525f, 0.002933f};
-#endif
-  RunBitexactnessTest(8000, 2, 0, false, 0,
-                      EchoCancellationImpl::SuppressionLevel::kHighSuppression,
-                      kStreamHasEchoReference, kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
-      defined(WEBRTC_ANDROID))
-TEST(EchoCancellationBitExactnessTest,
-     Stereo16kHz_HighLevel_NoDrift_StreamDelay0) {
-#else
-TEST(EchoCancellationBitExactnessTest,
-     DISABLED_Stereo16kHz_HighLevel_NoDrift_StreamDelay0) {
-#endif
-  const float kOutputReference[] = {0.000166f, 0.000735f, 0.000841f,
-                                    0.000166f, 0.000735f, 0.000841f};
-  RunBitexactnessTest(16000, 2, 0, false, 0,
-                      EchoCancellationImpl::SuppressionLevel::kHighSuppression,
-                      kStreamHasEchoReference, kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
-      defined(WEBRTC_ANDROID))
-TEST(EchoCancellationBitExactnessTest,
-     Stereo32kHz_HighLevel_NoDrift_StreamDelay0) {
-#else
-TEST(EchoCancellationBitExactnessTest,
-     DISABLED_Stereo32kHz_HighLevel_NoDrift_StreamDelay0) {
-#endif
-#if defined(WEBRTC_MAC)
-  const float kOutputReference[] = {-0.000458f, 0.000214f, 0.000122f,
-                                    -0.000458f, 0.000214f, 0.000122f};
-#else
-  const float kOutputReference[] = {-0.000427f, 0.000183f, 0.000183f,
-                                    -0.000427f, 0.000183f, 0.000183f};
-#endif
-  RunBitexactnessTest(32000, 2, 0, false, 0,
-                      EchoCancellationImpl::SuppressionLevel::kHighSuppression,
-                      kStreamHasEchoReference, kOutputReference);
-}
-
-#if !(defined(WEBRTC_ARCH_ARM64) || defined(WEBRTC_ARCH_ARM) || \
-      defined(WEBRTC_ANDROID))
-TEST(EchoCancellationBitExactnessTest,
-     Stereo48kHz_HighLevel_NoDrift_StreamDelay0) {
-#else
-TEST(EchoCancellationBitExactnessTest,
-     DISABLED_Stereo48kHz_HighLevel_NoDrift_StreamDelay0) {
-#endif
-  const float kOutputReference[] = {-0.001101f, -0.001101f, -0.000449f,
-                                    -0.001101f, -0.001101f, -0.000449f};
-  RunBitexactnessTest(48000, 2, 0, false, 0,
-                      EchoCancellationImpl::SuppressionLevel::kHighSuppression,
-                      kStreamHasEchoReference, kOutputReference);
-}
-
-}  // namespace webrtc
diff --git a/modules/audio_processing/echo_cancellation_impl.cc b/modules/audio_processing/echo_cancellation_impl.cc
deleted file mode 100644
index 25e8d70..0000000
--- a/modules/audio_processing/echo_cancellation_impl.cc
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "modules/audio_processing/echo_cancellation_impl.h"
-
-#include <stdint.h>
-#include <string.h>
-
-#include "modules/audio_processing/aec/aec_core.h"
-#include "modules/audio_processing/aec/echo_cancellation.h"
-#include "modules/audio_processing/audio_buffer.h"
-#include "rtc_base/checks.h"
-#include "system_wrappers/include/field_trial.h"
-
-namespace webrtc {
-
-namespace {
-int16_t MapSetting(EchoCancellationImpl::SuppressionLevel level) {
-  switch (level) {
-    case EchoCancellationImpl::kLowSuppression:
-      return kAecNlpConservative;
-    case EchoCancellationImpl::kModerateSuppression:
-      return kAecNlpModerate;
-    case EchoCancellationImpl::kHighSuppression:
-      return kAecNlpAggressive;
-  }
-  RTC_NOTREACHED();
-  return -1;
-}
-
-AudioProcessing::Error MapError(int err) {
-  switch (err) {
-    case AEC_UNSUPPORTED_FUNCTION_ERROR:
-      return AudioProcessing::kUnsupportedFunctionError;
-    case AEC_BAD_PARAMETER_ERROR:
-      return AudioProcessing::kBadParameterError;
-    case AEC_BAD_PARAMETER_WARNING:
-      return AudioProcessing::kBadStreamParameterWarning;
-    default:
-      // AEC_UNSPECIFIED_ERROR
-      // AEC_UNINITIALIZED_ERROR
-      // AEC_NULL_POINTER_ERROR
-      return AudioProcessing::kUnspecifiedError;
-  }
-}
-
-bool EnforceZeroStreamDelay() {
-#if defined(CHROMEOS)
-  return !field_trial::IsEnabled("WebRTC-Aec2ZeroStreamDelayKillSwitch");
-#else
-  return false;
-#endif
-}
-
-}  // namespace
-
-struct EchoCancellationImpl::StreamProperties {
-  StreamProperties() = delete;
-  StreamProperties(int sample_rate_hz,
-                   size_t num_reverse_channels,
-                   size_t num_output_channels,
-                   size_t num_proc_channels)
-      : sample_rate_hz(sample_rate_hz),
-        num_reverse_channels(num_reverse_channels),
-        num_output_channels(num_output_channels),
-        num_proc_channels(num_proc_channels) {}
-
-  const int sample_rate_hz;
-  const size_t num_reverse_channels;
-  const size_t num_output_channels;
-  const size_t num_proc_channels;
-};
-
-class EchoCancellationImpl::Canceller {
- public:
-  Canceller() {
-    state_ = WebRtcAec_Create();
-    RTC_DCHECK(state_);
-  }
-
-  ~Canceller() {
-    RTC_CHECK(state_);
-    WebRtcAec_Free(state_);
-  }
-
-  void* state() { return state_; }
-
-  void Initialize(int sample_rate_hz) {
-    // TODO(ajm): Drift compensation is disabled in practice. If restored, it
-    // should be managed internally and not depend on the hardware sample rate.
-    // For now, just hardcode a 48 kHz value.
-    const int error = WebRtcAec_Init(state_, sample_rate_hz, 48000);
-    RTC_DCHECK_EQ(0, error);
-  }
-
- private:
-  void* state_;
-};
-
-EchoCancellationImpl::EchoCancellationImpl()
-    : drift_compensation_enabled_(false),
-      metrics_enabled_(true),
-      suppression_level_(kHighSuppression),
-      stream_drift_samples_(0),
-      was_stream_drift_set_(false),
-      stream_has_echo_(false),
-      delay_logging_enabled_(true),
-      extended_filter_enabled_(false),
-      delay_agnostic_enabled_(false),
-      enforce_zero_stream_delay_(EnforceZeroStreamDelay()) {}
-
-EchoCancellationImpl::~EchoCancellationImpl() = default;
-
-void EchoCancellationImpl::ProcessRenderAudio(
-    rtc::ArrayView<const float> packed_render_audio) {
-  RTC_DCHECK(stream_properties_);
-  size_t handle_index = 0;
-  size_t buffer_index = 0;
-  const size_t num_frames_per_band =
-      packed_render_audio.size() / (stream_properties_->num_output_channels *
-                                    stream_properties_->num_reverse_channels);
-  for (size_t i = 0; i < stream_properties_->num_output_channels; i++) {
-    for (size_t j = 0; j < stream_properties_->num_reverse_channels; j++) {
-      WebRtcAec_BufferFarend(cancellers_[handle_index++]->state(),
-                             &packed_render_audio[buffer_index],
-                             num_frames_per_band);
-
-      buffer_index += num_frames_per_band;
-    }
-  }
-}
-
-int EchoCancellationImpl::ProcessCaptureAudio(AudioBuffer* audio,
-                                              int stream_delay_ms) {
-  const int stream_delay_ms_use =
-      enforce_zero_stream_delay_ ? 0 : stream_delay_ms;
-
-  if (drift_compensation_enabled_ && !was_stream_drift_set_) {
-    return AudioProcessing::kStreamParameterNotSetError;
-  }
-
-  RTC_DCHECK(stream_properties_);
-  RTC_DCHECK_GE(160, audio->num_frames_per_band());
-  RTC_DCHECK_EQ(audio->num_channels(), stream_properties_->num_proc_channels);
-
-  int err = AudioProcessing::kNoError;
-
-  // The ordering convention must be followed to pass to the correct AEC.
-  size_t handle_index = 0;
-  stream_has_echo_ = false;
-  for (size_t i = 0; i < audio->num_channels(); i++) {
-    for (size_t j = 0; j < stream_properties_->num_reverse_channels; j++) {
-      err =
-          WebRtcAec_Process(cancellers_[handle_index]->state(),
-                            audio->split_bands_const(i), audio->num_bands(),
-                            audio->split_bands(i), audio->num_frames_per_band(),
-                            stream_delay_ms_use, stream_drift_samples_);
-
-      if (err != AudioProcessing::kNoError) {
-        err = MapError(err);
-        // TODO(ajm): Figure out how to return warnings properly.
-        if (err != AudioProcessing::kBadStreamParameterWarning) {
-          return err;
-        }
-      }
-
-      int status = 0;
-      err = WebRtcAec_get_echo_status(cancellers_[handle_index]->state(),
-                                      &status);
-      if (err != AudioProcessing::kNoError) {
-        return MapError(err);
-      }
-
-      if (status == 1) {
-        stream_has_echo_ = true;
-      }
-
-      handle_index++;
-    }
-  }
-
-  was_stream_drift_set_ = false;
-  return AudioProcessing::kNoError;
-}
-
-int EchoCancellationImpl::set_suppression_level(SuppressionLevel level) {
-  if (MapSetting(level) == -1) {
-    return AudioProcessing::kBadParameterError;
-  }
-  suppression_level_ = level;
-  return Configure();
-}
-
-EchoCancellationImpl::SuppressionLevel EchoCancellationImpl::suppression_level()
-    const {
-  return suppression_level_;
-}
-
-int EchoCancellationImpl::enable_drift_compensation(bool enable) {
-  drift_compensation_enabled_ = enable;
-  return Configure();
-}
-
-bool EchoCancellationImpl::is_drift_compensation_enabled() const {
-  return drift_compensation_enabled_;
-}
-
-void EchoCancellationImpl::set_stream_drift_samples(int drift) {
-  was_stream_drift_set_ = true;
-  stream_drift_samples_ = drift;
-}
-
-int EchoCancellationImpl::stream_drift_samples() const {
-  return stream_drift_samples_;
-}
-
-int EchoCancellationImpl::enable_metrics(bool enable) {
-  metrics_enabled_ = enable;
-  return Configure();
-}
-
-bool EchoCancellationImpl::are_metrics_enabled() const {
-  return metrics_enabled_;
-}
-
-// TODO(ajm): we currently just use the metrics from the first AEC. Think more
-//            aboue the best way to extend this to multi-channel.
-int EchoCancellationImpl::GetMetrics(Metrics* metrics) {
-  if (metrics == NULL) {
-    return AudioProcessing::kNullPointerError;
-  }
-
-  if (!metrics_enabled_) {
-    return AudioProcessing::kNotEnabledError;
-  }
-
-  AecMetrics my_metrics;
-  memset(&my_metrics, 0, sizeof(my_metrics));
-  memset(metrics, 0, sizeof(Metrics));
-
-  const int err = WebRtcAec_GetMetrics(cancellers_[0]->state(), &my_metrics);
-  if (err != AudioProcessing::kNoError) {
-    return MapError(err);
-  }
-
-  metrics->residual_echo_return_loss.instant = my_metrics.rerl.instant;
-  metrics->residual_echo_return_loss.average = my_metrics.rerl.average;
-  metrics->residual_echo_return_loss.maximum = my_metrics.rerl.max;
-  metrics->residual_echo_return_loss.minimum = my_metrics.rerl.min;
-
-  metrics->echo_return_loss.instant = my_metrics.erl.instant;
-  metrics->echo_return_loss.average = my_metrics.erl.average;
-  metrics->echo_return_loss.maximum = my_metrics.erl.max;
-  metrics->echo_return_loss.minimum = my_metrics.erl.min;
-
-  metrics->echo_return_loss_enhancement.instant = my_metrics.erle.instant;
-  metrics->echo_return_loss_enhancement.average = my_metrics.erle.average;
-  metrics->echo_return_loss_enhancement.maximum = my_metrics.erle.max;
-  metrics->echo_return_loss_enhancement.minimum = my_metrics.erle.min;
-
-  metrics->a_nlp.instant = my_metrics.aNlp.instant;
-  metrics->a_nlp.average = my_metrics.aNlp.average;
-  metrics->a_nlp.maximum = my_metrics.aNlp.max;
-  metrics->a_nlp.minimum = my_metrics.aNlp.min;
-
-  metrics->divergent_filter_fraction = my_metrics.divergent_filter_fraction;
-  return AudioProcessing::kNoError;
-}
-
-bool EchoCancellationImpl::stream_has_echo() const {
-  return stream_has_echo_;
-}
-
-int EchoCancellationImpl::enable_delay_logging(bool enable) {
-  delay_logging_enabled_ = enable;
-  return Configure();
-}
-
-bool EchoCancellationImpl::is_delay_logging_enabled() const {
-  return delay_logging_enabled_;
-}
-
-bool EchoCancellationImpl::is_delay_agnostic_enabled() const {
-  return delay_agnostic_enabled_;
-}
-
-std::string EchoCancellationImpl::GetExperimentsDescription() {
-  return refined_adaptive_filter_enabled_ ? "Legacy AEC;RefinedAdaptiveFilter;"
-                                          : "Legacy AEC;";
-}
-
-bool EchoCancellationImpl::is_refined_adaptive_filter_enabled() const {
-  return refined_adaptive_filter_enabled_;
-}
-
-bool EchoCancellationImpl::is_extended_filter_enabled() const {
-  return extended_filter_enabled_;
-}
-
-// TODO(bjornv): How should we handle the multi-channel case?
-int EchoCancellationImpl::GetDelayMetrics(int* median, int* std) {
-  float fraction_poor_delays = 0;
-  return GetDelayMetrics(median, std, &fraction_poor_delays);
-}
-
-int EchoCancellationImpl::GetDelayMetrics(int* median,
-                                          int* std,
-                                          float* fraction_poor_delays) {
-  if (median == NULL) {
-    return AudioProcessing::kNullPointerError;
-  }
-  if (std == NULL) {
-    return AudioProcessing::kNullPointerError;
-  }
-
-  if (!delay_logging_enabled_) {
-    return AudioProcessing::kNotEnabledError;
-  }
-
-  const int err = WebRtcAec_GetDelayMetrics(cancellers_[0]->state(), median,
-                                            std, fraction_poor_delays);
-  if (err != AudioProcessing::kNoError) {
-    return MapError(err);
-  }
-
-  return AudioProcessing::kNoError;
-}
-
-struct AecCore* EchoCancellationImpl::aec_core() const {
-  return WebRtcAec_aec_core(cancellers_[0]->state());
-}
-
-void EchoCancellationImpl::Initialize(int sample_rate_hz,
-                                      size_t num_reverse_channels,
-                                      size_t num_output_channels,
-                                      size_t num_proc_channels) {
-  stream_properties_.reset(
-      new StreamProperties(sample_rate_hz, num_reverse_channels,
-                           num_output_channels, num_proc_channels));
-
-  const size_t num_cancellers_required =
-      NumCancellersRequired(stream_properties_->num_output_channels,
-                            stream_properties_->num_reverse_channels);
-  if (num_cancellers_required > cancellers_.size()) {
-    const size_t cancellers_old_size = cancellers_.size();
-    cancellers_.resize(num_cancellers_required);
-
-    for (size_t i = cancellers_old_size; i < cancellers_.size(); ++i) {
-      cancellers_[i].reset(new Canceller());
-    }
-  }
-
-  for (auto& canceller : cancellers_) {
-    canceller->Initialize(sample_rate_hz);
-  }
-
-  Configure();
-}
-
-int EchoCancellationImpl::GetSystemDelayInSamples() const {
-  // Report the delay for the first AEC component.
-  return WebRtcAec_system_delay(WebRtcAec_aec_core(cancellers_[0]->state()));
-}
-
-void EchoCancellationImpl::PackRenderAudioBuffer(
-    const AudioBuffer* audio,
-    size_t num_output_channels,
-    size_t num_channels,
-    std::vector<float>* packed_buffer) {
-  RTC_DCHECK_GE(160, audio->num_frames_per_band());
-  RTC_DCHECK_EQ(num_channels, audio->num_channels());
-
-  packed_buffer->clear();
-  // The ordering convention must be followed to pass the correct data.
-  for (size_t i = 0; i < num_output_channels; i++) {
-    for (size_t j = 0; j < audio->num_channels(); j++) {
-      // Buffer the samples in the render queue.
-      packed_buffer->insert(packed_buffer->end(),
-                            audio->split_bands_const(j)[kBand0To8kHz],
-                            (audio->split_bands_const(j)[kBand0To8kHz] +
-                             audio->num_frames_per_band()));
-    }
-  }
-}
-
-void EchoCancellationImpl::SetExtraOptions(bool use_extended_filter,
-                                           bool use_delay_agnostic,
-                                           bool use_refined_adaptive_filter) {
-  extended_filter_enabled_ = use_extended_filter;
-  delay_agnostic_enabled_ = use_delay_agnostic;
-  refined_adaptive_filter_enabled_ = use_refined_adaptive_filter;
-  Configure();
-}
-
-int EchoCancellationImpl::Configure() {
-  AecConfig config;
-  config.metricsMode = metrics_enabled_;
-  config.nlpMode = MapSetting(suppression_level_);
-  config.skewMode = drift_compensation_enabled_;
-  config.delay_logging = delay_logging_enabled_;
-
-  int error = AudioProcessing::kNoError;
-  for (auto& canceller : cancellers_) {
-    WebRtcAec_enable_extended_filter(WebRtcAec_aec_core(canceller->state()),
-                                     extended_filter_enabled_ ? 1 : 0);
-    WebRtcAec_enable_delay_agnostic(WebRtcAec_aec_core(canceller->state()),
-                                    delay_agnostic_enabled_ ? 1 : 0);
-    WebRtcAec_enable_refined_adaptive_filter(
-        WebRtcAec_aec_core(canceller->state()),
-        refined_adaptive_filter_enabled_);
-    const int handle_error = WebRtcAec_set_config(canceller->state(), config);
-    if (handle_error != AudioProcessing::kNoError) {
-      error = AudioProcessing::kNoError;
-    }
-  }
-  return error;
-}
-
-size_t EchoCancellationImpl::NumCancellersRequired(
-    size_t num_output_channels,
-    size_t num_reverse_channels) {
-  return num_output_channels * num_reverse_channels;
-}
-
-}  // namespace webrtc
diff --git a/modules/audio_processing/echo_cancellation_impl.h b/modules/audio_processing/echo_cancellation_impl.h
deleted file mode 100644
index 1df41a7..0000000
--- a/modules/audio_processing/echo_cancellation_impl.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_IMPL_H_
-#define MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_IMPL_H_
-
-#include <stddef.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "api/array_view.h"
-#include "rtc_base/constructor_magic.h"
-
-namespace webrtc {
-
-class AudioBuffer;
-
-// The acoustic echo cancellation (AEC) component provides better performance
-// than AECM but also requires more processing power and is dependent on delay
-// stability and reporting accuracy. As such it is well-suited and recommended
-// for PC and IP phone applications.
-class EchoCancellationImpl {
- public:
-  explicit EchoCancellationImpl();
-  ~EchoCancellationImpl();
-
-  void ProcessRenderAudio(rtc::ArrayView<const float> packed_render_audio);
-  int ProcessCaptureAudio(AudioBuffer* audio, int stream_delay_ms);
-
-  // Differences in clock speed on the primary and reverse streams can impact
-  // the AEC performance. On the client-side, this could be seen when different
-  // render and capture devices are used, particularly with webcams.
-  //
-  // This enables a compensation mechanism, and requires that
-  // set_stream_drift_samples() be called.
-  int enable_drift_compensation(bool enable);
-  bool is_drift_compensation_enabled() const;
-
-  // Sets the difference between the number of samples rendered and captured by
-  // the audio devices since the last call to |ProcessStream()|. Must be called
-  // if drift compensation is enabled, prior to |ProcessStream()|.
-  void set_stream_drift_samples(int drift);
-  int stream_drift_samples() const;
-
-  enum SuppressionLevel {
-    kLowSuppression,
-    kModerateSuppression,
-    kHighSuppression
-  };
-
-  // Sets the aggressiveness of the suppressor. A higher level trades off
-  // double-talk performance for increased echo suppression.
-  int set_suppression_level(SuppressionLevel level);
-  SuppressionLevel suppression_level() const;
-
-  // Returns false if the current frame almost certainly contains no echo
-  // and true if it _might_ contain echo.
-  bool stream_has_echo() const;
-
-  // Enables the computation of various echo metrics. These are obtained
-  // through |GetMetrics()|.
-  int enable_metrics(bool enable);
-  bool are_metrics_enabled() const;
-
-  // Each statistic is reported in dB.
-  // P_far:  Far-end (render) signal power.
-  // P_echo: Near-end (capture) echo signal power.
-  // P_out:  Signal power at the output of the AEC.
-  // P_a:    Internal signal power at the point before the AEC's non-linear
-  //         processor.
-  struct Metrics {
-    struct Statistic {
-      int instant = 0;  // Instantaneous value.
-      int average = 0;  // Long-term average.
-      int maximum = 0;  // Long-term maximum.
-      int minimum = 0;  // Long-term minimum.
-    };
-    // RERL = ERL + ERLE
-    Statistic residual_echo_return_loss;
-
-    // ERL = 10log_10(P_far / P_echo)
-    Statistic echo_return_loss;
-
-    // ERLE = 10log_10(P_echo / P_out)
-    Statistic echo_return_loss_enhancement;
-
-    // (Pre non-linear processing suppression) A_NLP = 10log_10(P_echo / P_a)
-    Statistic a_nlp;
-
-    // Fraction of time that the AEC linear filter is divergent, in a 1-second
-    // non-overlapped aggregation window.
-    float divergent_filter_fraction;
-  };
-
-  // Provides various statistics about the AEC.
-  int GetMetrics(Metrics* metrics);
-
-  // Enables computation and logging of delay values. Statistics are obtained
-  // through |GetDelayMetrics()|.
-  int enable_delay_logging(bool enable);
-  bool is_delay_logging_enabled() const;
-
-  // Provides delay metrics.
-  // The delay metrics consists of the delay |median| and the delay standard
-  // deviation |std|. It also consists of the fraction of delay estimates
-  // |fraction_poor_delays| that can make the echo cancellation perform poorly.
-  // The values are aggregated until the first call to |GetDelayMetrics()| and
-  // afterwards aggregated and updated every second.
-  // Note that if there are several clients pulling metrics from
-  // |GetDelayMetrics()| during a session the first call from any of them will
-  // change to one second aggregation window for all.
-  int GetDelayMetrics(int* median, int* std);
-  int GetDelayMetrics(int* median, int* std, float* fraction_poor_delays);
-
-  // Returns a pointer to the low level AEC component.  In case of multiple
-  // channels, the pointer to the first one is returned.  A NULL pointer is
-  // returned when the AEC component is disabled or has not been initialized
-  // successfully.
-  struct AecCore* aec_core() const;
-
-  void Initialize(int sample_rate_hz,
-                  size_t num_reverse_channels_,
-                  size_t num_output_channels_,
-                  size_t num_proc_channels_);
-  void SetExtraOptions(bool use_extended_filter,
-                       bool use_delay_agnostic,
-                       bool use_refined_adaptive_filter);
-  bool is_delay_agnostic_enabled() const;
-  bool is_extended_filter_enabled() const;
-  std::string GetExperimentsDescription();
-  bool is_refined_adaptive_filter_enabled() const;
-
-  // Returns the system delay of the first AEC component.
-  int GetSystemDelayInSamples() const;
-
-  static void PackRenderAudioBuffer(const AudioBuffer* audio,
-                                    size_t num_output_channels,
-                                    size_t num_channels,
-                                    std::vector<float>* packed_buffer);
-  static size_t NumCancellersRequired(size_t num_output_channels,
-                                      size_t num_reverse_channels);
-
- private:
-  class Canceller;
-  struct StreamProperties;
-
-  void AllocateRenderQueue();
-  int Configure();
-
-  bool drift_compensation_enabled_;
-  bool metrics_enabled_;
-  SuppressionLevel suppression_level_;
-  int stream_drift_samples_;
-  bool was_stream_drift_set_;
-  bool stream_has_echo_;
-  bool delay_logging_enabled_;
-  bool extended_filter_enabled_;
-  bool delay_agnostic_enabled_;
-  bool refined_adaptive_filter_enabled_ = false;
-
-  // Only active on Chrome OS devices.
-  const bool enforce_zero_stream_delay_;
-
-  std::vector<std::unique_ptr<Canceller>> cancellers_;
-  std::unique_ptr<StreamProperties> stream_properties_;
-};
-
-}  // namespace webrtc
-
-#endif  // MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_IMPL_H_
diff --git a/modules/audio_processing/echo_cancellation_impl_unittest.cc b/modules/audio_processing/echo_cancellation_impl_unittest.cc
deleted file mode 100644
index a970a4e..0000000
--- a/modules/audio_processing/echo_cancellation_impl_unittest.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "modules/audio_processing/echo_cancellation_impl.h"
-
-#include <memory>
-
-#include "modules/audio_processing/aec/aec_core.h"
-#include "modules/audio_processing/include/audio_processing.h"
-#include "rtc_base/critical_section.h"
-#include "test/gtest.h"
-
-namespace webrtc {
-TEST(EchoCancellationInternalTest, ExtendedFilter) {
-  EchoCancellationImpl echo_canceller;
-  echo_canceller.Initialize(AudioProcessing::kSampleRate32kHz, 2, 2, 2);
-
-  AecCore* aec_core = echo_canceller.aec_core();
-  ASSERT_TRUE(aec_core != NULL);
-  // Disabled by default.
-  EXPECT_EQ(0, WebRtcAec_extended_filter_enabled(aec_core));
-
-  Config config;
-  echo_canceller.SetExtraOptions(true, false, false);
-  EXPECT_EQ(1, WebRtcAec_extended_filter_enabled(aec_core));
-
-  // Retains setting after initialization.
-  echo_canceller.Initialize(AudioProcessing::kSampleRate16kHz, 2, 2, 2);
-  EXPECT_EQ(1, WebRtcAec_extended_filter_enabled(aec_core));
-
-  echo_canceller.SetExtraOptions(false, false, false);
-  EXPECT_EQ(0, WebRtcAec_extended_filter_enabled(aec_core));
-
-  // Retains setting after initialization.
-  echo_canceller.Initialize(AudioProcessing::kSampleRate16kHz, 1, 1, 1);
-  EXPECT_EQ(0, WebRtcAec_extended_filter_enabled(aec_core));
-}
-
-TEST(EchoCancellationInternalTest, DelayAgnostic) {
-  EchoCancellationImpl echo_canceller;
-  echo_canceller.Initialize(AudioProcessing::kSampleRate32kHz, 1, 1, 1);
-
-  AecCore* aec_core = echo_canceller.aec_core();
-  ASSERT_TRUE(aec_core != NULL);
-  // Enabled by default.
-  EXPECT_EQ(0, WebRtcAec_delay_agnostic_enabled(aec_core));
-
-  Config config;
-  echo_canceller.SetExtraOptions(false, true, false);
-  EXPECT_EQ(1, WebRtcAec_delay_agnostic_enabled(aec_core));
-
-  // Retains setting after initialization.
-  echo_canceller.Initialize(AudioProcessing::kSampleRate32kHz, 2, 2, 2);
-  EXPECT_EQ(1, WebRtcAec_delay_agnostic_enabled(aec_core));
-
-  config.Set<DelayAgnostic>(new DelayAgnostic(false));
-  echo_canceller.SetExtraOptions(false, false, false);
-  EXPECT_EQ(0, WebRtcAec_delay_agnostic_enabled(aec_core));
-
-  // Retains setting after initialization.
-  echo_canceller.Initialize(AudioProcessing::kSampleRate16kHz, 2, 2, 2);
-  EXPECT_EQ(0, WebRtcAec_delay_agnostic_enabled(aec_core));
-}
-
-TEST(EchoCancellationInternalTest, InterfaceConfiguration) {
-  EchoCancellationImpl echo_canceller;
-  echo_canceller.Initialize(AudioProcessing::kSampleRate16kHz, 1, 1, 1);
-
-  EXPECT_EQ(0, echo_canceller.enable_drift_compensation(true));
-  EXPECT_TRUE(echo_canceller.is_drift_compensation_enabled());
-  EXPECT_EQ(0, echo_canceller.enable_drift_compensation(false));
-  EXPECT_FALSE(echo_canceller.is_drift_compensation_enabled());
-
-  EchoCancellationImpl::SuppressionLevel level[] = {
-      EchoCancellationImpl::kLowSuppression,
-      EchoCancellationImpl::kModerateSuppression,
-      EchoCancellationImpl::kHighSuppression,
-  };
-  for (size_t i = 0; i < arraysize(level); i++) {
-    EXPECT_EQ(0, echo_canceller.set_suppression_level(level[i]));
-    EXPECT_EQ(level[i], echo_canceller.suppression_level());
-  }
-
-  EchoCancellationImpl::Metrics metrics;
-  EXPECT_EQ(0, echo_canceller.enable_metrics(true));
-  EXPECT_TRUE(echo_canceller.are_metrics_enabled());
-  EXPECT_EQ(0, echo_canceller.enable_metrics(false));
-  EXPECT_FALSE(echo_canceller.are_metrics_enabled());
-
-  EXPECT_EQ(0, echo_canceller.enable_delay_logging(true));
-  EXPECT_TRUE(echo_canceller.is_delay_logging_enabled());
-  EXPECT_EQ(0, echo_canceller.enable_delay_logging(false));
-  EXPECT_FALSE(echo_canceller.is_delay_logging_enabled());
-
-  int median = 0;
-  int std = 0;
-  float poor_fraction = 0;
-  EXPECT_EQ(AudioProcessing::kNotEnabledError,
-            echo_canceller.GetDelayMetrics(&median, &std, &poor_fraction));
-
-  EXPECT_TRUE(echo_canceller.aec_core() != NULL);
-}
-
-}  // namespace webrtc
diff --git a/modules/audio_processing/include/audio_processing.h b/modules/audio_processing/include/audio_processing.h
index e8ecd6e..2340834 100644
--- a/modules/audio_processing/include/audio_processing.h
+++ b/modules/audio_processing/include/audio_processing.h
@@ -37,8 +37,6 @@
 
 namespace webrtc {
 
-struct AecCore;
-
 class AecDump;
 class AudioBuffer;
 class AudioFrame;
@@ -50,53 +48,6 @@
 class CustomAudioAnalyzer;
 class CustomProcessing;
 
-// Use to enable the extended filter mode in the AEC, along with robustness
-// measures around the reported system delays. It comes with a significant
-// increase in AEC complexity, but is much more robust to unreliable reported
-// delays.
-//
-// Detailed changes to the algorithm:
-// - The filter length is changed from 48 to 128 ms. This comes with tuning of
-//   several parameters: i) filter adaptation stepsize and error threshold;
-//   ii) non-linear processing smoothing and overdrive.
-// - Option to ignore the reported delays on platforms which we deem
-//   sufficiently unreliable. See WEBRTC_UNTRUSTED_DELAY in echo_cancellation.c.
-// - Faster startup times by removing the excessive "startup phase" processing
-//   of reported delays.
-// - Much more conservative adjustments to the far-end read pointer. We smooth
-//   the delay difference more heavily, and back off from the difference more.
-//   Adjustments force a readaptation of the filter, so they should be avoided
-//   except when really necessary.
-struct ExtendedFilter {
-  ExtendedFilter() : enabled(false) {}
-  explicit ExtendedFilter(bool enabled) : enabled(enabled) {}
-  static const ConfigOptionID identifier = ConfigOptionID::kExtendedFilter;
-  bool enabled;
-};
-
-// Enables the refined linear filter adaptation in the echo canceller.
-// This configuration only applies to non-mobile echo cancellation.
-// It can be set in the constructor or using AudioProcessing::SetExtraOptions().
-struct RefinedAdaptiveFilter {
-  RefinedAdaptiveFilter() : enabled(false) {}
-  explicit RefinedAdaptiveFilter(bool enabled) : enabled(enabled) {}
-  static const ConfigOptionID identifier =
-      ConfigOptionID::kAecRefinedAdaptiveFilter;
-  bool enabled;
-};
-
-// Enables delay-agnostic echo cancellation. This feature relies on internally
-// estimated delays between the process and reverse streams, thus not relying
-// on reported system delays. This configuration only applies to non-mobile echo
-// cancellation. It can be set in the constructor or using
-// AudioProcessing::SetExtraOptions().
-struct DelayAgnostic {
-  DelayAgnostic() : enabled(false) {}
-  explicit DelayAgnostic(bool enabled) : enabled(enabled) {}
-  static const ConfigOptionID identifier = ConfigOptionID::kDelayAgnostic;
-  bool enabled;
-};
-
 // Use to enable experimental gain control (AGC). At startup the experimental
 // AGC moves the microphone volume up to |startup_min_volume| if the current
 // microphone volume is set too low. The value is clamped to its operating range
@@ -279,9 +230,10 @@
       bool enabled = false;
       bool mobile_mode = false;
       // Recommended not to use. Will be removed in the future.
-      // APM components are not fine-tuned for legacy suppression levels.
+      // TODO(peah): Remove.
       bool legacy_moderate_suppression_level = false;
       // Recommended not to use. Will be removed in the future.
+      // TODO(webrtc:11165): Remove.
       bool use_legacy_aec = false;
       bool export_linear_aec_output = false;
       // Enforce the highpass filter to be on (has no effect for the mobile
diff --git a/modules/audio_processing/include/config.h b/modules/audio_processing/include/config.h
index 930cf7e..8a24586 100644
--- a/modules/audio_processing/include/config.h
+++ b/modules/audio_processing/include/config.h
@@ -27,15 +27,15 @@
   kNetEqCapacityConfig,    // Deprecated
   kNetEqFastAccelerate,    // Deprecated
   kVoicePacing,            // Deprecated
-  kExtendedFilter,
-  kDelayAgnostic,
+  kExtendedFilter,         // Deprecated
+  kDelayAgnostic,          // Deprecated
   kExperimentalAgc,
   kExperimentalNs,
-  kBeamforming,      // Deprecated
-  kIntelligibility,  // Deprecated
-  kEchoCanceller3,   // Deprecated
-  kAecRefinedAdaptiveFilter,
-  kLevelControl  // Deprecated
+  kBeamforming,               // Deprecated
+  kIntelligibility,           // Deprecated
+  kEchoCanceller3,            // Deprecated
+  kAecRefinedAdaptiveFilter,  // Deprecated
+  kLevelControl               // Deprecated
 };
 
 // Class Config is designed to ease passing a set of options across webrtc code.
diff --git a/modules/audio_processing/test/aec_dump_based_simulator.cc b/modules/audio_processing/test/aec_dump_based_simulator.cc
index d9bd5bc..e050f48 100644
--- a/modules/audio_processing/test/aec_dump_based_simulator.cc
+++ b/modules/audio_processing/test/aec_dump_based_simulator.cc
@@ -13,7 +13,6 @@
 #include <iostream>
 #include <memory>
 
-#include "modules/audio_processing/echo_cancellation_impl.h"
 #include "modules/audio_processing/echo_control_mobile_impl.h"
 #include "modules/audio_processing/test/protobuf_utils.h"
 #include "rtc_base/checks.h"
@@ -300,57 +299,6 @@
       }
     }
 
-    if (msg.has_aec_delay_agnostic_enabled() || settings_.use_delay_agnostic) {
-      bool enable = settings_.use_delay_agnostic
-                        ? *settings_.use_delay_agnostic
-                        : msg.aec_delay_agnostic_enabled();
-      config.Set<DelayAgnostic>(new DelayAgnostic(enable));
-      if (settings_.use_verbose_logging) {
-        std::cout << " aec_delay_agnostic_enabled: "
-                  << (enable ? "true" : "false") << std::endl;
-      }
-    }
-
-    if (msg.has_aec_drift_compensation_enabled() ||
-        settings_.use_drift_compensation) {
-      if (settings_.use_drift_compensation
-              ? *settings_.use_drift_compensation
-              : msg.aec_drift_compensation_enabled()) {
-        RTC_LOG(LS_ERROR)
-            << "Ignoring deprecated setting: AEC2 drift compensation";
-      }
-    }
-
-    if (msg.has_aec_extended_filter_enabled() ||
-        settings_.use_extended_filter) {
-      bool enable = settings_.use_extended_filter
-                        ? *settings_.use_extended_filter
-                        : msg.aec_extended_filter_enabled();
-      config.Set<ExtendedFilter>(new ExtendedFilter(enable));
-      if (settings_.use_verbose_logging) {
-        std::cout << " aec_extended_filter_enabled: "
-                  << (enable ? "true" : "false") << std::endl;
-      }
-    }
-
-    if (msg.has_aec_suppression_level() || settings_.aec_suppression_level) {
-      auto level = static_cast<webrtc::EchoCancellationImpl::SuppressionLevel>(
-          settings_.aec_suppression_level ? *settings_.aec_suppression_level
-                                          : msg.aec_suppression_level());
-      if (level ==
-          webrtc::EchoCancellationImpl::SuppressionLevel::kLowSuppression) {
-        RTC_LOG(LS_ERROR)
-            << "Ignoring deprecated setting: AEC2 low suppression";
-      } else {
-        apm_config.echo_canceller.legacy_moderate_suppression_level =
-            (level == webrtc::EchoCancellationImpl::SuppressionLevel::
-                          kModerateSuppression);
-        if (settings_.use_verbose_logging) {
-          std::cout << " aec_suppression_level: " << level << std::endl;
-        }
-      }
-    }
-
     if (msg.has_aecm_enabled() || settings_.use_aecm) {
       bool enable =
           settings_.use_aecm ? *settings_.use_aecm : msg.aecm_enabled();
@@ -486,11 +434,6 @@
                 << msg.experiments_description() << std::endl;
     }
 
-    if (settings_.use_refined_adaptive_filter) {
-      config.Set<RefinedAdaptiveFilter>(
-          new RefinedAdaptiveFilter(*settings_.use_refined_adaptive_filter));
-    }
-
     if (settings_.use_ed) {
       apm_config.residual_echo_detector.enabled = *settings_.use_ed;
     }
diff --git a/modules/audio_processing/test/audio_processing_simulator.cc b/modules/audio_processing/test/audio_processing_simulator.cc
index cb1d1ed..5677600 100644
--- a/modules/audio_processing/test/audio_processing_simulator.cc
+++ b/modules/audio_processing/test/audio_processing_simulator.cc
@@ -22,7 +22,6 @@
 #include "api/audio/echo_canceller3_factory.h"
 #include "common_audio/include/audio_util.h"
 #include "modules/audio_processing/aec_dump/aec_dump_factory.h"
-#include "modules/audio_processing/echo_cancellation_impl.h"
 #include "modules/audio_processing/echo_control_mobile_impl.h"
 #include "modules/audio_processing/include/audio_processing.h"
 #include "modules/audio_processing/logging/apm_data_dumper.h"
@@ -433,23 +432,17 @@
     }
   }
 
-  const bool use_legacy_aec = settings_.use_aec && *settings_.use_aec &&
-                              settings_.use_legacy_aec &&
-                              *settings_.use_legacy_aec;
   const bool use_aec = settings_.use_aec && *settings_.use_aec;
   const bool use_aecm = settings_.use_aecm && *settings_.use_aecm;
-  if (use_legacy_aec || use_aec || use_aecm) {
+  if (use_aec || use_aecm) {
     apm_config.echo_canceller.enabled = true;
     apm_config.echo_canceller.mobile_mode = use_aecm;
-    apm_config.echo_canceller.use_legacy_aec = use_legacy_aec;
+    apm_config.echo_canceller.use_legacy_aec = false;
   }
   apm_config.echo_canceller.export_linear_aec_output =
       !!settings_.linear_aec_output_filename;
 
-  RTC_CHECK(!(use_legacy_aec && settings_.aec_settings_filename))
-      << "The legacy AEC cannot be configured using settings";
-
-  if (use_aec && !use_legacy_aec) {
+  if (use_aec) {
     EchoCanceller3Config cfg;
     if (settings_.aec_settings_filename) {
       if (settings_.use_verbose_logging) {
@@ -472,22 +465,6 @@
     }
   }
 
-  if (settings_.use_drift_compensation && *settings_.use_drift_compensation) {
-    RTC_LOG(LS_ERROR) << "Ignoring deprecated setting: AEC2 drift compensation";
-  }
-  if (settings_.aec_suppression_level) {
-    auto level = static_cast<webrtc::EchoCancellationImpl::SuppressionLevel>(
-        *settings_.aec_suppression_level);
-    if (level ==
-        webrtc::EchoCancellationImpl::SuppressionLevel::kLowSuppression) {
-      RTC_LOG(LS_ERROR) << "Ignoring deprecated setting: AEC2 low suppression";
-    } else {
-      apm_config.echo_canceller.legacy_moderate_suppression_level =
-          (level == webrtc::EchoCancellationImpl::SuppressionLevel::
-                        kModerateSuppression);
-    }
-  }
-
   if (settings_.use_hpf) {
     apm_config.high_pass_filter.enabled = *settings_.use_hpf;
   }
@@ -519,14 +496,6 @@
         *settings_.agc_compression_gain;
   }
 
-  if (settings_.use_refined_adaptive_filter) {
-    config.Set<RefinedAdaptiveFilter>(
-        new RefinedAdaptiveFilter(*settings_.use_refined_adaptive_filter));
-  }
-  config.Set<ExtendedFilter>(new ExtendedFilter(
-      !settings_.use_extended_filter || *settings_.use_extended_filter));
-  config.Set<DelayAgnostic>(new DelayAgnostic(!settings_.use_delay_agnostic ||
-                                              *settings_.use_delay_agnostic));
   config.Set<ExperimentalAgc>(new ExperimentalAgc(
       !settings_.use_experimental_agc || *settings_.use_experimental_agc,
       !!settings_.use_experimental_agc_agc2_level_estimator &&
diff --git a/modules/audio_processing/test/audio_processing_simulator.h b/modules/audio_processing/test/audio_processing_simulator.h
index 5b26b5f..abef2fa 100644
--- a/modules/audio_processing/test/audio_processing_simulator.h
+++ b/modules/audio_processing/test/audio_processing_simulator.h
@@ -37,7 +37,6 @@
   ~SimulationSettings();
   absl::optional<int> stream_delay;
   absl::optional<bool> use_stream_delay;
-  absl::optional<int> stream_drift_samples;
   absl::optional<int> output_sample_rate_hz;
   absl::optional<int> output_num_channels;
   absl::optional<int> reverse_output_sample_rate_hz;
@@ -61,11 +60,6 @@
   absl::optional<bool> use_vad;
   absl::optional<bool> use_le;
   absl::optional<bool> use_all;
-  absl::optional<int> aec_suppression_level;
-  absl::optional<bool> use_delay_agnostic;
-  absl::optional<bool> use_extended_filter;
-  absl::optional<bool> use_drift_compensation;
-  absl::optional<bool> use_legacy_aec;
   absl::optional<bool> use_legacy_ns;
   absl::optional<bool> use_experimental_agc;
   absl::optional<bool> use_experimental_agc_agc2_level_estimator;
@@ -82,7 +76,6 @@
   absl::optional<float> pre_amplifier_gain_factor;
   absl::optional<int> ns_level;
   absl::optional<int> maximum_internal_processing_rate;
-  absl::optional<bool> use_refined_adaptive_filter;
   int initial_mic_level;
   bool simulate_mic_gain = false;
   absl::optional<bool> multi_channel_render;
diff --git a/modules/audio_processing/test/audioproc_float_impl.cc b/modules/audio_processing/test/audioproc_float_impl.cc
index 4902acb..6cfcef2 100644
--- a/modules/audio_processing/test/audioproc_float_impl.cc
+++ b/modules/audio_processing/test/audioproc_float_impl.cc
@@ -115,25 +115,9 @@
           "Activate all of the default components (will be overridden by any "
           "other settings)");
 ABSL_FLAG(int,
-          aec_suppression_level,
-          kParameterNotSpecifiedValue,
-          "Set the aec suppression level (0-2)");
-ABSL_FLAG(int,
-          delay_agnostic,
-          kParameterNotSpecifiedValue,
-          "Activate (1) or deactivate(0) the AEC delay agnostic mode");
-ABSL_FLAG(int,
-          extended_filter,
-          kParameterNotSpecifiedValue,
-          "Activate (1) or deactivate(0) the AEC extended filter mode");
-ABSL_FLAG(int,
-          use_legacy_aec,
-          kParameterNotSpecifiedValue,
-          "Activate (1) or deactivate(0) the legacy AEC");
-ABSL_FLAG(int,
           use_legacy_ns,
           kParameterNotSpecifiedValue,
-          "Activate (1) or deactivate(0) the legacy AEC");
+          "Activate (1) or deactivate(0) the legacy NS");
 ABSL_FLAG(int,
           experimental_agc,
           kParameterNotSpecifiedValue,
@@ -153,11 +137,6 @@
           kParameterNotSpecifiedValue,
           "AGC2 level estimation"
           " in the experimental AGC. AGC1 level estimation is the default (0)");
-ABSL_FLAG(
-    int,
-    refined_adaptive_filter,
-    kParameterNotSpecifiedValue,
-    "Activate (1) or deactivate(0) the refined adaptive filter functionality");
 ABSL_FLAG(int,
           agc_mode,
           kParameterNotSpecifiedValue,
@@ -395,17 +374,6 @@
   SetSettingIfFlagSet(absl::GetFlag(FLAGS_ts), &settings.use_ts);
   SetSettingIfFlagSet(absl::GetFlag(FLAGS_vad), &settings.use_vad);
   SetSettingIfFlagSet(absl::GetFlag(FLAGS_le), &settings.use_le);
-  SetSettingIfSpecified(absl::GetFlag(FLAGS_aec_suppression_level),
-                        &settings.aec_suppression_level);
-  SetSettingIfFlagSet(absl::GetFlag(FLAGS_delay_agnostic),
-                      &settings.use_delay_agnostic);
-  SetSettingIfFlagSet(absl::GetFlag(FLAGS_extended_filter),
-                      &settings.use_extended_filter);
-  SetSettingIfFlagSet(absl::GetFlag(FLAGS_refined_adaptive_filter),
-                      &settings.use_refined_adaptive_filter);
-
-  SetSettingIfFlagSet(absl::GetFlag(FLAGS_use_legacy_aec),
-                      &settings.use_legacy_aec);
   SetSettingIfFlagSet(absl::GetFlag(FLAGS_use_legacy_ns),
                       &settings.use_legacy_ns);
   SetSettingIfFlagSet(absl::GetFlag(FLAGS_experimental_agc),
@@ -440,8 +408,6 @@
                         &settings.stream_delay);
   SetSettingIfFlagSet(absl::GetFlag(FLAGS_use_stream_delay),
                       &settings.use_stream_delay);
-  SetSettingIfSpecified(absl::GetFlag(FLAGS_stream_drift_samples),
-                        &settings.stream_drift_samples);
   SetSettingIfSpecified(absl::GetFlag(FLAGS_custom_call_order_file),
                         &settings.call_order_input_filename);
   SetSettingIfSpecified(absl::GetFlag(FLAGS_output_custom_call_order_file),
@@ -525,14 +491,6 @@
                                 "be specified without the AEC being active");
 
   ReportConditionalErrorAndExit(
-      ((settings.use_aec && *settings.use_aec && settings.use_legacy_aec &&
-        *settings.use_legacy_aec) ||
-       (settings.use_aecm && *settings.use_aecm)) &&
-          !!settings.linear_aec_output_filename,
-      "Error: The linear AEC ouput filename cannot be specified when the "
-      "legacy AEC or the AECm are used");
-
-  ReportConditionalErrorAndExit(
       settings.use_aec && *settings.use_aec && settings.use_aecm &&
           *settings.use_aecm,
       "Error: The AEC and the AECM cannot be activated at the same time!\n");
@@ -556,13 +514,6 @@
           *settings.reverse_output_num_channels <= 0,
       "Error: --reverse_output_num_channels must be positive!\n");
 
-  ReportConditionalErrorAndExit(settings.aec_suppression_level &&
-                                    ((*settings.aec_suppression_level) < 1 ||
-                                     (*settings.aec_suppression_level) > 2),
-                                "Error: --aec_suppression_level must be "
-                                "specified between 1 and 2. 0 is "
-                                "deprecated.\n");
-
   ReportConditionalErrorAndExit(
       settings.agc_target_level && ((*settings.agc_target_level) < 0 ||
                                     (*settings.agc_target_level) > 31),
diff --git a/modules/audio_processing/test/debug_dump_replayer.cc b/modules/audio_processing/test/debug_dump_replayer.cc
index 45600f0..7cb6ec8 100644
--- a/modules/audio_processing/test/debug_dump_replayer.cc
+++ b/modules/audio_processing/test/debug_dump_replayer.cc
@@ -10,7 +10,6 @@
 
 #include "modules/audio_processing/test/debug_dump_replayer.h"
 
-#include "modules/audio_processing/echo_cancellation_impl.h"
 #include "modules/audio_processing/test/protobuf_utils.h"
 #include "modules/audio_processing/test/runtime_setting_util.h"
 #include "rtc_base/checks.h"
@@ -181,8 +180,6 @@
   // These configurations cannot be changed on the fly.
   Config config;
   RTC_CHECK(msg.has_aec_delay_agnostic_enabled());
-  config.Set<DelayAgnostic>(
-      new DelayAgnostic(msg.aec_delay_agnostic_enabled()));
 
   RTC_CHECK(msg.has_noise_robust_agc_enabled());
   config.Set<ExperimentalAgc>(
@@ -193,8 +190,6 @@
       new ExperimentalNs(msg.transient_suppression_enabled()));
 
   RTC_CHECK(msg.has_aec_extended_filter_enabled());
-  config.Set<ExtendedFilter>(
-      new ExtendedFilter(msg.aec_extended_filter_enabled()));
 
   // We only create APM once, since changes on these fields should not
   // happen in current implementation.
@@ -212,12 +207,6 @@
   apm_config.echo_canceller.enabled = msg.aec_enabled() || msg.aecm_enabled();
   apm_config.echo_canceller.mobile_mode = msg.aecm_enabled();
 
-  RTC_CHECK(msg.has_aec_suppression_level());
-  apm_config.echo_canceller.legacy_moderate_suppression_level =
-      static_cast<EchoCancellationImpl::SuppressionLevel>(
-          msg.aec_suppression_level()) ==
-      EchoCancellationImpl::SuppressionLevel::kModerateSuppression;
-
   // HPF configs.
   RTC_CHECK(msg.has_hpf_enabled());
   apm_config.high_pass_filter.enabled = msg.hpf_enabled();
diff --git a/modules/audio_processing/test/debug_dump_test.cc b/modules/audio_processing/test/debug_dump_test.cc
index 9561091..2828091 100644
--- a/modules/audio_processing/test/debug_dump_test.cc
+++ b/modules/audio_processing/test/debug_dump_test.cc
@@ -354,35 +354,6 @@
   VerifyDebugDump(generator.dump_file_name());
 }
 
-TEST_F(DebugDumpTest, VerifyRefinedAdaptiveFilterExperimentalString) {
-  Config config;
-  AudioProcessing::Config apm_config;
-  apm_config.echo_canceller.enabled = true;
-  apm_config.echo_canceller.use_legacy_aec = true;
-  config.Set<RefinedAdaptiveFilter>(new RefinedAdaptiveFilter(true));
-  DebugDumpGenerator generator(config, apm_config);
-  generator.StartRecording();
-  generator.Process(100);
-  generator.StopRecording();
-
-  DebugDumpReplayer debug_dump_replayer_;
-
-  ASSERT_TRUE(debug_dump_replayer_.SetDumpFile(generator.dump_file_name()));
-
-  while (const absl::optional<audioproc::Event> event =
-             debug_dump_replayer_.GetNextEvent()) {
-    debug_dump_replayer_.RunNextEvent();
-    if (event->type() == audioproc::Event::CONFIG) {
-      const audioproc::Config* msg = &event->config();
-      ASSERT_TRUE(msg->has_experiments_description());
-      EXPECT_PRED_FORMAT2(::testing::IsSubstring, "RefinedAdaptiveFilter",
-                          msg->experiments_description().c_str());
-      EXPECT_PRED_FORMAT2(::testing::IsSubstring, "Legacy AEC",
-                          msg->experiments_description().c_str());
-    }
-  }
-}
-
 TEST_F(DebugDumpTest, VerifyCombinedExperimentalStringInclusive) {
   Config config;
   AudioProcessing::Config apm_config;
@@ -406,8 +377,6 @@
       ASSERT_TRUE(msg->has_experiments_description());
       EXPECT_PRED_FORMAT2(::testing::IsSubstring, "EchoController",
                           msg->experiments_description().c_str());
-      EXPECT_PRED_FORMAT2(::testing::IsNotSubstring, "Legacy AEC",
-                          msg->experiments_description().c_str());
       EXPECT_PRED_FORMAT2(::testing::IsSubstring, "AgcClippingLevelExperiment",
                           msg->experiments_description().c_str());
     }
@@ -418,7 +387,6 @@
   Config config;
   AudioProcessing::Config apm_config;
   apm_config.echo_canceller.enabled = true;
-  apm_config.echo_canceller.use_legacy_aec = true;
   DebugDumpGenerator generator(config, apm_config);
   generator.StartRecording();
   generator.Process(100);
@@ -434,8 +402,6 @@
     if (event->type() == audioproc::Event::CONFIG) {
       const audioproc::Config* msg = &event->config();
       ASSERT_TRUE(msg->has_experiments_description());
-      EXPECT_PRED_FORMAT2(::testing::IsNotSubstring, "EchoController",
-                          msg->experiments_description().c_str());
       EXPECT_PRED_FORMAT2(::testing::IsNotSubstring,
                           "AgcClippingLevelExperiment",
                           msg->experiments_description().c_str());
@@ -462,8 +428,6 @@
     if (event->type() == audioproc::Event::CONFIG) {
       const audioproc::Config* msg = &event->config();
       ASSERT_TRUE(msg->has_experiments_description());
-      EXPECT_PRED_FORMAT2(::testing::IsNotSubstring, "Legacy AEC",
-                          msg->experiments_description().c_str());
       EXPECT_PRED_FORMAT2(::testing::IsSubstring, "EchoController",
                           msg->experiments_description().c_str());
     }
diff --git a/modules/audio_processing/utility/BUILD.gn b/modules/audio_processing/utility/BUILD.gn
index 745775e..a808625 100644
--- a/modules/audio_processing/utility/BUILD.gn
+++ b/modules/audio_processing/utility/BUILD.gn
@@ -19,17 +19,6 @@
   ]
 }
 
-rtc_library("block_mean_calculator") {
-  sources = [
-    "block_mean_calculator.cc",
-    "block_mean_calculator.h",
-  ]
-  deps = [
-    "../../../rtc_base:checks",
-    "../../../rtc_base:rtc_base_approved",
-  ]
-}
-
 rtc_library("legacy_delay_estimator") {
   sources = [
     "delay_estimator.cc",
@@ -113,20 +102,6 @@
     ]
   }
 
-  rtc_library("block_mean_calculator_unittest") {
-    testonly = true
-
-    sources = [
-      "block_mean_calculator_unittest.cc",
-    ]
-    deps = [
-      ":block_mean_calculator",
-      "../../../rtc_base:rtc_base_approved",
-      "../../../test:test_support",
-      "//testing/gtest",
-    ]
-  }
-
   rtc_library("legacy_delay_estimator_unittest") {
     testonly = true
 
diff --git a/modules/audio_processing/utility/block_mean_calculator.cc b/modules/audio_processing/utility/block_mean_calculator.cc
deleted file mode 100644
index 82c1c0f..0000000
--- a/modules/audio_processing/utility/block_mean_calculator.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "modules/audio_processing/utility/block_mean_calculator.h"
-
-#include "rtc_base/checks.h"
-
-namespace webrtc {
-
-BlockMeanCalculator::BlockMeanCalculator(size_t block_length)
-    : block_length_(block_length), count_(0), sum_(0.0), mean_(0.0) {
-  RTC_DCHECK(block_length_ != 0);
-}
-
-void BlockMeanCalculator::Reset() {
-  Clear();
-  mean_ = 0.0;
-}
-
-void BlockMeanCalculator::AddValue(float value) {
-  sum_ += value;
-  ++count_;
-  if (count_ == block_length_) {
-    mean_ = sum_ / block_length_;
-    Clear();
-  }
-}
-
-bool BlockMeanCalculator::EndOfBlock() const {
-  return count_ == 0;
-}
-
-float BlockMeanCalculator::GetLatestMean() const {
-  return mean_;
-}
-
-// Flush all samples added.
-void BlockMeanCalculator::Clear() {
-  count_ = 0;
-  sum_ = 0.0;
-}
-
-}  // namespace webrtc
diff --git a/modules/audio_processing/utility/block_mean_calculator.h b/modules/audio_processing/utility/block_mean_calculator.h
deleted file mode 100644
index 5ccdbef..0000000
--- a/modules/audio_processing/utility/block_mean_calculator.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef MODULES_AUDIO_PROCESSING_UTILITY_BLOCK_MEAN_CALCULATOR_H_
-#define MODULES_AUDIO_PROCESSING_UTILITY_BLOCK_MEAN_CALCULATOR_H_
-
-#include <stddef.h>
-
-#include "rtc_base/constructor_magic.h"
-
-namespace webrtc {
-
-// BlockMeanCalculator calculates the mean of a block of values. Values are
-// added one after another, and the mean is updated at the end of every block.
-class BlockMeanCalculator {
- public:
-  explicit BlockMeanCalculator(size_t block_length);
-
-  // Reset.
-  void Reset();
-
-  // Add one value to the sequence.
-  void AddValue(float value);
-
-  // Return whether the latest added value was at the end of a block.
-  bool EndOfBlock() const;
-
-  // Return the latest mean.
-  float GetLatestMean() const;
-
- private:
-  // Clear all values added.
-  void Clear();
-
-  const size_t block_length_;
-  size_t count_;
-  float sum_;
-  float mean_;
-
-  RTC_DISALLOW_COPY_AND_ASSIGN(BlockMeanCalculator);
-};
-
-}  // namespace webrtc
-
-#endif  // MODULES_AUDIO_PROCESSING_UTILITY_BLOCK_MEAN_CALCULATOR_H_
diff --git a/modules/audio_processing/utility/block_mean_calculator_unittest.cc b/modules/audio_processing/utility/block_mean_calculator_unittest.cc
deleted file mode 100644
index e829f69..0000000
--- a/modules/audio_processing/utility/block_mean_calculator_unittest.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "modules/audio_processing/utility/block_mean_calculator.h"
-
-#include "test/gtest.h"
-
-namespace webrtc {
-
-TEST(MeanCalculatorTest, Correctness) {
-  const size_t kBlockLength = 10;
-  BlockMeanCalculator mean_calculator(kBlockLength);
-  size_t i = 0;
-  float reference = 0.0;
-
-  for (; i < kBlockLength - 1; ++i) {
-    mean_calculator.AddValue(static_cast<float>(i));
-    EXPECT_FALSE(mean_calculator.EndOfBlock());
-  }
-  mean_calculator.AddValue(static_cast<float>(i++));
-  EXPECT_TRUE(mean_calculator.EndOfBlock());
-
-  for (; i < 3 * kBlockLength; ++i) {
-    const bool end_of_block = i % kBlockLength == 0;
-    if (end_of_block) {
-      // Sum of (i - kBlockLength) ... (i - 1)
-      reference = i - 0.5 * (1 + kBlockLength);
-    }
-    EXPECT_EQ(mean_calculator.EndOfBlock(), end_of_block);
-    EXPECT_EQ(reference, mean_calculator.GetLatestMean());
-    mean_calculator.AddValue(static_cast<float>(i));
-  }
-}
-
-TEST(MeanCalculatorTest, Reset) {
-  const size_t kBlockLength = 10;
-  BlockMeanCalculator mean_calculator(kBlockLength);
-  for (size_t i = 0; i < kBlockLength - 1; ++i) {
-    mean_calculator.AddValue(static_cast<float>(i));
-  }
-  mean_calculator.Reset();
-  size_t i = 0;
-  for (; i < kBlockLength - 1; ++i) {
-    mean_calculator.AddValue(static_cast<float>(i));
-    EXPECT_FALSE(mean_calculator.EndOfBlock());
-  }
-  mean_calculator.AddValue(static_cast<float>(i));
-  EXPECT_TRUE(mean_calculator.EndOfBlock());
-  EXPECT_EQ(mean_calculator.GetLatestMean(), 0.5 * (kBlockLength - 1));
-}
-
-}  // namespace webrtc