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 20 matching lines...) Expand all Loading... | |
31 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h" | 31 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h" |
32 #include "webrtc/modules/audio_processing/aec/aec_common.h" | 32 #include "webrtc/modules/audio_processing/aec/aec_common.h" |
33 #include "webrtc/modules/audio_processing/aec/aec_core_internal.h" | 33 #include "webrtc/modules/audio_processing/aec/aec_core_internal.h" |
34 extern "C" { | 34 extern "C" { |
35 #include "webrtc/modules/audio_processing/aec/aec_rdft.h" | 35 #include "webrtc/modules/audio_processing/aec/aec_rdft.h" |
36 } | 36 } |
37 #include "webrtc/modules/audio_processing/logging/aec_logging.h" | 37 #include "webrtc/modules/audio_processing/logging/aec_logging.h" |
38 extern "C" { | 38 extern "C" { |
39 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h" | 39 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h" |
40 } | 40 } |
41 #include "webrtc/base/checks.h" | |
41 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" | 42 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" |
42 #include "webrtc/typedefs.h" | 43 #include "webrtc/typedefs.h" |
43 | 44 |
44 namespace webrtc { | 45 namespace webrtc { |
45 | 46 |
46 // Buffer size (samples) | 47 // Buffer size (samples) |
47 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz. | 48 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz. |
48 | 49 |
49 // Metrics | 50 // Metrics |
50 static const size_t kSubCountLen = 4; | 51 static const size_t kSubCountLen = 4; |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
362 } | 363 } |
363 | 364 |
364 if (wfEn > wfEnMax) { | 365 if (wfEn > wfEnMax) { |
365 wfEnMax = wfEn; | 366 wfEnMax = wfEn; |
366 delay = i; | 367 delay = i; |
367 } | 368 } |
368 } | 369 } |
369 return delay; | 370 return delay; |
370 } | 371 } |
371 | 372 |
373 // Update metric with 10 * log10(numerator / denominator), | |
374 static void UpdateMetric(Stats* metric, float numerator, float denominator) { | |
peah-webrtc
2016/04/19 07:03:37
Did you consider changing the name of the method t
peah-webrtc
2016/04/19 07:03:37
The roles of the numerator/denominator input varia
| |
375 RTC_DCHECK(metric); | |
376 RTC_CHECK(numerator >= 0); | |
377 RTC_CHECK(denominator >= 0); | |
378 | |
379 const float log_numerator = log10(numerator + 1e-10); | |
380 const float log_denominator = log10(denominator + 1e-10); | |
381 metric->instant = 10.0 * (log_numerator - log_denominator); | |
peah-webrtc
2016/04/19 07:03:37
I don't see why we cannot treat the case of the de
minyue-webrtc
2016/04/19 07:21:06
log(a) - log(b) does not only solve denominator be
peah-webrtc
2016/04/19 10:48:34
That is definitely true. Let's keep it like this.
| |
382 | |
383 // Max. | |
384 if (metric->instant > metric->max) | |
385 metric->max = metric->instant; | |
386 | |
387 // Min. | |
388 if (metric->instant < metric->min) | |
389 metric->min = metric->instant; | |
390 | |
391 // Average. | |
392 metric->counter++; | |
393 // This is to protect overflow, which should almost never happen. | |
394 RTC_CHECK_NE(0u, metric->counter); | |
395 metric->sum += metric->instant; | |
396 metric->average = metric->sum / metric->counter; | |
397 | |
398 // Upper mean. | |
399 if (metric->instant > metric->average) { | |
400 metric->hicounter++; | |
401 // This is to protect overflow, which should almost never happen. | |
402 RTC_CHECK_NE(0u, metric->hicounter); | |
403 metric->hisum += metric->instant; | |
404 metric->himean = metric->hisum / metric->hicounter; | |
405 } | |
406 } | |
407 | |
372 // Threshold to protect against the ill-effects of a zero far-end. | 408 // Threshold to protect against the ill-effects of a zero far-end. |
373 const float WebRtcAec_kMinFarendPSD = 15; | 409 const float WebRtcAec_kMinFarendPSD = 15; |
374 | 410 |
375 // Updates the following smoothed Power Spectral Densities (PSD): | 411 // Updates the following smoothed Power Spectral Densities (PSD): |
376 // - sd : near-end | 412 // - sd : near-end |
377 // - se : residual echo | 413 // - se : residual echo |
378 // - sx : far-end | 414 // - sx : far-end |
379 // - sde : cross-PSD of near-end and residual echo | 415 // - sde : cross-PSD of near-end and residual echo |
380 // - sxd : cross-PSD of near-end and far-end | 416 // - sxd : cross-PSD of near-end and far-end |
381 // | 417 // |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
635 level->minlevel = new_frame_level; // New minimum. | 671 level->minlevel = new_frame_level; // New minimum. |
636 } else { | 672 } else { |
637 level->minlevel *= (1 + 0.001f); // Small increase. | 673 level->minlevel *= (1 + 0.001f); // Small increase. |
638 } | 674 } |
639 } | 675 } |
640 level->averagelevel.AddValue(new_frame_level); | 676 level->averagelevel.AddValue(new_frame_level); |
641 } | 677 } |
642 } | 678 } |
643 | 679 |
644 static void UpdateMetrics(AecCore* aec) { | 680 static void UpdateMetrics(AecCore* aec) { |
645 float dtmp; | |
646 | |
647 const float actThresholdNoisy = 8.0f; | 681 const float actThresholdNoisy = 8.0f; |
648 const float actThresholdClean = 40.0f; | 682 const float actThresholdClean = 40.0f; |
649 const float safety = 0.99995f; | |
650 | 683 |
651 const float noisyPower = 300000.0f; | 684 const float noisyPower = 300000.0f; |
652 | 685 |
653 float actThreshold; | 686 float actThreshold; |
654 float echo, suppressedEcho; | |
655 | 687 |
656 if (aec->echoState) { // Check if echo is likely present | 688 if (aec->echoState) { // Check if echo is likely present |
657 aec->stateCounter++; | 689 aec->stateCounter++; |
658 } | 690 } |
659 | 691 |
660 if (aec->linoutlevel.framelevel.EndOfBlock()) { | 692 if (aec->linoutlevel.framelevel.EndOfBlock()) { |
661 aec->divergent_filter_fraction.AddObservation(aec->nearlevel, | 693 aec->divergent_filter_fraction.AddObservation(aec->nearlevel, |
662 aec->linoutlevel, | 694 aec->linoutlevel, |
663 aec->nlpoutlevel); | 695 aec->nlpoutlevel); |
664 } | 696 } |
665 | 697 |
666 if (aec->farlevel.averagelevel.EndOfBlock()) { | 698 if (aec->farlevel.averagelevel.EndOfBlock()) { |
667 if (aec->farlevel.minlevel < noisyPower) { | 699 if (aec->farlevel.minlevel < noisyPower) { |
668 actThreshold = actThresholdClean; | 700 actThreshold = actThresholdClean; |
669 } else { | 701 } else { |
670 actThreshold = actThresholdNoisy; | 702 actThreshold = actThresholdNoisy; |
671 } | 703 } |
672 | 704 |
673 const float far_average_level = aec->farlevel.averagelevel.GetLatestMean(); | 705 const float far_average_level = aec->farlevel.averagelevel.GetLatestMean(); |
674 | 706 |
675 // The last condition is to let estimation be made in active far-end | 707 // The last condition is to let estimation be made in active far-end |
676 // segments only. | 708 // segments only. |
677 if ((aec->stateCounter > (0.5f * kCountLen * kSubCountLen)) && | 709 if ((aec->stateCounter > (0.5f * kCountLen * kSubCountLen)) && |
678 (aec->farlevel.framelevel.EndOfBlock()) && | 710 (aec->farlevel.framelevel.EndOfBlock()) && |
679 (far_average_level > (actThreshold * aec->farlevel.minlevel))) { | 711 (far_average_level > (actThreshold * aec->farlevel.minlevel))) { |
680 | 712 |
713 // ERL | |
peah-webrtc
2016/04/19 07:03:37
The terminating period in the comment is still mis
| |
681 const float near_average_level = | 714 const float near_average_level = |
682 aec->nearlevel.averagelevel.GetLatestMean(); | 715 aec->nearlevel.averagelevel.GetLatestMean(); |
683 | 716 |
684 // Subtract noise power | 717 UpdateMetric(&aec->erl, far_average_level, near_average_level); |
685 echo = near_average_level - safety * aec->nearlevel.minlevel; | |
686 | |
687 // ERL | |
688 dtmp = 10 * static_cast<float>(log10(far_average_level / | |
689 near_average_level + 1e-10f)); | |
690 | |
691 aec->erl.instant = dtmp; | |
692 if (dtmp > aec->erl.max) { | |
693 aec->erl.max = dtmp; | |
694 } | |
695 | |
696 if (dtmp < aec->erl.min) { | |
697 aec->erl.min = dtmp; | |
698 } | |
699 | |
700 aec->erl.counter++; | |
701 aec->erl.sum += dtmp; | |
702 aec->erl.average = aec->erl.sum / aec->erl.counter; | |
703 | |
704 // Upper mean | |
705 if (dtmp > aec->erl.average) { | |
706 aec->erl.hicounter++; | |
707 aec->erl.hisum += dtmp; | |
708 aec->erl.himean = aec->erl.hisum / aec->erl.hicounter; | |
709 } | |
710 | 718 |
711 // A_NLP | 719 // A_NLP |
peah-webrtc
2016/04/19 07:03:37
The terminating period in the comment is still mis
| |
712 const float linout_average_level = | 720 const float linout_average_level = |
713 aec->linoutlevel.averagelevel.GetLatestMean(); | 721 aec->linoutlevel.averagelevel.GetLatestMean(); |
714 dtmp = 10 * static_cast<float>(log10(near_average_level / | 722 UpdateMetric(&aec->aNlp, near_average_level, linout_average_level); |
715 linout_average_level + 1e-10f)); | |
716 | |
717 // subtract noise power | |
718 suppressedEcho = | |
719 linout_average_level - safety * aec->linoutlevel.minlevel; | |
720 | |
721 aec->aNlp.instant = | |
722 10 * static_cast<float>(log10(echo / suppressedEcho + 1e-10f)); | |
723 | |
724 if (dtmp > aec->aNlp.max) { | |
725 aec->aNlp.max = dtmp; | |
726 } | |
727 | |
728 if (dtmp < aec->aNlp.min) { | |
729 aec->aNlp.min = dtmp; | |
730 } | |
731 | |
732 aec->aNlp.counter++; | |
733 aec->aNlp.sum += dtmp; | |
734 aec->aNlp.average = aec->aNlp.sum / aec->aNlp.counter; | |
735 | |
736 // Upper mean | |
737 if (dtmp > aec->aNlp.average) { | |
738 aec->aNlp.hicounter++; | |
739 aec->aNlp.hisum += dtmp; | |
740 aec->aNlp.himean = aec->aNlp.hisum / aec->aNlp.hicounter; | |
741 } | |
742 | 723 |
743 // ERLE | 724 // ERLE |
peah-webrtc
2016/04/19 07:03:37
The terminating period in the comment is still mis
| |
744 const float nlpout_average_level = | 725 const float nlpout_average_level = |
745 aec->nlpoutlevel.averagelevel.GetLatestMean(); | 726 aec->nlpoutlevel.averagelevel.GetLatestMean(); |
746 // subtract noise power | 727 UpdateMetric(&aec->erle, near_average_level, nlpout_average_level); |
747 suppressedEcho = | |
748 nlpout_average_level - safety * aec->nlpoutlevel.minlevel; | |
749 dtmp = 10 * static_cast<float>(log10(echo / suppressedEcho + 1e-10f)); | |
750 | |
751 aec->erle.instant = dtmp; | |
752 if (dtmp > aec->erle.max) { | |
753 aec->erle.max = dtmp; | |
754 } | |
755 | |
756 if (dtmp < aec->erle.min) { | |
757 aec->erle.min = dtmp; | |
758 } | |
759 | |
760 aec->erle.counter++; | |
761 aec->erle.sum += dtmp; | |
762 aec->erle.average = aec->erle.sum / aec->erle.counter; | |
763 | |
764 // Upper mean | |
765 if (dtmp > aec->erle.average) { | |
766 aec->erle.hicounter++; | |
767 aec->erle.hisum += dtmp; | |
768 aec->erle.himean = aec->erle.hisum / aec->erle.hicounter; | |
769 } | |
770 } | 728 } |
771 | 729 |
772 aec->stateCounter = 0; | 730 aec->stateCounter = 0; |
773 } | 731 } |
774 } | 732 } |
775 | 733 |
776 static void UpdateDelayMetrics(AecCore* self) { | 734 static void UpdateDelayMetrics(AecCore* self) { |
777 int i = 0; | 735 int i = 0; |
778 int delay_values = 0; | 736 int delay_values = 0; |
779 int median = 0; | 737 int median = 0; |
(...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1948 | 1906 |
1949 int WebRtcAec_system_delay(AecCore* self) { | 1907 int WebRtcAec_system_delay(AecCore* self) { |
1950 return self->system_delay; | 1908 return self->system_delay; |
1951 } | 1909 } |
1952 | 1910 |
1953 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1911 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1954 assert(delay >= 0); | 1912 assert(delay >= 0); |
1955 self->system_delay = delay; | 1913 self->system_delay = delay; |
1956 } | 1914 } |
1957 } // namespace webrtc | 1915 } // namespace webrtc |
OLD | NEW |