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

📄 dtx.c

📁 GSM中半速率语音编解码源码
💻 C
📖 第 1 页 / 共 3 页
字号:
        bestQl[iSeg] = bestQl[0];

    }

    /* find the quantized reflection coefficients */
    /*--------------------------------------------*/

    setupQuant(iSeg, bestQl[iSeg].iRCIndex);    /* set up vector ptrs */
    getNextVec((Shortword *) (pswFinalRc - 1));


    /* Update pBarFull and vBarFull for the next Rc-VQ segment, and */
    /* update the pswPBar and pswVBar for the next Rc-VQ segment    */
    /*--------------------------------------------------------------*/

    if (iSeg < LPC_VQ_SEG)
      aflatNewBarRecursionL(&pswFinalRc[psvqIndex[iSeg - 1].l - 1], iSeg,
                            pL_PBarFull, pL_VBarFull, pswPBar, pswVBar);

  }

  /* find the quantizer index (the values to be output in the symbol file) */
  /*-----------------------------------------------------------------*/

  for (iSeg = 1; iSeg <= LPC_VQ_SEG; iSeg++)
    piVQCodewds[iSeg - 1] = bestQl[iSeg].iRCIndex;

}


/*************************************************************************
 *
 *   FUNCTION NAME: getPnBits
 *
 *   PURPOSE:
 *
 *     Generate iBits pseudo-random bits using *pL_PNSeed as the
 *     pn-generators seed.
 *
 *   INPUTS:
 *
 *     iBits - integer indicating how many random bits to return.
 *     range [0,15], 0 yields 1 bit output
 *
 *     *pL_PNSeed - 32 bit seed (changed by function)
 *
 *   OUTPUTS:
 *
 *     *pL_PNSeed - 32 bit seed, modified.
 *
 *   RETURN VALUE:
 *
 *    random bits in iBits LSB's.
 *
 *
 *   IMPLEMENTATION:
 *
 *    implementation of x**31 + x**3 + 1 == PN_XOR_REG | PN_XOR_ADD a
 *    PN sequence generator using Longwords generating a 2**31 -1
 *    length pn-sequence.
 *
 *************************************************************************/

Shortword getPnBits(int iBits, Longword *pL_PNSeed)
{

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

  Shortword swPnBits = 0;
  Longword L_Taps,
         L_FeedBack;
  int    i;

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

  for (i = 0; i < iBits; i++)
  {
    /* update the state */
    /* ---------------- */

    L_Taps = *pL_PNSeed & PN_XOR_REG;
    L_FeedBack = L_Taps;               /* Xor tap bits to yield
                                        * feedback bit */
    L_Taps = L_shr(L_Taps, 1);

    while (L_Taps)
    {
      L_FeedBack = L_FeedBack ^ L_Taps;
      L_Taps = L_shr(L_Taps, 1);
    }

    /* LSB of L_FeedBack is next MSB of PN register */

    *pL_PNSeed = L_shr(*pL_PNSeed, 1);
    if (L_FeedBack & 1)
      *pL_PNSeed = *pL_PNSeed | PN_XOR_ADD;

    /* State update complete.  Get the output bit from the state, add/or it
     * into output */

    swPnBits = shl(swPnBits, 1);
    swPnBits = swPnBits | (extract_l(*pL_PNSeed) & 0x0001);

  }
  return (swPnBits);
}


/*************************************************************************
 *
 *   FUNCTION NAME: rxInterpR0Lpc
 *
 *   PURPOSE:
 *
 *     Perform part of the comfort noise algorithm at the decoder.
 *     LPC and R0 are derived in this routine
 *
 *   INPUTS:
 *
 *     pswOldKs - Last frame's reflection coeffs.
 *
 *     pswNewKs - This frame's decoded/received reflection coeffs.
 *     This will serve a new endpoint in interpolation.
 *
 *     swRxDTXState - primary DTX state variable (at the receiver).  A
 *     modulo 12 counter, which is 0 at SID frame.
 *
 *     swDecoMode - actual mode the decoder: speech decoding mode
 *     or comfort noise insertion mode (SPEECH = speech decoding;
 *     CNIFIRSTSID = comfort noise, 1st SID received; CNICONT = comfort
 *     noise, SID frame received, but not 1st SID; CNIBFI = comfort
 *     noise, bad frame received)
 *
 *     swFrameType - type of the received frame (VALIDSID, INVALIDSID
 *     GOODSPEECH or UNUSABLE)
 *
 *     swOldR0Dec - global variable, the decoded R0 value from the last
 *     frame .  This will be modified.
 *
 *     swR0NewCN - global variable the decoded R0 value from the frame
 *     just received. Valid information if current frame is a SID frame.
 *
 *
 *   OUTPUTS:
 *
 *     pswNewKs - This frames LPC coeffs. modified to reflect
 *     interpolated correlation sequence pL_CorrSeq[].
 *
 *     swR0Dec - global variable, interpolated R0 value
 *
 *     swR0OldCN - global variable, R0 interpolation point to
 *     interpolate from.
 *
 *     swR0NewCN - global variable, R0 interpolation point to
 *     interpolate to.
 *
 *     pL_OldCorrSeq[NP+1] - global variable, starting point for
 *     interpolation of LPC information.
 *
 *     pL_NewCorrSeq[NP+1] - global variable, end point for
 *     interpolation of LPC information.
 *
 *     pL_CorrSeq[NP+1] - global variable, interpolated value of LPC
 *     information to be used in this frame.
 *
 *
 *   RETURN VALUE:
 *
 *     None.
 *
 *   KEYWORDS: interpolation, comfort noise, SID, DTX
 *
 *************************************************************************/

