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 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 892 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); | 892 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); |
| 893 delay_quality = (delay_quality > kDelayQualityThresholdMax ? | 893 delay_quality = (delay_quality > kDelayQualityThresholdMax ? |
| 894 kDelayQualityThresholdMax : delay_quality); | 894 kDelayQualityThresholdMax : delay_quality); |
| 895 self->delay_quality_threshold = | 895 self->delay_quality_threshold = |
| 896 (delay_quality > self->delay_quality_threshold ? delay_quality : | 896 (delay_quality > self->delay_quality_threshold ? delay_quality : |
| 897 self->delay_quality_threshold); | 897 self->delay_quality_threshold); |
| 898 } | 898 } |
| 899 return delay_correction; | 899 return delay_correction; |
| 900 } | 900 } |
| 901 | 901 |
| 902 static void EchoSubtraction( | 902 static void EchoSubtraction(AecCore* aec, |
| 903 AecCore* aec, | 903 int num_partitions, |
| 904 int num_partitions, | 904 int metrics_mode, |
| 905 int x_fft_buf_block_pos, | 905 int extended_filter_enabled, |
| 906 int metrics_mode, | 906 float normal_mu, |
| 907 int extended_filter_enabled, | 907 float normal_error_threshold, |
| 908 float normal_mu, | 908 float* x_fft, |
| 909 float normal_error_threshold, | 909 int* x_fft_buf_block_pos, |
| 910 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], | 910 float x_fft_buf[2] |
| 911 float* const y, | 911 [kExtendedNumPartitions * PART_LEN1], |
| 912 float x_pow[PART_LEN1], | 912 float* const y, |
| 913 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1], | 913 float x_pow[PART_LEN1], |
| 914 PowerLevel* linout_level, | 914 float h_fft_buf[2] |
| 915 float echo_subtractor_output[PART_LEN]) { | 915 [kExtendedNumPartitions * PART_LEN1], |
| 916 PowerLevel* linout_level, | |
| 917 float echo_subtractor_output[PART_LEN]) { | |
|
ivoc
2016/02/05 09:05:04
Although I noticed that most functions in the file
peah-webrtc
2016/02/05 10:19:49
Great point! That would definitely make sense. I'm
| |
| 916 float s_fft[2][PART_LEN1]; | 918 float s_fft[2][PART_LEN1]; |
| 917 float e_extended[PART_LEN2]; | 919 float e_extended[PART_LEN2]; |
| 918 float s_extended[PART_LEN2]; | 920 float s_extended[PART_LEN2]; |
| 919 float *s; | 921 float *s; |
| 920 float e[PART_LEN]; | 922 float e[PART_LEN]; |
| 921 float e_fft[2][PART_LEN1]; | 923 float e_fft[2][PART_LEN1]; |
| 922 int i; | 924 int i; |
| 925 | |
| 926 // Update the x_fft_buf block position. | |
| 927 (*x_fft_buf_block_pos)--; | |
| 928 if ((*x_fft_buf_block_pos) == -1) { | |
| 929 *x_fft_buf_block_pos = num_partitions - 1; | |
| 930 } | |
| 931 | |
| 932 // Buffer x_fft. | |
| 933 memcpy(x_fft_buf[0] + (*x_fft_buf_block_pos) * PART_LEN1, x_fft, | |
| 934 sizeof(float) * PART_LEN1); | |
| 935 memcpy(x_fft_buf[1] + (*x_fft_buf_block_pos) * PART_LEN1, &x_fft[PART_LEN1], | |
| 936 sizeof(float) * PART_LEN1); | |
| 937 | |
| 923 memset(s_fft, 0, sizeof(s_fft)); | 938 memset(s_fft, 0, sizeof(s_fft)); |
| 924 | 939 |
| 925 // Conditionally reset the echo subtraction filter if the filter has diverged | 940 // Conditionally reset the echo subtraction filter if the filter has diverged |
| 926 // significantly. | 941 // significantly. |
| 927 if (!aec->extended_filter_enabled && | 942 if (!aec->extended_filter_enabled && |
| 928 aec->extreme_filter_divergence) { | 943 aec->extreme_filter_divergence) { |
| 929 memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); | 944 memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); |
| 930 aec->extreme_filter_divergence = 0; | 945 aec->extreme_filter_divergence = 0; |
| 931 } | 946 } |
| 932 | 947 |
| 933 // Produce echo estimate s_fft. | 948 // Produce echo estimate s_fft. |
| 934 WebRtcAec_FilterFar(num_partitions, | 949 WebRtcAec_FilterFar(num_partitions, *x_fft_buf_block_pos, x_fft_buf, |
| 935 x_fft_buf_block_pos, | 950 h_fft_buf, s_fft); |
| 936 x_fft_buf, | |
| 937 h_fft_buf, | |
| 938 s_fft); | |
| 939 | 951 |
| 940 // Compute the time-domain echo estimate s. | 952 // Compute the time-domain echo estimate s. |
| 941 ScaledInverseFft(s_fft, s_extended, 2.0f, 0); | 953 ScaledInverseFft(s_fft, s_extended, 2.0f, 0); |
| 942 s = &s_extended[PART_LEN]; | 954 s = &s_extended[PART_LEN]; |
| 943 | 955 |
| 944 // Compute the time-domain echo prediction error. | 956 // Compute the time-domain echo prediction error. |
| 945 for (i = 0; i < PART_LEN; ++i) { | 957 for (i = 0; i < PART_LEN; ++i) { |
| 946 e[i] = y[i] - s[i]; | 958 e[i] = y[i] - s[i]; |
| 947 } | 959 } |
| 948 | 960 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 961 // performed. That scaling is taken care of in UpdateMetrics() instead. | 973 // performed. That scaling is taken care of in UpdateMetrics() instead. |
| 962 UpdateLevel(linout_level, CalculatePower(e, PART_LEN) / 2.0f); | 974 UpdateLevel(linout_level, CalculatePower(e, PART_LEN) / 2.0f); |
| 963 } | 975 } |
| 964 | 976 |
| 965 // Scale error signal inversely with far power. | 977 // Scale error signal inversely with far power. |
| 966 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, | 978 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, |
| 967 normal_mu, | 979 normal_mu, |
| 968 normal_error_threshold, | 980 normal_error_threshold, |
| 969 x_pow, | 981 x_pow, |
| 970 e_fft); | 982 e_fft); |
| 971 WebRtcAec_FilterAdaptation(num_partitions, | 983 WebRtcAec_FilterAdaptation(num_partitions, *x_fft_buf_block_pos, x_fft_buf, |
| 972 x_fft_buf_block_pos, | 984 e_fft, h_fft_buf); |
| 973 x_fft_buf, | |
| 974 e_fft, | |
| 975 h_fft_buf); | |
| 976 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); | 985 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); |
| 977 } | 986 } |
| 978 | 987 |
| 979 | 988 |
| 980 static void EchoSuppression(AecCore* aec, | 989 static void EchoSuppression(AecCore* aec, |
| 981 float farend[PART_LEN2], | 990 float farend[PART_LEN2], |
| 982 float* echo_subtractor_output, | 991 float* echo_subtractor_output, |
| 983 float* output, | 992 float* output, |
| 984 float* const* outputH) { | 993 float* const* outputH) { |
| 985 float efw[2][PART_LEN1]; | 994 float efw[2][PART_LEN1]; |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1218 | 1227 |
| 1219 memmove(aec->xfwBuf + PART_LEN1, | 1228 memmove(aec->xfwBuf + PART_LEN1, |
| 1220 aec->xfwBuf, | 1229 aec->xfwBuf, |
| 1221 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); | 1230 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); |
| 1222 } | 1231 } |
| 1223 | 1232 |
| 1224 static void ProcessBlock(AecCore* aec) { | 1233 static void ProcessBlock(AecCore* aec) { |
| 1225 size_t i; | 1234 size_t i; |
| 1226 | 1235 |
| 1227 float fft[PART_LEN2]; | 1236 float fft[PART_LEN2]; |
| 1228 float xf[2][PART_LEN1]; | 1237 float x_fft[2][PART_LEN1]; |
| 1229 float df[2][PART_LEN1]; | 1238 float df[2][PART_LEN1]; |
| 1230 float far_spectrum = 0.0f; | 1239 float far_spectrum = 0.0f; |
| 1231 float near_spectrum = 0.0f; | 1240 float near_spectrum = 0.0f; |
| 1232 float abs_far_spectrum[PART_LEN1]; | 1241 float abs_far_spectrum[PART_LEN1]; |
| 1233 float abs_near_spectrum[PART_LEN1]; | 1242 float abs_near_spectrum[PART_LEN1]; |
| 1234 | 1243 |
| 1235 const float gPow[2] = {0.9f, 0.1f}; | 1244 const float gPow[2] = {0.9f, 0.1f}; |
| 1236 | 1245 |
| 1237 // Noise estimate constants. | 1246 // Noise estimate constants. |
| 1238 const int noiseInitBlocks = 500 * aec->mult; | 1247 const int noiseInitBlocks = 500 * aec->mult; |
| 1239 const float step = 0.1f; | 1248 const float step = 0.1f; |
| 1240 const float ramp = 1.0002f; | 1249 const float ramp = 1.0002f; |
| 1241 const float gInitNoise[2] = {0.999f, 0.001f}; | 1250 const float gInitNoise[2] = {0.999f, 0.001f}; |
| 1242 | 1251 |
| 1243 float nearend[PART_LEN]; | 1252 float nearend[PART_LEN]; |
| 1244 float* nearend_ptr = NULL; | 1253 float* nearend_ptr = NULL; |
| 1245 float farend[PART_LEN2]; | 1254 float farend[PART_LEN2]; |
| 1246 float* farend_ptr = NULL; | 1255 float* farend_ptr = NULL; |
| 1247 float echo_subtractor_output[PART_LEN]; | 1256 float echo_subtractor_output[PART_LEN]; |
| 1248 float output[PART_LEN]; | 1257 float output[PART_LEN]; |
| 1249 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; | 1258 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; |
| 1250 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; | 1259 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; |
| 1251 float* xf_ptr = NULL; | 1260 float* x_fft_ptr = NULL; |
| 1252 | 1261 |
| 1253 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1262 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
| 1254 outputH_ptr[i] = outputH[i]; | 1263 outputH_ptr[i] = outputH[i]; |
| 1255 } | 1264 } |
| 1256 | 1265 |
| 1257 // Concatenate old and new nearend blocks. | 1266 // Concatenate old and new nearend blocks. |
| 1258 for (i = 0; i < aec->num_bands - 1; ++i) { | 1267 for (i = 0; i < aec->num_bands - 1; ++i) { |
| 1259 WebRtc_ReadBuffer(aec->nearFrBufH[i], | 1268 WebRtc_ReadBuffer(aec->nearFrBufH[i], |
| 1260 (void**)&nearend_ptr, | 1269 (void**)&nearend_ptr, |
| 1261 nearend, | 1270 nearend, |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1274 // TODO(minyue): |farend_ptr| starts from buffered samples. This will be | 1283 // TODO(minyue): |farend_ptr| starts from buffered samples. This will be |
| 1275 // modified when |aec->far_time_buf| is revised. | 1284 // modified when |aec->far_time_buf| is revised. |
| 1276 RTC_AEC_DEBUG_WAV_WRITE(aec->farFile, &farend_ptr[PART_LEN], PART_LEN); | 1285 RTC_AEC_DEBUG_WAV_WRITE(aec->farFile, &farend_ptr[PART_LEN], PART_LEN); |
| 1277 | 1286 |
| 1278 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN); | 1287 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN); |
| 1279 } | 1288 } |
| 1280 #endif | 1289 #endif |
| 1281 | 1290 |
| 1282 // Convert far-end signal to the frequency domain. | 1291 // Convert far-end signal to the frequency domain. |
| 1283 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); | 1292 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); |
| 1284 Fft(fft, xf); | 1293 Fft(fft, x_fft); |
| 1285 xf_ptr = &xf[0][0]; | 1294 x_fft_ptr = &x_fft[0][0]; |
| 1286 | 1295 |
| 1287 // Near fft | 1296 // Near fft |
| 1288 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); | 1297 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); |
| 1289 Fft(fft, df); | 1298 Fft(fft, df); |
| 1290 | 1299 |
| 1291 if (aec->metricsMode == 1) { | 1300 if (aec->metricsMode == 1) { |
| 1292 // Update power levels | 1301 // Update power levels |
| 1293 UpdateLevel(&aec->farlevel, CalculatePower(farend_ptr, PART_LEN2)); | 1302 UpdateLevel(&aec->farlevel, CalculatePower(farend_ptr, PART_LEN2)); |
| 1294 UpdateLevel(&aec->nearlevel, CalculatePower(aec->dBuf, PART_LEN2)); | 1303 UpdateLevel(&aec->nearlevel, CalculatePower(aec->dBuf, PART_LEN2)); |
| 1295 } | 1304 } |
| 1296 | 1305 |
| 1297 // Power smoothing | 1306 // Power smoothing |
| 1298 for (i = 0; i < PART_LEN1; i++) { | 1307 for (i = 0; i < PART_LEN1; i++) { |
| 1299 far_spectrum = (xf_ptr[i] * xf_ptr[i]) + | 1308 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + |
| 1300 (xf_ptr[PART_LEN1 + i] * xf_ptr[PART_LEN1 + i]); | 1309 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); |
| 1301 aec->xPow[i] = | 1310 aec->xPow[i] = |
| 1302 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; | 1311 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; |
| 1303 // Calculate absolute spectra | 1312 // Calculate absolute spectra |
| 1304 abs_far_spectrum[i] = sqrtf(far_spectrum); | 1313 abs_far_spectrum[i] = sqrtf(far_spectrum); |
| 1305 | 1314 |
| 1306 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i]; | 1315 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i]; |
| 1307 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum; | 1316 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum; |
| 1308 // Calculate absolute spectra | 1317 // Calculate absolute spectra |
| 1309 abs_near_spectrum[i] = sqrtf(near_spectrum); | 1318 abs_near_spectrum[i] = sqrtf(near_spectrum); |
| 1310 } | 1319 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1349 aec->delay_histogram[delay_estimate]++; | 1358 aec->delay_histogram[delay_estimate]++; |
| 1350 aec->num_delay_values++; | 1359 aec->num_delay_values++; |
| 1351 } | 1360 } |
| 1352 if (aec->delay_metrics_delivered == 1 && | 1361 if (aec->delay_metrics_delivered == 1 && |
| 1353 aec->num_delay_values >= kDelayMetricsAggregationWindow) { | 1362 aec->num_delay_values >= kDelayMetricsAggregationWindow) { |
| 1354 UpdateDelayMetrics(aec); | 1363 UpdateDelayMetrics(aec); |
| 1355 } | 1364 } |
| 1356 } | 1365 } |
| 1357 } | 1366 } |
| 1358 | 1367 |
| 1359 // Update the xfBuf block position. | |
| 1360 aec->xfBufBlockPos--; | |
| 1361 if (aec->xfBufBlockPos == -1) { | |
| 1362 aec->xfBufBlockPos = aec->num_partitions - 1; | |
| 1363 } | |
| 1364 | |
| 1365 // Buffer xf | |
| 1366 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, | |
| 1367 xf_ptr, | |
| 1368 sizeof(float) * PART_LEN1); | |
| 1369 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, | |
| 1370 &xf_ptr[PART_LEN1], | |
| 1371 sizeof(float) * PART_LEN1); | |
| 1372 | |
| 1373 // Perform echo subtraction. | 1368 // Perform echo subtraction. |
| 1374 EchoSubtraction(aec, | 1369 EchoSubtraction(aec, aec->num_partitions, aec->metricsMode, |
| 1375 aec->num_partitions, | 1370 aec->extended_filter_enabled, aec->normal_mu, |
| 1376 aec->xfBufBlockPos, | 1371 aec->normal_error_threshold, &x_fft[0][0], |
| 1377 aec->metricsMode, | 1372 &aec->xfBufBlockPos, aec->xfBuf, nearend_ptr, aec->xPow, |
| 1378 aec->extended_filter_enabled, | 1373 aec->wfBuf, &aec->linoutlevel, echo_subtractor_output); |
| 1379 aec->normal_mu, | |
| 1380 aec->normal_error_threshold, | |
| 1381 aec->xfBuf, | |
| 1382 nearend_ptr, | |
| 1383 aec->xPow, | |
| 1384 aec->wfBuf, | |
| 1385 &aec->linoutlevel, | |
| 1386 echo_subtractor_output); | |
| 1387 | 1374 |
| 1388 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); | 1375 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); |
| 1389 | 1376 |
| 1390 // Perform echo suppression. | 1377 // Perform echo suppression. |
| 1391 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr); | 1378 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr); |
| 1392 | 1379 |
| 1393 if (aec->metricsMode == 1) { | 1380 if (aec->metricsMode == 1) { |
| 1394 UpdateMetrics(aec); | 1381 UpdateMetrics(aec); |
| 1395 } | 1382 } |
| 1396 | 1383 |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1924 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 1911 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
| 1925 return self->extended_filter_enabled; | 1912 return self->extended_filter_enabled; |
| 1926 } | 1913 } |
| 1927 | 1914 |
| 1928 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } | 1915 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } |
| 1929 | 1916 |
| 1930 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1917 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
| 1931 assert(delay >= 0); | 1918 assert(delay >= 0); |
| 1932 self->system_delay = delay; | 1919 self->system_delay = delay; |
| 1933 } | 1920 } |
| OLD | NEW |