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

📄 sp_sfrm.c

📁 GSM中半速率语音编解码源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    }
    else
      swQShift = negate(swQShift);

    for (i = 0; i < S_LEN; i++)
    {
      L_Accum = L_msu(0x00008000L, pswVects[i + iLoopCnt * S_LEN], SW_MIN);
      pswVects[iLoopCnt * S_LEN + i] = extract_h(L_mac(L_Accum, swTemp,
                                         shl(pswGivenVect[i], swQShift)));
    }
  }
}

/***************************************************************************
 *
 *    FUNCTION NAME: g_corr2
 *
 *    PURPOSE: Calculates correlation between subframe vectors.
 *
 *
 *    INPUT:
 *
 *       pswIn[0:39]
 *                     A subframe vector.
 *
 *       pswIn2[0:39]
 *                     A subframe vector.
 *
 *
 *    OUTPUT:
 *
 *       *pL_out
 *                     A Longword containing the normalized correlation
 *                     between the input vectors.
 *
 *    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.
 *
 *    REFERENCE:  Sub-clauses 4.1.10.1 and 4.1.11.1 of GSM
 *       Recommendation 06.20
 *
 *    keywords: energy, autocorrelation, correlation, g_corr2
 *
 *
 **************************************************************************/

Shortword g_corr2(Shortword *pswIn, Shortword *pswIn2,
                         Longword *pL_out)
{

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

  Longword L_sum;
  Shortword swEngyLShft;
  int    i;

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

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

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



  if (L_sum != 0)
  {

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

    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_quant_vl
 *
 *   PURPOSE:
 *
 *     Joint quantization of excitation gains.
 *     GS represents the subframe energy relative to the frame energy.
 *     P0 represents the relative contribution of the first exctitation
 *     source to the total excitation.
 *
 *   INPUTS:
 *
 *     swUVCode - voicing level (Mode 0-3)
 *     pswWInput[0:39] - weighted input p(n) (used in mode 0-3)
 *     swWIShift - weighted input shift factor (right shift, 0,1, or 2)
 *     pswWLTPVec[0:39] - weighted pitch excitation vector (used in mode 1-3)
 *     pswWVSVec1[0:39] - weighted 1st v-s codevector (used in mode 0-3)
 *     pswWVSVec2[0:39] - weighted 2nd v-s codevector (used in mode 0)
 *     snsRs00 - square root of RS/pitch excitation energy (used in mode 1-3)
 *     snsRs11 - square root of RS/1st v-s codevector energy
 *               (used in mode 0-3)
 *     snsRs22 - square root of RS/2nd v-s codevector energy (used in mode 0)
 *
 *     pppsrGsp0[0:3][0:31][0:4] - lookup table
 *
 *   OUTPUTS:
 *
 *     None
 *
 *   RETURN VALUE:
 *
 *     siCode - output quantized gain code (5 bits)
 *
 *   IMPLEMENTATION:
 *
 *     Calculates first the parameters required for error equation 7.21:
 *
 *     Rcc(k,j)        k = 0,1, j=k,1
 *     Rx(k)           k = 0,1
 *     RS
 *     Rpc(k)          k = 0,1
 *     a,b,c,d,e
 *
 *     The constant terms in equation 7.21 are stored in ROM instead of GS
 *     and P0. There is one vector quantizer for each voicing state.
 *
 *   REFERENCE:  Sub-clause 4.1.11 and 4.1.11.1 of GSM Recommendation 06.20
 *
 *   KEYWORDS: gain quantization, energy domain transforms, p0, gs
 *
 **************************************************************************/

Shortword g_quant_vl(Shortword swUVCode,
                            Shortword pswWInput[], Shortword swWIShift,
                            Shortword pswWLTPVec[],
                            Shortword pswWVSVec1[], Shortword pswWVSVec2[],
                            struct NormSw snsRs00, struct NormSw snsRs11,
                            struct NormSw snsRs22)
{

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

  Longword L_Temp,
         L_Temp2;
  Shortword swShift;
  struct NormSw ErrorTerm[6];
  Shortword i,
         siCode,
         siNormShift,
         siNormMin;

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

  /* Test voicing level, mode 0-3 */
  /* ---------------------------- */

  if (swUVCode == 0)
  {

    /* Unvoiced */
    /* -------- */

    /* Compute cross correlation Rpc(0) */
    /* -------------------------------- */


    ErrorTerm[0].sh = g_corr2(pswWInput, pswWVSVec1, &L_Temp);
    ErrorTerm[0].man = round(L_Temp);

    /* Compute cross correlation Rpc(1) */
    /* -------------------------------- */

    ErrorTerm[1].sh = g_corr2(pswWInput, pswWVSVec2, &L_Temp);
    ErrorTerm[1].man = round(L_Temp);

    /* Compute cross correlation Rcc(0,1) */
    /* ---------------------------------- */


    ErrorTerm[2].sh = g_corr2(pswWVSVec1, pswWVSVec2, &L_Temp);
    ErrorTerm[2].man = round(L_Temp);

    /* Compute correlation Rcc(0,0) */
    /* ---------------------------- */

    ErrorTerm[3].sh = g_corr1(pswWVSVec1, &L_Temp);
    ErrorTerm[3].man = round(L_Temp);

    /* Compute correlation Rcc(1,1) */
    /* ---------------------------- */

    ErrorTerm[4].sh = g_corr1(pswWVSVec2, &L_Temp);
    ErrorTerm[4].man = round(L_Temp);

    /* Compute correlation Rpp */
    /* ----------------------- */

    ErrorTerm[5].sh = g_corr1(pswWInput, &L_Temp);
    ErrorTerm[5].man = round(L_Temp);

    /* Compute gain tweak factor, adjusts A and B error coefs */
    /* ------------------------------------------------------ */
    gainTweak(&ErrorTerm[0]);

    /* Compute error coefficient A, equation 5.22 */
    /* ------------------------------------------ */

    L_Temp = L_mult(ErrorTerm[0].man, snsRs11.man);
    swShift = norm_s(extract_h(L_Temp));
    ErrorTerm[0].sh = add(ErrorTerm[0].sh, swShift);
    ErrorTerm[0].man = round(L_shl(L_Temp, swShift));
    ErrorTerm[0].sh = add(ErrorTerm[0].sh, snsRs11.sh);
    siNormMin = ErrorTerm[0].sh;

    /* Compute error coefficient B, equation 5.23 */
    /* ------------------------------------------ */

    L_Temp = L_mult(ErrorTerm[1].man, snsRs22.man);
    swShift = norm_s(extract_h(L_Temp));
    ErrorTerm[1].sh = add(ErrorTerm[1].sh, swShift);
    ErrorTerm[1].man = round(L_shl(L_Temp, swShift));
    ErrorTerm[1].sh = add(ErrorTerm[1].sh, snsRs22.sh);
    if (sub(ErrorTerm[1].sh, siNormMin) < 0)
      siNormMin = ErrorTerm[1].sh;

    /* Compute error coefficient C, equation 5.24 */
    /* ------------------------------------------ */

    L_Temp = L_mult(ErrorTerm[2].man, snsRs11.man);
    swShift = norm_s(extract_h(L_Temp));
    ErrorTerm[2].sh = add(ErrorTerm[2].sh, swShift);
    ErrorTerm[2].man = round(L_shl(L_Temp, swShift));
    L_Temp = L_mult(ErrorTerm[2].man, snsRs22.man);
    swShift = norm_s(extract_h(L_Temp));
    ErrorTerm[2].sh = add(ErrorTerm[2].sh, swShift);
    ErrorTerm[2].man = round(L_shl(L_Temp, swShift));
    ErrorTerm[2].sh = add(ErrorTerm[2].sh, snsRs11.sh);
    ErrorTerm[2].sh = add(ErrorTerm[2].sh, snsRs22.sh);
    ErrorTerm[2].sh = add(ErrorTerm[2].sh, swWIShift);
    if (sub(ErrorTerm[2].sh, siNormMin) < 0)
      siNormMin = ErrorTerm[2].sh;

    /* Compute error coefficient D, equation 5.25 */
    /* ------------------------------------------ */

    L_Temp = L_mult(ErrorTerm[3].man, snsRs11.man);
    swShift = norm_s(extract_h(L_Temp));
    ErrorTerm[3].sh = add(ErrorTerm[3].sh, swShift);
    ErrorTerm[3].man = round(L_shl(L_Temp, swShift));
    L_Temp = L_mult(ErrorTerm[3].man, snsRs11.man);
    swShift = norm_s(extract_h(L_Temp));
    ErrorTerm[3].sh = add(ErrorTerm[3].sh, swShift);
    ErrorTerm[3].man = round(L_shl(L_Temp, swShift));
    ErrorTerm[3].sh = add(ErrorTerm[3].sh, snsRs11.sh);
    ErrorTerm[3].sh = add(ErrorTerm[3].sh, snsRs11.sh);
    ErrorTerm[3].sh = add(ErrorTerm[3].sh, swWIShift);

    if (sub(ErrorTerm[3].sh, siNormMin) < 0)
      siNormMin = ErrorTerm[3].sh;

    /* Compute error coefficient E, equation 5.26 */
    /* ------------------------------------------ */

    L_Temp = L_mult(ErrorTerm[4].man, snsRs22.man);
    swShift = norm_s(extract_h(L_Temp));
    ErrorTerm[4].sh = add(ErrorTerm[4].sh, swShift);
    ErrorTerm[4].man = round(L_shl(L_Temp, swShift));
    L_Temp = L_mult(ErrorTerm[4].man, snsRs22.man);
    swShift = norm_s(extract_h(L_Temp));
    ErrorTerm[4].sh = add(ErrorTerm[4].sh, swShift);
    ErrorTerm[4].man = round(L_shl(L_Temp, swShift));
    ErrorTerm[4].sh = add(ErrorTerm[4].sh, snsRs22.sh);
    ErrorTerm[4].sh = add(ErrorTerm[4].sh, snsRs22.sh);
    ErrorTerm[4].sh = add(ErrorTerm[4].sh, swWIShift);

    if (sub(ErrorTerm[4].sh, siNormMin) < 0)
      siNormMin = ErrorTerm[4].sh;

  }

  else
  {                                    /* Voicing level */

    /* Voiced */
    /* ------ */

    /* Compute cross correlation Rpc(0) */
    /* -------------------------------- */


    ErrorTerm[0].sh = g_corr2(pswWInput, pswWLTPVec, &L_Temp);
    ErrorTerm[0].man = round(L_Temp);

    /* Compute cross correlation Rpc(1) */
    /* -------------------------------- */


    ErrorTerm[1].sh = g_corr2(pswWInput, pswWVSVec1, &L_Temp);
    ErrorTerm[1].man = round(L_Temp);

    /* Compute cross correlation Rcc(0,1) */
    /* ---------------------------------- */


    ErrorTerm[2].sh = g_corr2(pswWLTPVec, pswWVSVec1, &L_Temp);
    ErrorTerm[2].man = round(L_Temp);

    /* Compute correlation Rcc(0,0) */
    /* ---------------------------- */

    ErrorTerm[3].sh = g_corr1(pswWLTPVec, &L_Temp);
    ErrorTerm[3].man = round(L_Temp);

    /* Compute correlation Rcc(1,1) */
    /* ---------------------------- */

    ErrorTerm[4].sh = g_corr1(pswWVSVec1, &L_Temp);
    ErrorTerm[4].man = round(L_Temp);

    /* Compute correlation Rpp */
    /* ----------------------- */

    ErrorTerm[5].sh = g_corr1(pswWInput, &L_Temp);
    ErrorTerm[5].man = round(L_Temp);

    /* Compute gain tweak factor, adjusts A and B error coefs */
    /* ------------------------------------------------------ */

    gainTweak(&ErrorTerm[0]);

    /* Compute error coefficient A, equation 5.22 */
    /* ------------------------------------------ */

    L_Temp = L_mult(ErrorTerm[0].man, snsRs00.man);
    swShift = norm_s(extract_h(L_Temp));
    ErrorTerm[0].sh = add(ErrorTerm[0].sh, swShift);
    ErrorTerm[0].man = round(L_shl(L_Temp, swShift));
    ErrorTerm[0].sh = add(ErrorTerm[0].sh, snsRs00.sh);
    siNormMin = ErrorTerm[0].sh;

    /* Compute error coefficient B, equation 5.23 */
    /* ------------------------------------------ */

⌨️ 快捷键说明

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