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

📄 sp_dec.c

📁 GSM中半速率语音编解码源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************
 *
 *   File Name:  sp_dec.c
 *
 *   Purpose:
 *      Contains all functions for decoding speech.  It does not
 *      include those routines needed to decode channel information.
 *
 *      Since the GSM half-rate speech coder is an analysis-by-synthesis
 *      coder, many of the routines in this file are also called by the
 *      encoder.  Functions are included for coded-parameter lookup,
 *      LPC filter coefficient interpolation, excitation vector lookup
 *      and construction, vector quantized gain lookup, and LPC synthesis
 *      filtering.  In addition, some post-processing functions are
 *      included.
 *
 *     Below is a listing of all the functions appearing in the file.
 *     The functions are arranged according to their purpose.  Under
 *     each heading, the ordering is hierarchical.
 *
 *     The entire speech decoder, under which all these routines fall,
 *     except were noted:
 *     speechDecoder()
 *
 *     Spectral Smoothing of LPC:
 *       a_sst()
 *         aFlatRcDp()
 *         rcToCorrDpL()
 *         aToRc()
 *         rcToADp()
 *     VSELP codevector construction:
 *       b_con()
 *       v_con()
 *     LTP vector contruction:
 *       fp_ex()
 *         get_ipjj()
 *       lagDecode()
 *     LPC contruction
 *       getSfrmLpc()
 *         interpolateCheck()
 *         res_eng()
 *       lookupVq()
 *     Excitation scaling:
 *       rs_rr()
 *         g_corr1() (no scaling)
 *       rs_rrNs()
 *         g_corr1s() (g_corr1 with scaling)
 *       scaleExcite()
 *     Post filtering:
 *       pitchPreFilt()
 *         agcGain()
 *         lpcIir()
 *       r0BasedEnergyShft()
 *       spectralPostFilter()
 *         lpcFir()
 *
 *
 *     Routines not referenced by speechDecoder()
 *     Filtering routines:
 *       lpcIrZsIir()
 *       lpcZiIir()
 *       lpcZsFir()
 *       lpcZsIir()
 *       lpcZsIirP()
 *     Square root:
 *       sqroot()
 *
 **************************************************************************/

/*_________________________________________________________________________
 |                                                                         |
 |                            Include Files                                |
 |_________________________________________________________________________|
*/

#include "typedefs.h"
#include "mathhalf.h"
#include "sp_rom.h"
#include "sp_dec.h"
#include "err_conc.h"
#include "dtx.h"


/*_________________________________________________________________________
 |                                                                         |
 |            Local Functions (scope is limited to this file)              |
 |_________________________________________________________________________|
*/

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

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

  static Shortword agcGain(Shortword pswStateCurr[],
                                  struct NormSw snsInSigEnergy,
                                  Shortword swEngyRShft);

  static Shortword lagDecode(Shortword swDeltaLag);

  static void lookupVq(Shortword pswVqCodeWds[], Shortword pswRCOut[]);

  static void pitchPreFilt(Shortword pswExcite[],
                                  Shortword swRxGsp0,
                                  Shortword swRxLag,
                                  Shortword swUvCode,
                                  Shortword swSemiBeta,
                                  struct NormSw snsSqrtRs,
                                  Shortword pswExciteOut[],
                                  Shortword pswPPreState[]);

  static void spectralPostFilter(Shortword pswSPFIn[],
                           Shortword pswNumCoef[], Shortword pswDenomCoef[],
                                        Shortword pswSPFOut[]);

/*_________________________________________________________________________
 |                                                                         |
 |                              Local Defines                              |
 |_________________________________________________________________________|
*/

#define  P_INT_MACS   10
#define  ASCALE       0x0800
#define  ASHIFT       4
#define  DELTA_LEVELS 16
#define  GSP0_SCALE   1
#define  C_BITS_V     9                /* number of bits in any voiced VSELP
                                        * codeword */
#define  C_BITS_UV    7                /* number of bits in a unvoiced VSELP
                                        * codeword */
