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

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

Issue 2348213002: Move the aec_rdft* files to a more proper place beneath APM and make them thread-safe. (Closed)
Patch Set: Rebase Created 4 years, 2 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
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 10 matching lines...) Expand all
21 #include <string.h> 21 #include <string.h>
22 22
23 #include "webrtc/base/checks.h" 23 #include "webrtc/base/checks.h"
24 extern "C" { 24 extern "C" {
25 #include "webrtc/common_audio/ring_buffer.h" 25 #include "webrtc/common_audio/ring_buffer.h"
26 } 26 }
27 #include "webrtc/base/checks.h" 27 #include "webrtc/base/checks.h"
28 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h" 28 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h"
29 #include "webrtc/modules/audio_processing/aec/aec_common.h" 29 #include "webrtc/modules/audio_processing/aec/aec_common.h"
30 #include "webrtc/modules/audio_processing/aec/aec_core_optimized_methods.h" 30 #include "webrtc/modules/audio_processing/aec/aec_core_optimized_methods.h"
31 #include "webrtc/modules/audio_processing/aec/aec_rdft.h"
32 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" 31 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h"
33 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h" 32 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h"
34 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" 33 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h"
35 #include "webrtc/system_wrappers/include/metrics.h" 34 #include "webrtc/system_wrappers/include/metrics.h"
36 #include "webrtc/typedefs.h" 35 #include "webrtc/typedefs.h"
37 36
38 namespace webrtc { 37 namespace webrtc {
39 namespace { 38 namespace {
40 enum class DelaySource { 39 enum class DelaySource {
41 kSystemDelay, // The delay values come from the OS. 40 kSystemDelay, // The delay values come from the OS.
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 ef[1][i] *= abs_ef; 329 ef[1][i] *= abs_ef;
331 } 330 }
332 331
333 // Stepsize factor 332 // Stepsize factor
334 ef[0][i] *= mu; 333 ef[0][i] *= mu;
335 ef[1][i] *= mu; 334 ef[1][i] *= mu;
336 } 335 }
337 } 336 }
338 337
339 static void FilterAdaptation( 338 static void FilterAdaptation(
339 const OouraFft& ooura_fft,
340 int num_partitions, 340 int num_partitions,
341 int x_fft_buf_block_pos, 341 int x_fft_buf_block_pos,
342 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], 342 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
343 float e_fft[2][PART_LEN1], 343 float e_fft[2][PART_LEN1],
344 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) { 344 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) {
345 int i, j; 345 int i, j;
346 float fft[PART_LEN2]; 346 float fft[PART_LEN2];
347 for (i = 0; i < num_partitions; i++) { 347 for (i = 0; i < num_partitions; i++) {
348 int xPos = (i + x_fft_buf_block_pos) * (PART_LEN1); 348 int xPos = (i + x_fft_buf_block_pos) * (PART_LEN1);
349 int pos; 349 int pos;
350 // Check for wrap 350 // Check for wrap
351 if (i + x_fft_buf_block_pos >= num_partitions) { 351 if (i + x_fft_buf_block_pos >= num_partitions) {
352 xPos -= num_partitions * PART_LEN1; 352 xPos -= num_partitions * PART_LEN1;
353 } 353 }
354 354
355 pos = i * PART_LEN1; 355 pos = i * PART_LEN1;
356 356
357 for (j = 0; j < PART_LEN; j++) { 357 for (j = 0; j < PART_LEN; j++) {
358 fft[2 * j] = MulRe(x_fft_buf[0][xPos + j], -x_fft_buf[1][xPos + j], 358 fft[2 * j] = MulRe(x_fft_buf[0][xPos + j], -x_fft_buf[1][xPos + j],
359 e_fft[0][j], e_fft[1][j]); 359 e_fft[0][j], e_fft[1][j]);
360 fft[2 * j + 1] = MulIm(x_fft_buf[0][xPos + j], -x_fft_buf[1][xPos + j], 360 fft[2 * j + 1] = MulIm(x_fft_buf[0][xPos + j], -x_fft_buf[1][xPos + j],
361 e_fft[0][j], e_fft[1][j]); 361 e_fft[0][j], e_fft[1][j]);
362 } 362 }
363 fft[1] = 363 fft[1] =
364 MulRe(x_fft_buf[0][xPos + PART_LEN], -x_fft_buf[1][xPos + PART_LEN], 364 MulRe(x_fft_buf[0][xPos + PART_LEN], -x_fft_buf[1][xPos + PART_LEN],
365 e_fft[0][PART_LEN], e_fft[1][PART_LEN]); 365 e_fft[0][PART_LEN], e_fft[1][PART_LEN]);
366 366
367 aec_rdft_inverse_128(fft); 367 ooura_fft.InverseFft(fft);
368 memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN); 368 memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN);
369 369
370 // fft scaling 370 // fft scaling
371 { 371 {
372 float scale = 2.0f / PART_LEN2; 372 float scale = 2.0f / PART_LEN2;
373 for (j = 0; j < PART_LEN; j++) { 373 for (j = 0; j < PART_LEN; j++) {
374 fft[j] *= scale; 374 fft[j] *= scale;
375 } 375 }
376 } 376 }
377 aec_rdft_forward_128(fft); 377 ooura_fft.Fft(fft);
378 378
379 h_fft_buf[0][pos] += fft[0]; 379 h_fft_buf[0][pos] += fft[0];
380 h_fft_buf[0][pos + PART_LEN] += fft[1]; 380 h_fft_buf[0][pos + PART_LEN] += fft[1];
381 381
382 for (j = 1; j < PART_LEN; j++) { 382 for (j = 1; j < PART_LEN; j++) {
383 h_fft_buf[0][pos + j] += fft[2 * j]; 383 h_fft_buf[0][pos + j] += fft[2 * j];
384 h_fft_buf[1][pos + j] += fft[2 * j + 1]; 384 h_fft_buf[1][pos + j] += fft[2 * j + 1];
385 } 385 }
386 } 386 }
387 } 387 }
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 static_cast<float>(num_delays_out_of_bounds) / self->num_delay_values; 828 static_cast<float>(num_delays_out_of_bounds) / self->num_delay_values;
829 } 829 }
830 830
831 // Reset histogram. 831 // Reset histogram.
832 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); 832 memset(self->delay_histogram, 0, sizeof(self->delay_histogram));
833 self->num_delay_values = 0; 833 self->num_delay_values = 0;
834 834
835 return; 835 return;
836 } 836 }
837 837
838 static void ScaledInverseFft(float freq_data[2][PART_LEN1], 838 static void ScaledInverseFft(const OouraFft& ooura_fft,
839 float freq_data[2][PART_LEN1],
839 float time_data[PART_LEN2], 840 float time_data[PART_LEN2],
840 float scale, 841 float scale,
841 int conjugate) { 842 int conjugate) {
842 int i; 843 int i;
843 const float normalization = scale / static_cast<float>(PART_LEN2); 844 const float normalization = scale / static_cast<float>(PART_LEN2);
844 const float sign = (conjugate ? -1 : 1); 845 const float sign = (conjugate ? -1 : 1);
845 time_data[0] = freq_data[0][0] * normalization; 846 time_data[0] = freq_data[0][0] * normalization;
846 time_data[1] = freq_data[0][PART_LEN] * normalization; 847 time_data[1] = freq_data[0][PART_LEN] * normalization;
847 for (i = 1; i < PART_LEN; i++) { 848 for (i = 1; i < PART_LEN; i++) {
848 time_data[2 * i] = freq_data[0][i] * normalization; 849 time_data[2 * i] = freq_data[0][i] * normalization;
849 time_data[2 * i + 1] = sign * freq_data[1][i] * normalization; 850 time_data[2 * i + 1] = sign * freq_data[1][i] * normalization;
850 } 851 }
851 aec_rdft_inverse_128(time_data); 852 ooura_fft.InverseFft(time_data);
852 } 853 }
853 854
854 static void Fft(float time_data[PART_LEN2], float freq_data[2][PART_LEN1]) { 855 static void Fft(const OouraFft& ooura_fft,
856 float time_data[PART_LEN2],
857 float freq_data[2][PART_LEN1]) {
855 int i; 858 int i;
856 aec_rdft_forward_128(time_data); 859 ooura_fft.Fft(time_data);
857 860
858 // Reorder fft output data. 861 // Reorder fft output data.
859 freq_data[1][0] = 0; 862 freq_data[1][0] = 0;
860 freq_data[1][PART_LEN] = 0; 863 freq_data[1][PART_LEN] = 0;
861 freq_data[0][0] = time_data[0]; 864 freq_data[0][0] = time_data[0];
862 freq_data[0][PART_LEN] = time_data[1]; 865 freq_data[0][PART_LEN] = time_data[1];
863 for (i = 1; i < PART_LEN; i++) { 866 for (i = 1; i < PART_LEN; i++) {
864 freq_data[0][i] = time_data[2 * i]; 867 freq_data[0][i] = time_data[2 * i];
865 freq_data[1][i] = time_data[2 * i + 1]; 868 freq_data[1][i] = time_data[2 * i + 1];
866 } 869 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 966
964 ++partition; 967 ++partition;
965 if (partition == num_partitions) { 968 if (partition == num_partitions) {
966 partition = 0; 969 partition = 0;
967 RTC_DCHECK_EQ(num_partitions * PART_LEN1, x_fft_buf_position); 970 RTC_DCHECK_EQ(num_partitions * PART_LEN1, x_fft_buf_position);
968 x_fft_buf_position = 0; 971 x_fft_buf_position = 0;
969 } 972 }
970 } 973 }
971 } 974 }
972 975
973 static void EchoSubtraction(int num_partitions, 976 static void EchoSubtraction(const OouraFft& ooura_fft,
977 int num_partitions,
974 int extended_filter_enabled, 978 int extended_filter_enabled,
975 int* extreme_filter_divergence, 979 int* extreme_filter_divergence,
976 float filter_step_size, 980 float filter_step_size,
977 float error_threshold, 981 float error_threshold,
978 float* x_fft, 982 float* x_fft,
979 int* x_fft_buf_block_pos, 983 int* x_fft_buf_block_pos,
980 float x_fft_buf[2] 984 float x_fft_buf[2]
981 [kExtendedNumPartitions * PART_LEN1], 985 [kExtendedNumPartitions * PART_LEN1],
982 float* const y, 986 float* const y,
983 float x_pow[PART_LEN1], 987 float x_pow[PART_LEN1],
(...skipping 28 matching lines...) Expand all
1012 memset(h_fft_buf, 0, 1016 memset(h_fft_buf, 0,
1013 2 * kExtendedNumPartitions * PART_LEN1 * sizeof(h_fft_buf[0][0])); 1017 2 * kExtendedNumPartitions * PART_LEN1 * sizeof(h_fft_buf[0][0]));
1014 *extreme_filter_divergence = 0; 1018 *extreme_filter_divergence = 0;
1015 } 1019 }
1016 1020
1017 // Produce echo estimate s_fft. 1021 // Produce echo estimate s_fft.
1018 WebRtcAec_FilterFar(num_partitions, *x_fft_buf_block_pos, x_fft_buf, 1022 WebRtcAec_FilterFar(num_partitions, *x_fft_buf_block_pos, x_fft_buf,
1019 h_fft_buf, s_fft); 1023 h_fft_buf, s_fft);
1020 1024
1021 // Compute the time-domain echo estimate s. 1025 // Compute the time-domain echo estimate s.
1022 ScaledInverseFft(s_fft, s_extended, 2.0f, 0); 1026 ScaledInverseFft(ooura_fft, s_fft, s_extended, 2.0f, 0);
1023 s = &s_extended[PART_LEN]; 1027 s = &s_extended[PART_LEN];
1024 1028
1025 // Compute the time-domain echo prediction error. 1029 // Compute the time-domain echo prediction error.
1026 for (i = 0; i < PART_LEN; ++i) { 1030 for (i = 0; i < PART_LEN; ++i) {
1027 e[i] = y[i] - s[i]; 1031 e[i] = y[i] - s[i];
1028 } 1032 }
1029 1033
1030 // Compute the frequency domain echo prediction error. 1034 // Compute the frequency domain echo prediction error.
1031 memset(e_extended, 0, sizeof(float) * PART_LEN); 1035 memset(e_extended, 0, sizeof(float) * PART_LEN);
1032 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); 1036 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN);
1033 Fft(e_extended, e_fft); 1037 Fft(ooura_fft, e_extended, e_fft);
1034 1038
1035 // Scale error signal inversely with far power. 1039 // Scale error signal inversely with far power.
1036 WebRtcAec_ScaleErrorSignal(filter_step_size, error_threshold, x_pow, e_fft); 1040 WebRtcAec_ScaleErrorSignal(filter_step_size, error_threshold, x_pow, e_fft);
1037 WebRtcAec_FilterAdaptation(num_partitions, *x_fft_buf_block_pos, x_fft_buf, 1041 WebRtcAec_FilterAdaptation(ooura_fft, num_partitions, *x_fft_buf_block_pos,
1038 e_fft, h_fft_buf); 1042 x_fft_buf, e_fft, h_fft_buf);
1039 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); 1043 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN);
1040 } 1044 }
1041 1045
1042 static void FormSuppressionGain(AecCore* aec, 1046 static void FormSuppressionGain(AecCore* aec,
1043 float cohde[PART_LEN1], 1047 float cohde[PART_LEN1],
1044 float cohxd[PART_LEN1], 1048 float cohxd[PART_LEN1],
1045 float hNl[PART_LEN1]) { 1049 float hNl[PART_LEN1]) {
1046 float hNlDeAvg, hNlXdAvg; 1050 float hNlDeAvg, hNlXdAvg;
1047 float hNlPref[kPrefBandSize]; 1051 float hNlPref[kPrefBandSize];
1048 float hNlFb = 0, hNlFbLow = 0; 1052 float hNlFb = 0, hNlFbLow = 0;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1145 0.99f * aec->overdrive_scaling + 0.01f * aec->overDrive; 1149 0.99f * aec->overdrive_scaling + 0.01f * aec->overDrive;
1146 } else { 1150 } else {
1147 aec->overdrive_scaling = 1151 aec->overdrive_scaling =
1148 0.9f * aec->overdrive_scaling + 0.1f * aec->overDrive; 1152 0.9f * aec->overdrive_scaling + 0.1f * aec->overDrive;
1149 } 1153 }
1150 1154
1151 // Apply the overdrive. 1155 // Apply the overdrive.
1152 WebRtcAec_Overdrive(aec->overdrive_scaling, hNlFb, hNl); 1156 WebRtcAec_Overdrive(aec->overdrive_scaling, hNlFb, hNl);
1153 } 1157 }
1154 1158
1155 static void EchoSuppression(AecCore* aec, 1159 static void EchoSuppression(const OouraFft& ooura_fft,
1160 AecCore* aec,
1156 float* nearend_extended_block_lowest_band, 1161 float* nearend_extended_block_lowest_band,
1157 float farend_extended_block[PART_LEN2], 1162 float farend_extended_block[PART_LEN2],
1158 float* echo_subtractor_output, 1163 float* echo_subtractor_output,
1159 float output[NUM_HIGH_BANDS_MAX + 1][PART_LEN]) { 1164 float output[NUM_HIGH_BANDS_MAX + 1][PART_LEN]) {
1160 float efw[2][PART_LEN1]; 1165 float efw[2][PART_LEN1];
1161 float xfw[2][PART_LEN1]; 1166 float xfw[2][PART_LEN1];
1162 float dfw[2][PART_LEN1]; 1167 float dfw[2][PART_LEN1];
1163 float comfortNoiseHband[2][PART_LEN1]; 1168 float comfortNoiseHband[2][PART_LEN1];
1164 float fft[PART_LEN2]; 1169 float fft[PART_LEN2];
1165 float nlpGainHband; 1170 float nlpGainHband;
1166 int i; 1171 int i;
1167 size_t j; 1172 size_t j;
1168 1173
1169 // Coherence and non-linear filter 1174 // Coherence and non-linear filter
1170 float cohde[PART_LEN1], cohxd[PART_LEN1]; 1175 float cohde[PART_LEN1], cohxd[PART_LEN1];
1171 float hNl[PART_LEN1]; 1176 float hNl[PART_LEN1];
1172 1177
1173 // Filter energy 1178 // Filter energy
1174 const int delayEstInterval = 10 * aec->mult; 1179 const int delayEstInterval = 10 * aec->mult;
1175 1180
1176 float* xfw_ptr = NULL; 1181 float* xfw_ptr = NULL;
1177 1182
1178 // Update eBuf with echo subtractor output. 1183 // Update eBuf with echo subtractor output.
1179 memcpy(aec->eBuf + PART_LEN, echo_subtractor_output, 1184 memcpy(aec->eBuf + PART_LEN, echo_subtractor_output,
1180 sizeof(float) * PART_LEN); 1185 sizeof(float) * PART_LEN);
1181 1186
1182 // Analysis filter banks for the echo suppressor. 1187 // Analysis filter banks for the echo suppressor.
1183 // Windowed near-end ffts. 1188 // Windowed near-end ffts.
1184 WindowData(fft, nearend_extended_block_lowest_band); 1189 WindowData(fft, nearend_extended_block_lowest_band);
1185 aec_rdft_forward_128(fft); 1190 ooura_fft.Fft(fft);
1186 StoreAsComplex(fft, dfw); 1191 StoreAsComplex(fft, dfw);
1187 1192
1188 // Windowed echo suppressor output ffts. 1193 // Windowed echo suppressor output ffts.
1189 WindowData(fft, aec->eBuf); 1194 WindowData(fft, aec->eBuf);
1190 aec_rdft_forward_128(fft); 1195 ooura_fft.Fft(fft);
1191 StoreAsComplex(fft, efw); 1196 StoreAsComplex(fft, efw);
1192 1197
1193 // NLP 1198 // NLP
1194 1199
1195 // Convert far-end partition to the frequency domain with windowing. 1200 // Convert far-end partition to the frequency domain with windowing.
1196 WindowData(fft, farend_extended_block); 1201 WindowData(fft, farend_extended_block);
1197 Fft(fft, xfw); 1202 Fft(ooura_fft, fft, xfw);
1198 xfw_ptr = &xfw[0][0]; 1203 xfw_ptr = &xfw[0][0];
1199 1204
1200 // Buffer far. 1205 // Buffer far.
1201 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); 1206 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1);
1202 1207
1203 aec->delayEstCtr++; 1208 aec->delayEstCtr++;
1204 if (aec->delayEstCtr == delayEstInterval) { 1209 if (aec->delayEstCtr == delayEstInterval) {
1205 aec->delayEstCtr = 0; 1210 aec->delayEstCtr = 0;
1206 aec->delayIdx = WebRtcAec_PartitionDelay(aec->num_partitions, aec->wfBuf); 1211 aec->delayIdx = WebRtcAec_PartitionDelay(aec->num_partitions, aec->wfBuf);
1207 } 1212 }
(...skipping 21 matching lines...) Expand all
1229 1234
1230 aec->data_dumper->DumpRaw("aec_nlp_gain", PART_LEN1, hNl); 1235 aec->data_dumper->DumpRaw("aec_nlp_gain", PART_LEN1, hNl);
1231 1236
1232 WebRtcAec_Suppress(hNl, efw); 1237 WebRtcAec_Suppress(hNl, efw);
1233 1238
1234 // Add comfort noise. 1239 // Add comfort noise.
1235 ComfortNoise(aec->num_bands > 1, &aec->seed, efw, comfortNoiseHband, 1240 ComfortNoise(aec->num_bands > 1, &aec->seed, efw, comfortNoiseHband,
1236 aec->noisePow, hNl); 1241 aec->noisePow, hNl);
1237 1242
1238 // Inverse error fft. 1243 // Inverse error fft.
1239 ScaledInverseFft(efw, fft, 2.0f, 1); 1244 ScaledInverseFft(ooura_fft, efw, fft, 2.0f, 1);
1240 1245
1241 // Overlap and add to obtain output. 1246 // Overlap and add to obtain output.
1242 for (i = 0; i < PART_LEN; i++) { 1247 for (i = 0; i < PART_LEN; i++) {
1243 output[0][i] = (fft[i] * WebRtcAec_sqrtHanning[i] + 1248 output[0][i] = (fft[i] * WebRtcAec_sqrtHanning[i] +
1244 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]); 1249 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]);
1245 1250
1246 // Saturate output to keep it in the allowed range. 1251 // Saturate output to keep it in the allowed range.
1247 output[0][i] = WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, output[0][i], 1252 output[0][i] = WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, output[0][i],
1248 WEBRTC_SPL_WORD16_MIN); 1253 WEBRTC_SPL_WORD16_MIN);
1249 } 1254 }
1250 memcpy(aec->outBuf, &fft[PART_LEN], PART_LEN * sizeof(aec->outBuf[0])); 1255 memcpy(aec->outBuf, &fft[PART_LEN], PART_LEN * sizeof(aec->outBuf[0]));
1251 1256
1252 // For H band 1257 // For H band
1253 if (aec->num_bands > 1) { 1258 if (aec->num_bands > 1) {
1254 // H band gain 1259 // H band gain
1255 // average nlp over low band: average over second half of freq spectrum 1260 // average nlp over low band: average over second half of freq spectrum
1256 // (4->8khz) 1261 // (4->8khz)
1257 GetHighbandGain(hNl, &nlpGainHband); 1262 GetHighbandGain(hNl, &nlpGainHband);
1258 1263
1259 // Inverse comfort_noise 1264 // Inverse comfort_noise
1260 ScaledInverseFft(comfortNoiseHband, fft, 2.0f, 0); 1265 ScaledInverseFft(ooura_fft, comfortNoiseHband, fft, 2.0f, 0);
1261 1266
1262 // compute gain factor 1267 // compute gain factor
1263 for (j = 1; j < aec->num_bands; ++j) { 1268 for (j = 1; j < aec->num_bands; ++j) {
1264 for (i = 0; i < PART_LEN; i++) { 1269 for (i = 0; i < PART_LEN; i++) {
1265 output[j][i] = aec->previous_nearend_block[j][i] * nlpGainHband; 1270 output[j][i] = aec->previous_nearend_block[j][i] * nlpGainHband;
1266 } 1271 }
1267 } 1272 }
1268 1273
1269 // Add some comfort noise where Hband is attenuated. 1274 // Add some comfort noise where Hband is attenuated.
1270 for (i = 0; i < PART_LEN; i++) { 1275 for (i = 0; i < PART_LEN; i++) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1323 // Update power levels 1328 // Update power levels
1324 UpdateLevel( 1329 UpdateLevel(
1325 &aec->farlevel, 1330 &aec->farlevel,
1326 CalculatePower(&farend_extended_block_lowest_band[PART_LEN], PART_LEN)); 1331 CalculatePower(&farend_extended_block_lowest_band[PART_LEN], PART_LEN));
1327 UpdateLevel(&aec->nearlevel, 1332 UpdateLevel(&aec->nearlevel,
1328 CalculatePower(&nearend_block[0][0], PART_LEN)); 1333 CalculatePower(&nearend_block[0][0], PART_LEN));
1329 } 1334 }
1330 1335
1331 // Convert far-end signal to the frequency domain. 1336 // Convert far-end signal to the frequency domain.
1332 memcpy(fft, farend_extended_block_lowest_band, sizeof(float) * PART_LEN2); 1337 memcpy(fft, farend_extended_block_lowest_band, sizeof(float) * PART_LEN2);
1333 Fft(fft, farend_fft); 1338 Fft(aec->ooura_fft, fft, farend_fft);
1334 1339
1335 // Form extended nearend frame. 1340 // Form extended nearend frame.
1336 memcpy(&nearend_extended_block_lowest_band[0], 1341 memcpy(&nearend_extended_block_lowest_band[0],
1337 &aec->previous_nearend_block[0][0], sizeof(float) * PART_LEN); 1342 &aec->previous_nearend_block[0][0], sizeof(float) * PART_LEN);
1338 memcpy(&nearend_extended_block_lowest_band[PART_LEN], &nearend_block[0][0], 1343 memcpy(&nearend_extended_block_lowest_band[PART_LEN], &nearend_block[0][0],
1339 sizeof(float) * PART_LEN); 1344 sizeof(float) * PART_LEN);
1340 1345
1341 // Convert near-end signal to the frequency domain. 1346 // Convert near-end signal to the frequency domain.
1342 memcpy(fft, nearend_extended_block_lowest_band, sizeof(float) * PART_LEN2); 1347 memcpy(fft, nearend_extended_block_lowest_band, sizeof(float) * PART_LEN2);
1343 Fft(fft, nearend_fft); 1348 Fft(aec->ooura_fft, fft, nearend_fft);
1344 1349
1345 // Power smoothing. 1350 // Power smoothing.
1346 if (aec->refined_adaptive_filter_enabled) { 1351 if (aec->refined_adaptive_filter_enabled) {
1347 for (i = 0; i < PART_LEN1; ++i) { 1352 for (i = 0; i < PART_LEN1; ++i) {
1348 far_spectrum = farend_fft[0][i] * farend_fft[0][i] + 1353 far_spectrum = farend_fft[0][i] * farend_fft[0][i] +
1349 farend_fft[1][i] * farend_fft[1][i]; 1354 farend_fft[1][i] * farend_fft[1][i];
1350 // Calculate the magnitude spectrum. 1355 // Calculate the magnitude spectrum.
1351 abs_far_spectrum[i] = sqrtf(far_spectrum); 1356 abs_far_spectrum[i] = sqrtf(far_spectrum);
1352 } 1357 }
1353 RegressorPower(aec->num_partitions, aec->xfBufBlockPos, aec->xfBuf, 1358 RegressorPower(aec->num_partitions, aec->xfBufBlockPos, aec->xfBuf,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 aec->num_delay_values++; 1417 aec->num_delay_values++;
1413 } 1418 }
1414 if (aec->delay_metrics_delivered == 1 && 1419 if (aec->delay_metrics_delivered == 1 &&
1415 aec->num_delay_values >= kDelayMetricsAggregationWindow) { 1420 aec->num_delay_values >= kDelayMetricsAggregationWindow) {
1416 UpdateDelayMetrics(aec); 1421 UpdateDelayMetrics(aec);
1417 } 1422 }
1418 } 1423 }
1419 } 1424 }
1420 1425
1421 // Perform echo subtraction. 1426 // Perform echo subtraction.
1422 EchoSubtraction(aec->num_partitions, aec->extended_filter_enabled, 1427 EchoSubtraction(
1423 &aec->extreme_filter_divergence, aec->filter_step_size, 1428 aec->ooura_fft, aec->num_partitions, aec->extended_filter_enabled,
1424 aec->error_threshold, &farend_fft[0][0], &aec->xfBufBlockPos, 1429 &aec->extreme_filter_divergence, aec->filter_step_size,
1425 aec->xfBuf, &nearend_block[0][0], aec->xPow, aec->wfBuf, 1430 aec->error_threshold, &farend_fft[0][0], &aec->xfBufBlockPos, aec->xfBuf,
1426 echo_subtractor_output); 1431 &nearend_block[0][0], aec->xPow, aec->wfBuf, echo_subtractor_output);
1427 aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions, 1432 aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions,
1428 &aec->wfBuf[0][0]); 1433 &aec->wfBuf[0][0]);
1429 aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions, 1434 aec->data_dumper->DumpRaw("aec_h_fft", PART_LEN1 * aec->num_partitions,
1430 &aec->wfBuf[1][0]); 1435 &aec->wfBuf[1][0]);
1431 1436
1432 aec->data_dumper->DumpWav("aec_out_linear", PART_LEN, echo_subtractor_output, 1437 aec->data_dumper->DumpWav("aec_out_linear", PART_LEN, echo_subtractor_output,
1433 std::min(aec->sampFreq, 16000), 1); 1438 std::min(aec->sampFreq, 16000), 1);
1434 1439
1435 if (aec->metricsMode == 1) { 1440 if (aec->metricsMode == 1) {
1436 UpdateLevel(&aec->linoutlevel, 1441 UpdateLevel(&aec->linoutlevel,
1437 CalculatePower(echo_subtractor_output, PART_LEN)); 1442 CalculatePower(echo_subtractor_output, PART_LEN));
1438 } 1443 }
1439 1444
1440 // Perform echo suppression. 1445 // Perform echo suppression.
1441 EchoSuppression(aec, nearend_extended_block_lowest_band, 1446 EchoSuppression(aec->ooura_fft, aec, nearend_extended_block_lowest_band,
1442 farend_extended_block_lowest_band, echo_subtractor_output, 1447 farend_extended_block_lowest_band, echo_subtractor_output,
1443 output_block); 1448 output_block);
1444 1449
1445 if (aec->metricsMode == 1) { 1450 if (aec->metricsMode == 1) {
1446 UpdateLevel(&aec->nlpoutlevel, 1451 UpdateLevel(&aec->nlpoutlevel,
1447 CalculatePower(&output_block[0][0], PART_LEN)); 1452 CalculatePower(&output_block[0][0], PART_LEN));
1448 UpdateMetrics(aec); 1453 UpdateMetrics(aec);
1449 } 1454 }
1450 1455
1451 // Store the nearend signal until the next frame. 1456 // Store the nearend signal until the next frame.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1517 #endif 1522 #endif
1518 1523
1519 #if defined(MIPS_FPU_LE) 1524 #if defined(MIPS_FPU_LE)
1520 WebRtcAec_InitAec_mips(); 1525 WebRtcAec_InitAec_mips();
1521 #endif 1526 #endif
1522 1527
1523 #if defined(WEBRTC_HAS_NEON) 1528 #if defined(WEBRTC_HAS_NEON)
1524 WebRtcAec_InitAec_neon(); 1529 WebRtcAec_InitAec_neon();
1525 #endif 1530 #endif
1526 1531
1527 aec_rdft_init();
1528
1529 return aec; 1532 return aec;
1530 } 1533 }
1531 1534
1532 void WebRtcAec_FreeAec(AecCore* aec) { 1535 void WebRtcAec_FreeAec(AecCore* aec) {
1533 if (aec == NULL) { 1536 if (aec == NULL) {
1534 return; 1537 return;
1535 } 1538 }
1536 1539
1537 WebRtc_FreeDelayEstimator(aec->delay_estimator); 1540 WebRtc_FreeDelayEstimator(aec->delay_estimator);
1538 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); 1541 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend);
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
2046 2049
2047 int WebRtcAec_system_delay(AecCore* self) { 2050 int WebRtcAec_system_delay(AecCore* self) {
2048 return self->system_delay; 2051 return self->system_delay;
2049 } 2052 }
2050 2053
2051 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 2054 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
2052 RTC_DCHECK_GE(delay, 0); 2055 RTC_DCHECK_GE(delay, 0);
2053 self->system_delay = delay; 2056 self->system_delay = delay;
2054 } 2057 }
2055 } // namespace webrtc 2058 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_processing/aec/aec_core.h ('k') | webrtc/modules/audio_processing/aec/aec_core_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698