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 #include "webrtc/modules/audio_processing/aec/aec_rdft.h" | 35 #include "webrtc/modules/audio_processing/aec/aec_rdft.h" |
35 #include "webrtc/modules/audio_processing/logging/aec_logging.h" | 36 #include "webrtc/modules/audio_processing/logging/aec_logging.h" |
36 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h" | 37 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h" |
37 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" | 38 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
231 | 232 |
232 for (j = 0; j < PART_LEN1; j++) { | 233 for (j = 0; j < PART_LEN1; j++) { |
233 y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j], | 234 y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j], |
234 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]); | 235 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]); |
235 y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j], | 236 y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j], |
236 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]); | 237 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]); |
237 } | 238 } |
238 } | 239 } |
239 } | 240 } |
240 | 241 |
241 static void ScaleErrorSignal(int extended_filter_enabled, | 242 static void ScaleErrorSignal(float mu, |
242 float normal_mu, | 243 float error_threshold, |
243 float normal_error_threshold, | |
244 float x_pow[PART_LEN1], | 244 float x_pow[PART_LEN1], |
245 float ef[2][PART_LEN1]) { | 245 float ef[2][PART_LEN1]) { |
246 const float mu = extended_filter_enabled ? kExtendedMu : normal_mu; | |
247 const float error_threshold = extended_filter_enabled | |
248 ? kExtendedErrorThreshold | |
249 : normal_error_threshold; | |
250 int i; | 246 int i; |
251 float abs_ef; | 247 float abs_ef; |
252 for (i = 0; i < (PART_LEN1); i++) { | 248 for (i = 0; i < (PART_LEN1); i++) { |
253 ef[0][i] /= (x_pow[i] + 1e-10f); | 249 ef[0][i] /= (x_pow[i] + 1e-10f); |
254 ef[1][i] /= (x_pow[i] + 1e-10f); | 250 ef[1][i] /= (x_pow[i] + 1e-10f); |
255 abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]); | 251 abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]); |
256 | 252 |
257 if (abs_ef > error_threshold) { | 253 if (abs_ef > error_threshold) { |
258 abs_ef = error_threshold / (abs_ef + 1e-10f); | 254 abs_ef = error_threshold / (abs_ef + 1e-10f); |
259 ef[0][i] *= abs_ef; | 255 ef[0][i] *= abs_ef; |
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
929 (delay_quality > kDelayQualityThresholdMax ? kDelayQualityThresholdMax | 925 (delay_quality > kDelayQualityThresholdMax ? kDelayQualityThresholdMax |
930 : delay_quality); | 926 : delay_quality); |
931 self->delay_quality_threshold = | 927 self->delay_quality_threshold = |
932 (delay_quality > self->delay_quality_threshold | 928 (delay_quality > self->delay_quality_threshold |
933 ? delay_quality | 929 ? delay_quality |
934 : self->delay_quality_threshold); | 930 : self->delay_quality_threshold); |
935 } | 931 } |
936 return delay_correction; | 932 return delay_correction; |
937 } | 933 } |
938 | 934 |
935 static void RegressorPower(int num_partitions, | |
936 int latest_added_partition, | |
937 float x_fft_buf[2] | |
938 [kExtendedNumPartitions * PART_LEN1], | |
939 float x_pow[PART_LEN1]) { | |
940 RTC_DCHECK_LT(latest_added_partition, num_partitions); | |
941 memset(x_pow, 0, PART_LEN1 * sizeof(x_pow[0])); | |
942 | |
943 int partition = latest_added_partition; | |
944 int x_fft_buf_position = partition * PART_LEN1; | |
945 for (int i = 0; i < num_partitions; ++i) { | |
946 for (int bin = 0; bin < PART_LEN1; ++bin) { | |
947 float re = x_fft_buf[0][x_fft_buf_position]; | |
948 float im = x_fft_buf[1][x_fft_buf_position]; | |
949 x_pow[bin] += re * re + im * im; | |
950 ++x_fft_buf_position; | |
951 } | |
952 | |
953 ++partition; | |
954 if (partition == num_partitions) { | |
955 partition = 0; | |
956 RTC_DCHECK_EQ(num_partitions * PART_LEN1, x_fft_buf_position); | |
957 x_fft_buf_position = 0; | |
958 } | |
959 } | |
960 } | |
961 | |
939 static void EchoSubtraction(AecCore* aec, | 962 static void EchoSubtraction(AecCore* aec, |
940 int num_partitions, | 963 int num_partitions, |
941 int extended_filter_enabled, | 964 int extended_filter_enabled, |
hlundin-webrtc
2016/04/15 06:39:23
Now this is unused...
peah-webrtc
2016/04/15 06:53:26
Acknowledged.
| |
942 float normal_mu, | 965 float filter_step_size, |
943 float normal_error_threshold, | 966 float error_threshold, |
944 float* x_fft, | 967 float* x_fft, |
945 int* x_fft_buf_block_pos, | 968 int* x_fft_buf_block_pos, |
946 float x_fft_buf[2] | 969 float x_fft_buf[2] |
947 [kExtendedNumPartitions * PART_LEN1], | 970 [kExtendedNumPartitions * PART_LEN1], |
948 float* const y, | 971 float* const y, |
949 float x_pow[PART_LEN1], | 972 float x_pow[PART_LEN1], |
950 float h_fft_buf[2] | 973 float h_fft_buf[2] |
951 [kExtendedNumPartitions * PART_LEN1], | 974 [kExtendedNumPartitions * PART_LEN1], |
952 float echo_subtractor_output[PART_LEN]) { | 975 float echo_subtractor_output[PART_LEN]) { |
953 float s_fft[2][PART_LEN1]; | 976 float s_fft[2][PART_LEN1]; |
(...skipping 13 matching lines...) Expand all Loading... | |
967 // Buffer x_fft. | 990 // Buffer x_fft. |
968 memcpy(x_fft_buf[0] + (*x_fft_buf_block_pos) * PART_LEN1, x_fft, | 991 memcpy(x_fft_buf[0] + (*x_fft_buf_block_pos) * PART_LEN1, x_fft, |
969 sizeof(float) * PART_LEN1); | 992 sizeof(float) * PART_LEN1); |
970 memcpy(x_fft_buf[1] + (*x_fft_buf_block_pos) * PART_LEN1, &x_fft[PART_LEN1], | 993 memcpy(x_fft_buf[1] + (*x_fft_buf_block_pos) * PART_LEN1, &x_fft[PART_LEN1], |
971 sizeof(float) * PART_LEN1); | 994 sizeof(float) * PART_LEN1); |
972 | 995 |
973 memset(s_fft, 0, sizeof(s_fft)); | 996 memset(s_fft, 0, sizeof(s_fft)); |
974 | 997 |
975 // Conditionally reset the echo subtraction filter if the filter has diverged | 998 // Conditionally reset the echo subtraction filter if the filter has diverged |
976 // significantly. | 999 // significantly. |
977 if (!aec->extended_filter_enabled && aec->extreme_filter_divergence) { | 1000 if (!aec->extended_filter_enabled && aec->extreme_filter_divergence) { |
hlundin-webrtc
2016/04/15 06:39:24
... since you are getting the value from the aec s
peah-webrtc
2016/04/15 06:53:25
True! Good find! After offline discussions, we've
| |
978 memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); | 1001 memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); |
979 aec->extreme_filter_divergence = 0; | 1002 aec->extreme_filter_divergence = 0; |
980 } | 1003 } |
981 | 1004 |
982 // Produce echo estimate s_fft. | 1005 // Produce echo estimate s_fft. |
983 WebRtcAec_FilterFar(num_partitions, *x_fft_buf_block_pos, x_fft_buf, | 1006 WebRtcAec_FilterFar(num_partitions, *x_fft_buf_block_pos, x_fft_buf, |
984 h_fft_buf, s_fft); | 1007 h_fft_buf, s_fft); |
985 | 1008 |
986 // Compute the time-domain echo estimate s. | 1009 // Compute the time-domain echo estimate s. |
987 ScaledInverseFft(s_fft, s_extended, 2.0f, 0); | 1010 ScaledInverseFft(s_fft, s_extended, 2.0f, 0); |
988 s = &s_extended[PART_LEN]; | 1011 s = &s_extended[PART_LEN]; |
989 | 1012 |
990 // Compute the time-domain echo prediction error. | 1013 // Compute the time-domain echo prediction error. |
991 for (i = 0; i < PART_LEN; ++i) { | 1014 for (i = 0; i < PART_LEN; ++i) { |
992 e[i] = y[i] - s[i]; | 1015 e[i] = y[i] - s[i]; |
993 } | 1016 } |
994 | 1017 |
995 // Compute the frequency domain echo prediction error. | 1018 // Compute the frequency domain echo prediction error. |
996 memset(e_extended, 0, sizeof(float) * PART_LEN); | 1019 memset(e_extended, 0, sizeof(float) * PART_LEN); |
997 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); | 1020 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); |
998 Fft(e_extended, e_fft); | 1021 Fft(e_extended, e_fft); |
999 | 1022 |
1000 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, &e_fft[0][0], | 1023 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, &e_fft[0][0], |
1001 sizeof(e_fft[0][0]) * PART_LEN1 * 2); | 1024 sizeof(e_fft[0][0]) * PART_LEN1 * 2); |
1002 | 1025 |
1003 // Scale error signal inversely with far power. | 1026 // Scale error signal inversely with far power. |
1004 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, normal_mu, | 1027 WebRtcAec_ScaleErrorSignal(filter_step_size, error_threshold, x_pow, e_fft); |
1005 normal_error_threshold, x_pow, e_fft); | |
1006 WebRtcAec_FilterAdaptation(num_partitions, *x_fft_buf_block_pos, x_fft_buf, | 1028 WebRtcAec_FilterAdaptation(num_partitions, *x_fft_buf_block_pos, x_fft_buf, |
1007 e_fft, h_fft_buf); | 1029 e_fft, h_fft_buf); |
1008 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); | 1030 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); |
1009 } | 1031 } |
1010 | 1032 |
1011 static void EchoSuppression(AecCore* aec, | 1033 static void EchoSuppression(AecCore* aec, |
1012 float farend[PART_LEN2], | 1034 float farend[PART_LEN2], |
1013 float* echo_subtractor_output, | 1035 float* echo_subtractor_output, |
1014 float* output, | 1036 float* output, |
1015 float* const* outputH) { | 1037 float* const* outputH) { |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1309 // Convert far-end signal to the frequency domain. | 1331 // Convert far-end signal to the frequency domain. |
1310 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); | 1332 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); |
1311 Fft(fft, x_fft); | 1333 Fft(fft, x_fft); |
1312 x_fft_ptr = &x_fft[0][0]; | 1334 x_fft_ptr = &x_fft[0][0]; |
1313 | 1335 |
1314 // Near fft | 1336 // Near fft |
1315 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); | 1337 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); |
1316 Fft(fft, df); | 1338 Fft(fft, df); |
1317 | 1339 |
1318 // Power smoothing | 1340 // Power smoothing |
1319 for (i = 0; i < PART_LEN1; i++) { | 1341 if (aec->refined_adaptive_filter_enabled) { |
1320 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + | 1342 for (i = 0; i < PART_LEN1; ++i) { |
1321 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); | 1343 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + |
1322 aec->xPow[i] = | 1344 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); |
1323 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; | 1345 // Calculate absolute spectra |
1324 // Calculate absolute spectra | 1346 abs_far_spectrum[i] = sqrtf(far_spectrum); |
1325 abs_far_spectrum[i] = sqrtf(far_spectrum); | 1347 } |
1348 RegressorPower(aec->num_partitions, aec->xfBufBlockPos, aec->xfBuf, | |
1349 aec->xPow); | |
1350 } else { | |
1351 for (i = 0; i < PART_LEN1; ++i) { | |
1352 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + | |
1353 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); | |
1354 aec->xPow[i] = | |
1355 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; | |
1356 // Calculate absolute spectra | |
1357 abs_far_spectrum[i] = sqrtf(far_spectrum); | |
1358 } | |
1359 } | |
1326 | 1360 |
1361 for (i = 0; i < PART_LEN1; ++i) { | |
1327 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i]; | 1362 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i]; |
1328 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum; | 1363 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum; |
1329 // Calculate absolute spectra | 1364 // Calculate absolute spectra |
1330 abs_near_spectrum[i] = sqrtf(near_spectrum); | 1365 abs_near_spectrum[i] = sqrtf(near_spectrum); |
1331 } | 1366 } |
1332 | 1367 |
1333 // Estimate noise power. Wait until dPow is more stable. | 1368 // Estimate noise power. Wait until dPow is more stable. |
1334 if (aec->noiseEstCtr > 50) { | 1369 if (aec->noiseEstCtr > 50) { |
1335 for (i = 0; i < PART_LEN1; i++) { | 1370 for (i = 0; i < PART_LEN1; i++) { |
1336 if (aec->dPow[i] < aec->dMinPow[i]) { | 1371 if (aec->dPow[i] < aec->dMinPow[i]) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1372 } | 1407 } |
1373 if (aec->delay_metrics_delivered == 1 && | 1408 if (aec->delay_metrics_delivered == 1 && |
1374 aec->num_delay_values >= kDelayMetricsAggregationWindow) { | 1409 aec->num_delay_values >= kDelayMetricsAggregationWindow) { |
1375 UpdateDelayMetrics(aec); | 1410 UpdateDelayMetrics(aec); |
1376 } | 1411 } |
1377 } | 1412 } |
1378 } | 1413 } |
1379 | 1414 |
1380 // Perform echo subtraction. | 1415 // Perform echo subtraction. |
1381 EchoSubtraction(aec, aec->num_partitions, aec->extended_filter_enabled, | 1416 EchoSubtraction(aec, aec->num_partitions, aec->extended_filter_enabled, |
1382 aec->normal_mu, aec->normal_error_threshold, &x_fft[0][0], | 1417 aec->filter_step_size, aec->error_threshold, &x_fft[0][0], |
1383 &aec->xfBufBlockPos, aec->xfBuf, nearend_ptr, aec->xPow, | 1418 &aec->xfBufBlockPos, aec->xfBuf, nearend_ptr, aec->xPow, |
1384 aec->wfBuf, echo_subtractor_output); | 1419 aec->wfBuf, echo_subtractor_output); |
1385 | 1420 |
1386 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); | 1421 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); |
1387 | 1422 |
1388 if (aec->metricsMode == 1) { | 1423 if (aec->metricsMode == 1) { |
1389 UpdateLevel(&aec->linoutlevel, | 1424 UpdateLevel(&aec->linoutlevel, |
1390 CalculatePower(echo_subtractor_output, PART_LEN)); | 1425 CalculatePower(echo_subtractor_output, PART_LEN)); |
1391 } | 1426 } |
1392 | 1427 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1478 aec->delay_agnostic_enabled = 1; // DA-AEC enabled by default. | 1513 aec->delay_agnostic_enabled = 1; // DA-AEC enabled by default. |
1479 // DA-AEC assumes the system is causal from the beginning and will self adjust | 1514 // DA-AEC assumes the system is causal from the beginning and will self adjust |
1480 // the lookahead when shifting is required. | 1515 // the lookahead when shifting is required. |
1481 WebRtc_set_lookahead(aec->delay_estimator, 0); | 1516 WebRtc_set_lookahead(aec->delay_estimator, 0); |
1482 #else | 1517 #else |
1483 aec->delay_agnostic_enabled = 0; | 1518 aec->delay_agnostic_enabled = 0; |
1484 WebRtc_set_lookahead(aec->delay_estimator, kLookaheadBlocks); | 1519 WebRtc_set_lookahead(aec->delay_estimator, kLookaheadBlocks); |
1485 #endif | 1520 #endif |
1486 aec->extended_filter_enabled = 0; | 1521 aec->extended_filter_enabled = 0; |
1487 aec->aec3_enabled = 0; | 1522 aec->aec3_enabled = 0; |
1523 aec->refined_adaptive_filter_enabled = false; | |
1488 | 1524 |
1489 // Assembly optimization | 1525 // Assembly optimization |
1490 WebRtcAec_FilterFar = FilterFar; | 1526 WebRtcAec_FilterFar = FilterFar; |
1491 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; | 1527 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; |
1492 WebRtcAec_FilterAdaptation = FilterAdaptation; | 1528 WebRtcAec_FilterAdaptation = FilterAdaptation; |
1493 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; | 1529 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; |
1494 WebRtcAec_ComfortNoise = ComfortNoise; | 1530 WebRtcAec_ComfortNoise = ComfortNoise; |
1495 WebRtcAec_SubbandCoherence = SubbandCoherence; | 1531 WebRtcAec_SubbandCoherence = SubbandCoherence; |
1496 WebRtcAec_StoreAsComplex = StoreAsComplex; | 1532 WebRtcAec_StoreAsComplex = StoreAsComplex; |
1497 WebRtcAec_PartitionDelay = PartitionDelay; | 1533 WebRtcAec_PartitionDelay = PartitionDelay; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1541 RTC_AEC_DEBUG_WAV_CLOSE(aec->outFile); | 1577 RTC_AEC_DEBUG_WAV_CLOSE(aec->outFile); |
1542 RTC_AEC_DEBUG_WAV_CLOSE(aec->outLinearFile); | 1578 RTC_AEC_DEBUG_WAV_CLOSE(aec->outLinearFile); |
1543 RTC_AEC_DEBUG_RAW_CLOSE(aec->e_fft_file); | 1579 RTC_AEC_DEBUG_RAW_CLOSE(aec->e_fft_file); |
1544 | 1580 |
1545 WebRtc_FreeDelayEstimator(aec->delay_estimator); | 1581 WebRtc_FreeDelayEstimator(aec->delay_estimator); |
1546 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); | 1582 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); |
1547 | 1583 |
1548 delete aec; | 1584 delete aec; |
1549 } | 1585 } |
1550 | 1586 |
1587 static void SetAdaptiveFilterStepSize(AecCore* aec) { | |
1588 // Extended filter adaptation parameter. | |
1589 // TODO(ajm): No narrowband tuning yet. | |
1590 const float kExtendedMu = 0.4f; | |
1591 | |
1592 if (aec->refined_adaptive_filter_enabled) { | |
1593 aec->filter_step_size = 0.05f; | |
1594 } else { | |
1595 if (aec->extended_filter_enabled) { | |
1596 aec->filter_step_size = kExtendedMu; | |
1597 } else { | |
1598 if (aec->sampFreq == 8000) { | |
1599 aec->filter_step_size = 0.6f; | |
1600 } else { | |
1601 aec->filter_step_size = 0.5f; | |
1602 } | |
1603 } | |
1604 } | |
1605 } | |
1606 | |
1607 static void SetErrorThreshold(AecCore* aec) { | |
1608 // Extended filter adaptation parameter. | |
1609 // TODO(ajm): No narrowband tuning yet. | |
1610 static const float kExtendedErrorThreshold = 1.0e-6f; | |
1611 | |
1612 if (aec->extended_filter_enabled) { | |
1613 aec->error_threshold = kExtendedErrorThreshold; | |
1614 } else { | |
1615 if (aec->sampFreq == 8000) { | |
1616 aec->error_threshold = 2e-6f; | |
1617 } else { | |
1618 aec->error_threshold = 1.5e-6f; | |
1619 } | |
1620 } | |
1621 } | |
1622 | |
1551 int WebRtcAec_InitAec(AecCore* aec, int sampFreq) { | 1623 int WebRtcAec_InitAec(AecCore* aec, int sampFreq) { |
1552 int i; | 1624 int i; |
1553 | 1625 |
1554 aec->sampFreq = sampFreq; | 1626 aec->sampFreq = sampFreq; |
1555 | 1627 |
1628 SetAdaptiveFilterStepSize(aec); | |
1629 SetErrorThreshold(aec); | |
1630 | |
1556 if (sampFreq == 8000) { | 1631 if (sampFreq == 8000) { |
1557 aec->normal_mu = 0.6f; | |
1558 aec->normal_error_threshold = 2e-6f; | |
1559 aec->num_bands = 1; | 1632 aec->num_bands = 1; |
1560 } else { | 1633 } else { |
1561 aec->normal_mu = 0.5f; | |
1562 aec->normal_error_threshold = 1.5e-6f; | |
1563 aec->num_bands = (size_t)(sampFreq / 16000); | 1634 aec->num_bands = (size_t)(sampFreq / 16000); |
1564 } | 1635 } |
1565 | 1636 |
1566 WebRtc_InitBuffer(aec->nearFrBuf); | 1637 WebRtc_InitBuffer(aec->nearFrBuf); |
1567 WebRtc_InitBuffer(aec->outFrBuf); | 1638 WebRtc_InitBuffer(aec->outFrBuf); |
1568 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1639 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
1569 WebRtc_InitBuffer(aec->nearFrBufH[i]); | 1640 WebRtc_InitBuffer(aec->nearFrBufH[i]); |
1570 WebRtc_InitBuffer(aec->outFrBufH[i]); | 1641 WebRtc_InitBuffer(aec->outFrBufH[i]); |
1571 } | 1642 } |
1572 | 1643 |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1923 | 1994 |
1924 void WebRtcAec_enable_aec3(AecCore* self, int enable) { | 1995 void WebRtcAec_enable_aec3(AecCore* self, int enable) { |
1925 self->aec3_enabled = (enable != 0); | 1996 self->aec3_enabled = (enable != 0); |
1926 } | 1997 } |
1927 | 1998 |
1928 int WebRtcAec_aec3_enabled(AecCore* self) { | 1999 int WebRtcAec_aec3_enabled(AecCore* self) { |
1929 assert(self->aec3_enabled == 0 || self->aec3_enabled == 1); | 2000 assert(self->aec3_enabled == 0 || self->aec3_enabled == 1); |
1930 return self->aec3_enabled; | 2001 return self->aec3_enabled; |
1931 } | 2002 } |
1932 | 2003 |
2004 void WebRtcAec_enable_refined_adaptive_filter(AecCore* self, bool enable) { | |
2005 self->refined_adaptive_filter_enabled = enable; | |
2006 SetAdaptiveFilterStepSize(self); | |
2007 SetErrorThreshold(self); | |
2008 } | |
2009 | |
2010 bool WebRtcAec_refined_adaptive_filter_enabled(const AecCore* self) { | |
hlundin-webrtc
2016/04/15 06:39:23
You must do the same in the h file too.
peah-webrtc
2016/04/15 06:53:26
Done.
| |
2011 return self->refined_adaptive_filter_enabled; | |
2012 } | |
1933 | 2013 |
1934 void WebRtcAec_enable_extended_filter(AecCore* self, int enable) { | 2014 void WebRtcAec_enable_extended_filter(AecCore* self, int enable) { |
1935 self->extended_filter_enabled = enable; | 2015 self->extended_filter_enabled = enable; |
2016 SetAdaptiveFilterStepSize(self); | |
2017 SetErrorThreshold(self); | |
1936 self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions; | 2018 self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions; |
1937 // Update the delay estimator with filter length. See InitAEC() for details. | 2019 // Update the delay estimator with filter length. See InitAEC() for details. |
1938 WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2); | 2020 WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2); |
1939 } | 2021 } |
1940 | 2022 |
1941 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 2023 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
1942 return self->extended_filter_enabled; | 2024 return self->extended_filter_enabled; |
1943 } | 2025 } |
1944 | 2026 |
1945 int WebRtcAec_system_delay(AecCore* self) { | 2027 int WebRtcAec_system_delay(AecCore* self) { |
1946 return self->system_delay; | 2028 return self->system_delay; |
1947 } | 2029 } |
1948 | 2030 |
1949 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 2031 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1950 assert(delay >= 0); | 2032 assert(delay >= 0); |
1951 self->system_delay = delay; | 2033 self->system_delay = delay; |
1952 } | 2034 } |
1953 } // namespace webrtc | 2035 } // namespace webrtc |
OLD | NEW |