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 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
309 } | 309 } |
310 | 310 |
311 if (wfEn > wfEnMax) { | 311 if (wfEn > wfEnMax) { |
312 wfEnMax = wfEn; | 312 wfEnMax = wfEn; |
313 delay = i; | 313 delay = i; |
314 } | 314 } |
315 } | 315 } |
316 return delay; | 316 return delay; |
317 } | 317 } |
318 | 318 |
319 static void UpdateMetric(Stats* metric, float value) { | |
320 // Instant. | |
321 metric->instant = value; | |
322 | |
323 // Max. | |
324 if (metric->instant > metric->max) | |
325 metric->max = metric->instant; | |
326 | |
327 // Min. | |
328 if (metric->instant < metric->min) | |
329 metric->min = metric->instant; | |
330 | |
331 // Average. | |
332 metric->counter++; | |
peah-webrtc
2016/01/15 06:52:20
This increase should handle wraparounds. I know th
tlegrand-webrtc
2016/04/13 14:33:31
To Per: Are there any platforms today where int is
peah-webrtc
2016/04/14 13:46:10
I would guess there are are no important such plat
kwiberg-webrtc
2016/04/14 14:01:47
"You should assume that an int is at least 32 bits
| |
333 metric->sum += metric->instant; | |
334 metric->average = metric->sum / metric->counter; | |
335 | |
336 // Upper mean. | |
337 if (metric->instant > metric->average) { | |
338 metric->hicounter++; | |
peah-webrtc
2016/01/15 06:52:20
As above, please add handling of wraparound.
| |
339 metric->hisum += metric->instant; | |
340 metric->himean = metric->hisum / metric->hicounter; | |
341 } | |
342 } | |
343 | |
319 // Threshold to protect against the ill-effects of a zero far-end. | 344 // Threshold to protect against the ill-effects of a zero far-end. |
320 const float WebRtcAec_kMinFarendPSD = 15; | 345 const float WebRtcAec_kMinFarendPSD = 15; |
321 | 346 |
322 // Updates the following smoothed Power Spectral Densities (PSD): | 347 // Updates the following smoothed Power Spectral Densities (PSD): |
323 // - sd : near-end | 348 // - sd : near-end |
324 // - se : residual echo | 349 // - se : residual echo |
325 // - sx : far-end | 350 // - sx : far-end |
326 // - sde : cross-PSD of near-end and residual echo | 351 // - sde : cross-PSD of near-end and residual echo |
327 // - sxd : cross-PSD of near-end and far-end | 352 // - sxd : cross-PSD of near-end and far-end |
328 // | 353 // |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
618 level->frsum += level->framelevel; | 643 level->frsum += level->framelevel; |
619 if (level->frcounter > countLen) { | 644 if (level->frcounter > countLen) { |
620 level->averagelevel = level->frsum / countLen; | 645 level->averagelevel = level->frsum / countLen; |
621 level->frsum = 0; | 646 level->frsum = 0; |
622 level->frcounter = 0; | 647 level->frcounter = 0; |
623 } | 648 } |
624 } | 649 } |
625 } | 650 } |
626 | 651 |
627 static void UpdateMetrics(AecCore* aec) { | 652 static void UpdateMetrics(AecCore* aec) { |
628 float dtmp, dtmp2; | |
629 | |
630 const float actThresholdNoisy = 8.0f; | 653 const float actThresholdNoisy = 8.0f; |
631 const float actThresholdClean = 40.0f; | 654 const float actThresholdClean = 40.0f; |
632 const float safety = 0.99995f; | |
633 const float noisyPower = 300000.0f; | 655 const float noisyPower = 300000.0f; |
634 | 656 |
635 float actThreshold; | 657 float actThreshold; |
636 float echo, suppressedEcho; | |
637 | 658 |
638 if (aec->echoState) { // Check if echo is likely present | 659 if (aec->echoState) { // Check if echo is likely present |
639 aec->stateCounter++; | 660 aec->stateCounter++; |
640 } | 661 } |
641 | 662 |
642 if (aec->farlevel.frcounter == 0) { | 663 if (aec->farlevel.frcounter == 0) { |
643 | 664 |
644 if (aec->farlevel.minlevel < noisyPower) { | 665 if (aec->farlevel.minlevel < noisyPower) { |
645 actThreshold = actThresholdClean; | 666 actThreshold = actThresholdClean; |
646 } else { | 667 } else { |
647 actThreshold = actThresholdNoisy; | 668 actThreshold = actThresholdNoisy; |
648 } | 669 } |
649 | 670 |
650 if ((aec->stateCounter > (0.5f * countLen * subCountLen)) && | 671 if ((aec->stateCounter > (0.5f * countLen * subCountLen)) && |
651 (aec->farlevel.sfrcounter == 0) | 672 (aec->farlevel.sfrcounter == 0) |
652 | 673 |
653 // Estimate in active far-end segments only | 674 // Estimate in active far-end segments only |
654 && | 675 && |
655 (aec->farlevel.averagelevel > | 676 (aec->farlevel.averagelevel > |
656 (actThreshold * aec->farlevel.minlevel))) { | 677 (actThreshold * aec->farlevel.minlevel))) { |
657 | 678 |
658 // Subtract noise power | |
659 echo = aec->nearlevel.averagelevel - safety * aec->nearlevel.minlevel; | |
660 | |
661 // ERL | 679 // ERL |
662 dtmp = 10 * (float)log10(aec->farlevel.averagelevel / | 680 UpdateMetric(&aec->erl, 10 * (float)log10(1e-10f + |
peah-webrtc
2016/01/15 06:52:20
While we are anyway changing the metrics: is there
minyue-webrtc
2016/01/15 10:24:49
Good suggestion, but be minded that to an upper le
| |
663 aec->nearlevel.averagelevel + | 681 aec->farlevel.averagelevel / aec->nearlevel.averagelevel)); |
peah-webrtc
2016/01/15 06:52:20
Is there any guarantee that averagelevel cannot be
| |
664 1e-10f); | |
665 dtmp2 = 10 * (float)log10(aec->farlevel.averagelevel / echo + 1e-10f); | |
666 | |
667 aec->erl.instant = dtmp; | |
668 if (dtmp > aec->erl.max) { | |
669 aec->erl.max = dtmp; | |
670 } | |
671 | |
672 if (dtmp < aec->erl.min) { | |
673 aec->erl.min = dtmp; | |
674 } | |
675 | |
676 aec->erl.counter++; | |
677 aec->erl.sum += dtmp; | |
678 aec->erl.average = aec->erl.sum / aec->erl.counter; | |
679 | |
680 // Upper mean | |
681 if (dtmp > aec->erl.average) { | |
682 aec->erl.hicounter++; | |
683 aec->erl.hisum += dtmp; | |
684 aec->erl.himean = aec->erl.hisum / aec->erl.hicounter; | |
685 } | |
686 | 682 |
687 // A_NLP | 683 // A_NLP |
688 dtmp = 10 * (float)log10(aec->nearlevel.averagelevel / | 684 UpdateMetric(&aec->aNlp, 10 * (float)log10(1e-10f + |
689 (2 * aec->linoutlevel.averagelevel) + | 685 aec->nearlevel.averagelevel / (2 * aec->linoutlevel.averagelevel))); |
peah-webrtc
2016/01/15 06:52:20
Is there any guarantee that averagelevel cannot be
minyue-webrtc
2016/01/15 10:24:49
I don't see, and I am not sure how it did not run
| |
690 1e-10f); | |
691 | |
692 // subtract noise power | |
693 suppressedEcho = 2 * (aec->linoutlevel.averagelevel - | |
694 safety * aec->linoutlevel.minlevel); | |
695 | |
696 dtmp2 = 10 * (float)log10(echo / suppressedEcho + 1e-10f); | |
697 | |
698 aec->aNlp.instant = dtmp2; | |
699 if (dtmp > aec->aNlp.max) { | |
700 aec->aNlp.max = dtmp; | |
701 } | |
702 | |
703 if (dtmp < aec->aNlp.min) { | |
704 aec->aNlp.min = dtmp; | |
705 } | |
706 | |
707 aec->aNlp.counter++; | |
708 aec->aNlp.sum += dtmp; | |
709 aec->aNlp.average = aec->aNlp.sum / aec->aNlp.counter; | |
710 | |
711 // Upper mean | |
712 if (dtmp > aec->aNlp.average) { | |
713 aec->aNlp.hicounter++; | |
714 aec->aNlp.hisum += dtmp; | |
715 aec->aNlp.himean = aec->aNlp.hisum / aec->aNlp.hicounter; | |
716 } | |
717 | 686 |
718 // ERLE | 687 // ERLE |
719 | 688 UpdateMetric(&aec->erle, 10 * (float)log10(1e-10f + |
720 // subtract noise power | 689 aec->nearlevel.averagelevel / (2 * aec->nlpoutlevel.averagelevel))); |
peah-webrtc
2016/01/15 06:52:20
Is there any guarantee that averagelevel cannot be
| |
721 suppressedEcho = 2 * (aec->nlpoutlevel.averagelevel - | |
722 safety * aec->nlpoutlevel.minlevel); | |
723 | |
724 dtmp = 10 * (float)log10(aec->nearlevel.averagelevel / | |
725 (2 * aec->nlpoutlevel.averagelevel) + | |
726 1e-10f); | |
727 dtmp2 = 10 * (float)log10(echo / suppressedEcho + 1e-10f); | |
728 | |
729 dtmp = dtmp2; | |
730 aec->erle.instant = dtmp; | |
731 if (dtmp > aec->erle.max) { | |
732 aec->erle.max = dtmp; | |
733 } | |
734 | |
735 if (dtmp < aec->erle.min) { | |
736 aec->erle.min = dtmp; | |
737 } | |
738 | |
739 aec->erle.counter++; | |
740 aec->erle.sum += dtmp; | |
741 aec->erle.average = aec->erle.sum / aec->erle.counter; | |
742 | |
743 // Upper mean | |
744 if (dtmp > aec->erle.average) { | |
745 aec->erle.hicounter++; | |
746 aec->erle.hisum += dtmp; | |
747 aec->erle.himean = aec->erle.hisum / aec->erle.hicounter; | |
748 } | |
749 } | 690 } |
750 | 691 |
751 aec->stateCounter = 0; | 692 aec->stateCounter = 0; |
752 } | 693 } |
753 } | 694 } |
754 | 695 |
755 static void UpdateDelayMetrics(AecCore* self) { | 696 static void UpdateDelayMetrics(AecCore* self) { |
756 int i = 0; | 697 int i = 0; |
757 int delay_values = 0; | 698 int delay_values = 0; |
758 int median = 0; | 699 int median = 0; |
(...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1941 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 1882 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
1942 return self->extended_filter_enabled; | 1883 return self->extended_filter_enabled; |
1943 } | 1884 } |
1944 | 1885 |
1945 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } | 1886 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } |
1946 | 1887 |
1947 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1888 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1948 assert(delay >= 0); | 1889 assert(delay >= 0); |
1949 self->system_delay = delay; | 1890 self->system_delay = delay; |
1950 } | 1891 } |
OLD | NEW |