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