| 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 |