123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- /*
- ********************************************************************************
- *
- * 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 : qua_gain.c
- * Purpose : Quantization of pitch and codebook gains.
- *
- ********************************************************************************
- */
- /*
- ********************************************************************************
- * MODULE INCLUDE FILE AND VERSION ID
- ********************************************************************************
- */
- #include "qua_gain.h"
- const char qua_gain_id[] = "@(#)$Id $" qua_gain_h;
- /*
- ********************************************************************************
- * INCLUDE FILES
- ********************************************************************************
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include "typedef.h"
- #include "basic_op.h"
- #include "oper_32b.h"
- #include "mode.h"
- #include "count.h"
- #include "cnst.h"
- #include "pow2.h"
- #include "gc_pred.h"
- /*
- ********************************************************************************
- * LOCAL VARIABLES AND TABLES
- ********************************************************************************
- */
- #include "qua_gain.tab"
- /*
- ********************************************************************************
- * PUBLIC PROGRAM CODE
- ********************************************************************************
- */
- /*************************************************************************
- *
- * FUNCTION: Qua_gain()
- *
- * PURPOSE: Quantization of pitch and codebook gains.
- * (using predicted codebook gain)
- *
- *************************************************************************/
- Word16
- Qua_gain( /* o : index of quantization. */
- 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 frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */
- Word16 exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */
- /* (frac_coeff and exp_coeff computed in */
- /* calc_filt_energies()) */
- Word16 gp_limit, /* i : pitch gain limit */
- Word16 *gain_pit, /* o : Pitch gain, Q14 */
- Word16 *gain_cod, /* o : Code 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, j, index = 0;
- Word16 gcode0, e_max, exp_code;
- Word16 g_pitch, g2_pitch, g_code, g2_code, g_pit_cod;
- Word16 coeff[5], coeff_lo[5];
- Word16 exp_max[5];
- Word32 L_tmp, dist_min;
- const Word16 *table_gain;
- Word16 table_len;
-
- test(); test(); test();
- if ( sub_ex (mode, MR102) == 0 || sub_ex (mode, MR74) == 0 || sub_ex (mode, MR67) == 0)
- {
- table_len = VQ_SIZE_HIGHRATES; move16 ();
- table_gain = table_gain_highrates; move16 ();
- }
- else
- {
- table_len = VQ_SIZE_LOWRATES; move16 ();
- table_gain = table_gain_lowrates; move16 ();
- }
-
- /*-------------------------------------------------------------------*
- * predicted codebook gain *
- * ~~~~~~~~~~~~~~~~~~~~~~~ *
- * gc0 = 2^exp_gcode0 + 2^frac_gcode0 *
- * *
- * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) *
- *-------------------------------------------------------------------*/
- gcode0 = extract_l_ex(Pow2(14, frac_gcode0));
- /*-------------------------------------------------------------------*
- * Scaling considerations: *
- * ~~~~~~~~~~~~~~~~~~~~~~~ *
- *-------------------------------------------------------------------*/
- /*
- * The error energy (sum) to be minimized consists of five terms, t[0..4].
- *
- * t[0] = gp^2 * <y1 y1>
- * t[1] = -2*gp * <xn y1>
- * t[2] = gc^2 * <y2 y2>
- * t[3] = -2*gc * <xn y2>
- * t[4] = 2*gp*gc * <y1 y2>
- *
- */
- /* determine the scaling exponent for g_code: ec = ec0 - 11 */
- exp_code = sub_ex(exp_gcode0, 11);
- /* calculate exp_max[i] = s[i]-1 */
- exp_max[0] = sub_ex(exp_coeff[0], 13); move16 ();
- exp_max[1] = sub_ex(exp_coeff[1], 14); move16 ();
- exp_max[2] = add_ex(exp_coeff[2], add_ex(15, shl_ex(exp_code, 1))); move16 ();
- exp_max[3] = add_ex(exp_coeff[3], exp_code); move16 ();
- exp_max[4] = add_ex(exp_coeff[4], add_ex(1, exp_code)); move16 ();
- /*-------------------------------------------------------------------*
- * Find maximum exponent: *
- * ~~~~~~~~~~~~~~~~~~~~~~ *
- * *
- * For the sum operation, all terms must have the same scaling; *
- * that scaling should be low enough to prevent overflow. There- *
- * fore, the maximum scale is determined and all coefficients are *
- * re-scaled: *
- * *
- * e_max = max(exp_max[i]) + 1; *
- * e = exp_max[i]-e_max; e <= 0! *
- * c[i] = c[i]*2^e *
- *-------------------------------------------------------------------*/
- e_max = exp_max[0]; move16 ();
- for (i = 1; i < 5; i++)
- {
- move16(); test();
- if (sub_ex(exp_max[i], e_max) > 0)
- {
- e_max = exp_max[i]; move16 ();
- }
- }
- e_max = add_ex(e_max, 1); /* To avoid overflow */
- for (i = 0; i < 5; i++) {
- j = sub_ex(e_max, exp_max[i]);
- L_tmp = L_deposit_h_ex(frac_coeff[i]);
- L_tmp = L_shr_ex(L_tmp, j);
- L_Extract(L_tmp, &coeff[i], &coeff_lo[i]);
- }
- /*-------------------------------------------------------------------*
- * Codebook search: *
- * ~~~~~~~~~~~~~~~~ *
- * *
- * For each pair (g_pitch, g_fac) in the table calculate the *
- * terms t[0..4] and sum them up; the result is the mean squared *
- * error for the quantized gains from the table. The index for the *
- * minimum MSE is stored and finally used to retrieve the quantized *
- * gains *
- *-------------------------------------------------------------------*/
- /* start with "infinite" MSE */
- dist_min = MAX_32; move32();
- p = &table_gain[0]; move16 ();
- for (i = 0; i < table_len; i++)
- {
- g_pitch = *p++; move16 ();
- g_code = *p++; move16 (); /* this is g_fac */
- p++; /* skip log2(g_fac) */
- p++; /* skip 20*log10(g_fac) */
-
- test ();
- if (sub_ex(g_pitch, gp_limit) <= 0)
- {
- g_code = mult_ex(g_code, gcode0);
- g2_pitch = mult_ex(g_pitch, g_pitch);
- g2_code = mult_ex(g_code, g_code);
- g_pit_cod = mult_ex(g_code, g_pitch);
- L_tmp = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch);
- L_tmp = L_add_ex(L_tmp, Mpy_32_16(coeff[1], coeff_lo[1], g_pitch));
- L_tmp = L_add_ex(L_tmp, Mpy_32_16(coeff[2], coeff_lo[2], g2_code));
- L_tmp = L_add_ex(L_tmp, Mpy_32_16(coeff[3], coeff_lo[3], g_code));
- L_tmp = L_add_ex(L_tmp, Mpy_32_16(coeff[4], coeff_lo[4], g_pit_cod));
- /* store table index if MSE for this index is lower
- than the minimum MSE seen so far */
- test ();
- if (L_sub_ex(L_tmp, dist_min) < (Word32) 0)
- {
- dist_min = L_tmp; move32 ();
- index = i; move16 ();
- }
- }
- }
- /*------------------------------------------------------------------*
- * read quantized gains and new values for MA predictor memories *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
- *------------------------------------------------------------------*/
- /* Read the quantized gains */
- p = &table_gain[shl_ex (index, 2)]; move16 ();
- *gain_pit = *p++; move16();
- g_code = *p++; move16();
- *qua_ener_MR122 = *p++; move16();
- *qua_ener = *p; move16();
- /*------------------------------------------------------------------*
- * calculate final fixed codebook gain: *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
- * *
- * gc = gc0 * g *
- *------------------------------------------------------------------*/
- L_tmp = L_mult_ex(g_code, gcode0);
- L_tmp = L_shr_ex(L_tmp, sub_ex(10, exp_gcode0));
- *gain_cod = extract_h_ex(L_tmp);
- return index;
- }
|