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

📄 encamrwb.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (offsetWBE == 0)
       pPrm = pPrmvec;
    else
       pPrm = (Ipp16s*)dst;

    st = encoderObj;

    pSpeechNew = pSpeechOldvec + SPEECH_SIZE - FRAME_SIZE - UP_SAMPL_FILT_DELAY + offsetWBE;
    pSpeech = pSpeechOldvec + SPEECH_SIZE - FRAME_SIZE - SUBFRAME_SIZE;
    pWindow = pSpeechOldvec + SPEECH_SIZE - WINDOW_SIZE;

    pExc = pExcOldvec + PITCH_LAG_MAX + INTERPOL_LEN;
    pWgtSpch = pWgtSpchOldvec + (PITCH_LAG_MAX / OPL_DECIM);

    /* copy coder memory state into working space (internal memory for DSP) */

    ippsCopy_16s(st->asiSpeechOld, pSpeechOldvec, SPEECH_SIZE - FRAME_SIZE + offsetWBE);
    ippsCopy_16s(st->asiWspOld, pWgtSpchOldvec, PITCH_LAG_MAX / OPL_DECIM);
    ippsCopy_16s(st->asiExcOld, pExcOldvec, PITCH_LAG_MAX + INTERPOL_LEN);

    /* Down sampling signal from 16kHz to 12.8kHz */

    ownDecimation_AMRWB_16s((Ipp16s*)src, L_FRAME16k, pSpeechNew, st->asiSpeechDecimate);

    /* last UP_SAMPL_FILT_DELAY samples for autocorrelation window */
    ippsCopy_16s(st->asiSpeechDecimate, pFixCdbkvec, 2*DOWN_SAMPL_FILT_DELAY);
    ippsZero_16s(pErrQuant, DOWN_SAMPL_FILT_DELAY);            /* set next sample to zero */
    ownDecimation_AMRWB_16s(pErrQuant, DOWN_SAMPL_FILT_DELAY, pSpeechNew + FRAME_SIZE, pFixCdbkvec);

    /* Perform 50Hz HP filtering of input signal */

    ippsHighPassFilter_AMRWB_16s_ISfs(pSpeechNew, FRAME_SIZE, st->pSHPFiltStateSgnlIn, 14);

    /* last UP_SAMPL_FILT_DELAY samples for autocorrelation window */
    ippsHighPassFilterGetSize_AMRWB_16s(2, &valSize);
    ippsCopy_8u((const Ipp8u*)st->pSHPFiltStateSgnlIn, (Ipp8u*)pFixCdbkvec, valSize);
    ippsHighPassFilter_AMRWB_16s_ISfs(pSpeechNew + FRAME_SIZE, UP_SAMPL_FILT_DELAY, (IppsHighPassFilterState_AMRWB_16s *)pFixCdbkvec, 14);

    /* get max of new preemphased samples (FRAME_SIZE+UP_SAMPL_FILT_DELAY) */

    z = pSpeechNew[0] << 15;
    z -= st->siPreemph * PREEMPH_FACTOR;
    valMax = Abs_32s(z);

    for (i = 1; i < FRAME_SIZE + UP_SAMPL_FILT_DELAY; i++)
    {
        z  = pSpeechNew[i] << 15;
        z -= pSpeechNew[i - 1] * PREEMPH_FACTOR;
        z  = Abs_32s(z);
        if (z > valMax) valMax = z;
    }

    /* get scaling factor for new and previous samples */
    tmp = (Ipp16s)(valMax >> 16);

    if (tmp == 0)
    {
        valShift = MAX_SCALE_FACTOR;
    } else
    {
        valShift = (Ipp16s)(Exp_16s(tmp) - 1);
        if (valShift < 0) valShift = 0;
        if (valShift > MAX_SCALE_FACTOR) valShift = MAX_SCALE_FACTOR;
    }
    valQNew = valShift;

    if (valQNew > st->asiScaleFactorMax[0]) valQNew = st->asiScaleFactorMax[0];
    if (valQNew > st->asiScaleFactorMax[1]) valQNew = st->asiScaleFactorMax[1];
    valExp = (Ipp16s)(valQNew - st->siScaleFactorOld);
    st->siScaleFactorOld = valQNew;
    st->asiScaleFactorMax[1] = st->asiScaleFactorMax[0];
    st->asiScaleFactorMax[0] = valShift;

    /* preemphasis with scaling (FRAME_SIZE+UP_SAMPL_FILT_DELAY) */

    tmp = pSpeechNew[FRAME_SIZE - 1];

    ippsPreemphasize_AMRWB_16s_ISfs(PREEMPH_FACTOR, pSpeechNew, FRAME_SIZE + UP_SAMPL_FILT_DELAY, 15-valQNew, &st->siPreemph);

    st->siPreemph = tmp;

    /* scale previous samples and memory */

    ownScaleSignal_AMRWB_16s_ISfs(pSpeechOldvec, SPEECH_SIZE - FRAME_SIZE - UP_SAMPL_FILT_DELAY + offsetWBE, valExp);
    ownScaleSignal_AMRWB_16s_ISfs(pExcOldvec, PITCH_LAG_MAX + INTERPOL_LEN, valExp);

    ownScaleSignal_AMRWB_16s_ISfs(st->asiSynthesis, LP_ORDER, valExp);
    ownScaleSignal_AMRWB_16s_ISfs(st->asiWspDecimate, 3, valExp);
    ownScaleSignal_AMRWB_16s_ISfs(&(st->siWsp), 1, valExp);
    ownScaleSignal_AMRWB_16s_ISfs(&(st->siSpeechWgt), 1, valExp);

     /*  Call VAD */
    if (offsetWBE == 0) {
       ippsCopy_16s(pSpeechNew, pVadvec, FRAME_SIZE);
    } else {
       ippsCopy_16s(pSpeech + SUBFRAME_SIZE - UP_SAMPL_FILT_DELAY, pVadvec, FRAME_SIZE);
    }

    ownScaleSignal_AMRWB_16s_ISfs(pVadvec, FRAME_SIZE, (Ipp16s)(1 - valQNew));
    ippsVAD_AMRWB_16s(pVadvec, st->pSVadState, &encoderObj->siToneFlag, &valVadFlag);
    if (valVadFlag == 0)
        st->siVadHist += 1;
    else
        st->siVadHist = 0;

    /* DTX processing */

    if (Vad != 0)
    {
       Ipp16s foo;
       Ipp16s dtxMode = ~IPP_SPCHBR_DTX;
       ippsEncDTXHandler_GSMAMR_16s(&st->dtxEncState.siHangoverCount,
                  &st->dtxEncState.siAnaElapsedCount, &dtxMode, &foo, valVadFlag);
       if(dtxMode==IPP_SPCHBR_DTX) {
          *rate = AMRWB_RATE_DTX;
          irate = IPP_SPCHBR_DTX;
       }
    }

    if (*rate != AMRWB_RATE_DTX)
    {
        *(pPrm)++ = valVadFlag;
    }
     /* Perform LPC analysis */

    ownAutoCorr_AMRWB_16s32s(pWindow, LP_ORDER, pAutoCorrvec, LPWindowTbl, WINDOW_SIZE);
    ownLagWindow_AMRWB_32s_I(pAutoCorrvec, LP_ORDER);
    if(ippsLevinsonDurbin_G729_32s16s(pAutoCorrvec, LP_ORDER, pLPCUnQuantvec, pRCvec, &tmp) == ippStsOverflow){
         pLPCUnQuantvec[0] = 4096;
         ippsCopy_16s(st->asiLevinsonMem, &pLPCUnQuantvec[1], LP_ORDER);
         pRCvec[0] = st->asiLevinsonMem[LP_ORDER]; /* only two pRCvec coefficients are needed */
         pRCvec[1] = st->asiLevinsonMem[LP_ORDER+1];
    }else{
         ippsCopy_16s(pLPCUnQuantvec, st->asiLevinsonMem, LP_ORDER+1);
         st->asiLevinsonMem[LP_ORDER] = pRCvec[0];
         st->asiLevinsonMem[LP_ORDER+1] = pRCvec[1];
    }
    ippsLPCToISP_AMRWB_16s(pLPCUnQuantvec, pIspvec, st->asiIspOld);

    /* Find the interpolated ISPs and convert to pLPCUnQuantvec for all subframes */
    {
      IPP_ALIGNED_ARRAY(16, Ipp16s, isp, LP_ORDER);

      ippsInterpolateC_NR_G729_16s_Sfs(st->asiIspOld, 18022, pIspvec,14746, isp, LP_ORDER, 15);
      ippsISPToLPC_AMRWB_16s(isp, pLPCUnQuantvec, LP_ORDER);

      ippsInterpolateC_NR_G729_16s_Sfs(st->asiIspOld,  6554, pIspvec,26214, isp, LP_ORDER, 15);
      ippsISPToLPC_AMRWB_16s(isp, &pLPCUnQuantvec[LP_ORDER + 1], LP_ORDER);

      ippsInterpolateC_NR_G729_16s_Sfs(st->asiIspOld,  1311, pIspvec,31457, isp, LP_ORDER, 15);
      ippsISPToLPC_AMRWB_16s(isp, &pLPCUnQuantvec[2*(LP_ORDER + 1)], LP_ORDER);

      /* 4th subframe: pIspvec (frac=1.0) */

      ippsISPToLPC_AMRWB_16s(pIspvec, &pLPCUnQuantvec[3*(LP_ORDER + 1)], LP_ORDER);

      /* update asiIspOld[] for the next frame */
      ippsCopy_16s(pIspvec, st->asiIspOld, LP_ORDER);
    }

    /* Convert ISPs to frequency domain 0..6400 */
    ippsISPToISF_Norm_AMRWB_16s(pIspvec, pIsfvec, LP_ORDER);

    /* check resonance for pitch clipping algorithm */
    ownCheckGpClipIsf(pIsfvec, st->asiGainPitchClip);

     /* Perform PITCH_OL analysis */

    pLPCUnQuant = pLPCUnQuantvec;
    for (valSubFrame = 0; valSubFrame < FRAME_SIZE; valSubFrame += SUBFRAME_SIZE)
    {
        ippsMulPowerC_NR_16s_Sfs(pLPCUnQuant, WEIGHT_FACTOR, pLPCvec, LP_ORDER+1, 15);
        //ippsResidualFilter_AMRWB_16s_Sfs(pLPCvec, LP_ORDER, &pSpeech[valSubFrame], &pWgtSpch[valSubFrame], SUBFRAME_SIZE,10);
        ippsResidualFilter_Low_16s_Sfs(pLPCvec, LP_ORDER, &pSpeech[valSubFrame], &pWgtSpch[valSubFrame], SUBFRAME_SIZE, 11);
        pLPCUnQuant += (LP_ORDER + 1);
    }
    ippsDeemphasize_AMRWB_NR_16s_I(TILT_FACTOR, pWgtSpch, FRAME_SIZE, &(st->siWsp));

    /* find maximum value on pWgtSpch[] for 12 bits scaling */
    ippsMinMax_16s(pWgtSpch, FRAME_SIZE, &tmp, &max);

    max = Abs_16s(max);
    tmp = Abs_16s(tmp);

    if(tmp > max) max = tmp;
    tmp = st->siWspOldMax;

    if (max > tmp) tmp = max;
    st->siWspOldMax = max;

    valShift = (Ipp16s)(Exp_16s(tmp) - 3);
    if (valShift > 0) valShift = 0;               /* valShift = 0..-3 */

    /* decimation of pWgtSpch[] to search pitch in LF and to reduce complexity */
    ownLPDecim2(pWgtSpch, FRAME_SIZE, st->asiWspDecimate);

    /* scale pWgtSpch[] in 12 bits to avoid overflow */
    ownScaleSignal_AMRWB_16s_ISfs(pWgtSpch, FRAME_SIZE / OPL_DECIM, valShift);

    /* scale asiWspOld */
    valExp = (Ipp16s)(valExp + (valShift - st->siWspOldShift));
    st->siWspOldShift = valShift;
    ownScaleSignal_AMRWB_16s_ISfs(pWgtSpchOldvec, PITCH_LAG_MAX / OPL_DECIM, valExp);
    ownScaleSignal_AMRWB_16s_ISfs(st->asiHypassFiltWspOld, PITCH_LAG_MAX / OPL_DECIM, valExp);
    st->siScaleExp = (Ipp16s)(st->siScaleExp - valExp);

    /* Find open loop pitch lag for whole speech frame */

    pHPWgtSpch = st->asiHypassFiltWspOld + PITCH_LAG_MAX / OPL_DECIM;

    if(irate == IPP_SPCHBR_6600) {
       ippsHighPassFilter_AMRWB_16s_Sfs(pWgtSpch, pHPWgtSpch, (FRAME_SIZE) / OPL_DECIM, st->pSHPFiltStateWsp,st->siScaleExp);
       ippsOpenLoopPitchSearch_AMRWB_16s(pWgtSpch, pHPWgtSpch, &st->siMedianOld, &st->siAdaptiveParam, &pOpenLoopLag[0],
                              &encoderObj->siToneFlag, &st->siOpenLoopGain,
                              st->asiPitchLagOld, &st->siWeightFlag, (FRAME_SIZE) / OPL_DECIM);
       ippsMove_16s(&st->asiHypassFiltWspOld[(FRAME_SIZE) / OPL_DECIM],st->asiHypassFiltWspOld,PITCH_LAG_MAX / OPL_DECIM);
       pOpenLoopLag[1] = pOpenLoopLag[0];
    } else {
       ippsHighPassFilter_AMRWB_16s_Sfs(pWgtSpch, pHPWgtSpch, (FRAME_SIZE / 2) / OPL_DECIM, st->pSHPFiltStateWsp,st->siScaleExp);
       ippsOpenLoopPitchSearch_AMRWB_16s(pWgtSpch, pHPWgtSpch, &st->siMedianOld, &st->siAdaptiveParam, &pOpenLoopLag[0],
                              &encoderObj->siToneFlag, &st->siOpenLoopGain,
                              st->asiPitchLagOld, &st->siWeightFlag, (FRAME_SIZE / 2) / OPL_DECIM);
       ippsMove_16s(&st->asiHypassFiltWspOld[(FRAME_SIZE / 2) / OPL_DECIM],st->asiHypassFiltWspOld,PITCH_LAG_MAX / OPL_DECIM);
       ippsHighPassFilter_AMRWB_16s_Sfs(pWgtSpch + ((FRAME_SIZE / 2) / OPL_DECIM), pHPWgtSpch,
                              (FRAME_SIZE / 2) / OPL_DECIM, st->pSHPFiltStateWsp,st->siScaleExp);
       ippsOpenLoopPitchSearch_AMRWB_16s(pWgtSpch + ((FRAME_SIZE / 2) / OPL_DECIM), pHPWgtSpch, &st->siMedianOld, &st->siAdaptiveParam, &pOpenLoopLag[1],
                              &encoderObj->siToneFlag, &st->siOpenLoopGain,
                              st->asiPitchLagOld, &st->siWeightFlag, (FRAME_SIZE / 2) / OPL_DECIM);
       ippsMove_16s(&st->asiHypassFiltWspOld[(FRAME_SIZE / 2) / OPL_DECIM],st->asiHypassFiltWspOld,PITCH_LAG_MAX / OPL_DECIM);
    }

    if (irate == IPP_SPCHBR_DTX)            /* CNG mode */
    {
        //ippsResidualFilter_AMRWB_16s_Sfs(&pLPCUnQuantvec[3 * (LP_ORDER + 1)], LP_ORDER, pSpeech, pExc, FRAME_SIZE,10);
        ippsResidualFilter_Low_16s_Sfs(&pLPCUnQuantvec[3 * (LP_ORDER + 1)], LP_ORDER, pSpeech, pExc, FRAME_SIZE, 11);
        ippsRShiftC_16s(pExc, valQNew, pExc2vec, FRAME_SIZE);
        ippsEncDTXBuffer_AMRWB_16s(pExc2vec, pIsfvec, &st->dtxEncState.siHistPtr,
                  st->dtxEncState.asiIsfHistory, st->dtxEncState.siLogEnerHist, valCodecMode);
        ownDTXEnc(&st->dtxEncState, pIsfvec, pExc2vec, (Ipp16u*)pPrm);

        /* Convert ISFs to the cosine domain */
        ippsISFToISP_AMRWB_16s(pIsfvec, pIspQuantvec, LP_ORDER);
        ippsISPToLPC_AMRWB_16s(pIspQuantvec, pLPCQuantvec, LP_ORDER);

        for (valSubFrame = 0; valSubFrame < FRAME_SIZE; valSubFrame += SUBFRAME_SIZE)
        {
            valCorrGain = ownSynthesis(pLPCQuantvec, &pExc2vec[valSubFrame], 0, &src[valSubFrame * 5 / 4], st);
        }
        ippsCopy_16s(pIsfvec, st->asiIsfOld, LP_ORDER);
        InitEncoder(encoderObj);

        if (offsetWBE == 0)
           ownPrms2Bits(pPrmvec,dst,AMRWB_RATE_DTX);

        ippsCopy_16s(&pSpeechOldvec[FRAME_SIZE], st->asiSpeechOld, SPEECH_SIZE - FRAME_SIZE + offsetWBE);
        ippsCopy_16s(&pWgtSpchOldvec[FRAME_SIZE / OPL_DECIM], st->asiWspOld, PITCH_LAG_MAX / OPL_DECIM);

        return APIAMRWB_StsNoErr;
    }

    ippsISFQuant_AMRWB_16s(pIsfvec, st->asiIsfQuantPast, pIsfvec, (Ipp16s*)pPrm, irate);

    if (irate == IPP_SPCHBR_6600)
        pPrm += 5;
    else
        pPrm += 7;

    /* Check stability on pIsfvec : distance between old pIsfvec and current isf */
    if (irate == IPP_SPCHBR_23850 || offsetWBE!=0) {
        valStabFac = ownChkStab(pIsfvec, st->asiIsfOld, LP_ORDER-1);
    }
    ippsCopy_16s(pIsfvec, st->asiIsfOld, LP_ORDER);

    /* Convert ISFs to the cosine domain */
    ippsISFToISP_AMRWB_16s(pIsfvec, pIspQuantvec, LP_ORDER);

⌨️ 快捷键说明

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