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

📄 vad.c

📁 GSM中半速率语音编解码源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
 *
 *     TITLE:     Half-Rate GSM Voice Activity Detector (VAD) Modules
 *
 *     VERSION:   1.2
 *
 *     REFERENCE: Recommendation GSM 06.42
 *
 ***************************************************************************/

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

#include "typedefs.h"
#include "mathhalf.h"
#include "mathdp31.h"
#include "vad.h"


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

/*** Floating point representations of constants pth, plev and margin ***/

#define M_PTH    26250
#define E_PTH    18
#define M_PLEV   17500
#define E_PLEV   20
#define M_MARGIN 27343
#define E_MARGIN 27

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

static Shortword
       pswRvad[9],
       swNormRvad,
       swPt_sacf,
       swPt_sav0,
       swE_thvad,
       swM_thvad,
       swAdaptCount,
       swBurstCount,
       swHangCount,
       swOldLagCount,
       swVeryOldLagCount,
       swOldLag;

static Longword
       pL_sacf[27],
       pL_sav0[36],
       L_lastdm;

/****************************************************************************
 *
 *     FUNCTION:  vad_reset
 *
 *     VERSION:   1.2
 *
 *     PURPOSE:   Resets VAD static variables to their initial value.
 *
 ***************************************************************************/

void   vad_reset(void)

{

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

  int    i;

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

  pswRvad[0] = 24576;
  swNormRvad = 7;
  swPt_sacf = 0;
  swPt_sav0 = 0;
  L_lastdm = 0;
  swE_thvad = 21;
  swM_thvad = 21875;
  swAdaptCount = 0;
  swBurstCount = 0;
  swHangCount = -1;
  swOldLagCount = 0;
  swVeryOldLagCount = 0;
  swOldLag = 21;

  for (i = 1; i < 9; i++)
    pswRvad[i] = 0;
  for (i = 0; i < 27; i++)
    pL_sacf[i] = 0;
  for (i = 0; i < 36; i++)
    pL_sav0[i] = 0;

}

/****************************************************************************
 *
 *     FUNCTION:  vad_algorithm
 *
 *     VERSION:   1.2
 *
 *     PURPOSE:   Returns a decision as to whether the current frame being
 *                processed by the speech encoder contains speech or not.
 *
 *     INPUTS:    pL_acf[0..8]  autocorrelation of input signal frame
 *                swScaleAcf    L_acf scaling factor
 *                pswRc[0..3]   speech encoder reflection coefficients
 *                swPtch        flag to indicate a periodic signal component
 *
 *     OUTPUTS:   pswVadFlag    vad decision
 *
 ***************************************************************************/

void   vad_algorithm(Longword pL_acf[9],
                            Shortword swScaleAcf,
                            Shortword pswRc[4],
                            Shortword swPtch,
                            Shortword *pswVadFlag)
{

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

  Longword
         pL_av0[9],
         pL_av1[9];

  Shortword
         swM_acf0,
         swE_acf0,
         pswRav1[9],
         swNormRav1,
         swM_pvad,
         swE_pvad,
         swStat,
         swTone,
         swVvad;


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

  energy_computation
          (
           pL_acf, swScaleAcf,
           pswRvad, swNormRvad,
           &swM_pvad, &swE_pvad,
           &swM_acf0, &swE_acf0
          );

  average_acf
          (
           pL_acf, swScaleAcf,
           pL_av0, pL_av1
          );

  predictor_values
          (
           pL_av1,
           pswRav1,
           &swNormRav1
          );

  spectral_comparison
          (
           pswRav1, swNormRav1,
           pL_av0,
           &swStat
          );

  tone_detection
          (
           pswRc,
           &swTone
          );

  threshold_adaptation
          (
           swStat, swPtch, swTone,
           pswRav1, swNormRav1,
           swM_pvad, swE_pvad,
           swM_acf0, swE_acf0,
           pswRvad, &swNormRvad,
           &swM_thvad, &swE_thvad
          );

  vad_decision
          (
           swM_pvad, swE_pvad,
           swM_thvad, swE_thvad,
           &swVvad
          );

  vad_hangover
          (
           swVvad,
           pswVadFlag
          );

}

/****************************************************************************
 *
 *     FUNCTION:  energy_computation
 *
 *     VERSION:   1.2
 *
 *     PURPOSE:   Computes the input and residual energies of the adaptive
 *                filter in a floating point representation.
 *
 *     INPUTS:    pL_acf[0..8]   autocorrelation of input signal frame
 *                swScaleAcf     L_acf scaling factor
 *                pswRvad[0..8]  autocorrelated adaptive filter coefficients
 *                swNormRvad     rvad scaling factor
 *
 *     OUTPUTS:   pswM_pvad      mantissa of filtered signal energy
 *                pswE_pvad      exponent of filtered signal energy
 *                pswM_acf0      mantissa of signal frame energy
 *                pswE_acf0      exponent of signal frame energy
 *
 ***************************************************************************/

