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

📄 sp_sfrm.c

📁 GSM中半速率语音编解码源码
💻 C
📖 第 1 页 / 共 5 页
字号:
 *            pswInSample points to the "oldest" sample of the
 *            current subframe to be hnw filtered, S_LEN samples
 *            will be stored in this array, this data is not
 *            explicitly modified.
 *
 *         pswState[0:183] - array of state of samples, the most
 *            recent sample is the tail of the state buffer,
 *            used only for full- state filtering, this data is
 *            not modified
 *         pswInCoef[0:5] - array of unmodified filter coefficients
 *         iStateOffset - address offset from a sample in the subframe back
 *            to the oldest element of the state used in the interpolating
 *            filter for that sample. Although the subframe samples and
 *            state information can come from different buffers, this
 *            offset represents the case in which the state and sample
 *            information are in the same buffer
 *         swZeroState - indicate if the interpolating filter should be
 *            "zero-state" filtering or "full-state" filtering:
 *                       0 ==> zero-state filtering
 *                      !0 ==> full-state filtering
 *         iNumSamples - the number of samples that are to be filtered,
 *            required to be less than or equal to S_LEN in order to
 *            correctly match speech samples with sample states for the
 *            filtering procedure
 *
 *   OUTPUTS:
 *         pswOutSample[0:39] - array of output filtered speech signal,
 *            pswOutSample points to the "oldest" sample location, S_LEN
 *            filtered samples will be stored at the buffer associated with
 *            this array, can implicitly overwrite input samples with
 *            with filtered samples by setting pswOutSample = pswInSample
 *
 *   RETURN VALUE:
 *         none
 *
 *   IMPLEMENTATION:
 *         The harmonic noise weighting filter is implemented in reverse
 *         temporal order, from most recent input sample backwards through
 *         the input sample array. The procedure follows the equation:
 *                   x(n) = x(n) - PW_COEF*x(n - lag)
 *         where the PW_COEF is the pitch weighting for the current
 *         subframe and lag is the full-resolution lag for the current
 *         subframe. x(n - lag) is found by implementing a CG_INT_MACS-
 *         order FIR interpolating filter
 *
 *         Harmonic noise weighting is discussed in secion 5.5.
 *
 *   REFERENCE:  Sub-clause 4.1.9 of GSM Recommendation 06.20
 *
 *   KEYWORDS: T_SUB, LAG, HNW_FILT, PW_COEF, CG_INT_MACS, S_LEN, LSMAX
 *
 **************************************************************************/

void   hnwFilt(Shortword pswInSample[],
                      Shortword pswOutSample[],
                      Shortword pswState[],
                      Shortword pswInCoef[],
                      int iStateOffset,
                      Shortword swZeroState,
                      int iNumSamples)
{

/*_________________________________________________________________________
 |                                                                         |
 |                            Automatic Variables                          |
 |_________________________________________________________________________|
*/
  Longword L_temp;
  int    i,
         j;

  int    iStatIndx = S_LEN - 1 + iStateOffset;
  int    iStatIndx1 = S_LEN + iStateOffset;

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

  if (swZeroState == 0)
  {

    /* zero state response assumes input and output arrays are the same */
    /*------------------------------------------------------------------*/

    for (i = 0; i < iNumSamples; i++)
    {

      /* get input with rounding */
      /*-------------------------*/
      L_temp = L_mac((long) 16384, pswInSample[S_LEN - i - 1], 0x4000);

      for (j = 5; (j >= 0) && (iStatIndx - i + j >= 0); j--)
        /* evaluate taps 1 - 6 that point to input */
        /*-----------------------------------------*/
        L_temp = L_mac(L_temp, pswInSample[iStatIndx - i + j], pswInCoef[j]);

      pswOutSample[S_LEN - 1 - i] = extract_h(L_shl(L_temp, 1));
    }
  }
  else
  {
    for (i = 0; i < iNumSamples; i++)
    {

      /* get input with rounding */
      /*-------------------------*/
      L_temp = L_mac((long) 16384, pswInSample[S_LEN - i - 1], 0x4000);

      for (j = 5; (j >= 0) && (iStatIndx - i + j >= 0); j--)
        /* evaluate taps 1 - 6 that point to input */
        /*-----------------------------------------*/
        L_temp = L_mac(L_temp, pswInSample[iStatIndx - i + j], pswInCoef[j]);

      for (; (j >= 0); j--)
        /* evaluate taps 1 - 6 that point to state */
        /*----------------------------------------*/
        L_temp = L_mac(L_temp, pswState[iStatIndx1 - i + j], pswInCoef[j]);

      pswOutSample[S_LEN - 1 - i] = extract_h(L_shl(L_temp, 1));
    }
  }

}

