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

📄 vad.c

📁 GSM中半速率语音编解码源码
💻 C
📖 第 1 页 / 共 3 页
字号:
 *     INPUTS:    pL_av1[0..8]   autocorrelation function
 *
 *     OUTPUTS:   pswVpar[0..7]  reflection coefficients
 *
 ***************************************************************************/

void   schur_recursion(Longword pL_av1[],
                              Shortword pswVpar[])
{

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

  Shortword
         pswAcf[9],
         pswPp[9],
         pswKk[9],
         swTemp;

  int    i,
         k,
         m,
         n;


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

  /*** Schur recursion with 16-bit arithmetic ***/

  if (pL_av1[0] == 0)
  {
    for (i = 0; i < 8; i++)
      pswVpar[i] = 0;
    return;
  }

  swTemp = norm_l(pL_av1[0]);

  for (k = 0; k <= 8; k++)
    pswAcf[k] = extract_h(L_shl(pL_av1[k], swTemp));


  /*** Initialise array pp[..] and kk[..] for the recursion: ***/

  for (i = 1; i <= 7; i++)
    pswKk[9 - i] = pswAcf[i];

  for (i = 0; i <= 8; i++)
    pswPp[i] = pswAcf[i];


  /*** Compute Parcor coefficients: ***/

  for (n = 0; n < 8; n++)
  {
    if (pswPp[0] < abs_s(pswPp[1]))
    {
      for (i = n; i < 8; i++)
        pswVpar[i] = 0;
      return;
    }
    pswVpar[n] = divide_s(abs_s(pswPp[1]), pswPp[0]);

    if (pswPp[1] > 0)
      pswVpar[n] = negate(pswVpar[n]);
    if (n == 7)
      return;


    /*** Schur recursion: ***/

    pswPp[0] = add(pswPp[0], mult_r(pswPp[1], pswVpar[n]));

    for (m = 1; m <= (7 - n); m++)
    {
      pswPp[m] = add(pswPp[1 + m], mult_r(pswKk[9 - m], pswVpar[n]));
      pswKk[9 - m] = add(pswKk[9 - m], mult_r(pswPp[1 + m], pswVpar[n]));
    }
  }

}

/****************************************************************************
 *
 *     FUNCTION:  step_up
 *
 *     VERSION:   1.2
 *
 *     PURPOSE:   Computes the transversal filter coefficients from the
 *                reflection coefficients.
 *
 *     INPUTS:    swNp             filter order (2..8)
 *                pswVpar[0..np-1] reflection coefficients
 *
 *     OUTPUTS:   pswAav1[0..np]   transversal filter coefficients
 *
 ***************************************************************************/

void   step_up(Shortword swNp,
                      Shortword pswVpar[],
                      Shortword pswAav1[])
{

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

  Longword
         pL_coef[9],
         pL_work[9];

  Shortword
         swTemp;

  int
         i,
         m;


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

  /*** Initialisation of the step-up recursion ***/

  pL_coef[0] = L_shl(0x4000L, 15);
  pL_coef[1] = L_shl(L_deposit_l(pswVpar[0]), 14);


  /*** Loop on the LPC analysis order: ***/

  for (m = 2; m <= swNp; m++)
  {
    for (i = 1; i < m; i++)
    {
      swTemp = extract_h(pL_coef[m - i]);
      pL_work[i] = L_mac(pL_coef[i], pswVpar[m - 1], swTemp);
    }
    for (i = 1; i < m; i++)
      pL_coef[i] = pL_work[i];
    pL_coef[m] = L_shl(L_deposit_l(pswVpar[m - 1]), 14);
  }


  /*** Keep the aav1[0..swNp] in 15 bits for the following subclause ***/

  for (i = 0; i <= swNp; i++)
    pswAav1[i] = extract_h(L_shr(pL_coef[i], 3));

}

/****************************************************************************
 *
 *     FUNCTION:  compute_rav1
 *
 *     VERSION:   1.2
 *
 *     PURPOSE:   Computes the autocorrelation function of the adaptive
 *                filter coefficients.
 *
 *     INPUTS:    pswAav1[0..8]  adaptive filter coefficients
 *
 *     OUTPUTS:   pswRav1[0..8]  ACF of aav1
 *                pswNormRav1    r_av1 scaling factor
 *
 ***************************************************************************/

void   compute_rav1(Shortword pswAav1[],
                           Shortword pswRav1[],
                           Shortword *pswNormRav1)
{

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

  Longword
         pL_work[9];

  int
         i,
         k;


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

  /*** Computation of the rav1[0..8] ***/

  for (i = 0; i <= 8; i++)
  {
    pL_work[i] = 0;

    for (k = 0; k <= 8 - i; k++)
      pL_work[i] = L_mac(pL_work[i], pswAav1[k], pswAav1[k + i]);
  }

  if (pL_work[0] == 0)
    *pswNormRav1 = 0;
  else
    *pswNormRav1 = norm_l(pL_work[0]);

  for (i = 0; i <= 8; i++)
    pswRav1[i] = extract_h(L_shl(pL_work[i], *pswNormRav1));

}

