Delay Estimator: Converts a constant into a configurable parameter.

The parameter is used in the robust validation scheme, which will be turned on in a separate CL.

* Setter and getter for allowed delay offset.
* Updated unittests.

BUG=None
TESTED=modules_unittests, trybots
R=aluebs@webrtc.org, andrew@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5351 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_processing/utility/delay_estimator.c b/webrtc/modules/audio_processing/utility/delay_estimator.c
index dc429af..c67e174 100644
--- a/webrtc/modules/audio_processing/utility/delay_estimator.c
+++ b/webrtc/modules/audio_processing/utility/delay_estimator.c
@@ -30,10 +30,6 @@
 static const int kMinRequiredHits = 10;
 static const int kMaxHitsWhenPossiblyNonCausal = 10;
 static const int kMaxHitsWhenPossiblyCausal = 1000;
-// TODO(bjornv): Make kMaxDelayDifference a configurable parameter, since it
-// corresponds to the filter length if the delay estimation is used in echo
-// control.
-static const int kMaxDelayDifference = 32;
 static const float kQ14Scaling = 1.f / (1 << 14);  // Scaling by 2^14 to get Q0.
 static const float kFractionSlope = 0.05f;
 static const float kMinFractionWhenPossiblyCausal = 0.5f;
@@ -195,8 +191,8 @@
   // depending on the distance between the |candidate_delay| and |last_delay|.
   // TODO(bjornv): How much can we gain by turning the fraction calculation
   // into tables?
-  if (delay_difference >= kMaxDelayDifference) {
-    fraction = 1.f - kFractionSlope * (delay_difference - kMaxDelayDifference);
+  if (delay_difference > self->allowed_offset) {
+    fraction = 1.f - kFractionSlope * (delay_difference - self->allowed_offset);
     fraction = (fraction > kMinFractionWhenPossiblyCausal ? fraction :
         kMinFractionWhenPossiblyCausal);
   } else if (delay_difference < 0) {
@@ -363,6 +359,7 @@
     self->farend = farend;
     self->near_history_size = lookahead + 1;
     self->robust_validation_enabled = 0;  // Disabled by default.
+    self->allowed_offset = 0;
 
     // Allocate memory for spectrum buffers.  The extra array element in
     // |mean_bit_counts| and |histogram| is a dummy element only used while
diff --git a/webrtc/modules/audio_processing/utility/delay_estimator.h b/webrtc/modules/audio_processing/utility/delay_estimator.h
index 7ffb81b..b9a24bb 100644
--- a/webrtc/modules/audio_processing/utility/delay_estimator.h
+++ b/webrtc/modules/audio_processing/utility/delay_estimator.h
@@ -44,6 +44,7 @@
 
   // Robust validation
   int robust_validation_enabled;
+  int allowed_offset;
   int last_candidate_delay;
   int compare_delay;
   int candidate_hits;
diff --git a/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc b/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc
index c7e671a..83d1aed 100644
--- a/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc
+++ b/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc
@@ -246,6 +246,14 @@
   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFix(farend_handle_, far_u16_,
                                          spectrum_size_, 16));
 
+  // WebRtc_set_allowed_offset() should return -1 if we have:
+  // 1) NULL pointer as |handle|.
+  // 2) |allowed_offset| < 0.
+  EXPECT_EQ(-1, WebRtc_set_allowed_offset(NULL, 0));
+  EXPECT_EQ(-1, WebRtc_set_allowed_offset(handle_, -1));
+
+  EXPECT_EQ(-1, WebRtc_get_allowed_offset(NULL));
+
   // WebRtc_enable_robust_validation() should return -1 if we have:
   // 1) NULL pointer as |handle|.
   // 2) Incorrect |enable| value (not 0 or 1).
@@ -294,14 +302,26 @@
   WebRtc_FreeDelayEstimator(handle);
 }
 
+TEST_F(DelayEstimatorTest, VerifyAllowedOffset) {
+  // Is set to zero by default.
+  EXPECT_EQ(0, WebRtc_get_allowed_offset(handle_));
+  for (int i = 1; i >= 0; i--) {
+    EXPECT_EQ(0, WebRtc_set_allowed_offset(handle_, i));
+    EXPECT_EQ(i, WebRtc_get_allowed_offset(handle_));
+    Init();
+    // Unaffected over a reset.
+    EXPECT_EQ(i, WebRtc_get_allowed_offset(handle_));
+  }
+}
+
 TEST_F(DelayEstimatorTest, VerifyEnableRobustValidation) {
   // Disabled by default.
   EXPECT_EQ(0, WebRtc_is_robust_validation_enabled(handle_));
-  // Unaffected over a reset
   for (int i = 1; i >= 0; i--) {
     EXPECT_EQ(0, WebRtc_enable_robust_validation(handle_, i));
     EXPECT_EQ(i, WebRtc_is_robust_validation_enabled(handle_));
     Init();
+    // Unaffected over a reset.
     EXPECT_EQ(i, WebRtc_is_robust_validation_enabled(handle_));
   }
 }
@@ -393,7 +413,7 @@
 
   BinaryDelayEstimator* binary_handle = binary_;
   // WebRtc_CreateBinaryDelayEstimator() should return -1 if we have a NULL
-  // pointer as |binary_handle| or invalid input values. Upon failure, the
+  // pointer as |binary_farend| or invalid input values. Upon failure, the
   // |binary_handle| should be NULL.
   // Make sure we have a non-NULL value at start, so we can detect NULL after
   // create failure.
@@ -402,9 +422,6 @@
   binary_handle = binary_;
   binary_handle = WebRtc_CreateBinaryDelayEstimator(binary_farend_, -1);
   EXPECT_TRUE(binary_handle == NULL);
-  binary_handle = binary_;
-  binary_handle = WebRtc_CreateBinaryDelayEstimator(0, 0);
-  EXPECT_TRUE(binary_handle == NULL);
 }
 
 TEST_F(DelayEstimatorTest, MeanEstimatorFix) {
diff --git a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c
index ce44318..e48dc98 100644
--- a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c
+++ b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c
@@ -312,6 +312,25 @@
   return 0;
 }
 
+int WebRtc_set_allowed_offset(void* handle, int allowed_offset) {
+  DelayEstimator* self = (DelayEstimator*) handle;
+
+  if ((self == NULL) || (allowed_offset < 0)) {
+    return -1;
+  }
+  self->binary_handle->allowed_offset = allowed_offset;
+  return 0;
+}
+
+int WebRtc_get_allowed_offset(const void* handle) {
+  DelayEstimator* self = (DelayEstimator*) handle;
+
+  if (self == NULL) {
+    return -1;
+  }
+  return self->binary_handle->allowed_offset;
+}
+
 int WebRtc_enable_robust_validation(void* handle, int enable) {
   DelayEstimator* self = (DelayEstimator*) handle;
 
@@ -321,18 +340,16 @@
   if ((enable < 0) || (enable > 1)) {
     return -1;
   }
-  assert(self->binary_handle != NULL);
   self->binary_handle->robust_validation_enabled = enable;
   return 0;
 }
 
-int WebRtc_is_robust_validation_enabled(void* handle) {
+int WebRtc_is_robust_validation_enabled(const void* handle) {
   DelayEstimator* self = (DelayEstimator*) handle;
 
   if (self == NULL) {
     return -1;
   }
-  assert(self->binary_handle != NULL);
   return self->binary_handle->robust_validation_enabled;
 }
 
diff --git a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h
index 50bcdde..5d11cd2 100644
--- a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h
+++ b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h
@@ -123,17 +123,34 @@
 //
 int WebRtc_InitDelayEstimator(void* handle);
 
+// Sets the |allowed_offset| used in the robust validation scheme.  If the
+// delay estimator is used in an echo control component, this parameter is
+// related to the filter length.  In principle |allowed_offset| should be set to
+// the echo control filter length minus the expected echo duration, i.e., the
+// delay offset the echo control can handle without quality regression.  The
+// default value, used if not set manually, is zero.  Note that |allowed_offset|
+// has to be non-negative.
+// Inputs:
+//  - handle            : Pointer to the delay estimation instance.
+//  - allowed_offset    : The amount of delay offset, measured in partitions,
+//                        the echo control filter can handle.
+int WebRtc_set_allowed_offset(void* handle, int allowed_offset);
+
+// Returns the |allowed_offset| in number of partitions.
+int WebRtc_get_allowed_offset(const void* handle);
+
 // TODO(bjornv): Implement this functionality.  Currently, enabling it has no
 // impact, hence this is an empty API.
 // Enables/Disables a robust validation functionality in the delay estimation.
-// This is by default disabled upon initialization.
+// This is by default set to disabled at create time.  The state is preserved
+// over a reset.
 // Inputs:
 //      - handle        : Pointer to the delay estimation instance.
 //      - enable        : Enable (1) or disable (0) this feature.
 int WebRtc_enable_robust_validation(void* handle, int enable);
 
 // Returns 1 if robust validation is enabled and 0 if disabled.
-int WebRtc_is_robust_validation_enabled(void* handle);
+int WebRtc_is_robust_validation_enabled(const void* handle);
 
 // Estimates and returns the delay between the far-end and near-end blocks. The
 // value will be offset by the lookahead (i.e. the lookahead should be