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

📄 sp_frm.c

📁 GSM半数率源代码(VSELP) GSM半数率源代码(VSELP)
💻 C
📖 第 1 页 / 共 5 页
字号:

      /* initialize candidate list */
      /*---------------------------*/

      quantList.iNum = psrPreQSz[iSeg - 1];
      quantList.iRCIndex = 0;

      /* do aflat for all vectors in the list */
      /*--------------------------------------*/

      setupPreQ(iSeg, quantList.iRCIndex);        /* set up vector ptrs */

      for (iCnt = 0; iCnt < quantList.iNum; iCnt++)
      {
        /* get a vector */
        /*--------------*/

        getNextVec(pswRc);

        /* clear the limiter flag */
        /*------------------------*/

        iLimit = 0;

        /* find the error values for each vector */
        /*---------------------------------------*/

        quantList.pswPredErr[iCnt] =
                aflatRecursion(&pswRc[psvqIndex[iSeg - 1].l],
                               pswPBar, pswVBar,
                               ppswPAddrs, ppswVAddrs,
                               psvqIndex[iSeg - 1].len);

        /* check the limiter flag */
        /*------------------------*/

        if (iLimit)
        {
          quantList.pswPredErr[iCnt] = 0x7fff;    /* set error to bad value */
        }

      }                                  /* done list loop */

      /* find 4 best prequantizer levels */
      /*---------------------------------*/

      findBestInQuantList(quantList, 4, bestPql);

      for (iVec = 0; iVec < 4; iVec++)
      {

        /* initialize quantizer list */  
        /*---------------------------*/

        quantList.iNum = psrQuantSz[iSeg - 1];
        quantList.iRCIndex = bestPql[iVec].iRCIndex * psrQuantSz[iSeg - 1];

        setupQuant(iSeg, quantList.iRCIndex);     /* set up vector ptrs */

        /* do aflat recursion on each element of list */
        /*--------------------------------------------*/

        for (iCnt = 0; iCnt < quantList.iNum; iCnt++)
        {

          /* get a vector */
          /*--------------*/

          getNextVec(pswRc);

          /* clear the limiter flag */
          /*------------------------*/

          iLimit = 0;

          /* find the error values for each vector */
          /*---------------------------------------*/

          quantList.pswPredErr[iCnt] =
                  aflatRecursion(&pswRc[psvqIndex[iSeg - 1].l],
                                 pswPBar, pswVBar,
                                 ppswPAddrs, ppswVAddrs,
                                 psvqIndex[iSeg - 1].len);

          /* check the limiter flag */
          /*------------------------*/

          if (iLimit)
          {
            quantList.pswPredErr[iCnt] = 0x7fff;  /* set error to the worst
                                                   * value */
          }

        }                                /* done list loop */

        /* find best quantizer vector for this segment, and save it */
        /*----------------------------------------------------------*/

        findBestInQuantList(quantList, 1, bestQl);
        if (iVec == 0)
        {
          bestQl[iSeg] = bestQl[0];
        }
        else
        {
          if (sub(bestQl[iSeg].pswPredErr[0],
                  bestQl[0].pswPredErr[0]) > 0)
          {
            bestQl[iSeg] = bestQl[0];
          }
        }
      }

      /* find the quantized reflection coefficients */
      /*--------------------------------------------*/

      setupQuant(iSeg, bestQl[iSeg].iRCIndex);    /* set up vector ptrs */
      getNextVec((Shortword *) (pswFinalRc - 1));


      /* Update pBarFull and vBarFull for the next Rc-VQ segment, and */
      /* update the pswPBar and pswVBar for the next Rc-VQ segment    */
      /*--------------------------------------------------------------*/

      if (iSeg < LPC_VQ_SEG)
      {

        aflatNewBarRecursionL(&pswFinalRc[psvqIndex[iSeg - 1].l - 1], iSeg,
                              pL_PBarFull, pL_VBarFull, pswPBar, pswVBar);

      }

    }

    /* find the quantizer index (the values */
    /* to be output in the symbol file)     */
    /*--------------------------------------*/

    for (iSeg = 1; iSeg <= LPC_VQ_SEG; iSeg++)
    {
      piVQCodewds[iSeg - 1] = bestQl[iSeg].iRCIndex;
    }

  }
  
}

