Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(286)

Side by Side Diff: webrtc/modules/audio_processing/aec/aec_core.c

Issue 1639773002: Moved buffering of farend into the EchoSubtraction method. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Changed variable name according to reviewer comments Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 881 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); 892 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator);
893 delay_quality = (delay_quality > kDelayQualityThresholdMax ? 893 delay_quality = (delay_quality > kDelayQualityThresholdMax ?
894 kDelayQualityThresholdMax : delay_quality); 894 kDelayQualityThresholdMax : delay_quality);
895 self->delay_quality_threshold = 895 self->delay_quality_threshold =
896 (delay_quality > self->delay_quality_threshold ? delay_quality : 896 (delay_quality > self->delay_quality_threshold ? delay_quality :
897 self->delay_quality_threshold); 897 self->delay_quality_threshold);
898 } 898 }
899 return delay_correction; 899 return delay_correction;
900 } 900 }
901 901
902 static void EchoSubtraction( 902 static void EchoSubtraction(AecCore* aec,
903 AecCore* aec, 903 int num_partitions,
904 int num_partitions, 904 int metrics_mode,
905 int x_fft_buf_block_pos, 905 int extended_filter_enabled,
906 int metrics_mode, 906 float normal_mu,
907 int extended_filter_enabled, 907 float normal_error_threshold,
908 float normal_mu, 908 float* x_fft,
909 float normal_error_threshold, 909 int* x_fft_buf_block_pos,
910 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], 910 float x_fft_buf[2]
911 float* const y, 911 [kExtendedNumPartitions * PART_LEN1],
912 float x_pow[PART_LEN1], 912 float* const y,
913 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1], 913 float x_pow[PART_LEN1],
914 PowerLevel* linout_level, 914 float h_fft_buf[2]
915 float echo_subtractor_output[PART_LEN]) { 915 [kExtendedNumPartitions * PART_LEN1],
916 PowerLevel* linout_level,
917 float echo_subtractor_output[PART_LEN]) {
ivoc 2016/02/05 09:05:04 Although I noticed that most functions in the file
peah-webrtc 2016/02/05 10:19:49 Great point! That would definitely make sense. I'm
916 float s_fft[2][PART_LEN1]; 918 float s_fft[2][PART_LEN1];
917 float e_extended[PART_LEN2]; 919 float e_extended[PART_LEN2];
918 float s_extended[PART_LEN2]; 920 float s_extended[PART_LEN2];
919 float *s; 921 float *s;
920 float e[PART_LEN]; 922 float e[PART_LEN];
921 float e_fft[2][PART_LEN1]; 923 float e_fft[2][PART_LEN1];
922 int i; 924 int i;
925
926 // Update the x_fft_buf block position.
927 (*x_fft_buf_block_pos)--;
928 if ((*x_fft_buf_block_pos) == -1) {
929 *x_fft_buf_block_pos = num_partitions - 1;
930 }
931
932 // Buffer x_fft.
933 memcpy(x_fft_buf[0] + (*x_fft_buf_block_pos) * PART_LEN1, x_fft,
934 sizeof(float) * PART_LEN1);
935 memcpy(x_fft_buf[1] + (*x_fft_buf_block_pos) * PART_LEN1, &x_fft[PART_LEN1],
936 sizeof(float) * PART_LEN1);
937
923 memset(s_fft, 0, sizeof(s_fft)); 938 memset(s_fft, 0, sizeof(s_fft));
924 939
925 // Conditionally reset the echo subtraction filter if the filter has diverged 940 // Conditionally reset the echo subtraction filter if the filter has diverged
926 // significantly. 941 // significantly.
927 if (!aec->extended_filter_enabled && 942 if (!aec->extended_filter_enabled &&
928 aec->extreme_filter_divergence) { 943 aec->extreme_filter_divergence) {
929 memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); 944 memset(aec->wfBuf, 0, sizeof(aec->wfBuf));
930 aec->extreme_filter_divergence = 0; 945 aec->extreme_filter_divergence = 0;
931 } 946 }
932 947
933 // Produce echo estimate s_fft. 948 // Produce echo estimate s_fft.
934 WebRtcAec_FilterFar(num_partitions, 949 WebRtcAec_FilterFar(num_partitions, *x_fft_buf_block_pos, x_fft_buf,
935 x_fft_buf_block_pos, 950 h_fft_buf, s_fft);
936 x_fft_buf,
937 h_fft_buf,
938 s_fft);
939 951
940 // Compute the time-domain echo estimate s. 952 // Compute the time-domain echo estimate s.
941 ScaledInverseFft(s_fft, s_extended, 2.0f, 0); 953 ScaledInverseFft(s_fft, s_extended, 2.0f, 0);
942 s = &s_extended[PART_LEN]; 954 s = &s_extended[PART_LEN];
943 955
944 // Compute the time-domain echo prediction error. 956 // Compute the time-domain echo prediction error.
945 for (i = 0; i < PART_LEN; ++i) { 957 for (i = 0; i < PART_LEN; ++i) {
946 e[i] = y[i] - s[i]; 958 e[i] = y[i] - s[i];
947 } 959 }
948 960
(...skipping 12 matching lines...) Expand all
961 // performed. That scaling is taken care of in UpdateMetrics() instead. 973 // performed. That scaling is taken care of in UpdateMetrics() instead.
962 UpdateLevel(linout_level, CalculatePower(e, PART_LEN) / 2.0f); 974 UpdateLevel(linout_level, CalculatePower(e, PART_LEN) / 2.0f);
963 } 975 }
964 976
965 // Scale error signal inversely with far power. 977 // Scale error signal inversely with far power.
966 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, 978 WebRtcAec_ScaleErrorSignal(extended_filter_enabled,
967 normal_mu, 979 normal_mu,
968 normal_error_threshold, 980 normal_error_threshold,
969 x_pow, 981 x_pow,
970 e_fft); 982 e_fft);
971 WebRtcAec_FilterAdaptation(num_partitions, 983 WebRtcAec_FilterAdaptation(num_partitions, *x_fft_buf_block_pos, x_fft_buf,
972 x_fft_buf_block_pos, 984 e_fft, h_fft_buf);
973 x_fft_buf,
974 e_fft,
975 h_fft_buf);
976 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); 985 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN);
977 } 986 }
978 987
979 988
980 static void EchoSuppression(AecCore* aec, 989 static void EchoSuppression(AecCore* aec,
981 float farend[PART_LEN2], 990 float farend[PART_LEN2],
982 float* echo_subtractor_output, 991 float* echo_subtractor_output,
983 float* output, 992 float* output,
984 float* const* outputH) { 993 float* const* outputH) {
985 float efw[2][PART_LEN1]; 994 float efw[2][PART_LEN1];
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1218 1227
1219 memmove(aec->xfwBuf + PART_LEN1, 1228 memmove(aec->xfwBuf + PART_LEN1,
1220 aec->xfwBuf, 1229 aec->xfwBuf,
1221 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); 1230 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1);
1222 } 1231 }
1223 1232
1224 static void ProcessBlock(AecCore* aec) { 1233 static void ProcessBlock(AecCore* aec) {
1225 size_t i; 1234 size_t i;
1226 1235
1227 float fft[PART_LEN2]; 1236 float fft[PART_LEN2];
1228 float xf[2][PART_LEN1]; 1237 float x_fft[2][PART_LEN1];
1229 float df[2][PART_LEN1]; 1238 float df[2][PART_LEN1];
1230 float far_spectrum = 0.0f; 1239 float far_spectrum = 0.0f;
1231 float near_spectrum = 0.0f; 1240 float near_spectrum = 0.0f;
1232 float abs_far_spectrum[PART_LEN1]; 1241 float abs_far_spectrum[PART_LEN1];
1233 float abs_near_spectrum[PART_LEN1]; 1242 float abs_near_spectrum[PART_LEN1];
1234 1243
1235 const float gPow[2] = {0.9f, 0.1f}; 1244 const float gPow[2] = {0.9f, 0.1f};
1236 1245
1237 // Noise estimate constants. 1246 // Noise estimate constants.
1238 const int noiseInitBlocks = 500 * aec->mult; 1247 const int noiseInitBlocks = 500 * aec->mult;
1239 const float step = 0.1f; 1248 const float step = 0.1f;
1240 const float ramp = 1.0002f; 1249 const float ramp = 1.0002f;
1241 const float gInitNoise[2] = {0.999f, 0.001f}; 1250 const float gInitNoise[2] = {0.999f, 0.001f};
1242 1251
1243 float nearend[PART_LEN]; 1252 float nearend[PART_LEN];
1244 float* nearend_ptr = NULL; 1253 float* nearend_ptr = NULL;
1245 float farend[PART_LEN2]; 1254 float farend[PART_LEN2];
1246 float* farend_ptr = NULL; 1255 float* farend_ptr = NULL;
1247 float echo_subtractor_output[PART_LEN]; 1256 float echo_subtractor_output[PART_LEN];
1248 float output[PART_LEN]; 1257 float output[PART_LEN];
1249 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; 1258 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN];
1250 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; 1259 float* outputH_ptr[NUM_HIGH_BANDS_MAX];
1251 float* xf_ptr = NULL; 1260 float* x_fft_ptr = NULL;
1252 1261
1253 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { 1262 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) {
1254 outputH_ptr[i] = outputH[i]; 1263 outputH_ptr[i] = outputH[i];
1255 } 1264 }
1256 1265
1257 // Concatenate old and new nearend blocks. 1266 // Concatenate old and new nearend blocks.
1258 for (i = 0; i < aec->num_bands - 1; ++i) { 1267 for (i = 0; i < aec->num_bands - 1; ++i) {
1259 WebRtc_ReadBuffer(aec->nearFrBufH[i], 1268 WebRtc_ReadBuffer(aec->nearFrBufH[i],
1260 (void**)&nearend_ptr, 1269 (void**)&nearend_ptr,
1261 nearend, 1270 nearend,
(...skipping 12 matching lines...) Expand all
1274 // TODO(minyue): |farend_ptr| starts from buffered samples. This will be 1283 // TODO(minyue): |farend_ptr| starts from buffered samples. This will be
1275 // modified when |aec->far_time_buf| is revised. 1284 // modified when |aec->far_time_buf| is revised.
1276 RTC_AEC_DEBUG_WAV_WRITE(aec->farFile, &farend_ptr[PART_LEN], PART_LEN); 1285 RTC_AEC_DEBUG_WAV_WRITE(aec->farFile, &farend_ptr[PART_LEN], PART_LEN);
1277 1286
1278 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN); 1287 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN);
1279 } 1288 }
1280 #endif 1289 #endif
1281 1290
1282 // Convert far-end signal to the frequency domain. 1291 // Convert far-end signal to the frequency domain.
1283 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2); 1292 memcpy(fft, farend_ptr, sizeof(float) * PART_LEN2);
1284 Fft(fft, xf); 1293 Fft(fft, x_fft);
1285 xf_ptr = &xf[0][0]; 1294 x_fft_ptr = &x_fft[0][0];
1286 1295
1287 // Near fft 1296 // Near fft
1288 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); 1297 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2);
1289 Fft(fft, df); 1298 Fft(fft, df);
1290 1299
1291 if (aec->metricsMode == 1) { 1300 if (aec->metricsMode == 1) {
1292 // Update power levels 1301 // Update power levels
1293 UpdateLevel(&aec->farlevel, CalculatePower(farend_ptr, PART_LEN2)); 1302 UpdateLevel(&aec->farlevel, CalculatePower(farend_ptr, PART_LEN2));
1294 UpdateLevel(&aec->nearlevel, CalculatePower(aec->dBuf, PART_LEN2)); 1303 UpdateLevel(&aec->nearlevel, CalculatePower(aec->dBuf, PART_LEN2));
1295 } 1304 }
1296 1305
1297 // Power smoothing 1306 // Power smoothing
1298 for (i = 0; i < PART_LEN1; i++) { 1307 for (i = 0; i < PART_LEN1; i++) {
1299 far_spectrum = (xf_ptr[i] * xf_ptr[i]) + 1308 far_spectrum = (x_fft_ptr[i] * x_fft_ptr[i]) +
1300 (xf_ptr[PART_LEN1 + i] * xf_ptr[PART_LEN1 + i]); 1309 (x_fft_ptr[PART_LEN1 + i] * x_fft_ptr[PART_LEN1 + i]);
1301 aec->xPow[i] = 1310 aec->xPow[i] =
1302 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; 1311 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum;
1303 // Calculate absolute spectra 1312 // Calculate absolute spectra
1304 abs_far_spectrum[i] = sqrtf(far_spectrum); 1313 abs_far_spectrum[i] = sqrtf(far_spectrum);
1305 1314
1306 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i]; 1315 near_spectrum = df[0][i] * df[0][i] + df[1][i] * df[1][i];
1307 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum; 1316 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum;
1308 // Calculate absolute spectra 1317 // Calculate absolute spectra
1309 abs_near_spectrum[i] = sqrtf(near_spectrum); 1318 abs_near_spectrum[i] = sqrtf(near_spectrum);
1310 } 1319 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1349 aec->delay_histogram[delay_estimate]++; 1358 aec->delay_histogram[delay_estimate]++;
1350 aec->num_delay_values++; 1359 aec->num_delay_values++;
1351 } 1360 }
1352 if (aec->delay_metrics_delivered == 1 && 1361 if (aec->delay_metrics_delivered == 1 &&
1353 aec->num_delay_values >= kDelayMetricsAggregationWindow) { 1362 aec->num_delay_values >= kDelayMetricsAggregationWindow) {
1354 UpdateDelayMetrics(aec); 1363 UpdateDelayMetrics(aec);
1355 } 1364 }
1356 } 1365 }
1357 } 1366 }
1358 1367
1359 // Update the xfBuf block position.
1360 aec->xfBufBlockPos--;
1361 if (aec->xfBufBlockPos == -1) {
1362 aec->xfBufBlockPos = aec->num_partitions - 1;
1363 }
1364
1365 // Buffer xf
1366 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1,
1367 xf_ptr,
1368 sizeof(float) * PART_LEN1);
1369 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1,
1370 &xf_ptr[PART_LEN1],
1371 sizeof(float) * PART_LEN1);
1372
1373 // Perform echo subtraction. 1368 // Perform echo subtraction.
1374 EchoSubtraction(aec, 1369 EchoSubtraction(aec, aec->num_partitions, aec->metricsMode,
1375 aec->num_partitions, 1370 aec->extended_filter_enabled, aec->normal_mu,
1376 aec->xfBufBlockPos, 1371 aec->normal_error_threshold, &x_fft[0][0],
1377 aec->metricsMode, 1372 &aec->xfBufBlockPos, aec->xfBuf, nearend_ptr, aec->xPow,
1378 aec->extended_filter_enabled, 1373 aec->wfBuf, &aec->linoutlevel, echo_subtractor_output);
1379 aec->normal_mu,
1380 aec->normal_error_threshold,
1381 aec->xfBuf,
1382 nearend_ptr,
1383 aec->xPow,
1384 aec->wfBuf,
1385 &aec->linoutlevel,
1386 echo_subtractor_output);
1387 1374
1388 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); 1375 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN);
1389 1376
1390 // Perform echo suppression. 1377 // Perform echo suppression.
1391 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr); 1378 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr);
1392 1379
1393 if (aec->metricsMode == 1) { 1380 if (aec->metricsMode == 1) {
1394 UpdateMetrics(aec); 1381 UpdateMetrics(aec);
1395 } 1382 }
1396 1383
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
1924 int WebRtcAec_extended_filter_enabled(AecCore* self) { 1911 int WebRtcAec_extended_filter_enabled(AecCore* self) {
1925 return self->extended_filter_enabled; 1912 return self->extended_filter_enabled;
1926 } 1913 }
1927 1914
1928 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } 1915 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; }
1929 1916
1930 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 1917 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
1931 assert(delay >= 0); 1918 assert(delay >= 0);
1932 self->system_delay = delay; 1919 self->system_delay = delay;
1933 } 1920 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698