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

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 823 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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 }
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