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

📄 err_conc.c

📁 GSM中半速率语音编解码源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************
 *
 *   File Name:  err_conc.c
 *
 *   Purpose:
 *      Contains all functions for error concealment.
 *      Relevant specification: GSM 06.21
 *
 *     Below is a listing of all the functions appearing in the file.
 *     All functions are called within speechDecoder().
 *
 *     Error concealment on parameter level:
 *        para_conceal_speech_decoder()
 *
 *     Error concealment on signal level:
 *        signal_conceal_sub()
 *
 *     Additional functions to support concealment:
 *        level_estimator()
 *        level_calc()
 *
 **************************************************************************/

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

#include "mathhalf.h"
#include "sp_dec.h"
#include "err_conc.h"

/*_________________________________________________________________________
 |                                                                         |
 |                              Local Defines                              |
 |_________________________________________________________________________|
*/
#define  MIN_MUTE_LEVEL -45

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

Longword plSubfrEnergyMem[4];
Shortword swLevelMem[4],
       lastR0,
       pswLastGood[18],
       swState,
       swLastFlag;


/*****************************************************************************
 *
 *   FUNCTION NAME: para_conceal_speech_decoder
 *
 *     This subroutine performs concealment on parameter level. If the
 *     badframe flag (swErrorFlag[0]) has been set in the channel decoder
 *     parameter repetition is performed.
 *     If the average frame energy R0 shows an abnormal increase between two
 *     subsequent frames the badframe flag is also set and parameter
 *     repetition is performed.
 *     If R0 shows an important increase muting is permitted in the signal
 *     concealment unit. There the level of the synthesized speech signal is
 *     controlled and corrected if necessary.
 *
 *     In table "psrR0RepeatThreshold[]" the maximum allowed
 *     increase of R0 for badframe setting is stored. The table
 *     is controlled by the value of R0 of the last frame.
 *     If e.g. the previous R0 is 10 the allowed maximum increase
 *     is 9 (psrR0RepeatThreshold[10]).
 *     The figures in psrR0RepeatThreshold[] have been determined
 *     by measuring the R0 statistics of an error free speech
 *     signal. In approximately 95 % of the frames the increase of
 *     R0 is less than the defined figures for error free speech.
 *     If the level increase is higher than the determined limit
 *     then the badframe flag is set.
 *
 *     In table "psrR0MuteThreshold[]" the maximum allowed
 *     increase of R0 for muting is stored.
 *     The table is controlled by the value of R0 of the last frame
 *     If e.g. the previous R0 is 10 the allowed maximum increase
 *     is 7 (psrR0MuteThreshold[10]).
 *     The figures in psrR0MuteThreshold[] have been determined
 *     by measuring the R0 statistics of an error free speech
 *     signal. In approximately 85 % of the frames the increase of
 *     R0 is less than the defined figures for error free speech.
 *     If the level increase is higher than the determined limit
 *     then muting is allowed.
 *
 *     Input:     pswErrorFlag[0]   badframe flag from channel decoder
 *                pswErrorFlag[1]   unreliable frame flag from channel decoder
 *                pswSpeechPara[]   unconcealed speech parameters
 *     Output:    pswSpeechPara[]   concealed speech parameters
 *                swMutePermit      flag, indicating whether muting is
 *                                  permitted
 *
 *     Constants: psrR0RepeatThreshold[32]  maximum allowed R0 difference
 *                                          before frame is repeated
 *                psrR0MuteThreshold[32]    maximum allowed R0 difference
 *                                          before muting is permitted
 *
 *
 ****************************************************************************/

