Chromium Code Reviews| 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 |