| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |