📄 sp_dec.c
字号:
* extended resolution lag is divided by the oversampling factor
*
* INPUTS:
*
* swLagIn
* extended resolution lag as an integer, i.e.
* fractional lag x oversampling factor
*
* OUTPUTS:
*
* *pswIp
* fractional lag rounded down to nearest integer, IP
*
* *pswJj
* the remainder JJ
*
* RETURN VALUE:
*
* none
*
* DESCRIPTION:
*
* ip = integer[lag/OS_FCTR]
* jj = integer_round[((lag/OS_FCTR)-ip)*(OS_FCTR)]
* if the rounding caused an 'overflow'
* set remainder jj to 0 and add 'carry' to ip
*
* This routine is involved in the mechanics of fractional and
* integer LTP searchs. The LTP is described in section 5.
*
* REFERENCES: Sub-clause 4.1.8 and 4.2.2 of GSM Recomendation 06.20
*
* KEYWORDS: lag, fractional, remainder, ip, jj, get_ipjj
*
*************************************************************************/
void get_ipjj(Shortword swLagIn,
Shortword *pswIp, Shortword *pswJj)
{
/*_________________________________________________________________________
| |
| Local Constants |
|_________________________________________________________________________|
*/
#define OS_FCTR_INV (Shortword)0x1555/* SW_MAX/OS_FCTR */
/*_________________________________________________________________________
| |
| Automatic Variables |
|_________________________________________________________________________|
*/
Longword L_Temp;
Shortword swTemp,
swTempIp,
swTempJj;
/*_________________________________________________________________________
| |
| Executable Code |
|_________________________________________________________________________|
*/
/* calculate ip */
/* ------------ */
L_Temp = L_mult(OS_FCTR_INV, swLagIn); /* lag/OS_FCTR */
swTempIp = extract_h(L_Temp);
/* calculate jj */
/* ------------ */
swTemp = extract_l(L_Temp); /* loose ip */
swTemp = shr(swTemp, 1); /* isolate jj fraction */
swTemp = swTemp & SW_MAX;
L_Temp = L_mult(swTemp, OS_FCTR); /* ((lag/OS_FCTR)-ip))*(OS_FCTR) */
swTemp = round(L_Temp); /* round and pick-off jj */
if (sub(swTemp, OS_FCTR) == 0)
{ /* if 'overflow ' */
swTempJj = 0; /* set remainder,jj to 0 */
swTempIp = add(swTempIp, 1); /* 'carry' overflow into ip */
}
else
{
swTempJj = swTemp; /* read-off remainder,jj */
}
/* return ip and jj */
/* ---------------- */
*pswIp = swTempIp;
*pswJj = swTempJj;
}
/***************************************************************************
*
* FUNCTION NAME: interpolateCheck
*
* PURPOSE:
*
* Interpolates between direct form coefficient sets.
* Before releasing the interpolated coefficients, they are checked.
* If unstable, the "old" parameters are used.
*
* INPUTS:
*
* pswRefKs[0:9]
* decoded version of the rc's tx'd last frame
*
* pswRefCoefsA[0:9]
* above K's converted to direct form coefficients
*
* pswOldCoefsA[0:9]
* array of old Coefseters
*
* pswNewCoefsA[0:9]
* array of new Coefseters
*
* swOldPer
* amount old coefs supply to the output
*
* swNewPer
* amount new coefs supply to the output
*
* ASHIFT
* shift for reflection coef. conversion
*
* swRq
* quantized energy to use for subframe
* *
* OUTPUTS:
*
* psnsSqrtRsOut
* output pointer to sqrt(RS) normalized
*
* pswCoefOutA[0:9]
* output coefficients
*
* RETURN VALUE:
*
* siInterp_flg
* temporary subframe interpolation flag
* 0 - coef. interpolated, 1 -coef. not interpolated
*
* DESCRIPTION:
*
* For interpolated subframes, the direct form coefficients
* are converted to reflection coefficients to check for
* filter stability. If unstable, the uninterpolated coef.
* are used for that subframe. Section 4.1.6 describes
* interpolation.
*
* REFERENCES: Sub-clause 4.1.6 and 4.2.3 of GSM Recomendation 06.20
*
* KEYWORDS: soft interpolation, int_lpc, interpolate, atorc,res_eng,i_mov
*
*************************************************************************/
short int interpolateCheck(Shortword pswRefKs[],
Shortword pswRefCoefsA[],
Shortword pswOldCoefsA[], Shortword pswNewCoefsA[],
Shortword swOldPer, Shortword swNewPer,
Shortword swRq,
struct NormSw *psnsSqrtRsOut,
Shortword pswCoefOutA[])
{
/*_________________________________________________________________________
| |
| Automatic Variables |
|_________________________________________________________________________|
*/
Shortword pswRcTemp[NP];
Longword L_Temp;
short int siInterp_flg,
i;
/*_________________________________________________________________________
| |
| Executable Code |
|_________________________________________________________________________|
*/
/* Interpolation loop, NP is order of LPC filter */
/* --------------------------------------------- */
for (i = 0; i < NP; i++)
{
L_Temp = L_mult(pswNewCoefsA[i], swNewPer);
pswCoefOutA[i] = mac_r(L_Temp, pswOldCoefsA[i], swOldPer);
}
/* Convert to reflection coefficients and check stability */
/* ------------------------------------------------------ */
if (aToRc(ASHIFT, pswCoefOutA, pswRcTemp) != 0)
{
/* Unstable, use uninterpolated parameters and compute RS update the
* state with the frame data closest to this subfrm */
/* --------------------------------------------------------- */
res_eng(pswRefKs, swRq, psnsSqrtRsOut);
for (i = 0; i < NP; i++)
{
pswCoefOutA[i] = pswRefCoefsA[i];
}
siInterp_flg = 0;
}
else
{
/* Stable, compute RS */
/* ------------------ */
res_eng(pswRcTemp, swRq, psnsSqrtRsOut);
/* Set temporary subframe interpolation flag */
/* ----------------------------------------- */
siInterp_flg = 1;
}
/* Return subframe interpolation flag */
/* ---------------------------------- */
return (siInterp_flg);
}
/***************************************************************************
*
* FUNCTION NAME: lagDecode
*
* PURPOSE:
*
* The purpose of this function is to decode the lag received from the
* speech encoder into a full resolution lag for the speech decoder
*
* INPUTS:
*
* swDeltaLag
*
* lag received from channel decoder
*
* giSfrmCnt
*
* current sub-frame count
*
* swLastLag
*
* previous lag to un-delta this sub-frame's lag
*
* psrLagTbl[0:255]
*
* table used to look up full resolution lag
*
* OUTPUTS:
*
* swLastLag
*
* new previous lag for next sub-frame
*
* RETURN VALUE:
*
* swLag
*
* decoded full resolution lag
*
* DESCRIPTION:
*
* If first subframe, use lag as index to look up table directly.
*
* If it is one of the other subframes, the codeword represents a
* delta offset. The previously decoded lag is used as a starting
* point for decoding the current lag.
*
* REFERENCES: Sub-clause 4.2.1 of GSM Recomendation 06.20
*
* KEYWORDS: deltalags, lookup lag
*
*************************************************************************/
static Shortword lagDecode(Shortword swDeltaLag)
{
/*_________________________________________________________________________
| |
| Local Constants |
|_________________________________________________________________________|
*/
#define DELTA_LEVELS_D2 DELTA_LEVELS/2
#define MAX_LAG 0x00ff
#define MIN_LAG 0x0000
/*_________________________________________________________________________
| |
| Local Static Variables |
|_________________________________________________________________________|
*/
static Shortword swLastLag;
/*_________________________________________________________________________
| |
| Automatic Variables |
|_________________________________________________________________________|
*/
Shortword swLag;
/*_________________________________________________________________________
| |
| Executable Code |
|_________________________________________________________________________|
*/
/* first sub-frame */
/* --------------- */
if (giSfrmCnt == 0)
{
swLastLag = swDeltaLag;
}
/* remaining sub-frames */
/* -------------------- */
else
{
/* get lag biased around 0 */
/* ----------------------- */
swLag = sub(swDeltaLag, DELTA_LEVELS_D2);
/* get real lag relative to last */
/* ----------------------------- */
swLag = add(swLag, swLastLag);
/* clip to max or min */
/* ------------------ */
if (sub(swLag, MAX_LAG) > 0)
{
swLastLag = MAX_LAG;
}
else if (sub(swLag, MIN_LAG) < 0)
{
swLastLag = MIN_LAG;
}
else
{
swLastLag = swLag;
}
}
/* return lag after look up */
/* ------------------------ */
swLag = psrLagTbl[swLastLag];
return (swLag);
}
/***************************************************************************
*
* FUNCTION NAME: lookupVq
*
* PURPOSE:
*
* The purpose of this function is to recover the reflection coeffs from
* the received LPC codewords.
*
* INPUTS:
*
* pswVqCodeWds[0:2]
*
* the codewords for each of the segments
*
* OUTPUTS:
*
* pswRCOut[0:NP-1]
*
* the decoded reflection coefficients
*
* RETURN VALUE:
*
* none.
*
* DESCRIPTION:
*
* For each segment do the following:
* setup the retrieval pointers to the correct vector
* get that vector
*
* REFERENCES: Sub-clause 4.2.3 of GSM Recomendation 06.20
*
* KEYWORDS: vq, vectorquantizer, lpc
*
*************************************************************************/
static void lookupVq(Shortword pswVqCodeWds[], Shortword pswRCOut[])
{
/*_________________________________________________________________________
| |
| Local Constants
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -