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

📄 sp_dec.c

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

    pL_swap = pL_vjNew;
    pL_vjNew = pL_vjOld;
    pL_vjOld = pL_swap;

    /* Compute the j-th reflection coefficient */
    /*-----------------------------------------*/

    swTemp = norm_l(pL_pjOld[0]);      /* get shift count */
    swTemp1 = round(L_shl(pL_vjOld[0], swTemp));        /* normalize num.  */
    swTemp2 = round(L_shl(pL_pjOld[0], swTemp));        /* normalize den.  */

    /* Test for invalid divide conditions: a) devisor < 0 b) abs(divident) >
     * abs(devisor) If either of these conditions is true, zero out
     * reflection coefficients for i=j,...,NP-1 and return. */

    swAbsTemp1 = abs_s(swTemp1);
    if (swTemp2 <= 0 || sub(swAbsTemp1, swTemp2) >= 0)
    {
      i = j;
      for (i = j; i < NP; i++)
      {
        pswRc[i] = 0;
      }
      return;
    }

    swRc = divide_s(swAbsTemp1, swTemp2);       /* return division result */
    if (sub(swTemp1, swAbsTemp1) == 0)
      swRc = negate(swRc);             /* negate reflection Rc[j] */
    swRcSq = mult_r(swRc, swRc);       /* compute Rc^2 */
    pswRc[j] = swRc;                   /* copy Rc[j] to output array */

    /* Update pjNew and vjNew arrays for the next lattice stage if j < NP-1 */
    /*---------------------------------------------------------------------*/

    /* Updating pjNew: */
    /*-----------------*/

    for (i = 0; i <= NP - j - 2; i++)
    {
      L_temp = L_mpy_ls(pL_vjOld[i], swRc);
      L_sum = L_add(L_temp, pL_pjOld[i]);
      L_temp = L_mpy_ls(pL_pjOld[i], swRcSq);
      L_sum = L_add(L_temp, L_sum);
      L_temp = L_mpy_ls(pL_vjOld[-i], swRc);
      pL_pjNew[i] = L_add(L_sum, L_temp);
    }

    /* Updating vjNew: */
    /*-----------------*/

    for (i = -NP + j + 2; i <= NP - j - 2; i++)
    {
      L_temp = L_mpy_ls(pL_vjOld[-i - 1], swRcSq);
      L_sum = L_add(L_temp, pL_vjOld[i + 1]);
      L_temp = L_mpy_ls(pL_pjOld[(((i + 1) >= 0) ? i + 1 : -(i + 1))], swRc);
      L_temp = L_shl(L_temp, 1);
      pL_vjNew[i] = L_add(L_temp, L_sum);
    }
  }
  return;
}

/***************************************************************************
 *
 *   FUNCTION NAME: aToRc
 *
 *   PURPOSE:
 *
 *     This subroutine computes a vector of reflection coefficients, given
 *     an input vector of direct form LPC filter coefficients.
 *
 *   INPUTS:
 *
 *     NP
 *                     order of the LPC filter (global constant)
 *
 *     swAshift
 *                     The number of right shifts applied externally
 *                     to the direct form filter coefficients.
 *
 *     pswAin[0:NP-1]
 *                     The input vector of direct form LPC filter
 *                     coefficients.
 *
 *   OUTPUTS:
 *
 *     pswRc[0:NP-1]
 *                     Array containing the reflection coefficients.
 *
 *   RETURN VALUE:
 *
 *     siUnstableFlt
 *                     If stable reflection coefficients 0, 1 if unstable.
 *
 *
 *   DESCRIPTION:
 *
 *     This function performs the conversion from direct form
 *     coefficients to reflection coefficients. It is used in a_sst()
 *     and interpolateCheck().  In a_sst() reflection coefficients used
 *     as a transitional data format.  aToRc() is used for this
 *     conversion.
 *
 *     When performing interpolation, a stability check must be
 *     performed. interpolateCheck() does this by calling aToRc().
 *
 *     First coefficients are shifted down by iAshift. NP, the filter
 *     order is 10. The a's and rc's each have NP elements in them. An
 *     elaborate algorithm description can be found on page 443, of
 *     "Digital Processing of Speech Signals" by L.R. Rabiner and R.W.
 *     Schafer; Prentice-Hall; Englewood Cliffs, NJ (USA).  1978.
 *
 *   REFERENCES: Sub_Clause 4.1.6, and 4.2.3 of GSM Recomendation 06.20
 *
 *   KEYWORDS: reflectioncoefficients, parcors, conversion, atorc, ks, as
 *   KEYWORDS: parcorcoefficients, lpc, flat, vectorquantization
 *
 *************************************************************************/

static short aToRc(Shortword swAshift, Shortword pswAin[],
                          Shortword pswRc[])
{

/*_________________________________________________________________________
 |                                                                         |
 |                            Constants                                    |
 |_________________________________________________________________________|
*/

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

  Shortword pswTmpSpace[NP],
         pswASpace[NP],
         swNormShift,
         swActShift,
         swNormProd,
         swRcOverE,
         swDiv,
        *pswSwap,
        *pswTmp,
        *pswA;

  Longword L_temp;

  short int siUnstableFlt,
         i,
         j;                            /* Loop control variables */

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

  /* Initialize starting addresses for temporary buffers */
  /*-----------------------------------------------------*/

  pswA = pswASpace;
  pswTmp = pswTmpSpace;

  /* Copy the direct form filter coefficients to a temporary array */
  /*---------------------------------------------------------------*/

  for (i = 0; i < NP; i++)
  {
    pswA[i] = pswAin[i];
  }

  /* Initialize the flag for filter stability check */
  /*------------------------------------------------*/

  siUnstableFlt = 0;

  /* Start computation of the reflection coefficients, Rc[9],...,Rc[1] */
  /*-------------------------------------------------------------------*/

  for (i = NP - 1; i >= 1; i--)
  {

    pswRc[i] = shl(pswA[i], swAshift); /* write Rc[i] to output array */

    /* Check the stability of i-th reflection coefficient */
    /*----------------------------------------------------*/

    siUnstableFlt = siUnstableFlt | isSwLimit(pswRc[i]);

    /* Precompute intermediate variables for needed for the computation */
    /* of direct form filter of order i-1                               */
    /*------------------------------------------------------------------*/

    if (sub(pswRc[i], SW_MIN) == 0)
    {
      siUnstableFlt = 1;
      swRcOverE = 0;
      swDiv = 0;
      swActShift = 2;
    }
    else
    {
      L_temp = LW_MAX;                 /* Load ~1.0 into accum */
      L_temp = L_msu(L_temp, pswRc[i], pswRc[i]);       /* 1.-Rc[i]*Rc[i]  */
      swNormShift = norm_l(L_temp);
      L_temp = L_shl(L_temp, swNormShift);
      swNormProd = extract_h(L_temp);
      swActShift = add(2, swNormShift);
      swDiv = divide_s(0x2000, swNormProd);
      swRcOverE = mult_r(pswRc[i], swDiv);
    }
    /* Check stability   */
    /*---------------------*/
    siUnstableFlt = siUnstableFlt | isSwLimit(swRcOverE);

    /* Compute direct form filter coefficients corresponding to */
    /* a direct form filter of order i-1                        */
    /*----------------------------------------------------------*/

    for (j = 0; j <= i - 1; j++)
    {
      L_temp = L_mult(pswA[j], swDiv);
      L_temp = L_msu(L_temp, pswA[i - j - 1], swRcOverE);
      L_temp = L_shl(L_temp, swActShift);
      pswTmp[j] = round(L_temp);
      siUnstableFlt = siUnstableFlt | isSwLimit(pswTmp[j]);
    }

    /* Swap swA and swTmp buffers */
    /*----------------------------*/

    pswSwap = pswA;
    pswA = pswTmp;
    pswTmp = pswSwap;
  }

  /* Compute reflection coefficient Rc[0] */
  /*--------------------------------------*/

  pswRc[0] = shl(pswA[0], swAshift);   /* write Rc[0] to output array */

  /* Check the stability of 0-th reflection coefficient */
  /*----------------------------------------------------*/

  siUnstableFlt = siUnstableFlt | isSwLimit(pswRc[0]);

  return (siUnstableFlt);
}

