Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(623)

Side by Side Diff: webrtc/modules/audio_processing/aec/aec_core.cc

Issue 1713923002: Moved the AEC C code to be built using C++ (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Format changes to comply with lint Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « webrtc/modules/audio_processing/aec/aec_core.c ('k') | webrtc/modules/audio_processing/aec/aec_core_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698