📄 sp_sfrm.c
字号:
}
else
swQShift = negate(swQShift);
for (i = 0; i < S_LEN; i++)
{
L_Accum = L_msu(0x00008000L, pswVects[i + iLoopCnt * S_LEN], SW_MIN);
pswVects[iLoopCnt * S_LEN + i] = extract_h(L_mac(L_Accum, swTemp,
shl(pswGivenVect[i], swQShift)));
}
}
}
/***************************************************************************
*
* FUNCTION NAME: g_corr2
*
* PURPOSE: Calculates correlation between subframe vectors.
*
*
* INPUT:
*
* pswIn[0:39]
* A subframe vector.
*
* pswIn2[0:39]
* A subframe vector.
*
*
* OUTPUT:
*
* *pL_out
* A Longword containing the normalized correlation
* between the input vectors.
*
* 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.
*
* REFERENCE: Sub-clauses 4.1.10.1 and 4.1.11.1 of GSM
* Recommendation 06.20
*
* keywords: energy, autocorrelation, correlation, g_corr2
*
*
**************************************************************************/
Shortword g_corr2(Shortword *pswIn, Shortword *pswIn2,
Longword *pL_out)
{
/*_________________________________________________________________________
| |
| Automatic Variables |
|_________________________________________________________________________|
*/
Longword L_sum;
Shortword swEngyLShft;
int i;
/*_________________________________________________________________________
| |
| Executable Code |
|_________________________________________________________________________|
*/
/* Calculate energy in subframe vector (40 samples) */
/*--------------------------------------------------*/
L_sum = L_mult(pswIn[0], pswIn2[0]);
for (i = 1; i < S_LEN; i++)
{
L_sum = L_mac(L_sum, pswIn[i], pswIn2[i]);
}
if (L_sum != 0)
{
/* Normalize the energy in the output Longword */
/*---------------------------------------------*/
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_quant_vl
*
* PURPOSE:
*
* Joint quantization of excitation gains.
* GS represents the subframe energy relative to the frame energy.
* P0 represents the relative contribution of the first exctitation
* source to the total excitation.
*
* INPUTS:
*
* swUVCode - voicing level (Mode 0-3)
* pswWInput[0:39] - weighted input p(n) (used in mode 0-3)
* swWIShift - weighted input shift factor (right shift, 0,1, or 2)
* pswWLTPVec[0:39] - weighted pitch excitation vector (used in mode 1-3)
* pswWVSVec1[0:39] - weighted 1st v-s codevector (used in mode 0-3)
* pswWVSVec2[0:39] - weighted 2nd v-s codevector (used in mode 0)
* snsRs00 - square root of RS/pitch excitation energy (used in mode 1-3)
* snsRs11 - square root of RS/1st v-s codevector energy
* (used in mode 0-3)
* snsRs22 - square root of RS/2nd v-s codevector energy (used in mode 0)
*
* pppsrGsp0[0:3][0:31][0:4] - lookup table
*
* OUTPUTS:
*
* None
*
* RETURN VALUE:
*
* siCode - output quantized gain code (5 bits)
*
* IMPLEMENTATION:
*
* Calculates first the parameters required for error equation 7.21:
*
* Rcc(k,j) k = 0,1, j=k,1
* Rx(k) k = 0,1
* RS
* Rpc(k) k = 0,1
* a,b,c,d,e
*
* The constant terms in equation 7.21 are stored in ROM instead of GS
* and P0. There is one vector quantizer for each voicing state.
*
* REFERENCE: Sub-clause 4.1.11 and 4.1.11.1 of GSM Recommendation 06.20
*
* KEYWORDS: gain quantization, energy domain transforms, p0, gs
*
**************************************************************************/
Shortword g_quant_vl(Shortword swUVCode,
Shortword pswWInput[], Shortword swWIShift,
Shortword pswWLTPVec[],
Shortword pswWVSVec1[], Shortword pswWVSVec2[],
struct NormSw snsRs00, struct NormSw snsRs11,
struct NormSw snsRs22)
{
/*_________________________________________________________________________
| |
| Automatic Variables |
|_________________________________________________________________________|
*/
Longword L_Temp,
L_Temp2;
Shortword swShift;
struct NormSw ErrorTerm[6];
Shortword i,
siCode,
siNormShift,
siNormMin;
/*_________________________________________________________________________
| |
| Executable Code |
|_________________________________________________________________________|
*/
/* Test voicing level, mode 0-3 */
/* ---------------------------- */
if (swUVCode == 0)
{
/* Unvoiced */
/* -------- */
/* Compute cross correlation Rpc(0) */
/* -------------------------------- */
ErrorTerm[0].sh = g_corr2(pswWInput, pswWVSVec1, &L_Temp);
ErrorTerm[0].man = round(L_Temp);
/* Compute cross correlation Rpc(1) */
/* -------------------------------- */
ErrorTerm[1].sh = g_corr2(pswWInput, pswWVSVec2, &L_Temp);
ErrorTerm[1].man = round(L_Temp);
/* Compute cross correlation Rcc(0,1) */
/* ---------------------------------- */
ErrorTerm[2].sh = g_corr2(pswWVSVec1, pswWVSVec2, &L_Temp);
ErrorTerm[2].man = round(L_Temp);
/* Compute correlation Rcc(0,0) */
/* ---------------------------- */
ErrorTerm[3].sh = g_corr1(pswWVSVec1, &L_Temp);
ErrorTerm[3].man = round(L_Temp);
/* Compute correlation Rcc(1,1) */
/* ---------------------------- */
ErrorTerm[4].sh = g_corr1(pswWVSVec2, &L_Temp);
ErrorTerm[4].man = round(L_Temp);
/* Compute correlation Rpp */
/* ----------------------- */
ErrorTerm[5].sh = g_corr1(pswWInput, &L_Temp);
ErrorTerm[5].man = round(L_Temp);
/* Compute gain tweak factor, adjusts A and B error coefs */
/* ------------------------------------------------------ */
gainTweak(&ErrorTerm[0]);
/* Compute error coefficient A, equation 5.22 */
/* ------------------------------------------ */
L_Temp = L_mult(ErrorTerm[0].man, snsRs11.man);
swShift = norm_s(extract_h(L_Temp));
ErrorTerm[0].sh = add(ErrorTerm[0].sh, swShift);
ErrorTerm[0].man = round(L_shl(L_Temp, swShift));
ErrorTerm[0].sh = add(ErrorTerm[0].sh, snsRs11.sh);
siNormMin = ErrorTerm[0].sh;
/* Compute error coefficient B, equation 5.23 */
/* ------------------------------------------ */
L_Temp = L_mult(ErrorTerm[1].man, snsRs22.man);
swShift = norm_s(extract_h(L_Temp));
ErrorTerm[1].sh = add(ErrorTerm[1].sh, swShift);
ErrorTerm[1].man = round(L_shl(L_Temp, swShift));
ErrorTerm[1].sh = add(ErrorTerm[1].sh, snsRs22.sh);
if (sub(ErrorTerm[1].sh, siNormMin) < 0)
siNormMin = ErrorTerm[1].sh;
/* Compute error coefficient C, equation 5.24 */
/* ------------------------------------------ */
L_Temp = L_mult(ErrorTerm[2].man, snsRs11.man);
swShift = norm_s(extract_h(L_Temp));
ErrorTerm[2].sh = add(ErrorTerm[2].sh, swShift);
ErrorTerm[2].man = round(L_shl(L_Temp, swShift));
L_Temp = L_mult(ErrorTerm[2].man, snsRs22.man);
swShift = norm_s(extract_h(L_Temp));
ErrorTerm[2].sh = add(ErrorTerm[2].sh, swShift);
ErrorTerm[2].man = round(L_shl(L_Temp, swShift));
ErrorTerm[2].sh = add(ErrorTerm[2].sh, snsRs11.sh);
ErrorTerm[2].sh = add(ErrorTerm[2].sh, snsRs22.sh);
ErrorTerm[2].sh = add(ErrorTerm[2].sh, swWIShift);
if (sub(ErrorTerm[2].sh, siNormMin) < 0)
siNormMin = ErrorTerm[2].sh;
/* Compute error coefficient D, equation 5.25 */
/* ------------------------------------------ */
L_Temp = L_mult(ErrorTerm[3].man, snsRs11.man);
swShift = norm_s(extract_h(L_Temp));
ErrorTerm[3].sh = add(ErrorTerm[3].sh, swShift);
ErrorTerm[3].man = round(L_shl(L_Temp, swShift));
L_Temp = L_mult(ErrorTerm[3].man, snsRs11.man);
swShift = norm_s(extract_h(L_Temp));
ErrorTerm[3].sh = add(ErrorTerm[3].sh, swShift);
ErrorTerm[3].man = round(L_shl(L_Temp, swShift));
ErrorTerm[3].sh = add(ErrorTerm[3].sh, snsRs11.sh);
ErrorTerm[3].sh = add(ErrorTerm[3].sh, snsRs11.sh);
ErrorTerm[3].sh = add(ErrorTerm[3].sh, swWIShift);
if (sub(ErrorTerm[3].sh, siNormMin) < 0)
siNormMin = ErrorTerm[3].sh;
/* Compute error coefficient E, equation 5.26 */
/* ------------------------------------------ */
L_Temp = L_mult(ErrorTerm[4].man, snsRs22.man);
swShift = norm_s(extract_h(L_Temp));
ErrorTerm[4].sh = add(ErrorTerm[4].sh, swShift);
ErrorTerm[4].man = round(L_shl(L_Temp, swShift));
L_Temp = L_mult(ErrorTerm[4].man, snsRs22.man);
swShift = norm_s(extract_h(L_Temp));
ErrorTerm[4].sh = add(ErrorTerm[4].sh, swShift);
ErrorTerm[4].man = round(L_shl(L_Temp, swShift));
ErrorTerm[4].sh = add(ErrorTerm[4].sh, snsRs22.sh);
ErrorTerm[4].sh = add(ErrorTerm[4].sh, snsRs22.sh);
ErrorTerm[4].sh = add(ErrorTerm[4].sh, swWIShift);
if (sub(ErrorTerm[4].sh, siNormMin) < 0)
siNormMin = ErrorTerm[4].sh;
}
else
{ /* Voicing level */
/* Voiced */
/* ------ */
/* Compute cross correlation Rpc(0) */
/* -------------------------------- */
ErrorTerm[0].sh = g_corr2(pswWInput, pswWLTPVec, &L_Temp);
ErrorTerm[0].man = round(L_Temp);
/* Compute cross correlation Rpc(1) */
/* -------------------------------- */
ErrorTerm[1].sh = g_corr2(pswWInput, pswWVSVec1, &L_Temp);
ErrorTerm[1].man = round(L_Temp);
/* Compute cross correlation Rcc(0,1) */
/* ---------------------------------- */
ErrorTerm[2].sh = g_corr2(pswWLTPVec, pswWVSVec1, &L_Temp);
ErrorTerm[2].man = round(L_Temp);
/* Compute correlation Rcc(0,0) */
/* ---------------------------- */
ErrorTerm[3].sh = g_corr1(pswWLTPVec, &L_Temp);
ErrorTerm[3].man = round(L_Temp);
/* Compute correlation Rcc(1,1) */
/* ---------------------------- */
ErrorTerm[4].sh = g_corr1(pswWVSVec1, &L_Temp);
ErrorTerm[4].man = round(L_Temp);
/* Compute correlation Rpp */
/* ----------------------- */
ErrorTerm[5].sh = g_corr1(pswWInput, &L_Temp);
ErrorTerm[5].man = round(L_Temp);
/* Compute gain tweak factor, adjusts A and B error coefs */
/* ------------------------------------------------------ */
gainTweak(&ErrorTerm[0]);
/* Compute error coefficient A, equation 5.22 */
/* ------------------------------------------ */
L_Temp = L_mult(ErrorTerm[0].man, snsRs00.man);
swShift = norm_s(extract_h(L_Temp));
ErrorTerm[0].sh = add(ErrorTerm[0].sh, swShift);
ErrorTerm[0].man = round(L_shl(L_Temp, swShift));
ErrorTerm[0].sh = add(ErrorTerm[0].sh, snsRs00.sh);
siNormMin = ErrorTerm[0].sh;
/* Compute error coefficient B, equation 5.23 */
/* ------------------------------------------ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -