Lines Matching defs:aecm
11 #include "webrtc/modules/audio_processing/aecm/aecm_core.h"
18 #include "webrtc/modules/audio_processing/aecm/include/echo_control_mobile.h"
178 // - self : Pointer to the AECM instance.
212 AecmCore_t *aecm = malloc(sizeof(AecmCore_t));
213 *aecmInst = aecm;
214 if (aecm == NULL)
219 aecm->farFrameBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN,
221 if (!aecm->farFrameBuf)
223 WebRtcAecm_FreeCore(aecm);
224 aecm = NULL;
228 aecm->nearNoisyFrameBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN,
230 if (!aecm->nearNoisyFrameBuf)
232 WebRtcAecm_FreeCore(aecm);
233 aecm = NULL;
237 aecm->nearCleanFrameBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN,
239 if (!aecm->nearCleanFrameBuf)
241 WebRtcAecm_FreeCore(aecm);
242 aecm = NULL;
246 aecm->outFrameBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN,
248 if (!aecm->outFrameBuf)
250 WebRtcAecm_FreeCore(aecm);
251 aecm = NULL;
255 aecm->delay_estimator_farend = WebRtc_CreateDelayEstimatorFarend(PART_LEN1,
257 if (aecm->delay_estimator_farend == NULL) {
258 WebRtcAecm_FreeCore(aecm);
259 aecm = NULL;
262 aecm->delay_estimator =
263 WebRtc_CreateDelayEstimator(aecm->delay_estimator_farend, 0);
264 if (aecm->delay_estimator == NULL) {
265 WebRtcAecm_FreeCore(aecm);
266 aecm = NULL;
271 WebRtc_enable_robust_validation(aecm->delay_estimator, 0);
273 aecm->real_fft = WebRtcSpl_CreateRealFFT(PART_LEN_SHIFT);
274 if (aecm->real_fft == NULL) {
275 WebRtcAecm_FreeCore(aecm);
276 aecm = NULL;
280 // Init some aecm pointers. 16 and 32 byte alignment is only necessary
282 aecm->xBuf = (int16_t*) (((uintptr_t)aecm->xBuf_buf + 31) & ~ 31);
283 aecm->dBufClean = (int16_t*) (((uintptr_t)aecm->dBufClean_buf + 31) & ~ 31);
284 aecm->dBufNoisy = (int16_t*) (((uintptr_t)aecm->dBufNoisy_buf + 31) & ~ 31);
285 aecm->outBuf = (int16_t*) (((uintptr_t)aecm->outBuf_buf + 15) & ~ 15);
286 aecm->channelStored = (int16_t*) (((uintptr_t)
287 aecm->channelStored_buf + 15) & ~ 15);
288 aecm->channelAdapt16 = (int16_t*) (((uintptr_t)
289 aecm->channelAdapt16_buf + 15) & ~ 15);
290 aecm->channelAdapt32 = (int32_t*) (((uintptr_t)
291 aecm->channelAdapt32_buf + 31) & ~ 31);
296 void WebRtcAecm_InitEchoPathCore(AecmCore_t* aecm, const int16_t* echo_path)
301 memcpy(aecm->channelStored, echo_path, sizeof(int16_t) * PART_LEN1);
303 memcpy(aecm->channelAdapt16, echo_path, sizeof(int16_t) * PART_LEN1);
306 aecm->channelAdapt32[i] = WEBRTC_SPL_LSHIFT_W32(
307 (int32_t)(aecm->channelAdapt16[i]), 16);
311 aecm->mseAdaptOld = 1000;
312 aecm->mseStoredOld = 1000;
313 aecm->mseThreshold = WEBRTC_SPL_WORD32_MAX;
314 aecm->mseChannelCount = 0;
317 static void CalcLinearEnergiesC(AecmCore_t* aecm,
330 echo_est[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i],
333 *echo_energy_adapt += aecm->channelAdapt16[i] * far_spectrum[i];
338 static void StoreAdaptiveChannelC(AecmCore_t* aecm,
345 memcpy(aecm->channelStored, aecm->channelAdapt16, sizeof(int16_t) * PART_LEN1);
349 echo_est[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i],
351 echo_est[i + 1] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i + 1],
353 echo_est[i + 2] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i + 2],
355 echo_est[i + 3] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i + 3],
358 echo_est[i] = WEBRTC_SPL_MUL_16_U16(aecm->channelStored[i],
362 static void ResetAdaptiveChannelC(AecmCore_t* aecm)
368 memcpy(aecm->channelAdapt16, aecm->channelStored,
373 aecm->channelAdapt32[i] = WEBRTC_SPL_LSHIFT_W32(
374 (int32_t)aecm->channelStored[i], 16);
375 aecm->channelAdapt32[i + 1] = WEBRTC_SPL_LSHIFT_W32(
376 (int32_t)aecm->channelStored[i + 1], 16);
377 aecm
378 (int32_t)aecm->channelStored[i + 2], 16);
379 aecm->channelAdapt32[i + 3] = WEBRTC_SPL_LSHIFT_W32(
380 (int32_t)aecm->channelStored[i + 3], 16);
382 aecm->channelAdapt32[i] = WEBRTC_SPL_LSHIFT_W32((int32_t)aecm->channelStored[i], 16);
409 // This function initializes the AECM instant created with WebRtcAecm_CreateCore(...)
411 // - aecm : Pointer to the Echo Suppression instance
415 // - aecm : Initialized instance
420 int WebRtcAecm_InitCore(AecmCore_t * const aecm, int samplingFreq)
432 aecm->mult = (int16_t)samplingFreq / 8000;
434 aecm->farBufWritePos = 0;
435 aecm->farBufReadPos = 0;
436 aecm->knownDelay = 0;
437 aecm->lastKnownDelay = 0;
439 WebRtc_InitBuffer(aecm->farFrameBuf);
440 WebRtc_InitBuffer(aecm->nearNoisyFrameBuf);
441 WebRtc_InitBuffer(aecm->nearCleanFrameBuf);
442 WebRtc_InitBuffer(aecm->outFrameBuf);
444 memset(aecm->xBuf_buf, 0, sizeof(aecm->xBuf_buf));
445 memset(aecm->dBufClean_buf, 0, sizeof(aecm->dBufClean_buf));
446 memset(aecm->dBufNoisy_buf, 0, sizeof(aecm->dBufNoisy_buf));
447 memset(aecm->outBuf_buf, 0, sizeof(aecm->outBuf_buf));
449 aecm->seed = 666;
450 aecm->totCount = 0;
452 if (WebRtc_InitDelayEstimatorFarend(aecm->delay_estimator_farend) != 0) {
455 if (WebRtc_InitDelayEstimator(aecm->delay_estimator) != 0) {
459 memset(aecm->far_history, 0, sizeof(uint16_t) * PART_LEN1 * MAX_DELAY);
460 memset(aecm->far_q_domains, 0, sizeof(int) * MAX_DELAY);
461 aecm->far_history_pos = MAX_DELAY;
463 aecm->nlpFlag = 1;
464 aecm->fixedDelay = -1;
466 aecm->dfaCleanQDomain = 0;
467 aecm->dfaCleanQDomainOld = 0;
468 aecm->dfaNoisyQDomain = 0;
469 aecm->dfaNoisyQDomainOld = 0;
471 memset(aecm->nearLogEnergy, 0, sizeof(aecm->nearLogEnergy));
472 aecm->farLogEnergy = 0;
473 memset(aecm->echoAdaptLogEnergy, 0, sizeof(aecm->echoAdaptLogEnergy));
474 memset(aecm->echoStoredLogEnergy, 0, sizeof(aecm->echoStoredLogEnergy));
479 WebRtcAecm_InitEchoPathCore(aecm, kChannelStored8kHz);
483 WebRtcAecm_InitEchoPathCore(aecm, kChannelStored16kHz);
486 memset(aecm->echoFilt, 0, sizeof(aecm->echoFilt));
487 memset(aecm->nearFilt, 0, sizeof(aecm->nearFilt));
488 aecm->noiseEstCtr = 0;
490 aecm->cngMode = AecmTrue;
492 memset(aecm->noiseEstTooLowCtr, 0, sizeof(aecm->noiseEstTooLowCtr));
493 memset(aecm->noiseEstTooHighCtr, 0, sizeof(aecm->noiseEstTooHighCtr));
497 aecm->noiseEst[i] = (tmp32 << 8);
503 aecm->noiseEst[i] = (tmp32 << 8);
506 aecm->farEnergyMin = WEBRTC_SPL_WORD16_MAX;
507 aecm->farEnergyMax = WEBRTC_SPL_WORD16_MIN;
508 aecm->farEnergyMaxMin = 0;
509 aecm->farEnergyVAD = FAR_ENERGY_MIN; // This prevents false speech detection at the
511 aecm->farEnergyMSE = 0;
512 aecm->currentVADValue = 0;
513 aecm->vadUpdateCount = 0;
514 aecm->firstVAD = 1;
516 aecm->startupState = 0;
517 aecm->supGain = SUPGAIN_DEFAULT;
518 aecm->supGainOld = SUPGAIN_DEFAULT;
520 aecm->supGainErrParamA = SUPGAIN_ERROR_PARAM_A;
521 aecm->supGainErrParamD = SUPGAIN_ERROR_PARAM_D;
522 aecm->supGainErrParamDiffAB = SUPGAIN_ERROR_PARAM_A - SUPGAIN_ERROR_PARAM_B;
523 aecm->supGainErrParamDiffBD = SUPGAIN_ERROR_PARAM_B - SUPGAIN_ERROR_PARAM_D;
552 int WebRtcAecm_Control(AecmCore_t *aecm, int delay, int nlpFlag)
554 aecm->nlpFlag = nlpFlag;
555 aecm->fixedDelay = delay;
560 int WebRtcAecm_FreeCore(AecmCore_t *aecm)
562 if (aecm == NULL)
567 WebRtc_FreeBuffer(aecm->farFrameBuf);
568 WebRtc_FreeBuffer(aecm->nearNoisyFrameBuf);
569 WebRtc_FreeBuffer(aecm->nearCleanFrameBuf);
570 WebRtc_FreeBuffer(aecm->outFrameBuf);
572 WebRtc_FreeDelayEstimator(aecm->delay_estimator);
573 WebRtc_FreeDelayEstimatorFarend(aecm->delay_estimator_farend);
574 WebRtcSpl_FreeRealFFT(aecm->real_fft);
576 free(aecm);
581 int WebRtcAecm_ProcessFrame(AecmCore_t * aecm,
596 WebRtcAecm_BufferFarFrame(aecm, farend, FRAME_LEN);
597 WebRtcAecm_FetchFarFrame(aecm, farFrame, FRAME_LEN, aecm->knownDelay);
601 WebRtc_WriteBuffer(aecm->farFrameBuf, farFrame, FRAME_LEN);
602 WebRtc_WriteBuffer(aecm->nearNoisyFrameBuf, nearendNoisy, FRAME_LEN);
605 WebRtc_WriteBuffer(aecm->nearCleanFrameBuf, nearendClean, FRAME_LEN);
609 while (WebRtc_available_read(aecm->farFrameBuf) >= PART_LEN)
616 WebRtc_ReadBuffer(aecm->farFrameBuf, (void**) &far_block_ptr, far_block,
618 WebRtc_ReadBuffer(aecm->nearNoisyFrameBuf,
627 WebRtc_ReadBuffer(aecm->nearCleanFrameBuf,
631 if (WebRtcAecm_ProcessBlock(aecm,
641 if (WebRtcAecm_ProcessBlock(aecm,
651 WebRtc_WriteBuffer(aecm->outFrameBuf, outBlock, PART_LEN);
656 size = (int) WebRtc_available_read(aecm->outFrameBuf);
659 WebRtc_MoveReadPtr(aecm->outFrameBuf, size - FRAME_LEN);
663 WebRtc_ReadBuffer(aecm->outFrameBuf, (void**) &out_ptr, out, FRAME_LEN);
723 // @param aecm [i/o] Handle of the AECM instance.
727 // Q(aecm->dfaQDomain).
730 void WebRtcAecm_CalcEnergies(AecmCore_t * aecm,
754 memmove(aecm->nearLogEnergy + 1, aecm->nearLogEnergy,
765 tmp16 -= WEBRTC_SPL_LSHIFT_W16(aecm->dfaNoisyQDomain, 8);
767 aecm->nearLogEnergy[0] = tmp16;
770 WebRtcAecm_CalcLinearEnergies(aecm, far_spectrum, echoEst, &tmpFar, &tmpAdapt, &tmpStored);
773 memmove(aecm->echoAdaptLogEnergy + 1, aecm->echoAdaptLogEnergy,
775 memmove(aecm->echoStoredLogEnergy + 1, aecm->echoStoredLogEnergy,
788 aecm->farLogEnergy = tmp16;
800 aecm->echoAdaptLogEnergy[0] = tmp16;
812 aecm->echoStoredLogEnergy[0] = tmp16;
815 if (aecm->farLogEnergy > FAR_ENERGY_MIN)
817 if (aecm->startupState == 0)
824 aecm->farEnergyMin = WebRtcAecm_AsymFilt(aecm->farEnergyMin, aecm->farLogEnergy,
826 aecm->farEnergyMax = WebRtcAecm_AsymFilt(aecm->farEnergyMax, aecm->farLogEnergy,
828 aecm->farEnergyMaxMin = (aecm->farEnergyMax - aecm->farEnergyMin);
831 tmp16 = 2560 - aecm->farEnergyMin;
841 if ((aecm->startupState == 0) | (aecm->vadUpdateCount > 1024))
844 aecm->farEnergyVAD = aecm->farEnergyMin + tmp16;
847 if (aecm->farEnergyVAD > aecm->farLogEnergy)
849 aecm->farEnergyVAD += WEBRTC_SPL_RSHIFT_W16(aecm->farLogEnergy +
851 aecm->farEnergyVAD,
853 aecm->vadUpdateCount = 0;
856 aecm->vadUpdateCount++;
860 aecm->farEnergyMSE = aecm->farEnergyVAD + (1 << 8);
864 if (aecm->farLogEnergy > aecm->farEnergyVAD)
866 if ((aecm->startupState == 0) | (aecm
869 aecm->currentVADValue = 1;
873 aecm->currentVADValue = 0;
875 if ((aecm->currentVADValue) && (aecm->firstVAD))
877 aecm->firstVAD = 0;
878 if (aecm->echoAdaptLogEnergy[0] > aecm->nearLogEnergy[0])
885 aecm->channelAdapt16[i] >>= 3;
888 aecm->echoAdaptLogEnergy[0] -= (3 << 8);
889 aecm->firstVAD = 1;
899 // @param aecm [in] Handle of the AECM instance.
903 int16_t WebRtcAecm_CalcStepSize(AecmCore_t * const aecm)
912 if (!aecm->currentVADValue)
916 } else if (aecm->startupState > 0)
918 if (aecm->farEnergyMin >= aecm->farEnergyMax)
923 tmp16 = (aecm->farLogEnergy - aecm->farEnergyMin);
925 tmp32 = WebRtcSpl_DivW32W16(tmp32, aecm->farEnergyMaxMin);
944 // @param aecm [i/o] Handle of the AECM instance.
947 // @param dfa [in] Absolute value of the nearend signal (Q[aecm->dfaQDomain])
951 void WebRtcAecm_UpdateChannel(AecmCore_t * aecm,
979 zerosCh = WebRtcSpl_NormU32(aecm->channelAdapt32[i]);
984 tmpU32no1 = WEBRTC_SPL_UMUL_32_16(aecm->channelAdapt32[i],
992 WEBRTC_SPL_RSHIFT_W32(aecm->channelAdapt32[i], shiftChFar),
1004 tmp16no1 = zerosDfa - 2 + aecm->dfaNoisyQDomain -
1013 dfaQ = RESOLUTION_CHANNEL32 + far_q - aecm->dfaNoisyQDomain -
1028 // tmp32no1 = dfa[i] - (aecm->channelAdapt[i] * far_spectrum[i])
1030 // aecm->channelAdapt[i] += (2^mu) * tmp32no1
1073 aecm->channelAdapt32[i] =
1074 WebRtcSpl_AddSatW32(aecm->channelAdapt32[i], tmp32no2);
1075 if (aecm->channelAdapt32[i] < 0)
1078 aecm->channelAdapt32[i] = 0;
1080 aecm->channelAdapt16[i]
1081 = (int16_t)WEBRTC_SPL_RSHIFT_W32(aecm->channelAdapt32[i], 16);
1088 if ((aecm->startupState == 0) & (aecm->currentVADValue))
1092 WebRtcAecm_StoreAdaptiveChannel(aecm, far_spectrum, echoEst);
1095 if (aecm->farLogEnergy < aecm->farEnergyMSE)
1097 aecm->mseChannelCount = 0;
1100 aecm->mseChannelCount++;
1103 if (aecm->mseChannelCount >= (MIN_MSE_COUNT + 10))
1112 tmp32no1 = ((int32_t)aecm->echoStoredLogEnergy[i]
1113 - (int32_t)aecm->nearLogEnergy[i]);
1117 tmp32no1 = ((int32_t)aecm->echoAdaptLogEnergy[i]
1118 - (int32_t)aecm->nearLogEnergy[i]);
1123 & ((aecm->mseStoredOld << MSE_RESOLUTION) < (MIN_MSE_DIFF
1124 * aecm->mseAdaptOld)))
1128 WebRtcAecm_ResetAdaptiveChannel(aecm);
1130 < aecm->mseThreshold) & (aecm->mseAdaptOld < aecm->mseThreshold))
1135 WebRtcAecm_StoreAdaptiveChannel(aecm, far_spectrum, echoEst);
1138 if (aecm->mseThreshold == WEBRTC_SPL_WORD32_MAX)
1140 aecm->mseThreshold = (mseAdapt + aecm->mseAdaptOld);
1143 aecm->mseThreshold += WEBRTC_SPL_MUL_16_16_RSFT(mseAdapt
1144 - WEBRTC_SPL_MUL_16_16_RSFT(aecm->mseThreshold, 5, 3), 205, 8);
1150 aecm->mseChannelCount = 0;
1153 aecm->mseStoredOld = mseStored;
1154 aecm->mseAdaptOld = mseAdapt;
1165 // @param aecm [i/n] Handle of the AECM instance.
1170 int16_t WebRtcAecm_CalcSuppressionGain(AecmCore_t * const aecm)
1182 if (!aecm->currentVADValue)
1189 tmp16no1 = (aecm->nearLogEnergy[0] - aecm->echoStoredLogEnergy[0] - ENERGY_DEV_OFFSET);
1198 tmp32no1 = WEBRTC_SPL_MUL_16_16(aecm->supGainErrParamDiffAB, dE);
1201 supGain = aecm->supGainErrParamA - tmp16no1;
1204 tmp32no1 = WEBRTC_SPL_MUL_16_16(aecm->supGainErrParamDiffBD,
1209 supGain = aecm->supGainErrParamD + tmp16no1;
1214 supGain = aecm->supGainErrParamD;
1218 if (supGain > aecm->supGainOld)
1223 tmp16no1 = aecm->supGainOld;
1225 aecm->supGainOld = supGain;
1226 if (tmp16no1 < aecm->supGain)
1228 aecm->supGain += (int16_t)((tmp16no1 - aecm->supGain) >> 4);
1231 aecm->supGain += (int16_t)((tmp16no1 - aecm->supGain) >> 4);
1236 return aecm->supGain;
1239 void WebRtcAecm_BufferFarFrame(AecmCore_t* const aecm,
1246 while (aecm->farBufWritePos + writeLen > FAR_BUF_LEN)
1249 writeLen = FAR_BUF_LEN - aecm->farBufWritePos;
1250 memcpy(aecm->farBuf + aecm->farBufWritePos, farend + writePos,
1252 aecm->farBufWritePos = 0;
1257 memcpy(aecm->farBuf + aecm->farBufWritePos, farend + writePos,
1259 aecm->farBufWritePos += writeLen;
1262 void WebRtcAecm_FetchFarFrame(AecmCore_t * const aecm, int16_t * const farend,
1267 int delayChange = knownDelay - aecm->lastKnownDelay;
1269 aecm->farBufReadPos -= delayChange;
1272 while (aecm->farBufReadPos < 0)
1274 aecm->farBufReadPos += FAR_BUF_LEN;
1276 while (aecm->farBufReadPos > FAR_BUF_LEN - 1)
1278 aecm->farBufReadPos -= FAR_BUF_LEN;
1281 aecm->lastKnownDelay = knownDelay;
1284 while (aecm->farBufReadPos + readLen > FAR_BUF_LEN)
1288 readLen = FAR_BUF_LEN - aecm->farBufReadPos;
1289 memcpy(farend + readPos, aecm->farBuf + aecm->farBufReadPos,
1291 aecm->farBufReadPos = 0;
1295 memcpy(farend + readPos, aecm->farBuf + aecm->farBufReadPos,
1297 aecm->farBufReadPos += readLen;