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

📄 dtx.c

📁 GSM中半速率语音编解码源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************
 *
 *   File Name: dtx.c
 *
 *   Purpose:   DTX and comfort noise functions of the GSM half rate
 *              system
 *
 *   Reference: Recommendation GSM 06.41 (DTX)
 *              Recommendation GSM 06.22 (Comfort Noise)
 *
 *     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.
 *
 *     Evaluation of comfort noise parameters
 *       swComfortNoise()
 *         updateCNHist()
 *         avgGsHistQntz()
 *         gsQuant()
 *         avgCNHist()
 *         lpcCorrQntz()
 *         getPnBits()
 *
 *     Interpolation of comfort noise parameters
 *        rxInterpR0Lpc()
 *         linInterpSid()
 *
 **************************************************************************/

/*________________________________________________________________________
 |                                                                        |
 |                         Include Files                                  |
 |________________________________________________________________________|
*/

#include "typedefs.h"
#include "mathhalf.h"
#include "mathdp31.h"
#include "dtx.h"
#include "sp_dec.h"
#include "sp_rom.h"
#include "sp_frm.h"

/*________________________________________________________________________
 |                                                                        |
 |                            Defines                                     |
 |________________________________________________________________________|
*/

#define PN_XOR_REG (Longword)0x00000005L
#define PN_XOR_ADD (Longword)0x40000000L

#define OH_SHIFT 3                     /* shift corresponding to OVERHANG */

#define NP_AFLAT 4
#define LPC_VQ_SEG 3

#define ASHIFT 4
#define ASCALE 0x0800


/*________________________________________________________________________
 |                                                                        |
 |                        Global Variables                                |
 |________________________________________________________________________|
*/

Shortword swVadFrmCnt = 0;             /* Indicates the number of sequential
                                        * frames where VAD == 0 */

short int siUpdPointer = 0;
Shortword swNElapsed = 50;


Longword pL_GsHist[N_SUB * (OVERHANG - 1)];


/*________________________________________________________________________
 |                                                                        |
 |                     Other External Variables                           |
 |________________________________________________________________________|
*/

extern int iLimit;

extern Shortword swR0Dec,
       swOldR0Dec,
       swR0NewCN;

extern Shortword swCNR0,
       pswCNLpc[],
       pswCNGsp0Code[],
       pswCNVSCode1[],
       pswCNVSCode2[];

/*________________________________________________________________________
 |                                                                        |
 |                         DTX Rom Tables                                 |
 |________________________________________________________________________|
*/

/* interpolation curve for comfort noise (i*1/12) i=1..12 */
Shortword psrCNNewFactor[12] = {0x0aaa, 0x1554, 0x1ffe, 0x2aa8, 0x3552,
  0x3ffc, 0x4aa6, 0x5550, 0x5ffa, 0x6aa4,
0x754e, 0x7fff};


/* Values of GS for voicing state 0, all values shifted down by 2
   shifts */
LongwordRom ppLr_gsTable[4][32] =
{
  {
    0x000011ab, 0x000038d2, 0x0000773e, 0x000144ef,
    0x00035675, 0x000648c5, 0x000c3d65, 0x0017ae17,
    0x002a3dbb, 0x005238e7, 0x00695c1a, 0x00a60d45,
    0x00e4cc68, 0x01c3ba6a, 0x019e3c96, 0x02d1fbac,
    0x030453ec, 0x0549a998, 0x05190298, 0x08258920,
    0x08daff30, 0x0c3150e0, 0x0e45d850, 0x14c111a0,
    0x0ff7e1c0, 0x18a06860, 0x13810400, 0x1abc9ee0,
    0x28500940, 0x41f22800, 0x22fc5040, 0x2cd90180
  },

  {
    0x00003ede, 0x00021fc9, 0x0013f0c3, 0x003a7be2,
    0x007a6663, 0x00fe3773, 0x012fabf4, 0x02275cd0,
    0x01c0ef14, 0x02c0b1d8, 0x0350fc70, 0x05505078,
    0x04175f30, 0x052c1098, 0x08ed3310, 0x0a63b470,
    0x05417870, 0x08995ee0, 0x07bbe018, 0x0a19fa10,
    0x0b5818c0, 0x0fd96ea0, 0x0e5cad10, 0x13b40d40,
    0x12d45840, 0x14577320, 0x2b2e5e00, 0x333e9640,
    0x194c35c0, 0x1c30f8c0, 0x2d16db00, 0x2cc970ff
  },
  {
    0x002f18e7, 0x00a47be0, 0x01222efe, 0x01c42df8,
    0x024be794, 0x03424c40, 0x036950fc, 0x04973108,
    0x038405b4, 0x05d8c8f0, 0x05063e08, 0x070cdea0,
    0x05812be8, 0x06da5fc8, 0x088fcd60, 0x0a013cb0,
    0x0909a460, 0x09e6cf40, 0x0ee581d0, 0x0ec99f20,
    0x0b4e7470, 0x0c730e80, 0x0ff39d20, 0x105d0d80,
    0x158b0b00, 0x172babe0, 0x14576460, 0x181a6720,
    0x26126e80, 0x1f590180, 0x1fdaad60, 0x2e0e8000
  },
  {
    0x00c7f603, 0x01260cda, 0x01b3926a, 0x026d82bc,
    0x0228fba0, 0x036ec5b0, 0x034bf4cc, 0x043a55d0,
    0x044f9c20, 0x05c66f50, 0x0515f890, 0x06065300,
    0x0665dc00, 0x0802b630, 0x0737a1c0, 0x087294e0,
    0x09253fc0, 0x0a619760, 0x097bd060, 0x0a6d4e50,
    0x0d19e520, 0x0e15c420, 0x0c4e4eb0, 0x0e8880e0,
    0x11cdf480, 0x12c85800, 0x10f4c0a0, 0x13e51b00,
    0x189dbaa0, 0x18a6bb60, 0x22e31500, 0x21615240
  }
};

