Revert 4837 "Add an extended filter mode to AEC."

> Add an extended filter mode to AEC.
> 
> This mode extends the filter length from the current 48 ms to 128 ms.
> It is runtime selectable which allows it to be enabled through
> experiment. We reuse the DelayCorrection infrastructure to avoid having
> to replumb everything up to libjingle.
> 
> Increases AEC complexity by ~50% on modern x86 CPUs.
> Measurements (in percent of usage on one core):
> 
> Machine/CPU                                     Normal Extended
> MacBook Retina (Early 2013),
> Core i7 Ivy Bridge (2.7 GHz, hyperthreaded)     0.6%   0.9%
> 
> MacBook Air (Late 2010), Core 2 Duo (2.13 GHz)  1.4%   2.7%
> 
> Chromebook Pixel, Core i5 Ivy Bridge (1.8 GHz)  0.6%   1.0%
> 
> Samsung ARM Chromebook,
> Samsung Exynos 5 Dual (1.7 GHz)                 3.2%   5.6%
> 
> The relative value is large of course but the absolute should be
> acceptable in order to have a working AEC on some platforms.
> 
> 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. Currently this will be enabled in Chromium for
> Mac.
> - 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.
> 
> Corresponds to these changes:
> https://chromereviews.googleplex.com/9412014
> https://chromereviews.googleplex.com/9514013
> https://chromereviews.googleplex.com/9960013
> 
> BUG=454,827,1261
> R=bjornv@webrtc.org
> 
> Review URL: https://webrtc-codereview.appspot.com/2151007

TBR=andrew@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/2296005

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4839 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_processing/aec/aec_core.c b/webrtc/modules/audio_processing/aec/aec_core.c
index 40e9f67..d194c82 100644
--- a/webrtc/modules/audio_processing/aec/aec_core.c
+++ b/webrtc/modules/audio_processing/aec/aec_core.c
@@ -109,17 +109,7 @@
 // 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 };
-static const float kExtendedSmoothingCoefficients[2][2] =
-    { { 0.9f, 0.1f }, { 0.92f, 0.08f } };
-static const float kNormalSmoothingCoefficients[2][2] =
-    { { 0.9f, 0.1f }, { 0.93f, 0.07f } };
-
-// Number of partitions forming the NLP's "preferred" bands.
-enum { kPrefBandSize = 24 };
+static const float kMinOverDrive[3] = { 1.0f, 2.0f, 5.0f };
 
 #ifdef WEBRTC_AEC_DEBUG_DUMP
 extern int webrtc_aec_instance_count;
