Lines Matching refs:aec
12 * The core AEC algorithm, which is presented with time-aligned signals.
15 #include "webrtc/modules/audio_processing/aec/aec_core.h"
28 #include "webrtc/modules/audio_processing/aec/aec_common.h"
29 #include "webrtc/modules/audio_processing/aec/aec_core_internal.h"
30 #include "webrtc/modules/audio_processing/aec/aec_rdft.h"
143 static void FilterFar(AecCore* aec, float yf[2][PART_LEN1]) {
145 for (i = 0; i < aec->num_partitions; i++) {
147 int xPos = (i + aec->xfBufBlockPos) * PART_LEN1;
150 if (i + aec->xfBufBlockPos >= aec->num_partitions) {
151 xPos -= aec->num_partitions * (PART_LEN1);
155 yf[0][j] += MulRe(aec->xfBuf[0][xPos + j],
156 aec->xfBuf[1][xPos + j],
157 aec->wfBuf[0][pos + j],
158 aec->wfBuf[1][pos + j]);
159 yf[1][j] += MulIm(aec->xfBuf[0][xPos + j],
160 aec->xfBuf[1][xPos + j],
161 aec->wfBuf[0][pos + j],
162 aec->wfBuf[1][pos + j]);
167 static void ScaleErrorSignal(AecCore* aec, float ef[2][PART_LEN1]) {
168 const float mu = aec->extended_filter_enabled ? kExtendedMu : aec->normal_mu;
169 const float error_threshold = aec->extended_filter_enabled
171 : aec->normal_error_threshold;
175 ef[0][i] /= (aec->xPow[i] + 1e-10f);
176 ef[1][i] /= (aec->xPow[i] + 1e-10f);
193 // static void FilterAdaptationUnconstrained(AecCore* aec, float *fft,
196 // for (i = 0; i < aec->num_partitions; i++) {
197 // int xPos = (i + aec->xfBufBlockPos)*(PART_LEN1);
200 // if (i + aec->xfBufBlockPos >= aec->num_partitions) {
201 // xPos -= aec->num_partitions * PART_LEN1;
207 // aec->wfBuf[0][pos + j] += MulRe(aec->xfBuf[0][xPos + j],
208 // -aec->xfBuf[1][xPos + j],
210 // aec->wfBuf[1][pos + j] += MulIm(aec->xfBuf[0][xPos + j],
211 // -aec->xfBuf[1][xPos + j],
217 static void FilterAdaptation(AecCore* aec, float* fft, float ef[2][PART_LEN1]) {
219 for (i = 0; i < aec->num_partitions; i++) {
220 int xPos = (i + aec->xfBufBlockPos) * (PART_LEN1);
223 if (i + aec->xfBufBlockPos >= aec->num_partitions) {
224 xPos -= aec->num_partitions * PART_LEN1;
231 fft[2 * j] = MulRe(aec->xfBuf[0][xPos + j],
232 -aec->xfBuf[1][xPos + j],
235 fft[2 * j + 1] = MulIm(aec->xfBuf[0][xPos + j],
236 -aec->xfBuf[1][xPos + j],
240 fft[1] = MulRe(aec->xfBuf[0][xPos + PART_LEN],
241 -aec->xfBuf[1][xPos + PART_LEN],
257 aec->wfBuf[0][pos] += fft[0];
258 aec->wfBuf[0][pos + PART_LEN] += fft[1];
261 aec->wfBuf[0][pos + j] += fft[2 * j];
262 aec->wfBuf[1][pos + j] += fft[2 * j + 1];
267 static void OverdriveAndSuppress(AecCore* aec,
278 hNl[i] = powf(hNl[i], aec->overDriveSm * WebRtcAec_overDriveCurve[i]);
290 static int PartitionDelay(const AecCore* aec) {
299 for (i = 0; i < aec->num_partitions; i++) {
304 wfEn += aec->wfBuf[0][pos + j] * aec->wfBuf[0][pos + j] +
305 aec->wfBuf[1][pos + j] * aec->wfBuf[1][pos + j];
328 static void SmoothedPSD(AecCore* aec,
333 const float* ptrGCoh = aec->extended_filter_enabled
334 ? WebRtcAec_kExtendedSmoothingCoefficients[aec->mult - 1]
335 : WebRtcAec_kNormalSmoothingCoefficients[aec->mult - 1];
340 aec->sd[i] = ptrGCoh[0] * aec->sd[i] +
342 aec->se[i] = ptrGCoh[0] * aec->se[i] +
348 aec->sx[i] =
349 ptrGCoh[0] * aec->sx[i] +
354 aec->sde[i][0] =
355 ptrGCoh[0] * aec->sde[i][0] +
357 aec->sde[i][1] =
358 ptrGCoh[0] * aec->sde[i][1] +
361 aec->sxd[i][0] =
362 ptrGCoh[0] * aec->sxd[i][0] +
364 aec->sxd[i][1] =
365 ptrGCoh[0] * aec->sxd[i][1] +
368 sdSum += aec->sd[i];
369 seSum += aec->se[i];
373 aec->divergeState = (aec->divergeState ? 1.05f : 1.0f) * seSum > sdSum;
375 if (aec->divergeState)
379 if (!aec->extended_filter_enabled && seSum > (19.95f * sdSum))
380 memset(aec->wfBuf, 0, sizeof(aec->wfBuf));
407 static void SubbandCoherence(AecCore* aec,
416 if (aec->delayEstCtr == 0)
417 aec->delayIdx = PartitionDelay(aec);
421 aec->xfwBuf + aec->delayIdx * PART_LEN1,
425 WindowData(fft, aec->dBuf);
430 WindowData(fft, aec->eBuf);
434 SmoothedPSD(aec, efw, dfw, xfw);
439 (aec->sde[i][0] * aec->sde[i][0] + aec->sde[i][1] * aec->sde[i][1]) /
440 (aec->sd[i] * aec->se[i] + 1e-10f);
442 (aec->sxd[i][0] * aec->sxd[i][0] + aec->sxd[i][1] * aec->sxd[i][1]) /
443 (aec->sx[i] * aec->sd[i] + 1e-10f);
457 static void ComfortNoise(AecCore* aec,
471 WebRtcSpl_RandUArray(randW16, PART_LEN, &aec->seed);
501 if (aec->sampFreq == 32000 && flagHbandCn == 1) {
640 static void UpdateMetrics(AecCore* aec) {
651 if (aec->echoState) { // Check if echo is likely present
652 aec->stateCounter++;
655 if (aec->farlevel.frcounter == 0) {
657 if (aec->farlevel.minlevel < noisyPower) {
663 if ((aec->stateCounter > (0.5f * countLen * subCountLen)) &&
664 (aec->farlevel.sfrcounter == 0)
668 (aec->farlevel.averagelevel >
669 (actThreshold * aec->farlevel.minlevel))) {
672 echo = aec->nearlevel.averagelevel - safety * aec->nearlevel.minlevel;
675 dtmp = 10 * (float)log10(aec->farlevel.averagelevel /
676 aec->nearlevel.averagelevel +
678 dtmp2 = 10 * (float)log10(aec->farlevel.averagelevel / echo + 1e-10f);
680 aec->erl.instant = dtmp;
681 if (dtmp > aec->erl.max) {
682 aec->erl.max = dtmp;
685 if (dtmp < aec->erl.min) {
686 aec->erl.min = dtmp;
689 aec->erl.counter++;
690 aec->erl.sum += dtmp;
691 aec->erl.average = aec->erl.sum / aec->erl.counter;
694 if (dtmp > aec->erl.average) {
695 aec->erl.hicounter++;
696 aec->erl.hisum += dtmp;
697 aec->erl.himean = aec->erl.hisum / aec->erl.hicounter;
701 dtmp = 10 * (float)log10(aec->nearlevel.averagelevel /
702 (2 * aec->linoutlevel.averagelevel) +
706 suppressedEcho = 2 * (aec->linoutlevel.averagelevel -
707 safety * aec->linoutlevel.minlevel);
711 aec->aNlp.instant = dtmp2;
712 if (dtmp > aec->aNlp.max) {
713 aec->aNlp.max = dtmp;
716 if (dtmp < aec->aNlp.min) {
717 aec->aNlp.min = dtmp;
720 aec->aNlp.counter++;
721 aec->aNlp.sum += dtmp;
722 aec->aNlp.average = aec->aNlp.sum / aec->aNlp.counter;
725 if (dtmp > aec->aNlp.average) {
726 aec->aNlp.hicounter++;
727 aec->aNlp.hisum += dtmp;
728 aec->aNlp.himean = aec->aNlp.hisum / aec->aNlp.hicounter;
734 suppressedEcho = 2 * (aec->nlpoutlevel.averagelevel -
735 safety * aec->nlpoutlevel.minlevel);
737 dtmp = 10 * (float)log10(aec->nearlevel.averagelevel /
738 (2 * aec->nlpoutlevel.averagelevel) +
743 aec->erle.instant = dtmp;
744 if (dtmp > aec->erle.max) {
745 aec->erle.max = dtmp;
748 if (dtmp < aec->erle.min) {
749 aec->erle.min = dtmp;
752 aec->erle.counter++;
753 aec->erle.sum += dtmp;
754 aec->erle.average = aec->erle.sum / aec->erle.counter;
757 if (dtmp > aec->erle.average) {
758 aec->erle.hicounter++;
759 aec->erle.hisum += dtmp;
760 aec->erle.himean = aec->erle.hisum / aec->erle.hicounter;
764 aec->stateCounter = 0;
793 static void NonLinearProcessing(AecCore* aec, float* output, float* outputH) {
808 const int prefBandSize = kPrefBandSize / aec->mult;
809 const int minPrefBand = 4 / aec->mult;
811 const float* min_overdrive = aec->extended_filter_enabled
816 const int delayEstInterval = 10 * aec->mult;
820 aec->delayEstCtr++;
821 if (aec->delayEstCtr == delayEstInterval) {
822 aec->delayEstCtr = 0;
831 assert(WebRtc_available_read(aec->far_buf_windowed) > 0);
833 WebRtc_ReadBuffer(aec->far_buf_windowed, (void**)&xfw_ptr, &xfw[0][0], 1);
838 memcpy(aec->xfwBuf, xfw_ptr, sizeof(float) * 2 * PART_LEN1);
840 WebRtcAec_SubbandCoherence(aec, efw, xfw, fft, cohde, cohxd);
855 if (hNlXdAvg < 0.75f && hNlXdAvg < aec->hNlXdAvgMin) {
856 aec->hNlXdAvgMin = hNlXdAvg;
860 aec->stNearState = 1;
862 aec->stNearState = 0;
865 if (aec->hNlXdAvgMin == 1) {
866 aec->echoState = 0;
867 aec->overDrive = min_overdrive[aec->nlp_mode];
869 if (aec->stNearState == 1) {
882 if (aec->stNearState == 1) {
883 aec->echoState = 0;
888 aec->echoState = 1;
903 if (hNlFbLow < 0.6f && hNlFbLow < aec->hNlFbLocalMin) {
904 aec->hNlFbLocalMin = hNlFbLow;
905 aec->hNlFbMin = hNlFbLow;
906 aec->hNlNewMin = 1;
907 aec->hNlMinCtr = 0;
909 aec->hNlFbLocalMin =
910 WEBRTC_SPL_MIN(aec->hNlFbLocalMin + 0.0008f / aec->mult, 1);
911 aec->hNlXdAvgMin = WEBRTC_SPL_MIN(aec->hNlXdAvgMin + 0.0006f / aec->mult, 1);
913 if (aec->hNlNewMin == 1) {
914 aec->hNlMinCtr++;
916 if (aec->hNlMinCtr == 2) {
917 aec->hNlNewMin = 0;
918 aec->hNlMinCtr = 0;
919 aec->overDrive =
920 WEBRTC_SPL_MAX(kTargetSupp[aec->nlp_mode] /
921 ((float)log(aec->hNlFbMin + 1e-10f) + 1e-10f),
922 min_overdrive[aec->nlp_mode]);
926 if (aec->overDrive < aec->overDriveSm) {
927 aec->overDriveSm = 0.99f * aec->overDriveSm + 0.01f * aec->overDrive;
929 aec->overDriveSm = 0.9f * aec->overDriveSm + 0.1f * aec->overDrive;
932 WebRtcAec_OverdriveAndSuppress(aec, hNl, hNlFb, efw);
935 WebRtcAec_ComfortNoise(aec, efw, comfortNoiseHband, aec->noisePow, hNl);
939 if (aec->metricsMode == 1) {
944 UpdateLevel(&aec->nlpoutlevel, efw);
960 fft[i] = fft[i] * WebRtcAec_sqrtHanning[i] + aec->outBuf[i];
963 aec->outBuf[i] = fft[PART_LEN + i] * WebRtcAec_sqrtHanning[PART_LEN - i];
971 if (aec->sampFreq == 32000) {
992 dtmp = aec->dBufH[i];
1008 memcpy(aec->dBuf, aec->dBuf + PART_LEN, sizeof(float) * PART_LEN);
1009 memcpy(aec->eBuf, aec->eBuf + PART_LEN, sizeof(float) * PART_LEN);
1012 if (aec->sampFreq == 32000) {
1013 memcpy(aec->dBufH, aec->dBufH + PART_LEN, sizeof(float) * PART_LEN);
1016 memmove(aec->xfwBuf + PART_LEN1,
1017 aec->xfwBuf,
1018 sizeof(aec->xfwBuf) - sizeof(complex_t) * PART_LEN1);
1021 static void ProcessBlock(AecCore* aec) {
1037 const int noiseInitBlocks = 500 * aec->mult;
1050 if (aec->sampFreq == 32000) {
1051 WebRtc_ReadBuffer(aec->nearFrBufH, (void**)&nearend_ptr, nearend, PART_LEN);
1052 memcpy(aec->dBufH + PART_LEN, nearend_ptr, sizeof(nearend));
1054 WebRtc_ReadBuffer(aec->nearFrBuf, (void**)&nearend_ptr, nearend, PART_LEN);
1055 memcpy(aec->dBuf + PART_LEN, nearend_ptr, sizeof(nearend));
1063 WebRtc_ReadBuffer(aec->far_time_buf, (void**)&farend_ptr, farend, 1);
1064 rtc_WavWriteSamples(aec->farFile, farend_ptr, PART_LEN);
1065 rtc_WavWriteSamples(aec->nearFile, nearend_ptr, PART_LEN);
1070 assert(WebRtc_available_read(aec->far_buf) > 0);
1071 WebRtc_ReadBuffer(aec->far_buf, (void**)&xf_ptr, &xf[0][0], 1);
1074 memcpy(fft, aec->dBuf, sizeof(float) * PART_LEN2);
1081 aec->xPow[i] =
1082 gPow[0] * aec->xPow[i] + gPow[1] * aec->num_partitions * far_spectrum;
1087 aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum;
1093 if (aec->noiseEstCtr > 50) {
1095 if (aec->dPow[i] < aec->dMinPow[i]) {
1096 aec->dMinPow[i] =
1097 (aec->dPow[i] + step * (aec->dMinPow[i] - aec->dPow[i])) * ramp;
1099 aec->dMinPow[i] *= ramp;
1106 if (aec->noiseEstCtr < noiseInitBlocks) {
1107 aec->noiseEstCtr++;
1109 if (aec->dMinPow[i] > aec->dInitMinPow[i]) {
1110 aec->dInitMinPow[i] = gInitNoise[0] * aec->dInitMinPow[i] +
1111 gInitNoise[1] * aec->dMinPow[i];
1113 aec->dInitMinPow[i] = aec->dMinPow[i];
1116 aec->noisePow = aec->dInitMinPow;
1118 aec->noisePow = aec->dMinPow;
1122 if (aec->delay_logging_enabled) {
1125 aec->delay_estimator_farend, abs_far_spectrum, PART_LEN1) == 0) {
1127 aec->delay_estimator, abs_near_spectrum, PART_LEN1);
1130 aec->delay_histogram[delay_estimate]++;
1136 aec->xfBufBlockPos--;
1137 if (aec->xfBufBlockPos == -1) {
1138 aec->xfBufBlockPos = aec->num_partitions - 1;
1142 memcpy(aec->xfBuf[0] + aec->xfBufBlockPos * PART_LEN1,
1145 memcpy(aec->xfBuf[1] + aec->xfBufBlockPos * PART_LEN1,
1152 WebRtcAec_FilterFar(aec, yf);
1173 memcpy(aec->eBuf + PART_LEN, e, sizeof(float) * PART_LEN);
1188 if (aec->metricsMode == 1) {
1192 UpdateLevel(&aec->linoutlevel, ef);
1196 WebRtcAec_ScaleErrorSignal(aec, ef);
1197 WebRtcAec_FilterAdaptation(aec, fft, ef);
1198 NonLinearProcessing(aec, output, outputH);
1200 if (aec->metricsMode == 1) {
1202 UpdateLevel(&aec->farlevel, (float(*)[PART_LEN1])xf_ptr);
1203 UpdateLevel(&aec->nearlevel, df);
1204 UpdateMetrics(aec);
1208 WebRtc_WriteBuffer(aec->outFrBuf, output, PART_LEN);
1210 if (aec->sampFreq == 32000) {
1211 WebRtc_WriteBuffer(aec->outFrBufH, outputH, PART_LEN);
1215 rtc_WavWriteSamples(aec->outLinearFile, e, PART_LEN);
1216 rtc_WavWriteSamples(aec->outFile, output, PART_LEN);
1221 AecCore* aec = malloc(sizeof(AecCore));
1222 *aecInst = aec;
1223 if (aec == NULL) {
1227 aec->nearFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1228 if (!aec->nearFrBuf) {
1229 WebRtcAec_FreeAec(aec);
1230 aec = NULL;
1234 aec->outFrBuf = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1235 if (!aec->outFrBuf) {
1236 WebRtcAec_FreeAec(aec);
1237 aec = NULL;
1241 aec->nearFrBufH = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1242 if (!aec->nearFrBufH) {
1243 WebRtcAec_FreeAec(aec);
1244 aec = NULL;
1248 aec->outFrBufH = WebRtc_CreateBuffer(FRAME_LEN + PART_LEN, sizeof(float));
1249 if (!aec->outFrBufH) {
1250 WebRtcAec_FreeAec(aec);
1251 aec = NULL;
1256 aec->far_buf =
1258 if (!aec->far_buf) {
1259 WebRtcAec_FreeAec(aec);
1260 aec = NULL;
1263 aec->far_buf_windowed =
1265 if (!aec->far_buf_windowed) {
1266 WebRtcAec_FreeAec(aec);
1267 aec = NULL;
1271 aec->instance_index = webrtc_aec_instance_count;
1272 aec->far_time_buf =
1274 if (!aec->far_time_buf) {
1275 WebRtcAec_FreeAec(aec);
1276 aec = NULL;
1279 aec->farFile = aec->nearFile = aec->outFile = aec->outLinearFile = NULL;
1280 aec->debug_dump_count = 0;
1282 aec->delay_estimator_farend =
1284 if (aec->delay_estimator_farend == NULL) {
1285 WebRtcAec_FreeAec(aec);
1286 aec = NULL;
1289 aec->delay_estimator = WebRtc_CreateDelayEstimator(
1290 aec->delay_estimator_farend, kLookaheadBlocks);
1291 if (aec->delay_estimator == NULL) {
1292 WebRtcAec_FreeAec(aec);
1293 aec = NULL;
1324 int WebRtcAec_FreeAec(AecCore* aec) {
1325 if (aec == NULL) {
1329 WebRtc_FreeBuffer(aec->nearFrBuf);
1330 WebRtc_FreeBuffer(aec->outFrBuf);
1332 WebRtc_FreeBuffer(aec->nearFrBufH);
1333 WebRtc_FreeBuffer(aec->outFrBufH);
1335 WebRtc_FreeBuffer(aec->far_buf);
1336 WebRtc_FreeBuffer(aec->far_buf_windowed);
1338 WebRtc_FreeBuffer(aec->far_time_buf);
1339 rtc_WavClose(aec->farFile);
1340 rtc_WavClose(aec->nearFile);
1341 rtc_WavClose(aec->outFile);
1342 rtc_WavClose(aec->outLinearFile);
1344 WebRtc_FreeDelayEstimator(aec->delay_estimator);
1345 WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend);
1347 free(aec);
1374 int WebRtcAec_InitAec(AecCore* aec, int sampFreq) {
1377 aec->sampFreq = sampFreq;
1380 aec->normal_mu = 0.6f;
1381 aec->normal_error_threshold = 2e-6f;
1383 aec->normal_mu = 0.5f;
1384 aec->normal_error_threshold = 1.5e-6f;
1387 if (WebRtc_InitBuffer(aec->nearFrBuf) == -1) {
1391 if (WebRtc_InitBuffer(aec->outFrBuf) == -1) {
1395 if (WebRtc_InitBuffer(aec->nearFrBufH) == -1) {
1399 if (WebRtc_InitBuffer(aec->outFrBufH) == -1) {
1404 if (WebRtc_InitBuffer(aec->far_buf) == -1) {
1407 if (WebRtc_InitBuffer(aec->far_buf_windowed) == -1) {
1411 if (WebRtc_InitBuffer(aec->far_time_buf) == -1) {
1416 ReopenWav(&aec->farFile, "aec_far",
1417 aec->instance_index, aec->debug_dump_count, process_rate);
1418 ReopenWav(&aec->nearFile, "aec_near",
1419 aec->instance_index, aec->debug_dump_count, process_rate);
1420 ReopenWav(&aec->outFile, "aec_out",
1421 aec->instance_index, aec->debug_dump_count, process_rate);
1422 ReopenWav(&aec->outLinearFile, "aec_out_linear",
1423 aec->instance_index, aec->debug_dump_count, process_rate);
1425 ++aec->debug_dump_count;
1427 aec->system_delay = 0;
1429 if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) {
1432 if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) {
1435 aec->delay_logging_enabled = 0;
1436 memset(aec->delay_histogram, 0, sizeof(aec->delay_histogram));
1438 aec->reported_delay_enabled = 1;
1439 aec->extended_filter_enabled = 0;
1440 aec->num_partitions = kNormalNumPartitions;
1446 WebRtc_set_allowed_offset(aec->delay_estimator, aec->num_partitions / 2);
1451 WebRtc_enable_robust_validation(aec->delay_estimator, 1);
1454 aec->nlp_mode = 1;
1458 if (aec->sampFreq == 32000) {
1459 aec->mult = (short)aec->sampFreq / 16000;
1461 aec->mult = (short)aec->sampFreq / 8000;
1464 aec->farBufWritePos = 0;
1465 aec->farBufReadPos = 0;
1467 aec->inSamples = 0;
1468 aec->outSamples = 0;
1469 aec->knownDelay = 0;
1472 memset(aec->dBuf, 0, sizeof(aec->dBuf));
1473 memset(aec->eBuf, 0, sizeof(aec->eBuf));
1475 memset(aec->dBufH, 0, sizeof(aec->dBufH));
1477 memset(aec->xPow, 0, sizeof(aec->xPow));
1478 memset(aec->dPow, 0, sizeof(aec->dPow));
1479 memset(aec->dInitMinPow, 0, sizeof(aec->dInitMinPow));
1480 aec->noisePow = aec->dInitMinPow;
1481 aec->noiseEstCtr = 0;
1485 aec->dMinPow[i] = 1.0e6f;
1489 aec->xfBufBlockPos = 0;
1492 memset(aec->xfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
1493 memset(aec->wfBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
1494 memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1);
1495 memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1);
1497 aec->xfwBuf, 0, sizeof(complex_t) * kExtendedNumPartitions * PART_LEN1);
1498 memset(aec->se, 0, sizeof(float) * PART_LEN1);
1502 aec->sd[i] = 1;
1505 aec->sx[i] = 1;
1508 memset(aec->hNs, 0, sizeof(aec->hNs));
1509 memset(aec->outBuf, 0, sizeof(float) * PART_LEN);
1511 aec->hNlFbMin = 1;
1512 aec->hNlFbLocalMin = 1;
1513 aec->hNlXdAvgMin = 1;
1514 aec->hNlNewMin = 0;
1515 aec->hNlMinCtr = 0;
1516 aec->overDrive = 2;
1517 aec->overDriveSm = 2;
1518 aec->delayIdx = 0;
1519 aec->stNearState = 0;
1520 aec->echoState = 0;
1521 aec->divergeState = 0;
1523 aec->seed = 777;
1524 aec->delayEstCtr = 0;
1527 aec->metricsMode = 0;
1528 InitMetrics(aec);
1533 void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) {
1538 if (WebRtc_available_write(aec->far_buf) < 1) {
1539 WebRtcAec_MoveFarReadPtr(aec, 1);
1544 WebRtc_WriteBuffer(aec->far_buf, &xf[0][0], 1);
1549 WebRtc_WriteBuffer(aec->far_buf_windowed, &xf[0][0], 1);
1552 int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) {
1553 aec->far_buf_windowed, elements);
1554 WebRtc_MoveReadPtr(aec->far_buf, elements);
1556 WebRtc_MoveReadPtr(aec->far_time_buf, elements);
1558 aec->system_delay -= elements_moved * PART_LEN;
1562 void WebRtcAec_ProcessFrame(AecCore* aec,
1586 // than |aec->knownDelay|. We therefore, round (-32) in that direction. In
1590 int move_elements = (aec->knownDelay - knownDelay - 32) / PART_LEN;
1596 WebRtc_WriteBuffer(aec->nearFrBuf, nearend, FRAME_LEN);
1598 if (aec->sampFreq == 32000) {
1599 WebRtc_WriteBuffer(aec->nearFrBufH, nearendH, FRAME_LEN);
1602 // 1) At most we process |aec->mult|+1 partitions in 10 ms. Make sure we
1605 if (aec->system_delay < FRAME_LEN) {
1607 WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1));
1611 WebRtc_MoveReadPtr(aec->far_buf_windowed, move_elements);
1612 moved_elements = WebRtc_MoveReadPtr(aec->far_buf, move_elements);
1613 aec->knownDelay -= moved_elements * PART_LEN;
1615 WebRtc_MoveReadPtr(aec->far_time_buf, move_elements);
1619 while (WebRtc_available_read(aec->nearFrBuf) >= PART_LEN) {
1620 ProcessBlock(aec);
1624 aec->system_delay -= FRAME_LEN;
1629 out_elements = (int)WebRtc_available_read(aec->outFrBuf);
1631 WebRtc_MoveReadPtr(aec->outFrBuf, out_elements - FRAME_LEN);
1632 if (aec->sampFreq == 32000) {
1633 WebRtc_MoveReadPtr(aec->outFrBufH, out_elements - FRAME_LEN);
1637 WebRtc_ReadBuffer(aec->outFrBuf, NULL, out, FRAME_LEN);
1639 if (aec->sampFreq == 32000) {
1640 WebRtc_ReadBuffer(aec->outFrBufH, NULL, outH, FRAME_LEN);