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

📄 encamrwb.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 1 页 / 共 4 页
字号:
            valCodeGain += Mpy_32_16(valScaleCodeGain, valCodeGainLow, valFac);

            /* pitch enhancer */
            tmp = (Ipp16s)((valVoiceFac >> 3) + 4096); /* 0.25=voiced, 0=unvoiced */

            pSrcCoeff[0] = 1;
            pSrcCoeff[1] = tmp;
            ippsHighPassFilter_Direct_AMRWB_16s(pSrcCoeff, pFixCdbkvec, pFixCdbkExcvec, SUBFRAME_SIZE, 0);

            /* build excitation */

            valScaleCodeGain = Cnvrt_NR_32s16s(valCodeGain << valQNew);
            ippsInterpolateC_NR_16s(pFixCdbkExcvec, valScaleCodeGain, 7,
                pExc2vec, valPitchGain, 2, pExc2vec,SUBFRAME_SIZE);
            valCorrGain = ownSynthesis(pLPCQuant, pExc2vec, valQNew, &src[valSubFrame * 5 / 4], st);
            *(pPrm)++ = valCorrGain;
        }
        pLPCUnQuant += (LP_ORDER + 1);
        pLPCQuant += (LP_ORDER + 1);
    }                                      /* end of subframe loop */

    if (offsetWBE == 0)
       ownPrms2Bits(pPrmvec,dst,*rate);

    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);
    ippsCopy_16s(&pExcOldvec[FRAME_SIZE], st->asiExcOld, PITCH_LAG_MAX + INTERPOL_LEN);

    return APIAMRWB_StsNoErr;
}

/* Synthesis of signal at 16kHz with pHighFreqvec extension */
static Ipp16s ownSynthesis(Ipp16s *pLPCQuantvec, Ipp16s *pExc, Ipp16s valQNew,
                          const Ipp16u *pSynthSignal, AMRWBEncoder_Obj *st)
{
    Ipp16s valFac, tmp, valExp;
    Ipp16s valEner, valExpEner;
    Ipp32s i, z, sfs;

    IPP_ALIGNED_ARRAY( 16, Ipp32s, pSynthHighvec, LP_ORDER + SUBFRAME_SIZE);
    IPP_ALIGNED_ARRAY( 16, Ipp16s, pSynthvec, SUBFRAME_SIZE);
    IPP_ALIGNED_ARRAY( 16, Ipp16s, pHighFreqvec, SUBFRAME_SIZE_16k);
    IPP_ALIGNED_ARRAY( 16, Ipp16s, pLPCvec, LP_ORDER + 1);
    IPP_ALIGNED_ARRAY( 16, Ipp16s, pHighFreqSpchvec, SUBFRAME_SIZE_16k);

    Ipp16s valHPEstGain, valHPCalcGain, valHPCorrGain;
    Ipp16s valDistMin, valDist;
    Ipp16s valHPGainIndex = 0;
    Ipp16s valGainCoeff, valAdptGain;
    Ipp16s valWeight, valWeight2;

    /* speech synthesis */
    ippsCopy_16s((Ipp16s*)st->aiSynthMem, (Ipp16s*)pSynthHighvec, LP_ORDER*2);
    tmp = pLPCQuantvec[0];
    sfs = Exp_16s(tmp) - 2;
    pLPCQuantvec[0] >>= (4 + valQNew);
    if (sfs)
        ownSynthesisFilter_AMRWB_16s32s_ISfs(pLPCQuantvec, LP_ORDER, pExc, pSynthHighvec + LP_ORDER, SUBFRAME_SIZE, sfs + 3);
    else
        ippsSynthesisFilter_AMRWB_16s32s_I(pLPCQuantvec, LP_ORDER, pExc, pSynthHighvec + LP_ORDER, SUBFRAME_SIZE);
    pLPCQuantvec[0] = tmp;

    ippsCopy_16s((Ipp16s*)(&pSynthHighvec[SUBFRAME_SIZE]), (Ipp16s*)st->aiSynthMem, LP_ORDER*2);
    ippsDeemphasize_AMRWB_32s16s(PREEMPH_FACTOR>>1, pSynthHighvec + LP_ORDER, pSynthvec, SUBFRAME_SIZE, &(st->siDeemph));
    ippsHighPassFilter_AMRWB_16s_ISfs(pSynthvec, SUBFRAME_SIZE, st->pSHPFiltStateSgnlOut, 14);

    /* Original speech signal as reference for high band gain quantisation */
    ippsCopy_16s((Ipp16s*)pSynthSignal,pHighFreqSpchvec,SUBFRAME_SIZE_16k);

    /* pHighFreqvec noise synthesis */

    for (i = 0; i < SUBFRAME_SIZE_16k; i++)
        pHighFreqvec[i] = (Ipp16s)(Rand_16s(&(st->siHFSeed)) >> 3);

    /* energy of excitation */

    ownScaleSignal_AMRWB_16s_ISfs(pExc, SUBFRAME_SIZE, -3);
    valQNew -= 3;

    ippsDotProd_16s32s_Sfs( pExc, pExc,SUBFRAME_SIZE, &z, -1);
    z = Add_32s(z, 1);

    valExpEner = (Ipp16s)(30 - Norm_32s_I(&z));
    valEner = (Ipp16s)(z >> 16);

    valExpEner = (Ipp16s)(valExpEner - (valQNew + valQNew));

    /* set energy of white noise to energy of excitation */

    ippsDotProd_16s32s_Sfs( pHighFreqvec, pHighFreqvec,SUBFRAME_SIZE_16k, &z, -1);
    z = Add_32s(z, 1);

    valExp = (Ipp16s)(30 - Norm_32s_I(&z));
    tmp = (Ipp16s)(z >> 16);

    if (tmp > valEner)
    {
        tmp >>= 1;
        valExp += 1;
    }
    if (tmp == valEner)
        z = (Ipp32s)IPP_MAX_16S << 16;
    else
        z = (Ipp32s)(((Ipp32s)tmp << 15) / (Ipp32s)valEner) << 16;
    valExp = (Ipp16s)(valExp - valExpEner);
    ownInvSqrt_AMRWB_32s16s_I(&z, &valExp);
    if ((valExp+1) >= 0)
        z = ShiftL_32s(z, (Ipp16s)(valExp + 1));
    else
        z >>= (-(valExp + 1));
    tmp = (Ipp16s)(z >> 16);

    ownMulC_16s_ISfs(tmp, pHighFreqvec, SUBFRAME_SIZE_16k, 15);

    /* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */

    ippsHighPassFilter_AMRWB_16s_ISfs(pSynthvec, SUBFRAME_SIZE, st->pSHPFiltStateSgnl400, 15);
    ippsDotProd_16s32s_Sfs( pSynthvec, pSynthvec,SUBFRAME_SIZE, &z, -1);
    z = Add_32s(z, 1);

    valExp = Norm_32s_I(&z);
    valEner = (Ipp16s)(z>>16);

    ippsDotProd_16s32s_Sfs( pSynthvec, &pSynthvec[1],SUBFRAME_SIZE-1, &z, -1);
    z = Add_32s(z, 1);

    tmp = (Ipp16s)(ShiftL_32s(z, valExp) >> 16);
    if (tmp > 0)
    {
        if (tmp == valEner)
            valFac = IPP_MAX_16S;
        else
            valFac = (Ipp16s)(((Ipp32s)tmp << 15) / (Ipp32s)valEner);
    } else
        valFac = 0;

    /* modify energy of white noise according to synthesis tilt */
    valGainCoeff = (Ipp16s)(IPP_MAX_16S - valFac);
    valAdptGain = Cnvrt_32s16s((valGainCoeff * 5) >> 2);

    if (st->siVadHist > 0)
    {
        valWeight = 0;
        valWeight2 = IPP_MAX_16S;
    } else
    {
        valWeight = IPP_MAX_16S;
        valWeight2 = 0;
    }
    tmp = Mul_16s_Sfs(valWeight, valGainCoeff, 15);
    tmp = (Ipp16s)(tmp + Mul_16s_Sfs(valWeight2, valAdptGain, 15));

    if (tmp != 0) tmp += 1;
    valHPEstGain = tmp;

    if (valHPEstGain < 3277) valHPEstGain = 3277;

    /* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */
    ippsMulPowerC_NR_16s_Sfs(pLPCQuantvec, 19661, pLPCvec, LP_ORDER+1, 15); /* valFac=0.6 */
    {
      Ipp16s tmpLPCVec;
      tmpLPCVec = pLPCvec[0];
      pLPCvec[0] >>= 1;
      ippsSynthesisFilter_G729E_16s_I(pLPCvec, LP_ORDER, pHighFreqvec, SUBFRAME_SIZE_16k, st->asiSynthHighFilt);
      ippsCopy_16s(&pHighFreqvec[SUBFRAME_SIZE_16k-LP_ORDER],st->asiSynthHighFilt,LP_ORDER);
      pLPCvec[0] = tmpLPCVec;
    }

    /* noise High Pass filtering (1ms of delay) */
    HighPassFIR_AMRWB_16s_ISfs(pHighFreqvec, SUBFRAME_SIZE_16k, st->pSHPFIRState);

    /* filtering of the original signal */
    HighPassFIR_AMRWB_16s_ISfs(pHighFreqSpchvec, SUBFRAME_SIZE_16k, st->pSHPFIRState2);

    /* check the gain difference */
    ownScaleSignal_AMRWB_16s_ISfs(pHighFreqSpchvec, SUBFRAME_SIZE_16k, -1);

    ippsDotProd_16s32s_Sfs( pHighFreqSpchvec, pHighFreqSpchvec,SUBFRAME_SIZE_16k, &z, -1);
    z = Add_32s(z, 1);

    valExpEner = (Ipp16s)(30 - Norm_32s_I(&z));
    valEner = (Ipp16s)(z >> 16);

    /* set energy of white noise to energy of excitation */
    ippsDotProd_16s32s_Sfs( pHighFreqvec, pHighFreqvec,SUBFRAME_SIZE_16k, &z, -1);
    z = Add_32s(z, 1);

    valExp = (Ipp16s)(30 - Norm_32s_I(&z));
    tmp = (Ipp16s)(z >> 16);

    if (tmp > valEner)
    {
        tmp >>= 1;
        valExp += 1;
    }
    if (tmp == valEner)
        z = (Ipp32s)IPP_MAX_16S << 16;
    else
        z = (Ipp32s)(((Ipp32s)tmp << 15) / (Ipp32s)valEner) << 16;
    valExp = (Ipp16s)(valExp - valExpEner);
    ownInvSqrt_AMRWB_32s16s_I(&z, &valExp);
    if (valExp > 0)
        z = ShiftL_32s(z, valExp);
    else
        z >>= (-valExp);
    valHPCalcGain = (Ipp16s)(z >> 16);

    z = st->dtxEncState.siHangoverCount * 4681;
    st->siAlphaGain = Mul_16s_Sfs(st->siAlphaGain, (Ipp16s)z, 15);

    if (st->dtxEncState.siHangoverCount > 6)
        st->siAlphaGain = IPP_MAX_16S;
    valHPEstGain >>= 1;
    valHPCorrGain  = Mul_16s_Sfs(valHPCalcGain, st->siAlphaGain, 15);
    valHPCorrGain = (Ipp16s)(valHPCorrGain + Mul_16s_Sfs((Ipp16s)(IPP_MAX_16S - st->siAlphaGain), valHPEstGain, 15));

    /* Quantise the correction gain */
    valDistMin = IPP_MAX_16S;
    for (i = 0; i < 16; i++)
    {
        valDist = Mul_16s_Sfs((Ipp16s)(valHPCorrGain - HPGainTbl[i]), (Ipp16s)(valHPCorrGain - HPGainTbl[i]), 15);
        if (valDistMin > valDist)
        {
            valDistMin = valDist;
            valHPGainIndex = (Ipp16s)i;
        }
    }

    valHPCorrGain = HPGainTbl[valHPGainIndex];

    /* return the quantised gain index when using the highest mode, otherwise zero */
    return (valHPGainIndex);
}
static Ipp8s* ownPar2Ser( Ipp32s valPrm, Ipp8s *pBitStreamvec, Ipp32s valNumBits )
{
    Ipp32s i;
    Ipp16s tmp;
    Ipp8s *TempPnt = pBitStreamvec + valNumBits -1;

    for ( i = 0 ; i < valNumBits ; i ++ ) {
        tmp = (Ipp16s) (valPrm & 0x1);
        valPrm >>= 1;
        *TempPnt-- = (Ipp8s)tmp;
    }

    return (pBitStreamvec + valNumBits);
}

static void ownPrms2Bits(const Ipp16s* pPrms, Ipp8u *pBitstream, AMRWB_Rate_t rate)
{
    Ipp8s *pBsp;
    Ipp32s i, tmp, valSht, valBitCnt = 0;
    IPP_ALIGNED_ARRAY(16, Ipp8s, pBitStreamvec, NB_BITS_MAX);
    Ipp8u *pBits = (Ipp8u*)pBitstream;

    pBsp = pBitStreamvec ;

    for( i = 0; i < NumberPrmsTbl[rate]; i++) {
       valBitCnt += pNumberBitsTbl[rate][i];
       tmp = pPrms[i];
       pBsp = ownPar2Ser( tmp, pBsp, pNumberBitsTbl[rate][i] );
    }

    /* Clear the output vector */
    ippsZero_8u((Ipp8u*)pBitstream, (valBitCnt+7)/8);
    valSht  = (valBitCnt + 7) / 8 * 8 - valBitCnt;

    for ( i = 0 ; i < valBitCnt; i ++ ) {
        pBits[i/8] <<= 1;
        if (pBitStreamvec[i]) pBits[i/8]++;
    }
    pBits[(valBitCnt-1)/8] <<= valSht;
}

⌨️ 快捷键说明

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