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 |
(...skipping 28 matching lines...) Expand all Loading... | |
39 } | 39 } |
40 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" | 40 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" |
41 #include "webrtc/typedefs.h" | 41 #include "webrtc/typedefs.h" |
42 | 42 |
43 namespace webrtc { | 43 namespace webrtc { |
44 | 44 |
45 // Buffer size (samples) | 45 // Buffer size (samples) |
46 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz. | 46 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz. |
47 | 47 |
48 // Metrics | 48 // Metrics |
49 static const int subCountLen = 4; | 49 static const size_t kSubCountLen = 4; |
50 static const int countLen = 50; | 50 static const size_t kCountLen = 50; |
51 static const int kDelayMetricsAggregationWindow = 1250; // 5 seconds at 16 kHz. | 51 static const int kDelayMetricsAggregationWindow = 1250; // 5 seconds at 16 kHz. |
52 | 52 |
53 // Quantities to control H band scaling for SWB input | 53 // Quantities to control H band scaling for SWB input |
54 static const float cnScaleHband = 0.4f; // scale for comfort noise in H band. | 54 static const float cnScaleHband = 0.4f; // scale for comfort noise in H band. |
55 // Initial bin for averaging nlp gain in low band | 55 // Initial bin for averaging nlp gain in low band |
56 static const int freqAvgIc = PART_LEN / 2; | 56 static const int freqAvgIc = PART_LEN / 2; |
57 | 57 |
58 // Matlab code to produce table: | 58 // Matlab code to produce table: |
59 // win = sqrt(hanning(63)); win = [0 ; win(1:32)]; | 59 // win = sqrt(hanning(63)); win = [0 ; win(1:32)]; |
60 // fprintf(1, '\t%.14f, %.14f, %.14f,\n', win); | 60 // fprintf(1, '\t%.14f, %.14f, %.14f,\n', win); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
143 WebRtcAecWindowData WebRtcAec_WindowData; | 143 WebRtcAecWindowData WebRtcAec_WindowData; |
144 | 144 |
145 __inline static float MulRe(float aRe, float aIm, float bRe, float bIm) { | 145 __inline static float MulRe(float aRe, float aIm, float bRe, float bIm) { |
146 return aRe * bRe - aIm * bIm; | 146 return aRe * bRe - aIm * bIm; |
147 } | 147 } |
148 | 148 |
149 __inline static float MulIm(float aRe, float aIm, float bRe, float bIm) { | 149 __inline static float MulIm(float aRe, float aIm, float bRe, float bIm) { |
150 return aRe * bIm + aIm * bRe; | 150 return aRe * bIm + aIm * bRe; |
151 } | 151 } |
152 | 152 |
153 PowerLevel::PowerLevel() | |
154 // TODO(minyue): Due to a legacy bug, |framelevel| and |averagelevel| use a | |
155 // window, of which the length is 1 unit longer than indicated. Remove "+1" | |
156 // when the code is refactored. | |
157 : framelevel(kSubCountLen + 1), | |
158 averagelevel(kCountLen + 1) { | |
159 } | |
160 | |
161 // TODO(minyue): Moving some initialization from WebRtcAec_CreateAec() to ctor. | |
162 AecCore::AecCore() = default; | |
163 | |
153 static int CmpFloat(const void* a, const void* b) { | 164 static int CmpFloat(const void* a, const void* b) { |
154 const float* da = (const float*)a; | 165 const float* da = (const float*)a; |
155 const float* db = (const float*)b; | 166 const float* db = (const float*)b; |
156 | 167 |
157 return (*da > *db) - (*da < *db); | 168 return (*da > *db) - (*da < *db); |
158 } | 169 } |
159 | 170 |
160 static void FilterFar(int num_partitions, | 171 static void FilterFar(int num_partitions, |
161 int x_fft_buf_block_pos, | 172 int x_fft_buf_block_pos, |
162 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], | 173 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
516 comfortNoiseHband[1][i] = tmpAvg * u[1][i]; | 527 comfortNoiseHband[1][i] = tmpAvg * u[1][i]; |
517 } | 528 } |
518 } else { | 529 } else { |
519 memset(comfortNoiseHband, 0, | 530 memset(comfortNoiseHband, 0, |
520 2 * PART_LEN1 * sizeof(comfortNoiseHband[0][0])); | 531 2 * PART_LEN1 * sizeof(comfortNoiseHband[0][0])); |
521 } | 532 } |
522 } | 533 } |
523 | 534 |
524 static void InitLevel(PowerLevel* level) { | 535 static void InitLevel(PowerLevel* level) { |
525 const float kBigFloat = 1E17f; | 536 const float kBigFloat = 1E17f; |
526 | 537 level->averagelevel.Reset(); |
527 level->averagelevel = 0; | 538 level->framelevel.Reset(); |
528 level->framelevel = 0; | |
529 level->minlevel = kBigFloat; | 539 level->minlevel = kBigFloat; |
530 level->frsum = 0; | |
531 level->sfrsum = 0; | |
532 level->frcounter = 0; | |
533 level->sfrcounter = 0; | |
534 } | 540 } |
535 | 541 |
536 static void InitStats(Stats* stats) { | 542 static void InitStats(Stats* stats) { |
537 stats->instant = kOffsetLevel; | 543 stats->instant = kOffsetLevel; |
538 stats->average = kOffsetLevel; | 544 stats->average = kOffsetLevel; |
539 stats->max = kOffsetLevel; | 545 stats->max = kOffsetLevel; |
540 stats->min = kOffsetLevel * (-1); | 546 stats->min = kOffsetLevel * (-1); |
541 stats->sum = 0; | 547 stats->sum = 0; |
542 stats->hisum = 0; | 548 stats->hisum = 0; |
543 stats->himean = kOffsetLevel; | 549 stats->himean = kOffsetLevel; |
(...skipping 17 matching lines...) Expand all Loading... | |
561 static float CalculatePower(const float* in, size_t num_samples) { | 567 static float CalculatePower(const float* in, size_t num_samples) { |
562 size_t k; | 568 size_t k; |
563 float energy = 0.0f; | 569 float energy = 0.0f; |
564 | 570 |
565 for (k = 0; k < num_samples; ++k) { | 571 for (k = 0; k < num_samples; ++k) { |
566 energy += in[k] * in[k]; | 572 energy += in[k] * in[k]; |
567 } | 573 } |
568 return energy / num_samples; | 574 return energy / num_samples; |
569 } | 575 } |
570 | 576 |
571 static void UpdateLevel(PowerLevel* level, float energy) { | 577 static void UpdateLevel(PowerLevel* level, float power) { |
572 level->sfrsum += energy; | 578 level->framelevel.AddValue(power); |
573 level->sfrcounter++; | 579 if (level->framelevel.EndOfBlock()) { |
574 | 580 const float new_frame_level = level->framelevel.GetLatestMean(); |
575 if (level->sfrcounter > subCountLen) { | 581 if (new_frame_level > 0) { |
576 level->framelevel = level->sfrsum / (subCountLen * PART_LEN); | 582 if (new_frame_level < level->minlevel) { |
577 level->sfrsum = 0; | 583 level->minlevel = new_frame_level; // New minimum. |
578 level->sfrcounter = 0; | |
579 if (level->framelevel > 0) { | |
580 if (level->framelevel < level->minlevel) { | |
581 level->minlevel = level->framelevel; // New minimum. | |
582 } else { | 584 } else { |
583 level->minlevel *= (1 + 0.001f); // Small increase. | 585 level->minlevel *= (1 + 0.001f); // Small increase. |
584 } | 586 } |
585 } | 587 } |
586 level->frcounter++; | 588 level->averagelevel.AddValue(new_frame_level); |
587 level->frsum += level->framelevel; | |
588 if (level->frcounter > countLen) { | |
589 level->averagelevel = level->frsum / countLen; | |
590 level->frsum = 0; | |
591 level->frcounter = 0; | |
592 } | |
593 } | 589 } |
594 } | 590 } |
595 | 591 |
596 static void UpdateMetrics(AecCore* aec) { | 592 static void UpdateMetrics(AecCore* aec) { |
597 float dtmp, dtmp2; | 593 float dtmp, dtmp2; |
598 | 594 |
599 const float actThresholdNoisy = 8.0f; | 595 const float actThresholdNoisy = 8.0f; |
600 const float actThresholdClean = 40.0f; | 596 const float actThresholdClean = 40.0f; |
601 const float safety = 0.99995f; | 597 const float safety = 0.99995f; |
602 | 598 |
603 // To make noisePower consistent with the legacy code, a factor of | 599 const float noisyPower = 300000.0f; |
604 // 2.0f / PART_LEN2 is applied to noisyPower, since the legacy code uses | |
605 // the energy of a frame as the audio levels, while the new code uses a | |
606 // a per-sample energy (i.e., power). | |
607 const float noisyPower = 300000.0f * 2.0f / PART_LEN2; | |
608 | 600 |
609 float actThreshold; | 601 float actThreshold; |
610 float echo, suppressedEcho; | 602 float echo, suppressedEcho; |
611 | 603 |
612 if (aec->echoState) { // Check if echo is likely present | 604 if (aec->echoState) { // Check if echo is likely present |
613 aec->stateCounter++; | 605 aec->stateCounter++; |
614 } | 606 } |
615 | 607 |
616 if (aec->farlevel.frcounter == 0) { | 608 if (aec->farlevel.averagelevel.EndOfBlock()) { |
617 if (aec->farlevel.minlevel < noisyPower) { | 609 if (aec->farlevel.minlevel < noisyPower) { |
618 actThreshold = actThresholdClean; | 610 actThreshold = actThresholdClean; |
619 } else { | 611 } else { |
620 actThreshold = actThresholdNoisy; | 612 actThreshold = actThresholdNoisy; |
621 } | 613 } |
622 | 614 |
623 if ((aec->stateCounter > (0.5f * countLen * subCountLen)) && | 615 const float far_average_level = aec->farlevel.averagelevel.GetLatestMean(); |
624 (aec->farlevel.sfrcounter == 0) | 616 if ((aec->stateCounter > (0.5f * kCountLen * kSubCountLen)) && |
617 (aec->farlevel.framelevel.EndOfBlock()) | |
618 // Estimate in active far-end segments only | |
peah-webrtc
2016/03/24 11:21:58
Please move the comment so that it is not inside t
| |
619 && (far_average_level > (actThreshold * aec->farlevel.minlevel))) { | |
625 | 620 |
626 // Estimate in active far-end segments only | 621 const float near_average_level = |
627 && (aec->farlevel.averagelevel > | 622 aec->nearlevel.averagelevel.GetLatestMean(); |
628 (actThreshold * aec->farlevel.minlevel))) { | 623 |
629 // Subtract noise power | 624 // Subtract noise power |
630 echo = aec->nearlevel.averagelevel - safety * aec->nearlevel.minlevel; | 625 echo = near_average_level - safety * aec->nearlevel.minlevel; |
631 | 626 |
632 // ERL | 627 // ERL |
633 dtmp = 10 * static_cast<float>(log10(aec->farlevel.averagelevel / | 628 dtmp = 10 * static_cast<float>(log10(far_average_level / |
634 aec->nearlevel.averagelevel + | 629 near_average_level + 1e-10f)); |
635 1e-10f)); | 630 dtmp2 = 10 * static_cast<float>(log10(far_average_level / echo + 1e-10f)); |
636 dtmp2 = 10 * static_cast<float>(log10(aec->farlevel.averagelevel / | |
637 echo + | |
638 1e-10f)); | |
639 | 631 |
640 aec->erl.instant = dtmp; | 632 aec->erl.instant = dtmp; |
641 if (dtmp > aec->erl.max) { | 633 if (dtmp > aec->erl.max) { |
642 aec->erl.max = dtmp; | 634 aec->erl.max = dtmp; |
643 } | 635 } |
644 | 636 |
645 if (dtmp < aec->erl.min) { | 637 if (dtmp < aec->erl.min) { |
646 aec->erl.min = dtmp; | 638 aec->erl.min = dtmp; |
647 } | 639 } |
648 | 640 |
649 aec->erl.counter++; | 641 aec->erl.counter++; |
650 aec->erl.sum += dtmp; | 642 aec->erl.sum += dtmp; |
651 aec->erl.average = aec->erl.sum / aec->erl.counter; | 643 aec->erl.average = aec->erl.sum / aec->erl.counter; |
652 | 644 |
653 // Upper mean | 645 // Upper mean |
654 if (dtmp > aec->erl.average) { | 646 if (dtmp > aec->erl.average) { |
655 aec->erl.hicounter++; | 647 aec->erl.hicounter++; |
656 aec->erl.hisum += dtmp; | 648 aec->erl.hisum += dtmp; |
657 aec->erl.himean = aec->erl.hisum / aec->erl.hicounter; | 649 aec->erl.himean = aec->erl.hisum / aec->erl.hicounter; |
658 } | 650 } |
659 | 651 |
660 // A_NLP | 652 // A_NLP |
661 dtmp = 10 * static_cast<float>(log10(aec->nearlevel.averagelevel / | 653 const float linout_average_level = |
662 aec->linoutlevel.averagelevel + | 654 aec->linoutlevel.averagelevel.GetLatestMean(); |
663 1e-10f)); | 655 dtmp = 10 * static_cast<float>(log10(near_average_level / |
656 linout_average_level + 1e-10f)); | |
664 | 657 |
665 // subtract noise power | 658 // subtract noise power |
666 suppressedEcho = aec->linoutlevel.averagelevel - | 659 suppressedEcho = |
667 safety * aec->linoutlevel.minlevel; | 660 linout_average_level - safety * aec->linoutlevel.minlevel; |
668 | 661 |
669 dtmp2 = 10 * static_cast<float>(log10(echo / suppressedEcho + 1e-10f)); | 662 dtmp2 = 10 * static_cast<float>(log10(echo / suppressedEcho + 1e-10f)); |
670 | 663 |
671 aec->aNlp.instant = dtmp2; | 664 aec->aNlp.instant = dtmp2; |
672 if (dtmp > aec->aNlp.max) { | 665 if (dtmp > aec->aNlp.max) { |
673 aec->aNlp.max = dtmp; | 666 aec->aNlp.max = dtmp; |
674 } | 667 } |
675 | 668 |
676 if (dtmp < aec->aNlp.min) { | 669 if (dtmp < aec->aNlp.min) { |
677 aec->aNlp.min = dtmp; | 670 aec->aNlp.min = dtmp; |
678 } | 671 } |
679 | 672 |
680 aec->aNlp.counter++; | 673 aec->aNlp.counter++; |
681 aec->aNlp.sum += dtmp; | 674 aec->aNlp.sum += dtmp; |
682 aec->aNlp.average = aec->aNlp.sum / aec->aNlp.counter; | 675 aec->aNlp.average = aec->aNlp.sum / aec->aNlp.counter; |
683 | 676 |
684 // Upper mean | 677 // Upper mean |
685 if (dtmp > aec->aNlp.average) { | 678 if (dtmp > aec->aNlp.average) { |
686 aec->aNlp.hicounter++; | 679 aec->aNlp.hicounter++; |
687 aec->aNlp.hisum += dtmp; | 680 aec->aNlp.hisum += dtmp; |
688 aec->aNlp.himean = aec->aNlp.hisum / aec->aNlp.hicounter; | 681 aec->aNlp.himean = aec->aNlp.hisum / aec->aNlp.hicounter; |
689 } | 682 } |
690 | 683 |
691 // ERLE | 684 // ERLE |
685 const float nlpout_average_level = | |
686 aec->nlpoutlevel.averagelevel.GetLatestMean(); | |
687 // subtract noise power | |
688 suppressedEcho = | |
689 nlpout_average_level - safety * aec->nlpoutlevel.minlevel; | |
692 | 690 |
693 // subtract noise power | 691 dtmp = 10 * static_cast<float>(log10(near_average_level / |
694 suppressedEcho = aec->nlpoutlevel.averagelevel - | 692 nlpout_average_level + 1e-10f)); |
695 safety * aec->nlpoutlevel.minlevel; | |
696 | |
697 dtmp = 10 * static_cast<float>(log10(aec->nearlevel.averagelevel / | |
698 aec->nlpoutlevel.averagelevel + 1e-10f)); | |
699 dtmp2 = 10 * static_cast<float>(log10(echo / suppressedEcho + 1e-10f)); | 693 dtmp2 = 10 * static_cast<float>(log10(echo / suppressedEcho + 1e-10f)); |
700 | 694 |
701 dtmp = dtmp2; | 695 dtmp = dtmp2; |
702 aec->erle.instant = dtmp; | 696 aec->erle.instant = dtmp; |
703 if (dtmp > aec->erle.max) { | 697 if (dtmp > aec->erle.max) { |
704 aec->erle.max = dtmp; | 698 aec->erle.max = dtmp; |
705 } | 699 } |
706 | 700 |
707 if (dtmp < aec->erle.min) { | 701 if (dtmp < aec->erle.min) { |
708 aec->erle.min = dtmp; | 702 aec->erle.min = dtmp; |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1358 // For high bands | 1352 // For high bands |
1359 for (i = 0; i < aec->num_bands - 1; ++i) { | 1353 for (i = 0; i < aec->num_bands - 1; ++i) { |
1360 WebRtc_WriteBuffer(aec->outFrBufH[i], outputH[i], PART_LEN); | 1354 WebRtc_WriteBuffer(aec->outFrBufH[i], outputH[i], PART_LEN); |
1361 } | 1355 } |
1362 | 1356 |
1363 RTC_AEC_DEBUG_WAV_WRITE(aec->outFile, output, PART_LEN); | 1357 RTC_AEC_DEBUG_WAV_WRITE(aec->outFile, output, PART_LEN); |
1364 } | 1358 } |
1365 | 1359 |
1366 AecCore* WebRtcAec_CreateAec() { | 1360 AecCore* WebRtcAec_CreateAec() { |
1367 int i; | 1361 int i; |
1368 AecCore* aec = reinterpret_cast<AecCore*>(malloc(sizeof(AecCore))); | 1362 AecCore* aec = new AecCore; |
1369 if (!aec) { | 1363 if (!aec) { |
1370 return NULL; | 1364 return NULL; |
1371 } | 1365 } |
1372 | 1366 |
1373 aec->nearFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); | 1367 aec->nearFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); |
1374 if (!aec->nearFrBuf) { | 1368 if (!aec->nearFrBuf) { |
1375 WebRtcAec_FreeAec(aec); | 1369 WebRtcAec_FreeAec(aec); |
1376 return NULL; | 1370 return NULL; |
1377 } | 1371 } |
1378 | 1372 |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1896 | 1890 |
1897 int WebRtcAec_system_delay(AecCore* self) { | 1891 int WebRtcAec_system_delay(AecCore* self) { |
1898 return self->system_delay; | 1892 return self->system_delay; |
1899 } | 1893 } |
1900 | 1894 |
1901 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1895 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1902 assert(delay >= 0); | 1896 assert(delay >= 0); |
1903 self->system_delay = delay; | 1897 self->system_delay = delay; |
1904 } | 1898 } |
1905 } // namespace webrtc | 1899 } // namespace webrtc |
OLD | NEW |