void   energy_computation(Longword pL_acf[],
                                 Shortword swScaleAcf,
                                 Shortword pswRvad[],
                                 Shortword swNormRvad,
                                 Shortword *pswM_pvad,
                                 Shortword *pswE_pvad,
                                 Shortword *pswM_acf0,
                                 Shortword *pswE_acf0)
{

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

  Longword
         L_temp;

  Shortword
         pswSacf[9],
         swNormAcf,
         swNormProd,
         swShift;

  int
         i;


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

  /*** Test if acf[0] is zero ***/

  if (pL_acf[0] == 0)
  {
    *pswE_pvad = -0x8000;
    *pswM_pvad = 0;
    *pswE_acf0 = -0x8000;
    *pswM_acf0 = 0;
    return;
  }


  /*** Re-normalisation of L_acf[0..8] ***/

  swNormAcf = norm_l(pL_acf[0]);
  swShift = sub(swNormAcf, 3);

  for (i = 0; i <= 8; i++)
    pswSacf[i] = extract_h(L_shl(pL_acf[i], swShift));


  /*** Computation of e_acf0 and m_acf0 ***/

  *pswE_acf0 = add(32, shl(swScaleAcf, 1));
  *pswE_acf0 = sub(*pswE_acf0, swNormAcf);
  *pswM_acf0 = shl(pswSacf[0], 3);


  /*** Computation of e_pvad and m_pvad ***/

  *pswE_pvad = add(*pswE_acf0, 14);
  *pswE_pvad = sub(*pswE_pvad, swNormRvad);

  L_temp = 0;

  for (i = 1; i <= 8; i++)
    L_temp = L_mac(L_temp, pswSacf[i], pswRvad[i]);

  L_temp = L_add(L_temp, L_shr(L_mult(pswSacf[0], pswRvad[0]), 1));

  if (L_temp <= 0)
    L_temp = 1;

  swNormProd = norm_l(L_temp);
  *pswE_pvad = sub(*pswE_pvad, swNormProd);
  *pswM_pvad = extract_h(L_shl(L_temp, swNormProd));

}

/****************************************************************************
 *
 *     FUNCTION:  average_acf
 *
 *     VERSION:   1.2
 *
 *     PURPOSE:   Computes the arrays L_av0 [0..8] and L_av1 [0..8].
 *
 *     INPUTS:    pL_acf[0..8]  autocorrelation of input signal frame
 *                swScaleAcf    L_acf scaling factor
 *
 *     OUTPUTS:   pL_av0[0..8]  ACF averaged over last four frames
 *                pL_av1[0..8]  ACF averaged over previous four frames
 *
 ***************************************************************************/

void   average_acf(Longword pL_acf[],
                          Shortword swScaleAcf,
                          Longword pL_av0[],
                          Longword pL_av1[])
{

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

  Longword L_temp;

  Shortword swScale;

  int    i;

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

  /*** computation of the scaleing factor ***/

  swScale = sub(10, shl(swScaleAcf, 1));


  /*** Computation of the arrays L_av0 and L_av1 ***/

  for (i = 0; i <= 8; i++)
  {
    L_temp = L_shr(pL_acf[i], swScale);
    pL_av0[i] = L_add(pL_sacf[i], L_temp);
    pL_av0[i] = L_add(pL_sacf[i + 9], pL_av0[i]);
    pL_av0[i] = L_add(pL_sacf[i + 18], pL_av0[i]);
    pL_sacf[swPt_sacf + i] = L_temp;
    pL_av1[i] = pL_sav0[swPt_sav0 + i];
    pL_sav0[swPt_sav0 + i] = pL_av0[i];
  }


  /*** Update the array pointers ***/

  if (swPt_sacf == 18)
    swPt_sacf = 0;
  else
    swPt_sacf = add(swPt_sacf, 9);

  if (swPt_sav0 == 27)
    swPt_sav0 = 0;
  else
    swPt_sav0 = add(swPt_sav0, 9);

}

/****************************************************************************
 *
 *     FUNCTION:  predictor_values
 *
 *     VERSION:   1.2
 *
 *     PURPOSE:   Computes the array rav [0..8] needed for the spectral
 *                comparison and the threshold adaptation.
 *
 *     INPUTS:    pL_av1 [0..8]  ACF averaged over previous four frames
 *
 *     OUTPUTS:   pswRav1 [0..8] ACF obtained from L_av1
 *                pswNormRav1    r_av1 scaling factor
 *
 ***************************************************************************/

void   predictor_values(Longword pL_av1[],
                               Shortword pswRav1[],
                               Shortword *pswNormRav1)
{

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

  Shortword
         pswVpar[8],
         pswAav1[9];

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

  schur_recursion(pL_av1, pswVpar);
  step_up(8, pswVpar, pswAav1);
  compute_rav1(pswAav1, pswRav1, pswNormRav1);

}

/****************************************************************************
 *
 *     FUNCTION:  schur_recursion
 *
 *     VERSION:   1.2
 *
 *     PURPOSE:   Uses the Schur recursion to compute adaptive filter
 *                reflection coefficients from an autorrelation function.
 *

⌨️ 快捷键说明

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