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

📄 sp_dec.c

📁 GSM中半速率语音编解码源码
💻 C
📖 第 1 页 / 共 5 页
字号:

    swEngyLShft = norm_l(L_sum);
    *pL_out = L_shl(L_sum, swEngyLShft);        /* normalize output
                                                 * Longword */
  }
  else
  {

    /* Special case: energy is zero */
    /*------------------------------*/

    *pL_out = L_sum;
    swEngyLShft = 0;
  }

  return (swEngyLShft);
}

/***************************************************************************
 *
 *    FUNCTION NAME: g_corr1s (g_corr1 with scaling)
 *
 *    PURPOSE:
 *
 *     Calculates energy in subframe vector.  Differs from g_corr1,
 *     in that there is an estimate of the maximum possible energy in the
 *     vector.
 *
 *    INPUT:
 *
 *       pswIn[0:39]
 *                     A subframe vector.
 *
 *       swEngyRShft
 *
 *                     Number of right shifts to apply to the vectors energy
 *                     to ensure that it remains less than 1.0
 *                     (swEngyRShft is always positive or zero)
 *
 *    OUTPUT:
 *
 *       *pL_out
 *                     A Longword containing the normalized energy
 *                     in the input vector.
 *
 *    RETURN:
 *
 *       swOut
 *                     Number of right shifts which the accumulator was
 *                     shifted to normalize it.  Negative number implies
 *                     a left shift, and therefore an energy larger than
 *                     1.0.
 *
 *    REFERENCES: Sub-Clause 4.1.8, 4.2.1, 4.2.2, and 4.2.4
 *                of GSM Recomendation 06.20
 *
 *    keywords: energy, autocorrelation, correlation, g_corr1
 *
 *
 *************************************************************************/

Shortword g_corr1s(Shortword pswIn[], Shortword swEngyRShft,
                          Longword *pL_out)
{


/*_________________________________________________________________________
 |                                                                         |
 |                            Automatic Variables                          |
 |_________________________________________________________________________|
*/

  Longword L_sum;
  Shortword swTemp,
         swEngyLShft;
  Shortword swInputRShft;

  int    i;


/*_________________________________________________________________________
 |                                                                         |
 |                              Executable Code                            |
 |_________________________________________________________________________|
*/


  /* Calculate energy in subframe vector (40 samples) */
  /*--------------------------------------------------*/

  if (sub(swEngyRShft, 1) <= 0)
  {

    /* use the energy shift factor, although it is an odd shift count */
    /*----------------------------------------------------------------*/

    swTemp = shr(pswIn[0], swEngyRShft);
    L_sum = L_mult(pswIn[0], swTemp);
    for (i = 1; i < S_LEN; i++)
    {
      swTemp = shr(pswIn[i], swEngyRShft);
      L_sum = L_mac(L_sum, pswIn[i], swTemp);
    }

  }
  else
  {

    /* convert energy shift factor to an input shift factor */
    /*------------------------------------------------------*/

    swInputRShft = shift_r(swEngyRShft, -1);
    swEngyRShft = shl(swInputRShft, 1);

    swTemp = shr(pswIn[0], swInputRShft);
    L_sum = L_mult(swTemp, swTemp);
    for (i = 1; i < S_LEN; i++)
    {
      swTemp = shr(pswIn[i], swInputRShft);
      L_sum = L_mac(L_sum, swTemp, swTemp);
    }
  }

  if (L_sum != 0)
  {

    /* Normalize the energy in the output Longword */
    /*---------------------------------------------*/

    swTemp = norm_l(L_sum);
    *pL_out = L_shl(L_sum, swTemp);    /* normalize output Longword */
    swEngyLShft = sub(swTemp, swEngyRShft);
  }
  else
  {

    /* Special case: energy is zero */
    /*------------------------------*/

    *pL_out = L_sum;
    swEngyLShft = 0;
  }

  return (swEngyLShft);
}

