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 16 matching lines...) Expand all Loading... |
27 #include "webrtc/common_audio/ring_buffer.h" | 27 #include "webrtc/common_audio/ring_buffer.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_internal.h" | 30 #include "webrtc/modules/audio_processing/aec/aec_core_internal.h" |
31 #include "webrtc/modules/audio_processing/aec/aec_rdft.h" | 31 #include "webrtc/modules/audio_processing/aec/aec_rdft.h" |
32 #include "webrtc/modules/audio_processing/logging/aec_logging.h" | 32 #include "webrtc/modules/audio_processing/logging/aec_logging.h" |
33 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h" | 33 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h" |
34 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" | 34 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" |
35 #include "webrtc/typedefs.h" | 35 #include "webrtc/typedefs.h" |
36 | 36 |
37 | |
38 // Buffer size (samples) | 37 // Buffer size (samples) |
39 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz. | 38 static const size_t kBufSizePartitions = 250; // 1 second of audio in 16 kHz. |
40 | 39 |
41 // Metrics | 40 // Metrics |
42 static const int subCountLen = 4; | 41 static const int subCountLen = 4; |
43 static const int countLen = 50; | 42 static const int countLen = 50; |
44 static const int kDelayMetricsAggregationWindow = 1250; // 5 seconds at 16 kHz. | 43 static const int kDelayMetricsAggregationWindow = 1250; // 5 seconds at 16 kHz. |
45 | 44 |
46 // Quantities to control H band scaling for SWB input | 45 // Quantities to control H band scaling for SWB input |
47 static const float cnScaleHband = | 46 static const float cnScaleHband = |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 | 112 |
114 // Two sets of parameters, one for the extended filter mode. | 113 // Two sets of parameters, one for the extended filter mode. |
115 static const float kExtendedMinOverDrive[3] = {3.0f, 6.0f, 15.0f}; | 114 static const float kExtendedMinOverDrive[3] = {3.0f, 6.0f, 15.0f}; |
116 static const float kNormalMinOverDrive[3] = {1.0f, 2.0f, 5.0f}; | 115 static const float kNormalMinOverDrive[3] = {1.0f, 2.0f, 5.0f}; |
117 const float WebRtcAec_kExtendedSmoothingCoefficients[2][2] = {{0.9f, 0.1f}, | 116 const float WebRtcAec_kExtendedSmoothingCoefficients[2][2] = {{0.9f, 0.1f}, |
118 {0.92f, 0.08f}}; | 117 {0.92f, 0.08f}}; |
119 const float WebRtcAec_kNormalSmoothingCoefficients[2][2] = {{0.9f, 0.1f}, | 118 const float WebRtcAec_kNormalSmoothingCoefficients[2][2] = {{0.9f, 0.1f}, |
120 {0.93f, 0.07f}}; | 119 {0.93f, 0.07f}}; |
121 | 120 |
122 // Number of partitions forming the NLP's "preferred" bands. | 121 // Number of partitions forming the NLP's "preferred" bands. |
123 enum { | 122 enum { kPrefBandSize = 24 }; |
124 kPrefBandSize = 24 | |
125 }; | |
126 | 123 |
127 #ifdef WEBRTC_AEC_DEBUG_DUMP | 124 #ifdef WEBRTC_AEC_DEBUG_DUMP |
128 extern int webrtc_aec_instance_count; | 125 extern int webrtc_aec_instance_count; |
129 #endif | 126 #endif |
130 | 127 |
131 WebRtcAecFilterFar WebRtcAec_FilterFar; | 128 WebRtcAecFilterFar WebRtcAec_FilterFar; |
132 WebRtcAecScaleErrorSignal WebRtcAec_ScaleErrorSignal; | 129 WebRtcAecScaleErrorSignal WebRtcAec_ScaleErrorSignal; |
133 WebRtcAecFilterAdaptation WebRtcAec_FilterAdaptation; | 130 WebRtcAecFilterAdaptation WebRtcAec_FilterAdaptation; |
134 WebRtcAecOverdriveAndSuppress WebRtcAec_OverdriveAndSuppress; | 131 WebRtcAecOverdriveAndSuppress WebRtcAec_OverdriveAndSuppress; |
135 WebRtcAecComfortNoise WebRtcAec_ComfortNoise; | 132 WebRtcAecComfortNoise WebRtcAec_ComfortNoise; |
(...skipping 10 matching lines...) Expand all Loading... |
146 return aRe * bIm + aIm * bRe; | 143 return aRe * bIm + aIm * bRe; |
147 } | 144 } |
148 | 145 |
149 static int CmpFloat(const void* a, const void* b) { | 146 static int CmpFloat(const void* a, const void* b) { |
150 const float* da = (const float*)a; | 147 const float* da = (const float*)a; |
151 const float* db = (const float*)b; | 148 const float* db = (const float*)b; |
152 | 149 |
153 return (*da > *db) - (*da < *db); | 150 return (*da > *db) - (*da < *db); |
154 } | 151 } |
155 | 152 |
156 static void FilterFar( | 153 static void FilterFar(int num_partitions, |
157 int num_partitions, | 154 int x_fft_buf_block_pos, |
158 int x_fft_buf_block_pos, | 155 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], |
159 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], | 156 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1], |
160 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1], | 157 float y_fft[2][PART_LEN1]) { |
161 float y_fft[2][PART_LEN1]) { | |
162 int i; | 158 int i; |
163 for (i = 0; i < num_partitions; i++) { | 159 for (i = 0; i < num_partitions; i++) { |
164 int j; | 160 int j; |
165 int xPos = (i + x_fft_buf_block_pos) * PART_LEN1; | 161 int xPos = (i + x_fft_buf_block_pos) * PART_LEN1; |
166 int pos = i * PART_LEN1; | 162 int pos = i * PART_LEN1; |
167 // Check for wrap | 163 // Check for wrap |
168 if (i + x_fft_buf_block_pos >= num_partitions) { | 164 if (i + x_fft_buf_block_pos >= num_partitions) { |
169 xPos -= num_partitions * (PART_LEN1); | 165 xPos -= num_partitions * (PART_LEN1); |
170 } | 166 } |
171 | 167 |
172 for (j = 0; j < PART_LEN1; j++) { | 168 for (j = 0; j < PART_LEN1; j++) { |
173 y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j], | 169 y_fft[0][j] += MulRe(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j], |
174 x_fft_buf[1][xPos + j], | 170 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]); |
175 h_fft_buf[0][pos + j], | 171 y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j], x_fft_buf[1][xPos + j], |
176 h_fft_buf[1][pos + j]); | 172 h_fft_buf[0][pos + j], h_fft_buf[1][pos + j]); |
177 y_fft[1][j] += MulIm(x_fft_buf[0][xPos + j], | |
178 x_fft_buf[1][xPos + j], | |
179 h_fft_buf[0][pos + j], | |
180 h_fft_buf[1][pos + j]); | |
181 } | 173 } |
182 } | 174 } |
183 } | 175 } |
184 | 176 |
185 static void ScaleErrorSignal(int extended_filter_enabled, | 177 static void ScaleErrorSignal(int extended_filter_enabled, |
186 float normal_mu, | 178 float normal_mu, |
187 float normal_error_threshold, | 179 float normal_error_threshold, |
188 float x_pow[PART_LEN1], | 180 float x_pow[PART_LEN1], |
189 float ef[2][PART_LEN1]) { | 181 float ef[2][PART_LEN1]) { |
190 const float mu = extended_filter_enabled ? kExtendedMu : normal_mu; | 182 const float mu = extended_filter_enabled ? kExtendedMu : normal_mu; |
(...skipping 12 matching lines...) Expand all Loading... |
203 ef[0][i] *= abs_ef; | 195 ef[0][i] *= abs_ef; |
204 ef[1][i] *= abs_ef; | 196 ef[1][i] *= abs_ef; |
205 } | 197 } |
206 | 198 |
207 // Stepsize factor | 199 // Stepsize factor |
208 ef[0][i] *= mu; | 200 ef[0][i] *= mu; |
209 ef[1][i] *= mu; | 201 ef[1][i] *= mu; |
210 } | 202 } |
211 } | 203 } |
212 | 204 |
213 | |
214 static void FilterAdaptation( | 205 static void FilterAdaptation( |
215 int num_partitions, | 206 int num_partitions, |
216 int x_fft_buf_block_pos, | 207 int x_fft_buf_block_pos, |
217 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], | 208 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], |
218 float e_fft[2][PART_LEN1], | 209 float e_fft[2][PART_LEN1], |
219 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) { | 210 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1]) { |
220 int i, j; | 211 int i, j; |
221 float fft[PART_LEN2]; | 212 float fft[PART_LEN2]; |
222 for (i = 0; i < num_partitions; i++) { | 213 for (i = 0; i < num_partitions; i++) { |
223 int xPos = (i + x_fft_buf_block_pos) * (PART_LEN1); | 214 int xPos = (i + x_fft_buf_block_pos) * (PART_LEN1); |
224 int pos; | 215 int pos; |
225 // Check for wrap | 216 // Check for wrap |
226 if (i + x_fft_buf_block_pos >= num_partitions) { | 217 if (i + x_fft_buf_block_pos >= num_partitions) { |
227 xPos -= num_partitions * PART_LEN1; | 218 xPos -= num_partitions * PART_LEN1; |
228 } | 219 } |
229 | 220 |
230 pos = i * PART_LEN1; | 221 pos = i * PART_LEN1; |
231 | 222 |
232 for (j = 0; j < PART_LEN; j++) { | 223 for (j = 0; j < PART_LEN; j++) { |
233 | 224 fft[2 * j] = MulRe(x_fft_buf[0][xPos + j], -x_fft_buf[1][xPos + j], |
234 fft[2 * j] = MulRe(x_fft_buf[0][xPos + j], | 225 e_fft[0][j], e_fft[1][j]); |
235 -x_fft_buf[1][xPos + j], | 226 fft[2 * j + 1] = MulIm(x_fft_buf[0][xPos + j], -x_fft_buf[1][xPos + j], |
236 e_fft[0][j], | 227 e_fft[0][j], e_fft[1][j]); |
237 e_fft[1][j]); | |
238 fft[2 * j + 1] = MulIm(x_fft_buf[0][xPos + j], | |
239 -x_fft_buf[1][xPos + j], | |
240 e_fft[0][j], | |
241 e_fft[1][j]); | |
242 } | 228 } |
243 fft[1] = MulRe(x_fft_buf[0][xPos + PART_LEN], | 229 fft[1] = |
244 -x_fft_buf[1][xPos + PART_LEN], | 230 MulRe(x_fft_buf[0][xPos + PART_LEN], -x_fft_buf[1][xPos + PART_LEN], |
245 e_fft[0][PART_LEN], | 231 e_fft[0][PART_LEN], e_fft[1][PART_LEN]); |
246 e_fft[1][PART_LEN]); | |
247 | 232 |
248 aec_rdft_inverse_128(fft); | 233 aec_rdft_inverse_128(fft); |
249 memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN); | 234 memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN); |
250 | 235 |
251 // fft scaling | 236 // fft scaling |
252 { | 237 { |
253 float scale = 2.0f / PART_LEN2; | 238 float scale = 2.0f / PART_LEN2; |
254 for (j = 0; j < PART_LEN; j++) { | 239 for (j = 0; j < PART_LEN; j++) { |
255 fft[j] *= scale; | 240 fft[j] *= scale; |
256 } | 241 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 float wfEnMax = 0; | 283 float wfEnMax = 0; |
299 int i; | 284 int i; |
300 int delay = 0; | 285 int delay = 0; |
301 | 286 |
302 for (i = 0; i < aec->num_partitions; i++) { | 287 for (i = 0; i < aec->num_partitions; i++) { |
303 int j; | 288 int j; |
304 int pos = i * PART_LEN1; | 289 int pos = i * PART_LEN1; |
305 float wfEn = 0; | 290 float wfEn = 0; |
306 for (j = 0; j < PART_LEN1; j++) { | 291 for (j = 0; j < PART_LEN1; j++) { |
307 wfEn += aec->wfBuf[0][pos + j] * aec->wfBuf[0][pos + j] + | 292 wfEn += aec->wfBuf[0][pos + j] * aec->wfBuf[0][pos + j] + |
308 aec->wfBuf[1][pos + j] * aec->wfBuf[1][pos + j]; | 293 aec->wfBuf[1][pos + j] * aec->wfBuf[1][pos + j]; |
309 } | 294 } |
310 | 295 |
311 if (wfEn > wfEnMax) { | 296 if (wfEn > wfEnMax) { |
312 wfEnMax = wfEn; | 297 wfEnMax = wfEn; |
313 delay = i; | 298 delay = i; |
314 } | 299 } |
315 } | 300 } |
316 return delay; | 301 return delay; |
317 } | 302 } |
318 | 303 |
319 // Threshold to protect against the ill-effects of a zero far-end. | 304 // Threshold to protect against the ill-effects of a zero far-end. |
320 const float WebRtcAec_kMinFarendPSD = 15; | 305 const float WebRtcAec_kMinFarendPSD = 15; |
321 | 306 |
322 // Updates the following smoothed Power Spectral Densities (PSD): | 307 // Updates the following smoothed Power Spectral Densities (PSD): |
323 // - sd : near-end | 308 // - sd : near-end |
324 // - se : residual echo | 309 // - se : residual echo |
325 // - sx : far-end | 310 // - sx : far-end |
326 // - sde : cross-PSD of near-end and residual echo | 311 // - sde : cross-PSD of near-end and residual echo |
327 // - sxd : cross-PSD of near-end and far-end | 312 // - sxd : cross-PSD of near-end and far-end |
328 // | 313 // |
329 // In addition to updating the PSDs, also the filter diverge state is | 314 // In addition to updating the PSDs, also the filter diverge state is |
330 // determined. | 315 // determined. |
331 static void SmoothedPSD(AecCore* aec, | 316 static void SmoothedPSD(AecCore* aec, |
332 float efw[2][PART_LEN1], | 317 float efw[2][PART_LEN1], |
333 float dfw[2][PART_LEN1], | 318 float dfw[2][PART_LEN1], |
334 float xfw[2][PART_LEN1], | 319 float xfw[2][PART_LEN1], |
335 int* extreme_filter_divergence) { | 320 int* extreme_filter_divergence) { |
336 // Power estimate smoothing coefficients. | 321 // Power estimate smoothing coefficients. |
337 const float* ptrGCoh = aec->extended_filter_enabled | 322 const float* ptrGCoh = |
338 ? WebRtcAec_kExtendedSmoothingCoefficients[aec->mult - 1] | 323 aec->extended_filter_enabled |
339 : WebRtcAec_kNormalSmoothingCoefficients[aec->mult - 1]; | 324 ? WebRtcAec_kExtendedSmoothingCoefficients[aec->mult - 1] |
| 325 : WebRtcAec_kNormalSmoothingCoefficients[aec->mult - 1]; |
340 int i; | 326 int i; |
341 float sdSum = 0, seSum = 0; | 327 float sdSum = 0, seSum = 0; |
342 | 328 |
343 for (i = 0; i < PART_LEN1; i++) { | 329 for (i = 0; i < PART_LEN1; i++) { |
344 aec->sd[i] = ptrGCoh[0] * aec->sd[i] + | 330 aec->sd[i] = ptrGCoh[0] * aec->sd[i] + |
345 ptrGCoh[1] * (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]); | 331 ptrGCoh[1] * (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]); |
346 aec->se[i] = ptrGCoh[0] * aec->se[i] + | 332 aec->se[i] = ptrGCoh[0] * aec->se[i] + |
347 ptrGCoh[1] * (efw[0][i] * efw[0][i] + efw[1][i] * efw[1][i]); | 333 ptrGCoh[1] * (efw[0][i] * efw[0][i] + efw[1][i] * efw[1][i]); |
348 // We threshold here to protect against the ill-effects of a zero farend. | 334 // We threshold here to protect against the ill-effects of a zero farend. |
349 // The threshold is not arbitrarily chosen, but balances protection and | 335 // The threshold is not arbitrarily chosen, but balances protection and |
350 // adverse interaction with the algorithm's tuning. | 336 // adverse interaction with the algorithm's tuning. |
351 // TODO(bjornv): investigate further why this is so sensitive. | 337 // TODO(bjornv): investigate further why this is so sensitive. |
352 aec->sx[i] = | 338 aec->sx[i] = ptrGCoh[0] * aec->sx[i] + |
353 ptrGCoh[0] * aec->sx[i] + | 339 ptrGCoh[1] * WEBRTC_SPL_MAX( |
354 ptrGCoh[1] * WEBRTC_SPL_MAX( | 340 xfw[0][i] * xfw[0][i] + xfw[1][i] * xfw[1][i], |
355 xfw[0][i] * xfw[0][i] + xfw[1][i] * xfw[1][i], | 341 WebRtcAec_kMinFarendPSD); |
356 WebRtcAec_kMinFarendPSD); | |
357 | 342 |
358 aec->sde[i][0] = | 343 aec->sde[i][0] = |
359 ptrGCoh[0] * aec->sde[i][0] + | 344 ptrGCoh[0] * aec->sde[i][0] + |
360 ptrGCoh[1] * (dfw[0][i] * efw[0][i] + dfw[1][i] * efw[1][i]); | 345 ptrGCoh[1] * (dfw[0][i] * efw[0][i] + dfw[1][i] * efw[1][i]); |
361 aec->sde[i][1] = | 346 aec->sde[i][1] = |
362 ptrGCoh[0] * aec->sde[i][1] + | 347 ptrGCoh[0] * aec->sde[i][1] + |
363 ptrGCoh[1] * (dfw[0][i] * efw[1][i] - dfw[1][i] * efw[0][i]); | 348 ptrGCoh[1] * (dfw[0][i] * efw[1][i] - dfw[1][i] * efw[0][i]); |
364 | 349 |
365 aec->sxd[i][0] = | 350 aec->sxd[i][0] = |
366 ptrGCoh[0] * aec->sxd[i][0] + | 351 ptrGCoh[0] * aec->sxd[i][0] + |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 efw[0][i] += tmp * u[0][i]; | 461 efw[0][i] += tmp * u[0][i]; |
477 efw[1][i] += tmp * u[1][i]; | 462 efw[1][i] += tmp * u[1][i]; |
478 } | 463 } |
479 | 464 |
480 // For H band comfort noise | 465 // For H band comfort noise |
481 // TODO: don't compute noise and "tmp" twice. Use the previous results. | 466 // TODO: don't compute noise and "tmp" twice. Use the previous results. |
482 noiseAvg = 0.0; | 467 noiseAvg = 0.0; |
483 tmpAvg = 0.0; | 468 tmpAvg = 0.0; |
484 num = 0; | 469 num = 0; |
485 if (aec->num_bands > 1) { | 470 if (aec->num_bands > 1) { |
486 | |
487 // average noise scale | 471 // average noise scale |
488 // average over second half of freq spectrum (i.e., 4->8khz) | 472 // average over second half of freq spectrum (i.e., 4->8khz) |
489 // TODO: we shouldn't need num. We know how many elements we're summing. | 473 // TODO: we shouldn't need num. We know how many elements we're summing. |
490 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { | 474 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { |
491 num++; | 475 num++; |
492 noiseAvg += sqrtf(noisePow[i]); | 476 noiseAvg += sqrtf(noisePow[i]); |
493 } | 477 } |
494 noiseAvg /= (float)num; | 478 noiseAvg /= (float)num; |
495 | 479 |
496 // average nlp scale | 480 // average nlp scale |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 const float noisyPower = 300000.0f * 2.0f / PART_LEN2; | 598 const float noisyPower = 300000.0f * 2.0f / PART_LEN2; |
615 | 599 |
616 float actThreshold; | 600 float actThreshold; |
617 float echo, suppressedEcho; | 601 float echo, suppressedEcho; |
618 | 602 |
619 if (aec->echoState) { // Check if echo is likely present | 603 if (aec->echoState) { // Check if echo is likely present |
620 aec->stateCounter++; | 604 aec->stateCounter++; |
621 } | 605 } |
622 | 606 |
623 if (aec->farlevel.frcounter == 0) { | 607 if (aec->farlevel.frcounter == 0) { |
624 | |
625 if (aec->farlevel.minlevel < noisyPower) { | 608 if (aec->farlevel.minlevel < noisyPower) { |
626 actThreshold = actThresholdClean; | 609 actThreshold = actThresholdClean; |
627 } else { | 610 } else { |
628 actThreshold = actThresholdNoisy; | 611 actThreshold = actThresholdNoisy; |
629 } | 612 } |
630 | 613 |
631 if ((aec->stateCounter > (0.5f * countLen * subCountLen)) && | 614 if ((aec->stateCounter > (0.5f * countLen * subCountLen)) && |
632 (aec->farlevel.sfrcounter == 0) | 615 (aec->farlevel.sfrcounter == 0) |
633 | 616 |
634 // Estimate in active far-end segments only | 617 // Estimate in active far-end segments only |
635 && | 618 && (aec->farlevel.averagelevel > |
636 (aec->farlevel.averagelevel > | 619 (actThreshold * aec->farlevel.minlevel))) { |
637 (actThreshold * aec->farlevel.minlevel))) { | |
638 | |
639 // Subtract noise power | 620 // Subtract noise power |
640 echo = aec->nearlevel.averagelevel - safety * aec->nearlevel.minlevel; | 621 echo = aec->nearlevel.averagelevel - safety * aec->nearlevel.minlevel; |
641 | 622 |
642 // ERL | 623 // ERL |
643 dtmp = 10 * (float)log10(aec->farlevel.averagelevel / | 624 dtmp = 10 * (float)log10(aec->farlevel.averagelevel / |
644 aec->nearlevel.averagelevel + | 625 aec->nearlevel.averagelevel + |
645 1e-10f); | 626 1e-10f); |
646 dtmp2 = 10 * (float)log10(aec->farlevel.averagelevel / echo + 1e-10f); | 627 dtmp2 = 10 * (float)log10(aec->farlevel.averagelevel / echo + 1e-10f); |
647 | 628 |
648 aec->erl.instant = dtmp; | 629 aec->erl.instant = dtmp; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 break; | 744 break; |
764 } | 745 } |
765 } | 746 } |
766 // Account for lookahead. | 747 // Account for lookahead. |
767 self->delay_median = (median - lookahead) * kMsPerBlock; | 748 self->delay_median = (median - lookahead) * kMsPerBlock; |
768 | 749 |
769 // Calculate the L1 norm, with median value as central moment. | 750 // Calculate the L1 norm, with median value as central moment. |
770 for (i = 0; i < kHistorySizeBlocks; i++) { | 751 for (i = 0; i < kHistorySizeBlocks; i++) { |
771 l1_norm += abs(i - median) * self->delay_histogram[i]; | 752 l1_norm += abs(i - median) * self->delay_histogram[i]; |
772 } | 753 } |
773 self->delay_std = (int)((l1_norm + self->num_delay_values / 2) / | 754 self->delay_std = |
774 self->num_delay_values) * kMsPerBlock; | 755 (int)((l1_norm + self->num_delay_values / 2) / self->num_delay_values) * |
| 756 kMsPerBlock; |
775 | 757 |
776 // Determine fraction of delays that are out of bounds, that is, either | 758 // Determine fraction of delays that are out of bounds, that is, either |
777 // negative (anti-causal system) or larger than the AEC filter length. | 759 // negative (anti-causal system) or larger than the AEC filter length. |
778 { | 760 { |
779 int num_delays_out_of_bounds = self->num_delay_values; | 761 int num_delays_out_of_bounds = self->num_delay_values; |
780 const int histogram_length = sizeof(self->delay_histogram) / | 762 const int histogram_length = |
781 sizeof(self->delay_histogram[0]); | 763 sizeof(self->delay_histogram) / sizeof(self->delay_histogram[0]); |
782 for (i = lookahead; i < lookahead + self->num_partitions; ++i) { | 764 for (i = lookahead; i < lookahead + self->num_partitions; ++i) { |
783 if (i < histogram_length) | 765 if (i < histogram_length) |
784 num_delays_out_of_bounds -= self->delay_histogram[i]; | 766 num_delays_out_of_bounds -= self->delay_histogram[i]; |
785 } | 767 } |
786 self->fraction_poor_delays = (float)num_delays_out_of_bounds / | 768 self->fraction_poor_delays = |
787 self->num_delay_values; | 769 (float)num_delays_out_of_bounds / self->num_delay_values; |
788 } | 770 } |
789 | 771 |
790 // Reset histogram. | 772 // Reset histogram. |
791 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); | 773 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); |
792 self->num_delay_values = 0; | 774 self->num_delay_values = 0; |
793 | 775 |
794 return; | 776 return; |
795 } | 777 } |
796 | 778 |
797 static void ScaledInverseFft(float freq_data[2][PART_LEN1], | 779 static void ScaledInverseFft(float freq_data[2][PART_LEN1], |
798 float time_data[PART_LEN2], | 780 float time_data[PART_LEN2], |
799 float scale, | 781 float scale, |
800 int conjugate) { | 782 int conjugate) { |
801 int i; | 783 int i; |
802 const float normalization = scale / ((float)PART_LEN2); | 784 const float normalization = scale / ((float)PART_LEN2); |
803 const float sign = (conjugate ? -1 : 1); | 785 const float sign = (conjugate ? -1 : 1); |
804 time_data[0] = freq_data[0][0] * normalization; | 786 time_data[0] = freq_data[0][0] * normalization; |
805 time_data[1] = freq_data[0][PART_LEN] * normalization; | 787 time_data[1] = freq_data[0][PART_LEN] * normalization; |
806 for (i = 1; i < PART_LEN; i++) { | 788 for (i = 1; i < PART_LEN; i++) { |
807 time_data[2 * i] = freq_data[0][i] * normalization; | 789 time_data[2 * i] = freq_data[0][i] * normalization; |
808 time_data[2 * i + 1] = sign * freq_data[1][i] * normalization; | 790 time_data[2 * i + 1] = sign * freq_data[1][i] * normalization; |
809 } | 791 } |
810 aec_rdft_inverse_128(time_data); | 792 aec_rdft_inverse_128(time_data); |
811 } | 793 } |
812 | 794 |
813 | 795 static void Fft(float time_data[PART_LEN2], float freq_data[2][PART_LEN1]) { |
814 static void Fft(float time_data[PART_LEN2], | |
815 float freq_data[2][PART_LEN1]) { | |
816 int i; | 796 int i; |
817 aec_rdft_forward_128(time_data); | 797 aec_rdft_forward_128(time_data); |
818 | 798 |
819 // Reorder fft output data. | 799 // Reorder fft output data. |
820 freq_data[1][0] = 0; | 800 freq_data[1][0] = 0; |
821 freq_data[1][PART_LEN] = 0; | 801 freq_data[1][PART_LEN] = 0; |
822 freq_data[0][0] = time_data[0]; | 802 freq_data[0][0] = time_data[0]; |
823 freq_data[0][PART_LEN] = time_data[1]; | 803 freq_data[0][PART_LEN] = time_data[1]; |
824 for (i = 1; i < PART_LEN; i++) { | 804 for (i = 1; i < PART_LEN; i++) { |
825 freq_data[0][i] = time_data[2 * i]; | 805 freq_data[0][i] = time_data[2 * i]; |
(...skipping 20 matching lines...) Expand all Loading... |
846 // negative |last_delay| is an invalid one. | 826 // negative |last_delay| is an invalid one. |
847 // 2. Verify that there is a delay change. In addition, only allow a change | 827 // 2. Verify that there is a delay change. In addition, only allow a change |
848 // if the delay is outside a certain region taking the AEC filter length | 828 // if the delay is outside a certain region taking the AEC filter length |
849 // into account. | 829 // into account. |
850 // TODO(bjornv): Investigate if we can remove the non-zero delay change check. | 830 // TODO(bjornv): Investigate if we can remove the non-zero delay change check. |
851 // 3. Only allow delay correction if the delay estimation quality exceeds | 831 // 3. Only allow delay correction if the delay estimation quality exceeds |
852 // |delay_quality_threshold|. | 832 // |delay_quality_threshold|. |
853 // 4. Finally, verify that the proposed |delay_correction| is feasible by | 833 // 4. Finally, verify that the proposed |delay_correction| is feasible by |
854 // comparing with the size of the far-end buffer. | 834 // comparing with the size of the far-end buffer. |
855 last_delay = WebRtc_last_delay(self->delay_estimator); | 835 last_delay = WebRtc_last_delay(self->delay_estimator); |
856 if ((last_delay >= 0) && | 836 if ((last_delay >= 0) && (last_delay != self->previous_delay) && |
857 (last_delay != self->previous_delay) && | |
858 (WebRtc_last_delay_quality(self->delay_estimator) > | 837 (WebRtc_last_delay_quality(self->delay_estimator) > |
859 self->delay_quality_threshold)) { | 838 self->delay_quality_threshold)) { |
860 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); | 839 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); |
861 // Allow for a slack in the actual delay, defined by a |lower_bound| and an | 840 // Allow for a slack in the actual delay, defined by a |lower_bound| and an |
862 // |upper_bound|. The adaptive echo cancellation filter is currently | 841 // |upper_bound|. The adaptive echo cancellation filter is currently |
863 // |num_partitions| (of 64 samples) long. If the delay estimate is negative | 842 // |num_partitions| (of 64 samples) long. If the delay estimate is negative |
864 // or at least 3/4 of the filter length we open up for correction. | 843 // or at least 3/4 of the filter length we open up for correction. |
865 const int lower_bound = 0; | 844 const int lower_bound = 0; |
866 const int upper_bound = self->num_partitions * 3 / 4; | 845 const int upper_bound = self->num_partitions * 3 / 4; |
867 const int do_correction = delay <= lower_bound || delay > upper_bound; | 846 const int do_correction = delay <= lower_bound || delay > upper_bound; |
868 if (do_correction == 1) { | 847 if (do_correction == 1) { |
869 int available_read = (int)WebRtc_available_read(self->far_time_buf); | 848 int available_read = (int)WebRtc_available_read(self->far_time_buf); |
(...skipping 13 matching lines...) Expand all Loading... |
883 } else { | 862 } else { |
884 self->previous_delay = last_delay; | 863 self->previous_delay = last_delay; |
885 ++self->delay_correction_count; | 864 ++self->delay_correction_count; |
886 } | 865 } |
887 } | 866 } |
888 } | 867 } |
889 // Update the |delay_quality_threshold| once we have our first delay | 868 // Update the |delay_quality_threshold| once we have our first delay |
890 // correction. | 869 // correction. |
891 if (self->delay_correction_count > 0) { | 870 if (self->delay_correction_count > 0) { |
892 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); | 871 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); |
893 delay_quality = (delay_quality > kDelayQualityThresholdMax ? | 872 delay_quality = |
894 kDelayQualityThresholdMax : delay_quality); | 873 (delay_quality > kDelayQualityThresholdMax ? kDelayQualityThresholdMax |
| 874 : delay_quality); |
895 self->delay_quality_threshold = | 875 self->delay_quality_threshold = |
896 (delay_quality > self->delay_quality_threshold ? delay_quality : | 876 (delay_quality > self->delay_quality_threshold |
897 self->delay_quality_threshold); | 877 ? delay_quality |
| 878 : self->delay_quality_threshold); |
898 } | 879 } |
899 return delay_correction; | 880 return delay_correction; |
900 } | 881 } |
901 | 882 |
902 static void EchoSubtraction( | 883 static void EchoSubtraction(AecCore* aec, |
903 AecCore* aec, | 884 int num_partitions, |
904 int num_partitions, | 885 int x_fft_buf_block_pos, |
905 int x_fft_buf_block_pos, | 886 int metrics_mode, |
906 int metrics_mode, | 887 int extended_filter_enabled, |
907 int extended_filter_enabled, | 888 float normal_mu, |
908 float normal_mu, | 889 float normal_error_threshold, |
909 float normal_error_threshold, | 890 float x_fft_buf[2] |
910 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], | 891 [kExtendedNumPartitions * PART_LEN1], |
911 float* const y, | 892 float* const y, |
912 float x_pow[PART_LEN1], | 893 float x_pow[PART_LEN1], |
913 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1], | 894 float h_fft_buf[2] |
914 PowerLevel* linout_level, | 895 [kExtendedNumPartitions * PART_LEN1], |
915 float echo_subtractor_output[PART_LEN]) { | 896 PowerLevel* linout_level, |
| 897 float echo_subtractor_output[PART_LEN]) { |
916 float s_fft[2][PART_LEN1]; | 898 float s_fft[2][PART_LEN1]; |
917 float e_extended[PART_LEN2]; | 899 float e_extended[PART_LEN2]; |
918 float s_extended[PART_LEN2]; | 900 float s_extended[PART_LEN2]; |
919 float *s; | 901 float* s; |
920 float e[PART_LEN]; | 902 float e[PART_LEN]; |
921 float e_fft[2][PART_LEN1]; | 903 float e_fft[2][PART_LEN1]; |
922 int i; | 904 int i; |
923 memset(s_fft, 0, sizeof(s_fft)); | 905 memset(s_fft, 0, sizeof(s_fft)); |
924 | 906 |
925 // Conditionally reset the echo subtraction filter if the filter has diverged | 907 // Conditionally reset the echo subtraction filter if the filter has diverged |
926 // significantly. | 908 // significantly. |
927 if (!aec->extended_filter_enabled && | 909 if (!aec->extended_filter_enabled && aec->extreme_filter_divergence) { |
928 aec->extreme_filter_divergence) { | |
929 memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); | 910 memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); |
930 aec->extreme_filter_divergence = 0; | 911 aec->extreme_filter_divergence = 0; |
931 } | 912 } |
932 | 913 |
933 // Produce echo estimate s_fft. | 914 // Produce echo estimate s_fft. |
934 WebRtcAec_FilterFar(num_partitions, | 915 WebRtcAec_FilterFar(num_partitions, x_fft_buf_block_pos, x_fft_buf, h_fft_buf, |
935 x_fft_buf_block_pos, | |
936 x_fft_buf, | |
937 h_fft_buf, | |
938 s_fft); | 916 s_fft); |
939 | 917 |
940 // Compute the time-domain echo estimate s. | 918 // Compute the time-domain echo estimate s. |
941 ScaledInverseFft(s_fft, s_extended, 2.0f, 0); | 919 ScaledInverseFft(s_fft, s_extended, 2.0f, 0); |
942 s = &s_extended[PART_LEN]; | 920 s = &s_extended[PART_LEN]; |
943 | 921 |
944 // Compute the time-domain echo prediction error. | 922 // Compute the time-domain echo prediction error. |
945 for (i = 0; i < PART_LEN; ++i) { | 923 for (i = 0; i < PART_LEN; ++i) { |
946 e[i] = y[i] - s[i]; | 924 e[i] = y[i] - s[i]; |
947 } | 925 } |
948 | 926 |
949 // Compute the frequency domain echo prediction error. | 927 // Compute the frequency domain echo prediction error. |
950 memset(e_extended, 0, sizeof(float) * PART_LEN); | 928 memset(e_extended, 0, sizeof(float) * PART_LEN); |
951 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); | 929 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); |
952 Fft(e_extended, e_fft); | 930 Fft(e_extended, e_fft); |
953 | 931 |
954 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, | 932 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, &e_fft[0][0], |
955 &e_fft[0][0], | |
956 sizeof(e_fft[0][0]) * PART_LEN1 * 2); | 933 sizeof(e_fft[0][0]) * PART_LEN1 * 2); |
957 | 934 |
958 if (metrics_mode == 1) { | 935 if (metrics_mode == 1) { |
959 // Note that the first PART_LEN samples in fft (before transformation) are | 936 // Note that the first PART_LEN samples in fft (before transformation) are |
960 // zero. Hence, the scaling by two in UpdateLevel() should not be | 937 // zero. Hence, the scaling by two in UpdateLevel() should not be |
961 // performed. That scaling is taken care of in UpdateMetrics() instead. | 938 // performed. That scaling is taken care of in UpdateMetrics() instead. |
962 UpdateLevel(linout_level, CalculatePower(e, PART_LEN) / 2.0f); | 939 UpdateLevel(linout_level, CalculatePower(e, PART_LEN) / 2.0f); |
963 } | 940 } |
964 | 941 |
965 // Scale error signal inversely with far power. | 942 // Scale error signal inversely with far power. |
966 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, | 943 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, normal_mu, |
967 normal_mu, | 944 normal_error_threshold, x_pow, e_fft); |
968 normal_error_threshold, | 945 WebRtcAec_FilterAdaptation(num_partitions, x_fft_buf_block_pos, x_fft_buf, |
969 x_pow, | 946 e_fft, h_fft_buf); |
970 e_fft); | |
971 WebRtcAec_FilterAdaptation(num_partitions, | |
972 x_fft_buf_block_pos, | |
973 x_fft_buf, | |
974 e_fft, | |
975 h_fft_buf); | |
976 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); | 947 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); |
977 } | 948 } |
978 | 949 |
979 | |
980 static void EchoSuppression(AecCore* aec, | 950 static void EchoSuppression(AecCore* aec, |
981 float farend[PART_LEN2], | 951 float farend[PART_LEN2], |
982 float* echo_subtractor_output, | 952 float* echo_subtractor_output, |
983 float* output, | 953 float* output, |
984 float* const* outputH) { | 954 float* const* outputH) { |
985 float efw[2][PART_LEN1]; | 955 float efw[2][PART_LEN1]; |
986 float xfw[2][PART_LEN1]; | 956 float xfw[2][PART_LEN1]; |
987 float dfw[2][PART_LEN1]; | 957 float dfw[2][PART_LEN1]; |
988 float comfortNoiseHband[2][PART_LEN1]; | 958 float comfortNoiseHband[2][PART_LEN1]; |
989 float fft[PART_LEN2]; | 959 float fft[PART_LEN2]; |
(...skipping 14 matching lines...) Expand all Loading... |
1004 const float* min_overdrive = aec->extended_filter_enabled | 974 const float* min_overdrive = aec->extended_filter_enabled |
1005 ? kExtendedMinOverDrive | 975 ? kExtendedMinOverDrive |
1006 : kNormalMinOverDrive; | 976 : kNormalMinOverDrive; |
1007 | 977 |
1008 // Filter energy | 978 // Filter energy |
1009 const int delayEstInterval = 10 * aec->mult; | 979 const int delayEstInterval = 10 * aec->mult; |
1010 | 980 |
1011 float* xfw_ptr = NULL; | 981 float* xfw_ptr = NULL; |
1012 | 982 |
1013 // Update eBuf with echo subtractor output. | 983 // Update eBuf with echo subtractor output. |
1014 memcpy(aec->eBuf + PART_LEN, | 984 memcpy(aec->eBuf + PART_LEN, echo_subtractor_output, |
1015 echo_subtractor_output, | |
1016 sizeof(float) * PART_LEN); | 985 sizeof(float) * PART_LEN); |
1017 | 986 |
1018 // Analysis filter banks for the echo suppressor. | 987 // Analysis filter banks for the echo suppressor. |
1019 // Windowed near-end ffts. | 988 // Windowed near-end ffts. |
1020 WindowData(fft, aec->dBuf); | 989 WindowData(fft, aec->dBuf); |
1021 aec_rdft_forward_128(fft); | 990 aec_rdft_forward_128(fft); |
1022 StoreAsComplex(fft, dfw); | 991 StoreAsComplex(fft, dfw); |
1023 | 992 |
1024 // Windowed echo suppressor output ffts. | 993 // Windowed echo suppressor output ffts. |
1025 WindowData(fft, aec->eBuf); | 994 WindowData(fft, aec->eBuf); |
(...skipping 10 matching lines...) Expand all Loading... |
1036 // Buffer far. | 1005 // Buffer far. |
1037 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); | 1006 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); |
1038 | 1007 |
1039 aec->delayEstCtr++; | 1008 aec->delayEstCtr++; |
1040 if (aec->delayEstCtr == delayEstInterval) { | 1009 if (aec->delayEstCtr == delayEstInterval) { |
1041 aec->delayEstCtr = 0; | 1010 aec->delayEstCtr = 0; |
1042 aec->delayIdx = WebRtcAec_PartitionDelay(aec); | 1011 aec->delayIdx = WebRtcAec_PartitionDelay(aec); |
1043 } | 1012 } |
1044 | 1013 |
1045 // Use delayed far. | 1014 // Use delayed far. |
1046 memcpy(xfw, | 1015 memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1, |
1047 aec->xfwBuf + aec->delayIdx * PART_LEN1, | |
1048 sizeof(xfw[0][0]) * 2 * PART_LEN1); | 1016 sizeof(xfw[0][0]) * 2 * PART_LEN1); |
1049 | 1017 |
1050 WebRtcAec_SubbandCoherence(aec, efw, dfw, xfw, fft, cohde, cohxd, | 1018 WebRtcAec_SubbandCoherence(aec, efw, dfw, xfw, fft, cohde, cohxd, |
1051 &aec->extreme_filter_divergence); | 1019 &aec->extreme_filter_divergence); |
1052 | 1020 |
1053 // Select the microphone signal as output if the filter is deemed to have | 1021 // Select the microphone signal as output if the filter is deemed to have |
1054 // diverged. | 1022 // diverged. |
1055 if (aec->divergeState) { | 1023 if (aec->divergeState) { |
1056 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); | 1024 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); |
1057 } | 1025 } |
(...skipping 30 matching lines...) Expand all Loading... |
1088 hNlFb = hNlDeAvg; | 1056 hNlFb = hNlDeAvg; |
1089 hNlFbLow = hNlDeAvg; | 1057 hNlFbLow = hNlDeAvg; |
1090 } else { | 1058 } else { |
1091 for (i = 0; i < PART_LEN1; i++) { | 1059 for (i = 0; i < PART_LEN1; i++) { |
1092 hNl[i] = 1 - cohxd[i]; | 1060 hNl[i] = 1 - cohxd[i]; |
1093 } | 1061 } |
1094 hNlFb = hNlXdAvg; | 1062 hNlFb = hNlXdAvg; |
1095 hNlFbLow = hNlXdAvg; | 1063 hNlFbLow = hNlXdAvg; |
1096 } | 1064 } |
1097 } else { | 1065 } else { |
1098 | |
1099 if (aec->stNearState == 1) { | 1066 if (aec->stNearState == 1) { |
1100 aec->echoState = 0; | 1067 aec->echoState = 0; |
1101 memcpy(hNl, cohde, sizeof(hNl)); | 1068 memcpy(hNl, cohde, sizeof(hNl)); |
1102 hNlFb = hNlDeAvg; | 1069 hNlFb = hNlDeAvg; |
1103 hNlFbLow = hNlDeAvg; | 1070 hNlFbLow = hNlDeAvg; |
1104 } else { | 1071 } else { |
1105 aec->echoState = 1; | 1072 aec->echoState = 1; |
1106 for (i = 0; i < PART_LEN1; i++) { | 1073 for (i = 0; i < PART_LEN1; i++) { |
1107 hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]); | 1074 hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]); |
1108 } | 1075 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1163 // scaling only in UpdateMetrics(). | 1130 // scaling only in UpdateMetrics(). |
1164 UpdateLevel(&aec->nlpoutlevel, CalculatePower(fft, PART_LEN2)); | 1131 UpdateLevel(&aec->nlpoutlevel, CalculatePower(fft, PART_LEN2)); |
1165 } | 1132 } |
1166 | 1133 |
1167 // Overlap and add to obtain output. | 1134 // Overlap and add to obtain output. |
1168 for (i = 0; i < PART_LEN; i++) { | 1135 for (i = 0; i < PART_LEN; i++) { |
1169 output[i] = (fft[i] * WebRtcAec_sqrtHanning[i] + | 1136 output[i] = (fft[i] * WebRtcAec_sqrtHanning[i] + |
1170 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]); | 1137 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]); |
1171 | 1138 |
1172 // Saturate output to keep it in the allowed range. | 1139 // Saturate output to keep it in the allowed range. |
1173 output[i] = WEBRTC_SPL_SAT( | 1140 output[i] = |
1174 WEBRTC_SPL_WORD16_MAX, output[i], WEBRTC_SPL_WORD16_MIN); | 1141 WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, output[i], WEBRTC_SPL_WORD16_MIN); |
1175 } | 1142 } |
1176 memcpy(aec->outBuf, &fft[PART_LEN], PART_LEN * sizeof(aec->outBuf[0])); | 1143 memcpy(aec->outBuf, &fft[PART_LEN], PART_LEN * sizeof(aec->outBuf[0])); |
1177 | 1144 |
1178 // For H band | 1145 // For H band |
1179 if (aec->num_bands > 1) { | 1146 if (aec->num_bands > 1) { |
1180 // H band gain | 1147 // H band gain |
1181 // average nlp over low band: average over second half of freq spectrum | 1148 // average nlp over low band: average over second half of freq spectrum |
1182 // (4->8khz) | 1149 // (4->8khz) |
1183 GetHighbandGain(hNl, &nlpGainHband); | 1150 GetHighbandGain(hNl, &nlpGainHband); |
1184 | 1151 |
1185 // Inverse comfort_noise | 1152 // Inverse comfort_noise |
1186 ScaledInverseFft(comfortNoiseHband, fft, 2.0f, 0); | 1153 ScaledInverseFft(comfortNoiseHband, fft, 2.0f, 0); |
1187 | 1154 |
1188 // compute gain factor | 1155 // compute gain factor |
1189 for (j = 0; j < aec->num_bands - 1; ++j) { | 1156 for (j = 0; j < aec->num_bands - 1; ++j) { |
1190 for (i = 0; i < PART_LEN; i++) { | 1157 for (i = 0; i < PART_LEN; i++) { |
1191 outputH[j][i] = aec->dBufH[j][i] * nlpGainHband; | 1158 outputH[j][i] = aec->dBufH[j][i] * nlpGainHband; |
1192 } | 1159 } |
1193 } | 1160 } |
1194 | 1161 |
1195 // Add some comfort noise where Hband is attenuated. | 1162 // Add some comfort noise where Hband is attenuated. |
1196 for (i = 0; i < PART_LEN; i++) { | 1163 for (i = 0; i < PART_LEN; i++) { |
1197 outputH[0][i] += cnScaleHband * fft[i]; | 1164 outputH[0][i] += cnScaleHband * fft[i]; |
1198 } | 1165 } |
1199 | 1166 |
1200 // Saturate output to keep it in the allowed range. | 1167 // Saturate output to keep it in the allowed range. |
1201 for (j = 0; j < aec->num_bands - 1; ++j) { | 1168 for (j = 0; j < aec->num_bands - 1; ++j) { |
1202 for (i = 0; i < PART_LEN; i++) { | 1169 for (i = 0; i < PART_LEN; i++) { |
1203 outputH[j][i] = WEBRTC_SPL_SAT( | 1170 outputH[j][i] = WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, outputH[j][i], |
1204 WEBRTC_SPL_WORD16_MAX, outputH[j][i], WEBRTC_SPL_WORD16_MIN); | 1171 WEBRTC_SPL_WORD16_MIN); |
1205 } | 1172 } |
1206 } | 1173 } |
1207 | |
1208 } | 1174 } |
1209 | 1175 |
1210 // Copy the current block to the old position. | 1176 // Copy the current block to the old position. |
1211 memcpy(aec->dBuf, aec->dBuf + PART_LEN, sizeof(float) * PART_LEN); | 1177 memcpy(aec->dBuf, aec->dBuf + PART_LEN, sizeof(float) * PART_LEN); |
1212 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN); | 1178 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN); |
1213 | 1179 |
1214 // Copy the current block to the old position for H band | 1180 // Copy the current block to the old position for H band |
1215 for (j = 0; j < aec->num_bands - 1; ++j) { | 1181 for (j = 0; j < aec->num_bands - 1; ++j) { |
1216 memcpy(aec->dBufH[j], aec->dBufH[j] + PART_LEN, sizeof(float) * PART_LEN); | 1182 memcpy(aec->dBufH[j], aec->dBufH[j] + PART_LEN, sizeof(float) * PART_LEN); |
1217 } | 1183 } |
1218 | 1184 |
1219 memmove(aec->xfwBuf + PART_LEN1, | 1185 memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf, |
1220 aec->xfwBuf, | |
1221 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); | 1186 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); |
1222 } | 1187 } |
1223 | 1188 |
1224 static void ProcessBlock(AecCore* aec) { | 1189 static void ProcessBlock(AecCore* aec) { |
1225 size_t i; | 1190 size_t i; |
1226 | 1191 |
1227 float fft[PART_LEN2]; | 1192 float fft[PART_LEN2]; |
1228 float xf[2][PART_LEN1]; | 1193 float xf[2][PART_LEN1]; |
1229 float df[2][PART_LEN1]; | 1194 float df[2][PART_LEN1]; |
1230 float far_spectrum = 0.0f; | 1195 float far_spectrum = 0.0f; |
(...skipping 18 matching lines...) Expand all Loading... |
1249 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; | 1214 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; |
1250 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; | 1215 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; |
1251 float* xf_ptr = NULL; | 1216 float* xf_ptr = NULL; |
1252 | 1217 |
1253 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1218 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
1254 outputH_ptr[i] = outputH[i]; | 1219 outputH_ptr[i] = outputH[i]; |
1255 } | 1220 } |
1256 | 1221 |
1257 // Concatenate old and new nearend blocks. | 1222 // Concatenate old and new nearend blocks. |
1258 for (i = 0; i < aec->num_bands - 1; ++i) { | 1223 for (i = 0; i < aec->num_bands - 1; ++i) { |
1259 WebRtc_ReadBuffer(aec->nearFrBufH[i], | 1224 WebRtc_ReadBuffer(aec->nearFrBufH[i], (void**)&nearend_ptr, nearend, |
1260 (void**)&nearend_ptr, | |
1261 nearend, | |
1262 PART_LEN); | 1225 PART_LEN); |
1263 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); | 1226 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); |
1264 } | 1227 } |
1265 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN); | 1228 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN); |
1266 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend)); | 1229 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend)); |
1267 | 1230 |
1268 // We should always have at least one element stored in |far_buf|. | 1231 // We should always have at least one element stored in |far_buf|. |
1269 assert(WebRtc_available_read(aec->far_time_buf) > 0); | 1232 assert(WebRtc_available_read(aec->far_time_buf) > 0); |
1270 WebRtc_ReadBuffer(aec->far_time_buf, (void**)&farend_ptr, farend, 1); | 1233 WebRtc_ReadBuffer(aec->far_time_buf, (void**)&farend_ptr, farend, 1); |
1271 | 1234 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1333 aec->dInitMinPow[i] = aec->dMinPow[i]; | 1296 aec->dInitMinPow[i] = aec->dMinPow[i]; |
1334 } | 1297 } |
1335 } | 1298 } |
1336 aec->noisePow = aec->dInitMinPow; | 1299 aec->noisePow = aec->dInitMinPow; |
1337 } else { | 1300 } else { |
1338 aec->noisePow = aec->dMinPow; | 1301 aec->noisePow = aec->dMinPow; |
1339 } | 1302 } |
1340 | 1303 |
1341 // Block wise delay estimation used for logging | 1304 // Block wise delay estimation used for logging |
1342 if (aec->delay_logging_enabled) { | 1305 if (aec->delay_logging_enabled) { |
1343 if (WebRtc_AddFarSpectrumFloat( | 1306 if (WebRtc_AddFarSpectrumFloat(aec->delay_estimator_farend, |
1344 aec->delay_estimator_farend, abs_far_spectrum, PART_LEN1) == 0) { | 1307 abs_far_spectrum, PART_LEN1) == 0) { |
1345 int delay_estimate = WebRtc_DelayEstimatorProcessFloat( | 1308 int delay_estimate = WebRtc_DelayEstimatorProcessFloat( |
1346 aec->delay_estimator, abs_near_spectrum, PART_LEN1); | 1309 aec->delay_estimator, abs_near_spectrum, PART_LEN1); |
1347 if (delay_estimate >= 0) { | 1310 if (delay_estimate >= 0) { |
1348 // Update delay estimate buffer. | 1311 // Update delay estimate buffer. |
1349 aec->delay_histogram[delay_estimate]++; | 1312 aec->delay_histogram[delay_estimate]++; |
1350 aec->num_delay_values++; | 1313 aec->num_delay_values++; |
1351 } | 1314 } |
1352 if (aec->delay_metrics_delivered == 1 && | 1315 if (aec->delay_metrics_delivered == 1 && |
1353 aec->num_delay_values >= kDelayMetricsAggregationWindow) { | 1316 aec->num_delay_values >= kDelayMetricsAggregationWindow) { |
1354 UpdateDelayMetrics(aec); | 1317 UpdateDelayMetrics(aec); |
1355 } | 1318 } |
1356 } | 1319 } |
1357 } | 1320 } |
1358 | 1321 |
1359 // Update the xfBuf block position. | 1322 // Update the xfBuf block position. |
1360 aec->xfBufBlockPos--; | 1323 aec->xfBufBlockPos--; |
1361 if (aec->xfBufBlockPos == -1) { | 1324 if (aec->xfBufBlockPos == -1) { |
1362 aec->xfBufBlockPos = aec->num_partitions - 1; | 1325 aec->xfBufBlockPos = aec->num_partitions - 1; |
1363 } | 1326 } |
1364 | 1327 |
1365 // Buffer xf | 1328 // Buffer xf |
1366 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, | 1329 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, xf_ptr, |
1367 xf_ptr, | |
1368 sizeof(float) * PART_LEN1); | 1330 sizeof(float) * PART_LEN1); |
1369 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, | 1331 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, &xf_ptr[PART_LEN1], |
1370 &xf_ptr[PART_LEN1], | |
1371 sizeof(float) * PART_LEN1); | 1332 sizeof(float) * PART_LEN1); |
1372 | 1333 |
1373 // Perform echo subtraction. | 1334 // Perform echo subtraction. |
1374 EchoSubtraction(aec, | 1335 EchoSubtraction(aec, aec->num_partitions, aec->xfBufBlockPos, |
1375 aec->num_partitions, | 1336 aec->metricsMode, aec->extended_filter_enabled, |
1376 aec->xfBufBlockPos, | 1337 aec->normal_mu, aec->normal_error_threshold, aec->xfBuf, |
1377 aec->metricsMode, | 1338 nearend_ptr, aec->xPow, aec->wfBuf, &aec->linoutlevel, |
1378 aec->extended_filter_enabled, | |
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); | 1339 echo_subtractor_output); |
1387 | 1340 |
1388 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); | 1341 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); |
1389 | 1342 |
1390 // Perform echo suppression. | 1343 // Perform echo suppression. |
1391 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr); | 1344 EchoSuppression(aec, farend_ptr, echo_subtractor_output, output, outputH_ptr); |
1392 | 1345 |
1393 if (aec->metricsMode == 1) { | 1346 if (aec->metricsMode == 1) { |
1394 UpdateMetrics(aec); | 1347 UpdateMetrics(aec); |
1395 } | 1348 } |
(...skipping 21 matching lines...) Expand all Loading... |
1417 return NULL; | 1370 return NULL; |
1418 } | 1371 } |
1419 | 1372 |
1420 aec->outFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); | 1373 aec->outFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); |
1421 if (!aec->outFrBuf) { | 1374 if (!aec->outFrBuf) { |
1422 WebRtcAec_FreeAec(aec); | 1375 WebRtcAec_FreeAec(aec); |
1423 return NULL; | 1376 return NULL; |
1424 } | 1377 } |
1425 | 1378 |
1426 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1379 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
1427 aec->nearFrBufH[i] = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, | 1380 aec->nearFrBufH[i] = |
1428 sizeof(float)); | 1381 WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); |
1429 if (!aec->nearFrBufH[i]) { | 1382 if (!aec->nearFrBufH[i]) { |
1430 WebRtcAec_FreeAec(aec); | 1383 WebRtcAec_FreeAec(aec); |
1431 return NULL; | 1384 return NULL; |
1432 } | 1385 } |
1433 aec->outFrBufH[i] = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, | 1386 aec->outFrBufH[i] = |
1434 sizeof(float)); | 1387 WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); |
1435 if (!aec->outFrBufH[i]) { | 1388 if (!aec->outFrBufH[i]) { |
1436 WebRtcAec_FreeAec(aec); | 1389 WebRtcAec_FreeAec(aec); |
1437 return NULL; | 1390 return NULL; |
1438 } | 1391 } |
1439 } | 1392 } |
1440 | 1393 |
1441 // Create far-end buffers. | 1394 // Create far-end buffers. |
1442 // For bit exactness with legacy code, each element in |far_time_buf| is | 1395 // For bit exactness with legacy code, each element in |far_time_buf| is |
1443 // supposed to contain |PART_LEN2| samples with an overlap of |PART_LEN| | 1396 // supposed to contain |PART_LEN2| samples with an overlap of |PART_LEN| |
1444 // samples from the last frame. | 1397 // samples from the last frame. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1485 WebRtcAec_FilterFar = FilterFar; | 1438 WebRtcAec_FilterFar = FilterFar; |
1486 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; | 1439 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; |
1487 WebRtcAec_FilterAdaptation = FilterAdaptation; | 1440 WebRtcAec_FilterAdaptation = FilterAdaptation; |
1488 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; | 1441 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; |
1489 WebRtcAec_ComfortNoise = ComfortNoise; | 1442 WebRtcAec_ComfortNoise = ComfortNoise; |
1490 WebRtcAec_SubbandCoherence = SubbandCoherence; | 1443 WebRtcAec_SubbandCoherence = SubbandCoherence; |
1491 WebRtcAec_StoreAsComplex = StoreAsComplex; | 1444 WebRtcAec_StoreAsComplex = StoreAsComplex; |
1492 WebRtcAec_PartitionDelay = PartitionDelay; | 1445 WebRtcAec_PartitionDelay = PartitionDelay; |
1493 WebRtcAec_WindowData = WindowData; | 1446 WebRtcAec_WindowData = WindowData; |
1494 | 1447 |
1495 | |
1496 #if defined(WEBRTC_ARCH_X86_FAMILY) | 1448 #if defined(WEBRTC_ARCH_X86_FAMILY) |
1497 if (WebRtc_GetCPUInfo(kSSE2)) { | 1449 if (WebRtc_GetCPUInfo(kSSE2)) { |
1498 WebRtcAec_InitAec_SSE2(); | 1450 WebRtcAec_InitAec_SSE2(); |
1499 } | 1451 } |
1500 #endif | 1452 #endif |
1501 | 1453 |
1502 #if defined(MIPS_FPU_LE) | 1454 #if defined(MIPS_FPU_LE) |
1503 WebRtcAec_InitAec_mips(); | 1455 WebRtcAec_InitAec_mips(); |
1504 #endif | 1456 #endif |
1505 | 1457 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1567 } | 1519 } |
1568 | 1520 |
1569 // Initialize far-end buffers. | 1521 // Initialize far-end buffers. |
1570 WebRtc_InitBuffer(aec->far_time_buf); | 1522 WebRtc_InitBuffer(aec->far_time_buf); |
1571 | 1523 |
1572 #ifdef WEBRTC_AEC_DEBUG_DUMP | 1524 #ifdef WEBRTC_AEC_DEBUG_DUMP |
1573 { | 1525 { |
1574 int process_rate = sampFreq > 16000 ? 16000 : sampFreq; | 1526 int process_rate = sampFreq > 16000 ? 16000 : sampFreq; |
1575 RTC_AEC_DEBUG_WAV_REOPEN("aec_far", aec->instance_index, | 1527 RTC_AEC_DEBUG_WAV_REOPEN("aec_far", aec->instance_index, |
1576 aec->debug_dump_count, process_rate, | 1528 aec->debug_dump_count, process_rate, |
1577 &aec->farFile ); | 1529 &aec->farFile); |
1578 RTC_AEC_DEBUG_WAV_REOPEN("aec_near", aec->instance_index, | 1530 RTC_AEC_DEBUG_WAV_REOPEN("aec_near", aec->instance_index, |
1579 aec->debug_dump_count, process_rate, | 1531 aec->debug_dump_count, process_rate, |
1580 &aec->nearFile); | 1532 &aec->nearFile); |
1581 RTC_AEC_DEBUG_WAV_REOPEN("aec_out", aec->instance_index, | 1533 RTC_AEC_DEBUG_WAV_REOPEN("aec_out", aec->instance_index, |
1582 aec->debug_dump_count, process_rate, | 1534 aec->debug_dump_count, process_rate, |
1583 &aec->outFile ); | 1535 &aec->outFile); |
1584 RTC_AEC_DEBUG_WAV_REOPEN("aec_out_linear", aec->instance_index, | 1536 RTC_AEC_DEBUG_WAV_REOPEN("aec_out_linear", aec->instance_index, |
1585 aec->debug_dump_count, process_rate, | 1537 aec->debug_dump_count, process_rate, |
1586 &aec->outLinearFile); | 1538 &aec->outLinearFile); |
1587 } | 1539 } |
1588 | 1540 |
1589 RTC_AEC_DEBUG_RAW_OPEN("aec_e_fft", | 1541 RTC_AEC_DEBUG_RAW_OPEN("aec_e_fft", aec->debug_dump_count, &aec->e_fft_file); |
1590 aec->debug_dump_count, | |
1591 &aec->e_fft_file); | |
1592 | 1542 |
1593 ++aec->debug_dump_count; | 1543 ++aec->debug_dump_count; |
1594 #endif | 1544 #endif |
1595 aec->system_delay = 0; | 1545 aec->system_delay = 0; |
1596 | 1546 |
1597 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) { | 1547 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) { |
1598 return -1; | 1548 return -1; |
1599 } | 1549 } |
1600 if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) { | 1550 if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) { |
1601 return -1; | 1551 return -1; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1667 } | 1617 } |
1668 | 1618 |
1669 // Holds the last block written to | 1619 // Holds the last block written to |
1670 aec->xfBufBlockPos = 0; | 1620 aec->xfBufBlockPos = 0; |
1671 // TODO: Investigate need for these initializations. Deleting them doesn't | 1621 // TODO: Investigate need for these initializations. Deleting them doesn't |
1672 // change the output at all and yields 0.4% overall speedup. | 1622 // change the output at all and yields 0.4% overall speedup. |
1673 memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); | 1623 memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); |
1674 memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); | 1624 memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); |
1675 memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1); | 1625 memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1); |
1676 memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1); | 1626 memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1); |
1677 memset( | 1627 memset(aec->xfwBuf, 0, |
1678 aec->xfwBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); | 1628 sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); |
1679 memset(aec->se, 0, sizeof(float) * PART_LEN1); | 1629 memset(aec->se, 0, sizeof(float) * PART_LEN1); |
1680 | 1630 |
1681 // To prevent numerical instability in the first block. | 1631 // To prevent numerical instability in the first block. |
1682 for (i = 0; i < PART_LEN1; i++) { | 1632 for (i = 0; i < PART_LEN1; i++) { |
1683 aec->sd[i] = 1; | 1633 aec->sd[i] = 1; |
1684 } | 1634 } |
1685 for (i = 0; i < PART_LEN1; i++) { | 1635 for (i = 0; i < PART_LEN1; i++) { |
1686 aec->sx[i] = 1; | 1636 aec->sx[i] = 1; |
1687 } | 1637 } |
1688 | 1638 |
(...skipping 17 matching lines...) Expand all Loading... |
1706 | 1656 |
1707 aec->extreme_filter_divergence = 0; | 1657 aec->extreme_filter_divergence = 0; |
1708 | 1658 |
1709 // Metrics disabled by default | 1659 // Metrics disabled by default |
1710 aec->metricsMode = 0; | 1660 aec->metricsMode = 0; |
1711 InitMetrics(aec); | 1661 InitMetrics(aec); |
1712 | 1662 |
1713 return 0; | 1663 return 0; |
1714 } | 1664 } |
1715 | 1665 |
1716 | |
1717 // For bit exactness with a legacy code, |farend| is supposed to contain | 1666 // For bit exactness with a legacy code, |farend| is supposed to contain |
1718 // |PART_LEN2| samples with an overlap of |PART_LEN| samples from the last | 1667 // |PART_LEN2| samples with an overlap of |PART_LEN| samples from the last |
1719 // frame. | 1668 // frame. |
1720 // TODO(minyue): reduce |farend| to non-overlapped |PART_LEN| samples. | 1669 // TODO(minyue): reduce |farend| to non-overlapped |PART_LEN| samples. |
1721 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) { | 1670 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) { |
1722 // Check if the buffer is full, and in that case flush the oldest data. | 1671 // Check if the buffer is full, and in that case flush the oldest data. |
1723 if (WebRtc_available_write(aec->far_time_buf) < 1) { | 1672 if (WebRtc_available_write(aec->far_time_buf) < 1) { |
1724 WebRtcAec_MoveFarReadPtr(aec, 1); | 1673 WebRtcAec_MoveFarReadPtr(aec, 1); |
1725 } | 1674 } |
1726 | 1675 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1765 // give a guess on how much we need to shift far-end buffers to align with | 1714 // give a guess on how much we need to shift far-end buffers to align with |
1766 // the near-end signal. The other delay estimation algorithm uses the | 1715 // the near-end signal. The other delay estimation algorithm uses the |
1767 // far- and near-end signals to find the offset between them. This one | 1716 // far- and near-end signals to find the offset between them. This one |
1768 // (called "signal delay") is then used to fine tune the alignment, or | 1717 // (called "signal delay") is then used to fine tune the alignment, or |
1769 // simply compensate for errors in the system based one. | 1718 // simply compensate for errors in the system based one. |
1770 // Note that the two algorithms operate independently. Currently, we only | 1719 // Note that the two algorithms operate independently. Currently, we only |
1771 // allow one algorithm to be turned on. | 1720 // allow one algorithm to be turned on. |
1772 | 1721 |
1773 assert(aec->num_bands == num_bands); | 1722 assert(aec->num_bands == num_bands); |
1774 | 1723 |
1775 for (j = 0; j < num_samples; j+= FRAME_LEN) { | 1724 for (j = 0; j < num_samples; j += FRAME_LEN) { |
1776 // TODO(bjornv): Change the near-end buffer handling to be the same as for | 1725 // TODO(bjornv): Change the near-end buffer handling to be the same as for |
1777 // far-end, that is, with a near_pre_buf. | 1726 // far-end, that is, with a near_pre_buf. |
1778 // Buffer the near-end frame. | 1727 // Buffer the near-end frame. |
1779 WebRtc_WriteBuffer(aec->nearFrBuf, &nearend[0][j], FRAME_LEN); | 1728 WebRtc_WriteBuffer(aec->nearFrBuf, &nearend[0][j], FRAME_LEN); |
1780 // For H band | 1729 // For H band |
1781 for (i = 1; i < num_bands; ++i) { | 1730 for (i = 1; i < num_bands; ++i) { |
1782 WebRtc_WriteBuffer(aec->nearFrBufH[i - 1], &nearend[i][j], FRAME_LEN); | 1731 WebRtc_WriteBuffer(aec->nearFrBufH[i - 1], &nearend[i][j], FRAME_LEN); |
1783 } | 1732 } |
1784 | 1733 |
1785 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we | 1734 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we |
1786 // have enough far-end data for that by stuffing the buffer if the | 1735 // have enough far-end data for that by stuffing the buffer if the |
1787 // |system_delay| indicates others. | 1736 // |system_delay| indicates others. |
1788 if (aec->system_delay < FRAME_LEN) { | 1737 if (aec->system_delay < FRAME_LEN) { |
1789 // We don't have enough data so we rewind 10 ms. | 1738 // We don't have enough data so we rewind 10 ms. |
1790 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1)); | 1739 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1)); |
1791 } | 1740 } |
1792 | 1741 |
1793 if (!aec->delay_agnostic_enabled) { | 1742 if (!aec->delay_agnostic_enabled) { |
1794 // 2 a) Compensate for a possible change in the system delay. | 1743 // 2 a) Compensate for a possible change in the system delay. |
1795 | 1744 |
1796 // TODO(bjornv): Investigate how we should round the delay difference; | 1745 // TODO(bjornv): Investigate how we should round the delay difference; |
1797 // right now we know that incoming |knownDelay| is underestimated when | 1746 // right now we know that incoming |knownDelay| is underestimated when |
1798 // it's less than |aec->knownDelay|. We therefore, round (-32) in that | 1747 // it's less than |aec->knownDelay|. We therefore, round (-32) in that |
1799 // direction. In the other direction, we don't have this situation, but | 1748 // direction. In the other direction, we don't have this situation, but |
1800 // might flush one partition too little. This can cause non-causality, | 1749 // might flush one partition too little. This can cause non-causality, |
1801 // which should be investigated. Maybe, allow for a non-symmetric | 1750 // which should be investigated. Maybe, allow for a non-symmetric |
1802 // rounding, like -16. | 1751 // rounding, like -16. |
1803 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN; | 1752 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN; |
1804 int moved_elements = | 1753 int moved_elements = WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); |
1805 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); | |
1806 aec->knownDelay -= moved_elements * PART_LEN; | 1754 aec->knownDelay -= moved_elements * PART_LEN; |
1807 } else { | 1755 } else { |
1808 // 2 b) Apply signal based delay correction. | 1756 // 2 b) Apply signal based delay correction. |
1809 int move_elements = SignalBasedDelayCorrection(aec); | 1757 int move_elements = SignalBasedDelayCorrection(aec); |
1810 int moved_elements = | 1758 int moved_elements = WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); |
1811 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); | 1759 int far_near_buffer_diff = |
1812 int far_near_buffer_diff = WebRtc_available_read(aec->far_time_buf) - | 1760 WebRtc_available_read(aec->far_time_buf) - |
1813 WebRtc_available_read(aec->nearFrBuf) / PART_LEN; | 1761 WebRtc_available_read(aec->nearFrBuf) / PART_LEN; |
1814 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); | 1762 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); |
1815 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, | 1763 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, |
1816 moved_elements); | 1764 moved_elements); |
1817 aec->signal_delay_correction += moved_elements; | 1765 aec->signal_delay_correction += moved_elements; |
1818 // If we rely on reported system delay values only, a buffer underrun here | 1766 // If we rely on reported system delay values only, a buffer underrun here |
1819 // can never occur since we've taken care of that in 1) above. Here, we | 1767 // can never occur since we've taken care of that in 1) above. Here, we |
1820 // apply signal based delay correction and can therefore end up with | 1768 // apply signal based delay correction and can therefore end up with |
1821 // buffer underruns since the delay estimation can be wrong. We therefore | 1769 // buffer underruns since the delay estimation can be wrong. We therefore |
1822 // stuff the buffer with enough elements if needed. | 1770 // stuff the buffer with enough elements if needed. |
(...skipping 22 matching lines...) Expand all Loading... |
1845 } | 1793 } |
1846 // Obtain an output frame. | 1794 // Obtain an output frame. |
1847 WebRtc_ReadBuffer(aec->outFrBuf, NULL, &out[0][j], FRAME_LEN); | 1795 WebRtc_ReadBuffer(aec->outFrBuf, NULL, &out[0][j], FRAME_LEN); |
1848 // For H bands. | 1796 // For H bands. |
1849 for (i = 1; i < num_bands; ++i) { | 1797 for (i = 1; i < num_bands; ++i) { |
1850 WebRtc_ReadBuffer(aec->outFrBufH[i - 1], NULL, &out[i][j], FRAME_LEN); | 1798 WebRtc_ReadBuffer(aec->outFrBufH[i - 1], NULL, &out[i][j], FRAME_LEN); |
1851 } | 1799 } |
1852 } | 1800 } |
1853 } | 1801 } |
1854 | 1802 |
1855 int WebRtcAec_GetDelayMetricsCore(AecCore* self, int* median, int* std, | 1803 int WebRtcAec_GetDelayMetricsCore(AecCore* self, |
| 1804 int* median, |
| 1805 int* std, |
1856 float* fraction_poor_delays) { | 1806 float* fraction_poor_delays) { |
1857 assert(self != NULL); | 1807 assert(self != NULL); |
1858 assert(median != NULL); | 1808 assert(median != NULL); |
1859 assert(std != NULL); | 1809 assert(std != NULL); |
1860 | 1810 |
1861 if (self->delay_logging_enabled == 0) { | 1811 if (self->delay_logging_enabled == 0) { |
1862 // Logging disabled. | 1812 // Logging disabled. |
1863 return -1; | 1813 return -1; |
1864 } | 1814 } |
1865 | 1815 |
1866 if (self->delay_metrics_delivered == 0) { | 1816 if (self->delay_metrics_delivered == 0) { |
1867 UpdateDelayMetrics(self); | 1817 UpdateDelayMetrics(self); |
1868 self->delay_metrics_delivered = 1; | 1818 self->delay_metrics_delivered = 1; |
1869 } | 1819 } |
1870 *median = self->delay_median; | 1820 *median = self->delay_median; |
1871 *std = self->delay_std; | 1821 *std = self->delay_std; |
1872 *fraction_poor_delays = self->fraction_poor_delays; | 1822 *fraction_poor_delays = self->fraction_poor_delays; |
1873 | 1823 |
1874 return 0; | 1824 return 0; |
1875 } | 1825 } |
1876 | 1826 |
1877 int WebRtcAec_echo_state(AecCore* self) { return self->echoState; } | 1827 int WebRtcAec_echo_state(AecCore* self) { |
| 1828 return self->echoState; |
| 1829 } |
1878 | 1830 |
1879 void WebRtcAec_GetEchoStats(AecCore* self, | 1831 void WebRtcAec_GetEchoStats(AecCore* self, |
1880 Stats* erl, | 1832 Stats* erl, |
1881 Stats* erle, | 1833 Stats* erle, |
1882 Stats* a_nlp) { | 1834 Stats* a_nlp) { |
1883 assert(erl != NULL); | 1835 assert(erl != NULL); |
1884 assert(erle != NULL); | 1836 assert(erle != NULL); |
1885 assert(a_nlp != NULL); | 1837 assert(a_nlp != NULL); |
1886 *erl = self->erl; | 1838 *erl = self->erl; |
1887 *erle = self->erle; | 1839 *erle = self->erle; |
(...skipping 30 matching lines...) Expand all Loading... |
1918 self->extended_filter_enabled = enable; | 1870 self->extended_filter_enabled = enable; |
1919 self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions; | 1871 self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions; |
1920 // Update the delay estimator with filter length. See InitAEC() for details. | 1872 // Update the delay estimator with filter length. See InitAEC() for details. |
1921 WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2); | 1873 WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2); |
1922 } | 1874 } |
1923 | 1875 |
1924 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 1876 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
1925 return self->extended_filter_enabled; | 1877 return self->extended_filter_enabled; |
1926 } | 1878 } |
1927 | 1879 |
1928 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } | 1880 int WebRtcAec_system_delay(AecCore* self) { |
| 1881 return self->system_delay; |
| 1882 } |
1929 | 1883 |
1930 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1884 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1931 assert(delay >= 0); | 1885 assert(delay >= 0); |
1932 self->system_delay = delay; | 1886 self->system_delay = delay; |
1933 } | 1887 } |
OLD | NEW |