/***************************************************************************
 *
 *   FUNCTION NAME: sfrmAnalysis
 *
 *   PURPOSE:
 *
 *     Determines the synthetic excitation for a subframe.
 *
 *   INPUTS:
 *
 *     pswWSpeech
 *                     Input weighted speech vector to be matched.
 *
 *     swVoicingMode
 *
 *                     Voicing mode 0,1,2 or 3.  0 is unvoiced.  A
 *                     frame parameter.
 *
 *     snsSqrtRs
 *
 *                     Normalized estimate of the excitation energy
 *
 *     pswHCoefs
 *
 *                     Coefficientss used in weighted synthesis filter,
 *                     H(z), (a negated version is used).  pswHCoefs[0]
 *                     is  t=-1 tap, pswHCoefs[9] is t=-10 tap.
 *
 *     pswLagList
 *
 *                     List of lags to be searched in the long-term
 *                     predictor, determined by the open-loop lag search.
 *
 *     siNumLags
 *
 *                     Number of lags in pswLagList.
 *
 *     swPitch
 *
 *                     Fundamental pitch value to be used in harmonic-
 *                     noise-weighting, actualPitch*OS_FCTR.
 *
 *     swHNWCoef
 *                     Coefficient of the harmonic-noise-weighting filter.
 *
 *     ppsrCGIntFilt[0:5][0:5]
 *
 *                     polyphase interpolation filter,
 *                     ppsrCGIntFilt[iTap][iPhase], OS_FCTR phases,
 *                     CG_INT_MACS taps per phase.  Used to construct
 *                     sequences delayed by fractional lags for Harmonic-
 *                     Noise-Weighting.
 *
 *     pppsrUvCodeVec[0:1][0:6][0:39]
 *
 *                     unvoiced codebooks:
 *                     pppsrUvCodeVec[codeBook][vectorNumber][time]
 *
 *     pppsrVcdCodeVec[0][0:8][0:39]
 *
 *                     voiced codebook:
 *                     pppsrVcdCodeVect[codebook(=0)][vectorNumber][time]
 *
 *     swSP
 *                     speech flag (DTX mode)
 *
 *   OUTPUTS:
 *
 *     psiLagCode
 *
 *                     Lag code: frame- or delta-, or zero if unvoiced.
 *
 *     psiVSCode1
 *
 *                     First vector-sum codebook code.
 *
 *     psiVSCode2
 *
 *                     Second vector-sum codebook code, or zero if voiced.
 *
 *     psiGsp0Code
 *
 *                     Gain quantizer code.
 *
 *     DESCRIPTION:
 *
 *     sfrmAnalysis() is the calling function for the subframe analysis
 *     functions.  All subframe based processing is done by it and its
 *     daughter functions.  All functions in this file are called by
 *     sfrmAnalysis() or one of its daughter functions.  As can be seen
 *     above, this routine will select the LTP lag, the VSELP
 *     codevector(s) and the GSP0 codeword.  It is called by
 *     speechEncoder().
 *
 *     The subframe processing can follow one of two paths depending on
 *     whether the frame is voiced or unvoiced.  These two paths are now
 *     described.
 *
 *     First the zero input response of H(z) is calculated (lpcZiIir());
 *     then subtracted from the weighted speech (W(z)).  The outcome, p(n)
 *     or pswWSVec[], will be the vector matched by the first excitation
 *     vector (either adaptive or first VSELP codevector).  The p(n)
 *     vector is scaled to prevent overflow.
 *
 *     If the frame is voiced, the closed loop lag search (closedLoop())
 *     is performed.  An adaptive codevector lag is selected.  Using the
 *     open loop "pitch" value, the harmonic noise weighting
 *     coefficients are obtained.  The adaptive codevector is
 *     reconstructed (fp_ex()), and weighted through the (zero state)
 *     spectral (lpcZsIir()) and harmonic noise weighting filters
 *     (hnwFilt()).
 *
 *     The basis vectors are also filtered through the weighting
 *     filters.  If the frame is unvoiced, there is no spectral noise
 *     weighting.
 *
 *     If voiced the VSELP basis vectors are decorrelated (decorr())
 *     from the selected adaptive (LTP) codevector, and the VSELP
 *     codevector search is initiated (v_srch()).
 *
 *     If unvoiced, the first VSELP codevector search is performed
 *     (without any decorrelation). After a vector from the first VSELP
 *     codebook has been selected, the second set of basis vectors are
 *     decorrelated from the selected vector.
 *
 *     Once all the excitation vectors have been selected, the gain
 *     quantizer is called, g_quant_vl().
 *
 *     Finally, once all subframe parameters have been found, the
 *     selected excitation is scaled according to GSP0 (scaleExcite()),
 *     and the composite excitation is entered into the long term
 *     predictor history.  The final excitation is also used to update
 *     H(z) and C(z).
 *
 *   REFERENCE:  Sub-clauses 4.1.8.5, 4.1.9 - 4.1.12 of GSM
 *     Recommendation 06.20
 *
 *   Keywords: codewords, lag, codevectors, gsp0, decoding, analysis, t_sub
 *
 **************************************************************************/

