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

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

Issue 1936173002: Changed the AEC SubbandCoherence function to not use the full aec state (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@RefactorAec1_CL
Patch Set: Fixed bad merge Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | webrtc/modules/audio_processing/aec/aec_core_internal.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 397
398 // Updates the following smoothed Power Spectral Densities (PSD): 398 // Updates the following smoothed Power Spectral Densities (PSD):
399 // - sd : near-end 399 // - sd : near-end
400 // - se : residual echo 400 // - se : residual echo
401 // - sx : far-end 401 // - sx : far-end
402 // - sde : cross-PSD of near-end and residual echo 402 // - sde : cross-PSD of near-end and residual echo
403 // - sxd : cross-PSD of near-end and far-end 403 // - sxd : cross-PSD of near-end and far-end
404 // 404 //
405 // In addition to updating the PSDs, also the filter diverge state is 405 // In addition to updating the PSDs, also the filter diverge state is
406 // determined. 406 // determined.
407 static void SmoothedPSD(AecCore* aec, 407 static void SmoothedPSD(int mult,
408 bool extended_filter_enabled,
408 float efw[2][PART_LEN1], 409 float efw[2][PART_LEN1],
409 float dfw[2][PART_LEN1], 410 float dfw[2][PART_LEN1],
410 float xfw[2][PART_LEN1], 411 float xfw[2][PART_LEN1],
412 CoherenceState* coherence_state,
413 short* filter_divergence_state,
411 int* extreme_filter_divergence) { 414 int* extreme_filter_divergence) {
412 // Power estimate smoothing coefficients. 415 // Power estimate smoothing coefficients.
413 const float* ptrGCoh = 416 const float* ptrGCoh =
414 aec->extended_filter_enabled 417 extended_filter_enabled
415 ? WebRtcAec_kExtendedSmoothingCoefficients[aec->mult - 1] 418 ? WebRtcAec_kExtendedSmoothingCoefficients[mult - 1]
416 : WebRtcAec_kNormalSmoothingCoefficients[aec->mult - 1]; 419 : WebRtcAec_kNormalSmoothingCoefficients[mult - 1];
417 int i; 420 int i;
418 float sdSum = 0, seSum = 0; 421 float sdSum = 0, seSum = 0;
419 422
420 for (i = 0; i < PART_LEN1; i++) { 423 for (i = 0; i < PART_LEN1; i++) {
421 aec->sd[i] = ptrGCoh[0] * aec->sd[i] + 424 coherence_state->sd[i] =
422 ptrGCoh[1] * (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]); 425 ptrGCoh[0] * coherence_state->sd[i] +
423 aec->se[i] = ptrGCoh[0] * aec->se[i] + 426 ptrGCoh[1] * (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]);
424 ptrGCoh[1] * (efw[0][i] * efw[0][i] + efw[1][i] * efw[1][i]); 427 coherence_state->se[i] =
428 ptrGCoh[0] * coherence_state->se[i] +
429 ptrGCoh[1] * (efw[0][i] * efw[0][i] + efw[1][i] * efw[1][i]);
425 // We threshold here to protect against the ill-effects of a zero farend. 430 // We threshold here to protect against the ill-effects of a zero farend.
426 // The threshold is not arbitrarily chosen, but balances protection and 431 // The threshold is not arbitrarily chosen, but balances protection and
427 // adverse interaction with the algorithm's tuning. 432 // adverse interaction with the algorithm's tuning.
428 // TODO(bjornv): investigate further why this is so sensitive. 433 // TODO(bjornv): investigate further why this is so sensitive.
429 aec->sx[i] = ptrGCoh[0] * aec->sx[i] + 434 coherence_state->sx[i] =
430 ptrGCoh[1] * WEBRTC_SPL_MAX( 435 ptrGCoh[0] * coherence_state->sx[i] +
431 xfw[0][i] * xfw[0][i] + xfw[1][i] * xfw[1][i], 436 ptrGCoh[1] *
432 WebRtcAec_kMinFarendPSD); 437 WEBRTC_SPL_MAX(xfw[0][i] * xfw[0][i] + xfw[1][i] * xfw[1][i],
438 WebRtcAec_kMinFarendPSD);
433 439
434 aec->sde[i][0] = 440 coherence_state->sde[i][0] =
435 ptrGCoh[0] * aec->sde[i][0] + 441 ptrGCoh[0] * coherence_state->sde[i][0] +
436 ptrGCoh[1] * (dfw[0][i] * efw[0][i] + dfw[1][i] * efw[1][i]); 442 ptrGCoh[1] * (dfw[0][i] * efw[0][i] + dfw[1][i] * efw[1][i]);
437 aec->sde[i][1] = 443 coherence_state->sde[i][1] =
438 ptrGCoh[0] * aec->sde[i][1] + 444 ptrGCoh[0] * coherence_state->sde[i][1] +
439 ptrGCoh[1] * (dfw[0][i] * efw[1][i] - dfw[1][i] * efw[0][i]); 445 ptrGCoh[1] * (dfw[0][i] * efw[1][i] - dfw[1][i] * efw[0][i]);
440 446
441 aec->sxd[i][0] = 447 coherence_state->sxd[i][0] =
442 ptrGCoh[0] * aec->sxd[i][0] + 448 ptrGCoh[0] * coherence_state->sxd[i][0] +
443 ptrGCoh[1] * (dfw[0][i] * xfw[0][i] + dfw[1][i] * xfw[1][i]); 449 ptrGCoh[1] * (dfw[0][i] * xfw[0][i] + dfw[1][i] * xfw[1][i]);
444 aec->sxd[i][1] = 450 coherence_state->sxd[i][1] =
445 ptrGCoh[0] * aec->sxd[i][1] + 451 ptrGCoh[0] * coherence_state->sxd[i][1] +
446 ptrGCoh[1] * (dfw[0][i] * xfw[1][i] - dfw[1][i] * xfw[0][i]); 452 ptrGCoh[1] * (dfw[0][i] * xfw[1][i] - dfw[1][i] * xfw[0][i]);
447 453
448 sdSum += aec->sd[i]; 454 sdSum += coherence_state->sd[i];
449 seSum += aec->se[i]; 455 seSum += coherence_state->se[i];
450 } 456 }
451 457
452 // Divergent filter safeguard update. 458 // Divergent filter safeguard update.
453 aec->divergeState = (aec->divergeState ? 1.05f : 1.0f) * seSum > sdSum; 459 *filter_divergence_state =
460 (*filter_divergence_state ? 1.05f : 1.0f) * seSum > sdSum;
454 461
455 // Signal extreme filter divergence if the error is significantly larger 462 // Signal extreme filter divergence if the error is significantly larger
456 // than the nearend (13 dB). 463 // than the nearend (13 dB).
457 *extreme_filter_divergence = (seSum > (19.95f * sdSum)); 464 *extreme_filter_divergence = (seSum > (19.95f * sdSum));
458 } 465 }
459 466
460 // Window time domain data to be used by the fft. 467 // Window time domain data to be used by the fft.
461 __inline static void WindowData(float* x_windowed, const float* x) { 468 __inline static void WindowData(float* x_windowed, const float* x) {
462 int i; 469 int i;
463 for (i = 0; i < PART_LEN; i++) { 470 for (i = 0; i < PART_LEN; i++) {
(...skipping 10 matching lines...) Expand all
474 data_complex[0][0] = data[0]; 481 data_complex[0][0] = data[0];
475 data_complex[1][0] = 0; 482 data_complex[1][0] = 0;
476 for (i = 1; i < PART_LEN; i++) { 483 for (i = 1; i < PART_LEN; i++) {
477 data_complex[0][i] = data[2 * i]; 484 data_complex[0][i] = data[2 * i];
478 data_complex[1][i] = data[2 * i + 1]; 485 data_complex[1][i] = data[2 * i + 1];
479 } 486 }
480 data_complex[0][PART_LEN] = data[1]; 487 data_complex[0][PART_LEN] = data[1];
481 data_complex[1][PART_LEN] = 0; 488 data_complex[1][PART_LEN] = 0;
482 } 489 }
483 490
484 static void SubbandCoherence(AecCore* aec, 491 static void SubbandCoherence(int mult,
492 bool extended_filter_enabled,
485 float efw[2][PART_LEN1], 493 float efw[2][PART_LEN1],
486 float dfw[2][PART_LEN1], 494 float dfw[2][PART_LEN1],
487 float xfw[2][PART_LEN1], 495 float xfw[2][PART_LEN1],
488 float* fft, 496 float* fft,
489 float* cohde, 497 float* cohde,
490 float* cohxd, 498 float* cohxd,
499 CoherenceState* coherence_state,
500 short* filter_divergence_state,
491 int* extreme_filter_divergence) { 501 int* extreme_filter_divergence) {
492 int i; 502 int i;
493 503
494 SmoothedPSD(aec, efw, dfw, xfw, extreme_filter_divergence); 504 SmoothedPSD(mult, extended_filter_enabled, efw, dfw, xfw, coherence_state,
505 filter_divergence_state, extreme_filter_divergence);
495 506
496 // Subband coherence 507 // Subband coherence
497 for (i = 0; i < PART_LEN1; i++) { 508 for (i = 0; i < PART_LEN1; i++) {
498 cohde[i] = 509 cohde[i] = (coherence_state->sde[i][0] * coherence_state->sde[i][0] +
499 (aec->sde[i][0] * aec->sde[i][0] + aec->sde[i][1] * aec->sde[i][1]) / 510 coherence_state->sde[i][1] * coherence_state->sde[i][1]) /
500 (aec->sd[i] * aec->se[i] + 1e-10f); 511 (coherence_state->sd[i] * coherence_state->se[i] + 1e-10f);
501 cohxd[i] = 512 cohxd[i] = (coherence_state->sxd[i][0] * coherence_state->sxd[i][0] +
502 (aec->sxd[i][0] * aec->sxd[i][0] + aec->sxd[i][1] * aec->sxd[i][1]) / 513 coherence_state->sxd[i][1] * coherence_state->sxd[i][1]) /
503 (aec->sx[i] * aec->sd[i] + 1e-10f); 514 (coherence_state->sx[i] * coherence_state->sd[i] + 1e-10f);
504 } 515 }
505 } 516 }
506 517
507 static void GetHighbandGain(const float* lambda, float* nlpGainHband) { 518 static void GetHighbandGain(const float* lambda, float* nlpGainHband) {
508 int i; 519 int i;
509 520
510 *nlpGainHband = 0.0f; 521 *nlpGainHband = 0.0f;
511 for (i = freqAvgIc; i < PART_LEN1 - 1; i++) { 522 for (i = freqAvgIc; i < PART_LEN1 - 1; i++) {
512 *nlpGainHband += lambda[i]; 523 *nlpGainHband += lambda[i];
513 } 524 }
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 aec->delayEstCtr++; 1054 aec->delayEstCtr++;
1044 if (aec->delayEstCtr == delayEstInterval) { 1055 if (aec->delayEstCtr == delayEstInterval) {
1045 aec->delayEstCtr = 0; 1056 aec->delayEstCtr = 0;
1046 aec->delayIdx = WebRtcAec_PartitionDelay(aec); 1057 aec->delayIdx = WebRtcAec_PartitionDelay(aec);
1047 } 1058 }
1048 1059
1049 // Use delayed far. 1060 // Use delayed far.
1050 memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1, 1061 memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1,
1051 sizeof(xfw[0][0]) * 2 * PART_LEN1); 1062 sizeof(xfw[0][0]) * 2 * PART_LEN1);
1052 1063
1053 WebRtcAec_SubbandCoherence(aec, efw, dfw, xfw, fft, cohde, cohxd, 1064 WebRtcAec_SubbandCoherence(aec->mult, aec->extended_filter_enabled == 1, efw,
1065 dfw, xfw, fft, cohde, cohxd, &aec->coherence_state,
1066 &aec->divergeState,
1054 &aec->extreme_filter_divergence); 1067 &aec->extreme_filter_divergence);
1055 1068
1056 // Select the microphone signal as output if the filter is deemed to have 1069 // Select the microphone signal as output if the filter is deemed to have
1057 // diverged. 1070 // diverged.
1058 if (aec->divergeState) { 1071 if (aec->divergeState) {
1059 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); 1072 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1);
1060 } 1073 }
1061 1074
1062 hNlXdAvg = 0; 1075 hNlXdAvg = 0;
1063 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) { 1076 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) {
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
1659 for (i = 0; i < PART_LEN1; i++) { 1672 for (i = 0; i < PART_LEN1; i++) {
1660 aec->dMinPow[i] = 1.0e6f; 1673 aec->dMinPow[i] = 1.0e6f;
1661 } 1674 }
1662 1675
1663 // Holds the last block written to 1676 // Holds the last block written to
1664 aec->xfBufBlockPos = 0; 1677 aec->xfBufBlockPos = 0;
1665 // TODO(peah): Investigate need for these initializations. Deleting them 1678 // TODO(peah): Investigate need for these initializations. Deleting them
1666 // doesn't change the output at all and yields 0.4% overall speedup. 1679 // doesn't change the output at all and yields 0.4% overall speedup.
1667 memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); 1680 memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
1668 memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); 1681 memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
1669 memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1); 1682 memset(aec->coherence_state.sde, 0, sizeof(complex_t) * PART_LEN1);
1670 memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1); 1683 memset(aec->coherence_state.sxd, 0, sizeof(complex_t) * PART_LEN1);
1671 memset(aec->xfwBuf, 0, 1684 memset(aec->xfwBuf, 0,
1672 sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); 1685 sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
1673 memset(aec->se, 0, sizeof(float) * PART_LEN1); 1686 memset(aec->coherence_state.se, 0, sizeof(float) * PART_LEN1);
1674 1687
1675 // To prevent numerical instability in the first block. 1688 // To prevent numerical instability in the first block.
1676 for (i = 0; i < PART_LEN1; i++) { 1689 for (i = 0; i < PART_LEN1; i++) {
1677 aec->sd[i] = 1; 1690 aec->coherence_state.sd[i] = 1;
1678 } 1691 }
1679 for (i = 0; i < PART_LEN1; i++) { 1692 for (i = 0; i < PART_LEN1; i++) {
1680 aec->sx[i] = 1; 1693 aec->coherence_state.sx[i] = 1;
1681 } 1694 }
1682 1695
1683 memset(aec->hNs, 0, sizeof(aec->hNs)); 1696 memset(aec->hNs, 0, sizeof(aec->hNs));
1684 memset(aec->outBuf, 0, sizeof(float) * PART_LEN); 1697 memset(aec->outBuf, 0, sizeof(float) * PART_LEN);
1685 1698
1686 aec->hNlFbMin = 1; 1699 aec->hNlFbMin = 1;
1687 aec->hNlFbLocalMin = 1; 1700 aec->hNlFbLocalMin = 1;
1688 aec->hNlXdAvgMin = 1; 1701 aec->hNlXdAvgMin = 1;
1689 aec->hNlNewMin = 0; 1702 aec->hNlNewMin = 0;
1690 aec->hNlMinCtr = 0; 1703 aec->hNlMinCtr = 0;
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1947 1960
1948 int WebRtcAec_system_delay(AecCore* self) { 1961 int WebRtcAec_system_delay(AecCore* self) {
1949 return self->system_delay; 1962 return self->system_delay;
1950 } 1963 }
1951 1964
1952 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 1965 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
1953 assert(delay >= 0); 1966 assert(delay >= 0);
1954 self->system_delay = delay; 1967 self->system_delay = delay;
1955 } 1968 }
1956 } // namespace webrtc 1969 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/audio_processing/aec/aec_core_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698