/*************************************************************************
 *
 *   FUNCTION NAME: swComfortNoise
 *
 *   PURPOSE:
 *
 *   This routine perform the following tasks:
 *     - generation of the speech flag (swSP)
 *     - averaging and encoding of the comfort noise parameters
 *     - randomization of the codebook indices
 *
 *
 *   INPUTS:
 *
 *   swVadFrmCnt (global) - swVadFlag=0 frame counter.
 *   If swVadFlag=1 then this counter is 0, the first frame with
 *   swVadFlag=0 will set this counter to 1, with each additional
 *   swVadFlag=0 frame the counter is incremented.
 *
 *   swVadFlag - voise activity flag. swVadFlag=0 frame with
 *   no voice activity, swVadFlag=0 frame with voice activity
 *
 *   L_UnqntzdR0 - unquantized R(0), 32 bit value, output of
 *   FLAT.
 *
 *   pL_UnqntzdCorr[NP+1] - unquantized correlation sequence,
 *   also an output of FLAT.
 *
 *
 *   OUTPUTS:
 *
 *   swCNR0 - global variable, the output quantized R0 index
 *
 *   pswCNLpc[3]  - global variable, the output quantized LPC to the
 *   transmitted in the SID frame
 *
 *   pswCNGsp0Code[N_SUB] - global variable, the output quantized GSP0 indices
 *
 *   pswCNVSCode1[N_SUB] - global variable, the output quantized codevector 1
 *   indices.
 *
 *   pswCNVSCode2[N_SUB] - global variable, the output quantized codevector 2
 *   indices.
 *
 *
 *   RETURN VALUE:
 *
 *   swSP - speech flag, swSP=1 speech frames are generated, swSP=0
 *   SID frames are generated.
 *
 *************************************************************************/

