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 "options.h"
9 : #include "cnst.h"
10 : #include "stl.h"
11 : #include "prot_fx.h"
12 : #include "prot_fx_enc.h" /* Function prototypes */
13 : #include "stat_enc.h"
14 : #include "basop_util.h"
15 :
16 : /**********************************************************************/ /*
17 : write single bit to stream
18 : **************************************************************************/
19 7106 : static void IGF_write_bit_fx(
20 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
21 : Word16 *bitCount, /**< in/out: | bit counter */
22 : Word16 bit /**< in: | value of bit */
23 : )
24 : {
25 7106 : IGFCommonFuncsWriteSerialBit( hBstr, bitCount, bit );
26 7106 : }
27 :
28 : /**********************************************************************/ /*
29 : write bits to stream
30 : **************************************************************************/
31 5832 : static void IGF_write_bits(
32 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
33 : Word16 *bitCount, /**< in/out: | bit counter */
34 : Word16 value, /**< in: | value to be written */
35 : Word16 bits /**< in: Q0 | number of bits */
36 : )
37 : {
38 : Word16 tmp;
39 :
40 11664 : WHILE( bits )
41 : {
42 5832 : bits = sub( bits, 1 );
43 5832 : tmp = s_and( value, shl( 1, bits ) );
44 5832 : IF( tmp == 0 )
45 : {
46 2048 : IGF_write_bit_fx( hBstr, bitCount, 0 );
47 : }
48 : ELSE
49 : {
50 3784 : IGF_write_bit_fx( hBstr, bitCount, 1 );
51 : }
52 : }
53 :
54 5832 : return;
55 : }
56 :
57 :
58 : /**********************************************************************/ /*
59 : envelope estimation
60 : **************************************************************************/
61 637 : static void IGF_CalculateEnvelope( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */
62 : Word32 *pMDCTSpectrum, /**< in: Q31 | MDCT spectrum */
63 : Word16 MDCTSpectrum_e, /**< in: | exponent of MDCT spectrum */
64 : Word32 *pPowerSpectrum, /**< in: Q31 | MDCT^2 + MDST^2 spectrum, or estimate */
65 : Word16 PowerSpectrum_e, /**< in: | exponent of MDCT^2 + MDST^2 spectrum, or estimate */
66 : const Word16 igfGridIdx /**< in: Q0 | IGF grid index */
67 :
68 : )
69 : {
70 : IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
71 : H_IGF_GRID hGrid;
72 : Word16 *swb_offset;
73 : Word16 sfb; /* this is the actual scalefactor band */
74 : Word16 width; /* this is width in subbands of the actual scalefactor band */
75 : Word16 tile_idx;
76 : Word16 strt_cpy;
77 : Word16 gain; /* the gain which has to be applied to the source tile to get the destination energy */
78 : Word16 gain_exp;
79 : Word16 tb;
80 : Word16 zeroNrg; /* Q0 | flag indicating if the signal contains almost no energy */
81 : Word32 sfbEnergyR[IGF_MAX_SFB];
82 : Word16 sfbEnergyR_exp[IGF_MAX_SFB];
83 : Word32 sfbEnergyC[IGF_MAX_SFB]; /* the energy of the destination region of the tile */
84 : Word16 sfbEnergyC_exp[IGF_MAX_SFB];
85 : Word32 sfbEnergyTileR[IGF_MAX_SFB];
86 : Word16 sfbEnergyTileR_exp[IGF_MAX_SFB];
87 : Word32 sfbEnergyTileC[IGF_MAX_SFB]; /* the energy of the destination region of the tile */
88 : Word16 sfbEnergyTileC_exp[IGF_MAX_SFB];
89 : Word32 LFMDCTSpectrum[N_MAX];
90 : Word16 LFMDCTSpectrum_exp;
91 : Word32 LFPowerSpectrum[N_MAX];
92 : Word16 tmp;
93 : Word16 tmp_exp;
94 : Word32 L_tmp;
95 : Word16 shift;
96 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
97 637 : Flag Overflow = 0;
98 637 : move32();
99 : #endif
100 :
101 : /* initialize variables */
102 637 : Copy32( pMDCTSpectrum + IGF_START_MN, hInstance->spec_be_igf, hInstance->infoStopLine - IGF_START_MN );
103 637 : hPrivateData = &hInstance->igfData;
104 637 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
105 637 : swb_offset = hGrid->swb_offset;
106 637 : move16();
107 637 : hInstance->spec_be_igf_e = MDCTSpectrum_e;
108 637 : move16();
109 637 : zeroNrg = 0;
110 637 : move16();
111 :
112 :
113 637 : IF( pPowerSpectrum != NULL )
114 : {
115 2271 : FOR( tile_idx = 0; tile_idx < hGrid->nTiles; tile_idx++ )
116 : {
117 1638 : strt_cpy = hGrid->sbWrap[tile_idx];
118 1638 : move16();
119 6180 : FOR( sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++ )
120 : {
121 231366 : FOR( tb = swb_offset[sfb]; tb < swb_offset[sfb + 1]; tb++ )
122 : {
123 226824 : LFMDCTSpectrum[tb] = pMDCTSpectrum[strt_cpy];
124 226824 : move32();
125 226824 : LFPowerSpectrum[tb] = pPowerSpectrum[strt_cpy];
126 226824 : move32();
127 226824 : strt_cpy = add( strt_cpy, 1 );
128 : }
129 : }
130 : }
131 633 : IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->startSfb,
132 633 : hGrid->stopSfb,
133 633 : hGrid->swb_offset,
134 : pPowerSpectrum,
135 : &PowerSpectrum_e,
136 : sfbEnergyC,
137 : sfbEnergyC_exp );
138 633 : IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->startSfb,
139 633 : hGrid->stopSfb,
140 633 : hGrid->swb_offset,
141 : LFPowerSpectrum,
142 : &PowerSpectrum_e,
143 : sfbEnergyTileC,
144 : sfbEnergyTileC_exp );
145 633 : IGFCommonFuncsMDCTSquareSpec( hGrid->startLine,
146 633 : hGrid->stopLine,
147 : LFMDCTSpectrum,
148 : MDCTSpectrum_e,
149 : LFMDCTSpectrum,
150 : &LFMDCTSpectrum_exp,
151 : 0 );
152 633 : IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->startSfb,
153 633 : hGrid->stopSfb,
154 633 : hGrid->swb_offset,
155 : LFMDCTSpectrum,
156 : &LFMDCTSpectrum_exp,
157 : sfbEnergyTileR,
158 : sfbEnergyTileR_exp );
159 : }
160 : ELSE
161 : {
162 4 : IGFCommonFuncsMDCTSquareSpec( hGrid->startLine,
163 4 : hGrid->stopLine,
164 : pMDCTSpectrum,
165 : MDCTSpectrum_e,
166 : LFMDCTSpectrum,
167 : &LFMDCTSpectrum_exp,
168 : 0 );
169 4 : IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->startSfb,
170 4 : hGrid->stopSfb,
171 4 : hGrid->swb_offset,
172 : LFMDCTSpectrum,
173 : &LFMDCTSpectrum_exp,
174 : sfbEnergyR,
175 : sfbEnergyR_exp );
176 : }
177 :
178 2287 : FOR( tile_idx = 0; tile_idx < hGrid->nTiles; tile_idx++ )
179 : {
180 :
181 6224 : FOR( sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++ )
182 : {
183 :
184 :
185 4574 : width = sub( swb_offset[sfb + 1], swb_offset[sfb] );
186 4574 : L_tmp = 0;
187 4574 : move16();
188 4574 : gain_exp = 0;
189 4574 : move16();
190 :
191 4574 : IF( pPowerSpectrum )
192 : {
193 4542 : IF( sfbEnergyTileR[sfb] == 0 )
194 : {
195 0 : sfbEnergyTileR[sfb] = 0x00010000;
196 0 : move32();
197 0 : sfbEnergyTileR_exp[sfb] = 0;
198 0 : move16();
199 0 : zeroNrg = 1;
200 0 : move16();
201 : }
202 4542 : IF( sfbEnergyTileC[sfb] == 0 )
203 : {
204 0 : sfbEnergyTileC[sfb] = 0x00010000;
205 0 : move32();
206 0 : sfbEnergyTileC_exp[sfb] = 0;
207 0 : move16();
208 0 : zeroNrg = 1;
209 0 : move16();
210 : }
211 4542 : IF( sfbEnergyC[sfb] == 0 )
212 : {
213 0 : sfbEnergyC[sfb] = 0x00010000;
214 0 : move32();
215 0 : sfbEnergyC_exp[sfb] = 0;
216 0 : move16();
217 0 : zeroNrg = 1;
218 0 : move16();
219 : }
220 :
221 4542 : BASOP_Util_Divide_MantExp( round_fx_o( sfbEnergyTileR[sfb], &Overflow ), sfbEnergyTileR_exp[sfb], width, 15, &gain, &gain_exp );
222 4542 : BASOP_Util_Divide_MantExp( round_fx_o( sfbEnergyC[sfb], &Overflow ), sfbEnergyC_exp[sfb], round_fx_o( sfbEnergyTileC[sfb], &Overflow ), sfbEnergyTileC_exp[sfb], &tmp, &tmp_exp );
223 4542 : L_tmp = L_mult( gain, tmp );
224 4542 : gain_exp = add( gain_exp, tmp_exp );
225 : }
226 : ELSE
227 : {
228 32 : IF( sfbEnergyR[sfb] == 0 )
229 : {
230 0 : sfbEnergyR[sfb] = 0x00010000;
231 0 : move32();
232 0 : sfbEnergyR_exp[sfb] = 0;
233 0 : move16();
234 0 : zeroNrg = 1;
235 0 : move16();
236 : }
237 32 : BASOP_Util_Divide_MantExp( round_fx_sat( sfbEnergyR[sfb] ),
238 32 : sfbEnergyR_exp[sfb],
239 : width,
240 : 15,
241 : &gain,
242 : &gain_exp );
243 32 : L_tmp = L_deposit_h( gain );
244 : }
245 :
246 : /* gain = 0.5f + (float)((2.885390081777927f * log(gain) + 16.f)); */
247 4574 : L_tmp = BASOP_Util_Log2( L_tmp );
248 4574 : L_tmp = L_add( L_tmp, L_deposit_h( shl( gain_exp, 15 - 6 ) ) );
249 4574 : shift = norm_l( L_tmp );
250 4574 : gain = round_fx_o( L_shl_o( L_tmp, shift, &Overflow ), &Overflow );
251 4574 : gain_exp = sub( 7, shift );
252 4574 : gain_exp = BASOP_Util_Add_MantExp( gain, gain_exp, 32767 /*16 Q11*/, 4, &gain );
253 4574 : gain_exp = BASOP_Util_Add_MantExp( gain, gain_exp, 0x4000, 0, &gain );
254 4574 : gain = shr( gain, s_min( sub( 15, gain_exp ), 15 ) );
255 :
256 4574 : if ( gain > 91 )
257 : {
258 0 : gain = s_min( gain, 91 ); /* 13+15+63, see arithocde encode residual */
259 : }
260 4574 : if ( gain < 0 )
261 : {
262 0 : gain = s_max( gain, 0 );
263 : }
264 :
265 : /* set gain to zero if the signal contains too less energy */
266 4574 : if ( zeroNrg != 0 )
267 : {
268 0 : gain = 0;
269 0 : move16();
270 : }
271 :
272 4574 : hPrivateData->igfScfQuantized[sfb] = gain;
273 4574 : move16();
274 : }
275 : }
276 :
277 637 : return;
278 : }
279 :
280 : /**********************************************************************/ /*
281 : writes IGF SCF values
282 : **************************************************************************/
283 1274 : static void IGF_WriteEnvelope( /**< out: Q0 | number of bits writen */
284 : const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */
285 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
286 : Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */
287 : const Word16 igfGridIdx, /**< in: Q0 | igf grid index see declaration of IGF_GRID_IDX for details */
288 : const Word16 isIndepFlag, /**< in: Q0 | if 1 frame is independent, 0 = frame is coded with data from previous frame */
289 : Word16 *igfAllZero /**< in: Q0 | returns 1 if all IGF scfs are zero, else 0 */
290 : )
291 : {
292 : IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
293 : H_IGF_GRID hGrid;
294 : Word16 sfb;
295 :
296 1274 : *igfAllZero = 1;
297 1274 : move16();
298 1274 : hPrivateData = &hInstance->igfData;
299 1274 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
300 :
301 1274 : FOR( sfb = hGrid->startSfb; sfb < hGrid->stopSfb; sfb++ )
302 : {
303 1274 : IF( hPrivateData->igfScfQuantized[sfb] != 0 )
304 : {
305 1274 : *igfAllZero = 0;
306 1274 : move16();
307 1274 : BREAK;
308 : }
309 : }
310 :
311 1274 : IF( *igfAllZero != 0 )
312 : {
313 0 : IGF_write_bit_fx( hBstr, pBitOffset, 1 );
314 0 : if ( NULL == hBstr )
315 : {
316 0 : IGFSCFEncoderSaveContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx );
317 : }
318 0 : IGFSCFEncoderReset_fx( &hPrivateData->hIGFSCFArithEnc );
319 0 : if ( NULL == hBstr )
320 : {
321 0 : IGFSCFEncoderRestoreContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx );
322 : }
323 : }
324 : ELSE
325 : {
326 1274 : IGF_write_bit_fx( hBstr, pBitOffset, 0 );
327 1274 : if ( NULL == hBstr )
328 : {
329 637 : IGFSCFEncoderSaveContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx );
330 : }
331 :
332 1274 : *pBitOffset = IGFSCFEncoderEncode_fx( &hPrivateData->hIGFSCFArithEnc, hBstr, *pBitOffset, &hPrivateData->igfScfQuantized[hGrid->startSfb], igfGridIdx, isIndepFlag );
333 1274 : move16();
334 :
335 1274 : if ( NULL == hBstr )
336 : {
337 637 : IGFSCFEncoderRestoreContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx );
338 : }
339 : }
340 1274 : }
341 :
342 : /**********************************************************************/ /*
343 : identifies significant spectral content
344 : **************************************************************************/
345 637 : void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< out: | exponent of highPassEner */
346 : const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */
347 : Word32 *pSpectrum, /**< in/out: | MDCT spectrum */
348 : Word32 *pPowerSpectrum, /**< in/out: | power spectrum */
349 : Word16 pPowerSpectrum_exp, /**< in: | exponent of power spectrum */
350 : const Word16 igfGridIdx /**< in: Q0 | IGF grid index */
351 : )
352 : {
353 : IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
354 : H_IGF_GRID hGrid;
355 : Word16 i;
356 : Word16 igfBgn;
357 : Word16 igfEnd;
358 : Word32 highPassEner; /* Q31 */
359 : Word32 lastLine;
360 : Word32 nextLine;
361 : Word32 L_c;
362 : Word32 highPassEner_Ovfl;
363 : Word16 s;
364 : Word16 tmploop;
365 : Word16 *swb_offset;
366 : Word16 sfb;
367 : Word16 startSfb;
368 : Word16 stopSfb;
369 : Word16 line;
370 : Word16 flag;
371 : Word16 *igfScaleF;
372 : Word16 tmp;
373 : Word32 L_tmp;
374 :
375 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
376 637 : Flag Overflow = 0;
377 637 : Flag Carry = 0;
378 637 : move32();
379 637 : move32();
380 : #endif
381 :
382 637 : hPrivateData = &hInstance->igfData;
383 637 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
384 637 : igfBgn = hGrid->startLine;
385 637 : move16();
386 637 : igfEnd = hGrid->stopLine;
387 637 : move16();
388 637 : swb_offset = hGrid->swb_offset;
389 637 : move16();
390 637 : startSfb = hGrid->startSfb;
391 637 : move16();
392 637 : stopSfb = hGrid->stopSfb;
393 637 : move16();
394 637 : igfScaleF = hPrivateData->igfScfQuantized;
395 637 : move16();
396 637 : *highPassEner_exp = 0;
397 637 : move16();
398 637 : highPassEner = 0;
399 637 : move32();
400 :
401 637 : IF( NULL == pPowerSpectrum )
402 : {
403 0 : FOR( i = igfBgn; i < hGrid->infoGranuleLen; i++ )
404 : {
405 0 : pSpectrum[i] = L_deposit_l( 0 );
406 : }
407 0 : return;
408 : }
409 :
410 637 : IF( igfBgn > 0 )
411 : {
412 637 : L_c = 0;
413 637 : move32();
414 165885 : FOR( i = 0; i < igfBgn; i++ )
415 : {
416 165248 : Carry = 0;
417 165248 : move32();
418 165248 : highPassEner = L_add_co( highPassEner, Mpy_32_16_1( pPowerSpectrum[i], shl( i, 4 ) /*Q4*/ ) /*Q20, pPowerSpectrum_exp*/, &Carry, &Overflow );
419 165248 : Overflow = 0;
420 165248 : move32();
421 165248 : L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow );
422 : }
423 :
424 637 : highPassEner = norm_llQ31( L_c, highPassEner, highPassEner_exp ); /*Q20, highPassEner_exp*/
425 637 : *highPassEner_exp = add( *highPassEner_exp, pPowerSpectrum_exp );
426 637 : move16();
427 637 : test();
428 637 : test();
429 1274 : if ( NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_9600 ) &&
430 1274 : NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_RF_SWB_13200 ) &&
431 637 : NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_13200 ) )
432 : {
433 376 : igfBgn = shl( igfBgn, 1 );
434 : }
435 637 : highPassEner = L_deposit_l( BASOP_Util_Divide3216_Scale( highPassEner /*Q20, highPassEner_exp*/, igfBgn /*Q0*/, &s ) ); /*Q15, highPassEner_exp+11-16+s*/
436 637 : *highPassEner_exp = add( add( *highPassEner_exp, s ), 12 - 16 + ( 31 - 15 ) ); /*Q15->Q31,highPassEner_exp*/
437 637 : lastLine = pSpectrum[i - 1];
438 637 : move32();
439 637 : nextLine = 0;
440 637 : move32();
441 :
442 : /* May overflow - just for threshold comparison */
443 : /* negate because the negated may be 1 larger in abs, */
444 : /* so whenever compared to the negation of a maximum possible pPowerspectrum, it is still larger */
445 637 : highPassEner_Ovfl = L_shl_o( L_negate( highPassEner ), sub( *highPassEner_exp, pPowerSpectrum_exp ), &Overflow );
446 637 : L_tmp = L_add_o( pPowerSpectrum[i - 1], highPassEner_Ovfl, &Overflow );
447 :
448 637 : if ( L_tmp >= 0 )
449 : {
450 0 : nextLine = pSpectrum[i];
451 0 : move32();
452 : }
453 637 : tmploop = sub( igfEnd, 1 );
454 228360 : FOR( /*i*/; i < tmploop; i++ )
455 : {
456 : /* May overflow - just for threshold comparison */
457 : BASOP_SATURATE_WARNING_OFF_EVS
458 227723 : L_tmp = L_add_sat( pPowerSpectrum[i], highPassEner_Ovfl );
459 : BASOP_SATURATE_WARNING_ON_EVS;
460 :
461 227723 : IF( L_tmp < 0 )
462 : {
463 227692 : lastLine = pSpectrum[i];
464 227692 : move32();
465 227692 : pSpectrum[i] = nextLine;
466 227692 : move32();
467 227692 : nextLine = 0;
468 227692 : move32();
469 : }
470 : ELSE
471 : {
472 31 : pSpectrum[i - 1] = lastLine;
473 31 : move32();
474 31 : lastLine = pSpectrum[i];
475 31 : move32();
476 31 : nextLine = pSpectrum[i + 1];
477 31 : move32();
478 : }
479 : }
480 :
481 : /* May overflow - just for threshold comparison */
482 : BASOP_SATURATE_WARNING_OFF_EVS
483 637 : L_tmp = L_add_sat( pPowerSpectrum[i], highPassEner_Ovfl );
484 : BASOP_SATURATE_WARNING_ON_EVS
485 637 : if ( L_tmp < 0 )
486 : {
487 637 : pSpectrum[i] = L_deposit_l( 0 );
488 637 : move32();
489 : }
490 : }
491 :
492 : /* delete spectrum above igfEnd: */
493 20149 : FOR( i = igfEnd; i < hGrid->infoGranuleLen; i++ )
494 : {
495 19512 : pSpectrum[i] = L_deposit_l( 0 );
496 19512 : move32();
497 19512 : pPowerSpectrum[i] = L_deposit_l( 0 );
498 19512 : move32();
499 : }
500 :
501 5211 : FOR( sfb = startSfb; sfb < stopSfb; sfb++ )
502 : {
503 4574 : flag = 0;
504 4574 : move16();
505 232934 : FOR( line = swb_offset[sfb]; line < swb_offset[sfb + 1]; line++ )
506 : {
507 228360 : if ( pSpectrum[line] != 0 )
508 : {
509 61 : flag = 1;
510 61 : move16();
511 : }
512 : }
513 4574 : tmp = igfScaleF[sfb];
514 4574 : move16();
515 4574 : if ( flag )
516 : {
517 7 : tmp = sub( igfScaleF[sfb], 1 );
518 : }
519 4574 : if ( igfScaleF[sfb] )
520 : {
521 4574 : igfScaleF[sfb] = tmp;
522 4574 : move16();
523 : }
524 : }
525 : }
526 :
527 592511 : void IGF_ErodeSpectrum_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */
528 : Word32 *pSpectrum, /**< in/out: | MDCT spectrum Qx*/
529 : Word32 *pPowerSpectrum, /**< in/out: | power spectrum */
530 : Word16 pPowerSpectrum_exp, /**< in: | exponent of power spectrum */
531 : const Word16 igfGridIdx, /**< in: Q0 | IGF grid index */
532 : const Word16 mct_on )
533 : {
534 : IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
535 : H_IGF_GRID hGrid;
536 : Word16 i;
537 : Word16 igfBgn;
538 : Word16 igfEnd;
539 : Word32 highPassEner; /* Q31 */
540 : Word32 lastLine;
541 : Word32 nextLine;
542 : Word16 *swb_offset;
543 : Word16 sfb;
544 : Word16 startSfb;
545 : Word16 stopSfb;
546 : Word16 line;
547 : Word16 *igfScaleF;
548 : Word16 tmp;
549 : Word16 factor;
550 : Word16 exp1, exp2;
551 : Word16 num, den;
552 : Word32 temp;
553 :
554 592511 : hPrivateData = &hInstance->igfData;
555 592511 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
556 592511 : igfBgn = hGrid->startLine;
557 592511 : move16();
558 592511 : igfEnd = hGrid->stopLine;
559 592511 : move16();
560 592511 : swb_offset = hGrid->swb_offset;
561 592511 : move16();
562 592511 : startSfb = hGrid->startSfb;
563 592511 : move16();
564 592511 : stopSfb = hGrid->stopSfb;
565 592511 : move16();
566 592511 : igfScaleF = hPrivateData->igfScfQuantized;
567 592511 : move16();
568 :
569 592511 : IF( NULL == pPowerSpectrum )
570 : {
571 4476056 : FOR( i = igfBgn; i < hGrid->infoGranuleLen; i++ )
572 : {
573 4453960 : pSpectrum[i] = 0;
574 4453960 : move32();
575 : }
576 22096 : return;
577 : }
578 :
579 570415 : IF( igfBgn > 0 )
580 : {
581 570415 : Word64 sum = 0;
582 570415 : move64();
583 259232651 : FOR( i = 0; i < igfBgn; i++ )
584 : {
585 258662236 : sum = W_mac_32_16( sum, pPowerSpectrum[i], i ); // Q: 31-pPowerSpectrum_exp+1
586 : }
587 570415 : exp1 = W_norm( sum );
588 570415 : sum = W_shl( sum, sub( exp1, 1 ) ); // Q: 31-pPowerSpectrum_exp+1+exp1-1
589 570415 : num = extract_h( W_extract_h( sum ) ); // Q: 31-pPowerSpectrum_exp+exp1-48 = -pPowerSpectrum_exp+exp1-17
590 570415 : exp1 = add( 32, sub( pPowerSpectrum_exp, exp1 ) ); // exp: 32+pPowerSpectrum_exp-exp1
591 :
592 570415 : IF( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_9600 ) ||
593 : EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_RF_SWB_13200 ) ||
594 : EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_13200 ) ||
595 : EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_16400_CPE ) )
596 : {
597 27276 : factor = ONE_IN_Q14; // Q14
598 27276 : move16();
599 : }
600 543139 : ELSE IF( mct_on && ( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_64000_CPE ) ) )
601 : {
602 3908 : factor = 11469; // 0.7f in Q14
603 3908 : move16();
604 : }
605 : ELSE
606 : {
607 539231 : factor = 32767; // 2.f in Q14
608 539231 : move16();
609 : }
610 :
611 570415 : temp = L_mult( igfBgn, factor ); // exp: 16
612 570415 : exp2 = norm_l( temp );
613 570415 : den = extract_h( L_shl( temp, exp2 ) ); // exp: 16-exp2
614 570415 : exp2 = sub( 16, exp2 );
615 :
616 570415 : highPassEner = L_deposit_h( div_s( num, den ) ); // exp: exp1-exp2
617 :
618 : /* highPassEner is used only for comparison, saturation doesn't effect the outcome */
619 570415 : highPassEner = L_shl_sat( highPassEner, sub( sub( exp1, exp2 ), pPowerSpectrum_exp ) ); // exp: pPowerSpectrum_exp
620 :
621 570415 : lastLine = pSpectrum[i - 1]; // Qx
622 570415 : move32();
623 570415 : nextLine = pSpectrum[i]; // Qx
624 570415 : move32();
625 :
626 570415 : if ( LT_32( pPowerSpectrum[i - 1], highPassEner ) )
627 : {
628 570284 : nextLine = 0;
629 570284 : move32();
630 : }
631 :
632 168551956 : FOR( /*i*/; i < igfEnd - 1; i++ )
633 : {
634 : /* May overflow - just for threshold comparison */
635 167981541 : IF( LT_32( pPowerSpectrum[i], highPassEner ) )
636 : {
637 167934184 : lastLine = pSpectrum[i]; // Qx
638 167934184 : move32();
639 167934184 : pSpectrum[i] = nextLine; // Qx
640 167934184 : move32();
641 167934184 : nextLine = 0;
642 167934184 : move32();
643 : }
644 : ELSE
645 : {
646 47357 : pSpectrum[i - 1] = lastLine; // Qx
647 47357 : move32();
648 47357 : lastLine = pSpectrum[i]; // Qx
649 47357 : move32();
650 47357 : nextLine = pSpectrum[i + 1]; // Qx
651 47357 : move32();
652 : }
653 : }
654 :
655 : /* May overflow - just for threshold comparison */
656 570415 : if ( LT_32( pPowerSpectrum[i], highPassEner ) )
657 : {
658 570281 : pSpectrum[i] = 0;
659 570281 : move32();
660 : }
661 : }
662 :
663 : /* delete spectrum above igfEnd: */
664 68041583 : FOR( i = igfEnd; i < hGrid->infoGranuleLen; i++ )
665 : {
666 67471168 : pSpectrum[i] = 0;
667 67471168 : pPowerSpectrum[i] = 0;
668 67471168 : move32();
669 67471168 : move32();
670 : }
671 :
672 : // Below check is present at the beginning of the function and is not required here
673 : /* IF( NULL != pPowerSpectrum ) */
674 : {
675 3563156 : FOR( sfb = startSfb; sfb < stopSfb; sfb++ )
676 : {
677 2992741 : tmp = 0;
678 2992741 : move16();
679 171544697 : FOR( line = swb_offset[sfb]; line < swb_offset[sfb + 1]; line++ )
680 : {
681 168551956 : if ( pSpectrum[line] != 0 )
682 : {
683 15566 : tmp = add( tmp, 1 );
684 : }
685 : }
686 :
687 2992741 : Word16 igfScaleF_cnt = igfScaleF[sfb];
688 2992741 : move16();
689 2992741 : test();
690 2992741 : if ( tmp && igfScaleF[sfb] )
691 : {
692 2565 : igfScaleF_cnt = sub( igfScaleF[sfb], 1 );
693 : }
694 2992741 : igfScaleF[sfb] = igfScaleF_cnt;
695 2992741 : move16();
696 : }
697 : }
698 : }
699 :
700 : /**********************************************************************/ /*
701 : crest factor calculation
702 : **************************************************************************/
703 1228 : Word16 IGF_getCrest( /**< out: Q15| crest factor */
704 : Word16 *crest_exp, /**< out: | exponent of crest factor */
705 : const Word32 *powerSpectrum, /**< in: Q31 | power spectrum */
706 : const Word16 powerSpectrum_exp, /**< in: | exponent of power spectrum */
707 : const Word16 start, /**< in: Q0 | start subband index */
708 : const Word16 stop /**< in: Q0 | stop subband index */
709 : )
710 : {
711 : Word16 i;
712 : Word16 x;
713 : Word16 s;
714 : Word32 x_eff32;
715 : Word16 x_max;
716 : Word16 crest;
717 : Word16 tmp;
718 : Word32 tmp32;
719 :
720 1228 : x_eff32 = 0;
721 1228 : move32();
722 1228 : x_max = 0;
723 1228 : move16();
724 1228 : crest = 16384 /*.5f Q15*/;
725 1228 : move16();
726 1228 : *crest_exp = 1;
727 1228 : move16();
728 :
729 198006 : FOR( i = start; i < stop; i++ )
730 : {
731 : /*x = max(0, (int)(log(powerSpectrum[i]) * INV_LOG_2));*/
732 :
733 : /*see IGF_getSFM for more comment */
734 196778 : x = sub( sub( powerSpectrum_exp, norm_l( powerSpectrum[i] ) ), 1 ); /*Q0*/
735 196778 : if ( powerSpectrum[i] == 0 ) /*special case: energy is zero*/
736 : {
737 544 : x = 0;
738 544 : move16();
739 : }
740 196778 : x = s_max( 0, x );
741 196778 : x_eff32 = L_mac0( x_eff32, x, x ); /*Q0*/
742 196778 : x_max = s_max( x_max, x ); /*Q0*/
743 : }
744 :
745 : /*x_eff /= (stop - start);*/
746 1228 : x_eff32 = BASOP_Util_Divide3216_Scale( x_eff32, sub( stop, start ), &s ); /*Q-1, s*/
747 1228 : s = add( s, 32 ); /*make x_eff Q31*/
748 :
749 : /*trunkate to int*/
750 1228 : x_eff32 = L_shr( x_eff32, sub( 31, s ) );
751 1228 : x_eff32 = L_shl( x_eff32, sub( 31, s ) );
752 :
753 1228 : test();
754 1228 : IF( x_eff32 > 0 && x_max > 0 )
755 : {
756 : /*crest = max(1.f, (float)x_max/sqrt(x_eff));*/
757 1048 : tmp32 = ISqrt32( x_eff32, &s ); /*Q31, s*/
758 1048 : tmp32 = Mpy_32_16_1( tmp32 /*Q31, s*/, x_max /*Q0*/ ); /*Q16, s*/
759 1048 : i = norm_l( tmp32 );
760 1048 : tmp32 = L_shl( tmp32, i ); /*Q31, s-i+15*/
761 1048 : crest = extract_h( tmp32 );
762 1048 : *crest_exp = add( sub( s, i ), 15 );
763 1048 : move16();
764 : /* limit crest factor to a lower bound of 1, may overflow */
765 : BASOP_SATURATE_WARNING_OFF_EVS
766 1048 : tmp = shl_sat( -1, sub( 15, *crest_exp ) ); /* build negative threshold */
767 1048 : tmp = add_sat( crest, tmp );
768 : BASOP_SATURATE_WARNING_ON_EVS
769 1048 : if ( tmp < 0 )
770 : {
771 0 : crest = 1;
772 0 : move16();
773 : }
774 1048 : if ( tmp < 0 )
775 : {
776 0 : *crest_exp = 15;
777 0 : move16();
778 : }
779 : }
780 :
781 1228 : return crest;
782 : }
783 :
784 796699 : Word16 IGF_getCrest_ivas( /**< out: Q15| crest factor */
785 : Word16 *crest_exp, /**< out: | exponent of crest factor */
786 : const Word32 *powerSpectrum, /**< in: Q31 | power spectrum */
787 : const Word16 *powerSpectrum_exp, /**< in: | exponent of power spectrum */
788 : const Word16 start, /**< in: Q0 | start subband index */
789 : const Word16 stop /**< in: Q0 | stop subband index */
790 : )
791 : {
792 : Word16 i;
793 : Word16 x;
794 : Word16 s;
795 : Word32 x_eff32;
796 : Word16 x_max;
797 : Word16 crest;
798 : Word16 tmp;
799 : Word32 tmp32;
800 :
801 796699 : x_eff32 = 0;
802 796699 : move32();
803 796699 : x_max = 0;
804 796699 : move16();
805 796699 : crest = 16384 /*.5f Q15*/;
806 796699 : move16();
807 796699 : *crest_exp = 1;
808 796699 : move16();
809 :
810 42470875 : FOR( i = start; i < stop; i++ )
811 : {
812 : /*x = max(0, (int)(log(powerSpectrum[i]) * INV_LOG_2));*/
813 :
814 : /*see IGF_getSFM for more comment */
815 41674176 : x = sub( sub( powerSpectrum_exp[i], norm_l( powerSpectrum[i] ) ), 1 ); /*Q0*/
816 41674176 : if ( powerSpectrum[i] == 0 ) /*special case: energy is zero*/
817 : {
818 333 : x = 0;
819 333 : move16();
820 : }
821 41674176 : x = s_max( 0, x );
822 41674176 : x_eff32 = L_mac0( x_eff32, x, x ); /*Q0*/
823 41674176 : x_max = s_max( x_max, x ); /*Q0*/
824 : }
825 :
826 : /*x_eff /= (stop - start);*/
827 796699 : x_eff32 = BASOP_Util_Divide3216_Scale( x_eff32, sub( stop, start ), &s ); /*Q-1, s*/
828 796699 : s = add( s, 32 ); /*make x_eff Q31*/
829 :
830 : /*trunkate to int*/
831 796699 : x_eff32 = L_shr( x_eff32, sub( 31, s ) );
832 796699 : x_eff32 = L_shl( x_eff32, sub( 31, s ) );
833 :
834 796699 : test();
835 796699 : IF( x_eff32 > 0 && x_max > 0 )
836 : {
837 : /*crest = max(1.f, (float)x_max/sqrt(x_eff));*/
838 734031 : tmp32 = ISqrt32( x_eff32, &s ); /*Q31, s*/
839 734031 : tmp32 = Mpy_32_16_1( tmp32 /*Q31, s*/, x_max /*Q0*/ ); /*Q16, s*/
840 734031 : i = norm_l( tmp32 );
841 734031 : tmp32 = L_shl( tmp32, i ); /*Q31, s-i+15*/
842 734031 : crest = extract_h( tmp32 );
843 734031 : *crest_exp = add( sub( s, i ), 15 );
844 734031 : move16();
845 : /* limit crest factor to a lower bound of 1, may overflow */
846 : BASOP_SATURATE_WARNING_OFF_EVS
847 734031 : tmp = shl_sat( -1, sub( 15, *crest_exp ) ); /* build negative threshold */
848 734031 : tmp = add_sat( crest, tmp );
849 : BASOP_SATURATE_WARNING_ON_EVS
850 734031 : if ( tmp < 0 )
851 : {
852 0 : crest = 1;
853 0 : move16();
854 : }
855 734031 : if ( tmp < 0 )
856 : {
857 0 : *crest_exp = 15;
858 0 : move16();
859 : }
860 : }
861 :
862 796699 : return crest;
863 : }
864 :
865 : /*************************************************************************
866 : calculates spectral flatness measurment
867 : **************************************************************************/
868 1228 : Word16 IGF_getSFM( /**< out: Q15| SFM value */
869 : Word16 *SFM_exp, /**< out: | exponent of SFM Factor */
870 : const Word32 *energy, /**< in: Q31| energies */
871 : const Word16 *energy_exp, /**< in: | exponent of energies */
872 : const Word16 start, /**< in: Q0 | start subband index */
873 : const Word16 stop /**< in: Q0 | stop subband index */
874 : )
875 : {
876 : Word16 n, i, s;
877 : Word32 num;
878 : Word32 denom;
879 : Word16 denom_exp;
880 : Word16 invDenom_exp, numf_exp;
881 : Word16 numf;
882 : Word32 SFM32;
883 : Word32 L_c;
884 : Word16 invDenom, SFM;
885 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
886 1228 : Flag Overflow = 0;
887 1228 : Flag Carry = 0;
888 1228 : move32();
889 1228 : move32();
890 : #endif
891 :
892 1228 : L_c = 0;
893 1228 : move32();
894 1228 : num = 0;
895 1228 : move32();
896 1228 : denom = L_shr( 2147483 /*0,001 in Q31 - float is "1", here*/, s_min( *energy_exp, 31 ) );
897 1228 : denom = L_max( denom, 1 );
898 1228 : *SFM_exp = 0;
899 1228 : move16();
900 1228 : SFM = 32767 /*1.0f Q15*/;
901 1228 : move16();
902 :
903 198006 : FOR( i = start; i < stop; i++ )
904 : {
905 : /*ln(x * 2^-Qx * 2^xExp) = ln(x) - Qx + xExp*/
906 :
907 : /* n = sub(sub(31,norm_l(tmp32)),1); */ /*<- ld */
908 : /* n = sub(n,31); */ /*<- -Qx */
909 : /* n = add(n,*energy_exp); */ /*<- +xExp */
910 :
911 196778 : n = sub( sub( *energy_exp, norm_l( energy[i] ) ), 1 ); /*<-- short form*/
912 :
913 196778 : if ( energy[i] == 0 ) /*special case: energy is zero*/
914 : {
915 544 : n = 0;
916 544 : move16();
917 : }
918 :
919 196778 : n = s_max( 0, n );
920 196778 : num = L_add( num, L_deposit_l( n ) ); /*Q0*/
921 :
922 196778 : Carry = 0;
923 196778 : move32();
924 196778 : denom = L_add_co( energy[i], denom, &Carry, &Overflow );
925 196778 : Overflow = 0;
926 196778 : move32();
927 196778 : L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow );
928 : }
929 :
930 1228 : denom = norm_llQ31( L_c, denom, &denom_exp ); /*Q31*/
931 1228 : denom_exp = add( denom_exp, *energy_exp );
932 :
933 : /* calculate SFM only if signal is present */
934 1228 : IF( denom != 0 )
935 : {
936 : /*numf = (float)num / (float)(stop - start);*/
937 1228 : numf = BASOP_Util_Divide3216_Scale( num, /*Q0*/
938 1228 : sub( stop, start ), /*Q0*/
939 : &s ); /*Q-1 s*/
940 1228 : numf_exp = add( s, 16 ); /*-> numf Q15 numf_exp*/
941 : /*denom /= (float)(stop - start);*/
942 : /*return ((float)pow(2.0, numf + 0.5f) / denom);*/
943 :
944 : /*SFM= ((float)pow(2.0, numf + 0.5f) * invDenom);*/
945 1228 : invDenom = BASOP_Util_Divide3232_uu_1616_Scale( L_deposit_l( sub( stop, start ) ) /*Q0*/,
946 : denom /*Q31, denom_exp*/,
947 : &s ); /*Q-16, s-denom_exp*/
948 1228 : invDenom_exp = add( sub( s, denom_exp ), 31 ); /*invDenom: Q15, invDenom_exp*/
949 :
950 : /*add .5f to numf*/
951 1228 : SFM32 = L_add( L_shl( L_deposit_l( numf ), numf_exp ) /*16Q15*/, 16384l /*.5f Q15*/ ); /*16Q15*/
952 1228 : s = norm_l( SFM32 );
953 1228 : SFM32 = L_shl( SFM32, s );
954 1228 : s = sub( 16, s ); /*SFM32(numf) is Q31 now*/
955 :
956 : /*do the pow2 and the mult*/
957 1228 : SFM32 = BASOP_util_Pow2( SFM32, s, &s );
958 1228 : SFM32 = Mpy_32_16_1( SFM32, invDenom );
959 1228 : *SFM_exp = add( s, invDenom_exp );
960 :
961 : /*Transform to Q15*/
962 1228 : s = norm_l( SFM32 );
963 1228 : SFM = round_fx_sat( L_shl_sat( SFM32, s ) );
964 1228 : *SFM_exp = sub( *SFM_exp, s );
965 1228 : move16();
966 : /**SFM_exp = s_min(*SFM_exp, 0);*/
967 1228 : IF( *SFM_exp > 0 )
968 : {
969 180 : *SFM_exp = 0;
970 180 : move16();
971 180 : SFM = 32767 /*1.0f Q15*/;
972 180 : move16();
973 : }
974 : }
975 :
976 1228 : return SFM /*Q15*/;
977 : }
978 :
979 : /*************************************************************************
980 : calculates spectral flatness measurment
981 : **************************************************************************/
982 796699 : Word16 IGF_getSFM_ivas_fx( /**< out: Q15| SFM value */
983 : Word16 *SFM_exp, /**< out: | exponent of SFM Factor */
984 : const Word32 *energy, /**< in: Q31| energies */
985 : const Word16 *energy_exp, /**< in: | exponent of energies */
986 : const Word16 start, /**< in: Q0 | start subband index */
987 : const Word16 stop /**< in: Q0 | stop subband index */
988 : )
989 : {
990 : Word16 n, i, s;
991 : Word32 num;
992 : Word32 denom;
993 : Word16 denom_exp;
994 : Word16 invDenom_exp, numf_exp;
995 : Word16 numf;
996 : Word32 SFM32;
997 : Word16 invDenom, SFM;
998 :
999 796699 : num = 0;
1000 796699 : move32();
1001 796699 : denom = 65536; // 1.f in Q16
1002 796699 : denom_exp = 15;
1003 796699 : *SFM_exp = 0;
1004 796699 : move16();
1005 796699 : SFM = 32767 /*1.0f Q15*/;
1006 796699 : move16();
1007 :
1008 42470875 : FOR( i = start; i < stop; i++ )
1009 : {
1010 : /*ln(x * 2^-Qx * 2^xExp) = ln(x) - Qx + xExp*/
1011 :
1012 : /* n = sub(sub(31,norm_l(tmp32)),1); */ /*<- ld */
1013 : /* n = sub(n,31); */ /*<- -Qx */
1014 : /* n = add(n,*energy_exp); */ /*<- +xExp */
1015 :
1016 41674176 : n = sub( sub( energy_exp[i], norm_l( energy[i] ) ), 1 ); /*<-- short form*/
1017 :
1018 41674176 : if ( energy[i] == 0 ) /*special case: energy is zero*/
1019 : {
1020 333 : n = 0;
1021 333 : move16();
1022 : }
1023 :
1024 41674176 : n = s_max( 0, n );
1025 41674176 : num = L_add( num, L_deposit_l( n ) ); /*Q0*/
1026 :
1027 41674176 : denom = BASOP_Util_Add_Mant32Exp( energy[i], energy_exp[i], denom, denom_exp, &denom_exp );
1028 : }
1029 :
1030 : /* calculate SFM only if signal is present */
1031 796699 : IF( denom != 0 )
1032 : {
1033 : /*numf = (float)num / (float)(stop - start);*/
1034 796699 : numf = BASOP_Util_Divide3216_Scale( num, /*Q0*/
1035 796699 : sub( stop, start ), /*Q0*/
1036 : &s ); /*Q-1 s*/
1037 796699 : numf_exp = add( s, 16 ); /*-> numf Q15 numf_exp*/
1038 : /*denom /= (float)(stop - start);*/
1039 : /*return ((float)pow(2.0, numf + 0.5f) / denom);*/
1040 :
1041 : /*SFM= ((float)pow(2.0, numf + 0.5f) * invDenom);*/
1042 796699 : invDenom = BASOP_Util_Divide3232_uu_1616_Scale( L_deposit_l( sub( stop, start ) ) /*Q0*/,
1043 : denom /*Q31, denom_exp*/,
1044 : &s ); /*Q-16, s-denom_exp*/
1045 796699 : invDenom_exp = add( sub( s, denom_exp ), 31 ); /*invDenom: Q15, invDenom_exp*/
1046 :
1047 : /*add .5f to numf*/
1048 796699 : SFM32 = L_add( L_shl( L_deposit_l( numf ), numf_exp ) /*16Q15*/, 16384l /*.5f Q15*/ ); /*16Q15*/
1049 796699 : s = norm_l( SFM32 );
1050 796699 : SFM32 = L_shl( SFM32, s );
1051 796699 : s = sub( 16, s ); /*SFM32(numf) is Q31 now*/
1052 :
1053 : /*do the pow2 and the mult*/
1054 796699 : SFM32 = BASOP_util_Pow2( SFM32, s, &s );
1055 796699 : SFM32 = Mpy_32_16_1( SFM32, invDenom );
1056 796699 : *SFM_exp = add( s, invDenom_exp );
1057 :
1058 : /*Transform to Q15*/
1059 796699 : s = norm_l( SFM32 );
1060 796699 : SFM = round_fx_sat( L_shl_sat( SFM32, s ) );
1061 796699 : *SFM_exp = sub( *SFM_exp, s );
1062 796699 : move16();
1063 : /**SFM_exp = s_min(*SFM_exp, 0);*/
1064 796699 : IF( *SFM_exp > 0 )
1065 : {
1066 61198 : *SFM_exp = 0;
1067 61198 : move16();
1068 61198 : SFM = 32767 /*1.0f Q15*/;
1069 61198 : move16();
1070 : }
1071 : }
1072 :
1073 796699 : return SFM /*Q15*/;
1074 : }
1075 :
1076 : /**********************************************************************/ /*
1077 : calculates the IGF whitening levels by SFM and crest
1078 : **************************************************************************/
1079 637 : static void IGF_Whitening( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */
1080 : Word32 *powerSpectrum, /**< in: Q31 | MDCT/MDST power spectrum */
1081 : const Word16 powerSpectrum_exp, /**< in: | exponent of powerspectrum */
1082 : const Word16 igfGridIdx, /**< in: Q0 | IGF grid index */
1083 : Word16 isTransient, /**< in: Q0 | boolean, indicating if transient is detected */
1084 : Word16 last_core_acelp /**< in: Q0 | indictaor if last frame was acelp coded */
1085 : )
1086 : {
1087 : IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
1088 : H_IGF_GRID hGrid;
1089 : Word16 p; /*Q0*/
1090 : Word16 tmp;
1091 : Word16 SFM;
1092 : Word16 crest;
1093 : Word16 SFM_exp;
1094 : Word16 crest_exp;
1095 : Word16 s;
1096 : Word32 tmp32;
1097 : Word32 SFM32;
1098 :
1099 637 : hPrivateData = &hInstance->igfData;
1100 637 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
1101 :
1102 637 : IF( igfGridIdx != IGF_GRID_LB_NORM )
1103 : {
1104 125 : FOR( p = 0; p < hGrid->nTiles; p++ )
1105 : {
1106 : /* reset filter */
1107 91 : hPrivateData->prevSFM_FIR[p] = L_deposit_l( 0 );
1108 91 : move32();
1109 91 : hPrivateData->prevSFM_IIR[p] = 0;
1110 91 : move16();
1111 :
1112 : /* preset values: */
1113 91 : hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_OFF;
1114 91 : move16();
1115 : }
1116 : }
1117 7007 : FOR( p = 0; p < IGF_MAX_TILES; p++ )
1118 : {
1119 : /* update prev data: */
1120 6370 : hPrivateData->igfPrevWhiteningLevel[p] = hPrivateData->igfCurrWhiteningLevel[p];
1121 6370 : move16();
1122 : /* preset values: */
1123 6370 : hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_OFF;
1124 6370 : move16();
1125 : }
1126 :
1127 637 : IF( !s_or( isTransient, hPrivateData->wasTransient ) )
1128 : {
1129 614 : IF( powerSpectrum )
1130 : {
1131 614 : Word16 nT = hGrid->nTiles;
1132 614 : move16();
1133 614 : SWITCH( hPrivateData->igfInfo.bitRateIndex )
1134 : {
1135 374 : case IGF_BITRATE_WB_9600:
1136 : case IGF_BITRATE_SWB_9600:
1137 : case IGF_BITRATE_SWB_16400:
1138 : case IGF_BITRATE_SWB_24400:
1139 : case IGF_BITRATE_SWB_32000:
1140 : case IGF_BITRATE_FB_16400:
1141 : case IGF_BITRATE_FB_24400:
1142 : case IGF_BITRATE_FB_32000:
1143 374 : nT = sub( nT, 1 );
1144 374 : BREAK;
1145 240 : default:
1146 240 : BREAK;
1147 : }
1148 1842 : FOR( p = 0; p < nT; p++ )
1149 : {
1150 : /*tmp = IGF_getSFM(powerSpectrum, hGrid->tile[p], hGrid->tile[p+1]) / IGF_getCrest(powerSpectrum, hGrid->tile[p], hGrid->tile[p+1]);*/
1151 1228 : SFM = IGF_getSFM( &SFM_exp, powerSpectrum, &powerSpectrum_exp, hGrid->tile[p], hGrid->tile[p + 1] );
1152 1228 : crest = IGF_getCrest( &crest_exp, powerSpectrum, powerSpectrum_exp, hGrid->tile[p], hGrid->tile[p + 1] );
1153 :
1154 1228 : tmp = BASOP_Util_Divide1616_Scale( SFM, crest, &s ); /* Q15 */
1155 1228 : s = add( s, sub( SFM_exp, crest_exp ) );
1156 1228 : tmp32 = L_shl( L_deposit_l( tmp ) /*16Q15, s*/, add( s, 1 ) ); /* 15Q16 */
1157 :
1158 1228 : test();
1159 1228 : IF( last_core_acelp || hPrivateData->wasTransient )
1160 : {
1161 68 : hPrivateData->prevSFM_FIR[p] = tmp32; /* 15Q16 */
1162 68 : move32();
1163 68 : hPrivateData->prevSFM_IIR[p] = shr( tmp, 2 ); /* 2Q13 */
1164 68 : move16();
1165 : }
1166 :
1167 : /*SFM = tmp + hPrivateData->prevSFM_FIR[p] + 0.5f * hPrivateData->prevSFM_IIR[p];*/
1168 1228 : SFM32 = L_add( tmp32, hPrivateData->prevSFM_FIR[p] );
1169 1228 : SFM32 = L_mac0( SFM32, hPrivateData->prevSFM_IIR[p] /*Q13*/, 4 /*.5f Q3*/ ); /*15Q16*/
1170 :
1171 : BASOP_SATURATE_WARNING_OFF_EVS
1172 : /*SFM = min(2.7f, SFM);*/
1173 : /*Overflow possible in shift, intended*/
1174 1228 : tmp = add_sat( crest, tmp );
1175 1228 : SFM = s_min( 22118 /*2.7f Q13*/, extract_h( L_shr_sat( SFM32, 16 - 29 ) /*->Q29*/ ) /*->Q13*/ );
1176 : BASOP_SATURATE_WARNING_ON_EVS
1177 :
1178 1228 : hPrivateData->prevSFM_FIR[p] = tmp32; /*15Q16*/
1179 1228 : move32();
1180 1228 : hPrivateData->prevSFM_IIR[p] = SFM;
1181 1228 : move16();
1182 :
1183 1228 : IF( GT_16( SFM, hGrid->whiteningThreshold[1][p] ) )
1184 : {
1185 627 : hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_STRONG;
1186 627 : move16();
1187 : }
1188 601 : ELSE IF( GT_16( SFM, hGrid->whiteningThreshold[0][p] ) )
1189 : {
1190 395 : hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_MID;
1191 395 : move16();
1192 : }
1193 : }
1194 614 : SWITCH( hPrivateData->igfInfo.bitRateIndex )
1195 : {
1196 374 : case IGF_BITRATE_WB_9600:
1197 : case IGF_BITRATE_RF_WB_13200:
1198 : case IGF_BITRATE_RF_SWB_13200:
1199 : case IGF_BITRATE_SWB_9600:
1200 : case IGF_BITRATE_SWB_16400:
1201 : case IGF_BITRATE_SWB_24400:
1202 : case IGF_BITRATE_SWB_32000:
1203 : case IGF_BITRATE_FB_16400:
1204 : case IGF_BITRATE_FB_24400:
1205 : case IGF_BITRATE_FB_32000:
1206 374 : move16();
1207 374 : hPrivateData->igfCurrWhiteningLevel[hGrid->nTiles - 1] = hPrivateData->igfCurrWhiteningLevel[hGrid->nTiles - 2];
1208 374 : BREAK;
1209 240 : default:
1210 240 : BREAK;
1211 : }
1212 : }
1213 : ELSE
1214 : {
1215 0 : FOR( p = 0; p < hGrid->nTiles; p++ )
1216 : {
1217 0 : hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_MID;
1218 0 : move16();
1219 : }
1220 : }
1221 : }
1222 : ELSE
1223 : {
1224 : /* reset filter */
1225 253 : FOR( p = 0; p < IGF_MAX_TILES; p++ )
1226 : {
1227 230 : hPrivateData->prevSFM_FIR[p] = L_deposit_l( 0 );
1228 230 : move32();
1229 230 : hPrivateData->prevSFM_IIR[p] = 0;
1230 230 : move16();
1231 : }
1232 : }
1233 637 : hPrivateData->wasTransient = isTransient;
1234 637 : move16();
1235 637 : }
1236 :
1237 : /**********************************************************************/ /*
1238 : write whitening levels into bitstream
1239 : **************************************************************************/
1240 1970 : static void IGF_WriteWhiteningTile_fx( /**< out: Q0 | number of bits written */
1241 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
1242 : Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */
1243 : Word16 whiteningLevel /**< in: Q0 | whitening levels to write */
1244 : )
1245 : {
1246 1970 : IF( EQ_32( whiteningLevel, IGF_WHITENING_MID ) )
1247 : {
1248 656 : IGF_write_bits( hBstr, pBitOffset, 0, 1 );
1249 : }
1250 : ELSE
1251 : {
1252 1314 : IGF_write_bits( hBstr, pBitOffset, 1, 1 );
1253 1314 : IF( EQ_32( whiteningLevel, IGF_WHITENING_OFF ) )
1254 : {
1255 394 : IGF_write_bits( hBstr, pBitOffset, 0, 1 );
1256 : }
1257 : ELSE
1258 : {
1259 920 : IGF_write_bits( hBstr, pBitOffset, 1, 1 );
1260 : }
1261 : }
1262 1970 : }
1263 :
1264 : /**********************************************************************/ /*
1265 : writes the whitening levels
1266 : **************************************************************************/
1267 1274 : static void IGF_WriteWhiteningLevels_fx( /**< out: Q0 | total number of bits written */
1268 : const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF encoder */
1269 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
1270 : Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */
1271 : const Word16 igfGridIdx, /**< in: Q0 | igf grid index see declaration of IGF_GRID_IDX for details */
1272 : const Word16 isIndepFlag /**< in: Q0 | if 1 frame is independent, 0 = frame is coded with data from previous frame */
1273 : )
1274 : {
1275 : IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
1276 : H_IGF_GRID hGrid;
1277 : Word16 p;
1278 : Word16 nTiles;
1279 : Word16 isSame;
1280 : Word32 tmp32;
1281 :
1282 :
1283 1274 : isSame = 1;
1284 1274 : move16();
1285 1274 : hPrivateData = &hInstance->igfData;
1286 1274 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
1287 1274 : nTiles = hGrid->nTiles;
1288 1274 : move16();
1289 :
1290 1274 : IF( isIndepFlag )
1291 : {
1292 1274 : isSame = 0;
1293 1274 : move16();
1294 : }
1295 : ELSE
1296 : {
1297 0 : p = 0;
1298 0 : move16();
1299 0 : tmp32 = 0;
1300 0 : move32();
1301 0 : test();
1302 0 : WHILE( ( LT_16( p, nTiles ) ) && ( tmp32 == 0 ) )
1303 : {
1304 0 : test();
1305 0 : tmp32 = L_sub( hPrivateData->igfCurrWhiteningLevel[p], hPrivateData->igfPrevWhiteningLevel[p] );
1306 0 : if ( tmp32 != 0 )
1307 : {
1308 0 : isSame = 0;
1309 0 : move16();
1310 : }
1311 0 : p++;
1312 : }
1313 : }
1314 1274 : IF( isSame )
1315 : {
1316 0 : IGF_write_bits( hBstr, pBitOffset, 1, 1 );
1317 : }
1318 : ELSE
1319 : {
1320 1274 : IF( !isIndepFlag )
1321 : {
1322 0 : IGF_write_bits( hBstr, pBitOffset, 0, 1 );
1323 : }
1324 1274 : IGF_WriteWhiteningTile_fx( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[0] );
1325 1274 : p = 1;
1326 1274 : move16();
1327 1274 : tmp32 = 0;
1328 1274 : move32();
1329 1274 : if ( LT_16( p, nTiles ) )
1330 : {
1331 1274 : isSame = 1;
1332 1274 : move16();
1333 : }
1334 1274 : test();
1335 3024 : WHILE( ( LT_16( p, nTiles ) ) && ( tmp32 == 0 ) )
1336 : {
1337 1750 : test();
1338 1750 : tmp32 = L_sub( hPrivateData->igfCurrWhiteningLevel[p], hPrivateData->igfCurrWhiteningLevel[p - 1] );
1339 1750 : if ( tmp32 != 0 )
1340 : {
1341 420 : isSame = 0;
1342 420 : move16();
1343 : }
1344 1750 : p++;
1345 : }
1346 :
1347 1274 : IF( !isSame )
1348 : {
1349 420 : IGF_write_bits( hBstr, pBitOffset, 1, 1 );
1350 1116 : FOR( p = 1; p < nTiles; p++ )
1351 : {
1352 696 : IGF_WriteWhiteningTile_fx( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[p] );
1353 : }
1354 : }
1355 : ELSE
1356 : {
1357 854 : IGF_write_bits( hBstr, pBitOffset, 0, 1 );
1358 : }
1359 : }
1360 1274 : }
1361 :
1362 : /**********************************************************************/ /*
1363 : write flattening trigger
1364 : **************************************************************************/
1365 1274 : static void IGF_WriteFlatteningTrigger_fx( /**< out: | number of bits written */
1366 : const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */
1367 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
1368 : Word16 *pBitOffset /**< in: | ptr to bitOffset counter */
1369 : )
1370 : {
1371 : Word16 flatteningTrigger;
1372 :
1373 :
1374 1274 : flatteningTrigger = hInstance->flatteningTrigger;
1375 1274 : move16();
1376 :
1377 1274 : IGF_write_bits( hBstr, pBitOffset, flatteningTrigger, 1 );
1378 1274 : }
1379 :
1380 : /**********************************************************************/ /*
1381 : updates the start/stop frequency of IGF according to igfGridIdx
1382 : **************************************************************************/
1383 1185659 : void IGF_UpdateInfo( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */
1384 : const Word16 igfGridIdx /**< in: Q0 | IGF grid index */
1385 : )
1386 : {
1387 : IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
1388 : H_IGF_GRID hGrid;
1389 :
1390 :
1391 1185659 : hPrivateData = &hInstance->igfData;
1392 1185659 : hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
1393 1185659 : hInstance->infoStartFrequency = hGrid->startFrequency;
1394 1185659 : move16();
1395 1185659 : hInstance->infoStopFrequency = hGrid->stopFrequency;
1396 1185659 : move16();
1397 1185659 : hInstance->infoStartLine = hGrid->startLine;
1398 1185659 : move16();
1399 1185659 : hInstance->infoStopLine = hGrid->stopLine;
1400 1185659 : move16();
1401 :
1402 1185659 : return;
1403 : }
1404 :
1405 : /**********************************************************************/ /*
1406 : IGF bitsream writer
1407 : **************************************************************************/
1408 1274 : Word16 IGFEncWriteBitstream_fx( /**< out: | number of bits written per frame */
1409 : const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */
1410 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
1411 : Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */
1412 : const Word16 igfGridIdx, /**< in: Q0 | igf grid index see declaration of IGF_GRID_IDX for details */
1413 : const Word16 isIndepFlag /**< in: Q0 | if 1 frame is independent, 0 = frame is coded with data from previous frame */
1414 : )
1415 : {
1416 : Word16 igfAllZero;
1417 : Word16 startBitCount;
1418 :
1419 :
1420 1274 : startBitCount = *pBitOffset;
1421 1274 : move16();
1422 1274 : hInstance->infoTotalBitsPerFrameWritten = 0;
1423 1274 : move16();
1424 :
1425 1274 : if ( isIndepFlag )
1426 : {
1427 1274 : hInstance->infoTotalBitsWritten = 0;
1428 1274 : move16();
1429 : }
1430 :
1431 1274 : IGF_WriteEnvelope( hInstance, /* i: instance handle of IGF Encoder */
1432 : hBstr, /* i: encoder state */
1433 : pBitOffset, /* i: ptr to bitOffset counter */
1434 : igfGridIdx, /* i: igf grid index see definition of IGF_GRID_IDX for details */
1435 : isIndepFlag, /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */
1436 : &igfAllZero ); /* o: *igfAllZero */
1437 :
1438 1274 : IGF_WriteWhiteningLevels_fx( hInstance, /* i: instance handle of IGF Encoder */
1439 : hBstr, /* i: encoder state */
1440 : pBitOffset, /* i: ptr to bitOffset counter */
1441 : igfGridIdx, /* i: igf grid index see definition of IGF_GRID_IDX for details */
1442 : isIndepFlag ); /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */
1443 :
1444 1274 : IGF_WriteFlatteningTrigger_fx( hInstance, /* i: instance handle of IGF Encoder */
1445 : hBstr, /* i: encoder state */
1446 : pBitOffset ); /* i: ptr to bitOffset counter */
1447 :
1448 1274 : hInstance->infoTotalBitsPerFrameWritten = sub( *pBitOffset, startBitCount );
1449 1274 : hInstance->infoTotalBitsWritten = add( hInstance->infoTotalBitsWritten, hInstance->infoTotalBitsPerFrameWritten );
1450 1274 : move16();
1451 1274 : move16();
1452 1274 : return hInstance->infoTotalBitsPerFrameWritten;
1453 : }
1454 :
1455 : /**********************************************************************/ /*
1456 : sets the IGF mode according to given bitrate
1457 : **************************************************************************/
1458 81 : void IGFEncSetMode_fx(
1459 : const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i/o: instance handle of IGF Encoder */
1460 : const Word32 total_brate, /* i : encoder total bitrate */
1461 : const Word16 bwidth, /* i : encoder audio bandwidth */
1462 : const Word16 element_mode, /* i : IVAS element mode */
1463 : const Word16 rf_mode /* i : flag to signal the RF mode */
1464 : )
1465 : {
1466 : IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
1467 : Word16 i;
1468 :
1469 81 : hPrivateData = &hIGFEnc->igfData;
1470 81 : hPrivateData->igfBitstreamBits = 0;
1471 81 : move16();
1472 81 : set16_fx( hPrivateData->igfScfQuantized, 0, IGF_MAX_SFB );
1473 81 : set16_fx( hPrivateData->igfCurrWhiteningLevel, 0, IGF_MAX_TILES );
1474 81 : set16_fx( hPrivateData->igfPrevWhiteningLevel, 0, IGF_MAX_TILES );
1475 26001 : FOR( i = 0; i < IGF_BITBUFSIZE / 8; i++ )
1476 : {
1477 25920 : hPrivateData->igfBitstream[i] = 0;
1478 25920 : move16();
1479 : }
1480 81 : hPrivateData->wasTransient = 0;
1481 81 : move16();
1482 81 : set32_fx( hPrivateData->prevSFM_FIR, 0, IGF_MAX_TILES );
1483 81 : set16_fx( hPrivateData->prevSFM_IIR, 0, IGF_MAX_TILES );
1484 :
1485 81 : IF( IGFCommonFuncsIGFConfiguration( total_brate, bwidth, element_mode, &hPrivateData->igfInfo, rf_mode ) != 0 )
1486 : {
1487 81 : IGFSCFEncoderOpen_fx( &hPrivateData->hIGFSCFArithEnc, &hPrivateData->igfInfo, total_brate, bwidth, element_mode, rf_mode );
1488 :
1489 81 : hIGFEnc->infoSamplingRate = hPrivateData->igfInfo.sampleRate;
1490 81 : move32();
1491 81 : hIGFEnc->infoStartFrequency = hPrivateData->igfInfo.grid[0].startFrequency;
1492 81 : move16();
1493 81 : hIGFEnc->infoStopFrequency = hPrivateData->igfInfo.grid[0].stopFrequency;
1494 81 : move16();
1495 81 : hIGFEnc->infoStartLine = hPrivateData->igfInfo.grid[0].startLine;
1496 81 : move16();
1497 81 : hIGFEnc->infoStopLine = hPrivateData->igfInfo.grid[0].stopLine;
1498 81 : move16();
1499 : }
1500 : ELSE
1501 : {
1502 : /* IGF configuration failed -> error! */
1503 0 : hIGFEnc->infoSamplingRate = 0;
1504 0 : move32();
1505 0 : hIGFEnc->infoStartFrequency = -1;
1506 0 : move16();
1507 0 : hIGFEnc->infoStopFrequency = -1;
1508 0 : move16();
1509 0 : hIGFEnc->infoStartLine = -1;
1510 0 : move16();
1511 0 : hIGFEnc->infoStopLine = -1;
1512 0 : move16();
1513 0 : fprintf( stderr, "IGFEncSetMode_fx: initialization error!\n" );
1514 : }
1515 :
1516 : /* reset remaining variables */
1517 81 : hIGFEnc->infoTotalBitsWritten = 0;
1518 81 : move16();
1519 81 : hIGFEnc->infoTotalBitsPerFrameWritten = 0;
1520 81 : move16();
1521 81 : hIGFEnc->flatteningTrigger = 0;
1522 81 : move16();
1523 81 : hIGFEnc->spec_be_igf_e = 0;
1524 81 : move16();
1525 81 : hIGFEnc->tns_predictionGain = 0;
1526 81 : move16();
1527 81 : set32_fx( hIGFEnc->spec_be_igf, 0, N_MAX_TCX - IGF_START_MN );
1528 81 : return;
1529 : }
1530 :
1531 : /*-------------------------------------------------------------------*
1532 : * pack_bit()
1533 : *
1534 : * insert a bit into packed octet
1535 : *-------------------------------------------------------------------*/
1536 :
1537 495184 : static void pack_bit_ivas_fx(
1538 : const Word16 bit, /* i : bit to be packed */
1539 : UWord8 **pt, /* i/o: pointer to octet array into which bit will be placed */
1540 : UWord8 *omask /* i/o: output mask to indicate where in the octet the bit is to be written */
1541 : )
1542 : {
1543 495184 : if ( EQ_16( *omask, 0x80 ) )
1544 : {
1545 66890 : **pt = 0;
1546 66890 : move16();
1547 : }
1548 :
1549 495184 : if ( bit != 0 )
1550 : {
1551 264914 : **pt = (UWord8) s_or( **pt, *omask );
1552 264914 : move16();
1553 : }
1554 :
1555 495184 : *omask = (UWord8) UL_lshr( *omask, 1 );
1556 495184 : move16();
1557 495184 : IF( *omask == 0 )
1558 : {
1559 57074 : *omask = 0x80;
1560 57074 : move16();
1561 57074 : ( *pt )++;
1562 : }
1563 :
1564 495184 : return;
1565 : }
1566 :
1567 : /*-------------------------------------------------------------------*
1568 : * IGFEncConcatenateBitstream_fx()
1569 : *
1570 : * IGF bitstream concatenation for TCX10 modes
1571 : *-------------------------------------------------------------------*/
1572 :
1573 22096 : void IGFEncConcatenateBitstream_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */
1574 : const Word16 bsBits, /* i : number of IGF bits written to list of indices */
1575 : BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */
1576 : )
1577 : {
1578 : Word16 i;
1579 : IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
1580 : Indice *ind_list;
1581 : UWord8 *pFrame; /* byte array with bit packet and byte aligned coded speech data */
1582 : Word16 *pFrame_size; /* number of bits in the binary encoded access unit [bits] */
1583 : Word16 k, nb_bits_written;
1584 : Word32 imask;
1585 : UWord8 omask;
1586 :
1587 22096 : hPrivateData = &hIGFEnc->igfData;
1588 :
1589 22096 : ind_list = &hBstr->ind_list[hBstr->nb_ind_tot - bsBits]; /* here, we assume that each bit has been written as a single indice */
1590 22096 : pFrame = hPrivateData->igfBitstream;
1591 22096 : move16();
1592 22096 : pFrame_size = &hPrivateData->igfBitstreamBits;
1593 22096 : move16();
1594 22096 : nb_bits_written = 0;
1595 22096 : move16();
1596 :
1597 22096 : omask = (UWord8) UL_lshr( 0x80, s_and( *pFrame_size, 0x7 ) );
1598 22096 : move16();
1599 22096 : pFrame += *pFrame_size >> 3;
1600 :
1601 : /* bitstream packing (conversion of individual indices into a serial stream) */
1602 517280 : FOR( i = 0; i < bsBits; i++ ){
1603 495184 : IF( ind_list[i].nb_bits > 0 ){
1604 : /* mask from MSB to LSB */
1605 495184 : imask = L_shl( 1, sub( ind_list[i].nb_bits, 1 ) );
1606 :
1607 : /* write bit by bit */
1608 990368 : FOR( k = 0; k < ind_list[i].nb_bits; k++ )
1609 : {
1610 495184 : pack_bit_ivas_fx( extract_l( L_and( ind_list[i].value, imask ) ), &pFrame, &omask );
1611 495184 : imask = L_shr( imask, 1 );
1612 : }
1613 495184 : nb_bits_written = add( nb_bits_written, ind_list[i].nb_bits );
1614 :
1615 : /* delete the indice */
1616 495184 : ind_list[i].nb_bits = -1;
1617 495184 : move16();
1618 : }
1619 : }
1620 :
1621 22096 : *pFrame_size = add( *pFrame_size, nb_bits_written );
1622 22096 : move16();
1623 :
1624 : /* update list of indices */
1625 22096 : hBstr->nb_ind_tot = sub( hBstr->nb_ind_tot, bsBits );
1626 22096 : hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, nb_bits_written );
1627 :
1628 22096 : return;
1629 : }
1630 : /**********************************************************************/ /*
1631 : IGF reset bitsream bit counter for TCX10 modes
1632 : **************************************************************************/
1633 11048 : void IGFEncResetTCX10BitCounter_fx( const IGF_ENC_INSTANCE_HANDLE hInstance /**< in: | instance handle of IGF Encoder */
1634 : )
1635 : {
1636 : IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
1637 :
1638 11048 : hPrivateData = &hInstance->igfData;
1639 11048 : hPrivateData->igfBitstreamBits = 0;
1640 11048 : move16();
1641 11048 : hInstance->infoTotalBitsWritten = 0;
1642 11048 : move16();
1643 :
1644 11048 : return;
1645 : }
1646 :
1647 : /**********************************************************************/ /*
1648 : IGF write concatenated bitsream for TCX10 modes
1649 : **************************************************************************/
1650 0 : Word16 IGFEncWriteConcatenatedBitstream_fx( /**< out: Q0 | total number of bits written */
1651 : const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */
1652 : BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */
1653 : )
1654 : {
1655 : IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
1656 : Word16 i;
1657 : Word16 tmp;
1658 : Word16 bitsLeft;
1659 : UWord8 *pBitstream;
1660 :
1661 0 : hPrivateData = &hInstance->igfData;
1662 0 : pBitstream = &hPrivateData->igfBitstream[0];
1663 :
1664 0 : tmp = shr( hPrivateData->igfBitstreamBits, 3 );
1665 0 : FOR( i = 0; i < tmp; i++ )
1666 : {
1667 0 : push_next_indice( hBstr, pBitstream[i], 8 );
1668 : }
1669 :
1670 0 : bitsLeft = s_and( hPrivateData->igfBitstreamBits, 0x7 );
1671 0 : IF( bitsLeft > 0 )
1672 : {
1673 0 : push_next_indice( hBstr, shr( pBitstream[i], sub( 8, bitsLeft ) ), bitsLeft );
1674 : }
1675 :
1676 0 : return hInstance->infoTotalBitsWritten;
1677 : }
1678 11048 : Word16 IGFEncWriteConcatenatedBitstream_ivas_fx( /**< out: Q0 | total number of bits written */
1679 : const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */
1680 : BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */
1681 : )
1682 : {
1683 : IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
1684 : Word16 i;
1685 : Word16 tmp;
1686 : Word16 bitsLeft;
1687 : UWord8 *pBitstream;
1688 :
1689 11048 : hPrivateData = &hInstance->igfData;
1690 11048 : pBitstream = &hPrivateData->igfBitstream[0];
1691 :
1692 11048 : tmp = shr( hPrivateData->igfBitstreamBits, 3 );
1693 68122 : FOR( i = 0; i < tmp; i++ )
1694 : {
1695 57074 : push_next_indice( hBstr, pBitstream[i], 8 );
1696 : }
1697 :
1698 11048 : bitsLeft = s_and( hPrivateData->igfBitstreamBits, 0x7 );
1699 11048 : IF( bitsLeft > 0 )
1700 : {
1701 9816 : push_next_indice( hBstr, shr( pBitstream[i], sub( 8, bitsLeft ) ), bitsLeft );
1702 : }
1703 :
1704 11048 : return hInstance->infoTotalBitsWritten;
1705 : }
1706 :
1707 : /**********************************************************************/ /*
1708 : apply the IGF encoder, main encoder interface
1709 : **************************************************************************/
1710 637 : void IGFEncApplyMono_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */
1711 : const Word16 igfGridIdx, /**< in: Q0 | IGF grid index */
1712 : Encoder_State *st, /**< in: | Encoder state */
1713 : Word32 *pMDCTSpectrum, /**< in: Q31 | MDCT spectrum */
1714 : Word16 MDCTSpectrum_e, /**< in: | exponent of MDCT spectrum */
1715 : Word32 *pPowerSpectrum, /**< in: Q31 | MDCT^2 + MDST^2 spectrum, or estimate */
1716 : Word16 PowerSpectrum_e, /**< in: | exponent of pPowerSpectrum */
1717 : Word16 isTCX20, /**< in: Q0 | flag indicating if the input is TCX20 or TCX10/2xTCX5 */
1718 : Word16 isTNSActive, /**< in: Q0 | flag indicating if the TNS is active */
1719 : Word16 last_core_acelp /**< in: Q0 | indicator if last frame was acelp coded */
1720 : )
1721 : {
1722 : Word32 *pPowerSpectrumParameter; /* If it is NULL it informs a function that specific handling is needed */
1723 : Word32 *pPowerSpectrumParameterWhitening; /* If it is NULL it informs a function that specific handling is needed */
1724 : Word16 highPassEner_exp; /*exponent of highpass energy - maybe not needed*/
1725 :
1726 :
1727 637 : pPowerSpectrumParameter = NULL;
1728 637 : test();
1729 637 : if ( ( isTNSActive == 0 ) && ( isTCX20 != 0 ) )
1730 : {
1731 633 : pPowerSpectrumParameter = pPowerSpectrum;
1732 : }
1733 637 : pPowerSpectrumParameterWhitening = NULL;
1734 637 : if ( isTCX20 != 0 )
1735 : {
1736 637 : pPowerSpectrumParameterWhitening = pPowerSpectrum;
1737 : }
1738 :
1739 637 : IGF_UpdateInfo( hInstance, /* i: instance handle of IGF Encoder */
1740 : igfGridIdx ); /* i: IGF grid index */
1741 :
1742 637 : IGF_CalculateEnvelope( hInstance, /* i: instance handle of IGF Encoder */
1743 : pMDCTSpectrum, /* i: MDCT spectrum */
1744 : MDCTSpectrum_e, /* i: exponent of MDCT spectrum */
1745 : pPowerSpectrumParameter, /* i: MDCT^2 + MDST^2 spectrum, or estimate */
1746 : PowerSpectrum_e, /* i: exponent of pPowerSpectrum */
1747 : igfGridIdx /* i: IGF grid index */
1748 : );
1749 :
1750 :
1751 637 : IGF_Whitening( hInstance, /* i: instance handle of IGF Encoder */
1752 : pPowerSpectrumParameterWhitening, /* i: MDCT^2 + MDST^2 spectrum, or estimate */
1753 : PowerSpectrum_e, /* i: exponent of powerSpectrum */
1754 : igfGridIdx, /* i: IGF grid index */
1755 637 : ( st->transientDetection.transientDetector.bIsAttackPresent == 1 ),
1756 : last_core_acelp ); /* i: last frame was acelp indicator */
1757 :
1758 637 : pPowerSpectrumParameter = NULL;
1759 637 : if ( isTCX20 != 0 )
1760 : {
1761 637 : pPowerSpectrumParameter = pPowerSpectrum;
1762 : }
1763 :
1764 637 : IGF_ErodeSpectrum( /* o: highpass energy */
1765 : &highPassEner_exp, /* o: exponent of highPassEner */
1766 : hInstance, /* i: instance handle of IGF Encoder */
1767 : pMDCTSpectrum, /* i: MDCT spectrum */
1768 : pPowerSpectrumParameter, /* i: MDCT^2 + MDST^2 spectrum, or estimate */
1769 : PowerSpectrum_e, /* i: exponent of pPowerSpectrum */
1770 : igfGridIdx ); /* i: IGF grid index */
1771 637 : }
1772 :
1773 :
1774 13357 : ivas_error IGF_Reconfig_fx(
1775 : IGF_ENC_INSTANCE_HANDLE *hIGFEnc, /* i/o: instance handle of IGF Encoder */
1776 : const Word16 igf, /* i : IGF on/off */
1777 : const Word16 reset, /* i : reset flag */
1778 : const Word32 brate, /* i : bitrate for configuration */
1779 : const Word16 bwidth, /* i : signal bandwidth */
1780 : const Word16 element_mode, /* i : IVAS element mode */
1781 : const Word16 rf_mode /* i : flag to signal the RF mode */
1782 : )
1783 : {
1784 : ivas_error error;
1785 :
1786 13357 : error = IVAS_ERR_OK;
1787 13357 : move32();
1788 :
1789 13357 : test();
1790 13357 : test();
1791 13357 : test();
1792 13357 : IF( igf && *hIGFEnc == NULL )
1793 : {
1794 831 : IF( ( *hIGFEnc = (IGF_ENC_INSTANCE_HANDLE) malloc( sizeof( IGF_ENC_INSTANCE ) ) ) == NULL )
1795 : {
1796 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hIGFEnc\n" ) );
1797 : }
1798 831 : IGFEncSetMode_ivas_fx( *hIGFEnc, brate, bwidth, element_mode, rf_mode );
1799 : }
1800 12526 : ELSE IF( igf && reset )
1801 : {
1802 0 : IGFEncSetMode_ivas_fx( *hIGFEnc, brate, bwidth, element_mode, rf_mode );
1803 : }
1804 12526 : ELSE IF( !igf && *hIGFEnc != NULL )
1805 : {
1806 1018 : free( *hIGFEnc );
1807 1018 : *hIGFEnc = NULL;
1808 : }
1809 :
1810 13357 : return error;
1811 : }
|