📄 sp_dec.c
字号:
swEngyLShft = norm_l(L_sum);
*pL_out = L_shl(L_sum, swEngyLShft); /* normalize output
* Longword */
}
else
{
/* Special case: energy is zero */
/*------------------------------*/
*pL_out = L_sum;
swEngyLShft = 0;
}
return (swEngyLShft);
}
/***************************************************************************
*
* FUNCTION NAME: g_corr1s (g_corr1 with scaling)
*
* PURPOSE:
*
* Calculates energy in subframe vector. Differs from g_corr1,
* in that there is an estimate of the maximum possible energy in the
* vector.
*
* INPUT:
*
* pswIn[0:39]
* A subframe vector.
*
* 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:
*
* *pL_out
* A Longword containing the normalized energy
* in the input vector.
*
* RETURN:
*
* swOut
* Number of right shifts which the accumulator was
* shifted to normalize it. Negative number implies
* a left shift, and therefore an energy larger than
* 1.0.
*
* REFERENCES: Sub-Clause 4.1.8, 4.2.1, 4.2.2, and 4.2.4
* of GSM Recomendation 06.20
*
* keywords: energy, autocorrelation, correlation, g_corr1
*
*
*************************************************************************/
Shortword g_corr1s(Shortword pswIn[], Shortword swEngyRShft,
Longword *pL_out)
{
/*_________________________________________________________________________
| |
| Automatic Variables |
|_________________________________________________________________________|
*/
Longword L_sum;
Shortword swTemp,
swEngyLShft;
Shortword swInputRShft;
int i;
/*_________________________________________________________________________
| |
| Executable Code |
|_________________________________________________________________________|
*/
/* Calculate energy in subframe vector (40 samples) */
/*--------------------------------------------------*/
if (sub(swEngyRShft, 1) <= 0)
{
/* use the energy shift factor, although it is an odd shift count */
/*----------------------------------------------------------------*/
swTemp = shr(pswIn[0], swEngyRShft);
L_sum = L_mult(pswIn[0], swTemp);
for (i = 1; i < S_LEN; i++)
{
swTemp = shr(pswIn[i], swEngyRShft);
L_sum = L_mac(L_sum, pswIn[i], swTemp);
}
}
else
{
/* convert energy shift factor to an input shift factor */
/*------------------------------------------------------*/
swInputRShft = shift_r(swEngyRShft, -1);
swEngyRShft = shl(swInputRShft, 1);
swTemp = shr(pswIn[0], swInputRShft);
L_sum = L_mult(swTemp, swTemp);
for (i = 1; i < S_LEN; i++)
{
swTemp = shr(pswIn[i], swInputRShft);
L_sum = L_mac(L_sum, swTemp, swTemp);
}
}
if (L_sum != 0)
{
/* Normalize the energy in the output Longword */
/*---------------------------------------------*/
swTemp = norm_l(L_sum);
*pL_out = L_shl(L_sum, swTemp); /* normalize output Longword */
swEngyLShft = sub(swTemp, swEngyRShft);
}
else
{
/* Special case: energy is zero */
/*------------------------------*/
*pL_out = L_sum;
swEngyLShft = 0;
}
return (swEngyLShft);
}
/***************************************************************************
*
* FUNCTION NAME: getSfrmLpc
*
* PURPOSE:
*
* Given frame information from past and present frame, interpolate
* (or copy) the frame based LPC coefficients into subframe
* lpc coeffs, i.e. the ones which will be used by the subframe
* as opposed to those coded and transmitted.
*
* INPUTS:
*
* siSoftInterpolation
*
* interpolate 1/0, a coded parameter.
*
* swPrevR0,swNewR0
*
* Rq0 for the last frame and for this frame.
* These are the decoded values, not the codewords.
*
* Previous lpc coefficients from the previous frame:
* in all filters below array[0] is the t=-1 element array[9]
* t=-10 element.
*
* pswPrevFrmKs[0:9]
*
* decoded version of the rc's tx'd last frame
*
* pswPrevFrmAs[0:9]
*
* the above K's converted to A's. i.e. direct
* form coefficients.
*
* pswPrevFrmPFNum[0:9], pswPrevFrmPFDenom[0:9]
*
* numerator and denominator coefficients used in the
* postfilter
*
* Current lpc coefficients from the current frame:
*
* pswNewFrmKs[0:9], pswNewFrmAs[0:9],
* pswNewFrmPFNum[0:9], pswNewFrmPFDenom[0:9] same as above.
*
* OUTPUTS:
*
* psnsSqrtRs[0:3]
*
* a normalized number (struct NormSw)
* containing an estimate of RS for each subframe.
* (number and a shift)
*
* ppswSynthAs[0:3][0:9]
*
* filter coefficients used by the synthesis filter.
*
* ppswPFNumAs[0:3][0:9]
*
* filter coefficients used by the postfilters
* numerator.
*
* ppswPFDenomAs[0:3][0:9]
*
* filter coefficients used by postfilters denominator.
*
* RETURN VALUE:
*
* None
*
* DESCRIPTION:
*
* For interpolated subframes, the direct form coefficients
* are converted to reflection coeffiecients to check for
* filter stability. If unstable, the uninterpolated coef.
* are used for that subframe.
*
* Interpolation is described in section 4.1.6, "Soft Interpolation
* of the Spectral Parameters"
*
* REFERENCES: Sub_clause 4.2.1 of GSM Recomendation 06.20
*
* KEYWORDS: soft interpolation, int_lpc, interpolate, atorc,res_eng,i_mov
*
*************************************************************************/
void getSfrmLpc(short int siSoftInterpolation,
Shortword swPrevR0, Shortword swNewR0,
/* last frm */ Shortword pswPrevFrmKs[], Shortword pswPrevFrmAs[],
Shortword pswPrevFrmPFNum[],
Shortword pswPrevFrmPFDenom[],
/* this frm */ Shortword pswNewFrmKs[], Shortword pswNewFrmAs[],
Shortword pswNewFrmPFNum[],
Shortword pswNewFrmPFDenom[],
/* output */ struct NormSw *psnsSqrtRs,
Shortword *ppswSynthAs[], Shortword *ppswPFNumAs[],
Shortword *ppswPFDenomAs[])
{
/*_________________________________________________________________________
| |
| Local Static Variables |
|_________________________________________________________________________|
*/
/*_________________________________________________________________________
| |
| Automatic Variables |
|_________________________________________________________________________|
*/
short int siSfrm,
siStable,
i;
Longword L_Temp1,
L_Temp2;
/*_________________________________________________________________________
| |
| Executable Code |
|_________________________________________________________________________|
*/
if (siSoftInterpolation)
{
/* yes, interpolating */
/* ------------------ */
siSfrm = 0;
siStable = interpolateCheck(pswPrevFrmKs, pswPrevFrmAs,
pswPrevFrmAs, pswNewFrmAs,
psrOldCont[siSfrm], psrNewCont[siSfrm],
swPrevR0,
&psnsSqrtRs[siSfrm],
ppswSynthAs[siSfrm]);
if (siStable)
{
/* interpolate between direct form coefficient sets */
/* for both numerator and denominator coefficients */
/* assume output will be stable */
/* ------------------------------------------------ */
for (i = 0; i < NP; i++)
{
L_Temp1 = L_mult(pswNewFrmPFNum[i], psrNewCont[siSfrm]);
ppswPFNumAs[siSfrm][i] = mac_r(L_Temp1, pswPrevFrmPFNum[i],
psrOldCont[siSfrm]);
L_Temp2 = L_mult(pswNewFrmPFDenom[i], psrNewCont[siSfrm]);
ppswPFDenomAs[siSfrm][i] = mac_r(L_Temp2, pswPrevFrmPFDenom[i],
psrOldCont[siSfrm]);
}
}
else
{
/* this subframe is unstable */
/* ------------------------- */
for (i = 0; i < NP; i++)
{
ppswPFNumAs[siSfrm][i] = pswPrevFrmPFNum[i];
ppswPFDenomAs[siSfrm][i] = pswPrevFrmPFDenom[i];
}
}
for (siSfrm = 1; siSfrm < N_SUB - 1; siSfrm++)
{
siStable = interpolateCheck(pswNewFrmKs, pswNewFrmAs,
pswPrevFrmAs, pswNewFrmAs,
psrOldCont[siSfrm], psrNewCont[siSfrm],
swNewR0,
&psnsSqrtRs[siSfrm],
ppswSynthAs[siSfrm]);
if (siStable)
{
/* interpolate between direct form coefficient sets */
/* for both numerator and denominator coefficients */
/* assume output will be stable */
/* ------------------------------------------------ */
for (i = 0; i < NP; i++)
{
L_Temp1 = L_mult(pswNewFrmPFNum[i], psrNewCont[siSfrm]);
ppswPFNumAs[siSfrm][i] = mac_r(L_Temp1, pswPrevFrmPFNum[i],
psrOldCont[siSfrm]);
L_Temp2 = L_mult(pswNewFrmPFDenom[i], psrNewCont[siSfrm]);
ppswPFDenomAs[siSfrm][i] = mac_r(L_Temp2, pswPrevFrmPFDenom[i],
psrOldCont[siSfrm]);
}
}
else
{
/* this subframe has unstable filter coeffs, would like to
* interpolate but can not */
/* -------------------------------------- */
for (i = 0; i < NP; i++)
{
ppswPFNumAs[siSfrm][i] = pswNewFrmPFNum[i];
ppswPFDenomAs[siSfrm][i] = pswNewFrmPFDenom[i];
}
}
}
/* the last subframe never interpolate */
/* ----------------------------------- */
siSfrm = 3;
for (i = 0; i < NP; i++)
{
ppswPFNumAs[siSfrm][i] = pswNewFrmPFNum[i];
ppswPFDenomAs[siSfrm][i] = pswNewFrmPFDenom[i];
ppswSynthAs[siSfrm][i] = pswNewFrmAs[i];
}
res_eng(pswNewFrmKs, swNewR0, &psnsSqrtRs[siSfrm]);
}
/* SoftInterpolation == 0 - no interpolation */
/* ------------------------------------------ */
else
{
siSfrm = 0;
for (i = 0; i < NP; i++)
{
ppswPFNumAs[siSfrm][i] = pswPrevFrmPFNum[i];
ppswPFDenomAs[siSfrm][i] = pswPrevFrmPFDenom[i];
ppswSynthAs[siSfrm][i] = pswPrevFrmAs[i];
}
res_eng(pswPrevFrmKs, swPrevR0, &psnsSqrtRs[siSfrm]);
/* for subframe 1 and all subsequent sfrms, use result from new frm */
/* ---------------------------------------------------------------- */
res_eng(pswNewFrmKs, swNewR0, &psnsSqrtRs[1]);
for (siSfrm = 1; siSfrm < N_SUB; siSfrm++)
{
psnsSqrtRs[siSfrm].man = psnsSqrtRs[1].man;
psnsSqrtRs[siSfrm].sh = psnsSqrtRs[1].sh;
for (i = 0; i < NP; i++)
{
ppswPFNumAs[siSfrm][i] = pswNewFrmPFNum[i];
ppswPFDenomAs[siSfrm][i] = pswNewFrmPFDenom[i];
ppswSynthAs[siSfrm][i] = pswNewFrmAs[i];
}
}
}
}
/***************************************************************************
*
* FUNCTION NAME: get_ipjj
*
* PURPOSE:
*
* This subroutine calculates IP, the single-resolution lag rounded
* down to the nearest integer, and JJ, the remainder when the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -