annotate libtwamr/qgain475.c @ 581:e2d5cad04cbf

libgsmhr1 RxFE: store CN R0+LPC separately from speech In the original GSM 06.06 code the ECU for speech mode is entirely separate from the CN generator, maintaining separate state. (The main intertie between them is the speech vs CN state variable, distinguishing between speech and CN BFIs, in addition to the CN-specific function of distinguishing between initial and update SIDs.) In the present RxFE implementation I initially thought that we could use the same saved_frame buffer for both ECU and CN, overwriting just the first 4 params (R0 and LPC) when a valid SID comes in. However, I now realize it was a bad idea: the original code has a corner case (long sequence of speech-mode BFIs to put the ECU in state 6, then SID and CN-mode BFIs, then a good speech frame) that would be broken by that buffer reuse approach. We could eliminate this corner case by resetting the ECU state when passing through a CN insertion period, but doing so would needlessly increase the behavioral diffs between GSM 06.06 and our version. Solution: use a separate CN-specific buffer for CN R0+LPC parameters, and match the behavior of GSM 06.06 code in this regard.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 13 Feb 2025 10:02:45 +0000
parents 1d2b39027b70
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
375
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 ********************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 * R99 Version 3.3.0
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 * REL-4 Version 4.1.0
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 ********************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 * File : qg475.c
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 * Purpose : Quantization of pitch and codebook gains for MR475.
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 ********************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 /*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 ********************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 * MODULE INCLUDE FILE AND VERSION ID
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 ********************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 #include "namespace.h"
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 #include "qgain475.h"
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 /*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25 ********************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 * INCLUDE FILES
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 ********************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 #include "tw_amr.h"
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 #include "typedef.h"
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 #include "basic_op.h"
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 #include "mac_32.h"
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 #include "no_count.h"
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 #include "cnst.h"
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 #include "pow2.h"
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 #include "log2.h"
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 #include "qua_gain_tab.h"
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 /*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 ********************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 * LOCAL VARIABLES AND TABLES
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 ********************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 /* minimum allowed gain code prediction error: 102.887/4096 = 0.0251189 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 #define MIN_QUA_ENER ( -5443) /* Q10 <-> log2 (0.0251189) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 #define MIN_QUA_ENER_MR122 (-32768) /* Q10 <-> 20*log10(0.0251189) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 /* minimum allowed gain code prediction error: 32000/4096 = 7.8125 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 #define MAX_QUA_ENER ( 3037) /* Q10 <-> log2 (7.8125) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 #define MAX_QUA_ENER_MR122 ( 18284) /* Q10 <-> 20*log10(7.8125) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 /*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 ********************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 * PRIVATE PROGRAM CODE
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 ********************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 static void MR475_quant_store_results(
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 gc_predState *pred_st, /* i/o: gain predictor state struct */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 const Word16 *p, /* i : pointer to selected quantizer table entry */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 Word16 gcode0, /* i : predicted CB gain, Q(14 - exp_gcode0) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 Word16 exp_gcode0, /* i : exponent of predicted CB gain, Q0 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 Word16 *gain_pit, /* o : Pitch gain, Q14 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 Word16 *gain_cod /* o : Code gain, Q1 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 )
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 Word16 g_code, exp, frac, tmp;
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 Word32 L_tmp;
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 Word16 qua_ener_MR122; /* o : quantized energy error, MR122 version Q10 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 Word16 qua_ener; /* o : quantized energy error, Q10 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 /* Read the quantized gains */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 *gain_pit = *p++; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 g_code = *p++; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 /*------------------------------------------------------------------*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 * calculate final fixed codebook gain: *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80 * *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 * gc = gc0 * g *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 *------------------------------------------------------------------*/
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 L_tmp = L_mult(g_code, gcode0);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 L_tmp = L_shr(L_tmp, sub(10, exp_gcode0));
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 *gain_cod = extract_h(L_tmp);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 /*------------------------------------------------------------------*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89 * calculate predictor update values and update gain predictor: *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 * *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 * qua_ener = log2(g) *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 * qua_ener_MR122 = 20*log10(g) *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 *------------------------------------------------------------------*/
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 Log2 (L_deposit_l (g_code), &exp, &frac); /* Log2(x Q12) = log2(x) + 12 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 exp = sub(exp, 12);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 tmp = shr_r (frac, 5);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100 qua_ener_MR122 = add (tmp, shl (exp, 10));
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
102 L_tmp = Mpy_32_16(exp, frac, 24660); /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103 qua_ener = round (L_shl (L_tmp, 13)); /* Q12 * Q0 = Q13 -> Q10 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
105 gc_pred_update(pred_st, qua_ener_MR122, qua_ener);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
106 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
107
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
108 /*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
109 ********************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
110 * PUBLIC PROGRAM CODE
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
111 ********************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
112 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
113
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
114 /*************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
115 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
116 * FUNCTION: MR475_update_unq_pred()
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
117 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
118 * PURPOSE: use optimum codebook gain and update "unquantized"
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
119 * gain predictor with the (bounded) prediction error
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
120 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
121 *************************************************************************/
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
122 void
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
123 MR475_update_unq_pred(
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
124 gc_predState *pred_st, /* i/o: gain predictor state struct */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
125 Word16 exp_gcode0, /* i : predicted CB gain (exponent MSW), Q0 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
126 Word16 frac_gcode0, /* i : predicted CB gain (exponent LSW), Q15 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
127 Word16 cod_gain_exp, /* i : optimum codebook gain (exponent), Q0 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
128 Word16 cod_gain_frac /* i : optimum codebook gain (fraction), Q15 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
129 )
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
130 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
131 Word16 tmp, exp, frac;
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
132 Word16 qua_ener, qua_ener_MR122;
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
133 Word32 L_tmp;
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
134
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
135 /* calculate prediction error factor (given optimum CB gain gcu):
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
136 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
137 * predErrFact = gcu / gcode0
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
138 * (limit to MIN_PRED_ERR_FACT <= predErrFact <= MAX_PRED_ERR_FACT
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
139 * -> limit qua_ener*)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
140 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
141 * calculate prediction error (log):
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
142 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
143 * qua_ener_MR122 = log2(predErrFact)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
144 * qua_ener = 20*log10(predErrFact)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
145 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
146 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
147
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
148 if (test(), cod_gain_frac <= 0)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
149 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
150 /* if gcu <= 0 -> predErrFact = 0 < MIN_PRED_ERR_FACT */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
151 /* -> set qua_ener(_MR122) directly */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
152 qua_ener = MIN_QUA_ENER; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
153 qua_ener_MR122 = MIN_QUA_ENER_MR122; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
154 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
155 else
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
156 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
157 /* convert gcode0 from DPF to standard fraction/exponent format */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
158 /* with normalized frac, i.e. 16384 <= frac <= 32767 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
159 /* Note: exponent correction (exp=exp-14) is done after div_s */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
160 frac_gcode0 = extract_l (Pow2 (14, frac_gcode0));
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
161
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
162 /* make sure cod_gain_frac < frac_gcode0 for div_s */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
163 if (test (), sub(cod_gain_frac, frac_gcode0) >= 0)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
164 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
165 cod_gain_frac = shr (cod_gain_frac, 1);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
166 cod_gain_exp = add (cod_gain_exp, 1);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
167 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
168
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
169 /*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
170 predErrFact
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
171 = gcu / gcode0
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
172 = cod_gain_frac/frac_gcode0 * 2^(cod_gain_exp-(exp_gcode0-14))
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
173 = div_s (c_g_f, frac_gcode0)*2^-15 * 2^(c_g_e-exp_gcode0+14)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
174 = div_s * 2^(cod_gain_exp-exp_gcode0 - 1)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
175 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
176 frac = div_s (cod_gain_frac, frac_gcode0);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
177 tmp = sub (sub (cod_gain_exp, exp_gcode0), 1);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
178
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
179 Log2 (L_deposit_l (frac), &exp, &frac);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
180 exp = add (exp, tmp);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
181
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
182 /* calculate prediction error (log2, Q10) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
183 qua_ener_MR122 = shr_r (frac, 5);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
184 qua_ener_MR122 = add (qua_ener_MR122, shl (exp, 10));
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
185
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
186 if (test (), sub(qua_ener_MR122, MIN_QUA_ENER_MR122) < 0)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
187 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
188 qua_ener = MIN_QUA_ENER; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
189 qua_ener_MR122 = MIN_QUA_ENER_MR122; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
190 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
191 else if (test (), sub(qua_ener_MR122, MAX_QUA_ENER_MR122) > 0)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
192 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
193 qua_ener = MAX_QUA_ENER; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
194 qua_ener_MR122 = MAX_QUA_ENER_MR122; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
195 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
196 else
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
197 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
198 /* calculate prediction error (20*log10, Q10) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
199 L_tmp = Mpy_32_16(exp, frac, 24660);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
200 /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
201 qua_ener = round (L_shl (L_tmp, 13));
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
202 /* Q12 * Q0 = Q13 -> Q26 -> Q10 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
203 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
204 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
205
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
206 /* update MA predictor memory */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
207 gc_pred_update(pred_st, qua_ener_MR122, qua_ener);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
208 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
209
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
210
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
211 /*************************************************************************
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
212 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
213 * FUNCTION: MR475_gain_quant()
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
214 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
215 * PURPOSE: Quantization of pitch and codebook gains for two subframes
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
216 * (using predicted codebook gain)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
217 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
218 *************************************************************************/
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
219 Word16
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
220 MR475_gain_quant( /* o : index of quantization. */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
221 gc_predState *pred_st, /* i/o: gain predictor state struct */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
222
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
223 /* data from subframe 0 (or 2) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
224 Word16 sf0_exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
225 Word16 sf0_frac_gcode0, /* i : predicted CB gain (fraction), Q15 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
226 Word16 sf0_exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
227 Word16 sf0_frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
228 /* (frac_coeff and exp_coeff computed in */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
229 /* calc_filt_energies()) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
230 Word16 sf0_exp_target_en, /* i : exponent of target energy, Q0 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
231 Word16 sf0_frac_target_en, /* i : fraction of target energy, Q15 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
232
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
233 /* data from subframe 1 (or 3) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
234 Word16 sf1_code_nosharp[], /* i : innovative codebook vector (L_SUBFR) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
235 /* (whithout pitch sharpening) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
236 Word16 sf1_exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
237 Word16 sf1_frac_gcode0, /* i : predicted CB gain (fraction), Q15 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
238 Word16 sf1_exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
239 Word16 sf1_frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
240 /* (frac_coeff and exp_coeff computed in */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
241 /* calc_filt_energies()) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
242 Word16 sf1_exp_target_en, /* i : exponent of target energy, Q0 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
243 Word16 sf1_frac_target_en, /* i : fraction of target energy, Q15 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
244
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
245 Word16 gp_limit, /* i : pitch gain limit */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
246
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
247 Word16 *sf0_gain_pit, /* o : Pitch gain, Q14 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
248 Word16 *sf0_gain_cod, /* o : Code gain, Q1 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
249
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
250 Word16 *sf1_gain_pit, /* o : Pitch gain, Q14 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
251 Word16 *sf1_gain_cod /* o : Code gain, Q1 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
252 )
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
253 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
254 const Word16 *p;
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
255 Word16 i, index = 0;
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
256 Word16 tmp;
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
257 Word16 exp;
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
258 Word16 sf0_gcode0, sf1_gcode0;
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
259 Word16 g_pitch, g2_pitch, g_code, g2_code, g_pit_cod;
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
260 Word16 coeff[10], coeff_lo[10], exp_max[10]; /* 0..4: sf0; 5..9: sf1 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
261 Word32 L_tmp, dist_min;
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
262
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
263 /*-------------------------------------------------------------------*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
264 * predicted codebook gain *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
265 * ~~~~~~~~~~~~~~~~~~~~~~~ *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
266 * gc0 = 2^exp_gcode0 + 2^frac_gcode0 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
267 * *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
268 * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
269 *-------------------------------------------------------------------*/
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
270
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
271 sf0_gcode0 = extract_l(Pow2(14, sf0_frac_gcode0));
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
272 sf1_gcode0 = extract_l(Pow2(14, sf1_frac_gcode0));
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
273
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
274 /*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
275 * For each subframe, the error energy (sum) to be minimized consists
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
276 * of five terms, t[0..4].
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
277 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
278 * t[0] = gp^2 * <y1 y1>
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
279 * t[1] = -2*gp * <xn y1>
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
280 * t[2] = gc^2 * <y2 y2>
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
281 * t[3] = -2*gc * <xn y2>
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
282 * t[4] = 2*gp*gc * <y1 y2>
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
283 *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
284 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
285
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
286 /* sf 0 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
287 /* determine the scaling exponent for g_code: ec = ec0 - 11 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
288 exp = sub(sf0_exp_gcode0, 11);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
289
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
290 /* calculate exp_max[i] = s[i]-1 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
291 exp_max[0] = sub(sf0_exp_coeff[0], 13); move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
292 exp_max[1] = sub(sf0_exp_coeff[1], 14); move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
293 exp_max[2] = add(sf0_exp_coeff[2], add(15, shl(exp, 1))); move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
294 exp_max[3] = add(sf0_exp_coeff[3], exp); move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
295 exp_max[4] = add(sf0_exp_coeff[4], add(1, exp)); move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
296
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
297 /* sf 1 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
298 /* determine the scaling exponent for g_code: ec = ec0 - 11 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
299 exp = sub(sf1_exp_gcode0, 11);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
300
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
301 /* calculate exp_max[i] = s[i]-1 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
302 exp_max[5] = sub(sf1_exp_coeff[0], 13); move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
303 exp_max[6] = sub(sf1_exp_coeff[1], 14); move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
304 exp_max[7] = add(sf1_exp_coeff[2], add(15, shl(exp, 1))); move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
305 exp_max[8] = add(sf1_exp_coeff[3], exp); move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
306 exp_max[9] = add(sf1_exp_coeff[4], add(1, exp)); move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
307
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
308 /*-------------------------------------------------------------------*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
309 * Gain search equalisation: *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
310 * ~~~~~~~~~~~~~~~~~~~~~~~~~ *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
311 * The MSE for the two subframes is weighted differently if there *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
312 * is a big difference in the corresponding target energies *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
313 *-------------------------------------------------------------------*/
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
314
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
315 /* make the target energy exponents the same by de-normalizing the
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
316 fraction of the smaller one. This is necessary to be able to compare
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
317 them
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
318 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
319 exp = sf0_exp_target_en - sf1_exp_target_en;
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
320 test ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
321 if (exp > 0)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
322 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
323 sf1_frac_target_en = shr (sf1_frac_target_en, exp);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
324 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
325 else
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
326 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
327 sf0_frac_target_en = shl (sf0_frac_target_en, exp);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
328 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
329
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
330 /* assume no change of exponents */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
331 exp = 0; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
332
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
333 /* test for target energy difference; set exp to +1 or -1 to scale
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
334 * up/down coefficients for sf 1
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
335 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
336 tmp = shr_r (sf1_frac_target_en, 1); /* tmp = ceil(0.5*en(sf1)) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
337 test ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
338 if (sub (tmp, sf0_frac_target_en) > 0) /* tmp > en(sf0)? */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
339 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
340 /*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
341 * target_energy(sf1) > 2*target_energy(sf0)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
342 * -> scale up MSE(sf0) by 2 by adding 1 to exponents 0..4
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
343 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
344 exp = 1; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
345 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
346 else
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
347 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
348 tmp = shr (add (sf0_frac_target_en, 3), 2); /* tmp=ceil(0.25*en(sf0)) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
349 test();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
350 if (sub (tmp, sf1_frac_target_en) > 0) /* tmp > en(sf1)? */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
351 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
352 /*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
353 * target_energy(sf1) < 0.25*target_energy(sf0)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
354 * -> scale down MSE(sf0) by 0.5 by subtracting 1 from
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
355 * coefficients 0..4
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
356 */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
357 exp = -1; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
358 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
359 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
360
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
361 for (i = 0; i < 5; i++)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
362 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
363 exp_max[i] = add (exp_max[i], exp); move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
364 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
365
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
366 /*-------------------------------------------------------------------*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
367 * Find maximum exponent: *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
368 * ~~~~~~~~~~~~~~~~~~~~~~ *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
369 * *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
370 * For the sum operation, all terms must have the same scaling; *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
371 * that scaling should be low enough to prevent overflow. There- *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
372 * fore, the maximum scale is determined and all coefficients are *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
373 * re-scaled: *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
374 * *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
375 * exp = max(exp_max[i]) + 1; *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
376 * e = exp_max[i]-exp; e <= 0! *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
377 * c[i] = c[i]*2^e *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
378 *-------------------------------------------------------------------*/
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
379
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
380 exp = exp_max[0]; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
381 for (i = 1; i < 10; i++)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
382 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
383 move16(); test();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
384 if (sub(exp_max[i], exp) > 0)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
385 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
386 exp = exp_max[i]; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
387 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
388 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
389 exp = add(exp, 1); /* To avoid overflow */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
390
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
391 p = &sf0_frac_coeff[0]; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
392 for (i = 0; i < 5; i++) {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
393 tmp = sub(exp, exp_max[i]);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
394 L_tmp = L_deposit_h(*p++);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
395 L_tmp = L_shr(L_tmp, tmp);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
396 L_Extract(L_tmp, &coeff[i], &coeff_lo[i]);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
397 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
398 p = &sf1_frac_coeff[0]; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
399 for (; i < 10; i++) {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
400 tmp = sub(exp, exp_max[i]);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
401 L_tmp = L_deposit_h(*p++);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
402 L_tmp = L_shr(L_tmp, tmp);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
403 L_Extract(L_tmp, &coeff[i], &coeff_lo[i]);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
404 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
405
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
406 /*-------------------------------------------------------------------*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
407 * Codebook search: *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
408 * ~~~~~~~~~~~~~~~~ *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
409 * *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
410 * For each pair (g_pitch, g_fac) in the table calculate the *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
411 * terms t[0..4] and sum them up; the result is the mean squared *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
412 * error for the quantized gains from the table. The index for the *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
413 * minimum MSE is stored and finally used to retrieve the quantized *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
414 * gains *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
415 *-------------------------------------------------------------------*/
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
416
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
417 /* start with "infinite" MSE */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
418 dist_min = MAX_32; move32();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
419
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
420 p = &table_gain_MR475[0]; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
421
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
422 for (i = 0; i < MR475_VQ_SIZE; i++)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
423 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
424 /* subframe 0 (and 2) calculations */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
425 g_pitch = *p++; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
426 g_code = *p++; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
427
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
428 g_code = mult(g_code, sf0_gcode0);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
429 g2_pitch = mult(g_pitch, g_pitch);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
430 g2_code = mult(g_code, g_code);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
431 g_pit_cod = mult(g_code, g_pitch);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
432
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
433 L_tmp = Mpy_32_16( coeff[0], coeff_lo[0], g2_pitch);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
434 L_tmp = Mac_32_16(L_tmp, coeff[1], coeff_lo[1], g_pitch);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
435 L_tmp = Mac_32_16(L_tmp, coeff[2], coeff_lo[2], g2_code);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
436 L_tmp = Mac_32_16(L_tmp, coeff[3], coeff_lo[3], g_code);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
437 L_tmp = Mac_32_16(L_tmp, coeff[4], coeff_lo[4], g_pit_cod);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
438
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
439 tmp = sub (g_pitch, gp_limit);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
440
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
441 /* subframe 1 (and 3) calculations */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
442 g_pitch = *p++; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
443 g_code = *p++; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
444
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
445 test (); test (); test ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
446 if (tmp <= 0 && sub(g_pitch, gp_limit) <= 0)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
447 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
448 g_code = mult(g_code, sf1_gcode0);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
449 g2_pitch = mult(g_pitch, g_pitch);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
450 g2_code = mult(g_code, g_code);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
451 g_pit_cod = mult(g_code, g_pitch);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
452
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
453 L_tmp = Mac_32_16(L_tmp, coeff[5], coeff_lo[5], g2_pitch);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
454 L_tmp = Mac_32_16(L_tmp, coeff[6], coeff_lo[6], g_pitch);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
455 L_tmp = Mac_32_16(L_tmp, coeff[7], coeff_lo[7], g2_code);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
456 L_tmp = Mac_32_16(L_tmp, coeff[8], coeff_lo[8], g_code);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
457 L_tmp = Mac_32_16(L_tmp, coeff[9], coeff_lo[9], g_pit_cod);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
458
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
459 /* store table index if MSE for this index is lower
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
460 than the minimum MSE seen so far */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
461 test ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
462 if (L_sub(L_tmp, dist_min) < (Word32) 0)
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
463 {
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
464 dist_min = L_tmp; move32 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
465 index = i; move16 ();
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
466 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
467 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
468 }
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
469
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
470 /*------------------------------------------------------------------*
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
471 * read quantized gains and update MA predictor memories *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
472 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
473 *------------------------------------------------------------------*/
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
474
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
475 /* for subframe 0, the pre-calculated gcode0/exp_gcode0 are the same
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
476 as those calculated from the "real" predictor using quantized gains */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
477 tmp = shl(index, 2);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
478 MR475_quant_store_results(pred_st,
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
479 &table_gain_MR475[tmp],
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
480 sf0_gcode0,
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
481 sf0_exp_gcode0,
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
482 sf0_gain_pit,
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
483 sf0_gain_cod);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
484
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
485 /* calculate new predicted gain for subframe 1 (this time using
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
486 the real, quantized gains) */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
487 gc_pred(pred_st, MR475, sf1_code_nosharp,
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
488 &sf1_exp_gcode0, &sf1_frac_gcode0,
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
489 &sf0_exp_gcode0, &sf0_gcode0); /* last two args are dummy */
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
490 sf1_gcode0 = extract_l(Pow2(14, sf1_frac_gcode0));
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
491
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
492 tmp = add (tmp, 2);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
493 MR475_quant_store_results(pred_st,
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
494 &table_gain_MR475[tmp],
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
495 sf1_gcode0,
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
496 sf1_exp_gcode0,
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
497 sf1_gain_pit,
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
498 sf1_gain_cod);
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
499
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
500 return index;
1d2b39027b70 libtwamr: integrate qgain475.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
501 }