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

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

Issue 2321483002: Refactoring of the buffering of the output signal done inside the AEC (Closed)
Patch Set: New testvectors Created 4 years, 3 months 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 | « webrtc/modules/audio_processing/aec/aec_core.h ('k') | no next file » | 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 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 } 1101 }
1102 1102
1103 // Apply the overdrive. 1103 // Apply the overdrive.
1104 WebRtcAec_Overdrive(aec->overdrive_scaling, hNlFb, hNl); 1104 WebRtcAec_Overdrive(aec->overdrive_scaling, hNlFb, hNl);
1105 } 1105 }
1106 1106
1107 static void EchoSuppression(AecCore* aec, 1107 static void EchoSuppression(AecCore* aec,
1108 float* nearend_extended_block_lowest_band, 1108 float* nearend_extended_block_lowest_band,
1109 float farend[PART_LEN2], 1109 float farend[PART_LEN2],
1110 float* echo_subtractor_output, 1110 float* echo_subtractor_output,
1111 float* output, 1111 float output[NUM_HIGH_BANDS_MAX + 1][PART_LEN]) {
1112 float* const* outputH) {
1113 float efw[2][PART_LEN1]; 1112 float efw[2][PART_LEN1];
1114 float xfw[2][PART_LEN1]; 1113 float xfw[2][PART_LEN1];
1115 float dfw[2][PART_LEN1]; 1114 float dfw[2][PART_LEN1];
1116 float comfortNoiseHband[2][PART_LEN1]; 1115 float comfortNoiseHband[2][PART_LEN1];
1117 float fft[PART_LEN2]; 1116 float fft[PART_LEN2];
1118 float nlpGainHband; 1117 float nlpGainHband;
1119 int i; 1118 int i;
1120 size_t j; 1119 size_t j;
1121 1120
1122 // Coherence and non-linear filter 1121 // Coherence and non-linear filter
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 1185
1187 // Add comfort noise. 1186 // Add comfort noise.
1188 ComfortNoise(aec->num_bands > 1, &aec->seed, efw, comfortNoiseHband, 1187 ComfortNoise(aec->num_bands > 1, &aec->seed, efw, comfortNoiseHband,
1189 aec->noisePow, hNl); 1188 aec->noisePow, hNl);
1190 1189
1191 // Inverse error fft. 1190 // Inverse error fft.
1192 ScaledInverseFft(efw, fft, 2.0f, 1); 1191 ScaledInverseFft(efw, fft, 2.0f, 1);
1193 1192
1194 // Overlap and add to obtain output. 1193 // Overlap and add to obtain output.
1195 for (i = 0; i < PART_LEN; i++) { 1194 for (i = 0; i < PART_LEN; i++) {
1196 output[i] = (fft[i] * WebRtcAec_sqrtHanning[i] + 1195 output[0][i] = (fft[i] * WebRtcAec_sqrtHanning[i] +
1197 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]); 1196 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]);
1198 1197
1199 // Saturate output to keep it in the allowed range. 1198 // Saturate output to keep it in the allowed range.
1200 output[i] = 1199 output[0][i] = WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, output[0][i],
1201 WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, output[i], WEBRTC_SPL_WORD16_MIN); 1200 WEBRTC_SPL_WORD16_MIN);
1202 } 1201 }
1203 memcpy(aec->outBuf, &fft[PART_LEN], PART_LEN * sizeof(aec->outBuf[0])); 1202 memcpy(aec->outBuf, &fft[PART_LEN], PART_LEN * sizeof(aec->outBuf[0]));
1204 1203
1205 // For H band 1204 // For H band
1206 if (aec->num_bands > 1) { 1205 if (aec->num_bands > 1) {
1207 // H band gain 1206 // H band gain
1208 // average nlp over low band: average over second half of freq spectrum 1207 // average nlp over low band: average over second half of freq spectrum
1209 // (4->8khz) 1208 // (4->8khz)
1210 GetHighbandGain(hNl, &nlpGainHband); 1209 GetHighbandGain(hNl, &nlpGainHband);
1211 1210
1212 // Inverse comfort_noise 1211 // Inverse comfort_noise
1213 ScaledInverseFft(comfortNoiseHband, fft, 2.0f, 0); 1212 ScaledInverseFft(comfortNoiseHband, fft, 2.0f, 0);
1214 1213
1215 // compute gain factor 1214 // compute gain factor
1216 for (j = 0; j < aec->num_bands - 1; ++j) { 1215 for (j = 1; j < aec->num_bands; ++j) {
1217 for (i = 0; i < PART_LEN; i++) { 1216 for (i = 0; i < PART_LEN; i++) {
1218 outputH[j][i] = aec->previous_nearend_block[j + 1][i] * nlpGainHband; 1217 output[j][i] = aec->previous_nearend_block[j][i] * nlpGainHband;
1219 } 1218 }
1220 } 1219 }
1221 1220
1222 // Add some comfort noise where Hband is attenuated. 1221 // Add some comfort noise where Hband is attenuated.
1223 for (i = 0; i < PART_LEN; i++) { 1222 for (i = 0; i < PART_LEN; i++) {
1224 outputH[0][i] += cnScaleHband * fft[i]; 1223 output[1][i] += cnScaleHband * fft[i];
1225 } 1224 }
1226 1225
1227 // Saturate output to keep it in the allowed range. 1226 // Saturate output to keep it in the allowed range.
1228 for (j = 0; j < aec->num_bands - 1; ++j) { 1227 for (j = 1; j < aec->num_bands; ++j) {
1229 for (i = 0; i < PART_LEN; i++) { 1228 for (i = 0; i < PART_LEN; i++) {
1230 outputH[j][i] = WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, outputH[j][i], 1229 output[j][i] = WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, output[j][i],
1231 WEBRTC_SPL_WORD16_MIN); 1230 WEBRTC_SPL_WORD16_MIN);
1232 } 1231 }
1233 } 1232 }
1234 } 1233 }
1235 1234
1236 // Copy the current block to the old position. 1235 // Copy the current block to the old position.
1237 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN); 1236 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN);
1238 1237
1239 memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf, 1238 memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf,
1240 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); 1239 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1);
1241 } 1240 }
1242 1241
1243 static void ProcessBlock(AecCore* aec, 1242 static void ProcessBlock(AecCore* aec,
1244 float nearend_block[NUM_HIGH_BANDS_MAX + 1] 1243 float nearend_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN],
1245 [PART_LEN]) { 1244 float output_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN]) {
1246 size_t i; 1245 size_t i;
1247 1246
1248 float fft[PART_LEN2]; 1247 float fft[PART_LEN2];
1249 float nearend_extended_block_lowest_band[PART_LEN2]; 1248 float nearend_extended_block_lowest_band[PART_LEN2];
1250 float x_fft[2][PART_LEN1]; 1249 float x_fft[2][PART_LEN1];
1251 float df[2][PART_LEN1]; 1250 float df[2][PART_LEN1];
1252 float far_spectrum = 0.0f; 1251 float far_spectrum = 0.0f;
1253 float near_spectrum = 0.0f; 1252 float near_spectrum = 0.0f;
1254 float abs_far_spectrum[PART_LEN1]; 1253 float abs_far_spectrum[PART_LEN1];
1255 float abs_near_spectrum[PART_LEN1]; 1254 float abs_near_spectrum[PART_LEN1];
1256 1255
1257 const float gPow[2] = {0.9f, 0.1f}; 1256 const float gPow[2] = {0.9f, 0.1f};
1258 1257
1259 // Noise estimate constants. 1258 // Noise estimate constants.
1260 const int noiseInitBlocks = 500 * aec->mult; 1259 const int noiseInitBlocks = 500 * aec->mult;
1261 const float step = 0.1f; 1260 const float step = 0.1f;
1262 const float ramp = 1.0002f; 1261 const float ramp = 1.0002f;
1263 const float gInitNoise[2] = {0.999f, 0.001f}; 1262 const float gInitNoise[2] = {0.999f, 0.001f};
1264 1263
1265 float farend[PART_LEN2]; 1264 float farend[PART_LEN2];
1266 float* farend_ptr = NULL; 1265 float* farend_ptr = NULL;
1267 float echo_subtractor_output[PART_LEN]; 1266 float echo_subtractor_output[PART_LEN];
1268 float output[PART_LEN];
1269 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN];
1270 float* outputH_ptr[NUM_HIGH_BANDS_MAX];
1271 float* x_fft_ptr = NULL; 1267 float* x_fft_ptr = NULL;
1272 1268
1273 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) {
1274 outputH_ptr[i] = outputH[i];
1275 }
1276
1277 // We should always have at least one element stored in |far_buf|. 1269 // We should always have at least one element stored in |far_buf|.
1278 assert(WebRtc_available_read(aec->far_time_buf) > 0); 1270 assert(WebRtc_available_read(aec->far_time_buf) > 0);
1279 WebRtc_ReadBuffer(aec->far_time_buf, reinterpret_cast<void**>(&farend_ptr), 1271 WebRtc_ReadBuffer(aec->far_time_buf, reinterpret_cast<void**>(&farend_ptr),
1280 farend, 1); 1272 farend, 1);
1281 1273
1282 aec->data_dumper->DumpWav("aec_far", PART_LEN, &farend_ptr[PART_LEN], 1274 aec->data_dumper->DumpWav("aec_far", PART_LEN, &farend_ptr[PART_LEN],
1283 std::min(aec->sampFreq, 16000), 1); 1275 std::min(aec->sampFreq, 16000), 1);
1284 aec->data_dumper->DumpWav("aec_near", PART_LEN, &nearend_block[0][0], 1276 aec->data_dumper->DumpWav("aec_near", PART_LEN, &nearend_block[0][0],
1285 std::min(aec->sampFreq, 16000), 1); 1277 std::min(aec->sampFreq, 16000), 1);
1286 1278
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 aec->data_dumper->DumpWav("aec_out_linear", PART_LEN, echo_subtractor_output, 1388 aec->data_dumper->DumpWav("aec_out_linear", PART_LEN, echo_subtractor_output,
1397 std::min(aec->sampFreq, 16000), 1); 1389 std::min(aec->sampFreq, 16000), 1);
1398 1390
1399 if (aec->metricsMode == 1) { 1391 if (aec->metricsMode == 1) {
1400 UpdateLevel(&aec->linoutlevel, 1392 UpdateLevel(&aec->linoutlevel,
1401 CalculatePower(echo_subtractor_output, PART_LEN)); 1393 CalculatePower(echo_subtractor_output, PART_LEN));
1402 } 1394 }
1403 1395
1404 // Perform echo suppression. 1396 // Perform echo suppression.
1405 EchoSuppression(aec, nearend_extended_block_lowest_band, farend_ptr, 1397 EchoSuppression(aec, nearend_extended_block_lowest_band, farend_ptr,
1406 echo_subtractor_output, output, outputH_ptr); 1398 echo_subtractor_output, output_block);
1407 1399
1408 if (aec->metricsMode == 1) { 1400 if (aec->metricsMode == 1) {
1409 UpdateLevel(&aec->nlpoutlevel, CalculatePower(output, PART_LEN)); 1401 UpdateLevel(&aec->nlpoutlevel,
1402 CalculatePower(&output_block[0][0], PART_LEN));
1410 UpdateMetrics(aec); 1403 UpdateMetrics(aec);
1411 } 1404 }
1412 1405
1413 // Store the nearend signal until the next frame. 1406 // Store the nearend signal until the next frame.
1414 for (i = 0; i < aec->num_bands; ++i) { 1407 for (i = 0; i < aec->num_bands; ++i) {
1415 memcpy(&aec->previous_nearend_block[i][0], &nearend_block[i][0], 1408 memcpy(&aec->previous_nearend_block[i][0], &nearend_block[i][0],
1416 sizeof(float) * PART_LEN); 1409 sizeof(float) * PART_LEN);
1417 } 1410 }
1418 1411
1419 // Store the output block. 1412 aec->data_dumper->DumpWav("aec_out", PART_LEN, &output_block[0][0],
1420 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN);
1421 // For high bands
1422 for (i = 0; i < aec->num_bands - 1; ++i) {
1423 WebRtc_WriteBuffer(aec->outFrBufH[i], outputH[i], PART_LEN);
1424 }
1425
1426 aec->data_dumper->DumpWav("aec_out", PART_LEN, output,
1427 std::min(aec->sampFreq, 16000), 1); 1413 std::min(aec->sampFreq, 16000), 1);
1428 } 1414 }
1429 1415
1430 AecCore* WebRtcAec_CreateAec(int instance_count) { 1416 AecCore* WebRtcAec_CreateAec(int instance_count) {
1431 int i;
1432 AecCore* aec = new AecCore(instance_count); 1417 AecCore* aec = new AecCore(instance_count);
1433 1418
1434 if (!aec) { 1419 if (!aec) {
1435 return NULL; 1420 return NULL;
1436 } 1421 }
1437 aec->nearend_buffer_size = 0; 1422 aec->nearend_buffer_size = 0;
1438 memset(&aec->nearend_buffer[0], 0, sizeof(aec->nearend_buffer)); 1423 memset(&aec->nearend_buffer[0], 0, sizeof(aec->nearend_buffer));
1439 1424 // Start the output buffer with zeros to be able to produce
1440 aec->outFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); 1425 // a full output frame in the first frame.
1441 if (!aec->outFrBuf) { 1426 aec->output_buffer_size = PART_LEN - (FRAME_LEN - PART_LEN);
1442 WebRtcAec_FreeAec(aec); 1427 memset(&aec->output_buffer[0], 0, sizeof(aec->output_buffer));
1443 return NULL;
1444 }
1445
1446 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) {
1447 aec->outFrBufH[i] =
1448 WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1449 if (!aec->outFrBufH[i]) {
1450 WebRtcAec_FreeAec(aec);
1451 return NULL;
1452 }
1453 }
1454 1428
1455 // Create far-end buffers. 1429 // Create far-end buffers.
1456 // For bit exactness with legacy code, each element in |far_time_buf| is 1430 // For bit exactness with legacy code, each element in |far_time_buf| is
1457 // supposed to contain |PART_LEN2| samples with an overlap of |PART_LEN| 1431 // supposed to contain |PART_LEN2| samples with an overlap of |PART_LEN|
1458 // samples from the last frame. 1432 // samples from the last frame.
1459 // TODO(minyue): reduce |far_time_buf| to non-overlapped |PART_LEN| samples. 1433 // TODO(minyue): reduce |far_time_buf| to non-overlapped |PART_LEN| samples.
1460 aec->far_time_buf = 1434 aec->far_time_buf =
1461 WebRtc_CreateBuffer(kBufSizePartitions, sizeof(float) * PART_LEN2); 1435 WebRtc_CreateBuffer(kBufSizePartitions, sizeof(float) * PART_LEN2);
1462 if (!aec->far_time_buf) { 1436 if (!aec->far_time_buf) {
1463 WebRtcAec_FreeAec(aec); 1437 WebRtcAec_FreeAec(aec);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 #if defined(WEBRTC_HAS_NEON) 1490 #if defined(WEBRTC_HAS_NEON)
1517 WebRtcAec_InitAec_neon(); 1491 WebRtcAec_InitAec_neon();
1518 #endif 1492 #endif
1519 1493
1520 aec_rdft_init(); 1494 aec_rdft_init();
1521 1495
1522 return aec; 1496 return aec;
1523 } 1497 }
1524 1498
1525 void WebRtcAec_FreeAec(AecCore* aec) { 1499 void WebRtcAec_FreeAec(AecCore* aec) {
1526 int i;
1527 if (aec == NULL) { 1500 if (aec == NULL) {
1528 return; 1501 return;
1529 } 1502 }
1530 1503
1531 WebRtc_FreeBuffer(aec->outFrBuf);
1532
1533 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) {
1534 WebRtc_FreeBuffer(aec->outFrBufH[i]);
1535 }
1536
1537 WebRtc_FreeBuffer(aec->far_time_buf); 1504 WebRtc_FreeBuffer(aec->far_time_buf);
1538 1505
1539 WebRtc_FreeDelayEstimator(aec->delay_estimator); 1506 WebRtc_FreeDelayEstimator(aec->delay_estimator);
1540 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); 1507 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend);
1541 1508
1542 delete aec; 1509 delete aec;
1543 } 1510 }
1544 1511
1545 static void SetAdaptiveFilterStepSize(AecCore* aec) { 1512 static void SetAdaptiveFilterStepSize(AecCore* aec) {
1546 // Extended filter adaptation parameter. 1513 // Extended filter adaptation parameter.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1586 1553
1587 SetAdaptiveFilterStepSize(aec); 1554 SetAdaptiveFilterStepSize(aec);
1588 SetErrorThreshold(aec); 1555 SetErrorThreshold(aec);
1589 1556
1590 if (sampFreq == 8000) { 1557 if (sampFreq == 8000) {
1591 aec->num_bands = 1; 1558 aec->num_bands = 1;
1592 } else { 1559 } else {
1593 aec->num_bands = (size_t)(sampFreq / 16000); 1560 aec->num_bands = (size_t)(sampFreq / 16000);
1594 } 1561 }
1595 1562
1563 // Start the output buffer with zeros to be able to produce
1564 // a full output frame in the first frame.
1565 aec->output_buffer_size = PART_LEN - (FRAME_LEN - PART_LEN);
1566 memset(&aec->output_buffer[0], 0, sizeof(aec->output_buffer));
1596 aec->nearend_buffer_size = 0; 1567 aec->nearend_buffer_size = 0;
1597 memset(&aec->nearend_buffer[0], 0, sizeof(aec->nearend_buffer)); 1568 memset(&aec->nearend_buffer[0], 0, sizeof(aec->nearend_buffer));
1598 1569
1599 WebRtc_InitBuffer(aec->outFrBuf);
1600 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) {
1601 WebRtc_InitBuffer(aec->outFrBufH[i]);
1602 }
1603
1604 // Initialize far-end buffers. 1570 // Initialize far-end buffers.
1605 WebRtc_InitBuffer(aec->far_time_buf); 1571 WebRtc_InitBuffer(aec->far_time_buf);
1606 1572
1607 aec->system_delay = 0; 1573 aec->system_delay = 0;
1608 1574
1609 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) { 1575 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) {
1610 return -1; 1576 return -1;
1611 } 1577 }
1612 if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) { 1578 if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) {
1613 return -1; 1579 return -1;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1733 1699
1734 WebRtc_WriteBuffer(aec->far_time_buf, farend, 1); 1700 WebRtc_WriteBuffer(aec->far_time_buf, farend, 1);
1735 } 1701 }
1736 1702
1737 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) { 1703 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) {
1738 int elements_moved = WebRtc_MoveReadPtr(aec->far_time_buf, elements); 1704 int elements_moved = WebRtc_MoveReadPtr(aec->far_time_buf, elements);
1739 aec->system_delay -= elements_moved * PART_LEN; 1705 aec->system_delay -= elements_moved * PART_LEN;
1740 return elements_moved; 1706 return elements_moved;
1741 } 1707 }
1742 1708
1709 void FormNearendBlock(
1710 size_t nearend_start_index,
1711 size_t num_bands,
1712 const float* const* nearend_frame,
1713 size_t num_samples_from_nearend_frame,
1714 const float nearend_buffer[NUM_HIGH_BANDS_MAX + 1]
1715 [PART_LEN - (FRAME_LEN - PART_LEN)],
1716 float nearend_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN]) {
1717 RTC_DCHECK_LE(num_samples_from_nearend_frame, static_cast<size_t>(PART_LEN));
1718 const int num_samples_from_buffer = PART_LEN - num_samples_from_nearend_frame;
1719
1720 if (num_samples_from_buffer > 0) {
1721 for (size_t i = 0; i < num_bands; ++i) {
1722 memcpy(&nearend_block[i][0], &nearend_buffer[i][0],
1723 num_samples_from_buffer * sizeof(float));
1724 }
1725 }
1726
1727 for (size_t i = 0; i < num_bands; ++i) {
1728 memcpy(&nearend_block[i][num_samples_from_buffer],
1729 &nearend_frame[i][nearend_start_index],
1730 num_samples_from_nearend_frame * sizeof(float));
1731 }
1732 }
1733
1734 void BufferNearendFrame(
1735 size_t nearend_start_index,
1736 size_t num_bands,
1737 const float* const* nearend_frame,
1738 size_t num_samples_to_buffer,
1739 float nearend_buffer[NUM_HIGH_BANDS_MAX + 1]
1740 [PART_LEN - (FRAME_LEN - PART_LEN)]) {
1741 for (size_t i = 0; i < num_bands; ++i) {
1742 memcpy(
1743 &nearend_buffer[i][0],
1744 &nearend_frame[i]
1745 [nearend_start_index + FRAME_LEN - num_samples_to_buffer],
1746 num_samples_to_buffer * sizeof(float));
1747 }
1748 }
1749
1750 void BufferOutputBlock(size_t num_bands,
1751 const float output_block[NUM_HIGH_BANDS_MAX + 1]
1752 [PART_LEN],
1753 size_t* output_buffer_size,
1754 float output_buffer[NUM_HIGH_BANDS_MAX + 1]
1755 [2 * PART_LEN]) {
1756 for (size_t i = 0; i < num_bands; ++i) {
1757 memcpy(&output_buffer[i][*output_buffer_size], &output_block[i][0],
1758 PART_LEN * sizeof(float));
1759 }
1760 (*output_buffer_size) += PART_LEN;
1761 }
1762
1763 void FormOutputFrame(size_t output_start_index,
1764 size_t num_bands,
1765 size_t* output_buffer_size,
1766 float output_buffer[NUM_HIGH_BANDS_MAX + 1][2 * PART_LEN],
1767 float* const* output_frame) {
1768 RTC_DCHECK_LE(static_cast<size_t>(FRAME_LEN), *output_buffer_size);
1769 for (size_t i = 0; i < num_bands; ++i) {
1770 memcpy(&output_frame[i][output_start_index], &output_buffer[i][0],
1771 FRAME_LEN * sizeof(float));
1772 }
1773 (*output_buffer_size) -= FRAME_LEN;
1774 if (*output_buffer_size > 0) {
1775 RTC_DCHECK_GE(static_cast<size_t>(2 * PART_LEN - FRAME_LEN),
1776 (*output_buffer_size));
1777 for (size_t i = 0; i < num_bands; ++i) {
1778 memcpy(&output_buffer[i][0], &output_buffer[i][FRAME_LEN],
1779 (*output_buffer_size) * sizeof(float));
1780 }
1781 }
1782 }
1783
1743 void WebRtcAec_ProcessFrames(AecCore* aec, 1784 void WebRtcAec_ProcessFrames(AecCore* aec,
1744 const float* const* nearend, 1785 const float* const* nearend,
1745 size_t num_bands, 1786 size_t num_bands,
1746 size_t num_samples, 1787 size_t num_samples,
1747 int knownDelay, 1788 int knownDelay,
1748 float* const* out) { 1789 float* const* out) {
1749 int out_elements = 0;
1750
1751 RTC_DCHECK(num_samples == 80 || num_samples == 160); 1790 RTC_DCHECK(num_samples == 80 || num_samples == 160);
1752 1791
1753 aec->frame_count++; 1792 aec->frame_count++;
1754 // For each frame the process is as follows: 1793 // For each frame the process is as follows:
1755 // 1) If the system_delay indicates on being too small for processing a 1794 // 1) If the system_delay indicates on being too small for processing a
1756 // frame we stuff the buffer with enough data for 10 ms. 1795 // frame we stuff the buffer with enough data for 10 ms.
1757 // 2 a) Adjust the buffer to the system delay, by moving the read pointer. 1796 // 2 a) Adjust the buffer to the system delay, by moving the read pointer.
1758 // b) Apply signal based delay correction, if we have detected poor AEC 1797 // b) Apply signal based delay correction, if we have detected poor AEC
1759 // performance. 1798 // performance.
1760 // 3) TODO(bjornv): Investigate if we need to add this: 1799 // 3) TODO(bjornv): Investigate if we need to add this:
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1820 // If we rely on reported system delay values only, a buffer underrun here 1859 // If we rely on reported system delay values only, a buffer underrun here
1821 // can never occur since we've taken care of that in 1) above. Here, we 1860 // can never occur since we've taken care of that in 1) above. Here, we
1822 // apply signal based delay correction and can therefore end up with 1861 // apply signal based delay correction and can therefore end up with
1823 // buffer underruns since the delay estimation can be wrong. We therefore 1862 // buffer underruns since the delay estimation can be wrong. We therefore
1824 // stuff the buffer with enough elements if needed. 1863 // stuff the buffer with enough elements if needed.
1825 if (far_near_buffer_diff < 0) { 1864 if (far_near_buffer_diff < 0) {
1826 WebRtcAec_MoveFarReadPtr(aec, far_near_buffer_diff); 1865 WebRtcAec_MoveFarReadPtr(aec, far_near_buffer_diff);
1827 } 1866 }
1828 } 1867 }
1829 1868
1830 // Form a process a block of samples. 1869 static_assert(
1831 RTC_DCHECK_EQ(16, FRAME_LEN - PART_LEN); 1870 16 == (FRAME_LEN - PART_LEN),
1871 "These constants need to be properly related for this code to work");
1872 float output_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN];
1832 float nearend_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN]; 1873 float nearend_block[NUM_HIGH_BANDS_MAX + 1][PART_LEN];
1833 const int num_samples_to_block = PART_LEN - aec->nearend_buffer_size;
1834 const int num_samples_to_buffer = FRAME_LEN - num_samples_to_block;
1835 for (size_t i = 0; i < num_bands; ++i) {
1836 memcpy(&nearend_block[i][0], &aec->nearend_buffer[i][0],
1837 aec->nearend_buffer_size * sizeof(float));
1838 memcpy(&nearend_block[i][aec->nearend_buffer_size], &nearend[i][j],
1839 num_samples_to_block * sizeof(float));
1840 }
1841 ProcessBlock(aec, nearend_block);
1842 1874
1843 if (num_samples_to_buffer == PART_LEN) { 1875 // Form and process a block of nearend samples, buffer the output block of
1844 // If possible form and process a second block of samples. 1876 // samples.
1845 for (size_t i = 0; i < num_bands; ++i) { 1877 FormNearendBlock(j, num_bands, nearend, PART_LEN - aec->nearend_buffer_size,
1846 memcpy(&nearend_block[i][0], &nearend[i][j + num_samples_to_block], 1878 aec->nearend_buffer, nearend_block);
1847 num_samples_to_buffer * sizeof(float)); 1879 ProcessBlock(aec, nearend_block, output_block);
1848 } 1880 BufferOutputBlock(num_bands, output_block, &aec->output_buffer_size,
1849 ProcessBlock(aec, nearend_block); 1881 aec->output_buffer);
1882
1883 if ((FRAME_LEN - PART_LEN + aec->nearend_buffer_size) == PART_LEN) {
1884 // When possible (every fourth frame) form and process a second block of
1885 // nearend samples, buffer the output block of samples.
1886 FormNearendBlock(j + FRAME_LEN - PART_LEN, num_bands, nearend, PART_LEN,
1887 aec->nearend_buffer, nearend_block);
1888 ProcessBlock(aec, nearend_block, output_block);
1889 BufferOutputBlock(num_bands, output_block, &aec->output_buffer_size,
1890 aec->output_buffer);
1891
1892 // Reset the buffer size as there are no samples left in the nearend input
1893 // to buffer.
1850 aec->nearend_buffer_size = 0; 1894 aec->nearend_buffer_size = 0;
1851 } else { 1895 } else {
1852 // Buffer the remaining samples in the frame. 1896 // Buffer the remaining samples in the nearend input.
1853 for (size_t i = 0; i < num_bands; ++i) { 1897 aec->nearend_buffer_size += FRAME_LEN - PART_LEN;
1854 memcpy(&aec->nearend_buffer[i][0], 1898 BufferNearendFrame(j, num_bands, nearend, aec->nearend_buffer_size,
1855 &nearend[i][j + num_samples_to_block], 1899 aec->nearend_buffer);
1856 num_samples_to_buffer * sizeof(float));
1857 }
1858 aec->nearend_buffer_size = num_samples_to_buffer;
1859 } 1900 }
1860 1901
1861 // 5) Update system delay with respect to the entire frame. 1902 // 5) Update system delay with respect to the entire frame.
1862 aec->system_delay -= FRAME_LEN; 1903 aec->system_delay -= FRAME_LEN;
1863 1904
1864 // 6) Update output frame. 1905 // 6) Form the output frame.
1865 // Stuff the out buffer if we have less than a frame to output. 1906 FormOutputFrame(j, num_bands, &aec->output_buffer_size, aec->output_buffer,
1866 // This should only happen for the first frame. 1907 out);
1867 out_elements = static_cast<int>(WebRtc_available_read(aec->outFrBuf));
1868 if (out_elements < FRAME_LEN) {
1869 WebRtc_MoveReadPtr(aec->outFrBuf, out_elements - FRAME_LEN);
1870 for (size_t i = 0; i < num_bands - 1; ++i) {
1871 WebRtc_MoveReadPtr(aec->outFrBufH[i], out_elements - FRAME_LEN);
1872 }
1873 }
1874 // Obtain an output frame.
1875 WebRtc_ReadBuffer(aec->outFrBuf, NULL, &out[0][j], FRAME_LEN);
1876 // For H bands.
1877 for (size_t i = 1; i < num_bands; ++i) {
1878 WebRtc_ReadBuffer(aec->outFrBufH[i - 1], NULL, &out[i][j], FRAME_LEN);
1879 }
1880 } 1908 }
1881 } 1909 }
1882 1910
1883 int WebRtcAec_GetDelayMetricsCore(AecCore* self, 1911 int WebRtcAec_GetDelayMetricsCore(AecCore* self,
1884 int* median, 1912 int* median,
1885 int* std, 1913 int* std,
1886 float* fraction_poor_delays) { 1914 float* fraction_poor_delays) {
1887 assert(self != NULL); 1915 assert(self != NULL);
1888 assert(median != NULL); 1916 assert(median != NULL);
1889 assert(std != NULL); 1917 assert(std != NULL);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1983 2011
1984 int WebRtcAec_system_delay(AecCore* self) { 2012 int WebRtcAec_system_delay(AecCore* self) {
1985 return self->system_delay; 2013 return self->system_delay;
1986 } 2014 }
1987 2015
1988 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 2016 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
1989 assert(delay >= 0); 2017 assert(delay >= 0);
1990 self->system_delay = delay; 2018 self->system_delay = delay;
1991 } 2019 }
1992 } // namespace webrtc 2020 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_processing/aec/aec_core.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698