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 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
834 freq_data[1][0] = 0; | 834 freq_data[1][0] = 0; |
835 freq_data[1][PART_LEN] = 0; | 835 freq_data[1][PART_LEN] = 0; |
836 freq_data[0][0] = time_data[0]; | 836 freq_data[0][0] = time_data[0]; |
837 freq_data[0][PART_LEN] = time_data[1]; | 837 freq_data[0][PART_LEN] = time_data[1]; |
838 for (i = 1; i < PART_LEN; i++) { | 838 for (i = 1; i < PART_LEN; i++) { |
839 freq_data[0][i] = time_data[2 * i]; | 839 freq_data[0][i] = time_data[2 * i]; |
840 freq_data[1][i] = time_data[2 * i + 1]; | 840 freq_data[1][i] = time_data[2 * i + 1]; |
841 } | 841 } |
842 } | 842 } |
843 | 843 |
844 static int MoveFarReadPtrWithoutSystemDelayUpdate(AecCore* self, int elements) { | 844 static int MoveFarReadPtrWithoutSystemDelayUpdate(AecCore* self, int elements) { |
peah-webrtc
2015/12/16 12:52:22
I think that since this is now a one-liner, we sho
minyue-webrtc
2015/12/16 14:47:17
yes, certainly.
| |
845 WebRtc_MoveReadPtr(self->far_buf_windowed, elements); | 845 return WebRtc_MoveReadPtr(self->far_time_buf, elements); |
846 #ifdef WEBRTC_AEC_DEBUG_DUMP | |
847 WebRtc_MoveReadPtr(self->far_time_buf, elements); | |
848 #endif | |
849 return WebRtc_MoveReadPtr(self->far_buf, elements); | |
850 } | 846 } |
851 | 847 |
852 static int SignalBasedDelayCorrection(AecCore* self) { | 848 static int SignalBasedDelayCorrection(AecCore* self) { |
853 int delay_correction = 0; | 849 int delay_correction = 0; |
854 int last_delay = -2; | 850 int last_delay = -2; |
855 assert(self != NULL); | 851 assert(self != NULL); |
856 #if !defined(WEBRTC_ANDROID) | 852 #if !defined(WEBRTC_ANDROID) |
857 // On desktops, turn on correction after |kDelayCorrectionStart| frames. This | 853 // On desktops, turn on correction after |kDelayCorrectionStart| frames. This |
858 // is to let the delay estimation get a chance to converge. Also, if the | 854 // is to let the delay estimation get a chance to converge. Also, if the |
859 // playout audio volume is low (or even muted) the delay estimation can return | 855 // playout audio volume is low (or even muted) the delay estimation can return |
(...skipping 21 matching lines...) Expand all Loading... | |
881 self->delay_quality_threshold)) { | 877 self->delay_quality_threshold)) { |
882 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); | 878 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); |
883 // Allow for a slack in the actual delay, defined by a |lower_bound| and an | 879 // Allow for a slack in the actual delay, defined by a |lower_bound| and an |
884 // |upper_bound|. The adaptive echo cancellation filter is currently | 880 // |upper_bound|. The adaptive echo cancellation filter is currently |
885 // |num_partitions| (of 64 samples) long. If the delay estimate is negative | 881 // |num_partitions| (of 64 samples) long. If the delay estimate is negative |
886 // or at least 3/4 of the filter length we open up for correction. | 882 // or at least 3/4 of the filter length we open up for correction. |
887 const int lower_bound = 0; | 883 const int lower_bound = 0; |
888 const int upper_bound = self->num_partitions * 3 / 4; | 884 const int upper_bound = self->num_partitions * 3 / 4; |
889 const int do_correction = delay <= lower_bound || delay > upper_bound; | 885 const int do_correction = delay <= lower_bound || delay > upper_bound; |
890 if (do_correction == 1) { | 886 if (do_correction == 1) { |
891 int available_read = (int)WebRtc_available_read(self->far_buf); | 887 int available_read = (int)WebRtc_available_read(self->far_time_buf); |
892 // With |shift_offset| we gradually rely on the delay estimates. For | 888 // With |shift_offset| we gradually rely on the delay estimates. For |
893 // positive delays we reduce the correction by |shift_offset| to lower the | 889 // positive delays we reduce the correction by |shift_offset| to lower the |
894 // risk of pushing the AEC into a non causal state. For negative delays | 890 // risk of pushing the AEC into a non causal state. For negative delays |
895 // we rely on the values up to a rounding error, hence compensate by 1 | 891 // we rely on the values up to a rounding error, hence compensate by 1 |
896 // element to make sure to push the delay into the causal region. | 892 // element to make sure to push the delay into the causal region. |
897 delay_correction = -delay; | 893 delay_correction = -delay; |
898 delay_correction += delay > self->shift_offset ? self->shift_offset : 1; | 894 delay_correction += delay > self->shift_offset ? self->shift_offset : 1; |
899 self->shift_offset--; | 895 self->shift_offset--; |
900 self->shift_offset = (self->shift_offset <= 1 ? 1 : self->shift_offset); | 896 self->shift_offset = (self->shift_offset <= 1 ? 1 : self->shift_offset); |
901 if (delay_correction > available_read - self->mult - 1) { | 897 if (delay_correction > available_read - self->mult - 1) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
996 WebRtcAec_FilterAdaptation(num_partitions, | 992 WebRtcAec_FilterAdaptation(num_partitions, |
997 x_fft_buf_block_pos, | 993 x_fft_buf_block_pos, |
998 x_fft_buf, | 994 x_fft_buf, |
999 e_fft, | 995 e_fft, |
1000 h_fft_buf); | 996 h_fft_buf); |
1001 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); | 997 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); |
1002 } | 998 } |
1003 | 999 |
1004 | 1000 |
1005 static void EchoSuppression(AecCore* aec, | 1001 static void EchoSuppression(AecCore* aec, |
1002 float farend[PART_LEN2], | |
1006 float* echo_subtractor_output, | 1003 float* echo_subtractor_output, |
1007 float* output, | 1004 float* output, |
1008 float* const* outputH) { | 1005 float* const* outputH) { |
1009 float efw[2][PART_LEN1]; | 1006 float efw[2][PART_LEN1]; |
1010 float xfw[2][PART_LEN1]; | 1007 float xfw[2][PART_LEN1]; |
1011 float dfw[2][PART_LEN1]; | 1008 float dfw[2][PART_LEN1]; |
1012 complex_t comfortNoiseHband[PART_LEN1]; | 1009 complex_t comfortNoiseHband[PART_LEN1]; |
1013 float fft[PART_LEN2]; | 1010 float fft[PART_LEN2]; |
1014 float scale, dtmp; | 1011 float scale, dtmp; |
1015 float nlpGainHband; | 1012 float nlpGainHband; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1049 // Windowed echo suppressor output ffts. | 1046 // Windowed echo suppressor output ffts. |
1050 WindowData(fft, aec->eBuf); | 1047 WindowData(fft, aec->eBuf); |
1051 aec_rdft_forward_128(fft); | 1048 aec_rdft_forward_128(fft); |
1052 StoreAsComplex(fft, efw); | 1049 StoreAsComplex(fft, efw); |
1053 | 1050 |
1054 aec->delayEstCtr++; | 1051 aec->delayEstCtr++; |
1055 if (aec->delayEstCtr == delayEstInterval) { | 1052 if (aec->delayEstCtr == delayEstInterval) { |
1056 aec->delayEstCtr = 0; | 1053 aec->delayEstCtr = 0; |
1057 } | 1054 } |
1058 | 1055 |
1059 // We should always have at least one element stored in |far_buf|. | |
1060 assert(WebRtc_available_read(aec->far_buf_windowed) > 0); | |
1061 // NLP | 1056 // NLP |
1062 WebRtc_ReadBuffer(aec->far_buf_windowed, (void**)&xfw_ptr, &xfw[0][0], 1); | |
1063 | 1057 |
1064 // TODO(bjornv): Investigate if we can reuse |far_buf_windowed| instead of | 1058 // Convert far-end partition to the frequency domain with windowing. |
1065 // |xfwBuf|. | 1059 WindowData(fft, farend); |
1060 Fft(fft, xfw); | |
1061 xfw_ptr = &xfw[0][0]; | |
1062 | |
1066 // Buffer far. | 1063 // Buffer far. |
1067 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); | 1064 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); |
1068 | 1065 |
1069 if (aec->delayEstCtr == 0) | 1066 if (aec->delayEstCtr == 0) |
1070 aec->delayIdx = WebRtcAec_PartitionDelay(aec); | 1067 aec->delayIdx = WebRtcAec_PartitionDelay(aec); |
1071 | 1068 |
1072 // Use delayed far. | 1069 // Use delayed far. |
1073 memcpy(xfw, | 1070 memcpy(xfw, |
1074 aec->xfwBuf + aec->delayIdx * PART_LEN1, | 1071 aec->xfwBuf + aec->delayIdx * PART_LEN1, |
1075 sizeof(xfw[0][0]) * 2 * PART_LEN1); | 1072 sizeof(xfw[0][0]) * 2 * PART_LEN1); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1278 | 1275 |
1279 const float gPow[2] = {0.9f, 0.1f}; | 1276 const float gPow[2] = {0.9f, 0.1f}; |
1280 | 1277 |
1281 // Noise estimate constants. | 1278 // Noise estimate constants. |
1282 const int noiseInitBlocks = 500 * aec->mult; | 1279 const int noiseInitBlocks = 500 * aec->mult; |
1283 const float step = 0.1f; | 1280 const float step = 0.1f; |
1284 const float ramp = 1.0002f; | 1281 const float ramp = 1.0002f; |
1285 const float gInitNoise[2] = {0.999f, 0.001f}; | 1282 const float gInitNoise[2] = {0.999f, 0.001f}; |
1286 | 1283 |
1287 float nearend[PART_LEN]; | 1284 float nearend[PART_LEN]; |
1285 float* nearend_ptr = NULL; | |
1286 float farend[PART_LEN2]; | |
1287 float* farend_ptr = NULL; | |
1288 float echo_subtractor_output[PART_LEN]; | 1288 float echo_subtractor_output[PART_LEN]; |
1289 float* nearend_ptr = NULL; | |
1290 float output[PART_LEN]; | 1289 float output[PART_LEN]; |
1291 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; | 1290 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; |
1292 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; | 1291 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; |
1293 float* xf_ptr = NULL; | 1292 float* xf_ptr = NULL; |
1294 | 1293 |
1295 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1294 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
1296 outputH_ptr[i] = outputH[i]; | 1295 outputH_ptr[i] = outputH[i]; |
1297 } | 1296 } |
1298 | 1297 |
1299 // Concatenate old and new nearend blocks. | 1298 // Concatenate old and new nearend blocks. |
1300 for (i = 0; i < aec->num_bands - 1; ++i) { | 1299 for (i = 0; i < aec->num_bands - 1; ++i) { |
1301 WebRtc_ReadBuffer(aec->nearFrBufH[i], | 1300 WebRtc_ReadBuffer(aec->nearFrBufH[i], |
1302 (void**)&nearend_ptr, | 1301 (void**)&nearend_ptr, |
1303 nearend, | 1302 nearend, |
1304 PART_LEN); | 1303 PART_LEN); |
1305 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); | 1304 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); |
1306 } | 1305 } |
1307 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN); | 1306 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN); |
1308 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend)); | 1307 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend)); |
1309 | 1308 |
1310 // ---------- Ooura fft ---------- | 1309 // We should always have at least one element stored in |far_buf|. |
1310 assert(WebRtc_available_read(aec->far_time_buf) > 0); | |
1311 WebRtc_ReadBuffer(aec->far_time_buf, (void**)&farend_ptr, farend, 1); | |
1311 | 1312 |
1312 #ifdef WEBRTC_AEC_DEBUG_DUMP | 1313 #ifdef WEBRTC_AEC_DEBUG_DUMP |
1313 { | 1314 { |
1314 float farend[PART_LEN]; | 1315 // TODO(minyue): |farend_ptr| starts from buffered samples. This will be |
1315 float* farend_ptr = NULL; | 1316 // modified when |aec->far_time_buf| is revised. |
1316 WebRtc_ReadBuffer(aec->far_time_buf, (void**)&farend_ptr, farend, 1); | 1317 RTC_AEC_DEBUG_WAV_WRITE(aec->farFile, &farend_ptr[PART_LEN], PART_LEN); |
1317 RTC_AEC_DEBUG_WAV_WRITE(aec->farFile, farend_ptr, PART_LEN); | 1318 |
1318 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN); | 1319 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN); |
1319 } | 1320 } |
1320 #endif | 1321 #endif |
1321 | 1322 |
1322 // We should always have at least one element stored in |far_buf|. | 1323 // Convert far-end signal to the frequency domain. |
1323 assert(WebRtc_available_read(aec->far_buf) > 0); | 1324 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); |
1324 WebRtc_ReadBuffer(aec->far_buf, (void**)&xf_ptr, &xf[0][0], 1); | 1325 Fft(fft, xf); |
1326 xf_ptr = &xf[0][0]; | |
1325 | 1327 |
1326 // Near fft | 1328 // Near fft |
1327 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); | 1329 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); |
1328 Fft(fft, df); | 1330 Fft(fft, df); |
1329 | 1331 |
1330 // Power smoothing | 1332 // Power smoothing |
1331 for (i = 0; i < PART_LEN1; i++) { | 1333 for (i = 0; i < PART_LEN1; i++) { |
1332 far_spectrum = (xf_ptr[i] * xf_ptr[i]) + | 1334 far_spectrum = (xf_ptr[i] * xf_ptr[i]) + |
1333 (xf_ptr[PART_LEN1 + i] * xf_ptr[PART_LEN1 + i]); | 1335 (xf_ptr[PART_LEN1 + i] * xf_ptr[PART_LEN1 + i]); |
1334 aec->xPow[i] = | 1336 aec->xPow[i] = |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1414 aec->xfBuf, | 1416 aec->xfBuf, |
1415 nearend_ptr, | 1417 nearend_ptr, |
1416 aec->xPow, | 1418 aec->xPow, |
1417 aec->wfBuf, | 1419 aec->wfBuf, |
1418 &aec->linoutlevel, | 1420 &aec->linoutlevel, |
1419 echo_subtractor_output); | 1421 echo_subtractor_output); |
1420 | 1422 |
1421 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); | 1423 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); |
1422 | 1424 |
1423 // Perform echo suppression. | 1425 // Perform echo suppression. |
1424 EchoSuppression(aec, echo_subtractor_output, output, outputH_ptr); | 1426 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr); |
1425 | 1427 |
1426 if (aec->metricsMode == 1) { | 1428 if (aec->metricsMode == 1) { |
1427 // Update power levels and echo metrics | 1429 // Update power levels and echo metrics |
1428 UpdateLevel(&aec->farlevel, (float(*)[PART_LEN1])xf_ptr); | 1430 UpdateLevel(&aec->farlevel, (float(*)[PART_LEN1])xf_ptr); |
1429 UpdateLevel(&aec->nearlevel, df); | 1431 UpdateLevel(&aec->nearlevel, df); |
1430 UpdateMetrics(aec); | 1432 UpdateMetrics(aec); |
1431 } | 1433 } |
1432 | 1434 |
1433 // Store the output block. | 1435 // Store the output block. |
1434 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN); | 1436 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1468 } | 1470 } |
1469 aec->outFrBufH[i] = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, | 1471 aec->outFrBufH[i] = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, |
1470 sizeof(float)); | 1472 sizeof(float)); |
1471 if (!aec->outFrBufH[i]) { | 1473 if (!aec->outFrBufH[i]) { |
1472 WebRtcAec_FreeAec(aec); | 1474 WebRtcAec_FreeAec(aec); |
1473 return NULL; | 1475 return NULL; |
1474 } | 1476 } |
1475 } | 1477 } |
1476 | 1478 |
1477 // Create far-end buffers. | 1479 // Create far-end buffers. |
1478 aec->far_buf = | 1480 // For bit exactness with legacy code, each element in |far_time_buf| is |
1479 WebRtc_CreateBuffer(kBufSizePartitions, sizeof(float) * 2 * PART_LEN1); | 1481 // supposed to contain |PART_LEN2| samples with an overlap of |PART_LEN| |
1480 if (!aec->far_buf) { | 1482 // samples from the last frame. |
1481 WebRtcAec_FreeAec(aec); | 1483 // TODO(minyue): reduce |far_time_buf| to non-overlapped |PART_LEN| samples. |
1482 return NULL; | |
1483 } | |
1484 aec->far_buf_windowed = | |
1485 WebRtc_CreateBuffer(kBufSizePartitions, sizeof(float) * 2 * PART_LEN1); | |
1486 if (!aec->far_buf_windowed) { | |
1487 WebRtcAec_FreeAec(aec); | |
1488 return NULL; | |
1489 } | |
1490 #ifdef WEBRTC_AEC_DEBUG_DUMP | |
1491 aec->instance_index = webrtc_aec_instance_count; | |
1492 aec->far_time_buf = | 1484 aec->far_time_buf = |
1493 WebRtc_CreateBuffer(kBufSizePartitions, sizeof(float) * PART_LEN); | 1485 WebRtc_CreateBuffer(kBufSizePartitions, sizeof(float) * PART_LEN2); |
1494 if (!aec->far_time_buf) { | 1486 if (!aec->far_time_buf) { |
1495 WebRtcAec_FreeAec(aec); | 1487 WebRtcAec_FreeAec(aec); |
1496 return NULL; | 1488 return NULL; |
1497 } | 1489 } |
1490 | |
1491 #ifdef WEBRTC_AEC_DEBUG_DUMP | |
1492 aec->instance_index = webrtc_aec_instance_count; | |
1493 | |
1498 aec->farFile = aec->nearFile = aec->outFile = aec->outLinearFile = NULL; | 1494 aec->farFile = aec->nearFile = aec->outFile = aec->outLinearFile = NULL; |
1499 aec->debug_dump_count = 0; | 1495 aec->debug_dump_count = 0; |
1500 #endif | 1496 #endif |
1501 aec->delay_estimator_farend = | 1497 aec->delay_estimator_farend = |
1502 WebRtc_CreateDelayEstimatorFarend(PART_LEN1, kHistorySizeBlocks); | 1498 WebRtc_CreateDelayEstimatorFarend(PART_LEN1, kHistorySizeBlocks); |
1503 if (aec->delay_estimator_farend == NULL) { | 1499 if (aec->delay_estimator_farend == NULL) { |
1504 WebRtcAec_FreeAec(aec); | 1500 WebRtcAec_FreeAec(aec); |
1505 return NULL; | 1501 return NULL; |
1506 } | 1502 } |
1507 // We create the delay_estimator with the same amount of maximum lookahead as | 1503 // 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... | |
1565 } | 1561 } |
1566 | 1562 |
1567 WebRtc_FreeBuffer(aec->nearFrBuf); | 1563 WebRtc_FreeBuffer(aec->nearFrBuf); |
1568 WebRtc_FreeBuffer(aec->outFrBuf); | 1564 WebRtc_FreeBuffer(aec->outFrBuf); |
1569 | 1565 |
1570 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1566 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
1571 WebRtc_FreeBuffer(aec->nearFrBufH[i]); | 1567 WebRtc_FreeBuffer(aec->nearFrBufH[i]); |
1572 WebRtc_FreeBuffer(aec->outFrBufH[i]); | 1568 WebRtc_FreeBuffer(aec->outFrBufH[i]); |
1573 } | 1569 } |
1574 | 1570 |
1575 WebRtc_FreeBuffer(aec->far_buf); | |
1576 WebRtc_FreeBuffer(aec->far_buf_windowed); | |
1577 #ifdef WEBRTC_AEC_DEBUG_DUMP | |
1578 WebRtc_FreeBuffer(aec->far_time_buf); | 1571 WebRtc_FreeBuffer(aec->far_time_buf); |
1579 #endif | 1572 |
1580 RTC_AEC_DEBUG_WAV_CLOSE(aec->farFile); | 1573 RTC_AEC_DEBUG_WAV_CLOSE(aec->farFile); |
1581 RTC_AEC_DEBUG_WAV_CLOSE(aec->nearFile); | 1574 RTC_AEC_DEBUG_WAV_CLOSE(aec->nearFile); |
1582 RTC_AEC_DEBUG_WAV_CLOSE(aec->outFile); | 1575 RTC_AEC_DEBUG_WAV_CLOSE(aec->outFile); |
1583 RTC_AEC_DEBUG_WAV_CLOSE(aec->outLinearFile); | 1576 RTC_AEC_DEBUG_WAV_CLOSE(aec->outLinearFile); |
1584 RTC_AEC_DEBUG_RAW_CLOSE(aec->e_fft_file); | 1577 RTC_AEC_DEBUG_RAW_CLOSE(aec->e_fft_file); |
1585 | 1578 |
1586 WebRtc_FreeDelayEstimator(aec->delay_estimator); | 1579 WebRtc_FreeDelayEstimator(aec->delay_estimator); |
1587 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); | 1580 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); |
1588 | 1581 |
1589 free(aec); | 1582 free(aec); |
(...skipping 15 matching lines...) Expand all Loading... | |
1605 } | 1598 } |
1606 | 1599 |
1607 WebRtc_InitBuffer(aec->nearFrBuf); | 1600 WebRtc_InitBuffer(aec->nearFrBuf); |
1608 WebRtc_InitBuffer(aec->outFrBuf); | 1601 WebRtc_InitBuffer(aec->outFrBuf); |
1609 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1602 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
1610 WebRtc_InitBuffer(aec->nearFrBufH[i]); | 1603 WebRtc_InitBuffer(aec->nearFrBufH[i]); |
1611 WebRtc_InitBuffer(aec->outFrBufH[i]); | 1604 WebRtc_InitBuffer(aec->outFrBufH[i]); |
1612 } | 1605 } |
1613 | 1606 |
1614 // Initialize far-end buffers. | 1607 // Initialize far-end buffers. |
1615 WebRtc_InitBuffer(aec->far_buf); | 1608 WebRtc_InitBuffer(aec->far_time_buf); |
1616 WebRtc_InitBuffer(aec->far_buf_windowed); | 1609 |
1617 #ifdef WEBRTC_AEC_DEBUG_DUMP | 1610 #ifdef WEBRTC_AEC_DEBUG_DUMP |
1618 WebRtc_InitBuffer(aec->far_time_buf); | |
1619 { | 1611 { |
1620 int process_rate = sampFreq > 16000 ? 16000 : sampFreq; | 1612 int process_rate = sampFreq > 16000 ? 16000 : sampFreq; |
1621 RTC_AEC_DEBUG_WAV_REOPEN("aec_far", aec->instance_index, | 1613 RTC_AEC_DEBUG_WAV_REOPEN("aec_far", aec->instance_index, |
1622 aec->debug_dump_count, process_rate, | 1614 aec->debug_dump_count, process_rate, |
1623 &aec->farFile ); | 1615 &aec->farFile ); |
1624 RTC_AEC_DEBUG_WAV_REOPEN("aec_near", aec->instance_index, | 1616 RTC_AEC_DEBUG_WAV_REOPEN("aec_near", aec->instance_index, |
1625 aec->debug_dump_count, process_rate, | 1617 aec->debug_dump_count, process_rate, |
1626 &aec->nearFile); | 1618 &aec->nearFile); |
1627 RTC_AEC_DEBUG_WAV_REOPEN("aec_out", aec->instance_index, | 1619 RTC_AEC_DEBUG_WAV_REOPEN("aec_out", aec->instance_index, |
1628 aec->debug_dump_count, process_rate, | 1620 aec->debug_dump_count, process_rate, |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1752 | 1744 |
1753 aec->extreme_filter_divergence = 0; | 1745 aec->extreme_filter_divergence = 0; |
1754 | 1746 |
1755 // Metrics disabled by default | 1747 // Metrics disabled by default |
1756 aec->metricsMode = 0; | 1748 aec->metricsMode = 0; |
1757 InitMetrics(aec); | 1749 InitMetrics(aec); |
1758 | 1750 |
1759 return 0; | 1751 return 0; |
1760 } | 1752 } |
1761 | 1753 |
1754 | |
1755 // For bit exactness with a legacy code, |farend| is supposed to contain | |
1756 // |PART_LEN2| samples with an overlap of |PART_LEN| samples from the last | |
1757 // frame. | |
1758 // TODO(minyue): reduce |farend| to non-overlapped |PART_LEN| samples. | |
1762 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) { | 1759 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) { |
1763 float fft[PART_LEN2]; | |
1764 float xf[2][PART_LEN1]; | |
1765 | |
1766 // Check if the buffer is full, and in that case flush the oldest data. | 1760 // Check if the buffer is full, and in that case flush the oldest data. |
1767 if (WebRtc_available_write(aec->far_buf) < 1) { | 1761 if (WebRtc_available_write(aec->far_time_buf) < 1) { |
1768 WebRtcAec_MoveFarReadPtr(aec, 1); | 1762 WebRtcAec_MoveFarReadPtr(aec, 1); |
1769 } | 1763 } |
1770 // Convert far-end partition to the frequency domain without windowing. | |
1771 memcpy(fft, farend, sizeof(float) * PART_LEN2); | |
1772 Fft(fft, xf); | |
1773 WebRtc_WriteBuffer(aec->far_buf, &xf[0][0], 1); | |
1774 | 1764 |
1775 // Convert far-end partition to the frequency domain with windowing. | 1765 WebRtc_WriteBuffer(aec->far_time_buf, farend, 1); |
1776 WindowData(fft, farend); | |
1777 Fft(fft, xf); | |
1778 WebRtc_WriteBuffer(aec->far_buf_windowed, &xf[0][0], 1); | |
1779 } | 1766 } |
1780 | 1767 |
1781 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) { | 1768 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) { |
1782 int elements_moved = MoveFarReadPtrWithoutSystemDelayUpdate(aec, elements); | 1769 int elements_moved = MoveFarReadPtrWithoutSystemDelayUpdate(aec, elements); |
1783 aec->system_delay -= elements_moved * PART_LEN; | 1770 aec->system_delay -= elements_moved * PART_LEN; |
1784 return elements_moved; | 1771 return elements_moved; |
1785 } | 1772 } |
1786 | 1773 |
1787 void WebRtcAec_ProcessFrames(AecCore* aec, | 1774 void WebRtcAec_ProcessFrames(AecCore* aec, |
1788 const float* const* nearend, | 1775 const float* const* nearend, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1853 // rounding, like -16. | 1840 // rounding, like -16. |
1854 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN; | 1841 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN; |
1855 int moved_elements = | 1842 int moved_elements = |
1856 MoveFarReadPtrWithoutSystemDelayUpdate(aec, move_elements); | 1843 MoveFarReadPtrWithoutSystemDelayUpdate(aec, move_elements); |
1857 aec->knownDelay -= moved_elements * PART_LEN; | 1844 aec->knownDelay -= moved_elements * PART_LEN; |
1858 } else { | 1845 } else { |
1859 // 2 b) Apply signal based delay correction. | 1846 // 2 b) Apply signal based delay correction. |
1860 int move_elements = SignalBasedDelayCorrection(aec); | 1847 int move_elements = SignalBasedDelayCorrection(aec); |
1861 int moved_elements = | 1848 int moved_elements = |
1862 MoveFarReadPtrWithoutSystemDelayUpdate(aec, move_elements); | 1849 MoveFarReadPtrWithoutSystemDelayUpdate(aec, move_elements); |
1863 int far_near_buffer_diff = WebRtc_available_read(aec->far_buf) - | 1850 int far_near_buffer_diff = WebRtc_available_read(aec->far_time_buf) - |
1864 WebRtc_available_read(aec->nearFrBuf) / PART_LEN; | 1851 WebRtc_available_read(aec->nearFrBuf) / PART_LEN; |
1865 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); | 1852 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); |
1866 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, | 1853 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, |
1867 moved_elements); | 1854 moved_elements); |
1868 aec->signal_delay_correction += moved_elements; | 1855 aec->signal_delay_correction += moved_elements; |
1869 // If we rely on reported system delay values only, a buffer underrun here | 1856 // If we rely on reported system delay values only, a buffer underrun here |
1870 // can never occur since we've taken care of that in 1) above. Here, we | 1857 // can never occur since we've taken care of that in 1) above. Here, we |
1871 // apply signal based delay correction and can therefore end up with | 1858 // apply signal based delay correction and can therefore end up with |
1872 // buffer underruns since the delay estimation can be wrong. We therefore | 1859 // buffer underruns since the delay estimation can be wrong. We therefore |
1873 // stuff the buffer with enough elements if needed. | 1860 // stuff the buffer with enough elements if needed. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1932 Stats* erle, | 1919 Stats* erle, |
1933 Stats* a_nlp) { | 1920 Stats* a_nlp) { |
1934 assert(erl != NULL); | 1921 assert(erl != NULL); |
1935 assert(erle != NULL); | 1922 assert(erle != NULL); |
1936 assert(a_nlp != NULL); | 1923 assert(a_nlp != NULL); |
1937 *erl = self->erl; | 1924 *erl = self->erl; |
1938 *erle = self->erle; | 1925 *erle = self->erle; |
1939 *a_nlp = self->aNlp; | 1926 *a_nlp = self->aNlp; |
1940 } | 1927 } |
1941 | 1928 |
1942 #ifdef WEBRTC_AEC_DEBUG_DUMP | |
1943 void* WebRtcAec_far_time_buf(AecCore* self) { return self->far_time_buf; } | |
1944 #endif | |
1945 | |
1946 void WebRtcAec_SetConfigCore(AecCore* self, | 1929 void WebRtcAec_SetConfigCore(AecCore* self, |
1947 int nlp_mode, | 1930 int nlp_mode, |
1948 int metrics_mode, | 1931 int metrics_mode, |
1949 int delay_logging) { | 1932 int delay_logging) { |
1950 assert(nlp_mode >= 0 && nlp_mode < 3); | 1933 assert(nlp_mode >= 0 && nlp_mode < 3); |
1951 self->nlp_mode = nlp_mode; | 1934 self->nlp_mode = nlp_mode; |
1952 self->metricsMode = metrics_mode; | 1935 self->metricsMode = metrics_mode; |
1953 if (self->metricsMode) { | 1936 if (self->metricsMode) { |
1954 InitMetrics(self); | 1937 InitMetrics(self); |
1955 } | 1938 } |
(...skipping 23 matching lines...) Expand all Loading... | |
1979 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 1962 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
1980 return self->extended_filter_enabled; | 1963 return self->extended_filter_enabled; |
1981 } | 1964 } |
1982 | 1965 |
1983 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } | 1966 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } |
1984 | 1967 |
1985 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1968 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1986 assert(delay >= 0); | 1969 assert(delay >= 0); |
1987 self->system_delay = delay; | 1970 self->system_delay = delay; |
1988 } | 1971 } |
OLD | NEW |