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

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

Issue 1805633006: Adding BlockMeanCalculator for AEC. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: use delete instead of free Created 4 years, 9 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 28 matching lines...) Expand all
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
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
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 18 matching lines...) Expand all
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 power) { 577 static void UpdateLevel(PowerLevel* level, float power) {
572 level->sfrsum += power; 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; 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 const float noisyPower = 300000.0f; 599 const float noisyPower = 300000.0f;
604 600
605 float actThreshold; 601 float actThreshold;
606 float echo, suppressedEcho; 602 float echo, suppressedEcho;
607 603
608 if (aec->echoState) { // Check if echo is likely present 604 if (aec->echoState) { // Check if echo is likely present
609 aec->stateCounter++; 605 aec->stateCounter++;
610 } 606 }
611 607
612 if (aec->farlevel.frcounter == 0) { 608 if (aec->farlevel.averagelevel.EndOfBlock()) {
613 if (aec->farlevel.minlevel < noisyPower) { 609 if (aec->farlevel.minlevel < noisyPower) {
614 actThreshold = actThresholdClean; 610 actThreshold = actThresholdClean;
615 } else { 611 } else {
616 actThreshold = actThresholdNoisy; 612 actThreshold = actThresholdNoisy;
617 } 613 }
618 614
619 if ((aec->stateCounter > (0.5f * countLen * subCountLen)) && 615 const float far_average_level = aec->farlevel.averagelevel.GetLatestMean();
620 (aec->farlevel.sfrcounter == 0)
621 616
622 // Estimate in active far-end segments only 617 // The last condition is to let estimation be made in active far-end
623 && (aec->farlevel.averagelevel > 618 // segments only.
624 (actThreshold * aec->farlevel.minlevel))) { 619 if ((aec->stateCounter > (0.5f * kCountLen * kSubCountLen)) &&
620 (aec->farlevel.framelevel.EndOfBlock()) &&
621 (far_average_level > (actThreshold * aec->farlevel.minlevel))) {
622
623 const float near_average_level =
624 aec->nearlevel.averagelevel.GetLatestMean();
625
625 // Subtract noise power 626 // Subtract noise power
626 echo = aec->nearlevel.averagelevel - safety * aec->nearlevel.minlevel; 627 echo = near_average_level - safety * aec->nearlevel.minlevel;
627 628
628 // ERL 629 // ERL
629 dtmp = 10 * static_cast<float>(log10(aec->farlevel.averagelevel / 630 dtmp = 10 * static_cast<float>(log10(far_average_level /
630 aec->nearlevel.averagelevel + 631 near_average_level + 1e-10f));
631 1e-10f)); 632 dtmp2 = 10 * static_cast<float>(log10(far_average_level / echo + 1e-10f));
632 dtmp2 = 10 * static_cast<float>(log10(aec->farlevel.averagelevel /
633 echo +
634 1e-10f));
635 633
636 aec->erl.instant = dtmp; 634 aec->erl.instant = dtmp;
637 if (dtmp > aec->erl.max) { 635 if (dtmp > aec->erl.max) {
638 aec->erl.max = dtmp; 636 aec->erl.max = dtmp;
639 } 637 }
640 638
641 if (dtmp < aec->erl.min) { 639 if (dtmp < aec->erl.min) {
642 aec->erl.min = dtmp; 640 aec->erl.min = dtmp;
643 } 641 }
644 642
645 aec->erl.counter++; 643 aec->erl.counter++;
646 aec->erl.sum += dtmp; 644 aec->erl.sum += dtmp;
647 aec->erl.average = aec->erl.sum / aec->erl.counter; 645 aec->erl.average = aec->erl.sum / aec->erl.counter;
648 646
649 // Upper mean 647 // Upper mean
650 if (dtmp > aec->erl.average) { 648 if (dtmp > aec->erl.average) {
651 aec->erl.hicounter++; 649 aec->erl.hicounter++;
652 aec->erl.hisum += dtmp; 650 aec->erl.hisum += dtmp;
653 aec->erl.himean = aec->erl.hisum / aec->erl.hicounter; 651 aec->erl.himean = aec->erl.hisum / aec->erl.hicounter;
654 } 652 }
655 653
656 // A_NLP 654 // A_NLP
657 dtmp = 10 * static_cast<float>(log10(aec->nearlevel.averagelevel / 655 const float linout_average_level =
658 aec->linoutlevel.averagelevel + 656 aec->linoutlevel.averagelevel.GetLatestMean();
659 1e-10f)); 657 dtmp = 10 * static_cast<float>(log10(near_average_level /
658 linout_average_level + 1e-10f));
660 659
661 // subtract noise power 660 // subtract noise power
662 suppressedEcho = aec->linoutlevel.averagelevel - 661 suppressedEcho =
663 safety * aec->linoutlevel.minlevel; 662 linout_average_level - safety * aec->linoutlevel.minlevel;
664 663
665 dtmp2 = 10 * static_cast<float>(log10(echo / suppressedEcho + 1e-10f)); 664 dtmp2 = 10 * static_cast<float>(log10(echo / suppressedEcho + 1e-10f));
666 665
667 aec->aNlp.instant = dtmp2; 666 aec->aNlp.instant = dtmp2;
668 if (dtmp > aec->aNlp.max) { 667 if (dtmp > aec->aNlp.max) {
669 aec->aNlp.max = dtmp; 668 aec->aNlp.max = dtmp;
670 } 669 }
671 670
672 if (dtmp < aec->aNlp.min) { 671 if (dtmp < aec->aNlp.min) {
673 aec->aNlp.min = dtmp; 672 aec->aNlp.min = dtmp;
674 } 673 }
675 674
676 aec->aNlp.counter++; 675 aec->aNlp.counter++;
677 aec->aNlp.sum += dtmp; 676 aec->aNlp.sum += dtmp;
678 aec->aNlp.average = aec->aNlp.sum / aec->aNlp.counter; 677 aec->aNlp.average = aec->aNlp.sum / aec->aNlp.counter;
679 678
680 // Upper mean 679 // Upper mean
681 if (dtmp > aec->aNlp.average) { 680 if (dtmp > aec->aNlp.average) {
682 aec->aNlp.hicounter++; 681 aec->aNlp.hicounter++;
683 aec->aNlp.hisum += dtmp; 682 aec->aNlp.hisum += dtmp;
684 aec->aNlp.himean = aec->aNlp.hisum / aec->aNlp.hicounter; 683 aec->aNlp.himean = aec->aNlp.hisum / aec->aNlp.hicounter;
685 } 684 }
686 685
687 // ERLE 686 // ERLE
687 const float nlpout_average_level =
688 aec->nlpoutlevel.averagelevel.GetLatestMean();
689 // subtract noise power
690 suppressedEcho =
691 nlpout_average_level - safety * aec->nlpoutlevel.minlevel;
688 692
689 // subtract noise power 693 dtmp = 10 * static_cast<float>(log10(near_average_level /
690 suppressedEcho = aec->nlpoutlevel.averagelevel - 694 nlpout_average_level + 1e-10f));
691 safety * aec->nlpoutlevel.minlevel;
692
693 dtmp = 10 * static_cast<float>(log10(aec->nearlevel.averagelevel /
694 aec->nlpoutlevel.averagelevel + 1e-10f));
695 dtmp2 = 10 * static_cast<float>(log10(echo / suppressedEcho + 1e-10f)); 695 dtmp2 = 10 * static_cast<float>(log10(echo / suppressedEcho + 1e-10f));
696 696
697 dtmp = dtmp2; 697 dtmp = dtmp2;
698 aec->erle.instant = dtmp; 698 aec->erle.instant = dtmp;
699 if (dtmp > aec->erle.max) { 699 if (dtmp > aec->erle.max) {
700 aec->erle.max = dtmp; 700 aec->erle.max = dtmp;
701 } 701 }
702 702
703 if (dtmp < aec->erle.min) { 703 if (dtmp < aec->erle.min) {
704 aec->erle.min = dtmp; 704 aec->erle.min = dtmp;
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after
1354 // For high bands 1354 // For high bands
1355 for (i = 0; i < aec->num_bands - 1; ++i) { 1355 for (i = 0; i < aec->num_bands - 1; ++i) {
1356 WebRtc_WriteBuffer(aec->outFrBufH[i], outputH[i], PART_LEN); 1356 WebRtc_WriteBuffer(aec->outFrBufH[i], outputH[i], PART_LEN);
1357 } 1357 }
1358 1358
1359 RTC_AEC_DEBUG_WAV_WRITE(aec->outFile, output, PART_LEN); 1359 RTC_AEC_DEBUG_WAV_WRITE(aec->outFile, output, PART_LEN);
1360 } 1360 }
1361 1361
1362 AecCore* WebRtcAec_CreateAec() { 1362 AecCore* WebRtcAec_CreateAec() {
1363 int i; 1363 int i;
1364 AecCore* aec = reinterpret_cast<AecCore*>(malloc(sizeof(AecCore))); 1364 AecCore* aec = new AecCore;
1365 if (!aec) { 1365 if (!aec) {
1366 return NULL; 1366 return NULL;
1367 } 1367 }
1368 1368
1369 aec->nearFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); 1369 aec->nearFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1370 if (!aec->nearFrBuf) { 1370 if (!aec->nearFrBuf) {
1371 WebRtcAec_FreeAec(aec); 1371 WebRtcAec_FreeAec(aec);
1372 return NULL; 1372 return NULL;
1373 } 1373 }
1374 1374
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1489 1489
1490 RTC_AEC_DEBUG_WAV_CLOSE(aec->farFile); 1490 RTC_AEC_DEBUG_WAV_CLOSE(aec->farFile);
1491 RTC_AEC_DEBUG_WAV_CLOSE(aec->nearFile); 1491 RTC_AEC_DEBUG_WAV_CLOSE(aec->nearFile);
1492 RTC_AEC_DEBUG_WAV_CLOSE(aec->outFile); 1492 RTC_AEC_DEBUG_WAV_CLOSE(aec->outFile);
1493 RTC_AEC_DEBUG_WAV_CLOSE(aec->outLinearFile); 1493 RTC_AEC_DEBUG_WAV_CLOSE(aec->outLinearFile);
1494 RTC_AEC_DEBUG_RAW_CLOSE(aec->e_fft_file); 1494 RTC_AEC_DEBUG_RAW_CLOSE(aec->e_fft_file);
1495 1495
1496 WebRtc_FreeDelayEstimator(aec->delay_estimator); 1496 WebRtc_FreeDelayEstimator(aec->delay_estimator);
1497 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); 1497 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend);
1498 1498
1499 free(aec); 1499 delete aec;
1500 } 1500 }
1501 1501
1502 int WebRtcAec_InitAec(AecCore* aec, int sampFreq) { 1502 int WebRtcAec_InitAec(AecCore* aec, int sampFreq) {
1503 int i; 1503 int i;
1504 1504
1505 aec->sampFreq = sampFreq; 1505 aec->sampFreq = sampFreq;
1506 1506
1507 if (sampFreq == 8000) { 1507 if (sampFreq == 8000) {
1508 aec->normal_mu = 0.6f; 1508 aec->normal_mu = 0.6f;
1509 aec->normal_error_threshold = 2e-6f; 1509 aec->normal_error_threshold = 2e-6f;
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 1892
1893 int WebRtcAec_system_delay(AecCore* self) { 1893 int WebRtcAec_system_delay(AecCore* self) {
1894 return self->system_delay; 1894 return self->system_delay;
1895 } 1895 }
1896 1896
1897 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 1897 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
1898 assert(delay >= 0); 1898 assert(delay >= 0);
1899 self->system_delay = delay; 1899 self->system_delay = delay;
1900 } 1900 }
1901 } // namespace webrtc 1901 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_processing/BUILD.gn ('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