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 |