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

📄 utilgsmamr.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 1 页 / 共 3 页
字号:
/*/////////////////////////////////////////////////////////////////////////////
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//          Copyright(c) 2005-2007 Intel Corporation. All Rights Reserved.
//
//     Intel(R) Integrated Performance Primitives
//     USC - Unified Speech Codec interface library
//
// By downloading and installing USC codec, you hereby agree that the
// accompanying Materials are being provided to you under the terms and
// conditions of the End User License Agreement for the Intel(R) Integrated
// Performance Primitives product previously accepted by you. Please refer
// to the file ippEULA.rtf or ippEULA.txt located in the root directory of your Intel(R) IPP
// product installation for more information.
//
// A speech coding standards promoted by ITU, ETSI, 3GPP and other
// organizations. Implementations of these standards, or the standard enabled
// platforms may require licenses from various entities, including
// Intel Corporation.
//
//
// Purpose: GSMAMR speech codec: common utilities.
//
*/

#include "owngsmamr.h"

/****************************************************************************
 *  Function: ownVADPitchDetection_GSMAMR()
 ***************************************************************************/
void ownVADPitchDetection_GSMAMR(IppGSMAMRVad1State *st, Ipp16s *pTimeVec,
                                 Ipp16s *vLagCountOld, Ipp16s *vLagOld)
{
   Ipp16s lagcount, i;
   lagcount = 0;

   for (i = 0; i < 2; i++) {
      if(Abs_16s(*vLagOld - pTimeVec[i]) < LOW_THRESHOLD) lagcount++;
      *vLagOld = pTimeVec[i];
   }

   st->pitchFlag >>= 1;
   if (*vLagCountOld + lagcount >= NUM_THRESHOLD)
      st->pitchFlag = (Ipp16s)(st->pitchFlag | 0x4000);

   *vLagCountOld = lagcount;
}

/***************************************************************************
 *   Function: ownUpdateLTPFlag_GSMAMR()
 *************************************************************************/
