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

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: 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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 break; 744 break;
764 } 745 }
765 } 746 }
766 // Account for lookahead. 747 // Account for lookahead.
767 self->delay_median = (median - lookahead) * kMsPerBlock; 748 self->delay_median = (median - lookahead) * kMsPerBlock;
768 749
769 // Calculate the L1 norm, with median value as central moment. 750 // Calculate the L1 norm, with median value as central moment.
770 for (i = 0; i < kHistorySizeBlocks; i++) { 751 for (i = 0; i < kHistorySizeBlocks; i++) {
771 l1_norm += abs(i - median) * self->delay_histogram[i]; 752 l1_norm += abs(i - median) * self->delay_histogram[i];
772 } 753 }
773 self->delay_std = (int)((l1_norm + self->num_delay_values / 2) / 754 self->delay_std =
774 self->num_delay_values) * kMsPerBlock; 755 (int)((l1_norm + self->num_delay_values / 2) / self->num_delay_values) *
756 kMsPerBlock;
775 757
776 // Determine fraction of delays that are out of bounds, that is, either 758 // Determine fraction of delays that are out of bounds, that is, either
777 // negative (anti-causal system) or larger than the AEC filter length. 759 // negative (anti-causal system) or larger than the AEC filter length.
778 { 760 {
779 int num_delays_out_of_bounds = self->num_delay_values; 761 int num_delays_out_of_bounds = self->num_delay_values;
780 const int histogram_length = sizeof(self->delay_histogram) / 762 const int histogram_length =
781 sizeof(self->delay_histogram[0]); 763 sizeof(self->delay_histogram) / sizeof(self->delay_histogram[0]);
782 for (i = lookahead; i < lookahead + self->num_partitions; ++i) { 764 for (i = lookahead; i < lookahead + self->num_partitions; ++i) {
783 if (i < histogram_length) 765 if (i < histogram_length)
784 num_delays_out_of_bounds -= self->delay_histogram[i]; 766 num_delays_out_of_bounds -= self->delay_histogram[i];
785 } 767 }
786 self->fraction_poor_delays = (float)num_delays_out_of_bounds / 768 self->fraction_poor_delays =
787 self->num_delay_values; 769 (float)num_delays_out_of_bounds / self->num_delay_values;
788 } 770 }
789 771
790 // Reset histogram. 772 // Reset histogram.
791 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); 773 memset(self->delay_histogram, 0, sizeof(self->delay_histogram));
792 self->num_delay_values = 0; 774 self->num_delay_values = 0;
793 775
794 return; 776 return;
795 } 777 }
796 778
797 static void ScaledInverseFft(float freq_data[2][PART_LEN1], 779 static void ScaledInverseFft(float freq_data[2][PART_LEN1],
798 float time_data[PART_LEN2], 780 float time_data[PART_LEN2],
799 float scale, 781 float scale,
800 int conjugate) { 782 int conjugate) {
801 int i; 783 int i;
802 const float normalization = scale / ((float)PART_LEN2); 784 const float normalization = scale / ((float)PART_LEN2);
803 const float sign = (conjugate ? -1 : 1); 785 const float sign = (conjugate ? -1 : 1);
804 time_data[0] = freq_data[0][0] * normalization; 786 time_data[0] = freq_data[0][0] * normalization;
805 time_data[1] = freq_data[0][PART_LEN] * normalization; 787 time_data[1] = freq_data[0][PART_LEN] * normalization;
806 for (i = 1; i < PART_LEN; i++) { 788 for (i = 1; i < PART_LEN; i++) {
807 time_data[2 * i] = freq_data[0][i] * normalization; 789 time_data[2 * i] = freq_data[0][i] * normalization;
808 time_data[2 * i + 1] = sign * freq_data[1][i] * normalization; 790 time_data[2 * i + 1] = sign * freq_data[1][i] * normalization;
809 } 791 }
810 aec_rdft_inverse_128(time_data); 792 aec_rdft_inverse_128(time_data);
811 } 793 }
812 794
813 795 static void Fft(float time_data[PART_LEN2], float freq_data[2][PART_LEN1]) {
814 static void Fft(float time_data[PART_LEN2],
815 float freq_data[2][PART_LEN1]) {
816 int i; 796 int i;
817 aec_rdft_forward_128(time_data); 797 aec_rdft_forward_128(time_data);
818 798
819 // Reorder fft output data. 799 // Reorder fft output data.
820 freq_data[1][0] = 0; 800 freq_data[1][0] = 0;
821 freq_data[1][PART_LEN] = 0; 801 freq_data[1][PART_LEN] = 0;
822 freq_data[0][0] = time_data[0]; 802 freq_data[0][0] = time_data[0];
823 freq_data[0][PART_LEN] = time_data[1]; 803 freq_data[0][PART_LEN] = time_data[1];
824 for (i = 1; i < PART_LEN; i++) { 804 for (i = 1; i < PART_LEN; i++) {
825 freq_data[0][i] = time_data[2 * i]; 805 freq_data[0][i] = time_data[2 * i];
(...skipping 20 matching lines...) Expand all
846 // negative |last_delay| is an invalid one. 826 // negative |last_delay| is an invalid one.
847 // 2. Verify that there is a delay change. In addition, only allow a change 827 // 2. Verify that there is a delay change. In addition, only allow a change
848 // if the delay is outside a certain region taking the AEC filter length 828 // if the delay is outside a certain region taking the AEC filter length
849 // into account. 829 // into account.
850 // TODO(bjornv): Investigate if we can remove the non-zero delay change check. 830 // TODO(bjornv): Investigate if we can remove the non-zero delay change check.
851 // 3. Only allow delay correction if the delay estimation quality exceeds 831 // 3. Only allow delay correction if the delay estimation quality exceeds
852 // |delay_quality_threshold|. 832 // |delay_quality_threshold|.
853 // 4. Finally, verify that the proposed |delay_correction| is feasible by 833 // 4. Finally, verify that the proposed |delay_correction| is feasible by
854 // comparing with the size of the far-end buffer. 834 // comparing with the size of the far-end buffer.
855 last_delay = WebRtc_last_delay(self->delay_estimator); 835 last_delay = WebRtc_last_delay(self->delay_estimator);
856 if ((last_delay >= 0) && 836 if ((last_delay >= 0) && (last_delay != self->previous_delay) &&
857 (last_delay != self->previous_delay) &&
858 (WebRtc_last_delay_quality(self->delay_estimator) > 837 (WebRtc_last_delay_quality(self->delay_estimator) >
859 self->delay_quality_threshold)) { 838 self->delay_quality_threshold)) {
860 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); 839 int delay = last_delay - WebRtc_lookahead(self->delay_estimator);
861 // Allow for a slack in the actual delay, defined by a |lower_bound| and an 840 // Allow for a slack in the actual delay, defined by a |lower_bound| and an
862 // |upper_bound|. The adaptive echo cancellation filter is currently 841 // |upper_bound|. The adaptive echo cancellation filter is currently
863 // |num_partitions| (of 64 samples) long. If the delay estimate is negative 842 // |num_partitions| (of 64 samples) long. If the delay estimate is negative
864 // or at least 3/4 of the filter length we open up for correction. 843 // or at least 3/4 of the filter length we open up for correction.
865 const int lower_bound = 0; 844 const int lower_bound = 0;
866 const int upper_bound = self->num_partitions * 3 / 4; 845 const int upper_bound = self->num_partitions * 3 / 4;
867 const int do_correction = delay <= lower_bound || delay > upper_bound; 846 const int do_correction = delay <= lower_bound || delay > upper_bound;
868 if (do_correction == 1) { 847 if (do_correction == 1) {
869 int available_read = (int)WebRtc_available_read(self->far_time_buf); 848 int available_read = (int)WebRtc_available_read(self->far_time_buf);
(...skipping 13 matching lines...) Expand all
883 } else { 862 } else {
884 self->previous_delay = last_delay; 863 self->previous_delay = last_delay;
885 ++self->delay_correction_count; 864 ++self->delay_correction_count;
886 } 865 }
887 } 866 }
888 } 867 }
889 // Update the |delay_quality_threshold| once we have our first delay 868 // Update the |delay_quality_threshold| once we have our first delay
890 // correction. 869 // correction.
891 if (self->delay_correction_count > 0) { 870 if (self->delay_correction_count > 0) {
892 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); 871 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator);
893 delay_quality = (delay_quality > kDelayQualityThresholdMax ? 872 delay_quality =
894 kDelayQualityThresholdMax : delay_quality); 873 (delay_quality > kDelayQualityThresholdMax ? kDelayQualityThresholdMax
874 : delay_quality);
895 self->delay_quality_threshold = 875 self->delay_quality_threshold =
896 (delay_quality > self->delay_quality_threshold ? delay_quality : 876 (delay_quality > self->delay_quality_threshold
897 self->delay_quality_threshold); 877 ? delay_quality
878 : self->delay_quality_threshold);
898 } 879 }
899 return delay_correction; 880 return delay_correction;
900 } 881 }
901 882
902 static void EchoSubtraction( 883 static void EchoSubtraction(AecCore* aec,
903 AecCore* aec, 884 int num_partitions,
904 int num_partitions, 885 int x_fft_buf_block_pos,
905 int x_fft_buf_block_pos, 886 int metrics_mode,
906 int metrics_mode, 887 int extended_filter_enabled,
907 int extended_filter_enabled, 888 float normal_mu,
908 float normal_mu, 889 float normal_error_threshold,
909 float normal_error_threshold, 890 float x_fft_buf[2]
910 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], 891 [kExtendedNumPartitions * PART_LEN1],
911 float* const y, 892 float* const y,
912 float x_pow[PART_LEN1], 893 float x_pow[PART_LEN1],
913 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1], 894 float h_fft_buf[2]
914 PowerLevel* linout_level, 895 [kExtendedNumPartitions * PART_LEN1],
915 float echo_subtractor_output[PART_LEN]) { 896 PowerLevel* linout_level,
897 float echo_subtractor_output[PART_LEN]) {
916 float s_fft[2][PART_LEN1]; 898 float s_fft[2][PART_LEN1];
917 float e_extended[PART_LEN2]; 899 float e_extended[PART_LEN2];
918 float s_extended[PART_LEN2]; 900 float s_extended[PART_LEN2];
919 float *s; 901 float* s;
920 float e[PART_LEN]; 902 float e[PART_LEN];
921 float e_fft[2][PART_LEN1]; 903 float e_fft[2][PART_LEN1];
922 int i; 904 int i;
923 memset(s_fft, 0, sizeof(s_fft)); 905 memset(s_fft, 0, sizeof(s_fft));
924 906
925 // Conditionally reset the echo subtraction filter if the filter has diverged 907 // Conditionally reset the echo subtraction filter if the filter has diverged
926 // significantly. 908 // significantly.
927 if (!aec->extended_filter_enabled && 909 if (!aec->extended_filter_enabled && aec->extreme_filter_divergence) {
928 aec->extreme_filter_divergence) {
929 memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); 910 memset(aec->wfBuf, 0, sizeof(aec->wfBuf));
930 aec->extreme_filter_divergence = 0; 911 aec->extreme_filter_divergence = 0;
931 } 912 }
932 913
933 // Produce echo estimate s_fft. 914 // Produce echo estimate s_fft.
934 WebRtcAec_FilterFar(num_partitions, 915 WebRtcAec_FilterFar(num_partitions, x_fft_buf_block_pos, x_fft_buf, h_fft_buf,
935 x_fft_buf_block_pos,
936 x_fft_buf,
937 h_fft_buf,
938 s_fft); 916 s_fft);
939 917
940 // Compute the time-domain echo estimate s. 918 // Compute the time-domain echo estimate s.
941 ScaledInverseFft(s_fft, s_extended, 2.0f, 0); 919 ScaledInverseFft(s_fft, s_extended, 2.0f, 0);
942 s = &s_extended[PART_LEN]; 920 s = &s_extended[PART_LEN];
943 921
944 // Compute the time-domain echo prediction error. 922 // Compute the time-domain echo prediction error.
945 for (i = 0; i < PART_LEN; ++i) { 923 for (i = 0; i < PART_LEN; ++i) {
946 e[i] = y[i] - s[i]; 924 e[i] = y[i] - s[i];
947 } 925 }
948 926
949 // Compute the frequency domain echo prediction error. 927 // Compute the frequency domain echo prediction error.
950 memset(e_extended, 0, sizeof(float) * PART_LEN); 928 memset(e_extended, 0, sizeof(float) * PART_LEN);
951 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); 929 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN);
952 Fft(e_extended, e_fft); 930 Fft(e_extended, e_fft);
953 931
954 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, 932 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, &e_fft[0][0],
955 &e_fft[0][0],
956 sizeof(e_fft[0][0]) * PART_LEN1 * 2); 933 sizeof(e_fft[0][0]) * PART_LEN1 * 2);
957 934
958 if (metrics_mode == 1) { 935 if (metrics_mode == 1) {
959 // Note that the first PART_LEN samples in fft (before transformation) are 936 // Note that the first PART_LEN samples in fft (before transformation) are
960 // zero. Hence, the scaling by two in UpdateLevel() should not be 937 // zero. Hence, the scaling by two in UpdateLevel() should not be
961 // performed. That scaling is taken care of in UpdateMetrics() instead. 938 // performed. That scaling is taken care of in UpdateMetrics() instead.
962 UpdateLevel(linout_level, CalculatePower(e, PART_LEN) / 2.0f); 939 UpdateLevel(linout_level, CalculatePower(e, PART_LEN) / 2.0f);
963 } 940 }
964 941
965 // Scale error signal inversely with far power. 942 // Scale error signal inversely with far power.
966 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, 943 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, normal_mu,
967 normal_mu, 944 normal_error_threshold, x_pow, e_fft);
968 normal_error_threshold, 945 WebRtcAec_FilterAdaptation(num_partitions, x_fft_buf_block_pos, x_fft_buf,
969 x_pow, 946 e_fft, h_fft_buf);
970 e_fft);
971 WebRtcAec_FilterAdaptation(num_partitions,
972 x_fft_buf_block_pos,
973 x_fft_buf,
974 e_fft,
975 h_fft_buf);
976 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); 947 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN);
977 } 948 }
978 949
979
980 static void EchoSuppression(AecCore* aec, 950 static void EchoSuppression(AecCore* aec,
981 float farend[PART_LEN2], 951 float farend[PART_LEN2],
982 float* echo_subtractor_output, 952 float* echo_subtractor_output,
983 float* output, 953 float* output,
984 float* const* outputH) { 954 float* const* outputH) {
985 float efw[2][PART_LEN1]; 955 float efw[2][PART_LEN1];
986 float xfw[2][PART_LEN1]; 956 float xfw[2][PART_LEN1];
987 float dfw[2][PART_LEN1]; 957 float dfw[2][PART_LEN1];
988 float comfortNoiseHband[2][PART_LEN1]; 958 float comfortNoiseHband[2][PART_LEN1];
989 float fft[PART_LEN2]; 959 float fft[PART_LEN2];
(...skipping 14 matching lines...) Expand all
1004 const float* min_overdrive = aec->extended_filter_enabled 974 const float* min_overdrive = aec->extended_filter_enabled
1005 ? kExtendedMinOverDrive 975 ? kExtendedMinOverDrive
1006 : kNormalMinOverDrive; 976 : kNormalMinOverDrive;
1007 977
1008 // Filter energy 978 // Filter energy
1009 const int delayEstInterval = 10 * aec->mult; 979 const int delayEstInterval = 10 * aec->mult;
1010 980
1011 float* xfw_ptr = NULL; 981 float* xfw_ptr = NULL;
1012 982
1013 // Update eBuf with echo subtractor output. 983 // Update eBuf with echo subtractor output.
1014 memcpy(aec->eBuf + PART_LEN, 984 memcpy(aec->eBuf + PART_LEN, echo_subtractor_output,
1015 echo_subtractor_output,
1016 sizeof(float) * PART_LEN); 985 sizeof(float) * PART_LEN);
1017 986
1018 // Analysis filter banks for the echo suppressor. 987 // Analysis filter banks for the echo suppressor.
1019 // Windowed near-end ffts. 988 // Windowed near-end ffts.
1020 WindowData(fft, aec->dBuf); 989 WindowData(fft, aec->dBuf);
1021 aec_rdft_forward_128(fft); 990 aec_rdft_forward_128(fft);
1022 StoreAsComplex(fft, dfw); 991 StoreAsComplex(fft, dfw);
1023 992
1024 // Windowed echo suppressor output ffts. 993 // Windowed echo suppressor output ffts.
1025 WindowData(fft, aec->eBuf); 994 WindowData(fft, aec->eBuf);
(...skipping 10 matching lines...) Expand all
1036 // Buffer far. 1005 // Buffer far.
1037 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); 1006 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1);
1038 1007
1039 aec->delayEstCtr++; 1008 aec->delayEstCtr++;
1040 if (aec->delayEstCtr == delayEstInterval) { 1009 if (aec->delayEstCtr == delayEstInterval) {
1041 aec->delayEstCtr = 0; 1010 aec->delayEstCtr = 0;
1042 aec->delayIdx = WebRtcAec_PartitionDelay(aec); 1011 aec->delayIdx = WebRtcAec_PartitionDelay(aec);
1043 } 1012 }
1044 1013
1045 // Use delayed far. 1014 // Use delayed far.
1046 memcpy(xfw, 1015 memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1,
1047 aec->xfwBuf + aec->delayIdx * PART_LEN1,
1048 sizeof(xfw[0][0]) * 2 * PART_LEN1); 1016 sizeof(xfw[0][0]) * 2 * PART_LEN1);
1049 1017
1050 WebRtcAec_SubbandCoherence(aec, efw, dfw, xfw, fft, cohde, cohxd, 1018 WebRtcAec_SubbandCoherence(aec, efw, dfw, xfw, fft, cohde, cohxd,
1051 &aec->extreme_filter_divergence); 1019 &aec->extreme_filter_divergence);
1052 1020
1053 // Select the microphone signal as output if the filter is deemed to have 1021 // Select the microphone signal as output if the filter is deemed to have
1054 // diverged. 1022 // diverged.
1055 if (aec->divergeState) { 1023 if (aec->divergeState) {
1056 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); 1024 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1);
1057 } 1025 }
(...skipping 30 matching lines...) Expand all
1088 hNlFb = hNlDeAvg; 1056 hNlFb = hNlDeAvg;
1089 hNlFbLow = hNlDeAvg; 1057 hNlFbLow = hNlDeAvg;
1090 } else { 1058 } else {
1091 for (i = 0; i < PART_LEN1; i++) { 1059 for (i = 0; i < PART_LEN1; i++) {
1092 hNl[i] = 1 - cohxd[i]; 1060 hNl[i] = 1 - cohxd[i];
1093 } 1061 }
1094 hNlFb = hNlXdAvg; 1062 hNlFb = hNlXdAvg;
1095 hNlFbLow = hNlXdAvg; 1063 hNlFbLow = hNlXdAvg;
1096 } 1064 }
1097 } else { 1065 } else {
1098
1099 if (aec->stNearState == 1) { 1066 if (aec->stNearState == 1) {
1100 aec->echoState = 0; 1067 aec->echoState = 0;
1101 memcpy(hNl, cohde, sizeof(hNl)); 1068 memcpy(hNl, cohde, sizeof(hNl));
1102 hNlFb = hNlDeAvg; 1069 hNlFb = hNlDeAvg;
1103 hNlFbLow = hNlDeAvg; 1070 hNlFbLow = hNlDeAvg;
1104 } else { 1071 } else {
1105 aec->echoState = 1; 1072 aec->echoState = 1;
1106 for (i = 0; i < PART_LEN1; i++) { 1073 for (i = 0; i < PART_LEN1; i++) {
1107 hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]); 1074 hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]);
1108 } 1075 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 // scaling only in UpdateMetrics(). 1130 // scaling only in UpdateMetrics().
1164 UpdateLevel(&aec->nlpoutlevel, CalculatePower(fft, PART_LEN2)); 1131 UpdateLevel(&aec->nlpoutlevel, CalculatePower(fft, PART_LEN2));
1165 } 1132 }
1166 1133
1167 // Overlap and add to obtain output. 1134 // Overlap and add to obtain output.
1168 for (i = 0; i < PART_LEN; i++) { 1135 for (i = 0; i < PART_LEN; i++) {
1169 output[i] = (fft[i] * WebRtcAec_sqrtHanning[i] + 1136 output[i] = (fft[i] * WebRtcAec_sqrtHanning[i] +
1170 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]); 1137 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]);
1171 1138
1172 // Saturate output to keep it in the allowed range. 1139 // Saturate output to keep it in the allowed range.
1173 output[i] = WEBRTC_SPL_SAT( 1140 output[i] =
1174 WEBRTC_SPL_WORD16_MAX, output[i], WEBRTC_SPL_WORD16_MIN); 1141 WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, output[i], WEBRTC_SPL_WORD16_MIN);
1175 } 1142 }
1176 memcpy(aec->outBuf, &fft[PART_LEN], PART_LEN * sizeof(aec->outBuf[0])); 1143 memcpy(aec->outBuf, &fft[PART_LEN], PART_LEN * sizeof(aec->outBuf[0]));
1177 1144
1178 // For H band 1145 // For H band
1179 if (aec->num_bands > 1) { 1146 if (aec->num_bands > 1) {
1180 // H band gain 1147 // H band gain
1181 // average nlp over low band: average over second half of freq spectrum 1148 // average nlp over low band: average over second half of freq spectrum
1182 // (4->8khz) 1149 // (4->8khz)
1183 GetHighbandGain(hNl, &nlpGainHband); 1150 GetHighbandGain(hNl, &nlpGainHband);
1184 1151
1185 // Inverse comfort_noise 1152 // Inverse comfort_noise
1186 ScaledInverseFft(comfortNoiseHband, fft, 2.0f, 0); 1153 ScaledInverseFft(comfortNoiseHband, fft, 2.0f, 0);
1187 1154
1188 // compute gain factor 1155 // compute gain factor
1189 for (j = 0; j < aec->num_bands - 1; ++j) { 1156 for (j = 0; j < aec->num_bands - 1; ++j) {
1190 for (i = 0; i < PART_LEN; i++) { 1157 for (i = 0; i < PART_LEN; i++) {
1191 outputH[j][i] = aec->dBufH[j][i] * nlpGainHband; 1158 outputH[j][i] = aec->dBufH[j][i] * nlpGainHband;
1192 } 1159 }
1193 } 1160 }
1194 1161
1195 // Add some comfort noise where Hband is attenuated. 1162 // Add some comfort noise where Hband is attenuated.
1196 for (i = 0; i < PART_LEN; i++) { 1163 for (i = 0; i < PART_LEN; i++) {
1197 outputH[0][i] += cnScaleHband * fft[i]; 1164 outputH[0][i] += cnScaleHband * fft[i];
1198 } 1165 }
1199 1166
1200 // Saturate output to keep it in the allowed range. 1167 // Saturate output to keep it in the allowed range.
1201 for (j = 0; j < aec->num_bands - 1; ++j) { 1168 for (j = 0; j < aec->num_bands - 1; ++j) {
1202 for (i = 0; i < PART_LEN; i++) { 1169 for (i = 0; i < PART_LEN; i++) {
1203 outputH[j][i] = WEBRTC_SPL_SAT( 1170 outputH[j][i] = WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, outputH[j][i],
1204 WEBRTC_SPL_WORD16_MAX, outputH[j][i], WEBRTC_SPL_WORD16_MIN); 1171 WEBRTC_SPL_WORD16_MIN);
1205 } 1172 }
1206 } 1173 }
1207
1208 } 1174 }
1209 1175
1210 // Copy the current block to the old position. 1176 // Copy the current block to the old position.
1211 memcpy(aec->dBuf, aec->dBuf + PART_LEN, sizeof(float) * PART_LEN); 1177 memcpy(aec->dBuf, aec->dBuf + PART_LEN, sizeof(float) * PART_LEN);
1212 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN); 1178 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN);
1213 1179
1214 // Copy the current block to the old position for H band 1180 // Copy the current block to the old position for H band
1215 for (j = 0; j < aec->num_bands - 1; ++j) { 1181 for (j = 0; j < aec->num_bands - 1; ++j) {
1216 memcpy(aec->dBufH[j], aec->dBufH[j] + PART_LEN, sizeof(float) * PART_LEN); 1182 memcpy(aec->dBufH[j], aec->dBufH[j] + PART_LEN, sizeof(float) * PART_LEN);
1217 } 1183 }
1218 1184
1219 memmove(aec->xfwBuf + PART_LEN1, 1185 memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf,
1220 aec->xfwBuf,
1221 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); 1186 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1);
1222 } 1187 }
1223 1188
1224 static void ProcessBlock(AecCore* aec) { 1189 static void ProcessBlock(AecCore* aec) {
1225 size_t i; 1190 size_t i;
1226 1191
1227 float fft[PART_LEN2]; 1192 float fft[PART_LEN2];
1228 float xf[2][PART_LEN1]; 1193 float xf[2][PART_LEN1];
1229 float df[2][PART_LEN1]; 1194 float df[2][PART_LEN1];
1230 float far_spectrum = 0.0f; 1195 float far_spectrum = 0.0f;
(...skipping 18 matching lines...) Expand all
1249 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; 1214 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN];
1250 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; 1215 float* outputH_ptr[NUM_HIGH_BANDS_MAX];
1251 float* xf_ptr = NULL; 1216 float* xf_ptr = NULL;
1252 1217
1253 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { 1218 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) {
1254 outputH_ptr[i] = outputH[i]; 1219 outputH_ptr[i] = outputH[i];
1255 } 1220 }
1256 1221
1257 // Concatenate old and new nearend blocks. 1222 // Concatenate old and new nearend blocks.
1258 for (i = 0; i < aec->num_bands - 1; ++i) { 1223 for (i = 0; i < aec->num_bands - 1; ++i) {
1259 WebRtc_ReadBuffer(aec->nearFrBufH[i], 1224 WebRtc_ReadBuffer(aec->nearFrBufH[i], (void**)&nearend_ptr, nearend,
1260 (void**)&nearend_ptr,
1261 nearend,
1262 PART_LEN); 1225 PART_LEN);
1263 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); 1226 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend));
1264 } 1227 }
1265 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN); 1228 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN);
1266 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend)); 1229 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend));
1267 1230
1268 // We should always have at least one element stored in |far_buf|. 1231 // We should always have at least one element stored in |far_buf|.
1269 assert(WebRtc_available_read(aec->far_time_buf) > 0); 1232 assert(WebRtc_available_read(aec->far_time_buf) > 0);
1270 WebRtc_ReadBuffer(aec->far_time_buf, (void**)&farend_ptr, farend, 1); 1233 WebRtc_ReadBuffer(aec->far_time_buf, (void**)&farend_ptr, farend, 1);
1271 1234
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1333 aec->dInitMinPow[i] = aec->dMinPow[i]; 1296 aec->dInitMinPow[i] = aec->dMinPow[i];
1334 } 1297 }
1335 } 1298 }
1336 aec->noisePow = aec->dInitMinPow; 1299 aec->noisePow = aec->dInitMinPow;
1337 } else { 1300 } else {
1338 aec->noisePow = aec->dMinPow; 1301 aec->noisePow = aec->dMinPow;
1339 } 1302 }
1340 1303
1341 // Block wise delay estimation used for logging 1304 // Block wise delay estimation used for logging
1342 if (aec->delay_logging_enabled) { 1305 if (aec->delay_logging_enabled) {
1343 if (WebRtc_AddFarSpectrumFloat( 1306 if (WebRtc_AddFarSpectrumFloat(aec->delay_estimator_farend,
1344 aec->delay_estimator_farend, abs_far_spectrum, PART_LEN1) == 0) { 1307 abs_far_spectrum, PART_LEN1) == 0) {
1345 int delay_estimate = WebRtc_DelayEstimatorProcessFloat( 1308 int delay_estimate = WebRtc_DelayEstimatorProcessFloat(
1346 aec->delay_estimator, abs_near_spectrum, PART_LEN1); 1309 aec->delay_estimator, abs_near_spectrum, PART_LEN1);
1347 if (delay_estimate >= 0) { 1310 if (delay_estimate >= 0) {
1348 // Update delay estimate buffer. 1311 // Update delay estimate buffer.
1349 aec->delay_histogram[delay_estimate]++; 1312 aec->delay_histogram[delay_estimate]++;
1350 aec->num_delay_values++; 1313 aec->num_delay_values++;
1351 } 1314 }
1352 if (aec->delay_metrics_delivered == 1 && 1315 if (aec->delay_metrics_delivered == 1 &&
1353 aec->num_delay_values >= kDelayMetricsAggregationWindow) { 1316 aec->num_delay_values >= kDelayMetricsAggregationWindow) {
1354 UpdateDelayMetrics(aec); 1317 UpdateDelayMetrics(aec);
1355 } 1318 }
1356 } 1319 }
1357 } 1320 }
1358 1321
1359 // Update the xfBuf block position. 1322 // Update the xfBuf block position.
1360 aec->xfBufBlockPos--; 1323 aec->xfBufBlockPos--;
1361 if (aec->xfBufBlockPos == -1) { 1324 if (aec->xfBufBlockPos == -1) {
1362 aec->xfBufBlockPos = aec->num_partitions - 1; 1325 aec->xfBufBlockPos = aec->num_partitions - 1;
1363 } 1326 }
1364 1327
1365 // Buffer xf 1328 // Buffer xf
1366 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, 1329 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, xf_ptr,
1367 xf_ptr,
1368 sizeof(float) * PART_LEN1); 1330 sizeof(float) * PART_LEN1);
1369 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, 1331 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, &xf_ptr[PART_LEN1],
1370 &xf_ptr[PART_LEN1],
1371 sizeof(float) * PART_LEN1); 1332 sizeof(float) * PART_LEN1);
1372 1333
1373 // Perform echo subtraction. 1334 // Perform echo subtraction.
1374 EchoSubtraction(aec, 1335 EchoSubtraction(aec, aec->num_partitions, aec->xfBufBlockPos,
1375 aec->num_partitions, 1336 aec->metricsMode, aec->extended_filter_enabled,
1376 aec->xfBufBlockPos, 1337 aec->normal_mu, aec->normal_error_threshold, aec->xfBuf,
1377 aec->metricsMode, 1338 nearend_ptr, aec->xPow, aec->wfBuf, &aec->linoutlevel,
1378 aec->extended_filter_enabled,
1379 aec->normal_mu,
1380 aec->normal_error_threshold,
1381 aec->xfBuf,
1382 nearend_ptr,
1383 aec->xPow,
1384 aec->wfBuf,
1385 &aec->linoutlevel,
1386 echo_subtractor_output); 1339 echo_subtractor_output);
1387 1340
1388 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); 1341 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN);
1389 1342
1390 // Perform echo suppression. 1343 // Perform echo suppression.
1391 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr); 1344 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr);
1392 1345
1393 if (aec->metricsMode == 1) { 1346 if (aec->metricsMode == 1) {
1394 UpdateMetrics(aec); 1347 UpdateMetrics(aec);
1395 } 1348 }
(...skipping 21 matching lines...) Expand all
1417 return NULL; 1370 return NULL;
1418 } 1371 }
1419 1372
1420 aec->outFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); 1373 aec->outFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1421 if (!aec->outFrBuf) { 1374 if (!aec->outFrBuf) {
1422 WebRtcAec_FreeAec(aec); 1375 WebRtcAec_FreeAec(aec);
1423 return NULL; 1376 return NULL;
1424 } 1377 }
1425 1378
1426 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { 1379 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) {
1427 aec->nearFrBufH[i] = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, 1380 aec->nearFrBufH[i] =
1428 sizeof(float)); 1381 WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1429 if (!aec->nearFrBufH[i]) { 1382 if (!aec->nearFrBufH[i]) {
1430 WebRtcAec_FreeAec(aec); 1383 WebRtcAec_FreeAec(aec);
1431 return NULL; 1384 return NULL;
1432 } 1385 }
1433 aec->outFrBufH[i] = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, 1386 aec->outFrBufH[i] =
1434 sizeof(float)); 1387 WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1435 if (!aec->outFrBufH[i]) { 1388 if (!aec->outFrBufH[i]) {
1436 WebRtcAec_FreeAec(aec); 1389 WebRtcAec_FreeAec(aec);
1437 return NULL; 1390 return NULL;
1438 } 1391 }
1439 } 1392 }
1440 1393
1441 // Create far-end buffers. 1394 // Create far-end buffers.
1442 // For bit exactness with legacy code, each element in |far_time_buf| is 1395 // For bit exactness with legacy code, each element in |far_time_buf| is
1443 // supposed to contain |PART_LEN2| samples with an overlap of |PART_LEN| 1396 // supposed to contain |PART_LEN2| samples with an overlap of |PART_LEN|
1444 // samples from the last frame. 1397 // samples from the last frame.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1485 WebRtcAec_FilterFar = FilterFar; 1438 WebRtcAec_FilterFar = FilterFar;
1486 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; 1439 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal;
1487 WebRtcAec_FilterAdaptation = FilterAdaptation; 1440 WebRtcAec_FilterAdaptation = FilterAdaptation;
1488 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; 1441 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress;
1489 WebRtcAec_ComfortNoise = ComfortNoise; 1442 WebRtcAec_ComfortNoise = ComfortNoise;
1490 WebRtcAec_SubbandCoherence = SubbandCoherence; 1443 WebRtcAec_SubbandCoherence = SubbandCoherence;
1491 WebRtcAec_StoreAsComplex = StoreAsComplex; 1444 WebRtcAec_StoreAsComplex = StoreAsComplex;
1492 WebRtcAec_PartitionDelay = PartitionDelay; 1445 WebRtcAec_PartitionDelay = PartitionDelay;
1493 WebRtcAec_WindowData = WindowData; 1446 WebRtcAec_WindowData = WindowData;
1494 1447
1495
1496 #if defined(WEBRTC_ARCH_X86_FAMILY) 1448 #if defined(WEBRTC_ARCH_X86_FAMILY)
1497 if (WebRtc_GetCPUInfo(kSSE2)) { 1449 if (WebRtc_GetCPUInfo(kSSE2)) {
1498 WebRtcAec_InitAec_SSE2(); 1450 WebRtcAec_InitAec_SSE2();
1499 } 1451 }
1500 #endif 1452 #endif
1501 1453
1502 #if defined(MIPS_FPU_LE) 1454 #if defined(MIPS_FPU_LE)
1503 WebRtcAec_InitAec_mips(); 1455 WebRtcAec_InitAec_mips();
1504 #endif 1456 #endif
1505 1457
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1567 } 1519 }
1568 1520
1569 // Initialize far-end buffers. 1521 // Initialize far-end buffers.
1570 WebRtc_InitBuffer(aec->far_time_buf); 1522 WebRtc_InitBuffer(aec->far_time_buf);
1571 1523
1572 #ifdef WEBRTC_AEC_DEBUG_DUMP 1524 #ifdef WEBRTC_AEC_DEBUG_DUMP
1573 { 1525 {
1574 int process_rate = sampFreq > 16000 ? 16000 : sampFreq; 1526 int process_rate = sampFreq > 16000 ? 16000 : sampFreq;
1575 RTC_AEC_DEBUG_WAV_REOPEN("aec_far", aec->instance_index, 1527 RTC_AEC_DEBUG_WAV_REOPEN("aec_far", aec->instance_index,
1576 aec->debug_dump_count, process_rate, 1528 aec->debug_dump_count, process_rate,
1577 &aec->farFile ); 1529 &aec->farFile);
1578 RTC_AEC_DEBUG_WAV_REOPEN("aec_near", aec->instance_index, 1530 RTC_AEC_DEBUG_WAV_REOPEN("aec_near", aec->instance_index,
1579 aec->debug_dump_count, process_rate, 1531 aec->debug_dump_count, process_rate,
1580 &aec->nearFile); 1532 &aec->nearFile);
1581 RTC_AEC_DEBUG_WAV_REOPEN("aec_out", aec->instance_index, 1533 RTC_AEC_DEBUG_WAV_REOPEN("aec_out", aec->instance_index,
1582 aec->debug_dump_count, process_rate, 1534 aec->debug_dump_count, process_rate,
1583 &aec->outFile ); 1535 &aec->outFile);
1584 RTC_AEC_DEBUG_WAV_REOPEN("aec_out_linear", aec->instance_index, 1536 RTC_AEC_DEBUG_WAV_REOPEN("aec_out_linear", aec->instance_index,
1585 aec->debug_dump_count, process_rate, 1537 aec->debug_dump_count, process_rate,
1586 &aec->outLinearFile); 1538 &aec->outLinearFile);
1587 } 1539 }
1588 1540
1589 RTC_AEC_DEBUG_RAW_OPEN("aec_e_fft", 1541 RTC_AEC_DEBUG_RAW_OPEN("aec_e_fft", aec->debug_dump_count, &aec->e_fft_file);
1590 aec->debug_dump_count,
1591 &aec->e_fft_file);
1592 1542
1593 ++aec->debug_dump_count; 1543 ++aec->debug_dump_count;
1594 #endif 1544 #endif
1595 aec->system_delay = 0; 1545 aec->system_delay = 0;
1596 1546
1597 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) { 1547 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) {
1598 return -1; 1548 return -1;
1599 } 1549 }
1600 if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) { 1550 if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) {
1601 return -1; 1551 return -1;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 } 1617 }
1668 1618
1669 // Holds the last block written to 1619 // Holds the last block written to
1670 aec->xfBufBlockPos = 0; 1620 aec->xfBufBlockPos = 0;
1671 // TODO: Investigate need for these initializations. Deleting them doesn't 1621 // TODO: Investigate need for these initializations. Deleting them doesn't
1672 // change the output at all and yields 0.4% overall speedup. 1622 // change the output at all and yields 0.4% overall speedup.
1673 memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); 1623 memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
1674 memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); 1624 memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
1675 memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1); 1625 memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1);
1676 memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1); 1626 memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1);
1677 memset( 1627 memset(aec->xfwBuf, 0,
1678 aec->xfwBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); 1628 sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
1679 memset(aec->se, 0, sizeof(float) * PART_LEN1); 1629 memset(aec->se, 0, sizeof(float) * PART_LEN1);
1680 1630
1681 // To prevent numerical instability in the first block. 1631 // To prevent numerical instability in the first block.
1682 for (i = 0; i < PART_LEN1; i++) { 1632 for (i = 0; i < PART_LEN1; i++) {
1683 aec->sd[i] = 1; 1633 aec->sd[i] = 1;
1684 } 1634 }
1685 for (i = 0; i < PART_LEN1; i++) { 1635 for (i = 0; i < PART_LEN1; i++) {
1686 aec->sx[i] = 1; 1636 aec->sx[i] = 1;
1687 } 1637 }
1688 1638
(...skipping 17 matching lines...) Expand all
1706 1656
1707 aec->extreme_filter_divergence = 0; 1657 aec->extreme_filter_divergence = 0;
1708 1658
1709 // Metrics disabled by default 1659 // Metrics disabled by default
1710 aec->metricsMode = 0; 1660 aec->metricsMode = 0;
1711 InitMetrics(aec); 1661 InitMetrics(aec);
1712 1662
1713 return 0; 1663 return 0;
1714 } 1664 }
1715 1665
1716
1717 // For bit exactness with a legacy code, |farend| is supposed to contain 1666 // For bit exactness with a legacy code, |farend| is supposed to contain
1718 // |PART_LEN2| samples with an overlap of |PART_LEN| samples from the last 1667 // |PART_LEN2| samples with an overlap of |PART_LEN| samples from the last
1719 // frame. 1668 // frame.
1720 // TODO(minyue): reduce |farend| to non-overlapped |PART_LEN| samples. 1669 // TODO(minyue): reduce |farend| to non-overlapped |PART_LEN| samples.
1721 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) { 1670 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) {
1722 // Check if the buffer is full, and in that case flush the oldest data. 1671 // Check if the buffer is full, and in that case flush the oldest data.
1723 if (WebRtc_available_write(aec->far_time_buf) < 1) { 1672 if (WebRtc_available_write(aec->far_time_buf) < 1) {
1724 WebRtcAec_MoveFarReadPtr(aec, 1); 1673 WebRtcAec_MoveFarReadPtr(aec, 1);
1725 } 1674 }
1726 1675
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1765 // give a guess on how much we need to shift far-end buffers to align with 1714 // give a guess on how much we need to shift far-end buffers to align with
1766 // the near-end signal. The other delay estimation algorithm uses the 1715 // the near-end signal. The other delay estimation algorithm uses the
1767 // far- and near-end signals to find the offset between them. This one 1716 // far- and near-end signals to find the offset between them. This one
1768 // (called "signal delay") is then used to fine tune the alignment, or 1717 // (called "signal delay") is then used to fine tune the alignment, or
1769 // simply compensate for errors in the system based one. 1718 // simply compensate for errors in the system based one.
1770 // Note that the two algorithms operate independently. Currently, we only 1719 // Note that the two algorithms operate independently. Currently, we only
1771 // allow one algorithm to be turned on. 1720 // allow one algorithm to be turned on.
1772 1721
1773 assert(aec->num_bands == num_bands); 1722 assert(aec->num_bands == num_bands);
1774 1723
1775 for (j = 0; j < num_samples; j+= FRAME_LEN) { 1724 for (j = 0; j < num_samples; j += FRAME_LEN) {
1776 // TODO(bjornv): Change the near-end buffer handling to be the same as for 1725 // TODO(bjornv): Change the near-end buffer handling to be the same as for
1777 // far-end, that is, with a near_pre_buf. 1726 // far-end, that is, with a near_pre_buf.
1778 // Buffer the near-end frame. 1727 // Buffer the near-end frame.
1779 WebRtc_WriteBuffer(aec->nearFrBuf, &nearend[0][j], FRAME_LEN); 1728 WebRtc_WriteBuffer(aec->nearFrBuf, &nearend[0][j], FRAME_LEN);
1780 // For H band 1729 // For H band
1781 for (i = 1; i < num_bands; ++i) { 1730 for (i = 1; i < num_bands; ++i) {
1782 WebRtc_WriteBuffer(aec->nearFrBufH[i - 1], &nearend[i][j], FRAME_LEN); 1731 WebRtc_WriteBuffer(aec->nearFrBufH[i - 1], &nearend[i][j], FRAME_LEN);
1783 } 1732 }
1784 1733
1785 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we 1734 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we
1786 // have enough far-end data for that by stuffing the buffer if the 1735 // have enough far-end data for that by stuffing the buffer if the
1787 // |system_delay| indicates others. 1736 // |system_delay| indicates others.
1788 if (aec->system_delay < FRAME_LEN) { 1737 if (aec->system_delay < FRAME_LEN) {
1789 // We don't have enough data so we rewind 10 ms. 1738 // We don't have enough data so we rewind 10 ms.
1790 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1)); 1739 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1));
1791 } 1740 }
1792 1741
1793 if (!aec->delay_agnostic_enabled) { 1742 if (!aec->delay_agnostic_enabled) {
1794 // 2 a) Compensate for a possible change in the system delay. 1743 // 2 a) Compensate for a possible change in the system delay.
1795 1744
1796 // TODO(bjornv): Investigate how we should round the delay difference; 1745 // TODO(bjornv): Investigate how we should round the delay difference;
1797 // right now we know that incoming |knownDelay| is underestimated when 1746 // right now we know that incoming |knownDelay| is underestimated when
1798 // it's less than |aec->knownDelay|. We therefore, round (-32) in that 1747 // it's less than |aec->knownDelay|. We therefore, round (-32) in that
1799 // direction. In the other direction, we don't have this situation, but 1748 // direction. In the other direction, we don't have this situation, but
1800 // might flush one partition too little. This can cause non-causality, 1749 // might flush one partition too little. This can cause non-causality,
1801 // which should be investigated. Maybe, allow for a non-symmetric 1750 // which should be investigated. Maybe, allow for a non-symmetric
1802 // rounding, like -16. 1751 // rounding, like -16.
1803 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN; 1752 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN;
1804 int moved_elements = 1753 int moved_elements = WebRtc_MoveReadPtr(aec->far_time_buf, move_elements);
1805 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements);
1806 aec->knownDelay -= moved_elements * PART_LEN; 1754 aec->knownDelay -= moved_elements * PART_LEN;
1807 } else { 1755 } else {
1808 // 2 b) Apply signal based delay correction. 1756 // 2 b) Apply signal based delay correction.
1809 int move_elements = SignalBasedDelayCorrection(aec); 1757 int move_elements = SignalBasedDelayCorrection(aec);
1810 int moved_elements = 1758 int moved_elements = WebRtc_MoveReadPtr(aec->far_time_buf, move_elements);
1811 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); 1759 int far_near_buffer_diff =
1812 int far_near_buffer_diff = WebRtc_available_read(aec->far_time_buf) - 1760 WebRtc_available_read(aec->far_time_buf) -
1813 WebRtc_available_read(aec->nearFrBuf) / PART_LEN; 1761 WebRtc_available_read(aec->nearFrBuf) / PART_LEN;
1814 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); 1762 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements);
1815 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, 1763 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend,
1816 moved_elements); 1764 moved_elements);
1817 aec->signal_delay_correction += moved_elements; 1765 aec->signal_delay_correction += moved_elements;
1818 // If we rely on reported system delay values only, a buffer underrun here 1766 // If we rely on reported system delay values only, a buffer underrun here
1819 // can never occur since we've taken care of that in 1) above. Here, we 1767 // can never occur since we've taken care of that in 1) above. Here, we
1820 // apply signal based delay correction and can therefore end up with 1768 // apply signal based delay correction and can therefore end up with
1821 // buffer underruns since the delay estimation can be wrong. We therefore 1769 // buffer underruns since the delay estimation can be wrong. We therefore
1822 // stuff the buffer with enough elements if needed. 1770 // stuff the buffer with enough elements if needed.
(...skipping 22 matching lines...) Expand all
1845 } 1793 }
1846 // Obtain an output frame. 1794 // Obtain an output frame.
1847 WebRtc_ReadBuffer(aec->outFrBuf, NULL, &out[0][j], FRAME_LEN); 1795 WebRtc_ReadBuffer(aec->outFrBuf, NULL, &out[0][j], FRAME_LEN);
1848 // For H bands. 1796 // For H bands.
1849 for (i = 1; i < num_bands; ++i) { 1797 for (i = 1; i < num_bands; ++i) {
1850 WebRtc_ReadBuffer(aec->outFrBufH[i - 1], NULL, &out[i][j], FRAME_LEN); 1798 WebRtc_ReadBuffer(aec->outFrBufH[i - 1], NULL, &out[i][j], FRAME_LEN);
1851 } 1799 }
1852 } 1800 }
1853 } 1801 }
1854 1802
1855 int WebRtcAec_GetDelayMetricsCore(AecCore* self, int* median, int* std, 1803 int WebRtcAec_GetDelayMetricsCore(AecCore* self,
1804 int* median,
1805 int* std,
1856 float* fraction_poor_delays) { 1806 float* fraction_poor_delays) {
1857 assert(self != NULL); 1807 assert(self != NULL);
1858 assert(median != NULL); 1808 assert(median != NULL);
1859 assert(std != NULL); 1809 assert(std != NULL);
1860 1810
1861 if (self->delay_logging_enabled == 0) { 1811 if (self->delay_logging_enabled == 0) {
1862 // Logging disabled. 1812 // Logging disabled.
1863 return -1; 1813 return -1;
1864 } 1814 }
1865 1815
1866 if (self->delay_metrics_delivered == 0) { 1816 if (self->delay_metrics_delivered == 0) {
1867 UpdateDelayMetrics(self); 1817 UpdateDelayMetrics(self);
1868 self->delay_metrics_delivered = 1; 1818 self->delay_metrics_delivered = 1;
1869 } 1819 }
1870 *median = self->delay_median; 1820 *median = self->delay_median;
1871 *std = self->delay_std; 1821 *std = self->delay_std;
1872 *fraction_poor_delays = self->fraction_poor_delays; 1822 *fraction_poor_delays = self->fraction_poor_delays;
1873 1823
1874 return 0; 1824 return 0;
1875 } 1825 }
1876 1826
1877 int WebRtcAec_echo_state(AecCore* self) { return self->echoState; } 1827 int WebRtcAec_echo_state(AecCore* self) {
1828 return self->echoState;
1829 }
1878 1830
1879 void WebRtcAec_GetEchoStats(AecCore* self, 1831 void WebRtcAec_GetEchoStats(AecCore* self,
1880 Stats* erl, 1832 Stats* erl,
1881 Stats* erle, 1833 Stats* erle,
1882 Stats* a_nlp) { 1834 Stats* a_nlp) {
1883 assert(erl != NULL); 1835 assert(erl != NULL);
1884 assert(erle != NULL); 1836 assert(erle != NULL);
1885 assert(a_nlp != NULL); 1837 assert(a_nlp != NULL);
1886 *erl = self->erl; 1838 *erl = self->erl;
1887 *erle = self->erle; 1839 *erle = self->erle;
(...skipping 30 matching lines...) Expand all
1918 self->extended_filter_enabled = enable; 1870 self->extended_filter_enabled = enable;
1919 self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions; 1871 self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions;
1920 // Update the delay estimator with filter length. See InitAEC() for details. 1872 // Update the delay estimator with filter length. See InitAEC() for details.
1921 WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2); 1873 WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2);
1922 } 1874 }
1923 1875
1924 int WebRtcAec_extended_filter_enabled(AecCore* self) { 1876 int WebRtcAec_extended_filter_enabled(AecCore* self) {
1925 return self->extended_filter_enabled; 1877 return self->extended_filter_enabled;
1926 } 1878 }
1927 1879
1928 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } 1880 int WebRtcAec_system_delay(AecCore* self) {
1881 return self->system_delay;
1882 }
1929 1883
1930 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 1884 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
1931 assert(delay >= 0); 1885 assert(delay >= 0);
1932 self->system_delay = delay; 1886 self->system_delay = delay;
1933 } 1887 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698