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

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

Issue 1499573003: Some minor (bitexact) AEC echo suppressor refactoring (#2) (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@ESUP_refactoring_CL
Patch Set: Corrected the positions of the pointer indicators Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | webrtc/modules/audio_processing/aec/aec_core_internal.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 // Threshold to protect against the ill-effects of a zero far-end. 320 // Threshold to protect against the ill-effects of a zero far-end.
321 const float WebRtcAec_kMinFarendPSD = 15; 321 const float WebRtcAec_kMinFarendPSD = 15;
322 322
323 // Updates the following smoothed Power Spectral Densities (PSD): 323 // Updates the following smoothed Power Spectral Densities (PSD):
324 // - sd : near-end 324 // - sd : near-end
325 // - se : residual echo 325 // - se : residual echo
326 // - sx : far-end 326 // - sx : far-end
327 // - sde : cross-PSD of near-end and residual echo 327 // - sde : cross-PSD of near-end and residual echo
328 // - sxd : cross-PSD of near-end and far-end 328 // - sxd : cross-PSD of near-end and far-end
329 // 329 //
330 // In addition to updating the PSDs, also the filter diverge state is determined 330 // In addition to updating the PSDs, also the filter diverge state is
331 // upon actions are taken. 331 // determined.
332 static void SmoothedPSD(AecCore* aec, 332 static void SmoothedPSD(AecCore* aec,
333 float efw[2][PART_LEN1], 333 float efw[2][PART_LEN1],
334 float dfw[2][PART_LEN1], 334 float dfw[2][PART_LEN1],
335 float xfw[2][PART_LEN1]) { 335 float xfw[2][PART_LEN1],
336 int* extreme_filter_divergence) {
336 // Power estimate smoothing coefficients. 337 // Power estimate smoothing coefficients.
337 const float* ptrGCoh = aec->extended_filter_enabled 338 const float* ptrGCoh = aec->extended_filter_enabled
338 ? WebRtcAec_kExtendedSmoothingCoefficients[aec->mult - 1] 339 ? WebRtcAec_kExtendedSmoothingCoefficients[aec->mult - 1]
339 : WebRtcAec_kNormalSmoothingCoefficients[aec->mult - 1]; 340 : WebRtcAec_kNormalSmoothingCoefficients[aec->mult - 1];
340 int i; 341 int i;
341 float sdSum = 0, seSum = 0; 342 float sdSum = 0, seSum = 0;
342 343
343 for (i = 0; i < PART_LEN1; i++) { 344 for (i = 0; i < PART_LEN1; i++) {
344 aec->sd[i] = ptrGCoh[0] * aec->sd[i] + 345 aec->sd[i] = ptrGCoh[0] * aec->sd[i] +
345 ptrGCoh[1] * (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]); 346 ptrGCoh[1] * (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]);
(...skipping 20 matching lines...) Expand all
366 ptrGCoh[0] * aec->sxd[i][0] + 367 ptrGCoh[0] * aec->sxd[i][0] +
367 ptrGCoh[1] * (dfw[0][i] * xfw[0][i] + dfw[1][i] * xfw[1][i]); 368 ptrGCoh[1] * (dfw[0][i] * xfw[0][i] + dfw[1][i] * xfw[1][i]);
368 aec->sxd[i][1] = 369 aec->sxd[i][1] =
369 ptrGCoh[0] * aec->sxd[i][1] + 370 ptrGCoh[0] * aec->sxd[i][1] +
370 ptrGCoh[1] * (dfw[0][i] * xfw[1][i] - dfw[1][i] * xfw[0][i]); 371 ptrGCoh[1] * (dfw[0][i] * xfw[1][i] - dfw[1][i] * xfw[0][i]);
371 372
372 sdSum += aec->sd[i]; 373 sdSum += aec->sd[i];
373 seSum += aec->se[i]; 374 seSum += aec->se[i];
374 } 375 }
375 376
376 // Divergent filter safeguard. 377 // Divergent filter safeguard update.
377 aec->divergeState = (aec->divergeState ? 1.05f : 1.0f) * seSum > sdSum; 378 aec->divergeState = (aec->divergeState ? 1.05f : 1.0f) * seSum > sdSum;
378 379
379 if (aec->divergeState) 380 // Signal extreme filter divergence if the error is significantly larger
380 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); 381 // than the nearend (13 dB).
381 382 *extreme_filter_divergence = (seSum > (19.95f * sdSum));
382 // Reset if error is significantly larger than nearend (13 dB).
383 if (!aec->extended_filter_enabled && seSum > (19.95f * sdSum))
384 memset(aec->wfBuf, 0, sizeof(aec->wfBuf));
385 } 383 }
386 384
387 // Window time domain data to be used by the fft. 385 // Window time domain data to be used by the fft.
388 __inline static void WindowData(float* x_windowed, const float* x) { 386 __inline static void WindowData(float* x_windowed, const float* x) {
389 int i; 387 int i;
390 for (i = 0; i < PART_LEN; i++) { 388 for (i = 0; i < PART_LEN; i++) {
391 x_windowed[i] = x[i] * WebRtcAec_sqrtHanning[i]; 389 x_windowed[i] = x[i] * WebRtcAec_sqrtHanning[i];
392 x_windowed[PART_LEN + i] = 390 x_windowed[PART_LEN + i] =
393 x[PART_LEN + i] * WebRtcAec_sqrtHanning[PART_LEN - i]; 391 x[PART_LEN + i] * WebRtcAec_sqrtHanning[PART_LEN - i];
394 } 392 }
(...skipping 12 matching lines...) Expand all
407 data_complex[0][PART_LEN] = data[1]; 405 data_complex[0][PART_LEN] = data[1];
408 data_complex[1][PART_LEN] = 0; 406 data_complex[1][PART_LEN] = 0;
409 } 407 }
410 408
411 static void SubbandCoherence(AecCore* aec, 409 static void SubbandCoherence(AecCore* aec,
412 float efw[2][PART_LEN1], 410 float efw[2][PART_LEN1],
413 float dfw[2][PART_LEN1], 411 float dfw[2][PART_LEN1],
414 float xfw[2][PART_LEN1], 412 float xfw[2][PART_LEN1],
415 float* fft, 413 float* fft,
416 float* cohde, 414 float* cohde,
417 float* cohxd) { 415 float* cohxd,
416 int* extreme_filter_divergence) {
418 int i; 417 int i;
419 418
420 SmoothedPSD(aec, efw, dfw, xfw); 419 SmoothedPSD(aec, efw, dfw, xfw, extreme_filter_divergence);
421 420
422 // Subband coherence 421 // Subband coherence
423 for (i = 0; i < PART_LEN1; i++) { 422 for (i = 0; i < PART_LEN1; i++) {
424 cohde[i] = 423 cohde[i] =
425 (aec->sde[i][0] * aec->sde[i][0] + aec->sde[i][1] * aec->sde[i][1]) / 424 (aec->sde[i][0] * aec->sde[i][0] + aec->sde[i][1] * aec->sde[i][1]) /
426 (aec->sd[i] * aec->se[i] + 1e-10f); 425 (aec->sd[i] * aec->se[i] + 1e-10f);
427 cohxd[i] = 426 cohxd[i] =
428 (aec->sxd[i][0] * aec->sxd[i][0] + aec->sxd[i][1] * aec->sxd[i][1]) / 427 (aec->sxd[i][0] * aec->sxd[i][0] + aec->sxd[i][1] * aec->sxd[i][1]) /
429 (aec->sx[i] * aec->sd[i] + 1e-10f); 428 (aec->sx[i] * aec->sd[i] + 1e-10f);
430 } 429 }
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 float echo_subtractor_output[PART_LEN]) { 937 float echo_subtractor_output[PART_LEN]) {
939 float s_fft[2][PART_LEN1]; 938 float s_fft[2][PART_LEN1];
940 float e_extended[PART_LEN2]; 939 float e_extended[PART_LEN2];
941 float s_extended[PART_LEN2]; 940 float s_extended[PART_LEN2];
942 float *s; 941 float *s;
943 float e[PART_LEN]; 942 float e[PART_LEN];
944 float e_fft[2][PART_LEN1]; 943 float e_fft[2][PART_LEN1];
945 int i; 944 int i;
946 memset(s_fft, 0, sizeof(s_fft)); 945 memset(s_fft, 0, sizeof(s_fft));
947 946
947 // Conditionally reset the echo subtraction filter if the filter has diverged
948 // significantly.
949 if (!aec->extended_filter_enabled &&
950 aec->extreme_filter_divergence) {
951 memset(aec->wfBuf, 0, sizeof(aec->wfBuf));
952 aec->extreme_filter_divergence = 0;
953 }
954
948 // Produce echo estimate s_fft. 955 // Produce echo estimate s_fft.
949 WebRtcAec_FilterFar(num_partitions, 956 WebRtcAec_FilterFar(num_partitions,
950 x_fft_buf_block_pos, 957 x_fft_buf_block_pos,
951 x_fft_buf, 958 x_fft_buf,
952 h_fft_buf, 959 h_fft_buf,
953 s_fft); 960 s_fft);
954 961
955 // Compute the time-domain echo estimate s. 962 // Compute the time-domain echo estimate s.
956 InverseFft(s_fft, s_extended); 963 InverseFft(s_fft, s_extended);
957 s = &s_extended[PART_LEN]; 964 s = &s_extended[PART_LEN];
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); 1072 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1);
1066 1073
1067 if (aec->delayEstCtr == 0) 1074 if (aec->delayEstCtr == 0)
1068 aec->delayIdx = WebRtcAec_PartitionDelay(aec); 1075 aec->delayIdx = WebRtcAec_PartitionDelay(aec);
1069 1076
1070 // Use delayed far. 1077 // Use delayed far.
1071 memcpy(xfw, 1078 memcpy(xfw,
1072 aec->xfwBuf + aec->delayIdx * PART_LEN1, 1079 aec->xfwBuf + aec->delayIdx * PART_LEN1,
1073 sizeof(xfw[0][0]) * 2 * PART_LEN1); 1080 sizeof(xfw[0][0]) * 2 * PART_LEN1);
1074 1081
1075 WebRtcAec_SubbandCoherence(aec, efw, dfw, xfw, fft, cohde, cohxd); 1082 WebRtcAec_SubbandCoherence(aec, efw, dfw, xfw, fft, cohde, cohxd,
1083 &aec->extreme_filter_divergence);
1084
1085 // Select the microphone signal as output if the filter is deemed to have
1086 // diverged.
1087 if (aec->divergeState) {
1088 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1);
1089 }
1076 1090
1077 hNlXdAvg = 0; 1091 hNlXdAvg = 0;
1078 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) { 1092 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) {
1079 hNlXdAvg += cohxd[i]; 1093 hNlXdAvg += cohxd[i];
1080 } 1094 }
1081 hNlXdAvg /= prefBandSize; 1095 hNlXdAvg /= prefBandSize;
1082 hNlXdAvg = 1 - hNlXdAvg; 1096 hNlXdAvg = 1 - hNlXdAvg;
1083 1097
1084 hNlDeAvg = 0; 1098 hNlDeAvg = 0;
1085 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) { 1099 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) {
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after
1733 aec->overDrive = 2; 1747 aec->overDrive = 2;
1734 aec->overDriveSm = 2; 1748 aec->overDriveSm = 2;
1735 aec->delayIdx = 0; 1749 aec->delayIdx = 0;
1736 aec->stNearState = 0; 1750 aec->stNearState = 0;
1737 aec->echoState = 0; 1751 aec->echoState = 0;
1738 aec->divergeState = 0; 1752 aec->divergeState = 0;
1739 1753
1740 aec->seed = 777; 1754 aec->seed = 777;
1741 aec->delayEstCtr = 0; 1755 aec->delayEstCtr = 0;
1742 1756
1757 aec->extreme_filter_divergence = 0;
1758
1743 // Metrics disabled by default 1759 // Metrics disabled by default
1744 aec->metricsMode = 0; 1760 aec->metricsMode = 0;
1745 InitMetrics(aec); 1761 InitMetrics(aec);
1746 1762
1747 return 0; 1763 return 0;
1748 } 1764 }
1749 1765
1750 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) { 1766 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) {
1751 float fft[PART_LEN2]; 1767 float fft[PART_LEN2];
1752 float xf[2][PART_LEN1]; 1768 float xf[2][PART_LEN1];
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1967 int WebRtcAec_extended_filter_enabled(AecCore* self) { 1983 int WebRtcAec_extended_filter_enabled(AecCore* self) {
1968 return self->extended_filter_enabled; 1984 return self->extended_filter_enabled;
1969 } 1985 }
1970 1986
1971 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } 1987 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; }
1972 1988
1973 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 1989 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
1974 assert(delay >= 0); 1990 assert(delay >= 0);
1975 self->system_delay = delay; 1991 self->system_delay = delay;
1976 } 1992 }
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/audio_processing/aec/aec_core_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698