Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include "options.h" /* Compilation switches */
7 : #include "cnst.h" /* Common constants */
8 : #include "rom_com.h" /* Static table prototypes */
9 : #include "prot_fx.h" /* Function prototypes */
10 :
11 : /*--------------------------------------------------------------------------*
12 : * sfm2mqb_fx()
13 : *
14 : * Map sub-vectors to pbands
15 : *--------------------------------------------------------------------------*/
16 :
17 8029 : static void sfm2mqb_fx(
18 : Word16 spe[], /* i : sub-vectors Q0*/
19 : Word16 spe2q[], /* o : pbands Q0*/
20 : const Word16 nb_sfm /* i : number of norms Q0*/
21 : )
22 : {
23 : Word16 tmp, i;
24 :
25 : /* short groups */
26 8029 : spe2q[0] = add( spe[0], 3 ); /* Q0 */
27 8029 : move16();
28 8029 : spe2q[1] = add( spe[1], 3 ); /* Q0 */
29 8029 : move16();
30 8029 : spe2q[2] = add( spe[2], 3 ); /* Q0 */
31 8029 : move16();
32 8029 : spe2q[3] = add( spe[3], 3 ); /* Q0 */
33 8029 : move16();
34 8029 : spe2q[4] = add( spe[4], 3 ); /* Q0 */
35 8029 : move16();
36 8029 : spe2q[5] = add( spe[5], 3 ); /* Q0 */
37 8029 : move16();
38 8029 : spe2q[6] = add( spe[6], 3 ); /* Q0 */
39 8029 : move16();
40 8029 : spe2q[7] = add( spe[7], 3 ); /* Q0 */
41 8029 : move16();
42 8029 : spe2q[8] = add( spe[8], 3 ); /* Q0 */
43 8029 : move16();
44 8029 : spe2q[9] = add( spe[9], 3 ); /* Q0 */
45 8029 : move16();
46 :
47 8029 : spe2q[10] = add( shr( add( spe[10], spe[11] ), 1 ), 4 ); /* Q0 */
48 8029 : move16();
49 8029 : spe2q[11] = add( shr( add( spe[12], spe[13] ), 1 ), 4 ); /* Q0 */
50 8029 : move16();
51 8029 : spe2q[12] = add( shr( add( spe[14], spe[15] ), 1 ), 4 ); /* Q0 */
52 8029 : move16();
53 :
54 8029 : spe2q[13] = add( shr( add( spe[16], spe[17] ), 1 ), 5 ); /* Q0 */
55 8029 : move16();
56 8029 : spe2q[14] = add( shr( add( spe[18], spe[19] ), 1 ), 5 ); /* Q0 */
57 8029 : move16();
58 :
59 8029 : tmp = 0;
60 8029 : move16();
61 40145 : FOR( i = 20; i < 24; i++ )
62 : {
63 32116 : tmp = add( tmp, spe[i] );
64 : }
65 8029 : spe2q[15] = add( mult( tmp, 8192 ), 6 ); /* Q0 */
66 8029 : move16();
67 :
68 8029 : tmp = 0;
69 8029 : move16();
70 32116 : FOR( i = 24; i < 27; i++ )
71 : {
72 24087 : tmp = add( tmp, spe[i] ); /* Q0 */
73 : }
74 8029 : spe2q[16] = add( mult( tmp, 10923 ), 6 ); /* Q0 */
75 8029 : move16();
76 :
77 8029 : IF( GT_16( nb_sfm, SFM_N_STA_8k ) )
78 : {
79 8029 : tmp = 0;
80 8029 : move16();
81 32116 : FOR( i = 27; i < 30; i++ )
82 : {
83 24087 : tmp = add( tmp, spe[i] ); /* Q0 */
84 : }
85 8029 : spe2q[17] = add( mult( tmp, 10923 ), 6 ); /* Q0 */
86 8029 : move16();
87 :
88 8029 : IF( GT_16( nb_sfm, SFM_N_STA_10k ) )
89 : {
90 8029 : tmp = 0;
91 8029 : move16();
92 48174 : FOR( i = 30; i < 35; i++ )
93 : {
94 40145 : tmp = add( tmp, spe[i] ); /* Q0 */
95 : }
96 8029 : spe2q[18] = add( mult( tmp, 6553 ), 7 ); /* Q0 */
97 8029 : move16();
98 :
99 8029 : tmp = 0;
100 8029 : move16();
101 80290 : FOR( i = 35; i < 44; i++ )
102 : {
103 72261 : tmp = add( tmp, spe[i] ); /* Q0 */
104 : }
105 8029 : spe2q[19] = add( mult( tmp, 3641 ), 8 ); /* Q0 */
106 8029 : move16();
107 : }
108 : }
109 :
110 8029 : return;
111 : }
112 :
113 : /*--------------------------------------------------------------------------*
114 : * mqb2sfm_fx()
115 : *
116 : * Map pbands to sub-vectors
117 : *--------------------------------------------------------------------------*/
118 :
119 8029 : static void mqb2sfm_fx(
120 : Word16 spe2q[], /* i : pbands Q0*/
121 : Word16 spe[], /* o : sub-vectors Q0*/
122 : const Word16 lnb_sfm /* i : number of norms Q0*/
123 : )
124 : {
125 : Word16 i;
126 :
127 8029 : spe[0] = spe2q[0]; /* Q0 */
128 8029 : move16();
129 8029 : spe[1] = spe2q[1]; /* Q0 */
130 8029 : move16();
131 8029 : spe[2] = spe2q[2]; /* Q0 */
132 8029 : move16();
133 8029 : spe[3] = spe2q[3]; /* Q0 */
134 8029 : move16();
135 8029 : spe[4] = spe2q[4]; /* Q0 */
136 8029 : move16();
137 8029 : spe[5] = spe2q[5]; /* Q0 */
138 8029 : move16();
139 8029 : spe[6] = spe2q[6]; /* Q0 */
140 8029 : move16();
141 8029 : spe[7] = spe2q[7]; /* Q0 */
142 8029 : move16();
143 8029 : spe[8] = spe2q[8]; /* Q0 */
144 8029 : move16();
145 8029 : spe[9] = spe2q[9]; /* Q0 */
146 8029 : move16();
147 :
148 8029 : spe[10] = spe2q[10]; /* Q0 */
149 8029 : move16();
150 8029 : spe[11] = spe2q[10]; /* Q0 */
151 8029 : move16();
152 :
153 8029 : spe[12] = spe2q[11]; /* Q0 */
154 8029 : move16();
155 8029 : spe[13] = spe2q[11]; /* Q0 */
156 8029 : move16();
157 :
158 8029 : spe[14] = spe2q[12]; /* Q0 */
159 8029 : move16();
160 8029 : spe[15] = spe2q[12]; /* Q0 */
161 8029 : move16();
162 :
163 8029 : spe[16] = spe2q[13]; /* Q0 */
164 8029 : move16();
165 8029 : spe[17] = spe2q[13]; /* Q0 */
166 8029 : move16();
167 :
168 8029 : spe[18] = spe2q[14]; /* Q0 */
169 8029 : move16();
170 8029 : spe[19] = spe2q[14]; /* Q0 */
171 8029 : move16();
172 :
173 40145 : FOR( i = 20; i < 24; i++ )
174 : {
175 32116 : spe[i] = spe2q[15]; /* Q0 */
176 32116 : move16();
177 : }
178 :
179 32116 : FOR( i = 24; i < 27; i++ )
180 : {
181 24087 : spe[i] = spe2q[16]; /* Q0 */
182 24087 : move16();
183 : }
184 :
185 8029 : IF( GT_16( lnb_sfm, SFM_N_STA_8k ) )
186 : {
187 32116 : FOR( i = 27; i < 30; i++ )
188 : {
189 24087 : spe[i] = spe2q[17]; /* Q0 */
190 24087 : move16();
191 : }
192 :
193 8029 : IF( GT_16( lnb_sfm, SFM_N_STA_10k ) )
194 : {
195 48174 : FOR( i = 30; i < 35; i++ )
196 : {
197 40145 : spe[i] = spe2q[18]; /* Q0 */
198 40145 : move16();
199 : }
200 :
201 80290 : FOR( i = 35; i < 44; i++ )
202 : {
203 72261 : spe[i] = spe2q[19]; /* Q0 */
204 72261 : move16();
205 : }
206 : }
207 : }
208 :
209 8029 : return;
210 : }
211 :
212 : /*--------------------------------------------------------------------------*
213 : * map_quant_weight_fx()
214 : *
215 : * Calculate the quantization weights
216 : *--------------------------------------------------------------------------*/
217 :
218 8029 : void map_quant_weight_fx(
219 : const Word16 normqlg2[], /* i : quantized norms Q0*/
220 : Word16 wnorm[], /* o : weighted norm Q0*/
221 : const Word16 is_transient /* i : transient flag Q0*/
222 : )
223 : {
224 : Word16 sfm;
225 : Word16 tmp16;
226 : Word16 spe2q[NUM_MAP_BANDS];
227 : Word16 spe[NB_SFM];
228 :
229 : Word16 spe2q_max;
230 : Word16 spe2q_min;
231 : Word16 norm_max;
232 : Word16 shift;
233 : Word16 sum;
234 : Word16 k;
235 : Word16 lnb_sfm, num_map_bands;
236 :
237 8029 : lnb_sfm = NB_SFM;
238 8029 : move16();
239 8029 : num_map_bands = NUM_MAP_BANDS;
240 8029 : move16();
241 :
242 8029 : IF( is_transient != 0 )
243 : {
244 8904 : FOR( sfm = 0; sfm < lnb_sfm; sfm += 4 )
245 : {
246 8162 : sum = 0;
247 8162 : move16();
248 40810 : FOR( k = 0; k < 4; k++ )
249 : {
250 32648 : sum = add( sum, normqlg2[sfm + k] ); /* Q0 */
251 : }
252 8162 : sum = shr( sum, 2 );
253 :
254 40810 : FOR( k = 0; k < 4; k++ )
255 : {
256 32648 : spe[sfm + k] = sum; /* Q0 */
257 32648 : move16();
258 : }
259 : }
260 : }
261 : ELSE
262 : {
263 327915 : FOR( sfm = 0; sfm < lnb_sfm; sfm++ )
264 : {
265 320628 : spe[sfm] = normqlg2[sfm]; /* Q0 */
266 320628 : move16();
267 : }
268 : }
269 :
270 8029 : sfm2mqb_fx( spe, spe2q, lnb_sfm );
271 :
272 168609 : FOR( sfm = 0; sfm < num_map_bands; sfm++ )
273 : {
274 160580 : spe2q[sfm] = sub( spe2q[sfm], 10 ); /* Q0 */
275 160580 : move16();
276 : }
277 :
278 : /* spectral smoothing */
279 160580 : FOR( sfm = 1; sfm < num_map_bands; sfm++ )
280 : {
281 152551 : tmp16 = sub( spe2q[sfm - 1], 4 ); /* Q0 */
282 152551 : spe2q[sfm] = s_max( spe2q[sfm], tmp16 ); /* Q0 */
283 152551 : move16();
284 : }
285 :
286 160580 : FOR( sfm = num_map_bands - 2; sfm >= 0; sfm-- )
287 : {
288 152551 : tmp16 = sub( spe2q[sfm + 1], 8 ); /* Q0 */
289 152551 : spe2q[sfm] = s_max( spe2q[sfm], tmp16 ); /* Q0 */
290 152551 : move16();
291 : }
292 :
293 168609 : FOR( sfm = 0; sfm < num_map_bands; sfm++ )
294 : {
295 160580 : spe2q[sfm] = s_max( spe2q[sfm], a_map[sfm] ); /* Q0 */
296 160580 : move16();
297 : }
298 :
299 : /* Saturate by the Absolute Threshold of Hearing */
300 8029 : spe2q_max = -32768;
301 8029 : move16();
302 8029 : spe2q_min = MAX_16;
303 8029 : move16();
304 :
305 168609 : FOR( sfm = 0; sfm < num_map_bands; sfm++ )
306 : {
307 160580 : spe2q[sfm] = sub( sfm_width[sfm], spe2q[sfm] ); /* Q0 */
308 160580 : move16();
309 160580 : spe2q_max = s_max( spe2q[sfm], spe2q_max ); /* Q0 */
310 160580 : spe2q_min = s_min( spe2q[sfm], spe2q_min ); /* Q0 */
311 : }
312 :
313 168609 : FOR( sfm = 0; sfm < num_map_bands; sfm++ )
314 : {
315 160580 : spe2q[sfm] = sub( spe2q[sfm], spe2q_min ); /* Q0 */
316 160580 : move16();
317 : }
318 :
319 8029 : spe2q_max = sub( spe2q_max, spe2q_min );
320 :
321 8029 : norm_max = norm_s( spe2q_max );
322 :
323 8029 : shift = sub( norm_max, 13 );
324 :
325 168609 : FOR( sfm = 0; sfm < num_map_bands; sfm++ )
326 : {
327 160580 : spe2q[sfm] = shl( spe2q[sfm], shift );
328 160580 : move16();
329 : }
330 :
331 8029 : mqb2sfm_fx( spe2q, spe, lnb_sfm );
332 :
333 8029 : IF( is_transient != 0 )
334 : {
335 8904 : FOR( sfm = 0; sfm < lnb_sfm; sfm += 4 )
336 : {
337 8162 : sum = 0;
338 8162 : move16();
339 40810 : FOR( k = 0; k < 4; k++ )
340 : {
341 32648 : sum = add( sum, spe[sfm + k] ); /* Q0 */
342 : }
343 8162 : sum = shr( sum, 2 );
344 40810 : FOR( k = 0; k < 4; k++ )
345 : {
346 32648 : spe[sfm + k] = sum; /* Q0 */
347 32648 : move16();
348 : }
349 : }
350 : }
351 :
352 : /* modify the norms for bit-allocation */
353 361305 : FOR( sfm = 0; sfm < lnb_sfm; sfm++ )
354 : {
355 353276 : wnorm[sfm] = add( spe[sfm], normqlg2[sfm] ); /* Q0 */
356 353276 : move16();
357 : }
358 :
359 8029 : return;
360 : }
|