FreeCalypso > hg > gsm-codec-lib
diff libtwamr/q_gain_c.c @ 368:3a25bdfad0d8
libtwamr: integrate q_gain_c.c
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 06 May 2024 03:18:47 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/q_gain_c.c Mon May 06 03:18:47 2024 +0000 @@ -0,0 +1,151 @@ +/* +******************************************************************************** +* +* 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 : q_gain_c.c +* Purpose : Scalar quantization of the innovative +* : codebook gain. +* +******************************************************************************** +*/ + +/* +******************************************************************************** +* MODULE INCLUDE FILE AND VERSION ID +******************************************************************************** +*/ +#include "namespace.h" +#include "q_gain_c.h" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "tw_amr.h" +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" +#include "no_count.h" +#include "log2.h" +#include "pow2.h" +#include "gains_tab.h" + +/* +******************************************************************************** +* PUBLIC PROGRAM CODE +******************************************************************************** +*/ + +/*--------------------------------------------------------------------------* + * Function q_gain_code() * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * Scalar quantization of the innovative codebook gain. * + * * + *--------------------------------------------------------------------------*/ +Word16 q_gain_code ( /* o : quantization index, Q0 */ + enum Mode mode, /* i : AMR mode */ + Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ + Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ + Word16 *gain, /* i/o: quantized fixed codebook gain, Q1 */ + Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ + /* (for MR122 MA predictor update) */ + Word16 *qua_ener /* o : quantized energy error, Q10 */ + /* (for other MA predictor update) */ +) +{ + const Word16 *p; + Word16 i, index; + Word16 gcode0, err, err_min; + Word16 g_q0; + + test (); + g_q0 = 0; move16 (); + test (); + if (sub(mode, MR122) == 0) + { + g_q0 = shr (*gain, 1); /* Q1 -> Q0 */ + } + + /*-------------------------------------------------------------------* + * predicted codebook gain * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + * gc0 = Pow2(int(d)+frac(d)) * + * = 2^exp + 2^frac * + * * + *-------------------------------------------------------------------*/ + + gcode0 = extract_l (Pow2 (exp_gcode0, frac_gcode0)); /* predicted gain */ + + test (); + if (sub(mode, MR122) == 0) + { + gcode0 = shl (gcode0, 4); + } + else + { + gcode0 = shl (gcode0, 5); + } + + /*-------------------------------------------------------------------* + * Search for best quantizer * + *-------------------------------------------------------------------*/ + + p = &qua_gain_code[0]; move16 (); + test (); + if (sub(mode, MR122) == 0) + { + err_min = abs_s (sub (g_q0, mult (gcode0, *p++))); + } + else + { + err_min = abs_s (sub (*gain, mult (gcode0, *p++))); + } + p += 2; /* skip quantized energy errors */ + index = 0; move16 (); + + for (i = 1; i < NB_QUA_CODE; i++) + { + test (); + if (sub(mode, MR122) == 0) + { + err = abs_s (sub (g_q0, mult (gcode0, *p++))); + } + else + { + err = abs_s (sub (*gain, mult (gcode0, *p++))); + } + + p += 2; /* skip quantized energy error */ + + test (); + if (sub (err, err_min) < 0) + { + err_min = err; move16 (); + index = i; move16 (); + } + } + + p = &qua_gain_code[add (add (index,index), index)]; move16 (); + test (); + if (sub(mode, MR122) == 0) + { + *gain = shl (mult (gcode0, *p++), 1); + } + else + { + *gain = mult (gcode0, *p++); + } + move16 (); + + /* quantized error energies (for MA predictor update) */ + *qua_ener_MR122 = *p++; move16 (); + *qua_ener = *p; move16 (); + + return index; +}