#define  MAXBITS      C_BITS_V         /* max number of bits in any VSELP
                                        * codeword */
#define  LTP_LEN      147              /* 147==0x93 length of LTP history */
#define  SQRT_ONEHALF 0x5a82           /* the 0.5 ** 0.5 */
#define  LPC_ROUND    0x00000800L      /* 0x8000 >> ASHIFT */
#define  AFSHIFT      2                /* number of right shifts to be
                                        * applied to the autocorrelation
                                        * sequence in aFlatRcDp     */

/*_________________________________________________________________________
 |                                                                         |
 |                         State variables (globals)                       |
 |_________________________________________________________________________|
*/

  Shortword gswPostFiltAgcGain,
         gpswPostFiltStateNum[NP],
         gpswPostFiltStateDenom[NP],
         swPostEmphasisState,
         pswSynthFiltState[NP],
         pswOldFrmKsDec[NP],
         pswOldFrmAsDec[NP],
         pswOldFrmPFNum[NP],
         pswOldFrmPFDenom[NP],
         swOldR0Dec,
         pswLtpStateBaseDec[LTP_LEN + S_LEN],
         pswPPreState[LTP_LEN + S_LEN];


  Shortword swMuteFlagOld;             /* error concealment */


 /* DTX state variables */
 /* ------------------- */

  Shortword swRxDTXState = CNINTPER - 1;        /* DTX State at the rx.
                                                 * Modulo */

 /* counter [0,11].             */

  Shortword swDecoMode = SPEECH;
  Shortword swDtxMuting = 0;
  Shortword swDtxBfiCnt = 0;

  Shortword swOldR0IndexDec = 0;

  Shortword swRxGsHistPtr = 0;
  Longword pL_RxGsHist[(OVERHANG - 1) * N_SUB];


/*_________________________________________________________________________
 |                                                                         |
 |                               Global Data                               |
 |                     (scope is global to this file)                      |
 |_________________________________________________________________________|
*/

  Shortword swR0Dec;

  Shortword swVoicingMode,             /* MODE */
         pswVq[3],                     /* LPC1, LPC2, LPC3 */
         swSi,                         /* INT_LPC */
         swEngyRShift;                 /* for use by spectral postfilter */


  Shortword swR0NewCN;                 /* DTX mode */

  extern LongwordRom ppLr_gsTable[4][32];       /* DTX mode */


/***************************************************************************
 *
 *   FUNCTION NAME: aFlatRcDp
 *
 *   PURPOSE:
 *
 *     Given a Longword autocorrelation sequence, representing LPC
 *     information, aFlatRcDp converts the vector to one of NP
 *     Shortword reflection coefficients.
 *
 *   INPUT:
 *
 *
 *     pL_R[0:NP]    - An input Longword autocorrelation sequence, (pL_R[0] =
 *                     not necessarily 0x7fffffffL).  pL_R is altered in the
 *                     call, by being right shifted by global constant
 *                     AFSHIFT bits.
 *
 *                     The input array pL_R[] should be shifted left as much
 *                     as possible to improve precision.
 *
 *     AFSHIFT       - The number of right shifts to be applied to the
 *                     normalized autocorrelation sequence pL_R.
 *
 *   OUTPUT:
 *
 *     pswRc[0:NP-1] - A Shortword output vector of NP reflection
 *                     coefficients.
 *
 *   RETURN VALUE:
 *
 *     None
 *
 *   DESCRIPTION:
 *
 *     This routine transforms LPC information from one set of
 *     parameters to another.  It is better suited for fixed point
 *     implementations than the Levinson-Dubin recursion.
 *
 *     The function is called by a_sst(), and getNWCoefs().  In a_sst()
 *     direct form coefficients are converted to autocorrelations,
 *     and smoothed in that domain.  Conversion back to direct form
 *     coefficients is done by calling aFlatRc(), followed by rcToADp().
 *
 *     In getNwCoefs() again the conversion back to direct form
 *     coefficients is done by calling aFlatRc(), followed by rcToADp().
 *     In getNwCoefs() an autocorrelation sequence is generated from the
 *     impulse response of the weighting filters.
 *
 *     The fundamental recursion is derived from AFLAT, which is
 *     described in section 4.1.4.1.
 *
 *     Unlike in AFLAT where the reflection coefficients are known, here
 *     they are the unknowns.  PBar and VBar for j==0 are initially
 *     known, as is rSub1.  From this information the next set of P's
 *     and V's are generated.  At the end of the recursion the next,
 *     reflection coefficient rSubj (pswRc[j]) can be calcluated by
 *     dividing Vsubj by Psubj.
 *
 *     Precision is crucial in this routine.  At each stage, a
 *     normalization is performed prior to the reflection coefficient
 *     calculation.  In addition, to prevent overflow, the
 *     autocorrelation sequence is scaled down by ASHIFT (4) right
 *     shifts.
 *
 *
 *   REFERENCES: Sub_Clause 4.1.9 and 4.2.1  of GSM Recomendation 06.20
 *
 *   KEYWORDS: reflection coefficients, AFLAT, aflat, recursion, LPC
 *   KEYWORDS: autocorrelation
 *
 *************************************************************************/

  void   aFlatRcDp(Longword *pL_R, Shortword *pswRc)
{

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

  Longword pL_pjNewSpace[NP];
  Longword pL_pjOldSpace[NP];
  Longword pL_vjNewSpace[2 * NP - 1];
  Longword pL_vjOldSpace[2 * NP - 1];

  Longword *pL_pjOld;
  Longword *pL_pjNew;
  Longword *pL_vjOld;
  Longword *pL_vjNew;
  Longword *pL_swap;

  Longword L_temp;
  Longword L_sum;
  Shortword swRc,
         swRcSq,
         swTemp,
         swTemp1,
         swAbsTemp1,
         swTemp2;
  int    i,
         j;


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

  pL_pjOld = pL_pjOldSpace;
  pL_pjNew = pL_pjNewSpace;
  pL_vjOld = pL_vjOldSpace + NP - 1;
  pL_vjNew = pL_vjNewSpace + NP - 1;


  /* Extract the 0-th reflection coefficient */
  /*-----------------------------------------*/

  swTemp1 = round(pL_R[1]);
  swTemp2 = round(pL_R[0]);
  swAbsTemp1 = abs_s(swTemp1);
  if (swTemp2 <= 0 || sub(swAbsTemp1, swTemp2) >= 0)
  {
    j = 0;
    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] */

  pswRc[0] = swRc;                     /* copy into the output Rc array */

  for (i = 0; i <= NP; i++)
  {
    pL_R[i] = L_shr(pL_R[i], AFSHIFT);
  }

  /* Initialize the pjOld and vjOld recursion arrays */
  /*-------------------------------------------------*/

  for (i = 0; i < NP; i++)
  {
    pL_pjOld[i] = pL_R[i];
    pL_vjOld[i] = pL_R[i + 1];
  }
  for (i = -1; i > -NP; i--)
    pL_vjOld[i] = pL_R[-(i + 1)];


  /* Compute the square of the j=0 reflection coefficient */
  /*------------------------------------------------------*/

  swRcSq = mult_r(swRc, swRc);

  /* Update pjNew and vjNew arrays for lattice stage j=1 */
  /*-----------------------------------------------------*/

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

  for (i = 0; i <= NP - 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 + 2; i <= NP - 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);
  }



  j = 0;

  /* Compute reflection coefficients Rc[1],...,Rc[9] */
  /*-------------------------------------------------*/

  for (j = 1; j < NP; j++)
  {

    /* Swap pjNew and pjOld buffers */
    /*------------------------------*/

    pL_swap = pL_pjNew;
    pL_pjNew = pL_pjOld;
    pL_pjOld = pL_swap;

    /* Swap vjNew and vjOld buffers */
    /*------------------------------*/

⌨️ 快捷键说明

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