Shortword swComfortNoise(Shortword swVadFlag,
                             Longword L_UnqntzdR0, Longword *pL_UnqntzdCorr)
{

/*________________________________________________________________________
 |                                                                        |
 |                        Static Variables                                |
 |________________________________________________________________________|
*/

  /* history of unquantized parameters */
  static Longword pL_R0Hist[OVERHANG];
  static Longword ppL_CorrHist[OVERHANG][NP + 1];

  /* quantized reference parameters */
  static Shortword swQntRefR0,
         swRefGsIndex;
  static int piRefVqCodewds[3];

  /* handling of short speech bursts */
  static Shortword swShortBurst;

  /* state value of random generator */
  static Longword L_TxPNSeed;

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

  Shortword swSP;
  Shortword pswFinalRc[NP];

  /* unquantized reference parameters */
  Longword L_RefR0;
  Longword pL_RefCorr[NP + 1];
  Longword L_RefGs;

  int    i;


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

  swSP = 1;

  /* VadFrmCnt will indicate the number of sequential frames where */
  /* swVadFlag == 0                                                */
  /* ------------------------------------------------------------- */

  if (swVadFlag)
    swVadFrmCnt = 0;                   /* Voice acitvity present */
  else
    swVadFrmCnt = add(swVadFrmCnt, 1); /* no voice activity */


  /* swNElapsed will indicate the number of frames that have elapsed */
  /* since the last SID frame with updated comfort noise parameters  */
  /* was generated                                                   */
  /* --------------------------------------------------------------- */

  swNElapsed = add(swNElapsed, 1);


  /* If no voice activity was detected.  */
  /* ----------------------------------- */

  if (swVadFrmCnt)
  {

    /* Short speech burst ? */
    /* -------------------- */

    if (swVadFrmCnt == 1)
    {
      if (sub(swNElapsed, 24) < 0)
        swShortBurst = 1;              /* short speech burst detected */
      else
        swShortBurst = 0;              /* long speech burst detected */
    }


    /* Update history, with this frames data */
    /* ------------------------------------- */

    updateCNHist(L_UnqntzdR0, pL_UnqntzdCorr,
                 pL_R0Hist, ppL_CorrHist);


    /* first SID frame */
    /* --------------- */

    if (((swShortBurst == 0) && (swVadFrmCnt == OVERHANG)) ||
        ((swShortBurst == 1) && (swVadFrmCnt == 1)))
    {

      /* init. random generator */
      /* ---------------------- */
      L_TxPNSeed = PN_INIT_SEED;


      /* average GS */
      /* ---------- */
      avgGsHistQntz(pL_GsHist, &L_RefGs);


      /* GS quantization */
      /* --------------- */
      swRefGsIndex = gsQuant(L_RefGs, 0);

    }


    /* No Overhang in case of short speech bursts,                */
    /* generate SID frames with repeated comfort noise parameters */
    /* ---------------------------------------------------------- */

    if ((swShortBurst == 1) && (swVadFrmCnt < OVERHANG))
    {

      /* generate a SID frame with repeated parameters */
      /* --------------------------------------------- */

      swSP = 0;


      /* repeat data: r0, LPC, GS */
      /* ------------------------ */

      swCNR0 = swQntRefR0;

      for (i = 0; i < 3; i++)
        pswCNLpc[i] = piRefVqCodewds[i];

      for (i = 0; i < N_SUB; i++)
        pswCNGsp0Code[i] = swRefGsIndex;

    }


    /* generate SID frames with updated comfort noise parameters */
    /* --------------------------------------------------------- */

    if (swVadFrmCnt >= OVERHANG)
    {

      /* A SID frame with updated parameters */
      /* ----------------------------------- */

      swSP = 0;
      swNElapsed = 0;


      /* average R0 and correlation values */
      /* --------------------------------- */

      avgCNHist(pL_R0Hist, ppL_CorrHist, &L_RefR0,
                pL_RefCorr);


      /* now quantize the averaged R(0) */
      /* ------------------------------ */

      swQntRefR0 = r0Quant(L_RefR0);


      /* Quantize the averaged correlation */
      /* --------------------------------- */

      lpcCorrQntz(pL_RefCorr,
                  pswFinalRc,
                  piRefVqCodewds);


      /* update frame data: r0, LPC */
      /* -------------------------- */

      swCNR0 = swQntRefR0;
      for (i = 0; i < 3; i++)
        pswCNLpc[i] = piRefVqCodewds[i];


      /* update subframe data (unvoiced mode): GSP0 */
      /* ------------------------------------------ */

      for (i = 0; i < N_SUB; i++)
        pswCNGsp0Code[i] = swRefGsIndex;

    }


    /* random codevectors */
    /* ------------------ */

    if (swSP == 0)
    {
      for (i = 0; i < N_SUB; i++)
      {
        pswCNVSCode1[i] = getPnBits(7, &L_TxPNSeed);
        pswCNVSCode2[i] = getPnBits(7, &L_TxPNSeed);
      }
    }


  }

  return (swSP);
}


/*************************************************************************
 *
 *   FUNCTION NAME:  updateCNHist
 *
 *   PURPOSE:
 *
 *     Add current frame's unquantized R(0) and LPC information to the
 *     comfort noise history, so that it will be available for
 *     averaging.
 *
 *   INPUTS:
 *
 *     Unquantized values from the coder:
 *
 *
 *     L_UnqntzdR0 - unquantized frame energy R(0), an output of FLAT
 *
 *     pL_UnqntzdCorr[NP+1] - unquantized correlation coefficient
 *     array.  Also an output of FLAT.
 *
 *     siUpdPointer (global) - A modulo counter which counts up from
 *     0 to OVERHANG-1.
 *
 *   OUTPUTS:
 *
 *     pL_R0History[OVERHANG] - history of the OVERHANG frames worth of
 *     R(0).
 *

⌨️ 快捷键说明

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