OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 an process a block of samples. |
hlundin-webrtc
2016/09/07 21:28:46
Typo: an -> a
| |
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 Loading... | |
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 |
OLD | NEW |