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

📄 utilgsmamr.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 1 页 / 共 3 页
字号:
   if(*vCountHangover > 20) {
      if(ownGetMedianElements_GSMAMR(ltpGainHist, 9) > ltpLimit)  prevVoiced = 1;
      else                                                        prevVoiced = 0;
   }

   if(prevVoiced) *vVoiceHangover = 0;
   else {
      temp = (Ipp16s)(*vVoiceHangover + 1);
      if(temp > 10) *vVoiceHangover = 10;
      else          *vVoiceHangover = temp;
   }

   return inbgNoise;
   /* End of ownSourceChDetectorUpdate_GSMAMR() */
}
/*************************************************************************
 Function: ownCalcUnFiltEnergy_GSMAMR
 *************************************************************************/
void ownCalcUnFiltEnergy_GSMAMR(Ipp16s *pLPResVec, Ipp16s *pLTPExc, Ipp16s *code, Ipp16s gainPitch,
                                Ipp16s lenSubfr, Ipp16s *fracEnergyCoeff, Ipp16s *expEnergyCoeff, Ipp16s *ltpg)
{
    Ipp32s s, TmpVal;
    Ipp16s i, exp, tmp;
    Ipp16s ltp_res_en, pred_gain;
    Ipp16s ltpg_exp, ltpg_frac;

    ippsDotProd_16s32s_Sfs(pLPResVec, pLPResVec, lenSubfr, &s, -1);

    if (s < 400) {
        fracEnergyCoeff[0] = 0;
        expEnergyCoeff[0] = -15;
    } else {
        exp = Norm_32s_I(&s);
        fracEnergyCoeff[0] = (Ipp16s)(s >> 16);
        expEnergyCoeff[0] = (Ipp16s)(15 - exp);
    }

    ippsDotProd_16s32s_Sfs(pLTPExc, pLTPExc, lenSubfr, &s, -1);
    exp = Norm_32s_I(&s);
    fracEnergyCoeff[1] = (Ipp16s)(s >> 16);
    expEnergyCoeff[1] = (Ipp16s)(15 - exp);

    ippsDotProd_16s32s_Sfs(pLTPExc, code, lenSubfr, &s, -1);
    exp = Norm_32s_I(&s);
    fracEnergyCoeff[2] = (Ipp16s)(s >> 16);
    expEnergyCoeff[2] = (Ipp16s)(2 - exp);

    s = 0;
    for (i = 0; i < lenSubfr; i++) {
        TmpVal = pLTPExc[i] * gainPitch;
        tmp = (Ipp16s)(pLPResVec[i] - (Ipp16s)((TmpVal + 0x2000) >> 14));           /* LTP residual, Q0 */
        s += tmp * tmp;
    }
    exp = Norm_32s_I(&s);
    ltp_res_en = (Ipp16s)(s >> 16);
    exp = (Ipp16s)(16 - exp);

    fracEnergyCoeff[3] = ltp_res_en;
    expEnergyCoeff[3] = exp;

    if(ltp_res_en > 0 && fracEnergyCoeff[0] != 0) {
        pred_gain = (Ipp16s)(((fracEnergyCoeff[0] >> 1) << 15) / ltp_res_en);
        exp = (Ipp16s)(exp - expEnergyCoeff[0]);
        TmpVal = pred_gain << 16;

        if(exp < -3) ShiftL_32s(TmpVal, (Ipp16s)(-(exp + 3)));
        else         TmpVal >>= (exp + 3);

        ownLog2_GSMAMR(TmpVal, &ltpg_exp, &ltpg_frac);
        TmpVal = ((ltpg_exp - 27) << 15) + ltpg_frac;
        *ltpg = Cnvrt_NR_32s16s(TmpVal << 14);
    }
    else *ltpg = 0;

    return;
    /* End of ownCalcUnFiltEnergy_GSMAMR() */
}

/*************************************************************************
 * Function: ownCalcFiltEnergy_GSMAMR
 *************************************************************************/
void ownCalcFiltEnergy_GSMAMR(IppSpchBitRate rate, Ipp16s *pTargetPitchVec, Ipp16s *pTargetVec,
                              Ipp16s *pFltAdaptExc, Ipp16s *pFltVec, Ipp16s *fracEnergyCoeff,
                              Ipp16s *expEnergyCoeff, Ipp16s *optFracCodeGain, Ipp16s *optExpCodeGain)
{
    Ipp16s g_coeff[4];
    Ipp32s s, ener_init=1;
    Ipp16s exp, frac;
    Ipp16s pFltVecTmp[SUBFR_SIZE_GSMAMR];
    Ipp16s gain;

    if(rate == IPP_SPCHBR_7950 || rate == IPP_SPCHBR_4750) ener_init = 0;

    ippsRShiftC_16s(pFltVec, 3, pFltVecTmp, SUBFR_SIZE_GSMAMR);
    ippsAdaptiveCodebookGainCoeffs_GSMAMR_16s(pTargetPitchVec, pFltAdaptExc, &gain, g_coeff);

    fracEnergyCoeff[0] = g_coeff[0];
    expEnergyCoeff[0]  = g_coeff[1];
    //fracEnergyCoeff[1] = (g_coeff[2] == IPP_MIN_16S) ? IPP_MAX_16S : -g_coeff[2];/* coeff[1] = -2 xn y1 */
    if(g_coeff[2] == IPP_MIN_16S) fracEnergyCoeff[1] = IPP_MAX_16S; /* coeff[1] = -2 xn y1 */
    else fracEnergyCoeff[1] = (Ipp16s)(-g_coeff[2]);
    expEnergyCoeff[1]  = (Ipp16s)(g_coeff[3] + 1);

    ippsDotProd_16s32s_Sfs(pFltVecTmp, pFltVecTmp, SUBFR_SIZE_GSMAMR, &s, -1);
    s += ener_init;
    exp = Norm_32s_I(&s);
    fracEnergyCoeff[2] = (Ipp16s)(s >> 16);
    expEnergyCoeff[2] = (Ipp16s)(-3 - exp);

    ippsDotProd_16s32s_Sfs(pTargetPitchVec, pFltVecTmp, SUBFR_SIZE_GSMAMR, &s, -1);
    s += ener_init;
    exp = Norm_32s_I(&s);
    s >>= 16;
    //fracEnergyCoeff[3] = (s != IPP_MIN_16S)? -s : IPP_MAX_16S;
    if(s != IPP_MIN_16S) fracEnergyCoeff[3] = (Ipp16s)(-s);
    else fracEnergyCoeff[3] = IPP_MAX_16S;
    expEnergyCoeff[3] = (Ipp16s)(7 - exp);

    ippsDotProd_16s32s_Sfs(pFltAdaptExc, pFltVecTmp, SUBFR_SIZE_GSMAMR, &s, -1);
    s += ener_init;
    exp = Norm_32s_I(&s);
    fracEnergyCoeff[4] = (Ipp16s)(s >> 16);
    expEnergyCoeff[4] = (Ipp16s)(7 - exp);

    if(rate == IPP_SPCHBR_4750 || rate == IPP_SPCHBR_7950) {
        ippsDotProd_16s32s_Sfs( pTargetVec, pFltVecTmp, SUBFR_SIZE_GSMAMR, &s, -1);
        s += ener_init;
        exp = Norm_32s_I(&s);
        frac = (Ipp16s)(s >> 16);
        exp = (Ipp16s)(6 - exp);

        if (frac <= 0) {
            *optFracCodeGain = 0;
            *optExpCodeGain = 0;
        } else {
            *optFracCodeGain = (Ipp16s)(((frac >> 1) << 15) / fracEnergyCoeff[2]);
            *optExpCodeGain = (Ipp16s)(exp - expEnergyCoeff[2] - 14);
        }
    }
    return;
    /* End of ownCalcFiltEnergy_GSMAMR() */
}

/*************************************************************************
 * Function: ownCalcTargetEnergy_GSMAMR
 *************************************************************************/
void ownCalcTargetEnergy_GSMAMR(Ipp16s *pTargetPitchVec, Ipp16s *optExpCodeGain, Ipp16s *optFracCodeGain)
{
    Ipp32s s;
    Ipp16s exp;

    ippsDotProd_16s32s_Sfs(pTargetPitchVec, pTargetPitchVec, SUBFR_SIZE_GSMAMR, &s, -1);
    exp = Norm_32s_I(&s);
    *optFracCodeGain = (Ipp16s)(s >> 16);
    *optExpCodeGain = (Ipp16s)(16 - exp);

    return;
    /* End of ownCalcTargetEnergy_GSMAMR() */
}
/**************************************************************************
*  Function:    : A_Refl
*  Convert from direct form coefficients to reflection coefficients
**************************************************************************/
void ownConvertDirectCoeffToReflCoeff_GSMAMR(Ipp16s *pDirectCoeff, Ipp16s *pReflCoeff)
{

   Ipp16s i,j;
   Ipp16s aState[LP_ORDER_SIZE];
   Ipp16s bState[LP_ORDER_SIZE];
   Ipp16s normShift, normProd;
   Ipp16s scale, temp, mult;
   Ipp32s const1;
   Ipp32s TmpVal, TmpVal1, TmpVal2;

   ippsCopy_16s(pDirectCoeff, aState, LP_ORDER_SIZE);
   for (i = LP_ORDER_SIZE-1; i >= 0; i--) {
      if(Abs_16s(aState[i]) >= 4096) goto ExitRefl;

      pReflCoeff[i] = (Ipp16s)(aState[i] << 3);
      TmpVal1 = 2 * pReflCoeff[i] * pReflCoeff[i];
      TmpVal = IPP_MAX_32S - TmpVal1;
      normShift = Norm_32s_Pos_I(&TmpVal);
      scale = (Ipp16s)(14 - normShift);
      normProd = Cnvrt_NR_32s16s(TmpVal);
      mult = (Ipp16s)((16384 << 15) / normProd);
      const1 = 1<<(scale - 1);

      for (j = 0; j < i; j++) {
         TmpVal = (aState[j] << 15) - (pReflCoeff[i] * aState[i-j-1]);
         temp = (Ipp16s)((TmpVal + 0x4000) >> 15);
         TmpVal1 = mult * temp;
         TmpVal2 = (TmpVal1 + const1) >> scale;

         if(TmpVal2 > 32767) goto ExitRefl;
         bState[j] = (Ipp16s)TmpVal2;
      }

      ippsCopy_16s(bState, aState, i);
   }
   return;

ExitRefl:
   ippsZero_16s(pReflCoeff, LP_ORDER_SIZE);
}
/**************************************************************************
*  Function    : ownScaleExcitation_GSMAMR
***************************************************************************/
void ownScaleExcitation_GSMAMR(Ipp16s *pInputSignal, Ipp16s *pOutputSignal)
{
    Ipp16s exp;
    Ipp16s gain_in, gain_out, g0;
    Ipp32s i, s;
    Ipp16s temp[SUBFR_SIZE_GSMAMR];

    ippsDotProd_16s32s_Sfs(pOutputSignal, pOutputSignal, SUBFR_SIZE_GSMAMR, &s, 0);
    if (s >= IPP_MAX_32S/2) {
        ippsRShiftC_16s(pOutputSignal, 2, temp, SUBFR_SIZE_GSMAMR);
        ippsDotProd_16s32s_Sfs(temp, temp, SUBFR_SIZE_GSMAMR, &s, -1);
    } else s >>= 3;

    if(s == 0) return;

    exp = (Ipp16s)(Exp_32s_Pos(s) - 1);
    gain_out = Cnvrt_NR_32s16s(s << exp);

    ippsDotProd_16s32s_Sfs(pInputSignal, pInputSignal, SUBFR_SIZE_GSMAMR, &s, 0);
    if (s >= IPP_MAX_32S/2) {
        ippsRShiftC_16s(pInputSignal, 2, temp, SUBFR_SIZE_GSMAMR);
        ippsDotProd_16s32s_Sfs(temp, temp, SUBFR_SIZE_GSMAMR, &s, -1);
    } else s >>= 3;

    if(s == 0) g0 = 0;
    else {
        i = Norm_32s_I(&s);
        gain_in = Cnvrt_NR_32s16s(s);
        exp = (Ipp16s)(exp - i);
        s = ((gain_out << 15) / gain_in);
        s = ShiftL_32s(s, 7);
        if (exp < 0) s = ShiftL_32s(s, (Ipp16u)(-exp));
        else         s >>= exp;
        ippsInvSqrt_32s_I(&s, 1);
        g0 = Cnvrt_NR_32s16s(ShiftL_32s(s, 9));
    }

    for (i = 0; i < SUBFR_SIZE_GSMAMR; i++)
        pOutputSignal[i] = (Ipp16s)(Mul16_32s(pOutputSignal[i] * g0) >> 16);

    return;
    /* End of ownScaleExcitation_GSMAMR() */
}

static const Ipp16s TablePredCoeff[NUM_PRED_TAPS] = {5571, 4751, 2785, 1556};
/* MEAN_ENER  = 36.0/constant, constant = 20*Log10(2)       */
#define MEAN_ENER_MR122  783741
static const Ipp16s TablePredCoeff_M122[NUM_PRED_TAPS] = {44, 37, 22, 12};

/*************************************************************************
 * Function:  ownPredEnergyMA_GSMAMR()
 *************************************************************************/
void ownPredEnergyMA_GSMAMR(Ipp16s *a_PastQntEnergy, Ipp16s *a_PastQntEnergy_M122, IppSpchBitRate rate,
                            Ipp16s *code, Ipp16s *expGainCodeCB, Ipp16s *fracGainCodeCB, Ipp16s *expEnergyCoeff,
                            Ipp16s *fracEnergyCoeff)
{
    Ipp32s ener_code, ener;
    Ipp16s exp, frac;
    ippsDotProd_16s32s_Sfs( code, code, SUBFR_SIZE_GSMAMR, &ener_code, -1);

    if (rate == IPP_SPCHBR_12200) {
        ener_code = 2 *((ener_code + 0x8000) >> 16) * 26214;
        ownLog2_GSMAMR(ener_code, &exp, &frac);
        ener_code = ((exp - 30) << 16) + (frac << 1);
        ippsDotProd_16s32s_Sfs(a_PastQntEnergy_M122, TablePredCoeff_M122, NUM_PRED_TAPS, &ener, -1);
        ener += MEAN_ENER_MR122;
        ener = (ener - ener_code) >> 1;                /* Q16 */
        Unpack_32s(ener, expGainCodeCB, fracGainCodeCB);
    } else {
        Ipp32s TmpVal;
        Ipp16s exp_code, predGainCB;

        exp_code = Norm_32s_I(&ener_code);
        ownLog2_GSMAMR_norm (ener_code, exp_code, &exp, &frac);
        TmpVal = Mpy_32_16(exp, frac, -24660);
        if(rate == IPP_SPCHBR_10200) TmpVal += 2 * 16678 * 64;
        else if (rate == IPP_SPCHBR_7950) {
           *fracEnergyCoeff = (Ipp16s) (ener_code>>16);
           *expEnergyCoeff = (Ipp16s)(-11 - exp_code);
           TmpVal += 2 * 17062 * 64;
        } else if (rate == IPP_SPCHBR_7400) {
            TmpVal += 2 * 32588 * 32;
        } else if (rate == IPP_SPCHBR_6700) {
            TmpVal += 2 * 32268 * 32;
        } else { /* MR59, MR515, MR475 */
            TmpVal += 2 * 16678 * 64;
        }

        TmpVal <<= 10;
        ippsDotProd_16s32s_Sfs(a_PastQntEnergy, TablePredCoeff, NUM_PRED_TAPS, &ener, -1);
        TmpVal += ener;
        predGainCB = (Ipp16s)(TmpVal>>16);
        if(rate == IPP_SPCHBR_7400) TmpVal = predGainCB * 5439;
        else                        TmpVal = predGainCB * 5443;
        TmpVal >>= 7;
        Unpack_32s(TmpVal, expGainCodeCB, fracGainCodeCB);
    }
    return;
    /* End of ownPredEnergyMA_GSMAMR() */
}
/*************************************************************************
*  Function:   ownCloseLoopFracPitchSearch_GSMAMR
***************************************************************************/
Ipp32s ownCloseLoopFracPitchSearch_GSMAMR(Ipp16s *vTimePrevSubframe, Ipp16s *a_GainHistory, IppSpchBitRate rate,
                                       Ipp16s frameOffset, Ipp16s *pLoopPitchLags, Ipp16s *pImpResVec,
                                       Ipp16s *pLTPExc, Ipp16s *pPredRes, Ipp16s *pTargetPitchVec, Ipp16s lspFlag,
                                       Ipp16s *pTargetVec, Ipp16s *pFltAdaptExc, Ipp16s *pExpPitchDel,
                                       Ipp16s *pFracPitchDel, Ipp16s *gainPitch, Ipp16s **ppAnalysisParam,
                                       Ipp16s *gainPitchLimit)
{
    Ipp16s i;
    Ipp16s index;
    Ipp32s TmpVal;
    Ipp16s subfrNum;
    Ipp16s sum = 0;

    subfrNum = (Ipp16s)(frameOffset / SUBFR_SIZE_GSMAMR);
    ippsAdaptiveCodebookSearch_GSMAMR_16s(pTargetPitchVec, pImpResVec, pLoopPitchLags,
                                          vTimePrevSubframe, (pLTPExc - MAX_OFFSET),
                                          pFracPitchDel, &index, pFltAdaptExc, subfrNum, rate);

    ippsConvPartial_16s_Sfs(pLTPExc, pImpResVec, pFltAdaptExc, SUBFR_SIZE_GSMAMR, 12);

    *pExpPitchDel = *vTimePrevSubframe;
    *(*ppAnalysisParam)++ = index;

    ippsAdaptiveCodebookGain_GSMAMR_16s(pTargetPitchVec, pFltAdaptExc, gainPitch);

    if(rate == IPP_SPCHBR_12200) *gainPitch &= 0xfffC;

    *gainPitchLimit = IPP_MAX_16S;
    if((lspFlag != 0) && (*gainPitch > PITCH_GAIN_CLIP)) {
       ippsSum_16s_Sfs(a_GainHistory, PG_NUM_FRAME, &sum, 0);
       sum = (Ipp16s)(sum + (*gainPitch >> 3));          /* Division by 8 */
       if(sum > PITCH_GAIN_CLIP) *gainPitchLimit = PITCH_GAIN_CLIP;
    }

   if ((rate == IPP_SPCHBR_4750) || (rate == IPP_SPCHBR_5150)) {
      if(*gainPitch > 13926) *gainPitch = 13926;
   } else {
       if(sum > PITCH_GAIN_CLIP) *gainPitch = PITCH_GAIN_CLIP;

       if(rate == IPP_SPCHBR_12200) {
           index = ownQntGainPitch_M122_GSMAMR(*gainPitchLimit, *gainPitch);
           *gainPitch = (Ipp16s)(TableQuantGainPitch[index] & 0xFFFC);
           *(*ppAnalysisParam)++ = index;
       }
   }

   /* update target vector und evaluate LTP residual

      Algorithmically is equivalent to :

      ippsMulC_16s_Sfs(pFltAdaptExc,*gainPitch,y1Tmp,SUBFR_SIZE_GSMAMR,14);
      ippsMulC_16s_Sfs(pLTPExc,*gainPitch,excTmp,SUBFR_SIZE_GSMAMR,14);
      ippsSub_16s(y1Tmp,pTargetPitchVec,pTargetVec,SUBFR_SIZE_GSMAMR);
      ippsSub_16s_I(excTmp,pPredRes,SUBFR_SIZE_GSMAMR);

      But !!! could not be used due to bitexactness.
   */

   for (i = 0; i < SUBFR_SIZE_GSMAMR; i++) {
       TmpVal = pFltAdaptExc[i] * *gainPitch;
       pTargetVec[i] = (Ipp16s)(pTargetPitchVec[i] - (Ipp16s)(TmpVal >> 14));

       TmpVal = pLTPExc[i] * *gainPitch;
       pPredRes[i] = (Ipp16s)(pPredRes[i] - (Ipp16s)(TmpVal >> 14));
   }

   return 0;
   /* End of ownCloseLoopFracPitchSearch_GSMAMR() */
}

⌨️ 快捷键说明

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