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

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

Issue 1639283002: Clang format changes (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Merged with latest code from master Created 4 years, 10 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 16 matching lines...) Expand all
27 #include "webrtc/common_audio/ring_buffer.h" 27 #include "webrtc/common_audio/ring_buffer.h"
28 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h" 28 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h"
29 #include "webrtc/modules/audio_processing/aec/aec_common.h" 29 #include "webrtc/modules/audio_processing/aec/aec_common.h"
30 #include "webrtc/modules/audio_processing/aec/aec_core_internal.h" 30 #include "webrtc/modules/audio_processing/aec/aec_core_internal.h"
31 #include "webrtc/modules/audio_processing/aec/aec_rdft.h" 31 #include "webrtc/modules/audio_processing/aec/aec_rdft.h"
32 #include "webrtc/modules/audio_processing/logging/aec_logging.h" 32 #include "webrtc/modules/audio_processing/logging/aec_logging.h"
33 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h" 33 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h"
34 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" 34 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h"
35 #include "webrtc/typedefs.h" 35 #include "webrtc/typedefs.h"
36 36
37
38 // Buffer size (samples) 37 // Buffer size (samples)
39 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz. 38 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz.
40 39
41 // Metrics 40 // Metrics
42 static const int subCountLen = 4; 41 static const int subCountLen = 4;
43 static const int countLen = 50; 42 static const int countLen = 50;
44 static const int kDelayMetricsAggregationWindow = 1250; // 5 seconds at 16 kHz. 43 static const int kDelayMetricsAggregationWindow = 1250; // 5 seconds at 16 kHz.
45 44
46 // Quantities to control H band scaling for SWB input 45 // Quantities to control H band scaling for SWB input
47 static const float cnScaleHband = 46 static const float cnScaleHband =
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 112
114 // Two sets of parameters, one for the extended filter mode. 113 // Two sets of parameters, one for the extended filter mode.
115 static const float kExtendedMinOverDrive[3] = {3.0f, 6.0f, 15.0f}; 114 static const float kExtendedMinOverDrive[3] = {3.0f, 6.0f, 15.0f};
116 static const float kNormalMinOverDrive[3] = {1.0f, 2.0f, 5.0f}; 115 static const float kNormalMinOverDrive[3] = {1.0f, 2.0f, 5.0f};
117 const float WebRtcAec_kExtendedSmoothingCoefficients[2][2] = {{0.9f, 0.1f}, 116 const float WebRtcAec_kExtendedSmoothingCoefficients[2][2] = {{0.9f, 0.1f},
118 {0.92f, 0.08f}}; 117 {0.92f, 0.08f}};
119 const float WebRtcAec_kNormalSmoothingCoefficients[2][2] = {{0.9f, 0.1f}, 118 const float WebRtcAec_kNormalSmoothingCoefficients[2][2] = {{0.9f, 0.1f},
120 {0.93f, 0.07f}}; 119 {0.93f, 0.07f}};
121 120
122 // Number of partitions forming the NLP's "preferred" bands. 121 // Number of partitions forming the NLP's "preferred" bands.
123 enum { 122 enum { kPrefBandSize = 24 };
124 kPrefBandSize = 24
125 };
126 123
127 #ifdef WEBRTC_AEC_DEBUG_DUMP 124 #ifdef WEBRTC_AEC_DEBUG_DUMP
128 extern int webrtc_aec_instance_count; 125 extern int webrtc_aec_instance_count;
129 #endif 126 #endif
130 127
131 WebRtcAecFilterFar WebRtcAec_FilterFar; 128 WebRtcAecFilterFar WebRtcAec_FilterFar;
132 WebRtcAecScaleErrorSignal WebRtcAec_ScaleErrorSignal; 129 WebRtcAecScaleErrorSignal WebRtcAec_ScaleErrorSignal;
133 WebRtcAecFilterAdaptation WebRtcAec_FilterAdaptation; 130 WebRtcAecFilterAdaptation WebRtcAec_FilterAdaptation;
134 WebRtcAecOverdriveAndSuppress WebRtcAec_OverdriveAndSuppress; 131 WebRtcAecOverdriveAndSuppress WebRtcAec_OverdriveAndSuppress;
135 WebRtcAecComfortNoise WebRtcAec_ComfortNoise; 132 WebRtcAecComfortNoise WebRtcAec_ComfortNoise;
(...skipping 10 matching lines...) Expand all
146 return aRe * bIm + aIm * bRe; 143 return aRe * bIm + aIm * bRe;
147 } 144 }
148 145
149 static int CmpFloat(const void* a, const void* b) { 146 static int CmpFloat(const void* a, const void* b) {
150 const float* da = (const float*)a; 147 const float* da = (const float*)a;
151 const float* db = (const float*)b; 148 const float* db = (const float*)b;
152 149
153 return (*da > *db) - (*da < *db); 150 return (*da > *db) - (*da < *db);
154 } 151 }
155 152
156 static void FilterFar( 153 static void FilterFar(int num_partitions,
157 int num_partitions, 154 int x_fft_buf_block_pos,
158 int x_fft_buf_block_pos, 155 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
159 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], 156 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
160 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1], 157 float y_fft[2][PART_LEN1]) {
161 float y_fft[2][PART_LEN1]) {
162 int i; 158 int i;
163 for (i = 0; i < num_partitions; i++) { 159 for (i = 0; i < num_partitions; i++) {
164 int j; 160 int j;
165 int xPos = (i + x_fft_buf_block_pos) * PART_LEN1; 161 int xPos = (i + x_fft_buf_block_pos) * PART_LEN1;
166 int pos = i * PART_LEN1; 162 int pos = i * PART_LEN1;
167 // Check for wrap 163 // Check for wrap
168 if (i + x_fft_buf_block_pos >= num_partitions) { 164 if (i + x_fft_buf_block_pos >= num_partitions) {
169 xPos -= num_partitions * (PART_LEN1); 165 xPos -= num_partitions * (PART_LEN1);
170 } 166 }
171 167
172 for (j = 0; j < PART_LEN1; j++) { 168 for (j = 0; j < PART_LEN1; j++) {
173 y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j], 169 y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j],
174 x_fft_buf[1][xPos + j], 170 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]);
175 h_fft_buf[0][pos + j], 171 y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j],
176 h_fft_buf[1][pos + j]); 172 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]);
177 y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j],
178 x_fft_buf[1][xPos + j],
179 h_fft_buf[0][pos + j],
180 h_fft_buf[1][pos + j]);
181 } 173 }
182 } 174 }
183 } 175 }
184 176
185 static void ScaleErrorSignal(int extended_filter_enabled, 177 static void ScaleErrorSignal(int extended_filter_enabled,
186 float normal_mu, 178 float normal_mu,
187 float normal_error_threshold, 179 float normal_error_threshold,
188 float x_pow[PART_LEN1], 180 float x_pow[PART_LEN1],
189 float ef[2][PART_LEN1]) { 181 float ef[2][PART_LEN1]) {
190 const float mu = extended_filter_enabled ? kExtendedMu : normal_mu; 182 const float mu = extended_filter_enabled ? kExtendedMu : normal_mu;
(...skipping 12 matching lines...) Expand all
203 ef[0][i] *= abs_ef; 195 ef[0][i] *= abs_ef;
204 ef[1][i] *= abs_ef; 196 ef[1][i] *= abs_ef;
205 } 197 }
206 198
207 // Stepsize factor 199 // Stepsize factor
208 ef[0][i] *= mu; 200 ef[0][i] *= mu;
209 ef[1][i] *= mu; 201 ef[1][i] *= mu;
210 } 202 }
211 } 203 }
212 204
213
214 static void FilterAdaptation( 205 static void FilterAdaptation(
215 int num_partitions, 206 int num_partitions,
216 int x_fft_buf_block_pos, 207 int x_fft_buf_block_pos,
217 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], 208 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
218 float e_fft[2][PART_LEN1], 209 float e_fft[2][PART_LEN1],
219 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) { 210 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) {
220 int i, j; 211 int i, j;
221 float fft[PART_LEN2]; 212 float fft[PART_LEN2];
222 for (i = 0; i < num_partitions; i++) { 213 for (i = 0; i < num_partitions; i++) {
223 int xPos = (i + x_fft_buf_block_pos) * (PART_LEN1); 214 int xPos = (i + x_fft_buf_block_pos) * (PART_LEN1);
224 int pos; 215 int pos;
225 // Check for wrap 216 // Check for wrap
226 if (i + x_fft_buf_block_pos >= num_partitions) { 217 if (i + x_fft_buf_block_pos >= num_partitions) {
227 xPos -= num_partitions * PART_LEN1; 218 xPos -= num_partitions * PART_LEN1;
228 } 219 }
229 220
230 pos = i * PART_LEN1; 221 pos = i * PART_LEN1;
231 222
232 for (j = 0; j < PART_LEN; j++) { 223 for (j = 0; j < PART_LEN; j++) {
233 224 fft[2 * j] = MulRe(x_fft_buf[0][xPos + j], -x_fft_buf[1][xPos + j],
234 fft[2 * j] = MulRe(x_fft_buf[0][xPos + j], 225 e_fft[0][j], e_fft[1][j]);
235 -x_fft_buf[1][xPos + j], 226 fft[2 * j + 1] = MulIm(x_fft_buf[0][xPos + j], -x_fft_buf[1][xPos + j],
236 e_fft[0][j], 227 e_fft[0][j], e_fft[1][j]);
237 e_fft[1][j]);
238 fft[2 * j + 1] = MulIm(x_fft_buf[0][xPos + j],
239 -x_fft_buf[1][xPos + j],
240 e_fft[0][j],
241 e_fft[1][j]);
242 } 228 }
243 fft[1] = MulRe(x_fft_buf[0][xPos + PART_LEN], 229 fft[1] =
244 -x_fft_buf[1][xPos + PART_LEN], 230 MulRe(x_fft_buf[0][xPos + PART_LEN], -x_fft_buf[1][xPos + PART_LEN],
245 e_fft[0][PART_LEN], 231 e_fft[0][PART_LEN], e_fft[1][PART_LEN]);
246 e_fft[1][PART_LEN]);
247 232
248 aec_rdft_inverse_128(fft); 233 aec_rdft_inverse_128(fft);
249 memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN); 234 memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN);
250 235
251 // fft scaling 236 // fft scaling
252 { 237 {
253 float scale = 2.0f / PART_LEN2; 238 float scale = 2.0f / PART_LEN2;
254 for (j = 0; j < PART_LEN; j++) { 239 for (j = 0; j < PART_LEN; j++) {
255 fft[j] *= scale; 240 fft[j] *= scale;
256 } 241 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 float wfEnMax = 0; 283 float wfEnMax = 0;
299 int i; 284 int i;
300 int delay = 0; 285 int delay = 0;
301 286
302 for (i = 0; i < aec->num_partitions; i++) { 287 for (i = 0; i < aec->num_partitions; i++) {
303 int j; 288 int j;
304 int pos = i * PART_LEN1; 289 int pos = i * PART_LEN1;
305 float wfEn = 0; 290 float wfEn = 0;
306 for (j = 0; j < PART_LEN1; j++) { 291 for (j = 0; j < PART_LEN1; j++) {
307 wfEn += aec->wfBuf[0][pos + j] * aec->wfBuf[0][pos + j] + 292 wfEn += aec->wfBuf[0][pos + j] * aec->wfBuf[0][pos + j] +
308 aec->wfBuf[1][pos + j] * aec->wfBuf[1][pos + j]; 293 aec->wfBuf[1][pos + j] * aec->wfBuf[1][pos + j];
309 } 294 }
310 295
311 if (wfEn > wfEnMax) { 296 if (wfEn > wfEnMax) {
312 wfEnMax = wfEn; 297 wfEnMax = wfEn;
313 delay = i; 298 delay = i;
314 } 299 }
315 } 300 }
316 return delay; 301 return delay;
317 } 302 }
318 303
319 // Threshold to protect against the ill-effects of a zero far-end. 304 // Threshold to protect against the ill-effects of a zero far-end.
320 const float WebRtcAec_kMinFarendPSD = 15; 305 const float WebRtcAec_kMinFarendPSD = 15;
321 306
322 // Updates the following smoothed Power Spectral Densities (PSD): 307 // Updates the following smoothed Power Spectral Densities (PSD):
323 // - sd : near-end 308 // - sd : near-end
324 // - se : residual echo 309 // - se : residual echo
325 // - sx : far-end 310 // - sx : far-end
326 // - sde : cross-PSD of near-end and residual echo 311 // - sde : cross-PSD of near-end and residual echo
327 // - sxd : cross-PSD of near-end and far-end 312 // - sxd : cross-PSD of near-end and far-end
328 // 313 //
329 // In addition to updating the PSDs, also the filter diverge state is 314 // In addition to updating the PSDs, also the filter diverge state is
330 // determined. 315 // determined.
331 static void SmoothedPSD(AecCore* aec, 316 static void SmoothedPSD(AecCore* aec,
332 float efw[2][PART_LEN1], 317 float efw[2][PART_LEN1],
333 float dfw[2][PART_LEN1], 318 float dfw[2][PART_LEN1],
334 float xfw[2][PART_LEN1], 319 float xfw[2][PART_LEN1],
335 int* extreme_filter_divergence) { 320 int* extreme_filter_divergence) {
336 // Power estimate smoothing coefficients. 321 // Power estimate smoothing coefficients.
337 const float* ptrGCoh = aec->extended_filter_enabled 322 const float* ptrGCoh =
338 ? WebRtcAec_kExtendedSmoothingCoefficients[aec->mult - 1] 323 aec->extended_filter_enabled
339 : WebRtcAec_kNormalSmoothingCoefficients[aec->mult - 1]; 324 ? WebRtcAec_kExtendedSmoothingCoefficients[aec->mult - 1]
325 : WebRtcAec_kNormalSmoothingCoefficients[aec->mult - 1];
340 int i; 326 int i;
341 float sdSum = 0, seSum = 0; 327 float sdSum = 0, seSum = 0;
342 328
343 for (i = 0; i < PART_LEN1; i++) { 329 for (i = 0; i < PART_LEN1; i++) {
344 aec->sd[i] = ptrGCoh[0] * aec->sd[i] + 330 aec->sd[i] = ptrGCoh[0] * aec->sd[i] +
345 ptrGCoh[1] * (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]); 331 ptrGCoh[1] * (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]);
346 aec->se[i] = ptrGCoh[0] * aec->se[i] + 332 aec->se[i] = ptrGCoh[0] * aec->se[i] +
347 ptrGCoh[1] * (efw[0][i] * efw[0][i] + efw[1][i] * efw[1][i]); 333 ptrGCoh[1] * (efw[0][i] * efw[0][i] + efw[1][i] * efw[1][i]);
348 // We threshold here to protect against the ill-effects of a zero farend. 334 // We threshold here to protect against the ill-effects of a zero farend.
349 // The threshold is not arbitrarily chosen, but balances protection and 335 // The threshold is not arbitrarily chosen, but balances protection and
350 // adverse interaction with the algorithm's tuning. 336 // adverse interaction with the algorithm's tuning.
351 // TODO(bjornv): investigate further why this is so sensitive. 337 // TODO(bjornv): investigate further why this is so sensitive.
352 aec->sx[i] = 338 aec->sx[i] = ptrGCoh[0] * aec->sx[i] +
353 ptrGCoh[0] * aec->sx[i] + 339 ptrGCoh[1] * WEBRTC_SPL_MAX(
354 ptrGCoh[1] * WEBRTC_SPL_MAX( 340 xfw[0][i] * xfw[0][i] + xfw[1][i] * xfw[1][i],
355 xfw[0][i] * xfw[0][i] + xfw[1][i] * xfw[1][i], 341 WebRtcAec_kMinFarendPSD);
356 WebRtcAec_kMinFarendPSD);
357 342
358 aec->sde[i][0] = 343 aec->sde[i][0] =
359 ptrGCoh[0] * aec->sde[i][0] + 344 ptrGCoh[0] * aec->sde[i][0] +
360 ptrGCoh[1] * (dfw[0][i] * efw[0][i] + dfw[1][i] * efw[1][i]); 345 ptrGCoh[1] * (dfw[0][i] * efw[0][i] + dfw[1][i] * efw[1][i]);
361 aec->sde[i][1] = 346 aec->sde[i][1] =
362 ptrGCoh[0] * aec->sde[i][1] + 347 ptrGCoh[0] * aec->sde[i][1] +
363 ptrGCoh[1] * (dfw[0][i] * efw[1][i] - dfw[1][i] * efw[0][i]); 348 ptrGCoh[1] * (dfw[0][i] * efw[1][i] - dfw[1][i] * efw[0][i]);
364 349
365 aec->sxd[i][0] = 350 aec->sxd[i][0] =
366 ptrGCoh[0] * aec->sxd[i][0] + 351 ptrGCoh[0] * aec->sxd[i][0] +
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 efw[0][i] += tmp * u[0][i]; 461 efw[0][i] += tmp * u[0][i];
477 efw[1][i] += tmp * u[1][i]; 462 efw[1][i] += tmp * u[1][i];
478 } 463 }
479 464
480 // For H band comfort noise 465 // For H band comfort noise
481 // TODO: don't compute noise and "tmp" twice. Use the previous results. 466 // TODO: don't compute noise and "tmp" twice. Use the previous results.
482 noiseAvg = 0.0; 467 noiseAvg = 0.0;
483 tmpAvg = 0.0; 468 tmpAvg = 0.0;
484 num = 0; 469 num = 0;
485 if (aec->num_bands > 1) { 470 if (aec->num_bands > 1) {
486
487 // average noise scale 471 // average noise scale
488 // average over second half of freq spectrum (i.e., 4->8khz) 472 // average over second half of freq spectrum (i.e., 4->8khz)
489 // TODO: we shouldn't need num. We know how many elements we're summing. 473 // TODO: we shouldn't need num. We know how many elements we're summing.
490 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { 474 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) {
491 num++; 475 num++;
492 noiseAvg += sqrtf(noisePow[i]); 476 noiseAvg += sqrtf(noisePow[i]);
493 } 477 }
494 noiseAvg /= (float)num; 478 noiseAvg /= (float)num;
495 479
496 // average nlp scale 480 // average nlp scale
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 const float noisyPower = 300000.0f * 2.0f / PART_LEN2; 598 const float noisyPower = 300000.0f * 2.0f / PART_LEN2;
615 599
616 float actThreshold; 600 float actThreshold;
617 float echo, suppressedEcho; 601 float echo, suppressedEcho;
618 602
619 if (aec->echoState) { // Check if echo is likely present 603 if (aec->echoState) { // Check if echo is likely present
620 aec->stateCounter++; 604 aec->stateCounter++;
621 } 605 }
622 606
623 if (aec->farlevel.frcounter == 0) { 607 if (aec->farlevel.frcounter == 0) {
624
625 if (aec->farlevel.minlevel < noisyPower) { 608 if (aec->farlevel.minlevel < noisyPower) {
626 actThreshold = actThresholdClean; 609 actThreshold = actThresholdClean;
627 } else { 610 } else {
628 actThreshold = actThresholdNoisy; 611 actThreshold = actThresholdNoisy;
629 } 612 }
630 613
631 if ((aec->stateCounter > (0.5f * countLen * subCountLen)) && 614 if ((aec->stateCounter > (0.5f * countLen * subCountLen)) &&
632 (aec->farlevel.sfrcounter == 0) 615 (aec->farlevel.sfrcounter == 0)
633 616
634 // Estimate in active far-end segments only 617 // Estimate in active far-end segments only
635 && 618 && (aec->farlevel.averagelevel >
636 (aec->farlevel.averagelevel > 619 (actThreshold * aec->farlevel.minlevel))) {
637 (actThreshold * aec->farlevel.minlevel))) {
638
639 // Subtract noise power 620 // Subtract noise power
640 echo = aec->nearlevel.averagelevel - safety * aec->nearlevel.minlevel; 621 echo = aec->nearlevel.averagelevel - safety * aec->nearlevel.minlevel;
641 622
642 // ERL 623 // ERL
643 dtmp = 10 * (float)log10(aec->farlevel.averagelevel / 624 dtmp = 10 * (float)log10(aec->farlevel.averagelevel /
644 aec->nearlevel.averagelevel + 625 aec->nearlevel.averagelevel +
645 1e-10f); 626 1e-10f);
646 dtmp2 = 10 * (float)log10(aec->farlevel.averagelevel / echo + 1e-10f); 627 dtmp2 = 10 * (float)log10(aec->farlevel.averagelevel / echo + 1e-10f);
647 628
648 aec->erl.instant = dtmp; 629 aec->erl.instant = dtmp;
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 break; 743 break;
763 } 744 }
764 } 745 }
765 // Account for lookahead. 746 // Account for lookahead.
766 self->delay_median = (median - lookahead) * kMsPerBlock; 747 self->delay_median = (median - lookahead) * kMsPerBlock;
767 748
768 // Calculate the L1 norm, with median value as central moment. 749 // Calculate the L1 norm, with median value as central moment.
769 for (i = 0; i < kHistorySizeBlocks; i++) { 750 for (i = 0; i < kHistorySizeBlocks; i++) {
770 l1_norm += abs(i - median) * self->delay_histogram[i]; 751 l1_norm += abs(i - median) * self->delay_histogram[i];
771 } 752 }
772 self->delay_std = (int)((l1_norm + self->num_delay_values / 2) / 753 self->delay_std =
773 self->num_delay_values) * kMsPerBlock; 754 (int)((l1_norm + self->num_delay_values / 2) / self->num_delay_values) *
755 kMsPerBlock;
774 756
775 // Determine fraction of delays that are out of bounds, that is, either 757 // Determine fraction of delays that are out of bounds, that is, either
776 // negative (anti-causal system) or larger than the AEC filter length. 758 // negative (anti-causal system) or larger than the AEC filter length.
777 { 759 {
778 int num_delays_out_of_bounds = self->num_delay_values; 760 int num_delays_out_of_bounds = self->num_delay_values;
779 const int histogram_length = sizeof(self->delay_histogram) / 761 const int histogram_length =
780 sizeof(self->delay_histogram[0]); 762 sizeof(self->delay_histogram) / sizeof(self->delay_histogram[0]);
781 for (i = lookahead; i < lookahead + self->num_partitions; ++i) { 763 for (i = lookahead; i < lookahead + self->num_partitions; ++i) {
782 if (i < histogram_length) 764 if (i < histogram_length)
783 num_delays_out_of_bounds -= self->delay_histogram[i]; 765 num_delays_out_of_bounds -= self->delay_histogram[i];
784 } 766 }
785 self->fraction_poor_delays = (float)num_delays_out_of_bounds / 767 self->fraction_poor_delays =
786 self->num_delay_values; 768 (float)num_delays_out_of_bounds / self->num_delay_values;
787 } 769 }
788 770
789 // Reset histogram. 771 // Reset histogram.
790 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); 772 memset(self->delay_histogram, 0, sizeof(self->delay_histogram));
791 self->num_delay_values = 0; 773 self->num_delay_values = 0;
792 774
793 return; 775 return;
794 } 776 }
795 777
796 static void ScaledInverseFft(float freq_data[2][PART_LEN1], 778 static void ScaledInverseFft(float freq_data[2][PART_LEN1],
797 float time_data[PART_LEN2], 779 float time_data[PART_LEN2],
798 float scale, 780 float scale,
799 int conjugate) { 781 int conjugate) {
800 int i; 782 int i;
801 const float normalization = scale / ((float)PART_LEN2); 783 const float normalization = scale / ((float)PART_LEN2);
802 const float sign = (conjugate ? -1 : 1); 784 const float sign = (conjugate ? -1 : 1);
803 time_data[0] = freq_data[0][0] * normalization; 785 time_data[0] = freq_data[0][0] * normalization;
804 time_data[1] = freq_data[0][PART_LEN] * normalization; 786 time_data[1] = freq_data[0][PART_LEN] * normalization;
805 for (i = 1; i < PART_LEN; i++) { 787 for (i = 1; i < PART_LEN; i++) {
806 time_data[2 * i] = freq_data[0][i] * normalization; 788 time_data[2 * i] = freq_data[0][i] * normalization;
807 time_data[2 * i + 1] = sign * freq_data[1][i] * normalization; 789 time_data[2 * i + 1] = sign * freq_data[1][i] * normalization;
808 } 790 }
809 aec_rdft_inverse_128(time_data); 791 aec_rdft_inverse_128(time_data);
810 } 792 }
811 793
812 794 static void Fft(float time_data[PART_LEN2], float freq_data[2][PART_LEN1]) {
813 static void Fft(float time_data[PART_LEN2],
814 float freq_data[2][PART_LEN1]) {
815 int i; 795 int i;
816 aec_rdft_forward_128(time_data); 796 aec_rdft_forward_128(time_data);
817 797
818 // Reorder fft output data. 798 // Reorder fft output data.
819 freq_data[1][0] = 0; 799 freq_data[1][0] = 0;
820 freq_data[1][PART_LEN] = 0; 800 freq_data[1][PART_LEN] = 0;
821 freq_data[0][0] = time_data[0]; 801 freq_data[0][0] = time_data[0];
822 freq_data[0][PART_LEN] = time_data[1]; 802 freq_data[0][PART_LEN] = time_data[1];
823 for (i = 1; i < PART_LEN; i++) { 803 for (i = 1; i < PART_LEN; i++) {
824 freq_data[0][i] = time_data[2 * i]; 804 freq_data[0][i] = time_data[2 * i];
(...skipping 20 matching lines...) Expand all
845 // negative |last_delay| is an invalid one. 825 // negative |last_delay| is an invalid one.
846 // 2. Verify that there is a delay change. In addition, only allow a change 826 // 2. Verify that there is a delay change. In addition, only allow a change
847 // if the delay is outside a certain region taking the AEC filter length 827 // if the delay is outside a certain region taking the AEC filter length
848 // into account. 828 // into account.
849 // TODO(bjornv): Investigate if we can remove the non-zero delay change check. 829 // TODO(bjornv): Investigate if we can remove the non-zero delay change check.
850 // 3. Only allow delay correction if the delay estimation quality exceeds 830 // 3. Only allow delay correction if the delay estimation quality exceeds
851 // |delay_quality_threshold|. 831 // |delay_quality_threshold|.
852 // 4. Finally, verify that the proposed |delay_correction| is feasible by 832 // 4. Finally, verify that the proposed |delay_correction| is feasible by
853 // comparing with the size of the far-end buffer. 833 // comparing with the size of the far-end buffer.
854 last_delay = WebRtc_last_delay(self->delay_estimator); 834 last_delay = WebRtc_last_delay(self->delay_estimator);
855 if ((last_delay >= 0) && 835 if ((last_delay >= 0) && (last_delay != self->previous_delay) &&
856 (last_delay != self->previous_delay) &&
857 (WebRtc_last_delay_quality(self->delay_estimator) > 836 (WebRtc_last_delay_quality(self->delay_estimator) >
858 self->delay_quality_threshold)) { 837 self->delay_quality_threshold)) {
859 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); 838 int delay = last_delay - WebRtc_lookahead(self->delay_estimator);
860 // Allow for a slack in the actual delay, defined by a |lower_bound| and an 839 // Allow for a slack in the actual delay, defined by a |lower_bound| and an
861 // |upper_bound|. The adaptive echo cancellation filter is currently 840 // |upper_bound|. The adaptive echo cancellation filter is currently
862 // |num_partitions| (of 64 samples) long. If the delay estimate is negative 841 // |num_partitions| (of 64 samples) long. If the delay estimate is negative
863 // or at least 3/4 of the filter length we open up for correction. 842 // or at least 3/4 of the filter length we open up for correction.
864 const int lower_bound = 0; 843 const int lower_bound = 0;
865 const int upper_bound = self->num_partitions * 3 / 4; 844 const int upper_bound = self->num_partitions * 3 / 4;
866 const int do_correction = delay <= lower_bound || delay > upper_bound; 845 const int do_correction = delay <= lower_bound || delay > upper_bound;
867 if (do_correction == 1) { 846 if (do_correction == 1) {
868 int available_read = (int)WebRtc_available_read(self->far_time_buf); 847 int available_read = (int)WebRtc_available_read(self->far_time_buf);
(...skipping 13 matching lines...) Expand all
882 } else { 861 } else {
883 self->previous_delay = last_delay; 862 self->previous_delay = last_delay;
884 ++self->delay_correction_count; 863 ++self->delay_correction_count;
885 } 864 }
886 } 865 }
887 } 866 }
888 // Update the |delay_quality_threshold| once we have our first delay 867 // Update the |delay_quality_threshold| once we have our first delay
889 // correction. 868 // correction.
890 if (self->delay_correction_count > 0) { 869 if (self->delay_correction_count > 0) {
891 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); 870 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator);
892 delay_quality = (delay_quality > kDelayQualityThresholdMax ? 871 delay_quality =
893 kDelayQualityThresholdMax : delay_quality); 872 (delay_quality > kDelayQualityThresholdMax ? kDelayQualityThresholdMax
873 : delay_quality);
894 self->delay_quality_threshold = 874 self->delay_quality_threshold =
895 (delay_quality > self->delay_quality_threshold ? delay_quality : 875 (delay_quality > self->delay_quality_threshold
896 self->delay_quality_threshold); 876 ? delay_quality
877 : self->delay_quality_threshold);
897 } 878 }
898 return delay_correction; 879 return delay_correction;
899 } 880 }
900 881
901 static void EchoSubtraction( 882 static void EchoSubtraction(AecCore* aec,
902 AecCore* aec, 883 int num_partitions,
903 int num_partitions, 884 int x_fft_buf_block_pos,
904 int x_fft_buf_block_pos, 885 int extended_filter_enabled,
905 int extended_filter_enabled, 886 float normal_mu,
906 float normal_mu, 887 float normal_error_threshold,
907 float normal_error_threshold, 888 float x_fft_buf[2]
908 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], 889 [kExtendedNumPartitions * PART_LEN1],
909 float* const y, 890 float* const y,
910 float x_pow[PART_LEN1], 891 float x_pow[PART_LEN1],
911 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1], 892 float h_fft_buf[2]
912 float echo_subtractor_output[PART_LEN]) { 893 [kExtendedNumPartitions * PART_LEN1],
894 float echo_subtractor_output[PART_LEN]) {
913 float s_fft[2][PART_LEN1]; 895 float s_fft[2][PART_LEN1];
914 float e_extended[PART_LEN2]; 896 float e_extended[PART_LEN2];
915 float s_extended[PART_LEN2]; 897 float s_extended[PART_LEN2];
916 float *s; 898 float* s;
917 float e[PART_LEN]; 899 float e[PART_LEN];
918 float e_fft[2][PART_LEN1]; 900 float e_fft[2][PART_LEN1];
919 int i; 901 int i;
920 memset(s_fft, 0, sizeof(s_fft)); 902 memset(s_fft, 0, sizeof(s_fft));
921 903
922 // Conditionally reset the echo subtraction filter if the filter has diverged 904 // Conditionally reset the echo subtraction filter if the filter has diverged
923 // significantly. 905 // significantly.
924 if (!aec->extended_filter_enabled && 906 if (!aec->extended_filter_enabled && aec->extreme_filter_divergence) {
925 aec->extreme_filter_divergence) {
926 memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); 907 memset(aec->wfBuf, 0, sizeof(aec->wfBuf));
927 aec->extreme_filter_divergence = 0; 908 aec->extreme_filter_divergence = 0;
928 } 909 }
929 910
930 // Produce echo estimate s_fft. 911 // Produce echo estimate s_fft.
931 WebRtcAec_FilterFar(num_partitions, 912 WebRtcAec_FilterFar(num_partitions, x_fft_buf_block_pos, x_fft_buf, h_fft_buf,
932 x_fft_buf_block_pos,
933 x_fft_buf,
934 h_fft_buf,
935 s_fft); 913 s_fft);
936 914
937 // Compute the time-domain echo estimate s. 915 // Compute the time-domain echo estimate s.
938 ScaledInverseFft(s_fft, s_extended, 2.0f, 0); 916 ScaledInverseFft(s_fft, s_extended, 2.0f, 0);
939 s = &s_extended[PART_LEN]; 917 s = &s_extended[PART_LEN];
940 918
941 // Compute the time-domain echo prediction error. 919 // Compute the time-domain echo prediction error.
942 for (i = 0; i < PART_LEN; ++i) { 920 for (i = 0; i < PART_LEN; ++i) {
943 e[i] = y[i] - s[i]; 921 e[i] = y[i] - s[i];
944 } 922 }
945 923
946 // Compute the frequency domain echo prediction error. 924 // Compute the frequency domain echo prediction error.
947 memset(e_extended, 0, sizeof(float) * PART_LEN); 925 memset(e_extended, 0, sizeof(float) * PART_LEN);
948 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); 926 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN);
949 Fft(e_extended, e_fft); 927 Fft(e_extended, e_fft);
950 928
951 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, 929 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, &e_fft[0][0],
952 &e_fft[0][0],
953 sizeof(e_fft[0][0]) * PART_LEN1 * 2); 930 sizeof(e_fft[0][0]) * PART_LEN1 * 2);
954 931
955 // Scale error signal inversely with far power. 932 // Scale error signal inversely with far power.
956 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, 933 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, normal_mu,
957 normal_mu, 934 normal_error_threshold, x_pow, e_fft);
958 normal_error_threshold, 935 WebRtcAec_FilterAdaptation(num_partitions, x_fft_buf_block_pos, x_fft_buf,
959 x_pow, 936 e_fft, h_fft_buf);
960 e_fft);
961 WebRtcAec_FilterAdaptation(num_partitions,
962 x_fft_buf_block_pos,
963 x_fft_buf,
964 e_fft,
965 h_fft_buf);
966 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); 937 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN);
967 } 938 }
968 939
969 static void EchoSuppression(AecCore* aec, 940 static void EchoSuppression(AecCore* aec,
970 float farend[PART_LEN2], 941 float farend[PART_LEN2],
971 float* echo_subtractor_output, 942 float* echo_subtractor_output,
972 float* output, 943 float* output,
973 float* const* outputH) { 944 float* const* outputH) {
974 float efw[2][PART_LEN1]; 945 float efw[2][PART_LEN1];
975 float xfw[2][PART_LEN1]; 946 float xfw[2][PART_LEN1];
(...skipping 17 matching lines...) Expand all
993 const float* min_overdrive = aec->extended_filter_enabled 964 const float* min_overdrive = aec->extended_filter_enabled
994 ? kExtendedMinOverDrive 965 ? kExtendedMinOverDrive
995 : kNormalMinOverDrive; 966 : kNormalMinOverDrive;
996 967
997 // Filter energy 968 // Filter energy
998 const int delayEstInterval = 10 * aec->mult; 969 const int delayEstInterval = 10 * aec->mult;
999 970
1000 float* xfw_ptr = NULL; 971 float* xfw_ptr = NULL;
1001 972
1002 // Update eBuf with echo subtractor output. 973 // Update eBuf with echo subtractor output.
1003 memcpy(aec->eBuf + PART_LEN, 974 memcpy(aec->eBuf + PART_LEN, echo_subtractor_output,
1004 echo_subtractor_output,
1005 sizeof(float) * PART_LEN); 975 sizeof(float) * PART_LEN);
1006 976
1007 // Analysis filter banks for the echo suppressor. 977 // Analysis filter banks for the echo suppressor.
1008 // Windowed near-end ffts. 978 // Windowed near-end ffts.
1009 WindowData(fft, aec->dBuf); 979 WindowData(fft, aec->dBuf);
1010 aec_rdft_forward_128(fft); 980 aec_rdft_forward_128(fft);
1011 StoreAsComplex(fft, dfw); 981 StoreAsComplex(fft, dfw);
1012 982
1013 // Windowed echo suppressor output ffts. 983 // Windowed echo suppressor output ffts.
1014 WindowData(fft, aec->eBuf); 984 WindowData(fft, aec->eBuf);
(...skipping 10 matching lines...) Expand all
1025 // Buffer far. 995 // Buffer far.
1026 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); 996 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1);
1027 997
1028 aec->delayEstCtr++; 998 aec->delayEstCtr++;
1029 if (aec->delayEstCtr == delayEstInterval) { 999 if (aec->delayEstCtr == delayEstInterval) {
1030 aec->delayEstCtr = 0; 1000 aec->delayEstCtr = 0;
1031 aec->delayIdx = WebRtcAec_PartitionDelay(aec); 1001 aec->delayIdx = WebRtcAec_PartitionDelay(aec);
1032 } 1002 }
1033 1003
1034 // Use delayed far. 1004 // Use delayed far.
1035 memcpy(xfw, 1005 memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1,
1036 aec->xfwBuf + aec->delayIdx * PART_LEN1,
1037 sizeof(xfw[0][0]) * 2 * PART_LEN1); 1006 sizeof(xfw[0][0]) * 2 * PART_LEN1);
1038 1007
1039 WebRtcAec_SubbandCoherence(aec, efw, dfw, xfw, fft, cohde, cohxd, 1008 WebRtcAec_SubbandCoherence(aec, efw, dfw, xfw, fft, cohde, cohxd,
1040 &aec->extreme_filter_divergence); 1009 &aec->extreme_filter_divergence);
1041 1010
1042 // Select the microphone signal as output if the filter is deemed to have 1011 // Select the microphone signal as output if the filter is deemed to have
1043 // diverged. 1012 // diverged.
1044 if (aec->divergeState) { 1013 if (aec->divergeState) {
1045 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); 1014 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1);
1046 } 1015 }
(...skipping 30 matching lines...) Expand all
1077 hNlFb = hNlDeAvg; 1046 hNlFb = hNlDeAvg;
1078 hNlFbLow = hNlDeAvg; 1047 hNlFbLow = hNlDeAvg;
1079 } else { 1048 } else {
1080 for (i = 0; i < PART_LEN1; i++) { 1049 for (i = 0; i < PART_LEN1; i++) {
1081 hNl[i] = 1 - cohxd[i]; 1050 hNl[i] = 1 - cohxd[i];
1082 } 1051 }
1083 hNlFb = hNlXdAvg; 1052 hNlFb = hNlXdAvg;
1084 hNlFbLow = hNlXdAvg; 1053 hNlFbLow = hNlXdAvg;
1085 } 1054 }
1086 } else { 1055 } else {
1087
1088 if (aec->stNearState == 1) { 1056 if (aec->stNearState == 1) {
1089 aec->echoState = 0; 1057 aec->echoState = 0;
1090 memcpy(hNl, cohde, sizeof(hNl)); 1058 memcpy(hNl, cohde, sizeof(hNl));
1091 hNlFb = hNlDeAvg; 1059 hNlFb = hNlDeAvg;
1092 hNlFbLow = hNlDeAvg; 1060 hNlFbLow = hNlDeAvg;
1093 } else { 1061 } else {
1094 aec->echoState = 1; 1062 aec->echoState = 1;
1095 for (i = 0; i < PART_LEN1; i++) { 1063 for (i = 0; i < PART_LEN1; i++) {
1096 hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]); 1064 hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]);
1097 } 1065 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 // scaling only in UpdateMetrics(). 1120 // scaling only in UpdateMetrics().
1153 UpdateLevel(&aec->nlpoutlevel, CalculatePower(fft, PART_LEN2)); 1121 UpdateLevel(&aec->nlpoutlevel, CalculatePower(fft, PART_LEN2));
1154 } 1122 }
1155 1123
1156 // Overlap and add to obtain output. 1124 // Overlap and add to obtain output.
1157 for (i = 0; i < PART_LEN; i++) { 1125 for (i = 0; i < PART_LEN; i++) {
1158 output[i] = (fft[i] * WebRtcAec_sqrtHanning[i] + 1126 output[i] = (fft[i] * WebRtcAec_sqrtHanning[i] +
1159 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]); 1127 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]);
1160 1128
1161 // Saturate output to keep it in the allowed range. 1129 // Saturate output to keep it in the allowed range.
1162 output[i] = WEBRTC_SPL_SAT( 1130 output[i] =
1163 WEBRTC_SPL_WORD16_MAX, output[i], WEBRTC_SPL_WORD16_MIN); 1131 WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, output[i], WEBRTC_SPL_WORD16_MIN);
1164 } 1132 }
1165 memcpy(aec->outBuf, &fft[PART_LEN], PART_LEN * sizeof(aec->outBuf[0])); 1133 memcpy(aec->outBuf, &fft[PART_LEN], PART_LEN * sizeof(aec->outBuf[0]));
1166 1134
1167 // For H band 1135 // For H band
1168 if (aec->num_bands > 1) { 1136 if (aec->num_bands > 1) {
1169 // H band gain 1137 // H band gain
1170 // average nlp over low band: average over second half of freq spectrum 1138 // average nlp over low band: average over second half of freq spectrum
1171 // (4->8khz) 1139 // (4->8khz)
1172 GetHighbandGain(hNl, &nlpGainHband); 1140 GetHighbandGain(hNl, &nlpGainHband);
1173 1141
1174 // Inverse comfort_noise 1142 // Inverse comfort_noise
1175 ScaledInverseFft(comfortNoiseHband, fft, 2.0f, 0); 1143 ScaledInverseFft(comfortNoiseHband, fft, 2.0f, 0);
1176 1144
1177 // compute gain factor 1145 // compute gain factor
1178 for (j = 0; j < aec->num_bands - 1; ++j) { 1146 for (j = 0; j < aec->num_bands - 1; ++j) {
1179 for (i = 0; i < PART_LEN; i++) { 1147 for (i = 0; i < PART_LEN; i++) {
1180 outputH[j][i] = aec->dBufH[j][i] * nlpGainHband; 1148 outputH[j][i] = aec->dBufH[j][i] * nlpGainHband;
1181 } 1149 }
1182 } 1150 }
1183 1151
1184 // Add some comfort noise where Hband is attenuated. 1152 // Add some comfort noise where Hband is attenuated.
1185 for (i = 0; i < PART_LEN; i++) { 1153 for (i = 0; i < PART_LEN; i++) {
1186 outputH[0][i] += cnScaleHband * fft[i]; 1154 outputH[0][i] += cnScaleHband * fft[i];
1187 } 1155 }
1188 1156
1189 // Saturate output to keep it in the allowed range. 1157 // Saturate output to keep it in the allowed range.
1190 for (j = 0; j < aec->num_bands - 1; ++j) { 1158 for (j = 0; j < aec->num_bands - 1; ++j) {
1191 for (i = 0; i < PART_LEN; i++) { 1159 for (i = 0; i < PART_LEN; i++) {
1192 outputH[j][i] = WEBRTC_SPL_SAT( 1160 outputH[j][i] = WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, outputH[j][i],
1193 WEBRTC_SPL_WORD16_MAX, outputH[j][i], WEBRTC_SPL_WORD16_MIN); 1161 WEBRTC_SPL_WORD16_MIN);
1194 } 1162 }
1195 } 1163 }
1196
1197 } 1164 }
1198 1165
1199 // Copy the current block to the old position. 1166 // Copy the current block to the old position.
1200 memcpy(aec->dBuf, aec->dBuf + PART_LEN, sizeof(float) * PART_LEN); 1167 memcpy(aec->dBuf, aec->dBuf + PART_LEN, sizeof(float) * PART_LEN);
1201 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN); 1168 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN);
1202 1169
1203 // Copy the current block to the old position for H band 1170 // Copy the current block to the old position for H band
1204 for (j = 0; j < aec->num_bands - 1; ++j) { 1171 for (j = 0; j < aec->num_bands - 1; ++j) {
1205 memcpy(aec->dBufH[j], aec->dBufH[j] + PART_LEN, sizeof(float) * PART_LEN); 1172 memcpy(aec->dBufH[j], aec->dBufH[j] + PART_LEN, sizeof(float) * PART_LEN);
1206 } 1173 }
1207 1174
1208 memmove(aec->xfwBuf + PART_LEN1, 1175 memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf,
1209 aec->xfwBuf,
1210 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); 1176 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1);
1211 } 1177 }
1212 1178
1213 static void ProcessBlock(AecCore* aec) { 1179 static void ProcessBlock(AecCore* aec) {
1214 size_t i; 1180 size_t i;
1215 1181
1216 float fft[PART_LEN2]; 1182 float fft[PART_LEN2];
1217 float xf[2][PART_LEN1]; 1183 float xf[2][PART_LEN1];
1218 float df[2][PART_LEN1]; 1184 float df[2][PART_LEN1];
1219 float far_spectrum = 0.0f; 1185 float far_spectrum = 0.0f;
(...skipping 18 matching lines...) Expand all
1238 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; 1204 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN];
1239 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; 1205 float* outputH_ptr[NUM_HIGH_BANDS_MAX];
1240 float* xf_ptr = NULL; 1206 float* xf_ptr = NULL;
1241 1207
1242 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { 1208 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) {
1243 outputH_ptr[i] = outputH[i]; 1209 outputH_ptr[i] = outputH[i];
1244 } 1210 }
1245 1211
1246 // Concatenate old and new nearend blocks. 1212 // Concatenate old and new nearend blocks.
1247 for (i = 0; i < aec->num_bands - 1; ++i) { 1213 for (i = 0; i < aec->num_bands - 1; ++i) {
1248 WebRtc_ReadBuffer(aec->nearFrBufH[i], 1214 WebRtc_ReadBuffer(aec->nearFrBufH[i], (void**)&nearend_ptr, nearend,
1249 (void**)&nearend_ptr,
1250 nearend,
1251 PART_LEN); 1215 PART_LEN);
1252 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); 1216 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend));
1253 } 1217 }
1254 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN); 1218 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN);
1255 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend)); 1219 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend));
1256 1220
1257 // We should always have at least one element stored in |far_buf|. 1221 // We should always have at least one element stored in |far_buf|.
1258 assert(WebRtc_available_read(aec->far_time_buf) > 0); 1222 assert(WebRtc_available_read(aec->far_time_buf) > 0);
1259 WebRtc_ReadBuffer(aec->far_time_buf, (void**)&farend_ptr, farend, 1); 1223 WebRtc_ReadBuffer(aec->far_time_buf, (void**)&farend_ptr, farend, 1);
1260 1224
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1323 aec->dInitMinPow[i] = aec->dMinPow[i]; 1287 aec->dInitMinPow[i] = aec->dMinPow[i];
1324 } 1288 }
1325 } 1289 }
1326 aec->noisePow = aec->dInitMinPow; 1290 aec->noisePow = aec->dInitMinPow;
1327 } else { 1291 } else {
1328 aec->noisePow = aec->dMinPow; 1292 aec->noisePow = aec->dMinPow;
1329 } 1293 }
1330 1294
1331 // Block wise delay estimation used for logging 1295 // Block wise delay estimation used for logging
1332 if (aec->delay_logging_enabled) { 1296 if (aec->delay_logging_enabled) {
1333 if (WebRtc_AddFarSpectrumFloat( 1297 if (WebRtc_AddFarSpectrumFloat(aec->delay_estimator_farend,
1334 aec->delay_estimator_farend, abs_far_spectrum, PART_LEN1) == 0) { 1298 abs_far_spectrum, PART_LEN1) == 0) {
1335 int delay_estimate = WebRtc_DelayEstimatorProcessFloat( 1299 int delay_estimate = WebRtc_DelayEstimatorProcessFloat(
1336 aec->delay_estimator, abs_near_spectrum, PART_LEN1); 1300 aec->delay_estimator, abs_near_spectrum, PART_LEN1);
1337 if (delay_estimate >= 0) { 1301 if (delay_estimate >= 0) {
1338 // Update delay estimate buffer. 1302 // Update delay estimate buffer.
1339 aec->delay_histogram[delay_estimate]++; 1303 aec->delay_histogram[delay_estimate]++;
1340 aec->num_delay_values++; 1304 aec->num_delay_values++;
1341 } 1305 }
1342 if (aec->delay_metrics_delivered == 1 && 1306 if (aec->delay_metrics_delivered == 1 &&
1343 aec->num_delay_values >= kDelayMetricsAggregationWindow) { 1307 aec->num_delay_values >= kDelayMetricsAggregationWindow) {
1344 UpdateDelayMetrics(aec); 1308 UpdateDelayMetrics(aec);
1345 } 1309 }
1346 } 1310 }
1347 } 1311 }
1348 1312
1349 // Update the xfBuf block position. 1313 // Update the xfBuf block position.
1350 aec->xfBufBlockPos--; 1314 aec->xfBufBlockPos--;
1351 if (aec->xfBufBlockPos == -1) { 1315 if (aec->xfBufBlockPos == -1) {
1352 aec->xfBufBlockPos = aec->num_partitions - 1; 1316 aec->xfBufBlockPos = aec->num_partitions - 1;
1353 } 1317 }
1354 1318
1355 // Buffer xf 1319 // Buffer xf
1356 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, 1320 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, xf_ptr,
1357 xf_ptr,
1358 sizeof(float) * PART_LEN1); 1321 sizeof(float) * PART_LEN1);
1359 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, 1322 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, &xf_ptr[PART_LEN1],
1360 &xf_ptr[PART_LEN1],
1361 sizeof(float) * PART_LEN1); 1323 sizeof(float) * PART_LEN1);
1362 1324
1363 // Perform echo subtraction. 1325 // Perform echo subtraction.
1364 EchoSubtraction(aec, 1326 EchoSubtraction(aec, aec->num_partitions, aec->xfBufBlockPos,
1365 aec->num_partitions,
1366 aec->xfBufBlockPos,
1367 aec->extended_filter_enabled, 1327 aec->extended_filter_enabled,
1368 aec->normal_mu, 1328 aec->normal_mu, aec->normal_error_threshold, aec->xfBuf,
1369 aec->normal_error_threshold, 1329 nearend_ptr, aec->xPow, aec->wfBuf,
1370 aec->xfBuf,
1371 nearend_ptr,
1372 aec->xPow,
1373 aec->wfBuf,
1374 echo_subtractor_output); 1330 echo_subtractor_output);
1375 1331
1376 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); 1332 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN);
1377 1333
1378 if (aec->metricsMode == 1) { 1334 if (aec->metricsMode == 1) {
1379 UpdateLevel(&aec->linoutlevel, 1335 UpdateLevel(&aec->linoutlevel,
1380 CalculatePower(echo_subtractor_output, PART_LEN)); 1336 CalculatePower(echo_subtractor_output, PART_LEN));
1381 } 1337 }
1382 1338
1383 // Perform echo suppression. 1339 // Perform echo suppression.
(...skipping 26 matching lines...) Expand all
1410 return NULL; 1366 return NULL;
1411 } 1367 }
1412 1368
1413 aec->outFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); 1369 aec->outFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1414 if (!aec->outFrBuf) { 1370 if (!aec->outFrBuf) {
1415 WebRtcAec_FreeAec(aec); 1371 WebRtcAec_FreeAec(aec);
1416 return NULL; 1372 return NULL;
1417 } 1373 }
1418 1374
1419 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { 1375 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) {
1420 aec->nearFrBufH[i] = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, 1376 aec->nearFrBufH[i] =
1421 sizeof(float)); 1377 WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1422 if (!aec->nearFrBufH[i]) { 1378 if (!aec->nearFrBufH[i]) {
1423 WebRtcAec_FreeAec(aec); 1379 WebRtcAec_FreeAec(aec);
1424 return NULL; 1380 return NULL;
1425 } 1381 }
1426 aec->outFrBufH[i] = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, 1382 aec->outFrBufH[i] =
1427 sizeof(float)); 1383 WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1428 if (!aec->outFrBufH[i]) { 1384 if (!aec->outFrBufH[i]) {
1429 WebRtcAec_FreeAec(aec); 1385 WebRtcAec_FreeAec(aec);
1430 return NULL; 1386 return NULL;
1431 } 1387 }
1432 } 1388 }
1433 1389
1434 // Create far-end buffers. 1390 // Create far-end buffers.
1435 // For bit exactness with legacy code, each element in |far_time_buf| is 1391 // For bit exactness with legacy code, each element in |far_time_buf| is
1436 // supposed to contain |PART_LEN2| samples with an overlap of |PART_LEN| 1392 // supposed to contain |PART_LEN2| samples with an overlap of |PART_LEN|
1437 // samples from the last frame. 1393 // samples from the last frame.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 WebRtcAec_FilterFar = FilterFar; 1434 WebRtcAec_FilterFar = FilterFar;
1479 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; 1435 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal;
1480 WebRtcAec_FilterAdaptation = FilterAdaptation; 1436 WebRtcAec_FilterAdaptation = FilterAdaptation;
1481 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; 1437 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress;
1482 WebRtcAec_ComfortNoise = ComfortNoise; 1438 WebRtcAec_ComfortNoise = ComfortNoise;
1483 WebRtcAec_SubbandCoherence = SubbandCoherence; 1439 WebRtcAec_SubbandCoherence = SubbandCoherence;
1484 WebRtcAec_StoreAsComplex = StoreAsComplex; 1440 WebRtcAec_StoreAsComplex = StoreAsComplex;
1485 WebRtcAec_PartitionDelay = PartitionDelay; 1441 WebRtcAec_PartitionDelay = PartitionDelay;
1486 WebRtcAec_WindowData = WindowData; 1442 WebRtcAec_WindowData = WindowData;
1487 1443
1488
1489 #if defined(WEBRTC_ARCH_X86_FAMILY) 1444 #if defined(WEBRTC_ARCH_X86_FAMILY)
1490 if (WebRtc_GetCPUInfo(kSSE2)) { 1445 if (WebRtc_GetCPUInfo(kSSE2)) {
1491 WebRtcAec_InitAec_SSE2(); 1446 WebRtcAec_InitAec_SSE2();
1492 } 1447 }
1493 #endif 1448 #endif
1494 1449
1495 #if defined(MIPS_FPU_LE) 1450 #if defined(MIPS_FPU_LE)
1496 WebRtcAec_InitAec_mips(); 1451 WebRtcAec_InitAec_mips();
1497 #endif 1452 #endif
1498 1453
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1560 } 1515 }
1561 1516
1562 // Initialize far-end buffers. 1517 // Initialize far-end buffers.
1563 WebRtc_InitBuffer(aec->far_time_buf); 1518 WebRtc_InitBuffer(aec->far_time_buf);
1564 1519
1565 #ifdef WEBRTC_AEC_DEBUG_DUMP 1520 #ifdef WEBRTC_AEC_DEBUG_DUMP
1566 { 1521 {
1567 int process_rate = sampFreq > 16000 ? 16000 : sampFreq; 1522 int process_rate = sampFreq > 16000 ? 16000 : sampFreq;
1568 RTC_AEC_DEBUG_WAV_REOPEN("aec_far", aec->instance_index, 1523 RTC_AEC_DEBUG_WAV_REOPEN("aec_far", aec->instance_index,
1569 aec->debug_dump_count, process_rate, 1524 aec->debug_dump_count, process_rate,
1570 &aec->farFile ); 1525 &aec->farFile);
1571 RTC_AEC_DEBUG_WAV_REOPEN("aec_near", aec->instance_index, 1526 RTC_AEC_DEBUG_WAV_REOPEN("aec_near", aec->instance_index,
1572 aec->debug_dump_count, process_rate, 1527 aec->debug_dump_count, process_rate,
1573 &aec->nearFile); 1528 &aec->nearFile);
1574 RTC_AEC_DEBUG_WAV_REOPEN("aec_out", aec->instance_index, 1529 RTC_AEC_DEBUG_WAV_REOPEN("aec_out", aec->instance_index,
1575 aec->debug_dump_count, process_rate, 1530 aec->debug_dump_count, process_rate,
1576 &aec->outFile ); 1531 &aec->outFile);
1577 RTC_AEC_DEBUG_WAV_REOPEN("aec_out_linear", aec->instance_index, 1532 RTC_AEC_DEBUG_WAV_REOPEN("aec_out_linear", aec->instance_index,
1578 aec->debug_dump_count, process_rate, 1533 aec->debug_dump_count, process_rate,
1579 &aec->outLinearFile); 1534 &aec->outLinearFile);
1580 } 1535 }
1581 1536
1582 RTC_AEC_DEBUG_RAW_OPEN("aec_e_fft", 1537 RTC_AEC_DEBUG_RAW_OPEN("aec_e_fft", aec->debug_dump_count, &aec->e_fft_file);
1583 aec->debug_dump_count,
1584 &aec->e_fft_file);
1585 1538
1586 ++aec->debug_dump_count; 1539 ++aec->debug_dump_count;
1587 #endif 1540 #endif
1588 aec->system_delay = 0; 1541 aec->system_delay = 0;
1589 1542
1590 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) { 1543 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) {
1591 return -1; 1544 return -1;
1592 } 1545 }
1593 if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) { 1546 if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) {
1594 return -1; 1547 return -1;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1660 } 1613 }
1661 1614
1662 // Holds the last block written to 1615 // Holds the last block written to
1663 aec->xfBufBlockPos = 0; 1616 aec->xfBufBlockPos = 0;
1664 // TODO: Investigate need for these initializations. Deleting them doesn't 1617 // TODO: Investigate need for these initializations. Deleting them doesn't
1665 // change the output at all and yields 0.4% overall speedup. 1618 // change the output at all and yields 0.4% overall speedup.
1666 memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); 1619 memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
1667 memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); 1620 memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
1668 memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1); 1621 memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1);
1669 memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1); 1622 memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1);
1670 memset( 1623 memset(aec->xfwBuf, 0,
1671 aec->xfwBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); 1624 sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
1672 memset(aec->se, 0, sizeof(float) * PART_LEN1); 1625 memset(aec->se, 0, sizeof(float) * PART_LEN1);
1673 1626
1674 // To prevent numerical instability in the first block. 1627 // To prevent numerical instability in the first block.
1675 for (i = 0; i < PART_LEN1; i++) { 1628 for (i = 0; i < PART_LEN1; i++) {
1676 aec->sd[i] = 1; 1629 aec->sd[i] = 1;
1677 } 1630 }
1678 for (i = 0; i < PART_LEN1; i++) { 1631 for (i = 0; i < PART_LEN1; i++) {
1679 aec->sx[i] = 1; 1632 aec->sx[i] = 1;
1680 } 1633 }
1681 1634
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1757 // give a guess on how much we need to shift far-end buffers to align with 1710 // give a guess on how much we need to shift far-end buffers to align with
1758 // the near-end signal. The other delay estimation algorithm uses the 1711 // the near-end signal. The other delay estimation algorithm uses the
1759 // far- and near-end signals to find the offset between them. This one 1712 // far- and near-end signals to find the offset between them. This one
1760 // (called "signal delay") is then used to fine tune the alignment, or 1713 // (called "signal delay") is then used to fine tune the alignment, or
1761 // simply compensate for errors in the system based one. 1714 // simply compensate for errors in the system based one.
1762 // Note that the two algorithms operate independently. Currently, we only 1715 // Note that the two algorithms operate independently. Currently, we only
1763 // allow one algorithm to be turned on. 1716 // allow one algorithm to be turned on.
1764 1717
1765 assert(aec->num_bands == num_bands); 1718 assert(aec->num_bands == num_bands);
1766 1719
1767 for (j = 0; j < num_samples; j+= FRAME_LEN) { 1720 for (j = 0; j < num_samples; j += FRAME_LEN) {
1768 // TODO(bjornv): Change the near-end buffer handling to be the same as for 1721 // TODO(bjornv): Change the near-end buffer handling to be the same as for
1769 // far-end, that is, with a near_pre_buf. 1722 // far-end, that is, with a near_pre_buf.
1770 // Buffer the near-end frame. 1723 // Buffer the near-end frame.
1771 WebRtc_WriteBuffer(aec->nearFrBuf, &nearend[0][j], FRAME_LEN); 1724 WebRtc_WriteBuffer(aec->nearFrBuf, &nearend[0][j], FRAME_LEN);
1772 // For H band 1725 // For H band
1773 for (i = 1; i < num_bands; ++i) { 1726 for (i = 1; i < num_bands; ++i) {
1774 WebRtc_WriteBuffer(aec->nearFrBufH[i - 1], &nearend[i][j], FRAME_LEN); 1727 WebRtc_WriteBuffer(aec->nearFrBufH[i - 1], &nearend[i][j], FRAME_LEN);
1775 } 1728 }
1776 1729
1777 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we 1730 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we
1778 // have enough far-end data for that by stuffing the buffer if the 1731 // have enough far-end data for that by stuffing the buffer if the
1779 // |system_delay| indicates others. 1732 // |system_delay| indicates others.
1780 if (aec->system_delay < FRAME_LEN) { 1733 if (aec->system_delay < FRAME_LEN) {
1781 // We don't have enough data so we rewind 10 ms. 1734 // We don't have enough data so we rewind 10 ms.
1782 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1)); 1735 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1));
1783 } 1736 }
1784 1737
1785 if (!aec->delay_agnostic_enabled) { 1738 if (!aec->delay_agnostic_enabled) {
1786 // 2 a) Compensate for a possible change in the system delay. 1739 // 2 a) Compensate for a possible change in the system delay.
1787 1740
1788 // TODO(bjornv): Investigate how we should round the delay difference; 1741 // TODO(bjornv): Investigate how we should round the delay difference;
1789 // right now we know that incoming |knownDelay| is underestimated when 1742 // right now we know that incoming |knownDelay| is underestimated when
1790 // it's less than |aec->knownDelay|. We therefore, round (-32) in that 1743 // it's less than |aec->knownDelay|. We therefore, round (-32) in that
1791 // direction. In the other direction, we don't have this situation, but 1744 // direction. In the other direction, we don't have this situation, but
1792 // might flush one partition too little. This can cause non-causality, 1745 // might flush one partition too little. This can cause non-causality,
1793 // which should be investigated. Maybe, allow for a non-symmetric 1746 // which should be investigated. Maybe, allow for a non-symmetric
1794 // rounding, like -16. 1747 // rounding, like -16.
1795 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN; 1748 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN;
1796 int moved_elements = 1749 int moved_elements = WebRtc_MoveReadPtr(aec->far_time_buf, move_elements);
1797 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements);
1798 aec->knownDelay -= moved_elements * PART_LEN; 1750 aec->knownDelay -= moved_elements * PART_LEN;
1799 } else { 1751 } else {
1800 // 2 b) Apply signal based delay correction. 1752 // 2 b) Apply signal based delay correction.
1801 int move_elements = SignalBasedDelayCorrection(aec); 1753 int move_elements = SignalBasedDelayCorrection(aec);
1802 int moved_elements = 1754 int moved_elements = WebRtc_MoveReadPtr(aec->far_time_buf, move_elements);
1803 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); 1755 int far_near_buffer_diff =
1804 int far_near_buffer_diff = WebRtc_available_read(aec->far_time_buf) - 1756 WebRtc_available_read(aec->far_time_buf) -
1805 WebRtc_available_read(aec->nearFrBuf) / PART_LEN; 1757 WebRtc_available_read(aec->nearFrBuf) / PART_LEN;
1806 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); 1758 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements);
1807 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, 1759 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend,
1808 moved_elements); 1760 moved_elements);
1809 aec->signal_delay_correction += moved_elements; 1761 aec->signal_delay_correction += moved_elements;
1810 // If we rely on reported system delay values only, a buffer underrun here 1762 // If we rely on reported system delay values only, a buffer underrun here
1811 // can never occur since we've taken care of that in 1) above. Here, we 1763 // can never occur since we've taken care of that in 1) above. Here, we
1812 // apply signal based delay correction and can therefore end up with 1764 // apply signal based delay correction and can therefore end up with
1813 // buffer underruns since the delay estimation can be wrong. We therefore 1765 // buffer underruns since the delay estimation can be wrong. We therefore
1814 // stuff the buffer with enough elements if needed. 1766 // stuff the buffer with enough elements if needed.
(...skipping 22 matching lines...) Expand all
1837 } 1789 }
1838 // Obtain an output frame. 1790 // Obtain an output frame.
1839 WebRtc_ReadBuffer(aec->outFrBuf, NULL, &out[0][j], FRAME_LEN); 1791 WebRtc_ReadBuffer(aec->outFrBuf, NULL, &out[0][j], FRAME_LEN);
1840 // For H bands. 1792 // For H bands.
1841 for (i = 1; i < num_bands; ++i) { 1793 for (i = 1; i < num_bands; ++i) {
1842 WebRtc_ReadBuffer(aec->outFrBufH[i - 1], NULL, &out[i][j], FRAME_LEN); 1794 WebRtc_ReadBuffer(aec->outFrBufH[i - 1], NULL, &out[i][j], FRAME_LEN);
1843 } 1795 }
1844 } 1796 }
1845 } 1797 }
1846 1798
1847 int WebRtcAec_GetDelayMetricsCore(AecCore* self, int* median, int* std, 1799 int WebRtcAec_GetDelayMetricsCore(AecCore* self,
1800 int* median,
1801 int* std,
1848 float* fraction_poor_delays) { 1802 float* fraction_poor_delays) {
1849 assert(self != NULL); 1803 assert(self != NULL);
1850 assert(median != NULL); 1804 assert(median != NULL);
1851 assert(std != NULL); 1805 assert(std != NULL);
1852 1806
1853 if (self->delay_logging_enabled == 0) { 1807 if (self->delay_logging_enabled == 0) {
1854 // Logging disabled. 1808 // Logging disabled.
1855 return -1; 1809 return -1;
1856 } 1810 }
1857 1811
1858 if (self->delay_metrics_delivered == 0) { 1812 if (self->delay_metrics_delivered == 0) {
1859 UpdateDelayMetrics(self); 1813 UpdateDelayMetrics(self);
1860 self->delay_metrics_delivered = 1; 1814 self->delay_metrics_delivered = 1;
1861 } 1815 }
1862 *median = self->delay_median; 1816 *median = self->delay_median;
1863 *std = self->delay_std; 1817 *std = self->delay_std;
1864 *fraction_poor_delays = self->fraction_poor_delays; 1818 *fraction_poor_delays = self->fraction_poor_delays;
1865 1819
1866 return 0; 1820 return 0;
1867 } 1821 }
1868 1822
1869 int WebRtcAec_echo_state(AecCore* self) { return self->echoState; } 1823 int WebRtcAec_echo_state(AecCore* self) {
1824 return self->echoState;
1825 }
1870 1826
1871 void WebRtcAec_GetEchoStats(AecCore* self, 1827 void WebRtcAec_GetEchoStats(AecCore* self,
1872 Stats* erl, 1828 Stats* erl,
1873 Stats* erle, 1829 Stats* erle,
1874 Stats* a_nlp) { 1830 Stats* a_nlp) {
1875 assert(erl != NULL); 1831 assert(erl != NULL);
1876 assert(erle != NULL); 1832 assert(erle != NULL);
1877 assert(a_nlp != NULL); 1833 assert(a_nlp != NULL);
1878 *erl = self->erl; 1834 *erl = self->erl;
1879 *erle = self->erle; 1835 *erle = self->erle;
(...skipping 30 matching lines...) Expand all
1910 self->extended_filter_enabled = enable; 1866 self->extended_filter_enabled = enable;
1911 self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions; 1867 self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions;
1912 // Update the delay estimator with filter length. See InitAEC() for details. 1868 // Update the delay estimator with filter length. See InitAEC() for details.
1913 WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2); 1869 WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2);
1914 } 1870 }
1915 1871
1916 int WebRtcAec_extended_filter_enabled(AecCore* self) { 1872 int WebRtcAec_extended_filter_enabled(AecCore* self) {
1917 return self->extended_filter_enabled; 1873 return self->extended_filter_enabled;
1918 } 1874 }
1919 1875
1920 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } 1876 int WebRtcAec_system_delay(AecCore* self) {
1877 return self->system_delay;
1878 }
1921 1879
1922 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 1880 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
1923 assert(delay >= 0); 1881 assert(delay >= 0);
1924 self->system_delay = delay; 1882 self->system_delay = delay;
1925 } 1883 }
OLDNEW
« no previous file with comments | « webrtc/modules/audio_processing/aec/aec_core.h ('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