Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Side by Side Diff: webrtc/modules/audio_processing/aec/aec_core.c

Issue 1512573003: Moving FFT on farend signal to where it is used in AEC (bit exact). (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebasing Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | webrtc/modules/audio_processing/aec/aec_core_internal.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/audio_processing/aec/aec_core_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698