/***************************************************************************
 *
 *   FUNCTION NAME: getSfrmLpc
 *
 *   PURPOSE:
 *
 *     Given frame information from past and present frame, interpolate
 *     (or copy) the frame based LPC coefficients into subframe
 *     lpc coeffs, i.e. the ones which will be used by the subframe
 *     as opposed to those coded and transmitted.
 *
 *   INPUTS:
 *
 *     siSoftInterpolation
 *
 *                     interpolate 1/0, a coded parameter.
 *
 *     swPrevR0,swNewR0
 *
 *                     Rq0 for the last frame and for this frame.
 *                     These are the decoded values, not the codewords.
 *
 *     Previous lpc coefficients from the previous frame:
 *       in all filters below array[0] is the t=-1 element array[9]
 *       t=-10 element.
 *
 *     pswPrevFrmKs[0:9]
 *
 *                     decoded version of the rc's tx'd last frame
 *
 *     pswPrevFrmAs[0:9]
 *
 *                     the above K's converted to A's.  i.e. direct
 *                     form coefficients.
 *
 *     pswPrevFrmPFNum[0:9], pswPrevFrmPFDenom[0:9]
 *
 *                     numerator and denominator coefficients used in the
 *                     postfilter
 *
 *     Current lpc coefficients from the current frame:
 *
 *     pswNewFrmKs[0:9], pswNewFrmAs[0:9],
 *     pswNewFrmPFNum[0:9], pswNewFrmPFDenom[0:9] same as above.
 *
 *   OUTPUTS:
 *
 *     psnsSqrtRs[0:3]
 *
 *                      a normalized number (struct NormSw)
 *                      containing an estimate of RS for each subframe.
 *                      (number and a shift)
 *
 *     ppswSynthAs[0:3][0:9]
 *
 *                      filter coefficients used by the synthesis filter.
 *
 *     ppswPFNumAs[0:3][0:9]
 *
 *                      filter coefficients used by the postfilters
 *                      numerator.
 *
 *     ppswPFDenomAs[0:3][0:9]
 *
 *                      filter coefficients used by postfilters denominator.
 *
 *   RETURN VALUE:
 *
 *     None
 *
 *   DESCRIPTION:
 *
 *     For interpolated subframes, the direct form coefficients
 *     are converted to reflection coeffiecients to check for
 *     filter stability. If unstable, the uninterpolated coef.
 *     are used for that subframe.
 *
 *     Interpolation is described in section 4.1.6, "Soft Interpolation
 *     of the Spectral Parameters"
 *
 *    REFERENCES: Sub_clause 4.2.1 of GSM Recomendation 06.20
 *
 *   KEYWORDS: soft interpolation, int_lpc, interpolate, atorc,res_eng,i_mov
 *
 *************************************************************************/

