| 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 |
| 11 /* | 11 /* |
| 12 * The core AEC algorithm, which is presented with time-aligned signals. | 12 * The core AEC algorithm, which is presented with time-aligned signals. |
| 13 */ | 13 */ |
| 14 | 14 |
| 15 #include "webrtc/modules/audio_processing/aec/aec_core.h" | 15 #include "webrtc/modules/audio_processing/aec/aec_core.h" |
| 16 | 16 |
| 17 #ifdef WEBRTC_AEC_DEBUG_DUMP | 17 #ifdef WEBRTC_AEC_DEBUG_DUMP |
| 18 #include <stdio.h> | 18 #include <stdio.h> |
| 19 #endif | 19 #endif |
| 20 | 20 |
| 21 #include <algorithm> | 21 #include <algorithm> |
| 22 #include <assert.h> | 22 #include <assert.h> |
| 23 #include <math.h> | 23 #include <math.h> |
| 24 #include <stddef.h> // size_t | 24 #include <stddef.h> // size_t |
| 25 #include <stdlib.h> | 25 #include <stdlib.h> |
| 26 #include <string.h> | 26 #include <string.h> |
| 27 | 27 |
| 28 #include "webrtc/base/checks.h" |
| 28 extern "C" { | 29 extern "C" { |
| 29 #include "webrtc/common_audio/ring_buffer.h" | 30 #include "webrtc/common_audio/ring_buffer.h" |
| 30 } | 31 } |
| 31 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar
y.h" | 32 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar
y.h" |
| 32 #include "webrtc/modules/audio_processing/aec/aec_common.h" | 33 #include "webrtc/modules/audio_processing/aec/aec_common.h" |
| 33 #include "webrtc/modules/audio_processing/aec/aec_core_internal.h" | 34 #include "webrtc/modules/audio_processing/aec/aec_core_internal.h" |
| 34 extern "C" { | 35 extern "C" { |
| 35 #include "webrtc/modules/audio_processing/aec/aec_rdft.h" | 36 #include "webrtc/modules/audio_processing/aec/aec_rdft.h" |
| 36 } | 37 } |
| 37 #include "webrtc/modules/audio_processing/logging/aec_logging.h" | 38 #include "webrtc/modules/audio_processing/logging/aec_logging.h" |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 | 236 |
| 236 for (j = 0; j < PART_LEN1; j++) { | 237 for (j = 0; j < PART_LEN1; j++) { |
| 237 y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j], | 238 y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j], |
| 238 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]); | 239 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]); |
| 239 y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j], | 240 y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j], |
| 240 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]); | 241 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]); |
| 241 } | 242 } |
| 242 } | 243 } |
| 243 } | 244 } |
| 244 | 245 |
| 245 static void ScaleErrorSignal(int extended_filter_enabled, | 246 static void ScaleErrorSignal(float mu, |
| 246 float normal_mu, | 247 float error_threshold, |
| 247 float normal_error_threshold, | |
| 248 float x_pow[PART_LEN1], | 248 float x_pow[PART_LEN1], |
| 249 float ef[2][PART_LEN1]) { | 249 float ef[2][PART_LEN1]) { |
| 250 const float mu = extended_filter_enabled ? kExtendedMu : normal_mu; | |
| 251 const float error_threshold = extended_filter_enabled | |
| 252 ? kExtendedErrorThreshold | |
| 253 : normal_error_threshold; | |
| 254 int i; | 250 int i; |
| 255 float abs_ef; | 251 float abs_ef; |
| 256 for (i = 0; i < (PART_LEN1); i++) { | 252 for (i = 0; i < (PART_LEN1); i++) { |
| 257 ef[0][i] /= (x_pow[i] + 1e-10f); | 253 ef[0][i] /= (x_pow[i] + 1e-10f); |
| 258 ef[1][i] /= (x_pow[i] + 1e-10f); | 254 ef[1][i] /= (x_pow[i] + 1e-10f); |
| 259 abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]); | 255 abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]); |
| 260 | 256 |
| 261 if (abs_ef > error_threshold) { | 257 if (abs_ef > error_threshold) { |
| 262 abs_ef = error_threshold / (abs_ef + 1e-10f); | 258 abs_ef = error_threshold / (abs_ef + 1e-10f); |
| 263 ef[0][i] *= abs_ef; | 259 ef[0][i] *= abs_ef; |
| (...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 (delay_quality > kDelayQualityThresholdMax ? kDelayQualityThresholdMax | 929 (delay_quality > kDelayQualityThresholdMax ? kDelayQualityThresholdMax |
| 934 : delay_quality); | 930 : delay_quality); |
| 935 self->delay_quality_threshold = | 931 self->delay_quality_threshold = |
| 936 (delay_quality > self->delay_quality_threshold | 932 (delay_quality > self->delay_quality_threshold |
| 937 ? delay_quality | 933 ? delay_quality |
| 938 : self->delay_quality_threshold); | 934 : self->delay_quality_threshold); |
| 939 } | 935 } |
| 940 return delay_correction; | 936 return delay_correction; |
| 941 } | 937 } |
| 942 | 938 |
| 939 static void RegressorPower(int num_partitions, |
| 940 int latest_added_partition, |
| 941 float x_fft_buf[2] |
| 942 [kExtendedNumPartitions * PART_LEN1], |
| 943 float x_pow[PART_LEN1]) { |
| 944 RTC_DCHECK_LT(latest_added_partition, num_partitions); |
| 945 memset(x_pow, 0, PART_LEN1 * sizeof(x_pow[0])); |
| 946 |
| 947 int partition = latest_added_partition; |
| 948 int x_fft_buf_position = partition * PART_LEN1; |
| 949 for (int i = 0; i < num_partitions; ++i) { |
| 950 for (int bin = 0; bin < PART_LEN1; ++bin) { |
| 951 float re = x_fft_buf[0][x_fft_buf_position]; |
| 952 float im = x_fft_buf[1][x_fft_buf_position]; |
| 953 x_pow[bin] += re * re + im * im; |
| 954 ++x_fft_buf_position; |
| 955 } |
| 956 |
| 957 ++partition; |
| 958 if (partition == num_partitions) { |
| 959 partition = 0; |
| 960 RTC_DCHECK_EQ(num_partitions * PART_LEN1, x_fft_buf_position); |
| 961 x_fft_buf_position = 0; |
| 962 } |
| 963 } |
| 964 } |
| 965 |
| 943 static void EchoSubtraction(AecCore* aec, | 966 static void EchoSubtraction(AecCore* aec, |
| 944 int num_partitions, | 967 int num_partitions, |
| 945 int extended_filter_enabled, | 968 int extended_filter_enabled, |
| 946 float normal_mu, | 969 float filter_step_size, |
| 947 float normal_error_threshold, | 970 float error_threshold, |
| 948 float* x_fft, | 971 float* x_fft, |
| 949 int* x_fft_buf_block_pos, | 972 int* x_fft_buf_block_pos, |
| 950 float x_fft_buf[2] | 973 float x_fft_buf[2] |
| 951 [kExtendedNumPartitions * PART_LEN1], | 974 [kExtendedNumPartitions * PART_LEN1], |
| 952 float* const y, | 975 float* const y, |
| 953 float x_pow[PART_LEN1], | 976 float x_pow[PART_LEN1], |
| 954 float h_fft_buf[2] | 977 float h_fft_buf[2] |
| 955 [kExtendedNumPartitions * PART_LEN1], | 978 [kExtendedNumPartitions * PART_LEN1], |
| 956 float echo_subtractor_output[PART_LEN]) { | 979 float echo_subtractor_output[PART_LEN]) { |
| 957 float s_fft[2][PART_LEN1]; | 980 float s_fft[2][PART_LEN1]; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 | 1021 |
| 999 // Compute the frequency domain echo prediction error. | 1022 // Compute the frequency domain echo prediction error. |
| 1000 memset(e_extended, 0, sizeof(float) * PART_LEN); | 1023 memset(e_extended, 0, sizeof(float) * PART_LEN); |
| 1001 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); | 1024 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); |
| 1002 Fft(e_extended, e_fft); | 1025 Fft(e_extended, e_fft); |
| 1003 | 1026 |
| 1004 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, &e_fft[0][0], | 1027 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, &e_fft[0][0], |
| 1005 sizeof(e_fft[0][0]) * PART_LEN1 * 2); | 1028 sizeof(e_fft[0][0]) * PART_LEN1 * 2); |
| 1006 | 1029 |
| 1007 // Scale error signal inversely with far power. | 1030 // Scale error signal inversely with far power. |
| 1008 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, normal_mu, | 1031 WebRtcAec_ScaleErrorSignal(filter_step_size, error_threshold, x_pow, e_fft); |
| 1009 normal_error_threshold, x_pow, e_fft); | |
| 1010 WebRtcAec_FilterAdaptation(num_partitions, *x_fft_buf_block_pos, x_fft_buf, | 1032 WebRtcAec_FilterAdaptation(num_partitions, *x_fft_buf_block_pos, x_fft_buf, |
| 1011 e_fft, h_fft_buf); | 1033 e_fft, h_fft_buf); |
| 1012 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); | 1034 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); |
| 1013 } | 1035 } |
| 1014 | 1036 |
| 1015 static void EchoSuppression(AecCore* aec, | 1037 static void EchoSuppression(AecCore* aec, |
| 1016 float farend[PART_LEN2], | 1038 float farend[PART_LEN2], |
| 1017 float* echo_subtractor_output, | 1039 float* echo_subtractor_output, |
| 1018 float* output, | 1040 float* output, |
| 1019 float* const* outputH) { | 1041 float* const* outputH) { |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1312 | 1334 |
| 1313 // Convert far-end signal to the frequency domain. | 1335 // Convert far-end signal to the frequency domain. |
| 1314 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); | 1336 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); |
| 1315 Fft(fft, x_fft); | 1337 Fft(fft, x_fft); |
| 1316 x_fft_ptr = &x_fft[0][0]; | 1338 x_fft_ptr = &x_fft[0][0]; |
| 1317 | 1339 |
| 1318 // Near fft | 1340 // Near fft |
| 1319 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); | 1341 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); |
| 1320 Fft(fft, df); | 1342 Fft(fft, df); |
| 1321 | 1343 |
| 1322 // Power smoothing | 1344 // Power smoothing. |
| 1323 for (i = 0; i < PART_LEN1; i++) { | 1345 if (aec->refined_adaptive_filter_enabled) { |
| 1324 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + | 1346 for (i = 0; i < PART_LEN1; ++i) { |
| 1325 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); | 1347 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + |
| 1326 aec->xPow[i] = | 1348 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); |
| 1327 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; | 1349 // Calculate the magnitude spectrum. |
| 1328 // Calculate absolute spectra | 1350 abs_far_spectrum[i] = sqrtf(far_spectrum); |
| 1329 abs_far_spectrum[i] = sqrtf(far_spectrum); | 1351 } |
| 1352 RegressorPower(aec->num_partitions, aec->xfBufBlockPos, aec->xfBuf, |
| 1353 aec->xPow); |
| 1354 } else { |
| 1355 for (i = 0; i < PART_LEN1; ++i) { |
| 1356 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + |
| 1357 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); |
| 1358 aec->xPow[i] = |
| 1359 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; |
| 1360 // Calculate the magnitude spectrum. |
| 1361 abs_far_spectrum[i] = sqrtf(far_spectrum); |
| 1362 } |
| 1363 } |
| 1330 | 1364 |
| 1365 for (i = 0; i < PART_LEN1; ++i) { |
| 1331 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i]; | 1366 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i]; |
| 1332 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum; | 1367 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum; |
| 1333 // Calculate absolute spectra | 1368 // Calculate the magnitude spectrum. |
| 1334 abs_near_spectrum[i] = sqrtf(near_spectrum); | 1369 abs_near_spectrum[i] = sqrtf(near_spectrum); |
| 1335 } | 1370 } |
| 1336 | 1371 |
| 1337 // Estimate noise power. Wait until dPow is more stable. | 1372 // Estimate noise power. Wait until dPow is more stable. |
| 1338 if (aec->noiseEstCtr > 50) { | 1373 if (aec->noiseEstCtr > 50) { |
| 1339 for (i = 0; i < PART_LEN1; i++) { | 1374 for (i = 0; i < PART_LEN1; i++) { |
| 1340 if (aec->dPow[i] < aec->dMinPow[i]) { | 1375 if (aec->dPow[i] < aec->dMinPow[i]) { |
| 1341 aec->dMinPow[i] = | 1376 aec->dMinPow[i] = |
| 1342 (aec->dPow[i] + step * (aec->dMinPow[i] - aec->dPow[i])) * ramp; | 1377 (aec->dPow[i] + step * (aec->dMinPow[i] - aec->dPow[i])) * ramp; |
| 1343 } else { | 1378 } else { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1376 } | 1411 } |
| 1377 if (aec->delay_metrics_delivered == 1 && | 1412 if (aec->delay_metrics_delivered == 1 && |
| 1378 aec->num_delay_values >= kDelayMetricsAggregationWindow) { | 1413 aec->num_delay_values >= kDelayMetricsAggregationWindow) { |
| 1379 UpdateDelayMetrics(aec); | 1414 UpdateDelayMetrics(aec); |
| 1380 } | 1415 } |
| 1381 } | 1416 } |
| 1382 } | 1417 } |
| 1383 | 1418 |
| 1384 // Perform echo subtraction. | 1419 // Perform echo subtraction. |
| 1385 EchoSubtraction(aec, aec->num_partitions, aec->extended_filter_enabled, | 1420 EchoSubtraction(aec, aec->num_partitions, aec->extended_filter_enabled, |
| 1386 aec->normal_mu, aec->normal_error_threshold, &x_fft[0][0], | 1421 aec->filter_step_size, aec->error_threshold, &x_fft[0][0], |
| 1387 &aec->xfBufBlockPos, aec->xfBuf, nearend_ptr, aec->xPow, | 1422 &aec->xfBufBlockPos, aec->xfBuf, nearend_ptr, aec->xPow, |
| 1388 aec->wfBuf, echo_subtractor_output); | 1423 aec->wfBuf, echo_subtractor_output); |
| 1389 | 1424 |
| 1390 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); | 1425 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); |
| 1391 | 1426 |
| 1392 if (aec->metricsMode == 1) { | 1427 if (aec->metricsMode == 1) { |
| 1393 UpdateLevel(&aec->linoutlevel, | 1428 UpdateLevel(&aec->linoutlevel, |
| 1394 CalculatePower(echo_subtractor_output, PART_LEN)); | 1429 CalculatePower(echo_subtractor_output, PART_LEN)); |
| 1395 } | 1430 } |
| 1396 | 1431 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1482 aec->delay_agnostic_enabled = 1; // DA-AEC enabled by default. | 1517 aec->delay_agnostic_enabled = 1; // DA-AEC enabled by default. |
| 1483 // DA-AEC assumes the system is causal from the beginning and will self adjust | 1518 // DA-AEC assumes the system is causal from the beginning and will self adjust |
| 1484 // the lookahead when shifting is required. | 1519 // the lookahead when shifting is required. |
| 1485 WebRtc_set_lookahead(aec->delay_estimator, 0); | 1520 WebRtc_set_lookahead(aec->delay_estimator, 0); |
| 1486 #else | 1521 #else |
| 1487 aec->delay_agnostic_enabled = 0; | 1522 aec->delay_agnostic_enabled = 0; |
| 1488 WebRtc_set_lookahead(aec->delay_estimator, kLookaheadBlocks); | 1523 WebRtc_set_lookahead(aec->delay_estimator, kLookaheadBlocks); |
| 1489 #endif | 1524 #endif |
| 1490 aec->extended_filter_enabled = 0; | 1525 aec->extended_filter_enabled = 0; |
| 1491 aec->aec3_enabled = 0; | 1526 aec->aec3_enabled = 0; |
| 1527 aec->refined_adaptive_filter_enabled = false; |
| 1492 | 1528 |
| 1493 // Assembly optimization | 1529 // Assembly optimization |
| 1494 WebRtcAec_FilterFar = FilterFar; | 1530 WebRtcAec_FilterFar = FilterFar; |
| 1495 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; | 1531 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; |
| 1496 WebRtcAec_FilterAdaptation = FilterAdaptation; | 1532 WebRtcAec_FilterAdaptation = FilterAdaptation; |
| 1497 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; | 1533 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; |
| 1498 WebRtcAec_ComfortNoise = ComfortNoise; | 1534 WebRtcAec_ComfortNoise = ComfortNoise; |
| 1499 WebRtcAec_SubbandCoherence = SubbandCoherence; | 1535 WebRtcAec_SubbandCoherence = SubbandCoherence; |
| 1500 WebRtcAec_StoreAsComplex = StoreAsComplex; | 1536 WebRtcAec_StoreAsComplex = StoreAsComplex; |
| 1501 WebRtcAec_PartitionDelay = PartitionDelay; | 1537 WebRtcAec_PartitionDelay = PartitionDelay; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1545 RTC_AEC_DEBUG_WAV_CLOSE(aec->outFile); | 1581 RTC_AEC_DEBUG_WAV_CLOSE(aec->outFile); |
| 1546 RTC_AEC_DEBUG_WAV_CLOSE(aec->outLinearFile); | 1582 RTC_AEC_DEBUG_WAV_CLOSE(aec->outLinearFile); |
| 1547 RTC_AEC_DEBUG_RAW_CLOSE(aec->e_fft_file); | 1583 RTC_AEC_DEBUG_RAW_CLOSE(aec->e_fft_file); |
| 1548 | 1584 |
| 1549 WebRtc_FreeDelayEstimator(aec->delay_estimator); | 1585 WebRtc_FreeDelayEstimator(aec->delay_estimator); |
| 1550 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); | 1586 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); |
| 1551 | 1587 |
| 1552 delete aec; | 1588 delete aec; |
| 1553 } | 1589 } |
| 1554 | 1590 |
| 1591 static void SetAdaptiveFilterStepSize(AecCore* aec) { |
| 1592 // Extended filter adaptation parameter. |
| 1593 // TODO(ajm): No narrowband tuning yet. |
| 1594 const float kExtendedMu = 0.4f; |
| 1595 |
| 1596 if (aec->refined_adaptive_filter_enabled) { |
| 1597 aec->filter_step_size = 0.05f; |
| 1598 } else { |
| 1599 if (aec->extended_filter_enabled) { |
| 1600 aec->filter_step_size = kExtendedMu; |
| 1601 } else { |
| 1602 if (aec->sampFreq == 8000) { |
| 1603 aec->filter_step_size = 0.6f; |
| 1604 } else { |
| 1605 aec->filter_step_size = 0.5f; |
| 1606 } |
| 1607 } |
| 1608 } |
| 1609 } |
| 1610 |
| 1611 static void SetErrorThreshold(AecCore* aec) { |
| 1612 // Extended filter adaptation parameter. |
| 1613 // TODO(ajm): No narrowband tuning yet. |
| 1614 static const float kExtendedErrorThreshold = 1.0e-6f; |
| 1615 |
| 1616 if (aec->extended_filter_enabled) { |
| 1617 aec->error_threshold = kExtendedErrorThreshold; |
| 1618 } else { |
| 1619 if (aec->sampFreq == 8000) { |
| 1620 aec->error_threshold = 2e-6f; |
| 1621 } else { |
| 1622 aec->error_threshold = 1.5e-6f; |
| 1623 } |
| 1624 } |
| 1625 } |
| 1626 |
| 1555 int WebRtcAec_InitAec(AecCore* aec, int sampFreq) { | 1627 int WebRtcAec_InitAec(AecCore* aec, int sampFreq) { |
| 1556 int i; | 1628 int i; |
| 1557 | 1629 |
| 1558 aec->sampFreq = sampFreq; | 1630 aec->sampFreq = sampFreq; |
| 1559 | 1631 |
| 1632 SetAdaptiveFilterStepSize(aec); |
| 1633 SetErrorThreshold(aec); |
| 1634 |
| 1560 if (sampFreq == 8000) { | 1635 if (sampFreq == 8000) { |
| 1561 aec->normal_mu = 0.6f; | |
| 1562 aec->normal_error_threshold = 2e-6f; | |
| 1563 aec->num_bands = 1; | 1636 aec->num_bands = 1; |
| 1564 } else { | 1637 } else { |
| 1565 aec->normal_mu = 0.5f; | |
| 1566 aec->normal_error_threshold = 1.5e-6f; | |
| 1567 aec->num_bands = (size_t)(sampFreq / 16000); | 1638 aec->num_bands = (size_t)(sampFreq / 16000); |
| 1568 } | 1639 } |
| 1569 | 1640 |
| 1570 WebRtc_InitBuffer(aec->nearFrBuf); | 1641 WebRtc_InitBuffer(aec->nearFrBuf); |
| 1571 WebRtc_InitBuffer(aec->outFrBuf); | 1642 WebRtc_InitBuffer(aec->outFrBuf); |
| 1572 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1643 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
| 1573 WebRtc_InitBuffer(aec->nearFrBufH[i]); | 1644 WebRtc_InitBuffer(aec->nearFrBufH[i]); |
| 1574 WebRtc_InitBuffer(aec->outFrBufH[i]); | 1645 WebRtc_InitBuffer(aec->outFrBufH[i]); |
| 1575 } | 1646 } |
| 1576 | 1647 |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1927 | 1998 |
| 1928 void WebRtcAec_enable_aec3(AecCore* self, int enable) { | 1999 void WebRtcAec_enable_aec3(AecCore* self, int enable) { |
| 1929 self->aec3_enabled = (enable != 0); | 2000 self->aec3_enabled = (enable != 0); |
| 1930 } | 2001 } |
| 1931 | 2002 |
| 1932 int WebRtcAec_aec3_enabled(AecCore* self) { | 2003 int WebRtcAec_aec3_enabled(AecCore* self) { |
| 1933 assert(self->aec3_enabled == 0 || self->aec3_enabled == 1); | 2004 assert(self->aec3_enabled == 0 || self->aec3_enabled == 1); |
| 1934 return self->aec3_enabled; | 2005 return self->aec3_enabled; |
| 1935 } | 2006 } |
| 1936 | 2007 |
| 2008 void WebRtcAec_enable_refined_adaptive_filter(AecCore* self, bool enable) { |
| 2009 self->refined_adaptive_filter_enabled = enable; |
| 2010 SetAdaptiveFilterStepSize(self); |
| 2011 SetErrorThreshold(self); |
| 2012 } |
| 2013 |
| 2014 bool WebRtcAec_refined_adaptive_filter_enabled(const AecCore* self) { |
| 2015 return self->refined_adaptive_filter_enabled; |
| 2016 } |
| 1937 | 2017 |
| 1938 void WebRtcAec_enable_extended_filter(AecCore* self, int enable) { | 2018 void WebRtcAec_enable_extended_filter(AecCore* self, int enable) { |
| 1939 self->extended_filter_enabled = enable; | 2019 self->extended_filter_enabled = enable; |
| 2020 SetAdaptiveFilterStepSize(self); |
| 2021 SetErrorThreshold(self); |
| 1940 self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions; | 2022 self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions; |
| 1941 // Update the delay estimator with filter length. See InitAEC() for details. | 2023 // Update the delay estimator with filter length. See InitAEC() for details. |
| 1942 WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2); | 2024 WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2); |
| 1943 } | 2025 } |
| 1944 | 2026 |
| 1945 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 2027 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
| 1946 return self->extended_filter_enabled; | 2028 return self->extended_filter_enabled; |
| 1947 } | 2029 } |
| 1948 | 2030 |
| 1949 int WebRtcAec_system_delay(AecCore* self) { | 2031 int WebRtcAec_system_delay(AecCore* self) { |
| 1950 return self->system_delay; | 2032 return self->system_delay; |
| 1951 } | 2033 } |
| 1952 | 2034 |
| 1953 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 2035 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
| 1954 assert(delay >= 0); | 2036 assert(delay >= 0); |
| 1955 self->system_delay = delay; | 2037 self->system_delay = delay; |
| 1956 } | 2038 } |
| 1957 } // namespace webrtc | 2039 } // namespace webrtc |
| OLD | NEW |