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