void   getSfrmLpc(short int siSoftInterpolation,
                         Shortword swPrevR0, Shortword swNewR0,
          /* last frm */ Shortword pswPrevFrmKs[], Shortword pswPrevFrmAs[],
                         Shortword pswPrevFrmPFNum[],
                         Shortword pswPrevFrmPFDenom[],

            /* this frm */ Shortword pswNewFrmKs[], Shortword pswNewFrmAs[],
                         Shortword pswNewFrmPFNum[],
                         Shortword pswNewFrmPFDenom[],

                   /* output */ struct NormSw *psnsSqrtRs,
                         Shortword *ppswSynthAs[], Shortword *ppswPFNumAs[],
                         Shortword *ppswPFDenomAs[])
{

/*_________________________________________________________________________
 |                                                                         |
 |                           Local Static Variables                        |
 |_________________________________________________________________________|
*/


/*_________________________________________________________________________
 |                                                                         |
 |                            Automatic Variables                          |
 |_________________________________________________________________________|
*/

  short int siSfrm,
         siStable,
         i;

  Longword L_Temp1,
         L_Temp2;

/*_________________________________________________________________________
 |                                                                         |
 |                              Executable Code                            |
 |_________________________________________________________________________|
*/

  if (siSoftInterpolation)
  {
    /* yes, interpolating */
    /* ------------------ */

    siSfrm = 0;

    siStable = interpolateCheck(pswPrevFrmKs, pswPrevFrmAs,
                                pswPrevFrmAs, pswNewFrmAs,
                                psrOldCont[siSfrm], psrNewCont[siSfrm],
                                swPrevR0,
                                &psnsSqrtRs[siSfrm],
                                ppswSynthAs[siSfrm]);
    if (siStable)
    {

      /* interpolate between direct form coefficient sets */
      /* for both numerator and denominator coefficients  */
      /* assume output will be stable                     */
      /* ------------------------------------------------ */

      for (i = 0; i < NP; i++)
      {
        L_Temp1 = L_mult(pswNewFrmPFNum[i], psrNewCont[siSfrm]);
        ppswPFNumAs[siSfrm][i] = mac_r(L_Temp1, pswPrevFrmPFNum[i],
                                       psrOldCont[siSfrm]);
        L_Temp2 = L_mult(pswNewFrmPFDenom[i], psrNewCont[siSfrm]);
        ppswPFDenomAs[siSfrm][i] = mac_r(L_Temp2, pswPrevFrmPFDenom[i],
                                         psrOldCont[siSfrm]);
      }
    }
    else
    {
      /* this subframe is unstable */
      /* ------------------------- */
      for (i = 0; i < NP; i++)
      {
        ppswPFNumAs[siSfrm][i] = pswPrevFrmPFNum[i];
        ppswPFDenomAs[siSfrm][i] = pswPrevFrmPFDenom[i];
      }
    }
    for (siSfrm = 1; siSfrm < N_SUB - 1; siSfrm++)
    {

      siStable = interpolateCheck(pswNewFrmKs, pswNewFrmAs,
                                  pswPrevFrmAs, pswNewFrmAs,
                                  psrOldCont[siSfrm], psrNewCont[siSfrm],
                                  swNewR0,
                                  &psnsSqrtRs[siSfrm],
                                  ppswSynthAs[siSfrm]);
      if (siStable)
      {

        /* interpolate between direct form coefficient sets */
        /* for both numerator and denominator coefficients  */
        /* assume output will be stable                     */
        /* ------------------------------------------------ */

        for (i = 0; i < NP; i++)
        {
          L_Temp1 = L_mult(pswNewFrmPFNum[i], psrNewCont[siSfrm]);
          ppswPFNumAs[siSfrm][i] = mac_r(L_Temp1, pswPrevFrmPFNum[i],
                                         psrOldCont[siSfrm]);
          L_Temp2 = L_mult(pswNewFrmPFDenom[i], psrNewCont[siSfrm]);
          ppswPFDenomAs[siSfrm][i] = mac_r(L_Temp2, pswPrevFrmPFDenom[i],
                                           psrOldCont[siSfrm]);
        }
      }
      else
      {
        /* this subframe has unstable filter coeffs, would like to
         * interpolate but can not  */
        /* -------------------------------------- */
        for (i = 0; i < NP; i++)
        {
          ppswPFNumAs[siSfrm][i] = pswNewFrmPFNum[i];
          ppswPFDenomAs[siSfrm][i] = pswNewFrmPFDenom[i];
        }
      }
    }
    /* the last subframe never interpolate */
    /* ----------------------------------- */
    siSfrm = 3;
    for (i = 0; i < NP; i++)
    {
      ppswPFNumAs[siSfrm][i] = pswNewFrmPFNum[i];
      ppswPFDenomAs[siSfrm][i] = pswNewFrmPFDenom[i];
      ppswSynthAs[siSfrm][i] = pswNewFrmAs[i];
    }

    res_eng(pswNewFrmKs, swNewR0, &psnsSqrtRs[siSfrm]);

  }
  /* SoftInterpolation == 0  - no interpolation */
  /* ------------------------------------------ */
  else
  {
    siSfrm = 0;
    for (i = 0; i < NP; i++)
    {
      ppswPFNumAs[siSfrm][i] = pswPrevFrmPFNum[i];
      ppswPFDenomAs[siSfrm][i] = pswPrevFrmPFDenom[i];
      ppswSynthAs[siSfrm][i] = pswPrevFrmAs[i];
    }

    res_eng(pswPrevFrmKs, swPrevR0, &psnsSqrtRs[siSfrm]);

    /* for subframe 1 and all subsequent sfrms, use result from new frm */
    /* ---------------------------------------------------------------- */


    res_eng(pswNewFrmKs, swNewR0, &psnsSqrtRs[1]);

    for (siSfrm = 1; siSfrm < N_SUB; siSfrm++)
    {


      psnsSqrtRs[siSfrm].man = psnsSqrtRs[1].man;
      psnsSqrtRs[siSfrm].sh = psnsSqrtRs[1].sh;

      for (i = 0; i < NP; i++)
      {
        ppswPFNumAs[siSfrm][i] = pswNewFrmPFNum[i];
        ppswPFDenomAs[siSfrm][i] = pswNewFrmPFDenom[i];
        ppswSynthAs[siSfrm][i] = pswNewFrmAs[i];
      }
    }
  }
}

/***************************************************************************
 *
 *   FUNCTION NAME: get_ipjj
 *
 *   PURPOSE:
 *
 *     This subroutine calculates IP, the single-resolution lag rounded
 *     down to the nearest integer, and JJ, the remainder when the

⌨️ 快捷键说明

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