📄 calc_en.cpp
字号:
/*------------------------------------------------------------------------------ FUNCTION NAME: calc_filt_energies------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: mode = coder mode, type Mode xn = LTP target vector, buffer type Word16 xn2 = CB target vector, buffer type Word16 y1 = Adaptive codebook, buffer type Word16 Y2 = Filtered innovative vector, buffer type Word16 g_coeff = Correlations <xn y1> <y1 y1> computed in G_pitch() buffer type Word16 frac_coeff = energy coefficients (5), fraction part, buffer type Word16 exp_coeff = energy coefficients (5), exponent part, buffer type Word16 cod_gain_frac = optimum codebook gain (fraction part), pointer type Word16 cod_gain_exp = optimum codebook gain (exponent part), pointer type Word16 pOverflow = pointer to overflow indicator (Flag) Outputs: frac_coeff contains new fraction part energy coefficients exp_coeff contains new exponent part energy coefficients cod_gain_frac points to the new optimum codebook gain (fraction part) cod_gain_exp points to the new optimum codebook gain (exponent part) pOverflow = 1 if there is an overflow else it is zero. Returns: None. Global Variables Used: None Local Variables Needed: None------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function calculates several energy coefficients for filtered excitation 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[].------------------------------------------------------------------------------ REQUIREMENTS None.------------------------------------------------------------------------------ REFERENCES calc_en.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001------------------------------------------------------------------------------ PSEUDO-CODEvoidcalc_filt_energies( enum Mode mode, // i : coder mode Word16 xn[], // i : LTP target vector, Q0 Word16 xn2[], // i : CB target vector, Q0 Word16 y1[], // i : Adaptive codebook, Q0 Word16 Y2[], // i : Filtered innovative vector, Q12 Word16 g_coeff[], // i : Correlations <xn y1> <y1 y1> // computed in G_pitch() Word16 frac_coeff[],// o : energy coefficients (5), fraction part, Q15 Word16 exp_coeff[], // o : energy coefficients (5), exponent part, Q0 Word16 *cod_gain_frac,// o: optimum codebook gain (fraction part), Q15 Word16 *cod_gain_exp // o: optimum codebook gain (exponent part), Q0){ Word32 s, ener_init; Word16 i, exp, frac; Word16 y2[L_SUBFR]; if (sub(mode, MR795) == 0 || sub(mode, MR475) == 0) { ener_init = 0L; } else { ener_init = 1L; } for (i = 0; i < L_SUBFR; i++) { y2[i] = shr(Y2[i], 3); } frac_coeff[0] = g_coeff[0]; exp_coeff[0] = g_coeff[1]; frac_coeff[1] = negate(g_coeff[2]); // coeff[1] = -2 xn y1 exp_coeff[1] = add(g_coeff[3], 1); // Compute scalar product <y2[],y2[]> s = L_mac(ener_init, y2[0], y2[0]); for (i = 1; i < L_SUBFR; i++) s = L_mac(s, y2[i], y2[i]); exp = norm_l(s); frac_coeff[2] = extract_h(L_shl(s, exp)); exp_coeff[2] = sub(15 - 18, exp); // Compute scalar product -2*<xn[],y2[]> s = L_mac(ener_init, xn[0], y2[0]); for (i = 1; i < L_SUBFR; i++) s = L_mac(s, xn[i], y2[i]); exp = norm_l(s); frac_coeff[3] = negate(extract_h(L_shl(s, exp))); exp_coeff[3] = sub(15 - 9 + 1, exp); // Compute scalar product 2*<y1[],y2[]> s = L_mac(ener_init, y1[0], y2[0]); for (i = 1; i < L_SUBFR; i++) s = L_mac(s, y1[i], y2[i]); exp = norm_l(s); frac_coeff[4] = extract_h(L_shl(s, exp)); exp_coeff[4] = sub(15 - 9 + 1, exp); if (sub(mode, MR475) == 0 || sub(mode, MR795) == 0) { // Compute scalar product <xn2[],y2[]> s = L_mac(ener_init, xn2[0], y2[0]); for (i = 1; i < L_SUBFR; i++) s = L_mac(s, xn2[i], y2[i]); exp = norm_l(s); frac = extract_h(L_shl(s, exp)); exp = sub(15 - 9, exp); if (frac <= 0) { *cod_gain_frac = 0; *cod_gain_exp = 0; } else { // gcu = <xn2, y2> / c[2] = (frac>>1)/frac[2] * 2^(exp+1-exp[2]) = div_s(frac>>1, frac[2])*2^-15 * 2^(exp+1-exp[2]) = div_s * 2^(exp-exp[2]-14) *cod_gain_frac = div_s (shr (frac,1), frac_coeff[2]); *cod_gain_exp = sub (sub (exp, exp_coeff[2]), 14); } }}------------------------------------------------------------------------------ RESOURCES USED [optional] When the code is written for a specific target processor the the resources used should be documented below. HEAP MEMORY USED: x bytes STACK MEMORY USED: x bytes CLOCK CYCLES: (cycle count equation for this function) + (variable used to represent cycle count for each subroutine called) where: (cycle count variable) = cycle count for [subroutine name]------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function]------------------------------------------------------------------------------*/void calc_filt_energies( enum Mode mode, /* i : coder mode */ Word16 xn[], /* i : LTP target vector, Q0 */ Word16 xn2[], /* i : CB target vector, Q0 */ Word16 y1[], /* i : Adaptive codebook, Q0 */ Word16 Y2[], /* i : Filtered innovative vector, Q12 */ Word16 g_coeff[], /* i : Correlations <xn y1> <y1 y1> */ /* computed in G_pitch() */ Word16 frac_coeff[], /* o : energy coefficients (5), fraction part, Q15 */ Word16 exp_coeff[], /* o : energy coefficients (5), exponent part, Q0 */ Word16 *cod_gain_frac, /* o : optimum codebook gain (fraction part),Q15 */ Word16 *cod_gain_exp, /* o : optimum codebook gain (exponent part), Q0 */ Flag *pOverflow){ Word32 s1; /* Intermediate energy accumulator */ Word32 s2; /* Intermediate energy accumulator */ Word32 s3; /* Intermediate energy accumulator */ Word16 i; /* index used in all loops */ Word16 exp; /* number of '0's or '1's before MSB != 0 */ Word16 frac; /* fractional part */ Word16 tmp; /* temporal storage */ Word16 scaled_y2[L_SUBFR]; frac_coeff[0] = g_coeff[0]; exp_coeff[0] = g_coeff[1]; frac_coeff[1] = negate(g_coeff[2]); /* coeff[1] = -2 xn y1 */ exp_coeff[1] = add(g_coeff[3], 1, pOverflow); if ((mode == MR795) || (mode == MR475)) { s1 = 0L; s2 = 0L; s3 = 0L; } else { s1 = 1L; s2 = 1L; s3 = 1L; } for (i = 0; i < L_SUBFR; i++) { /* avoid multiple accesses to memory */ tmp = (Y2[i] >> 3); scaled_y2[i] = tmp; /* Compute scalar product <scaled_y2[],scaled_y2[]> */ s1 = L_mac(s1, tmp, tmp, pOverflow); /* Compute scalar product -2*<xn[],scaled_y2[]> */ s2 = L_mac(s2, xn[i], tmp, pOverflow); /* Compute scalar product 2*<y1[],scaled_y2[]> */ s3 = L_mac(s3, y1[i], tmp, pOverflow); } exp = norm_l(s1); frac_coeff[2] = (Word16)(L_shl(s1, exp, pOverflow) >> 16); exp_coeff[2] = (-3 - exp); exp = norm_l(s2); frac_coeff[3] = negate((Word16)(L_shl(s2, exp, pOverflow) >> 16)); exp_coeff[3] = (7 - exp); exp = norm_l(s3); frac_coeff[4] = (Word16)(L_shl(s3, exp, pOverflow) >> 16); exp_coeff[4] = sub(7, exp, pOverflow); if ((mode == MR795) || (mode == MR475)) { /* Compute scalar product <xn2[],scaled_y2[]> */ s1 = 0L; for (i = 0; i < L_SUBFR; i++) { s1 = amrnb_fxp_mac_16_by_16bb((Word32) xn2[i], (Word32)scaled_y2[i], s1); } s1 = s1 << 1; exp = norm_l(s1); frac = (Word16)(L_shl(s1, exp, pOverflow) >> 16); exp = (6 - exp); if (frac <= 0) { *cod_gain_frac = 0; *cod_gain_exp = 0; } else { /* gcu = <xn2, scaled_y2> / c[2] = (frac>>1)/frac[2] * 2^(exp+1-exp[2]) = div_s(frac>>1, frac[2])*2^-15 * 2^(exp+1-exp[2]) = div_s * 2^(exp-exp[2]-14) */ *cod_gain_frac = div_s(shr(frac, 1, pOverflow), frac_coeff[2]); *cod_gain_exp = ((exp - exp_coeff[2]) - 14); } } return;}/****************************************************************************//*------------------------------------------------------------------------------ FUNCTION NAME: calc_target_energy------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: xn = LTP target vector, buffer to type Word16 Q0 en_exp = optimum codebook gain (exponent part) pointer to type Word16 en_frac = optimum codebook gain (fraction part) pointer to type Word16 pOverflow = pointer to overflow indicator (Flag) Outputs: en_exp points to new optimum codebook gain (exponent part) en_frac points to new optimum codebook gain (fraction part) pOverflow = 1 if there is an overflow else it is zero. Returns: None. Global Variables Used: None Local Variables Needed: None------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function calculates the target energy using the formula, en = <xn, xn>------------------------------------------------------------------------------ REQUIREMENTS None.------------------------------------------------------------------------------ REFERENCES calc_en.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001------------------------------------------------------------------------------ PSEUDO-CODEvoidcalc_target_energy( Word16 xn[], // i: LTP target vector, Q0 Word16 *en_exp, // o: optimum codebook gain (exponent part), Q0 Word16 *en_frac // o: optimum codebook gain (fraction part), Q15){ Word32 s; Word16 i, exp; // Compute scalar product <xn[], xn[]> s = L_mac(0L, xn[0], xn[0]); for (i = 1; i < L_SUBFR; i++) s = L_mac(s, xn[i], xn[i]); // s = SUM 2*xn(i) * xn(i) = <xn xn> * 2 exp = norm_l(s); *en_frac = extract_h(L_shl(s, exp)); *en_exp = sub(16, exp);}------------------------------------------------------------------------------ RESOURCES USED [optional] When the code is written for a specific target processor the the resources used should be documented below. HEAP MEMORY USED: x bytes STACK MEMORY USED: x bytes CLOCK CYCLES: (cycle count equation for this function) + (variable used to represent cycle count for each subroutine called) where: (cycle count variable) = cycle count for [subroutine name]------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function]------------------------------------------------------------------------------*/void calc_target_energy( Word16 xn[], /* i: LTP target vector, Q0 */ Word16 *en_exp, /* o: optimum codebook gain (exponent part), Q0 */ Word16 *en_frac, /* o: optimum codebook gain (fraction part), Q15 */ Flag *pOverflow){ Word32 s; /* Intermediate energy accumulator */ Word16 i; /* index used in all loops */ Word16 exp; /* Compute scalar product <xn[], xn[]> */ s = 0; for (i = 0; i < L_SUBFR; i++) { s = amrnb_fxp_mac_16_by_16bb((Word32) xn[i], (Word32) xn[i], s); } if (s < 0) { *pOverflow = 1; s = MAX_32; } /* s = SUM 2*xn(i) * xn(i) = <xn xn> * 2 */ exp = norm_l(s); *en_frac = (Word16)(L_shl(s, exp, pOverflow) >> 16); *en_exp = (16 - exp); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -