1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "webrtc/modules/audio_processing/utility/delay_estimator.h"
12 #include "webrtc/modules/audio_processing/utility/delay_estimator_internal.h"
13 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h"
14 #include "webrtc/test/gtest.h"
15 #include "webrtc/typedefs.h"
16 
17 namespace {
18 
19 enum { kSpectrumSize = 65 };
20 // Delay history sizes.
21 enum { kMaxDelay = 100 };
22 enum { kLookahead = 10 };
23 enum { kHistorySize = kMaxDelay + kLookahead };
24 // Length of binary spectrum sequence.
25 enum { kSequenceLength = 400 };
26 
27 const int kDifferentHistorySize = 3;
28 const int kDifferentLookahead = 1;
29 
30 const int kEnable[] = { 0, 1 };
31 const size_t kSizeEnable = sizeof(kEnable) / sizeof(*kEnable);
32 
33 class DelayEstimatorTest : public ::testing::Test {
34  protected:
35   DelayEstimatorTest();
36   virtual void SetUp();
37   virtual void TearDown();
38 
39   void Init();
40   void InitBinary();
41   void VerifyDelay(BinaryDelayEstimator* binary_handle, int offset, int delay);
42   void RunBinarySpectra(BinaryDelayEstimator* binary1,
43                         BinaryDelayEstimator* binary2,
44                         int near_offset, int lookahead_offset, int far_offset);
45   void RunBinarySpectraTest(int near_offset, int lookahead_offset,
46                             int ref_robust_validation, int robust_validation);
47 
48   void* handle_;
49   DelayEstimator* self_;
50   void* farend_handle_;
51   DelayEstimatorFarend* farend_self_;
52   BinaryDelayEstimator* binary_;
53   BinaryDelayEstimatorFarend* binary_farend_;
54   int spectrum_size_;
55   // Dummy input spectra.
56   float far_f_[kSpectrumSize];
57   float near_f_[kSpectrumSize];
58   uint16_t far_u16_[kSpectrumSize];
59   uint16_t near_u16_[kSpectrumSize];
60   uint32_t binary_spectrum_[kSequenceLength + kHistorySize];
61 };
62 
DelayEstimatorTest()63 DelayEstimatorTest::DelayEstimatorTest()
64     : handle_(NULL),
65       self_(NULL),
66       farend_handle_(NULL),
67       farend_self_(NULL),
68       binary_(NULL),
69       binary_farend_(NULL),
70       spectrum_size_(kSpectrumSize) {
71   // Dummy input data are set with more or less arbitrary non-zero values.
72   memset(far_f_, 1, sizeof(far_f_));
73   memset(near_f_, 2, sizeof(near_f_));
74   memset(far_u16_, 1, sizeof(far_u16_));
75   memset(near_u16_, 2, sizeof(near_u16_));
76   // Construct a sequence of binary spectra used to verify delay estimate. The
77   // |kSequenceLength| has to be long enough for the delay estimation to leave
78   // the initialized state.
79   binary_spectrum_[0] = 1;
80   for (int i = 1; i < (kSequenceLength + kHistorySize); i++) {
81     binary_spectrum_[i] = 3 * binary_spectrum_[i - 1];
82   }
83 }
84 
SetUp()85 void DelayEstimatorTest::SetUp() {
86   farend_handle_ = WebRtc_CreateDelayEstimatorFarend(kSpectrumSize,
87                                                      kHistorySize);
88   ASSERT_TRUE(farend_handle_ != NULL);
89   farend_self_ = reinterpret_cast<DelayEstimatorFarend*>(farend_handle_);
90   handle_ = WebRtc_CreateDelayEstimator(farend_handle_, kLookahead);
91   ASSERT_TRUE(handle_ != NULL);
92   self_ = reinterpret_cast<DelayEstimator*>(handle_);
93   binary_farend_ = WebRtc_CreateBinaryDelayEstimatorFarend(kHistorySize);
94   ASSERT_TRUE(binary_farend_ != NULL);
95   binary_ = WebRtc_CreateBinaryDelayEstimator(binary_farend_, kLookahead);
96   ASSERT_TRUE(binary_ != NULL);
97 }
98 
TearDown()99 void DelayEstimatorTest::TearDown() {
100   WebRtc_FreeDelayEstimator(handle_);
101   handle_ = NULL;
102   self_ = NULL;
103   WebRtc_FreeDelayEstimatorFarend(farend_handle_);
104   farend_handle_ = NULL;
105   farend_self_ = NULL;
106   WebRtc_FreeBinaryDelayEstimator(binary_);
107   binary_ = NULL;
108   WebRtc_FreeBinaryDelayEstimatorFarend(binary_farend_);
109   binary_farend_ = NULL;
110 }
111 
Init()112 void DelayEstimatorTest::Init() {
113   // Initialize Delay Estimator
114   EXPECT_EQ(0, WebRtc_InitDelayEstimatorFarend(farend_handle_));
115   EXPECT_EQ(0, WebRtc_InitDelayEstimator(handle_));
116   // Verify initialization.
117   EXPECT_EQ(0, farend_self_->far_spectrum_initialized);
118   EXPECT_EQ(0, self_->near_spectrum_initialized);
119   EXPECT_EQ(-2, WebRtc_last_delay(handle_));  // Delay in initial state.
120   EXPECT_FLOAT_EQ(0, WebRtc_last_delay_quality(handle_));  // Zero quality.
121 }
122 
InitBinary()123 void DelayEstimatorTest::InitBinary() {
124   // Initialize Binary Delay Estimator (far-end part).
125   WebRtc_InitBinaryDelayEstimatorFarend(binary_farend_);
126   // Initialize Binary Delay Estimator
127   WebRtc_InitBinaryDelayEstimator(binary_);
128   // Verify initialization. This does not guarantee a complete check, since
129   // |last_delay| may be equal to -2 before initialization if done on the fly.
130   EXPECT_EQ(-2, binary_->last_delay);
131 }
132 
VerifyDelay(BinaryDelayEstimator * binary_handle,int offset,int delay)133 void DelayEstimatorTest::VerifyDelay(BinaryDelayEstimator* binary_handle,
134                                      int offset, int delay) {
135   // Verify that we WebRtc_binary_last_delay() returns correct delay.
136   EXPECT_EQ(delay, WebRtc_binary_last_delay(binary_handle));
137 
138   if (delay != -2) {
139     // Verify correct delay estimate. In the non-causal case the true delay
140     // is equivalent with the |offset|.
141     EXPECT_EQ(offset, delay);
142   }
143 }
144 
RunBinarySpectra(BinaryDelayEstimator * binary1,BinaryDelayEstimator * binary2,int near_offset,int lookahead_offset,int far_offset)145 void DelayEstimatorTest::RunBinarySpectra(BinaryDelayEstimator* binary1,
146                                           BinaryDelayEstimator* binary2,
147                                           int near_offset,
148                                           int lookahead_offset,
149                                           int far_offset) {
150   int different_validations = binary1->robust_validation_enabled ^
151       binary2->robust_validation_enabled;
152   WebRtc_InitBinaryDelayEstimatorFarend(binary_farend_);
153   WebRtc_InitBinaryDelayEstimator(binary1);
154   WebRtc_InitBinaryDelayEstimator(binary2);
155   // Verify initialization. This does not guarantee a complete check, since
156   // |last_delay| may be equal to -2 before initialization if done on the fly.
157   EXPECT_EQ(-2, binary1->last_delay);
158   EXPECT_EQ(-2, binary2->last_delay);
159   for (int i = kLookahead; i < (kSequenceLength + kLookahead); i++) {
160     WebRtc_AddBinaryFarSpectrum(binary_farend_,
161                                 binary_spectrum_[i + far_offset]);
162     int delay_1 = WebRtc_ProcessBinarySpectrum(binary1, binary_spectrum_[i]);
163     int delay_2 =
164         WebRtc_ProcessBinarySpectrum(binary2,
165                                      binary_spectrum_[i - near_offset]);
166 
167     VerifyDelay(binary1, far_offset + kLookahead, delay_1);
168     VerifyDelay(binary2,
169                 far_offset + kLookahead + lookahead_offset + near_offset,
170                 delay_2);
171     // Expect the two delay estimates to be offset by |lookahead_offset| +
172     // |near_offset| when we have left the initial state.
173     if ((delay_1 != -2) && (delay_2 != -2)) {
174       EXPECT_EQ(delay_1, delay_2 - lookahead_offset - near_offset);
175     }
176     // For the case of identical signals |delay_1| and |delay_2| should match
177     // all the time, unless one of them has robust validation turned on.  In
178     // that case the robust validation leaves the initial state faster.
179     if ((near_offset == 0) && (lookahead_offset == 0)) {
180       if  (!different_validations) {
181         EXPECT_EQ(delay_1, delay_2);
182       } else {
183         if (binary1->robust_validation_enabled) {
184           EXPECT_GE(delay_1, delay_2);
185         } else {
186           EXPECT_GE(delay_2, delay_1);
187         }
188       }
189     }
190   }
191   // Verify that we have left the initialized state.
192   EXPECT_NE(-2, WebRtc_binary_last_delay(binary1));
193   EXPECT_LT(0, WebRtc_binary_last_delay_quality(binary1));
194   EXPECT_NE(-2, WebRtc_binary_last_delay(binary2));
195   EXPECT_LT(0, WebRtc_binary_last_delay_quality(binary2));
196 }
197 
RunBinarySpectraTest(int near_offset,int lookahead_offset,int ref_robust_validation,int robust_validation)198 void DelayEstimatorTest::RunBinarySpectraTest(int near_offset,
199                                               int lookahead_offset,
200                                               int ref_robust_validation,
201                                               int robust_validation) {
202   BinaryDelayEstimator* binary2 =
203       WebRtc_CreateBinaryDelayEstimator(binary_farend_,
204                                         kLookahead + lookahead_offset);
205   // Verify the delay for both causal and non-causal systems. For causal systems
206   // the delay is equivalent with a positive |offset| of the far-end sequence.
207   // For non-causal systems the delay is equivalent with a negative |offset| of
208   // the far-end sequence.
209   binary_->robust_validation_enabled = ref_robust_validation;
210   binary2->robust_validation_enabled = robust_validation;
211   for (int offset = -kLookahead;
212       offset < kMaxDelay - lookahead_offset - near_offset;
213       offset++) {
214     RunBinarySpectra(binary_, binary2, near_offset, lookahead_offset, offset);
215   }
216   WebRtc_FreeBinaryDelayEstimator(binary2);
217   binary2 = NULL;
218   binary_->robust_validation_enabled = 0;  // Reset reference.
219 }
220 
TEST_F(DelayEstimatorTest,CorrectErrorReturnsOfWrapper)221 TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfWrapper) {
222   // In this test we verify correct error returns on invalid API calls.
223 
224   // WebRtc_CreateDelayEstimatorFarend() and WebRtc_CreateDelayEstimator()
225   // should return a NULL pointer on invalid input values.
226   // Make sure we have a non-NULL value at start, so we can detect NULL after
227   // create failure.
228   void* handle = farend_handle_;
229   handle = WebRtc_CreateDelayEstimatorFarend(33, kHistorySize);
230   EXPECT_TRUE(handle == NULL);
231   handle = WebRtc_CreateDelayEstimatorFarend(kSpectrumSize, 1);
232   EXPECT_TRUE(handle == NULL);
233 
234   handle = handle_;
235   handle = WebRtc_CreateDelayEstimator(NULL, kLookahead);
236   EXPECT_TRUE(handle == NULL);
237   handle = WebRtc_CreateDelayEstimator(farend_handle_, -1);
238   EXPECT_TRUE(handle == NULL);
239 
240   // WebRtc_InitDelayEstimatorFarend() and WebRtc_InitDelayEstimator() should
241   // return -1 if we have a NULL pointer as |handle|.
242   EXPECT_EQ(-1, WebRtc_InitDelayEstimatorFarend(NULL));
243   EXPECT_EQ(-1, WebRtc_InitDelayEstimator(NULL));
244 
245   // WebRtc_AddFarSpectrumFloat() should return -1 if we have:
246   // 1) NULL pointer as |handle|.
247   // 2) NULL pointer as far-end spectrum.
248   // 3) Incorrect spectrum size.
249   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFloat(NULL, far_f_, spectrum_size_));
250   // Use |farend_handle_| which is properly created at SetUp().
251   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFloat(farend_handle_, NULL,
252                                            spectrum_size_));
253   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFloat(farend_handle_, far_f_,
254                                            spectrum_size_ + 1));
255 
256   // WebRtc_AddFarSpectrumFix() should return -1 if we have:
257   // 1) NULL pointer as |handle|.
258   // 2) NULL pointer as far-end spectrum.
259   // 3) Incorrect spectrum size.
260   // 4) Too high precision in far-end spectrum (Q-domain > 15).
261   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFix(NULL, far_u16_, spectrum_size_, 0));
262   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFix(farend_handle_, NULL, spectrum_size_,
263                                          0));
264   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFix(farend_handle_, far_u16_,
265                                          spectrum_size_ + 1, 0));
266   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFix(farend_handle_, far_u16_,
267                                          spectrum_size_, 16));
268 
269   // WebRtc_set_history_size() should return -1 if:
270   // 1) |handle| is a NULL.
271   // 2) |history_size| <= 1.
272   EXPECT_EQ(-1, WebRtc_set_history_size(NULL, 1));
273   EXPECT_EQ(-1, WebRtc_set_history_size(handle_, 1));
274   // WebRtc_history_size() should return -1 if:
275   // 1) NULL pointer input.
276   EXPECT_EQ(-1, WebRtc_history_size(NULL));
277   // 2) there is a mismatch between history size.
278   void* tmp_handle = WebRtc_CreateDelayEstimator(farend_handle_, kHistorySize);
279   EXPECT_EQ(0, WebRtc_InitDelayEstimator(tmp_handle));
280   EXPECT_EQ(kDifferentHistorySize,
281             WebRtc_set_history_size(tmp_handle, kDifferentHistorySize));
282   EXPECT_EQ(kDifferentHistorySize, WebRtc_history_size(tmp_handle));
283   EXPECT_EQ(kHistorySize, WebRtc_set_history_size(handle_, kHistorySize));
284   EXPECT_EQ(-1, WebRtc_history_size(tmp_handle));
285 
286   // WebRtc_set_lookahead() should return -1 if we try a value outside the
287   /// buffer.
288   EXPECT_EQ(-1, WebRtc_set_lookahead(handle_, kLookahead + 1));
289   EXPECT_EQ(-1, WebRtc_set_lookahead(handle_, -1));
290 
291   // WebRtc_set_allowed_offset() should return -1 if we have:
292   // 1) NULL pointer as |handle|.
293   // 2) |allowed_offset| < 0.
294   EXPECT_EQ(-1, WebRtc_set_allowed_offset(NULL, 0));
295   EXPECT_EQ(-1, WebRtc_set_allowed_offset(handle_, -1));
296 
297   EXPECT_EQ(-1, WebRtc_get_allowed_offset(NULL));
298 
299   // WebRtc_enable_robust_validation() should return -1 if we have:
300   // 1) NULL pointer as |handle|.
301   // 2) Incorrect |enable| value (not 0 or 1).
302   EXPECT_EQ(-1, WebRtc_enable_robust_validation(NULL, kEnable[0]));
303   EXPECT_EQ(-1, WebRtc_enable_robust_validation(handle_, -1));
304   EXPECT_EQ(-1, WebRtc_enable_robust_validation(handle_, 2));
305 
306   // WebRtc_is_robust_validation_enabled() should return -1 if we have NULL
307   // pointer as |handle|.
308   EXPECT_EQ(-1, WebRtc_is_robust_validation_enabled(NULL));
309 
310   // WebRtc_DelayEstimatorProcessFloat() should return -1 if we have:
311   // 1) NULL pointer as |handle|.
312   // 2) NULL pointer as near-end spectrum.
313   // 3) Incorrect spectrum size.
314   // 4) Non matching history sizes if multiple delay estimators using the same
315   //    far-end reference.
316   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFloat(NULL, near_f_,
317                                                   spectrum_size_));
318   // Use |handle_| which is properly created at SetUp().
319   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFloat(handle_, NULL,
320                                                   spectrum_size_));
321   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFloat(handle_, near_f_,
322                                                   spectrum_size_ + 1));
323   // |tmp_handle| is already in a non-matching state.
324   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFloat(tmp_handle,
325                                                   near_f_,
326                                                   spectrum_size_));
327 
328   // WebRtc_DelayEstimatorProcessFix() should return -1 if we have:
329   // 1) NULL pointer as |handle|.
330   // 2) NULL pointer as near-end spectrum.
331   // 3) Incorrect spectrum size.
332   // 4) Too high precision in near-end spectrum (Q-domain > 15).
333   // 5) Non matching history sizes if multiple delay estimators using the same
334   //    far-end reference.
335   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFix(NULL, near_u16_, spectrum_size_,
336                                                 0));
337   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFix(handle_, NULL, spectrum_size_,
338                                                 0));
339   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFix(handle_, near_u16_,
340                                                 spectrum_size_ + 1, 0));
341   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFix(handle_, near_u16_,
342                                                 spectrum_size_, 16));
343   // |tmp_handle| is already in a non-matching state.
344   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFix(tmp_handle,
345                                                 near_u16_,
346                                                 spectrum_size_,
347                                                 0));
348   WebRtc_FreeDelayEstimator(tmp_handle);
349 
350   // WebRtc_last_delay() should return -1 if we have a NULL pointer as |handle|.
351   EXPECT_EQ(-1, WebRtc_last_delay(NULL));
352 
353   // Free any local memory if needed.
354   WebRtc_FreeDelayEstimator(handle);
355 }
356 
TEST_F(DelayEstimatorTest,VerifyAllowedOffset)357 TEST_F(DelayEstimatorTest, VerifyAllowedOffset) {
358   // Is set to zero by default.
359   EXPECT_EQ(0, WebRtc_get_allowed_offset(handle_));
360   for (int i = 1; i >= 0; i--) {
361     EXPECT_EQ(0, WebRtc_set_allowed_offset(handle_, i));
362     EXPECT_EQ(i, WebRtc_get_allowed_offset(handle_));
363     Init();
364     // Unaffected over a reset.
365     EXPECT_EQ(i, WebRtc_get_allowed_offset(handle_));
366   }
367 }
368 
TEST_F(DelayEstimatorTest,VerifyEnableRobustValidation)369 TEST_F(DelayEstimatorTest, VerifyEnableRobustValidation) {
370   // Disabled by default.
371   EXPECT_EQ(0, WebRtc_is_robust_validation_enabled(handle_));
372   for (size_t i = 0; i < kSizeEnable; ++i) {
373     EXPECT_EQ(0, WebRtc_enable_robust_validation(handle_, kEnable[i]));
374     EXPECT_EQ(kEnable[i], WebRtc_is_robust_validation_enabled(handle_));
375     Init();
376     // Unaffected over a reset.
377     EXPECT_EQ(kEnable[i], WebRtc_is_robust_validation_enabled(handle_));
378   }
379 }
380 
TEST_F(DelayEstimatorTest,InitializedSpectrumAfterProcess)381 TEST_F(DelayEstimatorTest, InitializedSpectrumAfterProcess) {
382   // In this test we verify that the mean spectra are initialized after first
383   // time we call WebRtc_AddFarSpectrum() and Process() respectively. The test
384   // also verifies the state is not left for zero spectra.
385   const float kZerosFloat[kSpectrumSize] = { 0.0 };
386   const uint16_t kZerosU16[kSpectrumSize] = { 0 };
387 
388   // For floating point operations, process one frame and verify initialization
389   // flag.
390   Init();
391   EXPECT_EQ(0, WebRtc_AddFarSpectrumFloat(farend_handle_, kZerosFloat,
392                                           spectrum_size_));
393   EXPECT_EQ(0, farend_self_->far_spectrum_initialized);
394   EXPECT_EQ(0, WebRtc_AddFarSpectrumFloat(farend_handle_, far_f_,
395                                            spectrum_size_));
396   EXPECT_EQ(1, farend_self_->far_spectrum_initialized);
397   EXPECT_EQ(-2, WebRtc_DelayEstimatorProcessFloat(handle_, kZerosFloat,
398                                                   spectrum_size_));
399   EXPECT_EQ(0, self_->near_spectrum_initialized);
400   EXPECT_EQ(-2, WebRtc_DelayEstimatorProcessFloat(handle_, near_f_,
401                                                   spectrum_size_));
402   EXPECT_EQ(1, self_->near_spectrum_initialized);
403 
404   // For fixed point operations, process one frame and verify initialization
405   // flag.
406   Init();
407   EXPECT_EQ(0, WebRtc_AddFarSpectrumFix(farend_handle_, kZerosU16,
408                                         spectrum_size_, 0));
409   EXPECT_EQ(0, farend_self_->far_spectrum_initialized);
410   EXPECT_EQ(0, WebRtc_AddFarSpectrumFix(farend_handle_, far_u16_,
411                                          spectrum_size_, 0));
412   EXPECT_EQ(1, farend_self_->far_spectrum_initialized);
413   EXPECT_EQ(-2, WebRtc_DelayEstimatorProcessFix(handle_, kZerosU16,
414                                                 spectrum_size_, 0));
415   EXPECT_EQ(0, self_->near_spectrum_initialized);
416   EXPECT_EQ(-2, WebRtc_DelayEstimatorProcessFix(handle_, near_u16_,
417                                                 spectrum_size_, 0));
418   EXPECT_EQ(1, self_->near_spectrum_initialized);
419 }
420 
TEST_F(DelayEstimatorTest,CorrectLastDelay)421 TEST_F(DelayEstimatorTest, CorrectLastDelay) {
422   // In this test we verify that we get the correct last delay upon valid call.
423   // We simply process the same data until we leave the initialized state
424   // (|last_delay| = -2). Then we compare the Process() output with the
425   // last_delay() call.
426 
427   // TODO(bjornv): Update quality values for robust validation.
428   int last_delay = 0;
429   // Floating point operations.
430   Init();
431   for (int i = 0; i < 200; i++) {
432     EXPECT_EQ(0, WebRtc_AddFarSpectrumFloat(farend_handle_, far_f_,
433                                             spectrum_size_));
434     last_delay = WebRtc_DelayEstimatorProcessFloat(handle_, near_f_,
435                                                    spectrum_size_);
436     if (last_delay != -2) {
437       EXPECT_EQ(last_delay, WebRtc_last_delay(handle_));
438       if (!WebRtc_is_robust_validation_enabled(handle_)) {
439         EXPECT_FLOAT_EQ(7203.f / kMaxBitCountsQ9,
440                         WebRtc_last_delay_quality(handle_));
441       }
442       break;
443     }
444   }
445   // Verify that we have left the initialized state.
446   EXPECT_NE(-2, WebRtc_last_delay(handle_));
447   EXPECT_LT(0, WebRtc_last_delay_quality(handle_));
448 
449   // Fixed point operations.
450   Init();
451   for (int i = 0; i < 200; i++) {
452     EXPECT_EQ(0, WebRtc_AddFarSpectrumFix(farend_handle_, far_u16_,
453                                           spectrum_size_, 0));
454     last_delay = WebRtc_DelayEstimatorProcessFix(handle_, near_u16_,
455                                                  spectrum_size_, 0);
456     if (last_delay != -2) {
457       EXPECT_EQ(last_delay, WebRtc_last_delay(handle_));
458       if (!WebRtc_is_robust_validation_enabled(handle_)) {
459         EXPECT_FLOAT_EQ(7203.f / kMaxBitCountsQ9,
460                         WebRtc_last_delay_quality(handle_));
461       }
462       break;
463     }
464   }
465   // Verify that we have left the initialized state.
466   EXPECT_NE(-2, WebRtc_last_delay(handle_));
467   EXPECT_LT(0, WebRtc_last_delay_quality(handle_));
468 }
469 
TEST_F(DelayEstimatorTest,CorrectErrorReturnsOfBinaryEstimatorFarend)470 TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfBinaryEstimatorFarend) {
471   // In this test we verify correct output on invalid API calls to the Binary
472   // Delay Estimator (far-end part).
473 
474   BinaryDelayEstimatorFarend* binary = binary_farend_;
475   // WebRtc_CreateBinaryDelayEstimatorFarend() should return -1 if the input
476   // history size is less than 2. This is to make sure the buffer shifting
477   // applies properly.
478   // Make sure we have a non-NULL value at start, so we can detect NULL after
479   // create failure.
480   binary = WebRtc_CreateBinaryDelayEstimatorFarend(1);
481   EXPECT_TRUE(binary == NULL);
482 }
483 
TEST_F(DelayEstimatorTest,CorrectErrorReturnsOfBinaryEstimator)484 TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfBinaryEstimator) {
485   // In this test we verify correct output on invalid API calls to the Binary
486   // Delay Estimator.
487 
488   BinaryDelayEstimator* binary_handle = binary_;
489   // WebRtc_CreateBinaryDelayEstimator() should return -1 if we have a NULL
490   // pointer as |binary_farend| or invalid input values. Upon failure, the
491   // |binary_handle| should be NULL.
492   // Make sure we have a non-NULL value at start, so we can detect NULL after
493   // create failure.
494   binary_handle = WebRtc_CreateBinaryDelayEstimator(NULL, kLookahead);
495   EXPECT_TRUE(binary_handle == NULL);
496   binary_handle = WebRtc_CreateBinaryDelayEstimator(binary_farend_, -1);
497   EXPECT_TRUE(binary_handle == NULL);
498 }
499 
TEST_F(DelayEstimatorTest,MeanEstimatorFix)500 TEST_F(DelayEstimatorTest, MeanEstimatorFix) {
501   // In this test we verify that we update the mean value in correct direction
502   // only. With "direction" we mean increase or decrease.
503 
504   int32_t mean_value = 4000;
505   int32_t mean_value_before = mean_value;
506   int32_t new_mean_value = mean_value * 2;
507 
508   // Increasing |mean_value|.
509   WebRtc_MeanEstimatorFix(new_mean_value, 10, &mean_value);
510   EXPECT_LT(mean_value_before, mean_value);
511   EXPECT_GT(new_mean_value, mean_value);
512 
513   // Decreasing |mean_value|.
514   new_mean_value = mean_value / 2;
515   mean_value_before = mean_value;
516   WebRtc_MeanEstimatorFix(new_mean_value, 10, &mean_value);
517   EXPECT_GT(mean_value_before, mean_value);
518   EXPECT_LT(new_mean_value, mean_value);
519 }
520 
TEST_F(DelayEstimatorTest,ExactDelayEstimateMultipleNearSameSpectrum)521 TEST_F(DelayEstimatorTest, ExactDelayEstimateMultipleNearSameSpectrum) {
522   // In this test we verify that we get the correct delay estimates if we shift
523   // the signal accordingly. We create two Binary Delay Estimators and feed them
524   // with the same signals, so they should output the same results.
525   // We verify both causal and non-causal delays.
526   // For these noise free signals, the robust validation should not have an
527   // impact, hence we turn robust validation on/off for both reference and
528   // delayed near end.
529 
530   for (size_t i = 0; i < kSizeEnable; ++i) {
531     for (size_t j = 0; j < kSizeEnable; ++j) {
532       RunBinarySpectraTest(0, 0, kEnable[i], kEnable[j]);
533     }
534   }
535 }
536 
TEST_F(DelayEstimatorTest,ExactDelayEstimateMultipleNearDifferentSpectrum)537 TEST_F(DelayEstimatorTest, ExactDelayEstimateMultipleNearDifferentSpectrum) {
538   // In this test we use the same setup as above, but we now feed the two Binary
539   // Delay Estimators with different signals, so they should output different
540   // results.
541   // For these noise free signals, the robust validation should not have an
542   // impact, hence we turn robust validation on/off for both reference and
543   // delayed near end.
544 
545   const int kNearOffset = 1;
546   for (size_t i = 0; i < kSizeEnable; ++i) {
547     for (size_t j = 0; j < kSizeEnable; ++j) {
548       RunBinarySpectraTest(kNearOffset, 0, kEnable[i], kEnable[j]);
549     }
550   }
551 }
552 
TEST_F(DelayEstimatorTest,ExactDelayEstimateMultipleNearDifferentLookahead)553 TEST_F(DelayEstimatorTest, ExactDelayEstimateMultipleNearDifferentLookahead) {
554   // In this test we use the same setup as above, feeding the two Binary
555   // Delay Estimators with the same signals. The difference is that we create
556   // them with different lookahead.
557   // For these noise free signals, the robust validation should not have an
558   // impact, hence we turn robust validation on/off for both reference and
559   // delayed near end.
560 
561   const int kLookaheadOffset = 1;
562   for (size_t i = 0; i < kSizeEnable; ++i) {
563     for (size_t j = 0; j < kSizeEnable; ++j) {
564       RunBinarySpectraTest(0, kLookaheadOffset, kEnable[i], kEnable[j]);
565     }
566   }
567 }
568 
TEST_F(DelayEstimatorTest,AllowedOffsetNoImpactWhenRobustValidationDisabled)569 TEST_F(DelayEstimatorTest, AllowedOffsetNoImpactWhenRobustValidationDisabled) {
570   // The same setup as in ExactDelayEstimateMultipleNearSameSpectrum with the
571   // difference that |allowed_offset| is set for the reference binary delay
572   // estimator.
573 
574   binary_->allowed_offset = 10;
575   RunBinarySpectraTest(0, 0, 0, 0);
576   binary_->allowed_offset = 0;  // Reset reference.
577 }
578 
TEST_F(DelayEstimatorTest,VerifyLookaheadAtCreate)579 TEST_F(DelayEstimatorTest, VerifyLookaheadAtCreate) {
580   void* farend_handle = WebRtc_CreateDelayEstimatorFarend(kSpectrumSize,
581                                                           kMaxDelay);
582   ASSERT_TRUE(farend_handle != NULL);
583   void* handle = WebRtc_CreateDelayEstimator(farend_handle, kLookahead);
584   ASSERT_TRUE(handle != NULL);
585   EXPECT_EQ(kLookahead, WebRtc_lookahead(handle));
586   WebRtc_FreeDelayEstimator(handle);
587   WebRtc_FreeDelayEstimatorFarend(farend_handle);
588 }
589 
TEST_F(DelayEstimatorTest,VerifyLookaheadIsSetAndKeptAfterInit)590 TEST_F(DelayEstimatorTest, VerifyLookaheadIsSetAndKeptAfterInit) {
591   EXPECT_EQ(kLookahead, WebRtc_lookahead(handle_));
592   EXPECT_EQ(kDifferentLookahead,
593             WebRtc_set_lookahead(handle_, kDifferentLookahead));
594   EXPECT_EQ(kDifferentLookahead, WebRtc_lookahead(handle_));
595   EXPECT_EQ(0, WebRtc_InitDelayEstimatorFarend(farend_handle_));
596   EXPECT_EQ(kDifferentLookahead, WebRtc_lookahead(handle_));
597   EXPECT_EQ(0, WebRtc_InitDelayEstimator(handle_));
598   EXPECT_EQ(kDifferentLookahead, WebRtc_lookahead(handle_));
599 }
600 
TEST_F(DelayEstimatorTest,VerifyHistorySizeAtCreate)601 TEST_F(DelayEstimatorTest, VerifyHistorySizeAtCreate) {
602   EXPECT_EQ(kHistorySize, WebRtc_history_size(handle_));
603 }
604 
TEST_F(DelayEstimatorTest,VerifyHistorySizeIsSetAndKeptAfterInit)605 TEST_F(DelayEstimatorTest, VerifyHistorySizeIsSetAndKeptAfterInit) {
606   EXPECT_EQ(kHistorySize, WebRtc_history_size(handle_));
607   EXPECT_EQ(kDifferentHistorySize,
608             WebRtc_set_history_size(handle_, kDifferentHistorySize));
609   EXPECT_EQ(kDifferentHistorySize, WebRtc_history_size(handle_));
610   EXPECT_EQ(0, WebRtc_InitDelayEstimator(handle_));
611   EXPECT_EQ(kDifferentHistorySize, WebRtc_history_size(handle_));
612   EXPECT_EQ(0, WebRtc_InitDelayEstimatorFarend(farend_handle_));
613   EXPECT_EQ(kDifferentHistorySize, WebRtc_history_size(handle_));
614 }
615 
616 // TODO(bjornv): Add tests for SoftReset...(...).
617 
618 }  // namespace
619