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

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

Issue 1456123003: Ducking fix #3: Removed the state as an input to the FilterAdaptation function (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@Aec_Code_Cleanup2_CL
Patch Set: Removed gcc build-breaking method argument specifiers Created 5 years 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 | webrtc/modules/audio_processing/aec/aec_core_internal.h » ('j') | 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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 return aRe * bIm + aIm * bRe; 144 return aRe * bIm + aIm * bRe;
145 } 145 }
146 146
147 static int CmpFloat(const void* a, const void* b) { 147 static int CmpFloat(const void* a, const void* b) {
148 const float* da = (const float*)a; 148 const float* da = (const float*)a;
149 const float* db = (const float*)b; 149 const float* db = (const float*)b;
150 150
151 return (*da > *db) - (*da < *db); 151 return (*da > *db) - (*da < *db);
152 } 152 }
153 153
154 static void FilterFar(int num_partitions, 154 static void FilterFar(
155 int x_fft_buffer_block_pos, 155 int num_partitions,
156 float x_fft_buffer[2][kExtendedNumPartitions * PART_LEN1], 156 int x_fft_buf_block_pos,
157 float h_fft_buffer[2][kExtendedNumPartitions * PART_LEN1], 157 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
158 float y_fft[2][PART_LEN1]) { 158 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
159 float y_fft[2][PART_LEN1]) {
159 int i; 160 int i;
160 for (i = 0; i < num_partitions; i++) { 161 for (i = 0; i < num_partitions; i++) {
161 int j; 162 int j;
162 int x_pos = (i + x_fft_buffer_block_pos) * PART_LEN1; 163 int xPos = (i + x_fft_buf_block_pos) * PART_LEN1;
163 int pos = i * PART_LEN1; 164 int pos = i * PART_LEN1;
164 // Check for wrapped buffer. 165 // Check for wrap
165 if (i + x_fft_buffer_block_pos >= num_partitions) { 166 if (i + x_fft_buf_block_pos >= num_partitions) {
166 x_pos -= num_partitions * (PART_LEN1); 167 xPos -= num_partitions * (PART_LEN1);
167 } 168 }
168 169
169 for (j = 0; j < PART_LEN1; j++) { 170 for (j = 0; j < PART_LEN1; j++) {
170 y_fft[0][j] += MulRe(x_fft_buffer[0][x_pos + j], 171 y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j],
171 x_fft_buffer[1][x_pos + j], 172 x_fft_buf[1][xPos + j],
172 h_fft_buffer[0][pos + j], 173 h_fft_buf[0][pos + j],
173 h_fft_buffer[1][pos + j]); 174 h_fft_buf[1][pos + j]);
174 y_fft[1][j] += MulIm(x_fft_buffer[0][x_pos + j], 175 y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j],
175 x_fft_buffer[1][x_pos + j], 176 x_fft_buf[1][xPos + j],
176 h_fft_buffer[0][pos + j], 177 h_fft_buf[0][pos + j],
177 h_fft_buffer[1][pos + j]); 178 h_fft_buf[1][pos + j]);
178 } 179 }
179 } 180 }
180 } 181 }
181 182
182 static void ScaleErrorSignal(int extended_filter_enabled, 183 static void ScaleErrorSignal(int extended_filter_enabled,
183 float normal_mu, 184 float normal_mu,
184 float normal_error_threshold, 185 float normal_error_threshold,
185 float *x_pow, 186 float x_pow[PART_LEN1],
186 float ef[2][PART_LEN1]) { 187 float ef[2][PART_LEN1]) {
187 const float mu = extended_filter_enabled ? kExtendedMu : normal_mu; 188 const float mu = extended_filter_enabled ? kExtendedMu : normal_mu;
188 const float error_threshold = extended_filter_enabled 189 const float error_threshold = extended_filter_enabled
189 ? kExtendedErrorThreshold 190 ? kExtendedErrorThreshold
190 : normal_error_threshold; 191 : normal_error_threshold;
191 int i; 192 int i;
192 float abs_ef; 193 float abs_ef;
193 for (i = 0; i < (PART_LEN1); i++) { 194 for (i = 0; i < (PART_LEN1); i++) {
194 ef[0][i] /= (x_pow[i] + 1e-10f); 195 ef[0][i] /= (x_pow[i] + 1e-10f);
195 ef[1][i] /= (x_pow[i] + 1e-10f); 196 ef[1][i] /= (x_pow[i] + 1e-10f);
196 abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]); 197 abs_ef = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]);
197 198
198 if (abs_ef > error_threshold) { 199 if (abs_ef > error_threshold) {
199 abs_ef = error_threshold / (abs_ef + 1e-10f); 200 abs_ef = error_threshold / (abs_ef + 1e-10f);
200 ef[0][i] *= abs_ef; 201 ef[0][i] *= abs_ef;
201 ef[1][i] *= abs_ef; 202 ef[1][i] *= abs_ef;
202 } 203 }
203 204
204 // Stepsize factor 205 // Stepsize factor
205 ef[0][i] *= mu; 206 ef[0][i] *= mu;
206 ef[1][i] *= mu; 207 ef[1][i] *= mu;
207 } 208 }
208 } 209 }
209 210
210 // Time-unconstrined filter adaptation.
211 // TODO(andrew): consider for a low-complexity mode.
212 // static void FilterAdaptationUnconstrained(AecCore* aec, float *fft,
213 // float ef[2][PART_LEN1]) {
214 // int i, j;
215 // for (i = 0; i < aec->num_partitions; i++) {
216 // int xPos = (i + aec->xfBufBlockPos)*(PART_LEN1);
217 // int pos;
218 // // Check for wrap
219 // if (i + aec->xfBufBlockPos >= aec->num_partitions) {
220 // xPos -= aec->num_partitions * PART_LEN1;
221 // }
222 //
223 // pos = i * PART_LEN1;
224 //
225 // for (j = 0; j < PART_LEN1; j++) {
226 // aec->wfBuf[0][pos + j] += MulRe(aec->xfBuf[0][xPos + j],
227 // -aec->xfBuf[1][xPos + j],
228 // ef[0][j], ef[1][j]);
229 // aec->wfBuf[1][pos + j] += MulIm(aec->xfBuf[0][xPos + j],
230 // -aec->xfBuf[1][xPos + j],
231 // ef[0][j], ef[1][j]);
232 // }
233 // }
234 //}
235 211
236 static void FilterAdaptation(AecCore* aec, float* fft, float ef[2][PART_LEN1]) { 212 static void FilterAdaptation(
213 int num_partitions,
214 int x_fft_buf_block_pos,
215 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
216 float e_fft[2][PART_LEN1],
217 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) {
237 int i, j; 218 int i, j;
238 for (i = 0; i < aec->num_partitions; i++) { 219 float fft[PART_LEN2];
239 int xPos = (i + aec->xfBufBlockPos) * (PART_LEN1); 220 for (i = 0; i < num_partitions; i++) {
221 int xPos = (i + x_fft_buf_block_pos) * (PART_LEN1);
240 int pos; 222 int pos;
241 // Check for wrap 223 // Check for wrap
242 if (i + aec->xfBufBlockPos >= aec->num_partitions) { 224 if (i + x_fft_buf_block_pos >= num_partitions) {
243 xPos -= aec->num_partitions * PART_LEN1; 225 xPos -= num_partitions * PART_LEN1;
244 } 226 }
245 227
246 pos = i * PART_LEN1; 228 pos = i * PART_LEN1;
247 229
248 for (j = 0; j < PART_LEN; j++) { 230 for (j = 0; j < PART_LEN; j++) {
249 231
250 fft[2 * j] = MulRe(aec->xfBuf[0][xPos + j], 232 fft[2 * j] = MulRe(x_fft_buf[0][xPos + j],
251 -aec->xfBuf[1][xPos + j], 233 -x_fft_buf[1][xPos + j],
252 ef[0][j], 234 e_fft[0][j],
253 ef[1][j]); 235 e_fft[1][j]);
254 fft[2 * j + 1] = MulIm(aec->xfBuf[0][xPos + j], 236 fft[2 * j + 1] = MulIm(x_fft_buf[0][xPos + j],
255 -aec->xfBuf[1][xPos + j], 237 -x_fft_buf[1][xPos + j],
256 ef[0][j], 238 e_fft[0][j],
257 ef[1][j]); 239 e_fft[1][j]);
258 } 240 }
259 fft[1] = MulRe(aec->xfBuf[0][xPos + PART_LEN], 241 fft[1] = MulRe(x_fft_buf[0][xPos + PART_LEN],
260 -aec->xfBuf[1][xPos + PART_LEN], 242 -x_fft_buf[1][xPos + PART_LEN],
261 ef[0][PART_LEN], 243 e_fft[0][PART_LEN],
262 ef[1][PART_LEN]); 244 e_fft[1][PART_LEN]);
263 245
264 aec_rdft_inverse_128(fft); 246 aec_rdft_inverse_128(fft);
265 memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN); 247 memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN);
266 248
267 // fft scaling 249 // fft scaling
268 { 250 {
269 float scale = 2.0f / PART_LEN2; 251 float scale = 2.0f / PART_LEN2;
270 for (j = 0; j < PART_LEN; j++) { 252 for (j = 0; j < PART_LEN; j++) {
271 fft[j] *= scale; 253 fft[j] *= scale;
272 } 254 }
273 } 255 }
274 aec_rdft_forward_128(fft); 256 aec_rdft_forward_128(fft);
275 257
276 aec->wfBuf[0][pos] += fft[0]; 258 h_fft_buf[0][pos] += fft[0];
277 aec->wfBuf[0][pos + PART_LEN] += fft[1]; 259 h_fft_buf[0][pos + PART_LEN] += fft[1];
278 260
279 for (j = 1; j < PART_LEN; j++) { 261 for (j = 1; j < PART_LEN; j++) {
280 aec->wfBuf[0][pos + j] += fft[2 * j]; 262 h_fft_buf[0][pos + j] += fft[2 * j];
281 aec->wfBuf[1][pos + j] += fft[2 * j + 1]; 263 h_fft_buf[1][pos + j] += fft[2 * j + 1];
282 } 264 }
283 } 265 }
284 } 266 }
285 267
286 static void OverdriveAndSuppress(AecCore* aec, 268 static void OverdriveAndSuppress(AecCore* aec,
287 float hNl[PART_LEN1], 269 float hNl[PART_LEN1],
288 const float hNlFb, 270 const float hNlFb,
289 float efw[2][PART_LEN1]) { 271 float efw[2][PART_LEN1]) {
290 int i; 272 int i;
291 for (i = 0; i < PART_LEN1; i++) { 273 for (i = 0; i < PART_LEN1; i++) {
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 self->num_delay_values; 820 self->num_delay_values;
839 } 821 }
840 822
841 // Reset histogram. 823 // Reset histogram.
842 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); 824 memset(self->delay_histogram, 0, sizeof(self->delay_histogram));
843 self->num_delay_values = 0; 825 self->num_delay_values = 0;
844 826
845 return; 827 return;
846 } 828 }
847 829
848 static void FrequencyToTime(float freq_data[2][PART_LEN1], 830 static void InverseFft(float freq_data[2][PART_LEN1],
849 float time_data[PART_LEN2]) { 831 float time_data[PART_LEN2]) {
850 int i; 832 int i;
851 time_data[0] = freq_data[0][0]; 833 const float scale = 1.0f / PART_LEN2;
852 time_data[1] = freq_data[0][PART_LEN]; 834 time_data[0] = freq_data[0][0] * scale;
835 time_data[1] = freq_data[0][PART_LEN] * scale;
853 for (i = 1; i < PART_LEN; i++) { 836 for (i = 1; i < PART_LEN; i++) {
854 time_data[2 * i] = freq_data[0][i]; 837 time_data[2 * i] = freq_data[0][i] * scale;
855 time_data[2 * i + 1] = freq_data[1][i]; 838 time_data[2 * i + 1] = freq_data[1][i] * scale;
856 } 839 }
857 aec_rdft_inverse_128(time_data); 840 aec_rdft_inverse_128(time_data);
858 } 841 }
859 842
860 843
861 static void TimeToFrequency(float time_data[PART_LEN2], 844 static void Fft(float time_data[PART_LEN2],
862 float freq_data[2][PART_LEN1], 845 float freq_data[2][PART_LEN1]) {
863 int window) { 846 int i;
864 int i = 0; 847 aec_rdft_forward_128(time_data);
865 848
866 // TODO(bjornv): Should we have a different function/wrapper for windowed FFT? 849 // Reorder fft output data.
867 if (window) {
868 for (i = 0; i < PART_LEN; i++) {
869 time_data[i] *= WebRtcAec_sqrtHanning[i];
870 time_data[PART_LEN + i] *= WebRtcAec_sqrtHanning[PART_LEN - i];
871 }
872 }
873
874 aec_rdft_forward_128(time_data);
875 // Reorder.
876 freq_data[1][0] = 0; 850 freq_data[1][0] = 0;
877 freq_data[1][PART_LEN] = 0; 851 freq_data[1][PART_LEN] = 0;
878 freq_data[0][0] = time_data[0]; 852 freq_data[0][0] = time_data[0];
879 freq_data[0][PART_LEN] = time_data[1]; 853 freq_data[0][PART_LEN] = time_data[1];
880 for (i = 1; i < PART_LEN; i++) { 854 for (i = 1; i < PART_LEN; i++) {
881 freq_data[0][i] = time_data[2 * i]; 855 freq_data[0][i] = time_data[2 * i];
882 freq_data[1][i] = time_data[2 * i + 1]; 856 freq_data[1][i] = time_data[2 * i + 1];
883 } 857 }
884 } 858 }
885 859
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); 930 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator);
957 delay_quality = (delay_quality > kDelayQualityThresholdMax ? 931 delay_quality = (delay_quality > kDelayQualityThresholdMax ?
958 kDelayQualityThresholdMax : delay_quality); 932 kDelayQualityThresholdMax : delay_quality);
959 self->delay_quality_threshold = 933 self->delay_quality_threshold =
960 (delay_quality > self->delay_quality_threshold ? delay_quality : 934 (delay_quality > self->delay_quality_threshold ? delay_quality :
961 self->delay_quality_threshold); 935 self->delay_quality_threshold);
962 } 936 }
963 return delay_correction; 937 return delay_correction;
964 } 938 }
965 939
966 static void EchoSubtraction(AecCore* aec, 940 static void EchoSubtraction(
967 float* nearend_ptr) { 941 AecCore* aec,
968 float yf[2][PART_LEN1]; 942 int num_partitions,
969 float fft[PART_LEN2]; 943 int x_fft_buf_block_pos,
970 float y[PART_LEN]; 944 int metrics_mode,
945 int extended_filter_enabled,
946 float normal_mu,
947 float normal_error_threshold,
948 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
949 float* const y,
950 float x_pow[PART_LEN1],
951 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1],
952 PowerLevel* linout_level,
953 float echo_subtractor_output[PART_LEN]) {
954 float s_fft[2][PART_LEN1];
955 float e_extended[PART_LEN2];
956 float s_extended[PART_LEN2];
957 float *s;
971 float e[PART_LEN]; 958 float e[PART_LEN];
972 float ef[2][PART_LEN1]; 959 float e_fft[2][PART_LEN1];
973 float scale;
974 int i; 960 int i;
975 memset(yf, 0, sizeof(yf)); 961 memset(s_fft, 0, sizeof(s_fft));
976 962
977 // Produce frequency domain echo estimate. 963 // Produce echo estimate s_fft.
978 WebRtcAec_FilterFar(aec->num_partitions, 964 WebRtcAec_FilterFar(num_partitions,
979 aec->xfBufBlockPos, 965 x_fft_buf_block_pos,
980 aec->xfBuf, 966 x_fft_buf,
981 aec->wfBuf, 967 h_fft_buf,
982 yf); 968 s_fft);
983 969
984 // Inverse fft to obtain echo estimate and error. 970 // Compute the time-domain echo estimate s.
985 FrequencyToTime(yf, fft); 971 InverseFft(s_fft, s_extended);
986 972 s = &s_extended[PART_LEN];
987 // Extract the output signal and compute the time-domain error.
988 scale = 2.0f / PART_LEN2;
989 for (i = 0; i < PART_LEN; ++i) { 973 for (i = 0; i < PART_LEN; ++i) {
990 y[i] = fft[PART_LEN + i] * scale; // fft scaling. 974 s[i] *= 2.0f;
991 e[i] = nearend_ptr[i] - y[i];
992 } 975 }
993 976
994 // Error fft 977 // Compute the time-domain echo prediction error.
995 memcpy(aec->eBuf + PART_LEN, e, sizeof(float) * PART_LEN); 978 for (i = 0; i < PART_LEN; ++i) {
996 memset(fft, 0, sizeof(float) * PART_LEN); 979 e[i] = y[i] - s[i];
997 memcpy(fft + PART_LEN, e, sizeof(float) * PART_LEN); 980 }
998 TimeToFrequency(fft, ef, 0); 981
982 // Compute the frequency domain echo prediction error.
983 memset(e_extended, 0, sizeof(float) * PART_LEN);
984 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN);
985 Fft(e_extended, e_fft);
999 986
1000 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, 987 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file,
1001 &ef[0][0], 988 &e_fft[0][0],
1002 sizeof(ef[0][0]) * PART_LEN1 * 2); 989 sizeof(e_fft[0][0]) * PART_LEN1 * 2);
1003 990
1004 if (aec->metricsMode == 1) { 991 if (metrics_mode == 1) {
1005 // Note that the first PART_LEN samples in fft (before transformation) are 992 // Note that the first PART_LEN samples in fft (before transformation) are
1006 // zero. Hence, the scaling by two in UpdateLevel() should not be 993 // zero. Hence, the scaling by two in UpdateLevel() should not be
1007 // performed. That scaling is taken care of in UpdateMetrics() instead. 994 // performed. That scaling is taken care of in UpdateMetrics() instead.
1008 UpdateLevel(&aec->linoutlevel, ef); 995 UpdateLevel(linout_level, e_fft);
1009 } 996 }
1010 997
1011 // Scale error signal inversely with far power. 998 // Scale error signal inversely with far power.
1012 WebRtcAec_ScaleErrorSignal(aec->extended_filter_enabled, 999 WebRtcAec_ScaleErrorSignal(extended_filter_enabled,
1013 aec->normal_mu, 1000 normal_mu,
1014 aec->normal_error_threshold, 1001 normal_error_threshold,
1015 aec->xPow, 1002 x_pow,
1016 ef); 1003 e_fft);
1017 WebRtcAec_FilterAdaptation(aec, fft, ef); 1004 WebRtcAec_FilterAdaptation(num_partitions,
1018 1005 x_fft_buf_block_pos,
1019 1006 x_fft_buf,
1020 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, e, PART_LEN); 1007 e_fft,
1008 h_fft_buf);
1009 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN);
1021 } 1010 }
1022 1011
1023 1012
1024 static void EchoSuppression(AecCore* aec, 1013 static void EchoSuppression(AecCore* aec,
1025 float* output, 1014 float* output,
1026 float* const* outputH) { 1015 float* const* outputH) {
1027 float efw[2][PART_LEN1], xfw[2][PART_LEN1]; 1016 float efw[2][PART_LEN1], xfw[2][PART_LEN1];
1028 complex_t comfortNoiseHband[PART_LEN1]; 1017 complex_t comfortNoiseHband[PART_LEN1];
1029 float fft[PART_LEN2]; 1018 float fft[PART_LEN2];
1030 float scale, dtmp; 1019 float scale, dtmp;
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 1256
1268 const float gPow[2] = {0.9f, 0.1f}; 1257 const float gPow[2] = {0.9f, 0.1f};
1269 1258
1270 // Noise estimate constants. 1259 // Noise estimate constants.
1271 const int noiseInitBlocks = 500 * aec->mult; 1260 const int noiseInitBlocks = 500 * aec->mult;
1272 const float step = 0.1f; 1261 const float step = 0.1f;
1273 const float ramp = 1.0002f; 1262 const float ramp = 1.0002f;
1274 const float gInitNoise[2] = {0.999f, 0.001f}; 1263 const float gInitNoise[2] = {0.999f, 0.001f};
1275 1264
1276 float nearend[PART_LEN]; 1265 float nearend[PART_LEN];
1266 float echo_subtractor_output[PART_LEN];
1277 float* nearend_ptr = NULL; 1267 float* nearend_ptr = NULL;
1278 float output[PART_LEN]; 1268 float output[PART_LEN];
1279 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; 1269 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN];
1280 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; 1270 float* outputH_ptr[NUM_HIGH_BANDS_MAX];
1281 float* xf_ptr = NULL; 1271 float* xf_ptr = NULL;
1282 1272
1283 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { 1273 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) {
1284 outputH_ptr[i] = outputH[i]; 1274 outputH_ptr[i] = outputH[i];
1285 } 1275 }
1286 1276
(...skipping 19 matching lines...) Expand all
1306 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN); 1296 RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN);
1307 } 1297 }
1308 #endif 1298 #endif
1309 1299
1310 // We should always have at least one element stored in |far_buf|. 1300 // We should always have at least one element stored in |far_buf|.
1311 assert(WebRtc_available_read(aec->far_buf) > 0); 1301 assert(WebRtc_available_read(aec->far_buf) > 0);
1312 WebRtc_ReadBuffer(aec->far_buf, (void**)&xf_ptr, &xf[0][0], 1); 1302 WebRtc_ReadBuffer(aec->far_buf, (void**)&xf_ptr, &xf[0][0], 1);
1313 1303
1314 // Near fft 1304 // Near fft
1315 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); 1305 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2);
1316 TimeToFrequency(fft, df, 0); 1306 Fft(fft, df);
1317 1307
1318 // Power smoothing 1308 // Power smoothing
1319 for (i = 0; i < PART_LEN1; i++) { 1309 for (i = 0; i < PART_LEN1; i++) {
1320 far_spectrum = (xf_ptr[i] * xf_ptr[i]) + 1310 far_spectrum = (xf_ptr[i] * xf_ptr[i]) +
1321 (xf_ptr[PART_LEN1 + i] * xf_ptr[PART_LEN1 + i]); 1311 (xf_ptr[PART_LEN1 + i] * xf_ptr[PART_LEN1 + i]);
1322 aec->xPow[i] = 1312 aec->xPow[i] =
1323 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum; 1313 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum;
1324 // Calculate absolute spectra 1314 // Calculate absolute spectra
1325 abs_far_spectrum[i] = sqrtf(far_spectrum); 1315 abs_far_spectrum[i] = sqrtf(far_spectrum);
1326 1316
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 1375
1386 // Buffer xf 1376 // Buffer xf
1387 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, 1377 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1,
1388 xf_ptr, 1378 xf_ptr,
1389 sizeof(float) * PART_LEN1); 1379 sizeof(float) * PART_LEN1);
1390 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, 1380 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1,
1391 &xf_ptr[PART_LEN1], 1381 &xf_ptr[PART_LEN1],
1392 sizeof(float) * PART_LEN1); 1382 sizeof(float) * PART_LEN1);
1393 1383
1394 // Perform echo subtraction. 1384 // Perform echo subtraction.
1395 EchoSubtraction(aec, nearend_ptr); 1385 EchoSubtraction(aec,
1386 aec->num_partitions,
1387 aec->xfBufBlockPos,
1388 aec->metricsMode,
1389 aec->extended_filter_enabled,
1390 aec->normal_mu,
1391 aec->normal_error_threshold,
1392 aec->xfBuf,
1393 nearend_ptr,
1394 aec->xPow,
1395 aec->wfBuf,
1396 &aec->linoutlevel,
1397 echo_subtractor_output);
1398
1399 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN);
1396 1400
1397 // Perform echo suppression. 1401 // Perform echo suppression.
1402 memcpy(aec->eBuf + PART_LEN,
1403 echo_subtractor_output,
1404 sizeof(float) * PART_LEN);
1398 EchoSuppression(aec, output, outputH_ptr); 1405 EchoSuppression(aec, output, outputH_ptr);
1399 1406
1400 if (aec->metricsMode == 1) { 1407 if (aec->metricsMode == 1) {
1401 // Update power levels and echo metrics 1408 // Update power levels and echo metrics
1402 UpdateLevel(&aec->farlevel, (float(*)[PART_LEN1])xf_ptr); 1409 UpdateLevel(&aec->farlevel, (float(*)[PART_LEN1])xf_ptr);
1403 UpdateLevel(&aec->nearlevel, df); 1410 UpdateLevel(&aec->nearlevel, df);
1404 UpdateMetrics(aec); 1411 UpdateMetrics(aec);
1405 } 1412 }
1406 1413
1407 // Store the output block. 1414 // Store the output block.
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) { 1737 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) {
1731 float fft[PART_LEN2]; 1738 float fft[PART_LEN2];
1732 float xf[2][PART_LEN1]; 1739 float xf[2][PART_LEN1];
1733 1740
1734 // Check if the buffer is full, and in that case flush the oldest data. 1741 // Check if the buffer is full, and in that case flush the oldest data.
1735 if (WebRtc_available_write(aec->far_buf) < 1) { 1742 if (WebRtc_available_write(aec->far_buf) < 1) {
1736 WebRtcAec_MoveFarReadPtr(aec, 1); 1743 WebRtcAec_MoveFarReadPtr(aec, 1);
1737 } 1744 }
1738 // Convert far-end partition to the frequency domain without windowing. 1745 // Convert far-end partition to the frequency domain without windowing.
1739 memcpy(fft, farend, sizeof(float) * PART_LEN2); 1746 memcpy(fft, farend, sizeof(float) * PART_LEN2);
1740 TimeToFrequency(fft, xf, 0); 1747 Fft(fft, xf);
1741 WebRtc_WriteBuffer(aec->far_buf, &xf[0][0], 1); 1748 WebRtc_WriteBuffer(aec->far_buf, &xf[0][0], 1);
1742 1749
1743 // Convert far-end partition to the frequency domain with windowing. 1750 // Convert far-end partition to the frequency domain with windowing.
1744 memcpy(fft, farend, sizeof(float) * PART_LEN2); 1751 WindowData(fft, farend);
1745 TimeToFrequency(fft, xf, 1); 1752 Fft(fft, xf);
1746 WebRtc_WriteBuffer(aec->far_buf_windowed, &xf[0][0], 1); 1753 WebRtc_WriteBuffer(aec->far_buf_windowed, &xf[0][0], 1);
1747 } 1754 }
1748 1755
1749 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) { 1756 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) {
1750 int elements_moved = MoveFarReadPtrWithoutSystemDelayUpdate(aec, elements); 1757 int elements_moved = MoveFarReadPtrWithoutSystemDelayUpdate(aec, elements);
1751 aec->system_delay -= elements_moved * PART_LEN; 1758 aec->system_delay -= elements_moved * PART_LEN;
1752 return elements_moved; 1759 return elements_moved;
1753 } 1760 }
1754 1761
1755 void WebRtcAec_ProcessFrames(AecCore* aec, 1762 void WebRtcAec_ProcessFrames(AecCore* aec,
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1947 int WebRtcAec_extended_filter_enabled(AecCore* self) { 1954 int WebRtcAec_extended_filter_enabled(AecCore* self) {
1948 return self->extended_filter_enabled; 1955 return self->extended_filter_enabled;
1949 } 1956 }
1950 1957
1951 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } 1958 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; }
1952 1959
1953 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { 1960 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
1954 assert(delay >= 0); 1961 assert(delay >= 0);
1955 self->system_delay = delay; 1962 self->system_delay = delay;
1956 } 1963 }
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/audio_processing/aec/aec_core_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698