Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdio.h>
6 : #include <stdlib.h>
7 : #include <assert.h>
8 : #include <memory.h>
9 : #include "options.h"
10 : #include "stl.h"
11 : #include "prot_fx.h"
12 : #include "ivas_prot_fx.h"
13 : #include "cnst.h"
14 : #include "stat_dec.h"
15 : #include "basop_util.h"
16 : #define MID 57 /* (.89*1<<6)*/
17 : #include "ivas_prot_fx.h"
18 :
19 : /**********************************************************************/ /*
20 : get scalefactor of an Word32 array with condition
21 : **************************************************************************/
22 515 : static Word16 IGF_getScaleFactor32Cond( /**< out: Q0 | measured headroom in range [0..31], 0 if all x[i] == 0 */
23 : const Word16 *cond, /**< in: Q0 | array conating the condition */
24 : const Word32 *x, /**< in: Q31 | array containing 32-bit data */
25 : const Word16 len_x /**< in: Q0 | length of the array to scan */
26 : )
27 : {
28 : Word16 i;
29 : Word16 i_min;
30 : Word16 i_max;
31 : Word32 x_min;
32 : Word32 x_max;
33 : Word32 tmp32;
34 :
35 :
36 515 : x_max = 0; // Q31
37 515 : move32();
38 515 : x_min = 0; // Q31
39 515 : move32();
40 118339 : FOR( i = 0; i < len_x; i++ )
41 : {
42 117824 : tmp32 = L_add( x[i], 0 ); /*L_and(x[i], cond[i]);*/ // Q31
43 :
44 117824 : IF( cond[i] == 0 )
45 : {
46 22463 : tmp32 = L_deposit_h( 0 ); // Q31
47 : }
48 :
49 :
50 117824 : IF( tmp32 >= 0 )
51 : {
52 69861 : x_max = L_max( x_max, tmp32 ); // Q31
53 : }
54 117824 : IF( tmp32 < 0 )
55 : {
56 47963 : x_min = L_min( x_min, tmp32 ); // Q31
57 : }
58 : }
59 :
60 515 : i_max = 0x20; // Q0
61 515 : move16();
62 515 : i_min = 0x20; // Q0
63 515 : move16();
64 :
65 515 : IF( x_max != 0 )
66 : {
67 514 : i_max = norm_l( x_max ); // Q0
68 : }
69 515 : IF( x_min != 0 )
70 : {
71 514 : i_min = norm_l( x_min ); // Q0
72 : }
73 :
74 515 : i = s_and( s_min( i_max, i_min ), 0x1F ); // Q0
75 :
76 515 : return i;
77 : }
78 :
79 : /**********************************************************************/ /*
80 : measures TCX noise
81 : **************************************************************************/
82 515 : static Word16 IGF_replaceTCXNoise_1( /**< out: Q0 | number of noise bands */
83 : const Word32 *in, /**< in: Q31 | MDCT spectrum */
84 : Word16 s_l, /**< in: Q0 | noise headroom */
85 : const Word16 *TCXNoise, /**< in: Q0 | tcx noise indicator vector */
86 : const Word16 start, /**< in: Q0 | start MDCT subband index */
87 : const Word16 stop, /**< in: Q0 | stop MDCT subband index */
88 : Word32 *totalNoiseNrg /**< out: | measured noise energy */
89 : )
90 : {
91 : Word16 sb;
92 : Word16 tmp16;
93 : Word16 noise;
94 : Word32 nE;
95 :
96 :
97 515 : tmp16 = 0;
98 515 : move16();
99 515 : noise = 0;
100 515 : move16();
101 515 : s_l = sub( s_l, 5 );
102 515 : nE = 0;
103 515 : move32();
104 :
105 118339 : FOR( sb = start; sb < stop; sb++ ){
106 117824 : IF( TCXNoise[sb] ){
107 95361 : tmp16 = extract_h( L_shl( in[sb], s_l ) ); // Q31 + s_l
108 : }
109 117824 : IF( TCXNoise[sb] )
110 : {
111 95361 : nE = L_mac( nE, tmp16, tmp16 ); // Q31 + s_l
112 : }
113 117824 : IF( TCXNoise[sb] )
114 : {
115 95361 : noise = add( noise, 1 ); // Q0
116 : }
117 : }
118 :
119 515 : *totalNoiseNrg = nE; // Q31 + s_l
120 515 : move32();
121 :
122 515 : return noise;
123 : }
124 :
125 575031 : static Word16 ivas_IGF_replaceTCXNoise_1_fx( /**< out: Q0 | number of noise bands */
126 : const Word32 *in, /**< in: in_exp | MDCT spectrum */
127 : Word16 in_exp, /**< in: Q0 | noise headroom */
128 : const Word16 *TCXNoise, /**< in: Q0 | tcx noise indicator vector */
129 : const Word16 start, /**< in: Q0 | start MDCT subband index */
130 : const Word16 stop, /**< in: Q0 | stop MDCT subband index */
131 : Word32 *totalNoiseNrg, /**< out: | measured noise energy */
132 : Word16 *totalNoiseNrg_exp )
133 : {
134 : Word16 sb;
135 : Word16 tmp16, shift;
136 : Word16 noise;
137 : Word32 tmp32;
138 : Word64 nE;
139 :
140 :
141 575031 : shift = 2;
142 575031 : move16();
143 575031 : noise = 0;
144 575031 : move16();
145 575031 : nE = 0;
146 575031 : move64();
147 :
148 575031 : *totalNoiseNrg = 0;
149 575031 : move32();
150 575031 : *totalNoiseNrg_exp = 0;
151 575031 : move16();
152 :
153 218263773 : FOR( sb = start; sb < stop; sb++ )
154 : {
155 217688742 : IF( TCXNoise[sb] )
156 : {
157 155014274 : tmp32 = L_shr( in[sb], shift );
158 155014274 : nE = W_mac_32_32( nE, tmp32, tmp32 ); // 62 - (in_exp + shift + in_exp + shift + 1)
159 155014274 : noise = add( noise, 1 );
160 : }
161 : }
162 :
163 575031 : IF( nE )
164 : {
165 555526 : tmp16 = W_norm( nE );
166 555526 : nE = W_shl( nE, tmp16 );
167 555526 : *totalNoiseNrg = W_extract_h( nE );
168 555526 : move32();
169 555526 : *totalNoiseNrg_exp = sub( add( shl( shift, 1 ), shl( in_exp, 1 ) ), tmp16 );
170 555526 : move16();
171 : }
172 :
173 :
174 575031 : return noise;
175 : }
176 :
177 : /**********************************************************************/ /*
178 : replaces TCX noise
179 : **************************************************************************/
180 879 : static void IGF_replaceTCXNoise_2( Word32 *in, /**< in/out: Q31 | MDCT spectrum */
181 : const Word16 *TCXNoise, /**< in: Q0 | tcx noise indicator vector */
182 : const Word16 start, /**< in: Q0 | start MDCT subband index */
183 : const Word16 stop, /**< in: Q0 | stop MDCT subband index */
184 : Word32 totalNoiseNrg, /**< in: | measured noise energy */
185 : const Word16 s_l, /**< in: Q0 | noise headroom */
186 : Word16 *nfSeed /**< in: | random generator noise seed */
187 : )
188 : {
189 : Word16 sb;
190 : Word16 g;
191 : Word16 val;
192 : Word32 rE;
193 : Word32 L_tmp;
194 :
195 :
196 879 : val = 0;
197 879 : move16();
198 879 : rE = 0;
199 879 : move32();
200 :
201 202311 : FOR( sb = start; sb < stop; sb++ )
202 : {
203 201432 : IF( TCXNoise[sb] )
204 : {
205 161664 : val = Random( nfSeed ); // Q0
206 : }
207 201432 : IF( TCXNoise[sb] )
208 : {
209 161664 : in[sb] = L_deposit_l( val ); // Q0
210 161664 : move32();
211 : }
212 201432 : IF( TCXNoise[sb] )
213 : {
214 161664 : val = shr( val, 5 ); // Q-5
215 : }
216 201432 : IF( TCXNoise[sb] )
217 : {
218 161664 : rE = L_mac( rE, val, val ); // Q-9
219 : }
220 : }
221 :
222 879 : totalNoiseNrg = L_shr( totalNoiseNrg, 1 ); // Q-9
223 :
224 :
225 : /* make sure that rE is never 0 */
226 879 : if ( rE == 0 )
227 : {
228 0 : rE = L_add( totalNoiseNrg, 0 ); /* save move32() -> use L_add(x, 0) = x; */ // Q-9
229 : }
230 :
231 : /* if totalNoiseNrg == 0, then rE must be at least 0x00010000, otherwise division by 0 will occur */
232 879 : if ( totalNoiseNrg == 0 )
233 : {
234 0 : rE = L_max( rE, 0x00010000 ); // Q-9
235 : }
236 :
237 : /* make sure that rE is never smaller than totalNoiseNrg */
238 879 : L_tmp = L_sub( rE, totalNoiseNrg ); // Q-9
239 879 : if ( L_tmp < 0 )
240 : {
241 0 : rE = totalNoiseNrg; /* save move32() -> use L_add(x, 0) = x; */ // Q-9
242 0 : move32();
243 : }
244 :
245 :
246 879 : g = getSqrtWord32( L_mult( divide3232( totalNoiseNrg, rE ), 8192 /*1.0f / 4.0f Q15*/ ) ); // ((Q15 + Q15 + Q1) / 2) -> Q15
247 879 : g = shl_sat( g, 1 ); // Q16
248 :
249 202311 : FOR( sb = start; sb < stop; sb++ )
250 : {
251 201432 : IF( TCXNoise[sb] )
252 : {
253 161664 : in[sb] = L_shr( L_mult( extract_l( in[sb] ), g ), s_l ); // Q15 + Q16 + Q1 - s_l
254 161664 : move32();
255 : }
256 : }
257 879 : }
258 :
259 : /**********************************************************************/ /*
260 : replaces TCX noise with noise band ratio (for IVAS)
261 : **************************************************************************/
262 1303599 : static void IGF_replaceTCXNoise_2_new_ivas( Word32 *in, /**< in/out: | MDCT spectrum */
263 : const Word16 in_e, /**< in: | MDCT spectrum exp */
264 : const Word16 *TCXNoise, /**< in: Q0 | tcx noise indicator vector */
265 : const Word16 start, /**< in: Q0 | start MDCT subband index */
266 : const Word16 stop, /**< in: Q0 | stop MDCT subband index */
267 : Word32 totalNoiseNrg, /**< in: | measured noise energy */
268 : Word16 totalNoiseNrg_e, /**< in: | measured noise energy exp */
269 : const Word16 n_noise_bands, /**< in: | number of noise bands in src */
270 : Word16 *nfSeed /**< in: | random generator noise seed */
271 : )
272 : {
273 : Word16 sb;
274 : Word16 g;
275 : Word16 val;
276 : Word32 rE;
277 : Word32 L_tmp;
278 : Word16 n_noise_bands_tile;
279 : Word16 noise_band_ratio;
280 :
281 1303599 : n_noise_bands_tile = 0;
282 1303599 : move16();
283 1303599 : val = 0;
284 1303599 : move16();
285 1303599 : rE = 0;
286 1303599 : move32();
287 :
288 101914007 : FOR( sb = start; sb < stop; sb++ )
289 : {
290 100610408 : IF( TCXNoise[sb] )
291 : {
292 85888481 : val = Random( nfSeed ); // Q0
293 85888481 : move16();
294 85888481 : in[sb] = L_deposit_l( val ); // Q0
295 85888481 : move32();
296 85888481 : val = shr( val, 5 ); // Q-5
297 85888481 : rE = L_mac( rE, val, val ); // Q-9
298 85888481 : n_noise_bands_tile = add( n_noise_bands_tile, 1 );
299 : }
300 : }
301 :
302 :
303 1303599 : IF( n_noise_bands_tile != 0 )
304 : {
305 1303456 : noise_band_ratio = div_s( n_noise_bands_tile, n_noise_bands ); // Q15
306 :
307 : /* make sure that rE is never 0 */
308 1303456 : if ( rE == 0 )
309 : {
310 0 : rE = L_add( totalNoiseNrg, 0 ); /* save move32() -> use L_add(x, 0) = x; */ // Q31 - totalNoiseNrg_e
311 : }
312 :
313 : /* if totalNoiseNrg == 0, then rE must be at least 0x00010000, otherwise division by 0 will occur */
314 1303456 : if ( totalNoiseNrg == 0 )
315 : {
316 0 : rE = L_max( rE, 0x00010000 ); // Q-9
317 : }
318 :
319 : Word16 tmp, tmp_e;
320 1303456 : L_tmp = Mpy_32_16_1( totalNoiseNrg, noise_band_ratio ); // Q31 - totalNoiseNrg_e
321 1303456 : tmp = BASOP_Util_Divide3232_Scale( L_tmp, rE, &tmp_e );
322 1303456 : tmp_e = add( tmp_e, sub( totalNoiseNrg_e, 40 ) );
323 1303456 : g = Sqrt16( tmp, &tmp_e );
324 :
325 101909852 : FOR( sb = start; sb < stop; sb++ )
326 : {
327 100606396 : IF( TCXNoise[sb] )
328 : {
329 85888481 : Word16 nrm = norm_l( in[sb] );
330 85888481 : in[sb] = L_shl( in[sb], nrm ); // exp: 31 - tmp
331 85888481 : move32();
332 85888481 : in[sb] = Mpy_32_16_1( in[sb], g ); // exp: 31 - tmp + tmp_e
333 85888481 : move32();
334 : /* To handle corner cases */
335 85888481 : in[sb] = L_shr_sat( in[sb], sub( in_e, sub( add( 31, tmp_e ), nrm ) ) ); // Making the exponent same as original
336 85888481 : move32();
337 : }
338 : }
339 : }
340 1303599 : }
341 :
342 :
343 : /**********************************************************************/ /*
344 : replaces TCX noise with noise band ratio (for IVAS)
345 : **************************************************************************/
346 218704 : static void IGF_replaceTCXNoise_2_new_ivas_with_var_shift( Word32 *in, /**< in/out: | MDCT spectrum */
347 : Word16 *in_e_arr, /**< in/out: | MDCT spectrum exp */
348 : const Word16 *TCXNoise, /**< in: Q0 | tcx noise indicator vector */
349 : const Word16 start, /**< in: Q0 | start MDCT subband index */
350 : const Word16 stop, /**< in: Q0 | stop MDCT subband index */
351 : Word32 totalNoiseNrg, /**< in: | measured noise energy */
352 : Word16 totalNoiseNrg_e, /**< in: | measured noise energy exp */
353 : const Word16 n_noise_bands, /**< in: Q0 | number of noise bands in src */
354 : Word16 *nfSeed /**< in: Q0 | random generator noise seed */
355 : )
356 : {
357 : Word16 sb;
358 : Word16 g;
359 : Word16 val;
360 : Word32 rE;
361 : Word32 L_tmp;
362 : Word16 n_noise_bands_tile;
363 : Word16 noise_band_ratio;
364 :
365 218704 : n_noise_bands_tile = 0;
366 218704 : move16();
367 218704 : val = 0;
368 218704 : move16();
369 218704 : rE = 0;
370 218704 : move32();
371 :
372 20532496 : FOR( sb = start; sb < stop; sb++ )
373 : {
374 20313792 : IF( TCXNoise[sb] )
375 : {
376 18189704 : val = Random( nfSeed ); // Q0
377 18189704 : move16();
378 18189704 : in[sb] = L_deposit_l( val ); // Q0
379 18189704 : move32();
380 18189704 : in_e_arr[sb] = 31;
381 18189704 : move16();
382 18189704 : val = shr( val, 5 ); // Q-5
383 18189704 : rE = L_mac( rE, val, val ); // Q-9
384 18189704 : n_noise_bands_tile = add( n_noise_bands_tile, 1 );
385 : }
386 : }
387 :
388 :
389 218704 : IF( n_noise_bands_tile != 0 )
390 : {
391 218704 : noise_band_ratio = div_s( n_noise_bands_tile, n_noise_bands ); // Q15
392 :
393 : /* make sure that rE is never 0 */
394 218704 : if ( rE == 0 )
395 : {
396 0 : rE = L_add( totalNoiseNrg, 0 ); /* save move32() -> use L_add(x, 0) = x; */ // Q31 - totalNoiseNrg_e
397 : }
398 :
399 : /* if totalNoiseNrg == 0, then rE must be at least 0x00010000, otherwise division by 0 will occur */
400 218704 : if ( totalNoiseNrg == 0 )
401 : {
402 0 : rE = L_max( rE, 0x00010000 ); // Q-9
403 : }
404 :
405 : Word16 tmp, tmp_e;
406 218704 : L_tmp = Mpy_32_16_1( totalNoiseNrg, noise_band_ratio ); // Q31 - totalNoiseNrg_e
407 218704 : tmp = BASOP_Util_Divide3232_Scale( L_tmp, rE, &tmp_e );
408 218704 : tmp_e = add( tmp_e, sub( totalNoiseNrg_e, 40 ) );
409 218704 : g = Sqrt16( tmp, &tmp_e );
410 :
411 20532496 : FOR( sb = start; sb < stop; sb++ )
412 : {
413 20313792 : Word16 nrm = norm_l( in[sb] );
414 20313792 : in[sb] = L_shl( in[sb], nrm );
415 20313792 : move32();
416 20313792 : in_e_arr[sb] = sub( in_e_arr[sb], nrm );
417 20313792 : move16();
418 20313792 : IF( TCXNoise[sb] )
419 : {
420 18189704 : in[sb] = Mpy_32_16_1( in[sb], g );
421 18189704 : move32();
422 18189704 : in_e_arr[sb] = add( in_e_arr[sb], tmp_e );
423 18189704 : move16();
424 : }
425 : }
426 : }
427 218704 : }
428 :
429 : /**********************************************************************/ /*
430 : reads whitening levels
431 : **************************************************************************/
432 1170566 : static void IGF_decode_whitening_level( Decoder_State *st, /**< in: | decoder state */
433 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in: | instance handle of IGF Deccoder */
434 : const Word16 p /**< in: Q0 | tile index, p = [0, 3] */
435 : )
436 : {
437 : Word16 tmp;
438 :
439 :
440 1170566 : tmp = get_next_indice_fx( st, 1 ); // Q0
441 :
442 1170566 : if ( tmp == 0 )
443 : {
444 431851 : hPrivateData->currWhiteningLevel[p] = IGF_WHITENING_MID; // Q0
445 431851 : move16();
446 :
447 431851 : return;
448 : }
449 :
450 738715 : tmp = get_next_indice_fx( st, 1 ); // Q0
451 738715 : hPrivateData->currWhiteningLevel[p] = IGF_WHITENING_STRONG; // Q0
452 738715 : move16();
453 :
454 738715 : if ( tmp == 0 )
455 : {
456 374088 : hPrivateData->currWhiteningLevel[p] = IGF_WHITENING_OFF; // Q0
457 374088 : move16();
458 : }
459 : }
460 :
461 : /**********************************************************************/ /*
462 : reads flattening trigger
463 : **************************************************************************/
464 569731 : static void IGF_decode_temp_flattening_trigger( Decoder_State *st, /**< in: | decoder state */
465 : IGF_DEC_INSTANCE_HANDLE hInstance /**< in: | instance handle of IGF Deccoder */
466 : )
467 : {
468 569731 : hInstance->flatteningTrigger = get_next_indice_fx( st, 1 ); // Q0
469 569731 : move16();
470 569731 : }
471 :
472 : /**********************************************************************/ /*
473 : set power spectrum values to zero, needed for energy calculation
474 : **************************************************************************/
475 1931551 : static void IGF_setLinesToZero( const Word16 startLine, /**< in: Q0 | start MDCT subband index */
476 : const Word16 stopLine, /**< in: Q0 | stop MDCT subband index */
477 : const Word32 *pSpectralData, /**< in: | original MDCT spectrum */
478 : Word32 *pPowerSpecIGF /**< in/out: | prepared IGF energy spectrum */
479 : )
480 : {
481 : Word16 i;
482 :
483 :
484 : /* set energy values in the IGF "power spectrum" to 0,
485 : if there is content in the original MDCT spectrum */
486 167808421 : FOR( i = startLine; i < stopLine; i++ )
487 : {
488 165876870 : if ( pSpectralData[i] != 0 )
489 : {
490 20986 : pPowerSpecIGF[i] = L_deposit_l( 0 );
491 : }
492 : }
493 1931551 : }
494 :
495 : /**********************************************************************/ /*
496 : Convert igfSpectrum fixed point values with exponent per index to per tile.
497 : **************************************************************************/
498 173518 : static void IGF_convert_exponent_per_idx_to_per_tile( H_IGF_GRID hGrid,
499 : Word32 *igfSpec,
500 : Word16 *igfSpec_e_per_idx,
501 : Word16 *igfSpec_e_per_tile )
502 : {
503 : Word16 i;
504 : Word16 j;
505 : Word16 max_e;
506 : Word16 start;
507 : Word16 stop;
508 732812 : FOR( i = 0; i < hGrid->nTiles; i++ )
509 : {
510 559294 : start = hGrid->tile[i];
511 559294 : move16();
512 559294 : stop = hGrid->tile[i + 1];
513 559294 : move16();
514 :
515 559294 : maximum_fx( igfSpec_e_per_idx + start, sub( stop, start ), &max_e );
516 :
517 48285558 : FOR( j = start; j < stop; j++ )
518 : {
519 47726264 : igfSpec[j] = L_shr( igfSpec[j], sub( max_e, igfSpec_e_per_idx[j] ) ); // Q31 - max_e
520 47726264 : move32();
521 : }
522 :
523 559294 : igfSpec_e_per_tile[i] = max_e;
524 559294 : move16();
525 : }
526 173518 : }
527 :
528 : /**********************************************************************/ /*
529 : prepare IGF spectrum
530 : **************************************************************************/
531 646 : static void IGF_prep( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in: | IGF private data handle */
532 : const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */
533 : const Word16 *TCXNoise, /**< in: Q0 | TCX noise vector */
534 : Word32 *igf_spec, /**< in: Q31 | prepared IGF spectrum */
535 : Word16 *igf_spec_e, /**< in: | array exponents of igf_spec, one exponent per tile */
536 : const Word32 *src_spec, /**< in: | source spectrum */
537 : const Word16 src_spec_e, /**< in: | exponent of src_spec, whitening off */
538 : const Word16 specMed_e /**< in: | exponent of medium flattening level */
539 : )
540 : {
541 : H_IGF_GRID hGrid;
542 : H_IGF_INFO hInfo;
543 : Word16 i;
544 : Word16 tb;
545 : Word16 sfb;
546 : Word16 nTiles;
547 : Word16 n_noise_bands;
548 : Word16 n_noise_bands_off;
549 : Word16 strt_cpy;
550 : Word16 startLine;
551 : Word16 minSrcSubband;
552 : Word16 tile_idx;
553 : Word32 totalNoiseNrg;
554 : Word32 totalNoiseNrg_off;
555 : const Word32 *sel_spec;
556 :
557 :
558 : /* initialize variables */
559 646 : hInfo = &hPrivateData->igfInfo;
560 646 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
561 646 : n_noise_bands = hPrivateData->n_noise_bands;
562 646 : move16();
563 646 : n_noise_bands_off = hPrivateData->n_noise_bands_off;
564 646 : move16();
565 646 : totalNoiseNrg = hPrivateData->totalNoiseNrg;
566 646 : move32();
567 646 : totalNoiseNrg_off = hPrivateData->totalNoiseNrg_off;
568 646 : move32();
569 646 : nTiles = hGrid->nTiles;
570 646 : move16();
571 646 : startLine = hGrid->startLine;
572 646 : move16();
573 646 : minSrcSubband = hGrid->minSrcSubband;
574 646 : move16();
575 646 : tile_idx = 0;
576 646 : move16();
577 :
578 2309 : FOR( tile_idx = 0; tile_idx < nTiles; tile_idx++ )
579 : {
580 1663 : strt_cpy = hGrid->sbWrap[tile_idx];
581 1663 : move16();
582 :
583 : /* strong whitening detected */
584 1663 : IF( EQ_16( IGF_WHITENING_STRONG, hPrivateData->currWhiteningLevel[tile_idx] ) )
585 : {
586 : Word32 abs_sum;
587 782 : abs_sum = 0;
588 782 : move32();
589 :
590 151022 : FOR( i = strt_cpy; i < hGrid->startLine; i++ )
591 : {
592 150240 : abs_sum = L_add( abs_sum, L_abs( src_spec[i] ) ); // Q31 - src_spec_e
593 : }
594 :
595 : /* fill igf_spec with random noise */
596 782 : tb = hGrid->swb_offset[hGrid->sfbWrap[tile_idx]];
597 782 : move16();
598 :
599 782 : IF( abs_sum != 0 )
600 : {
601 151022 : FOR( i = strt_cpy; i < startLine; i++ )
602 : {
603 150240 : igf_spec[tb++] = L_deposit_l( Random( hInfo->nfSeed ) ); /* 31Q0, fill LSBs */ // Q0
604 150240 : move32();
605 : }
606 : }
607 : ELSE
608 : {
609 0 : FOR( i = strt_cpy; i < startLine; i++ )
610 : {
611 0 : igf_spec[tb++] = 0; // Q0
612 0 : move32();
613 : }
614 : }
615 :
616 : /* set exponent of the current tile, random noise is 31Q0 */
617 782 : igf_spec_e[tile_idx] = 31;
618 782 : move16();
619 : }
620 : ELSE
621 : {
622 : /* medium whitening detected */
623 881 : IF( EQ_16( IGF_WHITENING_MID, hPrivateData->currWhiteningLevel[tile_idx] ) )
624 : {
625 564 : IF( n_noise_bands != 0 )
626 : {
627 564 : IGF_replaceTCXNoise_2( igf_spec,
628 : TCXNoise,
629 :
630 : minSrcSubband,
631 : startLine,
632 : totalNoiseNrg,
633 564 : hPrivateData->headroom_TCX_noise_white,
634 : hInfo->nfSeed );
635 : }
636 :
637 : /* selected source spectrum is igf_spec, igf_spec contains the whitened signal in the core region */
638 564 : sel_spec = igf_spec;
639 564 : move16();
640 :
641 : /* set exponent of the current tile */
642 564 : igf_spec_e[tile_idx] = specMed_e;
643 564 : move16();
644 : }
645 : /* off whitening detectded */
646 : ELSE
647 : {
648 317 : IF( n_noise_bands_off != 0 )
649 : {
650 315 : IGF_replaceTCXNoise_2( hPrivateData->pSpecFlat,
651 : TCXNoise,
652 : minSrcSubband,
653 : startLine,
654 : totalNoiseNrg_off,
655 315 : hPrivateData->headroom_TCX_noise,
656 : hInfo->nfSeed );
657 : }
658 : /* selected source spectrum is pSpecFlat, pSpecFlat contains the signal before the LPC reshaping */
659 317 : sel_spec = src_spec;
660 317 : move16();
661 :
662 : /* set exponent of the current tile */
663 317 : igf_spec_e[tile_idx] = src_spec_e;
664 317 : move16();
665 : }
666 : /* generate the raw IGF spectrum out if the selected spectrum */
667 6193 : FOR( sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++ )
668 : {
669 133166 : FOR( tb = hGrid->swb_offset[sfb]; tb < hGrid->swb_offset[sfb + 1]; tb++ )
670 : {
671 127854 : igf_spec[tb] = sel_spec[strt_cpy]; // Q31 - igf_spec_e
672 127854 : move32();
673 127854 : strt_cpy = add( strt_cpy, 1 );
674 : }
675 : }
676 : }
677 : }
678 646 : }
679 :
680 : /**********************************************************************/ /*
681 : prepare IGF spectrum (for IVAS)
682 : **************************************************************************/
683 398766 : static void IGF_prep_ivas( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in: | IGF private data handle */
684 : const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */
685 : const Word16 *TCXNoise, /**< in: Q0 | TCX noise vector */
686 : Word32 *igf_spec, /**< in/out: | prepared IGF spectrum */
687 : Word16 *igf_spec_e, /**< in/out: | array exponents of igf_spec, one exponent per tile */
688 : Word32 *src_spec, /**< in/out: | source spectrum */
689 : const Word16 src_spec_e, /**< in: | exponent of src_spec, whitening off */
690 : const Word16 specMed_e, /**< in: | exponent of medium flattening level */
691 : const Word16 element_mode /**< in: | element mode */
692 : )
693 : {
694 : H_IGF_GRID hGrid;
695 : H_IGF_INFO hInfo;
696 : Word16 i;
697 : Word16 tb;
698 : Word16 sfb;
699 : Word16 nTiles;
700 : Word16 n_noise_bands;
701 : Word16 n_noise_bands_off;
702 : Word16 strt_cpy;
703 : Word16 startLine;
704 : Word16 minSrcSubband;
705 : Word16 tile_idx;
706 : Word32 totalNoiseNrg;
707 : Word32 totalNoiseNrg_off;
708 : Word16 totalNoiseNrg_exp;
709 : Word16 totalNoiseNrg_off_exp;
710 : const Word32 *sel_spec;
711 :
712 : /* initialize variables */
713 398766 : hInfo = &hPrivateData->igfInfo;
714 398766 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
715 398766 : n_noise_bands = hPrivateData->n_noise_bands;
716 398766 : move16();
717 398766 : n_noise_bands_off = hPrivateData->n_noise_bands_off;
718 398766 : move16();
719 398766 : totalNoiseNrg = hPrivateData->totalNoiseNrg;
720 398766 : move32();
721 398766 : totalNoiseNrg_off = hPrivateData->totalNoiseNrg_off;
722 398766 : move32();
723 398766 : totalNoiseNrg_exp = hPrivateData->totalNoiseNrg_exp;
724 398766 : move16();
725 398766 : totalNoiseNrg_off_exp = hPrivateData->totalNoiseNrg_off_exp;
726 398766 : move16();
727 398766 : nTiles = hGrid->nTiles;
728 398766 : move16();
729 398766 : startLine = hGrid->startLine;
730 398766 : move16();
731 398766 : minSrcSubband = hGrid->minSrcSubband;
732 398766 : move16();
733 398766 : tile_idx = 0;
734 398766 : move16();
735 :
736 1769360 : FOR( tile_idx = 0; tile_idx < nTiles; tile_idx++ )
737 : {
738 : Word16 tile_width, stop;
739 :
740 1370594 : strt_cpy = hGrid->sbWrap[tile_idx];
741 1370594 : move16();
742 :
743 1370594 : IF( element_mode > EVS_MONO )
744 : {
745 1370594 : tile_width = sub( hGrid->swb_offset[hGrid->sfbWrap[tile_idx + 1]], hGrid->swb_offset[hGrid->sfbWrap[tile_idx]] ); // Q0
746 1370594 : stop = add( strt_cpy, tile_width ); // Q0
747 : }
748 : ELSE
749 : {
750 0 : stop = hGrid->startLine; // Q0
751 0 : move16();
752 : }
753 :
754 : /* strong whitening detected */
755 1370594 : IF( EQ_16( IGF_WHITENING_STRONG, hPrivateData->currWhiteningLevel[tile_idx] ) )
756 : {
757 : Word32 abs_sum;
758 377884 : abs_sum = 0;
759 377884 : move32();
760 :
761 39873050 : FOR( i = strt_cpy; i < stop; i++ )
762 : {
763 39495166 : abs_sum = L_add_sat( abs_sum, L_abs( src_spec[i] ) ); /* saturation since it just checks if abs_sum is greater than zero*/ // Q31 - src_spec_e
764 : }
765 :
766 : /* fill igf_spec with random noise */
767 377884 : tb = hGrid->swb_offset[hGrid->sfbWrap[tile_idx]]; // Q0
768 377884 : move16();
769 :
770 377884 : IF( abs_sum != 0 )
771 : {
772 39744265 : FOR( i = strt_cpy; i < stop; i++ )
773 : {
774 39368144 : igf_spec[tb++] = L_deposit_l( Random( hInfo->nfSeed ) ); /* 31Q0, fill LSBs */ // Q0
775 39368144 : move32();
776 : }
777 : }
778 : ELSE
779 : {
780 128785 : FOR( i = strt_cpy; i < stop; i++ )
781 : {
782 127022 : igf_spec[tb++] = 0; // Q0
783 127022 : move32();
784 : }
785 : }
786 :
787 : /* set exponent of the current tile, random noise is 31Q0 */
788 377884 : igf_spec_e[tile_idx] = 31;
789 377884 : move16();
790 : }
791 : ELSE
792 : {
793 : /* medium whitening detected */
794 992710 : IF( EQ_16( IGF_WHITENING_MID, hPrivateData->currWhiteningLevel[tile_idx] ) )
795 : {
796 429745 : IF( element_mode > EVS_MONO )
797 : {
798 429745 : IF( n_noise_bands != 0 )
799 : {
800 415145 : IGF_replaceTCXNoise_2_new_ivas( igf_spec,
801 : specMed_e,
802 : TCXNoise,
803 : strt_cpy,
804 : stop,
805 : totalNoiseNrg,
806 : totalNoiseNrg_exp,
807 415145 : hPrivateData->n_noise_bands,
808 : hInfo->nfSeed );
809 : }
810 : }
811 : ELSE
812 : {
813 0 : IF( n_noise_bands != 0 )
814 : {
815 0 : IGF_replaceTCXNoise_2( igf_spec,
816 : TCXNoise,
817 : minSrcSubband,
818 : startLine,
819 : totalNoiseNrg,
820 0 : hPrivateData->headroom_TCX_noise_white,
821 : hInfo->nfSeed );
822 : }
823 : }
824 :
825 : /* selected source spectrum is igf_spec, igf_spec contains the whitened signal in the core region */
826 429745 : sel_spec = igf_spec;
827 429745 : move16();
828 :
829 : /* set exponent of the current tile */
830 429745 : igf_spec_e[tile_idx] = specMed_e;
831 429745 : move16();
832 : }
833 : /* off whitening detectded */
834 : ELSE
835 : {
836 :
837 562965 : IF( GT_16( element_mode, EVS_MONO ) )
838 : {
839 562965 : IF( n_noise_bands_off != 0 )
840 : {
841 553151 : IGF_replaceTCXNoise_2_new_ivas( src_spec,
842 : src_spec_e,
843 : TCXNoise,
844 : strt_cpy,
845 : stop,
846 : totalNoiseNrg_off,
847 : totalNoiseNrg_off_exp,
848 553151 : hPrivateData->n_noise_bands_off,
849 : hInfo->nfSeed );
850 : }
851 : }
852 : ELSE
853 : {
854 0 : IF( n_noise_bands_off != 0 )
855 : {
856 0 : IGF_replaceTCXNoise_2( src_spec,
857 : TCXNoise,
858 : minSrcSubband,
859 : startLine,
860 : totalNoiseNrg_off,
861 0 : hPrivateData->headroom_TCX_noise,
862 : hInfo->nfSeed );
863 : }
864 : }
865 : /* selected source spectrum is pSpecFlat, pSpecFlat contains the signal before the LPC reshaping */
866 562965 : sel_spec = src_spec;
867 562965 : move16();
868 :
869 : /* set exponent of the current tile */
870 562965 : igf_spec_e[tile_idx] = src_spec_e;
871 562965 : move16();
872 : }
873 : /* generate the raw IGF spectrum out if the selected spectrum */
874 3609542 : FOR( sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++ )
875 : {
876 81041198 : FOR( tb = hGrid->swb_offset[sfb]; tb < hGrid->swb_offset[sfb + 1]; tb++ )
877 : {
878 78424366 : igf_spec[tb] = sel_spec[strt_cpy]; // Q31 - igf_spec_e
879 78424366 : move32();
880 78424366 : strt_cpy = add( strt_cpy, 1 );
881 : }
882 : }
883 : }
884 : }
885 398766 : }
886 :
887 :
888 : /**********************************************************************/ /*
889 : prepare IGF spectrum in stereo
890 : **************************************************************************/
891 86759 : static void IGF_prepStereo(
892 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateDataL, /* i : IGF private data handle */
893 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateDataR, /* i : IGF private data handle */
894 : const Word16 igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength Q0 */
895 : const Word16 *TCXNoiseL, /* i : left TCX noise vector Q0 */
896 : const Word16 *TCXNoiseR, /* i : right TCX noise vector Q0 */
897 : Word32 *igf_specL_fx, /* i/o: prepared left IGF spectrum */
898 : Word16 *igf_specL_e_arr, /* i/o: prepared left IGF spectrum exponents for each index */
899 : Word32 *igf_specR_fx, /* i/o: prepared right IGF spectrum */
900 : Word16 *igf_specR_e_arr, /* i/o: prepared right IGF spectrum exponents for each index */
901 : Word32 *src_specL_fx, /* i : left source spectrum */
902 : const Word16 src_specL_e, /* i : left source spectrum exp */
903 : Word32 *src_specR_fx, /* i : right source spectrum */
904 : const Word16 src_specR_e, /* i : right source spectrum exp */
905 : const Word16 *coreMsMask /* i : line wise ms Mask Q0 */
906 : )
907 : {
908 : H_IGF_GRID hGrid;
909 : H_IGF_INFO hInfoL, hInfoR;
910 : Word16 tb, sfb, strt_cpy, tile_idx;
911 : Word16 *swb_offset;
912 86759 : const Word32 c_fx = SQRT2_OVER_2_FIXED; // Q31
913 86759 : Word16 selectionL = 0; // 0 -> IGF, 1 -> pSpecFlat
914 86759 : Word16 selectionR = 0; // 0 -> IGF, 1 -> pSpecFlat
915 86759 : move32();
916 86759 : move16();
917 86759 : move16();
918 :
919 86759 : hInfoL = &hPrivateDataL->igfInfo;
920 86759 : hInfoR = &hPrivateDataR->igfInfo;
921 86759 : hGrid = &hPrivateDataL->igfInfo.grid[igfGridIdx];
922 86759 : swb_offset = hGrid->swb_offset;
923 86759 : move16();
924 :
925 366406 : FOR( tile_idx = 0; tile_idx < hGrid->nTiles; tile_idx++ )
926 : {
927 : Word16 tile_width, stop;
928 279647 : strt_cpy = hGrid->sbWrap[tile_idx];
929 279647 : move16();
930 :
931 279647 : tile_width = sub( swb_offset[hGrid->sfbWrap[tile_idx + 1]], swb_offset[hGrid->sfbWrap[tile_idx]] );
932 279647 : stop = add( strt_cpy, tile_width );
933 :
934 279647 : IF( EQ_16( IGF_WHITENING_STRONG, hPrivateDataL->currWhiteningLevel[tile_idx] ) )
935 : {
936 55932 : tb = swb_offset[hGrid->sfbWrap[tile_idx]];
937 55932 : move16();
938 :
939 5341592 : FOR( tb = swb_offset[hGrid->sfbWrap[tile_idx]]; tb < swb_offset[hGrid->sfbWrap[tile_idx + 1]]; tb++ )
940 : {
941 5285660 : igf_specL_fx[tb] = L_deposit_l( Random( hInfoL->nfSeed ) ); /* 31Q0, fill LSBs */ // Q0
942 5285660 : move32();
943 5285660 : igf_specL_e_arr[tb] = 31;
944 5285660 : move16();
945 : }
946 : }
947 : ELSE
948 : {
949 223715 : IF( EQ_16( IGF_WHITENING_MID, hPrivateDataL->currWhiteningLevel[tile_idx] ) )
950 : {
951 79632 : IF( hPrivateDataL->n_noise_bands )
952 : {
953 79425 : IGF_replaceTCXNoise_2_new_ivas_with_var_shift( igf_specL_fx,
954 : igf_specL_e_arr,
955 : TCXNoiseL,
956 : strt_cpy,
957 : stop,
958 : hPrivateDataL->totalNoiseNrg,
959 79425 : hPrivateDataL->totalNoiseNrg_exp,
960 79425 : hPrivateDataL->n_noise_bands,
961 : hInfoL->nfSeed );
962 : }
963 79632 : selectionL = 0;
964 79632 : move16();
965 : }
966 : ELSE
967 : {
968 144083 : IF( hPrivateDataL->n_noise_bands_off )
969 : {
970 141560 : IGF_replaceTCXNoise_2_new_ivas( src_specL_fx,
971 : src_specL_e,
972 : TCXNoiseL,
973 : strt_cpy,
974 : stop,
975 : hPrivateDataL->totalNoiseNrg_off,
976 141560 : hPrivateDataL->totalNoiseNrg_off_exp,
977 141560 : hPrivateDataL->n_noise_bands_off,
978 : hInfoL->nfSeed );
979 : }
980 144083 : selectionL = 1;
981 144083 : move16();
982 : }
983 :
984 223715 : IF( EQ_16( IGF_WHITENING_MID, hPrivateDataL->currWhiteningLevel[tile_idx] ) )
985 : {
986 79632 : IF( hPrivateDataR->n_noise_bands )
987 : {
988 78270 : IGF_replaceTCXNoise_2_new_ivas_with_var_shift( igf_specR_fx,
989 : igf_specR_e_arr,
990 : TCXNoiseR,
991 : strt_cpy,
992 : stop,
993 : hPrivateDataR->totalNoiseNrg,
994 78270 : hPrivateDataR->totalNoiseNrg_exp,
995 78270 : hPrivateDataR->n_noise_bands,
996 : hInfoR->nfSeed );
997 : }
998 79632 : selectionR = 0;
999 79632 : move16();
1000 : }
1001 : ELSE
1002 : {
1003 144083 : IF( hPrivateDataR->n_noise_bands_off )
1004 : {
1005 137046 : IGF_replaceTCXNoise_2_new_ivas( src_specR_fx,
1006 : src_specR_e,
1007 : TCXNoiseR,
1008 : strt_cpy,
1009 : stop,
1010 : hPrivateDataR->totalNoiseNrg_off,
1011 137046 : hPrivateDataR->totalNoiseNrg_off_exp,
1012 137046 : hPrivateDataR->n_noise_bands_off,
1013 : hInfoR->nfSeed );
1014 : }
1015 144083 : selectionR = 1;
1016 144083 : move16();
1017 : }
1018 :
1019 840053 : FOR( sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++ )
1020 : {
1021 19193810 : FOR( tb = swb_offset[sfb]; tb < swb_offset[sfb + 1]; tb++ )
1022 : {
1023 : Word16 tmp_e;
1024 : Word32 tmpL, tmpR;
1025 : Word32 selL, selR;
1026 : Word16 selL_e, selR_e;
1027 :
1028 18577472 : selL = igf_specL_fx[strt_cpy];
1029 18577472 : move32();
1030 18577472 : selL_e = igf_specL_e_arr[strt_cpy];
1031 18577472 : move16();
1032 18577472 : selR = igf_specR_fx[strt_cpy];
1033 18577472 : move32();
1034 18577472 : selR_e = igf_specR_e_arr[strt_cpy];
1035 18577472 : move16();
1036 18577472 : IF( selectionL )
1037 : {
1038 10568348 : selL = src_specL_fx[strt_cpy];
1039 10568348 : move32();
1040 10568348 : selL_e = src_specL_e;
1041 10568348 : move16();
1042 : }
1043 18577472 : IF( selectionR )
1044 : {
1045 10568348 : selR = src_specR_fx[strt_cpy];
1046 10568348 : move32();
1047 10568348 : selR_e = src_specR_e;
1048 10568348 : move16();
1049 : }
1050 :
1051 18577472 : IF( EQ_16( coreMsMask[tb], 0 ) )
1052 : {
1053 7328292 : IF( EQ_16( coreMsMask[strt_cpy], 0 ) ) /* LR->LR */
1054 : {
1055 2222198 : igf_specL_fx[tb] = selL;
1056 2222198 : move32();
1057 2222198 : igf_specL_e_arr[tb] = selL_e;
1058 2222198 : move16();
1059 : }
1060 : ELSE /* MS/DR -> LR */
1061 : {
1062 5106094 : tmpL = Mpy_32_32( selL, c_fx ); // Q31 - selL_e
1063 5106094 : tmpR = Mpy_32_32( selR, c_fx ); // Q31 - selR_e
1064 5106094 : igf_specL_fx[tb] = BASOP_Util_Add_Mant32Exp( tmpL, selL_e, tmpR, selR_e, &tmp_e );
1065 5106094 : move32();
1066 5106094 : igf_specL_e_arr[tb] = tmp_e;
1067 5106094 : move16();
1068 : }
1069 : }
1070 : ELSE
1071 : {
1072 11249180 : IF( EQ_16( coreMsMask[strt_cpy], 0 ) ) /* LR->MS/DR */
1073 : {
1074 279106 : tmpL = Mpy_32_32( selL, c_fx ); // Q31 - selL_e
1075 279106 : tmpR = Mpy_32_32( selR, c_fx ); // Q31 - selR_e
1076 279106 : igf_specL_fx[tb] = BASOP_Util_Add_Mant32Exp( tmpL, selL_e, tmpR, selR_e, &tmp_e );
1077 279106 : move32();
1078 279106 : igf_specL_e_arr[tb] = tmp_e;
1079 279106 : move16();
1080 : }
1081 : ELSE /* MS/DR -> MS/DR */
1082 : {
1083 10970074 : igf_specL_fx[tb] = selL;
1084 10970074 : move32();
1085 10970074 : igf_specL_e_arr[tb] = selL_e;
1086 10970074 : move16();
1087 : }
1088 : }
1089 18577472 : strt_cpy = add( strt_cpy, 1 );
1090 : }
1091 : }
1092 : }
1093 :
1094 279647 : strt_cpy = hGrid->sbWrap[tile_idx];
1095 279647 : move16();
1096 :
1097 279647 : IF( EQ_16( IGF_WHITENING_STRONG, hPrivateDataR->currWhiteningLevel[tile_idx] ) )
1098 : {
1099 52783 : tb = swb_offset[hGrid->sfbWrap[tile_idx]];
1100 52783 : move16();
1101 :
1102 5426323 : FOR( tb = swb_offset[hGrid->sfbWrap[tile_idx]]; tb < swb_offset[hGrid->sfbWrap[tile_idx + 1]]; tb++ )
1103 : {
1104 5373540 : igf_specR_fx[tb] = L_deposit_l( Random( hInfoR->nfSeed ) ); /* 31Q0, fill LSBs */ // Q0
1105 5373540 : move32();
1106 5373540 : igf_specR_e_arr[tb] = 31;
1107 5373540 : move16();
1108 : }
1109 : }
1110 : ELSE
1111 : {
1112 226864 : IF( NE_16( hPrivateDataR->currWhiteningLevel[tile_idx], hPrivateDataL->currWhiteningLevel[tile_idx] ) )
1113 : {
1114 59514 : IF( EQ_16( IGF_WHITENING_MID, hPrivateDataR->currWhiteningLevel[tile_idx] ) )
1115 : {
1116 30757 : IF( hPrivateDataL->n_noise_bands )
1117 : {
1118 30653 : IGF_replaceTCXNoise_2_new_ivas_with_var_shift( igf_specL_fx,
1119 : igf_specL_e_arr,
1120 : TCXNoiseL,
1121 : strt_cpy,
1122 : stop,
1123 : hPrivateDataL->totalNoiseNrg,
1124 30653 : hPrivateDataL->totalNoiseNrg_exp,
1125 30653 : hPrivateDataL->n_noise_bands,
1126 : hInfoL->nfSeed );
1127 : }
1128 30757 : selectionL = 0;
1129 30757 : move16();
1130 : }
1131 : ELSE
1132 : {
1133 28757 : IF( hPrivateDataL->n_noise_bands_off )
1134 : {
1135 28644 : IGF_replaceTCXNoise_2_new_ivas( src_specL_fx,
1136 : src_specL_e,
1137 : TCXNoiseL,
1138 : strt_cpy,
1139 : stop,
1140 : hPrivateDataL->totalNoiseNrg_off,
1141 28644 : hPrivateDataL->totalNoiseNrg_off_exp,
1142 28644 : hPrivateDataL->n_noise_bands_off,
1143 : hInfoL->nfSeed );
1144 : }
1145 28757 : selectionL = 1;
1146 28757 : move16();
1147 : }
1148 :
1149 59514 : IF( EQ_16( IGF_WHITENING_MID, hPrivateDataR->currWhiteningLevel[tile_idx] ) )
1150 : {
1151 30757 : IF( hPrivateDataR->n_noise_bands )
1152 : {
1153 30356 : IGF_replaceTCXNoise_2_new_ivas_with_var_shift( igf_specR_fx,
1154 : igf_specR_e_arr,
1155 : TCXNoiseR,
1156 : strt_cpy,
1157 : stop,
1158 : hPrivateDataR->totalNoiseNrg,
1159 30356 : hPrivateDataR->totalNoiseNrg_exp,
1160 30356 : hPrivateDataR->n_noise_bands,
1161 : hInfoR->nfSeed );
1162 : }
1163 30757 : selectionR = 0;
1164 30757 : move16();
1165 : }
1166 : ELSE
1167 : {
1168 28757 : IF( hPrivateDataR->n_noise_bands_off )
1169 : {
1170 28053 : IGF_replaceTCXNoise_2_new_ivas( src_specR_fx,
1171 : src_specR_e,
1172 : TCXNoiseR,
1173 : strt_cpy,
1174 : stop,
1175 : hPrivateDataR->totalNoiseNrg_off,
1176 28053 : hPrivateDataR->totalNoiseNrg_off_exp,
1177 28053 : hPrivateDataR->n_noise_bands_off,
1178 : hInfoR->nfSeed );
1179 : }
1180 28757 : selectionR = 1;
1181 28757 : move16();
1182 : }
1183 : }
1184 :
1185 855411 : FOR( sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++ )
1186 : {
1187 19118139 : FOR( tb = swb_offset[sfb]; tb < swb_offset[sfb + 1]; tb++ )
1188 : {
1189 : Word32 tmpL, tmpR;
1190 : Word16 tmp_e;
1191 : Word32 selL, selR;
1192 : Word16 selL_e, selR_e;
1193 :
1194 18489592 : selL = igf_specL_fx[strt_cpy];
1195 18489592 : move32();
1196 18489592 : selL_e = igf_specL_e_arr[strt_cpy];
1197 18489592 : move16();
1198 18489592 : selR = igf_specR_fx[strt_cpy];
1199 18489592 : move32();
1200 18489592 : selR_e = igf_specR_e_arr[strt_cpy];
1201 18489592 : move16();
1202 18489592 : IF( selectionL )
1203 : {
1204 10803580 : selL = src_specL_fx[strt_cpy];
1205 10803580 : move32();
1206 10803580 : selL_e = src_specL_e;
1207 10803580 : move16();
1208 : }
1209 18489592 : IF( selectionR )
1210 : {
1211 10803580 : selR = src_specR_fx[strt_cpy];
1212 10803580 : move32();
1213 10803580 : selR_e = src_specR_e;
1214 10803580 : move16();
1215 : }
1216 :
1217 18489592 : IF( ( coreMsMask[tb] == 0 ) )
1218 : {
1219 7252788 : IF( EQ_16( coreMsMask[strt_cpy], 0 ) ) /* LR->LR */
1220 : {
1221 2207488 : igf_specR_fx[tb] = selR;
1222 2207488 : move32();
1223 2207488 : igf_specR_e_arr[tb] = selR_e;
1224 2207488 : move16();
1225 : }
1226 : ELSE /* MS/DR -> LR */
1227 : {
1228 5045300 : tmpL = Mpy_32_32( selL, c_fx ); // Q31 - selL_e
1229 5045300 : tmpR = Mpy_32_32( selR, c_fx ); // Q31 - selR_e
1230 5045300 : igf_specR_fx[tb] = BASOP_Util_Add_Mant32Exp( tmpL, selL_e, L_negate( tmpR ), selR_e, &tmp_e );
1231 5045300 : move32();
1232 5045300 : igf_specR_e_arr[tb] = tmp_e;
1233 5045300 : move16();
1234 : }
1235 : }
1236 : ELSE
1237 : {
1238 11236804 : IF( EQ_16( coreMsMask[strt_cpy], 0 ) ) /* LR->MS/DR */
1239 : {
1240 277476 : tmpL = Mpy_32_32( selL, c_fx ); // Q31 - selL_e
1241 277476 : tmpR = Mpy_32_32( selR, c_fx ); // Q31 - selR_e
1242 277476 : igf_specR_fx[tb] = BASOP_Util_Add_Mant32Exp( tmpL, selL_e, L_negate( tmpR ), selR_e, &tmp_e );
1243 277476 : move32();
1244 277476 : igf_specR_e_arr[tb] = tmp_e;
1245 277476 : move16();
1246 : }
1247 : ELSE /* MS/DR -> MS/DR */
1248 : {
1249 10959328 : igf_specR_fx[tb] = selR;
1250 10959328 : move32();
1251 10959328 : igf_specR_e_arr[tb] = selR_e;
1252 10959328 : move16();
1253 : }
1254 : }
1255 18489592 : strt_cpy = add( strt_cpy, 1 );
1256 : }
1257 : }
1258 : }
1259 : }
1260 :
1261 86759 : return;
1262 : }
1263 :
1264 : /**********************************************************************/ /*
1265 : calculates IGF energies
1266 : **************************************************************************/
1267 646 : static void IGF_calc( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in: | IGF private data handle */
1268 : const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */
1269 : const Word32 *spectrum, /**< in: Q31 | MDCT spectrum */
1270 : const Word16 spectrum_e, /**< in: | exponent of pSpectralData */
1271 : Word32 *igf_spec, /**< in: Q31 | prepared IGF spectrum */
1272 : Word16 *igf_spec_e /**< in: | array exponents of igf_spec, one exponent per tile */
1273 : )
1274 : {
1275 : H_IGF_GRID hGrid;
1276 : Word16 i;
1277 : Word32 *igf_pN; /* Q31 | processed energy */
1278 : Word16 *igf_pN_e; /* | exponents of igf_pN, one for each entry of igf_pN */
1279 : Word32 *igf_sN; /* Q31 | survived energy */
1280 : Word16 *igf_sN_e; /* | exponents of igf_sN, one for each entry of igf_sN */
1281 : Word32 squaredSpectra[IGF_MAX_GRANULE_LEN]; /* Q31 | MDCT^2 spectra */
1282 : Word16 squaredSpectra_e[IGF_MAX_TILES]; /* | exponents of squaredSpectra, one exponent per tile! */
1283 :
1284 :
1285 : /* initialize variables */
1286 646 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
1287 646 : igf_pN = hPrivateData->igf_pN;
1288 646 : igf_pN_e = hPrivateData->igf_pN_e;
1289 646 : igf_sN = hPrivateData->igf_sN;
1290 646 : igf_sN_e = hPrivateData->igf_sN_e;
1291 :
1292 646 : set32_fx( squaredSpectra, 0, IGF_MAX_GRANULE_LEN );
1293 646 : set16_fx( squaredSpectra_e, 0, IGF_MAX_TILES );
1294 :
1295 : /* square the original spectrum */
1296 646 : IGFCommonFuncsMDCTSquareSpec( hGrid->startLine,
1297 646 : hGrid->stopLine,
1298 : spectrum,
1299 : spectrum_e,
1300 : squaredSpectra,
1301 : squaredSpectra_e,
1302 : 0 );
1303 :
1304 : /* calculate the energy per SFB of the survied subbands */
1305 646 : IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->startSfb,
1306 646 : hGrid->stopSfb,
1307 646 : hGrid->swb_offset,
1308 : squaredSpectra,
1309 : squaredSpectra_e,
1310 : igf_sN,
1311 : igf_sN_e );
1312 :
1313 : /* loop over tiles, every tile has his own exponent! */
1314 2309 : FOR( i = 0; i < hGrid->nTiles; i++ )
1315 : {
1316 : /* square the prepared IGF spectrum */
1317 1663 : IGFCommonFuncsMDCTSquareSpec( hGrid->tile[i],
1318 1663 : hGrid->tile[i + 1],
1319 : igf_spec,
1320 1663 : igf_spec_e[i],
1321 : squaredSpectra,
1322 1663 : &squaredSpectra_e[i],
1323 : 0 );
1324 :
1325 : /* set all squared values to 0, if the core contains survied lines */
1326 1663 : IGF_setLinesToZero( hGrid->tile[i],
1327 1663 : hGrid->tile[i + 1],
1328 : spectrum,
1329 : squaredSpectra );
1330 :
1331 : /* calculate the energy per SFB of the processed subbands */
1332 1663 : IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->sfbWrap[i],
1333 1663 : hGrid->sfbWrap[i + 1],
1334 1663 : hGrid->swb_offset,
1335 : squaredSpectra,
1336 1663 : &squaredSpectra_e[i],
1337 : igf_pN,
1338 : igf_pN_e );
1339 : }
1340 646 : }
1341 :
1342 :
1343 : /**********************************************************************/ /*
1344 : calculates IGF energies (for IVAS)
1345 : **************************************************************************/
1346 572284 : static void IGF_calc_ivas( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in: | IGF private data handle */
1347 : const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */
1348 : const Word32 *spectrum, /**< in: Q31 | MDCT spectrum */
1349 : const Word16 spectrum_e, /**< in: | exponent of pSpectralData */
1350 : Word32 *igf_spec, /**< in: Q31 | prepared IGF spectrum */
1351 : Word16 *igf_spec_e /**< in: | array exponents of igf_spec, one exponent per tile */
1352 : )
1353 : {
1354 : H_IGF_GRID hGrid;
1355 : Word16 i;
1356 : Word32 *igf_pN; /* Q31 | processed energy */
1357 : Word16 *igf_pN_e; /* | exponents of igf_pN, one for each entry of igf_pN */
1358 : Word32 *igf_sN; /* Q31 | survived energy */
1359 : Word16 *igf_sN_e; /* | exponents of igf_sN, one for each entry of igf_sN */
1360 : Word32 squaredSpectra[IGF_MAX_GRANULE_LEN]; /* Q31 | MDCT^2 spectra */
1361 : Word16 squaredSpectra_e[IGF_MAX_TILES]; /* | exponents of squaredSpectra, one exponent per tile! */
1362 :
1363 :
1364 : /* initialize variables */
1365 572284 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
1366 572284 : igf_pN = hPrivateData->igf_pN;
1367 572284 : igf_pN_e = hPrivateData->igf_pN_e;
1368 572284 : igf_sN = hPrivateData->igf_sN;
1369 572284 : igf_sN_e = hPrivateData->igf_sN_e;
1370 :
1371 572284 : set32_fx( squaredSpectra, 0, IGF_MAX_GRANULE_LEN );
1372 572284 : set16_fx( squaredSpectra_e, 0, IGF_MAX_TILES );
1373 :
1374 : /* square the original spectrum */
1375 572284 : IGFCommonFuncsMDCTSquareSpec_ivas( hGrid->startLine,
1376 572284 : hGrid->stopLine,
1377 : spectrum,
1378 : spectrum_e,
1379 : squaredSpectra,
1380 : squaredSpectra_e,
1381 : 0 );
1382 :
1383 : /* calculate the energy per SFB of the survied subbands */
1384 572284 : IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->startSfb,
1385 572284 : hGrid->stopSfb,
1386 572284 : hGrid->swb_offset,
1387 : squaredSpectra,
1388 : squaredSpectra_e,
1389 : igf_sN,
1390 : igf_sN_e );
1391 :
1392 : /* loop over tiles, every tile has his own exponent! */
1393 2502172 : FOR( i = 0; i < hGrid->nTiles; i++ )
1394 : {
1395 : /* square the prepared IGF spectrum */
1396 1929888 : IGFCommonFuncsMDCTSquareSpec_ivas( hGrid->tile[i],
1397 1929888 : hGrid->tile[i + 1],
1398 : igf_spec,
1399 1929888 : igf_spec_e[i],
1400 : squaredSpectra,
1401 1929888 : &squaredSpectra_e[i],
1402 : 0 );
1403 :
1404 : /* set all squared values to 0, if the core contains survied lines */
1405 1929888 : IGF_setLinesToZero( hGrid->tile[i],
1406 1929888 : hGrid->tile[i + 1],
1407 : spectrum,
1408 : squaredSpectra );
1409 :
1410 : /* calculate the energy per SFB of the processed subbands */
1411 1929888 : IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->sfbWrap[i],
1412 1929888 : hGrid->sfbWrap[i + 1],
1413 1929888 : hGrid->swb_offset,
1414 : squaredSpectra,
1415 1929888 : &squaredSpectra_e[i],
1416 : igf_pN,
1417 : igf_pN_e );
1418 : }
1419 572284 : }
1420 :
1421 : /**********************************************************************/ /*
1422 : apply IGF
1423 : **************************************************************************/
1424 646 : static void IGF_appl( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in: | IGF private data handle */
1425 : const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */
1426 : Word32 *spectrum, /**< in: Q31 | MDCT spectrum */
1427 : Word16 *spectrum_e, /**< in: | exponent of pSpectralData */
1428 : const Word32 *igf_spec, /**< in: Q31 | prepared IGF spectrum */
1429 : const Word16 *igf_spec_e, /**< in: | array exponents of igf_spec, one exponent per tile */
1430 : Word32 *virtualSpec, /**< out:Q31 | virtual IGF spectrum, used for temp flattening */
1431 : Word16 *virtualSpec_e, /**< out: | exponent of virtualSpec */
1432 : Word16 *flag_sparse /**< out: Q0 | temp flattening indicator */
1433 : )
1434 : {
1435 : H_IGF_GRID hGrid;
1436 : Word16 i;
1437 : Word16 tb;
1438 : Word16 sfb;
1439 : Word16 shift;
1440 : Word16 s;
1441 : Word16 s_sfb;
1442 : Word16 start_sfb;
1443 : Word16 stop_sfb;
1444 : Word16 sfb_p1;
1445 : Word16 sfb_m1;
1446 : Word16 hopsize;
1447 : Word16 sum;
1448 : Word16 tileIdx;
1449 : Word16 width; /* Q0 | width of the current sfb */
1450 : Word16 width_e; /* | exponent of widthent sfb, initialized as 15! */
1451 : Word16 gFactor; /* 1Q14 | general SCF adaption */
1452 : Word16 fFactor; /* 1Q14 | first SCF adaption */
1453 : Word16 lFactor; /* 1Q14 | last SCF adaption */
1454 : Word16 w0; /* Q15 | float value: 0.201f */
1455 : Word16 w1; /* Q15 | float value: 0.389f */
1456 : Word16 w2; /* Q15 | float value: 0.410f */
1457 : Word16 dE; /* Q31 | energy below igfBgn */
1458 : Word16 dE_e; /* | exponent of dE */
1459 : Word16 gn; /* Q0 | gain read from bitstream + processing */
1460 : Word16 gn_e; /* | exponent of gn */
1461 : Word16 maxGain_e; /* | maximal gain exponent over sfbs */
1462 : Word16 tmp;
1463 : Word16 tmp_e;
1464 : Word16 tmp_loop;
1465 : Word32 L_tmp;
1466 : Word16 L_tmp_e;
1467 : Word32 L_tmp2;
1468 : Word32 sNlocal;
1469 : Word16 sNlocal_e;
1470 : Word32 dNlocal;
1471 : Word16 dNlocal_e;
1472 : Word32 E;
1473 : Word16 E_e;
1474 : Word32 *sN;
1475 : Word16 *sN_e;
1476 : Word32 *pN;
1477 : Word16 *pN_e;
1478 : Word16 gain[IGF_MAX_SFB];
1479 : Word16 gain_e[IGF_MAX_SFB];
1480 : Word16 dN[IGF_MAX_SFB + 1];
1481 : Word16 dN_e[IGF_MAX_SFB + 1];
1482 : Word16 dS[IGF_MAX_SFB];
1483 : Word16 dS_e[IGF_MAX_SFB];
1484 : Word32 energyTmp[24];
1485 : Word32 L_c;
1486 : Word16 Hr;
1487 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1488 646 : Flag Overflow = 0;
1489 646 : Flag Carry = 0;
1490 646 : move16();
1491 646 : move16();
1492 : #endif
1493 :
1494 :
1495 : /* initialize variables */
1496 646 : w0 = 6586; // Q15
1497 646 : move16();
1498 646 : w1 = 12747; // Q15
1499 646 : move16();
1500 646 : w2 = 13435; // Q15
1501 646 : move16();
1502 646 : dE = 0;
1503 646 : move16();
1504 646 : dE_e = 0;
1505 646 : move16();
1506 646 : tmp = 0;
1507 646 : move16();
1508 646 : s = 0;
1509 646 : move16();
1510 646 : tmp_e = 0;
1511 646 : move16();
1512 646 : gn = 0;
1513 646 : move16();
1514 646 : gn_e = 0;
1515 646 : move16();
1516 646 : maxGain_e = 0;
1517 646 : move16();
1518 646 : L_tmp_e = 0;
1519 646 : move16();
1520 646 : dNlocal_e = 0;
1521 646 : move16();
1522 646 : L_tmp = 0;
1523 646 : move32();
1524 646 : dNlocal = 0;
1525 646 : move32();
1526 :
1527 646 : set16_fx( gain, 0, IGF_MAX_SFB );
1528 646 : set16_fx( gain_e, 0, IGF_MAX_SFB );
1529 646 : set16_fx( dN, 0, add( IGF_MAX_SFB, 1 ) );
1530 646 : set16_fx( dN_e, 0, add( IGF_MAX_SFB, 1 ) );
1531 646 : set16_fx( dS, 0, IGF_MAX_SFB );
1532 646 : set16_fx( dS_e, 0, IGF_MAX_SFB );
1533 646 : set32_fx( energyTmp, 0, 24 );
1534 :
1535 : /* more inits */
1536 646 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
1537 646 : sN = hPrivateData->igf_sN;
1538 646 : sN_e = hPrivateData->igf_sN_e;
1539 646 : pN = hPrivateData->igf_pN;
1540 646 : pN_e = hPrivateData->igf_pN_e;
1541 646 : start_sfb = hGrid->startSfb;
1542 646 : move16();
1543 646 : stop_sfb = hGrid->stopSfb;
1544 646 : move16();
1545 646 : gFactor = hGrid->gFactor;
1546 646 : move16();
1547 646 : fFactor = hGrid->fFactor;
1548 646 : move16();
1549 646 : lFactor = hGrid->lFactor;
1550 646 : move16();
1551 :
1552 : /* reset virtual spec */
1553 646 : set16_fx( flag_sparse, 0, N_MAX_TCX - IGF_START_MN );
1554 646 : set32_fx( virtualSpec, 0, N_MAX_TCX - IGF_START_MN );
1555 646 : *virtualSpec_e = *spectrum_e;
1556 646 : move16();
1557 :
1558 : /* collect energy below hGrid->startLine: */
1559 646 : tmp = sub( hGrid->startLine, 24 );
1560 646 : IGFCommonFuncsMDCTSquareSpec( tmp,
1561 646 : hGrid->startLine,
1562 : spectrum,
1563 646 : *spectrum_e,
1564 : energyTmp,
1565 : &dE_e,
1566 646 : negate( tmp ) );
1567 :
1568 646 : L_c = 0;
1569 646 : move32();
1570 16150 : FOR( tb = 0; tb < 24; tb++ )
1571 : {
1572 15504 : Carry = 0;
1573 15504 : move16();
1574 15504 : L_tmp = L_add_co( L_tmp, energyTmp[tb], &Carry, &Overflow ); // Q31 - dE_e
1575 15504 : Overflow = 0;
1576 15504 : move16();
1577 15504 : L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow );
1578 : }
1579 646 : L_tmp = norm_llQ31( L_c, L_tmp, &shift ); // Q31
1580 : /* float: dE = (float)sqrt(dE / 24.f); basop: */
1581 646 : shift = add( sub( shift, 4 ), dE_e ); /* x/24 = (x >> 4) * 1/1.5 */
1582 646 : dE = Sqrt16norm( extract_h( L_tmp ), &shift );
1583 646 : dE = mult_r( dE, 26755 /*0.81649658092772603273242802490196f Q15*/ ); /* 0.81649658092772603273242802490196f = sqrt(1/1.5)) */
1584 646 : dE_e = shift;
1585 646 : move16();
1586 :
1587 : /* select correct hopsize for envelope refinement */
1588 646 : hopsize = 2;
1589 646 : move16();
1590 646 : if ( EQ_16( hPrivateData->currWhiteningLevel[0], IGF_WHITENING_OFF ) )
1591 : {
1592 141 : hopsize = 4;
1593 141 : move16();
1594 : }
1595 646 : if ( EQ_16( hPrivateData->currWhiteningLevel[0], IGF_WHITENING_STRONG ) )
1596 : {
1597 199 : hopsize = 1;
1598 199 : move16();
1599 : }
1600 646 : hopsize = s_min( hopsize, hPrivateData->igfInfo.maxHopsize );
1601 :
1602 646 : IF( GT_16( hopsize, 1 ) )
1603 : {
1604 3136 : FOR( sfb = start_sfb; sfb < stop_sfb; sfb += hopsize )
1605 : {
1606 2689 : tmp_loop = s_min( add( sfb, hopsize ), stop_sfb );
1607 6336 : FOR( tb = sfb + 1; tb < tmp_loop; tb++ )
1608 : {
1609 7294 : sN[sfb] = BASOP_Util_Add_Mant32Exp( sN[sfb],
1610 3647 : sN_e[sfb],
1611 3647 : sN[tb],
1612 3647 : sN_e[tb],
1613 3647 : &sN_e[sfb] );
1614 3647 : move32();
1615 7294 : pN[sfb] = BASOP_Util_Add_Mant32Exp( pN[sfb],
1616 3647 : pN_e[sfb],
1617 3647 : pN[tb],
1618 3647 : pN_e[tb],
1619 3647 : &pN_e[sfb] );
1620 3647 : move32();
1621 3647 : sN[tb] = L_deposit_l( 0 );
1622 3647 : pN[tb] = L_deposit_l( 0 );
1623 : }
1624 : }
1625 : }
1626 :
1627 : /* IGF_rescale_SCF */
1628 646 : IF( hGrid->infoIsRefined != 0 )
1629 : {
1630 5264 : FOR( sfb = start_sfb; sfb < stop_sfb; sfb += 2 )
1631 : {
1632 : /* calculate and normalize the width of the current sfb */
1633 4618 : width = sub( hGrid->swb_offset[sfb + 2], hGrid->swb_offset[sfb] );
1634 4618 : shift = norm_s( width );
1635 4618 : width = shl( width, shift );
1636 4618 : width_e = sub( 15, shift ); /* initial value of width_e is 15, -> width = 15Q0 */
1637 :
1638 : /* float: gn = 0.25f * igf_curr - 4.f; basop: */
1639 4618 : gn = hPrivateData->igf_curr[sfb >> 1]; // Q15
1640 4618 : move16();
1641 4618 : move16();
1642 4618 : gn_e = 13; /* set exponent of igf_curr to 13 = 15 - 2; -> igf_curr = igf_curr * 0.25, virtual division by 4 */
1643 4618 : move16();
1644 4618 : gn = sub( gn, 16 ); /* 13Q2 | 4 = 16 * 2^(-15 + 13); ("4" has same exponent as igf_curr now) */
1645 :
1646 : /* float: tmp = pow(2.f, gn); basop: */
1647 4618 : L_tmp = BASOP_util_Pow2( L_deposit_h( gn ), gn_e, &L_tmp_e );
1648 :
1649 : /* float: tmp = tmp * tmp; basop: */
1650 4618 : tmp = round_fx( L_tmp );
1651 4618 : L_tmp = L_mult( tmp, tmp );
1652 4618 : L_tmp_e = add( L_tmp_e, L_tmp_e );
1653 :
1654 : /* get sNlocal | float: sNlocal = sN[ sfb ] + sN[ sfb+ 1 ]; basop: */
1655 4618 : sNlocal = BASOP_Util_Add_Mant32Exp( sN[sfb],
1656 4618 : sN_e[sfb],
1657 4618 : sN[sfb + 1],
1658 4618 : sN_e[sfb + 1],
1659 : &sNlocal_e );
1660 :
1661 : /* float: sNlocal /= width; basop: */
1662 4618 : shift = sub( norm_l( sNlocal ), 1 ); /* leave MSB empty, so in the division sNlocal is always smaller than width */
1663 4618 : sNlocal = L_deposit_h( div_s( extract_h( L_shl( sNlocal, shift ) ), width ) );
1664 4618 : sNlocal_e = sub( sub( sNlocal_e, shift ), width_e );
1665 :
1666 : /* float: tmp = max(0.001 * sNlocal, tmp - sNlocal); basop: */
1667 4618 : L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp,
1668 : L_tmp_e,
1669 : L_negate( sNlocal ),
1670 : sNlocal_e,
1671 : &L_tmp_e ); /* float: tmp = tmp - sNlocal */
1672 :
1673 : /* max(0.001 * sNlocal, L_tmp) */
1674 : /* Build a threshold and compare with L_tmp.
1675 : Build negated threshold and compare with negated L_tmp to cover also fullscale L_tmp case */
1676 : BASOP_SATURATE_WARNING_OFF_EVS
1677 4618 : L_tmp2 = L_shl_sat( L_negate( Mpy_32_16_1( sNlocal, 33 /*0.001f Q15*/ ) ), sub( sNlocal_e, L_tmp_e ) );
1678 4618 : L_tmp2 = L_sub_sat( L_tmp2, L_negate( L_tmp ) );
1679 : BASOP_SATURATE_WARNING_ON_EVS
1680 :
1681 4618 : IF( L_tmp2 < 0 )
1682 : {
1683 1 : L_tmp = Mpy_32_16_1( sNlocal, 33 /*0.001f Q15*/ );
1684 1 : L_tmp_e = sNlocal_e;
1685 1 : move16();
1686 : }
1687 :
1688 : /* calc square root of L_tmp and store result in dN */
1689 4618 : L_tmp = Sqrt32( L_tmp, &L_tmp_e );
1690 4618 : dN[sfb] = round_fx_sat( L_tmp );
1691 4618 : move16();
1692 4618 : dN_e[sfb] = L_tmp_e;
1693 4618 : move16();
1694 4618 : dN[sfb + 1] = dN[sfb];
1695 4618 : move16();
1696 4618 : dN_e[sfb + 1] = dN_e[sfb];
1697 4618 : move16();
1698 : }
1699 : }
1700 : ELSE
1701 : {
1702 0 : FOR( sfb = start_sfb; sfb < stop_sfb; sfb++ )
1703 : {
1704 : /* calculate and normalize the width of the current sfb */
1705 0 : width = sub( hGrid->swb_offset[sfb + 1], hGrid->swb_offset[sfb] );
1706 0 : shift = norm_s( width );
1707 0 : width = shl( width, shift );
1708 0 : width_e = sub( 15, shift ); /* initial value of width_e is 15, -> width = 15Q0 */
1709 :
1710 : /* float: gn = 0.25f * igf_curr - 4.f; basop: */
1711 0 : gn = hPrivateData->igf_curr[sfb];
1712 0 : move16();
1713 0 : move16();
1714 0 : gn_e = 13; /* set exponent of igf_curr to 13 = 15 - 2; -> igf_curr = igf_curr * 0.25, virtual division by 4 */
1715 0 : gn = sub( gn, 16 ); /* 13Q2 | 4 = 16 * 2^(-15 + 13); ("4" has same exponent as igf_curr now) */
1716 :
1717 : /* float: tmp = pow(2.f, gn); basop: */
1718 0 : L_tmp = BASOP_util_Pow2( L_deposit_h( gn ), gn_e, &L_tmp_e );
1719 :
1720 : /* float: tmp = tmp * tmp; basop: */
1721 0 : tmp = round_fx( L_tmp );
1722 0 : L_tmp = L_mult( tmp, tmp );
1723 0 : L_tmp_e = add( L_tmp_e, L_tmp_e );
1724 :
1725 : /* get sNlocal */
1726 0 : sNlocal = sN[sfb];
1727 0 : move32();
1728 0 : sNlocal_e = sN_e[sfb];
1729 0 : move16();
1730 :
1731 : /* float: sNlocal /= width; basop: */
1732 0 : shift = sub( norm_l( sNlocal ), 1 ); /* leave MSB empty, so in the division sNlocal is always smaller than width */
1733 0 : sNlocal = L_deposit_h( div_s( extract_h( L_shl( sNlocal, shift ) ), width ) );
1734 0 : sNlocal_e = sub( sub( sNlocal_e, shift ), width_e );
1735 :
1736 : /* float: tmp = max(0.001 * sNlocal, tmp - sNlocal); basop: */
1737 0 : L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp,
1738 : L_tmp_e,
1739 : L_negate( sNlocal ),
1740 : sNlocal_e,
1741 : &L_tmp_e ); /* float: tmp = tmp - sNlocal */
1742 :
1743 : /* max(0.001 * sNlocal, L_tmp) */
1744 : /* Build a threshold and compare with L_tmp.
1745 : Build negated threshold and compare with negated L_tmp to cover also fullscale L_tmp case */
1746 : BASOP_SATURATE_WARNING_OFF_EVS
1747 0 : L_tmp2 = L_shl_sat( L_negate( Mpy_32_16_1( sNlocal, 33 /*0.001f Q15*/ ) ), sub( sNlocal_e, L_tmp_e ) );
1748 0 : L_tmp2 = L_sub_sat( L_tmp2, L_negate( L_tmp ) );
1749 : BASOP_SATURATE_WARNING_ON_EVS
1750 :
1751 0 : IF( L_tmp2 < 0 )
1752 : {
1753 0 : L_tmp = Mpy_32_16_1( sNlocal, 33 /*0.001f Q15*/ );
1754 0 : L_tmp_e = sNlocal_e;
1755 0 : move16();
1756 : }
1757 :
1758 : /* calc square root of L_tmp and store result in dN */
1759 0 : L_tmp = Sqrt32( L_tmp, &L_tmp_e );
1760 0 : dN[sfb] = round_fx( L_tmp );
1761 0 : move16();
1762 0 : dN_e[sfb] = L_tmp_e;
1763 0 : move16();
1764 : }
1765 : }
1766 :
1767 646 : dS[start_sfb] = dN[start_sfb];
1768 646 : move16();
1769 646 : dS_e[start_sfb] = dN_e[start_sfb];
1770 646 : move16();
1771 :
1772 : /* first value with adaption to core energy: */
1773 646 : tmp_e = BASOP_Util_Add_MantExp( dE,
1774 : dE_e,
1775 646 : negate( dN[start_sfb] ),
1776 646 : dN_e[start_sfb],
1777 : &tmp ); /* float: tmp = dE - dN[start_sfb] */
1778 646 : IF( tmp < 0 )
1779 : {
1780 : /* float: dS[start_sfb] = dN[start_sfb] + fFactor * (dE-dN[start_sfb]); basop: */
1781 436 : L_tmp = L_mult( fFactor, tmp );
1782 436 : L_tmp_e = add( tmp_e, 1 ); /* 1Q14 | fFactor is 1Q14 */
1783 1308 : dS_e[start_sfb] = BASOP_Util_Add_MantExp( dN[start_sfb],
1784 436 : dN_e[start_sfb],
1785 436 : round_fx( L_tmp ),
1786 : L_tmp_e,
1787 436 : &dS[start_sfb] );
1788 436 : move16();
1789 : }
1790 : /* last value with less energy: */
1791 646 : dS[stop_sfb - 1] = mult_r( lFactor, dN[stop_sfb - 1] );
1792 646 : move16();
1793 646 : move16();
1794 646 : dS_e[stop_sfb - 1] = add( dN_e[stop_sfb - 1], 1 ); /* 1Q14 | lFactor is 1Q14 */
1795 :
1796 646 : sfb_p1 = add( start_sfb, 1 );
1797 646 : sfb_m1 = sub( stop_sfb, 1 );
1798 646 : test();
1799 646 : IF( hGrid->infoIsRefined != 0 && EQ_16( hopsize, 1 ) )
1800 : {
1801 : /* apply filter to absolute energy values: */
1802 2701 : FOR( sfb = sfb_p1; sfb < sfb_m1; sfb++ )
1803 : {
1804 : /* float: dS[sfb] = w0 * dN[sfb-1] + w1 * dN[sfb+0] + w2 * dN[sfb+1]; basop: */
1805 2502 : L_tmp = L_mult( w0, dN[sfb - 1] );
1806 2502 : dS[sfb] = round_fx( L_tmp );
1807 2502 : move16();
1808 2502 : dS_e[sfb] = dN_e[sfb - 1]; /* w0 is Q15, so no need to add an exponent */
1809 2502 : move16();
1810 2502 : L_tmp = L_mult( w1, dN[sfb] );
1811 7506 : dS_e[sfb] = BASOP_Util_Add_MantExp( dS[sfb],
1812 2502 : dS_e[sfb],
1813 2502 : round_fx( L_tmp ),
1814 2502 : dN_e[sfb], /* w1 is Q15, so no need to add an exponent */
1815 : &tmp );
1816 2502 : move16();
1817 2502 : dS[sfb] = tmp;
1818 2502 : move16();
1819 2502 : L_tmp = L_mult( w2, dN[sfb + 1] );
1820 7506 : dS_e[sfb] = BASOP_Util_Add_MantExp( dS[sfb],
1821 2502 : dS_e[sfb],
1822 2502 : round_fx( L_tmp ),
1823 2502 : dN_e[sfb + 1], /* w2 is Q15, so no need to add an exponent */
1824 : &tmp );
1825 2502 : move16();
1826 2502 : dS[sfb] = tmp;
1827 2502 : move16();
1828 : }
1829 : }
1830 : ELSE
1831 : {
1832 5889 : FOR( sfb = sfb_p1; sfb < sfb_m1; sfb++ )
1833 : {
1834 5442 : dS[sfb] = dN[sfb];
1835 5442 : move16();
1836 5442 : dS_e[sfb] = dN_e[sfb];
1837 5442 : move16();
1838 : }
1839 : }
1840 :
1841 646 : Hr = 0;
1842 646 : move16();
1843 646 : tileIdx = -1;
1844 646 : move16();
1845 6235 : FOR( sfb = start_sfb; sfb < stop_sfb; sfb += hopsize )
1846 : {
1847 5589 : E = 0;
1848 5589 : move32();
1849 5589 : E_e = 0;
1850 5589 : move16();
1851 5589 : sum = 0;
1852 5589 : move16();
1853 :
1854 14825 : FOR( tb = 0; tb < hopsize; tb++ )
1855 : {
1856 : /* calculate of the current sfb width */
1857 9236 : width = sub( hGrid->swb_offset[min( sfb + tb + 1, stop_sfb )], /* 15Q0 | width is Q0 */
1858 9236 : hGrid->swb_offset[min( sfb + tb, stop_sfb )] );
1859 :
1860 9236 : tmp = dS[min( sfb + tb, stop_sfb - 1 )];
1861 9236 : tmp_e = dS_e[min( sfb + tb, stop_sfb - 1 )];
1862 9236 : move16();
1863 9236 : move16();
1864 :
1865 : /* square tmp */
1866 9236 : L_tmp = L_mult( tmp, tmp );
1867 9236 : L_tmp_e = add( tmp_e, tmp_e );
1868 :
1869 : /* mult L_tmp times width */
1870 9236 : L_tmp = L_mult( round_fx( L_tmp ), width );
1871 9236 : L_tmp_e = add( L_tmp_e, 15 ); /* 15Q0 | width is Q0 */
1872 :
1873 : /* calculate resulting energy */
1874 9236 : E = BASOP_Util_Add_Mant32Exp( E,
1875 : E_e,
1876 : L_tmp,
1877 : L_tmp_e,
1878 : &E_e );
1879 9236 : sum = add( sum, width ); /* 15Q0 | sum shares its exponent with width */
1880 : }
1881 :
1882 : /* normalize sum for the following division */
1883 5589 : shift = norm_s( sum );
1884 5589 : sum = shl( sum, shift ); /* exponent of sum: sub(15, shift) */
1885 :
1886 : /* divide E by sum */
1887 : #ifdef ISSUE_1866_replace_overflow_libdec
1888 5589 : tmp = div_s( shr( round_fx_sat( E ), 1 ), sum ); /* shift E 1 bit to the right in order to make it smaller than sum */
1889 : #else
1890 : tmp = div_s( shr( round_fx_o( E, &Overflow ), 1 ), sum ); /* shift E 1 bit to the right in order to make it smaller than sum */
1891 : #endif
1892 5589 : tmp_e = sub( add( E_e, 1 ), sub( 15, shift ) ); /* 15Q0 | sum is 15Q0 */
1893 :
1894 : /* multiply the result by the hopsize */
1895 5589 : L_tmp = L_mult( tmp, hopsize );
1896 5589 : L_tmp_e = add( tmp_e, 15 ); /* 15Q0 | hopsize is 15Q0 */
1897 :
1898 : /* take the square root and store the result in dS */
1899 5589 : L_tmp = Sqrt32( L_tmp, &L_tmp_e );
1900 5589 : dS[sfb] = round_fx( L_tmp );
1901 5589 : dS_e[sfb] = L_tmp_e;
1902 5589 : move16();
1903 5589 : move16();
1904 :
1905 : /* calculate the new dN */
1906 5589 : dN[sfb] = mult_r( gFactor, dS[sfb] );
1907 5589 : move16();
1908 5589 : move16();
1909 5589 : dN_e[sfb] = add( dS_e[sfb], 1 ); /* 1Q14 | gFactor is 1Q14 */
1910 :
1911 : /* calculate of the current sfb width */
1912 5589 : width = sub( hGrid->swb_offset[sfb + 1], /* 15Q0 | width is Q0 */
1913 5589 : hGrid->swb_offset[sfb] );
1914 :
1915 : /* square dN */
1916 5589 : L_tmp = L_mult( dN[sfb], dN[sfb] );
1917 5589 : L_tmp_e = add( dN_e[sfb], dN_e[sfb] );
1918 :
1919 : /* mult L_tmp times width */
1920 5589 : shift = norm_l( L_tmp );
1921 5589 : L_tmp = L_shl( L_tmp, shift );
1922 5589 : L_tmp = L_mult( round_fx( L_tmp ), width );
1923 5589 : L_tmp_e = sub( add( L_tmp_e, 15 ), shift ); /* 15Q0 | width is Q0 */
1924 5589 : shift = norm_l( L_tmp );
1925 :
1926 : /* store normalized result */
1927 5589 : dNlocal = L_shl( L_tmp, shift );
1928 5589 : dNlocal_e = sub( L_tmp_e, shift );
1929 :
1930 : /* gain calculation */
1931 5589 : gain[sfb] = 0;
1932 5589 : move16();
1933 5589 : IF( pN[sfb] != 0 )
1934 : {
1935 5589 : tmp = BASOP_Util_Divide3232_Scale( dNlocal, pN[sfb], &s );
1936 5589 : s = sub( add( s, dNlocal_e ), pN_e[sfb] );
1937 5589 : gain[sfb] = Sqrt16( tmp, &s );
1938 5589 : move16();
1939 5589 : gain_e[sfb] = s;
1940 5589 : move16();
1941 :
1942 :
1943 : /* get the maximal exponent of the gain array, needed for exponent adjustment of the spectrum */
1944 5589 : maxGain_e = s_max( maxGain_e, gain_e[sfb] );
1945 : }
1946 5589 : sfb_p1 = add( sfb, 1 );
1947 5589 : sfb_m1 = s_min( add( sfb, hopsize ), stop_sfb );
1948 9236 : FOR( s_sfb = sfb_p1; s_sfb < sfb_m1; s_sfb++ )
1949 : {
1950 3647 : gain[s_sfb] = gain[sfb];
1951 3647 : move16();
1952 3647 : gain_e[s_sfb] = gain_e[sfb];
1953 3647 : move16();
1954 : }
1955 :
1956 : /*--- check gains /spectrum exponents for possible overflows --- */
1957 : /* get tile index */
1958 5589 : IF( LE_16( hGrid->sfbWrap[tileIdx + 1], sfb ) )
1959 : {
1960 1607 : tileIdx = add( tileIdx, 1 );
1961 : }
1962 : /*do a test multiplication with the highest possible value*/
1963 5589 : L_tmp = Mpy_32_16_1( (Word32) 0xFFFF8000 /*igf_spec occupies only the 16LSBs */, gain[sfb] );
1964 5589 : L_tmp_e = add( igf_spec_e[tileIdx], gain_e[sfb] );
1965 : /*check whether overflow would occur and calculate Headroom, needed*/
1966 5589 : shift = sub( L_tmp_e, *spectrum_e );
1967 5589 : tmp = sub( shift, sub( norm_l( L_tmp ), TCX_IMDCT_HEADROOM ) );
1968 5589 : if ( tmp > 0 )
1969 : {
1970 0 : Hr = s_max( Hr, tmp );
1971 : }
1972 :
1973 : /* disable rescaling if gain is smaler than 1 */
1974 : /* gain < 1, if norm_s(gain[sfb]) >= gain_e[sfb] */
1975 5589 : tmp = sub( norm_s( gain[sfb] ), gain_e[sfb] );
1976 5589 : if ( tmp >= 0 )
1977 : {
1978 5586 : Hr = 0;
1979 5586 : move16();
1980 : }
1981 : }
1982 :
1983 : /* Rescale spectrum if overflow may occur */
1984 646 : tileIdx = -1;
1985 646 : move16();
1986 646 : IF( Hr > 0 )
1987 : {
1988 : /* rescale virtual Spec, cheap and easy: reset scalingfactor */
1989 0 : *virtualSpec_e = add( *virtualSpec_e, Hr );
1990 0 : move16();
1991 :
1992 : /* rescale spectrum */
1993 0 : FOR( i = 0; i < hGrid->stopLine; i++ )
1994 : {
1995 0 : spectrum[i] = L_shr( spectrum[i], Hr );
1996 0 : move16();
1997 : }
1998 0 : *spectrum_e = add( *spectrum_e, Hr );
1999 0 : move16();
2000 : }
2001 :
2002 : /* tiling */
2003 646 : tileIdx = -1;
2004 646 : move16();
2005 9882 : FOR( sfb = start_sfb; sfb < stop_sfb; sfb++ )
2006 : {
2007 : /* get tile index */
2008 9236 : IF( EQ_16( hGrid->sfbWrap[tileIdx + 1], sfb ) )
2009 : {
2010 1663 : tileIdx = add( tileIdx, 1 );
2011 : }
2012 :
2013 9236 : IF( hPrivateData->frameLossCounter > 0 )
2014 : {
2015 : /* normalize gain */
2016 0 : tmp = norm_s( gain[sfb] );
2017 0 : gain[sfb] = shl( gain[sfb], tmp );
2018 0 : move16();
2019 0 : gain_e[sfb] = sub( gain_e[sfb], tmp );
2020 0 : move16();
2021 :
2022 : /* gain[sfb] = min(gain[sfb], 12.f); */
2023 : BASOP_SATURATE_WARNING_OFF_EVS /* threshold, may overflow */
2024 0 : tmp = shl_sat( gain[sfb], sub( gain_e[sfb], 15 - 5 ) ); /* 10Q5 | tmp is in 10Q5 */
2025 : BASOP_SATURATE_WARNING_ON_EVS
2026 :
2027 0 : IF( tmp > 384 ) /* 10Q5 | 384 = 12 in 10Q5 */
2028 : {
2029 0 : gain[sfb] = 384;
2030 0 : move16();
2031 0 : gain_e[sfb] = 10;
2032 0 : move16();
2033 : }
2034 :
2035 0 : IF( LT_16( hPrivateData->frameLossCounter, 5 ) )
2036 : {
2037 : /* gain[sfb] -= gain[sfb] / 8 * hPrivateData->frameLossCounter; -> multiply with 0Q15 -> adaption of the exponent not needed */
2038 0 : IF( EQ_16( hPrivateData->frameLossCounter, 1 ) )
2039 : {
2040 : /* 0Q15 | >> 3 ^= * 0.125 = 1 / 8 */
2041 0 : gain[sfb] = sub( gain[sfb], shr_r( gain[sfb], 3 ) );
2042 0 : move16();
2043 : }
2044 0 : ELSE IF( EQ_16( hPrivateData->frameLossCounter, 2 ) )
2045 : {
2046 : /* 0Q15 | >> 2 ^= * 0.25 = 2 / 8 */
2047 0 : gain[sfb] = sub( gain[sfb], shr_r( gain[sfb], 2 ) );
2048 0 : move16();
2049 : }
2050 0 : ELSE IF( EQ_16( hPrivateData->frameLossCounter, 3 ) )
2051 : {
2052 : /* 0Q15 | * 12288 ^= * 0.3750 = 3 / 8 */
2053 0 : gain[sfb] = sub( gain[sfb], mult_r( gain[sfb], 12288 ) );
2054 0 : move16();
2055 : }
2056 : ELSE
2057 : {
2058 : /* 0Q15 | >> 1 ^= * 0.5 = 4 / 8 */
2059 0 : gain[sfb] = sub( gain[sfb], shr_r( gain[sfb], 1 ) );
2060 0 : move16();
2061 : }
2062 : }
2063 : ELSE
2064 : {
2065 : /* gain[sfb] /= 2; -> reduce exponent by 1 */
2066 0 : gain_e[sfb] = sub( gain_e[sfb], 1 );
2067 0 : move16();
2068 : }
2069 : }
2070 :
2071 240310 : FOR( tb = hGrid->swb_offset[sfb]; tb < hGrid->swb_offset[sfb + 1]; tb++ )
2072 : {
2073 : /* multiply the prepared IGF spectrum with the gain */
2074 231074 : L_tmp2 = 0; /* set L_tmp2 to default value */
2075 231074 : move32();
2076 231074 : L_tmp = Mpy_32_16_1( igf_spec[tb], gain[sfb] );
2077 231074 : L_tmp_e = add( igf_spec_e[tileIdx], gain_e[sfb] );
2078 :
2079 : /* store the finalized IGF spectrum */
2080 231074 : IF( spectrum[tb] == 0 )
2081 : {
2082 231037 : shift = sub( L_tmp_e, *spectrum_e );
2083 231037 : tmp = sub( sub( norm_l( L_tmp ), shift ), 32 );
2084 231037 : IF( tmp < 0 )
2085 : {
2086 229932 : L_tmp2 = L_shl( L_tmp, shift );
2087 : }
2088 231037 : spectrum[tb] = L_tmp2;
2089 231037 : move32();
2090 231037 : flag_sparse[tb - IGF_START_MN] = 1;
2091 231037 : move16();
2092 : }
2093 : ELSE
2094 : {
2095 37 : shift = sub( L_tmp_e, *virtualSpec_e );
2096 37 : tmp = sub( sub( norm_l( L_tmp ), shift ), 32 );
2097 37 : IF( tmp < 0 )
2098 : {
2099 37 : L_tmp2 = L_shl( L_tmp, shift );
2100 : }
2101 37 : virtualSpec[tb - IGF_START_MN] = L_tmp2;
2102 37 : move32();
2103 37 : flag_sparse[tb - IGF_START_MN] = 2;
2104 37 : move16();
2105 : }
2106 : }
2107 : }
2108 646 : }
2109 :
2110 : /**********************************************************************/ /*
2111 : apply IGF (for IVAS)
2112 : **************************************************************************/
2113 572284 : static void IGF_appl_ivas( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in: | IGF private data handle */
2114 : const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */
2115 : Word32 *spectrum, /**< in: Q31 | MDCT spectrum */
2116 : Word16 *spectrum_e, /**< in: | exponent of pSpectralData */
2117 : const Word32 *igf_spec, /**< in: Q31 | prepared IGF spectrum */
2118 : const Word16 *igf_spec_e, /**< in: | array exponents of igf_spec, one exponent per tile */
2119 : Word32 *virtualSpec, /**< out:Q31 | virtual IGF spectrum, used for temp flattening */
2120 : Word16 *virtualSpec_e, /**< out: | exponent of virtualSpec */
2121 : Word16 *flag_sparse, /**< out: Q0 | temp flattening indicator */
2122 : Word16 bfi_apply_damping /**< in: | bfi apply damping */
2123 : )
2124 : {
2125 : H_IGF_GRID hGrid;
2126 : Word16 i;
2127 : Word16 tb;
2128 : Word16 sfb;
2129 : Word16 shift;
2130 : Word16 s;
2131 : Word16 s_sfb;
2132 : Word16 start_sfb;
2133 : Word16 stop_sfb;
2134 : Word16 sfb_p1;
2135 : Word16 sfb_m1;
2136 : Word16 hopsize;
2137 : Word16 sum;
2138 : Word16 tileIdx;
2139 : Word16 width; /* Q0 | width of the current sfb */
2140 : Word16 width_e; /* | exponent of widthent sfb, initialized as 15! */
2141 : Word16 gFactor; /* 1Q14 | general SCF adaption */
2142 : Word16 fFactor; /* 1Q14 | first SCF adaption */
2143 : Word16 lFactor; /* 1Q14 | last SCF adaption */
2144 : Word16 w0; /* Q15 | float value: 0.201f */
2145 : Word16 w1; /* Q15 | float value: 0.389f */
2146 : Word16 w2; /* Q15 | float value: 0.410f */
2147 : Word16 dE; /* Q31 | energy below igfBgn */
2148 : Word16 dE_e; /* | exponent of dE */
2149 : Word16 gn; /* Q0 | gain read from bitstream + processing */
2150 : Word16 gn_e; /* | exponent of gn */
2151 : Word16 maxGain_e; /* | maximal gain exponent over sfbs */
2152 : Word16 tmp;
2153 : Word16 tmp_e;
2154 : Word16 tmp_loop;
2155 : Word32 L_tmp;
2156 : Word16 L_tmp_e;
2157 : Word32 L_tmp2;
2158 : Word32 sNlocal;
2159 : Word16 sNlocal_e;
2160 : Word32 dNlocal;
2161 : Word16 dNlocal_e;
2162 : Word32 E;
2163 : Word16 E_e;
2164 : Word32 *sN;
2165 : Word16 *sN_e;
2166 : Word32 *pN;
2167 : Word16 *pN_e;
2168 : Word16 gain[IGF_MAX_SFB];
2169 : Word16 gain_e[IGF_MAX_SFB];
2170 : Word16 dN[IGF_MAX_SFB + 1];
2171 : Word16 dN_e[IGF_MAX_SFB + 1];
2172 : Word16 dS[IGF_MAX_SFB];
2173 : Word16 dS_e[IGF_MAX_SFB];
2174 : Word32 energyTmp[24];
2175 : Word32 L_c;
2176 : Word16 spec_e_arr[N_MAX];
2177 : Word16 vspec_e_arr[N_MAX_TCX - IGF_START_MN];
2178 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2179 572284 : Flag Overflow = 0;
2180 572284 : move16();
2181 572284 : Flag Carry = 0;
2182 572284 : move16();
2183 : #endif
2184 :
2185 :
2186 : /* initialize variables */
2187 572284 : w0 = 6586; // Q15
2188 572284 : move16();
2189 572284 : w1 = 12747; // Q15
2190 572284 : move16();
2191 572284 : w2 = 13435; // Q15
2192 572284 : move16();
2193 572284 : dE = 0;
2194 572284 : move16();
2195 572284 : dE_e = 0;
2196 572284 : move16();
2197 572284 : tmp = 0;
2198 572284 : move16();
2199 572284 : s = 0;
2200 572284 : move16();
2201 572284 : tmp_e = 0;
2202 572284 : move16();
2203 572284 : gn = 0;
2204 572284 : move16();
2205 572284 : gn_e = 0;
2206 572284 : move16();
2207 572284 : maxGain_e = 0;
2208 572284 : move16();
2209 572284 : L_tmp_e = 0;
2210 572284 : move16();
2211 572284 : dNlocal_e = 0;
2212 572284 : move16();
2213 572284 : L_tmp = 0;
2214 572284 : move32();
2215 572284 : dNlocal = 0;
2216 572284 : move32();
2217 :
2218 572284 : set16_fx( gain, 0, IGF_MAX_SFB );
2219 572284 : set16_fx( gain_e, 0, IGF_MAX_SFB );
2220 572284 : set16_fx( dN, 0, add( IGF_MAX_SFB, 1 ) );
2221 572284 : set16_fx( dN_e, 0, add( IGF_MAX_SFB, 1 ) );
2222 572284 : set16_fx( dS, 0, IGF_MAX_SFB );
2223 572284 : set16_fx( dS_e, 0, IGF_MAX_SFB );
2224 572284 : set32_fx( energyTmp, 0, 24 );
2225 572284 : set16_fx( spec_e_arr, *spectrum_e, N_MAX );
2226 572284 : set16_fx( vspec_e_arr, 0, N_MAX_TCX - IGF_START_MN );
2227 :
2228 : /* more inits */
2229 572284 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
2230 572284 : sN = hPrivateData->igf_sN;
2231 572284 : sN_e = hPrivateData->igf_sN_e;
2232 572284 : pN = hPrivateData->igf_pN;
2233 572284 : pN_e = hPrivateData->igf_pN_e;
2234 572284 : start_sfb = hGrid->startSfb;
2235 572284 : move16();
2236 572284 : stop_sfb = hGrid->stopSfb;
2237 572284 : move16();
2238 572284 : gFactor = hGrid->gFactor;
2239 572284 : move16();
2240 572284 : fFactor = hGrid->fFactor;
2241 572284 : move16();
2242 572284 : lFactor = hGrid->lFactor;
2243 572284 : move16();
2244 :
2245 : /* reset virtual spec */
2246 572284 : set16_fx( flag_sparse, 0, N_MAX_TCX - IGF_START_MN );
2247 572284 : set32_fx( virtualSpec, 0, N_MAX_TCX - IGF_START_MN );
2248 572284 : *virtualSpec_e = *spectrum_e;
2249 572284 : move16();
2250 :
2251 : /* collect energy below hGrid->startLine: */
2252 572284 : tmp = sub( hGrid->startLine, 24 );
2253 572284 : IGFCommonFuncsMDCTSquareSpec_ivas( tmp,
2254 572284 : hGrid->startLine,
2255 : spectrum,
2256 572284 : *spectrum_e,
2257 : energyTmp,
2258 : &dE_e,
2259 572284 : negate( tmp ) );
2260 :
2261 572284 : L_c = 0;
2262 572284 : move32();
2263 14307100 : FOR( tb = 0; tb < 24; tb++ )
2264 : {
2265 13734816 : Carry = 0;
2266 13734816 : move16();
2267 13734816 : L_tmp = L_add_co( L_tmp, energyTmp[tb], &Carry, &Overflow ); // Q31 - dE_e
2268 13734816 : Overflow = 0;
2269 13734816 : L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow );
2270 : }
2271 572284 : L_tmp = norm_llQ31( L_c, L_tmp, &shift ); // Q31
2272 : /* float: dE = (float)sqrt(dE / 24.f); basop: */
2273 572284 : shift = add( sub( shift, 4 ), dE_e ); /* x/24 = (x >> 4) * 1/1.5 */
2274 572284 : dE = Sqrt16norm( extract_h( L_tmp ), &shift );
2275 572284 : dE = mult_r( dE, 26755 /*0.81649658092772603273242802490196f Q15*/ ); /* 0.81649658092772603273242802490196f = sqrt(1/1.5)) */
2276 572284 : dE_e = shift;
2277 572284 : move16();
2278 :
2279 : /* select correct hopsize for envelope refinement */
2280 572284 : hopsize = 2;
2281 572284 : move16();
2282 572284 : if ( EQ_16( hPrivateData->currWhiteningLevel[0], IGF_WHITENING_OFF ) )
2283 : {
2284 218110 : hopsize = 4;
2285 218110 : move16();
2286 : }
2287 572284 : if ( EQ_16( hPrivateData->currWhiteningLevel[0], IGF_WHITENING_STRONG ) )
2288 : {
2289 132885 : hopsize = 1;
2290 132885 : move16();
2291 : }
2292 572284 : hopsize = s_min( hopsize, hPrivateData->igfInfo.maxHopsize );
2293 572284 : IF( hPrivateData->restrict_hopsize )
2294 : {
2295 27834 : hopsize = s_min( hopsize, 2 );
2296 : }
2297 :
2298 572284 : IF( GT_16( hopsize, 1 ) )
2299 : {
2300 2090670 : FOR( sfb = start_sfb; sfb < stop_sfb; sfb += hopsize )
2301 : {
2302 1809871 : tmp_loop = s_min( add( sfb, hopsize ), stop_sfb );
2303 3664392 : FOR( tb = sfb + 1; tb < tmp_loop; tb++ )
2304 : {
2305 3709042 : sN[sfb] = BASOP_Util_Add_Mant32Exp( sN[sfb],
2306 1854521 : sN_e[sfb],
2307 1854521 : sN[tb],
2308 1854521 : sN_e[tb],
2309 1854521 : &sN_e[sfb] );
2310 1854521 : move32();
2311 3709042 : pN[sfb] = BASOP_Util_Add_Mant32Exp( pN[sfb],
2312 1854521 : pN_e[sfb],
2313 1854521 : pN[tb],
2314 1854521 : pN_e[tb],
2315 1854521 : &pN_e[sfb] );
2316 1854521 : move32();
2317 1854521 : sN[tb] = L_deposit_l( 0 );
2318 1854521 : pN[tb] = L_deposit_l( 0 );
2319 : }
2320 : }
2321 : }
2322 :
2323 : /* IGF_rescale_SCF */
2324 572284 : IF( hGrid->infoIsRefined != 0 )
2325 : {
2326 2937144 : FOR( sfb = start_sfb; sfb < stop_sfb; sfb += 2 )
2327 : {
2328 : /* calculate and normalize the width of the current sfb */
2329 2535641 : width = sub( hGrid->swb_offset[sfb + 2], hGrid->swb_offset[sfb] );
2330 2535641 : shift = norm_s( width );
2331 2535641 : width = shl( width, shift );
2332 2535641 : width_e = sub( 15, shift ); /* initial value of width_e is 15, -> width = 15Q0 */
2333 :
2334 : /* float: gn = 0.25f * igf_curr - 4.f; basop: */
2335 2535641 : gn = hPrivateData->igf_curr[sfb >> 1]; // Q15
2336 2535641 : move16();
2337 2535641 : move16();
2338 2535641 : gn_e = 13; /* set exponent of igf_curr to 13 = 15 - 2; -> igf_curr = igf_curr * 0.25, virtual division by 4 */
2339 2535641 : gn = sub( gn, 16 ); /* 13Q2 | 4 = 16 * 2^(-15 + 13); ("4" has same exponent as igf_curr now) */
2340 :
2341 : /* float: tmp = pow(2.f, gn); basop: */
2342 2535641 : L_tmp = BASOP_util_Pow2( L_deposit_h( gn ), gn_e, &L_tmp_e );
2343 :
2344 : /* float: tmp = tmp * tmp; basop: */
2345 2535641 : tmp = round_fx( L_tmp );
2346 2535641 : L_tmp = L_mult( tmp, tmp );
2347 2535641 : L_tmp_e = add( L_tmp_e, L_tmp_e );
2348 :
2349 : /* get sNlocal | float: sNlocal = sN[ sfb ] + sN[ sfb+ 1 ]; basop: */
2350 2535641 : sNlocal = BASOP_Util_Add_Mant32Exp( sN[sfb],
2351 2535641 : sN_e[sfb],
2352 2535641 : sN[sfb + 1],
2353 2535641 : sN_e[sfb + 1],
2354 : &sNlocal_e );
2355 :
2356 : /* float: sNlocal /= width; basop: */
2357 2535641 : shift = sub( norm_l( sNlocal ), 1 ); /* leave MSB empty, so in the division sNlocal is always smaller than width */
2358 2535641 : sNlocal = L_deposit_h( div_s( extract_h( L_shl( sNlocal, shift ) ), width ) );
2359 2535641 : sNlocal_e = sub( sub( sNlocal_e, shift ), width_e );
2360 :
2361 : /* float: tmp = max(0.001 * sNlocal, tmp - sNlocal); basop: */
2362 2535641 : L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp,
2363 : L_tmp_e,
2364 : L_negate( sNlocal ),
2365 : sNlocal_e,
2366 : &L_tmp_e ); /* float: tmp = tmp - sNlocal */
2367 :
2368 : /* max(0.001 * sNlocal, L_tmp) */
2369 : /* Build a threshold and compare with L_tmp.
2370 : Build negated threshold and compare with negated L_tmp to cover also fullscale L_tmp case */
2371 : BASOP_SATURATE_WARNING_OFF_EVS
2372 2535641 : L_tmp2 = L_shl_sat( L_negate( Mpy_32_16_1( sNlocal, 33 /*0.001f Q15*/ ) ), sub( sNlocal_e, L_tmp_e ) );
2373 2535641 : L_tmp2 = L_sub_sat( L_tmp2, L_negate( L_tmp ) );
2374 : BASOP_SATURATE_WARNING_ON_EVS
2375 :
2376 2535641 : IF( L_tmp2 < 0 )
2377 : {
2378 536 : L_tmp = Mpy_32_16_1( sNlocal, 33 /*0.001f Q15*/ );
2379 536 : L_tmp_e = sNlocal_e;
2380 536 : move16();
2381 : }
2382 :
2383 : /* calc square root of L_tmp and store result in dN */
2384 2535641 : L_tmp = Sqrt32( L_tmp, &L_tmp_e );
2385 2535641 : dN[sfb] = extract_h( L_tmp );
2386 2535641 : move16();
2387 2535641 : dN_e[sfb] = L_tmp_e;
2388 2535641 : move16();
2389 2535641 : dN[sfb + 1] = dN[sfb];
2390 2535641 : move16();
2391 2535641 : dN_e[sfb + 1] = dN_e[sfb];
2392 2535641 : move16();
2393 : }
2394 : }
2395 : ELSE
2396 : {
2397 629235 : FOR( sfb = start_sfb; sfb < stop_sfb; sfb++ )
2398 : {
2399 : /* calculate and normalize the width of the current sfb */
2400 458454 : width = sub( hGrid->swb_offset[sfb + 1], hGrid->swb_offset[sfb] );
2401 458454 : shift = norm_s( width );
2402 458454 : width = shl( width, shift );
2403 458454 : width_e = sub( 15, shift ); /* initial value of width_e is 15, -> width = 15Q0 */
2404 :
2405 : /* float: gn = 0.25f * igf_curr - 4.f; basop: */
2406 458454 : gn = hPrivateData->igf_curr[sfb];
2407 458454 : move16();
2408 458454 : move16();
2409 458454 : gn_e = 13; /* set exponent of igf_curr to 13 = 15 - 2; -> igf_curr = igf_curr * 0.25, virtual division by 4 */
2410 458454 : gn = sub( gn, 16 ); /* 13Q2 | 4 = 16 * 2^(-15 + 13); ("4" has same exponent as igf_curr now) */
2411 :
2412 : /* float: tmp = pow(2.f, gn); basop: */
2413 458454 : L_tmp = BASOP_util_Pow2( L_deposit_h( gn ), gn_e, &L_tmp_e );
2414 :
2415 : /* float: tmp = tmp * tmp; basop: */
2416 458454 : tmp = round_fx( L_tmp );
2417 458454 : L_tmp = L_mult( tmp, tmp );
2418 458454 : L_tmp_e = add( L_tmp_e, L_tmp_e );
2419 :
2420 : /* get sNlocal */
2421 458454 : sNlocal = sN[sfb];
2422 458454 : move32();
2423 458454 : sNlocal_e = sN_e[sfb];
2424 458454 : move16();
2425 :
2426 : /* float: sNlocal /= width; basop: */
2427 458454 : shift = sub( norm_l( sNlocal ), 1 ); /* leave MSB empty, so in the division sNlocal is always smaller than width */
2428 458454 : sNlocal = L_deposit_h( div_s( extract_h( L_shl( sNlocal, shift ) ), width ) );
2429 458454 : sNlocal_e = sub( sub( sNlocal_e, shift ), width_e );
2430 :
2431 : /* float: tmp = max(0.001 * sNlocal, tmp - sNlocal); basop: */
2432 458454 : L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp,
2433 : L_tmp_e,
2434 : L_negate( sNlocal ),
2435 : sNlocal_e,
2436 : &L_tmp_e ); /* float: tmp = tmp - sNlocal */
2437 :
2438 : /* max(0.001 * sNlocal, L_tmp) */
2439 : /* Build a threshold and compare with L_tmp.
2440 : Build negated threshold and compare with negated L_tmp to cover also fullscale L_tmp case */
2441 458454 : L_tmp2 = L_shl_sat( L_negate( Mpy_32_16_1( sNlocal, 33 /*0.001f Q15*/ ) ), sub( sNlocal_e, L_tmp_e ) );
2442 458454 : L_tmp2 = L_sub_sat( L_tmp2, L_negate( L_tmp ) );
2443 :
2444 458454 : IF( L_tmp2 < 0 )
2445 : {
2446 13 : L_tmp = Mpy_32_16_1( sNlocal, 33 /*0.001f Q15*/ );
2447 13 : L_tmp_e = sNlocal_e;
2448 13 : move16();
2449 : }
2450 :
2451 : /* calc square root of L_tmp and store result in dN */
2452 458454 : L_tmp = Sqrt32( L_tmp, &L_tmp_e );
2453 458454 : dN[sfb] = round_fx_sat( L_tmp );
2454 458454 : move16();
2455 458454 : dN_e[sfb] = L_tmp_e;
2456 458454 : move16();
2457 : }
2458 : }
2459 :
2460 572284 : dS[start_sfb] = dN[start_sfb];
2461 572284 : move16();
2462 572284 : dS_e[start_sfb] = dN_e[start_sfb];
2463 572284 : move16();
2464 :
2465 : /* first value with adaption to core energy: */
2466 572284 : tmp_e = BASOP_Util_Add_MantExp( dE,
2467 : dE_e,
2468 572284 : negate( dN[start_sfb] ),
2469 572284 : dN_e[start_sfb],
2470 : &tmp ); /* float: tmp = dE - dN[start_sfb] */
2471 572284 : IF( tmp < 0 )
2472 : {
2473 : /* float: dS[start_sfb] = dN[start_sfb] + fFactor * (dE-dN[start_sfb]); basop: */
2474 350011 : L_tmp = L_mult( fFactor, tmp );
2475 350011 : L_tmp_e = add( tmp_e, 1 ); /* 1Q14 | fFactor is 1Q14 */
2476 1050033 : dS_e[start_sfb] = BASOP_Util_Add_MantExp( dN[start_sfb],
2477 350011 : dN_e[start_sfb],
2478 350011 : round_fx( L_tmp ),
2479 : L_tmp_e,
2480 350011 : &dS[start_sfb] );
2481 350011 : move16();
2482 : }
2483 : /* last value with less energy: */
2484 572284 : dS[stop_sfb - 1] = mult_r( lFactor, dN[stop_sfb - 1] );
2485 572284 : move16();
2486 572284 : move16();
2487 572284 : dS_e[stop_sfb - 1] = add( dN_e[stop_sfb - 1], 1 ); /* 1Q14 | lFactor is 1Q14 */
2488 :
2489 572284 : sfb_p1 = add( start_sfb, 1 );
2490 572284 : sfb_m1 = sub( stop_sfb, 1 );
2491 572284 : test();
2492 572284 : IF( hGrid->infoIsRefined != 0 && EQ_16( hopsize, 1 ) )
2493 : {
2494 : /* apply filter to absolute energy values: */
2495 1286186 : FOR( sfb = sfb_p1; sfb < sfb_m1; sfb++ )
2496 : {
2497 : /* float: dS[sfb] = w0 * dN[sfb-1] + w1 * dN[sfb+0] + w2 * dN[sfb+1]; basop: */
2498 1165482 : L_tmp = L_mult( w0, dN[sfb - 1] );
2499 1165482 : dS[sfb] = round_fx( L_tmp );
2500 1165482 : move16();
2501 1165482 : dS_e[sfb] = dN_e[sfb - 1]; /* w0 is Q15, so no need to add an exponent */
2502 1165482 : move16();
2503 1165482 : L_tmp = L_mult( w1, dN[sfb] );
2504 3496446 : dS_e[sfb] = BASOP_Util_Add_MantExp( dS[sfb],
2505 1165482 : dS_e[sfb],
2506 1165482 : round_fx( L_tmp ),
2507 1165482 : dN_e[sfb], /* w1 is Q15, so no need to add an exponent */
2508 : &tmp );
2509 1165482 : move16();
2510 1165482 : dS[sfb] = tmp;
2511 1165482 : move16();
2512 1165482 : L_tmp = L_mult( w2, dN[sfb + 1] );
2513 3496446 : dS_e[sfb] = BASOP_Util_Add_MantExp( dS[sfb],
2514 1165482 : dS_e[sfb],
2515 1165482 : round_fx( L_tmp ),
2516 1165482 : dN_e[sfb + 1], /* w2 is Q15, so no need to add an exponent */
2517 : &tmp );
2518 1165482 : move16();
2519 1165482 : dS[sfb] = tmp;
2520 1165482 : move16();
2521 : }
2522 : }
2523 : ELSE
2524 : {
2525 3671266 : FOR( sfb = sfb_p1; sfb < sfb_m1; sfb++ )
2526 : {
2527 3219686 : dS[sfb] = dN[sfb];
2528 3219686 : move16();
2529 3219686 : dS_e[sfb] = dN_e[sfb];
2530 3219686 : move16();
2531 : }
2532 : }
2533 :
2534 572284 : tileIdx = -1;
2535 572284 : move16();
2536 4247499 : FOR( sfb = start_sfb; sfb < stop_sfb; sfb += hopsize )
2537 : {
2538 3675215 : E = 0;
2539 3675215 : move32();
2540 3675215 : E_e = 0;
2541 3675215 : move16();
2542 3675215 : sum = 0;
2543 3675215 : move16();
2544 :
2545 9230721 : FOR( tb = 0; tb < hopsize; tb++ )
2546 : {
2547 : /* calculate of the current sfb width */
2548 5555506 : width = sub( hGrid->swb_offset[min( sfb + tb + 1, stop_sfb )], /* 15Q0 | width is Q0 */
2549 5555506 : hGrid->swb_offset[min( sfb + tb, stop_sfb )] );
2550 :
2551 5555506 : tmp = dS[min( sfb + tb, stop_sfb - 1 )];
2552 5555506 : tmp_e = dS_e[min( sfb + tb, stop_sfb - 1 )];
2553 5555506 : move16();
2554 5555506 : move16();
2555 :
2556 : /* square tmp */
2557 5555506 : L_tmp = L_mult( tmp, tmp );
2558 5555506 : L_tmp_e = add( tmp_e, tmp_e );
2559 :
2560 : /* mult L_tmp times width */
2561 5555506 : L_tmp = L_mult( round_fx( L_tmp ), width );
2562 5555506 : L_tmp_e = add( L_tmp_e, 15 ); /* 15Q0 | width is Q0 */
2563 :
2564 : /* calculate resulting energy */
2565 5555506 : E = BASOP_Util_Add_Mant32Exp( E,
2566 : E_e,
2567 : L_tmp,
2568 : L_tmp_e,
2569 : &E_e );
2570 5555506 : sum = add( sum, width ); /* 15Q0 | sum shares its exponent with width */
2571 : }
2572 :
2573 : /* normalize sum for the following division */
2574 3675215 : shift = norm_s( sum );
2575 3675215 : sum = shl( sum, shift ); /* exponent of sum: sub(15, shift) */
2576 :
2577 : /* divide E by sum */
2578 : #ifdef ISSUE_1866_replace_overflow_libdec
2579 3675215 : tmp = div_s( shr( round_fx_sat( E ), 1 ), sum ); /* shift E 1 bit to the right in order to make it smaller than sum */
2580 : #else
2581 : tmp = div_s( shr( round_fx_o( E, &Overflow ), 1 ), sum ); /* shift E 1 bit to the right in order to make it smaller than sum */
2582 : #endif
2583 3675215 : tmp_e = sub( add( E_e, 1 ), sub( 15, shift ) ); /* 15Q0 | sum is 15Q0 */
2584 :
2585 : /* multiply the result by the hopsize */
2586 3675215 : L_tmp = L_mult( tmp, hopsize );
2587 3675215 : L_tmp_e = add( tmp_e, 15 ); /* 15Q0 | hopsize is 15Q0 */
2588 :
2589 : /* take the square root and store the result in dS */
2590 3675215 : L_tmp = Sqrt32( L_tmp, &L_tmp_e );
2591 3675215 : dS[sfb] = round_fx( L_tmp );
2592 3675215 : move16();
2593 3675215 : dS_e[sfb] = L_tmp_e;
2594 3675215 : move16();
2595 :
2596 : /* calculate the new dN */
2597 3675215 : dN[sfb] = mult_r( gFactor, dS[sfb] );
2598 3675215 : move16();
2599 3675215 : move16();
2600 3675215 : dN_e[sfb] = add( dS_e[sfb], 1 ); /* 1Q14 | gFactor is 1Q14 */
2601 :
2602 : /* calculate of the current sfb width */
2603 3675215 : width = sub( hGrid->swb_offset[sfb + 1], /* 15Q0 | width is Q0 */
2604 3675215 : hGrid->swb_offset[sfb] );
2605 :
2606 : /* square dN */
2607 3675215 : L_tmp = L_mult( dN[sfb], dN[sfb] );
2608 3675215 : L_tmp_e = add( dN_e[sfb], dN_e[sfb] );
2609 :
2610 : /* mult L_tmp times width */
2611 3675215 : shift = norm_l( L_tmp );
2612 3675215 : L_tmp = L_shl( L_tmp, shift );
2613 3675215 : L_tmp = L_mult( round_fx( L_tmp ), width );
2614 3675215 : L_tmp_e = sub( add( L_tmp_e, 15 ), shift ); /* 15Q0 | width is Q0 */
2615 3675215 : shift = norm_l( L_tmp );
2616 :
2617 : /* store normalized result */
2618 3675215 : dNlocal = L_shl( L_tmp, shift );
2619 3675215 : dNlocal_e = sub( L_tmp_e, shift );
2620 :
2621 : /* gain calculation */
2622 3675215 : gain[sfb] = 0;
2623 3675215 : move16();
2624 3675215 : IF( pN[sfb] != 0 )
2625 : {
2626 3655270 : tmp = BASOP_Util_Divide3232_Scale( dNlocal, pN[sfb], &s );
2627 3655270 : s = sub( add( s, dNlocal_e ), pN_e[sfb] );
2628 3655270 : gain[sfb] = Sqrt16( tmp, &s );
2629 3655270 : move16();
2630 3655270 : gain_e[sfb] = s;
2631 3655270 : move16();
2632 :
2633 :
2634 : /* get the maximal exponent of the gain array, needed for exponent adjustment of the spectrum */
2635 3655270 : maxGain_e = s_max( maxGain_e, gain_e[sfb] );
2636 : }
2637 3675215 : sfb_p1 = add( sfb, 1 );
2638 3675215 : sfb_m1 = s_min( add( sfb, hopsize ), stop_sfb );
2639 5529736 : FOR( s_sfb = sfb_p1; s_sfb < sfb_m1; s_sfb++ )
2640 : {
2641 1854521 : gain[s_sfb] = gain[sfb];
2642 1854521 : move16();
2643 1854521 : gain_e[s_sfb] = gain_e[sfb];
2644 1854521 : move16();
2645 : }
2646 : }
2647 :
2648 : /* tiling */
2649 572284 : tileIdx = -1;
2650 572284 : move16();
2651 6102020 : FOR( sfb = start_sfb; sfb < stop_sfb; sfb++ )
2652 : {
2653 : /* get tile index */
2654 5529736 : if ( EQ_16( hGrid->sfbWrap[tileIdx + 1], sfb ) )
2655 : {
2656 1929888 : tileIdx = add( tileIdx, 1 );
2657 : }
2658 :
2659 5529736 : test();
2660 5529736 : IF( bfi_apply_damping && hPrivateData->frameLossCounter > 0 )
2661 : {
2662 : /* normalize gain */
2663 42068 : tmp = norm_s( gain[sfb] );
2664 42068 : gain[sfb] = shl( gain[sfb], tmp );
2665 42068 : move16();
2666 42068 : gain_e[sfb] = sub( gain_e[sfb], tmp );
2667 42068 : move16();
2668 :
2669 : /* gain[sfb] = min(gain[sfb], 12.f); */
2670 : BASOP_SATURATE_WARNING_OFF_EVS /* threshold, may overflow */
2671 42068 : tmp = shl_sat( gain[sfb], sub( gain_e[sfb], 15 - 5 ) ); /* 10Q5 | tmp is in 10Q5 */
2672 : BASOP_SATURATE_WARNING_ON_EVS
2673 :
2674 42068 : IF( tmp > 384 ) /* 10Q5 | 384 = 12 in 10Q5 */
2675 : {
2676 5 : gain[sfb] = 384;
2677 5 : move16();
2678 5 : gain_e[sfb] = 10;
2679 5 : move16();
2680 : }
2681 :
2682 42068 : IF( LT_16( hPrivateData->frameLossCounter, 5 ) )
2683 : {
2684 : /* gain[sfb] -= gain[sfb] / 8 * hPrivateData->frameLossCounter; -> multiply with 0Q15 -> adaption of the exponent not needed */
2685 29752 : IF( EQ_16( hPrivateData->frameLossCounter, 1 ) )
2686 : {
2687 : /* 0Q15 | >> 3 ^= * 0.125 = 1 / 8 */
2688 21582 : gain[sfb] = sub( gain[sfb], shr_r( gain[sfb], 3 ) );
2689 21582 : move16();
2690 : }
2691 8170 : ELSE IF( EQ_16( hPrivateData->frameLossCounter, 2 ) )
2692 : {
2693 : /* 0Q15 | >> 2 ^= * 0.25 = 2 / 8 */
2694 6658 : gain[sfb] = sub( gain[sfb], shr_r( gain[sfb], 2 ) );
2695 6658 : move16();
2696 : }
2697 1512 : ELSE IF( EQ_16( hPrivateData->frameLossCounter, 3 ) )
2698 : {
2699 : /* 0Q15 | * 12288 ^= * 0.3750 = 3 / 8 */
2700 914 : gain[sfb] = sub( gain[sfb], mult_r( gain[sfb], 12288 ) );
2701 914 : move16();
2702 : }
2703 : ELSE
2704 : {
2705 : /* 0Q15 | >> 1 ^= * 0.5 = 4 / 8 */
2706 598 : gain[sfb] = sub( gain[sfb], shr_r( gain[sfb], 1 ) );
2707 598 : move16();
2708 : }
2709 : }
2710 : ELSE
2711 : {
2712 : /* gain[sfb] /= 2; -> reduce exponent by 1 */
2713 12316 : gain_e[sfb] = sub( gain_e[sfb], 1 );
2714 12316 : move16();
2715 : }
2716 : }
2717 :
2718 171175532 : FOR( tb = hGrid->swb_offset[sfb]; tb < hGrid->swb_offset[sfb + 1]; tb++ )
2719 : {
2720 : /* multiply the prepared IGF spectrum with the gain */
2721 165645796 : L_tmp2 = 0; /* set L_tmp2 to default value */
2722 165645796 : move32();
2723 165645796 : L_tmp = Mpy_32_16_1( igf_spec[tb], gain[sfb] );
2724 165645796 : L_tmp_e = add( igf_spec_e[tileIdx], gain_e[sfb] );
2725 :
2726 : /* store the finalized IGF spectrum */
2727 165645796 : IF( spectrum[tb] == 0 )
2728 : {
2729 165624847 : spectrum[tb] = L_tmp;
2730 165624847 : move32();
2731 165624847 : spec_e_arr[tb] = L_tmp_e;
2732 165624847 : move16();
2733 165624847 : flag_sparse[tb - IGF_START_MN] = 1;
2734 165624847 : move16();
2735 : }
2736 : ELSE
2737 : {
2738 20949 : virtualSpec[tb - IGF_START_MN] = L_tmp;
2739 20949 : move32();
2740 20949 : vspec_e_arr[tb - IGF_START_MN] = L_tmp_e;
2741 20949 : move16();
2742 20949 : flag_sparse[tb - IGF_START_MN] = 2;
2743 20949 : move16();
2744 : }
2745 : }
2746 : }
2747 :
2748 : Word16 max_e;
2749 572284 : max_e = *spectrum_e;
2750 572284 : move16();
2751 421972508 : FOR( i = 0; i < hGrid->stopLine; i++ )
2752 : {
2753 421400224 : IF( spectrum[i] != 0 )
2754 : {
2755 393652122 : max_e = s_max( max_e, sub( spec_e_arr[i], norm_l( spectrum[i] ) ) );
2756 : }
2757 : }
2758 421972508 : FOR( i = 0; i < hGrid->stopLine; i++ )
2759 : {
2760 421400224 : spectrum[i] = L_shr( spectrum[i], sub( max_e, spec_e_arr[i] ) );
2761 421400224 : move16();
2762 : }
2763 572284 : *spectrum_e = max_e;
2764 572284 : move16();
2765 :
2766 572284 : max_e = *virtualSpec_e;
2767 572284 : move16();
2768 166218080 : FOR( i = hGrid->startLine - IGF_START_MN; i < hGrid->stopLine - IGF_START_MN; i++ )
2769 : {
2770 165645796 : IF( virtualSpec[i] )
2771 : {
2772 5504 : max_e = s_max( max_e, sub( vspec_e_arr[i], norm_l( virtualSpec[i] ) ) );
2773 : }
2774 : }
2775 166218080 : FOR( i = hGrid->startLine - IGF_START_MN; i < hGrid->stopLine - IGF_START_MN; i++ )
2776 : {
2777 165645796 : virtualSpec[i] = L_shr( virtualSpec[i], sub( max_e, vspec_e_arr[i] ) );
2778 165645796 : move16();
2779 : }
2780 572284 : *virtualSpec_e = max_e;
2781 572284 : move16();
2782 572284 : }
2783 :
2784 : /**********************************************************************/ /*
2785 : spectral whitening
2786 : **************************************************************************/
2787 347 : static void IGF_getWhiteSpectralData( const Word32 *in, /**< in: Q31 | MDCT spectrum */
2788 : Word16 s_l, /**< in: Q0 | getScaleFactor32() of in */
2789 : Word32 *out, /**< out: Q31| whitened spectrum */
2790 : const Word16 start, /**< in: Q0 | start MDCT subband index */
2791 : const Word16 stop, /**< in: Q0 | stop MDCT subband index */
2792 : const Word16 level /**< in: Q0 | whitening strength */
2793 : )
2794 : {
2795 : Word16 j;
2796 : Word32 ak; /* moving average */
2797 : Word32 ak_norm;
2798 : Word16 tmp_16;
2799 : Word16 div;
2800 : Word16 nrm_i;
2801 347 : Word16 nrm_tab[] = { 2341 /* 1/14 */, 2521 /* 1/13 */, 2731 /* 1/12 */, 2979 /* 1/11 */, 3277 /* 1/10 */, 3641 /* 1/9 */, 4096 /* 1/8 */, 4681 /* 1/7 */ };
2802 347 : move16();
2803 347 : move16();
2804 347 : move16();
2805 347 : move16();
2806 347 : move16();
2807 347 : move16();
2808 347 : move16();
2809 347 : move16();
2810 :
2811 : /* inits */
2812 347 : div = 0;
2813 347 : move16();
2814 347 : s_l = sub( s_l, 2 );
2815 347 : ak = 0;
2816 347 : move32();
2817 :
2818 5205 : FOR( j = start - level; j < start + level; j++ )
2819 : {
2820 4858 : tmp_16 = extract_h( L_shl( in[j], s_l ) ); // e: in_e - s_l
2821 4858 : ak = L_mac( ak, tmp_16, tmp_16 ); // e: 2 * (in_e - s_l)
2822 : }
2823 76430 : FOR( j = start; j < stop - level; j++ )
2824 : {
2825 76083 : tmp_16 = extract_h( L_shl( in[j + level], s_l ) ); // e: in_e - s_l
2826 76083 : ak = L_mac( ak, tmp_16, tmp_16 ); // e: 2 * (in_e - s_l)
2827 76083 : ak_norm = Mpy_32_16_r( ak, 2185 /* 1/15 in Q15 */ ); // e: 2 * (in_e - s_l)
2828 76083 : tmp_16 = sub( 31, norm_l( ak_norm ) );
2829 :
2830 76083 : if ( ak == 0 )
2831 : {
2832 42 : tmp_16 = 0;
2833 42 : move16();
2834 : }
2835 :
2836 76083 : tmp_16 = s_min( 14, sub( 15, shr( tmp_16, 1 ) ) );
2837 76083 : div = shl( 1, tmp_16 );
2838 76083 : out[j] = Mpy_32_16_1( L_shl( in[j], s_l ), div ); // e: in_e - s_l
2839 76083 : move32();
2840 :
2841 76083 : tmp_16 = extract_h( L_shl( in[j - level], s_l ) ); // e: in_e - s_l
2842 76083 : ak = L_msu( ak, tmp_16, tmp_16 ); // e: 2 * (in_e - s_l)
2843 : }
2844 :
2845 347 : nrm_i = 0;
2846 347 : move16();
2847 :
2848 2776 : FOR( ; j < stop; j++ )
2849 : {
2850 2429 : ak_norm = Mpy_32_16_r( ak, nrm_tab[nrm_i++] ); // e: 2 * (in_e - s_l)
2851 2429 : tmp_16 = sub( 31, norm_l( ak_norm ) );
2852 :
2853 2429 : if ( ak == 0 )
2854 : {
2855 0 : tmp_16 = 0;
2856 0 : move16();
2857 : }
2858 :
2859 2429 : tmp_16 = s_min( 14, sub( 15, shr( tmp_16, 1 ) ) );
2860 2429 : div = shl( 1, tmp_16 );
2861 :
2862 2429 : if ( LT_32( ak, 16 ) )
2863 : {
2864 0 : div = 1;
2865 0 : move16();
2866 : }
2867 :
2868 2429 : out[j] = Mpy_32_16_1( L_shl( in[j], s_l ), div ); // e: in_e - s_l
2869 2429 : move32();
2870 2429 : tmp_16 = extract_h( L_shl( in[j - level], s_l ) ); // e: in_e - s_l
2871 2429 : ak = L_msu( ak, tmp_16, tmp_16 ); // e: 2 * (in_e - s_l)
2872 : }
2873 347 : }
2874 :
2875 : /*-------------------------------------------------------------------*
2876 : * IGF_getWhiteSpectralData_ivas()
2877 : *
2878 : * spectral whitening
2879 : *-------------------------------------------------------------------*/
2880 :
2881 291102 : static void IGF_getWhiteSpectralData_ivas(
2882 : const Word32 *in, /* i : MDCT spectrum */
2883 : const Word16 in_e, /* i : MDCT spectrum exp */
2884 : Word16 s_l, /* i : getScaleFactor32() of in Q0 */
2885 : Word32 *out, /* o : whitened spectrum */
2886 : Word16 *out_e, /* o : whitened spectrum exp */
2887 : const Word16 start, /* i : start MDCT subband index Q0 */
2888 : const Word16 stop, /* i : stop MDCT subband index Q0 */
2889 : const Word16 level /* i : whitening strength Q0 */
2890 : )
2891 : {
2892 : Word16 i;
2893 : Word16 n;
2894 : Word16 j;
2895 : Word32 ak;
2896 : Word16 ak_e;
2897 : Word16 tmp_e;
2898 : Word16 out_e_arr[IGF_START_MX + MAX_IGF_SFB_LEN];
2899 : Word16 max_out_e;
2900 291102 : assert( LT_16( stop, IGF_START_MX + MAX_IGF_SFB_LEN ) );
2901 :
2902 : /* inits */
2903 291102 : ak = 0;
2904 291102 : move16();
2905 291102 : ak_e = 0;
2906 291102 : move16();
2907 291102 : tmp_e = 0;
2908 291102 : move16();
2909 291102 : max_out_e = 0;
2910 291102 : move16();
2911 : /* find the gaurd bits for a length of (i + level + 1) - (i - level)*/
2912 291102 : Word16 guard_bits = add( find_guarded_bits_fx( add( i_mult( 2, level ), 1 ) ), 1 ) / 2;
2913 291102 : s_l = sub( s_l, guard_bits );
2914 :
2915 291102 : Word16 shift = sub( shl( s_l, 1 ), 32 );
2916 291102 : Word16 eff_e = sub( shl( sub( in_e, s_l ), 1 ), 15 );
2917 291102 : Word16 diff = add( 21, in_e );
2918 :
2919 291102 : Word16 quo = BASOP_Util_Divide3216_Scale( ONE_IN_Q30, add( shl( level, 1 ), 1 ), &tmp_e );
2920 291102 : tmp_e = add( tmp_e, 1 );
2921 :
2922 291102 : ak_e = add( tmp_e, sub( shl( sub( in_e, s_l ), 1 ), 15 ) ); // tmp_e + 2 * (in_e - s_l) - 15
2923 291102 : ak_e = sub( ak_e, 1 );
2924 :
2925 118997958 : FOR( i = start; i < stop - level; i++ )
2926 : {
2927 118706856 : Word64 temp = 0;
2928 118706856 : move64();
2929 2374137120 : FOR( j = i - level; j < i + level + 1; j++ )
2930 : {
2931 2255430264 : temp = W_mac_32_32( temp, in[j], in[j] );
2932 : }
2933 118706856 : ak = Mult_32_16( W_shl_sat_l( temp, shift ), quo ); // add( shl( level, 1 ), 1 ), &tmp_e ) );
2934 :
2935 :
2936 118706856 : n = sub( ak_e, norm_l( ak ) );
2937 118706856 : n = shr( n, 1 );
2938 :
2939 118706856 : out_e_arr[i] = sub( diff, n );
2940 118706856 : move16();
2941 118706856 : max_out_e = s_max( max_out_e, out_e_arr[i] );
2942 : }
2943 :
2944 2911020 : FOR( ; i < stop; i++ )
2945 : {
2946 2619918 : Word64 temp = 0;
2947 2619918 : move64();
2948 :
2949 39298770 : FOR( j = i - level; j < stop; j++ )
2950 : {
2951 36678852 : temp = W_mac_32_32( temp, in[j], in[j] );
2952 : }
2953 :
2954 2619918 : ak = L_deposit_h( BASOP_Util_Divide3216_Scale( W_shl_sat_l( temp, shift ), sub( stop, sub( i, level ) ), &tmp_e ) );
2955 2619918 : ak_e = add( tmp_e, eff_e ); // tmp_e + 2 * (in_e - s_l) - 15
2956 2619918 : n = sub( ak_e, add( norm_l( ak ), 1 ) );
2957 2619918 : n = shr( n, 1 );
2958 :
2959 2619918 : out_e_arr[i] = sub( diff, n );
2960 2619918 : move16();
2961 2619918 : max_out_e = s_max( max_out_e, out_e_arr[i] );
2962 : }
2963 :
2964 291102 : *out_e = max_out_e;
2965 291102 : move16();
2966 121617876 : FOR( i = start; i < stop; i++ )
2967 : {
2968 121326774 : out[i] = L_shr( in[i], sub( *out_e, out_e_arr[i] ) );
2969 121326774 : move32();
2970 : }
2971 :
2972 291102 : return;
2973 : }
2974 :
2975 :
2976 : /**********************************************************************/ /*
2977 : refines the IGF grid
2978 : **************************************************************************/
2979 114 : static void IGF_RefineGrid( H_IGF_GRID hGrid /**< in/out: | IGF grid handle */
2980 : )
2981 : {
2982 : Word16 a[IGF_MAX_SFB + 1];
2983 : Word16 sfb;
2984 : Word16 tmp;
2985 : Word16 delta;
2986 : #ifndef ISSUE_1866_replace_overflow_libdec
2987 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2988 : Flag Overflow = 0;
2989 : move16();
2990 : #endif
2991 : #endif
2992 :
2993 114 : set16_fx( a, 0, IGF_MAX_SFB + 1 );
2994 :
2995 :
2996 114 : hGrid->infoIsRefined = 1;
2997 114 : move16();
2998 996 : FOR( sfb = 0; sfb < hGrid->swb_offset_len; sfb++ )
2999 : {
3000 882 : tmp = shl( sfb, 1 );
3001 882 : a[tmp] = hGrid->swb_offset[sfb];
3002 882 : move16();
3003 882 : tmp = add( tmp, 1 );
3004 882 : delta = sub( hGrid->swb_offset[sfb + 1], hGrid->swb_offset[sfb] );
3005 : #ifdef ISSUE_1866_replace_overflow_libdec
3006 882 : delta = mac_r( 0x00195000, 29491 /*0.45f Q16*/, shl_sat( delta, 5 ) );
3007 : #else
3008 : delta = mac_r( 0x00195000, 29491 /*0.45f Q16*/, shl_o( delta, 5, &Overflow ) );
3009 : #endif
3010 882 : a[tmp] = add( hGrid->swb_offset[sfb], shr( delta, 6 ) );
3011 882 : move16();
3012 882 : IF( s_and( a[tmp], 1 ) != 0 )
3013 : {
3014 421 : a[tmp] = sub( a[tmp], 1 );
3015 421 : move16();
3016 : }
3017 : }
3018 114 : hGrid->stopSfb = shl( hGrid->stopSfb, 1 );
3019 114 : move16();
3020 1764 : FOR( sfb = 0; sfb <= hGrid->stopSfb; sfb++ )
3021 : {
3022 1650 : hGrid->swb_offset[sfb] = a[sfb];
3023 1650 : move16();
3024 : }
3025 :
3026 498 : FOR( sfb = 0; sfb <= hGrid->nTiles; sfb++ )
3027 : {
3028 384 : hGrid->sfbWrap[sfb] = shl( hGrid->sfbWrap[sfb], 1 );
3029 384 : move16();
3030 : }
3031 114 : }
3032 :
3033 49506 : static void IGF_RefineGrid_ivas_fx( H_IGF_GRID hGrid /**< in/out: | IGF grid handle */
3034 : )
3035 : {
3036 : Word16 a[IGF_MAX_SFB + 1];
3037 : Word16 sfb;
3038 : Word16 tmp;
3039 : Word16 delta;
3040 : #ifndef ISSUE_1866_replace_overflow_libdec
3041 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
3042 : Flag Overflow = 0;
3043 : move16();
3044 : #endif
3045 : #endif
3046 :
3047 49506 : set16_fx( a, 0, IGF_MAX_SFB + 1 );
3048 :
3049 :
3050 49506 : hGrid->infoIsRefined = 1;
3051 49506 : move16();
3052 443908 : FOR( sfb = 0; sfb < hGrid->swb_offset_len; sfb++ )
3053 : {
3054 394402 : tmp = shl( sfb, 1 );
3055 394402 : a[tmp] = hGrid->swb_offset[sfb];
3056 394402 : move16();
3057 394402 : tmp = add( tmp, 1 );
3058 394402 : delta = sub( hGrid->swb_offset[sfb + 1], hGrid->swb_offset[sfb] );
3059 : #ifdef ISSUE_1796_replace_shl_o
3060 394402 : delta = mac_r( 0x00195000, 29491 /*0.45f Q16*/, shl_sat( delta, 5 ) );
3061 : #else
3062 : delta = mac_r( 0x00195000, 29491 /*0.45f Q16*/, shl_o( delta, 5, &Overflow ) );
3063 : #endif
3064 394402 : a[tmp] = add( hGrid->swb_offset[sfb], shr( delta, 6 ) );
3065 394402 : move16();
3066 : // Rounding off delta values >=t+0.5 to t+1
3067 394402 : IF( GE_16( sub( delta, shl( shr( delta, 6 ), 6 ) ), MID ) )
3068 : {
3069 25420 : a[tmp] = add( a[tmp], 1 );
3070 25420 : move16();
3071 : }
3072 394402 : IF( s_and( a[tmp], 1 ) != 0 )
3073 : {
3074 147147 : a[tmp] = sub( a[tmp], 1 );
3075 147147 : move16();
3076 : }
3077 : }
3078 49506 : hGrid->stopSfb = shl( hGrid->stopSfb, 1 );
3079 49506 : move16();
3080 788804 : FOR( sfb = 0; sfb <= hGrid->stopSfb; sfb++ )
3081 : {
3082 739298 : hGrid->swb_offset[sfb] = a[sfb];
3083 739298 : move16();
3084 : }
3085 :
3086 363771 : FOR( sfb = 0; sfb <= hGrid->nTiles; sfb++ )
3087 : {
3088 314265 : hGrid->sfbWrap[sfb] = shl( hGrid->sfbWrap[sfb], 1 );
3089 314265 : move16();
3090 : }
3091 49506 : }
3092 :
3093 : /**********************************************************************/ /*
3094 : reads whitening information from the bitstream
3095 : **************************************************************************/
3096 360345 : void IGFDecReadData_ivas_fx( const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Deccoder */
3097 : Decoder_State *st, /**< in: | decoder state */
3098 : const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */
3099 : const Word16 isIndepFrame /**< in: Q0 | if 1: arith dec force reset, if 0: no reset */
3100 : )
3101 : {
3102 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData;
3103 : H_IGF_GRID hGrid;
3104 : Word16 p;
3105 : Word16 nT;
3106 : Word16 tmp;
3107 :
3108 :
3109 360345 : IF( hInstance != NULL )
3110 : {
3111 360345 : hPrivateData = &hInstance->igfData;
3112 360345 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
3113 360345 : nT = hGrid->nTiles;
3114 360345 : move16();
3115 360345 : tmp = 0;
3116 360345 : move16();
3117 :
3118 : /* set/reset all values to default = IGF_WHITENING_OFF */
3119 3963795 : FOR( p = 0; p < IGF_MAX_TILES; p++ )
3120 : {
3121 3603450 : hPrivateData->currWhiteningLevel[p] = IGF_WHITENING_OFF; // Q0
3122 3603450 : move16();
3123 : }
3124 :
3125 360345 : IF( isIndepFrame == 0 )
3126 : {
3127 9326 : tmp = get_next_indice_fx( st, 1 ); // Q0
3128 : }
3129 :
3130 360345 : IF( tmp == 1 )
3131 : {
3132 31725 : FOR( p = 0; p < nT; p++ )
3133 : {
3134 23051 : hPrivateData->currWhiteningLevel[p] = hPrivateData->prevWhiteningLevel[p]; // Q0
3135 23051 : move16();
3136 : }
3137 : }
3138 : ELSE
3139 : {
3140 351671 : IGF_decode_whitening_level( st, hPrivateData, 0 );
3141 351671 : test();
3142 351671 : IF( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_48000_CPE ) )
3143 : {
3144 73950 : tmp = 0;
3145 73950 : move16();
3146 : }
3147 : ELSE
3148 : {
3149 277721 : tmp = get_next_indice_fx( st, 1 ); // Q0
3150 : }
3151 :
3152 351671 : IF( EQ_16( tmp, 1 ) )
3153 : {
3154 406018 : FOR( p = 1; p < nT; p++ )
3155 : {
3156 204279 : IGF_decode_whitening_level( st, hPrivateData, p );
3157 : }
3158 : }
3159 : ELSE
3160 : {
3161 710852 : FOR( p = 1; p < nT; p++ )
3162 : {
3163 560920 : hPrivateData->currWhiteningLevel[p] = hPrivateData->currWhiteningLevel[0]; // Q0
3164 560920 : move16();
3165 : }
3166 : }
3167 : }
3168 :
3169 : /* save current level for concealment */
3170 3963795 : FOR( p = 0; p < IGF_MAX_TILES; p++ )
3171 : {
3172 3603450 : hPrivateData->prevWhiteningLevel[p] = hPrivateData->currWhiteningLevel[p]; // Q0
3173 3603450 : move16();
3174 : }
3175 :
3176 : /* read flattening trigger from bitstream */
3177 360345 : IGF_decode_temp_flattening_trigger( st, hInstance );
3178 : }
3179 360345 : }
3180 :
3181 209386 : void IGFDecReadData( const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Deccoder */
3182 : Decoder_State *st, /**< in: | decoder state */
3183 : const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */
3184 : const Word16 isIndepFrame /**< in: Q0 | if 1: arith dec force reset, if 0: no reset */
3185 : )
3186 : {
3187 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData;
3188 : H_IGF_GRID hGrid;
3189 : Word16 p;
3190 : Word16 nT;
3191 : Word16 tmp;
3192 :
3193 :
3194 209386 : IF( hInstance != NULL )
3195 : {
3196 209386 : hPrivateData = &hInstance->igfData;
3197 209386 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
3198 209386 : nT = hGrid->nTiles;
3199 209386 : move16();
3200 209386 : tmp = 0;
3201 209386 : move16();
3202 :
3203 : /* set/reset all values to default = IGF_WHITENING_OFF */
3204 2303246 : FOR( p = 0; p < IGF_MAX_TILES; p++ )
3205 : {
3206 2093860 : hPrivateData->currWhiteningLevel[p] = IGF_WHITENING_OFF; // Q0
3207 2093860 : move16();
3208 : }
3209 :
3210 209386 : IF( isIndepFrame == 0 )
3211 : {
3212 1893 : tmp = get_next_indice_fx( st, 1 ); // Q0
3213 : }
3214 :
3215 209386 : IF( EQ_16( tmp, 1 ) )
3216 : {
3217 3786 : FOR( p = 0; p < nT; p++ )
3218 : {
3219 1893 : hPrivateData->currWhiteningLevel[p] = hPrivateData->prevWhiteningLevel[p]; // Q0
3220 1893 : move16();
3221 : }
3222 : }
3223 : ELSE
3224 : {
3225 207493 : IGF_decode_whitening_level( st, hPrivateData, 0 );
3226 207493 : tmp = get_next_indice_fx( st, 1 ); // Q0
3227 207493 : IF( EQ_16( tmp, 1 ) )
3228 : {
3229 581786 : FOR( p = 1; p < nT; p++ )
3230 : {
3231 407123 : IGF_decode_whitening_level( st, hPrivateData, p );
3232 : }
3233 : }
3234 : ELSE
3235 : {
3236 193186 : FOR( p = 1; p < nT; p++ )
3237 : {
3238 160356 : hPrivateData->currWhiteningLevel[p] = hPrivateData->currWhiteningLevel[0]; // Q0
3239 160356 : move16();
3240 : }
3241 : }
3242 : }
3243 :
3244 : /* save current level for concealment */
3245 2303246 : FOR( p = 0; p < IGF_MAX_TILES; p++ )
3246 : {
3247 2093860 : hPrivateData->prevWhiteningLevel[p] = hPrivateData->currWhiteningLevel[p]; // Q0
3248 2093860 : move16();
3249 : }
3250 :
3251 : /* read flattening trigger from bitstream */
3252 209386 : IGF_decode_temp_flattening_trigger( st, hInstance );
3253 : }
3254 209386 : }
3255 :
3256 : /**********************************************************************/ /*
3257 : read the IGF level information from the bitsream
3258 : **************************************************************************/
3259 569731 : void IGFDecReadLevel( /**< out: Q0 | return igfAllZero flag indicating if no envelope is transmitted */
3260 : const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */
3261 : Decoder_State *st, /**< in: | decoder state */
3262 : const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */
3263 : const Word16 isIndepFrame /**< in: Q0 | if 1: arith dec force reset, if 0: no reset */
3264 : )
3265 : {
3266 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData;
3267 : H_IGF_GRID hGrid;
3268 : Word16 m_igfSfbStart;
3269 : Word16 IGFAllZero;
3270 :
3271 569731 : IGFAllZero = 1;
3272 569731 : move16();
3273 :
3274 569731 : IF( hInstance != NULL )
3275 : {
3276 569731 : hPrivateData = &hInstance->igfData;
3277 569731 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
3278 569731 : m_igfSfbStart = hGrid->startSfb;
3279 569731 : move16();
3280 569731 : IGFAllZero = get_next_indice_fx( st, 1 ); // Q0
3281 :
3282 569731 : IF( IGFAllZero == 0 )
3283 : {
3284 569330 : Copy( hPrivateData->igf_curr, hPrivateData->igf_prev, hGrid->stopSfb );
3285 569330 : IGFSCFDecoderDecode( &hPrivateData->hArithSCFdec, st, &hPrivateData->igf_curr[m_igfSfbStart], /* 0Q15, hPrivateData->igf_curr = [0, 91] */ igfGridIdx, isIndepFrame );
3286 : }
3287 : ELSE
3288 : {
3289 401 : IGFSCFDecoderReset( &hPrivateData->hArithSCFdec );
3290 401 : set16_fx( &hPrivateData->igf_curr[m_igfSfbStart], 0, sub( hGrid->stopSfb, m_igfSfbStart ) );
3291 : }
3292 : }
3293 :
3294 569731 : hInstance->infoIGFAllZero = IGFAllZero;
3295 569731 : move16();
3296 569731 : }
3297 :
3298 : /**********************************************************************/ /*
3299 : apply the IGF decoder
3300 : **************************************************************************/
3301 646 : void IGFDecApplyMono( const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */
3302 : Word32 *spectrum, /**< in/out: | MDCT spectrum */
3303 : Word16 *spectrum_e, /**< in/out: | exponent of spectrum */
3304 : const Word16 igfGridIdx, /**< in: | in case of CELP->TCX switching, use 1.25 framelength */
3305 : Word16 bfi /**< in: | frame loss == 1, frame good == 0 */
3306 : )
3307 : {
3308 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData;
3309 : H_IGF_GRID hGrid;
3310 : Word16 i;
3311 : Word16 whiteningLevel;
3312 : Word16 s_l; /* | headroom of pSpecFlat */
3313 : Word16 specMed_e; /* | exponent of the medium whitened spectrum */
3314 : Word32 igf_spec[IGF_MAX_GRANULE_LEN]; /* Q31 | prepared IGF spectrum */
3315 : Word16 igf_spec_e[IGF_MAX_TILES]; /* | exponents of igf_spec, one exponent per tile */
3316 :
3317 :
3318 646 : hPrivateData = &hInstance->igfData;
3319 646 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
3320 :
3321 : /* initialize variables */
3322 646 : whiteningLevel = 7;
3323 646 : move16();
3324 646 : specMed_e = 0;
3325 646 : move16();
3326 646 : hPrivateData->n_noise_bands = 0;
3327 646 : move16();
3328 646 : hPrivateData->n_noise_bands_off = 0;
3329 646 : move16();
3330 646 : hPrivateData->headroom_TCX_noise_white = 0;
3331 646 : move16();
3332 646 : hPrivateData->headroom_TCX_noise = 0;
3333 646 : move16();
3334 646 : hPrivateData->totalNoiseNrg = 0;
3335 646 : move32();
3336 646 : hPrivateData->totalNoiseNrg_off = 0;
3337 646 : move32();
3338 :
3339 646 : set32_fx( igf_spec, 0, IGF_MAX_GRANULE_LEN );
3340 646 : set16_fx( igf_spec_e, 0, IGF_MAX_TILES );
3341 :
3342 : /* concealment counter */
3343 646 : IF( bfi != 0 )
3344 : {
3345 0 : hPrivateData->frameLossCounter = add( hPrivateData->frameLossCounter, 1 );
3346 0 : move16();
3347 : }
3348 : ELSE
3349 : {
3350 646 : hPrivateData->frameLossCounter = 0;
3351 646 : move16();
3352 : }
3353 :
3354 : /* skip IGF processing if all IGF levels are zero */
3355 646 : IF( hInstance->infoIGFAllZero == 0 )
3356 : {
3357 :
3358 :
3359 1442 : FOR( i = 0; i < hGrid->nTiles; i++ )
3360 : {
3361 1143 : IF( EQ_16( hPrivateData->currWhiteningLevel[i], IGF_WHITENING_MID ) )
3362 : {
3363 347 : s_l = getScaleFactor32( hPrivateData->pSpecFlat + hGrid->minSrcSubband - whiteningLevel,
3364 347 : add( sub( hGrid->startLine, hGrid->minSrcSubband ), whiteningLevel ) );
3365 :
3366 347 : specMed_e = hPrivateData->pSpecFlat_exp;
3367 347 : move16();
3368 347 : IGF_getWhiteSpectralData( hPrivateData->pSpecFlat,
3369 : s_l,
3370 : igf_spec,
3371 347 : hGrid->minSrcSubband,
3372 347 : hGrid->startLine,
3373 : whiteningLevel );
3374 :
3375 : /*14 seems to be precise enough*/
3376 694 : hPrivateData->headroom_TCX_noise_white = IGF_getScaleFactor32Cond( hInstance->infoTCXNoise_evs + hGrid->minSrcSubband,
3377 347 : igf_spec + hGrid->minSrcSubband,
3378 347 : sub( hGrid->startLine, hGrid->minSrcSubband ) );
3379 694 : hPrivateData->n_noise_bands = IGF_replaceTCXNoise_1( igf_spec,
3380 347 : hPrivateData->headroom_TCX_noise_white,
3381 347 : hInstance->infoTCXNoise_evs,
3382 347 : hGrid->minSrcSubband,
3383 347 : hGrid->startLine,
3384 : &hPrivateData->totalNoiseNrg );
3385 347 : move16();
3386 347 : move16();
3387 :
3388 347 : BREAK;
3389 : }
3390 : }
3391 :
3392 1920 : FOR( i = 0; i < hGrid->nTiles; i++ )
3393 : {
3394 1442 : IF( hPrivateData->currWhiteningLevel[i] == IGF_WHITENING_OFF )
3395 : {
3396 336 : hPrivateData->headroom_TCX_noise = IGF_getScaleFactor32Cond( hInstance->infoTCXNoise_evs + hGrid->minSrcSubband,
3397 168 : hPrivateData->pSpecFlat + hGrid->minSrcSubband,
3398 168 : sub( hGrid->startLine, hGrid->minSrcSubband ) );
3399 :
3400 336 : hPrivateData->n_noise_bands_off = IGF_replaceTCXNoise_1( hPrivateData->pSpecFlat,
3401 168 : hPrivateData->headroom_TCX_noise,
3402 168 : hInstance->infoTCXNoise_evs,
3403 168 : hGrid->minSrcSubband,
3404 168 : hGrid->startLine,
3405 : &hPrivateData->totalNoiseNrg_off );
3406 168 : move16();
3407 168 : move16();
3408 :
3409 168 : BREAK;
3410 : }
3411 : }
3412 :
3413 : /* apply IGF in three steps: */
3414 646 : IGF_prep( hPrivateData,
3415 : igfGridIdx,
3416 646 : hInstance->infoTCXNoise_evs,
3417 : igf_spec,
3418 : igf_spec_e,
3419 646 : hPrivateData->pSpecFlat,
3420 646 : hPrivateData->pSpecFlat_exp,
3421 : specMed_e );
3422 646 : IGF_calc( hPrivateData,
3423 : igfGridIdx,
3424 : spectrum,
3425 646 : *spectrum_e,
3426 : igf_spec,
3427 : igf_spec_e );
3428 646 : IGF_appl( hPrivateData,
3429 : igfGridIdx,
3430 : spectrum,
3431 : spectrum_e,
3432 : igf_spec,
3433 : igf_spec_e,
3434 646 : hInstance->virtualSpec,
3435 : &hInstance->virtualSpec_e,
3436 646 : hInstance->flag_sparseBuf );
3437 : }
3438 :
3439 : /* reset TCX noise indicator vector */
3440 646 : set16_fx( hInstance->infoTCXNoise_evs, 0, IGF_START_MX );
3441 646 : }
3442 :
3443 : /**********************************************************************/ /*
3444 : apply the IGF decoder (for IVAS)
3445 : **************************************************************************/
3446 399094 : void IGFDecApplyMono_ivas( const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */
3447 : Word32 *spectrum, /**< in/out: | MDCT spectrum */
3448 : Word16 *spectrum_e, /**< in/out: | exponent of spectrum */
3449 : const Word16 igfGridIdx, /**< in: | in case of CELP->TCX switching, use 1.25 framelength */
3450 : Word16 bfi, /**< in: | frame loss == 1, frame good == 0 */
3451 : Word16 element_mode /**< in: | IVAS element mode */
3452 : )
3453 : {
3454 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData;
3455 : H_IGF_GRID hGrid;
3456 : Word16 i;
3457 : Word16 whiteningLevel;
3458 : Word16 s_l; /* | headroom of pSpecFlat */
3459 : Word16 specMed_e; /* | exponent of the medium whitened spectrum */
3460 : Word32 igf_spec[IGF_MAX_GRANULE_LEN]; /* Q31 | prepared IGF spectrum */
3461 : Word16 igf_spec_e[IGF_MAX_TILES]; /* | exponents of igf_spec, one exponent per tile */
3462 : Word16 len;
3463 :
3464 399094 : hPrivateData = &hInstance->igfData;
3465 399094 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
3466 :
3467 : /* initialize variables */
3468 :
3469 399094 : IF( GT_16( element_mode, EVS_MONO ) )
3470 : {
3471 399094 : whiteningLevel = IGF_MID_WHITENING_LEVEL2;
3472 399094 : move16();
3473 : }
3474 : ELSE
3475 : {
3476 0 : whiteningLevel = IGF_MID_WHITENING_LEVEL;
3477 0 : move16();
3478 : }
3479 :
3480 399094 : IF( EQ_16( igfGridIdx, IGF_GRID_LB_SHORT ) )
3481 : {
3482 13510 : len = ( N_MAX_TCX - IGF_START_MN ) / 2;
3483 13510 : move16();
3484 : }
3485 : ELSE
3486 : {
3487 385584 : len = ( N_MAX_TCX - IGF_START_MN );
3488 385584 : move16();
3489 : }
3490 :
3491 399094 : set16_fx( hInstance->flag_sparse, 0, len );
3492 399094 : set32_fx( hInstance->virtualSpec_fx, 0, len );
3493 399094 : hInstance->virtualSpec_e = 0;
3494 399094 : move16();
3495 :
3496 399094 : specMed_e = 0;
3497 399094 : move16();
3498 399094 : hPrivateData->n_noise_bands = 0;
3499 399094 : move16();
3500 399094 : hPrivateData->n_noise_bands_off = 0;
3501 399094 : move16();
3502 399094 : hPrivateData->headroom_TCX_noise_white = 0;
3503 399094 : move16();
3504 399094 : hPrivateData->headroom_TCX_noise = 0;
3505 399094 : move16();
3506 399094 : hPrivateData->totalNoiseNrg = 0;
3507 399094 : move32();
3508 399094 : hPrivateData->totalNoiseNrg_off = 0;
3509 399094 : move32();
3510 399094 : hPrivateData->restrict_hopsize = 0;
3511 399094 : move16();
3512 :
3513 399094 : set32_fx( igf_spec, 0, IGF_MAX_GRANULE_LEN );
3514 399094 : set16_fx( igf_spec_e, 0, IGF_MAX_TILES );
3515 :
3516 : /* concealment counter */
3517 399094 : IF( bfi != 0 )
3518 : {
3519 3195 : hPrivateData->frameLossCounter = add( hPrivateData->frameLossCounter, 1 );
3520 3195 : move16();
3521 : }
3522 : ELSE
3523 : {
3524 395899 : hPrivateData->frameLossCounter = 0;
3525 395899 : move16();
3526 : }
3527 :
3528 : /* skip IGF processing if all IGF levels are zero */
3529 399094 : IF( hInstance->infoIGFAllZero == 0 )
3530 : {
3531 1130445 : FOR( i = 0; i < hGrid->nTiles; i++ )
3532 : {
3533 916040 : IF( EQ_16( hPrivateData->currWhiteningLevel[i], IGF_WHITENING_MID ) )
3534 : {
3535 184361 : test();
3536 184361 : IF( EQ_16( element_mode, EVS_MONO ) || !bfi )
3537 : {
3538 183350 : s_l = getScaleFactor32( hPrivateData->pSpecFlat + hGrid->minSrcSubband - whiteningLevel,
3539 183350 : add( sub( hGrid->startLine, hGrid->minSrcSubband ), whiteningLevel ) );
3540 :
3541 183350 : IGF_getWhiteSpectralData_ivas( hPrivateData->pSpecFlat,
3542 183350 : hPrivateData->pSpecFlat_exp,
3543 : s_l,
3544 : igf_spec,
3545 183350 : &igf_spec_e[i],
3546 183350 : hGrid->minSrcSubband,
3547 183350 : hGrid->startLine,
3548 : whiteningLevel );
3549 : }
3550 : ELSE
3551 : {
3552 1011 : Copy32( hPrivateData->pSpecFlat, igf_spec, hGrid->startLine );
3553 1011 : igf_spec_e[i] = hPrivateData->pSpecFlat_exp,
3554 1011 : move16();
3555 : }
3556 184361 : specMed_e = igf_spec_e[i];
3557 184361 : move16();
3558 :
3559 368722 : hPrivateData->n_noise_bands = ivas_IGF_replaceTCXNoise_1_fx( igf_spec,
3560 184361 : igf_spec_e[i],
3561 184361 : hInstance->infoTCXNoise_ptr,
3562 184361 : hGrid->minSrcSubband,
3563 184361 : hGrid->startLine,
3564 : &hPrivateData->totalNoiseNrg,
3565 : &hPrivateData->totalNoiseNrg_exp );
3566 184361 : move16();
3567 :
3568 184361 : BREAK;
3569 : }
3570 : }
3571 :
3572 :
3573 1047912 : FOR( i = 0; i < hGrid->nTiles; i++ )
3574 : {
3575 832032 : IF( EQ_16( hPrivateData->currWhiteningLevel[i], IGF_WHITENING_OFF ) )
3576 : {
3577 :
3578 365772 : hPrivateData->n_noise_bands_off = ivas_IGF_replaceTCXNoise_1_fx( hPrivateData->pSpecFlat,
3579 182886 : hPrivateData->pSpecFlat_exp,
3580 182886 : hInstance->infoTCXNoise_ptr,
3581 182886 : hGrid->minSrcSubband,
3582 182886 : hGrid->startLine,
3583 : &hPrivateData->totalNoiseNrg_off,
3584 : &hPrivateData->totalNoiseNrg_off_exp );
3585 182886 : move16();
3586 182886 : BREAK;
3587 : }
3588 : }
3589 :
3590 398766 : IGF_prep_ivas( hPrivateData,
3591 : igfGridIdx,
3592 398766 : hInstance->infoTCXNoise_ptr,
3593 : igf_spec,
3594 : igf_spec_e,
3595 : hPrivateData->pSpecFlat,
3596 398766 : hPrivateData->pSpecFlat_exp,
3597 : specMed_e,
3598 : element_mode );
3599 398766 : IGF_calc_ivas( hPrivateData,
3600 : igfGridIdx,
3601 : spectrum,
3602 398766 : *spectrum_e,
3603 : igf_spec,
3604 : igf_spec_e );
3605 398766 : IGF_appl_ivas( hPrivateData,
3606 : igfGridIdx,
3607 : spectrum,
3608 : spectrum_e,
3609 : igf_spec,
3610 : igf_spec_e,
3611 398766 : hInstance->virtualSpec,
3612 : &hInstance->virtualSpec_e,
3613 398766 : hInstance->flag_sparseBuf,
3614 : 1 );
3615 : }
3616 :
3617 : /* reset TCX noise indicator vector */
3618 399094 : IF( EQ_16( igfGridIdx, IGF_GRID_LB_SHORT ) )
3619 : {
3620 13510 : set16_fx( hInstance->infoTCXNoise_ptr, 0, IGF_START_MX / 2 );
3621 : }
3622 : ELSE
3623 : {
3624 385584 : set16_fx( hInstance->infoTCXNoise_ptr, 0, IGF_START_MX );
3625 : }
3626 399094 : }
3627 :
3628 : /**********************************************************************/ /*
3629 : apply the IGF decoder in stereo
3630 : **************************************************************************/
3631 86760 : void IGFDecApplyStereo(
3632 : const IGF_DEC_INSTANCE_HANDLE hIGFDecL, /* i : instance handle of IGF Decoder */
3633 : const IGF_DEC_INSTANCE_HANDLE hIGFDecR, /* i : instance handle of IGF Decoder */
3634 : Word32 *spectrumL_fx, /* i/o: L MDCT spectrum */
3635 : Word16 *spectrumL_e, /* i/o: L MDCT spectrum exp */
3636 : Word32 *spectrumR_fx, /* i/o: R MDCT spectrum */
3637 : Word16 *spectrumR_e, /* i/o: R MDCT spectrum exp */
3638 : const Word16 igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */
3639 : const Word16 *coreMsMask,
3640 : const Word16 restrict_hopsize,
3641 : const Word16 bfi, /* i : frame loss == 1, frame good == 0 */
3642 : const Word16 bfi_apply_damping )
3643 : {
3644 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateDataL, hPrivateDataR;
3645 : H_IGF_GRID hGrid;
3646 : Word16 i, whiteningLevel;
3647 : Word32 igf_specL_fx[IGF_MAX_GRANULE_LEN];
3648 : Word32 igf_specR_fx[IGF_MAX_GRANULE_LEN];
3649 : Word16 igf_specL_e[IGF_MAX_TILES];
3650 : Word16 igf_specR_e[IGF_MAX_TILES];
3651 : Word16 igf_specL_e_arr[IGF_MAX_GRANULE_LEN];
3652 : Word16 igf_specR_e_arr[IGF_MAX_GRANULE_LEN];
3653 :
3654 : Word16 specMedL_e; /* | exponent of the medium whitened spectrum */
3655 : Word16 specMedR_e; /* | exponent of the medium whitened spectrum */
3656 : Word16 v_len;
3657 : Word16 s_l;
3658 :
3659 86760 : set32_fx( igf_specL_fx, 0, IGF_MAX_GRANULE_LEN );
3660 86760 : set32_fx( igf_specR_fx, 0, IGF_MAX_GRANULE_LEN );
3661 86760 : set16_fx( igf_specL_e, 0, IGF_MAX_TILES );
3662 86760 : set16_fx( igf_specR_e, 0, IGF_MAX_TILES );
3663 86760 : set16_fx( igf_specL_e_arr, 0, IGF_MAX_GRANULE_LEN );
3664 86760 : set16_fx( igf_specR_e_arr, 0, IGF_MAX_GRANULE_LEN );
3665 :
3666 : /* initialize variables */
3667 86760 : whiteningLevel = IGF_MID_WHITENING_LEVEL2;
3668 86760 : move16();
3669 :
3670 86760 : IF( EQ_16( igfGridIdx, IGF_GRID_LB_SHORT ) )
3671 : {
3672 4484 : v_len = ( N_MAX_TCX - IGF_START_MN ) / 2;
3673 4484 : move16();
3674 : }
3675 : ELSE
3676 : {
3677 82276 : v_len = ( N_MAX_TCX - IGF_START_MN );
3678 82276 : move16();
3679 : }
3680 :
3681 86760 : set16_fx( hIGFDecL->flag_sparse, 0, v_len );
3682 86760 : set16_fx( hIGFDecR->flag_sparse, 0, v_len );
3683 :
3684 86760 : set32_fx( hIGFDecL->virtualSpec_fx, 0, v_len );
3685 86760 : set32_fx( hIGFDecR->virtualSpec_fx, 0, v_len );
3686 :
3687 86760 : hPrivateDataL = &hIGFDecL->igfData;
3688 86760 : hGrid = &hPrivateDataL->igfInfo.grid[igfGridIdx];
3689 86760 : hPrivateDataL->n_noise_bands = 0;
3690 86760 : move16();
3691 86760 : hPrivateDataL->n_noise_bands_off = 0;
3692 86760 : move16();
3693 86760 : hPrivateDataL->restrict_hopsize = restrict_hopsize;
3694 86760 : move16();
3695 :
3696 86760 : hPrivateDataR = &hIGFDecR->igfData;
3697 86760 : hPrivateDataR->n_noise_bands = 0;
3698 86760 : move16();
3699 86760 : hPrivateDataR->n_noise_bands_off = 0;
3700 86760 : move16();
3701 86760 : hPrivateDataR->restrict_hopsize = restrict_hopsize;
3702 86760 : move16();
3703 :
3704 86760 : specMedL_e = 0;
3705 86760 : move16();
3706 86760 : specMedR_e = 0;
3707 86760 : move16();
3708 86760 : hPrivateDataL->totalNoiseNrg = 0;
3709 86760 : move32();
3710 86760 : hPrivateDataL->totalNoiseNrg_off = 0;
3711 86760 : move32();
3712 86760 : hPrivateDataR->totalNoiseNrg = 0;
3713 86760 : move32();
3714 86760 : hPrivateDataR->totalNoiseNrg_off = 0;
3715 86760 : move32();
3716 86760 : hPrivateDataL->totalNoiseNrg_exp = 0;
3717 86760 : move16();
3718 86760 : hPrivateDataL->totalNoiseNrg_off_exp = 0;
3719 86760 : move16();
3720 86760 : hPrivateDataR->totalNoiseNrg_exp = 0;
3721 86760 : move16();
3722 86760 : hPrivateDataR->totalNoiseNrg_off_exp = 0;
3723 86760 : move16();
3724 :
3725 : /* concealment counter */
3726 86760 : IF( bfi )
3727 : {
3728 167 : hPrivateDataL->frameLossCounter = add( hPrivateDataL->frameLossCounter, 1 );
3729 167 : hPrivateDataR->frameLossCounter = add( hPrivateDataR->frameLossCounter, 1 );
3730 167 : move16();
3731 167 : move16();
3732 : }
3733 : ELSE
3734 : {
3735 86593 : hPrivateDataL->frameLossCounter = 0;
3736 86593 : move16();
3737 86593 : hPrivateDataR->frameLossCounter = 0;
3738 86593 : move16();
3739 : }
3740 :
3741 : /* skip IGF processing if all IGF levels are zero */
3742 86760 : test();
3743 86760 : IF( !hIGFDecL->infoIGFAllZero || !hIGFDecR->infoIGFAllZero )
3744 : {
3745 224446 : FOR( i = 0; i < hGrid->nTiles; i++ )
3746 : {
3747 191633 : test();
3748 191633 : IF( EQ_16( hPrivateDataL->currWhiteningLevel[i], IGF_WHITENING_MID ) || EQ_16( hPrivateDataR->currWhiteningLevel[i], IGF_WHITENING_MID ) )
3749 : {
3750 53946 : IF( !bfi )
3751 : {
3752 53876 : s_l = getScaleFactor32( hPrivateDataL->pSpecFlat + sub( hGrid->minSrcSubband, whiteningLevel ),
3753 53876 : add( sub( hGrid->startLine, hGrid->minSrcSubband ), whiteningLevel ) );
3754 53876 : IGF_getWhiteSpectralData_ivas( hPrivateDataL->pSpecFlat,
3755 53876 : hPrivateDataL->pSpecFlat_exp,
3756 : s_l,
3757 : igf_specL_fx,
3758 : &specMedL_e,
3759 53876 : hGrid->minSrcSubband,
3760 53876 : hGrid->startLine,
3761 : whiteningLevel );
3762 : }
3763 : ELSE
3764 : {
3765 70 : Copy32( hPrivateDataL->pSpecFlat, igf_specL_fx, hGrid->startLine );
3766 70 : specMedL_e = hPrivateDataL->pSpecFlat_exp;
3767 70 : move16();
3768 : }
3769 :
3770 :
3771 107892 : hPrivateDataL->n_noise_bands = ivas_IGF_replaceTCXNoise_1_fx( igf_specL_fx,
3772 : specMedL_e,
3773 53946 : hIGFDecL->infoTCXNoise_ptr,
3774 53946 : hGrid->minSrcSubband,
3775 53946 : hGrid->startLine,
3776 : &hPrivateDataL->totalNoiseNrg,
3777 : &hPrivateDataL->totalNoiseNrg_exp );
3778 53946 : move16();
3779 :
3780 53946 : IF( !bfi )
3781 : {
3782 53876 : s_l = getScaleFactor32( hPrivateDataR->pSpecFlat + hGrid->minSrcSubband - whiteningLevel,
3783 53876 : add( sub( hGrid->startLine, hGrid->minSrcSubband ), whiteningLevel ) );
3784 53876 : IGF_getWhiteSpectralData_ivas( hPrivateDataR->pSpecFlat,
3785 53876 : hPrivateDataR->pSpecFlat_exp,
3786 : s_l,
3787 : igf_specR_fx,
3788 : &specMedR_e,
3789 53876 : hGrid->minSrcSubband,
3790 53876 : hGrid->startLine,
3791 : whiteningLevel );
3792 : }
3793 : ELSE
3794 : {
3795 70 : Copy32( hPrivateDataR->pSpecFlat, igf_specR_fx, hGrid->startLine );
3796 70 : specMedR_e = hPrivateDataL->pSpecFlat_exp;
3797 70 : move16();
3798 : }
3799 :
3800 107892 : hPrivateDataR->n_noise_bands = ivas_IGF_replaceTCXNoise_1_fx( igf_specR_fx,
3801 : specMedR_e,
3802 53946 : hIGFDecR->infoTCXNoise_ptr,
3803 53946 : hGrid->minSrcSubband,
3804 53946 : hGrid->startLine,
3805 : &hPrivateDataR->totalNoiseNrg,
3806 : &hPrivateDataR->totalNoiseNrg_exp );
3807 53946 : move16();
3808 53946 : BREAK;
3809 : }
3810 : }
3811 :
3812 180145 : FOR( i = 0; i < hGrid->nTiles; i++ )
3813 : {
3814 143332 : test();
3815 143332 : IF( EQ_16( hPrivateDataL->currWhiteningLevel[i], IGF_WHITENING_OFF ) || EQ_16( hPrivateDataR->currWhiteningLevel[i], IGF_WHITENING_OFF ) )
3816 : {
3817 99892 : hPrivateDataL->n_noise_bands_off = ivas_IGF_replaceTCXNoise_1_fx( hPrivateDataL->pSpecFlat,
3818 49946 : hPrivateDataL->pSpecFlat_exp,
3819 49946 : hIGFDecL->infoTCXNoise_ptr,
3820 49946 : hGrid->minSrcSubband,
3821 49946 : hGrid->startLine,
3822 : &hPrivateDataL->totalNoiseNrg_off,
3823 : &hPrivateDataL->totalNoiseNrg_off_exp );
3824 49946 : move16();
3825 :
3826 99892 : hPrivateDataR->n_noise_bands_off = ivas_IGF_replaceTCXNoise_1_fx( hPrivateDataR->pSpecFlat,
3827 49946 : hPrivateDataR->pSpecFlat_exp,
3828 49946 : hIGFDecR->infoTCXNoise_ptr,
3829 49946 : hGrid->minSrcSubband,
3830 49946 : hGrid->startLine,
3831 : &hPrivateDataR->totalNoiseNrg_off,
3832 : &hPrivateDataR->totalNoiseNrg_off_exp );
3833 49946 : move16();
3834 49946 : BREAK;
3835 : }
3836 : }
3837 :
3838 : /* apply IGF in three steps: */
3839 86759 : IF( specMedL_e )
3840 : {
3841 53946 : set16_fx( igf_specL_e_arr + hGrid->minSrcSubband, specMedL_e, sub( hGrid->stopLine, hGrid->minSrcSubband ) );
3842 : }
3843 86759 : IF( specMedR_e )
3844 : {
3845 53946 : set16_fx( igf_specR_e_arr + hGrid->minSrcSubband, specMedR_e, sub( hGrid->stopLine, hGrid->minSrcSubband ) );
3846 : }
3847 :
3848 86759 : IGF_prepStereo( hPrivateDataL,
3849 : hPrivateDataR,
3850 : igfGridIdx,
3851 86759 : hIGFDecL->infoTCXNoise_ptr,
3852 86759 : hIGFDecR->infoTCXNoise_ptr,
3853 : igf_specL_fx,
3854 : igf_specL_e_arr,
3855 : igf_specR_fx,
3856 : igf_specR_e_arr,
3857 : hPrivateDataL->pSpecFlat,
3858 86759 : hPrivateDataL->pSpecFlat_exp,
3859 : hPrivateDataR->pSpecFlat,
3860 86759 : hPrivateDataR->pSpecFlat_exp,
3861 : coreMsMask );
3862 :
3863 86759 : IGF_convert_exponent_per_idx_to_per_tile(
3864 : hGrid,
3865 : igf_specL_fx,
3866 : igf_specL_e_arr,
3867 : igf_specL_e );
3868 86759 : IGF_convert_exponent_per_idx_to_per_tile(
3869 : hGrid,
3870 : igf_specR_fx,
3871 : igf_specR_e_arr,
3872 : igf_specR_e );
3873 :
3874 86759 : IGF_calc_ivas( hPrivateDataL,
3875 : igfGridIdx,
3876 : spectrumL_fx,
3877 86759 : *spectrumL_e,
3878 : igf_specL_fx,
3879 : igf_specL_e );
3880 86759 : IGF_calc_ivas( hPrivateDataR,
3881 : igfGridIdx,
3882 : spectrumR_fx,
3883 86759 : *spectrumR_e,
3884 : igf_specR_fx,
3885 : igf_specR_e );
3886 86759 : IGF_appl_ivas( hPrivateDataL,
3887 : igfGridIdx,
3888 : spectrumL_fx,
3889 : spectrumL_e,
3890 : igf_specL_fx,
3891 : igf_specL_e,
3892 86759 : hIGFDecL->virtualSpec,
3893 : &hIGFDecL->virtualSpec_e,
3894 86759 : hIGFDecL->flag_sparseBuf,
3895 : bfi_apply_damping );
3896 86759 : IGF_appl_ivas( hPrivateDataR,
3897 : igfGridIdx,
3898 : spectrumR_fx,
3899 : spectrumR_e,
3900 : igf_specR_fx,
3901 : igf_specR_e,
3902 86759 : hIGFDecR->virtualSpec,
3903 : &hIGFDecR->virtualSpec_e,
3904 86759 : hIGFDecR->flag_sparseBuf,
3905 : bfi_apply_damping );
3906 : }
3907 :
3908 : /* reset TCX noise indicator vector */
3909 86760 : IF( EQ_16( igfGridIdx, IGF_GRID_LB_SHORT ) )
3910 : {
3911 4484 : set16_fx( hIGFDecL->infoTCXNoise_ptr, 0, IGF_START_MX / 2 );
3912 4484 : set16_fx( hIGFDecR->infoTCXNoise_ptr, 0, IGF_START_MX / 2 );
3913 : }
3914 : ELSE
3915 : {
3916 82276 : set16_fx( hIGFDecL->infoTCXNoise_ptr, 0, IGF_START_MX );
3917 82276 : set16_fx( hIGFDecR->infoTCXNoise_ptr, 0, IGF_START_MX );
3918 : }
3919 :
3920 86760 : return;
3921 : }
3922 :
3923 :
3924 : /**********************************************************************/ /*
3925 : set mode is used to init the IGF dec with a new bitrate
3926 : **************************************************************************/
3927 38 : void IGFDecSetMode(
3928 : const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* o : instance handle of IGF Decoder */
3929 : const Word32 total_brate, /* i : bitrate */
3930 : const Word16 bwidth, /* i : audio bandwidth */
3931 : const Word16 element_mode, /* i : IVAS element mode */
3932 : const Word16 defaultStartLine, /* i : default start subband index */
3933 : const Word16 defaultStopLine, /* i : default stop subband index */
3934 : const Word16 rf_mode /* i : flag to signal the RF mode */
3935 : )
3936 : {
3937 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData;
3938 :
3939 :
3940 38 : hPrivateData = &hIGFDec->igfData;
3941 38 : hIGFDec->isIGFActive = 0;
3942 38 : move16();
3943 :
3944 38 : IF( IGFCommonFuncsIGFConfiguration( total_brate, bwidth, element_mode, &hPrivateData->igfInfo, rf_mode ) != 0 )
3945 : {
3946 38 : IGFSCFDecoderOpen( &hPrivateData->hArithSCFdec, &hPrivateData->igfInfo, total_brate, bwidth, element_mode, rf_mode );
3947 :
3948 38 : hIGFDec->infoIGFStopLine = hPrivateData->igfInfo.grid[0].stopLine;
3949 38 : move16();
3950 38 : hIGFDec->infoIGFStartLine = hPrivateData->igfInfo.grid[0].startLine;
3951 38 : move16();
3952 38 : hIGFDec->infoIGFStopFreq = hPrivateData->igfInfo.grid[0].stopFrequency;
3953 38 : move16();
3954 38 : hIGFDec->infoIGFStartFreq = hPrivateData->igfInfo.grid[0].startFrequency;
3955 38 : move16();
3956 38 : hIGFDec->infoIGFAllZero = 0;
3957 38 : move16();
3958 38 : hIGFDec->isIGFActive = 1;
3959 38 : move16();
3960 :
3961 38 : test();
3962 38 : IF( ( LE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000 ) ) || ( LE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_48000 ) ) )
3963 : {
3964 38 : IGF_RefineGrid( &hPrivateData->igfInfo.grid[IGF_GRID_LB_NORM] );
3965 38 : IGF_RefineGrid( &hPrivateData->igfInfo.grid[IGF_GRID_LB_TRAN] );
3966 38 : IGF_RefineGrid( &hPrivateData->igfInfo.grid[IGF_GRID_LB_SHORT] );
3967 : }
3968 : }
3969 : ELSE
3970 : {
3971 0 : hIGFDec->infoIGFStopLine = defaultStopLine;
3972 0 : move16();
3973 0 : hIGFDec->infoIGFStartLine = defaultStartLine;
3974 0 : move16();
3975 0 : hIGFDec->infoIGFStopFreq = -1;
3976 0 : move16();
3977 0 : hIGFDec->infoIGFStartFreq = -1;
3978 0 : move16();
3979 0 : fprintf( stderr, "IGFDecSetMode: initialization error!\n" );
3980 : }
3981 38 : }
3982 :
3983 19700 : void IGFDecSetMode_ivas_fx(
3984 : const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i : instance handle of IGF Decoder */
3985 : const Word32 total_brate, /* i : bitrate */
3986 : const Word16 bwidth, /* i : audio bandwidth */
3987 : const Word16 element_mode, /* i : IVAS element mode */
3988 : const Word16 defaultStartLine, /* i : default start subband index */
3989 : const Word16 defaultStopLine, /* i : default stop subband index */
3990 : const Word16 rf_mode /* i : flag to signal the RF mode */
3991 : )
3992 : {
3993 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData;
3994 :
3995 19700 : hPrivateData = &hIGFDec->igfData;
3996 19700 : hIGFDec->isIGFActive = 0;
3997 19700 : move16();
3998 :
3999 19700 : IF( IGFCommonFuncsIGFConfiguration_ivas_fx( total_brate, bwidth, element_mode, &hPrivateData->igfInfo, rf_mode ) )
4000 : {
4001 19700 : IGFSCFDecoderOpen( &hPrivateData->hArithSCFdec, &hPrivateData->igfInfo, total_brate, bwidth, element_mode, rf_mode );
4002 :
4003 19700 : hIGFDec->infoIGFAllZero = 0;
4004 19700 : move16();
4005 19700 : hIGFDec->isIGFActive = 1;
4006 19700 : move16();
4007 19700 : hIGFDec->infoIGFStopLine = hPrivateData->igfInfo.grid[0].stopLine;
4008 19700 : move16();
4009 19700 : hIGFDec->infoIGFStartLine = hPrivateData->igfInfo.grid[0].startLine;
4010 19700 : move16();
4011 19700 : hIGFDec->infoIGFStopFreq = hPrivateData->igfInfo.grid[0].stopFrequency;
4012 19700 : move16();
4013 19700 : hIGFDec->infoIGFStartFreq = hPrivateData->igfInfo.grid[0].startFrequency;
4014 19700 : move16();
4015 :
4016 19700 : test();
4017 : /* no refinement if maxHopsize is 1 */
4018 19700 : IF( NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_96000 ) && NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_96000_CPE ) &&
4019 : NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_128000 ) && NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_128000_CPE ) )
4020 : {
4021 16502 : IGF_RefineGrid_ivas_fx( &hPrivateData->igfInfo.grid[IGF_GRID_LB_NORM] );
4022 16502 : IGF_RefineGrid_ivas_fx( &hPrivateData->igfInfo.grid[IGF_GRID_LB_TRAN] );
4023 16502 : IGF_RefineGrid_ivas_fx( &hPrivateData->igfInfo.grid[IGF_GRID_LB_SHORT] );
4024 : }
4025 : /* IGFDecOutInformation(hIGFDec); */
4026 : }
4027 : ELSE
4028 : {
4029 0 : hIGFDec->infoIGFStopLine = defaultStopLine;
4030 0 : move16();
4031 0 : hIGFDec->infoIGFStartLine = defaultStartLine;
4032 0 : move16();
4033 0 : hIGFDec->infoIGFStopFreq = -1;
4034 0 : move16();
4035 0 : hIGFDec->infoIGFStartFreq = -1;
4036 0 : move16();
4037 0 : IVAS_ERROR( IVAS_ERR_INTERNAL, "IGFDecSetMode: initialization error!" );
4038 : }
4039 :
4040 19700 : hIGFDec->flag_sparse = &hIGFDec->flag_sparseBuf[0];
4041 19700 : hIGFDec->infoTCXNoise_ptr = &hIGFDec->infoTCXNoise_evs[0];
4042 19700 : hIGFDec->virtualSpec_fx = &hIGFDec->virtualSpec[0];
4043 19700 : hIGFDec->igfData.pSpecFlat = &hIGFDec->igfData.pSpecFlatBuf_fx[0];
4044 19700 : hIGFDec->igfData.igfInfo.nfSeed = &hIGFDec->igfData.igfInfo.nfSeedBuf[0];
4045 19700 : return;
4046 : }
4047 : /**********************************************************************/ /*
4048 : updates the start/stop frequency of IGF according to igfGridIdx
4049 : **************************************************************************/
4050 646 : void IGFDecUpdateInfo( const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */
4051 : const Word16 igfGridIdx /**< in: | IGF grid index */
4052 : )
4053 : {
4054 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData;
4055 : H_IGF_GRID hGrid;
4056 :
4057 :
4058 646 : hPrivateData = &hInstance->igfData;
4059 646 : IF( hInstance->isIGFActive != 0 )
4060 : {
4061 646 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
4062 646 : hInstance->infoIGFStartFreq = hGrid->startFrequency;
4063 646 : move16();
4064 646 : hInstance->infoIGFStopFreq = hGrid->stopFrequency;
4065 646 : move16();
4066 646 : hInstance->infoIGFStartLine = hGrid->startLine;
4067 646 : move16();
4068 646 : hInstance->infoIGFStopLine = hGrid->stopLine;
4069 646 : move16();
4070 : }
4071 646 : }
4072 :
4073 : /*-------------------------------------------------------------------*
4074 : * IGFDecUpdateInfo_ivas_fx()
4075 : *
4076 : * updates the start/stop frequency of IGF according to igfGridIdx
4077 : *-------------------------------------------------------------------*/
4078 :
4079 2007488 : void IGFDecUpdateInfo_ivas_fx(
4080 : const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */
4081 : const Word16 subFrameIdx, /* i : index of subframe */
4082 : const Word16 igfGridIdx /* i : IGF grid index */
4083 : )
4084 : {
4085 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData;
4086 : H_IGF_GRID hGrid;
4087 :
4088 2007488 : hIGFDec->flag_sparse = &hIGFDec->flag_sparseBuf[0];
4089 2007488 : hIGFDec->infoTCXNoise_ptr = &hIGFDec->infoTCXNoise_evs[0];
4090 :
4091 2007488 : hIGFDec->virtualSpec_fx = &hIGFDec->virtualSpec[0];
4092 2007488 : hIGFDec->igfData.pSpecFlat = &hIGFDec->igfData.pSpecFlatBuf_fx[0];
4093 :
4094 2007488 : hIGFDec->igfData.igfInfo.nfSeed = &hIGFDec->igfData.igfInfo.nfSeedBuf[0];
4095 :
4096 2007488 : IF( EQ_16( igfGridIdx, IGF_GRID_LB_SHORT ) )
4097 : {
4098 94228 : IGFDecRestoreTCX10SubFrameData_fx( hIGFDec, subFrameIdx );
4099 : }
4100 :
4101 2007488 : hPrivateData = &hIGFDec->igfData;
4102 2007488 : IF( hIGFDec->isIGFActive )
4103 : {
4104 2007488 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
4105 2007488 : hIGFDec->infoIGFStartFreq = hGrid->startFrequency;
4106 2007488 : move16();
4107 2007488 : hIGFDec->infoIGFStopFreq = hGrid->stopFrequency;
4108 2007488 : move16();
4109 2007488 : hIGFDec->infoIGFStartLine = hGrid->startLine;
4110 2007488 : move16();
4111 2007488 : hIGFDec->infoIGFStopLine = hGrid->stopLine;
4112 2007488 : move16();
4113 : }
4114 2007488 : return;
4115 : }
4116 :
4117 15 : void IGFDecReplicateTCX10State_fx(
4118 : IGF_DEC_INSTANCE_HANDLE hIGFDec /* i/o: instance handle of IGF Decoder */
4119 : )
4120 : {
4121 15 : Copy( &hIGFDec->flag_sparseBuf[( N_MAX_TCX - IGF_START_MN ) / 2], &hIGFDec->flag_sparseBuf[0], ( N_MAX_TCX - IGF_START_MN ) / 2 );
4122 15 : Copy( &hIGFDec->infoTCXNoise_evs[( IGF_START_MX ) / 2], &hIGFDec->infoTCXNoise_evs[0], ( IGF_START_MX ) / 2 );
4123 :
4124 15 : Copy32( &hIGFDec->virtualSpec[( N_MAX_TCX - IGF_START_MN ) / 2], &hIGFDec->virtualSpec[0], ( N_MAX_TCX - IGF_START_MN ) / 2 );
4125 15 : Copy32( &hIGFDec->igfData.pSpecFlatBuf_fx[IGF_START_MX / 2], &hIGFDec->igfData.pSpecFlatBuf_fx[0], IGF_START_MX / 2 );
4126 :
4127 15 : hIGFDec->igfData.igfInfo.nfSeedBuf[0] = hIGFDec->igfData.igfInfo.nfSeedBuf[1];
4128 15 : move16();
4129 :
4130 15 : return;
4131 : }
4132 :
4133 :
4134 : /**********************************************************************/ /*
4135 : copy the LPC flat spectrum to IGF buffer
4136 : **************************************************************************/
4137 646 : void IGFDecCopyLPCFlatSpectrum( const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */
4138 : const Word32 *pSpectrumFlat, /**< in: Q31 | LPC flattend spectrum from TCX dec */
4139 : const Word16 pSpectrumFlat_exp, /**< in: | exponent of pSpectrumFlat */
4140 : const Word16 igfGridIdx /**< in: Q0 | IGF grid index */
4141 : )
4142 : {
4143 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData;
4144 : H_IGF_GRID hGrid;
4145 :
4146 :
4147 646 : IF( hInstance )
4148 : {
4149 646 : hPrivateData = &hInstance->igfData;
4150 646 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
4151 :
4152 :
4153 : /* pSpectrumFlat_exp has to be multiplied with 1024 = 2^10 go achive proper gain values */
4154 646 : hPrivateData->pSpecFlat_exp = add( pSpectrumFlat_exp, 10 );
4155 646 : move16();
4156 :
4157 646 : Copy32( pSpectrumFlat, hPrivateData->pSpecFlat, hGrid->startLine );
4158 : }
4159 646 : }
4160 :
4161 570119 : void IGFDecCopyLPCFlatSpectrum_fx(
4162 : const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */
4163 : const Word32 *pSpectrumFlat, /**< in: Q31 | LPC flattend spectrum from TCX dec */
4164 : const Word16 pSpectrumFlat_exp, /**< in: | exponent of pSpectrumFlat */
4165 : const Word16 igfGridIdx /**< in: Q0 | IGF grid index */
4166 : )
4167 : {
4168 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData;
4169 : H_IGF_GRID hGrid;
4170 :
4171 570119 : IF( hInstance )
4172 : {
4173 570119 : hPrivateData = &hInstance->igfData;
4174 570119 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
4175 :
4176 :
4177 : /* pSpectrumFlat_exp has to be multiplied with 1024 = 2^10 go achive proper gain values */
4178 570119 : hPrivateData->pSpecFlat_exp = 30;
4179 570119 : move16();
4180 :
4181 570119 : Copy_Scale_sig32( pSpectrumFlat, hPrivateData->pSpecFlat, hGrid->startLine, sub( pSpectrumFlat_exp, 20 ) ); // Q11
4182 : }
4183 570119 : }
4184 :
4185 : /**********************************************************************/ /*
4186 : store the IGF bitstream information for TCX10 subframes
4187 : **************************************************************************/
4188 22438 : void IGFDecStoreTCX10SubFrameData( const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */
4189 : const Word16 subFrameIdx /**< in: Q0 | index of subframe */
4190 : )
4191 : {
4192 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData;
4193 :
4194 :
4195 22438 : hPrivateData = &hInstance->igfData;
4196 :
4197 : /* store igf energies for subframe*/
4198 22438 : Copy( hPrivateData->igf_curr, hPrivateData->igf_curr_subframe[subFrameIdx][0], IGF_MAX_SFB );
4199 22438 : Copy( hPrivateData->igf_prev, hPrivateData->igf_prev_subframe[subFrameIdx], IGF_MAX_SFB );
4200 :
4201 : /* store spectral whitening information for current subframe */
4202 22438 : Copy( hPrivateData->currWhiteningLevel, hPrivateData->currWhiteningLevel_subframe[subFrameIdx], IGF_MAX_TILES );
4203 22438 : Copy( hPrivateData->prevWhiteningLevel, hPrivateData->prevWhiteningLevel_subframe[subFrameIdx], IGF_MAX_TILES );
4204 : /* store flattening trigger for current subframe */
4205 22438 : hPrivateData->igf_flatteningTrigger_subframe[subFrameIdx] = hInstance->flatteningTrigger;
4206 22438 : move16();
4207 22438 : }
4208 :
4209 : /**********************************************************************/ /*
4210 : restore the IGF bitstream information for TCX10 subframes
4211 : **************************************************************************/
4212 0 : void IGFDecRestoreTCX10SubFrameData( const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */
4213 : const Word16 subFrameIdx /**< in: Q0 | index of subframe */
4214 : )
4215 : {
4216 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData;
4217 :
4218 :
4219 0 : hPrivateData = &hInstance->igfData;
4220 :
4221 : /* store igf energies for subframe*/
4222 0 : Copy( hPrivateData->igf_curr_subframe[subFrameIdx][0], hPrivateData->igf_curr, IGF_MAX_SFB );
4223 0 : Copy( hPrivateData->igf_prev_subframe[subFrameIdx], hPrivateData->igf_prev, IGF_MAX_SFB );
4224 :
4225 : /* store spectral whitening information for current subframe */
4226 0 : Copy( hPrivateData->currWhiteningLevel_subframe[subFrameIdx], hPrivateData->currWhiteningLevel, IGF_MAX_TILES );
4227 0 : Copy( hPrivateData->prevWhiteningLevel_subframe[subFrameIdx], hPrivateData->prevWhiteningLevel, IGF_MAX_TILES );
4228 : /* restore flattening trigger for current subframe */
4229 0 : hInstance->flatteningTrigger = hPrivateData->igf_flatteningTrigger_subframe[subFrameIdx];
4230 0 : move16();
4231 0 : }
4232 :
4233 98156 : void IGFDecRestoreTCX10SubFrameData_fx(
4234 : const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */
4235 : const Word16 subFrameIdx /* i : index of subframe */
4236 : )
4237 : {
4238 : IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData;
4239 :
4240 98156 : hPrivateData = &hIGFDec->igfData;
4241 :
4242 : /* store igf energies for subframe*/
4243 98156 : Copy( hPrivateData->igf_curr_subframe[subFrameIdx][0], hPrivateData->igf_curr, IGF_MAX_SFB );
4244 98156 : Copy( hPrivateData->igf_prev_subframe[subFrameIdx], hPrivateData->igf_prev, IGF_MAX_SFB );
4245 :
4246 : /* store spectral whitening information for current subframe */
4247 98156 : Copy( hPrivateData->currWhiteningLevel_subframe[subFrameIdx], hPrivateData->currWhiteningLevel, IGF_MAX_TILES );
4248 98156 : Copy( hPrivateData->prevWhiteningLevel_subframe[subFrameIdx], hPrivateData->prevWhiteningLevel, IGF_MAX_TILES );
4249 :
4250 : /* restore flattening trigger for current subframe */
4251 98156 : hIGFDec->flatteningTrigger = hPrivateData->igf_flatteningTrigger_subframe[subFrameIdx];
4252 98156 : move16();
4253 98156 : hIGFDec->flag_sparse = &hIGFDec->flag_sparseBuf[subFrameIdx * ( N_MAX_TCX - IGF_START_MN ) / 2];
4254 98156 : hIGFDec->infoTCXNoise_ptr = &hIGFDec->infoTCXNoise_evs[subFrameIdx * ( IGF_START_MX ) / 2];
4255 :
4256 98156 : hIGFDec->virtualSpec_fx = &hIGFDec->virtualSpec[subFrameIdx * ( N_MAX_TCX - IGF_START_MN ) / 2];
4257 98156 : hIGFDec->igfData.pSpecFlat = &hIGFDec->igfData.pSpecFlatBuf_fx[subFrameIdx * IGF_START_MX / 2];
4258 :
4259 98156 : hIGFDec->igfData.igfInfo.nfSeed = &hIGFDec->igfData.igfInfo.nfSeedBuf[subFrameIdx];
4260 :
4261 98156 : return;
4262 : }
4263 :
4264 : /*-----------------------------------------------------------------------*
4265 : * init_igf_dec()
4266 : *
4267 : * Initialize IGF decoder parameters
4268 : *-----------------------------------------------------------------------*/
4269 8787 : void init_igf_dec(
4270 : IGF_DEC_INSTANCE_HANDLE hIGFDec /* i/o: IGF decoder handle */
4271 : )
4272 : {
4273 8787 : set16_fx( (Word16 *) hIGFDec, 0, ( sizeof( IGFDEC_INSTANCE ) ) / sizeof( Word16 ) );
4274 8787 : hIGFDec->igfData.igfInfo.nfSeedBuf[0] = 9733;
4275 8787 : hIGFDec->igfData.igfInfo.nfSeedBuf[1] = 9733;
4276 8787 : move16();
4277 8787 : move16();
4278 8787 : hIGFDec->igfData.igfInfo.nfSeed = &hIGFDec->igfData.igfInfo.nfSeedBuf[0];
4279 :
4280 8787 : set16_fx( hIGFDec->infoTCXNoise_evs, 0, IGF_START_MX );
4281 8787 : set16_fx( hIGFDec->flag_sparseBuf, 0, N_MAX_TCX - IGF_START_MN );
4282 8787 : set32_fx( hIGFDec->virtualSpec, 0, N_MAX_TCX - IGF_START_MN );
4283 8787 : hIGFDec->virtualSpec_e = 0;
4284 8787 : move16();
4285 8787 : hIGFDec->infoIGFStopFreq = -1;
4286 8787 : move16();
4287 8787 : hIGFDec->infoIGFStartFreq = -1;
4288 8787 : move16();
4289 8787 : hIGFDec->flatteningTrigger = -1;
4290 8787 : move16();
4291 8787 : hIGFDec->infoIGFStartLine = -1;
4292 8787 : move16();
4293 8787 : hIGFDec->isIGFActive = -1;
4294 8787 : move16();
4295 8787 : hIGFDec->infoIGFAllZero = 0;
4296 8787 : move16();
4297 8787 : hIGFDec->infoIGFStopLine = -1;
4298 8787 : move16();
4299 8787 : hIGFDec->infoIGFStartLine = -1;
4300 8787 : move16();
4301 :
4302 8787 : set32_fx( hIGFDec->igfData.pSpecFlatBuf_fx, 0, IGF_START_MX );
4303 8787 : hIGFDec->igfData.pSpecFlat = &hIGFDec->igfData.pSpecFlatBuf_fx[0];
4304 8787 : hIGFDec->flag_sparse = &hIGFDec->flag_sparseBuf[0];
4305 8787 : hIGFDec->infoTCXNoise_ptr = &hIGFDec->infoTCXNoise_evs[0];
4306 8787 : hIGFDec->virtualSpec_fx = &hIGFDec->virtualSpec[0];
4307 :
4308 8787 : return;
4309 : }
4310 :
4311 1455737 : Word16 get_igf_startline(
4312 : Decoder_State *st, /* i : decoder state */
4313 : const Word16 L_frame, /* i : length of the frame */
4314 : const Word16 L_frameTCX /* i : full band frame length */
4315 : )
4316 : {
4317 : Word16 igf_startline;
4318 :
4319 1455737 : IF( st->igf == 0 )
4320 : {
4321 533439 : IF( st->narrowBand == 0 )
4322 : {
4323 : /* minimum needed for output with sampling rates lower then the
4324 : nominal sampling rate */
4325 533439 : igf_startline = s_min( L_frameTCX, L_frame );
4326 533439 : move16();
4327 : }
4328 : ELSE
4329 : {
4330 0 : igf_startline = L_frameTCX;
4331 0 : move16();
4332 : }
4333 : }
4334 : ELSE
4335 : {
4336 922298 : igf_startline = s_min( st->hIGFDec->infoIGFStartLine, L_frameTCX );
4337 922298 : move16();
4338 : }
4339 :
4340 1455737 : return igf_startline;
4341 : }
|