FreeCalypso > hg > gsm-codec-lib
diff libtwamr/dec_gain.c @ 356:5ccfe176bae1
libtwamr: integrate dec_gain.c
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 05 May 2024 22:24:42 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/dec_gain.c Sun May 05 22:24:42 2024 +0000 @@ -0,0 +1,156 @@ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 +* R99 Version 3.3.0 +* REL-4 Version 4.1.0 +* +******************************************************************************** +* +* File : dec_gain.c +* Purpose : Decode the pitch and codebook gains +* +******************************************************************************** +*/ + +/* +******************************************************************************** +* MODULE INCLUDE FILE AND VERSION ID +******************************************************************************** +*/ +#include "namespace.h" +#include "dec_gain.h" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include <stddef.h> +#include "tw_amr.h" +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" +#include "no_count.h" +#include "cnst.h" +#include "pow2.h" +#include "log2.h" +#include "gc_pred.h" +#include "qua_gain_tab.h" + +/* +******************************************************************************** +* PUBLIC PROGRAM CODE +******************************************************************************** +*/ + +/************************************************************************* + * + * FUNCTION: Dec_gain() + * + * PURPOSE: Decode the pitch and codebook gains + * + ************************************************************************/ +void Dec_gain( + gc_predState *pred_state, /* i/o: MA predictor state */ + enum Mode mode, /* i : AMR mode */ + Word16 index, /* i : index of quantization. */ + Word16 code[], /* i : Innovative vector. */ + Word16 evenSubfr, /* i : Flag for even subframes */ + Word16 * gain_pit, /* o : Pitch gain. */ + Word16 * gain_cod /* o : Code gain. */ +) +{ + const Word16 *p; + Word16 frac, gcode0, exp, qua_ener, qua_ener_MR122; + Word16 g_code; + Word32 L_tmp; + + /* Read the quantized gains (table depends on mode) */ + index = shl (index, 2); + + test(); test(); test(); + if ( sub (mode, MR102) == 0 + || sub (mode, MR74) == 0 + || sub (mode, MR67) == 0) + { + p = &table_gain_highrates[index]; move16 (); + + *gain_pit = *p++; move16 (); + g_code = *p++; move16 (); + qua_ener_MR122 = *p++; move16 (); + qua_ener = *p; move16 (); + } + else + { + test(); + if (sub (mode, MR475) == 0) + { + index = add (index, shl(sub(1, evenSubfr), 1)); + p = &table_gain_MR475[index]; move16 (); + + *gain_pit = *p++; move16 (); + g_code = *p++; move16 (); + + /*---------------------------------------------------------* + * calculate predictor update values (not stored in 4.75 * + * quantizer table to save space): * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * * + * qua_ener = log2(g) * + * qua_ener_MR122 = 20*log10(g) * + *---------------------------------------------------------*/ + + /* Log2(x Q12) = log2(x) + 12 */ + Log2 (L_deposit_l (g_code), &exp, &frac); + exp = sub(exp, 12); + + qua_ener_MR122 = add (shr_r (frac, 5), shl (exp, 10)); + + /* 24660 Q12 ~= 6.0206 = 20*log10(2) */ + L_tmp = Mpy_32_16(exp, frac, 24660); + qua_ener = round (L_shl (L_tmp, 13)); /* Q12 * Q0 = Q13 -> Q10 */ + } + else + { + p = &table_gain_lowrates[index]; move16 (); + + *gain_pit = *p++; move16 (); + g_code = *p++; move16 (); + qua_ener_MR122 = *p++; move16 (); + qua_ener = *p; move16 (); + } + } + + /*-------------------------------------------------------------------* + * predict codebook gain * + * ~~~~~~~~~~~~~~~~~~~~~ * + * gc0 = Pow2(int(d)+frac(d)) * + * = 2^exp + 2^frac * + * * + * gcode0 (Q14) = 2^14*2^frac = gc0 * 2^(14-exp) * + *-------------------------------------------------------------------*/ + + gc_pred(pred_state, mode, code, &exp, &frac, NULL, NULL); + + gcode0 = extract_l(Pow2(14, frac)); + + /*------------------------------------------------------------------* + * read quantized gains, update table of past quantized energies * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * st->past_qua_en(Q10) = 20 * Log10(g_fac) / constant * + * = Log2(g_fac) * + * = qua_ener * + * constant = 20*Log10(2) * + *------------------------------------------------------------------*/ + + L_tmp = L_mult(g_code, gcode0); + L_tmp = L_shr(L_tmp, sub(10, exp)); + *gain_cod = extract_h(L_tmp); + + /* update table of past quantized energies */ + + gc_pred_update(pred_state, qua_ener_MR122, qua_ener); + + return; +}