📄 gc_pred.cpp
字号:
{ *pOverflow = 1; L_tmp = MAX_32; } else if (L_tmp < (Word32) 0xffe00000L) { *pOverflow = 1; L_tmp = MIN_32; } else { L_tmp = L_tmp << 10; } for (i = 0; i < 4; i++) { L_temp2 = ((((Word32) pred[i]) * st->past_qua_en[i]) << 1); L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q13 * Q10 -> Q24 */ } gcode0 = (Word16)(L_tmp >> 16); /* 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 (mode == MR74) /* For IS641 bitexactness */ { L_tmp = (((Word32) gcode0) * 5439) << 1; /* Q8 * Q15 -> Q24 */ } else { L_tmp = (((Word32) gcode0) * 5443) << 1; /* Q8 * Q15 -> Q24 */ } if (L_tmp < 0) { L_tmp = ~((~L_tmp) >> 8); } else { L_tmp = L_tmp >> 8; /* -> Q16 */ } *exp_gcode0 = (Word16)(L_tmp >> 16); if (L_tmp < 0) { L_temp1 = ~((~L_tmp) >> 1); } else { L_temp1 = L_tmp >> 1; } L_temp2 = (Word32) * exp_gcode0 << 15; *frac_gcode0 = (Word16)(L_sub(L_temp1, L_temp2, pOverflow)); /* -> Q0.Q15 */ } return;}/****************************************************************************//*------------------------------------------------------------------------------ FUNCTION NAME: gc_pred_update------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: st = pointer to a structure of type gc_predState qua_ener_MR122 = quantized energy for update (Q10); calculated as (log2(qua_err)) (Word16) qua_ener = quantized energy for update (Q10); calculated as (20*log10(qua_err)) (Word16) Outputs: structure pointed to by st contains the calculated quantized energy for update Returns: None Global Variables Used: None Local Variables Needed: None------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function updates the MA predictor with the last quantized energy.------------------------------------------------------------------------------ REQUIREMENTS None------------------------------------------------------------------------------ REFERENCES gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001------------------------------------------------------------------------------ PSEUDO-CODEvoid gc_pred_update( gc_predState *st, // i/o: State struct Word16 qua_ener_MR122, // i : quantized energy for update, Q10 // (log2(qua_err)) Word16 qua_ener // i : quantized energy for update, Q10 // (20*log10(qua_err))){ Word16 i; for (i = 3; i > 0; i--) { st->past_qua_en[i] = st->past_qua_en[i - 1]; st->past_qua_en_MR122[i] = st->past_qua_en_MR122[i - 1]; } st->past_qua_en_MR122[0] = qua_ener_MR122; // log2 (qua_err), Q10 st->past_qua_en[0] = qua_ener; // 20*log10(qua_err), Q10}------------------------------------------------------------------------------ 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_update( gc_predState *st, /* i/o: State struct */ Word16 qua_ener_MR122, /* i : quantized energy for update, Q10 */ /* (log2(qua_err)) */ Word16 qua_ener /* i : quantized energy for update, Q10 */ /* (20*log10(qua_err)) */){ st->past_qua_en[3] = st->past_qua_en[2]; st->past_qua_en_MR122[3] = st->past_qua_en_MR122[2]; st->past_qua_en[2] = st->past_qua_en[1]; st->past_qua_en_MR122[2] = st->past_qua_en_MR122[1]; st->past_qua_en[1] = st->past_qua_en[0]; st->past_qua_en_MR122[1] = st->past_qua_en_MR122[0]; st->past_qua_en_MR122[0] = qua_ener_MR122; /* log2 (qua_err), Q10 */ st->past_qua_en[0] = qua_ener; /* 20*log10(qua_err), Q10 */ return;}/****************************************************************************//*------------------------------------------------------------------------------ FUNCTION NAME: gc_pred_average_limited------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: st = pointer to a structure of type gc_predState ener_avg_MR122 = pointer to the averaged quantized energy (Q10); calculated as (log2(qua_err)) (Word16) ener_avg = pointer to the averaged quantized energy (Q10); calculated as (20*log10(qua_err)) (Word16) pOverflow = pointer to overflow (Flag) Outputs: store pointed to by ener_avg_MR122 contains the new averaged quantized energy store pointed to by ener_avg contains the new averaged quantized energy pOverflow = 1 if the math functions called by gc_pred_average_limited results in overflow else zero. Returns: None Global Variables Used: None Local Variables Needed: None------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function calculates the average of MA predictor state values (with a lower limit) used in error concealment.------------------------------------------------------------------------------ REQUIREMENTS None------------------------------------------------------------------------------ REFERENCES gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001------------------------------------------------------------------------------ PSEUDO-CODEThe original etsi reference code uses a global flag Overflow. However, in theactual implementation a pointer to a the overflow flag is passed in.void gc_pred_average_limited( gc_predState *st, // i: State struct Word16 *ener_avg_MR122, // o: everaged quantized energy, Q10 // (log2(qua_err)) Word16 *ener_avg // o: averaged quantized energy, Q10 // (20*log10(qua_err))){ Word16 av_pred_en; Word16 i; // do average in MR122 mode (log2() domain) av_pred_en = 0; for (i = 0; i < NPRED; i++) { av_pred_en = add (av_pred_en, st->past_qua_en_MR122[i]); } // av_pred_en = 0.25*av_pred_en av_pred_en = mult (av_pred_en, 8192); // if (av_pred_en < -14/(20Log10(2))) av_pred_en = .. if (sub (av_pred_en, MIN_ENERGY_MR122) < 0) { av_pred_en = MIN_ENERGY_MR122; } *ener_avg_MR122 = av_pred_en; // do average for other modes (20*log10() domain) av_pred_en = 0; for (i = 0; i < NPRED; i++) { av_pred_en = add (av_pred_en, st->past_qua_en[i]); } // av_pred_en = 0.25*av_pred_en av_pred_en = mult (av_pred_en, 8192); // if (av_pred_en < -14) av_pred_en = .. if (sub (av_pred_en, MIN_ENERGY) < 0) { av_pred_en = MIN_ENERGY; } *ener_avg = av_pred_en;}------------------------------------------------------------------------------ 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_average_limited( gc_predState *st, /* i: State struct */ Word16 *ener_avg_MR122, /* o: everaged quantized energy, Q10 */ /* (log2(qua_err)) */ Word16 *ener_avg, /* o: averaged quantized energy, Q10 */ /* (20*log10(qua_err)) */ Flag *pOverflow){ Word16 av_pred_en; register Word16 i; /* do average in MR122 mode (log2() domain) */ av_pred_en = 0; for (i = 0; i < NPRED; i++) { av_pred_en = add(av_pred_en, st->past_qua_en_MR122[i], pOverflow); } /* av_pred_en = 0.25*av_pred_en (with sign-extension)*/ if (av_pred_en < 0) { av_pred_en = (av_pred_en >> 2) | 0xc000; } else { av_pred_en >>= 2; } /* if (av_pred_en < -14/(20Log10(2))) av_pred_en = .. */ if (av_pred_en < MIN_ENERGY_MR122) { av_pred_en = MIN_ENERGY_MR122; } *ener_avg_MR122 = av_pred_en; /* do average for other modes (20*log10() domain) */ av_pred_en = 0; for (i = 0; i < NPRED; i++) { av_pred_en = add(av_pred_en, st->past_qua_en[i], pOverflow); } /* av_pred_en = 0.25*av_pred_en (with sign-extension)*/ if (av_pred_en < 0) { av_pred_en = (av_pred_en >> 2) | 0xc000; } else { av_pred_en >>= 2; } /* if (av_pred_en < -14) av_pred_en = .. */ if (av_pred_en < MIN_ENERGY) { av_pred_en = MIN_ENERGY; } *ener_avg = av_pred_en;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -