tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

delay_estimator_unittest.cc (26056B)


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