This refactoring CL contains an API to get low level echo metrics stats.

TEST=audioproc_unittest, trybots
BUG=None

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3523 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 2dbd067..104b3dd 100644
--- a/webrtc/modules/audio_processing/aec/aec_core.c
+++ b/webrtc/modules/audio_processing/aec/aec_core.c
@@ -122,7 +122,7 @@
                                   const float *noisePow, const float *lambda);
 
 static void WebRtcAec_InitLevel(power_level_t *level);
-static void WebRtcAec_InitStats(stats_t *stats);
+static void WebRtcAec_InitStats(stats* stats);
 static void UpdateLevel(power_level_t* level, float in[2][PART_LEN1]);
 static void UpdateMetrics(aec_t *aec);
 // Convert from time domain to frequency domain. Note that |time_data| are
@@ -721,6 +721,17 @@
   return self->echoState;
 }
 
+void WebRtcAec_GetEchoStats(aec_t* self, stats* erl, stats* erle,
+                            stats* a_nlp) {
+  assert(self != NULL);
+  assert(erl != NULL);
+  assert(erle != NULL);
+  assert(a_nlp != NULL);
+  *erl = self->erl;
+  *erle = self->erle;
+  *a_nlp = self->aNlp;
+}
+
 static void ProcessBlock(aec_t* aec) {
     int i;
     float d[PART_LEN], y[PART_LEN], e[PART_LEN], dH[PART_LEN];
@@ -1391,7 +1402,7 @@
     level->sfrcounter = 0;
 }
 
-static void WebRtcAec_InitStats(stats_t *stats)
+static void WebRtcAec_InitStats(stats* stats)
 {
     stats->instant = offsetLevel;
     stats->average = offsetLevel;
diff --git a/webrtc/modules/audio_processing/aec/aec_core.h b/webrtc/modules/audio_processing/aec/aec_core.h
index 7474ec7..a740b0d 100644
--- a/webrtc/modules/audio_processing/aec/aec_core.h
+++ b/webrtc/modules/audio_processing/aec/aec_core.h
@@ -56,16 +56,16 @@
 } power_level_t;
 
 typedef struct {
-    float instant;
-    float average;
-    float min;
-    float max;
-    float sum;
-    float hisum;
-    float himean;
-    int counter;
-    int hicounter;
-} stats_t;
+  float instant;
+  float average;
+  float min;
+  float max;
+  float sum;
+  float hisum;
+  float himean;
+  int counter;
+  int hicounter;
+} stats;
 
 typedef struct {
     int farBufWritePos, farBufReadPos;
@@ -131,10 +131,10 @@
 
     int metricsMode;
     int stateCounter;
-    stats_t erl;
-    stats_t erle;
-    stats_t aNlp;
-    stats_t rerl;
+    stats erl;
+    stats erle;
+    stats aNlp;
+    stats rerl;
 
     // Quantities to control H band scaling for SWB input
     int freq_avg_ic;  // initial bin for averaging nlp gain
@@ -187,5 +187,7 @@
 int WebRtcAec_GetDelayMetricsCore(aec_t* self, int* median, int* std);
 // Returns the echo state (1: echo, 0: no echo).
 int WebRtcAec_echo_state(aec_t* self);
+// Gets statistics of the echo metrics ERL, ERLE, A_NLP.
+void WebRtcAec_GetEchoStats(aec_t* self, stats* erl, stats* erle, stats* a_nlp);
 
 #endif  // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_CORE_H_
diff --git a/webrtc/modules/audio_processing/aec/echo_cancellation.c b/webrtc/modules/audio_processing/aec/echo_cancellation.c
index c6aa454..25f44e2 100644
--- a/webrtc/modules/audio_processing/aec/echo_cancellation.c
+++ b/webrtc/modules/audio_processing/aec/echo_cancellation.c
@@ -629,104 +629,101 @@
   return 0;
 }
 
