+ // keep track of noise spectrum for next frame
+ for (i = 0; i < inst->magnLen; i++) {
+ inst->noisePrev[i] = noise[i];
+ }
+ } // end of if inst->outLen == 0
+
+ return 0;
+}
+
+int WebRtcNs_ProcessCore(NSinst_t* inst,
+ float* speechFrame,
+ float* speechFrameHB,
+ float* outFrame,
+ float* outFrameHB) {
+ // main routine for noise reduction
+ int flagHB = 0;
+ int i;
+
+ float energy1, energy2, gain, factor, factor1, factor2;
+ float snrPrior, currentEstimateStsa;
+ float tmpFloat1, tmpFloat2;
+ float fTmp;
+ float fout[BLOCKL_MAX];
+ float winData[ANAL_BLOCKL_MAX];
+ float magn[HALF_ANAL_BLOCKL];
+ float theFilter[HALF_ANAL_BLOCKL], theFilterTmp[HALF_ANAL_BLOCKL];
+ float real[ANAL_BLOCKL_MAX], imag[HALF_ANAL_BLOCKL];
+
+ // SWB variables
+ int deltaBweHB = 1;
+ int deltaGainHB = 1;
+ float decayBweHB = 1.0;
+ float gainMapParHB = 1.0;
+ float gainTimeDomainHB = 1.0;
+ float avgProbSpeechHB, avgProbSpeechHBTmp, avgFilterGainHB, gainModHB;
+
+ // Check that initiation has been done
+ if (inst->initFlag != 1) {
+ return (-1);
+ }
+ // Check for valid pointers based on sampling rate
+ if (inst->fs == 32000) {
+ if (speechFrameHB == NULL) {
+ return -1;
+ }
+ flagHB = 1;
+ // range for averaging low band quantities for H band gain
+ deltaBweHB = (int)inst->magnLen / 4;
+ deltaGainHB = deltaBweHB;
+ }
+
+ // update analysis buffer for L band
+ memcpy(inst->dataBuf,
+ inst->dataBuf + inst->blockLen10ms,
+ sizeof(float) * (inst->anaLen - inst->blockLen10ms));
+ memcpy(inst->dataBuf + inst->anaLen - inst->blockLen10ms,
+ speechFrame,
+ sizeof(float) * inst->blockLen10ms);
+
+ if (flagHB == 1) {
+ // update analysis buffer for H band
+ memcpy(inst->dataBufHB,
+ inst->dataBufHB + inst->blockLen10ms,
+ sizeof(float) * (inst->anaLen - inst->blockLen10ms));
+ memcpy(inst->dataBufHB + inst->anaLen - inst->blockLen10ms,
+ speechFrameHB,
+ sizeof(float) * inst->blockLen10ms);
+ }
+
+ // check if processing needed
+ if (inst->outLen == 0) {
+ // windowing
+ energy1 = 0.0;
+ for (i = 0; i < inst->anaLen; i++) {
+ winData[i] = inst->window[i] * inst->dataBuf[i];
+ energy1 += winData[i] * winData[i];
+ }
+ if (energy1 == 0.0) {
+ // synthesize the special case of zero input
+ // read out fully processed segment
+ for (i = inst->windShift; i < inst->blockLen + inst->windShift; i++) {
+ fout[i - inst->windShift] = inst->syntBuf[i];
+ }
+ // update synthesis buffer
+ memcpy(inst->syntBuf,
+ inst->syntBuf + inst->blockLen,
+ sizeof(float) * (inst->anaLen - inst->blockLen));
+ memset(inst->syntBuf + inst->anaLen - inst->blockLen,
+ 0,
+ sizeof(float) * inst->blockLen);
+
+ // out buffer
+ inst->outLen = inst->blockLen - inst->blockLen10ms;
+ if (inst->blockLen > inst->blockLen10ms) {
+ for (i = 0; i < inst->outLen; i++) {
+ inst->outBuf[i] = fout[i + inst->blockLen10ms];
+ }
+ }
+ for (i = 0; i < inst->blockLen10ms; ++i)
+ outFrame[i] = WEBRTC_SPL_SAT(
+ WEBRTC_SPL_WORD16_MAX, fout[i], WEBRTC_SPL_WORD16_MIN);
+
+ // for time-domain gain of HB
+ if (flagHB == 1)
+ for (i = 0; i < inst->blockLen10ms; ++i)
+ outFrameHB[i] = WEBRTC_SPL_SAT(
+ WEBRTC_SPL_WORD16_MAX, inst->dataBufHB[i], WEBRTC_SPL_WORD16_MIN);
+
+ return 0;
+ }
+
+ // FFT
+ WebRtc_rdft(inst->anaLen, 1, winData, inst->ip, inst->wfft);
+
+ imag[0] = 0;
+ real[0] = winData[0];
+ magn[0] = (float)(fabs(real[0]) + 1.0f);
+ imag[inst->magnLen - 1] = 0;
+ real[inst->magnLen - 1] = winData[1];
+ magn[inst->magnLen - 1] = (float)(fabs(real[inst->magnLen - 1]) + 1.0f);
+ if (inst->blockInd < END_STARTUP_SHORT) {
+ inst->initMagnEst[0] += magn[0];
+ inst->initMagnEst[inst->magnLen - 1] += magn[inst->magnLen - 1];
+ }
+ for (i = 1; i < inst->magnLen - 1; i++) {
+ real[i] = winData[2 * i];
+ imag[i] = winData[2 * i + 1];
+ // magnitude spectrum
+ fTmp = real[i] * real[i];
+ fTmp += imag[i] * imag[i];
+ magn[i] = ((float)sqrt(fTmp)) + 1.0f;
+ if (inst->blockInd < END_STARTUP_SHORT) {
+ inst->initMagnEst[i] += magn[i];
+ }
+ }
+
+ // Compute dd update of prior snr and post snr based on new noise estimate