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

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

Issue 1494563002: Refactoring (bitexact) of the EchoSuppressor in WebRTC AEC (#1) (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixed error in the function header Created 5 years 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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 #ifdef WEBRTC_AEC_DEBUG_DUMP 128 #ifdef WEBRTC_AEC_DEBUG_DUMP
129 extern int webrtc_aec_instance_count; 129 extern int webrtc_aec_instance_count;
130 #endif 130 #endif
131 131
132 WebRtcAecFilterFar WebRtcAec_FilterFar; 132 WebRtcAecFilterFar WebRtcAec_FilterFar;
133 WebRtcAecScaleErrorSignal WebRtcAec_ScaleErrorSignal; 133 WebRtcAecScaleErrorSignal WebRtcAec_ScaleErrorSignal;
134 WebRtcAecFilterAdaptation WebRtcAec_FilterAdaptation; 134 WebRtcAecFilterAdaptation WebRtcAec_FilterAdaptation;
135 WebRtcAecOverdriveAndSuppress WebRtcAec_OverdriveAndSuppress; 135 WebRtcAecOverdriveAndSuppress WebRtcAec_OverdriveAndSuppress;
136 WebRtcAecComfortNoise WebRtcAec_ComfortNoise; 136 WebRtcAecComfortNoise WebRtcAec_ComfortNoise;
137 WebRtcAecSubBandCoherence WebRtcAec_SubbandCoherence; 137 WebRtcAecSubBandCoherence WebRtcAec_SubbandCoherence;
138 WebRtcAecStoreAsComplex WebRtcAec_StoreAsComplex;
139 WebRtcAecPartitionDelay WebRtcAec_PartitionDelay;
140 WebRtcAecWindowData WebRtcAec_WindowData;
138 141
139 __inline static float MulRe(float aRe, float aIm, float bRe, float bIm) { 142 __inline static float MulRe(float aRe, float aIm, float bRe, float bIm) {
140 return aRe * bRe - aIm * bIm; 143 return aRe * bRe - aIm * bIm;
141 } 144 }
142 145
143 __inline static float MulIm(float aRe, float aIm, float bRe, float bIm) { 146 __inline static float MulIm(float aRe, float aIm, float bRe, float bIm) {
144 return aRe * bIm + aIm * bRe; 147 return aRe * bIm + aIm * bRe;
145 } 148 }
146 149
147 static int CmpFloat(const void* a, const void* b) { 150 static int CmpFloat(const void* a, const void* b) {
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 for (i = 1; i < PART_LEN; i++) { 403 for (i = 1; i < PART_LEN; i++) {
401 data_complex[0][i] = data[2 * i]; 404 data_complex[0][i] = data[2 * i];
402 data_complex[1][i] = data[2 * i + 1]; 405 data_complex[1][i] = data[2 * i + 1];
403 } 406 }
404 data_complex[0][PART_LEN] = data[1]; 407 data_complex[0][PART_LEN] = data[1];
405 data_complex[1][PART_LEN] = 0; 408 data_complex[1][PART_LEN] = 0;
406 } 409 }
407 410
408 static void SubbandCoherence(AecCore* aec, 411 static void SubbandCoherence(AecCore* aec,
409 float efw[2][PART_LEN1], 412 float efw[2][PART_LEN1],
413 float dfw[2][PART_LEN1],
410 float xfw[2][PART_LEN1], 414 float xfw[2][PART_LEN1],
411 float* fft, 415 float* fft,
412 float* cohde, 416 float* cohde,
413 float* cohxd) { 417 float* cohxd) {
414 float dfw[2][PART_LEN1];
415 int i; 418 int i;
416 419
417 if (aec->delayEstCtr == 0)
418 aec->delayIdx = PartitionDelay(aec);
419
420 // Use delayed far.
421 memcpy(xfw,
422 aec->xfwBuf + aec->delayIdx * PART_LEN1,
423 sizeof(xfw[0][0]) * 2 * PART_LEN1);
424
425 // Windowed near fft
426 WindowData(fft, aec->dBuf);
427 aec_rdft_forward_128(fft);
428 StoreAsComplex(fft, dfw);
429
430 // Windowed error fft
431 WindowData(fft, aec->eBuf);
432 aec_rdft_forward_128(fft);
433 StoreAsComplex(fft, efw);
434
435 SmoothedPSD(aec, efw, dfw, xfw); 420 SmoothedPSD(aec, efw, dfw, xfw);
436 421
437 // Subband coherence 422 // Subband coherence
438 for (i = 0; i < PART_LEN1; i++) { 423 for (i = 0; i < PART_LEN1; i++) {
439 cohde[i] = 424 cohde[i] =
440 (aec->sde[i][0] * aec->sde[i][0] + aec->sde[i][1] * aec->sde[i][1]) / 425 (aec->sde[i][0] * aec->sde[i][0] + aec->sde[i][1] * aec->sde[i][1]) /
441 (aec->sd[i] * aec->se[i] + 1e-10f); 426 (aec->sd[i] * aec->se[i] + 1e-10f);
442 cohxd[i] = 427 cohxd[i] =
443 (aec->sxd[i][0] * aec->sxd[i][0] + aec->sxd[i][1] * aec->sxd[i][1]) / 428 (aec->sxd[i][0] * aec->sxd[i][0] + aec->sxd[i][1] * aec->sxd[i][1]) /
444 (aec->sx[i] * aec->sd[i] + 1e-10f); 429 (aec->sx[i] * aec->sd[i] + 1e-10f);
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 WebRtcAec_FilterAdaptation(num_partitions, 989 WebRtcAec_FilterAdaptation(num_partitions,
1005 x_fft_buf_block_pos, 990 x_fft_buf_block_pos,
1006 x_fft_buf, 991 x_fft_buf,
1007 e_fft, 992 e_fft,
1008 h_fft_buf); 993 h_fft_buf);
1009 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); 994 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN);
1010 } 995 }
1011 996
1012 997
1013 static void EchoSuppression(AecCore* aec, 998 static void EchoSuppression(AecCore* aec,
999 float* echo_subtractor_output,
1014 float* output, 1000 float* output,
1015 float* const* outputH) { 1001 float* const* outputH) {
1016 float efw[2][PART_LEN1], xfw[2][PART_LEN1]; 1002 float efw[2][PART_LEN1];
1003 float xfw[2][PART_LEN1];
1004 float dfw[2][PART_LEN1];
1017 complex_t comfortNoiseHband[PART_LEN1]; 1005 complex_t comfortNoiseHband[PART_LEN1];
1018 float fft[PART_LEN2]; 1006 float fft[PART_LEN2];
1019 float scale, dtmp; 1007 float scale, dtmp;
1020 float nlpGainHband; 1008 float nlpGainHband;
1021 int i; 1009 int i;
1022 size_t j; 1010 size_t j;
1023 1011
1024 // Coherence and non-linear filter 1012 // Coherence and non-linear filter
1025 float cohde[PART_LEN1], cohxd[PART_LEN1]; 1013 float cohde[PART_LEN1], cohxd[PART_LEN1];
1026 float hNlDeAvg, hNlXdAvg; 1014 float hNlDeAvg, hNlXdAvg;
1027 float hNl[PART_LEN1]; 1015 float hNl[PART_LEN1];
1028 float hNlPref[kPrefBandSize]; 1016 float hNlPref[kPrefBandSize];
1029 float hNlFb = 0, hNlFbLow = 0; 1017 float hNlFb = 0, hNlFbLow = 0;
1030 const float prefBandQuant = 0.75f, prefBandQuantLow = 0.5f; 1018 const float prefBandQuant = 0.75f, prefBandQuantLow = 0.5f;
1031 const int prefBandSize = kPrefBandSize / aec->mult; 1019 const int prefBandSize = kPrefBandSize / aec->mult;
1032 const int minPrefBand = 4 / aec->mult; 1020 const int minPrefBand = 4 / aec->mult;
1033 // Power estimate smoothing coefficients. 1021 // Power estimate smoothing coefficients.
1034 const float* min_overdrive = aec->extended_filter_enabled 1022 const float* min_overdrive = aec->extended_filter_enabled
1035 ? kExtendedMinOverDrive 1023 ? kExtendedMinOverDrive
1036 : kNormalMinOverDrive; 1024 : kNormalMinOverDrive;
1037 1025
1038 // Filter energy 1026 // Filter energy
1039 const int delayEstInterval = 10 * aec->mult; 1027 const int delayEstInterval = 10 * aec->mult;
1040 1028
1041 float* xfw_ptr = NULL; 1029 float* xfw_ptr = NULL;
1042 1030
1031 // Update eBuf with echo subtractor output.
1032 memcpy(aec->eBuf + PART_LEN,
1033 echo_subtractor_output,
1034 sizeof(float) * PART_LEN);
1035
1036 // Analysis filter banks for the echo suppressor.
1037 // Windowed near-end ffts.
1038 WindowData(fft, aec->dBuf);
1039 aec_rdft_forward_128(fft);
1040 StoreAsComplex(fft, dfw);
1041
1042 // Windowed echo suppressor output ffts.
1043 WindowData(fft, aec->eBuf);
1044 aec_rdft_forward_128(fft);
1045 StoreAsComplex(fft, efw);
1046
1043 aec->delayEstCtr++; 1047 aec->delayEstCtr++;
1044 if (aec->delayEstCtr == delayEstInterval) { 1048 if (aec->delayEstCtr == delayEstInterval) {
1045 aec->delayEstCtr = 0; 1049 aec->delayEstCtr = 0;
1046 } 1050 }
1047 1051
1048 // initialize comfort noise for H band 1052 // initialize comfort noise for H band
1049 memset(comfortNoiseHband, 0, sizeof(comfortNoiseHband)); 1053 memset(comfortNoiseHband, 0, sizeof(comfortNoiseHband));
1050 nlpGainHband = (float)0.0; 1054 nlpGainHband = (float)0.0;
1051 dtmp = (float)0.0; 1055 dtmp = (float)0.0;
1052 1056
1053 // We should always have at least one element stored in |far_buf|. 1057 // We should always have at least one element stored in |far_buf|.
1054 assert(WebRtc_available_read(aec->far_buf_windowed) > 0); 1058 assert(WebRtc_available_read(aec->far_buf_windowed) > 0);
1055 // NLP 1059 // NLP
1056 WebRtc_ReadBuffer(aec->far_buf_windowed, (void**)&xfw_ptr, &xfw[0][0], 1); 1060 WebRtc_ReadBuffer(aec->far_buf_windowed, (void**)&xfw_ptr, &xfw[0][0], 1);
1057 1061
1058 // TODO(bjornv): Investigate if we can reuse |far_buf_windowed| instead of 1062 // TODO(bjornv): Investigate if we can reuse |far_buf_windowed| instead of
1059 // |xfwBuf|. 1063 // |xfwBuf|.
1060 // Buffer far. 1064 // Buffer far.
1061 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); 1065 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1);
1062 1066
1063 WebRtcAec_SubbandCoherence(aec, efw, xfw, fft, cohde, cohxd); 1067 if (aec->delayEstCtr == 0)
1068 aec->delayIdx = WebRtcAec_PartitionDelay(aec);
1069
1070 // Use delayed far.
1071 memcpy(xfw,
1072 aec->xfwBuf + aec->delayIdx * PART_LEN1,
1073 sizeof(xfw[0][0]) * 2 * PART_LEN1);
1074
1075 WebRtcAec_SubbandCoherence(aec, efw, dfw, xfw, fft, cohde, cohxd);
1064 1076
1065 hNlXdAvg = 0; 1077 hNlXdAvg = 0;
1066 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) { 1078 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) {
1067 hNlXdAvg += cohxd[i]; 1079 hNlXdAvg += cohxd[i];
1068 } 1080 }
1069 hNlXdAvg /= prefBandSize; 1081 hNlXdAvg /= prefBandSize;
1070 hNlXdAvg = 1 - hNlXdAvg; 1082 hNlXdAvg = 1 - hNlXdAvg;
1071 1083
1072 hNlDeAvg = 0; 1084 hNlDeAvg = 0;
1073 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) { 1085 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) {
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 aec->xfBuf, 1404 aec->xfBuf,
1393 nearend_ptr, 1405 nearend_ptr,
1394 aec->xPow, 1406 aec->xPow,
1395 aec->wfBuf, 1407 aec->wfBuf,
1396 &aec->linoutlevel, 1408 &aec->linoutlevel,
1397 echo_subtractor_output); 1409 echo_subtractor_output);
1398 1410
1399 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); 1411 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN);
1400 1412
1401 // Perform echo suppression. 1413 // Perform echo suppression.
1402 memcpy(aec->eBuf + PART_LEN, 1414 EchoSuppression(aec, echo_subtractor_output, output, outputH_ptr);
1403 echo_subtractor_output,
1404 sizeof(float) * PART_LEN);
1405 EchoSuppression(aec, output, outputH_ptr);
1406 1415
1407 if (aec->metricsMode == 1) { 1416 if (aec->metricsMode == 1) {
1408 // Update power levels and echo metrics 1417 // Update power levels and echo metrics
1409 UpdateLevel(&aec->farlevel, (float(*)[PART_LEN1])xf_ptr); 1418 UpdateLevel(&aec->farlevel, (float(*)[PART_LEN1])xf_ptr);
1410 UpdateLevel(&aec->nearlevel, df); 1419 UpdateLevel(&aec->nearlevel, df);
1411 UpdateMetrics(aec); 1420 UpdateMetrics(aec);
1412 } 1421 }
1413 1422
1414 // Store the output block. 1423 // Store the output block.
1415 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN); 1424 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 #endif 1513 #endif
1505 aec->extended_filter_enabled = 0; 1514 aec->extended_filter_enabled = 0;
1506 1515
1507 // Assembly optimization 1516 // Assembly optimization
1508 WebRtcAec_FilterFar = FilterFar; 1517 WebRtcAec_FilterFar = FilterFar;
1509 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; 1518 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal;
1510 WebRtcAec_FilterAdaptation = FilterAdaptation; 1519 WebRtcAec_FilterAdaptation = FilterAdaptation;
1511 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; 1520 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress;
1512 WebRtcAec_ComfortNoise = ComfortNoise; 1521 WebRtcAec_ComfortNoise = ComfortNoise;
1513 WebRtcAec_SubbandCoherence = SubbandCoherence; 1522 WebRtcAec_SubbandCoherence = SubbandCoherence;
1523 WebRtcAec_StoreAsComplex = StoreAsComplex;
1524 WebRtcAec_PartitionDelay = PartitionDelay;
1525 WebRtcAec_WindowData = WindowData;
1526
1514 1527
1515 #if defined(WEBRTC_ARCH_X86_FAMILY) 1528 #if defined(WEBRTC_ARCH_X86_FAMILY)
1516 if (WebRtc_GetCPUInfo(kSSE2)) { 1529 if (WebRtc_GetCPUInfo(kSSE2)) {
1517 WebRtcAec_InitAec_SSE2(); 1530 WebRtcAec_InitAec_SSE2();
1518 } 1531 }
1519 #endif 1532 #endif
1520 1533
1521 #if defined(MIPS_FPU_LE) 1534 #if defined(MIPS_FPU_LE)
1522 WebRtcAec_InitAec_mips(); 1535 WebRtcAec_InitAec_mips();
1523 #endif 1536 #endif
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
1954 int WebRtcAec_extended_filter_enabled(AecCore* self) { 1967 int WebRtcAec_extended_filter_enabled(AecCore* self) {
1955 return self->extended_filter_enabled; 1968 return self->extended_filter_enabled;
1956 } 1969 }
1957 1970
1958 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } 1971 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; }
1959 1972
1960 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 1973 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
1961 assert(delay >= 0); 1974 assert(delay >= 0);
1962 self->system_delay = delay; 1975 self->system_delay = delay;
1963 } 1976 }
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