| 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 <assert.h> | 21 #include <assert.h> |
| 22 #include <math.h> | 22 #include <math.h> |
| 23 #include <stddef.h> // size_t | 23 #include <stddef.h> // size_t |
| 24 #include <stdlib.h> | 24 #include <stdlib.h> |
| 25 #include <string.h> | 25 #include <string.h> |
| 26 | 26 |
| 27 #include "webrtc/base/checks.h" |
| 27 extern "C" { | 28 extern "C" { |
| 28 #include "webrtc/common_audio/ring_buffer.h" | 29 #include "webrtc/common_audio/ring_buffer.h" |
| 29 } | 30 } |
| 30 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar
y.h" | 31 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar
y.h" |
| 31 #include "webrtc/modules/audio_processing/aec/aec_common.h" | 32 #include "webrtc/modules/audio_processing/aec/aec_common.h" |
| 32 #include "webrtc/modules/audio_processing/aec/aec_core_internal.h" | 33 #include "webrtc/modules/audio_processing/aec/aec_core_internal.h" |
| 33 extern "C" { | 34 extern "C" { |
| 34 #include "webrtc/modules/audio_processing/aec/aec_rdft.h" | 35 #include "webrtc/modules/audio_processing/aec/aec_rdft.h" |
| 35 } | 36 } |
| 36 #include "webrtc/modules/audio_processing/logging/aec_logging.h" | 37 #include "webrtc/modules/audio_processing/logging/aec_logging.h" |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 | 173 |
| 173 for (j = 0; j < PART_LEN1; j++) { | 174 for (j = 0; j < PART_LEN1; j++) { |
| 174 y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j], | 175 y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j], |
| 175 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]); | 176 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]); |
| 176 y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j], | 177 y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j], |
| 177 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]); | 178 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]); |
| 178 } | 179 } |
| 179 } | 180 } |
| 180 } | 181 } |
| 181 | 182 |
| 182 static void ScaleErrorSignal(int extended_filter_enabled, | 183 static void ScaleErrorSignal(float mu, |
| 183 float normal_mu, | 184 float error_threshold, |
| 184 float normal_error_threshold, | |
| 185 float x_pow[PART_LEN1], | 185 float x_pow[PART_LEN1], |
| 186 float ef[2][PART_LEN1]) { | 186 float ef[2][PART_LEN1]) { |
| 187 const float mu = extended_filter_enabled ? kExtendedMu : normal_mu; | |
| 188 const float error_threshold = extended_filter_enabled | |
| 189 ? kExtendedErrorThreshold | |
| 190 : normal_error_threshold; | |
| 191 int i; | 187 int i; |
| 192 float abs_ef; | 188 float abs_ef; |
| 193 for (i = 0; i < (PART_LEN1); i++) { | 189 for (i = 0; i < (PART_LEN1); i++) { |
| 194 ef[0][i] /= (x_pow[i] + 1e-10f); | 190 ef[0][i] /= (x_pow[i] + 1e-10f); |
| 195 ef[1][i] /= (x_pow[i] + 1e-10f); | 191 ef[1][i] /= (x_pow[i] + 1e-10f); |
| 196 abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]); | 192 abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]); |
| 197 | 193 |
| 198 if (abs_ef > error_threshold) { | 194 if (abs_ef > error_threshold) { |
| 199 abs_ef = error_threshold / (abs_ef + 1e-10f); | 195 abs_ef = error_threshold / (abs_ef + 1e-10f); |
| 200 ef[0][i] *= abs_ef; | 196 ef[0][i] *= abs_ef; |
| (...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 (delay_quality > kDelayQualityThresholdMax ? kDelayQualityThresholdMax | 879 (delay_quality > kDelayQualityThresholdMax ? kDelayQualityThresholdMax |
| 884 : delay_quality); | 880 : delay_quality); |
| 885 self->delay_quality_threshold = | 881 self->delay_quality_threshold = |
| 886 (delay_quality > self->delay_quality_threshold | 882 (delay_quality > self->delay_quality_threshold |
| 887 ? delay_quality | 883 ? delay_quality |
| 888 : self->delay_quality_threshold); | 884 : self->delay_quality_threshold); |
| 889 } | 885 } |
| 890 return delay_correction; | 886 return delay_correction; |
| 891 } | 887 } |
| 892 | 888 |
| 889 static void RegressorPower(int num_partitions, |
| 890 int latest_added_partition, |
| 891 float x_fft_buf[2] |
| 892 [kExtendedNumPartitions * PART_LEN1], |
| 893 float x_pow[PART_LEN1]) { |
| 894 RTC_DCHECK_LT(latest_added_partition, num_partitions); |
| 895 memset(x_pow, 0, PART_LEN1 * sizeof(x_pow[0])); |
| 896 |
| 897 int partition = latest_added_partition; |
| 898 int x_fft_buf_position = partition * PART_LEN1; |
| 899 for (int i = 0; i < num_partitions; ++i) { |
| 900 for (int bin = 0; bin < PART_LEN1; ++bin) { |
| 901 float re = x_fft_buf[0][x_fft_buf_position]; |
| 902 float im = x_fft_buf[1][x_fft_buf_position]; |
| 903 x_pow[bin] += re * re + im * im; |
| 904 ++x_fft_buf_position; |
| 905 } |
| 906 |
| 907 ++partition; |
| 908 if (partition == num_partitions) { |
| 909 partition = 0; |
| 910 RTC_DCHECK_EQ(num_partitions * PART_LEN1, x_fft_buf_position); |
| 911 x_fft_buf_position = 0; |
| 912 } |
| 913 } |
| 914 } |
| 915 |
| 893 static void EchoSubtraction(AecCore* aec, | 916 static void EchoSubtraction(AecCore* aec, |
| 894 int num_partitions, | 917 int num_partitions, |
| 895 int extended_filter_enabled, | 918 int extended_filter_enabled, |
| 896 float normal_mu, | 919 float filter_step_size, |
| 897 float normal_error_threshold, | 920 float error_threshold, |
| 898 float* x_fft, | 921 float* x_fft, |
| 899 int* x_fft_buf_block_pos, | 922 int* x_fft_buf_block_pos, |
| 900 float x_fft_buf[2] | 923 float x_fft_buf[2] |
| 901 [kExtendedNumPartitions * PART_LEN1], | 924 [kExtendedNumPartitions * PART_LEN1], |
| 902 float* const y, | 925 float* const y, |
| 903 float x_pow[PART_LEN1], | 926 float x_pow[PART_LEN1], |
| 904 float h_fft_buf[2] | 927 float h_fft_buf[2] |
| 905 [kExtendedNumPartitions * PART_LEN1], | 928 [kExtendedNumPartitions * PART_LEN1], |
| 906 float echo_subtractor_output[PART_LEN]) { | 929 float echo_subtractor_output[PART_LEN]) { |
| 907 float s_fft[2][PART_LEN1]; | 930 float s_fft[2][PART_LEN1]; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 | 971 |
| 949 // Compute the frequency domain echo prediction error. | 972 // Compute the frequency domain echo prediction error. |
| 950 memset(e_extended, 0, sizeof(float) * PART_LEN); | 973 memset(e_extended, 0, sizeof(float) * PART_LEN); |
| 951 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); | 974 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); |
| 952 Fft(e_extended, e_fft); | 975 Fft(e_extended, e_fft); |
| 953 | 976 |
| 954 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, &e_fft[0][0], | 977 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, &e_fft[0][0], |
| 955 sizeof(e_fft[0][0]) * PART_LEN1 * 2); | 978 sizeof(e_fft[0][0]) * PART_LEN1 * 2); |
| 956 | 979 |
| 957 // Scale error signal inversely with far power. | 980 // Scale error signal inversely with far power. |
| 958 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, normal_mu, | 981 WebRtcAec_ScaleErrorSignal(filter_step_size, error_threshold, x_pow, e_fft); |
| 959 normal_error_threshold, x_pow, e_fft); | |
| 960 WebRtcAec_FilterAdaptation(num_partitions, *x_fft_buf_block_pos, x_fft_buf, | 982 WebRtcAec_FilterAdaptation(num_partitions, *x_fft_buf_block_pos, x_fft_buf, |
| 961 e_fft, h_fft_buf); | 983 e_fft, h_fft_buf); |
| 962 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); | 984 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); |
| 963 } | 985 } |
| 964 | 986 |
| 965 static void EchoSuppression(AecCore* aec, | 987 static void EchoSuppression(AecCore* aec, |
| 966 float farend[PART_LEN2], | 988 float farend[PART_LEN2], |
| 967 float* echo_subtractor_output, | 989 float* echo_subtractor_output, |
| 968 float* output, | 990 float* output, |
| 969 float* const* outputH) { | 991 float* const* outputH) { |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1272 | 1294 |
| 1273 // Convert far-end signal to the frequency domain. | 1295 // Convert far-end signal to the frequency domain. |
| 1274 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); | 1296 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); |
| 1275 Fft(fft, x_fft); | 1297 Fft(fft, x_fft); |
| 1276 x_fft_ptr = &x_fft[0][0]; | 1298 x_fft_ptr = &x_fft[0][0]; |
| 1277 | 1299 |
| 1278 // Near fft | 1300 // Near fft |
| 1279 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); | 1301 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); |
| 1280 Fft(fft, df); | 1302 Fft(fft, df); |
| 1281 | 1303 |
| 1282 // Power smoothing | 1304 // Power smoothing. |
| 1283 for (i = 0; i < PART_LEN1; i++) { | 1305 if (aec->refined_adaptive_filter_enabled) { |
| 1284 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + | 1306 for (i = 0; i < PART_LEN1; ++i) { |
| 1285 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); | 1307 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + |
| 1286 aec->xPow[i] = | 1308 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); |
| 1287 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; | 1309 // Calculate the magnitude spectrum. |
| 1288 // Calculate absolute spectra | 1310 abs_far_spectrum[i] = sqrtf(far_spectrum); |
| 1289 abs_far_spectrum[i] = sqrtf(far_spectrum); | 1311 } |
| 1312 RegressorPower(aec->num_partitions, aec->xfBufBlockPos, aec->xfBuf, |
| 1313 aec->xPow); |
| 1314 } else { |
| 1315 for (i = 0; i < PART_LEN1; ++i) { |
| 1316 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + |
| 1317 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); |
| 1318 aec->xPow[i] = |
| 1319 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; |
| 1320 // Calculate the magnitude spectrum. |
| 1321 abs_far_spectrum[i] = sqrtf(far_spectrum); |
| 1322 } |
| 1323 } |
| 1290 | 1324 |
| 1325 for (i = 0; i < PART_LEN1; ++i) { |
| 1291 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i]; | 1326 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i]; |
| 1292 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum; | 1327 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum; |
| 1293 // Calculate absolute spectra | 1328 // Calculate the magnitude spectrum. |
| 1294 abs_near_spectrum[i] = sqrtf(near_spectrum); | 1329 abs_near_spectrum[i] = sqrtf(near_spectrum); |
| 1295 } | 1330 } |
| 1296 | 1331 |
| 1297 // Estimate noise power. Wait until dPow is more stable. | 1332 // Estimate noise power. Wait until dPow is more stable. |
| 1298 if (aec->noiseEstCtr > 50) { | 1333 if (aec->noiseEstCtr > 50) { |
| 1299 for (i = 0; i < PART_LEN1; i++) { | 1334 for (i = 0; i < PART_LEN1; i++) { |
| 1300 if (aec->dPow[i] < aec->dMinPow[i]) { | 1335 if (aec->dPow[i] < aec->dMinPow[i]) { |
| 1301 aec->dMinPow[i] = | 1336 aec->dMinPow[i] = |
| 1302 (aec->dPow[i] + step * (aec->dMinPow[i] - aec->dPow[i])) * ramp; | 1337 (aec->dPow[i] + step * (aec->dMinPow[i] - aec->dPow[i])) * ramp; |
| 1303 } else { | 1338 } else { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1336 } | 1371 } |
| 1337 if (aec->delay_metrics_delivered == 1 && | 1372 if (aec->delay_metrics_delivered == 1 && |
| 1338 aec->num_delay_values >= kDelayMetricsAggregationWindow) { | 1373 aec->num_delay_values >= kDelayMetricsAggregationWindow) { |
| 1339 UpdateDelayMetrics(aec); | 1374 UpdateDelayMetrics(aec); |
| 1340 } | 1375 } |
| 1341 } | 1376 } |
| 1342 } | 1377 } |
| 1343 | 1378 |
| 1344 // Perform echo subtraction. | 1379 // Perform echo subtraction. |
| 1345 EchoSubtraction(aec, aec->num_partitions, aec->extended_filter_enabled, | 1380 EchoSubtraction(aec, aec->num_partitions, aec->extended_filter_enabled, |
| 1346 aec->normal_mu, aec->normal_error_threshold, &x_fft[0][0], | 1381 aec->filter_step_size, aec->error_threshold, &x_fft[0][0], |
| 1347 &aec->xfBufBlockPos, aec->xfBuf, nearend_ptr, aec->xPow, | 1382 &aec->xfBufBlockPos, aec->xfBuf, nearend_ptr, aec->xPow, |
| 1348 aec->wfBuf, echo_subtractor_output); | 1383 aec->wfBuf, echo_subtractor_output); |
| 1349 | 1384 |
| 1350 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); | 1385 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); |
| 1351 | 1386 |
| 1352 if (aec->metricsMode == 1) { | 1387 if (aec->metricsMode == 1) { |
| 1353 UpdateLevel(&aec->linoutlevel, | 1388 UpdateLevel(&aec->linoutlevel, |
| 1354 CalculatePower(echo_subtractor_output, PART_LEN)); | 1389 CalculatePower(echo_subtractor_output, PART_LEN)); |
| 1355 } | 1390 } |
| 1356 | 1391 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1441 aec->delay_agnostic_enabled = 1; // DA-AEC enabled by default. | 1476 aec->delay_agnostic_enabled = 1; // DA-AEC enabled by default. |
| 1442 // DA-AEC assumes the system is causal from the beginning and will self adjust | 1477 // DA-AEC assumes the system is causal from the beginning and will self adjust |
| 1443 // the lookahead when shifting is required. | 1478 // the lookahead when shifting is required. |
| 1444 WebRtc_set_lookahead(aec->delay_estimator, 0); | 1479 WebRtc_set_lookahead(aec->delay_estimator, 0); |
| 1445 #else | 1480 #else |
| 1446 aec->delay_agnostic_enabled = 0; | 1481 aec->delay_agnostic_enabled = 0; |
| 1447 WebRtc_set_lookahead(aec->delay_estimator, kLookaheadBlocks); | 1482 WebRtc_set_lookahead(aec->delay_estimator, kLookaheadBlocks); |
| 1448 #endif | 1483 #endif |
| 1449 aec->extended_filter_enabled = 0; | 1484 aec->extended_filter_enabled = 0; |
| 1450 aec->next_generation_aec_enabled = 0; | 1485 aec->next_generation_aec_enabled = 0; |
| 1486 aec->refined_adaptive_filter_enabled = 0; |
| 1451 | 1487 |
| 1452 // Assembly optimization | 1488 // Assembly optimization |
| 1453 WebRtcAec_FilterFar = FilterFar; | 1489 WebRtcAec_FilterFar = FilterFar; |
| 1454 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; | 1490 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; |
| 1455 WebRtcAec_FilterAdaptation = FilterAdaptation; | 1491 WebRtcAec_FilterAdaptation = FilterAdaptation; |
| 1456 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; | 1492 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; |
| 1457 WebRtcAec_ComfortNoise = ComfortNoise; | 1493 WebRtcAec_ComfortNoise = ComfortNoise; |
| 1458 WebRtcAec_SubbandCoherence = SubbandCoherence; | 1494 WebRtcAec_SubbandCoherence = SubbandCoherence; |
| 1459 WebRtcAec_StoreAsComplex = StoreAsComplex; | 1495 WebRtcAec_StoreAsComplex = StoreAsComplex; |
| 1460 WebRtcAec_PartitionDelay = PartitionDelay; | 1496 WebRtcAec_PartitionDelay = PartitionDelay; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 RTC_AEC_DEBUG_WAV_CLOSE(aec->outFile); | 1540 RTC_AEC_DEBUG_WAV_CLOSE(aec->outFile); |
| 1505 RTC_AEC_DEBUG_WAV_CLOSE(aec->outLinearFile); | 1541 RTC_AEC_DEBUG_WAV_CLOSE(aec->outLinearFile); |
| 1506 RTC_AEC_DEBUG_RAW_CLOSE(aec->e_fft_file); | 1542 RTC_AEC_DEBUG_RAW_CLOSE(aec->e_fft_file); |
| 1507 | 1543 |
| 1508 WebRtc_FreeDelayEstimator(aec->delay_estimator); | 1544 WebRtc_FreeDelayEstimator(aec->delay_estimator); |
| 1509 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); | 1545 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); |
| 1510 | 1546 |
| 1511 free(aec); | 1547 free(aec); |
| 1512 } | 1548 } |
| 1513 | 1549 |
| 1550 static void SetAdaptiveFilterStepSize(AecCore* aec) { |
| 1551 // Extended filter adaptation parameter. |
| 1552 // TODO(ajm): No narrowband tuning yet. |
| 1553 const float kExtendedMu = 0.4f; |
| 1554 |
| 1555 if (aec->refined_adaptive_filter_enabled) { |
| 1556 aec->filter_step_size = 0.05f; |
| 1557 } else { |
| 1558 if (aec->extended_filter_enabled) { |
| 1559 aec->filter_step_size = kExtendedMu; |
| 1560 } else { |
| 1561 if (aec->sampFreq == 8000) { |
| 1562 aec->filter_step_size = 0.6f; |
| 1563 } else { |
| 1564 aec->filter_step_size = 0.5f; |
| 1565 } |
| 1566 } |
| 1567 } |
| 1568 } |
| 1569 |
| 1570 static void SetErrorThreshold(AecCore* aec) { |
| 1571 // Extended filter adaptation parameter. |
| 1572 // TODO(ajm): No narrowband tuning yet. |
| 1573 static const float kExtendedErrorThreshold = 1.0e-6f; |
| 1574 |
| 1575 if (aec->extended_filter_enabled) { |
| 1576 aec->error_threshold = kExtendedErrorThreshold; |
| 1577 } else { |
| 1578 if (aec->sampFreq == 8000) { |
| 1579 aec->error_threshold = 2e-6f; |
| 1580 } else { |
| 1581 aec->error_threshold = 1.5e-6f; |
| 1582 } |
| 1583 } |
| 1584 } |
| 1585 |
| 1514 int WebRtcAec_InitAec(AecCore* aec, int sampFreq) { | 1586 int WebRtcAec_InitAec(AecCore* aec, int sampFreq) { |
| 1515 int i; | 1587 int i; |
| 1516 | 1588 |
| 1517 aec->sampFreq = sampFreq; | 1589 aec->sampFreq = sampFreq; |
| 1518 | 1590 |
| 1591 SetAdaptiveFilterStepSize(aec); |
| 1592 SetErrorThreshold(aec); |
| 1593 |
| 1519 if (sampFreq == 8000) { | 1594 if (sampFreq == 8000) { |
| 1520 aec->normal_mu = 0.6f; | |
| 1521 aec->normal_error_threshold = 2e-6f; | |
| 1522 aec->num_bands = 1; | 1595 aec->num_bands = 1; |
| 1523 } else { | 1596 } else { |
| 1524 aec->normal_mu = 0.5f; | |
| 1525 aec->normal_error_threshold = 1.5e-6f; | |
| 1526 aec->num_bands = (size_t)(sampFreq / 16000); | 1597 aec->num_bands = (size_t)(sampFreq / 16000); |
| 1527 } | 1598 } |
| 1528 | 1599 |
| 1529 WebRtc_InitBuffer(aec->nearFrBuf); | 1600 WebRtc_InitBuffer(aec->nearFrBuf); |
| 1530 WebRtc_InitBuffer(aec->outFrBuf); | 1601 WebRtc_InitBuffer(aec->outFrBuf); |
| 1531 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1602 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
| 1532 WebRtc_InitBuffer(aec->nearFrBufH[i]); | 1603 WebRtc_InitBuffer(aec->nearFrBufH[i]); |
| 1533 WebRtc_InitBuffer(aec->outFrBufH[i]); | 1604 WebRtc_InitBuffer(aec->outFrBufH[i]); |
| 1534 } | 1605 } |
| 1535 | 1606 |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1884 void WebRtcAec_enable_next_generation_aec(AecCore* self, int enable) { | 1955 void WebRtcAec_enable_next_generation_aec(AecCore* self, int enable) { |
| 1885 self->next_generation_aec_enabled = (enable != 0); | 1956 self->next_generation_aec_enabled = (enable != 0); |
| 1886 } | 1957 } |
| 1887 | 1958 |
| 1888 int WebRtcAec_next_generation_aec_enabled(AecCore* self) { | 1959 int WebRtcAec_next_generation_aec_enabled(AecCore* self) { |
| 1889 assert(self->next_generation_aec_enabled == 0 || | 1960 assert(self->next_generation_aec_enabled == 0 || |
| 1890 self->next_generation_aec_enabled == 1); | 1961 self->next_generation_aec_enabled == 1); |
| 1891 return self->next_generation_aec_enabled; | 1962 return self->next_generation_aec_enabled; |
| 1892 } | 1963 } |
| 1893 | 1964 |
| 1965 void WebRtcAec_enable_refined_adaptive_filter(AecCore* self, int enable) { |
| 1966 self->refined_adaptive_filter_enabled = (enable != 0); |
| 1967 SetAdaptiveFilterStepSize(self); |
| 1968 SetErrorThreshold(self); |
| 1969 } |
| 1970 |
| 1971 int WebRtcAec_refined_adaptive_filter_enabled(const AecCore* self) { |
| 1972 assert(self->refined_adaptive_filter_enabled == 0 || |
| 1973 self->refined_adaptive_filter_enabled == 1); |
| 1974 return self->refined_adaptive_filter_enabled; |
| 1975 } |
| 1894 | 1976 |
| 1895 void WebRtcAec_enable_extended_filter(AecCore* self, int enable) { | 1977 void WebRtcAec_enable_extended_filter(AecCore* self, int enable) { |
| 1896 self->extended_filter_enabled = enable; | 1978 self->extended_filter_enabled = enable; |
| 1979 SetAdaptiveFilterStepSize(self); |
| 1980 SetErrorThreshold(self); |
| 1897 self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions; | 1981 self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions; |
| 1898 // Update the delay estimator with filter length. See InitAEC() for details. | 1982 // Update the delay estimator with filter length. See InitAEC() for details. |
| 1899 WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2); | 1983 WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2); |
| 1900 } | 1984 } |
| 1901 | 1985 |
| 1902 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 1986 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
| 1903 return self->extended_filter_enabled; | 1987 return self->extended_filter_enabled; |
| 1904 } | 1988 } |
| 1905 | 1989 |
| 1906 int WebRtcAec_system_delay(AecCore* self) { | 1990 int WebRtcAec_system_delay(AecCore* self) { |
| 1907 return self->system_delay; | 1991 return self->system_delay; |
| 1908 } | 1992 } |
| 1909 | 1993 |
| 1910 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1994 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
| 1911 assert(delay >= 0); | 1995 assert(delay >= 0); |
| 1912 self->system_delay = delay; | 1996 self->system_delay = delay; |
| 1913 } | 1997 } |
| OLD | NEW |