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

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

Issue 2311833002: Refactoring of the buffering of the nearend signal done inside the AEC (Closed)
Patch Set: Rebase 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
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 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 } else { 1098 } else {
1099 aec->overdrive_scaling = 1099 aec->overdrive_scaling =
1100 0.9f * aec->overdrive_scaling + 0.1f * aec->overDrive; 1100 0.9f * aec->overdrive_scaling + 0.1f * aec->overDrive;
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 farend[PART_LEN2], 1109 float farend[PART_LEN2],
1109 float* echo_subtractor_output, 1110 float* echo_subtractor_output,
1110 float* output, 1111 float* output,
1111 float* const* outputH) { 1112 float* const* outputH) {
1112 float efw[2][PART_LEN1]; 1113 float efw[2][PART_LEN1];
1113 float xfw[2][PART_LEN1]; 1114 float xfw[2][PART_LEN1];
1114 float dfw[2][PART_LEN1]; 1115 float dfw[2][PART_LEN1];
1115 float comfortNoiseHband[2][PART_LEN1]; 1116 float comfortNoiseHband[2][PART_LEN1];
1116 float fft[PART_LEN2]; 1117 float fft[PART_LEN2];
1117 float nlpGainHband; 1118 float nlpGainHband;
1118 int i; 1119 int i;
1119 size_t j; 1120 size_t j;
1120 1121
1121 // Coherence and non-linear filter 1122 // Coherence and non-linear filter
1122 float cohde[PART_LEN1], cohxd[PART_LEN1]; 1123 float cohde[PART_LEN1], cohxd[PART_LEN1];
1123 float hNl[PART_LEN1]; 1124 float hNl[PART_LEN1];
1124 1125
1125 // Filter energy 1126 // Filter energy
1126 const int delayEstInterval = 10 * aec->mult; 1127 const int delayEstInterval = 10 * aec->mult;
1127 1128
1128 float* xfw_ptr = NULL; 1129 float* xfw_ptr = NULL;
1129 1130
1130 // Update eBuf with echo subtractor output. 1131 // Update eBuf with echo subtractor output.
1131 memcpy(aec->eBuf + PART_LEN, echo_subtractor_output, 1132 memcpy(aec->eBuf + PART_LEN, echo_subtractor_output,
1132 sizeof(float) * PART_LEN); 1133 sizeof(float) * PART_LEN);
1133 1134
1134 // Analysis filter banks for the echo suppressor. 1135 // Analysis filter banks for the echo suppressor.
1135 // Windowed near-end ffts. 1136 // Windowed near-end ffts.
1136 WindowData(fft, aec->dBuf); 1137 WindowData(fft, nearend_extended_block_lowest_band);
1137 aec_rdft_forward_128(fft); 1138 aec_rdft_forward_128(fft);
1138 StoreAsComplex(fft, dfw); 1139 StoreAsComplex(fft, dfw);
1139 1140
1140 // Windowed echo suppressor output ffts. 1141 // Windowed echo suppressor output ffts.
1141 WindowData(fft, aec->eBuf); 1142 WindowData(fft, aec->eBuf);
1142 aec_rdft_forward_128(fft); 1143 aec_rdft_forward_128(fft);
1143 StoreAsComplex(fft, efw); 1144 StoreAsComplex(fft, efw);
1144 1145
1145 // NLP 1146 // NLP
1146 1147
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 // average nlp over low band: average over second half of freq spectrum 1208 // average nlp over low band: average over second half of freq spectrum
1208 // (4->8khz) 1209 // (4->8khz)
1209 GetHighbandGain(hNl, &nlpGainHband); 1210 GetHighbandGain(hNl, &nlpGainHband);
1210 1211
1211 // Inverse comfort_noise 1212 // Inverse comfort_noise
1212 ScaledInverseFft(comfortNoiseHband, fft, 2.0f, 0); 1213 ScaledInverseFft(comfortNoiseHband, fft, 2.0f, 0);
1213 1214
1214 // compute gain factor 1215 // compute gain factor
1215 for (j = 0; j < aec->num_bands - 1; ++j) { 1216 for (j = 0; j < aec->num_bands - 1; ++j) {
1216 for (i = 0; i < PART_LEN; i++) { 1217 for (i = 0; i < PART_LEN; i++) {
1217 outputH[j][i] = aec->dBufH[j][i] * nlpGainHband; 1218 outputH[j][i] = aec->previous_nearend_block[j + 1][i] * nlpGainHband;
1218 } 1219 }
1219 } 1220 }
1220 1221
1221 // Add some comfort noise where Hband is attenuated. 1222 // Add some comfort noise where Hband is attenuated.
1222 for (i = 0; i < PART_LEN; i++) { 1223 for (i = 0; i < PART_LEN; i++) {
1223 outputH[0][i] += cnScaleHband * fft[i]; 1224 outputH[0][i] += cnScaleHband * fft[i];
1224 } 1225 }
1225 1226
1226 // Saturate output to keep it in the allowed range. 1227 // Saturate output to keep it in the allowed range.
1227 for (j = 0; j < aec->num_bands - 1; ++j) { 1228 for (j = 0; j < aec->num_bands - 1; ++j) {
1228 for (i = 0; i < PART_LEN; i++) { 1229 for (i = 0; i < PART_LEN; i++) {
1229 outputH[j][i] = WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, outputH[j][i], 1230 outputH[j][i] = WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, outputH[j][i],
1230 WEBRTC_SPL_WORD16_MIN); 1231 WEBRTC_SPL_WORD16_MIN);
1231 } 1232 }
1232 } 1233 }
1233 } 1234 }
1234 1235
1235 // Copy the current block to the old position. 1236 // Copy the current block to the old position.
1236 memcpy(aec->dBuf, aec->dBuf + PART_LEN, sizeof(float) * PART_LEN);
1237 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN); 1237 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN);
1238 1238
1239 // Copy the current block to the old position for H band
1240 for (j = 0; j < aec->num_bands - 1; ++j) {
1241 memcpy(aec->dBufH[j], aec->dBufH[j] + PART_LEN, sizeof(float) * PART_LEN);
1242 }
1243
1244 memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf, 1239 memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf,
1245 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); 1240 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1);
1246 } 1241 }
1247 1242
1248 static void ProcessBlock(AecCore* aec) { 1243 static void ProcessBlock(AecCore* aec,
1244 float nearend_block[NUM_HIGH_BANDS_MAX + 1]
1245 [PART_LEN]) {
1249 size_t i; 1246 size_t i;
1250 1247
1251 float fft[PART_LEN2]; 1248 float fft[PART_LEN2];
1249 float nearend_extended_block_lowest_band[PART_LEN2];
1252 float x_fft[2][PART_LEN1]; 1250 float x_fft[2][PART_LEN1];
1253 float df[2][PART_LEN1]; 1251 float df[2][PART_LEN1];
1254 float far_spectrum = 0.0f; 1252 float far_spectrum = 0.0f;
1255 float near_spectrum = 0.0f; 1253 float near_spectrum = 0.0f;
1256 float abs_far_spectrum[PART_LEN1]; 1254 float abs_far_spectrum[PART_LEN1];
1257 float abs_near_spectrum[PART_LEN1]; 1255 float abs_near_spectrum[PART_LEN1];
1258 1256
1259 const float gPow[2] = {0.9f, 0.1f}; 1257 const float gPow[2] = {0.9f, 0.1f};
1260 1258
1261 // Noise estimate constants. 1259 // Noise estimate constants.
1262 const int noiseInitBlocks = 500 * aec->mult; 1260 const int noiseInitBlocks = 500 * aec->mult;
1263 const float step = 0.1f; 1261 const float step = 0.1f;
1264 const float ramp = 1.0002f; 1262 const float ramp = 1.0002f;
1265 const float gInitNoise[2] = {0.999f, 0.001f}; 1263 const float gInitNoise[2] = {0.999f, 0.001f};
1266 1264
1267 float nearend[PART_LEN];
1268 float* nearend_ptr = NULL;
1269 float farend[PART_LEN2]; 1265 float farend[PART_LEN2];
1270 float* farend_ptr = NULL; 1266 float* farend_ptr = NULL;
1271 float echo_subtractor_output[PART_LEN]; 1267 float echo_subtractor_output[PART_LEN];
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* x_fft_ptr = NULL; 1271 float* x_fft_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.
1282 for (i = 0; i < aec->num_bands - 1; ++i) {
1283 WebRtc_ReadBuffer(aec->nearFrBufH[i],
1284 reinterpret_cast<void**>(&nearend_ptr),
1285 nearend, PART_LEN);
1286 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend));
1287 }
1288 WebRtc_ReadBuffer(aec->nearFrBuf, reinterpret_cast<void**>(&nearend_ptr),
1289 nearend, PART_LEN);
1290 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend));
1291
1292 // We should always have at least one element stored in |far_buf|. 1277 // We should always have at least one element stored in |far_buf|.
1293 assert(WebRtc_available_read(aec->far_time_buf) > 0); 1278 assert(WebRtc_available_read(aec->far_time_buf) > 0);
1294 WebRtc_ReadBuffer(aec->far_time_buf, reinterpret_cast<void**>(&farend_ptr), 1279 WebRtc_ReadBuffer(aec->far_time_buf, reinterpret_cast<void**>(&farend_ptr),
1295 farend, 1); 1280 farend, 1);
1296 1281
1297 aec->data_dumper->DumpWav("aec_far", PART_LEN, &farend_ptr[PART_LEN], 1282 aec->data_dumper->DumpWav("aec_far", PART_LEN, &farend_ptr[PART_LEN],
1298 std::min(aec->sampFreq, 16000), 1); 1283 std::min(aec->sampFreq, 16000), 1);
1299 aec->data_dumper->DumpWav("aec_near", PART_LEN, nearend_ptr, 1284 aec->data_dumper->DumpWav("aec_near", PART_LEN, &nearend_block[0][0],
1300 std::min(aec->sampFreq, 16000), 1); 1285 std::min(aec->sampFreq, 16000), 1);
1301 1286
1302 if (aec->metricsMode == 1) { 1287 if (aec->metricsMode == 1) {
1303 // Update power levels 1288 // Update power levels
1304 UpdateLevel(&aec->farlevel, 1289 UpdateLevel(&aec->farlevel,
1305 CalculatePower(&farend_ptr[PART_LEN], PART_LEN)); 1290 CalculatePower(&farend_ptr[PART_LEN], PART_LEN));
1306 UpdateLevel(&aec->nearlevel, CalculatePower(nearend_ptr, PART_LEN)); 1291 UpdateLevel(&aec->nearlevel,
1292 CalculatePower(&nearend_block[0][0], PART_LEN));
1307 } 1293 }
1308 1294
1309 // Convert far-end signal to the frequency domain. 1295 // Convert far-end signal to the frequency domain.
1310 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); 1296 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2);
1311 Fft(fft, x_fft); 1297 Fft(fft, x_fft);
1312 x_fft_ptr = &x_fft[0][0]; 1298 x_fft_ptr = &x_fft[0][0];
1313 1299
1300 // Form extended nearend frame.
1301 memcpy(&nearend_extended_block_lowest_band[0],
1302 &aec->previous_nearend_block[0][0], sizeof(float) * PART_LEN);
1303 memcpy(&nearend_extended_block_lowest_band[PART_LEN], &nearend_block[0][0],
1304 sizeof(float) * PART_LEN);
1305
1314 // Near fft 1306 // Near fft
1315 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); 1307 memcpy(fft, nearend_extended_block_lowest_band, sizeof(float) * PART_LEN2);
1316 Fft(fft, df); 1308 Fft(fft, df);
1317 1309
1318 // Power smoothing. 1310 // Power smoothing.
1319 if (aec->refined_adaptive_filter_enabled) { 1311 if (aec->refined_adaptive_filter_enabled) {
1320 for (i = 0; i < PART_LEN1; ++i) { 1312 for (i = 0; i < PART_LEN1; ++i) {
1321 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + 1313 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) +
1322 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); 1314 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]);
1323 // Calculate the magnitude spectrum. 1315 // Calculate the magnitude spectrum.
1324 abs_far_spectrum[i] = sqrtf(far_spectrum); 1316 abs_far_spectrum[i] = sqrtf(far_spectrum);
1325 } 1317 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1387 aec->num_delay_values >= kDelayMetricsAggregationWindow) { 1379 aec->num_delay_values >= kDelayMetricsAggregationWindow) {
1388 UpdateDelayMetrics(aec); 1380 UpdateDelayMetrics(aec);
1389 } 1381 }
1390 } 1382 }
1391 } 1383 }
1392 1384
1393 // Perform echo subtraction. 1385 // Perform echo subtraction.
1394 EchoSubtraction(aec->num_partitions, aec->extended_filter_enabled, 1386 EchoSubtraction(aec->num_partitions, aec->extended_filter_enabled,
1395 &aec->extreme_filter_divergence, aec->filter_step_size, 1387 &aec->extreme_filter_divergence, aec->filter_step_size,
1396 aec->error_threshold, &x_fft[0][0], &aec->xfBufBlockPos, 1388 aec->error_threshold, &x_fft[0][0], &aec->xfBufBlockPos,
1397 aec->xfBuf, nearend_ptr, aec->xPow, aec->wfBuf, 1389 aec->xfBuf, &nearend_block[0][0], aec->xPow, aec->wfBuf,
1398 echo_subtractor_output); 1390 echo_subtractor_output);
1399 aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions, 1391 aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions,
1400 &aec->wfBuf[0][0]); 1392 &aec->wfBuf[0][0]);
1401 aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions, 1393 aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions,
1402 &aec->wfBuf[1][0]); 1394 &aec->wfBuf[1][0]);
1403 1395
1404 aec->data_dumper->DumpWav("aec_out_linear", PART_LEN, echo_subtractor_output, 1396 aec->data_dumper->DumpWav("aec_out_linear", PART_LEN, echo_subtractor_output,
1405 std::min(aec->sampFreq, 16000), 1); 1397 std::min(aec->sampFreq, 16000), 1);
1406 1398
1407 if (aec->metricsMode == 1) { 1399 if (aec->metricsMode == 1) {
1408 UpdateLevel(&aec->linoutlevel, 1400 UpdateLevel(&aec->linoutlevel,
1409 CalculatePower(echo_subtractor_output, PART_LEN)); 1401 CalculatePower(echo_subtractor_output, PART_LEN));
1410 } 1402 }
1411 1403
1412 // Perform echo suppression. 1404 // Perform echo suppression.
1413 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr); 1405 EchoSuppression(aec, nearend_extended_block_lowest_band, farend_ptr,
1406 echo_subtractor_output, output, outputH_ptr);
1414 1407
1415 if (aec->metricsMode == 1) { 1408 if (aec->metricsMode == 1) {
1416 UpdateLevel(&aec->nlpoutlevel, CalculatePower(output, PART_LEN)); 1409 UpdateLevel(&aec->nlpoutlevel, CalculatePower(output, PART_LEN));
1417 UpdateMetrics(aec); 1410 UpdateMetrics(aec);
1418 } 1411 }
1419 1412
1413 // Store the nearend signal until the next frame.
1414 for (i = 0; i < aec->num_bands; ++i) {
1415 memcpy(&aec->previous_nearend_block[i][0], &nearend_block[i][0],
1416 sizeof(float) * PART_LEN);
1417 }
1418
1420 // Store the output block. 1419 // Store the output block.
1421 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN); 1420 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN);
1422 // For high bands 1421 // For high bands
1423 for (i = 0; i < aec->num_bands - 1; ++i) { 1422 for (i = 0; i < aec->num_bands - 1; ++i) {
1424 WebRtc_WriteBuffer(aec->outFrBufH[i], outputH[i], PART_LEN); 1423 WebRtc_WriteBuffer(aec->outFrBufH[i], outputH[i], PART_LEN);
1425 } 1424 }
1426 1425
1427 aec->data_dumper->DumpWav("aec_out", PART_LEN, output, 1426 aec->data_dumper->DumpWav("aec_out", PART_LEN, output,
1428 std::min(aec->sampFreq, 16000), 1); 1427 std::min(aec->sampFreq, 16000), 1);
1429 } 1428 }
1430 1429
1431 AecCore* WebRtcAec_CreateAec(int instance_count) { 1430 AecCore* WebRtcAec_CreateAec(int instance_count) {
1432 int i; 1431 int i;
1433 AecCore* aec = new AecCore(instance_count); 1432 AecCore* aec = new AecCore(instance_count);
1434 1433
1435 if (!aec) { 1434 if (!aec) {
1436 return NULL; 1435 return NULL;
1437 } 1436 }
1438 1437 aec->nearend_buffer_size = 0;
1439 aec->nearFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); 1438 memset(&aec->nearend_buffer[0], 0, sizeof(aec->nearend_buffer));
1440 if (!aec->nearFrBuf) {
1441 WebRtcAec_FreeAec(aec);
1442 return NULL;
1443 }
1444 1439
1445 aec->outFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); 1440 aec->outFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1446 if (!aec->outFrBuf) { 1441 if (!aec->outFrBuf) {
1447 WebRtcAec_FreeAec(aec); 1442 WebRtcAec_FreeAec(aec);
1448 return NULL; 1443 return NULL;
1449 } 1444 }
1450 1445
1451 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { 1446 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) {
1452 aec->nearFrBufH[i] =
1453 WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1454 if (!aec->nearFrBufH[i]) {
1455 WebRtcAec_FreeAec(aec);
1456 return NULL;
1457 }
1458 aec->outFrBufH[i] = 1447 aec->outFrBufH[i] =
1459 WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); 1448 WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1460 if (!aec->outFrBufH[i]) { 1449 if (!aec->outFrBufH[i]) {
1461 WebRtcAec_FreeAec(aec); 1450 WebRtcAec_FreeAec(aec);
1462 return NULL; 1451 return NULL;
1463 } 1452 }
1464 } 1453 }
1465 1454
1466 // Create far-end buffers. 1455 // Create far-end buffers.
1467 // For bit exactness with legacy code, each element in |far_time_buf| is 1456 // For bit exactness with legacy code, each element in |far_time_buf| is
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1532 1521
1533 return aec; 1522 return aec;
1534 } 1523 }
1535 1524
1536 void WebRtcAec_FreeAec(AecCore* aec) { 1525 void WebRtcAec_FreeAec(AecCore* aec) {
1537 int i; 1526 int i;
1538 if (aec == NULL) { 1527 if (aec == NULL) {
1539 return; 1528 return;
1540 } 1529 }
1541 1530
1542 WebRtc_FreeBuffer(aec->nearFrBuf);
1543 WebRtc_FreeBuffer(aec->outFrBuf); 1531 WebRtc_FreeBuffer(aec->outFrBuf);
1544 1532
1545 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { 1533 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) {
1546 WebRtc_FreeBuffer(aec->nearFrBufH[i]);
1547 WebRtc_FreeBuffer(aec->outFrBufH[i]); 1534 WebRtc_FreeBuffer(aec->outFrBufH[i]);
1548 } 1535 }
1549 1536
1550 WebRtc_FreeBuffer(aec->far_time_buf); 1537 WebRtc_FreeBuffer(aec->far_time_buf);
1551 1538
1552 WebRtc_FreeDelayEstimator(aec->delay_estimator); 1539 WebRtc_FreeDelayEstimator(aec->delay_estimator);
1553 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); 1540 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend);
1554 1541
1555 delete aec; 1542 delete aec;
1556 } 1543 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1599 1586
1600 SetAdaptiveFilterStepSize(aec); 1587 SetAdaptiveFilterStepSize(aec);
1601 SetErrorThreshold(aec); 1588 SetErrorThreshold(aec);
1602 1589
1603 if (sampFreq == 8000) { 1590 if (sampFreq == 8000) {
1604 aec->num_bands = 1; 1591 aec->num_bands = 1;
1605 } else { 1592 } else {
1606 aec->num_bands = (size_t)(sampFreq / 16000); 1593 aec->num_bands = (size_t)(sampFreq / 16000);
1607 } 1594 }
1608 1595
1609 WebRtc_InitBuffer(aec->nearFrBuf); 1596 aec->nearend_buffer_size = 0;
1597 memset(&aec->nearend_buffer[0], 0, sizeof(aec->nearend_buffer));
1598
1610 WebRtc_InitBuffer(aec->outFrBuf); 1599 WebRtc_InitBuffer(aec->outFrBuf);
1611 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { 1600 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) {
1612 WebRtc_InitBuffer(aec->nearFrBufH[i]);
1613 WebRtc_InitBuffer(aec->outFrBufH[i]); 1601 WebRtc_InitBuffer(aec->outFrBufH[i]);
1614 } 1602 }
1615 1603
1616 // Initialize far-end buffers. 1604 // Initialize far-end buffers.
1617 WebRtc_InitBuffer(aec->far_time_buf); 1605 WebRtc_InitBuffer(aec->far_time_buf);
1618 1606
1619 aec->system_delay = 0; 1607 aec->system_delay = 0;
1620 1608
1621 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) { 1609 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) {
1622 return -1; 1610 return -1;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1665 } 1653 }
1666 1654
1667 aec->farBufWritePos = 0; 1655 aec->farBufWritePos = 0;
1668 aec->farBufReadPos = 0; 1656 aec->farBufReadPos = 0;
1669 1657
1670 aec->inSamples = 0; 1658 aec->inSamples = 0;
1671 aec->outSamples = 0; 1659 aec->outSamples = 0;
1672 aec->knownDelay = 0; 1660 aec->knownDelay = 0;
1673 1661
1674 // Initialize buffers 1662 // Initialize buffers
1675 memset(aec->dBuf, 0, sizeof(aec->dBuf)); 1663 memset(aec->previous_nearend_block, 0, sizeof(aec->previous_nearend_block));
1676 memset(aec->eBuf, 0, sizeof(aec->eBuf)); 1664 memset(aec->eBuf, 0, sizeof(aec->eBuf));
1677 // For H bands
1678 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) {
1679 memset(aec->dBufH[i], 0, sizeof(aec->dBufH[i]));
1680 }
1681 1665
1682 memset(aec->xPow, 0, sizeof(aec->xPow)); 1666 memset(aec->xPow, 0, sizeof(aec->xPow));
1683 memset(aec->dPow, 0, sizeof(aec->dPow)); 1667 memset(aec->dPow, 0, sizeof(aec->dPow));
1684 memset(aec->dInitMinPow, 0, sizeof(aec->dInitMinPow)); 1668 memset(aec->dInitMinPow, 0, sizeof(aec->dInitMinPow));
1685 aec->noisePow = aec->dInitMinPow; 1669 aec->noisePow = aec->dInitMinPow;
1686 aec->noiseEstCtr = 0; 1670 aec->noiseEstCtr = 0;
1687 1671
1688 // Initial comfort noise power 1672 // Initial comfort noise power
1689 for (i = 0; i < PART_LEN1; i++) { 1673 for (i = 0; i < PART_LEN1; i++) {
1690 aec->dMinPow[i] = 1.0e6f; 1674 aec->dMinPow[i] = 1.0e6f;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1755 aec->system_delay -= elements_moved * PART_LEN; 1739 aec->system_delay -= elements_moved * PART_LEN;
1756 return elements_moved; 1740 return elements_moved;
1757 } 1741 }
1758 1742
1759 void WebRtcAec_ProcessFrames(AecCore* aec, 1743 void WebRtcAec_ProcessFrames(AecCore* aec,
1760 const float* const* nearend, 1744 const float* const* nearend,
1761 size_t num_bands, 1745 size_t num_bands,
1762 size_t num_samples, 1746 size_t num_samples,
1763 int knownDelay, 1747 int knownDelay,
1764 float* const* out) { 1748 float* const* out) {
1765 size_t i, j;
1766 int out_elements = 0; 1749 int out_elements = 0;
1767 1750
1751 RTC_DCHECK(num_samples == 80 || num_samples == 160);
1752
1768 aec->frame_count++; 1753 aec->frame_count++;
1769 // For each frame the process is as follows: 1754 // For each frame the process is as follows:
1770 // 1) If the system_delay indicates on being too small for processing a 1755 // 1) If the system_delay indicates on being too small for processing a
1771 // frame we stuff the buffer with enough data for 10 ms. 1756 // frame we stuff the buffer with enough data for 10 ms.
1772 // 2 a) Adjust the buffer to the system delay, by moving the read pointer. 1757 // 2 a) Adjust the buffer to the system delay, by moving the read pointer.
1773 // b) Apply signal based delay correction, if we have detected poor AEC 1758 // b) Apply signal based delay correction, if we have detected poor AEC
1774 // performance. 1759 // performance.
1775 // 3) TODO(bjornv): Investigate if we need to add this: 1760 // 3) TODO(bjornv): Investigate if we need to add this:
1776 // If we can't move read pointer due to buffer size limitations we 1761 // If we can't move read pointer due to buffer size limitations we
1777 // flush/stuff the buffer. 1762 // flush/stuff the buffer.
(...skipping 10 matching lines...) Expand all
1788 // give a guess on how much we need to shift far-end buffers to align with 1773 // give a guess on how much we need to shift far-end buffers to align with
1789 // the near-end signal. The other delay estimation algorithm uses the 1774 // the near-end signal. The other delay estimation algorithm uses the
1790 // far- and near-end signals to find the offset between them. This one 1775 // far- and near-end signals to find the offset between them. This one
1791 // (called "signal delay") is then used to fine tune the alignment, or 1776 // (called "signal delay") is then used to fine tune the alignment, or
1792 // simply compensate for errors in the system based one. 1777 // simply compensate for errors in the system based one.
1793 // Note that the two algorithms operate independently. Currently, we only 1778 // Note that the two algorithms operate independently. Currently, we only
1794 // allow one algorithm to be turned on. 1779 // allow one algorithm to be turned on.
1795 1780
1796 assert(aec->num_bands == num_bands); 1781 assert(aec->num_bands == num_bands);
1797 1782
1798 for (j = 0; j < num_samples; j += FRAME_LEN) { 1783 for (size_t j = 0; j < num_samples; j += FRAME_LEN) {
1799 // TODO(bjornv): Change the near-end buffer handling to be the same as for
1800 // far-end, that is, with a near_pre_buf.
1801 // Buffer the near-end frame.
1802 WebRtc_WriteBuffer(aec->nearFrBuf, &nearend[0][j], FRAME_LEN);
1803 // For H band
1804 for (i = 1; i < num_bands; ++i) {
1805 WebRtc_WriteBuffer(aec->nearFrBufH[i - 1], &nearend[i][j], FRAME_LEN);
1806 }
1807
1808 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we 1784 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we
1809 // have enough far-end data for that by stuffing the buffer if the 1785 // have enough far-end data for that by stuffing the buffer if the
1810 // |system_delay| indicates others. 1786 // |system_delay| indicates others.
1811 if (aec->system_delay < FRAME_LEN) { 1787 if (aec->system_delay < FRAME_LEN) {
1812 // We don't have enough data so we rewind 10 ms. 1788 // We don't have enough data so we rewind 10 ms.
1813 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1)); 1789 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1));
1814 } 1790 }
1815 1791
1816 if (!aec->delay_agnostic_enabled) { 1792 if (!aec->delay_agnostic_enabled) {
1817 // 2 a) Compensate for a possible change in the system delay. 1793 // 2 a) Compensate for a possible change in the system delay.
(...skipping 11 matching lines...) Expand all
1829 DelaySource::kSystemDelay); 1805 DelaySource::kSystemDelay);
1830 aec->knownDelay -= moved_elements * PART_LEN; 1806 aec->knownDelay -= moved_elements * PART_LEN;
1831 } else { 1807 } else {
1832 // 2 b) Apply signal based delay correction. 1808 // 2 b) Apply signal based delay correction.
1833 int move_elements = SignalBasedDelayCorrection(aec); 1809 int move_elements = SignalBasedDelayCorrection(aec);
1834 int moved_elements = WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); 1810 int moved_elements = WebRtc_MoveReadPtr(aec->far_time_buf, move_elements);
1835 MaybeLogDelayAdjustment(moved_elements * (aec->sampFreq == 8000 ? 8 : 4), 1811 MaybeLogDelayAdjustment(moved_elements * (aec->sampFreq == 8000 ? 8 : 4),
1836 DelaySource::kDelayAgnostic); 1812 DelaySource::kDelayAgnostic);
1837 int far_near_buffer_diff = 1813 int far_near_buffer_diff =
1838 WebRtc_available_read(aec->far_time_buf) - 1814 WebRtc_available_read(aec->far_time_buf) -
1839 WebRtc_available_read(aec->nearFrBuf) / PART_LEN; 1815 (aec->nearend_buffer_size + FRAME_LEN) / PART_LEN;
1840 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); 1816 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements);
1841 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, 1817 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend,
1842 moved_elements); 1818 moved_elements);
1843 aec->signal_delay_correction += moved_elements; 1819 aec->signal_delay_correction += moved_elements;
1844 // If we rely on reported system delay values only, a buffer underrun here 1820 // If we rely on reported system delay values only, a buffer underrun here
1845 // can never occur since we've taken care of that in 1) above. Here, we 1821 // can never occur since we've taken care of that in 1) above. Here, we
1846 // apply signal based delay correction and can therefore end up with 1822 // apply signal based delay correction and can therefore end up with
1847 // buffer underruns since the delay estimation can be wrong. We therefore 1823 // buffer underruns since the delay estimation can be wrong. We therefore
1848 // stuff the buffer with enough elements if needed. 1824 // stuff the buffer with enough elements if needed.
1849 if (far_near_buffer_diff < 0) { 1825 if (far_near_buffer_diff < 0) {
1850 WebRtcAec_MoveFarReadPtr(aec, far_near_buffer_diff); 1826 WebRtcAec_MoveFarReadPtr(aec, far_near_buffer_diff);
1851 } 1827 }
1852 } 1828 }
1853 1829
1854 // 4) Process as many blocks as possible. 1830 // Form a process a block of samples.
1855 while (WebRtc_available_read(aec->nearFrBuf) >= PART_LEN) { 1831 RTC_DCHECK_EQ(16, FRAME_LEN - PART_LEN);
1856 ProcessBlock(aec); 1832 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
1843 if (num_samples_to_buffer == PART_LEN) {
1844 // If possible form and process a second block of samples.
1845 for (size_t i = 0; i < num_bands; ++i) {
1846 memcpy(&nearend_block[i][0], &nearend[i][j + num_samples_to_block],
1847 num_samples_to_buffer * sizeof(float));
1848 }
1849 ProcessBlock(aec, nearend_block);
1850 aec->nearend_buffer_size = 0;
1851 } else {
1852 // Buffer the remaining samples in the frame.
1853 for (size_t i = 0; i < num_bands; ++i) {
1854 memcpy(&aec->nearend_buffer[i][0],
1855 &nearend[i][j + num_samples_to_block],
1856 num_samples_to_buffer * sizeof(float));
1857 }
1858 aec->nearend_buffer_size = num_samples_to_buffer;
1857 } 1859 }
1858 1860
1859 // 5) Update system delay with respect to the entire frame. 1861 // 5) Update system delay with respect to the entire frame.
1860 aec->system_delay -= FRAME_LEN; 1862 aec->system_delay -= FRAME_LEN;
1861 1863
1862 // 6) Update output frame. 1864 // 6) Update output frame.
1863 // Stuff the out buffer if we have less than a frame to output. 1865 // Stuff the out buffer if we have less than a frame to output.
1864 // This should only happen for the first frame. 1866 // This should only happen for the first frame.
1865 out_elements = static_cast<int>(WebRtc_available_read(aec->outFrBuf)); 1867 out_elements = static_cast<int>(WebRtc_available_read(aec->outFrBuf));
1866 if (out_elements < FRAME_LEN) { 1868 if (out_elements < FRAME_LEN) {
1867 WebRtc_MoveReadPtr(aec->outFrBuf, out_elements - FRAME_LEN); 1869 WebRtc_MoveReadPtr(aec->outFrBuf, out_elements - FRAME_LEN);
1868 for (i = 0; i < num_bands - 1; ++i) { 1870 for (size_t i = 0; i < num_bands - 1; ++i) {
1869 WebRtc_MoveReadPtr(aec->outFrBufH[i], out_elements - FRAME_LEN); 1871 WebRtc_MoveReadPtr(aec->outFrBufH[i], out_elements - FRAME_LEN);
1870 } 1872 }
1871 } 1873 }
1872 // Obtain an output frame. 1874 // Obtain an output frame.
1873 WebRtc_ReadBuffer(aec->outFrBuf, NULL, &out[0][j], FRAME_LEN); 1875 WebRtc_ReadBuffer(aec->outFrBuf, NULL, &out[0][j], FRAME_LEN);
1874 // For H bands. 1876 // For H bands.
1875 for (i = 1; i < num_bands; ++i) { 1877 for (size_t i = 1; i < num_bands; ++i) {
1876 WebRtc_ReadBuffer(aec->outFrBufH[i - 1], NULL, &out[i][j], FRAME_LEN); 1878 WebRtc_ReadBuffer(aec->outFrBufH[i - 1], NULL, &out[i][j], FRAME_LEN);
1877 } 1879 }
1878 } 1880 }
1879 } 1881 }
1880 1882
1881 int WebRtcAec_GetDelayMetricsCore(AecCore* self, 1883 int WebRtcAec_GetDelayMetricsCore(AecCore* self,
1882 int* median, 1884 int* median,
1883 int* std, 1885 int* std,
1884 float* fraction_poor_delays) { 1886 float* fraction_poor_delays) {
1885 assert(self != NULL); 1887 assert(self != NULL);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1981 1983
1982 int WebRtcAec_system_delay(AecCore* self) { 1984 int WebRtcAec_system_delay(AecCore* self) {
1983 return self->system_delay; 1985 return self->system_delay;
1984 } 1986 }
1985 1987
1986 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 1988 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
1987 assert(delay >= 0); 1989 assert(delay >= 0);
1988 self->system_delay = delay; 1990 self->system_delay = delay;
1989 } 1991 }
1990 } // namespace webrtc 1992 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_processing/aec/aec_core.h ('k') | webrtc/modules/audio_processing/aec/echo_cancellation.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698