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 863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 self->delay_quality_threshold = | 874 self->delay_quality_threshold = |
875 (delay_quality > self->delay_quality_threshold | 875 (delay_quality > self->delay_quality_threshold |
876 ? delay_quality | 876 ? delay_quality |
877 : self->delay_quality_threshold); | 877 : self->delay_quality_threshold); |
878 } | 878 } |
879 return delay_correction; | 879 return delay_correction; |
880 } | 880 } |
881 | 881 |
882 static void EchoSubtraction(AecCore* aec, | 882 static void EchoSubtraction(AecCore* aec, |
883 int num_partitions, | 883 int num_partitions, |
884 int x_fft_buf_block_pos, | |
885 int extended_filter_enabled, | 884 int extended_filter_enabled, |
886 float normal_mu, | 885 float normal_mu, |
887 float normal_error_threshold, | 886 float normal_error_threshold, |
| 887 float* x_fft, |
| 888 int* x_fft_buf_block_pos, |
888 float x_fft_buf[2] | 889 float x_fft_buf[2] |
889 [kExtendedNumPartitions * PART_LEN1], | 890 [kExtendedNumPartitions * PART_LEN1], |
890 float* const y, | 891 float* const y, |
891 float x_pow[PART_LEN1], | 892 float x_pow[PART_LEN1], |
892 float h_fft_buf[2] | 893 float h_fft_buf[2] |
893 [kExtendedNumPartitions * PART_LEN1], | 894 [kExtendedNumPartitions * PART_LEN1], |
894 float echo_subtractor_output[PART_LEN]) { | 895 float echo_subtractor_output[PART_LEN]) { |
895 float s_fft[2][PART_LEN1]; | 896 float s_fft[2][PART_LEN1]; |
896 float e_extended[PART_LEN2]; | 897 float e_extended[PART_LEN2]; |
897 float s_extended[PART_LEN2]; | 898 float s_extended[PART_LEN2]; |
898 float* s; | 899 float* s; |
899 float e[PART_LEN]; | 900 float e[PART_LEN]; |
900 float e_fft[2][PART_LEN1]; | 901 float e_fft[2][PART_LEN1]; |
901 int i; | 902 int i; |
| 903 |
| 904 // Update the x_fft_buf block position. |
| 905 (*x_fft_buf_block_pos)--; |
| 906 if ((*x_fft_buf_block_pos) == -1) { |
| 907 *x_fft_buf_block_pos = num_partitions - 1; |
| 908 } |
| 909 |
| 910 // Buffer x_fft. |
| 911 memcpy(x_fft_buf[0] + (*x_fft_buf_block_pos) * PART_LEN1, x_fft, |
| 912 sizeof(float) * PART_LEN1); |
| 913 memcpy(x_fft_buf[1] + (*x_fft_buf_block_pos) * PART_LEN1, &x_fft[PART_LEN1], |
| 914 sizeof(float) * PART_LEN1); |
| 915 |
902 memset(s_fft, 0, sizeof(s_fft)); | 916 memset(s_fft, 0, sizeof(s_fft)); |
903 | 917 |
904 // Conditionally reset the echo subtraction filter if the filter has diverged | 918 // Conditionally reset the echo subtraction filter if the filter has diverged |
905 // significantly. | 919 // significantly. |
906 if (!aec->extended_filter_enabled && aec->extreme_filter_divergence) { | 920 if (!aec->extended_filter_enabled && aec->extreme_filter_divergence) { |
907 memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); | 921 memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); |
908 aec->extreme_filter_divergence = 0; | 922 aec->extreme_filter_divergence = 0; |
909 } | 923 } |
910 | 924 |
911 // Produce echo estimate s_fft. | 925 // Produce echo estimate s_fft. |
912 WebRtcAec_FilterFar(num_partitions, x_fft_buf_block_pos, x_fft_buf, h_fft_buf, | 926 WebRtcAec_FilterFar(num_partitions, *x_fft_buf_block_pos, x_fft_buf, |
913 s_fft); | 927 h_fft_buf, s_fft); |
914 | 928 |
915 // Compute the time-domain echo estimate s. | 929 // Compute the time-domain echo estimate s. |
916 ScaledInverseFft(s_fft, s_extended, 2.0f, 0); | 930 ScaledInverseFft(s_fft, s_extended, 2.0f, 0); |
917 s = &s_extended[PART_LEN]; | 931 s = &s_extended[PART_LEN]; |
918 | 932 |
919 // Compute the time-domain echo prediction error. | 933 // Compute the time-domain echo prediction error. |
920 for (i = 0; i < PART_LEN; ++i) { | 934 for (i = 0; i < PART_LEN; ++i) { |
921 e[i] = y[i] - s[i]; | 935 e[i] = y[i] - s[i]; |
922 } | 936 } |
923 | 937 |
924 // Compute the frequency domain echo prediction error. | 938 // Compute the frequency domain echo prediction error. |
925 memset(e_extended, 0, sizeof(float) * PART_LEN); | 939 memset(e_extended, 0, sizeof(float) * PART_LEN); |
926 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); | 940 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); |
927 Fft(e_extended, e_fft); | 941 Fft(e_extended, e_fft); |
928 | 942 |
929 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, &e_fft[0][0], | 943 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, &e_fft[0][0], |
930 sizeof(e_fft[0][0]) * PART_LEN1 * 2); | 944 sizeof(e_fft[0][0]) * PART_LEN1 * 2); |
931 | 945 |
932 // Scale error signal inversely with far power. | 946 // Scale error signal inversely with far power. |
933 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, normal_mu, | 947 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, normal_mu, |
934 normal_error_threshold, x_pow, e_fft); | 948 normal_error_threshold, x_pow, e_fft); |
935 WebRtcAec_FilterAdaptation(num_partitions, x_fft_buf_block_pos, x_fft_buf, | 949 WebRtcAec_FilterAdaptation(num_partitions, *x_fft_buf_block_pos, x_fft_buf, |
936 e_fft, h_fft_buf); | 950 e_fft, h_fft_buf); |
937 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); | 951 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); |
938 } | 952 } |
939 | 953 |
940 static void EchoSuppression(AecCore* aec, | 954 static void EchoSuppression(AecCore* aec, |
941 float farend[PART_LEN2], | 955 float farend[PART_LEN2], |
942 float* echo_subtractor_output, | 956 float* echo_subtractor_output, |
943 float* output, | 957 float* output, |
944 float* const* outputH) { | 958 float* const* outputH) { |
945 float efw[2][PART_LEN1]; | 959 float efw[2][PART_LEN1]; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1173 } | 1187 } |
1174 | 1188 |
1175 memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf, | 1189 memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf, |
1176 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); | 1190 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); |
1177 } | 1191 } |
1178 | 1192 |
1179 static void ProcessBlock(AecCore* aec) { | 1193 static void ProcessBlock(AecCore* aec) { |
1180 size_t i; | 1194 size_t i; |
1181 | 1195 |
1182 float fft[PART_LEN2]; | 1196 float fft[PART_LEN2]; |
1183 float xf[2][PART_LEN1]; | 1197 float x_fft[2][PART_LEN1]; |
1184 float df[2][PART_LEN1]; | 1198 float df[2][PART_LEN1]; |
1185 float far_spectrum = 0.0f; | 1199 float far_spectrum = 0.0f; |
1186 float near_spectrum = 0.0f; | 1200 float near_spectrum = 0.0f; |
1187 float abs_far_spectrum[PART_LEN1]; | 1201 float abs_far_spectrum[PART_LEN1]; |
1188 float abs_near_spectrum[PART_LEN1]; | 1202 float abs_near_spectrum[PART_LEN1]; |
1189 | 1203 |
1190 const float gPow[2] = {0.9f, 0.1f}; | 1204 const float gPow[2] = {0.9f, 0.1f}; |
1191 | 1205 |
1192 // Noise estimate constants. | 1206 // Noise estimate constants. |
1193 const int noiseInitBlocks = 500 * aec->mult; | 1207 const int noiseInitBlocks = 500 * aec->mult; |
1194 const float step = 0.1f; | 1208 const float step = 0.1f; |
1195 const float ramp = 1.0002f; | 1209 const float ramp = 1.0002f; |
1196 const float gInitNoise[2] = {0.999f, 0.001f}; | 1210 const float gInitNoise[2] = {0.999f, 0.001f}; |
1197 | 1211 |
1198 float nearend[PART_LEN]; | 1212 float nearend[PART_LEN]; |
1199 float* nearend_ptr = NULL; | 1213 float* nearend_ptr = NULL; |
1200 float farend[PART_LEN2]; | 1214 float farend[PART_LEN2]; |
1201 float* farend_ptr = NULL; | 1215 float* farend_ptr = NULL; |
1202 float echo_subtractor_output[PART_LEN]; | 1216 float echo_subtractor_output[PART_LEN]; |
1203 float output[PART_LEN]; | 1217 float output[PART_LEN]; |
1204 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; | 1218 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; |
1205 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; | 1219 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; |
1206 float* xf_ptr = NULL; | 1220 float* x_fft_ptr = NULL; |
1207 | 1221 |
1208 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1222 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
1209 outputH_ptr[i] = outputH[i]; | 1223 outputH_ptr[i] = outputH[i]; |
1210 } | 1224 } |
1211 | 1225 |
1212 // Concatenate old and new nearend blocks. | 1226 // Concatenate old and new nearend blocks. |
1213 for (i = 0; i < aec->num_bands - 1; ++i) { | 1227 for (i = 0; i < aec->num_bands - 1; ++i) { |
1214 WebRtc_ReadBuffer(aec->nearFrBufH[i], (void**)&nearend_ptr, nearend, | 1228 WebRtc_ReadBuffer(aec->nearFrBufH[i], (void**)&nearend_ptr, nearend, |
1215 PART_LEN); | 1229 PART_LEN); |
1216 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); | 1230 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); |
(...skipping 17 matching lines...) Expand all Loading... |
1234 | 1248 |
1235 if (aec->metricsMode == 1) { | 1249 if (aec->metricsMode == 1) { |
1236 // Update power levels | 1250 // Update power levels |
1237 UpdateLevel(&aec->farlevel, | 1251 UpdateLevel(&aec->farlevel, |
1238 CalculatePower(&farend_ptr[PART_LEN], PART_LEN)); | 1252 CalculatePower(&farend_ptr[PART_LEN], PART_LEN)); |
1239 UpdateLevel(&aec->nearlevel, CalculatePower(nearend_ptr, PART_LEN)); | 1253 UpdateLevel(&aec->nearlevel, CalculatePower(nearend_ptr, PART_LEN)); |
1240 } | 1254 } |
1241 | 1255 |
1242 // Convert far-end signal to the frequency domain. | 1256 // Convert far-end signal to the frequency domain. |
1243 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); | 1257 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); |
1244 Fft(fft, xf); | 1258 Fft(fft, x_fft); |
1245 xf_ptr = &xf[0][0]; | 1259 x_fft_ptr = &x_fft[0][0]; |
1246 | 1260 |
1247 // Near fft | 1261 // Near fft |
1248 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); | 1262 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); |
1249 Fft(fft, df); | 1263 Fft(fft, df); |
1250 | 1264 |
1251 // Power smoothing | 1265 // Power smoothing |
1252 for (i = 0; i < PART_LEN1; i++) { | 1266 for (i = 0; i < PART_LEN1; i++) { |
1253 far_spectrum = (xf_ptr[i] * xf_ptr[i]) + | 1267 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) + |
1254 (xf_ptr[PART_LEN1 + i] * xf_ptr[PART_LEN1 + i]); | 1268 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]); |
1255 aec->xPow[i] = | 1269 aec->xPow[i] = |
1256 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; | 1270 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; |
1257 // Calculate absolute spectra | 1271 // Calculate absolute spectra |
1258 abs_far_spectrum[i] = sqrtf(far_spectrum); | 1272 abs_far_spectrum[i] = sqrtf(far_spectrum); |
1259 | 1273 |
1260 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i]; | 1274 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i]; |
1261 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum; | 1275 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum; |
1262 // Calculate absolute spectra | 1276 // Calculate absolute spectra |
1263 abs_near_spectrum[i] = sqrtf(near_spectrum); | 1277 abs_near_spectrum[i] = sqrtf(near_spectrum); |
1264 } | 1278 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1303 aec->delay_histogram[delay_estimate]++; | 1317 aec->delay_histogram[delay_estimate]++; |
1304 aec->num_delay_values++; | 1318 aec->num_delay_values++; |
1305 } | 1319 } |
1306 if (aec->delay_metrics_delivered == 1 && | 1320 if (aec->delay_metrics_delivered == 1 && |
1307 aec->num_delay_values >= kDelayMetricsAggregationWindow) { | 1321 aec->num_delay_values >= kDelayMetricsAggregationWindow) { |
1308 UpdateDelayMetrics(aec); | 1322 UpdateDelayMetrics(aec); |
1309 } | 1323 } |
1310 } | 1324 } |
1311 } | 1325 } |
1312 | 1326 |
1313 // Update the xfBuf block position. | |
1314 aec->xfBufBlockPos--; | |
1315 if (aec->xfBufBlockPos == -1) { | |
1316 aec->xfBufBlockPos = aec->num_partitions - 1; | |
1317 } | |
1318 | |
1319 // Buffer xf | |
1320 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, xf_ptr, | |
1321 sizeof(float) * PART_LEN1); | |
1322 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, &xf_ptr[PART_LEN1], | |
1323 sizeof(float) * PART_LEN1); | |
1324 | |
1325 // Perform echo subtraction. | 1327 // Perform echo subtraction. |
1326 EchoSubtraction(aec, aec->num_partitions, aec->xfBufBlockPos, | 1328 EchoSubtraction(aec, aec->num_partitions, aec->extended_filter_enabled, |
1327 aec->extended_filter_enabled, | 1329 aec->normal_mu, aec->normal_error_threshold, &x_fft[0][0], |
1328 aec->normal_mu, aec->normal_error_threshold, aec->xfBuf, | 1330 &aec->xfBufBlockPos, aec->xfBuf, nearend_ptr, aec->xPow, |
1329 nearend_ptr, aec->xPow, aec->wfBuf, | 1331 aec->wfBuf, echo_subtractor_output); |
1330 echo_subtractor_output); | |
1331 | 1332 |
1332 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); | 1333 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); |
1333 | 1334 |
1334 if (aec->metricsMode == 1) { | 1335 if (aec->metricsMode == 1) { |
1335 UpdateLevel(&aec->linoutlevel, | 1336 UpdateLevel(&aec->linoutlevel, |
1336 CalculatePower(echo_subtractor_output, PART_LEN)); | 1337 CalculatePower(echo_subtractor_output, PART_LEN)); |
1337 } | 1338 } |
1338 | 1339 |
1339 // Perform echo suppression. | 1340 // Perform echo suppression. |
1340 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr); | 1341 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr); |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1874 } | 1875 } |
1875 | 1876 |
1876 int WebRtcAec_system_delay(AecCore* self) { | 1877 int WebRtcAec_system_delay(AecCore* self) { |
1877 return self->system_delay; | 1878 return self->system_delay; |
1878 } | 1879 } |
1879 | 1880 |
1880 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1881 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1881 assert(delay >= 0); | 1882 assert(delay >= 0); |
1882 self->system_delay = delay; | 1883 self->system_delay = delay; |
1883 } | 1884 } |
OLD | NEW |