| 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 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 freq_data[1][0] = 0; | 839 freq_data[1][0] = 0; |
| 840 freq_data[1][PART_LEN] = 0; | 840 freq_data[1][PART_LEN] = 0; |
| 841 freq_data[0][0] = time_data[0]; | 841 freq_data[0][0] = time_data[0]; |
| 842 freq_data[0][PART_LEN] = time_data[1]; | 842 freq_data[0][PART_LEN] = time_data[1]; |
| 843 for (i = 1; i < PART_LEN; i++) { | 843 for (i = 1; i < PART_LEN; i++) { |
| 844 freq_data[0][i] = time_data[2 * i]; | 844 freq_data[0][i] = time_data[2 * i]; |
| 845 freq_data[1][i] = time_data[2 * i + 1]; | 845 freq_data[1][i] = time_data[2 * i + 1]; |
| 846 } | 846 } |
| 847 } | 847 } |
| 848 | 848 |
| 849 static int MoveFarReadPtrWithoutSystemDelayUpdate(AecCore* self, int elements) { | |
| 850 WebRtc_MoveReadPtr(self->far_buf_windowed, elements); | |
| 851 #ifdef WEBRTC_AEC_DEBUG_DUMP | |
| 852 WebRtc_MoveReadPtr(self->far_time_buf, elements); | |
| 853 #endif | |
| 854 return WebRtc_MoveReadPtr(self->far_buf, elements); | |
| 855 } | |
| 856 | 849 |
| 857 static int SignalBasedDelayCorrection(AecCore* self) { | 850 static int SignalBasedDelayCorrection(AecCore* self) { |
| 858 int delay_correction = 0; | 851 int delay_correction = 0; |
| 859 int last_delay = -2; | 852 int last_delay = -2; |
| 860 assert(self != NULL); | 853 assert(self != NULL); |
| 861 #if !defined(WEBRTC_ANDROID) | 854 #if !defined(WEBRTC_ANDROID) |
| 862 // On desktops, turn on correction after |kDelayCorrectionStart| frames. This | 855 // On desktops, turn on correction after |kDelayCorrectionStart| frames. This |
| 863 // is to let the delay estimation get a chance to converge. Also, if the | 856 // is to let the delay estimation get a chance to converge. Also, if the |
| 864 // playout audio volume is low (or even muted) the delay estimation can return | 857 // playout audio volume is low (or even muted) the delay estimation can return |
| 865 // a very large delay, which will break the AEC if it is applied. | 858 // a very large delay, which will break the AEC if it is applied. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 886 self->delay_quality_threshold)) { | 879 self->delay_quality_threshold)) { |
| 887 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); | 880 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); |
| 888 // Allow for a slack in the actual delay, defined by a |lower_bound| and an | 881 // Allow for a slack in the actual delay, defined by a |lower_bound| and an |
| 889 // |upper_bound|. The adaptive echo cancellation filter is currently | 882 // |upper_bound|. The adaptive echo cancellation filter is currently |
| 890 // |num_partitions| (of 64 samples) long. If the delay estimate is negative | 883 // |num_partitions| (of 64 samples) long. If the delay estimate is negative |
| 891 // or at least 3/4 of the filter length we open up for correction. | 884 // or at least 3/4 of the filter length we open up for correction. |
| 892 const int lower_bound = 0; | 885 const int lower_bound = 0; |
| 893 const int upper_bound = self->num_partitions * 3 / 4; | 886 const int upper_bound = self->num_partitions * 3 / 4; |
| 894 const int do_correction = delay <= lower_bound || delay > upper_bound; | 887 const int do_correction = delay <= lower_bound || delay > upper_bound; |
| 895 if (do_correction == 1) { | 888 if (do_correction == 1) { |
| 896 int available_read = (int)WebRtc_available_read(self->far_buf); | 889 int available_read = (int)WebRtc_available_read(self->far_time_buf); |
| 897 // With |shift_offset| we gradually rely on the delay estimates. For | 890 // With |shift_offset| we gradually rely on the delay estimates. For |
| 898 // positive delays we reduce the correction by |shift_offset| to lower the | 891 // positive delays we reduce the correction by |shift_offset| to lower the |
| 899 // risk of pushing the AEC into a non causal state. For negative delays | 892 // risk of pushing the AEC into a non causal state. For negative delays |
| 900 // we rely on the values up to a rounding error, hence compensate by 1 | 893 // we rely on the values up to a rounding error, hence compensate by 1 |
| 901 // element to make sure to push the delay into the causal region. | 894 // element to make sure to push the delay into the causal region. |
| 902 delay_correction = -delay; | 895 delay_correction = -delay; |
| 903 delay_correction += delay > self->shift_offset ? self->shift_offset : 1; | 896 delay_correction += delay > self->shift_offset ? self->shift_offset : 1; |
| 904 self->shift_offset--; | 897 self->shift_offset--; |
| 905 self->shift_offset = (self->shift_offset <= 1 ? 1 : self->shift_offset); | 898 self->shift_offset = (self->shift_offset <= 1 ? 1 : self->shift_offset); |
| 906 if (delay_correction > available_read - self->mult - 1) { | 899 if (delay_correction > available_read - self->mult - 1) { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 WebRtcAec_FilterAdaptation(num_partitions, | 991 WebRtcAec_FilterAdaptation(num_partitions, |
| 999 x_fft_buf_block_pos, | 992 x_fft_buf_block_pos, |
| 1000 x_fft_buf, | 993 x_fft_buf, |
| 1001 e_fft, | 994 e_fft, |
| 1002 h_fft_buf); | 995 h_fft_buf); |
| 1003 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); | 996 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); |
| 1004 } | 997 } |
| 1005 | 998 |
| 1006 | 999 |
| 1007 static void EchoSuppression(AecCore* aec, | 1000 static void EchoSuppression(AecCore* aec, |
| 1001 float farend[PART_LEN2], |
| 1008 float* echo_subtractor_output, | 1002 float* echo_subtractor_output, |
| 1009 float* output, | 1003 float* output, |
| 1010 float* const* outputH) { | 1004 float* const* outputH) { |
| 1011 float efw[2][PART_LEN1]; | 1005 float efw[2][PART_LEN1]; |
| 1012 float xfw[2][PART_LEN1]; | 1006 float xfw[2][PART_LEN1]; |
| 1013 float dfw[2][PART_LEN1]; | 1007 float dfw[2][PART_LEN1]; |
| 1014 float comfortNoiseHband[2][PART_LEN1]; | 1008 float comfortNoiseHband[2][PART_LEN1]; |
| 1015 float fft[PART_LEN2]; | 1009 float fft[PART_LEN2]; |
| 1016 float nlpGainHband; | 1010 float nlpGainHband; |
| 1017 int i; | 1011 int i; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1045 // Windowed near-end ffts. | 1039 // Windowed near-end ffts. |
| 1046 WindowData(fft, aec->dBuf); | 1040 WindowData(fft, aec->dBuf); |
| 1047 aec_rdft_forward_128(fft); | 1041 aec_rdft_forward_128(fft); |
| 1048 StoreAsComplex(fft, dfw); | 1042 StoreAsComplex(fft, dfw); |
| 1049 | 1043 |
| 1050 // Windowed echo suppressor output ffts. | 1044 // Windowed echo suppressor output ffts. |
| 1051 WindowData(fft, aec->eBuf); | 1045 WindowData(fft, aec->eBuf); |
| 1052 aec_rdft_forward_128(fft); | 1046 aec_rdft_forward_128(fft); |
| 1053 StoreAsComplex(fft, efw); | 1047 StoreAsComplex(fft, efw); |
| 1054 | 1048 |
| 1055 // We should always have at least one element stored in |far_buf|. | |
| 1056 assert(WebRtc_available_read(aec->far_buf_windowed) > 0); | |
| 1057 // NLP | 1049 // NLP |
| 1058 WebRtc_ReadBuffer(aec->far_buf_windowed, (void**)&xfw_ptr, &xfw[0][0], 1); | |
| 1059 | 1050 |
| 1060 // TODO(bjornv): Investigate if we can reuse |far_buf_windowed| instead of | 1051 // Convert far-end partition to the frequency domain with windowing. |
| 1061 // |xfwBuf|. | 1052 WindowData(fft, farend); |
| 1053 Fft(fft, xfw); |
| 1054 xfw_ptr = &xfw[0][0]; |
| 1055 |
| 1062 // Buffer far. | 1056 // Buffer far. |
| 1063 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); | 1057 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); |
| 1064 | 1058 |
| 1065 aec->delayEstCtr++; | 1059 aec->delayEstCtr++; |
| 1066 if (aec->delayEstCtr == delayEstInterval) { | 1060 if (aec->delayEstCtr == delayEstInterval) { |
| 1067 aec->delayEstCtr = 0; | 1061 aec->delayEstCtr = 0; |
| 1068 aec->delayIdx = WebRtcAec_PartitionDelay(aec); | 1062 aec->delayIdx = WebRtcAec_PartitionDelay(aec); |
| 1069 } | 1063 } |
| 1070 | 1064 |
| 1071 // Use delayed far. | 1065 // Use delayed far. |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1260 | 1254 |
| 1261 const float gPow[2] = {0.9f, 0.1f}; | 1255 const float gPow[2] = {0.9f, 0.1f}; |
| 1262 | 1256 |
| 1263 // Noise estimate constants. | 1257 // Noise estimate constants. |
| 1264 const int noiseInitBlocks = 500 * aec->mult; | 1258 const int noiseInitBlocks = 500 * aec->mult; |
| 1265 const float step = 0.1f; | 1259 const float step = 0.1f; |
| 1266 const float ramp = 1.0002f; | 1260 const float ramp = 1.0002f; |
| 1267 const float gInitNoise[2] = {0.999f, 0.001f}; | 1261 const float gInitNoise[2] = {0.999f, 0.001f}; |
| 1268 | 1262 |
| 1269 float nearend[PART_LEN]; | 1263 float nearend[PART_LEN]; |
| 1264 float* nearend_ptr = NULL; |
| 1265 float farend[PART_LEN2]; |
| 1266 float* farend_ptr = NULL; |
| 1270 float echo_subtractor_output[PART_LEN]; | 1267 float echo_subtractor_output[PART_LEN]; |
| 1271 float* nearend_ptr = NULL; | |
| 1272 float output[PART_LEN]; | 1268 float output[PART_LEN]; |
| 1273 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; | 1269 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; |
| 1274 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; | 1270 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; |
| 1275 float* xf_ptr = NULL; | 1271 float* xf_ptr = NULL; |
| 1276 | 1272 |
| 1277 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1273 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
| 1278 outputH_ptr[i] = outputH[i]; | 1274 outputH_ptr[i] = outputH[i]; |
| 1279 } | 1275 } |
| 1280 | 1276 |
| 1281 // Concatenate old and new nearend blocks. | 1277 // Concatenate old and new nearend blocks. |
| 1282 for (i = 0; i < aec->num_bands - 1; ++i) { | 1278 for (i = 0; i < aec->num_bands - 1; ++i) { |
| 1283 WebRtc_ReadBuffer(aec->nearFrBufH[i], | 1279 WebRtc_ReadBuffer(aec->nearFrBufH[i], |
| 1284 (void**)&nearend_ptr, | 1280 (void**)&nearend_ptr, |
| 1285 nearend, | 1281 nearend, |
| 1286 PART_LEN); | 1282 PART_LEN); |
| 1287 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); | 1283 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); |
| 1288 } | 1284 } |
| 1289 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN); | 1285 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN); |
| 1290 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend)); | 1286 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend)); |
| 1291 | 1287 |
| 1292 // ---------- Ooura fft ---------- | 1288 // We should always have at least one element stored in |far_buf|. |
| 1289 assert(WebRtc_available_read(aec->far_time_buf) > 0); |
| 1290 WebRtc_ReadBuffer(aec->far_time_buf, (void**)&farend_ptr, farend, 1); |
| 1293 | 1291 |
| 1294 #ifdef WEBRTC_AEC_DEBUG_DUMP | 1292 #ifdef WEBRTC_AEC_DEBUG_DUMP |
| 1295 { | 1293 { |
| 1296 float farend[PART_LEN]; | 1294 // TODO(minyue): |farend_ptr| starts from buffered samples. This will be |
| 1297 float* farend_ptr = NULL; | 1295 // modified when |aec->far_time_buf| is revised. |
| 1298 WebRtc_ReadBuffer(aec->far_time_buf, (void**)&farend_ptr, farend, 1); | 1296 RTC_AEC_DEBUG_WAV_WRITE(aec->farFile, &farend_ptr[PART_LEN], PART_LEN); |
| 1299 RTC_AEC_DEBUG_WAV_WRITE(aec->farFile, farend_ptr, PART_LEN); | 1297 |
| 1300 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN); | 1298 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN); |
| 1301 } | 1299 } |
| 1302 #endif | 1300 #endif |
| 1303 | 1301 |
| 1304 // We should always have at least one element stored in |far_buf|. | 1302 // Convert far-end signal to the frequency domain. |
| 1305 assert(WebRtc_available_read(aec->far_buf) > 0); | 1303 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); |
| 1306 WebRtc_ReadBuffer(aec->far_buf, (void**)&xf_ptr, &xf[0][0], 1); | 1304 Fft(fft, xf); |
| 1305 xf_ptr = &xf[0][0]; |
| 1307 | 1306 |
| 1308 // Near fft | 1307 // Near fft |
| 1309 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); | 1308 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); |
| 1310 Fft(fft, df); | 1309 Fft(fft, df); |
| 1311 | 1310 |
| 1312 // Power smoothing | 1311 // Power smoothing |
| 1313 for (i = 0; i < PART_LEN1; i++) { | 1312 for (i = 0; i < PART_LEN1; i++) { |
| 1314 far_spectrum = (xf_ptr[i] * xf_ptr[i]) + | 1313 far_spectrum = (xf_ptr[i] * xf_ptr[i]) + |
| 1315 (xf_ptr[PART_LEN1 + i] * xf_ptr[PART_LEN1 + i]); | 1314 (xf_ptr[PART_LEN1 + i] * xf_ptr[PART_LEN1 + i]); |
| 1316 aec->xPow[i] = | 1315 aec->xPow[i] = |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 aec->xfBuf, | 1395 aec->xfBuf, |
| 1397 nearend_ptr, | 1396 nearend_ptr, |
| 1398 aec->xPow, | 1397 aec->xPow, |
| 1399 aec->wfBuf, | 1398 aec->wfBuf, |
| 1400 &aec->linoutlevel, | 1399 &aec->linoutlevel, |
| 1401 echo_subtractor_output); | 1400 echo_subtractor_output); |
| 1402 | 1401 |
| 1403 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); | 1402 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); |
| 1404 | 1403 |
| 1405 // Perform echo suppression. | 1404 // Perform echo suppression. |
| 1406 EchoSuppression(aec, echo_subtractor_output, output, outputH_ptr); | 1405 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr); |
| 1407 | 1406 |
| 1408 if (aec->metricsMode == 1) { | 1407 if (aec->metricsMode == 1) { |
| 1409 // Update power levels and echo metrics | 1408 // Update power levels and echo metrics |
| 1410 UpdateLevel(&aec->farlevel, (float(*)[PART_LEN1])xf_ptr); | 1409 UpdateLevel(&aec->farlevel, (float(*)[PART_LEN1])xf_ptr); |
| 1411 UpdateLevel(&aec->nearlevel, df); | 1410 UpdateLevel(&aec->nearlevel, df); |
| 1412 UpdateMetrics(aec); | 1411 UpdateMetrics(aec); |
| 1413 } | 1412 } |
| 1414 | 1413 |
| 1415 // Store the output block. | 1414 // Store the output block. |
| 1416 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN); | 1415 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1450 } | 1449 } |
| 1451 aec->outFrBufH[i] = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, | 1450 aec->outFrBufH[i] = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, |
| 1452 sizeof(float)); | 1451 sizeof(float)); |
| 1453 if (!aec->outFrBufH[i]) { | 1452 if (!aec->outFrBufH[i]) { |
| 1454 WebRtcAec_FreeAec(aec); | 1453 WebRtcAec_FreeAec(aec); |
| 1455 return NULL; | 1454 return NULL; |
| 1456 } | 1455 } |
| 1457 } | 1456 } |
| 1458 | 1457 |
| 1459 // Create far-end buffers. | 1458 // Create far-end buffers. |
| 1460 aec->far_buf = | 1459 // For bit exactness with legacy code, each element in |far_time_buf| is |
| 1461 WebRtc_CreateBuffer(kBufSizePartitions, sizeof(float) * 2 * PART_LEN1); | 1460 // supposed to contain |PART_LEN2| samples with an overlap of |PART_LEN| |
| 1462 if (!aec->far_buf) { | 1461 // samples from the last frame. |
| 1463 WebRtcAec_FreeAec(aec); | 1462 // TODO(minyue): reduce |far_time_buf| to non-overlapped |PART_LEN| samples. |
| 1464 return NULL; | |
| 1465 } | |
| 1466 aec->far_buf_windowed = | |
| 1467 WebRtc_CreateBuffer(kBufSizePartitions, sizeof(float) * 2 * PART_LEN1); | |
| 1468 if (!aec->far_buf_windowed) { | |
| 1469 WebRtcAec_FreeAec(aec); | |
| 1470 return NULL; | |
| 1471 } | |
| 1472 #ifdef WEBRTC_AEC_DEBUG_DUMP | |
| 1473 aec->instance_index = webrtc_aec_instance_count; | |
| 1474 aec->far_time_buf = | 1463 aec->far_time_buf = |
| 1475 WebRtc_CreateBuffer(kBufSizePartitions, sizeof(float) * PART_LEN); | 1464 WebRtc_CreateBuffer(kBufSizePartitions, sizeof(float) * PART_LEN2); |
| 1476 if (!aec->far_time_buf) { | 1465 if (!aec->far_time_buf) { |
| 1477 WebRtcAec_FreeAec(aec); | 1466 WebRtcAec_FreeAec(aec); |
| 1478 return NULL; | 1467 return NULL; |
| 1479 } | 1468 } |
| 1469 |
| 1470 #ifdef WEBRTC_AEC_DEBUG_DUMP |
| 1471 aec->instance_index = webrtc_aec_instance_count; |
| 1472 |
| 1480 aec->farFile = aec->nearFile = aec->outFile = aec->outLinearFile = NULL; | 1473 aec->farFile = aec->nearFile = aec->outFile = aec->outLinearFile = NULL; |
| 1481 aec->debug_dump_count = 0; | 1474 aec->debug_dump_count = 0; |
| 1482 #endif | 1475 #endif |
| 1483 aec->delay_estimator_farend = | 1476 aec->delay_estimator_farend = |
| 1484 WebRtc_CreateDelayEstimatorFarend(PART_LEN1, kHistorySizeBlocks); | 1477 WebRtc_CreateDelayEstimatorFarend(PART_LEN1, kHistorySizeBlocks); |
| 1485 if (aec->delay_estimator_farend == NULL) { | 1478 if (aec->delay_estimator_farend == NULL) { |
| 1486 WebRtcAec_FreeAec(aec); | 1479 WebRtcAec_FreeAec(aec); |
| 1487 return NULL; | 1480 return NULL; |
| 1488 } | 1481 } |
| 1489 // We create the delay_estimator with the same amount of maximum lookahead as | 1482 // We create the delay_estimator with the same amount of maximum lookahead as |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1547 } | 1540 } |
| 1548 | 1541 |
| 1549 WebRtc_FreeBuffer(aec->nearFrBuf); | 1542 WebRtc_FreeBuffer(aec->nearFrBuf); |
| 1550 WebRtc_FreeBuffer(aec->outFrBuf); | 1543 WebRtc_FreeBuffer(aec->outFrBuf); |
| 1551 | 1544 |
| 1552 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1545 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
| 1553 WebRtc_FreeBuffer(aec->nearFrBufH[i]); | 1546 WebRtc_FreeBuffer(aec->nearFrBufH[i]); |
| 1554 WebRtc_FreeBuffer(aec->outFrBufH[i]); | 1547 WebRtc_FreeBuffer(aec->outFrBufH[i]); |
| 1555 } | 1548 } |
| 1556 | 1549 |
| 1557 WebRtc_FreeBuffer(aec->far_buf); | |
| 1558 WebRtc_FreeBuffer(aec->far_buf_windowed); | |
| 1559 #ifdef WEBRTC_AEC_DEBUG_DUMP | |
| 1560 WebRtc_FreeBuffer(aec->far_time_buf); | 1550 WebRtc_FreeBuffer(aec->far_time_buf); |
| 1561 #endif | 1551 |
| 1562 RTC_AEC_DEBUG_WAV_CLOSE(aec->farFile); | 1552 RTC_AEC_DEBUG_WAV_CLOSE(aec->farFile); |
| 1563 RTC_AEC_DEBUG_WAV_CLOSE(aec->nearFile); | 1553 RTC_AEC_DEBUG_WAV_CLOSE(aec->nearFile); |
| 1564 RTC_AEC_DEBUG_WAV_CLOSE(aec->outFile); | 1554 RTC_AEC_DEBUG_WAV_CLOSE(aec->outFile); |
| 1565 RTC_AEC_DEBUG_WAV_CLOSE(aec->outLinearFile); | 1555 RTC_AEC_DEBUG_WAV_CLOSE(aec->outLinearFile); |
| 1566 RTC_AEC_DEBUG_RAW_CLOSE(aec->e_fft_file); | 1556 RTC_AEC_DEBUG_RAW_CLOSE(aec->e_fft_file); |
| 1567 | 1557 |
| 1568 WebRtc_FreeDelayEstimator(aec->delay_estimator); | 1558 WebRtc_FreeDelayEstimator(aec->delay_estimator); |
| 1569 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); | 1559 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); |
| 1570 | 1560 |
| 1571 free(aec); | 1561 free(aec); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1587 } | 1577 } |
| 1588 | 1578 |
| 1589 WebRtc_InitBuffer(aec->nearFrBuf); | 1579 WebRtc_InitBuffer(aec->nearFrBuf); |
| 1590 WebRtc_InitBuffer(aec->outFrBuf); | 1580 WebRtc_InitBuffer(aec->outFrBuf); |
| 1591 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1581 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
| 1592 WebRtc_InitBuffer(aec->nearFrBufH[i]); | 1582 WebRtc_InitBuffer(aec->nearFrBufH[i]); |
| 1593 WebRtc_InitBuffer(aec->outFrBufH[i]); | 1583 WebRtc_InitBuffer(aec->outFrBufH[i]); |
| 1594 } | 1584 } |
| 1595 | 1585 |
| 1596 // Initialize far-end buffers. | 1586 // Initialize far-end buffers. |
| 1597 WebRtc_InitBuffer(aec->far_buf); | 1587 WebRtc_InitBuffer(aec->far_time_buf); |
| 1598 WebRtc_InitBuffer(aec->far_buf_windowed); | 1588 |
| 1599 #ifdef WEBRTC_AEC_DEBUG_DUMP | 1589 #ifdef WEBRTC_AEC_DEBUG_DUMP |
| 1600 WebRtc_InitBuffer(aec->far_time_buf); | |
| 1601 { | 1590 { |
| 1602 int process_rate = sampFreq > 16000 ? 16000 : sampFreq; | 1591 int process_rate = sampFreq > 16000 ? 16000 : sampFreq; |
| 1603 RTC_AEC_DEBUG_WAV_REOPEN("aec_far", aec->instance_index, | 1592 RTC_AEC_DEBUG_WAV_REOPEN("aec_far", aec->instance_index, |
| 1604 aec->debug_dump_count, process_rate, | 1593 aec->debug_dump_count, process_rate, |
| 1605 &aec->farFile ); | 1594 &aec->farFile ); |
| 1606 RTC_AEC_DEBUG_WAV_REOPEN("aec_near", aec->instance_index, | 1595 RTC_AEC_DEBUG_WAV_REOPEN("aec_near", aec->instance_index, |
| 1607 aec->debug_dump_count, process_rate, | 1596 aec->debug_dump_count, process_rate, |
| 1608 &aec->nearFile); | 1597 &aec->nearFile); |
| 1609 RTC_AEC_DEBUG_WAV_REOPEN("aec_out", aec->instance_index, | 1598 RTC_AEC_DEBUG_WAV_REOPEN("aec_out", aec->instance_index, |
| 1610 aec->debug_dump_count, process_rate, | 1599 aec->debug_dump_count, process_rate, |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1734 | 1723 |
| 1735 aec->extreme_filter_divergence = 0; | 1724 aec->extreme_filter_divergence = 0; |
| 1736 | 1725 |
| 1737 // Metrics disabled by default | 1726 // Metrics disabled by default |
| 1738 aec->metricsMode = 0; | 1727 aec->metricsMode = 0; |
| 1739 InitMetrics(aec); | 1728 InitMetrics(aec); |
| 1740 | 1729 |
| 1741 return 0; | 1730 return 0; |
| 1742 } | 1731 } |
| 1743 | 1732 |
| 1733 |
| 1734 // For bit exactness with a legacy code, |farend| is supposed to contain |
| 1735 // |PART_LEN2| samples with an overlap of |PART_LEN| samples from the last |
| 1736 // frame. |
| 1737 // TODO(minyue): reduce |farend| to non-overlapped |PART_LEN| samples. |
| 1744 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) { | 1738 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) { |
| 1745 float fft[PART_LEN2]; | |
| 1746 float xf[2][PART_LEN1]; | |
| 1747 | |
| 1748 // Check if the buffer is full, and in that case flush the oldest data. | 1739 // Check if the buffer is full, and in that case flush the oldest data. |
| 1749 if (WebRtc_available_write(aec->far_buf) < 1) { | 1740 if (WebRtc_available_write(aec->far_time_buf) < 1) { |
| 1750 WebRtcAec_MoveFarReadPtr(aec, 1); | 1741 WebRtcAec_MoveFarReadPtr(aec, 1); |
| 1751 } | 1742 } |
| 1752 // Convert far-end partition to the frequency domain without windowing. | |
| 1753 memcpy(fft, farend, sizeof(float) * PART_LEN2); | |
| 1754 Fft(fft, xf); | |
| 1755 WebRtc_WriteBuffer(aec->far_buf, &xf[0][0], 1); | |
| 1756 | 1743 |
| 1757 // Convert far-end partition to the frequency domain with windowing. | 1744 WebRtc_WriteBuffer(aec->far_time_buf, farend, 1); |
| 1758 WindowData(fft, farend); | |
| 1759 Fft(fft, xf); | |
| 1760 WebRtc_WriteBuffer(aec->far_buf_windowed, &xf[0][0], 1); | |
| 1761 } | 1745 } |
| 1762 | 1746 |
| 1763 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) { | 1747 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) { |
| 1764 int elements_moved = MoveFarReadPtrWithoutSystemDelayUpdate(aec, elements); | 1748 int elements_moved = WebRtc_MoveReadPtr(aec->far_time_buf, elements); |
| 1765 aec->system_delay -= elements_moved * PART_LEN; | 1749 aec->system_delay -= elements_moved * PART_LEN; |
| 1766 return elements_moved; | 1750 return elements_moved; |
| 1767 } | 1751 } |
| 1768 | 1752 |
| 1769 void WebRtcAec_ProcessFrames(AecCore* aec, | 1753 void WebRtcAec_ProcessFrames(AecCore* aec, |
| 1770 const float* const* nearend, | 1754 const float* const* nearend, |
| 1771 size_t num_bands, | 1755 size_t num_bands, |
| 1772 size_t num_samples, | 1756 size_t num_samples, |
| 1773 int knownDelay, | 1757 int knownDelay, |
| 1774 float* const* out) { | 1758 float* const* out) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1828 | 1812 |
| 1829 // TODO(bjornv): Investigate how we should round the delay difference; | 1813 // TODO(bjornv): Investigate how we should round the delay difference; |
| 1830 // right now we know that incoming |knownDelay| is underestimated when | 1814 // right now we know that incoming |knownDelay| is underestimated when |
| 1831 // it's less than |aec->knownDelay|. We therefore, round (-32) in that | 1815 // it's less than |aec->knownDelay|. We therefore, round (-32) in that |
| 1832 // direction. In the other direction, we don't have this situation, but | 1816 // direction. In the other direction, we don't have this situation, but |
| 1833 // might flush one partition too little. This can cause non-causality, | 1817 // might flush one partition too little. This can cause non-causality, |
| 1834 // which should be investigated. Maybe, allow for a non-symmetric | 1818 // which should be investigated. Maybe, allow for a non-symmetric |
| 1835 // rounding, like -16. | 1819 // rounding, like -16. |
| 1836 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN; | 1820 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN; |
| 1837 int moved_elements = | 1821 int moved_elements = |
| 1838 MoveFarReadPtrWithoutSystemDelayUpdate(aec, move_elements); | 1822 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); |
| 1839 aec->knownDelay -= moved_elements * PART_LEN; | 1823 aec->knownDelay -= moved_elements * PART_LEN; |
| 1840 } else { | 1824 } else { |
| 1841 // 2 b) Apply signal based delay correction. | 1825 // 2 b) Apply signal based delay correction. |
| 1842 int move_elements = SignalBasedDelayCorrection(aec); | 1826 int move_elements = SignalBasedDelayCorrection(aec); |
| 1843 int moved_elements = | 1827 int moved_elements = |
| 1844 MoveFarReadPtrWithoutSystemDelayUpdate(aec, move_elements); | 1828 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); |
| 1845 int far_near_buffer_diff = WebRtc_available_read(aec->far_buf) - | 1829 int far_near_buffer_diff = WebRtc_available_read(aec->far_time_buf) - |
| 1846 WebRtc_available_read(aec->nearFrBuf) / PART_LEN; | 1830 WebRtc_available_read(aec->nearFrBuf) / PART_LEN; |
| 1847 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); | 1831 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); |
| 1848 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, | 1832 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, |
| 1849 moved_elements); | 1833 moved_elements); |
| 1850 aec->signal_delay_correction += moved_elements; | 1834 aec->signal_delay_correction += moved_elements; |
| 1851 // If we rely on reported system delay values only, a buffer underrun here | 1835 // If we rely on reported system delay values only, a buffer underrun here |
| 1852 // can never occur since we've taken care of that in 1) above. Here, we | 1836 // can never occur since we've taken care of that in 1) above. Here, we |
| 1853 // apply signal based delay correction and can therefore end up with | 1837 // apply signal based delay correction and can therefore end up with |
| 1854 // buffer underruns since the delay estimation can be wrong. We therefore | 1838 // buffer underruns since the delay estimation can be wrong. We therefore |
| 1855 // stuff the buffer with enough elements if needed. | 1839 // stuff the buffer with enough elements if needed. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1914 Stats* erle, | 1898 Stats* erle, |
| 1915 Stats* a_nlp) { | 1899 Stats* a_nlp) { |
| 1916 assert(erl != NULL); | 1900 assert(erl != NULL); |
| 1917 assert(erle != NULL); | 1901 assert(erle != NULL); |
| 1918 assert(a_nlp != NULL); | 1902 assert(a_nlp != NULL); |
| 1919 *erl = self->erl; | 1903 *erl = self->erl; |
| 1920 *erle = self->erle; | 1904 *erle = self->erle; |
| 1921 *a_nlp = self->aNlp; | 1905 *a_nlp = self->aNlp; |
| 1922 } | 1906 } |
| 1923 | 1907 |
| 1924 #ifdef WEBRTC_AEC_DEBUG_DUMP | |
| 1925 void* WebRtcAec_far_time_buf(AecCore* self) { return self->far_time_buf; } | |
| 1926 #endif | |
| 1927 | |
| 1928 void WebRtcAec_SetConfigCore(AecCore* self, | 1908 void WebRtcAec_SetConfigCore(AecCore* self, |
| 1929 int nlp_mode, | 1909 int nlp_mode, |
| 1930 int metrics_mode, | 1910 int metrics_mode, |
| 1931 int delay_logging) { | 1911 int delay_logging) { |
| 1932 assert(nlp_mode >= 0 && nlp_mode < 3); | 1912 assert(nlp_mode >= 0 && nlp_mode < 3); |
| 1933 self->nlp_mode = nlp_mode; | 1913 self->nlp_mode = nlp_mode; |
| 1934 self->metricsMode = metrics_mode; | 1914 self->metricsMode = metrics_mode; |
| 1935 if (self->metricsMode) { | 1915 if (self->metricsMode) { |
| 1936 InitMetrics(self); | 1916 InitMetrics(self); |
| 1937 } | 1917 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1961 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 1941 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
| 1962 return self->extended_filter_enabled; | 1942 return self->extended_filter_enabled; |
| 1963 } | 1943 } |
| 1964 | 1944 |
| 1965 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } | 1945 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } |
| 1966 | 1946 |
| 1967 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1947 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
| 1968 assert(delay >= 0); | 1948 assert(delay >= 0); |
| 1969 self->system_delay = delay; | 1949 self->system_delay = delay; |
| 1970 } | 1950 } |
| OLD | NEW |