RingBuffer* WebRtc_CreateBuffer(size_t element_count, size_t element_size) { RingBuffer* self = NULL; if (element_count == 0 || element_size == 0) { return NULL; } self = malloc(sizeof(RingBuffer)); if (!self) { return NULL; } self->data = malloc(element_count * element_size); if (!self->data) { free(self); self = NULL; return NULL; } self->element_count = element_count; self->element_size = element_size; WebRtc_InitBuffer(self); return self; }
int WebRtcAec_InitAec(aec_t *aec, int sampFreq) { int i; aec->sampFreq = sampFreq; if (sampFreq == 8000) { aec->mu = 0.6f; aec->errThresh = 2e-6f; } else { aec->mu = 0.5f; aec->errThresh = 1.5e-6f; } if (WebRtc_InitBuffer(aec->nearFrBuf) == -1) { return -1; } if (WebRtc_InitBuffer(aec->outFrBuf) == -1) { return -1; } if (WebRtc_InitBuffer(aec->nearFrBufH) == -1) { return -1; } if (WebRtc_InitBuffer(aec->outFrBufH) == -1) { return -1; } // Initialize far-end buffers. if (WebRtc_InitBuffer(aec->far_buf) == -1) { return -1; } if (WebRtc_InitBuffer(aec->far_buf_windowed) == -1) { return -1; } #ifdef WEBRTC_AEC_DEBUG_DUMP if (WebRtc_InitBuffer(aec->far_time_buf) == -1) { return -1; } #endif aec->system_delay = 0; if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) { return -1; } aec->delay_logging_enabled = 0; memset(aec->delay_histogram, 0, sizeof(aec->delay_histogram)); // Default target suppression level aec->targetSupp = -11.5; aec->minOverDrive = 2.0; // Sampling frequency multiplier // SWB is processed as 160 frame size if (aec->sampFreq == 32000) { aec->mult = (short)aec->sampFreq / 16000; } else { aec->mult = (short)aec->sampFreq / 8000; } aec->farBufWritePos = 0; aec->farBufReadPos = 0; aec->inSamples = 0; aec->outSamples = 0; aec->knownDelay = 0; // Initialize buffers memset(aec->dBuf, 0, sizeof(aec->dBuf)); memset(aec->eBuf, 0, sizeof(aec->eBuf)); // For H band memset(aec->dBufH, 0, sizeof(aec->dBufH)); memset(aec->xPow, 0, sizeof(aec->xPow)); memset(aec->dPow, 0, sizeof(aec->dPow)); memset(aec->dInitMinPow, 0, sizeof(aec->dInitMinPow)); aec->noisePow = aec->dInitMinPow; aec->noiseEstCtr = 0; // Initial comfort noise power for (i = 0; i < PART_LEN1; i++) { aec->dMinPow[i] = 1.0e6f; } // Holds the last block written to aec->xfBufBlockPos = 0; // TODO: Investigate need for these initializations. Deleting them doesn't // change the output at all and yields 0.4% overall speedup. memset(aec->xfBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1); memset(aec->wfBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1); memset(aec->sde, 0, sizeof(complex_t) * PART_LEN1); memset(aec->sxd, 0, sizeof(complex_t) * PART_LEN1); memset(aec->xfwBuf, 0, sizeof(complex_t) * NR_PART * PART_LEN1); memset(aec->se, 0, sizeof(float) * PART_LEN1); // To prevent numerical instability in the first block. for (i = 0; i < PART_LEN1; i++) { aec->sd[i] = 1; } for (i = 0; i < PART_LEN1; i++) { aec->sx[i] = 1; } memset(aec->hNs, 0, sizeof(aec->hNs)); memset(aec->outBuf, 0, sizeof(float) * PART_LEN); aec->hNlFbMin = 1; aec->hNlFbLocalMin = 1; aec->hNlXdAvgMin = 1; aec->hNlNewMin = 0; aec->hNlMinCtr = 0; aec->overDrive = 2; aec->overDriveSm = 2; aec->delayIdx = 0; aec->stNearState = 0; aec->echoState = 0; aec->divergeState = 0; aec->seed = 777; aec->delayEstCtr = 0; // Metrics disabled by default aec->metricsMode = 0; WebRtcAec_InitMetrics(aec); // Assembly optimization WebRtcAec_FilterFar = FilterFar; WebRtcAec_ScaleErrorSignal = ScaleErrorSignal; WebRtcAec_FilterAdaptation = FilterAdaptation; WebRtcAec_OverdriveAndSuppress = OverdriveAndSuppress; #if defined(WEBRTC_ARCH_X86_FAMILY) if (WebRtc_GetCPUInfo(kSSE2)) { WebRtcAec_InitAec_SSE2(); } #endif aec_rdft_init(); return 0; }
int32_t WebRtcAec_Init(void *aecInst, int32_t sampFreq, int32_t scSampFreq) { aecpc_t *aecpc = aecInst; AecConfig aecConfig; if (aecpc == NULL) { return -1; } if (sampFreq != 8000 && sampFreq != 16000 && sampFreq != 32000) { aecpc->lastError = AEC_BAD_PARAMETER_ERROR; return -1; } aecpc->sampFreq = sampFreq; if (scSampFreq < 1 || scSampFreq > 96000) { aecpc->lastError = AEC_BAD_PARAMETER_ERROR; return -1; } aecpc->scSampFreq = scSampFreq; // Initialize echo canceller core if (WebRtcAec_InitAec(aecpc->aec, aecpc->sampFreq) == -1) { aecpc->lastError = AEC_UNSPECIFIED_ERROR; return -1; } if (WebRtcAec_InitResampler(aecpc->resampler, aecpc->scSampFreq) == -1) { aecpc->lastError = AEC_UNSPECIFIED_ERROR; return -1; } if (WebRtc_InitBuffer(aecpc->far_pre_buf) == -1) { aecpc->lastError = AEC_UNSPECIFIED_ERROR; return -1; } WebRtc_MoveReadPtr(aecpc->far_pre_buf, -PART_LEN); // Start overlap. aecpc->initFlag = initCheck; // indicates that initialization has been done if (aecpc->sampFreq == 32000) { aecpc->splitSampFreq = 16000; } else { aecpc->splitSampFreq = sampFreq; } aecpc->skewFrCtr = 0; aecpc->activity = 0; aecpc->delayCtr = 0; aecpc->sum = 0; aecpc->counter = 0; aecpc->checkBuffSize = 1; aecpc->firstVal = 0; aecpc->ECstartup = 1; aecpc->bufSizeStart = 0; aecpc->checkBufSizeCtr = 0; aecpc->filtDelay = 0; aecpc->timeForDelayChange = 0; aecpc->knownDelay = 0; aecpc->lastDelayDiff = 0; aecpc->skew = 0; aecpc->resample = kAecFalse; aecpc->highSkewCtr = 0; aecpc->sampFactor = (aecpc->scSampFreq * 1.0f) / aecpc->splitSampFreq; // Sampling frequency multiplier (SWB is processed as 160 frame size). aecpc->rate_factor = aecpc->splitSampFreq / 8000; // Default settings. aecConfig.nlpMode = kAecNlpModerate; aecConfig.skewMode = kAecFalse; aecConfig.metricsMode = kAecFalse; aecConfig.delay_logging = kAecFalse; if (WebRtcAec_set_config(aecpc, aecConfig) == -1) { aecpc->lastError = AEC_UNSPECIFIED_ERROR; return -1; } #ifdef WEBRTC_AEC_DEBUG_DUMP if (WebRtc_InitBuffer(aecpc->far_pre_buf_s16) == -1) { aecpc->lastError = AEC_UNSPECIFIED_ERROR; return -1; } WebRtc_MoveReadPtr(aecpc->far_pre_buf_s16, -PART_LEN); // Start overlap. #endif return 0; }
int32_t WebRtcAec_Init(void* aecInst, int32_t sampFreq, int32_t scSampFreq) { Aec* aecpc = aecInst; AecConfig aecConfig; if (sampFreq != 8000 && sampFreq != 16000 && sampFreq != 32000 && sampFreq != 48000) { return AEC_BAD_PARAMETER_ERROR; } aecpc->sampFreq = sampFreq; if (scSampFreq < 1 || scSampFreq > 96000) { return AEC_BAD_PARAMETER_ERROR; } aecpc->scSampFreq = scSampFreq; // Initialize echo canceller core if (WebRtcAec_InitAec(aecpc->aec, aecpc->sampFreq) == -1) { return AEC_UNSPECIFIED_ERROR; } if (WebRtcAec_InitResampler(aecpc->resampler, aecpc->scSampFreq) == -1) { return AEC_UNSPECIFIED_ERROR; } WebRtc_InitBuffer(aecpc->far_pre_buf); WebRtc_MoveReadPtr(aecpc->far_pre_buf, -PART_LEN); // Start overlap. aecpc->initFlag = initCheck; // indicates that initialization has been done if (aecpc->sampFreq == 32000 || aecpc->sampFreq == 48000) { aecpc->splitSampFreq = 16000; } else { aecpc->splitSampFreq = sampFreq; } aecpc->delayCtr = 0; aecpc->sampFactor = (aecpc->scSampFreq * 1.0f) / aecpc->splitSampFreq; // Sampling frequency multiplier (SWB is processed as 160 frame size). aecpc->rate_factor = aecpc->splitSampFreq / 8000; aecpc->sum = 0; aecpc->counter = 0; aecpc->checkBuffSize = 1; aecpc->firstVal = 0; // We skip the startup_phase completely (setting to 0) if DA-AEC is enabled, // but not extended_filter mode. aecpc->startup_phase = WebRtcAec_extended_filter_enabled(aecpc->aec) || !WebRtcAec_delay_agnostic_enabled(aecpc->aec); aecpc->bufSizeStart = 0; aecpc->checkBufSizeCtr = 0; aecpc->msInSndCardBuf = 0; aecpc->filtDelay = -1; // -1 indicates an initialized state. aecpc->timeForDelayChange = 0; aecpc->knownDelay = 0; aecpc->lastDelayDiff = 0; aecpc->skewFrCtr = 0; aecpc->resample = kAecFalse; aecpc->highSkewCtr = 0; aecpc->skew = 0; aecpc->farend_started = 0; // Default settings. aecConfig.nlpMode = kAecNlpModerate; aecConfig.skewMode = kAecFalse; aecConfig.metricsMode = kAecFalse; aecConfig.delay_logging = kAecFalse; if (WebRtcAec_set_config(aecpc, aecConfig) == -1) { return AEC_UNSPECIFIED_ERROR; } return 0; }