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 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 13 matching lines...) Expand all Loading... | |
1003 // Power estimate smoothing coefficients. | 992 // Power estimate smoothing coefficients. |
1004 const float* min_overdrive = aec->extended_filter_enabled | 993 const float* min_overdrive = aec->extended_filter_enabled |
1005 ? kExtendedMinOverDrive | 994 ? kExtendedMinOverDrive |
1006 : kNormalMinOverDrive; | 995 : kNormalMinOverDrive; |
1007 | 996 |
1008 // Filter energy | 997 // Filter energy |
1009 const int delayEstInterval = 10 * aec->mult; | 998 const int delayEstInterval = 10 * aec->mult; |
1010 | 999 |
1011 float* xfw_ptr = NULL; | 1000 float* xfw_ptr = NULL; |
1012 | 1001 |
1013 // Update eBuf with echo subtractor output. | |
1014 memcpy(aec->eBuf + PART_LEN, | |
1015 echo_subtractor_output, | |
1016 sizeof(float) * PART_LEN); | |
1017 | |
1018 // Analysis filter banks for the echo suppressor. | 1002 // Analysis filter banks for the echo suppressor. |
1019 // Windowed near-end ffts. | 1003 // Windowed near-end ffts. |
1020 WindowData(fft, aec->dBuf); | 1004 WindowData(fft, aec->dBuf); |
1021 aec_rdft_forward_128(fft); | 1005 aec_rdft_forward_128(fft); |
1022 StoreAsComplex(fft, dfw); | 1006 StoreAsComplex(fft, dfw); |
1023 | 1007 |
1024 // Windowed echo suppressor output ffts. | 1008 // Windowed echo suppressor output ffts. |
1025 WindowData(fft, aec->eBuf); | 1009 WindowData(fft, aec->eBuf); |
1026 aec_rdft_forward_128(fft); | 1010 aec_rdft_forward_128(fft); |
1027 StoreAsComplex(fft, efw); | 1011 StoreAsComplex(fft, efw); |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1367 xf_ptr, | 1351 xf_ptr, |
1368 sizeof(float) * PART_LEN1); | 1352 sizeof(float) * PART_LEN1); |
1369 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, | 1353 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, |
1370 &xf_ptr[PART_LEN1], | 1354 &xf_ptr[PART_LEN1], |
1371 sizeof(float) * PART_LEN1); | 1355 sizeof(float) * PART_LEN1); |
1372 | 1356 |
1373 // Perform echo subtraction. | 1357 // Perform echo subtraction. |
1374 EchoSubtraction(aec, | 1358 EchoSubtraction(aec, |
1375 aec->num_partitions, | 1359 aec->num_partitions, |
1376 aec->xfBufBlockPos, | 1360 aec->xfBufBlockPos, |
1377 aec->metricsMode, | |
1378 aec->extended_filter_enabled, | 1361 aec->extended_filter_enabled, |
1379 aec->normal_mu, | 1362 aec->normal_mu, |
1380 aec->normal_error_threshold, | 1363 aec->normal_error_threshold, |
1381 aec->xfBuf, | 1364 aec->xfBuf, |
1382 nearend_ptr, | 1365 nearend_ptr, |
1383 aec->xPow, | 1366 aec->xPow, |
1384 aec->wfBuf, | 1367 aec->wfBuf, |
1385 &aec->linoutlevel, | |
1386 echo_subtractor_output); | 1368 echo_subtractor_output); |
1387 | 1369 |
1388 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); | 1370 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); |
1389 | 1371 |
1372 // Update eBuf with echo subtractor output. | |
peah-webrtc
2016/01/25 12:23:02
This may be affected by changes in the future. As
minyue-webrtc
2016/01/25 14:26:55
Good point. It is true that when the linear filter
| |
1373 memcpy(aec->eBuf + PART_LEN, | |
1374 echo_subtractor_output, | |
1375 sizeof(float) * PART_LEN); | |
1376 | |
1377 if (aec->metricsMode == 1) { | |
1378 UpdateLevel(&aec->linoutlevel, CalculatePower(aec->eBuf, PART_LEN2)); | |
1379 } | |
1380 | |
1390 // Perform echo suppression. | 1381 // Perform echo suppression. |
1391 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr); | 1382 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr); |
1392 | 1383 |
1393 if (aec->metricsMode == 1) { | 1384 if (aec->metricsMode == 1) { |
1394 UpdateMetrics(aec); | 1385 UpdateMetrics(aec); |
1395 } | 1386 } |
1396 | 1387 |
1397 // Store the output block. | 1388 // Store the output block. |
1398 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN); | 1389 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN); |
1399 // For high bands | 1390 // For high bands |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1924 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 1915 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
1925 return self->extended_filter_enabled; | 1916 return self->extended_filter_enabled; |
1926 } | 1917 } |
1927 | 1918 |
1928 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } | 1919 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } |
1929 | 1920 |
1930 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1921 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1931 assert(delay >= 0); | 1922 assert(delay >= 0); |
1932 self->system_delay = delay; | 1923 self->system_delay = delay; |
1933 } | 1924 } |
OLD | NEW |