comparison libgsmefr/q_gains.c @ 53:49dd1ac8e75b

libgsmefr: import most *.c files from ETSI source
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 25 Nov 2022 16:18:21 +0000
parents
children 03599300d2db
comparison
equal deleted inserted replaced
52:988fd7ff514f 53:49dd1ac8e75b
1 /*--------------------------------------------------------------------------*
2 * Function q_gain_pitch(), q_gain_code() *
3 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
4 * Scalar quantization of the pitch gain and the innovative codebook gain. *
5 * *
6 * MA prediction is performed on the innovation energy *
7 * (in dB/(20*log10(2))) with mean removed. *
8 *-------------------------------------------------------------------------*/
9
10 #include "typedef.h"
11 #include "basic_op.h"
12 #include "oper_32b.h"
13 #include "count.h"
14 #include "sig_proc.h"
15
16 #include "gains_tb.h"
17
18 #include "cnst.h"
19 #include "dtx.h"
20
21 /* past quantized energies. */
22 /* initialized to -14.0/constant, constant = 20*Log10(2) */
23 Word16 past_qua_en[4];
24
25 /* MA prediction coeff */
26 Word16 pred[4];
27
28 extern Word16 CN_excitation_gain, gain_code_old_tx[4 * DTX_HANGOVER];
29
30 Word16 q_gain_pitch ( /* Return index of quantization */
31 Word16 *gain /* (i) : Pitch gain to quantize */
32 )
33 {
34 Word16 i, index, gain_q14, err, err_min;
35
36 gain_q14 = shl (*gain, 2);
37
38 err_min = abs_s (sub (gain_q14, qua_gain_pitch[0]));
39 index = 0; move16 ();
40
41 for (i = 1; i < NB_QUA_PITCH; i++)
42 {
43 err = abs_s (sub (gain_q14, qua_gain_pitch[i]));
44
45 test ();
46 if (sub (err, err_min) < 0)
47 {
48 err_min = err; move16 ();
49 index = i; move16 ();
50 }
51 }
52
53 *gain = shr (qua_gain_pitch[index], 2); move16 ();
54
55 return index;
56 }
57
58 /* average innovation energy. */
59 /* MEAN_ENER = 36.0/constant, constant = 20*Log10(2) */
60
61 #define MEAN_ENER 783741L /* 36/(20*log10(2)) */
62
63 Word16 q_gain_code ( /* Return quantization index */
64 Word16 code[], /* (i) : fixed codebook excitation */
65 Word16 lcode, /* (i) : codevector size */
66 Word16 *gain, /* (i/o) : quantized fixed codebook gain */
67 Word16 txdtx_ctrl,
68 Word16 i_subfr
69 )
70 {
71 Word16 i, index;
72 Word16 gcode0, err, err_min, exp, frac;
73 Word32 ener, ener_code;
74 Word16 aver_gain;
75 static Word16 gcode0_CN;
76
77 logic16 (); test ();
78 if ((txdtx_ctrl & TX_SP_FLAG) != 0)
79 {
80
81 /*-------------------------------------------------------------------*
82 * energy of code: *
83 * ~~~~~~~~~~~~~~~ *
84 * ener_code(Q17) = 10 * Log10(energy/lcode) / constant *
85 * = 1/2 * Log2(energy/lcode) *
86 * constant = 20*Log10(2) *
87 *-------------------------------------------------------------------*/
88
89 /* ener_code = log10(ener_code/lcode) / (20*log10(2)) */
90 ener_code = 0; move32 ();
91 for (i = 0; i < lcode; i++)
92 {
93 ener_code = L_mac (ener_code, code[i], code[i]);
94 }
95 /* ener_code = ener_code / lcode */
96 ener_code = L_mult (round (ener_code), 26214);
97
98 /* ener_code = 1/2 * Log2(ener_code) */
99 Log2 (ener_code, &exp, &frac);
100 ener_code = L_Comp (sub (exp, 30), frac);
101
102 /* predicted energy */
103
104 ener = MEAN_ENER; move32 ();
105 for (i = 0; i < 4; i++)
106 {
107 ener = L_mac (ener, past_qua_en[i], pred[i]);
108 }
109
110 /*-------------------------------------------------------------------*
111 * predicted codebook gain *
112 * ~~~~~~~~~~~~~~~~~~~~~~~ *
113 * gcode0(Qx) = Pow10( (ener*constant - ener_code*constant) / 20 ) *
114 * = Pow2(ener-ener_code) *
115 * constant = 20*Log10(2) *
116 *-------------------------------------------------------------------*/
117
118 ener = L_shr (L_sub (ener, ener_code), 1);
119 L_Extract (ener, &exp, &frac);
120
121 gcode0 = extract_l (Pow2 (exp, frac)); /* predicted gain */
122
123 gcode0 = shl (gcode0, 4);
124
125 /*-------------------------------------------------------------------*
126 * Search for best quantizer *
127 *-------------------------------------------------------------------*/
128
129 err_min = abs_s (sub (*gain, mult (gcode0, qua_gain_code[0])));
130 index = 0; move16 ();
131
132 for (i = 1; i < NB_QUA_CODE; i++)
133 {
134 err = abs_s (sub (*gain, mult (gcode0, qua_gain_code[i])));
135
136 test ();
137 if (sub (err, err_min) < 0)
138 {
139 err_min = err; move16 ();
140 index = i; move16 ();
141 }
142 }
143
144 *gain = mult (gcode0, qua_gain_code[index]);
145 move16 ();
146
147 /*------------------------------------------------------------------*
148 * update table of past quantized energies *
149 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
150 * past_qua_en(Q12) = 20 * Log10(qua_gain_code) / constant *
151 * = Log2(qua_gain_code) *
152 * constant = 20*Log10(2) *
153 *------------------------------------------------------------------*/
154
155 for (i = 3; i > 0; i--)
156 {
157 past_qua_en[i] = past_qua_en[i - 1];move16 ();
158 }
159 Log2 (L_deposit_l (qua_gain_code[index]), &exp, &frac);
160
161 past_qua_en[0] = shr (frac, 5); move16 ();
162 past_qua_en[0] = add (past_qua_en[0], shl (sub (exp, 11), 10));
163 move16 ();
164
165 update_gain_code_history_tx (*gain, gain_code_old_tx);
166 }
167 else
168 {
169 logic16 (); test (); test ();
170 if ((txdtx_ctrl & TX_PREV_HANGOVER_ACTIVE) != 0 && (i_subfr == 0))
171 {
172 gcode0_CN = update_gcode0_CN (gain_code_old_tx);
173 gcode0_CN = shl (gcode0_CN, 4);
174 }
175 *gain = CN_excitation_gain; move16 ();
176
177 logic16 (); test (); test ();
178 if ((txdtx_ctrl & TX_SID_UPDATE) != 0)
179 {
180 aver_gain = aver_gain_code_history (CN_excitation_gain,
181 gain_code_old_tx);
182
183 /*---------------------------------------------------------------*
184 * Search for best quantizer *
185 *---------------------------------------------------------------*/
186
187 err_min = abs_s (sub (aver_gain,
188 mult (gcode0_CN, qua_gain_code[0])));
189 index = 0; move16 ();
190
191 for (i = 1; i < NB_QUA_CODE; i++)
192 {
193 err = abs_s (sub (aver_gain,
194 mult (gcode0_CN, qua_gain_code[i])));
195
196 test ();
197 if (sub (err, err_min) < 0)
198 {
199 err_min = err; move16 ();
200 index = i; move16 ();
201 }
202 }
203 }
204 update_gain_code_history_tx (*gain, gain_code_old_tx);
205
206 /*-------------------------------------------------------------------*
207 * reset table of past quantized energies *
208 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
209 *-------------------------------------------------------------------*/
210
211 for (i = 0; i < 4; i++)
212 {
213 past_qua_en[i] = -2381; move16 ();
214 }
215 }
216
217 return index;
218 }