⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ec_sb_int.c

📁 C__ code For Audio Coding
💻 C
📖 第 1 页 / 共 2 页
字号:
    for (i = 0; i < state->frameSize; i++) {
        r_in_pwr += r_in[i] * r_in[i];
        s_in_pwr += s_in[i] * s_in[i];
    }

    ADDWEIGHTED_INT(state->r_in_pwr, r_in_pwr, state->td_coeff);
    ADDWEIGHTED_INT(state->s_in_pwr, s_in_pwr, state->td_coeff);

    if (state->td_ress || state->td_resr) {
       if ((!state->td_resr || state->r_in_pwr < state->td_thres) &&
            (!state->td_ress || state->s_in_pwr < state->td_thres))
        {
            /* Restore previous mode */
            state->td_resr = state->td_ress = 0;
            if (state->td_mode & 1)
                ec_isb_ModeOp(state, EC_ADAPTATION_ENABLE);
            if (state->td_mode & 2)
                ec_isb_ModeOp(state, EC_NLP_ENABLE);
        }
    } else if (resr || ress) {
        /* Zero coeffs, disable adaptation and NLP */
        if (resr) state->td_resr = 1;
        if (ress) state->td_ress = 1;

        state->td_mode = state->mode;
        ec_isb_ModeOp(state, EC_COEFFS_ZERO);
        ec_isb_ModeOp(state, EC_ADAPTATION_DISABLE);
        ec_isb_ModeOp(state, EC_NLP_DISABLE);
    }

    return 0;
}
static void isb_ownConstrainCoeff(_isbECState *state, int subbandNum){
   int k,s;
   LOCAL_ALIGN_ARRAY(32,Ipp32s,bsrc,SB_SUBBANDS * 4,state);
   LOCAL_ALIGN_ARRAY(32,Ipp32s,bsrc1,SB_SUBBANDS * 4,state);
   LOCAL_ALIGN_ARRAY(32,Ipp32s,bdst,SB_FFT_LEN,state);

   ippsFFTInv_CCSToR_32s_Sfs((Ipp32s *)(state->ppAdaptiveCoefs[subbandNum]), bdst, state->spec_fft32, 0, state->pBuf);

   ippsZero_32s(bsrc1,SB_SUBBANDS * 4);
   for (k = 0; k < SB_FRAME_SIZE; k++) {
      bsrc1[2 * k] = SB_FFT_LEN * bdst[k];
   }

   ippsFFTFwd_CToC_32sc_Sfs((const Ipp32sc *)bsrc1, (Ipp32sc *)bsrc, state->spec_fftC, 0, state->pBuf);

   for (s = 0; s < SB_SUBBANDS; s++) {
      state->ppAdaptiveCoefs[subbandNum][s].re = bsrc[2 * s];
      state->ppAdaptiveCoefs[subbandNum][s].im = bsrc[2 * s + 1];
   }
   LOCAL_ALIGN_ARRAY_FREE(32,Ipp32s,bdst,SB_FFT_LEN,state);
   LOCAL_ALIGN_ARRAY_FREE(32,Ipp32s,bsrc1,SB_SUBBANDS * 4,state);
   LOCAL_ALIGN_ARRAY_FREE(32,Ipp32s,bsrc,SB_SUBBANDS * 4,state);

}
#define COEF_SF 14
#define COEF_ONE (1 << COEF_SF)
#define COEF_0_5 (COEF_ONE / 2)
#define COEF_0_2 (COEF_ONE / 5)
#define COEF_0_77 (COEF_ONE * 10 / 13)
#define COEF_0_35 (COEF_ONE * 7 / 20)
#define COEF_0_48 (COEF_ONE * 12 / 25)
#define COEF_0_66 (COEF_ONE * 2 / 3)
#define COEF_0_8 (COEF_ONE * 4 / 5)
#define COEF_Q15_ONE ((1 << 15) - 1)
#define THRESH_POW 100 /* 20dBm */
#define PSD_SF   10          /* scale factor for input PSD */
#define CMUL(x, v) SCALE((x) * (v), COEF_SF)
#define WEIGHTED_INT(val, add, coef) SCALE(((val) * (coef) + (COEF_ONE - coef) * (add)), COEF_SF)

typedef struct _SubbandControllerState_EC_16s {
    int numSubbands;
    int frameSize;
    int numSegments;
    int sampleFreq;
    Ipp32s *adaptive_pwr;
    Ipp32s *fixed_pwr;
    Ipp32s *rin_pwr;
    Ipp32s *rin_pwr_n;
    Ipp32s *cf_pwr;
    Ipp32s muQ31;
    Ipp32s sin_pwr;
    Ipp32s coef_werr;
    Ipp32s coef_wcoef;
    Ipp32s coef_nlp0, coef_nlp1;
    Ipp32s sgain, rgain, nlp_val;
    Ipp32s rin_pwr_min;
    Ipp32s_EC_Sfs stepSize_max;
    int nlp_count;
    int sub_use;
} SubbandControllerState_EC_16s;

