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

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

Issue 1581183005: Cleaning up AEC metrics. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: revising comment Created 4 years, 8 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
(...skipping 10 matching lines...) Expand all
21 #include <algorithm> 21 #include <algorithm>
22 #include <assert.h> 22 #include <assert.h>
23 #include <math.h> 23 #include <math.h>
24 #include <stddef.h> // size_t 24 #include <stddef.h> // size_t
25 #include <stdlib.h> 25 #include <stdlib.h>
26 #include <string.h> 26 #include <string.h>
27 27
28 extern "C" { 28 extern "C" {
29 #include "webrtc/common_audio/ring_buffer.h" 29 #include "webrtc/common_audio/ring_buffer.h"
30 } 30 }
31 #include "webrtc/base/checks.h"
31 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h" 32 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h"
32 #include "webrtc/modules/audio_processing/aec/aec_common.h" 33 #include "webrtc/modules/audio_processing/aec/aec_common.h"
33 #include "webrtc/modules/audio_processing/aec/aec_core_internal.h" 34 #include "webrtc/modules/audio_processing/aec/aec_core_internal.h"
34 #include "webrtc/modules/audio_processing/aec/aec_rdft.h" 35 #include "webrtc/modules/audio_processing/aec/aec_rdft.h"
35 #include "webrtc/modules/audio_processing/logging/aec_logging.h" 36 #include "webrtc/modules/audio_processing/logging/aec_logging.h"
36 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h" 37 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h"
37 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" 38 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h"
38 #include "webrtc/typedefs.h" 39 #include "webrtc/typedefs.h"
39 40
40 namespace webrtc { 41 namespace webrtc {
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 } 359 }
359 360
360 if (wfEn > wfEnMax) { 361 if (wfEn > wfEnMax) {
361 wfEnMax = wfEn; 362 wfEnMax = wfEn;
362 delay = i; 363 delay = i;
363 } 364 }
364 } 365 }
365 return delay; 366 return delay;
366 } 367 }
367 368
369 // Update metric with 10 * log10(numerator / denominator).
370 static void UpdateLogRatioMetric(Stats* metric, float numerator,
371 float denominator) {
372 RTC_DCHECK(metric);
373 RTC_CHECK(numerator >= 0);
tlegrand-webrtc 2016/04/25 13:09:56 Why isn't numerator = 0 allowed?
kwiberg-webrtc 2016/04/25 13:23:58 It is. But what I'm wondering is why we allow deno
minyue-webrtc 2016/04/25 13:26:56 It is allowed, isn't it?
tlegrand-webrtc 2016/04/28 08:17:30 Right, my mistake. I was thinking 0 wouldn't be al
374 RTC_CHECK(denominator >= 0);
375
376 const float log_numerator = log10(numerator + 1e-10f);
377 const float log_denominator = log10(denominator + 1e-10f);
tlegrand-webrtc 2016/04/25 13:09:56 Which is more computational complex, log10 or divi
kwiberg-webrtc 2016/04/25 13:23:58 Yes, I'd be surprised if division wasn't significa
minyue-webrtc 2016/04/25 13:26:56 Per also asked about this. My reasoning was that i
tlegrand-webrtc 2016/04/28 08:17:30 Acknowledged.
378 metric->instant = 10.0f * (log_numerator - log_denominator);
379
380 // Max.
tlegrand-webrtc 2016/04/25 13:09:56 This comment doesn't add any value. Same with "Min
minyue-webrtc 2016/04/25 13:26:56 I agree. I'd like to make a separate CL, which may
tlegrand-webrtc 2016/04/28 08:17:30 Acknowledged.
381 if (metric->instant > metric->max)
382 metric->max = metric->instant;
383
384 // Min.
385 if (metric->instant < metric->min)
386 metric->min = metric->instant;
387
388 // Average.
389 metric->counter++;
390 // This is to protect overflow, which should almost never happen.
391 RTC_CHECK_NE(0u, metric->counter);
392 metric->sum += metric->instant;
393 metric->average = metric->sum / metric->counter;
394
395 // Upper mean.
tlegrand-webrtc 2016/04/25 13:09:56 hicounter, hisum and himean doesn't follow the nam
minyue-webrtc 2016/04/25 13:26:56 True, this will need to refactor other part of AEC
tlegrand-webrtc 2016/04/28 08:17:30 Acknowledged.
396 if (metric->instant > metric->average) {
397 metric->hicounter++;
398 // This is to protect overflow, which should almost never happen.
399 RTC_CHECK_NE(0u, metric->hicounter);
400 metric->hisum += metric->instant;
401 metric->himean = metric->hisum / metric->hicounter;
402 }
403 }
404
368 // Threshold to protect against the ill-effects of a zero far-end. 405 // Threshold to protect against the ill-effects of a zero far-end.
369 const float WebRtcAec_kMinFarendPSD = 15; 406 const float WebRtcAec_kMinFarendPSD = 15;
370 407
371 // Updates the following smoothed Power Spectral Densities (PSD): 408 // Updates the following smoothed Power Spectral Densities (PSD):
372 // - sd : near-end 409 // - sd : near-end
373 // - se : residual echo 410 // - se : residual echo
374 // - sx : far-end 411 // - sx : far-end
375 // - sde : cross-PSD of near-end and residual echo 412 // - sde : cross-PSD of near-end and residual echo
376 // - sxd : cross-PSD of near-end and far-end 413 // - sxd : cross-PSD of near-end and far-end
377 // 414 //
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 level->minlevel = new_frame_level; // New minimum. 668 level->minlevel = new_frame_level; // New minimum.
632 } else { 669 } else {
633 level->minlevel *= (1 + 0.001f); // Small increase. 670 level->minlevel *= (1 + 0.001f); // Small increase.
634 } 671 }
635 } 672 }
636 level->averagelevel.AddValue(new_frame_level); 673 level->averagelevel.AddValue(new_frame_level);
637 } 674 }
638 } 675 }
639 676
640 static void UpdateMetrics(AecCore* aec) { 677 static void UpdateMetrics(AecCore* aec) {
641 float dtmp;
642
643 const float actThresholdNoisy = 8.0f; 678 const float actThresholdNoisy = 8.0f;
644 const float actThresholdClean = 40.0f; 679 const float actThresholdClean = 40.0f;
645 const float safety = 0.99995f;
646 680
647 const float noisyPower = 300000.0f; 681 const float noisyPower = 300000.0f;
648 682
649 float actThreshold; 683 float actThreshold;
650 float echo, suppressedEcho;
651 684
652 if (aec->echoState) { // Check if echo is likely present 685 if (aec->echoState) { // Check if echo is likely present
653 aec->stateCounter++; 686 aec->stateCounter++;
654 } 687 }
655 688
656 if (aec->linoutlevel.framelevel.EndOfBlock()) { 689 if (aec->linoutlevel.framelevel.EndOfBlock()) {
657 aec->divergent_filter_fraction.AddObservation(aec->nearlevel, 690 aec->divergent_filter_fraction.AddObservation(aec->nearlevel,
658 aec->linoutlevel, 691 aec->linoutlevel,
659 aec->nlpoutlevel); 692 aec->nlpoutlevel);
660 } 693 }
661 694
662 if (aec->farlevel.averagelevel.EndOfBlock()) { 695 if (aec->farlevel.averagelevel.EndOfBlock()) {
663 if (aec->farlevel.minlevel < noisyPower) { 696 if (aec->farlevel.minlevel < noisyPower) {
664 actThreshold = actThresholdClean; 697 actThreshold = actThresholdClean;
665 } else { 698 } else {
666 actThreshold = actThresholdNoisy; 699 actThreshold = actThresholdNoisy;
667 } 700 }
668 701
669 const float far_average_level = aec->farlevel.averagelevel.GetLatestMean(); 702 const float far_average_level = aec->farlevel.averagelevel.GetLatestMean();
670 703
671 // The last condition is to let estimation be made in active far-end 704 // The last condition is to let estimation be made in active far-end
672 // segments only. 705 // segments only.
673 if ((aec->stateCounter > (0.5f * kCountLen * kSubCountLen)) && 706 if ((aec->stateCounter > (0.5f * kCountLen * kSubCountLen)) &&
674 (aec->farlevel.framelevel.EndOfBlock()) && 707 (aec->farlevel.framelevel.EndOfBlock()) &&
675 (far_average_level > (actThreshold * aec->farlevel.minlevel))) { 708 (far_average_level > (actThreshold * aec->farlevel.minlevel))) {
676 709
710 // ERL: error return loss.
677 const float near_average_level = 711 const float near_average_level =
678 aec->nearlevel.averagelevel.GetLatestMean(); 712 aec->nearlevel.averagelevel.GetLatestMean();
713 UpdateLogRatioMetric(&aec->erl, far_average_level, near_average_level);
679 714
680 // Subtract noise power 715 // A_NLP: error return loss enhanced before the nonlinear suppression.
681 echo = near_average_level - safety * aec->nearlevel.minlevel;
682
683 // ERL
684 dtmp = 10 * static_cast<float>(log10(far_average_level /
685 near_average_level + 1e-10f));
686
687 aec->erl.instant = dtmp;
688 if (dtmp > aec->erl.max) {
689 aec->erl.max = dtmp;
690 }
691
692 if (dtmp < aec->erl.min) {
693 aec->erl.min = dtmp;
694 }
695
696 aec->erl.counter++;
697 aec->erl.sum += dtmp;
698 aec->erl.average = aec->erl.sum / aec->erl.counter;
699
700 // Upper mean
701 if (dtmp > aec->erl.average) {
702 aec->erl.hicounter++;
703 aec->erl.hisum += dtmp;
704 aec->erl.himean = aec->erl.hisum / aec->erl.hicounter;
705 }
706
707 // A_NLP
708 const float linout_average_level = 716 const float linout_average_level =
709 aec->linoutlevel.averagelevel.GetLatestMean(); 717 aec->linoutlevel.averagelevel.GetLatestMean();
710 dtmp = 10 * static_cast<float>(log10(near_average_level / 718 UpdateLogRatioMetric(&aec->aNlp, near_average_level,
711 linout_average_level + 1e-10f)); 719 linout_average_level);
712 720
713 // subtract noise power 721 // ERLE: error return loss enhanced.
714 suppressedEcho =
715 linout_average_level - safety * aec->linoutlevel.minlevel;
716
717 aec->aNlp.instant =
718 10 * static_cast<float>(log10(echo / suppressedEcho + 1e-10f));
719
720 if (dtmp > aec->aNlp.max) {
721 aec->aNlp.max = dtmp;
722 }
723
724 if (dtmp < aec->aNlp.min) {
725 aec->aNlp.min = dtmp;
726 }
727
728 aec->aNlp.counter++;
729 aec->aNlp.sum += dtmp;
730 aec->aNlp.average = aec->aNlp.sum / aec->aNlp.counter;
731
732 // Upper mean
733 if (dtmp > aec->aNlp.average) {
734 aec->aNlp.hicounter++;
735 aec->aNlp.hisum += dtmp;
736 aec->aNlp.himean = aec->aNlp.hisum / aec->aNlp.hicounter;
737 }
738
739 // ERLE
740 const float nlpout_average_level = 722 const float nlpout_average_level =
741 aec->nlpoutlevel.averagelevel.GetLatestMean(); 723 aec->nlpoutlevel.averagelevel.GetLatestMean();
742 // subtract noise power 724 UpdateLogRatioMetric(&aec->erle, near_average_level,
743 suppressedEcho = 725 nlpout_average_level);
744 nlpout_average_level - safety * aec->nlpoutlevel.minlevel;
745 dtmp = 10 * static_cast<float>(log10(echo / suppressedEcho + 1e-10f));
746
747 aec->erle.instant = dtmp;
748 if (dtmp > aec->erle.max) {
749 aec->erle.max = dtmp;
750 }
751
752 if (dtmp < aec->erle.min) {
753 aec->erle.min = dtmp;
754 }
755
756 aec->erle.counter++;
757 aec->erle.sum += dtmp;
758 aec->erle.average = aec->erle.sum / aec->erle.counter;
759
760 // Upper mean
761 if (dtmp > aec->erle.average) {
762 aec->erle.hicounter++;
763 aec->erle.hisum += dtmp;
764 aec->erle.himean = aec->erle.hisum / aec->erle.hicounter;
765 }
766 } 726 }
767 727
768 aec->stateCounter = 0; 728 aec->stateCounter = 0;
769 } 729 }
770 } 730 }
771 731
772 static void UpdateDelayMetrics(AecCore* self) { 732 static void UpdateDelayMetrics(AecCore* self) {
773 int i = 0; 733 int i = 0;
774 int delay_values = 0; 734 int delay_values = 0;
775 int median = 0; 735 int median = 0;
(...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1944 1904
1945 int WebRtcAec_system_delay(AecCore* self) { 1905 int WebRtcAec_system_delay(AecCore* self) {
1946 return self->system_delay; 1906 return self->system_delay;
1947 } 1907 }
1948 1908
1949 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 1909 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
1950 assert(delay >= 0); 1910 assert(delay >= 0);
1951 self->system_delay = delay; 1911 self->system_delay = delay;
1952 } 1912 }
1953 } // namespace webrtc 1913 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698