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 /* | 11 /* |
12 * The core AEC algorithm, which is presented with time-aligned signals. | 12 * The core AEC algorithm, which is presented with time-aligned signals. |
13 */ | 13 */ |
14 | 14 |
15 #include "webrtc/modules/audio_processing/aec/aec_core.h" | 15 #include "webrtc/modules/audio_processing/aec/aec_core.h" |
16 | 16 |
17 #ifdef WEBRTC_AEC_DEBUG_DUMP | 17 #ifdef WEBRTC_AEC_DEBUG_DUMP |
18 #include <stdio.h> | 18 #include <stdio.h> |
19 #endif | 19 #endif |
20 | 20 |
21 #include <assert.h> | 21 #include <assert.h> |
22 #include <math.h> | 22 #include <math.h> |
23 #include <stddef.h> // size_t | 23 #include <stddef.h> // size_t |
24 #include <stdlib.h> | 24 #include <stdlib.h> |
25 #include <string.h> | 25 #include <string.h> |
26 | 26 |
| 27 extern "C" { |
27 #include "webrtc/common_audio/ring_buffer.h" | 28 #include "webrtc/common_audio/ring_buffer.h" |
| 29 } |
28 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar
y.h" | 30 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar
y.h" |
29 #include "webrtc/modules/audio_processing/aec/aec_common.h" | 31 #include "webrtc/modules/audio_processing/aec/aec_common.h" |
30 #include "webrtc/modules/audio_processing/aec/aec_core_internal.h" | 32 #include "webrtc/modules/audio_processing/aec/aec_core_internal.h" |
| 33 extern "C" { |
31 #include "webrtc/modules/audio_processing/aec/aec_rdft.h" | 34 #include "webrtc/modules/audio_processing/aec/aec_rdft.h" |
| 35 } |
32 #include "webrtc/modules/audio_processing/logging/aec_logging.h" | 36 #include "webrtc/modules/audio_processing/logging/aec_logging.h" |
| 37 extern "C" { |
33 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h" | 38 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h" |
| 39 } |
34 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" | 40 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" |
35 #include "webrtc/typedefs.h" | 41 #include "webrtc/typedefs.h" |
36 | 42 |
37 // Buffer size (samples) | 43 // Buffer size (samples) |
38 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz. | 44 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz. |
39 | 45 |
40 // Metrics | 46 // Metrics |
41 static const int subCountLen = 4; | 47 static const int subCountLen = 4; |
42 static const int countLen = 50; | 48 static const int countLen = 50; |
43 static const int kDelayMetricsAggregationWindow = 1250; // 5 seconds at 16 kHz. | 49 static const int kDelayMetricsAggregationWindow = 1250; // 5 seconds at 16 kHz. |
44 | 50 |
45 // Quantities to control H band scaling for SWB input | 51 // Quantities to control H band scaling for SWB input |
46 static const float cnScaleHband = | 52 static const float cnScaleHband = 0.4f; // scale for comfort noise in H band. |
47 (float)0.4; // scale for comfort noise in H band | |
48 // Initial bin for averaging nlp gain in low band | 53 // Initial bin for averaging nlp gain in low band |
49 static const int freqAvgIc = PART_LEN / 2; | 54 static const int freqAvgIc = PART_LEN / 2; |
50 | 55 |
51 // Matlab code to produce table: | 56 // Matlab code to produce table: |
52 // win = sqrt(hanning(63)); win = [0 ; win(1:32)]; | 57 // win = sqrt(hanning(63)); win = [0 ; win(1:32)]; |
53 // fprintf(1, '\t%.14f, %.14f, %.14f,\n', win); | 58 // fprintf(1, '\t%.14f, %.14f, %.14f,\n', win); |
54 ALIGN16_BEG const float ALIGN16_END WebRtcAec_sqrtHanning[65] = { | 59 ALIGN16_BEG const float ALIGN16_END WebRtcAec_sqrtHanning[65] = { |
55 0.00000000000000f, 0.02454122852291f, 0.04906767432742f, 0.07356456359967f, | 60 0.00000000000000f, 0.02454122852291f, 0.04906767432742f, 0.07356456359967f, |
56 0.09801714032956f, 0.12241067519922f, 0.14673047445536f, 0.17096188876030f, | 61 0.09801714032956f, 0.12241067519922f, 0.14673047445536f, 0.17096188876030f, |
57 0.19509032201613f, 0.21910124015687f, 0.24298017990326f, 0.26671275747490f, | 62 0.19509032201613f, 0.21910124015687f, 0.24298017990326f, 0.26671275747490f, |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 (aec->sd[i] * aec->se[i] + 1e-10f); | 414 (aec->sd[i] * aec->se[i] + 1e-10f); |
410 cohxd[i] = | 415 cohxd[i] = |
411 (aec->sxd[i][0] * aec->sxd[i][0] + aec->sxd[i][1] * aec->sxd[i][1]) / | 416 (aec->sxd[i][0] * aec->sxd[i][0] + aec->sxd[i][1] * aec->sxd[i][1]) / |
412 (aec->sx[i] * aec->sd[i] + 1e-10f); | 417 (aec->sx[i] * aec->sd[i] + 1e-10f); |
413 } | 418 } |
414 } | 419 } |
415 | 420 |
416 static void GetHighbandGain(const float* lambda, float* nlpGainHband) { | 421 static void GetHighbandGain(const float* lambda, float* nlpGainHband) { |
417 int i; | 422 int i; |
418 | 423 |
419 *nlpGainHband = (float)0.0; | 424 *nlpGainHband = 0.0f; |
420 for (i = freqAvgIc; i < PART_LEN1 - 1; i++) { | 425 for (i = freqAvgIc; i < PART_LEN1 - 1; i++) { |
421 *nlpGainHband += lambda[i]; | 426 *nlpGainHband += lambda[i]; |
422 } | 427 } |
423 *nlpGainHband /= (float)(PART_LEN1 - 1 - freqAvgIc); | 428 *nlpGainHband /= static_cast<float>(PART_LEN1 - 1 - freqAvgIc); |
424 } | 429 } |
425 | 430 |
426 static void ComfortNoise(AecCore* aec, | 431 static void ComfortNoise(AecCore* aec, |
427 float efw[2][PART_LEN1], | 432 float efw[2][PART_LEN1], |
428 float comfortNoiseHband[2][PART_LEN1], | 433 float comfortNoiseHband[2][PART_LEN1], |
429 const float* noisePow, | 434 const float* noisePow, |
430 const float* lambda) { | 435 const float* lambda) { |
431 int i, num; | 436 int i, num; |
432 float rand[PART_LEN]; | 437 float rand[PART_LEN]; |
433 float noise, noiseAvg, tmp, tmpAvg; | 438 float noise, noiseAvg, tmp, tmpAvg; |
434 int16_t randW16[PART_LEN]; | 439 int16_t randW16[PART_LEN]; |
435 float u[2][PART_LEN1]; | 440 float u[2][PART_LEN1]; |
436 | 441 |
437 const float pi2 = 6.28318530717959f; | 442 const float pi2 = 6.28318530717959f; |
438 | 443 |
439 // Generate a uniform random array on [0 1] | 444 // Generate a uniform random array on [0 1] |
440 WebRtcSpl_RandUArray(randW16, PART_LEN, &aec->seed); | 445 WebRtcSpl_RandUArray(randW16, PART_LEN, &aec->seed); |
441 for (i = 0; i < PART_LEN; i++) { | 446 for (i = 0; i < PART_LEN; i++) { |
442 rand[i] = ((float)randW16[i]) / 32768; | 447 rand[i] = static_cast<float>(randW16[i]) / 32768; |
443 } | 448 } |
444 | 449 |
445 // Reject LF noise | 450 // Reject LF noise |
446 u[0][0] = 0; | 451 u[0][0] = 0; |
447 u[1][0] = 0; | 452 u[1][0] = 0; |
448 for (i = 1; i < PART_LEN1; i++) { | 453 for (i = 1; i < PART_LEN1; i++) { |
449 tmp = pi2 * rand[i - 1]; | 454 tmp = pi2 * rand[i - 1]; |
450 | 455 |
451 noise = sqrtf(noisePow[i]); | 456 noise = sqrtf(noisePow[i]); |
452 u[0][i] = noise * cosf(tmp); | 457 u[0][i] = noise * cosf(tmp); |
453 u[1][i] = -noise * sinf(tmp); | 458 u[1][i] = -noise * sinf(tmp); |
454 } | 459 } |
455 u[1][PART_LEN] = 0; | 460 u[1][PART_LEN] = 0; |
456 | 461 |
457 for (i = 0; i < PART_LEN1; i++) { | 462 for (i = 0; i < PART_LEN1; i++) { |
458 // This is the proper weighting to match the background noise power | 463 // This is the proper weighting to match the background noise power |
459 tmp = sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); | 464 tmp = sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); |
460 // tmp = 1 - lambda[i]; | 465 // tmp = 1 - lambda[i]; |
461 efw[0][i] += tmp * u[0][i]; | 466 efw[0][i] += tmp * u[0][i]; |
462 efw[1][i] += tmp * u[1][i]; | 467 efw[1][i] += tmp * u[1][i]; |
463 } | 468 } |
464 | 469 |
465 // For H band comfort noise | 470 // For H band comfort noise |
466 // TODO: don't compute noise and "tmp" twice. Use the previous results. | 471 // TODO(peah): don't compute noise and "tmp" twice. Use the previous results. |
467 noiseAvg = 0.0; | 472 noiseAvg = 0.0; |
468 tmpAvg = 0.0; | 473 tmpAvg = 0.0; |
469 num = 0; | 474 num = 0; |
470 if (aec->num_bands > 1) { | 475 if (aec->num_bands > 1) { |
471 // average noise scale | 476 // average noise scale |
472 // average over second half of freq spectrum (i.e., 4->8khz) | 477 // average over second half of freq spectrum (i.e., 4->8khz) |
473 // TODO: we shouldn't need num. We know how many elements we're summing. | 478 // TODO(peah): we shouldn't need num. We know how many elements we're |
| 479 // summing. |
474 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { | 480 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { |
475 num++; | 481 num++; |
476 noiseAvg += sqrtf(noisePow[i]); | 482 noiseAvg += sqrtf(noisePow[i]); |
477 } | 483 } |
478 noiseAvg /= (float)num; | 484 noiseAvg /= static_cast<float>(num); |
479 | 485 |
480 // average nlp scale | 486 // average nlp scale |
481 // average over second half of freq spectrum (i.e., 4->8khz) | 487 // average over second half of freq spectrum (i.e., 4->8khz) |
482 // TODO: we shouldn't need num. We know how many elements we're summing. | 488 // TODO(peah): we shouldn't need num. We know how many elements |
| 489 // we're summing. |
483 num = 0; | 490 num = 0; |
484 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { | 491 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { |
485 num++; | 492 num++; |
486 tmpAvg += sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); | 493 tmpAvg += sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); |
487 } | 494 } |
488 tmpAvg /= (float)num; | 495 tmpAvg /= static_cast<float>(num); |
489 | 496 |
490 // Use average noise for H band | 497 // Use average noise for H band |
491 // TODO: we should probably have a new random vector here. | 498 // TODO(peah): we should probably have a new random vector here. |
492 // Reject LF noise | 499 // Reject LF noise |
493 u[0][0] = 0; | 500 u[0][0] = 0; |
494 u[1][0] = 0; | 501 u[1][0] = 0; |
495 for (i = 1; i < PART_LEN1; i++) { | 502 for (i = 1; i < PART_LEN1; i++) { |
496 tmp = pi2 * rand[i - 1]; | 503 tmp = pi2 * rand[i - 1]; |
497 | 504 |
498 // Use average noise for H band | 505 // Use average noise for H band |
499 u[0][i] = noiseAvg * (float)cos(tmp); | 506 u[0][i] = noiseAvg * static_cast<float>(cos(tmp)); |
500 u[1][i] = -noiseAvg * (float)sin(tmp); | 507 u[1][i] = -noiseAvg * static_cast<float>(sin(tmp)); |
501 } | 508 } |
502 u[1][PART_LEN] = 0; | 509 u[1][PART_LEN] = 0; |
503 | 510 |
504 for (i = 0; i < PART_LEN1; i++) { | 511 for (i = 0; i < PART_LEN1; i++) { |
505 // Use average NLP weight for H band | 512 // Use average NLP weight for H band |
506 comfortNoiseHband[0][i] = tmpAvg * u[0][i]; | 513 comfortNoiseHband[0][i] = tmpAvg * u[0][i]; |
507 comfortNoiseHband[1][i] = tmpAvg * u[1][i]; | 514 comfortNoiseHband[1][i] = tmpAvg * u[1][i]; |
508 } | 515 } |
509 } else { | 516 } else { |
510 memset(comfortNoiseHband, 0, | 517 memset(comfortNoiseHband, 0, |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 if ((aec->stateCounter > (0.5f * countLen * subCountLen)) && | 621 if ((aec->stateCounter > (0.5f * countLen * subCountLen)) && |
615 (aec->farlevel.sfrcounter == 0) | 622 (aec->farlevel.sfrcounter == 0) |
616 | 623 |
617 // Estimate in active far-end segments only | 624 // Estimate in active far-end segments only |
618 && (aec->farlevel.averagelevel > | 625 && (aec->farlevel.averagelevel > |
619 (actThreshold * aec->farlevel.minlevel))) { | 626 (actThreshold * aec->farlevel.minlevel))) { |
620 // Subtract noise power | 627 // Subtract noise power |
621 echo = aec->nearlevel.averagelevel - safety * aec->nearlevel.minlevel; | 628 echo = aec->nearlevel.averagelevel - safety * aec->nearlevel.minlevel; |
622 | 629 |
623 // ERL | 630 // ERL |
624 dtmp = 10 * (float)log10(aec->farlevel.averagelevel / | 631 dtmp = 10 * static_cast<float>(log10(aec->farlevel.averagelevel / |
625 aec->nearlevel.averagelevel + | 632 aec->nearlevel.averagelevel + |
626 1e-10f); | 633 1e-10f)); |
627 dtmp2 = 10 * (float)log10(aec->farlevel.averagelevel / echo + 1e-10f); | 634 dtmp2 = 10 * static_cast<float>(log10(aec->farlevel.averagelevel / |
| 635 echo + |
| 636 1e-10f)); |
628 | 637 |
629 aec->erl.instant = dtmp; | 638 aec->erl.instant = dtmp; |
630 if (dtmp > aec->erl.max) { | 639 if (dtmp > aec->erl.max) { |
631 aec->erl.max = dtmp; | 640 aec->erl.max = dtmp; |
632 } | 641 } |
633 | 642 |
634 if (dtmp < aec->erl.min) { | 643 if (dtmp < aec->erl.min) { |
635 aec->erl.min = dtmp; | 644 aec->erl.min = dtmp; |
636 } | 645 } |
637 | 646 |
638 aec->erl.counter++; | 647 aec->erl.counter++; |
639 aec->erl.sum += dtmp; | 648 aec->erl.sum += dtmp; |
640 aec->erl.average = aec->erl.sum / aec->erl.counter; | 649 aec->erl.average = aec->erl.sum / aec->erl.counter; |
641 | 650 |
642 // Upper mean | 651 // Upper mean |
643 if (dtmp > aec->erl.average) { | 652 if (dtmp > aec->erl.average) { |
644 aec->erl.hicounter++; | 653 aec->erl.hicounter++; |
645 aec->erl.hisum += dtmp; | 654 aec->erl.hisum += dtmp; |
646 aec->erl.himean = aec->erl.hisum / aec->erl.hicounter; | 655 aec->erl.himean = aec->erl.hisum / aec->erl.hicounter; |
647 } | 656 } |
648 | 657 |
649 // A_NLP | 658 // A_NLP |
650 dtmp = 10 * (float)log10(aec->nearlevel.averagelevel / | 659 dtmp = 10 * static_cast<float>(log10(aec->nearlevel.averagelevel / |
651 aec->linoutlevel.averagelevel + 1e-10f); | 660 aec->linoutlevel.averagelevel + |
| 661 1e-10f)); |
652 | 662 |
653 // subtract noise power | 663 // subtract noise power |
654 suppressedEcho = aec->linoutlevel.averagelevel - | 664 suppressedEcho = aec->linoutlevel.averagelevel - |
655 safety * aec->linoutlevel.minlevel; | 665 safety * aec->linoutlevel.minlevel; |
656 | 666 |
657 dtmp2 = 10 * (float)log10(echo / suppressedEcho + 1e-10f); | 667 dtmp2 = 10 * static_cast<float>(log10(echo / suppressedEcho + 1e-10f)); |
658 | 668 |
659 aec->aNlp.instant = dtmp2; | 669 aec->aNlp.instant = dtmp2; |
660 if (dtmp > aec->aNlp.max) { | 670 if (dtmp > aec->aNlp.max) { |
661 aec->aNlp.max = dtmp; | 671 aec->aNlp.max = dtmp; |
662 } | 672 } |
663 | 673 |
664 if (dtmp < aec->aNlp.min) { | 674 if (dtmp < aec->aNlp.min) { |
665 aec->aNlp.min = dtmp; | 675 aec->aNlp.min = dtmp; |
666 } | 676 } |
667 | 677 |
668 aec->aNlp.counter++; | 678 aec->aNlp.counter++; |
669 aec->aNlp.sum += dtmp; | 679 aec->aNlp.sum += dtmp; |
670 aec->aNlp.average = aec->aNlp.sum / aec->aNlp.counter; | 680 aec->aNlp.average = aec->aNlp.sum / aec->aNlp.counter; |
671 | 681 |
672 // Upper mean | 682 // Upper mean |
673 if (dtmp > aec->aNlp.average) { | 683 if (dtmp > aec->aNlp.average) { |
674 aec->aNlp.hicounter++; | 684 aec->aNlp.hicounter++; |
675 aec->aNlp.hisum += dtmp; | 685 aec->aNlp.hisum += dtmp; |
676 aec->aNlp.himean = aec->aNlp.hisum / aec->aNlp.hicounter; | 686 aec->aNlp.himean = aec->aNlp.hisum / aec->aNlp.hicounter; |
677 } | 687 } |
678 | 688 |
679 // ERLE | 689 // ERLE |
680 | 690 |
681 // subtract noise power | 691 // subtract noise power |
682 suppressedEcho = 2 * (aec->nlpoutlevel.averagelevel - | 692 suppressedEcho = 2 * (aec->nlpoutlevel.averagelevel - |
683 safety * aec->nlpoutlevel.minlevel); | 693 safety * aec->nlpoutlevel.minlevel); |
684 | 694 |
685 dtmp = 10 * (float)log10(aec->nearlevel.averagelevel / | 695 dtmp = 10 * static_cast<float>(log10(aec->nearlevel.averagelevel / |
686 (2 * aec->nlpoutlevel.averagelevel) + | 696 (2 * aec->nlpoutlevel.averagelevel) + |
687 1e-10f); | 697 1e-10f)); |
688 dtmp2 = 10 * (float)log10(echo / suppressedEcho + 1e-10f); | 698 dtmp2 = 10 * static_cast<float>(log10(echo / suppressedEcho + 1e-10f)); |
689 | 699 |
690 dtmp = dtmp2; | 700 dtmp = dtmp2; |
691 aec->erle.instant = dtmp; | 701 aec->erle.instant = dtmp; |
692 if (dtmp > aec->erle.max) { | 702 if (dtmp > aec->erle.max) { |
693 aec->erle.max = dtmp; | 703 aec->erle.max = dtmp; |
694 } | 704 } |
695 | 705 |
696 if (dtmp < aec->erle.min) { | 706 if (dtmp < aec->erle.min) { |
697 aec->erle.min = dtmp; | 707 aec->erle.min = dtmp; |
698 } | 708 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 } | 754 } |
745 } | 755 } |
746 // Account for lookahead. | 756 // Account for lookahead. |
747 self->delay_median = (median - lookahead) * kMsPerBlock; | 757 self->delay_median = (median - lookahead) * kMsPerBlock; |
748 | 758 |
749 // Calculate the L1 norm, with median value as central moment. | 759 // Calculate the L1 norm, with median value as central moment. |
750 for (i = 0; i < kHistorySizeBlocks; i++) { | 760 for (i = 0; i < kHistorySizeBlocks; i++) { |
751 l1_norm += abs(i - median) * self->delay_histogram[i]; | 761 l1_norm += abs(i - median) * self->delay_histogram[i]; |
752 } | 762 } |
753 self->delay_std = | 763 self->delay_std = |
754 (int)((l1_norm + self->num_delay_values / 2) / self->num_delay_values) * | 764 static_cast<int>((l1_norm + self->num_delay_values / 2) / |
755 kMsPerBlock; | 765 self->num_delay_values) * kMsPerBlock; |
756 | 766 |
757 // Determine fraction of delays that are out of bounds, that is, either | 767 // Determine fraction of delays that are out of bounds, that is, either |
758 // negative (anti-causal system) or larger than the AEC filter length. | 768 // negative (anti-causal system) or larger than the AEC filter length. |
759 { | 769 { |
760 int num_delays_out_of_bounds = self->num_delay_values; | 770 int num_delays_out_of_bounds = self->num_delay_values; |
761 const int histogram_length = | 771 const int histogram_length = |
762 sizeof(self->delay_histogram) / sizeof(self->delay_histogram[0]); | 772 sizeof(self->delay_histogram) / sizeof(self->delay_histogram[0]); |
763 for (i = lookahead; i < lookahead + self->num_partitions; ++i) { | 773 for (i = lookahead; i < lookahead + self->num_partitions; ++i) { |
764 if (i < histogram_length) | 774 if (i < histogram_length) |
765 num_delays_out_of_bounds -= self->delay_histogram[i]; | 775 num_delays_out_of_bounds -= self->delay_histogram[i]; |
766 } | 776 } |
767 self->fraction_poor_delays = | 777 self->fraction_poor_delays = |
768 (float)num_delays_out_of_bounds / self->num_delay_values; | 778 static_cast<float>(num_delays_out_of_bounds) / self->num_delay_values; |
769 } | 779 } |
770 | 780 |
771 // Reset histogram. | 781 // Reset histogram. |
772 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); | 782 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); |
773 self->num_delay_values = 0; | 783 self->num_delay_values = 0; |
774 | 784 |
775 return; | 785 return; |
776 } | 786 } |
777 | 787 |
778 static void ScaledInverseFft(float freq_data[2][PART_LEN1], | 788 static void ScaledInverseFft(float freq_data[2][PART_LEN1], |
779 float time_data[PART_LEN2], | 789 float time_data[PART_LEN2], |
780 float scale, | 790 float scale, |
781 int conjugate) { | 791 int conjugate) { |
782 int i; | 792 int i; |
783 const float normalization = scale / ((float)PART_LEN2); | 793 const float normalization = scale / static_cast<float>(PART_LEN2); |
784 const float sign = (conjugate ? -1 : 1); | 794 const float sign = (conjugate ? -1 : 1); |
785 time_data[0] = freq_data[0][0] * normalization; | 795 time_data[0] = freq_data[0][0] * normalization; |
786 time_data[1] = freq_data[0][PART_LEN] * normalization; | 796 time_data[1] = freq_data[0][PART_LEN] * normalization; |
787 for (i = 1; i < PART_LEN; i++) { | 797 for (i = 1; i < PART_LEN; i++) { |
788 time_data[2 * i] = freq_data[0][i] * normalization; | 798 time_data[2 * i] = freq_data[0][i] * normalization; |
789 time_data[2 * i + 1] = sign * freq_data[1][i] * normalization; | 799 time_data[2 * i + 1] = sign * freq_data[1][i] * normalization; |
790 } | 800 } |
791 aec_rdft_inverse_128(time_data); | 801 aec_rdft_inverse_128(time_data); |
792 } | 802 } |
793 | 803 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 self->delay_quality_threshold)) { | 847 self->delay_quality_threshold)) { |
838 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); | 848 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); |
839 // Allow for a slack in the actual delay, defined by a |lower_bound| and an | 849 // Allow for a slack in the actual delay, defined by a |lower_bound| and an |
840 // |upper_bound|. The adaptive echo cancellation filter is currently | 850 // |upper_bound|. The adaptive echo cancellation filter is currently |
841 // |num_partitions| (of 64 samples) long. If the delay estimate is negative | 851 // |num_partitions| (of 64 samples) long. If the delay estimate is negative |
842 // or at least 3/4 of the filter length we open up for correction. | 852 // or at least 3/4 of the filter length we open up for correction. |
843 const int lower_bound = 0; | 853 const int lower_bound = 0; |
844 const int upper_bound = self->num_partitions * 3 / 4; | 854 const int upper_bound = self->num_partitions * 3 / 4; |
845 const int do_correction = delay <= lower_bound || delay > upper_bound; | 855 const int do_correction = delay <= lower_bound || delay > upper_bound; |
846 if (do_correction == 1) { | 856 if (do_correction == 1) { |
847 int available_read = (int)WebRtc_available_read(self->far_time_buf); | 857 int available_read = |
| 858 static_cast<int>(WebRtc_available_read(self->far_time_buf)); |
848 // With |shift_offset| we gradually rely on the delay estimates. For | 859 // With |shift_offset| we gradually rely on the delay estimates. For |
849 // positive delays we reduce the correction by |shift_offset| to lower the | 860 // positive delays we reduce the correction by |shift_offset| to lower the |
850 // risk of pushing the AEC into a non causal state. For negative delays | 861 // risk of pushing the AEC into a non causal state. For negative delays |
851 // we rely on the values up to a rounding error, hence compensate by 1 | 862 // we rely on the values up to a rounding error, hence compensate by 1 |
852 // element to make sure to push the delay into the causal region. | 863 // element to make sure to push the delay into the causal region. |
853 delay_correction = -delay; | 864 delay_correction = -delay; |
854 delay_correction += delay > self->shift_offset ? self->shift_offset : 1; | 865 delay_correction += delay > self->shift_offset ? self->shift_offset : 1; |
855 self->shift_offset--; | 866 self->shift_offset--; |
856 self->shift_offset = (self->shift_offset <= 1 ? 1 : self->shift_offset); | 867 self->shift_offset = (self->shift_offset <= 1 ? 1 : self->shift_offset); |
857 if (delay_correction > available_read - self->mult - 1) { | 868 if (delay_correction > available_read - self->mult - 1) { |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 memcpy(hNl, cohde, sizeof(hNl)); | 1083 memcpy(hNl, cohde, sizeof(hNl)); |
1073 hNlFb = hNlDeAvg; | 1084 hNlFb = hNlDeAvg; |
1074 hNlFbLow = hNlDeAvg; | 1085 hNlFbLow = hNlDeAvg; |
1075 } else { | 1086 } else { |
1076 aec->echoState = 1; | 1087 aec->echoState = 1; |
1077 for (i = 0; i < PART_LEN1; i++) { | 1088 for (i = 0; i < PART_LEN1; i++) { |
1078 hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]); | 1089 hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]); |
1079 } | 1090 } |
1080 | 1091 |
1081 // Select an order statistic from the preferred bands. | 1092 // Select an order statistic from the preferred bands. |
1082 // TODO: Using quicksort now, but a selection algorithm may be preferred. | 1093 // TODO(peah): Using quicksort now, but a selection algorithm may be |
| 1094 // preferred. |
1083 memcpy(hNlPref, &hNl[minPrefBand], sizeof(float) * prefBandSize); | 1095 memcpy(hNlPref, &hNl[minPrefBand], sizeof(float) * prefBandSize); |
1084 qsort(hNlPref, prefBandSize, sizeof(float), CmpFloat); | 1096 qsort(hNlPref, prefBandSize, sizeof(float), CmpFloat); |
1085 hNlFb = hNlPref[(int)floor(prefBandQuant * (prefBandSize - 1))]; | 1097 hNlFb = hNlPref[static_cast<int>(floor(prefBandQuant * |
1086 hNlFbLow = hNlPref[(int)floor(prefBandQuantLow * (prefBandSize - 1))]; | 1098 (prefBandSize - 1)))]; |
| 1099 hNlFbLow = hNlPref[static_cast<int>(floor(prefBandQuantLow * |
| 1100 (prefBandSize - 1)))]; |
1087 } | 1101 } |
1088 } | 1102 } |
1089 | 1103 |
1090 // Track the local filter minimum to determine suppression overdrive. | 1104 // Track the local filter minimum to determine suppression overdrive. |
1091 if (hNlFbLow < 0.6f && hNlFbLow < aec->hNlFbLocalMin) { | 1105 if (hNlFbLow < 0.6f && hNlFbLow < aec->hNlFbLocalMin) { |
1092 aec->hNlFbLocalMin = hNlFbLow; | 1106 aec->hNlFbLocalMin = hNlFbLow; |
1093 aec->hNlFbMin = hNlFbLow; | 1107 aec->hNlFbMin = hNlFbLow; |
1094 aec->hNlNewMin = 1; | 1108 aec->hNlNewMin = 1; |
1095 aec->hNlMinCtr = 0; | 1109 aec->hNlMinCtr = 0; |
1096 } | 1110 } |
1097 aec->hNlFbLocalMin = | 1111 aec->hNlFbLocalMin = |
1098 WEBRTC_SPL_MIN(aec->hNlFbLocalMin + 0.0008f / aec->mult, 1); | 1112 WEBRTC_SPL_MIN(aec->hNlFbLocalMin + 0.0008f / aec->mult, 1); |
1099 aec->hNlXdAvgMin = WEBRTC_SPL_MIN(aec->hNlXdAvgMin + 0.0006f / aec->mult, 1); | 1113 aec->hNlXdAvgMin = WEBRTC_SPL_MIN(aec->hNlXdAvgMin + 0.0006f / aec->mult, 1); |
1100 | 1114 |
1101 if (aec->hNlNewMin == 1) { | 1115 if (aec->hNlNewMin == 1) { |
1102 aec->hNlMinCtr++; | 1116 aec->hNlMinCtr++; |
1103 } | 1117 } |
1104 if (aec->hNlMinCtr == 2) { | 1118 if (aec->hNlMinCtr == 2) { |
1105 aec->hNlNewMin = 0; | 1119 aec->hNlNewMin = 0; |
1106 aec->hNlMinCtr = 0; | 1120 aec->hNlMinCtr = 0; |
1107 aec->overDrive = | 1121 aec->overDrive = |
1108 WEBRTC_SPL_MAX(kTargetSupp[aec->nlp_mode] / | 1122 WEBRTC_SPL_MAX(kTargetSupp[aec->nlp_mode] / |
1109 ((float)log(aec->hNlFbMin + 1e-10f) + 1e-10f), | 1123 static_cast<float>(log(aec->hNlFbMin + 1e-10f) + 1e-10f), |
1110 min_overdrive[aec->nlp_mode]); | 1124 min_overdrive[aec->nlp_mode]); |
1111 } | 1125 } |
1112 | 1126 |
1113 // Smooth the overdrive. | 1127 // Smooth the overdrive. |
1114 if (aec->overDrive < aec->overDriveSm) { | 1128 if (aec->overDrive < aec->overDriveSm) { |
1115 aec->overDriveSm = 0.99f * aec->overDriveSm + 0.01f * aec->overDrive; | 1129 aec->overDriveSm = 0.99f * aec->overDriveSm + 0.01f * aec->overDrive; |
1116 } else { | 1130 } else { |
1117 aec->overDriveSm = 0.9f * aec->overDriveSm + 0.1f * aec->overDrive; | 1131 aec->overDriveSm = 0.9f * aec->overDriveSm + 0.1f * aec->overDrive; |
1118 } | 1132 } |
1119 | 1133 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1218 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; | 1232 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; |
1219 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; | 1233 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; |
1220 float* x_fft_ptr = NULL; | 1234 float* x_fft_ptr = NULL; |
1221 | 1235 |
1222 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1236 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
1223 outputH_ptr[i] = outputH[i]; | 1237 outputH_ptr[i] = outputH[i]; |
1224 } | 1238 } |
1225 | 1239 |
1226 // Concatenate old and new nearend blocks. | 1240 // Concatenate old and new nearend blocks. |
1227 for (i = 0; i < aec->num_bands - 1; ++i) { | 1241 for (i = 0; i < aec->num_bands - 1; ++i) { |
1228 WebRtc_ReadBuffer(aec->nearFrBufH[i], (void**)&nearend_ptr, nearend, | 1242 WebRtc_ReadBuffer(aec->nearFrBufH[i], |
1229 PART_LEN); | 1243 reinterpret_cast<void**>(&nearend_ptr), |
| 1244 nearend, PART_LEN); |
1230 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); | 1245 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); |
1231 } | 1246 } |
1232 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN); | 1247 WebRtc_ReadBuffer(aec->nearFrBuf, reinterpret_cast<void**>(&nearend_ptr), |
| 1248 nearend, PART_LEN); |
1233 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend)); | 1249 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend)); |
1234 | 1250 |
1235 // We should always have at least one element stored in |far_buf|. | 1251 // We should always have at least one element stored in |far_buf|. |
1236 assert(WebRtc_available_read(aec->far_time_buf) > 0); | 1252 assert(WebRtc_available_read(aec->far_time_buf) > 0); |
1237 WebRtc_ReadBuffer(aec->far_time_buf, (void**)&farend_ptr, farend, 1); | 1253 WebRtc_ReadBuffer(aec->far_time_buf, reinterpret_cast<void**>(&farend_ptr), |
| 1254 farend, 1); |
1238 | 1255 |
1239 #ifdef WEBRTC_AEC_DEBUG_DUMP | 1256 #ifdef WEBRTC_AEC_DEBUG_DUMP |
1240 { | 1257 { |
1241 // TODO(minyue): |farend_ptr| starts from buffered samples. This will be | 1258 // TODO(minyue): |farend_ptr| starts from buffered samples. This will be |
1242 // modified when |aec->far_time_buf| is revised. | 1259 // modified when |aec->far_time_buf| is revised. |
1243 RTC_AEC_DEBUG_WAV_WRITE(aec->farFile, &farend_ptr[PART_LEN], PART_LEN); | 1260 RTC_AEC_DEBUG_WAV_WRITE(aec->farFile, &farend_ptr[PART_LEN], PART_LEN); |
1244 | 1261 |
1245 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN); | 1262 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN); |
1246 } | 1263 } |
1247 #endif | 1264 #endif |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1349 // For high bands | 1366 // For high bands |
1350 for (i = 0; i < aec->num_bands - 1; ++i) { | 1367 for (i = 0; i < aec->num_bands - 1; ++i) { |
1351 WebRtc_WriteBuffer(aec->outFrBufH[i], outputH[i], PART_LEN); | 1368 WebRtc_WriteBuffer(aec->outFrBufH[i], outputH[i], PART_LEN); |
1352 } | 1369 } |
1353 | 1370 |
1354 RTC_AEC_DEBUG_WAV_WRITE(aec->outFile, output, PART_LEN); | 1371 RTC_AEC_DEBUG_WAV_WRITE(aec->outFile, output, PART_LEN); |
1355 } | 1372 } |
1356 | 1373 |
1357 AecCore* WebRtcAec_CreateAec() { | 1374 AecCore* WebRtcAec_CreateAec() { |
1358 int i; | 1375 int i; |
1359 AecCore* aec = malloc(sizeof(AecCore)); | 1376 AecCore* aec = reinterpret_cast<AecCore*>(malloc(sizeof(AecCore))); |
1360 if (!aec) { | 1377 if (!aec) { |
1361 return NULL; | 1378 return NULL; |
1362 } | 1379 } |
1363 | 1380 |
1364 aec->nearFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); | 1381 aec->nearFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); |
1365 if (!aec->nearFrBuf) { | 1382 if (!aec->nearFrBuf) { |
1366 WebRtcAec_FreeAec(aec); | 1383 WebRtcAec_FreeAec(aec); |
1367 return NULL; | 1384 return NULL; |
1368 } | 1385 } |
1369 | 1386 |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1578 | 1595 |
1579 // Default target suppression mode. | 1596 // Default target suppression mode. |
1580 aec->nlp_mode = 1; | 1597 aec->nlp_mode = 1; |
1581 | 1598 |
1582 // Sampling frequency multiplier w.r.t. 8 kHz. | 1599 // Sampling frequency multiplier w.r.t. 8 kHz. |
1583 // In case of multiple bands we process the lower band in 16 kHz, hence the | 1600 // In case of multiple bands we process the lower band in 16 kHz, hence the |
1584 // multiplier is always 2. | 1601 // multiplier is always 2. |
1585 if (aec->num_bands > 1) { | 1602 if (aec->num_bands > 1) { |
1586 aec->mult = 2; | 1603 aec->mult = 2; |
1587 } else { | 1604 } else { |
1588 aec->mult = (short)aec->sampFreq / 8000; | 1605 aec->mult = static_cast<int16_t>(aec->sampFreq) / 8000; |
1589 } | 1606 } |
1590 | 1607 |
1591 aec->farBufWritePos = 0; | 1608 aec->farBufWritePos = 0; |
1592 aec->farBufReadPos = 0; | 1609 aec->farBufReadPos = 0; |
1593 | 1610 |
1594 aec->inSamples = 0; | 1611 aec->inSamples = 0; |
1595 aec->outSamples = 0; | 1612 aec->outSamples = 0; |
1596 aec->knownDelay = 0; | 1613 aec->knownDelay = 0; |
1597 | 1614 |
1598 // Initialize buffers | 1615 // Initialize buffers |
(...skipping 10 matching lines...) Expand all Loading... |
1609 aec->noisePow = aec->dInitMinPow; | 1626 aec->noisePow = aec->dInitMinPow; |
1610 aec->noiseEstCtr = 0; | 1627 aec->noiseEstCtr = 0; |
1611 | 1628 |
1612 // Initial comfort noise power | 1629 // Initial comfort noise power |
1613 for (i = 0; i < PART_LEN1; i++) { | 1630 for (i = 0; i < PART_LEN1; i++) { |
1614 aec->dMinPow[i] = 1.0e6f; | 1631 aec->dMinPow[i] = 1.0e6f; |
1615 } | 1632 } |
1616 | 1633 |
1617 // Holds the last block written to | 1634 // Holds the last block written to |
1618 aec->xfBufBlockPos = 0; | 1635 aec->xfBufBlockPos = 0; |
1619 // TODO: Investigate need for these initializations. Deleting them doesn't | 1636 // TODO(peah): Investigate need for these initializations. Deleting them |
1620 // change the output at all and yields 0.4% overall speedup. | 1637 // doesn't change the output at all and yields 0.4% overall speedup. |
1621 memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); | 1638 memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); |
1622 memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); | 1639 memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); |
1623 memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1); | 1640 memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1); |
1624 memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1); | 1641 memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1); |
1625 memset(aec->xfwBuf, 0, | 1642 memset(aec->xfwBuf, 0, |
1626 sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); | 1643 sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); |
1627 memset(aec->se, 0, sizeof(float) * PART_LEN1); | 1644 memset(aec->se, 0, sizeof(float) * PART_LEN1); |
1628 | 1645 |
1629 // To prevent numerical instability in the first block. | 1646 // To prevent numerical instability in the first block. |
1630 for (i = 0; i < PART_LEN1; i++) { | 1647 for (i = 0; i < PART_LEN1; i++) { |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1775 while (WebRtc_available_read(aec->nearFrBuf) >= PART_LEN) { | 1792 while (WebRtc_available_read(aec->nearFrBuf) >= PART_LEN) { |
1776 ProcessBlock(aec); | 1793 ProcessBlock(aec); |
1777 } | 1794 } |
1778 | 1795 |
1779 // 5) Update system delay with respect to the entire frame. | 1796 // 5) Update system delay with respect to the entire frame. |
1780 aec->system_delay -= FRAME_LEN; | 1797 aec->system_delay -= FRAME_LEN; |
1781 | 1798 |
1782 // 6) Update output frame. | 1799 // 6) Update output frame. |
1783 // Stuff the out buffer if we have less than a frame to output. | 1800 // Stuff the out buffer if we have less than a frame to output. |
1784 // This should only happen for the first frame. | 1801 // This should only happen for the first frame. |
1785 out_elements = (int)WebRtc_available_read(aec->outFrBuf); | 1802 out_elements = static_cast<int>(WebRtc_available_read(aec->outFrBuf)); |
1786 if (out_elements < FRAME_LEN) { | 1803 if (out_elements < FRAME_LEN) { |
1787 WebRtc_MoveReadPtr(aec->outFrBuf, out_elements - FRAME_LEN); | 1804 WebRtc_MoveReadPtr(aec->outFrBuf, out_elements - FRAME_LEN); |
1788 for (i = 0; i < num_bands - 1; ++i) { | 1805 for (i = 0; i < num_bands - 1; ++i) { |
1789 WebRtc_MoveReadPtr(aec->outFrBufH[i], out_elements - FRAME_LEN); | 1806 WebRtc_MoveReadPtr(aec->outFrBufH[i], out_elements - FRAME_LEN); |
1790 } | 1807 } |
1791 } | 1808 } |
1792 // Obtain an output frame. | 1809 // Obtain an output frame. |
1793 WebRtc_ReadBuffer(aec->outFrBuf, NULL, &out[0][j], FRAME_LEN); | 1810 WebRtc_ReadBuffer(aec->outFrBuf, NULL, &out[0][j], FRAME_LEN); |
1794 // For H bands. | 1811 // For H bands. |
1795 for (i = 1; i < num_bands; ++i) { | 1812 for (i = 1; i < num_bands; ++i) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1887 } | 1904 } |
1888 | 1905 |
1889 int WebRtcAec_system_delay(AecCore* self) { | 1906 int WebRtcAec_system_delay(AecCore* self) { |
1890 return self->system_delay; | 1907 return self->system_delay; |
1891 } | 1908 } |
1892 | 1909 |
1893 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1910 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1894 assert(delay >= 0); | 1911 assert(delay >= 0); |
1895 self->system_delay = delay; | 1912 self->system_delay = delay; |
1896 } | 1913 } |
OLD | NEW |