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