void   sfrmAnalysis(Shortword *pswWSpeech,
                           Shortword swVoicingMode,
                           struct NormSw snsSqrtRs,
                           Shortword *pswHCoefs,
                           Shortword *pswLagList,
                           short siNumLags,
                           Shortword swPitch,
                           Shortword swHNWCoef,
                           short *psiLagCode,
                           short *psiVSCode1,
                           short *psiVSCode2,
                           short *psiGsp0Code,
                           Shortword swSP)
{

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

  static short siPrevLagCode;

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

  short  i,
         j,
         siCode,
         siIntPitch,
         siRemainder;
  short  siHnwOffset,
         siHnwNum,
         siNumBasisVecs;

  Shortword swLag,
         swPnEnergy,
         swPnShift,
         swSampleA;
  Shortword swLtpShift;

  Longword L_PnEnergy;

  struct NormSw snsRs00,
         snsRs11,
         snsRs22;

  Shortword pswWSVec[S_LEN],
         pswTempVec[S_LEN];
  Shortword pswPVec[S_LEN],
         pswWPVec[S_LEN];
  Shortword ppswVselpEx[2][S_LEN],
         ppswWVselpEx[2][S_LEN];
  Shortword pswWBasisVecs[9 * S_LEN],
         pswBitArray[9];
  Shortword pswHNWCoefs[CG_INT_MACS];

  Shortword *pswLtpStateOut;

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

  pswLtpStateOut = pswLtpStateBase + LTP_LEN;

  if (swSP == 1)                                             /* DTX mode */ 
  {                                                          /* DTX mode */   

    /* if not in CNI mode */
    /*--------------------*/

    /* Get the zero-input response of H(z) */
    /*-------------------------------------*/

    lpcZiIir(pswHCoefs, pswHState, pswTempVec);

    /* Subtract the zero-input response of H(z) from W(z)-weighted speech. */
    /* The result is the vector to match for the adaptive codebook (long-  */
    /* term-predictor) search in voiced modes, or the vector to match for  */
    /* all synthetic excitation searches in unvoiced mode.                 */
    /*---------------------------------------------------------------------*/

    for (i = 0; i < S_LEN; i++)
    {

      pswWSVec[i] = sub(pswWSpeech[i], pswTempVec[i]);  
    }

    /* scale the weighted speech vector (p[n]) s.t. its energy is strictly */
    /* less than 1.0                                                       */
    /*---------------------------------------------------------------------*/

    swSampleA = shr(pswWSVec[0], 2);
    L_PnEnergy = L_mac(0x001dff4cL, swSampleA, swSampleA);
    for (i = 1; i < S_LEN; i++)
    {
      swSampleA = shr(pswWSVec[i], 2);   /* reduces energy by 16 */
      L_PnEnergy = L_mac(L_PnEnergy, swSampleA, swSampleA);
    }

    swPnEnergy = round(L_PnEnergy);

    if (sub(swPnEnergy, 0x7ff) <= 0)
    {                                    /* E = [0..0x7ff] */

⌨️ 快捷键说明

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