?? sp_dec.c
字號:
pL_swap = pL_vjNew;
pL_vjNew = pL_vjOld;
pL_vjOld = pL_swap;
/* Compute the j-th reflection coefficient */
/*-----------------------------------------*/
swTemp = norm_l(pL_pjOld[0]); /* get shift count */
swTemp1 = round(L_shl(pL_vjOld[0], swTemp)); /* normalize num. */
swTemp2 = round(L_shl(pL_pjOld[0], swTemp)); /* normalize den. */
/* Test for invalid divide conditions: a) devisor < 0 b) abs(divident) >
* abs(devisor) If either of these conditions is true, zero out
* reflection coefficients for i=j,...,NP-1 and return. */
swAbsTemp1 = abs_s(swTemp1);
if (swTemp2 <= 0 || sub(swAbsTemp1, swTemp2) >= 0)
{
i = j;
for (i = j; i < NP; i++)
{
pswRc[i] = 0;
}
return;
}
swRc = divide_s(swAbsTemp1, swTemp2); /* return division result */
if (sub(swTemp1, swAbsTemp1) == 0)
swRc = negate(swRc); /* negate reflection Rc[j] */
swRcSq = mult_r(swRc, swRc); /* compute Rc^2 */
pswRc[j] = swRc; /* copy Rc[j] to output array */
/* Update pjNew and vjNew arrays for the next lattice stage if j < NP-1 */
/*---------------------------------------------------------------------*/
/* Updating pjNew: */
/*-----------------*/
for (i = 0; i <= NP - j - 2; i++)
{
L_temp = L_mpy_ls(pL_vjOld[i], swRc);
L_sum = L_add(L_temp, pL_pjOld[i]);
L_temp = L_mpy_ls(pL_pjOld[i], swRcSq);
L_sum = L_add(L_temp, L_sum);
L_temp = L_mpy_ls(pL_vjOld[-i], swRc);
pL_pjNew[i] = L_add(L_sum, L_temp);
}
/* Updating vjNew: */
/*-----------------*/
for (i = -NP + j + 2; i <= NP - j - 2; i++)
{
L_temp = L_mpy_ls(pL_vjOld[-i - 1], swRcSq);
L_sum = L_add(L_temp, pL_vjOld[i + 1]);
L_temp = L_mpy_ls(pL_pjOld[(((i + 1) >= 0) ? i + 1 : -(i + 1))], swRc);
L_temp = L_shl(L_temp, 1);
pL_vjNew[i] = L_add(L_temp, L_sum);
}
}
return;
}
/***************************************************************************
*
* FUNCTION NAME: aToRc
*
* PURPOSE:
*
* This subroutine computes a vector of reflection coefficients, given
* an input vector of direct form LPC filter coefficients.
*
* INPUTS:
*
* NP
* order of the LPC filter (global constant)
*
* swAshift
* The number of right shifts applied externally
* to the direct form filter coefficients.
*
* pswAin[0:NP-1]
* The input vector of direct form LPC filter
* coefficients.
*
* OUTPUTS:
*
* pswRc[0:NP-1]
* Array containing the reflection coefficients.
*
* RETURN VALUE:
*
* siUnstableFlt
* If stable reflection coefficients 0, 1 if unstable.
*
*
* DESCRIPTION:
*
* This function performs the conversion from direct form
* coefficients to reflection coefficients. It is used in a_sst()
* and interpolateCheck(). In a_sst() reflection coefficients used
* as a transitional data format. aToRc() is used for this
* conversion.
*
* When performing interpolation, a stability check must be
* performed. interpolateCheck() does this by calling aToRc().
*
* First coefficients are shifted down by iAshift. NP, the filter
* order is 10. The a's and rc's each have NP elements in them. An
* elaborate algorithm description can be found on page 443, of
* "Digital Processing of Speech Signals" by L.R. Rabiner and R.W.
* Schafer; Prentice-Hall; Englewood Cliffs, NJ (USA). 1978.
*
* REFERENCES: Sub_Clause 4.1.6, and 4.2.3 of GSM Recomendation 06.20
*
* KEYWORDS: reflectioncoefficients, parcors, conversion, atorc, ks, as
* KEYWORDS: parcorcoefficients, lpc, flat, vectorquantization
*
*************************************************************************/
static short aToRc(Shortword swAshift, Shortword pswAin[],
Shortword pswRc[])
{
/*_________________________________________________________________________
| |
| Constants |
|_________________________________________________________________________|
*/
/*_________________________________________________________________________
| |
| Automatic Variables |
|_________________________________________________________________________|
*/
Shortword pswTmpSpace[NP],
pswASpace[NP],
swNormShift,
swActShift,
swNormProd,
swRcOverE,
swDiv,
*pswSwap,
*pswTmp,
*pswA;
Longword L_temp;
short int siUnstableFlt,
i,
j; /* Loop control variables */
/*_________________________________________________________________________
| |
| Executable Code |
|_________________________________________________________________________|
*/
/* Initialize starting addresses for temporary buffers */
/*-----------------------------------------------------*/
pswA = pswASpace;
pswTmp = pswTmpSpace;
/* Copy the direct form filter coefficients to a temporary array */
/*---------------------------------------------------------------*/
for (i = 0; i < NP; i++)
{
pswA[i] = pswAin[i];
}
/* Initialize the flag for filter stability check */
/*------------------------------------------------*/
siUnstableFlt = 0;
/* Start computation of the reflection coefficients, Rc[9],...,Rc[1] */
/*-------------------------------------------------------------------*/
for (i = NP - 1; i >= 1; i--)
{
pswRc[i] = shl(pswA[i], swAshift); /* write Rc[i] to output array */
/* Check the stability of i-th reflection coefficient */
/*----------------------------------------------------*/
siUnstableFlt = siUnstableFlt | isSwLimit(pswRc[i]);
/* Precompute intermediate variables for needed for the computation */
/* of direct form filter of order i-1 */
/*------------------------------------------------------------------*/
if (sub(pswRc[i], SW_MIN) == 0)
{
siUnstableFlt = 1;
swRcOverE = 0;
swDiv = 0;
swActShift = 2;
}
else
{
L_temp = LW_MAX; /* Load ~1.0 into accum */
L_temp = L_msu(L_temp, pswRc[i], pswRc[i]); /* 1.-Rc[i]*Rc[i] */
swNormShift = norm_l(L_temp);
L_temp = L_shl(L_temp, swNormShift);
swNormProd = extract_h(L_temp);
swActShift = add(2, swNormShift);
swDiv = divide_s(0x2000, swNormProd);
swRcOverE = mult_r(pswRc[i], swDiv);
}
/* Check stability */
/*---------------------*/
siUnstableFlt = siUnstableFlt | isSwLimit(swRcOverE);
/* Compute direct form filter coefficients corresponding to */
/* a direct form filter of order i-1 */
/*----------------------------------------------------------*/
for (j = 0; j <= i - 1; j++)
{
L_temp = L_mult(pswA[j], swDiv);
L_temp = L_msu(L_temp, pswA[i - j - 1], swRcOverE);
L_temp = L_shl(L_temp, swActShift);
pswTmp[j] = round(L_temp);
siUnstableFlt = siUnstableFlt | isSwLimit(pswTmp[j]);
}
/* Swap swA and swTmp buffers */
/*----------------------------*/
pswSwap = pswA;
pswA = pswTmp;
pswTmp = pswSwap;
}
/* Compute reflection coefficient Rc[0] */
/*--------------------------------------*/
pswRc[0] = shl(pswA[0], swAshift); /* write Rc[0] to output array */
/* Check the stability of 0-th reflection coefficient */
/*----------------------------------------------------*/
siUnstableFlt = siUnstableFlt | isSwLimit(pswRc[0]);
return (siUnstableFlt);
}
/***************************************************************************
*
* FUNCTION NAME: a_sst
*
* PURPOSE:
*
* The purpose of this function is to perform spectral smoothing of the
* direct form filter coefficients
*
* INPUTS:
*
* swAshift
* number of shift for coefficients
*
* swAscale
* scaling factor for coefficients
*
* pswDirectFormCoefIn[0:NP-1]
*
* array of input direct form coefficients
*
* OUTPUTS:
*
* pswDirectFormCoefOut[0:NP-1]
*
* array of output direct form coefficients
*
* RETURN VALUE:
*
* none
*
* DESCRIPTION:
*
* In a_sst() direct form coefficients are converted to
* autocorrelations, and smoothed in that domain. The function is
* used in the spectral postfilter. A description can be found in
* section 3.2.4 as well as in the reference by Y. Tohkura et al.
* "Spectral Smoothing Technique in PARCOR Speech
* Analysis-Synthesis", IEEE Trans. ASSP, vol. ASSP-26, pp. 591-596,
* Dec. 1978.
*
* After smoothing is performed conversion back to direct form
* coefficients is done by calling aFlatRc(), followed by rcToADp().
*
* The spectral smoothing filter coefficients with bandwidth set to 300
* and a sampling rate of 8000 be :
* static ShortwordRom psrSST[NP+1] = { 0x7FFF,
* 0x7F5C, 0x7D76, 0x7A5B, 0x7622, 0x70EC,
* 0x6ADD, 0x641F, 0x5CDD, 0x5546, 0x4D86
* }
*
* REFERENCES: Sub_Clause 4.2.4 of GSM Recomendation 06.20
*
* KEYWORDS: spectral smoothing, direct form coef, sst, atorc, atocor
* KEYWORDS: levinson
*
*************************************************************************/
static void a_sst(Shortword swAshift, Shortword swAscale,
Shortword pswDirectFormCoefIn[],
Shortword pswDirectFormCoefOut[])
{
/*_________________________________________________________________________
| |
| Local Static Variables |
|_________________________________________________________________________|
*/
static ShortwordRom psrSST[NP + 1] = {0x7FFF,
0x7F5C, 0x7D76, 0x7A5B, 0x7622, 0x70EC,
0x6ADD, 0x641F, 0x5CDD, 0x5546, 0x4D86,
};
/*_________________________________________________________________________
| |
| Automatic Variables |
|_________________________________________________________________________|
*/
Longword pL_CorrTemp[NP + 1];
Shortword pswRCNum[NP],
pswRCDenom[NP];
short int siLoopCnt;
/*_________________________________________________________________________
| |
| Executable Code |
|_________________________________________________________________________|
*/
/* convert direct form coefs to reflection coefs */
/* --------------------------------------------- */
aToRc(swAshift, pswDirectFormCoefIn, pswRCDenom);
/* convert to autocorrelation coefficients */
/* --------------------------------------- */
rcToCorrDpL(swAshift, swAscale, pswRCDenom, pL_CorrTemp);
/* do spectral smoothing technique */
/* ------------------------------- */
for (siLoopCnt = 1; siLoopCnt <= NP; siLoopCnt++)
{
pL_CorrTemp[siLoopCnt] = L_mpy_ls(pL_CorrTemp[siLoopCnt],
psrSST[siLoopCnt]);
}
/* Compute the reflection coefficients via AFLAT */
/*-----------------------------------------------*/
aFlatRcDp(pL_CorrTemp, pswRCNum);
/* Convert reflection coefficients to direct form filter coefficients */
/*-------------------------------------------------------------------*/
rcToADp(swAscale, pswRCNum, pswDirectFormCoefOut);
}
/**************************************************************************
*
* FUNCTION NAME: agcGain
*
* PURPOSE:
*
* Figure out what the agc gain should be to make the energy in the
* output signal match that of the input signal. Used in the post
* filters.
*
* INPUT:
*
* pswStateCurr[0:39]
* Input signal into agc block whose energy is
* to be modified using the gain returned. Signal is not
* modified in this routine.
*
* snsInSigEnergy
* Normalized number with shift count - the energy in
* the input signal.
*
* swEngyRShft
* Number of right shifts to apply to the vectors energy
* to ensure that it remains less than 1.0
* (swEngyRShft is always positive or zero)
*
* OUTPUT:
*
* none
*
* RETURN:
*
* the agc's gain/2 note DIVIDED by 2
*
*
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -