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 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |