📄 gc_pred.cpp
字号:
* ~~~~~~~~~~~~~~~~~ * * ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant * * = MEAN_ENER + sum(pred[i]*past_qua_en[i]) * * constant = 20*Log10(2) * *-------------------------------------------------------------------* ener = MEAN_ENER_MR122; // Q24 (Q17) for (i = 0; i < NPRED; i++) { ener = L_mac (ener, st->past_qua_en_MR122[i], pred_MR122[i]); // Q10 * Q13 -> Q24 // Q10 * Q6 -> Q17 } *-------------------------------------------------------------------* * predicted codebook gain * * ~~~~~~~~~~~~~~~~~~~~~~~ * * gc0 = Pow10( (ener*constant - ener_code*constant) / 20 ) * * = Pow2(ener-ener_code) * * = Pow2(int(d)+frac(d)) * * * * (store exp and frac for pow2()) * *-------------------------------------------------------------------* ener = L_shr (L_sub (ener, ener_code), 1); // Q16 L_Extract(ener, exp_gcode0, frac_gcode0); } else // all modes except 12.2 { Word32 L_tmp; Word16 exp_code, gcode0; *-----------------------------------------------------------------* * Compute: means_ener - 10log10(ener_code/ L_sufr) * *-----------------------------------------------------------------* exp_code = norm_l (ener_code); ener_code = L_shl (ener_code, exp_code); // Log2 = log2 + 27 Log2_norm (ener_code, exp_code, &exp, &frac); // fact = 10/log2(10) = 3.01 = 24660 Q13 L_tmp = Mpy_32_16(exp, frac, -24660); // Q0.Q15 * Q13 -> Q14 * L_tmp = means_ener - 10log10(ener_code/L_SUBFR) * = means_ener - 10log10(ener_code) + 10log10(L_SUBFR) * = K - fact * Log2(ener_code) * = K - fact * log2(ener_code) - fact*27 * * ==> K = means_ener + fact*27 + 10log10(L_SUBFR) * * means_ener = 33 = 540672 Q14 (MR475, MR515, MR59) * means_ener = 28.75 = 471040 Q14 (MR67) * means_ener = 30 = 491520 Q14 (MR74) * means_ener = 36 = 589824 Q14 (MR795) * means_ener = 33 = 540672 Q14 (MR102) * 10log10(L_SUBFR) = 16.02 = 262481.51 Q14 * fact * 27 = 1331640 Q14 * ----------------------------------------- * (MR475, MR515, MR59) K = 2134793.51 Q14 ~= 16678 * 64 * 2 * (MR67) K = 2065161.51 Q14 ~= 32268 * 32 * 2 * (MR74) K = 2085641.51 Q14 ~= 32588 * 32 * 2 * (MR795) K = 2183945.51 Q14 ~= 17062 * 64 * 2 * (MR102) K = 2134793.51 Q14 ~= 16678 * 64 * 2 if (sub (mode, MR102) == 0) { // mean = 33 dB L_tmp = L_mac(L_tmp, 16678, 64); // Q14 } else if (sub (mode, MR795) == 0) { // ener_code = <xn xn> * 2^27*2^exp_code // frac_en = ener_code / 2^16 // = <xn xn> * 2^11*2^exp_code // <xn xn> = <xn xn>*2^11*2^exp * 2^exp_en // := frac_en * 2^exp_en // ==> exp_en = -11-exp_code; *frac_en = extract_h (ener_code); *exp_en = sub (-11, exp_code); // mean = 36 dB L_tmp = L_mac(L_tmp, 17062, 64); // Q14 } else if (sub (mode, MR74) == 0) { // mean = 30 dB L_tmp = L_mac(L_tmp, 32588, 32); // Q14 } else if (sub (mode, MR67) == 0) { // mean = 28.75 dB L_tmp = L_mac(L_tmp, 32268, 32); // Q14 } else // MR59, MR515, MR475 { // mean = 33 dB L_tmp = L_mac(L_tmp, 16678, 64); // Q14 } *-----------------------------------------------------------------* * Compute gcode0. * * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener * *-----------------------------------------------------------------* L_tmp = L_shl(L_tmp, 10); // Q24 for (i = 0; i < 4; i++) L_tmp = L_mac(L_tmp, pred[i], st->past_qua_en[i]); // Q13 * Q10 -> Q24 gcode0 = extract_h(L_tmp); // Q8 *-----------------------------------------------------------------* * gcode0 = pow(10.0, gcode0/20) * * = pow(2, 3.3219*gcode0/20) * * = pow(2, 0.166*gcode0) * *-----------------------------------------------------------------* // 5439 Q15 = 0.165985 // (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15) if (sub (mode, MR74) == 0) // For IS641 bitexactness L_tmp = L_mult(gcode0, 5439); // Q8 * Q15 -> Q24 else L_tmp = L_mult(gcode0, 5443); // Q8 * Q15 -> Q24 L_tmp = L_shr(L_tmp, 8); // -> Q16 L_Extract(L_tmp, exp_gcode0, frac_gcode0); // -> Q0.Q15 }}------------------------------------------------------------------------------ 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 gc_pred( gc_predState *st, /* i/o: State struct */ enum Mode mode, /* i : AMR mode */ Word16 *code, /* i : innovative codebook vector (L_SUBFR) */ /* MR122: Q12, other modes: Q13 */ Word16 *exp_gcode0, /* o : exponent of predicted gain factor, Q0 */ Word16 *frac_gcode0,/* o : fraction of predicted gain factor Q15 */ Word16 *exp_en, /* o : exponent of innovation energy, Q0 */ /* (only calculated for MR795) */ Word16 *frac_en, /* o : fraction of innovation energy, Q15 */ /* (only calculated for MR795) */ Flag *pOverflow){ register Word16 i; register Word32 L_temp1, L_temp2; register Word32 L_tmp; Word32 ener_code; Word32 ener; Word16 exp, frac; Word16 exp_code, gcode0; Word16 tmp; Word16 *p_code = &code[0]; /*-------------------------------------------------------------------* * energy of code: * * ~~~~~~~~~~~~~~~ * * ener_code = sum(code[i]^2) * *-------------------------------------------------------------------*/ ener_code = 0; /* MR122: Q12*Q12 -> Q25 */ /* others: Q13*Q13 -> Q27 */ for (i = L_SUBFR >> 2; i != 0; i--) { tmp = *(p_code++); ener_code += ((Word32) tmp * tmp) >> 3; tmp = *(p_code++); ener_code += ((Word32) tmp * tmp) >> 3; tmp = *(p_code++); ener_code += ((Word32) tmp * tmp) >> 3; tmp = *(p_code++); ener_code += ((Word32) tmp * tmp) >> 3; } ener_code <<= 4; if (ener_code < 0) /* Check for saturation */ { ener_code = MAX_32; } if (mode == MR122) { /* ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20 */ /* Q9 * Q20 -> Q30 */ ener_code = ((Word32)(pv_round(ener_code, pOverflow) * 26214)) << 1; /*-------------------------------------------------------------* * energy of code: * * ~~~~~~~~~~~~~~~ * * ener_code(Q17) = 10 * Log10(energy) / constant * * = 1/2 * Log2(energy) * * constant = 20*Log10(2) * *-------------------------------------------------------------*/ /* ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30 */ Log2(ener_code, &exp, &frac, pOverflow); /* Q16 for log() */ /* ->Q17 for 1/2 log()*/ L_temp1 = (Word32)(exp - 30) << 16; ener_code = L_temp1 + ((Word32)frac << 1); /*-------------------------------------------------------------* * predicted energy: * * ~~~~~~~~~~~~~~~~~ * * ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant * * = MEAN_ENER + sum(pred[i]*past_qua_en[i]) * * constant = 20*Log10(2) * *-------------------------------------------------------------*/ ener = MEAN_ENER_MR122; /* Q24 (Q17) */ for (i = 0; i < NPRED; i++) { L_temp1 = (((Word32) st->past_qua_en_MR122[i]) * pred_MR122[i]) << 1; ener = L_add(ener, L_temp1, pOverflow); /* Q10 * Q13 -> Q24 */ /* Q10 * Q6 -> Q17 */ } /*---------------------------------------------------------------* * predicted codebook gain * * ~~~~~~~~~~~~~~~~~~~~~~~ * * gc0 = Pow10( (ener*constant - ener_code*constant) / 20 ) * * = Pow2(ener-ener_code) * * = Pow2(int(d)+frac(d)) * * * * (store exp and frac for pow2()) * *---------------------------------------------------------------*/ /* Q16 */ L_temp1 = L_sub(ener, ener_code, pOverflow); *exp_gcode0 = (Word16)(L_temp1 >> 17); L_temp2 = (Word32) * exp_gcode0 << 15; L_temp1 >>= 2; *frac_gcode0 = (Word16)(L_temp1 - L_temp2); } else /* all modes except 12.2 */ { /*-----------------------------------------------------------------* * Compute: means_ener - 10log10(ener_code/ L_sufr) * *-----------------------------------------------------------------*/ exp_code = norm_l(ener_code); ener_code = L_shl(ener_code, exp_code, pOverflow); /* Log2 = log2 + 27 */ Log2_norm(ener_code, exp_code, &exp, &frac); /* fact = 10/log2(10) = 3.01 = 24660 Q13 */ /* Q0.Q15 * Q13 -> Q14 */ L_temp2 = (((Word32) exp) * -24660) << 1; L_tmp = (((Word32) frac) * -24660) >> 15; /* Sign-extend resulting product */ if (L_tmp & (Word32) 0x00010000L) { L_tmp = L_tmp | (Word32) 0xffff0000L; } L_tmp = L_tmp << 1; L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* L_tmp = means_ener - 10log10(ener_code/L_SUBFR) * = means_ener - 10log10(ener_code) + 10log10(L_SUBFR) * = K - fact * Log2(ener_code) * = K - fact * log2(ener_code) - fact*27 * * ==> K = means_ener + fact*27 + 10log10(L_SUBFR) * * means_ener = 33 = 540672 Q14 (MR475, MR515, MR59) * means_ener = 28.75 = 471040 Q14 (MR67) * means_ener = 30 = 491520 Q14 (MR74) * means_ener = 36 = 589824 Q14 (MR795) * means_ener = 33 = 540672 Q14 (MR102) * 10log10(L_SUBFR) = 16.02 = 262481.51 Q14 * fact * 27 = 1331640 Q14 * ----------------------------------------- * (MR475, MR515, MR59) K = 2134793.51 Q14 ~= 16678 * 64 * 2 * (MR67) K = 2065161.51 Q14 ~= 32268 * 32 * 2 * (MR74) K = 2085641.51 Q14 ~= 32588 * 32 * 2 * (MR795) K = 2183945.51 Q14 ~= 17062 * 64 * 2 * (MR102) K = 2134793.51 Q14 ~= 16678 * 64 * 2 */ if (mode == MR102) { /* mean = 33 dB */ L_temp2 = (Word32) 16678 << 7; L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ } else if (mode == MR795) { /* ener_code = <xn xn> * 2^27*2^exp_code frac_en = ener_code / 2^16 = <xn xn> * 2^11*2^exp_code <xn xn> = <xn xn>*2^11*2^exp * 2^exp_en : = frac_en * 2^exp_en ==> exp_en = -11-exp_code; */ *frac_en = (Word16)(ener_code >> 16); *exp_en = sub(-11, exp_code, pOverflow); /* mean = 36 dB */ L_temp2 = (Word32) 17062 << 7; L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ } else if (mode == MR74) { /* mean = 30 dB */ L_temp2 = (Word32) 32588 << 6; L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ } else if (mode == MR67) { /* mean = 28.75 dB */ L_temp2 = (Word32) 32268 << 6; L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ } else /* MR59, MR515, MR475 */ { /* mean = 33 dB */ L_temp2 = (Word32) 16678 << 7; L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ } /*-------------------------------------------------------------* * Compute gcode0. * * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener * *--------------------------------------------------------------*/ /* Q24 */ if (L_tmp > (Word32) 0X001fffffL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -