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 |