/****************************************************************************
 *
 *     FUNCTION:  spectral_comparison
 *
 *     VERSION:   1.2
 *
 *     PURPOSE:   Computes the stat flag needed for the threshold
 *                adaptation decision.
 *
 *     INPUTS:    pswRav1[0..8]   ACF obtained from L_av1
 *                swNormRav1      rav1 scaling factor
 *                pL_av0[0..8]    ACF averaged over last four frames
 *
 *     OUTPUTS:   pswStat         flag to indicate spectral stationarity
 *
 ***************************************************************************/

void   spectral_comparison(Shortword pswRav1[],
                                  Shortword swNormRav1,
                                  Longword pL_av0[],
                                  Shortword *pswStat)
{

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

  Longword
         L_dm,
         L_sump,
         L_temp;

  Shortword
         pswSav0[9],
         swShift,
         swDivShift,
         swTemp;

  int
         i;


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

  /*** Re-normalise L_av0[0..8] ***/

  if (pL_av0[0] == 0)
  {
    for (i = 0; i <= 8; i++)
      pswSav0[i] = 4095;
  }
  else
  {
    swShift = sub(norm_l(pL_av0[0]), 3);
    for (i = 0; i <= 8; i++)
      pswSav0[i] = extract_h(L_shl(pL_av0[i], swShift));
  }

  /*** compute partial sum of dm ***/

  L_sump = 0;

  for (i = 1; i <= 8; i++)
    L_sump = L_mac(L_sump, pswRav1[i], pswSav0[i]);

  /*** compute the division of the partial sum by sav0[0] ***/

  if (L_sump < 0)
    L_temp = L_negate(L_sump);
  else
    L_temp = L_sump;

  if (L_temp == 0)
  {
    L_dm = 0;
    swShift = 0;
  }
  else
  {
    pswSav0[0] = shl(pswSav0[0], 3);
    swShift = norm_l(L_temp);
    swTemp = extract_h(L_shl(L_temp, swShift));

    if (pswSav0[0] >= swTemp)
    {
      swDivShift = 0;
      swTemp = divide_s(swTemp, pswSav0[0]);
    }
    else
    {
      swDivShift = 1;
      swTemp = sub(swTemp, pswSav0[0]);
      swTemp = divide_s(swTemp, pswSav0[0]);
    }

    if (swDivShift == 1)
      L_dm = 0x8000L;
    else
      L_dm = 0;

    L_dm = L_shl((L_add(L_dm, L_deposit_l(swTemp))), 1);

    if (L_sump < 0)
      L_dm = L_sub(0L, L_dm);
  }


  /*** Re-normalisation and final computation of L_dm ***/

  L_dm = L_shl(L_dm, 14);
  L_dm = L_shr(L_dm, swShift);
  L_dm = L_add(L_dm, L_shl(L_deposit_l(pswRav1[0]), 11));
  L_dm = L_shr(L_dm, swNormRav1);


  /*** Compute the difference and save L_dm ***/

  L_temp = L_sub(L_dm, L_lastdm);
  L_lastdm = L_dm;

  if (L_temp < 0L)
    L_temp = L_negate(L_temp);


  /*** Evaluation of the state flag  ***/

  L_temp = L_sub(L_temp, 4456L);

  if (L_temp < 0)
    *pswStat = 1;
  else
    *pswStat = 0;

}

/****************************************************************************
 *
 *     FUNCTION:  tone_detection
 *
 *     VERSION:   1.2
 *
 *     PURPOSE:   Computes the tone flag needed for the threshold
 *                adaptation decision.
 *
 *     INPUTS:    pswRc[0..3] reflection coefficients calculated in the
 *                            speech encoder short term predictor
 *
 *     OUTPUTS:   pswTone     flag to indicate a periodic signal component
 *
 ***************************************************************************/

void   tone_detection(Shortword pswRc[4],
                             Shortword *pswTone)
{

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

  Longword
         L_num,
         L_den,
         L_temp;

  Shortword
         swTemp,
         swPredErr,
         pswA[3];

  int
         i;

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

  *pswTone = 0;


  /*** Calculate filter coefficients ***/

  step_up(2, pswRc, pswA);


  /*** Calculate ( a[1] * a[1] ) ***/

  swTemp = shl(pswA[1], 3);
  L_den = L_mult(swTemp, swTemp);


  /*** Calculate ( 4*a[2] - a[1]*a[1] ) ***/

  L_temp = L_shl(L_deposit_h(pswA[2]), 3);
  L_num = L_sub(L_temp, L_den);


  /*** Check if pole frequency is less than 385 Hz ***/

  if (L_num <= 0)
    return;

  if (pswA[1] < 0)
  {
    swTemp = extract_h(L_den);
    L_temp = L_msu(L_num, swTemp, 3189);

    if (L_temp < 0)
      return;
  }


  /*** Calculate normalised prediction error ***/

  swPredErr = 0x7fff;

  for (i = 0; i < 4; i++)
  {
    swTemp = mult(pswRc[i], pswRc[i]);
    swTemp = sub(32767, swTemp);
    swPredErr = mult(swPredErr, swTemp);
  }

⌨️ 快捷键说明

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