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

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

Issue 1739993003: Adding fraction of filter divergence in AEC metrics. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: adding a header 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
« no previous file with comments | « no previous file | webrtc/modules/audio_processing/aec/aec_core_internal.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
11 /* 11 /*
12 * The core AEC algorithm, which is presented with time-aligned signals. 12 * The core AEC algorithm, which is presented with time-aligned signals.
13 */ 13 */
14 14
15 #include "webrtc/modules/audio_processing/aec/aec_core.h" 15 #include "webrtc/modules/audio_processing/aec/aec_core.h"
16 16
17 #ifdef WEBRTC_AEC_DEBUG_DUMP 17 #ifdef WEBRTC_AEC_DEBUG_DUMP
18 #include <stdio.h> 18 #include <stdio.h>
19 #endif 19 #endif
20 20
21 #include <algorithm>
21 #include <assert.h> 22 #include <assert.h>
22 #include <math.h> 23 #include <math.h>
23 #include <stddef.h> // size_t 24 #include <stddef.h> // size_t
24 #include <stdlib.h> 25 #include <stdlib.h>
25 #include <string.h> 26 #include <string.h>
26 27
27 extern "C" { 28 extern "C" {
28 #include "webrtc/common_audio/ring_buffer.h" 29 #include "webrtc/common_audio/ring_buffer.h"
29 } 30 }
30 #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"
(...skipping 12 matching lines...) Expand all
43 namespace webrtc { 44 namespace webrtc {
44 45
45 // Buffer size (samples) 46 // Buffer size (samples)
46 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz. 47 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz.
47 48
48 // Metrics 49 // Metrics
49 static const size_t kSubCountLen = 4; 50 static const size_t kSubCountLen = 4;
50 static const size_t kCountLen = 50; 51 static const size_t kCountLen = 50;
51 static const int kDelayMetricsAggregationWindow = 1250; // 5 seconds at 16 kHz. 52 static const int kDelayMetricsAggregationWindow = 1250; // 5 seconds at 16 kHz.
52 53
54 // Divergence metric is based on audio level, which gets updated every
55 // |kCountLen + 1| * 10 milliseconds. Divergence metric takes the statistics of
56 // |kDivergentFilterFractionAggregationWindowSize| samples. Current value
57 // corresponds to 0.5 seconds at 16 kHz.
58 static const int kDivergentFilterFractionAggregationWindowSize = 25;
59
53 // Quantities to control H band scaling for SWB input 60 // Quantities to control H band scaling for SWB input
54 static const float cnScaleHband = 0.4f; // scale for comfort noise in H band. 61 static const float cnScaleHband = 0.4f; // scale for comfort noise in H band.
55 // Initial bin for averaging nlp gain in low band 62 // Initial bin for averaging nlp gain in low band
56 static const int freqAvgIc = PART_LEN / 2; 63 static const int freqAvgIc = PART_LEN / 2;
57 64
58 // Matlab code to produce table: 65 // Matlab code to produce table:
59 // win = sqrt(hanning(63)); win = [0 ; win(1:32)]; 66 // win = sqrt(hanning(63)); win = [0 ; win(1:32)];
60 // fprintf(1, '\t%.14f, %.14f, %.14f,\n', win); 67 // fprintf(1, '\t%.14f, %.14f, %.14f,\n', win);
61 ALIGN16_BEG const float ALIGN16_END WebRtcAec_sqrtHanning[65] = { 68 ALIGN16_BEG const float ALIGN16_END WebRtcAec_sqrtHanning[65] = {
62 0.00000000000000f, 0.02454122852291f, 0.04906767432742f, 0.07356456359967f, 69 0.00000000000000f, 0.02454122852291f, 0.04906767432742f, 0.07356456359967f,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 WebRtcAecWindowData WebRtcAec_WindowData; 150 WebRtcAecWindowData WebRtcAec_WindowData;
144 151
145 __inline static float MulRe(float aRe, float aIm, float bRe, float bIm) { 152 __inline static float MulRe(float aRe, float aIm, float bRe, float bIm) {
146 return aRe * bRe - aIm * bIm; 153 return aRe * bRe - aIm * bIm;
147 } 154 }
148 155
149 __inline static float MulIm(float aRe, float aIm, float bRe, float bIm) { 156 __inline static float MulIm(float aRe, float aIm, float bRe, float bIm) {
150 return aRe * bIm + aIm * bRe; 157 return aRe * bIm + aIm * bRe;
151 } 158 }
152 159
160 // TODO(minyue): Due to a legacy bug, |framelevel| and |averagelevel| use a
161 // window, of which the length is 1 unit longer than indicated. Remove "+1" when
162 // the code is refactored.
153 PowerLevel::PowerLevel() 163 PowerLevel::PowerLevel()
154 // TODO(minyue): Due to a legacy bug, |framelevel| and |averagelevel| use a 164 : framelevel(kSubCountLen + 1),
155 // window, of which the length is 1 unit longer than indicated. Remove "+1" 165 averagelevel(kCountLen + 1) {
156 // when the code is refactored. 166 }
157 : framelevel(kSubCountLen + 1), 167
158 averagelevel(kCountLen + 1) { 168 DivergentFilterFraction::DivergentFilterFraction()
169 : count_(0),
170 occurrence_(0),
171 fraction_(-1.0) {
172 }
173
174 void DivergentFilterFraction::Reset() {
175 Clear();
176 fraction_ = -1.0;
177 }
178
179 void DivergentFilterFraction::AddObservation(const PowerLevel& nearlevel,
180 const PowerLevel& linoutlevel,
181 const PowerLevel& nlpoutlevel) {
182 const float near_level = nearlevel.framelevel.GetLatestMean();
183 const float level_increase =
184 linoutlevel.framelevel.GetLatestMean() - near_level;
185 const bool output_signal_active = nlpoutlevel.framelevel.GetLatestMean() >
186 40.0 * nlpoutlevel.minlevel;
187 // Level increase should be, in principle, negative, when the filter
188 // does not diverge. Here we allow some margin (0.01 * near end level) and
189 // numerical error (1.0). We count divergence only when the AEC output
190 // signal is active.
191 if (output_signal_active &&
192 level_increase > std::max(0.01 * near_level, 1.0))
193 occurrence_++;
194 ++count_;
195 if (count_ == kDivergentFilterFractionAggregationWindowSize) {
196 fraction_ = static_cast<float>(occurrence_) /
197 kDivergentFilterFractionAggregationWindowSize;
198 Clear();
199 }
200 }
201
202 float DivergentFilterFraction::GetLatestFraction() const {
203 return fraction_;
204 }
205
206 void DivergentFilterFraction::Clear() {
207 count_ = 0;
208 occurrence_ = 0;
159 } 209 }
160 210
161 // TODO(minyue): Moving some initialization from WebRtcAec_CreateAec() to ctor. 211 // TODO(minyue): Moving some initialization from WebRtcAec_CreateAec() to ctor.
162 AecCore::AecCore() = default; 212 AecCore::AecCore() = default;
163 213
164 static int CmpFloat(const void* a, const void* b) { 214 static int CmpFloat(const void* a, const void* b) {
165 const float* da = (const float*)a; 215 const float* da = (const float*)a;
166 const float* db = (const float*)b; 216 const float* db = (const float*)b;
167 217
168 return (*da > *db) - (*da < *db); 218 return (*da > *db) - (*da < *db);
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 self->stateCounter = 0; 605 self->stateCounter = 0;
556 InitLevel(&self->farlevel); 606 InitLevel(&self->farlevel);
557 InitLevel(&self->nearlevel); 607 InitLevel(&self->nearlevel);
558 InitLevel(&self->linoutlevel); 608 InitLevel(&self->linoutlevel);
559 InitLevel(&self->nlpoutlevel); 609 InitLevel(&self->nlpoutlevel);
560 610
561 InitStats(&self->erl); 611 InitStats(&self->erl);
562 InitStats(&self->erle); 612 InitStats(&self->erle);
563 InitStats(&self->aNlp); 613 InitStats(&self->aNlp);
564 InitStats(&self->rerl); 614 InitStats(&self->rerl);
615
616 self->divergent_filter_fraction.Reset();
565 } 617 }
566 618
567 static float CalculatePower(const float* in, size_t num_samples) { 619 static float CalculatePower(const float* in, size_t num_samples) {
568 size_t k; 620 size_t k;
569 float energy = 0.0f; 621 float energy = 0.0f;
570 622
571 for (k = 0; k < num_samples; ++k) { 623 for (k = 0; k < num_samples; ++k) {
572 energy += in[k] * in[k]; 624 energy += in[k] * in[k];
573 } 625 }
574 return energy / num_samples; 626 return energy / num_samples;
(...skipping 23 matching lines...) Expand all
598 650
599 const float noisyPower = 300000.0f; 651 const float noisyPower = 300000.0f;
600 652
601 float actThreshold; 653 float actThreshold;
602 float echo, suppressedEcho; 654 float echo, suppressedEcho;
603 655
604 if (aec->echoState) { // Check if echo is likely present 656 if (aec->echoState) { // Check if echo is likely present
605 aec->stateCounter++; 657 aec->stateCounter++;
606 } 658 }
607 659
660 if (aec->linoutlevel.framelevel.EndOfBlock()) {
661 aec->divergent_filter_fraction.AddObservation(aec->nearlevel,
662 aec->linoutlevel,
663 aec->nlpoutlevel);
664 }
665
608 if (aec->farlevel.averagelevel.EndOfBlock()) { 666 if (aec->farlevel.averagelevel.EndOfBlock()) {
609 if (aec->farlevel.minlevel < noisyPower) { 667 if (aec->farlevel.minlevel < noisyPower) {
610 actThreshold = actThresholdClean; 668 actThreshold = actThresholdClean;
611 } else { 669 } else {
612 actThreshold = actThresholdNoisy; 670 actThreshold = actThresholdNoisy;
613 } 671 }
614 672
615 const float far_average_level = aec->farlevel.averagelevel.GetLatestMean(); 673 const float far_average_level = aec->farlevel.averagelevel.GetLatestMean();
616 674
617 // The last condition is to let estimation be made in active far-end 675 // The last condition is to let estimation be made in active far-end
(...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 1950
1893 int WebRtcAec_system_delay(AecCore* self) { 1951 int WebRtcAec_system_delay(AecCore* self) {
1894 return self->system_delay; 1952 return self->system_delay;
1895 } 1953 }
1896 1954
1897 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 1955 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
1898 assert(delay >= 0); 1956 assert(delay >= 0);
1899 self->system_delay = delay; 1957 self->system_delay = delay;
1900 } 1958 }
1901 } // namespace webrtc 1959 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/audio_processing/aec/aec_core_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698