__INLINE int Cnvrt_64s32s(__INT64 z) {
    if(IPP_MAX_32S < z) return IPP_MAX_32S;
    else if(IPP_MIN_32S > z) return IPP_MIN_32S;
    return (int)z;
}
__INLINE int Add_32s(int x, int y) {
    return Cnvrt_64s32s((__INT64)x + y);
}
__INLINE int Cnvrt_32s16s_NR_Sfs15(int x)
{
    int z = Add_32s(x,0x8000);
    return (z >> 16);
}
__INLINE short Cnvrt_32s16s(int x){
    if (IPP_MAX_16S < x) return IPP_MAX_16S;
    else if (IPP_MIN_16S > x) return IPP_MIN_16S;
    return (short)(x);
}
static void ownSubbandController_EC_16s(const Ipp32sc *pSrcAdaptiveFilterErr,
       const Ipp32sc *pSrcFixedFilterErr,
       Ipp32sc **ppDstAdaptiveCoefs, Ipp32sc **ppDstFixedCoefs,
       Ipp16s *pDstSGain, SubbandControllerState_EC_16s *pState,int *convergedNum)
{
    int i,j;
    Ipp32s powa = 0, powc = 0, powd = 0, uval;
    Ipp32s *cf_pwr, *fixed_pwr, *adaptive_pwr;
    Ipp32s coef_wcoef, coef_werr;

    //IPP_BAD_PTR4_RET(pSrcAdaptiveFilterErr, pSrcFixedFilterErr, ppDstAdaptiveCoefs,
    //    ppDstFixedCoefs);
    //IPP_BAD_PTR2_RET(pDstSGain, pState);

    pState = IPP_ALIGNED_PTR(pState, 16);
    cf_pwr = pState->cf_pwr;
    fixed_pwr = pState->fixed_pwr;
    adaptive_pwr = pState->adaptive_pwr;
    coef_wcoef = pState->coef_wcoef;
    coef_werr = pState->coef_werr;
    (*convergedNum)=0;

    for (i = 0; i < pState->numSubbands; i++) {
        Ipp64s fpwr64, apwr64, cpwr64, cdlt64;
        fpwr64 = SCALE(pSrcFixedFilterErr[i].re * (Ipp64s)pSrcFixedFilterErr[i].re +
            pSrcFixedFilterErr[i].im * (Ipp64s)pSrcFixedFilterErr[i].im, PSD_SF);
        apwr64 = SCALE(pSrcAdaptiveFilterErr[i].re * (Ipp64s)pSrcAdaptiveFilterErr[i].re +
            pSrcAdaptiveFilterErr[i].im * (Ipp64s)pSrcAdaptiveFilterErr[i].im, PSD_SF);
//#if _IPPXSC >= _IPPXSC_S2
//        ownSumSquareColMtrx_NR_32sc64s_Sfs_S2(ppDstAdaptiveCoefs,
//            pState->numSegments, i, &cpwr64);
//        cpwr64 = SCALE(cpwr64, PSD_SF);
//#else
        cpwr64 = 0;
        for (j = 0; j < pState->numSegments; j++)
            cpwr64 += SCALE(ppDstAdaptiveCoefs[j][i].re * (Ipp64s)ppDstAdaptiveCoefs[j][i].re +
            ppDstAdaptiveCoefs[j][i].im * (Ipp64s)ppDstAdaptiveCoefs[j][i].im,PSD_SF);
//#endif
        cdlt64 = (cf_pwr[i] < cpwr64)? cpwr64 - cf_pwr[i] : cf_pwr[i] - cpwr64;

        cf_pwr[i] = Cnvrt_64s32s(WEIGHTED_INT(cf_pwr[i], cpwr64, (Ipp64s)coef_wcoef));
        fixed_pwr[i] = Cnvrt_64s32s(WEIGHTED_INT(fixed_pwr[i], fpwr64, (Ipp64s)coef_werr));
        adaptive_pwr[i] = Cnvrt_64s32s(WEIGHTED_INT(adaptive_pwr[i], apwr64, (Ipp64s)coef_werr));

        if (cf_pwr[i] > cdlt64 * 10 &&
            CMUL((Ipp64s)COEF_0_35, fixed_pwr[i]) > adaptive_pwr[i]) {
//#if _IPPXSC >= _IPPXSC_S2
//                ownCopyColMtrx32sc_S2(ppDstAdaptiveCoefs, ppDstFixedCoefs, pState->numSegments, i);
//#else
                for (j = 0; j < pState->numSegments; j++) {
                    ppDstFixedCoefs[j][i] = ppDstAdaptiveCoefs[j][i];
                }
                (*convergedNum)++;
//#endif
                fixed_pwr[i] = adaptive_pwr[i];
                powc = Add_32s(powc, fixed_pwr[i]);
            } else if (fixed_pwr[i] < CMUL((Ipp64s)COEF_0_66, adaptive_pwr[i])) {
//#if _IPPXSC >= _IPPXSC_S2
//                ownCopyColMtrx32sc_S2(ppDstFixedCoefs, ppDstAdaptiveCoefs, pState->numSegments, i);
//#else
                for (j = 0; j < pState->numSegments; j++) {
                    ppDstAdaptiveCoefs[j][i] = ppDstFixedCoefs[j][i];
                }
//#endif
                adaptive_pwr[i] = fixed_pwr[i];
                powd = Add_32s(powd, fixed_pwr[i]);
            }
            powa = Add_32s(powa, fixed_pwr[i]);
    }


    if (pState->sub_use) {
        if ((Ipp64s)10 * powc > powa && pState->sin_pwr > (Ipp64s)5 * powa) {
            pState->nlp_val = Cnvrt_64s32s(WEIGHTED_INT(pState->nlp_val, 0, pState->coef_nlp0));
        } else if ((Ipp64s)10 * powd >= powa) {
            pState->nlp_val = Cnvrt_64s32s(WEIGHTED_INT(pState->nlp_val, COEF_ONE, pState->coef_nlp0));
        }
    } else {
        if ((Ipp64s)10 * powc > powa) {
            pState->nlp_val = Cnvrt_64s32s(WEIGHTED_INT(pState->nlp_val, 0, pState->coef_nlp0));
        } else if ((Ipp64s)10 * powd >= powa) {
            pState->nlp_val = Cnvrt_64s32s(WEIGHTED_INT(pState->nlp_val, COEF_ONE, pState->coef_nlp0));
        }
    }

    if (pState->nlp_val >= COEF_0_5 || (powd < THRESH_POW && powc < THRESH_POW ) ) {
        uval = COEF_Q15_ONE;
    } else {
        uval = 0;
    }
    pState->sgain = Cnvrt_64s32s(WEIGHTED_INT(pState->sgain, uval, pState->coef_nlp1));

    *pDstSGain = Cnvrt_32s16s(pState->sgain);

    return ;
}
/* Process one frame */
int ec_isb_ProcessFrame(_isbECState *state, Ipp16s *rin, Ipp16s *sin, Ipp16s *sout)
{
    int i;
    int numSegments = state->numSegments;
    LOCAL_ALIGN_ARRAY(32,Ipp32sc,fira_err,SB_SUBBANDS,state);
    LOCAL_ALIGN_ARRAY(32,Ipp32sc,firf_err,SB_SUBBANDS,state);
    LOCAL_ALIGN_ARRAY(32,Ipp32sc,fira_out,SB_SUBBANDS,state);
    LOCAL_ALIGN_ARRAY(32,Ipp32sc,firf_out,SB_SUBBANDS,state);
    LOCAL_ALIGN_ARRAY(32,Ipp32s_EC_Sfs,pStepSize,SB_SUBBANDS*2,state);
    LOCAL_ALIGN_ARRAY(32,Ipp16s,pTimeFiltOut,SB_FFT_LEN,state);
    LOCAL_ALIGN_ARRAY(32,Ipp16s,pTimeError,SB_FFT_LEN,state);
    Ipp32sc* pSegment; /* Pointer to segment of input history */
    int iSegment;
    Ipp16s *pRinHistory = state->pRinHistory;
    int windowLen = state->windowLen;
    int frameSize = state->frameSize;

    /* Tone Disabler */
    if (TD_ENABLED)
        ec_isb_ToneDisabler(state, rin, sin);

    /* update receive-in subband history buffer */
    pSegment = state->ppRinSubbandHistory[state->numSegments-1];
    for(iSegment = state->numSegments-1; iSegment > 0; iSegment--)
    {
      state->ppRinSubbandHistory[iSegment] = state->ppRinSubbandHistory[iSegment-1];
    }
    state->ppRinSubbandHistory[0] = pSegment;

    /* update receive-in history buffer */
    for (i = 0; i < windowLen - frameSize; i++)
        pRinHistory[i] = pRinHistory[i + frameSize];

    for (i = 0; i < frameSize; i++)
        pRinHistory[i + windowLen - frameSize] = rin[i];

    /* Apply FFT to receive-in signal */
    ippsFFTFwd_RToCCS_16s32s_Sfs(pRinHistory, (Ipp32s *)(state->ppRinSubbandHistory[0]), state->spec_fft, 0, state->pBuf);

    /* Do filtering with fixed coeffs */
    ippsFIRSubband_EC_32sc_Sfs(state->ppRinSubbandHistory, state->ppFixedCoefs, firf_out,
        numSegments, state->numSubbands, F_SF);

    /* Get fixed filter output in time domain: apply inverse FFT */
    ippsFFTInv_CCSToR_32s16s_Sfs((Ipp32s *)firf_out, pTimeFiltOut, state->spec_fft, 0, state->pBuf);

    /* First half of error is set to zero. */
    for (i = 0; i < SB_FRAME_SIZE; i++)
        pTimeError[i] = 0;

    /* Subtract microphone signal from fixed filter output. */
    for (i = 0; i < SB_FRAME_SIZE; i++) {
        pTimeError[SB_FRAME_SIZE + i] = SAT_32S_16S(sin[i] - pTimeFiltOut[SB_FRAME_SIZE + i]);
        sout[i] = pTimeError[SB_FRAME_SIZE + i];
    }

    if (ADAPTATION_ENABLED) // Adaptation Enabled
    {
        int numSegAdapt = numSegments;

        /* Get fixed filter error in frequency domain */
        ippsFFTFwd_RToCCS_16s32s_Sfs(pTimeError, (Ipp32s *)firf_err, state->spec_fft, 0, state->pBuf);

        /* Do filtering with adaptive coeffs */
        ippsFIRSubband_EC_32sc_Sfs(state->ppRinSubbandHistory, state->ppAdaptiveCoefs, fira_out,
            numSegments, state->numSubbands, F_SF);
        /* Get adaptive filter output in time domain */
        ippsFFTInv_CCSToR_32s16s_Sfs((Ipp32s *)fira_out, pTimeFiltOut, state->spec_fft, 0, state->pBuf);

        /* Subtract microphone signal from adaptive filter output. */
        for (i = 0; i < SB_FRAME_SIZE; i++) {
            pTimeError[SB_FRAME_SIZE + i] = SAT_32S_16S(sin[i] - pTimeFiltOut[SB_FRAME_SIZE + i]);
        }

        ippsFFTFwd_RToCCS_16s32s_Sfs(pTimeError, (Ipp32s *)fira_err, state->spec_fft, 0, state->pBuf);

        /* Update subband controller */
        ippsSubbandControllerUpdate_EC_16s(rin, sin, (const Ipp32sc **)(state->ppRinSubbandHistory),
            0, pStepSize, state->controller);

        /* Update adaptive coeffs */
        ippsFIRSubbandCoeffUpdate_EC_32sc_I(pStepSize, (const Ipp32sc **)(state->ppRinSubbandHistory), fira_err,
            state->ppAdaptiveCoefs, numSegments, state->numSubbands, F_SF);


        if(state->mode & 8){ /* lite */
            /* Constrain coeffs each 10th frame. */
           if(!(state->constrainSubbandNum)) {
               for (i = 0; i < numSegments; i++) {
                  isb_ownConstrainCoeff(state,i);
               }
           }
           state->constrainSubbandNum++;
           if(state->constrainSubbandNum >= 10) state->constrainSubbandNum=0;
        }else{
            /* Constrain coeffs. */
            for (i = 0; i < numSegments; i++) {
                  isb_ownConstrainCoeff(state,i);
            }
        }

        /* Apply subband controller */
         ownSubbandController_EC_16s(fira_err, firf_err, state->ppAdaptiveCoefs, state->ppFixedCoefs,
            &state->sgain,(SubbandControllerState_EC_16s*) state->controller,&state->convergedSBNum);
         //state->convergedSBNum+=convergedSBNum;
         //if(state->convergedSBNum==state->subbandsNum){
         //    i=0;
         //}
        /* Apply NLP coeff */
       if (NLP_ENABLED)
            for (i = 0; i < frameSize; i++)
                sout[i] = SCALE((Ipp32s)sout[i] * state->sgain, 15);
    }

    LOCAL_ALIGN_ARRAY_FREE(32,Ipp16s,pTimeError,SB_FFT_LEN,state);
    LOCAL_ALIGN_ARRAY_FREE(32,Ipp16s,pTimeFiltOut,SB_FFT_LEN,state);
    LOCAL_ALIGN_ARRAY_FREE(32,Ipp32s_EC_Sfs,pStepSize,SB_SUBBANDS*2,state);
    LOCAL_ALIGN_ARRAY_FREE(32,Ipp32sc,firf_out,SB_SUBBANDS,state);
    LOCAL_ALIGN_ARRAY_FREE(32,Ipp32sc,fira_out,SB_SUBBANDS,state);
    LOCAL_ALIGN_ARRAY_FREE(32,Ipp32sc,firf_err,SB_SUBBANDS,state);
    LOCAL_ALIGN_ARRAY_FREE(32,Ipp32sc,fira_err,SB_SUBBANDS,state);


    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -