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

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

Issue 1510873004: Using buffered signal to calculate the level of echo cancellation. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: reducing buffer for nearLevel and farLevel Created 4 years, 10 months 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/test/audio_processing_unittest.cc » ('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 649 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 660
661 // Upper mean 661 // Upper mean
662 if (dtmp > aec->erl.average) { 662 if (dtmp > aec->erl.average) {
663 aec->erl.hicounter++; 663 aec->erl.hicounter++;
664 aec->erl.hisum += dtmp; 664 aec->erl.hisum += dtmp;
665 aec->erl.himean = aec->erl.hisum / aec->erl.hicounter; 665 aec->erl.himean = aec->erl.hisum / aec->erl.hicounter;
666 } 666 }
667 667
668 // A_NLP 668 // A_NLP
669 dtmp = 10 * (float)log10(aec->nearlevel.averagelevel / 669 dtmp = 10 * (float)log10(aec->nearlevel.averagelevel /
670 (2 * aec->linoutlevel.averagelevel) + 670 aec->linoutlevel.averagelevel + 1e-10f);
671 1e-10f);
672 671
673 // subtract noise power 672 // subtract noise power
674 suppressedEcho = 2 * (aec->linoutlevel.averagelevel - 673 suppressedEcho = aec->linoutlevel.averagelevel -
675 safety * aec->linoutlevel.minlevel); 674 safety * aec->linoutlevel.minlevel;
676 675
677 dtmp2 = 10 * (float)log10(echo / suppressedEcho + 1e-10f); 676 dtmp2 = 10 * (float)log10(echo / suppressedEcho + 1e-10f);
678 677
679 aec->aNlp.instant = dtmp2; 678 aec->aNlp.instant = dtmp2;
680 if (dtmp > aec->aNlp.max) { 679 if (dtmp > aec->aNlp.max) {
681 aec->aNlp.max = dtmp; 680 aec->aNlp.max = dtmp;
682 } 681 }
683 682
684 if (dtmp < aec->aNlp.min) { 683 if (dtmp < aec->aNlp.min) {
685 aec->aNlp.min = dtmp; 684 aec->aNlp.min = dtmp;
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 (delay_quality > self->delay_quality_threshold ? delay_quality : 895 (delay_quality > self->delay_quality_threshold ? delay_quality :
897 self->delay_quality_threshold); 896 self->delay_quality_threshold);
898 } 897 }
899 return delay_correction; 898 return delay_correction;
900 } 899 }
901 900
902 static void EchoSubtraction( 901 static void EchoSubtraction(
903 AecCore* aec, 902 AecCore* aec,
904 int num_partitions, 903 int num_partitions,
905 int x_fft_buf_block_pos, 904 int x_fft_buf_block_pos,
906 int metrics_mode,
907 int extended_filter_enabled, 905 int extended_filter_enabled,
908 float normal_mu, 906 float normal_mu,
909 float normal_error_threshold, 907 float normal_error_threshold,
910 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], 908 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
911 float* const y, 909 float* const y,
912 float x_pow[PART_LEN1], 910 float x_pow[PART_LEN1],
913 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1], 911 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
914 PowerLevel* linout_level,
915 float echo_subtractor_output[PART_LEN]) { 912 float echo_subtractor_output[PART_LEN]) {
916 float s_fft[2][PART_LEN1]; 913 float s_fft[2][PART_LEN1];
917 float e_extended[PART_LEN2]; 914 float e_extended[PART_LEN2];
918 float s_extended[PART_LEN2]; 915 float s_extended[PART_LEN2];
919 float *s; 916 float *s;
920 float e[PART_LEN]; 917 float e[PART_LEN];
921 float e_fft[2][PART_LEN1]; 918 float e_fft[2][PART_LEN1];
922 int i; 919 int i;
923 memset(s_fft, 0, sizeof(s_fft)); 920 memset(s_fft, 0, sizeof(s_fft));
924 921
(...skipping 23 matching lines...) Expand all
948 945
949 // Compute the frequency domain echo prediction error. 946 // Compute the frequency domain echo prediction error.
950 memset(e_extended, 0, sizeof(float) * PART_LEN); 947 memset(e_extended, 0, sizeof(float) * PART_LEN);
951 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); 948 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN);
952 Fft(e_extended, e_fft); 949 Fft(e_extended, e_fft);
953 950
954 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, 951 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file,
955 &e_fft[0][0], 952 &e_fft[0][0],
956 sizeof(e_fft[0][0]) * PART_LEN1 * 2); 953 sizeof(e_fft[0][0]) * PART_LEN1 * 2);
957 954
958 if (metrics_mode == 1) {
959 // Note that the first PART_LEN samples in fft (before transformation) are
960 // zero. Hence, the scaling by two in UpdateLevel() should not be
961 // performed. That scaling is taken care of in UpdateMetrics() instead.
962 UpdateLevel(linout_level, CalculatePower(e, PART_LEN) / 2.0f);
963 }
964
965 // Scale error signal inversely with far power. 955 // Scale error signal inversely with far power.
966 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, 956 WebRtcAec_ScaleErrorSignal(extended_filter_enabled,
967 normal_mu, 957 normal_mu,
968 normal_error_threshold, 958 normal_error_threshold,
969 x_pow, 959 x_pow,
970 e_fft); 960 e_fft);
971 WebRtcAec_FilterAdaptation(num_partitions, 961 WebRtcAec_FilterAdaptation(num_partitions,
972 x_fft_buf_block_pos, 962 x_fft_buf_block_pos,
973 x_fft_buf, 963 x_fft_buf,
974 e_fft, 964 e_fft,
975 h_fft_buf); 965 h_fft_buf);
976 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); 966 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN);
977 } 967 }
978 968
979
980 static void EchoSuppression(AecCore* aec, 969 static void EchoSuppression(AecCore* aec,
981 float farend[PART_LEN2], 970 float farend[PART_LEN2],
982 float* echo_subtractor_output, 971 float* echo_subtractor_output,
983 float* output, 972 float* output,
984 float* const* outputH) { 973 float* const* outputH) {
985 float efw[2][PART_LEN1]; 974 float efw[2][PART_LEN1];
986 float xfw[2][PART_LEN1]; 975 float xfw[2][PART_LEN1];
987 float dfw[2][PART_LEN1]; 976 float dfw[2][PART_LEN1];
988 float comfortNoiseHband[2][PART_LEN1]; 977 float comfortNoiseHband[2][PART_LEN1];
989 float fft[PART_LEN2]; 978 float fft[PART_LEN2];
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 #ifdef WEBRTC_AEC_DEBUG_DUMP 1261 #ifdef WEBRTC_AEC_DEBUG_DUMP
1273 { 1262 {
1274 // TODO(minyue): |farend_ptr| starts from buffered samples. This will be 1263 // TODO(minyue): |farend_ptr| starts from buffered samples. This will be
1275 // modified when |aec->far_time_buf| is revised. 1264 // modified when |aec->far_time_buf| is revised.
1276 RTC_AEC_DEBUG_WAV_WRITE(aec->farFile, &farend_ptr[PART_LEN], PART_LEN); 1265 RTC_AEC_DEBUG_WAV_WRITE(aec->farFile, &farend_ptr[PART_LEN], PART_LEN);
1277 1266
1278 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN); 1267 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN);
1279 } 1268 }
1280 #endif 1269 #endif
1281 1270
1271 if (aec->metricsMode == 1) {
minyue-webrtc 2016/01/26 16:46:47 I reduced the buffer sizes for calculating farleve
1272 // Update power levels
1273 UpdateLevel(&aec->farlevel,
1274 CalculatePower(&farend_ptr[PART_LEN], PART_LEN));
1275 UpdateLevel(&aec->nearlevel, CalculatePower(nearend_ptr, PART_LEN));
1276 }
1277
1282 // Convert far-end signal to the frequency domain. 1278 // Convert far-end signal to the frequency domain.
1283 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); 1279 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2);
1284 Fft(fft, xf); 1280 Fft(fft, xf);
1285 xf_ptr = &xf[0][0]; 1281 xf_ptr = &xf[0][0];
1286 1282
1287 // Near fft 1283 // Near fft
1288 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); 1284 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2);
1289 Fft(fft, df); 1285 Fft(fft, df);
1290 1286
1291 if (aec->metricsMode == 1) {
1292 // Update power levels
1293 UpdateLevel(&aec->farlevel, CalculatePower(farend_ptr, PART_LEN2));
1294 UpdateLevel(&aec->nearlevel, CalculatePower(aec->dBuf, PART_LEN2));
1295 }
1296
1297 // Power smoothing 1287 // Power smoothing
1298 for (i = 0; i < PART_LEN1; i++) { 1288 for (i = 0; i < PART_LEN1; i++) {
1299 far_spectrum = (xf_ptr[i] * xf_ptr[i]) + 1289 far_spectrum = (xf_ptr[i] * xf_ptr[i]) +
1300 (xf_ptr[PART_LEN1 + i] * xf_ptr[PART_LEN1 + i]); 1290 (xf_ptr[PART_LEN1 + i] * xf_ptr[PART_LEN1 + i]);
1301 aec->xPow[i] = 1291 aec->xPow[i] =
1302 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; 1292 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum;
1303 // Calculate absolute spectra 1293 // Calculate absolute spectra
1304 abs_far_spectrum[i] = sqrtf(far_spectrum); 1294 abs_far_spectrum[i] = sqrtf(far_spectrum);
1305 1295
1306 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i]; 1296 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i];
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1367 xf_ptr, 1357 xf_ptr,
1368 sizeof(float) * PART_LEN1); 1358 sizeof(float) * PART_LEN1);
1369 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, 1359 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1,
1370 &xf_ptr[PART_LEN1], 1360 &xf_ptr[PART_LEN1],
1371 sizeof(float) * PART_LEN1); 1361 sizeof(float) * PART_LEN1);
1372 1362
1373 // Perform echo subtraction. 1363 // Perform echo subtraction.
1374 EchoSubtraction(aec, 1364 EchoSubtraction(aec,
1375 aec->num_partitions, 1365 aec->num_partitions,
1376 aec->xfBufBlockPos, 1366 aec->xfBufBlockPos,
1377 aec->metricsMode,
1378 aec->extended_filter_enabled, 1367 aec->extended_filter_enabled,
1379 aec->normal_mu, 1368 aec->normal_mu,
1380 aec->normal_error_threshold, 1369 aec->normal_error_threshold,
1381 aec->xfBuf, 1370 aec->xfBuf,
1382 nearend_ptr, 1371 nearend_ptr,
1383 aec->xPow, 1372 aec->xPow,
1384 aec->wfBuf, 1373 aec->wfBuf,
1385 &aec->linoutlevel,
1386 echo_subtractor_output); 1374 echo_subtractor_output);
1387 1375
1388 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); 1376 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN);
1389 1377
1378 if (aec->metricsMode == 1) {
1379 UpdateLevel(&aec->linoutlevel,
1380 CalculatePower(echo_subtractor_output, PART_LEN));
1381 }
1382
1390 // Perform echo suppression. 1383 // Perform echo suppression.
1391 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr); 1384 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr);
1392 1385
1393 if (aec->metricsMode == 1) { 1386 if (aec->metricsMode == 1) {
1394 UpdateMetrics(aec); 1387 UpdateMetrics(aec);
1395 } 1388 }
1396 1389
1397 // Store the output block. 1390 // Store the output block.
1398 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN); 1391 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN);
1399 // For high bands 1392 // For high bands
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
1706 1699
1707 aec->extreme_filter_divergence = 0; 1700 aec->extreme_filter_divergence = 0;
1708 1701
1709 // Metrics disabled by default 1702 // Metrics disabled by default
1710 aec->metricsMode = 0; 1703 aec->metricsMode = 0;
1711 InitMetrics(aec); 1704 InitMetrics(aec);
1712 1705
1713 return 0; 1706 return 0;
1714 } 1707 }
1715 1708
1716
1717 // For bit exactness with a legacy code, |farend| is supposed to contain 1709 // For bit exactness with a legacy code, |farend| is supposed to contain
1718 // |PART_LEN2| samples with an overlap of |PART_LEN| samples from the last 1710 // |PART_LEN2| samples with an overlap of |PART_LEN| samples from the last
1719 // frame. 1711 // frame.
1720 // TODO(minyue): reduce |farend| to non-overlapped |PART_LEN| samples. 1712 // TODO(minyue): reduce |farend| to non-overlapped |PART_LEN| samples.
1721 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) { 1713 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) {
1722 // Check if the buffer is full, and in that case flush the oldest data. 1714 // Check if the buffer is full, and in that case flush the oldest data.
1723 if (WebRtc_available_write(aec->far_time_buf) < 1) { 1715 if (WebRtc_available_write(aec->far_time_buf) < 1) {
1724 WebRtcAec_MoveFarReadPtr(aec, 1); 1716 WebRtcAec_MoveFarReadPtr(aec, 1);
1725 } 1717 }
1726 1718
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1924 int WebRtcAec_extended_filter_enabled(AecCore* self) { 1916 int WebRtcAec_extended_filter_enabled(AecCore* self) {
1925 return self->extended_filter_enabled; 1917 return self->extended_filter_enabled;
1926 } 1918 }
1927 1919
1928 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } 1920 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; }
1929 1921
1930 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 1922 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
1931 assert(delay >= 0); 1923 assert(delay >= 0);
1932 self->system_delay = delay; 1924 self->system_delay = delay;
1933 } 1925 }
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/audio_processing/test/audio_processing_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698