@@ -291,13 +281,13 @@
 static void FilterFar(AecCore* aec, float yf[2][PART_LEN1])
 {
   int i;
-  for (i = 0; i < aec->num_partitions; i++) {
+  for (i = 0; i < NR_PART; i++) {
     int j;
     int xPos = (i + aec->xfBufBlockPos) * PART_LEN1;
     int pos = i * PART_LEN1;
     // Check for wrap
-    if (i + aec->xfBufBlockPos >= aec->num_partitions) {
-      xPos -= aec->num_partitions*(PART_LEN1);
+    if (i + aec->xfBufBlockPos >= NR_PART) {
+      xPos -= NR_PART*(PART_LEN1);
     }
 
     for (j = 0; j < PART_LEN1; j++) {
@@ -311,25 +301,22 @@
 
 static void ScaleErrorSignal(AecCore* aec, float ef[2][PART_LEN1])
 {
-  const float mu = aec->extended_filter_enabled ? kExtendedMu : aec->normal_mu;
-  const float error_threshold = aec->extended_filter_enabled ?
-      kExtendedErrorThreshold : aec->normal_error_threshold;
   int i;
-  float abs_ef;
+  float absEf;
   for (i = 0; i < (PART_LEN1); i++) {
     ef[0][i] /= (aec->xPow[i] + 1e-10f);
     ef[1][i] /= (aec->xPow[i] + 1e-10f);
-    abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]);
+    absEf = 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;
+    if (absEf > aec->errThresh) {
+      absEf = aec->errThresh / (absEf + 1e-10f);
+      ef[0][i] *= absEf;
+      ef[1][i] *= absEf;
     }
 
     // Stepsize factor
-    ef[0][i] *= mu;
-    ef[1][i] *= mu;
+    ef[0][i] *= aec->mu;
+    ef[1][i] *= aec->mu;
   }
 }
 
@@ -338,35 +325,35 @@
 //static void FilterAdaptationUnconstrained(AecCore* aec, float *fft,
 //                                          float ef[2][PART_LEN1]) {
 //  int i, j;
-//  for (i = 0; i < aec->num_partitions; i++) {
+//  for (i = 0; i < NR_PART; i++) {
 //    int xPos = (i + aec->xfBufBlockPos)*(PART_LEN1);
 //    int pos;
 //    // Check for wrap
-//    if (i + aec->xfBufBlockPos >= aec->num_partitions) {
-//      xPos -= aec->num_partitions * PART_LEN1;
+//    if (i + aec->xfBufBlockPos >= NR_PART) {
+//      xPos -= NR_PART * PART_LEN1;
 //    }
 //
 //    pos = i * PART_LEN1;
 //
 //    for (j = 0; j < PART_LEN1; j++) {
-//      aec->wfBuf[0][pos + j] += MulRe(aec->xfBuf[0][xPos + j],
-//                                      -aec->xfBuf[1][xPos + j],
-//                                      ef[0][j], ef[1][j]);
-//      aec->wfBuf[1][pos + j] += MulIm(aec->xfBuf[0][xPos + j],
-//                                      -aec->xfBuf[1][xPos + j],
-//                                      ef[0][j], ef[1][j]);
+//      aec->wfBuf[pos + j][0] += MulRe(aec->xfBuf[xPos + j][0],
+//                                      -aec->xfBuf[xPos + j][1],
+//                                      ef[j][0], ef[j][1]);
+//      aec->wfBuf[pos + j][1] += MulIm(aec->xfBuf[xPos + j][0],
+//                                      -aec->xfBuf[xPos + j][1],
+//                                      ef[j][0], ef[j][1]);
 //    }
 //  }
 //}
 
 static void FilterAdaptation(AecCore* aec, float *fft, float ef[2][PART_LEN1]) {
   int i, j;
-  for (i = 0; i < aec->num_partitions; i++) {
+  for (i = 0; i < NR_PART; i++) {
     int xPos = (i + aec->xfBufBlockPos)*(PART_LEN1);
     int pos;
     // Check for wrap
-    if (i + aec->xfBufBlockPos >= aec->num_partitions) {
-      xPos -= aec->num_partitions * PART_LEN1;
+    if (i + aec->xfBufBlockPos >= NR_PART) {
+      xPos -= NR_PART * PART_LEN1;
     }
 
     pos = i * PART_LEN1;
@@ -440,12 +427,12 @@
     aec->sampFreq = sampFreq;
 
     if (sampFreq == 8000) {
-        aec->normal_mu = 0.6f;
-        aec->normal_error_threshold = 2e-6f;
+        aec->mu = 0.6f;
+        aec->errThresh = 2e-6f;
     }
     else {
-        aec->normal_mu = 0.5f;
-        aec->normal_error_threshold = 1.5e-6f;
+        aec->mu = 0.5f;
+        aec->errThresh = 1.5e-6f;
     }
 
     if (WebRtc_InitBuffer(aec->nearFrBuf) == -1) {
@@ -487,9 +474,6 @@
     aec->delay_logging_enabled = 0;
     memset(aec->delay_histogram, 0, sizeof(aec->delay_histogram));
 
-    aec->extended_filter_enabled = 0;
-    aec->num_partitions = kNormalNumPartitions;
-
     // Default target suppression mode.
     aec->nlp_mode = 1;
 
@@ -499,7 +483,7 @@
       aec->mult = (short)aec->sampFreq / 16000;
     }
     else {
-      aec->mult = (short)aec->sampFreq / 8000;
+        aec->mult = (short)aec->sampFreq / 8000;
     }
 
     aec->farBufWritePos = 0;
@@ -530,14 +514,11 @@
     aec->xfBufBlockPos = 0;
     // TODO: 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->xfBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1);
+    memset(aec->wfBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1);
     memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1);
     memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1);
-    memset(aec->xfwBuf, 0, sizeof(complex_t) * kExtendedNumPartitions *
-        PART_LEN1);
+    memset(aec->xfwBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1);
     memset(aec->se, 0, sizeof(float) * PART_LEN1);
 
     // To prevent numerical instability in the first block.
@@ -753,11 +734,13 @@
 }
 
 int WebRtcAec_echo_state(AecCore* self) {
+  assert(self != NULL);
   return self->echoState;
 }
 
 void WebRtcAec_GetEchoStats(AecCore* self, Stats* erl, Stats* erle,
                             Stats* a_nlp) {
+  assert(self != NULL);
   assert(erl != NULL);
   assert(erle != NULL);
   assert(a_nlp != NULL);
@@ -768,12 +751,14 @@
 
 #ifdef WEBRTC_AEC_DEBUG_DUMP
 void* WebRtcAec_far_time_buf(AecCore* self) {
+  assert(self != NULL);
   return self->far_time_buf;
 }
 #endif
 
 void WebRtcAec_SetConfigCore(AecCore* self, int nlp_mode, int metrics_mode,
                              int delay_logging) {
+  assert(self != NULL);
   assert(nlp_mode >= 0 && nlp_mode < 3);
   self->nlp_mode = nlp_mode;
   self->metricsMode = metrics_mode;
@@ -786,20 +771,13 @@
   }
 }
 
-void WebRtcAec_enable_delay_correction(AecCore* self, int enable) {
-  self->extended_filter_enabled = enable;
-  self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions;
-}
-
-int WebRtcAec_delay_correction_enabled(AecCore* self) {
-  return self->extended_filter_enabled;
-}
-
 int WebRtcAec_system_delay(AecCore* self) {
+  assert(self != NULL);
   return self->system_delay;
 }
 
 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
+  assert(self != NULL);
   assert(delay >= 0);
   self->system_delay = delay;
 }
@@ -875,8 +853,7 @@
     for (i = 0; i < PART_LEN1; i++) {
       far_spectrum = (xf_ptr[i] * xf_ptr[i]) +
           (xf_ptr[PART_LEN1 + i] * xf_ptr[PART_LEN1 + i]);
-      aec->xPow[i] = gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions *
-          far_spectrum;
+      aec->xPow[i] = gPow[0] * aec->xPow[i] + gPow[1] * NR_PART * far_spectrum;
       // Calculate absolute spectra
       abs_far_spectrum[i] = sqrtf(far_spectrum);
 
@@ -936,7 +913,7 @@
     // Update the xfBuf block position.
     aec->xfBufBlockPos--;
     if (aec->xfBufBlockPos == -1) {
-        aec->xfBufBlockPos = aec->num_partitions - 1;
+        aec->xfBufBlockPos = NR_PART - 1;
     }
 
     // Buffer xf
@@ -1037,21 +1014,18 @@
     float cohde[PART_LEN1], cohxd[PART_LEN1];
     float hNlDeAvg, hNlXdAvg;
     float hNl[PART_LEN1];
-    float hNlPref[kPrefBandSize];
+    float hNlPref[PREF_BAND_SIZE];
     float hNlFb = 0, hNlFbLow = 0;
     const float prefBandQuant = 0.75f, prefBandQuantLow = 0.5f;
-    const int prefBandSize = kPrefBandSize / aec->mult;
+    const int prefBandSize = PREF_BAND_SIZE / aec->mult;
     const int minPrefBand = 4 / aec->mult;
 
     // Near and error power sums
     float sdSum = 0, seSum = 0;
 
-    // Power estimate smoothing coefficients.
-    const float *ptrGCoh = aec->extended_filter_enabled ?
-        kExtendedSmoothingCoefficients[aec->mult - 1] :
-        kNormalSmoothingCoefficients[aec->mult - 1];
-    const float* min_overdrive = aec->extended_filter_enabled ?
-        kExtendedMinOverDrive : kNormalMinOverDrive;
+    // Power estimate smoothing coefficients
+    const float gCoh[2][2] = {{0.9f, 0.1f}, {0.93f, 0.07f}};
+    const float *ptrGCoh = gCoh[aec->mult - 1];
 
     // Filter energy
     float wfEnMax = 0, wfEn = 0;
@@ -1074,7 +1048,7 @@
     if (aec->delayEstCtr == 0) {
         wfEnMax = 0;
         aec->delayIdx = 0;
-        for (i = 0; i < aec->num_partitions; i++) {
+        for (i = 0; i < NR_PART; i++) {
             pos = i * PART_LEN1;
             wfEn = 0;
             for (j = 0; j < PART_LEN1; j++) {
@@ -1215,7 +1189,7 @@
 
     if (aec->hNlXdAvgMin == 1) {
         aec->echoState = 0;
-        aec->overDrive = min_overdrive[aec->nlp_mode];
+        aec->overDrive = kMinOverDrive[aec->nlp_mode];
 
         if (aec->stNearState == 1) {
             memcpy(hNl, cohde, sizeof(hNl));
@@ -1271,7 +1245,7 @@
         aec->hNlMinCtr = 0;
         aec->overDrive = WEBRTC_SPL_MAX(kTargetSupp[aec->nlp_mode] /
             ((float)log(aec->hNlFbMin + 1e-10f) + 1e-10f),
-            min_overdrive[aec->nlp_mode]);
+            kMinOverDrive[aec->nlp_mode]);
     }
 
     // Smooth the overdrive.
@@ -1491,6 +1465,7 @@
 }
 
 static void InitMetrics(AecCore* self) {
+  assert(self != NULL);
   self->stateCounter = 0;
   InitLevel(&self->farlevel);
   InitLevel(&self->nearlevel);
@@ -1712,4 +1687,3 @@
     freq_data[1][i] = time_data[2 * i + 1];
   }
 }
-
diff --git a/webrtc/modules/audio_processing/aec/aec_core.h b/webrtc/modules/audio_processing/aec/aec_core.h
index f83c37c..6380717 100644
--- a/webrtc/modules/audio_processing/aec/aec_core.h
+++ b/webrtc/modules/audio_processing/aec/aec_core.h
@@ -70,38 +70,23 @@
 // Returns the number of elements moved, and adjusts |system_delay| by the
 // corresponding amount in ms.
 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements);
-
 // Calculates the median and standard deviation among the delay estimates
 // collected since the last call to this function.
 int WebRtcAec_GetDelayMetricsCore(AecCore* self, int* median, int* std);
-
 // 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);
 #ifdef WEBRTC_AEC_DEBUG_DUMP
 void* WebRtcAec_far_time_buf(AecCore* self);
 #endif
-
 // Sets local configuration modes.
 void WebRtcAec_SetConfigCore(AecCore* self, int nlp_mode, int metrics_mode,
                              int delay_logging);
-
-// We now interpret delay correction to mean an extended filter length feature.
-// We reuse the delay correction infrastructure to avoid changes through to
-// libjingle. See details along with |DelayCorrection| in
-// echo_cancellation_impl.h. Non-zero enables, zero disables.
-void WebRtcAec_enable_delay_correction(AecCore* self, int enable);
-
-// Returns non-zero if delay correction is enabled and zero if disabled.
-int WebRtcAec_delay_correction_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.
diff --git a/webrtc/modules/audio_processing/aec/aec_core_internal.h b/webrtc/modules/audio_processing/aec/aec_core_internal.h
index 4480101..3b92bd6 100644
--- a/webrtc/modules/audio_processing/aec/aec_core_internal.h
+++ b/webrtc/modules/audio_processing/aec/aec_core_internal.h
@@ -19,15 +19,8 @@
 #include "webrtc/modules/audio_processing/utility/ring_buffer.h"
 #include "webrtc/typedefs.h"
 
-// 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;
-
-// Extended filter adaptation parameters.
-// TODO(ajm): No narrowband tuning yet.
-static const float kExtendedMu = 0.4f;
-static const float kExtendedErrorThreshold = 1.0e-6f;
+#define NR_PART 12  // Number of partitions in filter.
+#define PREF_BAND_SIZE 24
 
 typedef struct PowerLevel {
   float sfrsum;
@@ -63,12 +56,11 @@
   float dInitMinPow[PART_LEN1];
   float *noisePow;
 
-  float xfBuf[2][kExtendedNumPartitions * PART_LEN1];  // farend fft buffer
-  float wfBuf[2][kExtendedNumPartitions * PART_LEN1];  // filter fft
+  float xfBuf[2][NR_PART * PART_LEN1];  // farend fft buffer
+  float wfBuf[2][NR_PART * PART_LEN1];  // filter fft
   complex_t sde[PART_LEN1];  // cross-psd of nearend and error
   complex_t sxd[PART_LEN1];  // cross-psd of farend and nearend
-  // Farend windowed fft buffer.
-  complex_t xfwBuf[kExtendedNumPartitions * PART_LEN1];
+  complex_t xfwBuf[NR_PART * PART_LEN1];  // farend windowed fft buffer
 
   float sx[PART_LEN1], sd[PART_LEN1], se[PART_LEN1];  // far, near, error psd
   float hNs[PART_LEN1];
@@ -93,8 +85,8 @@
   int sampFreq;
   uint32_t seed;
 
-  float normal_mu;  // stepsize
-  float normal_error_threshold;  // error threshold
+  float mu;  // stepsize
+  float errThresh;  // error threshold
 
   int noiseEstCtr;
 
@@ -120,11 +112,6 @@
   void* delay_estimator_farend;
   void* delay_estimator;
 
-  // 1 = extended filter mode enabled, 0 = disabled.
-  int extended_filter_enabled;
-  // Runtime selection of number of filter partitions.
-  int num_partitions;
-
 #ifdef WEBRTC_AEC_DEBUG_DUMP
   RingBuffer* far_time_buf;
   FILE *farFile;
diff --git a/webrtc/modules/audio_processing/aec/aec_core_sse2.c b/webrtc/modules/audio_processing/aec/aec_core_sse2.c
index 61602a8..fdc6872 100644
--- a/webrtc/modules/audio_processing/aec/aec_core_sse2.c
+++ b/webrtc/modules/audio_processing/aec/aec_core_sse2.c
@@ -34,14 +34,13 @@
 static void FilterFarSSE2(AecCore* aec, float yf[2][PART_LEN1])
 {
   int i;
-  const int num_partitions = aec->num_partitions;
-  for (i = 0; i < num_partitions; i++) {
+  for (i = 0; i < NR_PART; i++) {
     int j;
     int xPos = (i + aec->xfBufBlockPos) * PART_LEN1;
     int pos = i * PART_LEN1;
     // Check for wrap
-    if (i + aec->xfBufBlockPos >= num_partitions) {
-      xPos -= num_partitions*(PART_LEN1);
+    if (i + aec->xfBufBlockPos >= NR_PART) {
+      xPos -= NR_PART*(PART_LEN1);
     }
 
     // vectorized code (four at once)
@@ -76,11 +75,8 @@
 static void ScaleErrorSignalSSE2(AecCore* aec, float ef[2][PART_LEN1])
 {
   const __m128 k1e_10f = _mm_set1_ps(1e-10f);
-  const __m128 kMu = aec->extended_filter_enabled ?
-      _mm_set1_ps(kExtendedMu) : _mm_set1_ps(aec->normal_mu);
-  const __m128 kThresh = aec->extended_filter_enabled ?
-      _mm_set1_ps(kExtendedErrorThreshold) :
-      _mm_set1_ps(aec->normal_error_threshold);
+  const __m128 kThresh = _mm_set1_ps(aec->errThresh);
+  const __m128 kMu = _mm_set1_ps(aec->mu);
 
   int i;
   // vectorized code (four at once)
@@ -114,39 +110,32 @@
     _mm_storeu_ps(&ef[1][i], ef_im);
   }
   // scalar code for the remaining items.
-  {
-    const float mu = aec->extended_filter_enabled ?
-        kExtendedMu : aec->normal_mu;
-    const float error_threshold = aec->extended_filter_enabled ?
-        kExtendedErrorThreshold : aec->normal_error_threshold;
-    for (; i < (PART_LEN1); i++) {
-    float abs_ef;
-      ef[0][i] /= (aec->xPow[i] + 1e-10f);
-      ef[1][i] /= (aec->xPow[i] + 1e-10f);
-      abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]);
+  for (; i < (PART_LEN1); i++) {
+    float absEf;
+    ef[0][i] /= (aec->xPow[i] + 1e-10f);
+    ef[1][i] /= (aec->xPow[i] + 1e-10f);
+    absEf = 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;
+    if (absEf > aec->errThresh) {
+      absEf = aec->errThresh / (absEf + 1e-10f);
+      ef[0][i] *= absEf;
+      ef[1][i] *= absEf;
     }
+
+    // Stepsize factor
+    ef[0][i] *= aec->mu;
+    ef[1][i] *= aec->mu;
   }
 }
 
 static void FilterAdaptationSSE2(AecCore* aec, float *fft, float ef[2][PART_LEN1]) {
   int i, j;
-  const int num_partitions = aec->num_partitions;
-  for (i = 0; i < num_partitions; i++) {
+  for (i = 0; i < NR_PART; i++) {
     int xPos = (i + aec->xfBufBlockPos)*(PART_LEN1);
     int pos = i * PART_LEN1;
     // Check for wrap
-    if (i + aec->xfBufBlockPos >= num_partitions) {
-      xPos -= num_partitions * PART_LEN1;
+    if (i + aec->xfBufBlockPos >= NR_PART) {
+      xPos -= NR_PART * PART_LEN1;
     }
 
     // Process the whole array...
@@ -424,4 +413,3 @@
   WebRtcAec_FilterAdaptation = FilterAdaptationSSE2;
   WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppressSSE2;
 }
-
diff --git a/webrtc/modules/audio_processing/aec/echo_cancellation.c b/webrtc/modules/audio_processing/aec/echo_cancellation.c
index 07bca55..2d41359 100644
--- a/webrtc/modules/audio_processing/aec/echo_cancellation.c
+++ b/webrtc/modules/audio_processing/aec/echo_cancellation.c
@@ -27,61 +27,6 @@
 #include "webrtc/modules/audio_processing/utility/ring_buffer.h"
 #include "webrtc/typedefs.h"
 
-// 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_MAC)
-static const int kFixedDelayMs = 20;
-static const int kDelayDiffOffsetSamples = -160;
-#elif defined(WEBRTC_WIN)
-static const int kFixedDelayMs = 50;
-static const int kDelayDiffOffsetSamples = 0;
-#else
-// Essentially ChromeOS.
-static const int kFixedDelayMs = 50;
-static const int kDelayDiffOffsetSamples = 0;
-#endif
-static const int kMinTrustedDelayMs = 20;
-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
@@ -98,14 +43,7 @@
 
 // Estimates delay to set the position of the far-end buffer read pointer
 // (controlled by knownDelay)
-static void EstBufDelayNormal(aecpc_t *aecInst);
-static void EstBufDelayExtended(aecpc_t *aecInst);
-static int ProcessNormal(aecpc_t* self, const int16_t* near,
-    const int16_t* near_high, int16_t* out, int16_t* out_high,
-    int16_t num_samples, int16_t reported_delay_ms, int32_t skew);
-static void ProcessExtended(aecpc_t* self, const int16_t* near,
-    const int16_t* near_high, int16_t* out, int16_t* out_high,
-    int16_t num_samples, int16_t reported_delay_ms, int32_t skew);
+static int EstBufDelay(aecpc_t *aecInst);
 
 int32_t WebRtcAec_Create(void **aecInst)
 {
@@ -197,6 +135,10 @@
     aecpc_t *aecpc = aecInst;
     AecConfig aecConfig;
 
+    if (aecpc == NULL) {
+        return -1;
+    }
+
     if (sampFreq != 8000 && sampFreq != 16000  && sampFreq != 32000) {
         aecpc->lastError = AEC_BAD_PARAMETER_ERROR;
         return -1;
@@ -235,31 +177,31 @@
         aecpc->splitSampFreq = sampFreq;
     }
 
+    aecpc->skewFrCtr = 0;
+    aecpc->activity = 0;
+
     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;
 
-    aecpc->startup_phase = 1;
+    aecpc->ECstartup = 1;
     aecpc->bufSizeStart = 0;
     aecpc->checkBufSizeCtr = 0;
-    aecpc->msInSndCardBuf = 0;
-    aecpc->filtDelay = -1;  // -1 indicates an initialized state.
+    aecpc->filtDelay = 0;
     aecpc->timeForDelayChange = 0;
     aecpc->knownDelay = 0;
     aecpc->lastDelayDiff = 0;
 
-    aecpc->skewFrCtr = 0;
+    aecpc->skew = 0;
     aecpc->resample = kAecFalse;
     aecpc->highSkewCtr = 0;
-    aecpc->skew = 0;
+    aecpc->sampFactor = (aecpc->scSampFreq * 1.0f) / aecpc->splitSampFreq;
 
-    aecpc->farend_started = 0;
+    // Sampling frequency multiplier (SWB is processed as 160 frame size).
+    aecpc->rate_factor = aecpc->splitSampFreq / 8000;
 
     // Default settings.
     aecConfig.nlpMode = kAecNlpModerate;
@@ -297,6 +239,10 @@
     float skew;
     int i = 0;
 
+    if (aecpc == NULL) {
+        return -1;
+    }
+
     if (farend == NULL) {
         aecpc->lastError = AEC_NULL_POINTER_ERROR;
         return -1;
@@ -322,7 +268,6 @@
         farend_ptr = (const int16_t*) newFarend;
     }
 
-    aecpc->farend_started = 1;
     WebRtcAec_SetSystemDelay(aecpc->aec, WebRtcAec_system_delay(aecpc->aec) +
                              newNrOfSamples);
 
@@ -366,6 +311,17 @@
 {
     aecpc_t *aecpc = aecInst;
     int32_t retVal = 0;
+    short i;
+    short nBlocks10ms;
+    short nFrames;
+    // Limit resampling to doubling/halving of signal
+    const float minSkewEst = -0.5f;
+    const float maxSkewEst = 1.0f;
+
+    if (aecpc == NULL) {
+        return -1;
+    }
+
     if (nearend == NULL) {
         aecpc->lastError = AEC_NULL_POINTER_ERROR;
         return -1;
@@ -398,21 +354,144 @@
         aecpc->lastError = AEC_BAD_PARAMETER_WARNING;
         retVal = -1;
     }
-    else if (msInSndCardBuf > kMaxTrustedDelayMs) {
-        // The clamping is now done in ProcessExtended/Normal().
+    else if (msInSndCardBuf > 500) {
+        msInSndCardBuf = 500;
         aecpc->lastError = AEC_BAD_PARAMETER_WARNING;
         retVal = -1;
     }
+    // TODO(andrew): we need to investigate if this +10 is really wanted.
+    msInSndCardBuf += 10;
+    aecpc->msInSndCardBuf = msInSndCardBuf;
 
-    // This returns the value of aec->extended_filter_enabled.
-    if (WebRtcAec_delay_correction_enabled(aecpc->aec)) {
-      ProcessExtended(aecpc, nearend, nearendH, out, outH, nrOfSamples,
-                      msInSndCardBuf, skew);
+    if (aecpc->skewMode == kAecTrue) {
+        if (aecpc->skewFrCtr < 25) {
+            aecpc->skewFrCtr++;
+        }
+        else {
+            retVal = WebRtcAec_GetSkew(aecpc->resampler, skew, &aecpc->skew);
+            if (retVal == -1) {
+                aecpc->skew = 0;
+                aecpc->lastError = AEC_BAD_PARAMETER_WARNING;
+            }
+
+            aecpc->skew /= aecpc->sampFactor*nrOfSamples;
+
+            if (aecpc->skew < 1.0e-3 && aecpc->skew > -1.0e-3) {
+                aecpc->resample = kAecFalse;
+            }
+            else {
+                aecpc->resample = kAecTrue;
+            }
+
+            if (aecpc->skew < minSkewEst) {
+                aecpc->skew = minSkewEst;
+            }
+            else if (aecpc->skew > maxSkewEst) {
+                aecpc->skew = maxSkewEst;
+            }
+
+#ifdef WEBRTC_AEC_DEBUG_DUMP
+            (void)fwrite(&aecpc->skew, sizeof(aecpc->skew), 1, aecpc->skewFile);
+#endif
+        }
+    }
+
+    nFrames = nrOfSamples / FRAME_LEN;
+    nBlocks10ms = nFrames / aecpc->rate_factor;
+
+    if (aecpc->ECstartup) {
+        if (nearend != out) {
+            // Only needed if they don't already point to the same place.
+            memcpy(out, nearend, sizeof(short) * nrOfSamples);
+        }
+
+        // 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 (aecpc->checkBuffSize) {
+            aecpc->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 (aecpc->counter == 0) {
+                aecpc->firstVal = aecpc->msInSndCardBuf;
+                aecpc->sum = 0;
+            }
+
+            if (abs(aecpc->firstVal - aecpc->msInSndCardBuf) <
+                WEBRTC_SPL_MAX(0.2 * aecpc->msInSndCardBuf, sampMsNb)) {
+                aecpc->sum += aecpc->msInSndCardBuf;
+                aecpc->counter++;
+            }
+            else {
+                aecpc->counter = 0;
+            }
+
+            if (aecpc->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.
+                aecpc->bufSizeStart = WEBRTC_SPL_MIN((3 * aecpc->sum *
+                  aecpc->rate_factor * 8) / (4 * aecpc->counter * PART_LEN),
+                  kMaxBufSizeStart);
+                // Buffer size has now been determined.
+                aecpc->checkBuffSize = 0;
+            }
+
+            if (aecpc->checkBufSizeCtr * nBlocks10ms > 50) {
+                // For really bad systems, don't disable the echo canceller for
+                // more than 0.5 sec.
+                aecpc->bufSizeStart = WEBRTC_SPL_MIN((aecpc->msInSndCardBuf *
+                    aecpc->rate_factor * 3) / 40, kMaxBufSizeStart);
+                aecpc->checkBuffSize = 0;
+            }
+        }
+
+        // If |checkBuffSize| changed in the if-statement above.
+        if (!aecpc->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(aecpc->aec) / PART_LEN -
+                aecpc->bufSizeStart;
+            if (overhead_elements == 0) {
+                // Enable the AEC
+                aecpc->ECstartup = 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_MoveFarReadPtr(aecpc->aec, overhead_elements);
+
+                // Enable the AEC
+                aecpc->ECstartup = 0;
+            }
+        }
     } else {
-      if (ProcessNormal(aecpc, nearend, nearendH, out, outH, nrOfSamples,
-                        msInSndCardBuf, skew) != 0) {
-        retVal = -1;
-      }
+        // AEC is enabled.
+
+        EstBufDelay(aecpc);
+
+        // Note that 1 frame is supported for NB and 2 frames for WB.
+        for (i = 0; i < nFrames; i++) {
+            // Call the AEC.
+            WebRtcAec_ProcessFrame(aecpc->aec,
+                                   &nearend[FRAME_LEN * i],
+                                   &nearendH[FRAME_LEN * i],
+                                   aecpc->knownDelay,
+                                   &out[FRAME_LEN * i],
+                                   &outH[FRAME_LEN * i]);
+            // TODO(bjornv): Re-structure such that we don't have to pass
+            // |aecpc->knownDelay| as input. Change name to something like
+            // |system_buffer_diff|.
+        }
     }
 
 #ifdef WEBRTC_AEC_DEBUG_DUMP
@@ -430,6 +509,11 @@
 
 int WebRtcAec_set_config(void* handle, AecConfig config) {
   aecpc_t* self = (aecpc_t*)handle;
+
+  if (handle == NULL ) {
+    return -1;
+  }
+
   if (self->initFlag != initCheck) {
     self->lastError = AEC_UNINITIALIZED_ERROR;
     return -1;
@@ -464,6 +548,10 @@
 
 int WebRtcAec_get_echo_status(void* handle, int* status) {
   aecpc_t* self = (aecpc_t*)handle;
+
+  if (handle == NULL ) {
+    return -1;
+  }
   if (status == NULL ) {
     self->lastError = AEC_NULL_POINTER_ERROR;
     return -1;
@@ -577,6 +665,10 @@
 
 int WebRtcAec_GetDelayMetrics(void* handle, int* median, int* std) {
   aecpc_t* self = handle;
+
+  if (handle == NULL) {
+    return -1;
+  }
   if (median == NULL) {
     self->lastError = AEC_NULL_POINTER_ERROR;
     return -1;
@@ -601,6 +693,11 @@
 int32_t WebRtcAec_get_error_code(void *aecInst)
 {
     aecpc_t *aecpc = aecInst;
+
+    if (aecpc == NULL) {
+        return -1;
+    }
+
     return aecpc->lastError;
 }
 
@@ -611,220 +708,7 @@
   return ((aecpc_t*) handle)->aec;
 }
 
-static int ProcessNormal(aecpc_t *aecpc, const int16_t *nearend,
-                         const int16_t *nearendH, int16_t *out, int16_t *outH,
-                         int16_t nrOfSamples, int16_t msInSndCardBuf,
-                         int32_t skew) {
-  int retVal = 0;
-  short i;
-  short nBlocks10ms;
-  short nFrames;
-  // Limit resampling to doubling/halving of signal
-  const float minSkewEst = -0.5f;
-  const float maxSkewEst = 1.0f;
-
-  msInSndCardBuf = msInSndCardBuf > kMaxTrustedDelayMs ?
-      kMaxTrustedDelayMs : msInSndCardBuf;
-  // TODO(andrew): we need to investigate if this +10 is really wanted.
-  msInSndCardBuf += 10;
-  aecpc->msInSndCardBuf = msInSndCardBuf;
-
-  if (aecpc->skewMode == kAecTrue) {
-    if (aecpc->skewFrCtr < 25) {
-      aecpc->skewFrCtr++;
-    }
-    else {
-      retVal = WebRtcAec_GetSkew(aecpc->resampler, skew, &aecpc->skew);
-      if (retVal == -1) {
-        aecpc->skew = 0;
-        aecpc->lastError = AEC_BAD_PARAMETER_WARNING;
-      }
-
-      aecpc->skew /= aecpc->sampFactor*nrOfSamples;
-
-      if (aecpc->skew < 1.0e-3 && aecpc->skew > -1.0e-3) {
-        aecpc->resample = kAecFalse;
-      }
-      else {
-        aecpc->resample = kAecTrue;
-      }
-
-      if (aecpc->skew < minSkewEst) {
-        aecpc->skew = minSkewEst;
-      }
-      else if (aecpc->skew > maxSkewEst) {
-        aecpc->skew = maxSkewEst;
-      }
-
-#ifdef WEBRTC_AEC_DEBUG_DUMP
-      (void)fwrite(&aecpc->skew, sizeof(aecpc->skew), 1, aecpc->skewFile);
-#endif
-    }
-  }
-
-  nFrames = nrOfSamples / FRAME_LEN;
-  nBlocks10ms = nFrames / aecpc->rate_factor;
-
-  if (aecpc->startup_phase) {
-    // Only needed if they don't already point to the same place.
-    if (nearend != out) {
-      memcpy(out, nearend, sizeof(short) * nrOfSamples);
-    }
-    if (nearendH != outH) {
-      memcpy(outH, nearendH, sizeof(short) * nrOfSamples);
-    }
-
-    // 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 (aecpc->checkBuffSize) {
-      aecpc->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 (aecpc->counter == 0) {
-        aecpc->firstVal = aecpc->msInSndCardBuf;
-        aecpc->sum = 0;
-      }
-
-      if (abs(aecpc->firstVal - aecpc->msInSndCardBuf) <
-        WEBRTC_SPL_MAX(0.2 * aecpc->msInSndCardBuf, sampMsNb)) {
-        aecpc->sum += aecpc->msInSndCardBuf;
-        aecpc->counter++;
-      }
-      else {
-        aecpc->counter = 0;
-      }
-
-      if (aecpc->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.
-        aecpc->bufSizeStart = WEBRTC_SPL_MIN((3 * aecpc->sum *
-            aecpc->rate_factor * 8) / (4 * aecpc->counter * PART_LEN),
-            kMaxBufSizeStart);
-        // Buffer size has now been determined.
-        aecpc->checkBuffSize = 0;
-      }
-
-      if (aecpc->checkBufSizeCtr * nBlocks10ms > 50) {
-        // For really bad systems, don't disable the echo canceller for
-        // more than 0.5 sec.
-        aecpc->bufSizeStart = WEBRTC_SPL_MIN((aecpc->msInSndCardBuf *
-            aecpc->rate_factor * 3) / 40, kMaxBufSizeStart);
-        aecpc->checkBuffSize = 0;
-      }
-    }
-
-    // If |checkBuffSize| changed in the if-statement above.
-    if (!aecpc->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(aecpc->aec) / PART_LEN - aecpc->bufSizeStart;
-      if (overhead_elements == 0) {
-        // Enable the AEC
-        aecpc->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_MoveFarReadPtr(aecpc->aec, overhead_elements);
-
-        // Enable the AEC
-        aecpc->startup_phase = 0;
-      }
-    }
-  } else {
-    // AEC is enabled.
-    EstBufDelayNormal(aecpc);
-
-    // Note that 1 frame is supported for NB and 2 frames for WB.
-    for (i = 0; i < nFrames; i++) {
-      // Call the AEC.
-      WebRtcAec_ProcessFrame(aecpc->aec,
-                             &nearend[FRAME_LEN * i],
-                             &nearendH[FRAME_LEN * i],
-                             aecpc->knownDelay,
-                             &out[FRAME_LEN * i],
-                             &outH[FRAME_LEN * i]);
-      // TODO(bjornv): Re-structure such that we don't have to pass
-      // |aecpc->knownDelay| as input. Change name to something like
-      // |system_buffer_diff|.
-    }
-  }
-
-  return retVal;
-}
-
-static void ProcessExtended(aecpc_t* self, const int16_t* near,
-    const int16_t* near_high, int16_t* out, int16_t* out_high,
-    int16_t num_samples, int16_t reported_delay_ms, int32_t skew) {
-  int i;
-  const int num_frames = num_samples / FRAME_LEN;
-#if defined(WEBRTC_UNTRUSTED_DELAY)
-  const int delay_diff_offset = kDelayDiffOffsetSamples;
-  reported_delay_ms = kFixedDelayMs;
-#else
-  // This is the usual mode where we trust the reported system delay values.
-  const int delay_diff_offset = 0;
-  // 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) {
-    // Only needed if they don't already point to the same place.
-    if (near != out) {
-      memcpy(out, near, sizeof(short) * num_samples);
-    }
-    if (near_high != out_high) {
-      memcpy(out_high, near_high, sizeof(short) * 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;
-    int overhead_elements = (WebRtcAec_system_delay(self->aec) -
-        startup_size_ms / 2 * self->rate_factor * 8) / PART_LEN;
-    WebRtcAec_MoveFarReadPtr(self->aec, overhead_elements);
-    self->startup_phase = 0;
-  }
-
-  EstBufDelayExtended(self);
-
-  for (i = 0; i < num_frames; ++i) {
-    // |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|.
-    WebRtcAec_ProcessFrame(self->aec, &near[FRAME_LEN * i],
-        &near_high[FRAME_LEN * i], self->knownDelay + delay_diff_offset,
-        &out[FRAME_LEN * i], &out_high[FRAME_LEN * i]);
-  }
-}
-
-static void EstBufDelayNormal(aecpc_t* aecpc) {
+static int EstBufDelay(aecpc_t* aecpc) {
   int nSampSndCard = aecpc->msInSndCardBuf * sampMsNb * aecpc->rate_factor;
   int current_delay = nSampSndCard - WebRtcAec_system_delay(aecpc->aec);
   int delay_difference = 0;
@@ -848,11 +732,8 @@
     current_delay += WebRtcAec_MoveFarReadPtr(aecpc->aec, 1) * PART_LEN;
   }
 
-  // We use -1 to signal an initialized state in the "extended" implementation;
-  // compensate for that.
-  aecpc->filtDelay = aecpc->filtDelay < 0 ? 0 : aecpc->filtDelay;
   aecpc->filtDelay = WEBRTC_SPL_MAX(0, (short) (0.8 * aecpc->filtDelay +
-      0.2 * current_delay));
+          0.2 * current_delay));
 
   delay_difference = aecpc->filtDelay - aecpc->knownDelay;
   if (delay_difference > 224) {
@@ -875,58 +756,6 @@
   if (aecpc->timeForDelayChange > 25) {
     aecpc->knownDelay = WEBRTC_SPL_MAX((int) aecpc->filtDelay - 160, 0);
   }
-}
 
-static void EstBufDelayExtended(aecpc_t* self) {
-  int reported_delay = self->msInSndCardBuf * sampMsNb * self->rate_factor;
-  int current_delay = reported_delay - WebRtcAec_system_delay(self->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 * self->rate_factor;
-
-  // 2) Account for resampling frame delay.
-  if (self->skewMode == kAecTrue && self->resample == kAecTrue) {
-    current_delay -= kResamplingDelay;
-  }
-
-  // 3) Compensate for non-causality, if needed, by flushing two blocks.
-  if (current_delay < PART_LEN) {
-    current_delay += WebRtcAec_MoveFarReadPtr(self->aec, 2) * PART_LEN;
-  }
-
-  if (self->filtDelay == -1) {
-    self->filtDelay = WEBRTC_SPL_MAX(0, 0.5 * current_delay);
-  } else {
-    self->filtDelay = WEBRTC_SPL_MAX(0, (short) (0.95 * self->filtDelay +
-        0.05 * current_delay));
-  }
-
-  delay_difference = self->filtDelay - self->knownDelay;
-  if (delay_difference > 384) {
-    if (self->lastDelayDiff < 128) {
-      self->timeForDelayChange = 0;
-    } else {
-      self->timeForDelayChange++;
-    }
-  } else if (delay_difference < 128 && self->knownDelay > 0) {
-    if (self->lastDelayDiff > 384) {
-      self->timeForDelayChange = 0;
-    } else {
-      self->timeForDelayChange++;
-    }
-  } else {
-    self->timeForDelayChange = 0;
-  }
-  self->lastDelayDiff = delay_difference;
-
-  if (self->timeForDelayChange > 25) {
-    self->knownDelay = WEBRTC_SPL_MAX((int) self->filtDelay - 256, 0);
-  }
+  return 0;
 }
diff --git a/webrtc/modules/audio_processing/aec/echo_cancellation_internal.h b/webrtc/modules/audio_processing/aec/echo_cancellation_internal.h
index e939c42..1298901 100644
--- a/webrtc/modules/audio_processing/aec/echo_cancellation_internal.h
+++ b/webrtc/modules/audio_processing/aec/echo_cancellation_internal.h
@@ -20,6 +20,8 @@
   int splitSampFreq;
   int scSampFreq;
   float sampFactor;  // scSampRate / sampFreq
+  short autoOnOff;
+  short activity;
   short skewMode;
   int bufSizeStart;
   int knownDelay;
@@ -37,7 +39,7 @@
   short msInSndCardBuf;
   short filtDelay;  // Filtered delay estimate.
   int timeForDelayChange;
-  int startup_phase;
+  int ECstartup;
   int checkBuffSize;
   short lastDelayDiff;
 
@@ -60,8 +62,6 @@
 
   int lastError;
 
-  int farend_started;
-
   AecCore* aec;
 } aecpc_t;
 
diff --git a/webrtc/modules/audio_processing/aec/system_delay_unittest.cc b/webrtc/modules/audio_processing/aec/system_delay_unittest.cc
index db37f0e..97ebea3 100644
--- a/webrtc/modules/audio_processing/aec/system_delay_unittest.cc
+++ b/webrtc/modules/audio_processing/aec/system_delay_unittest.cc
@@ -128,7 +128,7 @@
   for (; process_time_ms < kStableConvergenceMs; process_time_ms += 10) {
     RenderAndCapture(kDeviceBufMs);
     buffer_size += samples_per_frame_;
-    if (self_->startup_phase == 0) {
+    if (self_->ECstartup == 0) {
       // We have left the startup phase.
       break;
     }
@@ -222,7 +222,7 @@
       RenderAndCapture(reported_delay_ms);
       buffer_size += samples_per_frame_;
       buffer_offset_ms = -buffer_offset_ms;
-      if (self_->startup_phase == 0) {
+      if (self_->ECstartup == 0) {
         // We have left the startup phase.
         break;
       }
@@ -268,7 +268,7 @@
     for (; process_time_ms <= kMaxConvergenceMs; process_time_ms += 10) {
       RenderAndCapture(kDeviceBufMs);
       buffer_size += samples_per_frame_;
-      if (self_->startup_phase == 0) {
+      if (self_->ECstartup == 0) {
         // We have left the startup phase.
         break;
       }
diff --git a/webrtc/modules/audio_processing/echo_cancellation_impl.cc b/webrtc/modules/audio_processing/echo_cancellation_impl.cc
index cd12363..47ee802 100644
--- a/webrtc/modules/audio_processing/echo_cancellation_impl.cc
+++ b/webrtc/modules/audio_processing/echo_cancellation_impl.cc
@@ -13,14 +13,12 @@
 #include <assert.h>
 #include <string.h>
 
-extern "C" {
-#include "webrtc/modules/audio_processing/aec/aec_core.h"
-}
-#include "webrtc/modules/audio_processing/aec/include/echo_cancellation.h"
 #include "webrtc/modules/audio_processing/audio_buffer.h"
 #include "webrtc/modules/audio_processing/audio_processing_impl.h"
 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
 
+#include "webrtc/modules/audio_processing/aec/include/echo_cancellation.h"
+
 namespace webrtc {
 
 typedef void Handle;
@@ -71,8 +69,7 @@
     stream_drift_samples_(0),
     was_stream_drift_set_(false),
     stream_has_echo_(false),
-    delay_logging_enabled_(false),
-    delay_correction_enabled_(false) {}
+    delay_logging_enabled_(false) {}
 
 EchoCancellationImpl::~EchoCancellationImpl() {}
 
@@ -341,11 +338,6 @@
   return apm_->kNoError;
 }
 
-void EchoCancellationImpl::SetExtraOptions(const Config& config) {
-  delay_correction_enabled_ = config.Get<DelayCorrection>().enabled;
-  Configure();
-}
-
 void* EchoCancellationImpl::CreateHandle() const {
   Handle* handle = NULL;
   if (WebRtcAec_Create(&handle) != apm_->kNoError) {
@@ -377,8 +369,6 @@
   config.skewMode = drift_compensation_enabled_;
   config.delay_logging = delay_logging_enabled_;
 
-  WebRtcAec_enable_delay_correction(WebRtcAec_aec_core(
-      static_cast<Handle*>(handle)), delay_correction_enabled_ ? 1 : 0);
   return WebRtcAec_set_config(static_cast<Handle*>(handle), config);
 }
 
diff --git a/webrtc/modules/audio_processing/echo_cancellation_impl.h b/webrtc/modules/audio_processing/echo_cancellation_impl.h
index 2b57ebb..07506d4 100644
--- a/webrtc/modules/audio_processing/echo_cancellation_impl.h
+++ b/webrtc/modules/audio_processing/echo_cancellation_impl.h
@@ -15,30 +15,6 @@
 
 namespace webrtc {
 
-// Use to enable the delay correction feature. This now engages an 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 DelayCorrection {
-  DelayCorrection() : enabled(false) {}
-  DelayCorrection(bool enabled) : enabled(enabled) {}
-
-  bool enabled;
-};
-
 class AudioProcessingImpl;
 class AudioBuffer;
 
@@ -58,7 +34,6 @@
 
   // ProcessingComponent implementation.
   virtual int Initialize() OVERRIDE;
-  virtual void SetExtraOptions(const Config& config) OVERRIDE;
 
  private:
   // EchoCancellation implementation.
@@ -95,7 +70,6 @@
   bool was_stream_drift_set_;
   bool stream_has_echo_;
   bool delay_logging_enabled_;
-  bool delay_correction_enabled_;
 };
 
 }  // namespace webrtc
diff --git a/webrtc/modules/audio_processing/echo_cancellation_impl_unittest.cc b/webrtc/modules/audio_processing/echo_cancellation_impl_unittest.cc
deleted file mode 100644
index 16ecf02..0000000
--- a/webrtc/modules/audio_processing/echo_cancellation_impl_unittest.cc
+++ /dev/null
@@ -1,51 +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 "testing/gtest/include/gtest/gtest.h"
-extern "C" {
-#include "webrtc/modules/audio_processing/aec/aec_core.h"
-}
-#include "webrtc/modules/audio_processing/echo_cancellation_impl.h"
-#include "webrtc/modules/audio_processing/include/audio_processing.h"
-#include "webrtc/system_wrappers/interface/scoped_ptr.h"
-
-namespace webrtc {
-
-TEST(EchoCancellationInternalTest, DelayCorrection) {
-  scoped_ptr<AudioProcessing> ap(AudioProcessing::Create(0));
-  EXPECT_TRUE(ap->echo_cancellation()->aec_core() == NULL);
-
-  EXPECT_EQ(ap->kNoError, ap->echo_cancellation()->Enable(true));
-  EXPECT_TRUE(ap->echo_cancellation()->is_enabled());
-
-  AecCore* aec_core = ap->echo_cancellation()->aec_core();
-  ASSERT_TRUE(aec_core != NULL);
-  // Disabled by default.
-  EXPECT_EQ(0, WebRtcAec_delay_correction_enabled(aec_core));
-
-  Config config;
-  config.Set<DelayCorrection>(new DelayCorrection(true));
-  ap->SetExtraOptions(config);
-  EXPECT_EQ(1, WebRtcAec_delay_correction_enabled(aec_core));
-
-  // Retains setting after initialization.
-  EXPECT_EQ(ap->kNoError, ap->Initialize());
-  EXPECT_EQ(1, WebRtcAec_delay_correction_enabled(aec_core));
-
-  config.Set<DelayCorrection>(new DelayCorrection(false));
-  ap->SetExtraOptions(config);
-  EXPECT_EQ(0, WebRtcAec_delay_correction_enabled(aec_core));
-
-  // Retains setting after initialization.
-  EXPECT_EQ(ap->kNoError, ap->Initialize());
-  EXPECT_EQ(0, WebRtcAec_delay_correction_enabled(aec_core));
-}
-
-}  // namespace webrtc
diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp
index 5dab6f7..d5d3cbe 100644
--- a/webrtc/modules/modules.gyp
+++ b/webrtc/modules/modules.gyp
@@ -145,7 +145,6 @@
             'audio_coding/neteq4/mock/mock_payload_splitter.h',
             'audio_processing/aec/system_delay_unittest.cc',
             'audio_processing/aec/echo_cancellation_unittest.cc',
-            'audio_processing/echo_cancellation_impl_unittest.cc',
             'audio_processing/test/audio_processing_unittest.cc',
             'audio_processing/utility/delay_estimator_unittest.cc',
             'audio_processing/utility/ring_buffer_unittest.cc',