void   para_conceal_speech_decoder(Shortword pswErrorFlag[],
                        Shortword pswSpeechPara[], Shortword *pswMutePermit)
{

/*_________________________________________________________________________
 |                                                                         |
 |                           Local Static Variables                        |
 |_________________________________________________________________________|
*/
  static const Shortword psrR0RepeatThreshold[32] =
  {15, 15, 15, 12, 12, 12, 12, 11,
    10, 10, 9, 9, 9, 9, 8, 8,
    7, 6, 5, 5, 5, 4, 4, 3,
  2, 2, 2, 2, 2, 2, 10, 10};
  static const Shortword psrR0MuteThreshold[32] =
  {14, 12, 11, 9, 9, 9, 9, 7,
    7, 7, 7, 7, 6, 6, 6, 5,
    5, 4, 3, 3, 3, 3, 3, 2,
  1, 1, 1, 1, 1, 1, 10, 10};

/*_________________________________________________________________________
 |                                                                         |
 |                            Automatic Variables                          |
 |_________________________________________________________________________|
*/
  Shortword swLastLag,
         swR0,
         swLag,
         r0_diff,
         i;


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

  /* Initialise mute permission flag */
  /* ------------------------------- */
  *pswMutePermit = 0;

  /* Determine R0-difference to last frame */
  /* ------------------------------------- */
  r0_diff = sub(pswSpeechPara[0], lastR0);

  /* If no badframe has been declared, but the frame is unreliable then */
  /* check whether there is an abnormal increase of R0                  */
  /* ------------------------------------------------------------------ */
  if ((pswErrorFlag[0] == 0) && (pswErrorFlag[1] > 0))
  {

    /* Check if difference exceeds the maximum allowed threshold. */
    /* If yes, set badframe flag                                  */
    /* ---------------------------------------------------------- */
    if (sub(r0_diff, psrR0RepeatThreshold[lastR0]) >= 0)
    {
      pswErrorFlag[0] = 1;
    }
    else
    {
      /* Allow muting if R0 >= 30 */
      /* ------------------------ */
      if (sub(pswSpeechPara[0], 30) >= 0)
        *pswMutePermit = 1;
    }
  }

  /* If no badframe has been declared, but the frame is unreliable then */
  /* check whether there is an important increase of R0                 */
  /* ------------------------------------------------------------------ */
  if ((pswErrorFlag[1] > 0) && (pswErrorFlag[0] == 0))
  {

    /* Check if difference exceeds a threshold.                   */
    /* If yes, allow muting in the signal concealment unit        */
    /* ---------------------------------------------------------- */
    if (sub(r0_diff, psrR0MuteThreshold[lastR0]) >= 0)
    {
      *pswMutePermit = 1;
    }
  }


  /* Perform parameter repetition, if necessary (badframe handling) */
  /* -------------------------------------------------------------- */

  if (pswErrorFlag[0] > 0)
  {
    swState = add(swState, 1);         /* update the bad frame
                                        * masking state */
    if (sub(swState, 6) > 0)
      swState = 6;
  }
  else
  {
    if (sub(swState, 6) < 0)
      swState = 0;
    else if (swLastFlag == 0)
      swState = 0;
  }

  swLastFlag = pswErrorFlag[0];

  /* if the decoded frame is good, save it */
  /* ------------------------------------- */
  if (swState == 0)
  {
    for (i = 0; i < 18; i++)
      pswLastGood[i] = pswSpeechPara[i];
  }

  /* if the frame is bad, attenuate and repeat last good frame */
  /* --------------------------------------------------------- */
  else
  {
    if ((sub(swState, 3) >= 0) && (sub(swState, 5) <= 0))
    {
      swR0 = sub(pswLastGood[0], 2);   /* attenuate by 4 dB */
      if (swR0 < 0)
        swR0 = 0;
      pswLastGood[0] = swR0;
    }

    if (sub(swState, 6) >= 0)          /* mute */
      pswLastGood[0] = 0;

    /* If the last good frame is unvoiced, use its energy, voicing mode, lpc
     * coefficients, and soft interpolation.   For gsp0, use only the gsp0
     * value from the last good subframe.  If the current bad frame is
     * unvoiced, use the current codewords.  If not, use the codewords from
     * the last good frame.               */
    /* -------------------------------------------------------------- */
    if (pswLastGood[5] == 0)
    {                                  /* unvoiced good frame */
      if (pswSpeechPara[5] == 0)
      {                                /* unvoiced bad frame */
        for (i = 0; i < 5; i++)
          pswSpeechPara[i] = pswLastGood[i];
        for (i = 0; i < 4; i++)
          pswSpeechPara[3 * i + 8] = pswLastGood[17];
      }
      else
      {                                /* voiced bad frame */
        for (i = 0; i < 18; i++)
          pswSpeechPara[i] = pswLastGood[i];
        for (i = 0; i < 3; i++)
          pswSpeechPara[3 * i + 8] = pswLastGood[17];
      }
    }

    /* If the last good frame is voiced, the long term predictor lag at the
     * last subframe is used for all subsequent subframes. Use the last good
     * frame's energy, voicing mode, lpc coefficients, and soft
     * interpolation.  For gsp0 in all subframes, use the gsp0 value from the
     * last good subframe.  If the current bad frame is voiced, use the
     * current codewords.  If not, use the codewords from the last good
     * frame.                              */
    /* ---------------------------------------------------------------- */
    else
    {                                  /* voiced good frame */
      swLastLag = pswLastGood[6];      /* frame lag */
      for (i = 0; i < 3; i++)
      {                                /* each delta lag */
        swLag = sub(pswLastGood[3 * i + 9], 0x8);       /* biased around 0 */
        swLag = add(swLag, swLastLag); /* reconstruct pitch */
        if (sub(swLag, 0x00ff) > 0)
        {                              /* limit, as needed */
          swLastLag = 0x00ff;
        }
        else if (swLag < 0)
        {
          swLastLag = 0;
        }
        else
          swLastLag = swLag;
      }
      pswLastGood[6] = swLastLag;      /* saved frame lag */
      pswLastGood[9] = 0x8;            /* saved delta lags */
      pswLastGood[12] = 0x8;
      pswLastGood[15] = 0x8;

      if (pswSpeechPara[5] != 0)
      {                                /* voiced bad frame */
        for (i = 0; i < 6; i++)
          pswSpeechPara[i] = pswLastGood[i];
        for (i = 0; i < 4; i++)
          pswSpeechPara[3 * i + 6] = pswLastGood[3 * i + 6];
        for (i = 0; i < 4; i++)
          pswSpeechPara[3 * i + 8] = pswLastGood[17];
      }
      else
      {                                /* unvoiced bad frame */
        for (i = 0; i < 18; i++)
          pswSpeechPara[i] = pswLastGood[i];
        for (i = 0; i < 3; i++)
          pswSpeechPara[3 * i + 8] = pswLastGood[17];
      }
    }

  }                                    /* end of bad frame */


  /* Update last value of R0 */
  /* ----------------------- */
  lastR0 = pswSpeechPara[0];

}


/****************************************************************************
 *
 *   FUNCTION NAME: level_estimator
 *
 *     This subroutine determines the mean level and the maximum level
 *     of the last four speech sub-frames. These parameters are the basis
 *     for the level estimation in signal_conceal_sub().
 *
 *     Input:     swUpdate      = 0: the levels are determined
 *                              = 1: the memory of the level estimator
 *                                   is updated

⌨️ 快捷键说明

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