FreeCalypso > hg > gsm-codec-lib
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 } |