📄 gain_q.c
字号:
/* determine the scaling exponent for g_code: ec = ec0 - 11 */
exp_code = exp_gcode0 - 11;
/* calculate exp_max[i] = s[i]-1 */
exp_max[0] = pexp_coeff[0] -13;
exp_max[1] = pexp_coeff[1] -14;
exp_max[2] = pexp_coeff[2] +15+(exp_code<<1);
exp_max[3] = pexp_coeff[3] + exp_code;
exp_max[4] = pexp_coeff[4] + 1 + exp_code;
/*-------------------------------------------------------------------*
* Find maximum exponent: *
* ~~~~~~~~~~~~~~~~~~~~~~ *
* *
* For the sum operation, all terms must have the same scaling; *
* that scaling should be low enough to prevent overflow. There- *
* fore, the maximum scale is determined and all coefficients are *
* re-scaled: *
* *
* e_max = max(exp_max[i]) + 1; *
* e = exp_max[i]-e_max; e <= 0! *
* c[i] = c[i]*2^e *
*-------------------------------------------------------------------*/
e_max = exp_max[0];
t1 = exp_max[1] > exp_max[2] ? exp_max[1] : exp_max[2];
t2 = exp_max[3] > exp_max[4] ? exp_max[3] : exp_max[4];
t1 = t1 > t2 ? t1 : t2;
e_max = e_max > t1 ? e_max : t1;
e_max++; /* To avoid overflow */
for (i = 0; i < 5; i++)
{
j = e_max-exp_max[i];
L_tmp = (pfrac_coeff[i]<<16);
if( j < 0)
{
j = j<-32 ? -32 : j;
L_tmp = (L_tmp >= (MAX_32>>(-j) )) ? MAX_32 : ((L_tmp <= (MIN_32>>(-j) ) )? MIN_32 : L_tmp << -j );
}
else
{
L_tmp = j>= 31 ? (L_tmp > 0 ? 0: -1) : L_tmp >> j;
}
coeff[i] = (Word16)(L_tmp >> 16);
coeff_lo[i] = (L_tmp - (coeff[i]<<16))>>1;
}
/*-------------------------------------------------------------------*
* Codebook search: *
* ~~~~~~~~~~~~~~~~ *
* *
* For each pair (g_pitch, g_fac) in the table calculate the *
* terms t[0..4] and sum them up; the result is the mean squared *
* error for the quantized gains from the table. The index for the *
* minimum MSE is stored and finally used to retrieve the quantized *
* gains *
*-------------------------------------------------------------------*/
/* start with "infinite" MSE */
dist_min = MAX_32;
p = &table_gain[0];
for (i = 0; i < table_len; i++)
{
g_pitch = *p++;
g_code = *p++;
p++; /* skip log2(g_fac) */
p++; /* skip 20*log10(g_fac) */
if ( g_pitch <= gp_limit)
{
g_code = (g_code*gcode0 >>15);
g2_pitch = (g_pitch*g_pitch >>15);
g2_code = (g_code*g_code >>15);
g_pit_cod =(g_code*g_pitch >>15);
L_tmp = (coeff[0]*g2_pitch<<1)+(( coeff_lo[0]* g2_pitch>>15)<<1);
L_tmp += (coeff[1]*g_pitch<<1) + ((coeff_lo[1]*g_pitch>>15)<<1);
L_tmp += (coeff[2]*g2_code<<1) +((coeff_lo[2]*g2_code>>15)<<1);
L_tmp += (coeff[3]*g_code<<1) +((coeff_lo[3]*g_code>>15 )<<1);
L_tmp += (coeff[4]*g_pit_cod<<1)+((coeff_lo[4]*g_pit_cod>>15)<<1);
/* store table index if MSE for this index is lower
than the minimum MSE seen so far */
index = (L_tmp < dist_min) ? i : index;
dist_min = (L_tmp < dist_min) ? L_tmp : dist_min;
}
}
/*------------------------------------------------------------------*
* read quantized gains and new values for MA predictor memories *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
*------------------------------------------------------------------*/
/* Read the quantized gains */
p = &table_gain[index<<2];
*gain_pit = *p++;
g_code = *p++;
*qua_ener_MR122 = *p++;
*qua_ener = *p;
/*------------------------------------------------------------------*
* calculate final fixed codebook gain: *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* *
* gc = gc0 * g *
*------------------------------------------------------------------*/
L_tmp = (g_code*gcode0 << 1);
L_tmp = (10 > exp_gcode0) ? L_tmp >> (10 - exp_gcode0): L_tmp <<(exp_gcode0 -10);
*gain_cod = (Word16)(L_tmp>>16);
return index;
}
/****************************************************
Function: q_gain_code
Description:
Input :
mode: AMR mode
exp_gcode0 : predicted CB gain (exponent), Q0
frac_gcode0 : predicted CB gain (fraction), Q15
gain : quantized fixed codebook gain, Q1
Output :
gain : quantized fixed codebook gain, Q1
qua_ener_MR122 : quantized energy error, Q10
qua_ener : quantized energy error, Q10
Return :
Quantizaiotn index
*******************************************************/
Word16 q_gain_code (Mode mode, Word16 exp_gcode0, Word16 frac_gcode0, Word16 *gain, Word16 *qua_ener_MR122, Word16 *qua_ener )
{
const Word16 *p,*pqua_gain_code = qua_gain_code; Word16 i, index; Word16 gcode0, err, err_min; Word16 g_q0,temp;
Word16 *pgain = gain, *pqua_ener_MR122 = qua_ener_MR122, *pqua_ener = qua_ener;
g_q0 = *gain >>1 ;
/*-------------------------------------------------------------------* * predicted codebook gain * * ~~~~~~~~~~~~~~~~~~~~~~~ * * gc0 = Pow2(int(d)+frac(d)) * * = 2^exp + 2^frac * * * *-------------------------------------------------------------------*/ gcode0 = (Word16)(Pow2 (exp_gcode0, frac_gcode0)); /* predicted gain */
gcode0 = gcode0>= 0x07ff ? MAX_16 : gcode0<<4;
/*-------------------------------------------------------------------* * Search for best quantizer * *-------------------------------------------------------------------*/ p = &pqua_gain_code[0];
temp = g_q0 - (gcode0*( *p++)>>15);
err_min = temp > 0 ? temp : -temp ;
p += 2; /* skip quantized energy errors */ index = 0; for (i = 1; i < NB_QUA_CODE; i++) {
temp = g_q0 - (gcode0*(*p++)>>15);
err = temp>0 ? temp: -temp;
p += 2; /* skip quantized energy error */
index = err<err_min? i : index;
err_min = err < err_min ? err : err_min;
} p = &pqua_gain_code[index+index+ index];
*gain = ( (gcode0*(*p++)>>15) <<1);
/* quantized error energies (for MA predictor update) */ *pqua_ener_MR122 = *p++;
*pqua_ener = *p;
return index;
}
/*************************************************************************
Function : calc_filt_energies
Purpose: calculation of several energy coefficients for filteredexcitation signals
Compute coefficients need for the quantization and the optimum
codebook gain gcu (for MR475 only).
coeff[0] = y1 y1
coeff[1] = -2 xn y1
coeff[2] = y2 y2
coeff[3] = -2 xn y2
coeff[4] = 2 y1 y2
gcu = <xn2, y2> / <y2, y2> (0 if <xn2, y2> <= 0)
Product <y1 y1> and <xn y1> have been computed in G_pitch() and
are in vector g_coeff[].
Input:
mode : coder mode
xn[] : LTP target vector, Q0
xn2[] : CB target vector, Q0
y1[] : Adaptive codebook, Q0
Y2[] : Filtered innovative vector, Q12
g_coeff[] : Correlations <xn y1> <y1 y1>
Output:
frac_coeff[] : energy coefficients (5), fraction part, Q15
exp_coeff[] : energy coefficients (5), exponent part, Q0
cod_gain_frac : optimum codebook gain (fraction part), Q15
cod_gain_exp : optimum codebook gain (exponent part), Q0
Return: void
*************************************************************************/void calc_filt_energies( Mode mode, Word16 xn[], Word16 xn2[], Word16 y1[], Word16 Y2[], Word16 g_coeff[],
Word16 frac_coeff[], Word16 exp_coeff[], Word16 *cod_gain_frac, Word16 *cod_gain_exp )
{
Word32 s,s1,s2,s3, ener_init;
Word16 i, exp,exp1,exp2,exp3, frac;
Word16 y2[L_SUBFR];
Word16*pY2 = Y2, *pfrac_coeff = frac_coeff, *pexp_coeff = exp_coeff, *pg_coeff = g_coeff, *pcod_gain_frac = cod_gain_frac, *pcod_gain_exp = cod_gain_exp;
Word16 *pxn = xn, *pxn2 = xn2, *py1 = y1;
ener_init = ((mode == MR795)||(mode == MR475)) ? 0 : 1 ;
for (i = 0; i < L_SUBFR; i+=8)
{
y2[i] = pY2[i] >> 3; y2[i+1] = pY2[i+1] >> 3;y2[i+2] = pY2[i+2] >> 3;y2[i+3] = pY2[i+3] >> 3;
y2[i+4] = pY2[i+4] >> 3; y2[i+5] = pY2[i+5] >> 3;y2[i+6] = pY2[i+6] >> 3;y2[i+7] = pY2[i+7] >> 3;
}
pfrac_coeff[0] = pg_coeff[0];
pexp_coeff[0] = pg_coeff[1];
pfrac_coeff[1] = (pg_coeff[2] == MIN_16 ? MAX_16 : -pg_coeff[2]);
pexp_coeff[1] = (pg_coeff[3] + 1);
/* Compute scalar product <y2[],y2[]> */ s = ener_init;
s1 = ener_init;
s2 = ener_init;
s3 = ener_init;
for (i = 0; i < L_SUBFR; i+=4 )
{
s += (y2[i]*y2[i] + y2[i+1]*y2[i+1] + y2[i+2]*y2[i+2] + y2[i+3]*y2[i+3]) <<1;
s1 += (pxn[i]*y2[i] + pxn[i+1]*y2[i+1] + pxn[i+2]*y2[i+2] + pxn[i+3]*y2[i+3]) <<1;
s2 += (py1[i]*y2[i] + py1[i+1]*y2[i+1] + py1[i+2]*y2[i+2] + py1[i+3]*y2[i+3]) <<1;
}
exp = norm_l(s);
exp1 = norm_l(s1);
exp2 = norm_l(s2);
pfrac_coeff[2] = (Word16)((s<< exp)>>16);
pexp_coeff[2] = (-3 - exp);
pfrac_coeff[3] = (Word16)(( (s1 << exp1)>>16) == MIN_16 ? MAX_16 : -( (s1 << exp1)>>16)) ;
pexp_coeff[3] = 7 - exp1;
pfrac_coeff[4] = (Word16)((s2 << exp2)>>16 );
pexp_coeff[4] = 7 - exp2 ;
if ((mode == MR475) ||(mode == MR795) ) { /* Compute scalar product <xn2[],y2[]> */
for (i = 0; i < L_SUBFR; i+=4 )
{
s3 += (pxn2[i]*y2[i] +pxn2[i+1]*y2[i+1] +pxn2[i+2]*y2[i+2]+pxn2[i+3]*y2[i+3])<<1;
}
exp3 = norm_l(s3);
frac = (Word16)((s3<<exp3)>>16);
exp3 = 6 - exp3;
if ( frac <= 0) { *pcod_gain_frac = 0;
*pcod_gain_exp = 0;
} else { *pcod_gain_frac = div_s ((frac>>1), pfrac_coeff[2]);
*pcod_gain_exp = exp3 - pexp_coeff[2] - 14;
} }
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -