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 |