void ownUpdateLTPFlag_GSMAMR(IppSpchBitRate rate, Ipp32s L_Rmax, Ipp32s L_R0, Ipp16s *vFlagLTP)
{
    Ipp16s thresh;
    Ipp16s hi1;
    Ipp16s lo1;
    Ipp32s Ltmp;

    if ((rate == IPP_SPCHBR_4750) || (rate == IPP_SPCHBR_5150)) thresh = 18022;
    else if (rate == IPP_SPCHBR_10200) thresh = 19660;
    else thresh = 21299;

    hi1 = (Ipp16s)(L_R0 >> 16);
    lo1 = (Ipp16s)((L_R0 >> 1) & 0x7fff);
    Ltmp = (hi1 * thresh +  ((lo1 * thresh) >> 15));
    if (L_Rmax > 2*Ltmp) *vFlagLTP = 1;
    else                 *vFlagLTP = 0;

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

static __ALIGN32 CONST Ipp16s TableLog2[33] = {
     0,  1455,  2866,  4236,  5568,  6863,  8124,  9352,
 10549, 11716, 12855, 13967, 15054, 16117, 17156, 18172,
 19167, 20142, 21097, 22033, 22951, 23852, 24735, 25603,
 26455, 27291, 28113, 28922, 29716, 30497, 31266, 32023,
 32767 };

 /*************************************************************************
 * Function:   ownLog2_GSMAMR_norm
 *************************************************************************/
void ownLog2_GSMAMR_norm(Ipp32s inVal, Ipp16s exp, Ipp16s *expPart, Ipp16s *fracPart)
{
  Ipp16s idx, a, tmp;
  Ipp32s outVal;

  if( inVal <= 0 ) {
    *expPart = 0;
    *fracPart = 0;
    return;
  }

  *expPart = (Ipp16s)(30 - exp);
  idx = (Ipp16s)(inVal >> 25);
  a = (Ipp16s)((inVal >> 10) & 0x7fff);
  idx   -=  32;

  outVal = TableLog2[idx] << 16;
  tmp = (Ipp16s)(TableLog2[idx] - TableLog2[idx+1]);
  outVal -= 2 * tmp * a;

  *fracPart =  (Ipp16s)(outVal >> 16);

  return;
  /* End of ownLog2_GSMAMR_norm() */
}
/*************************************************************************
 *  Function:  ownLog2_GSMAMR()
 *************************************************************************/
void ownLog2_GSMAMR(Ipp32s inVal, Ipp16s *expPart, Ipp16s *fracPart)
{
  Ipp16s exp;

  exp = Norm_32s_I(&inVal);
  ownLog2_GSMAMR_norm (inVal, exp, expPart, fracPart);

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

/*************************************************************************
 *  Function:  ownPow2_GSMAMR
 *************************************************************************/
static __ALIGN32 CONST Ipp16s TablePow2[33] = {
 16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066,
 19484, 19911, 20347, 20792, 21247, 21713, 22188, 22674,
 23170, 23678, 24196, 24726, 25268, 25821, 26386, 26964,
 27554, 28158, 28774, 29405, 30048, 30706, 31379, 32066,
 32767 };

Ipp32s ownPow2_GSMAMR(Ipp16s expPart, Ipp16s fracPart)
{
  Ipp16s exp, idx, a, tmp;
  Ipp32s inVal, outVal, temp;

  exp = (Ipp16s)(30 - expPart);
  if (exp > 31) return 0;
  idx = (Ipp16s)(fracPart >> 10);
  a   = (Ipp16s)((fracPart << 5) & 0x7fff);

  inVal = TablePow2[idx] << 16;
  tmp = (Ipp16s)(TablePow2[idx] - TablePow2[idx+1]);
  inVal = inVal - 2*tmp*a;

  if (exp >= 31) outVal = (inVal < 0) ? -1 : 0;
  else           outVal = inVal >> exp;

  temp = 1 << (exp-1);
  if(inVal & temp) outVal++;

  return(outVal);
  /* End of ownPow2_GSMAMR() */
}

/* table[i] = sqrt((i+16)*2^-6) * 2^15, i.e. sqrt(x) scaled Q15 */
static __ALIGN32 CONST Ipp16s TableSqrt[49] =
{
 16384, 16888, 17378, 17854, 18318, 18770, 19212, 19644,
 20066, 20480, 20886, 21283, 21674, 22058, 22435, 22806,
 23170, 23530, 23884, 24232, 24576, 24915, 25249, 25580,
 25905, 26227, 26545, 26859, 27170, 27477, 27780, 28081,
 28378, 28672, 28963, 29251, 29537, 29819, 30099, 30377,
 30652, 30924, 31194, 31462, 31727, 31991, 32252, 32511,
 32767};

/********************************************************************************
 *  Function: ownSqrt_Exp_GSMAMR()
 ********************************************************************************/

Ipp32s ownSqrt_Exp_GSMAMR (Ipp32s inVal, Ipp16s *exp)
{
    Ipp16s idx, a, tmp;
    Ipp32s outVal;

    if (inVal <= 0) { *exp = 0; return 0; }

    outVal = inVal;
    *exp = (Ipp16s)(Norm_32s_I(&outVal) & 0xFFFE);
    inVal <<= *exp;

    idx = (Ipp16s)(inVal >> 25);
    a = (Ipp16s)((inVal >> 10) & 0x7fff);

    idx -= 16;
    outVal = TableSqrt[idx] << 16;
    tmp = (Ipp16s)(TableSqrt[idx] - TableSqrt[idx+1]);
    outVal = outVal - 2*tmp*a;

    return (outVal);
    /* End of ownSqrt_Exp_GSMAMR() */
}

/*************************************************************************
 *  Function: Reorder_lsf()
 *************************************************************************/
void ownReorderLSFVec_GSMAMR(Ipp16s *lsf, Ipp16s minDistance, Ipp16s len)
{
    Ipp32s i;
    Ipp16s lsf_min;

    lsf_min = minDistance;

    for (i = 0; i < len; i++)  {
        if(lsf[i] < lsf_min) lsf[i] = lsf_min;
        lsf_min = (Ipp16s)(lsf[i] + minDistance);
    }
}
/*************************************************************************
 *  Function: ownGetMedianElements_GSMAMR()
 *************************************************************************/
Ipp16s ownGetMedianElements_GSMAMR (Ipp16s *pPastGainVal, Ipp16s num)
{
    Ipp16s i, j, idx = 0;
    Ipp16s max;
    Ipp16s medianIndex;
    Ipp16s tmp[MAX_MED_SIZE];
    Ipp16s tmp2[MAX_MED_SIZE];

    ippsCopy_16s(pPastGainVal, tmp2, num);

    for (i = 0; i < num; i++) {
        max = -32767;
        for (j = 0; j < num; j++)  {
            if (tmp2[j] >= max) {
                max = tmp2[j];
                idx = j;
            }
        }
        tmp2[idx] = -32768;
        tmp[i] = idx;
    }
    medianIndex = tmp[num >> 1];

    return (pPastGainVal[medianIndex]);
}
/**************************************************************************
*  Proc: ownCtrlDetectBackgroundNoise_GSMAMR()  -
***************************************************************************/
Ipp16s ownCtrlDetectBackgroundNoise_GSMAMR (Ipp16s excitation[], Ipp16s excEnergy, Ipp16s exEnergyHist[],
                                           Ipp16s vVoiceHangover, Ipp16s prevBFI, Ipp16s carefulFlag)
{
   Ipp16s exp;
   Ipp16s testEnergy, scaleFactor, avgEnergy, prevEnergy;
   Ipp32s t0;

   avgEnergy = ownGetMedianElements_GSMAMR(exEnergyHist, 9);
   prevEnergy = (Ipp16s)((exEnergyHist[7] + exEnergyHist[8]) >> 1);

   if( exEnergyHist[8] < prevEnergy) prevEnergy = exEnergyHist[8];

   if( excEnergy < avgEnergy && excEnergy > 5) {
      testEnergy = (Ipp16s)(prevEnergy << 2);

      if( vVoiceHangover < 7 || prevBFI != 0 ) testEnergy = (Ipp16s)(testEnergy - prevEnergy);
      if( avgEnergy > testEnergy) avgEnergy = testEnergy;

      exp = 0;
      for(; excEnergy < 0x4000; exp++) excEnergy <<= 1;
      excEnergy = (Ipp16s)((16383<<15)/excEnergy);
      t0 = avgEnergy * excEnergy;
      t0 >>= 19 - exp;
      if(t0 > 32767)  t0 = 32767;
      scaleFactor = (Ipp16s)t0;

      if((carefulFlag != 0) && (scaleFactor > 3072))  scaleFactor = 3072;

      ippsMulC_16s_ISfs(scaleFactor, excitation, SUBFR_SIZE_GSMAMR, 10);
   }

   return 0;
}
/*************************************************************************
 *  Function: ownComputeCodebookGain_GSMAMR
 *************************************************************************/
Ipp16s ownComputeCodebookGain_GSMAMR (Ipp16s *pTargetVec, Ipp16s *pFltVec)
{
    Ipp16s i;
    Ipp16s xy, yy, exp_xy, exp_yy, gain;
    IPP_ALIGNED_ARRAY(16, Ipp16s, pFltVecScale, SUBFR_SIZE_GSMAMR);
    Ipp32s s;

    ippsRShiftC_16s(pFltVec, 1, pFltVecScale, SUBFR_SIZE_GSMAMR);
    ippsDotProd_16s32s_Sfs(pTargetVec, pFltVecScale, SUBFR_SIZE_GSMAMR, &s, 0);

    if(s == 0) s = 1;
    s <<= 1;
    exp_xy = Norm_32s_I(&s);
    xy = (Ipp16s)(s >> 16);
    if(xy <= 0) return ((Ipp16s) 0);

    ippsDotProd_16s32s_Sfs(pFltVecScale, pFltVecScale, SUBFR_SIZE_GSMAMR, &s, -1);

    exp_yy = Norm_32s_I(&s);
    yy = (Ipp16s)(s >> 16);
    xy >>= 1;
    //gain = (yy > 0)? (xy<<15)/yy : IPP_MAX_16S;
    if(yy > 0) gain = (Ipp16s)((xy<<15)/yy);
    else gain = IPP_MAX_16S;

    i = (Ipp16s)(exp_xy + 5);
    i = (Ipp16s)(i - exp_yy);
    gain = (Ipp16s)((gain >> i) << 1);

    return (gain);
}
/*************************************************************************
 *  Function: ownGainAdaptAlpha_GSMAMR
 *************************************************************************/
void ownGainAdaptAlpha_GSMAMR(Ipp16s *vOnSetQntGain, Ipp16s *vPrevAdaptOut, Ipp16s *vPrevGainZero,
                              Ipp16s *a_LTPHistoryGain, Ipp16s ltpg, Ipp16s gainCode, Ipp16s *alpha)
{
    Ipp16s adapt;
    Ipp16s result;
    Ipp16s filt;
    Ipp16s tmp, i;
    Ipp32s temp;

    if (ltpg <= LTP_GAIN_LOG10_1) adapt = 0;
    else if (ltpg <= LTP_GAIN_LOG10_2) adapt = 1;
    else adapt = 2;

    tmp = (Ipp16s)(gainCode >> 1);
    if (gainCode & 1) tmp++;

    if (tmp > *vPrevGainZero && gainCode > 200) *vOnSetQntGain = 8;
    else if (*vOnSetQntGain != 0) *vOnSetQntGain -= 1;

    if ((*vOnSetQntGain != 0) && (adapt < 2)) adapt += 1;

    a_LTPHistoryGain[0] = ltpg;
    filt = ownGetMedianElements_GSMAMR(a_LTPHistoryGain, 5);

    if(adapt == 0) {
       if (filt > 5443)   result = 0;
       else if (filt < 0)  result = 16384;
       else {
           temp = (24660 * filt)>>13;
           result = (Ipp16s)(16384 - temp);
       }
    } else result = 0;

    if (*vPrevAdaptOut == 0) result >>= 1;
    *alpha = result;

    *vPrevAdaptOut = result;
    *vPrevGainZero = gainCode;

    for (i = NUM_MEM_LTPG-1; i > 0; i--)
        a_LTPHistoryGain[i] = a_LTPHistoryGain[i-1];

}
/**************************************************************************
*  Function: ownCBGainAverage_GSMAMR()
**************************************************************************/
Ipp16s ownCBGainAverage_GSMAMR(Ipp16s *a_GainHistory, Ipp16s *vHgAverageVar, Ipp16s *vHgAverageCount,
                              IppSpchBitRate rate, Ipp16s gainCode, Ipp16s *lsp, Ipp16s *lspAver,
                              Ipp16s badFrame, Ipp16s vPrevBadFr, Ipp16s potDegBadFrame, Ipp16s vPrevDegBadFr,
                              Ipp16s vBackgroundNoise, Ipp16s vVoiceHangover)
{
   Ipp16s i;
   Ipp16s cbGainMix, diff, bgMix, cbGainMean;
   Ipp32s L_sum;
   Ipp16s tmp[LP_ORDER_SIZE], tmp1, tmp2, shift1, shift2, shift;

   cbGainMix = gainCode;
   for (i = 0; i < (CBGAIN_HIST_SIZE-1); i++)
      a_GainHistory[i] = a_GainHistory[i+1];

   a_GainHistory[CBGAIN_HIST_SIZE-1] = gainCode;

   for (i = 0; i < LP_ORDER_SIZE; i++) {
      tmp1 = (Ipp16s)Abs_16s(lspAver[i] - lsp[i]);
      shift1 = (Ipp16s)(Exp_16s(tmp1) - 1);
      tmp1 <<= shift1;
      shift2 = Exp_16s(lspAver[i]);
      tmp2 = (Ipp16s)(lspAver[i] << shift2);
      //tmp[i] = (tmp2>0)? (tmp1<<15)/tmp2 : IPP_MAX_16S;
      if(tmp2 > 0) tmp[i] = (Ipp16s)((tmp1<<15)/tmp2);

⌨️ 快捷键说明

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