1 /* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 /* 12 * The core AEC algorithm, which is presented with time-aligned signals. 13 */ 14 15 #include <math.h> 16 #include <stdlib.h> 17 #include <string.h> 18 19 #include "aec_core.h" 20 #include "aec_rdft.h" 21 #include "ring_buffer.h" 22 #include "system_wrappers/interface/cpu_features_wrapper.h" 23 24 // Noise suppression 25 static const int converged = 250; 26 27 // Metrics 28 static const int subCountLen = 4; 29 static const int countLen = 50; 30 31 // Quantities to control H band scaling for SWB input 32 static const int flagHbandCn = 1; // flag for adding comfort noise in H band 33 static const float cnScaleHband = (float)0.4; // scale for comfort noise in H band 34 // Initial bin for averaging nlp gain in low band 35 static const int freqAvgIc = PART_LEN / 2; 36 37 /* Matlab code to produce table: 38 win = sqrt(hanning(63)); win = [0 ; win(1:32)]; 39 fprintf(1, '\t%.14f, %.14f, %.14f,\n', win); 40 */ 41 /* 42 static const float sqrtHanning[33] = { 43 0.00000000000000, 0.04906767432742, 0.09801714032956, 44 0.14673047445536, 0.19509032201613, 0.24298017990326, 45 0.29028467725446, 0.33688985339222, 0.38268343236509, 46 0.42755509343028, 0.47139673682600, 0.51410274419322, 47 0.55557023301960, 0.59569930449243, 0.63439328416365, 48 0.67155895484702, 0.70710678118655, 0.74095112535496, 49 0.77301045336274, 0.80320753148064, 0.83146961230255, 50 0.85772861000027, 0.88192126434835, 0.90398929312344, 51 0.92387953251129, 0.94154406518302, 0.95694033573221, 52 0.97003125319454, 0.98078528040323, 0.98917650996478, 53 0.99518472667220, 0.99879545620517, 1.00000000000000 54 }; 55 */ 56 57 static const float sqrtHanning[65] = { 58 0.00000000000000f, 0.02454122852291f, 0.04906767432742f, 59 0.07356456359967f, 0.09801714032956f, 0.12241067519922f, 60 0.14673047445536f, 0.17096188876030f, 0.19509032201613f, 61 0.21910124015687f, 0.24298017990326f, 0.26671275747490f, 62 0.29028467725446f, 0.31368174039889f, 0.33688985339222f, 63 0.35989503653499f, 0.38268343236509f, 0.40524131400499f, 64 0.42755509343028f, 0.44961132965461f, 0.47139673682600f, 65 0.49289819222978f, 0.51410274419322f, 0.53499761988710f, 66 0.55557023301960f, 0.57580819141785f, 0.59569930449243f, 67 0.61523159058063f, 0.63439328416365f, 0.65317284295378f, 68 0.67155895484702f, 0.68954054473707f, 0.70710678118655f, 69 0.72424708295147f, 0.74095112535496f, 0.75720884650648f, 70 0.77301045336274f, 0.78834642762661f, 0.80320753148064f, 71 0.81758481315158f, 0.83146961230255f, 0.84485356524971f, 72 0.85772861000027f, 0.87008699110871f, 0.88192126434835f, 73 0.89322430119552f, 0.90398929312344f, 0.91420975570353f, 74 0.92387953251129f, 0.93299279883474f, 0.94154406518302f, 75 0.94952818059304f, 0.95694033573221f, 0.96377606579544f, 76 0.97003125319454f, 0.97570213003853f, 0.98078528040323f, 77 0.98527764238894f, 0.98917650996478f, 0.99247953459871f, 78 0.99518472667220f, 0.99729045667869f, 0.99879545620517f, 79 0.99969881869620f, 1.00000000000000f 80 }; 81 82 /* Matlab code to produce table: 83 weightCurve = [0 ; 0.3 * sqrt(linspace(0,1,64))' + 0.1]; 84 fprintf(1, '\t%.4f, %.4f, %.4f, %.4f, %.4f, %.4f,\n', weightCurve); 85 */ 86 const float WebRtcAec_weightCurve[65] = { 87 0.0000f, 0.1000f, 0.1378f, 0.1535f, 0.1655f, 0.1756f, 88 0.1845f, 0.1926f, 0.2000f, 0.2069f, 0.2134f, 0.2195f, 89 0.2254f, 0.2309f, 0.2363f, 0.2414f, 0.2464f, 0.2512f, 90 0.2558f, 0.2604f, 0.2648f, 0.2690f, 0.2732f, 0.2773f, 91 0.2813f, 0.2852f, 0.2890f, 0.2927f, 0.2964f, 0.3000f, 92 0.3035f, 0.3070f, 0.3104f, 0.3138f, 0.3171f, 0.3204f, 93 0.3236f, 0.3268f, 0.3299f, 0.3330f, 0.3360f, 0.3390f, 94 0.3420f, 0.3449f, 0.3478f, 0.3507f, 0.3535f, 0.3563f, 95 0.3591f, 0.3619f, 0.3646f, 0.3673f, 0.3699f, 0.3726f, 96 0.3752f, 0.3777f, 0.3803f, 0.3828f, 0.3854f, 0.3878f, 97 0.3903f, 0.3928f, 0.3952f, 0.3976f, 0.4000f 98 }; 99 100 /* Matlab code to produce table: 101 overDriveCurve = [sqrt(linspace(0,1,65))' + 1]; 102 fprintf(1, '\t%.4f, %.4f, %.4f, %.4f, %.4f, %.4f,\n', overDriveCurve); 103 */ 104 const float WebRtcAec_overDriveCurve[65] = { 105 1.0000f, 1.1250f, 1.1768f, 1.2165f, 1.2500f, 1.2795f, 106 1.3062f, 1.3307f, 1.3536f, 1.3750f, 1.3953f, 1.4146f, 107 1.4330f, 1.4507f, 1.4677f, 1.4841f, 1.5000f, 1.5154f, 108 1.5303f, 1.5449f, 1.5590f, 1.5728f, 1.5863f, 1.5995f, 109 1.6124f, 1.6250f, 1.6374f, 1.6495f, 1.6614f, 1.6731f, 110 1.6847f, 1.6960f, 1.7071f, 1.7181f, 1.7289f, 1.7395f, 111 1.7500f, 1.7603f, 1.7706f, 1.7806f, 1.7906f, 1.8004f, 112 1.8101f, 1.8197f, 1.8292f, 1.8385f, 1.8478f, 1.8570f, 113 1.8660f, 1.8750f, 1.8839f, 1.8927f, 1.9014f, 1.9100f, 114 1.9186f, 1.9270f, 1.9354f, 1.9437f, 1.9520f, 1.9601f, 115 1.9682f, 1.9763f, 1.9843f, 1.9922f, 2.0000f 116 }; 117 118 // "Private" function prototypes. 119 static void ProcessBlock(aec_t *aec, const short *farend, 120 const short *nearend, const short *nearendH, 121 short *out, short *outH); 122 123 static void BufferFar(aec_t *aec, const short *farend, int farLen); 124 static void FetchFar(aec_t *aec, short *farend, int farLen, int knownDelay); 125 126 static void NonLinearProcessing(aec_t *aec, short *output, short *outputH); 127 128 static void GetHighbandGain(const float *lambda, float *nlpGainHband); 129 130 // Comfort_noise also computes noise for H band returned in comfortNoiseHband 131 static void ComfortNoise(aec_t *aec, float efw[2][PART_LEN1], 132 complex_t *comfortNoiseHband, 133 const float *noisePow, const float *lambda); 134 135 static void WebRtcAec_InitLevel(power_level_t *level); 136 static void WebRtcAec_InitStats(stats_t *stats); 137 static void UpdateLevel(power_level_t *level, const short *in); 138 static void UpdateMetrics(aec_t *aec); 139 140 __inline static float MulRe(float aRe, float aIm, float bRe, float bIm) 141 { 142 return aRe * bRe - aIm * bIm; 143 } 144 145 __inline static float MulIm(float aRe, float aIm, float bRe, float bIm) 146 { 147 return aRe * bIm + aIm * bRe; 148 } 149 150 static int CmpFloat(const void *a, const void *b) 151 { 152 const float *da = (const float *)a; 153 const float *db = (const float *)b; 154 155 return (*da > *db) - (*da < *db); 156 } 157 158 int WebRtcAec_CreateAec(aec_t **aecInst) 159 { 160 aec_t *aec = malloc(sizeof(aec_t)); 161 *aecInst = aec; 162 if (aec == NULL) { 163 return -1; 164 } 165 166 if (WebRtcApm_CreateBuffer(&aec->farFrBuf, FRAME_LEN + PART_LEN) == -1) { 167 WebRtcAec_FreeAec(aec); 168 aec = NULL; 169 return -1; 170 } 171 172 if (WebRtcApm_CreateBuffer(&aec->nearFrBuf, FRAME_LEN + PART_LEN) == -1) { 173 WebRtcAec_FreeAec(aec); 174 aec = NULL; 175 return -1; 176 } 177 178 if (WebRtcApm_CreateBuffer(&aec->outFrBuf, FRAME_LEN + PART_LEN) == -1) { 179 WebRtcAec_FreeAec(aec); 180 aec = NULL; 181 return -1; 182 } 183 184 if (WebRtcApm_CreateBuffer(&aec->nearFrBufH, FRAME_LEN + PART_LEN) == -1) { 185 WebRtcAec_FreeAec(aec); 186 aec = NULL; 187 return -1; 188 } 189 190 if (WebRtcApm_CreateBuffer(&aec->outFrBufH, FRAME_LEN + PART_LEN) == -1) { 191 WebRtcAec_FreeAec(aec); 192 aec = NULL; 193 return -1; 194 } 195 196 return 0; 197 } 198 199 int WebRtcAec_FreeAec(aec_t *aec) 200 { 201 if (aec == NULL) { 202 return -1; 203 } 204 205 WebRtcApm_FreeBuffer(aec->farFrBuf); 206 WebRtcApm_FreeBuffer(aec->nearFrBuf); 207 WebRtcApm_FreeBuffer(aec->outFrBuf); 208 209 WebRtcApm_FreeBuffer(aec->nearFrBufH); 210 WebRtcApm_FreeBuffer(aec->outFrBufH); 211 212 free(aec); 213 return 0; 214 } 215 216 static void FilterFar(aec_t *aec, float yf[2][PART_LEN1]) 217 { 218 int i; 219 for (i = 0; i < NR_PART; i++) { 220 int j; 221 int xPos = (i + aec->xfBufBlockPos) * PART_LEN1; 222 int pos = i * PART_LEN1; 223 // Check for wrap 224 if (i + aec->xfBufBlockPos >= NR_PART) { 225 xPos -= NR_PART*(PART_LEN1); 226 } 227 228 for (j = 0; j < PART_LEN1; j++) { 229 yf[0][j] += MulRe(aec->xfBuf[0][xPos + j], aec->xfBuf[1][xPos + j], 230 aec->wfBuf[0][ pos + j], aec->wfBuf[1][ pos + j]); 231 yf[1][j] += MulIm(aec->xfBuf[0][xPos + j], aec->xfBuf[1][xPos + j], 232 aec->wfBuf[0][ pos + j], aec->wfBuf[1][ pos + j]); 233 } 234 } 235 } 236 237 static void ScaleErrorSignal(aec_t *aec, float ef[2][PART_LEN1]) 238 { 239 int i; 240 float absEf; 241 for (i = 0; i < (PART_LEN1); i++) { 242 ef[0][i] /= (aec->xPow[i] + 1e-10f); 243 ef[1][i] /= (aec->xPow[i] + 1e-10f); 244 absEf = sqrtf(ef[0][i] * ef[0][i] + ef[1][i] * ef[1][i]); 245 246 if (absEf > aec->errThresh) { 247 absEf = aec->errThresh / (absEf + 1e-10f); 248 ef[0][i] *= absEf; 249 ef[1][i] *= absEf; 250 } 251 252 // Stepsize factor 253 ef[0][i] *= aec->mu; 254 ef[1][i] *= aec->mu; 255 } 256 } 257 258 static void FilterAdaptation(aec_t *aec, float *fft, float ef[2][PART_LEN1]) { 259 int i, j; 260 for (i = 0; i < NR_PART; i++) { 261 int xPos = (i + aec->xfBufBlockPos)*(PART_LEN1); 262 int pos; 263 // Check for wrap 264 if (i + aec->xfBufBlockPos >= NR_PART) { 265 xPos -= NR_PART * PART_LEN1; 266 } 267 268 pos = i * PART_LEN1; 269 270 #ifdef UNCONSTR 271 for (j = 0; j < PART_LEN1; j++) { 272 aec->wfBuf[pos + j][0] += MulRe(aec->xfBuf[xPos + j][0], 273 -aec->xfBuf[xPos + j][1], 274 ef[j][0], ef[j][1]); 275 aec->wfBuf[pos + j][1] += MulIm(aec->xfBuf[xPos + j][0], 276 -aec->xfBuf[xPos + j][1], 277 ef[j][0], ef[j][1]); 278 } 279 #else 280 for (j = 0; j < PART_LEN; j++) { 281 282 fft[2 * j] = MulRe(aec->xfBuf[0][xPos + j], 283 -aec->xfBuf[1][xPos + j], 284 ef[0][j], ef[1][j]); 285 fft[2 * j + 1] = MulIm(aec->xfBuf[0][xPos + j], 286 -aec->xfBuf[1][xPos + j], 287 ef[0][j], ef[1][j]); 288 } 289 fft[1] = MulRe(aec->xfBuf[0][xPos + PART_LEN], 290 -aec->xfBuf[1][xPos + PART_LEN], 291 ef[0][PART_LEN], ef[1][PART_LEN]); 292 293 aec_rdft_inverse_128(fft); 294 memset(fft + PART_LEN, 0, sizeof(float) * PART_LEN); 295 296 // fft scaling 297 { 298 float scale = 2.0f / PART_LEN2; 299 for (j = 0; j < PART_LEN; j++) { 300 fft[j] *= scale; 301 } 302 } 303 aec_rdft_forward_128(fft); 304 305 aec->wfBuf[0][pos] += fft[0]; 306 aec->wfBuf[0][pos + PART_LEN] += fft[1]; 307 308 for (j = 1; j < PART_LEN; j++) { 309 aec->wfBuf[0][pos + j] += fft[2 * j]; 310 aec->wfBuf[1][pos + j] += fft[2 * j + 1]; 311 } 312 #endif // UNCONSTR 313 } 314 } 315 316 static void OverdriveAndSuppress(aec_t *aec, float hNl[PART_LEN1], 317 const float hNlFb, 318 float efw[2][PART_LEN1]) { 319 int i; 320 for (i = 0; i < PART_LEN1; i++) { 321 // Weight subbands 322 if (hNl[i] > hNlFb) { 323 hNl[i] = WebRtcAec_weightCurve[i] * hNlFb + 324 (1 - WebRtcAec_weightCurve[i]) * hNl[i]; 325 } 326 hNl[i] = powf(hNl[i], aec->overDriveSm * WebRtcAec_overDriveCurve[i]); 327 328 // Suppress error signal 329 efw[0][i] *= hNl[i]; 330 efw[1][i] *= hNl[i]; 331 332 // Ooura fft returns incorrect sign on imaginary component. It matters here 333 // because we are making an additive change with comfort noise. 334 efw[1][i] *= -1; 335 } 336 } 337 338 WebRtcAec_FilterFar_t WebRtcAec_FilterFar; 339 WebRtcAec_ScaleErrorSignal_t WebRtcAec_ScaleErrorSignal; 340 WebRtcAec_FilterAdaptation_t WebRtcAec_FilterAdaptation; 341 WebRtcAec_OverdriveAndSuppress_t WebRtcAec_OverdriveAndSuppress; 342 343 int WebRtcAec_InitAec(aec_t *aec, int sampFreq) 344 { 345 int i; 346 347 aec->sampFreq = sampFreq; 348 349 if (sampFreq == 8000) { 350 aec->mu = 0.6f; 351 aec->errThresh = 2e-6f; 352 } 353 else { 354 aec->mu = 0.5f; 355 aec->errThresh = 1.5e-6f; 356 } 357 358 if (WebRtcApm_InitBuffer(aec->farFrBuf) == -1) { 359 return -1; 360 } 361 362 if (WebRtcApm_InitBuffer(aec->nearFrBuf) == -1) { 363 return -1; 364 } 365 366 if (WebRtcApm_InitBuffer(aec->outFrBuf) == -1) { 367 return -1; 368 } 369 370 if (WebRtcApm_InitBuffer(aec->nearFrBufH) == -1) { 371 return -1; 372 } 373 374 if (WebRtcApm_InitBuffer(aec->outFrBufH) == -1) { 375 return -1; 376 } 377 378 // Default target suppression level 379 aec->targetSupp = -11.5; 380 aec->minOverDrive = 2.0; 381 382 // Sampling frequency multiplier 383 // SWB is processed as 160 frame size 384 if (aec->sampFreq == 32000) { 385 aec->mult = (short)aec->sampFreq / 16000; 386 } 387 else { 388 aec->mult = (short)aec->sampFreq / 8000; 389 } 390 391 aec->farBufWritePos = 0; 392 aec->farBufReadPos = 0; 393 394 aec->inSamples = 0; 395 aec->outSamples = 0; 396 aec->knownDelay = 0; 397 398 // Initialize buffers 399 memset(aec->farBuf, 0, sizeof(aec->farBuf)); 400 memset(aec->xBuf, 0, sizeof(aec->xBuf)); 401 memset(aec->dBuf, 0, sizeof(aec->dBuf)); 402 memset(aec->eBuf, 0, sizeof(aec->eBuf)); 403 // For H band 404 memset(aec->dBufH, 0, sizeof(aec->dBufH)); 405 406 memset(aec->xPow, 0, sizeof(aec->xPow)); 407 memset(aec->dPow, 0, sizeof(aec->dPow)); 408 memset(aec->dInitMinPow, 0, sizeof(aec->dInitMinPow)); 409 aec->noisePow = aec->dInitMinPow; 410 aec->noiseEstCtr = 0; 411 412 // Initial comfort noise power 413 for (i = 0; i < PART_LEN1; i++) { 414 aec->dMinPow[i] = 1.0e6f; 415 } 416 417 // Holds the last block written to 418 aec->xfBufBlockPos = 0; 419 // TODO: Investigate need for these initializations. Deleting them doesn't 420 // change the output at all and yields 0.4% overall speedup. 421 memset(aec->xfBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1); 422 memset(aec->wfBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1); 423 memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1); 424 memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1); 425 memset(aec->xfwBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1); 426 memset(aec->se, 0, sizeof(float) * PART_LEN1); 427 428 // To prevent numerical instability in the first block. 429 for (i = 0; i < PART_LEN1; i++) { 430 aec->sd[i] = 1; 431 } 432 for (i = 0; i < PART_LEN1; i++) { 433 aec->sx[i] = 1; 434 } 435 436 memset(aec->hNs, 0, sizeof(aec->hNs)); 437 memset(aec->outBuf, 0, sizeof(float) * PART_LEN); 438 439 aec->hNlFbMin = 1; 440 aec->hNlFbLocalMin = 1; 441 aec->hNlXdAvgMin = 1; 442 aec->hNlNewMin = 0; 443 aec->hNlMinCtr = 0; 444 aec->overDrive = 2; 445 aec->overDriveSm = 2; 446 aec->delayIdx = 0; 447 aec->stNearState = 0; 448 aec->echoState = 0; 449 aec->divergeState = 0; 450 451 aec->seed = 777; 452 aec->delayEstCtr = 0; 453 454 // Features on by default (G.167) 455 #ifdef G167 456 aec->adaptToggle = 1; 457 aec->nlpToggle = 1; 458 aec->cnToggle = 1; 459 #endif 460 461 // Metrics disabled by default 462 aec->metricsMode = 0; 463 WebRtcAec_InitMetrics(aec); 464 465 // Assembly optimization 466 WebRtcAec_FilterFar = FilterFar; 467 WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; 468 WebRtcAec_FilterAdaptation = FilterAdaptation; 469 WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; 470 if (WebRtc_GetCPUInfo(kSSE2)) { 471 #if defined(__SSE2__) 472 WebRtcAec_InitAec_SSE2(); 473 #endif 474 } 475 aec_rdft_init(); 476 477 return 0; 478 } 479 480 void WebRtcAec_InitMetrics(aec_t *aec) 481 { 482 aec->stateCounter = 0; 483 WebRtcAec_InitLevel(&aec->farlevel); 484 WebRtcAec_InitLevel(&aec->nearlevel); 485 WebRtcAec_InitLevel(&aec->linoutlevel); 486 WebRtcAec_InitLevel(&aec->nlpoutlevel); 487 488 WebRtcAec_InitStats(&aec->erl); 489 WebRtcAec_InitStats(&aec->erle); 490 WebRtcAec_InitStats(&aec->aNlp); 491 WebRtcAec_InitStats(&aec->rerl); 492 } 493 494 495 void WebRtcAec_ProcessFrame(aec_t *aec, const short *farend, 496 const short *nearend, const short *nearendH, 497 short *out, short *outH, 498 int knownDelay) 499 { 500 short farBl[PART_LEN], nearBl[PART_LEN], outBl[PART_LEN]; 501 short farFr[FRAME_LEN]; 502 // For H band 503 short nearBlH[PART_LEN], outBlH[PART_LEN]; 504 505 int size = 0; 506 507 // initialize: only used for SWB 508 memset(nearBlH, 0, sizeof(nearBlH)); 509 memset(outBlH, 0, sizeof(outBlH)); 510 511 // Buffer the current frame. 512 // Fetch an older one corresponding to the delay. 513 BufferFar(aec, farend, FRAME_LEN); 514 FetchFar(aec, farFr, FRAME_LEN, knownDelay); 515 516 // Buffer the synchronized far and near frames, 517 // to pass the smaller blocks individually. 518 WebRtcApm_WriteBuffer(aec->farFrBuf, farFr, FRAME_LEN); 519 WebRtcApm_WriteBuffer(aec->nearFrBuf, nearend, FRAME_LEN); 520 // For H band 521 if (aec->sampFreq == 32000) { 522 WebRtcApm_WriteBuffer(aec->nearFrBufH, nearendH, FRAME_LEN); 523 } 524 525 // Process as many blocks as possible. 526 while (WebRtcApm_get_buffer_size(aec->farFrBuf) >= PART_LEN) { 527 528 WebRtcApm_ReadBuffer(aec->farFrBuf, farBl, PART_LEN); 529 WebRtcApm_ReadBuffer(aec->nearFrBuf, nearBl, PART_LEN); 530 531 // For H band 532 if (aec->sampFreq == 32000) { 533 WebRtcApm_ReadBuffer(aec->nearFrBufH, nearBlH, PART_LEN); 534 } 535 536 ProcessBlock(aec, farBl, nearBl, nearBlH, outBl, outBlH); 537 538 WebRtcApm_WriteBuffer(aec->outFrBuf, outBl, PART_LEN); 539 // For H band 540 if (aec->sampFreq == 32000) { 541 WebRtcApm_WriteBuffer(aec->outFrBufH, outBlH, PART_LEN); 542 } 543 } 544 545 // Stuff the out buffer if we have less than a frame to output. 546 // This should only happen for the first frame. 547 size = WebRtcApm_get_buffer_size(aec->outFrBuf); 548 if (size < FRAME_LEN) { 549 WebRtcApm_StuffBuffer(aec->outFrBuf, FRAME_LEN - size); 550 if (aec->sampFreq == 32000) { 551 WebRtcApm_StuffBuffer(aec->outFrBufH, FRAME_LEN - size); 552 } 553 } 554 555 // Obtain an output frame. 556 WebRtcApm_ReadBuffer(aec->outFrBuf, out, FRAME_LEN); 557 // For H band 558 if (aec->sampFreq == 32000) { 559 WebRtcApm_ReadBuffer(aec->outFrBufH, outH, FRAME_LEN); 560 } 561 } 562 563 static void ProcessBlock(aec_t *aec, const short *farend, 564 const short *nearend, const short *nearendH, 565 short *output, short *outputH) 566 { 567 int i; 568 float d[PART_LEN], y[PART_LEN], e[PART_LEN], dH[PART_LEN]; 569 short eInt16[PART_LEN]; 570 float scale; 571 572 float fft[PART_LEN2]; 573 float xf[2][PART_LEN1], yf[2][PART_LEN1], ef[2][PART_LEN1]; 574 complex_t df[PART_LEN1]; 575 576 const float gPow[2] = {0.9f, 0.1f}; 577 578 // Noise estimate constants. 579 const int noiseInitBlocks = 500 * aec->mult; 580 const float step = 0.1f; 581 const float ramp = 1.0002f; 582 const float gInitNoise[2] = {0.999f, 0.001f}; 583 584 #ifdef AEC_DEBUG 585 fwrite(farend, sizeof(short), PART_LEN, aec->farFile); 586 fwrite(nearend, sizeof(short), PART_LEN, aec->nearFile); 587 #endif 588 589 memset(dH, 0, sizeof(dH)); 590 591 // ---------- Ooura fft ---------- 592 // Concatenate old and new farend blocks. 593 for (i = 0; i < PART_LEN; i++) { 594 aec->xBuf[i + PART_LEN] = (float)farend[i]; 595 d[i] = (float)nearend[i]; 596 } 597 598 if (aec->sampFreq == 32000) { 599 for (i = 0; i < PART_LEN; i++) { 600 dH[i] = (float)nearendH[i]; 601 } 602 } 603 604 605 memcpy(fft, aec->xBuf, sizeof(float) * PART_LEN2); 606 memcpy(aec->dBuf + PART_LEN, d, sizeof(float) * PART_LEN); 607 // For H band 608 if (aec->sampFreq == 32000) { 609 memcpy(aec->dBufH + PART_LEN, dH, sizeof(float) * PART_LEN); 610 } 611 612 aec_rdft_forward_128(fft); 613 614 // Far fft 615 xf[1][0] = 0; 616 xf[1][PART_LEN] = 0; 617 xf[0][0] = fft[0]; 618 xf[0][PART_LEN] = fft[1]; 619 620 for (i = 1; i < PART_LEN; i++) { 621 xf[0][i] = fft[2 * i]; 622 xf[1][i] = fft[2 * i + 1]; 623 } 624 625 // Near fft 626 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2); 627 aec_rdft_forward_128(fft); 628 df[0][1] = 0; 629 df[PART_LEN][1] = 0; 630 df[0][0] = fft[0]; 631 df[PART_LEN][0] = fft[1]; 632 633 for (i = 1; i < PART_LEN; i++) { 634 df[i][0] = fft[2 * i]; 635 df[i][1] = fft[2 * i + 1]; 636 } 637 638 // Power smoothing 639 for (i = 0; i < PART_LEN1; i++) { 640 aec->xPow[i] = gPow[0] * aec->xPow[i] + gPow[1] * NR_PART * 641 (xf[0][i] * xf[0][i] + xf[1][i] * xf[1][i]); 642 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * 643 (df[i][0] * df[i][0] + df[i][1] * df[i][1]); 644 } 645 646 // Estimate noise power. Wait until dPow is more stable. 647 if (aec->noiseEstCtr > 50) { 648 for (i = 0; i < PART_LEN1; i++) { 649 if (aec->dPow[i] < aec->dMinPow[i]) { 650 aec->dMinPow[i] = (aec->dPow[i] + step * (aec->dMinPow[i] - 651 aec->dPow[i])) * ramp; 652 } 653 else { 654 aec->dMinPow[i] *= ramp; 655 } 656 } 657 } 658 659 // Smooth increasing noise power from zero at the start, 660 // to avoid a sudden burst of comfort noise. 661 if (aec->noiseEstCtr < noiseInitBlocks) { 662 aec->noiseEstCtr++; 663 for (i = 0; i < PART_LEN1; i++) { 664 if (aec->dMinPow[i] > aec->dInitMinPow[i]) { 665 aec->dInitMinPow[i] = gInitNoise[0] * aec->dInitMinPow[i] + 666 gInitNoise[1] * aec->dMinPow[i]; 667 } 668 else { 669 aec->dInitMinPow[i] = aec->dMinPow[i]; 670 } 671 } 672 aec->noisePow = aec->dInitMinPow; 673 } 674 else { 675 aec->noisePow = aec->dMinPow; 676 } 677 678 679 // Update the xfBuf block position. 680 aec->xfBufBlockPos--; 681 if (aec->xfBufBlockPos == -1) { 682 aec->xfBufBlockPos = NR_PART - 1; 683 } 684 685 // Buffer xf 686 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1, xf[0], 687 sizeof(float) * PART_LEN1); 688 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1, xf[1], 689 sizeof(float) * PART_LEN1); 690 691 memset(yf[0], 0, sizeof(float) * (PART_LEN1 * 2)); 692 693 // Filter far 694 WebRtcAec_FilterFar(aec, yf); 695 696 // Inverse fft to obtain echo estimate and error. 697 fft[0] = yf[0][0]; 698 fft[1] = yf[0][PART_LEN]; 699 for (i = 1; i < PART_LEN; i++) { 700 fft[2 * i] = yf[0][i]; 701 fft[2 * i + 1] = yf[1][i]; 702 } 703 aec_rdft_inverse_128(fft); 704 705 scale = 2.0f / PART_LEN2; 706 for (i = 0; i < PART_LEN; i++) { 707 y[i] = fft[PART_LEN + i] * scale; // fft scaling 708 } 709 710 for (i = 0; i < PART_LEN; i++) { 711 e[i] = d[i] - y[i]; 712 } 713 714 // Error fft 715 memcpy(aec->eBuf + PART_LEN, e, sizeof(float) * PART_LEN); 716 memset(fft, 0, sizeof(float) * PART_LEN); 717 memcpy(fft + PART_LEN, e, sizeof(float) * PART_LEN); 718 aec_rdft_forward_128(fft); 719 720 ef[1][0] = 0; 721 ef[1][PART_LEN] = 0; 722 ef[0][0] = fft[0]; 723 ef[0][PART_LEN] = fft[1]; 724 for (i = 1; i < PART_LEN; i++) { 725 ef[0][i] = fft[2 * i]; 726 ef[1][i] = fft[2 * i + 1]; 727 } 728 729 // Scale error signal inversely with far power. 730 WebRtcAec_ScaleErrorSignal(aec, ef); 731 #ifdef G167 732 if (aec->adaptToggle) { 733 #endif 734 // Filter adaptation 735 WebRtcAec_FilterAdaptation(aec, fft, ef); 736 #ifdef G167 737 } 738 #endif 739 740 NonLinearProcessing(aec, output, outputH); 741 742 #if defined(AEC_DEBUG) || defined(G167) 743 for (i = 0; i < PART_LEN; i++) { 744 eInt16[i] = (short)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, e[i], 745 WEBRTC_SPL_WORD16_MIN); 746 } 747 #endif 748 #ifdef G167 749 if (aec->nlpToggle == 0) { 750 memcpy(output, eInt16, sizeof(eInt16)); 751 } 752 #endif 753 754 if (aec->metricsMode == 1) { 755 for (i = 0; i < PART_LEN; i++) { 756 eInt16[i] = (short)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, e[i], 757 WEBRTC_SPL_WORD16_MIN); 758 } 759 760 // Update power levels and echo metrics 761 UpdateLevel(&aec->farlevel, farend); 762 UpdateLevel(&aec->nearlevel, nearend); 763 UpdateLevel(&aec->linoutlevel, eInt16); 764 UpdateLevel(&aec->nlpoutlevel, output); 765 UpdateMetrics(aec); 766 } 767 768 #ifdef AEC_DEBUG 769 fwrite(eInt16, sizeof(short), PART_LEN, aec->outLpFile); 770 fwrite(output, sizeof(short), PART_LEN, aec->outFile); 771 #endif 772 } 773 774 static void NonLinearProcessing(aec_t *aec, short *output, short *outputH) 775 { 776 float efw[2][PART_LEN1], dfw[2][PART_LEN1]; 777 complex_t xfw[PART_LEN1]; 778 complex_t comfortNoiseHband[PART_LEN1]; 779 float fft[PART_LEN2]; 780 float scale, dtmp; 781 float nlpGainHband; 782 int i, j, pos; 783 784 // Coherence and non-linear filter 785 float cohde[PART_LEN1], cohxd[PART_LEN1]; 786 float hNlDeAvg, hNlXdAvg; 787 float hNl[PART_LEN1]; 788 float hNlPref[PREF_BAND_SIZE]; 789 float hNlFb = 0, hNlFbLow = 0; 790 const float prefBandQuant = 0.75f, prefBandQuantLow = 0.5f; 791 const int prefBandSize = PREF_BAND_SIZE / aec->mult; 792 const int minPrefBand = 4 / aec->mult; 793 794 // Near and error power sums 795 float sdSum = 0, seSum = 0; 796 797 // Power estimate smoothing coefficients 798 const float gCoh[2][2] = {{0.9f, 0.1f}, {0.93f, 0.07f}}; 799 const float *ptrGCoh = gCoh[aec->mult - 1]; 800 801 // Filter energey 802 float wfEnMax = 0, wfEn = 0; 803 const int delayEstInterval = 10 * aec->mult; 804 805 aec->delayEstCtr++; 806 if (aec->delayEstCtr == delayEstInterval) { 807 aec->delayEstCtr = 0; 808 } 809 810 // initialize comfort noise for H band 811 memset(comfortNoiseHband, 0, sizeof(comfortNoiseHband)); 812 nlpGainHband = (float)0.0; 813 dtmp = (float)0.0; 814 815 // Measure energy in each filter partition to determine delay. 816 // TODO: Spread by computing one partition per block? 817 if (aec->delayEstCtr == 0) { 818 wfEnMax = 0; 819 aec->delayIdx = 0; 820 for (i = 0; i < NR_PART; i++) { 821 pos = i * PART_LEN1; 822 wfEn = 0; 823 for (j = 0; j < PART_LEN1; j++) { 824 wfEn += aec->wfBuf[0][pos + j] * aec->wfBuf[0][pos + j] + 825 aec->wfBuf[1][pos + j] * aec->wfBuf[1][pos + j]; 826 } 827 828 if (wfEn > wfEnMax) { 829 wfEnMax = wfEn; 830 aec->delayIdx = i; 831 } 832 } 833 } 834 835 // NLP 836 // Windowed far fft 837 for (i = 0; i < PART_LEN; i++) { 838 fft[i] = aec->xBuf[i] * sqrtHanning[i]; 839 fft[PART_LEN + i] = aec->xBuf[PART_LEN + i] * sqrtHanning[PART_LEN - i]; 840 } 841 aec_rdft_forward_128(fft); 842 843 xfw[0][1] = 0; 844 xfw[PART_LEN][1] = 0; 845 xfw[0][0] = fft[0]; 846 xfw[PART_LEN][0] = fft[1]; 847 for (i = 1; i < PART_LEN; i++) { 848 xfw[i][0] = fft[2 * i]; 849 xfw[i][1] = fft[2 * i + 1]; 850 } 851 852 // Buffer far. 853 memcpy(aec->xfwBuf, xfw, sizeof(xfw)); 854 855 // Use delayed far. 856 memcpy(xfw, aec->xfwBuf + aec->delayIdx * PART_LEN1, sizeof(xfw)); 857 858 // Windowed near fft 859 for (i = 0; i < PART_LEN; i++) { 860 fft[i] = aec->dBuf[i] * sqrtHanning[i]; 861 fft[PART_LEN + i] = aec->dBuf[PART_LEN + i] * sqrtHanning[PART_LEN - i]; 862 } 863 aec_rdft_forward_128(fft); 864 865 dfw[1][0] = 0; 866 dfw[1][PART_LEN] = 0; 867 dfw[0][0] = fft[0]; 868 dfw[0][PART_LEN] = fft[1]; 869 for (i = 1; i < PART_LEN; i++) { 870 dfw[0][i] = fft[2 * i]; 871 dfw[1][i] = fft[2 * i + 1]; 872 } 873 874 // Windowed error fft 875 for (i = 0; i < PART_LEN; i++) { 876 fft[i] = aec->eBuf[i] * sqrtHanning[i]; 877 fft[PART_LEN + i] = aec->eBuf[PART_LEN + i] * sqrtHanning[PART_LEN - i]; 878 } 879 aec_rdft_forward_128(fft); 880 efw[1][0] = 0; 881 efw[1][PART_LEN] = 0; 882 efw[0][0] = fft[0]; 883 efw[0][PART_LEN] = fft[1]; 884 for (i = 1; i < PART_LEN; i++) { 885 efw[0][i] = fft[2 * i]; 886 efw[1][i] = fft[2 * i + 1]; 887 } 888 889 // Smoothed PSD 890 for (i = 0; i < PART_LEN1; i++) { 891 aec->sd[i] = ptrGCoh[0] * aec->sd[i] + ptrGCoh[1] * 892 (dfw[0][i] * dfw[0][i] + dfw[1][i] * dfw[1][i]); 893 aec->se[i] = ptrGCoh[0] * aec->se[i] + ptrGCoh[1] * 894 (efw[0][i] * efw[0][i] + efw[1][i] * efw[1][i]); 895 // We threshold here to protect against the ill-effects of a zero farend. 896 // The threshold is not arbitrarily chosen, but balances protection and 897 // adverse interaction with the algorithm's tuning. 898 // TODO: investigate further why this is so sensitive. 899 aec->sx[i] = ptrGCoh[0] * aec->sx[i] + ptrGCoh[1] * 900 WEBRTC_SPL_MAX(xfw[i][0] * xfw[i][0] + xfw[i][1] * xfw[i][1], 15); 901 902 aec->sde[i][0] = ptrGCoh[0] * aec->sde[i][0] + ptrGCoh[1] * 903 (dfw[0][i] * efw[0][i] + dfw[1][i] * efw[1][i]); 904 aec->sde[i][1] = ptrGCoh[0] * aec->sde[i][1] + ptrGCoh[1] * 905 (dfw[0][i] * efw[1][i] - dfw[1][i] * efw[0][i]); 906 907 aec->sxd[i][0] = ptrGCoh[0] * aec->sxd[i][0] + ptrGCoh[1] * 908 (dfw[0][i] * xfw[i][0] + dfw[1][i] * xfw[i][1]); 909 aec->sxd[i][1] = ptrGCoh[0] * aec->sxd[i][1] + ptrGCoh[1] * 910 (dfw[0][i] * xfw[i][1] - dfw[1][i] * xfw[i][0]); 911 912 sdSum += aec->sd[i]; 913 seSum += aec->se[i]; 914 } 915 916 // Divergent filter safeguard. 917 if (aec->divergeState == 0) { 918 if (seSum > sdSum) { 919 aec->divergeState = 1; 920 } 921 } 922 else { 923 if (seSum * 1.05f < sdSum) { 924 aec->divergeState = 0; 925 } 926 } 927 928 if (aec->divergeState == 1) { 929 memcpy(efw, dfw, sizeof(efw)); 930 } 931 932 // Reset if error is significantly larger than nearend (13 dB). 933 if (seSum > (19.95f * sdSum)) { 934 memset(aec->wfBuf, 0, sizeof(aec->wfBuf)); 935 } 936 937 // Subband coherence 938 for (i = 0; i < PART_LEN1; i++) { 939 cohde[i] = (aec->sde[i][0] * aec->sde[i][0] + aec->sde[i][1] * aec->sde[i][1]) / 940 (aec->sd[i] * aec->se[i] + 1e-10f); 941 cohxd[i] = (aec->sxd[i][0] * aec->sxd[i][0] + aec->sxd[i][1] * aec->sxd[i][1]) / 942 (aec->sx[i] * aec->sd[i] + 1e-10f); 943 } 944 945 hNlXdAvg = 0; 946 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) { 947 hNlXdAvg += cohxd[i]; 948 } 949 hNlXdAvg /= prefBandSize; 950 hNlXdAvg = 1 - hNlXdAvg; 951 952 hNlDeAvg = 0; 953 for (i = minPrefBand; i < prefBandSize + minPrefBand; i++) { 954 hNlDeAvg += cohde[i]; 955 } 956 hNlDeAvg /= prefBandSize; 957 958 if (hNlXdAvg < 0.75f && hNlXdAvg < aec->hNlXdAvgMin) { 959 aec->hNlXdAvgMin = hNlXdAvg; 960 } 961 962 if (hNlDeAvg > 0.98f && hNlXdAvg > 0.9f) { 963 aec->stNearState = 1; 964 } 965 else if (hNlDeAvg < 0.95f || hNlXdAvg < 0.8f) { 966 aec->stNearState = 0; 967 } 968 969 if (aec->hNlXdAvgMin == 1) { 970 aec->echoState = 0; 971 aec->overDrive = aec->minOverDrive; 972 973 if (aec->stNearState == 1) { 974 memcpy(hNl, cohde, sizeof(hNl)); 975 hNlFb = hNlDeAvg; 976 hNlFbLow = hNlDeAvg; 977 } 978 else { 979 for (i = 0; i < PART_LEN1; i++) { 980 hNl[i] = 1 - cohxd[i]; 981 } 982 hNlFb = hNlXdAvg; 983 hNlFbLow = hNlXdAvg; 984 } 985 } 986 else { 987 988 if (aec->stNearState == 1) { 989 aec->echoState = 0; 990 memcpy(hNl, cohde, sizeof(hNl)); 991 hNlFb = hNlDeAvg; 992 hNlFbLow = hNlDeAvg; 993 } 994 else { 995 aec->echoState = 1; 996 for (i = 0; i < PART_LEN1; i++) { 997 hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]); 998 } 999 1000 // Select an order statistic from the preferred bands. 1001 // TODO: Using quicksort now, but a selection algorithm may be preferred. 1002 memcpy(hNlPref, &hNl[minPrefBand], sizeof(float) * prefBandSize); 1003 qsort(hNlPref, prefBandSize, sizeof(float), CmpFloat); 1004 hNlFb = hNlPref[(int)floor(prefBandQuant * (prefBandSize - 1))]; 1005 hNlFbLow = hNlPref[(int)floor(prefBandQuantLow * (prefBandSize - 1))]; 1006 } 1007 } 1008 1009 // Track the local filter minimum to determine suppression overdrive. 1010 if (hNlFbLow < 0.6f && hNlFbLow < aec->hNlFbLocalMin) { 1011 aec->hNlFbLocalMin = hNlFbLow; 1012 aec->hNlFbMin = hNlFbLow; 1013 aec->hNlNewMin = 1; 1014 aec->hNlMinCtr = 0; 1015 } 1016 aec->hNlFbLocalMin = WEBRTC_SPL_MIN(aec->hNlFbLocalMin + 0.0008f / aec->mult, 1); 1017 aec->hNlXdAvgMin = WEBRTC_SPL_MIN(aec->hNlXdAvgMin + 0.0006f / aec->mult, 1); 1018 1019 if (aec->hNlNewMin == 1) { 1020 aec->hNlMinCtr++; 1021 } 1022 if (aec->hNlMinCtr == 2) { 1023 aec->hNlNewMin = 0; 1024 aec->hNlMinCtr = 0; 1025 aec->overDrive = WEBRTC_SPL_MAX(aec->targetSupp / 1026 ((float)log(aec->hNlFbMin + 1e-10f) + 1e-10f), aec->minOverDrive); 1027 } 1028 1029 // Smooth the overdrive. 1030 if (aec->overDrive < aec->overDriveSm) { 1031 aec->overDriveSm = 0.99f * aec->overDriveSm + 0.01f * aec->overDrive; 1032 } 1033 else { 1034 aec->overDriveSm = 0.9f * aec->overDriveSm + 0.1f * aec->overDrive; 1035 } 1036 1037 WebRtcAec_OverdriveAndSuppress(aec, hNl, hNlFb, efw); 1038 1039 #ifdef G167 1040 if (aec->cnToggle) { 1041 ComfortNoise(aec, efw, comfortNoiseHband, aec->noisePow, hNl); 1042 } 1043 #else 1044 // Add comfort noise. 1045 ComfortNoise(aec, efw, comfortNoiseHband, aec->noisePow, hNl); 1046 #endif 1047 1048 // Inverse error fft. 1049 fft[0] = efw[0][0]; 1050 fft[1] = efw[0][PART_LEN]; 1051 for (i = 1; i < PART_LEN; i++) { 1052 fft[2*i] = efw[0][i]; 1053 // Sign change required by Ooura fft. 1054 fft[2*i + 1] = -efw[1][i]; 1055 } 1056 aec_rdft_inverse_128(fft); 1057 1058 // Overlap and add to obtain output. 1059 scale = 2.0f / PART_LEN2; 1060 for (i = 0; i < PART_LEN; i++) { 1061 fft[i] *= scale; // fft scaling 1062 fft[i] = fft[i]*sqrtHanning[i] + aec->outBuf[i]; 1063 1064 // Saturation protection 1065 output[i] = (short)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, fft[i], 1066 WEBRTC_SPL_WORD16_MIN); 1067 1068 fft[PART_LEN + i] *= scale; // fft scaling 1069 aec->outBuf[i] = fft[PART_LEN + i] * sqrtHanning[PART_LEN - i]; 1070 } 1071 1072 // For H band 1073 if (aec->sampFreq == 32000) { 1074 1075 // H band gain 1076 // average nlp over low band: average over second half of freq spectrum 1077 // (4->8khz) 1078 GetHighbandGain(hNl, &nlpGainHband); 1079 1080 // Inverse comfort_noise 1081 if (flagHbandCn == 1) { 1082 fft[0] = comfortNoiseHband[0][0]; 1083 fft[1] = comfortNoiseHband[PART_LEN][0]; 1084 for (i = 1; i < PART_LEN; i++) { 1085 fft[2*i] = comfortNoiseHband[i][0]; 1086 fft[2*i + 1] = comfortNoiseHband[i][1]; 1087 } 1088 aec_rdft_inverse_128(fft); 1089 scale = 2.0f / PART_LEN2; 1090 } 1091 1092 // compute gain factor 1093 for (i = 0; i < PART_LEN; i++) { 1094 dtmp = (float)aec->dBufH[i]; 1095 dtmp = (float)dtmp * nlpGainHband; // for variable gain 1096 1097 // add some comfort noise where Hband is attenuated 1098 if (flagHbandCn == 1) { 1099 fft[i] *= scale; // fft scaling 1100 dtmp += cnScaleHband * fft[i]; 1101 } 1102 1103 // Saturation protection 1104 outputH[i] = (short)WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, dtmp, 1105 WEBRTC_SPL_WORD16_MIN); 1106 } 1107 } 1108 1109 // Copy the current block to the old position. 1110 memcpy(aec->xBuf, aec->xBuf + PART_LEN, sizeof(float) * PART_LEN); 1111 memcpy(aec->dBuf, aec->dBuf + PART_LEN, sizeof(float) * PART_LEN); 1112 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN); 1113 1114 // Copy the current block to the old position for H band 1115 if (aec->sampFreq == 32000) { 1116 memcpy(aec->dBufH, aec->dBufH + PART_LEN, sizeof(float) * PART_LEN); 1117 } 1118 1119 memmove(aec->xfwBuf + PART_LEN1, aec->xfwBuf, sizeof(aec->xfwBuf) - 1120 sizeof(complex_t) * PART_LEN1); 1121 } 1122 1123 static void GetHighbandGain(const float *lambda, float *nlpGainHband) 1124 { 1125 int i; 1126 1127 nlpGainHband[0] = (float)0.0; 1128 for (i = freqAvgIc; i < PART_LEN1 - 1; i++) { 1129 nlpGainHband[0] += lambda[i]; 1130 } 1131 nlpGainHband[0] /= (float)(PART_LEN1 - 1 - freqAvgIc); 1132 } 1133 1134 static void ComfortNoise(aec_t *aec, float efw[2][PART_LEN1], 1135 complex_t *comfortNoiseHband, const float *noisePow, const float *lambda) 1136 { 1137 int i, num; 1138 float rand[PART_LEN]; 1139 float noise, noiseAvg, tmp, tmpAvg; 1140 WebRtc_Word16 randW16[PART_LEN]; 1141 complex_t u[PART_LEN1]; 1142 1143 const float pi2 = 6.28318530717959f; 1144 1145 // Generate a uniform random array on [0 1] 1146 WebRtcSpl_RandUArray(randW16, PART_LEN, &aec->seed); 1147 for (i = 0; i < PART_LEN; i++) { 1148 rand[i] = ((float)randW16[i]) / 32768; 1149 } 1150 1151 // Reject LF noise 1152 u[0][0] = 0; 1153 u[0][1] = 0; 1154 for (i = 1; i < PART_LEN1; i++) { 1155 tmp = pi2 * rand[i - 1]; 1156 1157 noise = sqrtf(noisePow[i]); 1158 u[i][0] = noise * (float)cos(tmp); 1159 u[i][1] = -noise * (float)sin(tmp); 1160 } 1161 u[PART_LEN][1] = 0; 1162 1163 for (i = 0; i < PART_LEN1; i++) { 1164 // This is the proper weighting to match the background noise power 1165 tmp = sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); 1166 //tmp = 1 - lambda[i]; 1167 efw[0][i] += tmp * u[i][0]; 1168 efw[1][i] += tmp * u[i][1]; 1169 } 1170 1171 // For H band comfort noise 1172 // TODO: don't compute noise and "tmp" twice. Use the previous results. 1173 noiseAvg = 0.0; 1174 tmpAvg = 0.0; 1175 num = 0; 1176 if (aec->sampFreq == 32000 && flagHbandCn == 1) { 1177 1178 // average noise scale 1179 // average over second half of freq spectrum (i.e., 4->8khz) 1180 // TODO: we shouldn't need num. We know how many elements we're summing. 1181 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { 1182 num++; 1183 noiseAvg += sqrtf(noisePow[i]); 1184 } 1185 noiseAvg /= (float)num; 1186 1187 // average nlp scale 1188 // average over second half of freq spectrum (i.e., 4->8khz) 1189 // TODO: we shouldn't need num. We know how many elements we're summing. 1190 num = 0; 1191 for (i = PART_LEN1 >> 1; i < PART_LEN1; i++) { 1192 num++; 1193 tmpAvg += sqrtf(WEBRTC_SPL_MAX(1 - lambda[i] * lambda[i], 0)); 1194 } 1195 tmpAvg /= (float)num; 1196 1197 // Use average noise for H band 1198 // TODO: we should probably have a new random vector here. 1199 // Reject LF noise 1200 u[0][0] = 0; 1201 u[0][1] = 0; 1202 for (i = 1; i < PART_LEN1; i++) { 1203 tmp = pi2 * rand[i - 1]; 1204 1205 // Use average noise for H band 1206 u[i][0] = noiseAvg * (float)cos(tmp); 1207 u[i][1] = -noiseAvg * (float)sin(tmp); 1208 } 1209 u[PART_LEN][1] = 0; 1210 1211 for (i = 0; i < PART_LEN1; i++) { 1212 // Use average NLP weight for H band 1213 comfortNoiseHband[i][0] = tmpAvg * u[i][0]; 1214 comfortNoiseHband[i][1] = tmpAvg * u[i][1]; 1215 } 1216 } 1217 } 1218 1219 // Buffer the farend to account for knownDelay 1220 static void BufferFar(aec_t *aec, const short *farend, int farLen) 1221 { 1222 int writeLen = farLen, writePos = 0; 1223 1224 // Check if the write position must be wrapped. 1225 while (aec->farBufWritePos + writeLen > FAR_BUF_LEN) { 1226 1227 // Write to remaining buffer space before wrapping. 1228 writeLen = FAR_BUF_LEN - aec->farBufWritePos; 1229 memcpy(aec->farBuf + aec->farBufWritePos, farend + writePos, 1230 sizeof(short) * writeLen); 1231 aec->farBufWritePos = 0; 1232 writePos = writeLen; 1233 writeLen = farLen - writeLen; 1234 } 1235 1236 memcpy(aec->farBuf + aec->farBufWritePos, farend + writePos, 1237 sizeof(short) * writeLen); 1238 aec->farBufWritePos += writeLen; 1239 } 1240 1241 static void FetchFar(aec_t *aec, short *farend, int farLen, int knownDelay) 1242 { 1243 int readLen = farLen, readPos = 0, delayChange = knownDelay - aec->knownDelay; 1244 1245 aec->farBufReadPos -= delayChange; 1246 1247 // Check if delay forces a read position wrap. 1248 while(aec->farBufReadPos < 0) { 1249 aec->farBufReadPos += FAR_BUF_LEN; 1250 } 1251 while(aec->farBufReadPos > FAR_BUF_LEN - 1) { 1252 aec->farBufReadPos -= FAR_BUF_LEN; 1253 } 1254 1255 aec->knownDelay = knownDelay; 1256 1257 // Check if read position must be wrapped. 1258 while (aec->farBufReadPos + readLen > FAR_BUF_LEN) { 1259 1260 // Read from remaining buffer space before wrapping. 1261 readLen = FAR_BUF_LEN - aec->farBufReadPos; 1262 memcpy(farend + readPos, aec->farBuf + aec->farBufReadPos, 1263 sizeof(short) * readLen); 1264 aec->farBufReadPos = 0; 1265 readPos = readLen; 1266 readLen = farLen - readLen; 1267 } 1268 memcpy(farend + readPos, aec->farBuf + aec->farBufReadPos, 1269 sizeof(short) * readLen); 1270 aec->farBufReadPos += readLen; 1271 } 1272 1273 static void WebRtcAec_InitLevel(power_level_t *level) 1274 { 1275 const float bigFloat = 1E17f; 1276 1277 level->averagelevel = 0; 1278 level->framelevel = 0; 1279 level->minlevel = bigFloat; 1280 level->frsum = 0; 1281 level->sfrsum = 0; 1282 level->frcounter = 0; 1283 level->sfrcounter = 0; 1284 } 1285 1286 static void WebRtcAec_InitStats(stats_t *stats) 1287 { 1288 stats->instant = offsetLevel; 1289 stats->average = offsetLevel; 1290 stats->max = offsetLevel; 1291 stats->min = offsetLevel * (-1); 1292 stats->sum = 0; 1293 stats->hisum = 0; 1294 stats->himean = offsetLevel; 1295 stats->counter = 0; 1296 stats->hicounter = 0; 1297 } 1298 1299 static void UpdateLevel(power_level_t *level, const short *in) 1300 { 1301 int k; 1302 1303 for (k = 0; k < PART_LEN; k++) { 1304 level->sfrsum += in[k] * in[k]; 1305 } 1306 level->sfrcounter++; 1307 1308 if (level->sfrcounter > subCountLen) { 1309 level->framelevel = level->sfrsum / (subCountLen * PART_LEN); 1310 level->sfrsum = 0; 1311 level->sfrcounter = 0; 1312 1313 if (level->framelevel > 0) { 1314 if (level->framelevel < level->minlevel) { 1315 level->minlevel = level->framelevel; // New minimum 1316 } else { 1317 level->minlevel *= (1 + 0.001f); // Small increase 1318 } 1319 } 1320 level->frcounter++; 1321 level->frsum += level->framelevel; 1322 1323 if (level->frcounter > countLen) { 1324 level->averagelevel = level->frsum / countLen; 1325 level->frsum = 0; 1326 level->frcounter = 0; 1327 } 1328 1329 } 1330 } 1331 1332 static void UpdateMetrics(aec_t *aec) 1333 { 1334 float dtmp, dtmp2, dtmp3; 1335 1336 const float actThresholdNoisy = 8.0f; 1337 const float actThresholdClean = 40.0f; 1338 const float safety = 0.99995f; 1339 const float noisyPower = 300000.0f; 1340 1341 float actThreshold; 1342 float echo, suppressedEcho; 1343 1344 if (aec->echoState) { // Check if echo is likely present 1345 aec->stateCounter++; 1346 } 1347 1348 if (aec->farlevel.frcounter == countLen) { 1349 1350 if (aec->farlevel.minlevel < noisyPower) { 1351 actThreshold = actThresholdClean; 1352 } 1353 else { 1354 actThreshold = actThresholdNoisy; 1355 } 1356 1357 if ((aec->stateCounter > (0.5f * countLen * subCountLen)) 1358 && (aec->farlevel.sfrcounter == 0) 1359 1360 // Estimate in active far-end segments only 1361 && (aec->farlevel.averagelevel > (actThreshold * aec->farlevel.minlevel)) 1362 ) { 1363 1364 // Subtract noise power 1365 echo = aec->nearlevel.averagelevel - safety * aec->nearlevel.minlevel; 1366 1367 // ERL 1368 dtmp = 10 * (float)log10(aec->farlevel.averagelevel / 1369 aec->nearlevel.averagelevel + 1e-10f); 1370 dtmp2 = 10 * (float)log10(aec->farlevel.averagelevel / echo + 1e-10f); 1371 1372 aec->erl.instant = dtmp; 1373 if (dtmp > aec->erl.max) { 1374 aec->erl.max = dtmp; 1375 } 1376 1377 if (dtmp < aec->erl.min) { 1378 aec->erl.min = dtmp; 1379 } 1380 1381 aec->erl.counter++; 1382 aec->erl.sum += dtmp; 1383 aec->erl.average = aec->erl.sum / aec->erl.counter; 1384 1385 // Upper mean 1386 if (dtmp > aec->erl.average) { 1387 aec->erl.hicounter++; 1388 aec->erl.hisum += dtmp; 1389 aec->erl.himean = aec->erl.hisum / aec->erl.hicounter; 1390 } 1391 1392 // A_NLP 1393 dtmp = 10 * (float)log10(aec->nearlevel.averagelevel / 1394 aec->linoutlevel.averagelevel + 1e-10f); 1395 1396 // subtract noise power 1397 suppressedEcho = aec->linoutlevel.averagelevel - safety * aec->linoutlevel.minlevel; 1398 1399 dtmp2 = 10 * (float)log10(echo / suppressedEcho + 1e-10f); 1400 dtmp3 = 10 * (float)log10(aec->nearlevel.averagelevel / suppressedEcho + 1e-10f); 1401 1402 aec->aNlp.instant = dtmp2; 1403 if (dtmp > aec->aNlp.max) { 1404 aec->aNlp.max = dtmp; 1405 } 1406 1407 if (dtmp < aec->aNlp.min) { 1408 aec->aNlp.min = dtmp; 1409 } 1410 1411 aec->aNlp.counter++; 1412 aec->aNlp.sum += dtmp; 1413 aec->aNlp.average = aec->aNlp.sum / aec->aNlp.counter; 1414 1415 // Upper mean 1416 if (dtmp > aec->aNlp.average) { 1417 aec->aNlp.hicounter++; 1418 aec->aNlp.hisum += dtmp; 1419 aec->aNlp.himean = aec->aNlp.hisum / aec->aNlp.hicounter; 1420 } 1421 1422 // ERLE 1423 1424 // subtract noise power 1425 suppressedEcho = aec->nlpoutlevel.averagelevel - safety * aec->nlpoutlevel.minlevel; 1426 1427 dtmp = 10 * (float)log10(aec->nearlevel.averagelevel / 1428 aec->nlpoutlevel.averagelevel + 1e-10f); 1429 dtmp2 = 10 * (float)log10(echo / suppressedEcho + 1e-10f); 1430 1431 dtmp = dtmp2; 1432 aec->erle.instant = dtmp; 1433 if (dtmp > aec->erle.max) { 1434 aec->erle.max = dtmp; 1435 } 1436 1437 if (dtmp < aec->erle.min) { 1438 aec->erle.min = dtmp; 1439 } 1440 1441 aec->erle.counter++; 1442 aec->erle.sum += dtmp; 1443 aec->erle.average = aec->erle.sum / aec->erle.counter; 1444 1445 // Upper mean 1446 if (dtmp > aec->erle.average) { 1447 aec->erle.hicounter++; 1448 aec->erle.hisum += dtmp; 1449 aec->erle.himean = aec->erle.hisum / aec->erle.hicounter; 1450 } 1451 } 1452 1453 aec->stateCounter = 0; 1454 } 1455 } 1456 1457