| 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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 const float WebRtcAec_kNormalSmoothingCoefficients[2][2] = {{0.9f, 0.1f}, | 125 const float WebRtcAec_kNormalSmoothingCoefficients[2][2] = {{0.9f, 0.1f}, |
| 126 {0.93f, 0.07f}}; | 126 {0.93f, 0.07f}}; |
| 127 | 127 |
| 128 // Number of partitions forming the NLP's "preferred" bands. | 128 // Number of partitions forming the NLP's "preferred" bands. |
| 129 enum { kPrefBandSize = 24 }; | 129 enum { kPrefBandSize = 24 }; |
| 130 | 130 |
| 131 WebRtcAecFilterFar WebRtcAec_FilterFar; | 131 WebRtcAecFilterFar WebRtcAec_FilterFar; |
| 132 WebRtcAecScaleErrorSignal WebRtcAec_ScaleErrorSignal; | 132 WebRtcAecScaleErrorSignal WebRtcAec_ScaleErrorSignal; |
| 133 WebRtcAecFilterAdaptation WebRtcAec_FilterAdaptation; | 133 WebRtcAecFilterAdaptation WebRtcAec_FilterAdaptation; |
| 134 WebRtcAecOverdriveAndSuppress WebRtcAec_OverdriveAndSuppress; | 134 WebRtcAecOverdriveAndSuppress WebRtcAec_OverdriveAndSuppress; |
| 135 WebRtcAecSubBandCoherence WebRtcAec_SubbandCoherence; | 135 WebRtcAecComputeCoherence WebRtcAec_ComputeCoherence; |
| 136 WebRtcAecUpdateCoherenceSpectra WebRtcAec_UpdateCoherenceSpectra; |
| 136 WebRtcAecStoreAsComplex WebRtcAec_StoreAsComplex; | 137 WebRtcAecStoreAsComplex WebRtcAec_StoreAsComplex; |
| 137 WebRtcAecPartitionDelay WebRtcAec_PartitionDelay; | 138 WebRtcAecPartitionDelay WebRtcAec_PartitionDelay; |
| 138 WebRtcAecWindowData WebRtcAec_WindowData; | 139 WebRtcAecWindowData WebRtcAec_WindowData; |
| 139 | 140 |
| 140 __inline static float MulRe(float aRe, float aIm, float bRe, float bIm) { | 141 __inline static float MulRe(float aRe, float aIm, float bRe, float bIm) { |
| 141 return aRe * bRe - aIm * bIm; | 142 return aRe * bRe - aIm * bIm; |
| 142 } | 143 } |
| 143 | 144 |
| 144 __inline static float MulIm(float aRe, float aIm, float bRe, float bIm) { | 145 __inline static float MulIm(float aRe, float aIm, float bRe, float bIm) { |
| 145 return aRe * bIm + aIm * bRe; | 146 return aRe * bIm + aIm * bRe; |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 // This is to protect overflow, which should almost never happen. | 390 // This is to protect overflow, which should almost never happen. |
| 390 RTC_CHECK_NE(0u, metric->hicounter); | 391 RTC_CHECK_NE(0u, metric->hicounter); |
| 391 metric->hisum += metric->instant; | 392 metric->hisum += metric->instant; |
| 392 metric->himean = metric->hisum / metric->hicounter; | 393 metric->himean = metric->hisum / metric->hicounter; |
| 393 } | 394 } |
| 394 } | 395 } |
| 395 | 396 |
| 396 // Threshold to protect against the ill-effects of a zero far-end. | 397 // Threshold to protect against the ill-effects of a zero far-end. |
| 397 const float WebRtcAec_kMinFarendPSD = 15; | 398 const float WebRtcAec_kMinFarendPSD = 15; |
| 398 | 399 |
| 399 // Updates the following smoothed Power Spectral Densities (PSD): | 400 // Updates the following smoothed Power Spectral Densities (PSD): |
| 400 // - sd : near-end | 401 // - sd : near-end |
| 401 // - se : residual echo | 402 // - se : residual echo |
| 402 // - sx : far-end | 403 // - sx : far-end |
| 403 // - sde : cross-PSD of near-end and residual echo | 404 // - sde : cross-PSD of near-end and residual echo |
| 404 // - sxd : cross-PSD of near-end and far-end | 405 // - sxd : cross-PSD of near-end and far-end |
| 405 // | 406 // |
| 406 // In addition to updating the PSDs, also the filter diverge state is | 407 // In addition to updating the PSDs, also the filter diverge state is |
| 407 // determined. | 408 // determined. |
| 408 static void SmoothedPSD(int mult, | 409 static void UpdateCoherenceSpectra(int mult, |
| 409 bool extended_filter_enabled, | 410 bool extended_filter_enabled, |
| 410 float efw[2][PART_LEN1], | 411 float efw[2][PART_LEN1], |
| 411 float dfw[2][PART_LEN1], | 412 float dfw[2][PART_LEN1], |
| 412 float xfw[2][PART_LEN1], | 413 float xfw[2][PART_LEN1], |
| 413 CoherenceState* coherence_state, | 414 CoherenceState* coherence_state, |
| 414 short* filter_divergence_state, | 415 short* filter_divergence_state, |
| 415 int* extreme_filter_divergence) { | 416 int* extreme_filter_divergence) { |
| 416 // Power estimate smoothing coefficients. | 417 // Power estimate smoothing coefficients. |
| 417 const float* ptrGCoh = | 418 const float* ptrGCoh = |
| 418 extended_filter_enabled | 419 extended_filter_enabled |
| 419 ? WebRtcAec_kExtendedSmoothingCoefficients[mult - 1] | 420 ? WebRtcAec_kExtendedSmoothingCoefficients[mult - 1] |
| 420 : WebRtcAec_kNormalSmoothingCoefficients[mult - 1]; | 421 : WebRtcAec_kNormalSmoothingCoefficients[mult - 1]; |
| 421 int i; | 422 int i; |
| 422 float sdSum = 0, seSum = 0; | 423 float sdSum = 0, seSum = 0; |
| 423 | 424 |
| 424 for (i = 0; i < PART_LEN1; i++) { | 425 for (i = 0; i < PART_LEN1; i++) { |
| 425 coherence_state->sd[i] = | 426 coherence_state->sd[i] = |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 data_complex[0][0] = data[0]; | 483 data_complex[0][0] = data[0]; |
| 483 data_complex[1][0] = 0; | 484 data_complex[1][0] = 0; |
| 484 for (i = 1; i < PART_LEN; i++) { | 485 for (i = 1; i < PART_LEN; i++) { |
| 485 data_complex[0][i] = data[2 * i]; | 486 data_complex[0][i] = data[2 * i]; |
| 486 data_complex[1][i] = data[2 * i + 1]; | 487 data_complex[1][i] = data[2 * i + 1]; |
| 487 } | 488 } |
| 488 data_complex[0][PART_LEN] = data[1]; | 489 data_complex[0][PART_LEN] = data[1]; |
| 489 data_complex[1][PART_LEN] = 0; | 490 data_complex[1][PART_LEN] = 0; |
| 490 } | 491 } |
| 491 | 492 |
| 492 static void SubbandCoherence(int mult, | 493 static void ComputeCoherence(const CoherenceState* coherence_state, |
| 493 bool extended_filter_enabled, | |
| 494 float efw[2][PART_LEN1], | |
| 495 float dfw[2][PART_LEN1], | |
| 496 float xfw[2][PART_LEN1], | |
| 497 float* fft, | |
| 498 float* cohde, | 494 float* cohde, |
| 499 float* cohxd, | 495 float* cohxd) { |
| 500 CoherenceState* coherence_state, | |
| 501 short* filter_divergence_state, | |
| 502 int* extreme_filter_divergence) { | |
| 503 int i; | |
| 504 | |
| 505 SmoothedPSD(mult, extended_filter_enabled, efw, dfw, xfw, coherence_state, | |
| 506 filter_divergence_state, extreme_filter_divergence); | |
| 507 | |
| 508 // Subband coherence | 496 // Subband coherence |
| 509 for (i = 0; i < PART_LEN1; i++) { | 497 for (int i = 0; i < PART_LEN1; i++) { |
| 510 cohde[i] = (coherence_state->sde[i][0] * coherence_state->sde[i][0] + | 498 cohde[i] = (coherence_state->sde[i][0] * coherence_state->sde[i][0] + |
| 511 coherence_state->sde[i][1] * coherence_state->sde[i][1]) / | 499 coherence_state->sde[i][1] * coherence_state->sde[i][1]) / |
| 512 (coherence_state->sd[i] * coherence_state->se[i] + 1e-10f); | 500 (coherence_state->sd[i] * coherence_state->se[i] + 1e-10f); |
| 513 cohxd[i] = (coherence_state->sxd[i][0] * coherence_state->sxd[i][0] + | 501 cohxd[i] = (coherence_state->sxd[i][0] * coherence_state->sxd[i][0] + |
| 514 coherence_state->sxd[i][1] * coherence_state->sxd[i][1]) / | 502 coherence_state->sxd[i][1] * coherence_state->sxd[i][1]) / |
| 515 (coherence_state->sx[i] * coherence_state->sd[i] + 1e-10f); | 503 (coherence_state->sx[i] * coherence_state->sd[i] + 1e-10f); |
| 516 } | 504 } |
| 517 } | 505 } |
| 518 | 506 |
| 519 static void GetHighbandGain(const float* lambda, float* nlpGainHband) { | 507 static void GetHighbandGain(const float* lambda, float* nlpGainHband) { |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1055 aec->delayEstCtr++; | 1043 aec->delayEstCtr++; |
| 1056 if (aec->delayEstCtr == delayEstInterval) { | 1044 if (aec->delayEstCtr == delayEstInterval) { |
| 1057 aec->delayEstCtr = 0; | 1045 aec->delayEstCtr = 0; |
| 1058 aec->delayIdx = WebRtcAec_PartitionDelay(aec->num_partitions, aec->wfBuf); | 1046 aec->delayIdx = WebRtcAec_PartitionDelay(aec->num_partitions, aec->wfBuf); |
| 1059 } | 1047 } |
| 1060 | 1048 |
| 1061 // Use delayed far. | 1049 // Use delayed far. |
| 1062 memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1, | 1050 memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1, |
| 1063 sizeof(xfw[0][0]) * 2 * PART_LEN1); | 1051 sizeof(xfw[0][0]) * 2 * PART_LEN1); |
| 1064 | 1052 |
| 1065 WebRtcAec_SubbandCoherence(aec->mult, aec->extended_filter_enabled == 1, efw, | 1053 WebRtcAec_UpdateCoherenceSpectra(aec->mult, aec->extended_filter_enabled == 1, |
| 1066 dfw, xfw, fft, cohde, cohxd, &aec->coherence_state, | 1054 efw, dfw, xfw, &aec->coherence_state, |
| 1067 &aec->divergeState, | 1055 &aec->divergeState, |
| 1068 &aec->extreme_filter_divergence); | 1056 &aec->extreme_filter_divergence); |
| 1057 |
| 1058 WebRtcAec_ComputeCoherence(&aec->coherence_state, cohde, cohxd); |
| 1069 | 1059 |
| 1070 // Select the microphone signal as output if the filter is deemed to have | 1060 // Select the microphone signal as output if the filter is deemed to have |
| 1071 // diverged. | 1061 // diverged. |
| 1072 if (aec->divergeState) { | 1062 if (aec->divergeState) { |
| 1073 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); | 1063 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); |
| 1074 } | 1064 } |
| 1075 | 1065 |
| 1076 hNlXdAvg = 0; | 1066 hNlXdAvg = 0; |
| 1077 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) { | 1067 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) { |
| 1078 hNlXdAvg += cohxd[i]; | 1068 hNlXdAvg += cohxd[i]; |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1481 #endif | 1471 #endif |
| 1482 aec->extended_filter_enabled = 0; | 1472 aec->extended_filter_enabled = 0; |
| 1483 aec->aec3_enabled = 0; | 1473 aec->aec3_enabled = 0; |
| 1484 aec->refined_adaptive_filter_enabled = false; | 1474 aec->refined_adaptive_filter_enabled = false; |
| 1485 | 1475 |
| 1486 // Assembly optimization | 1476 // Assembly optimization |
| 1487 WebRtcAec_FilterFar = FilterFar; | 1477 WebRtcAec_FilterFar = FilterFar; |
| 1488 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; | 1478 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; |
| 1489 WebRtcAec_FilterAdaptation = FilterAdaptation; | 1479 WebRtcAec_FilterAdaptation = FilterAdaptation; |
| 1490 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; | 1480 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; |
| 1491 WebRtcAec_SubbandCoherence = SubbandCoherence; | 1481 WebRtcAec_ComputeCoherence = ComputeCoherence; |
| 1482 WebRtcAec_UpdateCoherenceSpectra = UpdateCoherenceSpectra; |
| 1492 WebRtcAec_StoreAsComplex = StoreAsComplex; | 1483 WebRtcAec_StoreAsComplex = StoreAsComplex; |
| 1493 WebRtcAec_PartitionDelay = PartitionDelay; | 1484 WebRtcAec_PartitionDelay = PartitionDelay; |
| 1494 WebRtcAec_WindowData = WindowData; | 1485 WebRtcAec_WindowData = WindowData; |
| 1495 | 1486 |
| 1496 #if defined(WEBRTC_ARCH_X86_FAMILY) | 1487 #if defined(WEBRTC_ARCH_X86_FAMILY) |
| 1497 if (WebRtc_GetCPUInfo(kSSE2)) { | 1488 if (WebRtc_GetCPUInfo(kSSE2)) { |
| 1498 WebRtcAec_InitAec_SSE2(); | 1489 WebRtcAec_InitAec_SSE2(); |
| 1499 } | 1490 } |
| 1500 #endif | 1491 #endif |
| 1501 | 1492 |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1960 | 1951 |
| 1961 int WebRtcAec_system_delay(AecCore* self) { | 1952 int WebRtcAec_system_delay(AecCore* self) { |
| 1962 return self->system_delay; | 1953 return self->system_delay; |
| 1963 } | 1954 } |
| 1964 | 1955 |
| 1965 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1956 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
| 1966 assert(delay >= 0); | 1957 assert(delay >= 0); |
| 1967 self->system_delay = delay; | 1958 self->system_delay = delay; |
| 1968 } | 1959 } |
| 1969 } // namespace webrtc | 1960 } // namespace webrtc |
| OLD | NEW |