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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 aec->wfBuf[0][pos + j], | 168 aec->wfBuf[0][pos + j], |
169 aec->wfBuf[1][pos + j]); | 169 aec->wfBuf[1][pos + j]); |
170 yf[1][j] += MulIm(aec->xfBuf[0][xPos + j], | 170 yf[1][j] += MulIm(aec->xfBuf[0][xPos + j], |
171 aec->xfBuf[1][xPos + j], | 171 aec->xfBuf[1][xPos + j], |
172 aec->wfBuf[0][pos + j], | 172 aec->wfBuf[0][pos + j], |
173 aec->wfBuf[1][pos + j]); | 173 aec->wfBuf[1][pos + j]); |
174 } | 174 } |
175 } | 175 } |
176 } | 176 } |
177 | 177 |
178 static void ScaleErrorSignal(AecCore* aec, float ef[2][PART_LEN1]) { | 178 static void ScaleErrorSignal(int extended_filter_enabled, |
179 const float mu = aec->extended_filter_enabled ? kExtendedMu : aec->normal_mu; | 179 float normal_mu, |
180 const float error_threshold = aec->extended_filter_enabled | 180 float normal_error_threshold, |
| 181 float *x_pow, |
| 182 float ef[2][PART_LEN1]) { |
| 183 const float mu = extended_filter_enabled ? kExtendedMu : normal_mu; |
| 184 const float error_threshold = extended_filter_enabled |
181 ? kExtendedErrorThreshold | 185 ? kExtendedErrorThreshold |
182 : aec->normal_error_threshold; | 186 : normal_error_threshold; |
183 int i; | 187 int i; |
184 float abs_ef; | 188 float abs_ef; |
185 for (i = 0; i < (PART_LEN1); i++) { | 189 for (i = 0; i < (PART_LEN1); i++) { |
186 ef[0][i] /= (aec->xPow[i] + 1e-10f); | 190 ef[0][i] /= (x_pow[i] + 1e-10f); |
187 ef[1][i] /= (aec->xPow[i] + 1e-10f); | 191 ef[1][i] /= (x_pow[i] + 1e-10f); |
188 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]); |
189 | 193 |
190 if (abs_ef > error_threshold) { | 194 if (abs_ef > error_threshold) { |
191 abs_ef = error_threshold / (abs_ef + 1e-10f); | 195 abs_ef = error_threshold / (abs_ef + 1e-10f); |
192 ef[0][i] *= abs_ef; | 196 ef[0][i] *= abs_ef; |
193 ef[1][i] *= abs_ef; | 197 ef[1][i] *= abs_ef; |
194 } | 198 } |
195 | 199 |
196 // Stepsize factor | 200 // Stepsize factor |
197 ef[0][i] *= mu; | 201 ef[0][i] *= mu; |
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 self->num_delay_values; | 834 self->num_delay_values; |
831 } | 835 } |
832 | 836 |
833 // Reset histogram. | 837 // Reset histogram. |
834 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); | 838 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); |
835 self->num_delay_values = 0; | 839 self->num_delay_values = 0; |
836 | 840 |
837 return; | 841 return; |
838 } | 842 } |
839 | 843 |
| 844 static void FrequencyToTime(float freq_data[2][PART_LEN1], |
| 845 float time_data[PART_LEN2]) { |
| 846 int i; |
| 847 time_data[0] = freq_data[0][0]; |
| 848 time_data[1] = freq_data[0][PART_LEN]; |
| 849 for (i = 1; i < PART_LEN; i++) { |
| 850 time_data[2 * i] = freq_data[0][i]; |
| 851 time_data[2 * i + 1] = freq_data[1][i]; |
| 852 } |
| 853 aec_rdft_inverse_128(time_data); |
| 854 } |
| 855 |
| 856 |
840 static void TimeToFrequency(float time_data[PART_LEN2], | 857 static void TimeToFrequency(float time_data[PART_LEN2], |
841 float freq_data[2][PART_LEN1], | 858 float freq_data[2][PART_LEN1], |
842 int window) { | 859 int window) { |
843 int i = 0; | 860 int i = 0; |
844 | 861 |
845 // TODO(bjornv): Should we have a different function/wrapper for windowed FFT? | 862 // TODO(bjornv): Should we have a different function/wrapper for windowed FFT? |
846 if (window) { | 863 if (window) { |
847 for (i = 0; i < PART_LEN; i++) { | 864 for (i = 0; i < PART_LEN; i++) { |
848 time_data[i] *= WebRtcAec_sqrtHanning[i]; | 865 time_data[i] *= WebRtcAec_sqrtHanning[i]; |
849 time_data[PART_LEN + i] *= WebRtcAec_sqrtHanning[PART_LEN - i]; | 866 time_data[PART_LEN + i] *= WebRtcAec_sqrtHanning[PART_LEN - i]; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); | 952 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); |
936 delay_quality = (delay_quality > kDelayQualityThresholdMax ? | 953 delay_quality = (delay_quality > kDelayQualityThresholdMax ? |
937 kDelayQualityThresholdMax : delay_quality); | 954 kDelayQualityThresholdMax : delay_quality); |
938 self->delay_quality_threshold = | 955 self->delay_quality_threshold = |
939 (delay_quality > self->delay_quality_threshold ? delay_quality : | 956 (delay_quality > self->delay_quality_threshold ? delay_quality : |
940 self->delay_quality_threshold); | 957 self->delay_quality_threshold); |
941 } | 958 } |
942 return delay_correction; | 959 return delay_correction; |
943 } | 960 } |
944 | 961 |
945 static void NonLinearProcessing(AecCore* aec, | 962 static void EchoSubtraction(AecCore* aec, |
946 float* output, | 963 float* nearend_ptr) { |
947 float* const* outputH) { | 964 float yf[2][PART_LEN1]; |
| 965 float fft[PART_LEN2]; |
| 966 float y[PART_LEN]; |
| 967 float e[PART_LEN]; |
| 968 float ef[2][PART_LEN1]; |
| 969 float scale; |
| 970 int i; |
| 971 memset(yf, 0, sizeof(yf)); |
| 972 |
| 973 // Produce frequency domain echo estimate. |
| 974 WebRtcAec_FilterFar(aec, yf); |
| 975 |
| 976 // Inverse fft to obtain echo estimate and error. |
| 977 FrequencyToTime(yf, fft); |
| 978 |
| 979 // Extract the output signal and compute the time-domain error. |
| 980 scale = 2.0f / PART_LEN2; |
| 981 for (i = 0; i < PART_LEN; ++i) { |
| 982 y[i] = fft[PART_LEN + i] * scale; // fft scaling. |
| 983 e[i] = nearend_ptr[i] - y[i]; |
| 984 } |
| 985 |
| 986 // Error fft |
| 987 memcpy(aec->eBuf + PART_LEN, e, sizeof(float) * PART_LEN); |
| 988 memset(fft, 0, sizeof(float) * PART_LEN); |
| 989 memcpy(fft + PART_LEN, e, sizeof(float) * PART_LEN); |
| 990 TimeToFrequency(fft, ef, 0); |
| 991 |
| 992 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, |
| 993 &ef[0][0], |
| 994 sizeof(ef[0][0]) * PART_LEN1 * 2); |
| 995 |
| 996 if (aec->metricsMode == 1) { |
| 997 // Note that the first PART_LEN samples in fft (before transformation) are |
| 998 // zero. Hence, the scaling by two in UpdateLevel() should not be |
| 999 // performed. That scaling is taken care of in UpdateMetrics() instead. |
| 1000 UpdateLevel(&aec->linoutlevel, ef); |
| 1001 } |
| 1002 |
| 1003 // Scale error signal inversely with far power. |
| 1004 WebRtcAec_ScaleErrorSignal(aec->extended_filter_enabled, |
| 1005 aec->normal_mu, |
| 1006 aec->normal_error_threshold, |
| 1007 aec->xPow, |
| 1008 ef); |
| 1009 WebRtcAec_FilterAdaptation(aec, fft, ef); |
| 1010 |
| 1011 |
| 1012 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, e, PART_LEN); |
| 1013 } |
| 1014 |
| 1015 |
| 1016 static void EchoSuppression(AecCore* aec, |
| 1017 float* output, |
| 1018 float* const* outputH) { |
948 float efw[2][PART_LEN1], xfw[2][PART_LEN1]; | 1019 float efw[2][PART_LEN1], xfw[2][PART_LEN1]; |
949 complex_t comfortNoiseHband[PART_LEN1]; | 1020 complex_t comfortNoiseHband[PART_LEN1]; |
950 float fft[PART_LEN2]; | 1021 float fft[PART_LEN2]; |
951 float scale, dtmp; | 1022 float scale, dtmp; |
952 float nlpGainHband; | 1023 float nlpGainHband; |
953 int i; | 1024 int i; |
954 size_t j; | 1025 size_t j; |
955 | 1026 |
956 // Coherence and non-linear filter | 1027 // Coherence and non-linear filter |
957 float cohde[PART_LEN1], cohxd[PART_LEN1]; | 1028 float cohde[PART_LEN1], cohxd[PART_LEN1]; |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 memcpy(aec->dBufH[j], aec->dBufH[j] + PART_LEN, sizeof(float) * PART_LEN); | 1241 memcpy(aec->dBufH[j], aec->dBufH[j] + PART_LEN, sizeof(float) * PART_LEN); |
1171 } | 1242 } |
1172 | 1243 |
1173 memmove(aec->xfwBuf + PART_LEN1, | 1244 memmove(aec->xfwBuf + PART_LEN1, |
1174 aec->xfwBuf, | 1245 aec->xfwBuf, |
1175 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); | 1246 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); |
1176 } | 1247 } |
1177 | 1248 |
1178 static void ProcessBlock(AecCore* aec) { | 1249 static void ProcessBlock(AecCore* aec) { |
1179 size_t i; | 1250 size_t i; |
1180 float y[PART_LEN], e[PART_LEN]; | |
1181 float scale; | |
1182 | 1251 |
1183 float fft[PART_LEN2]; | 1252 float fft[PART_LEN2]; |
1184 float xf[2][PART_LEN1], yf[2][PART_LEN1], ef[2][PART_LEN1]; | 1253 float xf[2][PART_LEN1]; |
1185 float df[2][PART_LEN1]; | 1254 float df[2][PART_LEN1]; |
1186 float far_spectrum = 0.0f; | 1255 float far_spectrum = 0.0f; |
1187 float near_spectrum = 0.0f; | 1256 float near_spectrum = 0.0f; |
1188 float abs_far_spectrum[PART_LEN1]; | 1257 float abs_far_spectrum[PART_LEN1]; |
1189 float abs_near_spectrum[PART_LEN1]; | 1258 float abs_near_spectrum[PART_LEN1]; |
1190 | 1259 |
1191 const float gPow[2] = {0.9f, 0.1f}; | 1260 const float gPow[2] = {0.9f, 0.1f}; |
1192 | 1261 |
1193 // Noise estimate constants. | 1262 // Noise estimate constants. |
1194 const int noiseInitBlocks = 500 * aec->mult; | 1263 const int noiseInitBlocks = 500 * aec->mult; |
1195 const float step = 0.1f; | 1264 const float step = 0.1f; |
1196 const float ramp = 1.0002f; | 1265 const float ramp = 1.0002f; |
1197 const float gInitNoise[2] = {0.999f, 0.001f}; | 1266 const float gInitNoise[2] = {0.999f, 0.001f}; |
1198 | 1267 |
1199 float nearend[PART_LEN]; | 1268 float nearend[PART_LEN]; |
1200 float* nearend_ptr = NULL; | 1269 float* nearend_ptr = NULL; |
1201 float output[PART_LEN]; | 1270 float output[PART_LEN]; |
1202 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; | 1271 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; |
1203 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; | 1272 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; |
| 1273 float* xf_ptr = NULL; |
| 1274 |
1204 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1275 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
1205 outputH_ptr[i] = outputH[i]; | 1276 outputH_ptr[i] = outputH[i]; |
1206 } | 1277 } |
1207 | 1278 |
1208 float* xf_ptr = NULL; | |
1209 | |
1210 // Concatenate old and new nearend blocks. | 1279 // Concatenate old and new nearend blocks. |
1211 for (i = 0; i < aec->num_bands - 1; ++i) { | 1280 for (i = 0; i < aec->num_bands - 1; ++i) { |
1212 WebRtc_ReadBuffer(aec->nearFrBufH[i], | 1281 WebRtc_ReadBuffer(aec->nearFrBufH[i], |
1213 (void**)&nearend_ptr, | 1282 (void**)&nearend_ptr, |
1214 nearend, | 1283 nearend, |
1215 PART_LEN); | 1284 PART_LEN); |
1216 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); | 1285 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); |
1217 } | 1286 } |
1218 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN); | 1287 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN); |
1219 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend)); | 1288 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend)); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1307 } | 1376 } |
1308 | 1377 |
1309 // Buffer xf | 1378 // Buffer xf |
1310 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, | 1379 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, |
1311 xf_ptr, | 1380 xf_ptr, |
1312 sizeof(float) * PART_LEN1); | 1381 sizeof(float) * PART_LEN1); |
1313 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, | 1382 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, |
1314 &xf_ptr[PART_LEN1], | 1383 &xf_ptr[PART_LEN1], |
1315 sizeof(float) * PART_LEN1); | 1384 sizeof(float) * PART_LEN1); |
1316 | 1385 |
1317 memset(yf, 0, sizeof(yf)); | 1386 // Perform echo subtraction. |
| 1387 EchoSubtraction(aec, nearend_ptr); |
1318 | 1388 |
1319 // Filter far | 1389 // Perform echo suppression. |
1320 WebRtcAec_FilterFar(aec, yf); | 1390 EchoSuppression(aec, output, outputH_ptr); |
1321 | |
1322 // Inverse fft to obtain echo estimate and error. | |
1323 fft[0] = yf[0][0]; | |
1324 fft[1] = yf[0][PART_LEN]; | |
1325 for (i = 1; i < PART_LEN; i++) { | |
1326 fft[2 * i] = yf[0][i]; | |
1327 fft[2 * i + 1] = yf[1][i]; | |
1328 } | |
1329 aec_rdft_inverse_128(fft); | |
1330 | |
1331 scale = 2.0f / PART_LEN2; | |
1332 for (i = 0; i < PART_LEN; i++) { | |
1333 y[i] = fft[PART_LEN + i] * scale; // fft scaling | |
1334 } | |
1335 | |
1336 for (i = 0; i < PART_LEN; i++) { | |
1337 e[i] = nearend_ptr[i] - y[i]; | |
1338 } | |
1339 | |
1340 // Error fft | |
1341 memcpy(aec->eBuf + PART_LEN, e, sizeof(float) * PART_LEN); | |
1342 memset(fft, 0, sizeof(float) * PART_LEN); | |
1343 memcpy(fft + PART_LEN, e, sizeof(float) * PART_LEN); | |
1344 // TODO(bjornv): Change to use TimeToFrequency(). | |
1345 aec_rdft_forward_128(fft); | |
1346 | |
1347 ef[1][0] = 0; | |
1348 ef[1][PART_LEN] = 0; | |
1349 ef[0][0] = fft[0]; | |
1350 ef[0][PART_LEN] = fft[1]; | |
1351 for (i = 1; i < PART_LEN; i++) { | |
1352 ef[0][i] = fft[2 * i]; | |
1353 ef[1][i] = fft[2 * i + 1]; | |
1354 } | |
1355 | |
1356 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, | |
1357 &ef[0][0], | |
1358 sizeof(ef[0][0]) * PART_LEN1 * 2); | |
1359 | |
1360 if (aec->metricsMode == 1) { | |
1361 // Note that the first PART_LEN samples in fft (before transformation) are | |
1362 // zero. Hence, the scaling by two in UpdateLevel() should not be | |
1363 // performed. That scaling is taken care of in UpdateMetrics() instead. | |
1364 UpdateLevel(&aec->linoutlevel, ef); | |
1365 } | |
1366 | |
1367 // Scale error signal inversely with far power. | |
1368 WebRtcAec_ScaleErrorSignal(aec, ef); | |
1369 WebRtcAec_FilterAdaptation(aec, fft, ef); | |
1370 NonLinearProcessing(aec, output, outputH_ptr); | |
1371 | 1391 |
1372 if (aec->metricsMode == 1) { | 1392 if (aec->metricsMode == 1) { |
1373 // Update power levels and echo metrics | 1393 // Update power levels and echo metrics |
1374 UpdateLevel(&aec->farlevel, (float(*)[PART_LEN1])xf_ptr); | 1394 UpdateLevel(&aec->farlevel, (float(*)[PART_LEN1])xf_ptr); |
1375 UpdateLevel(&aec->nearlevel, df); | 1395 UpdateLevel(&aec->nearlevel, df); |
1376 UpdateMetrics(aec); | 1396 UpdateMetrics(aec); |
1377 } | 1397 } |
1378 | 1398 |
1379 // Store the output block. | 1399 // Store the output block. |
1380 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN); | 1400 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN); |
1381 // For high bands | 1401 // For high bands |
1382 for (i = 0; i < aec->num_bands - 1; ++i) { | 1402 for (i = 0; i < aec->num_bands - 1; ++i) { |
1383 WebRtc_WriteBuffer(aec->outFrBufH[i], outputH[i], PART_LEN); | 1403 WebRtc_WriteBuffer(aec->outFrBufH[i], outputH[i], PART_LEN); |
1384 } | 1404 } |
1385 | 1405 |
1386 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, e, PART_LEN); | |
1387 RTC_AEC_DEBUG_WAV_WRITE(aec->outFile, output, PART_LEN); | 1406 RTC_AEC_DEBUG_WAV_WRITE(aec->outFile, output, PART_LEN); |
1388 } | 1407 } |
1389 | 1408 |
1390 AecCore* WebRtcAec_CreateAec() { | 1409 AecCore* WebRtcAec_CreateAec() { |
1391 int i; | 1410 int i; |
1392 AecCore* aec = malloc(sizeof(AecCore)); | 1411 AecCore* aec = malloc(sizeof(AecCore)); |
1393 if (!aec) { | 1412 if (!aec) { |
1394 return NULL; | 1413 return NULL; |
1395 } | 1414 } |
1396 | 1415 |
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1920 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 1939 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
1921 return self->extended_filter_enabled; | 1940 return self->extended_filter_enabled; |
1922 } | 1941 } |
1923 | 1942 |
1924 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } | 1943 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } |
1925 | 1944 |
1926 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1945 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1927 assert(delay >= 0); | 1946 assert(delay >= 0); |
1928 self->system_delay = delay; | 1947 self->system_delay = delay; |
1929 } | 1948 } |
OLD | NEW |