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

📄 utilgsmamr.c

📁 G.711,G.723.1,G.726,G.729,GSM CODEC C/C++ code
💻 C
📖 第 1 页 / 共 3 页
字号:
   prevVoiced = 0;
   if(ownGetMedianElements_GSMAMR(&ltpGainHist[4], 5) > ltpLimit) prevVoiced = 1;
   if(*vCountHangover > 20) {
      if(ownGetMedianElements_GSMAMR(ltpGainHist, 9) > ltpLimit)  prevVoiced = 1;
      else                                                        prevVoiced = 0;
   }

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

   return inbgNoise;
   /* End of ownSourceChDetectorUpdate_GSMAMR() */
}
/*************************************************************************
 Function: ownCalcUnFiltEnergy_GSMAMR
 *************************************************************************/
void ownCalcUnFiltEnergy_GSMAMR(short *pLPResVec, short *pLTPExc, short *code, short gainPitch,
                                short lenSubfr, short *fracEnergyCoeff, short *expEnergyCoeff, short *ltpg)
{
    int s, TmpVal;
    short i, exp, tmp;
    short ltp_res_en, pred_gain;
    short 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] = (short)(s >> 16);
        expEnergyCoeff[0] = 15 - exp;
    }

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

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

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

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

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

        if(exp < -3) ShiftL_32s(TmpVal, (short)(-(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, short *pTargetPitchVec, short *pTargetVec,
                              short *pFltAdaptExc, short *pFltVec, short *fracEnergyCoeff,
                              short *expEnergyCoeff, short *optFracCodeGain, short *optExpCodeGain)
{
    short g_coeff[4];
    int s, ener_init=1;
    short exp, frac;
    short pFltVecTmp[SUBFR_SIZE_GSMAMR];
    short 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 */
    expEnergyCoeff[1]  = g_coeff[3] + 1;

    ippsDotProd_16s32s_Sfs(pFltVecTmp, pFltVecTmp, SUBFR_SIZE_GSMAMR, &s, -1);
    s += ener_init;
    exp = Norm_32s_I(&s);
    fracEnergyCoeff[2] = (short)(s >> 16);
    expEnergyCoeff[2] = -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;
    expEnergyCoeff[3] = 7 - exp;

    ippsDotProd_16s32s_Sfs(pFltAdaptExc, pFltVecTmp, SUBFR_SIZE_GSMAMR, &s, -1);
    s += ener_init;
    exp = Norm_32s_I(&s);
    fracEnergyCoeff[4] = (short)(s >> 16);
    expEnergyCoeff[4] = 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 = (short)(s >> 16);
        exp = 6 - exp;

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

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

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

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

   short i,j;
   short aState[LP_ORDER_SIZE];
   short bState[LP_ORDER_SIZE];
   short normShift, normProd;
   short scale, temp, mult;
   int const1;
   int 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] = aState[i] << 3;
      TmpVal1 = 2 * pReflCoeff[i] * pReflCoeff[i];
      TmpVal = IPP_MAX_32S - TmpVal1;
      normShift = Norm_32s_Pos_I(&TmpVal);
      scale = 14 - normShift;
      normProd = Cnvrt_NR_32s16s(TmpVal);
      mult = (16384 << 15) / normProd;
      const1 = 1<<(scale - 1);

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

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

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

ExitRefl:
   ippsZero_16s(pReflCoeff, LP_ORDER_SIZE);
}
/**************************************************************************
*  Function    : ownScaleExcitation_GSMAMR
***************************************************************************/
void ownScaleExcitation_GSMAMR(short *pInputSignal, short *pOutputSignal)
{
    short exp;
    short gain_in, gain_out, g0;
    int i, s;
    short 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 = 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 -= i;
        s = ((gain_out << 15) / gain_in);
        s = ShiftL_32s(s, 7);
        if (exp < 0) s = ShiftL_32s(s, (unsigned short)(-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] = (short)(Mul16_32s(pOutputSignal[i] * g0) >> 16);

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

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

/*************************************************************************
 * Function:  ownPredEnergyMA_GSMAMR()
 *************************************************************************/
void ownPredEnergyMA_GSMAMR(short *a_PastQntEnergy, short *a_PastQntEnergy_M122, IppSpchBitRate rate,
                            short *code, short *expGainCodeCB, short *fracGainCodeCB, short *expEnergyCoeff,
                            short *fracEnergyCoeff)
{
    int ener_code, ener;
    short 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 */
        L_Extract(ener, expGainCodeCB, fracGainCodeCB);
    } else {
        int TmpVal;
        short exp_code, predGainCB;

        exp_code = Norm_32s_I(&ener_code);
        ownLog2_GSMAMR_norm (ener_code, exp_code, &exp, &frac);
        TmpVal = Mul16s_32s(exp, frac, -24660);
        if(rate == IPP_SPCHBR_10200) TmpVal += 2 * 16678 * 64;
        else if (rate == IPP_SPCHBR_7950) {
           *fracEnergyCoeff = (short) (ener_code>>16);
           *expEnergyCoeff = -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 = (short)(TmpVal>>16);
        if(rate == IPP_SPCHBR_7400) TmpVal = predGainCB * 5439;
        else                        TmpVal = predGainCB * 5443;
        TmpVal >>= 7;
        L_Extract(TmpVal, expGainCodeCB, fracGainCodeCB);
    }
    return;
    /* End of ownPredEnergyMA_GSMAMR() */
}
/*************************************************************************
*  Function:   ownCloseLoopFracPitchSearch_GSMAMR
***************************************************************************/
int ownCloseLoopFracPitchSearch_GSMAMR(short *vTimePrevSubframe, short *a_GainHistory, IppSpchBitRate rate,
                                       short frameOffset, short *pLoopPitchLags, short *pImpResVec,
                                       short *pLTPExc, short *pPredRes, short *pTargetPitchVec, short lspFlag,
                                       short *pTargetVec, short *pFltAdaptExc, short *pExpPitchDel,
                                       short *pFracPitchDel, short *gainPitch, short **ppAnalysisParam,
                                       short *gainPitchLimit)
{
    short i;
    short index;
    int TmpVal;
    short subfrNum;
    short sum = 0;

    subfrNum = 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 += *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 = 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] = pTargetPitchVec[i] - (short)(TmpVal >> 14);

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

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

⌨️ 快捷键说明

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