| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/modules/audio_processing/utility/delay_estimator.h" | 11 #include "webrtc/modules/audio_processing/utility/delay_estimator.h" |
| 12 | 12 |
| 13 #include <assert.h> | |
| 14 #include <stdlib.h> | 13 #include <stdlib.h> |
| 15 #include <string.h> | 14 #include <string.h> |
| 16 #include <algorithm> | 15 #include <algorithm> |
| 17 | 16 |
| 17 #include "webrtc/base/checks.h" |
| 18 |
| 18 // Number of right shifts for scaling is linearly depending on number of bits in | 19 // Number of right shifts for scaling is linearly depending on number of bits in |
| 19 // the far-end binary spectrum. | 20 // the far-end binary spectrum. |
| 20 static const int kShiftsAtZero = 13; // Right shifts at zero binary spectrum. | 21 static const int kShiftsAtZero = 13; // Right shifts at zero binary spectrum. |
| 21 static const int kShiftsLinearSlope = 3; | 22 static const int kShiftsLinearSlope = 3; |
| 22 | 23 |
| 23 static const int32_t kProbabilityOffset = 1024; // 2 in Q9. | 24 static const int32_t kProbabilityOffset = 1024; // 2 in Q9. |
| 24 static const int32_t kProbabilityLowerLimit = 8704; // 17 in Q9. | 25 static const int32_t kProbabilityLowerLimit = 8704; // 17 in Q9. |
| 25 static const int32_t kProbabilityMinSpread = 2816; // 5.5 in Q9. | 26 static const int32_t kProbabilityMinSpread = 2816; // 5.5 in Q9. |
| 26 | 27 |
| 27 // Robust validation settings | 28 // Robust validation settings |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 static void UpdateRobustValidationStatistics(BinaryDelayEstimator* self, | 93 static void UpdateRobustValidationStatistics(BinaryDelayEstimator* self, |
| 93 int candidate_delay, | 94 int candidate_delay, |
| 94 int32_t valley_depth_q14, | 95 int32_t valley_depth_q14, |
| 95 int32_t valley_level_q14) { | 96 int32_t valley_level_q14) { |
| 96 const float valley_depth = valley_depth_q14 * kQ14Scaling; | 97 const float valley_depth = valley_depth_q14 * kQ14Scaling; |
| 97 float decrease_in_last_set = valley_depth; | 98 float decrease_in_last_set = valley_depth; |
| 98 const int max_hits_for_slow_change = (candidate_delay < self->last_delay) ? | 99 const int max_hits_for_slow_change = (candidate_delay < self->last_delay) ? |
| 99 kMaxHitsWhenPossiblyNonCausal : kMaxHitsWhenPossiblyCausal; | 100 kMaxHitsWhenPossiblyNonCausal : kMaxHitsWhenPossiblyCausal; |
| 100 int i = 0; | 101 int i = 0; |
| 101 | 102 |
| 102 assert(self->history_size == self->farend->history_size); | 103 RTC_DCHECK_EQ(self->history_size, self->farend->history_size); |
| 103 // Reset |candidate_hits| if we have a new candidate. | 104 // Reset |candidate_hits| if we have a new candidate. |
| 104 if (candidate_delay != self->last_candidate_delay) { | 105 if (candidate_delay != self->last_candidate_delay) { |
| 105 self->candidate_hits = 0; | 106 self->candidate_hits = 0; |
| 106 self->last_candidate_delay = candidate_delay; | 107 self->last_candidate_delay = candidate_delay; |
| 107 } | 108 } |
| 108 self->candidate_hits++; | 109 self->candidate_hits++; |
| 109 | 110 |
| 110 // The |histogram| is updated differently across the bins. | 111 // The |histogram| is updated differently across the bins. |
| 111 // 1. The |candidate_delay| histogram bin is increased with the | 112 // 1. The |candidate_delay| histogram bin is increased with the |
| 112 // |valley_depth|, which is a simple measure of how reliable the | 113 // |valley_depth|, which is a simple measure of how reliable the |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 self->far_bit_counts = NULL; | 290 self->far_bit_counts = NULL; |
| 290 if (WebRtc_AllocateFarendBufferMemory(self, history_size) == 0) { | 291 if (WebRtc_AllocateFarendBufferMemory(self, history_size) == 0) { |
| 291 WebRtc_FreeBinaryDelayEstimatorFarend(self); | 292 WebRtc_FreeBinaryDelayEstimatorFarend(self); |
| 292 self = NULL; | 293 self = NULL; |
| 293 } | 294 } |
| 294 return self; | 295 return self; |
| 295 } | 296 } |
| 296 | 297 |
| 297 int WebRtc_AllocateFarendBufferMemory(BinaryDelayEstimatorFarend* self, | 298 int WebRtc_AllocateFarendBufferMemory(BinaryDelayEstimatorFarend* self, |
| 298 int history_size) { | 299 int history_size) { |
| 299 assert(self != NULL); | 300 RTC_DCHECK(self); |
| 300 // (Re-)Allocate memory for history buffers. | 301 // (Re-)Allocate memory for history buffers. |
| 301 self->binary_far_history = static_cast<uint32_t*>( | 302 self->binary_far_history = static_cast<uint32_t*>( |
| 302 realloc(self->binary_far_history, | 303 realloc(self->binary_far_history, |
| 303 history_size * sizeof(*self->binary_far_history))); | 304 history_size * sizeof(*self->binary_far_history))); |
| 304 self->far_bit_counts = static_cast<int*>( | 305 self->far_bit_counts = static_cast<int*>( |
| 305 realloc(self->far_bit_counts, | 306 realloc(self->far_bit_counts, |
| 306 history_size * sizeof(*self->far_bit_counts))); | 307 history_size * sizeof(*self->far_bit_counts))); |
| 307 if ((self->binary_far_history == NULL) || (self->far_bit_counts == NULL)) { | 308 if ((self->binary_far_history == NULL) || (self->far_bit_counts == NULL)) { |
| 308 history_size = 0; | 309 history_size = 0; |
| 309 } | 310 } |
| 310 // Fill with zeros if we have expanded the buffers. | 311 // Fill with zeros if we have expanded the buffers. |
| 311 if (history_size > self->history_size) { | 312 if (history_size > self->history_size) { |
| 312 int size_diff = history_size - self->history_size; | 313 int size_diff = history_size - self->history_size; |
| 313 memset(&self->binary_far_history[self->history_size], | 314 memset(&self->binary_far_history[self->history_size], |
| 314 0, | 315 0, |
| 315 sizeof(*self->binary_far_history) * size_diff); | 316 sizeof(*self->binary_far_history) * size_diff); |
| 316 memset(&self->far_bit_counts[self->history_size], | 317 memset(&self->far_bit_counts[self->history_size], |
| 317 0, | 318 0, |
| 318 sizeof(*self->far_bit_counts) * size_diff); | 319 sizeof(*self->far_bit_counts) * size_diff); |
| 319 } | 320 } |
| 320 self->history_size = history_size; | 321 self->history_size = history_size; |
| 321 | 322 |
| 322 return self->history_size; | 323 return self->history_size; |
| 323 } | 324 } |
| 324 | 325 |
| 325 void WebRtc_InitBinaryDelayEstimatorFarend(BinaryDelayEstimatorFarend* self) { | 326 void WebRtc_InitBinaryDelayEstimatorFarend(BinaryDelayEstimatorFarend* self) { |
| 326 assert(self != NULL); | 327 RTC_DCHECK(self); |
| 327 memset(self->binary_far_history, 0, sizeof(uint32_t) * self->history_size); | 328 memset(self->binary_far_history, 0, sizeof(uint32_t) * self->history_size); |
| 328 memset(self->far_bit_counts, 0, sizeof(int) * self->history_size); | 329 memset(self->far_bit_counts, 0, sizeof(int) * self->history_size); |
| 329 } | 330 } |
| 330 | 331 |
| 331 void WebRtc_SoftResetBinaryDelayEstimatorFarend( | 332 void WebRtc_SoftResetBinaryDelayEstimatorFarend( |
| 332 BinaryDelayEstimatorFarend* self, int delay_shift) { | 333 BinaryDelayEstimatorFarend* self, int delay_shift) { |
| 333 int abs_shift = abs(delay_shift); | 334 int abs_shift = abs(delay_shift); |
| 334 int shift_size = 0; | 335 int shift_size = 0; |
| 335 int dest_index = 0; | 336 int dest_index = 0; |
| 336 int src_index = 0; | 337 int src_index = 0; |
| 337 int padding_index = 0; | 338 int padding_index = 0; |
| 338 | 339 |
| 339 assert(self != NULL); | 340 RTC_DCHECK(self); |
| 340 shift_size = self->history_size - abs_shift; | 341 shift_size = self->history_size - abs_shift; |
| 341 assert(shift_size > 0); | 342 RTC_DCHECK_GT(shift_size, 0); |
| 342 if (delay_shift == 0) { | 343 if (delay_shift == 0) { |
| 343 return; | 344 return; |
| 344 } else if (delay_shift > 0) { | 345 } else if (delay_shift > 0) { |
| 345 dest_index = abs_shift; | 346 dest_index = abs_shift; |
| 346 } else if (delay_shift < 0) { | 347 } else if (delay_shift < 0) { |
| 347 src_index = abs_shift; | 348 src_index = abs_shift; |
| 348 padding_index = shift_size; | 349 padding_index = shift_size; |
| 349 } | 350 } |
| 350 | 351 |
| 351 // Shift and zero pad buffers. | 352 // Shift and zero pad buffers. |
| 352 memmove(&self->binary_far_history[dest_index], | 353 memmove(&self->binary_far_history[dest_index], |
| 353 &self->binary_far_history[src_index], | 354 &self->binary_far_history[src_index], |
| 354 sizeof(*self->binary_far_history) * shift_size); | 355 sizeof(*self->binary_far_history) * shift_size); |
| 355 memset(&self->binary_far_history[padding_index], 0, | 356 memset(&self->binary_far_history[padding_index], 0, |
| 356 sizeof(*self->binary_far_history) * abs_shift); | 357 sizeof(*self->binary_far_history) * abs_shift); |
| 357 memmove(&self->far_bit_counts[dest_index], | 358 memmove(&self->far_bit_counts[dest_index], |
| 358 &self->far_bit_counts[src_index], | 359 &self->far_bit_counts[src_index], |
| 359 sizeof(*self->far_bit_counts) * shift_size); | 360 sizeof(*self->far_bit_counts) * shift_size); |
| 360 memset(&self->far_bit_counts[padding_index], 0, | 361 memset(&self->far_bit_counts[padding_index], 0, |
| 361 sizeof(*self->far_bit_counts) * abs_shift); | 362 sizeof(*self->far_bit_counts) * abs_shift); |
| 362 } | 363 } |
| 363 | 364 |
| 364 void WebRtc_AddBinaryFarSpectrum(BinaryDelayEstimatorFarend* handle, | 365 void WebRtc_AddBinaryFarSpectrum(BinaryDelayEstimatorFarend* handle, |
| 365 uint32_t binary_far_spectrum) { | 366 uint32_t binary_far_spectrum) { |
| 366 assert(handle != NULL); | 367 RTC_DCHECK(handle); |
| 367 // Shift binary spectrum history and insert current |binary_far_spectrum|. | 368 // Shift binary spectrum history and insert current |binary_far_spectrum|. |
| 368 memmove(&(handle->binary_far_history[1]), &(handle->binary_far_history[0]), | 369 memmove(&(handle->binary_far_history[1]), &(handle->binary_far_history[0]), |
| 369 (handle->history_size - 1) * sizeof(uint32_t)); | 370 (handle->history_size - 1) * sizeof(uint32_t)); |
| 370 handle->binary_far_history[0] = binary_far_spectrum; | 371 handle->binary_far_history[0] = binary_far_spectrum; |
| 371 | 372 |
| 372 // Shift history of far-end binary spectrum bit counts and insert bit count | 373 // Shift history of far-end binary spectrum bit counts and insert bit count |
| 373 // of current |binary_far_spectrum|. | 374 // of current |binary_far_spectrum|. |
| 374 memmove(&(handle->far_bit_counts[1]), &(handle->far_bit_counts[0]), | 375 memmove(&(handle->far_bit_counts[1]), &(handle->far_bit_counts[0]), |
| 375 (handle->history_size - 1) * sizeof(int)); | 376 (handle->history_size - 1) * sizeof(int)); |
| 376 handle->far_bit_counts[0] = BitCount(binary_far_spectrum); | 377 handle->far_bit_counts[0] = BitCount(binary_far_spectrum); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 0, | 475 0, |
| 475 sizeof(*self->histogram) * size_diff); | 476 sizeof(*self->histogram) * size_diff); |
| 476 } | 477 } |
| 477 self->history_size = history_size; | 478 self->history_size = history_size; |
| 478 | 479 |
| 479 return self->history_size; | 480 return self->history_size; |
| 480 } | 481 } |
| 481 | 482 |
| 482 void WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator* self) { | 483 void WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator* self) { |
| 483 int i = 0; | 484 int i = 0; |
| 484 assert(self != NULL); | 485 RTC_DCHECK(self); |
| 485 | 486 |
| 486 memset(self->bit_counts, 0, sizeof(int32_t) * self->history_size); | 487 memset(self->bit_counts, 0, sizeof(int32_t) * self->history_size); |
| 487 memset(self->binary_near_history, | 488 memset(self->binary_near_history, |
| 488 0, | 489 0, |
| 489 sizeof(uint32_t) * self->near_history_size); | 490 sizeof(uint32_t) * self->near_history_size); |
| 490 for (i = 0; i <= self->history_size; ++i) { | 491 for (i = 0; i <= self->history_size; ++i) { |
| 491 self->mean_bit_counts[i] = (20 << 9); // 20 in Q9. | 492 self->mean_bit_counts[i] = (20 << 9); // 20 in Q9. |
| 492 self->histogram[i] = 0.f; | 493 self->histogram[i] = 0.f; |
| 493 } | 494 } |
| 494 self->minimum_probability = kMaxBitCountsQ9; // 32 in Q9. | 495 self->minimum_probability = kMaxBitCountsQ9; // 32 in Q9. |
| 495 self->last_delay_probability = (int) kMaxBitCountsQ9; // 32 in Q9. | 496 self->last_delay_probability = (int) kMaxBitCountsQ9; // 32 in Q9. |
| 496 | 497 |
| 497 // Default return value if we're unable to estimate. -1 is used for errors. | 498 // Default return value if we're unable to estimate. -1 is used for errors. |
| 498 self->last_delay = -2; | 499 self->last_delay = -2; |
| 499 | 500 |
| 500 self->last_candidate_delay = -2; | 501 self->last_candidate_delay = -2; |
| 501 self->compare_delay = self->history_size; | 502 self->compare_delay = self->history_size; |
| 502 self->candidate_hits = 0; | 503 self->candidate_hits = 0; |
| 503 self->last_delay_histogram = 0.f; | 504 self->last_delay_histogram = 0.f; |
| 504 } | 505 } |
| 505 | 506 |
| 506 int WebRtc_SoftResetBinaryDelayEstimator(BinaryDelayEstimator* self, | 507 int WebRtc_SoftResetBinaryDelayEstimator(BinaryDelayEstimator* self, |
| 507 int delay_shift) { | 508 int delay_shift) { |
| 508 int lookahead = 0; | 509 int lookahead = 0; |
| 509 assert(self != NULL); | 510 RTC_DCHECK(self); |
| 510 lookahead = self->lookahead; | 511 lookahead = self->lookahead; |
| 511 self->lookahead -= delay_shift; | 512 self->lookahead -= delay_shift; |
| 512 if (self->lookahead < 0) { | 513 if (self->lookahead < 0) { |
| 513 self->lookahead = 0; | 514 self->lookahead = 0; |
| 514 } | 515 } |
| 515 if (self->lookahead > self->near_history_size - 1) { | 516 if (self->lookahead > self->near_history_size - 1) { |
| 516 self->lookahead = self->near_history_size - 1; | 517 self->lookahead = self->near_history_size - 1; |
| 517 } | 518 } |
| 518 return lookahead - self->lookahead; | 519 return lookahead - self->lookahead; |
| 519 } | 520 } |
| 520 | 521 |
| 521 int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator* self, | 522 int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator* self, |
| 522 uint32_t binary_near_spectrum) { | 523 uint32_t binary_near_spectrum) { |
| 523 int i = 0; | 524 int i = 0; |
| 524 int candidate_delay = -1; | 525 int candidate_delay = -1; |
| 525 int valid_candidate = 0; | 526 int valid_candidate = 0; |
| 526 | 527 |
| 527 int32_t value_best_candidate = kMaxBitCountsQ9; | 528 int32_t value_best_candidate = kMaxBitCountsQ9; |
| 528 int32_t value_worst_candidate = 0; | 529 int32_t value_worst_candidate = 0; |
| 529 int32_t valley_depth = 0; | 530 int32_t valley_depth = 0; |
| 530 | 531 |
| 531 assert(self != NULL); | 532 RTC_DCHECK(self); |
| 532 if (self->farend->history_size != self->history_size) { | 533 if (self->farend->history_size != self->history_size) { |
| 533 // Non matching history sizes. | 534 // Non matching history sizes. |
| 534 return -1; | 535 return -1; |
| 535 } | 536 } |
| 536 if (self->near_history_size > 1) { | 537 if (self->near_history_size > 1) { |
| 537 // If we apply lookahead, shift near-end binary spectrum history. Insert | 538 // If we apply lookahead, shift near-end binary spectrum history. Insert |
| 538 // current |binary_near_spectrum| and pull out the delayed one. | 539 // current |binary_near_spectrum| and pull out the delayed one. |
| 539 memmove(&(self->binary_near_history[1]), &(self->binary_near_history[0]), | 540 memmove(&(self->binary_near_history[1]), &(self->binary_near_history[0]), |
| 540 (self->near_history_size - 1) * sizeof(uint32_t)); | 541 (self->near_history_size - 1) * sizeof(uint32_t)); |
| 541 self->binary_near_history[0] = binary_near_spectrum; | 542 self->binary_near_history[0] = binary_near_spectrum; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 if (value_best_candidate < self->last_delay_probability) { | 658 if (value_best_candidate < self->last_delay_probability) { |
| 658 self->last_delay_probability = value_best_candidate; | 659 self->last_delay_probability = value_best_candidate; |
| 659 } | 660 } |
| 660 self->compare_delay = self->last_delay; | 661 self->compare_delay = self->last_delay; |
| 661 } | 662 } |
| 662 | 663 |
| 663 return self->last_delay; | 664 return self->last_delay; |
| 664 } | 665 } |
| 665 | 666 |
| 666 int WebRtc_binary_last_delay(BinaryDelayEstimator* self) { | 667 int WebRtc_binary_last_delay(BinaryDelayEstimator* self) { |
| 667 assert(self != NULL); | 668 RTC_DCHECK(self); |
| 668 return self->last_delay; | 669 return self->last_delay; |
| 669 } | 670 } |
| 670 | 671 |
| 671 float WebRtc_binary_last_delay_quality(BinaryDelayEstimator* self) { | 672 float WebRtc_binary_last_delay_quality(BinaryDelayEstimator* self) { |
| 672 float quality = 0; | 673 float quality = 0; |
| 673 assert(self != NULL); | 674 RTC_DCHECK(self); |
| 674 | 675 |
| 675 if (self->robust_validation_enabled) { | 676 if (self->robust_validation_enabled) { |
| 676 // Simply a linear function of the histogram height at delay estimate. | 677 // Simply a linear function of the histogram height at delay estimate. |
| 677 quality = self->histogram[self->compare_delay] / kHistogramMax; | 678 quality = self->histogram[self->compare_delay] / kHistogramMax; |
| 678 } else { | 679 } else { |
| 679 // Note that |last_delay_probability| states how deep the minimum of the | 680 // Note that |last_delay_probability| states how deep the minimum of the |
| 680 // cost function is, so it is rather an error probability. | 681 // cost function is, so it is rather an error probability. |
| 681 quality = (float) (kMaxBitCountsQ9 - self->last_delay_probability) / | 682 quality = (float) (kMaxBitCountsQ9 - self->last_delay_probability) / |
| 682 kMaxBitCountsQ9; | 683 kMaxBitCountsQ9; |
| 683 if (quality < 0) { | 684 if (quality < 0) { |
| 684 quality = 0; | 685 quality = 0; |
| 685 } | 686 } |
| 686 } | 687 } |
| 687 return quality; | 688 return quality; |
| 688 } | 689 } |
| 689 | 690 |
| 690 void WebRtc_MeanEstimatorFix(int32_t new_value, | 691 void WebRtc_MeanEstimatorFix(int32_t new_value, |
| 691 int factor, | 692 int factor, |
| 692 int32_t* mean_value) { | 693 int32_t* mean_value) { |
| 693 int32_t diff = new_value - *mean_value; | 694 int32_t diff = new_value - *mean_value; |
| 694 | 695 |
| 695 // mean_new = mean_value + ((new_value - mean_value) >> factor); | 696 // mean_new = mean_value + ((new_value - mean_value) >> factor); |
| 696 if (diff < 0) { | 697 if (diff < 0) { |
| 697 diff = -((-diff) >> factor); | 698 diff = -((-diff) >> factor); |
| 698 } else { | 699 } else { |
| 699 diff = (diff >> factor); | 700 diff = (diff >> factor); |
| 700 } | 701 } |
| 701 *mean_value += diff; | 702 *mean_value += diff; |
| 702 } | 703 } |
| OLD | NEW |