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