/***************************************************************************
 *
 *    FUNCTION NAME: aflatNewBarRecursionL
 *
 *    PURPOSE:  Given the Longword initial condition arrays, pL_PBarFull and
 *              pL_VBarFull, a reflection coefficient vector selected from
 *              the Rc-VQ at the current stage, and index of the current
 *              Rc-VQ stage, the AFLAT recursion is evaluated to obtain the
 *              updated initial conditions for the AFLAT recursion at the
 *              next Rc-VQ stage. At each lattice stage the pL_PBarFull and
 *              pL_VBarFull arrays are shifted to be RSHIFT down from full
 *              scale. Two sets of initial conditions are output:
 *
 *              1) pswPBar and pswVBar Shortword arrays are used at the
 *                 next Rc-VQ segment as the AFLAT initial conditions
 *                 for the Rc prequantizer and the Rc quantizer searches.
 *              2) pL_PBarFull and pL_VBarFull arrays are output and serve
 *                 as the initial conditions for the function call to
 *                 aflatNewBarRecursionL at the next lattice stage.
 *
 *
 *              This is an implementation of equations 4.24 through
 *              4.27.
 *    INPUTS:
 *
 *        pswQntRc[0:NP_AFLAT-1]
 *                     An input reflection coefficient vector selected from
 *                     the Rc-VQ quantizer at the current stage.
 *
 *        iSegment
 *                    An input describing the current Vector quantizer
 *                    quantizer segment (1, 2, or 3).
 *
 *        RSHIFT      The number of shifts down from full scale the
 *                     pL_PBarFull and pL_VBarFull arrays are to be shifted
 *                     at each lattice stage. RSHIFT is a global constant.
 *
 *        pL_PBar[0:NP-1]
 *                     A Longword input array containing the P initial
 *                     conditions for the full 10-th order LPC filter.
 *                     The address of the 0-th element of  pL_PBarFull
 *                     is passed in when function aflatNewBarRecursionL
 *                     is called.
 *
 *        pL_VBar[-NP+1:NP-1]
 *                     A Longword input array containing the V initial
 *                     conditions for the full 10-th order LPC filter.
 *                     The address of the 0-th element of  pL_VBarFull
 *                     is passed in when function aflatNewBarRecursionL
 *                     is called.
 *
 *    OUTPUTS:
 *
 *        pL_PBar[0:NP-1]
 *                     A Longword output array containing the updated P
 *                     initial conditions for the full 10-th order LPC
 *                     filter.
 *
 *        pL_VBar[-NP+1:NP-1]
 *                     A Longword output array containing the updated V
 *                     initial conditions for the full 10-th order LPC
 *                     filter.
 *
 *        pswPBar[0:NP_AFLAT-1]
 *                     An output Shortword array containing the P initial
 *                     conditions for the P-V AFLAT recursion for the next
 *                     Rc-VQ segment. The address of the 0-th element of
 *                     pswVBar is passed in.
 *
 *        pswVBar[-NP_AFLAT+1:NP_AFLAT-1]
 *                     The output Shortword array containing the V initial
 *                     conditions for the P-V AFLAT recursion, for the next
 *                     Rc-VQ segment. The address of the 0-th element of
 *                     pswVBar is passed in.
 *
 *    RETURN:
 *        None.
 *
 *    REFERENCE:  Sub-clause 4.1.4.1 GSM Recommendation 06.20
 *
 *************************************************************************/

