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