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