void   aflatNewBarRecursionL(Shortword pswQntRc[], int iSegment,
                                    Longword pL_PBar[], Longword pL_VBar[],
                                 Shortword pswPBar[], Shortword pswVBar[])
{

/*_________________________________________________________________________
 |                                                                         |
 |                            Automatic Variables                          |
 |_________________________________________________________________________|
*/
  Longword *pL_VOld,
        *pL_VNew,
        *pL_POld,
        *pL_PNew,
        *ppL_PAddrs[2],
        *ppL_VAddrs[2],
         pL_VOldSpace[2 * NP - 1],
         pL_VNewSpace[2 * NP - 1],
         pL_POldSpace[NP],
         pL_PNewSpace[NP],
         L_temp,
         L_sum;
  Shortword swQntRcSq,
         swNShift;
  short int i,
         j,
         bound;

/*_________________________________________________________________________
 |                                                                         |
 |                              Executable Code                            |
 |_________________________________________________________________________|
*/
  /* Copy the addresses of the input PBar and VBar arrays into  */
  /* pL_POld and pL_VOld respectively.                          */
  /*------------------------------------------------------------*/

  pL_POld = pL_PBar;
  pL_VOld = pL_VBar;

  /* Point to PNew and VNew temporary arrays */
  /*-----------------------------------------*/

  pL_PNew = pL_PNewSpace;
  pL_VNew = pL_VNewSpace + NP - 1;

  /* Load the addresses of the temporary buffers into the address arrays. */
  /* The address arrays are used to swap PNew and POld (VNew and VOLd)    */
  /* buffers to avoid copying of the buffer contents at the end of a      */
  /* lattice filter stage.                                                */
  /*----------------------------------------------------------------------*/

  ppL_PAddrs[0] = pL_POldSpace;
  ppL_PAddrs[1] = pL_PNewSpace;
  ppL_VAddrs[0] = pL_VOldSpace + NP - 1;
  ppL_VAddrs[1] = pL_VNewSpace + NP - 1;


  /* Update AFLAT recursion initial conditions for searching the Rc vector */
  /* quantizer at the next VQ segment.                                     */
  /*-------------------------------------------------------------------*/

  for (j = 0; j < psvqIndex[iSegment - 1].len; j++)
  {
    bound = NP - psvqIndex[iSegment - 1].l - j - 1;

    /* Compute rc squared, used by the recursion at the j-th lattice stage. */
    /*---------------------------------------------------------------------*/

    swQntRcSq = mult_r(pswQntRc[j], pswQntRc[j]);

    /* Calculate PNew(i) */
    /*-------------------*/

    L_temp = L_mpy_ls(pL_VOld[0], pswQntRc[j]);
    L_sum = L_add(L_temp, pL_POld[0]);
    L_temp = L_mpy_ls(pL_POld[0], swQntRcSq);
    L_sum = L_add(L_temp, L_sum);
    L_temp = L_mpy_ls(pL_VOld[0], pswQntRc[j]);
    L_temp = L_add(L_sum, L_temp);

    /* Compute the number of bits to shift left by to achieve  */
    /* the nominal value of PNew[0] which is right shifted by  */
    /* RSHIFT bits relative to full scale.                     */
    /*---------------------------------------------------------*/

    swNShift = sub(norm_s(extract_h(L_temp)), RSHIFT);

    /* Rescale PNew[0] by shifting left by swNShift bits */
    /*---------------------------------------------------*/

    pL_PNew[0] = L_shl(L_temp, swNShift);

    for (i = 1; i <= bound; i++)
    {
      L_temp = L_mpy_ls(pL_VOld[i], pswQntRc[j]);
      L_sum = L_add(L_temp, pL_POld[i]);
      L_temp = L_mpy_ls(pL_POld[i], swQntRcSq);
      L_sum = L_add(L_temp, L_sum);
      L_temp = L_mpy_ls(pL_VOld[-i], pswQntRc[j]);
      L_temp = L_add(L_sum, L_temp);
      pL_PNew[i] = L_shl(L_temp, swNShift);
    }

    /* Calculate VNew(i) */
    /*-------------------*/

    for (i = -bound; i < 0; i++)
    {
      L_temp = L_mpy_ls(pL_VOld[-i - 1], swQntRcSq);
      L_sum = L_add(L_temp, pL_VOld[i + 1]);
      L_temp = L_mpy_ls(pL_POld[-i - 1], pswQntRc[j]);
      L_temp = L_shl(L_temp, 1);
      L_temp = L_add(L_temp, L_sum);
      pL_VNew[i] = L_shl(L_temp, swNShift);
    }
    for (i = 0; i <= bound; i++)
    {
      L_temp = L_mpy_ls(pL_VOld[-i - 1], swQntRcSq);
      L_sum = L_add(L_temp, pL_VOld[i + 1]);
      L_temp = L_mpy_ls(pL_POld[i + 1], pswQntRc[j]);
      L_temp = L_shl(L_temp, 1);
      L_temp = L_add(L_temp, L_sum);
      pL_VNew[i] = L_shl(L_temp, swNShift);
    }

    if (j < psvqIndex[iSegment - 1].len - 2)
    {

      /* Swap POld and PNew buffers, using modulo addressing */
      /*-----------------------------------------------------*/

      pL_POld = ppL_PAddrs[(j + 1) % 2];
      pL_PNew = ppL_PAddrs[j % 2];

      /* Swap VOld and VNew buffers, using modulo addressing */
      /*-----------------------------------------------------*/

      pL_VOld = ppL_VAddrs[(j + 1) % 2];
      pL_VNew = ppL_VAddrs[j % 2];

⌨️ 快捷键说明

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