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 |