void   rxInterpR0Lpc(Shortword *pswOldKs, Shortword *pswNewKs,
                            Shortword swRxDTXState,
                            Shortword swDecoMode, Shortword swFrameType)
{

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

  static Shortword swR0OldCN;
  static Longword pL_OldCorrSeq[NP + 1],
         pL_NewCorrSeq[NP + 1],
         pL_CorrSeq[NP + 1];


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

  int    i;


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

  if (swDecoMode == CNIFIRSTSID)
  {
    /* first SID frame arrived */
    /* ----------------------- */

    /* use tx'd R0 frame as both endpoints of interp curve. */
    /* i.e. no interpolation for the first frames           */
    /* ---------------------------------------------------- */


    swR0OldCN = swOldR0Dec;            /* last non-SID, received R0 */
    swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState);


    /* generate the LPC end points for interpolation */
    /* --------------------------------------------- */

    rcToCorrDpL(ASHIFT, ASCALE, pswOldKs, pL_OldCorrSeq);
    rcToCorrDpL(ASHIFT, ASCALE, pswNewKs, pL_NewCorrSeq);

    /* linearly interpolate between the two sets of correlation coefs */
    /* -------------------------------------------------------------- */

    for (i = 0; i < NP + 1; i++)
    {
      pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i],
                                   swRxDTXState);
    }

    /* Generate this frames K's (overwrite input) */
    /* ------------------------------------------ */

    aFlatRcDp(pL_CorrSeq, pswNewKs);

  }
  else if ((swDecoMode == CNICONT) && (swFrameType == VALIDSID))
  {
    /* new (not the first) SID frame arrived */
    /* ------------------------------------- */

    swR0OldCN = swOldR0Dec;            /* move current state of R0 to old */
    swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState);


    /* LPC: generate new endpoints for interpolation */
    /* --------------------------------------------- */

    for (i = 0; i < NP + 1; i++)
    {
      pL_OldCorrSeq[i] = pL_CorrSeq[i];
    }

    rcToCorrDpL(ASHIFT, ASCALE, pswNewKs, pL_NewCorrSeq);


    /* linearly interpolate between the two sets of correlation coefs */
    /* -------------------------------------------------------------- */

    for (i = 0; i < NP + 1; i++)
    {
      pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i],
                                   swRxDTXState);
    }


    /* Use interpolated LPC for this frame, overwrite the input K's */
    /* ------------------------------------------------------------ */

    aFlatRcDp(pL_CorrSeq, pswNewKs);

  }
  else
  {
    /* in between SID frames / invalid SID frames */
    /* ------------------------------------------ */

    swR0Dec = linInterpSidShort(swR0NewCN, swR0OldCN, swRxDTXState);


    /* linearly interpolate between the two sets of correlation coefs */
    /* -------------------------------------------------------------- */

    for (i = 0; i < NP + 1; i++)
    {
      pL_CorrSeq[i] = linInterpSid(pL_NewCorrSeq[i], pL_OldCorrSeq[i],
                                   swRxDTXState);
    }


    /* Use interpolated LPC for this frame, overwrite the input K's */
    /* ------------------------------------------------------------ */

    aFlatRcDp(pL_CorrSeq, pswNewKs);

  }
}


/*************************************************************************
 *
 *   FUNCTION NAME: linInterpSid
 *
 *   PURPOSE:
 *
 *     Linearly interpolate between two input numbers based on what the
 *     current DtxState is.
 *
 *   INPUTS:
 *
 *     L_New - longword more current value
 *
 *     L_Old - longword oldest value
 *
 *     swDtxState - state is 0 at the transmitted SID Frame.
 *
 *
 *   OUTPUTS:
 *
 *     none
 *
 *   RETURN VALUE:
 *
 *     A value between old and new inputs with dtxState+1/12 of the new
 *     (dtxState+1)-12/12 of the old
 *
 *
 *************************************************************************/

Longword linInterpSid(Longword L_New, Longword L_Old, Shortword swDtxState)
{

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

  Shortword swOldFactor;


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

  /* old factor = (1.0 - newFactor) */
  /* ------------------------------ */

  swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]);
  swOldFactor = add(0x1, swOldFactor);


  /* contributions from new and old */
  /* ------------------------------ */

  L_New = L_mpy_ls(L_New, psrCNNewFactor[swDtxState]);
  L_Old = L_mpy_ls(L_Old, swOldFactor);

  return (L_add(L_New, L_Old));

}


/*************************************************************************
 *
 *   FUNCTION NAME: linInterpSidShort
 *
 *   PURPOSE:
 *
 *     Linearly interpolate between two input numbers based on what
 *     the current DtxState is.
 *
 *   INPUTS:
 *
 *     swNew - 16 bit,  more current value
 *
 *     swOld - 16 bit, oldest value
 *
 *     swDtxState - state is 0 at the transmitted SID Frame.
 *
 *
 *   OUTPUTS:
 *
 *     none
 *
 *   RETURN VALUE:
 *
 *     A value between old and new inputs with dtxState+1/12 of the new
 *     (dtxState+1)-12/12 of the old
 *
 *************************************************************************/

Shortword linInterpSidShort(Shortword swNew, Shortword swOld,
                                   Shortword swDtxState)
{

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

  Shortword swOldFactor;
  Longword L_New,
         L_Old;


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

  /* old factor = (1.0 - newFactor) */
  /* ------------------------------ */

  swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]);
  swOldFactor = add(0x1, swOldFactor);


  /* contributions from new and old */
  /* ------------------------------ */

  L_New = L_mult(swNew, psrCNNewFactor[swDtxState]);
  L_Old = L_mult(swOld, swOldFactor);


  return (round(L_add(L_New, L_Old)));

}

⌨️ 快捷键说明

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