?? vad.c
字號:
/****************************************************************************
*
* 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 + -