-WebRtc_Word32 WebRtcAec_GetMetrics(void *aecInst, AecMetrics *metrics)
-{
-    const float upweight = 0.7f;
-    float dtmp;
-    short stmp;
-    aecpc_t *aecpc = aecInst;
+int WebRtcAec_GetMetrics(void* handle, AecMetrics* metrics) {
+  const float kUpWeight = 0.7f;
+  float dtmp;
+  int stmp;
+  aecpc_t* self = (aecpc_t*)handle;
+  stats erl;
+  stats erle;
+  stats a_nlp;
 
-    if (aecpc == NULL) {
-        return -1;
-    }
+  if (handle == NULL ) {
+    return -1;
+  }
+  if (metrics == NULL ) {
+    self->lastError = AEC_NULL_POINTER_ERROR;
+    return -1;
+  }
+  if (self->initFlag != initCheck) {
+    self->lastError = AEC_UNINITIALIZED_ERROR;
+    return -1;
+  }
 
-    if (metrics == NULL) {
-        aecpc->lastError = AEC_NULL_POINTER_ERROR;
-        return -1;
-    }
+  WebRtcAec_GetEchoStats(self->aec, &erl, &erle, &a_nlp);
 
-    if (aecpc->initFlag != initCheck) {
-        aecpc->lastError = AEC_UNINITIALIZED_ERROR;
-        return -1;
-    }
+  // ERL
+  metrics->erl.instant = (int) erl.instant;
 
-    // ERL
-    metrics->erl.instant = (short) aecpc->aec->erl.instant;
+  if ((erl.himean > offsetLevel) && (erl.average > offsetLevel)) {
+    // Use a mix between regular average and upper part average.
+    dtmp = kUpWeight * erl.himean + (1 - kUpWeight) * erl.average;
+    metrics->erl.average = (int) dtmp;
+  } else {
+    metrics->erl.average = offsetLevel;
+  }
 
-    if ((aecpc->aec->erl.himean > offsetLevel) && (aecpc->aec->erl.average > offsetLevel)) {
-    // Use a mix between regular average and upper part average
-        dtmp = upweight * aecpc->aec->erl.himean + (1 - upweight) * aecpc->aec->erl.average;
-        metrics->erl.average = (short) dtmp;
-    }
-    else {
-        metrics->erl.average = offsetLevel;
-    }
+  metrics->erl.max = (int) erl.max;
 
-    metrics->erl.max = (short) aecpc->aec->erl.max;
+  if (erl.min < (offsetLevel * (-1))) {
+    metrics->erl.min = (int) erl.min;
+  } else {
+    metrics->erl.min = offsetLevel;
+  }
 
-    if (aecpc->aec->erl.min < (offsetLevel * (-1))) {
-        metrics->erl.min = (short) aecpc->aec->erl.min;
-    }
-    else {
-        metrics->erl.min = offsetLevel;
-    }
+  // ERLE
+  metrics->erle.instant = (int) erle.instant;
 
-    // ERLE
-    metrics->erle.instant = (short) aecpc->aec->erle.instant;
+  if ((erle.himean > offsetLevel) && (erle.average > offsetLevel)) {
+    // Use a mix between regular average and upper part average.
+    dtmp = kUpWeight * erle.himean + (1 - kUpWeight) * erle.average;
+    metrics->erle.average = (int) dtmp;
+  } else {
+    metrics->erle.average = offsetLevel;
+  }
 
-    if ((aecpc->aec->erle.himean > offsetLevel) && (aecpc->aec->erle.average > offsetLevel)) {
-        // Use a mix between regular average and upper part average
-        dtmp =  upweight * aecpc->aec->erle.himean + (1 - upweight) * aecpc->aec->erle.average;
-        metrics->erle.average = (short) dtmp;
-    }
-    else {
-        metrics->erle.average = offsetLevel;
-    }
+  metrics->erle.max = (int) erle.max;
 
-    metrics->erle.max = (short) aecpc->aec->erle.max;
+  if (erle.min < (offsetLevel * (-1))) {
+    metrics->erle.min = (int) erle.min;
+  } else {
+    metrics->erle.min = offsetLevel;
+  }
 
-    if (aecpc->aec->erle.min < (offsetLevel * (-1))) {
-        metrics->erle.min = (short) aecpc->aec->erle.min;
-    } else {
-        metrics->erle.min = offsetLevel;
-    }
+  // RERL
+  if ((metrics->erl.average > offsetLevel)
+      && (metrics->erle.average > offsetLevel)) {
+    stmp = metrics->erl.average + metrics->erle.average;
+  } else {
+    stmp = offsetLevel;
+  }
+  metrics->rerl.average = stmp;
 
-    // RERL
-    if ((metrics->erl.average > offsetLevel) && (metrics->erle.average > offsetLevel)) {
-        stmp = metrics->erl.average + metrics->erle.average;
-    }
-    else {
-        stmp = offsetLevel;
-    }
-    metrics->rerl.average = stmp;
+  // No other statistics needed, but returned for completeness.
+  metrics->rerl.instant = stmp;
+  metrics->rerl.max = stmp;
+  metrics->rerl.min = 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 = (int) a_nlp.instant;
 
-    // A_NLP
-    metrics->aNlp.instant = (short) aecpc->aec->aNlp.instant;
+  if ((a_nlp.himean > offsetLevel) && (a_nlp.average > offsetLevel)) {
+    // Use a mix between regular average and upper part average.
+    dtmp = kUpWeight * a_nlp.himean + (1 - kUpWeight) * a_nlp.average;
+    metrics->aNlp.average = (int) dtmp;
+  } else {
+    metrics->aNlp.average = offsetLevel;
+  }
 
-    if ((aecpc->aec->aNlp.himean > offsetLevel) && (aecpc->aec->aNlp.average > offsetLevel)) {
-        // Use a mix between regular average and upper part average
-        dtmp =  upweight * aecpc->aec->aNlp.himean + (1 - upweight) * aecpc->aec->aNlp.average;
-        metrics->aNlp.average = (short) dtmp;
-    }
-    else {
-        metrics->aNlp.average = offsetLevel;
-    }
+  metrics->aNlp.max = (int) a_nlp.max;
 
-    metrics->aNlp.max = (short) aecpc->aec->aNlp.max;
+  if (a_nlp.min < (offsetLevel * (-1))) {
+    metrics->aNlp.min = (int) a_nlp.min;
+  } else {
+    metrics->aNlp.min = offsetLevel;
+  }
 
-    if (aecpc->aec->aNlp.min < (offsetLevel * (-1))) {
-        metrics->aNlp.min = (short) aecpc->aec->aNlp.min;
-    }
-    else {
-        metrics->aNlp.min = offsetLevel;
-    }
-
-    return 0;
+  return 0;
 }
 
 int WebRtcAec_GetDelayMetrics(void* handle, int* median, int* std) {
diff --git a/webrtc/modules/audio_processing/aec/include/echo_cancellation.h b/webrtc/modules/audio_processing/aec/include/echo_cancellation.h
index 82dc0d3..367ed56 100644
--- a/webrtc/modules/audio_processing/aec/include/echo_cancellation.h
+++ b/webrtc/modules/audio_processing/aec/include/echo_cancellation.h
@@ -43,10 +43,10 @@
 } AecConfig;
 
 typedef struct {
-    WebRtc_Word16 instant;
-    WebRtc_Word16 average;
-    WebRtc_Word16 max;
-    WebRtc_Word16 min;
+  int instant;
+  int average;
+  int max;
+  int min;
 } AecLevel;
 
 typedef struct {
@@ -215,16 +215,16 @@
  *
  * Inputs                       Description
  * -------------------------------------------------------------------
- * void           *aecInst      Pointer to the AEC instance
+ * void           *handle       Pointer to the AEC instance
  *
  * Outputs                      Description
  * -------------------------------------------------------------------
  * AecMetrics     *metrics      Struct which will be filled out with the
  *                              current echo metrics.
- * WebRtc_Word32  return         0: OK
+ * int            return         0: OK
  *                              -1: error
  */
-WebRtc_Word32 WebRtcAec_GetMetrics(void *aecInst, AecMetrics *metrics);
+int WebRtcAec_GetMetrics(void* handle, AecMetrics* metrics);
 
 /*
  * Gets the current delay metrics for the session.