| 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 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 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 |