/***************************************************************************
 *
 *   FUNCTION NAME: a_sst
 *
 *   PURPOSE:
 *
 *     The purpose of this function is to perform spectral smoothing of the
 *     direct form filter coefficients
 *
 *   INPUTS:
 *
 *     swAshift
 *                     number of shift for coefficients
 *
 *     swAscale
 *                     scaling factor for coefficients
 *
 *     pswDirectFormCoefIn[0:NP-1]
 *
 *                     array of input direct form coefficients
 *
 *   OUTPUTS:
 *
 *     pswDirectFormCoefOut[0:NP-1]
 *
 *                     array of output direct form coefficients
 *
 *   RETURN VALUE:
 *
 *     none
 *
 *   DESCRIPTION:
 *
 *     In a_sst() direct form coefficients are converted to
 *     autocorrelations, and smoothed in that domain.  The function is
 *     used in the spectral postfilter.  A description can be found in
 *     section 3.2.4 as well as in the reference by Y. Tohkura et al.
 *     "Spectral Smoothing Technique in PARCOR Speech
 *     Analysis-Synthesis", IEEE Trans. ASSP, vol. ASSP-26, pp. 591-596,
 *     Dec. 1978.
 *
 *     After smoothing is performed conversion back to direct form
 *     coefficients is done by calling aFlatRc(), followed by rcToADp().
 *
 *     The spectral smoothing filter coefficients with bandwidth set to 300
 *     and a sampling rate of 8000 be :
 *     static ShortwordRom psrSST[NP+1] = { 0x7FFF,
 *         0x7F5C, 0x7D76, 0x7A5B, 0x7622, 0x70EC,
 *         0x6ADD, 0x641F, 0x5CDD, 0x5546, 0x4D86
 *     }
 *
 *   REFERENCES: Sub_Clause 4.2.4 of GSM Recomendation 06.20
 *
 *   KEYWORDS: spectral smoothing, direct form coef, sst, atorc, atocor
 *   KEYWORDS: levinson
 *
 *************************************************************************/

static void a_sst(Shortword swAshift, Shortword swAscale,
                         Shortword pswDirectFormCoefIn[],
                         Shortword pswDirectFormCoefOut[])
{

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

  static ShortwordRom psrSST[NP + 1] = {0x7FFF,
    0x7F5C, 0x7D76, 0x7A5B, 0x7622, 0x70EC,
    0x6ADD, 0x641F, 0x5CDD, 0x5546, 0x4D86,
  };

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

  Longword pL_CorrTemp[NP + 1];

  Shortword pswRCNum[NP],
         pswRCDenom[NP];

  short int siLoopCnt;

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

  /* convert direct form coefs to reflection coefs */
  /* --------------------------------------------- */

  aToRc(swAshift, pswDirectFormCoefIn, pswRCDenom);

  /* convert to autocorrelation coefficients */
  /* --------------------------------------- */

  rcToCorrDpL(swAshift, swAscale, pswRCDenom, pL_CorrTemp);

  /* do spectral smoothing technique */
  /* ------------------------------- */

  for (siLoopCnt = 1; siLoopCnt <= NP; siLoopCnt++)
  {
    pL_CorrTemp[siLoopCnt] = L_mpy_ls(pL_CorrTemp[siLoopCnt],
                                      psrSST[siLoopCnt]);
  }

  /* Compute the reflection coefficients via AFLAT */
  /*-----------------------------------------------*/

  aFlatRcDp(pL_CorrTemp, pswRCNum);


  /* Convert reflection coefficients to direct form filter coefficients */
  /*-------------------------------------------------------------------*/

  rcToADp(swAscale, pswRCNum, pswDirectFormCoefOut);
}

/**************************************************************************
 *
 *   FUNCTION NAME: agcGain
 *
 *   PURPOSE:
 *
 *     Figure out what the agc gain should be to make the energy in the
 *     output signal match that of the input signal.  Used in the post
 *     filters.
 *
 *   INPUT:
 *
 *      pswStateCurr[0:39]
 *                     Input signal into agc block whose energy is
 *                     to be modified using the gain returned. Signal is not
 *                     modified in this routine.
 *
 *      snsInSigEnergy
 *                     Normalized number with shift count - the energy in
 *                     the input signal.
 *
 *      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:
 *
 *      none
 *
 *   RETURN:
 *
 *      the agc's gain/2 note DIVIDED by 2
 *
 *

⌨️ 快捷键说明

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