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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 break; | 743 break; |
763 } | 744 } |
764 } | 745 } |
765 // Account for lookahead. | 746 // Account for lookahead. |
766 self->delay_median = (median - lookahead) * kMsPerBlock; | 747 self->delay_median = (median - lookahead) * kMsPerBlock; |
767 | 748 |
768 // Calculate the L1 norm, with median value as central moment. | 749 // Calculate the L1 norm, with median value as central moment. |
769 for (i = 0; i < kHistorySizeBlocks; i++) { | 750 for (i = 0; i < kHistorySizeBlocks; i++) { |
770 l1_norm += abs(i - median) * self->delay_histogram[i]; | 751 l1_norm += abs(i - median) * self->delay_histogram[i]; |
771 } | 752 } |
772 self->delay_std = (int)((l1_norm + self->num_delay_values / 2) / | 753 self->delay_std = |
773 self->num_delay_values) * kMsPerBlock; | 754 (int)((l1_norm + self->num_delay_values / 2) / self->num_delay_values) * |
| 755 kMsPerBlock; |
774 | 756 |
775 // Determine fraction of delays that are out of bounds, that is, either | 757 // Determine fraction of delays that are out of bounds, that is, either |
776 // negative (anti-causal system) or larger than the AEC filter length. | 758 // negative (anti-causal system) or larger than the AEC filter length. |
777 { | 759 { |
778 int num_delays_out_of_bounds = self->num_delay_values; | 760 int num_delays_out_of_bounds = self->num_delay_values; |
779 const int histogram_length = sizeof(self->delay_histogram) / | 761 const int histogram_length = |
780 sizeof(self->delay_histogram[0]); | 762 sizeof(self->delay_histogram) / sizeof(self->delay_histogram[0]); |
781 for (i = lookahead; i < lookahead + self->num_partitions; ++i) { | 763 for (i = lookahead; i < lookahead + self->num_partitions; ++i) { |
782 if (i < histogram_length) | 764 if (i < histogram_length) |
783 num_delays_out_of_bounds -= self->delay_histogram[i]; | 765 num_delays_out_of_bounds -= self->delay_histogram[i]; |
784 } | 766 } |
785 self->fraction_poor_delays = (float)num_delays_out_of_bounds / | 767 self->fraction_poor_delays = |
786 self->num_delay_values; | 768 (float)num_delays_out_of_bounds / self->num_delay_values; |
787 } | 769 } |
788 | 770 |
789 // Reset histogram. | 771 // Reset histogram. |
790 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); | 772 memset(self->delay_histogram, 0, sizeof(self->delay_histogram)); |
791 self->num_delay_values = 0; | 773 self->num_delay_values = 0; |
792 | 774 |
793 return; | 775 return; |
794 } | 776 } |
795 | 777 |
796 static void ScaledInverseFft(float freq_data[2][PART_LEN1], | 778 static void ScaledInverseFft(float freq_data[2][PART_LEN1], |
797 float time_data[PART_LEN2], | 779 float time_data[PART_LEN2], |
798 float scale, | 780 float scale, |
799 int conjugate) { | 781 int conjugate) { |
800 int i; | 782 int i; |
801 const float normalization = scale / ((float)PART_LEN2); | 783 const float normalization = scale / ((float)PART_LEN2); |
802 const float sign = (conjugate ? -1 : 1); | 784 const float sign = (conjugate ? -1 : 1); |
803 time_data[0] = freq_data[0][0] * normalization; | 785 time_data[0] = freq_data[0][0] * normalization; |
804 time_data[1] = freq_data[0][PART_LEN] * normalization; | 786 time_data[1] = freq_data[0][PART_LEN] * normalization; |
805 for (i = 1; i < PART_LEN; i++) { | 787 for (i = 1; i < PART_LEN; i++) { |
806 time_data[2 * i] = freq_data[0][i] * normalization; | 788 time_data[2 * i] = freq_data[0][i] * normalization; |
807 time_data[2 * i + 1] = sign * freq_data[1][i] * normalization; | 789 time_data[2 * i + 1] = sign * freq_data[1][i] * normalization; |
808 } | 790 } |
809 aec_rdft_inverse_128(time_data); | 791 aec_rdft_inverse_128(time_data); |
810 } | 792 } |
811 | 793 |
812 | 794 static void Fft(float time_data[PART_LEN2], float freq_data[2][PART_LEN1]) { |
813 static void Fft(float time_data[PART_LEN2], | |
814 float freq_data[2][PART_LEN1]) { | |
815 int i; | 795 int i; |
816 aec_rdft_forward_128(time_data); | 796 aec_rdft_forward_128(time_data); |
817 | 797 |
818 // Reorder fft output data. | 798 // Reorder fft output data. |
819 freq_data[1][0] = 0; | 799 freq_data[1][0] = 0; |
820 freq_data[1][PART_LEN] = 0; | 800 freq_data[1][PART_LEN] = 0; |
821 freq_data[0][0] = time_data[0]; | 801 freq_data[0][0] = time_data[0]; |
822 freq_data[0][PART_LEN] = time_data[1]; | 802 freq_data[0][PART_LEN] = time_data[1]; |
823 for (i = 1; i < PART_LEN; i++) { | 803 for (i = 1; i < PART_LEN; i++) { |
824 freq_data[0][i] = time_data[2 * i]; | 804 freq_data[0][i] = time_data[2 * i]; |
(...skipping 20 matching lines...) Expand all Loading... |
845 // negative |last_delay| is an invalid one. | 825 // negative |last_delay| is an invalid one. |
846 // 2. Verify that there is a delay change. In addition, only allow a change | 826 // 2. Verify that there is a delay change. In addition, only allow a change |
847 // if the delay is outside a certain region taking the AEC filter length | 827 // if the delay is outside a certain region taking the AEC filter length |
848 // into account. | 828 // into account. |
849 // TODO(bjornv): Investigate if we can remove the non-zero delay change check. | 829 // TODO(bjornv): Investigate if we can remove the non-zero delay change check. |
850 // 3. Only allow delay correction if the delay estimation quality exceeds | 830 // 3. Only allow delay correction if the delay estimation quality exceeds |
851 // |delay_quality_threshold|. | 831 // |delay_quality_threshold|. |
852 // 4. Finally, verify that the proposed |delay_correction| is feasible by | 832 // 4. Finally, verify that the proposed |delay_correction| is feasible by |
853 // comparing with the size of the far-end buffer. | 833 // comparing with the size of the far-end buffer. |
854 last_delay = WebRtc_last_delay(self->delay_estimator); | 834 last_delay = WebRtc_last_delay(self->delay_estimator); |
855 if ((last_delay >= 0) && | 835 if ((last_delay >= 0) && (last_delay != self->previous_delay) && |
856 (last_delay != self->previous_delay) && | |
857 (WebRtc_last_delay_quality(self->delay_estimator) > | 836 (WebRtc_last_delay_quality(self->delay_estimator) > |
858 self->delay_quality_threshold)) { | 837 self->delay_quality_threshold)) { |
859 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); | 838 int delay = last_delay - WebRtc_lookahead(self->delay_estimator); |
860 // Allow for a slack in the actual delay, defined by a |lower_bound| and an | 839 // Allow for a slack in the actual delay, defined by a |lower_bound| and an |
861 // |upper_bound|. The adaptive echo cancellation filter is currently | 840 // |upper_bound|. The adaptive echo cancellation filter is currently |
862 // |num_partitions| (of 64 samples) long. If the delay estimate is negative | 841 // |num_partitions| (of 64 samples) long. If the delay estimate is negative |
863 // or at least 3/4 of the filter length we open up for correction. | 842 // or at least 3/4 of the filter length we open up for correction. |
864 const int lower_bound = 0; | 843 const int lower_bound = 0; |
865 const int upper_bound = self->num_partitions * 3 / 4; | 844 const int upper_bound = self->num_partitions * 3 / 4; |
866 const int do_correction = delay <= lower_bound || delay > upper_bound; | 845 const int do_correction = delay <= lower_bound || delay > upper_bound; |
867 if (do_correction == 1) { | 846 if (do_correction == 1) { |
868 int available_read = (int)WebRtc_available_read(self->far_time_buf); | 847 int available_read = (int)WebRtc_available_read(self->far_time_buf); |
(...skipping 13 matching lines...) Expand all Loading... |
882 } else { | 861 } else { |
883 self->previous_delay = last_delay; | 862 self->previous_delay = last_delay; |
884 ++self->delay_correction_count; | 863 ++self->delay_correction_count; |
885 } | 864 } |
886 } | 865 } |
887 } | 866 } |
888 // Update the |delay_quality_threshold| once we have our first delay | 867 // Update the |delay_quality_threshold| once we have our first delay |
889 // correction. | 868 // correction. |
890 if (self->delay_correction_count > 0) { | 869 if (self->delay_correction_count > 0) { |
891 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); | 870 float delay_quality = WebRtc_last_delay_quality(self->delay_estimator); |
892 delay_quality = (delay_quality > kDelayQualityThresholdMax ? | 871 delay_quality = |
893 kDelayQualityThresholdMax : delay_quality); | 872 (delay_quality > kDelayQualityThresholdMax ? kDelayQualityThresholdMax |
| 873 : delay_quality); |
894 self->delay_quality_threshold = | 874 self->delay_quality_threshold = |
895 (delay_quality > self->delay_quality_threshold ? delay_quality : | 875 (delay_quality > self->delay_quality_threshold |
896 self->delay_quality_threshold); | 876 ? delay_quality |
| 877 : self->delay_quality_threshold); |
897 } | 878 } |
898 return delay_correction; | 879 return delay_correction; |
899 } | 880 } |
900 | 881 |
901 static void EchoSubtraction( | 882 static void EchoSubtraction(AecCore* aec, |
902 AecCore* aec, | 883 int num_partitions, |
903 int num_partitions, | 884 int x_fft_buf_block_pos, |
904 int x_fft_buf_block_pos, | 885 int extended_filter_enabled, |
905 int extended_filter_enabled, | 886 float normal_mu, |
906 float normal_mu, | 887 float normal_error_threshold, |
907 float normal_error_threshold, | 888 float x_fft_buf[2] |
908 float x_fft_buf[2][kExtendedNumPartitions * PART_LEN1], | 889 [kExtendedNumPartitions * PART_LEN1], |
909 float* const y, | 890 float* const y, |
910 float x_pow[PART_LEN1], | 891 float x_pow[PART_LEN1], |
911 float h_fft_buf[2][kExtendedNumPartitions * PART_LEN1], | 892 float h_fft_buf[2] |
912 float echo_subtractor_output[PART_LEN]) { | 893 [kExtendedNumPartitions * PART_LEN1], |
| 894 float echo_subtractor_output[PART_LEN]) { |
913 float s_fft[2][PART_LEN1]; | 895 float s_fft[2][PART_LEN1]; |
914 float e_extended[PART_LEN2]; | 896 float e_extended[PART_LEN2]; |
915 float s_extended[PART_LEN2]; | 897 float s_extended[PART_LEN2]; |
916 float *s; | 898 float* s; |
917 float e[PART_LEN]; | 899 float e[PART_LEN]; |
918 float e_fft[2][PART_LEN1]; | 900 float e_fft[2][PART_LEN1]; |
919 int i; | 901 int i; |
920 memset(s_fft, 0, sizeof(s_fft)); | 902 memset(s_fft, 0, sizeof(s_fft)); |
921 | 903 |
922 // Conditionally reset the echo subtraction filter if the filter has diverged | 904 // Conditionally reset the echo subtraction filter if the filter has diverged |
923 // significantly. | 905 // significantly. |
924 if (!aec->extended_filter_enabled && | 906 if (!aec->extended_filter_enabled && aec->extreme_filter_divergence) { |
925 aec->extreme_filter_divergence) { | |
926 memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); | 907 memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); |
927 aec->extreme_filter_divergence = 0; | 908 aec->extreme_filter_divergence = 0; |
928 } | 909 } |
929 | 910 |
930 // Produce echo estimate s_fft. | 911 // Produce echo estimate s_fft. |
931 WebRtcAec_FilterFar(num_partitions, | 912 WebRtcAec_FilterFar(num_partitions, x_fft_buf_block_pos, x_fft_buf, h_fft_buf, |
932 x_fft_buf_block_pos, | |
933 x_fft_buf, | |
934 h_fft_buf, | |
935 s_fft); | 913 s_fft); |
936 | 914 |
937 // Compute the time-domain echo estimate s. | 915 // Compute the time-domain echo estimate s. |
938 ScaledInverseFft(s_fft, s_extended, 2.0f, 0); | 916 ScaledInverseFft(s_fft, s_extended, 2.0f, 0); |
939 s = &s_extended[PART_LEN]; | 917 s = &s_extended[PART_LEN]; |
940 | 918 |
941 // Compute the time-domain echo prediction error. | 919 // Compute the time-domain echo prediction error. |
942 for (i = 0; i < PART_LEN; ++i) { | 920 for (i = 0; i < PART_LEN; ++i) { |
943 e[i] = y[i] - s[i]; | 921 e[i] = y[i] - s[i]; |
944 } | 922 } |
945 | 923 |
946 // Compute the frequency domain echo prediction error. | 924 // Compute the frequency domain echo prediction error. |
947 memset(e_extended, 0, sizeof(float) * PART_LEN); | 925 memset(e_extended, 0, sizeof(float) * PART_LEN); |
948 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); | 926 memcpy(e_extended + PART_LEN, e, sizeof(float) * PART_LEN); |
949 Fft(e_extended, e_fft); | 927 Fft(e_extended, e_fft); |
950 | 928 |
951 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, | 929 RTC_AEC_DEBUG_RAW_WRITE(aec->e_fft_file, &e_fft[0][0], |
952 &e_fft[0][0], | |
953 sizeof(e_fft[0][0]) * PART_LEN1 * 2); | 930 sizeof(e_fft[0][0]) * PART_LEN1 * 2); |
954 | 931 |
955 // Scale error signal inversely with far power. | 932 // Scale error signal inversely with far power. |
956 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, | 933 WebRtcAec_ScaleErrorSignal(extended_filter_enabled, normal_mu, |
957 normal_mu, | 934 normal_error_threshold, x_pow, e_fft); |
958 normal_error_threshold, | 935 WebRtcAec_FilterAdaptation(num_partitions, x_fft_buf_block_pos, x_fft_buf, |
959 x_pow, | 936 e_fft, h_fft_buf); |
960 e_fft); | |
961 WebRtcAec_FilterAdaptation(num_partitions, | |
962 x_fft_buf_block_pos, | |
963 x_fft_buf, | |
964 e_fft, | |
965 h_fft_buf); | |
966 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); | 937 memcpy(echo_subtractor_output, e, sizeof(float) * PART_LEN); |
967 } | 938 } |
968 | 939 |
969 static void EchoSuppression(AecCore* aec, | 940 static void EchoSuppression(AecCore* aec, |
970 float farend[PART_LEN2], | 941 float farend[PART_LEN2], |
971 float* echo_subtractor_output, | 942 float* echo_subtractor_output, |
972 float* output, | 943 float* output, |
973 float* const* outputH) { | 944 float* const* outputH) { |
974 float efw[2][PART_LEN1]; | 945 float efw[2][PART_LEN1]; |
975 float xfw[2][PART_LEN1]; | 946 float xfw[2][PART_LEN1]; |
(...skipping 17 matching lines...) Expand all Loading... |
993 const float* min_overdrive = aec->extended_filter_enabled | 964 const float* min_overdrive = aec->extended_filter_enabled |
994 ? kExtendedMinOverDrive | 965 ? kExtendedMinOverDrive |
995 : kNormalMinOverDrive; | 966 : kNormalMinOverDrive; |
996 | 967 |
997 // Filter energy | 968 // Filter energy |
998 const int delayEstInterval = 10 * aec->mult; | 969 const int delayEstInterval = 10 * aec->mult; |
999 | 970 |
1000 float* xfw_ptr = NULL; | 971 float* xfw_ptr = NULL; |
1001 | 972 |
1002 // Update eBuf with echo subtractor output. | 973 // Update eBuf with echo subtractor output. |
1003 memcpy(aec->eBuf + PART_LEN, | 974 memcpy(aec->eBuf + PART_LEN, echo_subtractor_output, |
1004 echo_subtractor_output, | |
1005 sizeof(float) * PART_LEN); | 975 sizeof(float) * PART_LEN); |
1006 | 976 |
1007 // Analysis filter banks for the echo suppressor. | 977 // Analysis filter banks for the echo suppressor. |
1008 // Windowed near-end ffts. | 978 // Windowed near-end ffts. |
1009 WindowData(fft, aec->dBuf); | 979 WindowData(fft, aec->dBuf); |
1010 aec_rdft_forward_128(fft); | 980 aec_rdft_forward_128(fft); |
1011 StoreAsComplex(fft, dfw); | 981 StoreAsComplex(fft, dfw); |
1012 | 982 |
1013 // Windowed echo suppressor output ffts. | 983 // Windowed echo suppressor output ffts. |
1014 WindowData(fft, aec->eBuf); | 984 WindowData(fft, aec->eBuf); |
(...skipping 10 matching lines...) Expand all Loading... |
1025 // Buffer far. | 995 // Buffer far. |
1026 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); | 996 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1); |
1027 | 997 |
1028 aec->delayEstCtr++; | 998 aec->delayEstCtr++; |
1029 if (aec->delayEstCtr == delayEstInterval) { | 999 if (aec->delayEstCtr == delayEstInterval) { |
1030 aec->delayEstCtr = 0; | 1000 aec->delayEstCtr = 0; |
1031 aec->delayIdx = WebRtcAec_PartitionDelay(aec); | 1001 aec->delayIdx = WebRtcAec_PartitionDelay(aec); |
1032 } | 1002 } |
1033 | 1003 |
1034 // Use delayed far. | 1004 // Use delayed far. |
1035 memcpy(xfw, | 1005 memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1, |
1036 aec->xfwBuf + aec->delayIdx * PART_LEN1, | |
1037 sizeof(xfw[0][0]) * 2 * PART_LEN1); | 1006 sizeof(xfw[0][0]) * 2 * PART_LEN1); |
1038 | 1007 |
1039 WebRtcAec_SubbandCoherence(aec, efw, dfw, xfw, fft, cohde, cohxd, | 1008 WebRtcAec_SubbandCoherence(aec, efw, dfw, xfw, fft, cohde, cohxd, |
1040 &aec->extreme_filter_divergence); | 1009 &aec->extreme_filter_divergence); |
1041 | 1010 |
1042 // Select the microphone signal as output if the filter is deemed to have | 1011 // Select the microphone signal as output if the filter is deemed to have |
1043 // diverged. | 1012 // diverged. |
1044 if (aec->divergeState) { | 1013 if (aec->divergeState) { |
1045 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); | 1014 memcpy(efw, dfw, sizeof(efw[0][0]) * 2 * PART_LEN1); |
1046 } | 1015 } |
(...skipping 30 matching lines...) Expand all Loading... |
1077 hNlFb = hNlDeAvg; | 1046 hNlFb = hNlDeAvg; |
1078 hNlFbLow = hNlDeAvg; | 1047 hNlFbLow = hNlDeAvg; |
1079 } else { | 1048 } else { |
1080 for (i = 0; i < PART_LEN1; i++) { | 1049 for (i = 0; i < PART_LEN1; i++) { |
1081 hNl[i] = 1 - cohxd[i]; | 1050 hNl[i] = 1 - cohxd[i]; |
1082 } | 1051 } |
1083 hNlFb = hNlXdAvg; | 1052 hNlFb = hNlXdAvg; |
1084 hNlFbLow = hNlXdAvg; | 1053 hNlFbLow = hNlXdAvg; |
1085 } | 1054 } |
1086 } else { | 1055 } else { |
1087 | |
1088 if (aec->stNearState == 1) { | 1056 if (aec->stNearState == 1) { |
1089 aec->echoState = 0; | 1057 aec->echoState = 0; |
1090 memcpy(hNl, cohde, sizeof(hNl)); | 1058 memcpy(hNl, cohde, sizeof(hNl)); |
1091 hNlFb = hNlDeAvg; | 1059 hNlFb = hNlDeAvg; |
1092 hNlFbLow = hNlDeAvg; | 1060 hNlFbLow = hNlDeAvg; |
1093 } else { | 1061 } else { |
1094 aec->echoState = 1; | 1062 aec->echoState = 1; |
1095 for (i = 0; i < PART_LEN1; i++) { | 1063 for (i = 0; i < PART_LEN1; i++) { |
1096 hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]); | 1064 hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]); |
1097 } | 1065 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1152 // scaling only in UpdateMetrics(). | 1120 // scaling only in UpdateMetrics(). |
1153 UpdateLevel(&aec->nlpoutlevel, CalculatePower(fft, PART_LEN2)); | 1121 UpdateLevel(&aec->nlpoutlevel, CalculatePower(fft, PART_LEN2)); |
1154 } | 1122 } |
1155 | 1123 |
1156 // Overlap and add to obtain output. | 1124 // Overlap and add to obtain output. |
1157 for (i = 0; i < PART_LEN; i++) { | 1125 for (i = 0; i < PART_LEN; i++) { |
1158 output[i] = (fft[i] * WebRtcAec_sqrtHanning[i] + | 1126 output[i] = (fft[i] * WebRtcAec_sqrtHanning[i] + |
1159 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]); | 1127 aec->outBuf[i] * WebRtcAec_sqrtHanning[PART_LEN - i]); |
1160 | 1128 |
1161 // Saturate output to keep it in the allowed range. | 1129 // Saturate output to keep it in the allowed range. |
1162 output[i] = WEBRTC_SPL_SAT( | 1130 output[i] = |
1163 WEBRTC_SPL_WORD16_MAX, output[i], WEBRTC_SPL_WORD16_MIN); | 1131 WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, output[i], WEBRTC_SPL_WORD16_MIN); |
1164 } | 1132 } |
1165 memcpy(aec->outBuf, &fft[PART_LEN], PART_LEN * sizeof(aec->outBuf[0])); | 1133 memcpy(aec->outBuf, &fft[PART_LEN], PART_LEN * sizeof(aec->outBuf[0])); |
1166 | 1134 |
1167 // For H band | 1135 // For H band |
1168 if (aec->num_bands > 1) { | 1136 if (aec->num_bands > 1) { |
1169 // H band gain | 1137 // H band gain |
1170 // average nlp over low band: average over second half of freq spectrum | 1138 // average nlp over low band: average over second half of freq spectrum |
1171 // (4->8khz) | 1139 // (4->8khz) |
1172 GetHighbandGain(hNl, &nlpGainHband); | 1140 GetHighbandGain(hNl, &nlpGainHband); |
1173 | 1141 |
1174 // Inverse comfort_noise | 1142 // Inverse comfort_noise |
1175 ScaledInverseFft(comfortNoiseHband, fft, 2.0f, 0); | 1143 ScaledInverseFft(comfortNoiseHband, fft, 2.0f, 0); |
1176 | 1144 |
1177 // compute gain factor | 1145 // compute gain factor |
1178 for (j = 0; j < aec->num_bands - 1; ++j) { | 1146 for (j = 0; j < aec->num_bands - 1; ++j) { |
1179 for (i = 0; i < PART_LEN; i++) { | 1147 for (i = 0; i < PART_LEN; i++) { |
1180 outputH[j][i] = aec->dBufH[j][i] * nlpGainHband; | 1148 outputH[j][i] = aec->dBufH[j][i] * nlpGainHband; |
1181 } | 1149 } |
1182 } | 1150 } |
1183 | 1151 |
1184 // Add some comfort noise where Hband is attenuated. | 1152 // Add some comfort noise where Hband is attenuated. |
1185 for (i = 0; i < PART_LEN; i++) { | 1153 for (i = 0; i < PART_LEN; i++) { |
1186 outputH[0][i] += cnScaleHband * fft[i]; | 1154 outputH[0][i] += cnScaleHband * fft[i]; |
1187 } | 1155 } |
1188 | 1156 |
1189 // Saturate output to keep it in the allowed range. | 1157 // Saturate output to keep it in the allowed range. |
1190 for (j = 0; j < aec->num_bands - 1; ++j) { | 1158 for (j = 0; j < aec->num_bands - 1; ++j) { |
1191 for (i = 0; i < PART_LEN; i++) { | 1159 for (i = 0; i < PART_LEN; i++) { |
1192 outputH[j][i] = WEBRTC_SPL_SAT( | 1160 outputH[j][i] = WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, outputH[j][i], |
1193 WEBRTC_SPL_WORD16_MAX, outputH[j][i], WEBRTC_SPL_WORD16_MIN); | 1161 WEBRTC_SPL_WORD16_MIN); |
1194 } | 1162 } |
1195 } | 1163 } |
1196 | |
1197 } | 1164 } |
1198 | 1165 |
1199 // Copy the current block to the old position. | 1166 // Copy the current block to the old position. |
1200 memcpy(aec->dBuf, aec->dBuf + PART_LEN, sizeof(float) * PART_LEN); | 1167 memcpy(aec->dBuf, aec->dBuf + PART_LEN, sizeof(float) * PART_LEN); |
1201 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN); | 1168 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN); |
1202 | 1169 |
1203 // Copy the current block to the old position for H band | 1170 // Copy the current block to the old position for H band |
1204 for (j = 0; j < aec->num_bands - 1; ++j) { | 1171 for (j = 0; j < aec->num_bands - 1; ++j) { |
1205 memcpy(aec->dBufH[j], aec->dBufH[j] + PART_LEN, sizeof(float) * PART_LEN); | 1172 memcpy(aec->dBufH[j], aec->dBufH[j] + PART_LEN, sizeof(float) * PART_LEN); |
1206 } | 1173 } |
1207 | 1174 |
1208 memmove(aec->xfwBuf + PART_LEN1, | 1175 memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf, |
1209 aec->xfwBuf, | |
1210 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); | 1176 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1); |
1211 } | 1177 } |
1212 | 1178 |
1213 static void ProcessBlock(AecCore* aec) { | 1179 static void ProcessBlock(AecCore* aec) { |
1214 size_t i; | 1180 size_t i; |
1215 | 1181 |
1216 float fft[PART_LEN2]; | 1182 float fft[PART_LEN2]; |
1217 float xf[2][PART_LEN1]; | 1183 float xf[2][PART_LEN1]; |
1218 float df[2][PART_LEN1]; | 1184 float df[2][PART_LEN1]; |
1219 float far_spectrum = 0.0f; | 1185 float far_spectrum = 0.0f; |
(...skipping 18 matching lines...) Expand all Loading... |
1238 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; | 1204 float outputH[NUM_HIGH_BANDS_MAX][PART_LEN]; |
1239 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; | 1205 float* outputH_ptr[NUM_HIGH_BANDS_MAX]; |
1240 float* xf_ptr = NULL; | 1206 float* xf_ptr = NULL; |
1241 | 1207 |
1242 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1208 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
1243 outputH_ptr[i] = outputH[i]; | 1209 outputH_ptr[i] = outputH[i]; |
1244 } | 1210 } |
1245 | 1211 |
1246 // Concatenate old and new nearend blocks. | 1212 // Concatenate old and new nearend blocks. |
1247 for (i = 0; i < aec->num_bands - 1; ++i) { | 1213 for (i = 0; i < aec->num_bands - 1; ++i) { |
1248 WebRtc_ReadBuffer(aec->nearFrBufH[i], | 1214 WebRtc_ReadBuffer(aec->nearFrBufH[i], (void**)&nearend_ptr, nearend, |
1249 (void**)&nearend_ptr, | |
1250 nearend, | |
1251 PART_LEN); | 1215 PART_LEN); |
1252 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); | 1216 memcpy(aec->dBufH[i] + PART_LEN, nearend_ptr, sizeof(nearend)); |
1253 } | 1217 } |
1254 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN); | 1218 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN); |
1255 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend)); | 1219 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend)); |
1256 | 1220 |
1257 // We should always have at least one element stored in |far_buf|. | 1221 // We should always have at least one element stored in |far_buf|. |
1258 assert(WebRtc_available_read(aec->far_time_buf) > 0); | 1222 assert(WebRtc_available_read(aec->far_time_buf) > 0); |
1259 WebRtc_ReadBuffer(aec->far_time_buf, (void**)&farend_ptr, farend, 1); | 1223 WebRtc_ReadBuffer(aec->far_time_buf, (void**)&farend_ptr, farend, 1); |
1260 | 1224 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1323 aec->dInitMinPow[i] = aec->dMinPow[i]; | 1287 aec->dInitMinPow[i] = aec->dMinPow[i]; |
1324 } | 1288 } |
1325 } | 1289 } |
1326 aec->noisePow = aec->dInitMinPow; | 1290 aec->noisePow = aec->dInitMinPow; |
1327 } else { | 1291 } else { |
1328 aec->noisePow = aec->dMinPow; | 1292 aec->noisePow = aec->dMinPow; |
1329 } | 1293 } |
1330 | 1294 |
1331 // Block wise delay estimation used for logging | 1295 // Block wise delay estimation used for logging |
1332 if (aec->delay_logging_enabled) { | 1296 if (aec->delay_logging_enabled) { |
1333 if (WebRtc_AddFarSpectrumFloat( | 1297 if (WebRtc_AddFarSpectrumFloat(aec->delay_estimator_farend, |
1334 aec->delay_estimator_farend, abs_far_spectrum, PART_LEN1) == 0) { | 1298 abs_far_spectrum, PART_LEN1) == 0) { |
1335 int delay_estimate = WebRtc_DelayEstimatorProcessFloat( | 1299 int delay_estimate = WebRtc_DelayEstimatorProcessFloat( |
1336 aec->delay_estimator, abs_near_spectrum, PART_LEN1); | 1300 aec->delay_estimator, abs_near_spectrum, PART_LEN1); |
1337 if (delay_estimate >= 0) { | 1301 if (delay_estimate >= 0) { |
1338 // Update delay estimate buffer. | 1302 // Update delay estimate buffer. |
1339 aec->delay_histogram[delay_estimate]++; | 1303 aec->delay_histogram[delay_estimate]++; |
1340 aec->num_delay_values++; | 1304 aec->num_delay_values++; |
1341 } | 1305 } |
1342 if (aec->delay_metrics_delivered == 1 && | 1306 if (aec->delay_metrics_delivered == 1 && |
1343 aec->num_delay_values >= kDelayMetricsAggregationWindow) { | 1307 aec->num_delay_values >= kDelayMetricsAggregationWindow) { |
1344 UpdateDelayMetrics(aec); | 1308 UpdateDelayMetrics(aec); |
1345 } | 1309 } |
1346 } | 1310 } |
1347 } | 1311 } |
1348 | 1312 |
1349 // Update the xfBuf block position. | 1313 // Update the xfBuf block position. |
1350 aec->xfBufBlockPos--; | 1314 aec->xfBufBlockPos--; |
1351 if (aec->xfBufBlockPos == -1) { | 1315 if (aec->xfBufBlockPos == -1) { |
1352 aec->xfBufBlockPos = aec->num_partitions - 1; | 1316 aec->xfBufBlockPos = aec->num_partitions - 1; |
1353 } | 1317 } |
1354 | 1318 |
1355 // Buffer xf | 1319 // Buffer xf |
1356 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, | 1320 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, xf_ptr, |
1357 xf_ptr, | |
1358 sizeof(float) * PART_LEN1); | 1321 sizeof(float) * PART_LEN1); |
1359 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, | 1322 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, &xf_ptr[PART_LEN1], |
1360 &xf_ptr[PART_LEN1], | |
1361 sizeof(float) * PART_LEN1); | 1323 sizeof(float) * PART_LEN1); |
1362 | 1324 |
1363 // Perform echo subtraction. | 1325 // Perform echo subtraction. |
1364 EchoSubtraction(aec, | 1326 EchoSubtraction(aec, aec->num_partitions, aec->xfBufBlockPos, |
1365 aec->num_partitions, | |
1366 aec->xfBufBlockPos, | |
1367 aec->extended_filter_enabled, | 1327 aec->extended_filter_enabled, |
1368 aec->normal_mu, | 1328 aec->normal_mu, aec->normal_error_threshold, aec->xfBuf, |
1369 aec->normal_error_threshold, | 1329 nearend_ptr, aec->xPow, aec->wfBuf, |
1370 aec->xfBuf, | |
1371 nearend_ptr, | |
1372 aec->xPow, | |
1373 aec->wfBuf, | |
1374 echo_subtractor_output); | 1330 echo_subtractor_output); |
1375 | 1331 |
1376 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); | 1332 RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); |
1377 | 1333 |
1378 if (aec->metricsMode == 1) { | 1334 if (aec->metricsMode == 1) { |
1379 UpdateLevel(&aec->linoutlevel, | 1335 UpdateLevel(&aec->linoutlevel, |
1380 CalculatePower(echo_subtractor_output, PART_LEN)); | 1336 CalculatePower(echo_subtractor_output, PART_LEN)); |
1381 } | 1337 } |
1382 | 1338 |
1383 // Perform echo suppression. | 1339 // Perform echo suppression. |
(...skipping 26 matching lines...) Expand all Loading... |
1410 return NULL; | 1366 return NULL; |
1411 } | 1367 } |
1412 | 1368 |
1413 aec->outFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); | 1369 aec->outFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); |
1414 if (!aec->outFrBuf) { | 1370 if (!aec->outFrBuf) { |
1415 WebRtcAec_FreeAec(aec); | 1371 WebRtcAec_FreeAec(aec); |
1416 return NULL; | 1372 return NULL; |
1417 } | 1373 } |
1418 | 1374 |
1419 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { | 1375 for (i = 0; i < NUM_HIGH_BANDS_MAX; ++i) { |
1420 aec->nearFrBufH[i] = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, | 1376 aec->nearFrBufH[i] = |
1421 sizeof(float)); | 1377 WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); |
1422 if (!aec->nearFrBufH[i]) { | 1378 if (!aec->nearFrBufH[i]) { |
1423 WebRtcAec_FreeAec(aec); | 1379 WebRtcAec_FreeAec(aec); |
1424 return NULL; | 1380 return NULL; |
1425 } | 1381 } |
1426 aec->outFrBufH[i] = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, | 1382 aec->outFrBufH[i] = |
1427 sizeof(float)); | 1383 WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float)); |
1428 if (!aec->outFrBufH[i]) { | 1384 if (!aec->outFrBufH[i]) { |
1429 WebRtcAec_FreeAec(aec); | 1385 WebRtcAec_FreeAec(aec); |
1430 return NULL; | 1386 return NULL; |
1431 } | 1387 } |
1432 } | 1388 } |
1433 | 1389 |
1434 // Create far-end buffers. | 1390 // Create far-end buffers. |
1435 // For bit exactness with legacy code, each element in |far_time_buf| is | 1391 // For bit exactness with legacy code, each element in |far_time_buf| is |
1436 // supposed to contain |PART_LEN2| samples with an overlap of |PART_LEN| | 1392 // supposed to contain |PART_LEN2| samples with an overlap of |PART_LEN| |
1437 // samples from the last frame. | 1393 // samples from the last frame. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1478 WebRtcAec_FilterFar = FilterFar; | 1434 WebRtcAec_FilterFar = FilterFar; |
1479 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; | 1435 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; |
1480 WebRtcAec_FilterAdaptation = FilterAdaptation; | 1436 WebRtcAec_FilterAdaptation = FilterAdaptation; |
1481 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; | 1437 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; |
1482 WebRtcAec_ComfortNoise = ComfortNoise; | 1438 WebRtcAec_ComfortNoise = ComfortNoise; |
1483 WebRtcAec_SubbandCoherence = SubbandCoherence; | 1439 WebRtcAec_SubbandCoherence = SubbandCoherence; |
1484 WebRtcAec_StoreAsComplex = StoreAsComplex; | 1440 WebRtcAec_StoreAsComplex = StoreAsComplex; |
1485 WebRtcAec_PartitionDelay = PartitionDelay; | 1441 WebRtcAec_PartitionDelay = PartitionDelay; |
1486 WebRtcAec_WindowData = WindowData; | 1442 WebRtcAec_WindowData = WindowData; |
1487 | 1443 |
1488 | |
1489 #if defined(WEBRTC_ARCH_X86_FAMILY) | 1444 #if defined(WEBRTC_ARCH_X86_FAMILY) |
1490 if (WebRtc_GetCPUInfo(kSSE2)) { | 1445 if (WebRtc_GetCPUInfo(kSSE2)) { |
1491 WebRtcAec_InitAec_SSE2(); | 1446 WebRtcAec_InitAec_SSE2(); |
1492 } | 1447 } |
1493 #endif | 1448 #endif |
1494 | 1449 |
1495 #if defined(MIPS_FPU_LE) | 1450 #if defined(MIPS_FPU_LE) |
1496 WebRtcAec_InitAec_mips(); | 1451 WebRtcAec_InitAec_mips(); |
1497 #endif | 1452 #endif |
1498 | 1453 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1560 } | 1515 } |
1561 | 1516 |
1562 // Initialize far-end buffers. | 1517 // Initialize far-end buffers. |
1563 WebRtc_InitBuffer(aec->far_time_buf); | 1518 WebRtc_InitBuffer(aec->far_time_buf); |
1564 | 1519 |
1565 #ifdef WEBRTC_AEC_DEBUG_DUMP | 1520 #ifdef WEBRTC_AEC_DEBUG_DUMP |
1566 { | 1521 { |
1567 int process_rate = sampFreq > 16000 ? 16000 : sampFreq; | 1522 int process_rate = sampFreq > 16000 ? 16000 : sampFreq; |
1568 RTC_AEC_DEBUG_WAV_REOPEN("aec_far", aec->instance_index, | 1523 RTC_AEC_DEBUG_WAV_REOPEN("aec_far", aec->instance_index, |
1569 aec->debug_dump_count, process_rate, | 1524 aec->debug_dump_count, process_rate, |
1570 &aec->farFile ); | 1525 &aec->farFile); |
1571 RTC_AEC_DEBUG_WAV_REOPEN("aec_near", aec->instance_index, | 1526 RTC_AEC_DEBUG_WAV_REOPEN("aec_near", aec->instance_index, |
1572 aec->debug_dump_count, process_rate, | 1527 aec->debug_dump_count, process_rate, |
1573 &aec->nearFile); | 1528 &aec->nearFile); |
1574 RTC_AEC_DEBUG_WAV_REOPEN("aec_out", aec->instance_index, | 1529 RTC_AEC_DEBUG_WAV_REOPEN("aec_out", aec->instance_index, |
1575 aec->debug_dump_count, process_rate, | 1530 aec->debug_dump_count, process_rate, |
1576 &aec->outFile ); | 1531 &aec->outFile); |
1577 RTC_AEC_DEBUG_WAV_REOPEN("aec_out_linear", aec->instance_index, | 1532 RTC_AEC_DEBUG_WAV_REOPEN("aec_out_linear", aec->instance_index, |
1578 aec->debug_dump_count, process_rate, | 1533 aec->debug_dump_count, process_rate, |
1579 &aec->outLinearFile); | 1534 &aec->outLinearFile); |
1580 } | 1535 } |
1581 | 1536 |
1582 RTC_AEC_DEBUG_RAW_OPEN("aec_e_fft", | 1537 RTC_AEC_DEBUG_RAW_OPEN("aec_e_fft", aec->debug_dump_count, &aec->e_fft_file); |
1583 aec->debug_dump_count, | |
1584 &aec->e_fft_file); | |
1585 | 1538 |
1586 ++aec->debug_dump_count; | 1539 ++aec->debug_dump_count; |
1587 #endif | 1540 #endif |
1588 aec->system_delay = 0; | 1541 aec->system_delay = 0; |
1589 | 1542 |
1590 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) { | 1543 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) { |
1591 return -1; | 1544 return -1; |
1592 } | 1545 } |
1593 if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) { | 1546 if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) { |
1594 return -1; | 1547 return -1; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1660 } | 1613 } |
1661 | 1614 |
1662 // Holds the last block written to | 1615 // Holds the last block written to |
1663 aec->xfBufBlockPos = 0; | 1616 aec->xfBufBlockPos = 0; |
1664 // TODO: Investigate need for these initializations. Deleting them doesn't | 1617 // TODO: Investigate need for these initializations. Deleting them doesn't |
1665 // change the output at all and yields 0.4% overall speedup. | 1618 // change the output at all and yields 0.4% overall speedup. |
1666 memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); | 1619 memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); |
1667 memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); | 1620 memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); |
1668 memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1); | 1621 memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1); |
1669 memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1); | 1622 memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1); |
1670 memset( | 1623 memset(aec->xfwBuf, 0, |
1671 aec->xfwBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); | 1624 sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1); |
1672 memset(aec->se, 0, sizeof(float) * PART_LEN1); | 1625 memset(aec->se, 0, sizeof(float) * PART_LEN1); |
1673 | 1626 |
1674 // To prevent numerical instability in the first block. | 1627 // To prevent numerical instability in the first block. |
1675 for (i = 0; i < PART_LEN1; i++) { | 1628 for (i = 0; i < PART_LEN1; i++) { |
1676 aec->sd[i] = 1; | 1629 aec->sd[i] = 1; |
1677 } | 1630 } |
1678 for (i = 0; i < PART_LEN1; i++) { | 1631 for (i = 0; i < PART_LEN1; i++) { |
1679 aec->sx[i] = 1; | 1632 aec->sx[i] = 1; |
1680 } | 1633 } |
1681 | 1634 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1757 // give a guess on how much we need to shift far-end buffers to align with | 1710 // give a guess on how much we need to shift far-end buffers to align with |
1758 // the near-end signal. The other delay estimation algorithm uses the | 1711 // the near-end signal. The other delay estimation algorithm uses the |
1759 // far- and near-end signals to find the offset between them. This one | 1712 // far- and near-end signals to find the offset between them. This one |
1760 // (called "signal delay") is then used to fine tune the alignment, or | 1713 // (called "signal delay") is then used to fine tune the alignment, or |
1761 // simply compensate for errors in the system based one. | 1714 // simply compensate for errors in the system based one. |
1762 // Note that the two algorithms operate independently. Currently, we only | 1715 // Note that the two algorithms operate independently. Currently, we only |
1763 // allow one algorithm to be turned on. | 1716 // allow one algorithm to be turned on. |
1764 | 1717 |
1765 assert(aec->num_bands == num_bands); | 1718 assert(aec->num_bands == num_bands); |
1766 | 1719 |
1767 for (j = 0; j < num_samples; j+= FRAME_LEN) { | 1720 for (j = 0; j < num_samples; j += FRAME_LEN) { |
1768 // TODO(bjornv): Change the near-end buffer handling to be the same as for | 1721 // TODO(bjornv): Change the near-end buffer handling to be the same as for |
1769 // far-end, that is, with a near_pre_buf. | 1722 // far-end, that is, with a near_pre_buf. |
1770 // Buffer the near-end frame. | 1723 // Buffer the near-end frame. |
1771 WebRtc_WriteBuffer(aec->nearFrBuf, &nearend[0][j], FRAME_LEN); | 1724 WebRtc_WriteBuffer(aec->nearFrBuf, &nearend[0][j], FRAME_LEN); |
1772 // For H band | 1725 // For H band |
1773 for (i = 1; i < num_bands; ++i) { | 1726 for (i = 1; i < num_bands; ++i) { |
1774 WebRtc_WriteBuffer(aec->nearFrBufH[i - 1], &nearend[i][j], FRAME_LEN); | 1727 WebRtc_WriteBuffer(aec->nearFrBufH[i - 1], &nearend[i][j], FRAME_LEN); |
1775 } | 1728 } |
1776 | 1729 |
1777 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we | 1730 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we |
1778 // have enough far-end data for that by stuffing the buffer if the | 1731 // have enough far-end data for that by stuffing the buffer if the |
1779 // |system_delay| indicates others. | 1732 // |system_delay| indicates others. |
1780 if (aec->system_delay < FRAME_LEN) { | 1733 if (aec->system_delay < FRAME_LEN) { |
1781 // We don't have enough data so we rewind 10 ms. | 1734 // We don't have enough data so we rewind 10 ms. |
1782 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1)); | 1735 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1)); |
1783 } | 1736 } |
1784 | 1737 |
1785 if (!aec->delay_agnostic_enabled) { | 1738 if (!aec->delay_agnostic_enabled) { |
1786 // 2 a) Compensate for a possible change in the system delay. | 1739 // 2 a) Compensate for a possible change in the system delay. |
1787 | 1740 |
1788 // TODO(bjornv): Investigate how we should round the delay difference; | 1741 // TODO(bjornv): Investigate how we should round the delay difference; |
1789 // right now we know that incoming |knownDelay| is underestimated when | 1742 // right now we know that incoming |knownDelay| is underestimated when |
1790 // it's less than |aec->knownDelay|. We therefore, round (-32) in that | 1743 // it's less than |aec->knownDelay|. We therefore, round (-32) in that |
1791 // direction. In the other direction, we don't have this situation, but | 1744 // direction. In the other direction, we don't have this situation, but |
1792 // might flush one partition too little. This can cause non-causality, | 1745 // might flush one partition too little. This can cause non-causality, |
1793 // which should be investigated. Maybe, allow for a non-symmetric | 1746 // which should be investigated. Maybe, allow for a non-symmetric |
1794 // rounding, like -16. | 1747 // rounding, like -16. |
1795 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN; | 1748 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN; |
1796 int moved_elements = | 1749 int moved_elements = WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); |
1797 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); | |
1798 aec->knownDelay -= moved_elements * PART_LEN; | 1750 aec->knownDelay -= moved_elements * PART_LEN; |
1799 } else { | 1751 } else { |
1800 // 2 b) Apply signal based delay correction. | 1752 // 2 b) Apply signal based delay correction. |
1801 int move_elements = SignalBasedDelayCorrection(aec); | 1753 int move_elements = SignalBasedDelayCorrection(aec); |
1802 int moved_elements = | 1754 int moved_elements = WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); |
1803 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements); | 1755 int far_near_buffer_diff = |
1804 int far_near_buffer_diff = WebRtc_available_read(aec->far_time_buf) - | 1756 WebRtc_available_read(aec->far_time_buf) - |
1805 WebRtc_available_read(aec->nearFrBuf) / PART_LEN; | 1757 WebRtc_available_read(aec->nearFrBuf) / PART_LEN; |
1806 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); | 1758 WebRtc_SoftResetDelayEstimator(aec->delay_estimator, moved_elements); |
1807 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, | 1759 WebRtc_SoftResetDelayEstimatorFarend(aec->delay_estimator_farend, |
1808 moved_elements); | 1760 moved_elements); |
1809 aec->signal_delay_correction += moved_elements; | 1761 aec->signal_delay_correction += moved_elements; |
1810 // If we rely on reported system delay values only, a buffer underrun here | 1762 // If we rely on reported system delay values only, a buffer underrun here |
1811 // can never occur since we've taken care of that in 1) above. Here, we | 1763 // can never occur since we've taken care of that in 1) above. Here, we |
1812 // apply signal based delay correction and can therefore end up with | 1764 // apply signal based delay correction and can therefore end up with |
1813 // buffer underruns since the delay estimation can be wrong. We therefore | 1765 // buffer underruns since the delay estimation can be wrong. We therefore |
1814 // stuff the buffer with enough elements if needed. | 1766 // stuff the buffer with enough elements if needed. |
(...skipping 22 matching lines...) Expand all Loading... |
1837 } | 1789 } |
1838 // Obtain an output frame. | 1790 // Obtain an output frame. |
1839 WebRtc_ReadBuffer(aec->outFrBuf, NULL, &out[0][j], FRAME_LEN); | 1791 WebRtc_ReadBuffer(aec->outFrBuf, NULL, &out[0][j], FRAME_LEN); |
1840 // For H bands. | 1792 // For H bands. |
1841 for (i = 1; i < num_bands; ++i) { | 1793 for (i = 1; i < num_bands; ++i) { |
1842 WebRtc_ReadBuffer(aec->outFrBufH[i - 1], NULL, &out[i][j], FRAME_LEN); | 1794 WebRtc_ReadBuffer(aec->outFrBufH[i - 1], NULL, &out[i][j], FRAME_LEN); |
1843 } | 1795 } |
1844 } | 1796 } |
1845 } | 1797 } |
1846 | 1798 |
1847 int WebRtcAec_GetDelayMetricsCore(AecCore* self, int* median, int* std, | 1799 int WebRtcAec_GetDelayMetricsCore(AecCore* self, |
| 1800 int* median, |
| 1801 int* std, |
1848 float* fraction_poor_delays) { | 1802 float* fraction_poor_delays) { |
1849 assert(self != NULL); | 1803 assert(self != NULL); |
1850 assert(median != NULL); | 1804 assert(median != NULL); |
1851 assert(std != NULL); | 1805 assert(std != NULL); |
1852 | 1806 |
1853 if (self->delay_logging_enabled == 0) { | 1807 if (self->delay_logging_enabled == 0) { |
1854 // Logging disabled. | 1808 // Logging disabled. |
1855 return -1; | 1809 return -1; |
1856 } | 1810 } |
1857 | 1811 |
1858 if (self->delay_metrics_delivered == 0) { | 1812 if (self->delay_metrics_delivered == 0) { |
1859 UpdateDelayMetrics(self); | 1813 UpdateDelayMetrics(self); |
1860 self->delay_metrics_delivered = 1; | 1814 self->delay_metrics_delivered = 1; |
1861 } | 1815 } |
1862 *median = self->delay_median; | 1816 *median = self->delay_median; |
1863 *std = self->delay_std; | 1817 *std = self->delay_std; |
1864 *fraction_poor_delays = self->fraction_poor_delays; | 1818 *fraction_poor_delays = self->fraction_poor_delays; |
1865 | 1819 |
1866 return 0; | 1820 return 0; |
1867 } | 1821 } |
1868 | 1822 |
1869 int WebRtcAec_echo_state(AecCore* self) { return self->echoState; } | 1823 int WebRtcAec_echo_state(AecCore* self) { |
| 1824 return self->echoState; |
| 1825 } |
1870 | 1826 |
1871 void WebRtcAec_GetEchoStats(AecCore* self, | 1827 void WebRtcAec_GetEchoStats(AecCore* self, |
1872 Stats* erl, | 1828 Stats* erl, |
1873 Stats* erle, | 1829 Stats* erle, |
1874 Stats* a_nlp) { | 1830 Stats* a_nlp) { |
1875 assert(erl != NULL); | 1831 assert(erl != NULL); |
1876 assert(erle != NULL); | 1832 assert(erle != NULL); |
1877 assert(a_nlp != NULL); | 1833 assert(a_nlp != NULL); |
1878 *erl = self->erl; | 1834 *erl = self->erl; |
1879 *erle = self->erle; | 1835 *erle = self->erle; |
(...skipping 30 matching lines...) Expand all Loading... |
1910 self->extended_filter_enabled = enable; | 1866 self->extended_filter_enabled = enable; |
1911 self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions; | 1867 self->num_partitions = enable ? kExtendedNumPartitions : kNormalNumPartitions; |
1912 // Update the delay estimator with filter length. See InitAEC() for details. | 1868 // Update the delay estimator with filter length. See InitAEC() for details. |
1913 WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2); | 1869 WebRtc_set_allowed_offset(self->delay_estimator, self->num_partitions / 2); |
1914 } | 1870 } |
1915 | 1871 |
1916 int WebRtcAec_extended_filter_enabled(AecCore* self) { | 1872 int WebRtcAec_extended_filter_enabled(AecCore* self) { |
1917 return self->extended_filter_enabled; | 1873 return self->extended_filter_enabled; |
1918 } | 1874 } |
1919 | 1875 |
1920 int WebRtcAec_system_delay(AecCore* self) { return self->system_delay; } | 1876 int WebRtcAec_system_delay(AecCore* self) { |
| 1877 return self->system_delay; |
| 1878 } |
1921 | 1879 |
1922 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { | 1880 void WebRtcAec_SetSystemDelay(AecCore* self, int delay) { |
1923 assert(delay >= 0); | 1881 assert(delay >= 0); |
1924 self->system_delay = delay; | 1882 self->system_delay = delay; |
1925 } | 1883 } |
OLD | NEW |