Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 :
6 : #include <stdlib.h>
7 : #include <stdio.h>
8 : #include <assert.h>
9 : #include "stl.h"
10 : #include "options.h"
11 : #include "cnst.h"
12 : //#include "prot_fx.h"
13 : #include "rom_basop_util.h"
14 : #include "basop_util.h"
15 : #include "rom_com.h"
16 : #include "prot_fx.h" /* Function prototypes */
17 : #include "prot_fx_enc.h" /* Function prototypes */
18 : #include "ivas_prot_fx.h"
19 :
20 : #define inv_int InvIntTable
21 : extern const Word16 int_sqr[17];
22 :
23 : #define ONE_POINT_ONE_FIVE_Q7 147
24 : #define ONE_POINT_ONE_FIVE_Q23 9646899
25 :
26 4982909 : static Word16 quantize( Word32 x, Word16 invGain, Word16 shift, Word32 offset )
27 : {
28 : Word16 tmp16;
29 : Word32 tmp32;
30 :
31 4982909 : tmp32 = Mpy_32_16_1( L_abs( x ), invGain ); /* multiply */
32 4982909 : tmp32 = L_shl( tmp32, shift ); /* convert to 15Q16 */
33 4982909 : tmp32 = L_add( tmp32, offset ); /* add offset */
34 4982909 : tmp16 = extract_h( tmp32 ); /* truncate */
35 4982909 : IF( x < 0 )
36 : {
37 2463580 : tmp16 = negate( tmp16 ); /* restore sign */
38 : }
39 :
40 4982909 : return tmp16;
41 : }
42 :
43 : /* compute noise-measure flags for spectrum filling and quantization (0: tonal, 1: noise-like) */
44 478680 : void ComputeSpectrumNoiseMeasure_fx( const Word32 *powerSpec,
45 : Word16 L_frame,
46 : Word16 startLine,
47 : Word8 resetMemory,
48 : Word8 *noiseFlags,
49 : Word16 lowpassLine )
50 : {
51 : Word16 i, lastTone, j;
52 : Word32 s, c;
53 : Word16 tmp16;
54 478680 : Word32 tmp1, tmp2 = 0; /* initialization only to avoid compiler warning, not counted */
55 478680 : move32();
56 :
57 478680 : IF( resetMemory != 0 )
58 : {
59 26706360 : FOR( i = 0; i < lowpassLine; i++ )
60 : {
61 26678800 : noiseFlags[i] = 0;
62 26678800 : move16();
63 : }
64 : }
65 :
66 478680 : FOR( i = lowpassLine; i < L_frame; i++ )
67 : {
68 0 : noiseFlags[i] = 1;
69 0 : move16();
70 : }
71 :
72 478680 : test();
73 478680 : IF( powerSpec != NULL && LT_16( add( startLine, 6 ), L_frame ) )
74 : {
75 472712 : lastTone = 0;
76 472712 : move16();
77 :
78 : /* noise-measure flags for spectrum filling and quantization (0: tonal, 1: noise-like) */
79 472712 : i = sub( startLine, 1 );
80 472712 : s = 0;
81 472712 : move32();
82 7563392 : FOR( j = -7; j < 8; j++ )
83 : {
84 7090680 : s = L_add( s, L_shr( powerSpec[i + j], 4 ) );
85 : }
86 472712 : tmp16 = sub( lowpassLine, 7 );
87 299055711 : FOR( i = i + 1; i < tmp16; i++ )
88 : {
89 298582999 : c = L_shr( powerSpec[i - 1], 4 );
90 298582999 : c = L_add( c, L_shr( powerSpec[i], 4 ) );
91 298582999 : c = L_add( c, L_shr( powerSpec[i + 1], 4 ) );
92 :
93 298582999 : s = L_sub( s, L_shr( powerSpec[i - 8], 4 ) );
94 298582999 : s = L_add( s, L_shr( powerSpec[i + 7], 4 ) );
95 :
96 298582999 : tmp1 = L_shr( c, 2 );
97 298582999 : IF( noiseFlags[i] == 0 )
98 : {
99 21520930 : c = L_shl( c, 1 );
100 : }
101 298582999 : IF( noiseFlags[i] == 0 )
102 : {
103 21520930 : tmp2 = L_sub( c, tmp1 ); /* 1.75 * c */
104 : }
105 298582999 : IF( noiseFlags[i] != 0 )
106 : {
107 277062069 : tmp2 = L_add( c, tmp1 ); /* 1.25 * c */
108 : }
109 :
110 298582999 : tmp2 = L_sub( s, tmp2 );
111 298582999 : if ( tmp2 >= 0 )
112 : {
113 296905733 : noiseFlags[i] = 1;
114 296905733 : move16();
115 : }
116 298582999 : if ( tmp2 < 0 )
117 : {
118 1677266 : noiseFlags[i] = 0;
119 1677266 : move16();
120 : }
121 298582999 : if ( tmp2 < 0 )
122 : {
123 1677266 : lastTone = i;
124 1677266 : move16();
125 : }
126 : }
127 :
128 : /* lower L_frame*startRatio lines are tonal (0), upper 7 lines are processed separately */
129 472712 : tmp16 = sub( lowpassLine, 1 );
130 3308984 : FOR( ; i < tmp16; i++ )
131 : {
132 2836272 : c = L_shr( powerSpec[i - 1], 4 );
133 2836272 : c = L_add( c, L_shr( powerSpec[i], 4 ) );
134 2836272 : c = L_add( c, L_shr( powerSpec[i + 1], 4 ) );
135 :
136 2836272 : tmp1 = L_shr( c, 2 );
137 2836272 : IF( noiseFlags[i] == 0 )
138 : {
139 169018 : c = L_shl( c, 1 );
140 : }
141 2836272 : IF( noiseFlags[i] == 0 )
142 : {
143 169018 : tmp2 = L_sub( c, tmp1 ); /* 1.75 * c */
144 : }
145 2836272 : IF( noiseFlags[i] != 0 )
146 : {
147 2667254 : tmp2 = L_add( c, tmp1 ); /* 1.25 * c */
148 : }
149 :
150 : /* running sum can't be updated any more, just use the latest one */
151 2836272 : tmp2 = L_sub( s, tmp2 );
152 2836272 : if ( tmp2 >= 0 )
153 : {
154 2830003 : noiseFlags[i] = 1;
155 2830003 : move16();
156 : }
157 2836272 : if ( tmp2 < 0 )
158 : {
159 6269 : noiseFlags[i] = 0;
160 6269 : move16();
161 : /* lastTone = i; */
162 : }
163 : }
164 472712 : noiseFlags[i] = 1; /* uppermost line is defined as noise-like (1) */
165 472712 : move16();
166 :
167 472712 : if ( lastTone > 0 ) /* spread uppermost tonal line one line upward */
168 : {
169 146944 : noiseFlags[lastTone + 1] = 0;
170 146944 : move16();
171 : }
172 : }
173 478680 : }
174 :
175 147090 : void ComputeSpectrumNoiseMeasure_ivas_fx( Word64 *powerSpec, /* Qx */
176 : Word16 L_frame, /* Q0 */
177 : Word16 startLine, /* Q0 */
178 : Word8 resetMemory, /* Q0 */
179 : Word8 *noiseFlags, /* Q0 */
180 : Word16 lowpassLine /* Q0 */
181 : )
182 : {
183 : Word16 i, lastTone, j, exp;
184 : Word32 c;
185 : Word64 s, temp;
186 :
187 147090 : IF( resetMemory != 0 )
188 : {
189 6508542 : FOR( i = 0; i < lowpassLine; i++ )
190 : {
191 6500960 : noiseFlags[i] = 0;
192 6500960 : move16();
193 : }
194 : }
195 :
196 147090 : FOR( i = lowpassLine; i < L_frame; i++ )
197 : {
198 0 : noiseFlags[i] = 1;
199 0 : move16();
200 : }
201 :
202 147090 : test();
203 147090 : IF( powerSpec != NULL && LT_16( add( startLine, 6 ), L_frame ) )
204 : {
205 134198 : lastTone = 0;
206 134198 : move16();
207 :
208 : /* noise-measure flags for spectrum filling and quantization (0: tonal, 1: noise-like) */
209 134198 : i = sub( startLine, 1 );
210 : /* s = powerSpec[i - 7] + powerSpec[i - 6] + powerSpec[i - 5] +
211 : powerSpec[i - 4] + powerSpec[i - 3] + powerSpec[i - 2] +
212 : powerSpec[i - 1] + powerSpec[i] + powerSpec[i + 1] +
213 : powerSpec[i + 2] + powerSpec[i + 3] + powerSpec[i + 4] +
214 : powerSpec[i + 5] + powerSpec[i + 6] + powerSpec[i + 7]; */
215 :
216 134198 : s = powerSpec[i - 7]; // Qx
217 134198 : move64();
218 2012970 : FOR( j = -6; j < 8; j++ )
219 : {
220 1878772 : s = W_add( s, powerSpec[i + j] ); // Qx
221 : }
222 :
223 63530738 : FOR( i = i + 1; i < lowpassLine - 7; i++ )
224 : {
225 : /* c = powerSpec[i - 1] + powerSpec[i] + powerSpec[i + 1]; */
226 63396540 : temp = W_add( W_add( powerSpec[i - 1], powerSpec[i] ), powerSpec[i + 1] );
227 63396540 : exp = W_norm( temp );
228 63396540 : c = W_extract_h( W_shl( temp, exp ) ); // Qx+exp-32
229 :
230 : /* s += powerSpec[i + 7] - powerSpec[i - 8]; */
231 63396540 : s = W_sub( s, powerSpec[i - 8] ); // Qx
232 63396540 : s = W_add( s, powerSpec[i + 7] ); // Qx
233 :
234 : /* ( 1.75f - 0.5f * noiseFlags[i] ) * c */
235 63396540 : temp = W_mult_32_32( c, L_msu0( 28672 /* 1.75 in Q14*/, 8192 /* 0.5 in Q14 */, noiseFlags[i] ) ); // Qx+exp-32+14+1 = Qx+exp-17
236 :
237 63396540 : IF( GE_64( W_shl( s, sub( exp, Q17 ) ), temp ) /* s >= ( 1.75f - 0.5f * noiseFlags[i] ) * c */ ) // Qx+exp-17
238 : {
239 63243624 : noiseFlags[i] = 1;
240 63243624 : move16();
241 : }
242 : ELSE
243 : {
244 152916 : noiseFlags[i] = 0;
245 152916 : lastTone = i;
246 152916 : move16();
247 152916 : move16();
248 : }
249 : }
250 :
251 : /* lower L_frame*startRatio lines are tonal (0), upper 7 lines are processed separately */
252 939386 : FOR( ; i < lowpassLine - 1; i++ )
253 : {
254 : /* c = powerSpec[i - 1] + powerSpec[i] + powerSpec[i + 1]; */
255 805188 : temp = W_add( W_add( powerSpec[i - 1], powerSpec[i] ), powerSpec[i + 1] );
256 805188 : exp = W_norm( temp );
257 805188 : c = W_extract_h( W_shl( temp, exp ) ); // Qx+exp-32
258 :
259 : /* ( 1.75f - 0.5f * noiseFlags[i] ) * c */
260 805188 : temp = W_mult_32_32( c, L_msu0( 28672 /* 1.75 in Q14*/, 8192 /* 0.5 in Q14 */, noiseFlags[i] ) ); // Qx+exp-32+14+1 = Qx+exp-17
261 :
262 805188 : IF( GE_64( W_shl( s, sub( exp, Q17 ) ), temp ) /* s >= ( 1.75f - 0.5f * noiseFlags[i] ) * c */ ) // Qx+exp-17
263 : {
264 801140 : noiseFlags[i] = 1;
265 801140 : move16();
266 : }
267 : ELSE
268 : {
269 4048 : noiseFlags[i] = 0;
270 4048 : lastTone = i;
271 4048 : move16();
272 4048 : move16();
273 : }
274 : }
275 134198 : noiseFlags[i] = 1; /* uppermost line is defined as noise-like (1) */
276 134198 : move16();
277 :
278 134198 : if ( lastTone > 0 ) /* spread uppermost tonal line one line upward */
279 : {
280 26064 : noiseFlags[lastTone + 1] = 0;
281 26064 : move16();
282 : }
283 : }
284 147090 : }
285 :
286 88880 : static void detectLowpassFac( const Word32 *powerSpec, Word16 powerSpec_e, Word16 L_frame, Word8 rectWin, Word16 *pLpFac, Word16 lowpassLine )
287 : {
288 : Word16 i, tmp;
289 : Word32 threshold;
290 : #ifndef ISSUE_1867_replace_overflow_libenc
291 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
292 : Flag Overflow = 0;
293 : move32();
294 : #endif
295 : #endif
296 :
297 :
298 88880 : threshold = 256l /*0.1f * 2*NORM_MDCT_FACTOR Q3*/; /* Q3 */
299 88880 : move32();
300 : BASOP_SATURATE_WARNING_OFF_EVS /* Allow saturation, because threshold is being compared to powerSpec[i] below. */
301 : #ifdef ISSUE_1867_replace_overflow_libenc
302 88880 : threshold = L_shl_sat( threshold, sub( 28, powerSpec_e ) );
303 : #else
304 : threshold = L_shl_o( threshold, sub( 28, powerSpec_e ), &Overflow );
305 : #endif
306 :
307 88880 : IF( rectWin != 0 )
308 : {
309 : /* compensate for bad side-lobe attenuation with asymmetric windows */
310 : #ifdef ISSUE_1867_replace_overflow_libenc
311 5740 : threshold = L_shl_sat( threshold, 1 );
312 : #else
313 : threshold = L_shl_o( threshold, 1, &Overflow );
314 : #endif
315 : }
316 : BASOP_SATURATE_WARNING_ON_EVS
317 :
318 88880 : tmp = shr( lowpassLine, 1 );
319 1886103 : FOR( i = lowpassLine - 1; i >= tmp; i-- )
320 : {
321 1879394 : IF( GT_32( powerSpec[i], threshold ) )
322 : {
323 82171 : BREAK;
324 : }
325 : }
326 :
327 88880 : tmp = getInvFrameLen( L_frame );
328 :
329 88880 : tmp = mult_r( 22938 /*0.7f Q15*/, round_fx( L_shl( L_mult0( add( i, 1 ), tmp ), 9 ) ) );
330 88880 : *pLpFac = add( tmp, mult_r( 9830 /*0.3f Q15*/, *pLpFac ) );
331 88880 : move16();
332 88880 : }
333 :
334 : /*-----------------------------------------------------------*
335 : * Compute noise-measure flags for spectrum filling *
336 : * and quantization (0: tonal, 1: noise-like). *
337 : * Detect low pass if present. *
338 : *-----------------------------------------------------------*/
339 634 : void AnalyzePowerSpectrum_fx(
340 : Encoder_State *st, /* i/o: encoder states */
341 : Word16 L_frame, /* input: frame length */
342 : Word16 L_frameTCX, /* input: full band frame length */
343 : Word16 left_overlap, /* input: left overlap length */
344 : Word16 right_overlap, /* input: right overlap length */
345 : Word32 const mdctSpectrum[], /* input: MDCT spectrum */
346 : Word16 mdctSpectrum_e,
347 : Word16 const signal[], /* input: windowed signal corresponding to mdctSpectrum */
348 : Word32 powerSpec[], /* output: Power spectrum. Can point to signal */
349 : Word16 *powerSpec_e )
350 : {
351 : Word16 i, iStart, iEnd, lowpassLine;
352 : Word16 tmp, s1, s2;
353 : Word32 tmp32;
354 : Word8 tmp8;
355 634 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
356 :
357 634 : lowpassLine = L_frameTCX;
358 634 : move16();
359 :
360 634 : *powerSpec_e = 16;
361 634 : move16();
362 634 : TCX_MDST( signal, powerSpec, powerSpec_e, left_overlap, sub( L_frameTCX, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode );
363 :
364 634 : iStart = 0;
365 634 : move16();
366 634 : iEnd = L_frameTCX;
367 634 : move16();
368 :
369 634 : IF( st->narrowBand != 0 )
370 : {
371 0 : attenuateNbSpectrum_fx( L_frameTCX, powerSpec );
372 : }
373 :
374 : /* get shift to common exponent */
375 634 : s1 = 0;
376 634 : move16();
377 634 : s2 = 0;
378 634 : move16();
379 634 : tmp = sub( mdctSpectrum_e, *powerSpec_e );
380 634 : IF( tmp > 0 )
381 : {
382 349 : s2 = negate( tmp );
383 : }
384 634 : if ( tmp < 0 )
385 : {
386 0 : s1 = tmp;
387 0 : move16();
388 : }
389 :
390 : /* get headroom */
391 634 : tmp = sub( getScaleFactor32( mdctSpectrum, L_frameTCX ), s1 );
392 634 : tmp = s_min( tmp, sub( getScaleFactor32( powerSpec, L_frameTCX ), s2 ) );
393 634 : s1 = add( s1, tmp );
394 634 : s2 = add( s2, tmp );
395 :
396 : /* power spectrum: MDCT^2 + MDST^2 */
397 533354 : FOR( i = iStart; i < iEnd; i++ )
398 : {
399 532720 : tmp = round_fx_sat( L_shl_sat( mdctSpectrum[i], s1 ) );
400 532720 : tmp32 = L_mult0( tmp, tmp );
401 :
402 532720 : tmp = round_fx_sat( L_shl_sat( powerSpec[i], s2 ) );
403 532720 : tmp32 = L_mac0( tmp32, tmp, tmp );
404 :
405 532720 : powerSpec[i] = tmp32;
406 532720 : move32();
407 : }
408 :
409 634 : *powerSpec_e = add( shl( sub( mdctSpectrum_e, s1 ), 1 ), 1 );
410 634 : move16();
411 :
412 634 : tmp8 = 0;
413 634 : move16();
414 634 : test();
415 634 : if ( L_msu0( L_mult0( st->L_frame, extract_l( st->last_sr_core ) ), st->L_frame_past, extract_l( st->sr_core ) ) != 0 || NE_16( st->last_core, TCX_20_CORE ) )
416 : {
417 88 : tmp8 = 1;
418 88 : move16();
419 : }
420 :
421 634 : ComputeSpectrumNoiseMeasure_fx( powerSpec,
422 : L_frameTCX,
423 634 : divide3216( L_mult( hTcxEnc->nmStartLine, L_frame ), st->L_frame ),
424 : tmp8,
425 634 : hTcxEnc->memQuantZeros,
426 : lowpassLine );
427 :
428 634 : IF( LE_32( st->total_brate, ACELP_24k40 ) )
429 : {
430 634 : lowpassLine = shl( mult( st->hTcxCfg->bandwidth, L_frame ), 1 );
431 :
432 634 : detectLowpassFac( powerSpec, *powerSpec_e,
433 : L_frame,
434 634 : sub( st->last_core, ACELP_CORE ) == 0,
435 : &hTcxEnc->measuredBwRatio,
436 : lowpassLine );
437 : }
438 : ELSE
439 : {
440 0 : hTcxEnc->measuredBwRatio = 0x4000;
441 0 : move16();
442 : }
443 634 : }
444 :
445 233208 : void AnalyzePowerSpectrum_ivas_fx(
446 : Encoder_State *st, /* i/o: encoder states */
447 : Word16 L_frame, /* input: frame length */
448 : Word16 L_frameTCX, /* input: full band frame length */
449 : Word16 left_overlap, /* input: left overlap length */
450 : Word16 right_overlap, /* input: right overlap length */
451 : Word32 const mdctSpectrum[], /* input: MDCT spectrum */
452 : Word16 mdctSpectrum_e,
453 : Word16 const signal[], /* input: windowed signal corresponding to mdctSpectrum */
454 : const Word16 q_signal,
455 : Word32 powerSpec[], /* output: Power spectrum. Can point to signal */
456 : Word16 powerSpec_e[] )
457 : {
458 : Word16 i, iStart, iEnd, lowpassLine;
459 : Word16 shift;
460 : Word32 tmp32;
461 : Word8 tmp8;
462 233208 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
463 : Word32 common_powerSpec[N_MAX + L_MDCT_OVLP_MAX];
464 233208 : lowpassLine = L_frameTCX;
465 233208 : move16();
466 :
467 233208 : Word16 temp_powerSpec_e = sub( 16, q_signal );
468 233208 : TCX_MDST( signal, powerSpec, &temp_powerSpec_e, left_overlap, sub( L_frameTCX, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode );
469 :
470 233208 : shift = L_norm_arr( powerSpec, N_MAX + L_MDCT_OVLP_MAX );
471 233208 : scale_sig32( powerSpec, N_MAX + L_MDCT_OVLP_MAX, shift );
472 233208 : set16_fx( powerSpec_e, sub( temp_powerSpec_e, shift ), N_MAX + L_MDCT_OVLP_MAX );
473 :
474 233208 : iStart = 0;
475 233208 : move16();
476 233208 : iEnd = L_frameTCX;
477 233208 : move16();
478 :
479 233208 : IF( st->narrowBand != 0 )
480 : {
481 0 : attenuateNbSpectrum_fx( L_frameTCX, powerSpec );
482 : }
483 :
484 233208 : temp_powerSpec_e = MIN16B;
485 233208 : move16();
486 : /* power spectrum: MDCT^2 + MDST^2 */
487 216223448 : FOR( i = iStart; i < iEnd; i++ )
488 : {
489 215990240 : powerSpec[i] = Mpy_32_32( powerSpec[i], powerSpec[i] );
490 215990240 : move32();
491 215990240 : shift = norm_l( mdctSpectrum[i] );
492 215990240 : tmp32 = L_shl( mdctSpectrum[i], shift );
493 215990240 : powerSpec[i] = BASOP_Util_Add_Mant32Exp( powerSpec[i], shl( powerSpec_e[i], 1 ), Mpy_32_32( tmp32, tmp32 ), shl( sub( mdctSpectrum_e, shift ), 1 ), &powerSpec_e[i] );
494 215990240 : move32();
495 215990240 : IF( LT_16( powerSpec_e[i], -31 ) )
496 : {
497 14 : powerSpec[i] = L_shl( powerSpec[i], sub( powerSpec_e[i], -31 ) );
498 14 : move32();
499 14 : powerSpec_e[i] = -31;
500 14 : move16();
501 : }
502 215990240 : temp_powerSpec_e = s_max( temp_powerSpec_e, powerSpec_e[i] );
503 : }
504 :
505 378030168 : FOR( i = 0; i < N_MAX + L_MDCT_OVLP_MAX; i++ )
506 : {
507 377796960 : common_powerSpec[i] = L_shl( powerSpec[i], sub( powerSpec_e[i], temp_powerSpec_e ) );
508 377796960 : move32();
509 : }
510 :
511 233208 : tmp8 = 0;
512 233208 : move16();
513 233208 : test();
514 233208 : if ( L_msu0( L_mult0( st->L_frame, extract_l( st->last_sr_core ) ), st->L_frame_past, extract_l( st->sr_core ) ) != 0 || NE_16( st->last_core, TCX_20_CORE ) )
515 : {
516 19000 : tmp8 = 1;
517 19000 : move16();
518 : }
519 :
520 233208 : ComputeSpectrumNoiseMeasure_fx( common_powerSpec,
521 : L_frameTCX,
522 233208 : divide3216( L_mult( hTcxEnc->nmStartLine, L_frame ), st->L_frame ),
523 : tmp8,
524 233208 : hTcxEnc->memQuantZeros,
525 : lowpassLine );
526 :
527 233208 : IF( LE_32( st->total_brate, ACELP_24k40 ) )
528 : {
529 88246 : lowpassLine = shl( mult( st->hTcxCfg->bandwidth, L_frame ), 1 );
530 :
531 88246 : detectLowpassFac( common_powerSpec, temp_powerSpec_e,
532 : L_frame,
533 88246 : sub( st->last_core, ACELP_CORE ) == 0,
534 : &hTcxEnc->measuredBwRatio,
535 : lowpassLine );
536 : }
537 : ELSE
538 : {
539 144962 : hTcxEnc->measuredBwRatio = 0x4000;
540 144962 : move16();
541 : }
542 233208 : }
543 :
544 693931 : void AdaptLowFreqEmph_fx( Word32 x[],
545 : Word16 x_e,
546 : Word16 xq[],
547 : Word16 invGain,
548 : Word16 invGain_e,
549 : Word16 tcx_lpc_shaped_ari,
550 : Word16 lpcGains[],
551 : Word16 lpcGains_e[],
552 : const Word16 lg )
553 : {
554 : Word16 i, i_max, i_max_old, lg_4, tmp16, s;
555 : Word32 tmp32;
556 :
557 :
558 693931 : IF( tcx_lpc_shaped_ari == 0 )
559 : {
560 676506 : lg_4 = shr( lg, 2 );
561 :
562 : /* 1. find first magnitude maximum in lower quarter of spectrum */
563 676506 : invGain_e = add( invGain_e, 1 );
564 676506 : i_max = -1;
565 676506 : move16();
566 :
567 8005835 : FOR( i = 0; i < lg_4; i++ )
568 : {
569 7982406 : tmp32 = Mpy_32_16_1( L_abs( x[i] ), invGain ); /* multiply */
570 7982406 : tmp32 = L_shl( tmp32, sub( add( x_e, invGain_e ), 15 ) ); /* convert to 15Q16 */
571 :
572 7982406 : test();
573 7982406 : IF( ( GE_16( abs_s( xq[i] ), 2 ) ) && ( tmp32 >= 0x3A000 ) ) /* 0x3A000 -> 3.625 (15Q16) */
574 : {
575 :
576 : /* Debug initialization to catch illegal cases of xq[i] */
577 653077 : tmp16 = 0;
578 653077 : move16();
579 :
580 653077 : if ( xq[i] > 0 )
581 : {
582 324655 : tmp16 = 2;
583 324655 : move16();
584 : }
585 653077 : if ( xq[i] < 0 )
586 : {
587 328422 : tmp16 = -2;
588 328422 : move16();
589 : }
590 :
591 653077 : assert( tmp16 != 0 );
592 :
593 653077 : xq[i] = add( xq[i], tmp16 );
594 653077 : move16();
595 :
596 653077 : i_max = i;
597 653077 : move16();
598 653077 : BREAK;
599 : }
600 : }
601 :
602 676506 : s = sub( add( x_e, invGain_e ), 15 );
603 :
604 : /* 2. compress value range of all xq up to i_max: add two steps */
605 3430555 : FOR( i = 0; i < i_max; i++ )
606 : {
607 2754049 : xq[i] = quantize( x[i], invGain, s, 0x6000 );
608 2754049 : move16();
609 : }
610 :
611 : /* 3. find first mag. maximum below i_max which is half as high */
612 676506 : i_max_old = i_max;
613 676506 : move16();
614 :
615 676506 : IF( i_max_old >= 0 )
616 : {
617 653077 : invGain_e = add( invGain_e, 1 );
618 653077 : i_max = -1; /* reset first maximum, update inverse gain */
619 653077 : move16();
620 :
621 2258750 : FOR( i = 0; i < lg_4; i++ )
622 : {
623 2258750 : tmp32 = Mpy_32_16_1( L_abs( x[i] ), invGain ); /* multiply */
624 2258750 : tmp32 = L_shl( tmp32, sub( add( x_e, invGain_e ), 15 ) ); /* convert to 15Q16 */
625 :
626 2258750 : test();
627 2258750 : IF( ( GE_16( abs_s( xq[i] ), 2 ) ) && ( tmp32 >= 0x3A000 ) ) /* 0x3A000 -> 3.625 (15Q16) */
628 : {
629 :
630 : /* Debug initialization to catch illegal cases of xq[i] */
631 653077 : tmp16 = 0;
632 653077 : move16();
633 :
634 653077 : if ( xq[i] > 0 )
635 : {
636 326598 : tmp16 = 2;
637 326598 : move16();
638 : }
639 653077 : if ( xq[i] < 0 )
640 : {
641 326479 : tmp16 = -2;
642 326479 : move16();
643 : }
644 :
645 653077 : assert( tmp16 != 0 );
646 :
647 653077 : xq[i] = add( xq[i], tmp16 );
648 653077 : move16();
649 :
650 653077 : i_max = i;
651 653077 : move16();
652 653077 : BREAK;
653 : }
654 : }
655 : }
656 :
657 676506 : s = sub( add( x_e, invGain_e ), 15 );
658 :
659 : /* 4. re-compress and quantize all xq up to half-height i_max+1 */
660 2282179 : FOR( i = 0; i < i_max; i++ )
661 : {
662 1605673 : xq[i] = quantize( x[i], invGain, s, 0x6000 );
663 1605673 : move16();
664 : }
665 :
666 : /* 5. always compress 2 lines; lines could be at index 0 and 1! */
667 676506 : IF( i_max_old >= 0 )
668 : {
669 653077 : invGain_e = sub( invGain_e, 1 ); /* reset inverse gain */
670 653077 : if ( LT_16( i_max, i_max_old ) )
671 : {
672 279570 : i_max = i_max_old;
673 279570 : move16();
674 : }
675 : }
676 :
677 676506 : i = add( i_max, 1 );
678 :
679 676506 : tmp32 = Mpy_32_16_1( L_abs( x[i] ), invGain ); /* multiply */
680 676506 : tmp32 = L_shl( tmp32, sub( add( x_e, invGain_e ), 15 ) ); /* convert to 15Q16 */
681 676506 : IF( GE_32( tmp32, 0x3A000 ) )
682 : {
683 :
684 : /* Debug initialization to catch illegal cases of xq[i] */
685 386773 : tmp16 = 0;
686 386773 : move16();
687 :
688 386773 : if ( xq[i] > 0 )
689 : {
690 195760 : tmp16 = 2;
691 195760 : move16();
692 : }
693 386773 : if ( xq[i] < 0 )
694 : {
695 191013 : tmp16 = -2;
696 191013 : move16();
697 : }
698 :
699 386773 : assert( tmp16 != 0 );
700 :
701 386773 : xq[i] = add( xq[i], tmp16 );
702 386773 : move16();
703 : }
704 : ELSE
705 : {
706 289733 : xq[i] = quantize( x[i], invGain, sub( add( x_e, invGain_e ), 15 ), 0x6000 );
707 289733 : move16();
708 : }
709 :
710 676506 : i = add( i, 1 );
711 :
712 676506 : tmp32 = Mpy_32_16_1( L_abs( x[i] ), invGain ); /* multiply */
713 676506 : tmp32 = L_shl( tmp32, sub( add( x_e, invGain_e ), 15 ) ); /* convert to 15Q16 */
714 676506 : IF( GE_32( tmp32, 0x3A000 ) )
715 : {
716 :
717 : /* Debug initialization to catch illegal cases of xq[i] */
718 343052 : tmp16 = 0;
719 343052 : move16();
720 :
721 343052 : if ( xq[i] > 0 )
722 : {
723 171783 : tmp16 = 2;
724 171783 : move16();
725 : }
726 343052 : if ( xq[i] < 0 )
727 : {
728 171269 : tmp16 = -2;
729 171269 : move16();
730 : }
731 :
732 343052 : assert( tmp16 != 0 );
733 :
734 343052 : xq[i] = add( xq[i], tmp16 );
735 343052 : move16();
736 : }
737 : ELSE
738 : {
739 333454 : xq[i] = quantize( x[i], invGain, sub( add( x_e, invGain_e ), 15 ), 0x6000 );
740 333454 : move16();
741 : }
742 : }
743 : ELSE /*if(!tcx_lpc_shaped_ari)*/
744 : {
745 17425 : PsychAdaptLowFreqEmph_fx( x, lpcGains, lpcGains_e );
746 : } /*if(!tcx_lpc_shaped_ari)*/
747 693931 : }
748 :
749 21155 : void PsychAdaptLowFreqEmph_fx( Word32 x[],
750 : const Word16 lpcGains[],
751 : const Word16 lpcGains_e[] )
752 : {
753 : Word16 i;
754 : Word16 max, max_e, fac, min, min_e, tmp, tmp_e;
755 : Word32 L_tmp;
756 :
757 :
758 21155 : assert( lpcGains[0] >= 0x4000 );
759 :
760 21155 : max = lpcGains[0];
761 21155 : move16();
762 21155 : max_e = lpcGains_e[0];
763 21155 : move16();
764 21155 : min = lpcGains[0];
765 21155 : move16();
766 21155 : min_e = lpcGains_e[0];
767 21155 : move16();
768 :
769 : /* find minimum (min) and maximum (max) of LPC gains in low frequencies */
770 190395 : FOR( i = 1; i < 9; i++ )
771 : {
772 169240 : IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], min, min_e ) < 0 )
773 : {
774 127554 : min = lpcGains[i];
775 127554 : move16();
776 127554 : min_e = lpcGains_e[i];
777 127554 : move16();
778 : }
779 :
780 169240 : IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], max, max_e ) > 0 )
781 : {
782 29469 : max = lpcGains[i];
783 29469 : move16();
784 29469 : max_e = lpcGains_e[i];
785 29469 : move16();
786 : }
787 : }
788 :
789 21155 : min_e = add( min_e, 5 ); /* min *= 32.0f; */
790 :
791 21155 : test();
792 21155 : IF( ( compMantExp16Unorm( max, max_e, min, min_e ) < 0 ) && ( max > 0 ) )
793 : {
794 : /* fac = tmp = (float)pow(min / max, 0.0078125f); */
795 21155 : tmp_e = max_e;
796 21155 : move16();
797 21155 : tmp = Inv16( max, &tmp_e );
798 21155 : L_tmp = L_shl( L_mult( tmp, min ), sub( add( tmp_e, min_e ), 6 ) ); /* Q25 */
799 21155 : L_tmp = L_add( BASOP_Util_Log2( L_tmp ), 6 << 25 ); /* Q25 */
800 21155 : L_tmp = L_shr( L_tmp, 7 ); /* 0.0078125f = 1.f/(1<<7) */
801 21155 : L_tmp = BASOP_Util_InvLog2( L_sub( L_tmp, 1 << 25 ) ); /* Q30 */
802 21155 : tmp = round_fx( L_tmp ); /* Q14 */
803 21155 : fac = shr( tmp, 1 ); /* Q13 */
804 :
805 : /* gradual boosting of lowest 32 bins; DC is boosted by (min/max)^1/4 */
806 698115 : FOR( i = 31; i >= 0; i-- )
807 : {
808 676960 : x[i] = L_shl( Mpy_32_16_1( x[i], fac ), 2 );
809 676960 : move32();
810 676960 : fac = shl( mult_r( fac, tmp ), 1 );
811 : }
812 : }
813 21155 : }
814 :
815 634 : Word16 SQ_gain_fx( /* output: SQ gain */
816 : Word32 x[], /* input: vector to quantize */
817 : Word16 x_e, /* input: exponent */
818 : Word16 nbitsSQ, /* input: number of bits targeted */
819 : Word16 lg, /* input: vector size (2048 max) */
820 : Word16 *gain_e ) /* output: SQ gain exponent */
821 : {
822 : Word16 i, iter, lg_4, s, tmp16;
823 : Word32 ener, tmp32;
824 : Word32 target, fac, offset;
825 : Word32 en[N_MAX / 4];
826 :
827 :
828 634 : lg_4 = shr( lg, 2 );
829 :
830 : /* energy of quadruples with 9dB offset */
831 103594 : FOR( i = 0; i < lg_4; i++ )
832 : {
833 : /* normalization */
834 102960 : s = 15;
835 102960 : move16();
836 :
837 102960 : tmp16 = norm_l( x[0] );
838 102960 : IF( x[0] != 0 )
839 : {
840 41163 : s = s_min( s, tmp16 );
841 : }
842 :
843 102960 : tmp16 = norm_l( x[1] );
844 102960 : IF( x[1] != 0 )
845 : {
846 41168 : s = s_min( s, tmp16 );
847 : }
848 :
849 102960 : tmp16 = norm_l( x[2] );
850 102960 : IF( x[2] != 0 )
851 : {
852 41168 : s = s_min( s, tmp16 );
853 : }
854 102960 : tmp16 = norm_l( x[3] );
855 102960 : IF( x[3] != 0 )
856 : {
857 41160 : s = s_min( s, tmp16 );
858 : }
859 :
860 102960 : s = sub( s, 2 ); /* 2 bits headroom */
861 :
862 : /* calc quadruple energy */
863 102960 : ener = L_deposit_l( 1 );
864 :
865 102960 : tmp16 = extract_h( L_shl( x[0], s ) );
866 102960 : ener = L_mac( ener, tmp16, tmp16 );
867 :
868 102960 : tmp16 = extract_h( L_shl( x[1], s ) );
869 102960 : ener = L_mac( ener, tmp16, tmp16 );
870 :
871 102960 : tmp16 = extract_h( L_shl( x[2], s ) );
872 102960 : ener = L_mac( ener, tmp16, tmp16 );
873 :
874 102960 : tmp16 = extract_h( L_shl( x[3], s ) );
875 102960 : ener = L_mac( ener, tmp16, tmp16 );
876 :
877 102960 : s = shl( sub( x_e, s ), 1 );
878 :
879 : /* log */
880 102960 : tmp32 = L_add( BASOP_Util_Log2( ener ), L_shl( L_deposit_l( s ), 25 ) ); /* log2, 6Q25 */
881 102960 : en[i] = L_shr( tmp32, 9 ); /* 15Q16 */
882 102960 : move32();
883 102960 : x += 4;
884 : }
885 :
886 : /* SQ scale: 4 bits / 6 dB per quadruple */
887 634 : target = L_mult( 0x3FC8, sub( nbitsSQ, shr( lg, 4 ) ) ); /* 0x3FC8 -> 0.15*log2(10) */
888 634 : fac = L_add( 0x2A854B, 0 ); /* -> 12.8f*log2(10); */
889 634 : offset = L_add( fac, 0 );
890 :
891 : /* find offset (0 to 128 dB with step of 0.125dB) */
892 6974 : FOR( iter = 0; iter < 10; iter++ )
893 : {
894 6340 : fac = L_shr( fac, 1 );
895 6340 : offset = L_sub( offset, fac );
896 6340 : ener = L_deposit_l( 0 );
897 :
898 760101 : FOR( i = 0; i < lg_4; i++ )
899 : {
900 756156 : tmp32 = L_sub( en[i], offset );
901 :
902 : /* avoid SV with 1 bin of amp < 0.5f */
903 756156 : IF( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 0.3*log2(10); */
904 : {
905 185652 : ener = L_add( ener, tmp32 );
906 : }
907 :
908 : /* if ener is above target -> break and increase offset */
909 756156 : IF( GT_32( ener, target ) )
910 : {
911 2395 : offset = L_add( offset, fac );
912 2395 : BREAK;
913 : }
914 : }
915 : }
916 :
917 634 : offset = L_add( L_shr( offset, 1 ), 0x17EB0 ); /* 0x17EB0 -> 0.45*log2(10) */
918 :
919 634 : *gain_e = add( extract_h( offset ), 1 );
920 634 : move16();
921 634 : offset = L_sub( L_and( offset, 0xFFFF ), 0x10000 );
922 634 : tmp16 = extract_h( BASOP_Util_InvLog2( L_shl( offset, 9 ) ) );
923 :
924 : /* return gain */
925 :
926 634 : return tmp16;
927 : }
928 :
929 221065 : Word16 SQ_gain_ivas_fx( /* output: SQ gain */
930 : Word32 x[], /* input: vector to quantize */
931 : Word16 x_e, /* input: exponent */
932 : Word16 nbitsSQ, /* input: number of bits targeted */
933 : Word16 lg, /* input: vector size (2048 max) */
934 : Word16 *gain_e ) /* output: SQ gain exponent */
935 : {
936 : Word16 i, iter, lg_4, s, tmp16;
937 : Word32 ener, tmp32;
938 : Word32 target, fac, offset;
939 : Word32 en[N_MAX / 4];
940 :
941 :
942 221065 : lg_4 = shr( lg, 2 );
943 :
944 : /* energy of quadruples with 9dB offset */
945 47155945 : FOR( i = 0; i < lg_4; i++ )
946 : {
947 : /* normalization */
948 46934880 : s = 15;
949 46934880 : move16();
950 :
951 46934880 : tmp16 = norm_l( x[0] );
952 46934880 : IF( x[0] != 0 )
953 : {
954 22323761 : s = s_min( s, tmp16 );
955 : }
956 :
957 46934880 : tmp16 = norm_l( x[1] );
958 46934880 : IF( x[1] != 0 )
959 : {
960 22323904 : s = s_min( s, tmp16 );
961 : }
962 :
963 46934880 : tmp16 = norm_l( x[2] );
964 46934880 : IF( x[2] != 0 )
965 : {
966 22322372 : s = s_min( s, tmp16 );
967 : }
968 :
969 46934880 : tmp16 = norm_l( x[3] );
970 46934880 : IF( x[3] != 0 )
971 : {
972 22322496 : s = s_min( s, tmp16 );
973 : }
974 :
975 46934880 : s = sub( s, 2 ); /* 2 bits headroom */
976 :
977 : /* calc quadruple energy */
978 46934880 : ener = L_deposit_l( 1 );
979 :
980 46934880 : tmp16 = extract_h( L_shl( x[0], s ) );
981 46934880 : ener = L_mac( ener, tmp16, tmp16 );
982 :
983 46934880 : tmp16 = extract_h( L_shl( x[1], s ) );
984 46934880 : ener = L_mac( ener, tmp16, tmp16 );
985 :
986 46934880 : tmp16 = extract_h( L_shl( x[2], s ) );
987 46934880 : ener = L_mac( ener, tmp16, tmp16 );
988 :
989 46934880 : tmp16 = extract_h( L_shl( x[3], s ) );
990 46934880 : ener = L_mac( ener, tmp16, tmp16 );
991 :
992 46934880 : s = shl( sub( x_e, s ), 1 );
993 :
994 : /* log */
995 46934880 : IF( EQ_32( ener, 1 ) )
996 : {
997 24609570 : en[i] = -131072; /* log10(0.01) in Q16 */
998 24609570 : move32();
999 : }
1000 : ELSE
1001 : {
1002 22325310 : tmp32 = L_add( BASOP_Util_Log2( ener ), L_shl( L_deposit_l( s ), 25 ) ); /* log2, 6Q25 */
1003 22325310 : en[i] = L_shr( tmp32, 9 ); /* 15Q16 */
1004 22325310 : move32();
1005 : }
1006 46934880 : x += 4;
1007 : }
1008 :
1009 : /* SQ scale: 4 bits / 6 dB per quadruple */
1010 221065 : target = L_mult( 0x3FC8, sub( nbitsSQ, shr( lg, 4 ) ) ); /* 0x3FC8 -> 0.15*log2(10) */
1011 221065 : fac = L_add( 0x2A854B, 0 ); /* -> 12.8f*log2(10); */
1012 221065 : offset = L_add( fac, 0 );
1013 :
1014 : /* find offset (0 to 128 dB with step of 0.125dB) */
1015 2431715 : FOR( iter = 0; iter < 10; iter++ )
1016 : {
1017 2210650 : fac = L_shr( fac, 1 );
1018 2210650 : offset = L_sub( offset, fac );
1019 2210650 : ener = L_deposit_l( 0 );
1020 :
1021 361761654 : FOR( i = 0; i < lg_4; i++ )
1022 : {
1023 360371347 : tmp32 = L_sub( en[i], offset );
1024 :
1025 : /* avoid SV with 1 bin of amp < 0.5f */
1026 360371347 : IF( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 0.3*log2(10); */
1027 : {
1028 135716852 : ener = L_add( ener, tmp32 );
1029 : }
1030 :
1031 : /* if ener is above target -> break and increase offset */
1032 360371347 : IF( GT_32( ener, target ) )
1033 : {
1034 820343 : offset = L_add( offset, fac );
1035 820343 : BREAK;
1036 : }
1037 : }
1038 : }
1039 :
1040 221065 : offset = L_add( L_shr( offset, 1 ), 0x17EB0 ); /* 0x17EB0 -> 0.45*log2(10) */
1041 :
1042 221065 : *gain_e = add( extract_h( offset ), 1 );
1043 221065 : move16();
1044 221065 : offset = L_sub( L_and( offset, 0xFFFF ), 0x10000 );
1045 221065 : tmp16 = extract_h( BASOP_Util_InvLog2( L_shl( offset, 9 ) ) );
1046 :
1047 : /* return gain */
1048 :
1049 221065 : return tmp16;
1050 : }
1051 :
1052 655747 : Word16 SQ_gain_estimate_fx( /* output: SQ gain */
1053 : Word32 x[], /* input: vector to quantize */
1054 : Word16 x_e, /* input: exponent */
1055 : Word16 nbitsSQ, /* input: number of bits targeted */
1056 : Word16 lg, /* input: vector size (2048 max) */
1057 : Word16 *gain_e ) /* output: SQ gain exponent */
1058 : {
1059 : Word16 i, iter, max_iter, lg_4, s, tmp16;
1060 : Word32 ener, tmp32;
1061 : Word32 target, fac, offset;
1062 : Word32 en[N_MAX / 4];
1063 655747 : Word32 tmp = 0, tmpp = 0;
1064 655747 : move32();
1065 655747 : move32();
1066 : Word64 ener64_fx;
1067 : Word16 tmp_exp;
1068 :
1069 : /* tmp = 0.5f * (float) log10( (float) lg / (float) NORM_MDCT_FACTOR ) + + 0.94f; lowest gain + expected value of the quantization noise energy per quadruple (log10(4/12)) in Q16*/
1070 : /* tmpp = 0.5f * (float) log10( (float) lg / (float) NORM_MDCT_FACTOR ) * log2(10) in Q16 */
1071 655747 : SWITCH( lg )
1072 : {
1073 0 : case 80:
1074 0 : tmp = 171876;
1075 0 : tmpp = -32768;
1076 0 : move32();
1077 0 : move32();
1078 0 : BREAK;
1079 0 : case 100:
1080 0 : tmp = 182424;
1081 0 : tmpp = -22219;
1082 0 : move32();
1083 0 : move32();
1084 0 : BREAK;
1085 2418 : case 160:
1086 2418 : tmp = 204644;
1087 2418 : tmpp = 0;
1088 2418 : move32();
1089 2418 : move32();
1090 2418 : BREAK;
1091 0 : case 200:
1092 0 : tmp = 215192;
1093 0 : tmpp = 10549;
1094 0 : move32();
1095 0 : move32();
1096 0 : BREAK;
1097 0 : case 240:
1098 0 : tmp = 223812;
1099 0 : tmpp = 19168;
1100 0 : move32();
1101 0 : move32();
1102 0 : BREAK;
1103 0 : case 300:
1104 0 : tmp = 234361;
1105 0 : tmpp = 29717;
1106 0 : move32();
1107 0 : move32();
1108 0 : BREAK;
1109 68158 : case 320:
1110 68158 : tmp = 237412;
1111 68158 : tmpp = 32768;
1112 68158 : move32();
1113 68158 : move32();
1114 68158 : BREAK;
1115 54 : case 400:
1116 54 : tmp = 247960;
1117 54 : tmpp = 43317;
1118 54 : move32();
1119 54 : move32();
1120 54 : BREAK;
1121 19262 : case 480:
1122 19262 : tmp = 256580;
1123 19262 : tmpp = 51936;
1124 19262 : move32();
1125 19262 : move32();
1126 19262 : BREAK;
1127 0 : case 600:
1128 0 : tmp = 267128;
1129 0 : tmpp = 62485;
1130 0 : move32();
1131 0 : move32();
1132 0 : BREAK;
1133 163285 : case 640:
1134 163285 : tmp = 270180;
1135 163285 : tmpp = 65536;
1136 163285 : move32();
1137 163285 : move32();
1138 163285 : BREAK;
1139 280 : case 800:
1140 280 : tmp = 280728;
1141 280 : tmpp = 76085;
1142 280 : move32();
1143 280 : move32();
1144 280 : BREAK;
1145 401295 : case 960:
1146 401295 : tmp = 289348;
1147 401295 : tmpp = 84704;
1148 401295 : move32();
1149 401295 : move32();
1150 401295 : BREAK;
1151 995 : case 1200:
1152 995 : tmp = 299896;
1153 995 : tmpp = 95253;
1154 995 : move32();
1155 995 : move32();
1156 995 : BREAK;
1157 0 : case 1440:
1158 0 : tmp = 308516;
1159 0 : tmpp = 103872;
1160 0 : move32();
1161 0 : move32();
1162 0 : BREAK;
1163 0 : case 1800:
1164 0 : tmp = 319064;
1165 0 : tmpp = 114422;
1166 0 : move32();
1167 0 : move32();
1168 0 : BREAK;
1169 0 : case 2048:
1170 0 : tmp = 325167;
1171 0 : tmpp = 120523;
1172 0 : move32();
1173 0 : move32();
1174 0 : BREAK;
1175 0 : default:
1176 0 : assert( 0 );
1177 : }
1178 :
1179 655747 : lg_4 = shr( lg, 2 );
1180 :
1181 655747 : tmp_exp = shl( x_e, 1 );
1182 : /* SNR of quadruples for unit step quantizer and lowest possible gain */
1183 131312847 : FOR( i = 0; i < lg_4; i++ )
1184 : {
1185 130657100 : ener64_fx = W_mac_32_32( 1, x[0], x[0] ); // exp:2*x_e
1186 130657100 : ener64_fx = W_mac_32_32( ener64_fx, x[1], x[1] ); // exp:2*x_e
1187 130657100 : ener64_fx = W_mac_32_32( ener64_fx, x[2], x[2] ); // exp:2*x_e
1188 130657100 : ener64_fx = W_mac_32_32( ener64_fx, x[3], x[3] ); // exp:2*x_e
1189 130657100 : s = W_norm( ener64_fx );
1190 130657100 : ener = W_extract_h( W_shl( ener64_fx, s ) );
1191 130657100 : s = sub( tmp_exp, s );
1192 : /* log */
1193 130657100 : tmp32 = L_add_sat( BASOP_Util_Log2( ener ), L_shl_sat( L_deposit_l( s ), 25 ) ); /* log2, 6Q25 */
1194 130657100 : en[i] = L_add_sat( L_shr( tmp32, 9 ), tmp ); /* 15Q16 */
1195 130657100 : move32();
1196 130657100 : x += 4;
1197 : }
1198 :
1199 : /* SQ scale: 4 bits / 6 dB per quadruple */
1200 655747 : target = L_mult( 0x3FC8, sub( nbitsSQ, shr( lg, 4 ) ) ); /* 0x3FC8 -> 0.15*log2(10) */
1201 655747 : fac = L_add( 4005789, 0 ); /* -> 18.4f*log2(10); */
1202 655747 : offset = 3997967; /*fac - fac / (float) ( 2 << max_iter )*/
1203 655747 : move32();
1204 655747 : max_iter = 8;
1205 655747 : move16();
1206 : /* find offset, resolution similar to SQ gain quantizer resolution (92dB range, 0.719db resolution) */
1207 5901723 : FOR( iter = 0; iter < max_iter; iter++ )
1208 : {
1209 5245976 : fac = L_shr( fac, 1 );
1210 5245976 : offset = L_sub( offset, fac );
1211 5245976 : ener = L_deposit_l( 0 );
1212 :
1213 775956499 : FOR( i = 0; i < lg_4; i++ )
1214 : {
1215 772862587 : tmp32 = L_sub( en[i], offset );
1216 :
1217 : /* avoid SV with 1 bin of amp < 0.5f */
1218 772862587 : if ( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 0.3*log2(10); */
1219 : {
1220 276449394 : ener = L_add( ener, tmp32 );
1221 : }
1222 :
1223 : /* if SNR is above target -> break and increase offset */
1224 772862587 : IF( GT_32( ener, target ) )
1225 : {
1226 2152064 : offset = L_add( offset, fac );
1227 2152064 : BREAK;
1228 : }
1229 : }
1230 : }
1231 :
1232 655747 : offset = L_sub( L_shr( offset, 1 ), tmpp ); /* tmpp -> minGainInv*log2(10) */
1233 655747 : *gain_e = add( extract_h( offset ), 1 );
1234 655747 : move16();
1235 655747 : offset = L_sub( L_and( offset, 0xFFFF ), 0x10000 );
1236 655747 : tmp16 = extract_h( BASOP_Util_InvLog2( L_shl( offset, 9 ) ) );
1237 :
1238 : /* return gain */
1239 :
1240 655747 : return tmp16;
1241 : }
1242 :
1243 3804 : void tcx_scalar_quantization_fx(
1244 : Word32 *x, /* i: input coefficients */
1245 : Word16 x_e, /* i: exponent */
1246 : Word16 *xq, /* o: quantized coefficients */
1247 : Word16 L_frame, /* i: frame length */
1248 : Word16 gain, /* i: quantization gain */
1249 : Word16 gain_e, /* i: quantization gain exponent */
1250 : Word16 offset, /* i: rounding offset (deadzone) */
1251 : Word8 const *memQuantZeros_fx, /* i: coefficients to be set to 0 */
1252 : const Word16 alfe_flag )
1253 : {
1254 : Word16 i, tmp16, s;
1255 : Word32 tmp32, offs32;
1256 :
1257 :
1258 : /* common exponent for x and gain for comparison */
1259 3804 : tmp16 = sub( gain_e, x_e );
1260 3804 : tmp32 = L_shl( L_deposit_h( gain ), s_max( -31, s_min( tmp16, 0 ) ) );
1261 3804 : tmp16 = negate( s_max( tmp16, 0 ) );
1262 :
1263 3804 : i = sub( L_frame, 1 );
1264 :
1265 3804 : test();
1266 1274862 : WHILE( ( memQuantZeros_fx[i] != 0 ) && ( LT_32( L_abs( L_shl( x[i], tmp16 ) ), tmp32 ) ) )
1267 : {
1268 1271058 : test();
1269 1271058 : xq[i] = 0;
1270 1271058 : move16();
1271 1271058 : i = sub( i, 1 );
1272 : }
1273 :
1274 : /* invert gain */
1275 3804 : gain = Inv16( gain, &gain_e );
1276 :
1277 3804 : s = sub( add( x_e, gain_e ), 15 );
1278 :
1279 : /*It should almost never happen and if so the quantization will be discarded later on (saturation of gain Quantizer).*/
1280 3804 : IF( GT_16( s, 31 ) )
1281 : {
1282 : /* Limit the inverse gain to maximal possible value=sqrtL_spec/NORM_MDCT_FACTOR)*/
1283 0 : gain = 22435; /*sqrt(1200/NORM_MDCT_FACTOR) in 2Q13*/
1284 0 : gain_e = 2;
1285 0 : move16();
1286 0 : move16();
1287 :
1288 0 : s = sub( add( x_e, gain_e ), 15 );
1289 : }
1290 :
1291 : /* substract 0x8000 to affect the mac_r in the following loop
1292 : so it acts like extract_h. the 0x4000 will be multiplied by 2
1293 : by the mac_r to get to 0x8000 and disable the round. */
1294 3804 : offset = sub( offset, 0x4000 );
1295 :
1296 1203786 : FOR( ; i >= 0; i-- )
1297 : {
1298 1199982 : offs32 = Mpy_32_16_1( L_abs( x[i] ), gain ); /* multiply */
1299 1199982 : offs32 = L_shl_sat( offs32, s ); /* convert to 15Q16 */
1300 1199982 : tmp16 = mac_r_sat( offs32, offset, 1 ); /* add offset and truncate */
1301 1199982 : IF( x[i] < 0 )
1302 : {
1303 434373 : tmp16 = negate( tmp16 ); /* restore sign */
1304 : }
1305 :
1306 1199982 : xq[i] = tmp16;
1307 1199982 : move16();
1308 : }
1309 :
1310 3804 : IF( alfe_flag == 0 )
1311 : {
1312 3804 : AdaptLowFreqEmph_fx( x, x_e, xq, gain, gain_e,
1313 : 0, NULL, NULL,
1314 : L_frame );
1315 : }
1316 3804 : }
1317 :
1318 4510709 : void tcx_scalar_quantization_ivas_fx(
1319 : Word32 *x, /* i: input coefficients exponent = x_e */
1320 : Word16 x_e, /* i: exponent */
1321 : Word16 *xq, /* o: quantized coefficients */
1322 : Word16 L_frame, /* i: frame length */
1323 : Word16 gain, /* i: quantization gain exponent = gain_e */
1324 : Word16 gain_e, /* i: quantization gain exponent */
1325 : Word16 offset, /* i: rounding offset (deadzone) */
1326 : Word8 const *memQuantZeros_fx, /* i: coefficients to be set to 0 */
1327 : const Word16 alfe_flag )
1328 : {
1329 : Word16 i, tmp16, s;
1330 : Word32 tmp32, offs32;
1331 : Word32 offs32_1;
1332 4510709 : Word32 offset_Q16 = L_shl( offset, 1 ); // Q16
1333 :
1334 :
1335 : /* common exponent for x and gain for comparison */
1336 4510709 : tmp16 = sub( gain_e, x_e );
1337 4510709 : tmp32 = L_shl_sat( L_deposit_h( gain ), tmp16 ); // exp:x_e
1338 :
1339 4510709 : i = sub( L_frame, 1 );
1340 4510709 : IF( memQuantZeros_fx != NULL )
1341 : {
1342 3942505 : test();
1343 1121153096 : FOR( ; ( ( memQuantZeros_fx[i] != 0 ) && ( L_abs( x[i] ) < tmp32 ) ); i-- )
1344 : {
1345 1117210591 : test();
1346 1117210591 : xq[i] = 0;
1347 1117210591 : move16();
1348 : }
1349 : }
1350 :
1351 : /* invert gain */
1352 4510709 : gain = Inv16( gain, &gain_e );
1353 :
1354 4510709 : s = sub( add( x_e, gain_e ), 15 );
1355 :
1356 : /*It should almost never happen and if so the quantization will be discarded later on (saturation of gain Quantizer).*/
1357 4510709 : IF( GT_16( s, 31 ) )
1358 : {
1359 : /* Limit the inverse gain to maximal possible value=sqrtL_spec/NORM_MDCT_FACTOR)*/
1360 0 : gain = 22435; /*sqrt(1200/NORM_MDCT_FACTOR) in 2Q13*/
1361 0 : move16();
1362 0 : gain_e = 2;
1363 0 : move16();
1364 :
1365 0 : s = sub( add( x_e, gain_e ), 15 );
1366 : }
1367 :
1368 2424288214 : FOR( ; i >= 0; i-- )
1369 : {
1370 2419777505 : offs32 = Mpy_32_16_1( x[i], gain );
1371 2419777505 : offs32 = L_shl_sat( offs32, s ); /* convert to 15Q16 */
1372 :
1373 2419777505 : offs32_1 = L_add_sat( offs32, offset_Q16 ); /*15Q16 */
1374 2419777505 : tmp16 = extract_h( offs32_1 );
1375 2419777505 : IF( x[i] < 0 )
1376 : {
1377 1105099148 : offs32 = L_sub_sat( offs32, offset_Q16 ); /*15Q16 */
1378 1105099148 : tmp16 = extract_h( offs32 );
1379 1105099148 : if ( L_mac_sat( offs32, tmp16, -ONE_IN_Q15 ) > 0 )
1380 : {
1381 1105087076 : tmp16 = add( tmp16, 1 );
1382 : }
1383 : }
1384 2419777505 : xq[i] = tmp16;
1385 2419777505 : move16();
1386 : }
1387 :
1388 :
1389 4510709 : IF( alfe_flag == 0 )
1390 : {
1391 672702 : AdaptLowFreqEmph_fx( x, x_e, xq, gain, gain_e,
1392 : 0, NULL, NULL,
1393 : L_frame );
1394 : }
1395 4510709 : }
1396 :
1397 634 : Word16 tcx_scalar_quantization_rateloop_fx(
1398 : Word32 *x, /* i : input coefficients */
1399 : Word16 x_e, /* i : exponent */
1400 : Word16 *xq, /* o : quantized coefficients */
1401 : Word16 L_frame, /* i : frame length */
1402 : Word16 *gain, /* i/o: quantization gain */
1403 : Word16 *gain_e, /* i/o: gain exponent */
1404 : Word16 offset, /* i : rounding offset (deadzone) */
1405 : Word8 const *memQuantZeros_fx, /* i : coefficients to be set to 0 */
1406 : Word16 *lastnz_out, /* i/o: last nonzero coeff index */
1407 : Word16 target, /* i : target number of bits */
1408 : Word16 *nEncoded, /* o : number of encoded coeff */
1409 : Word16 *stop, /* i/o: stop param */
1410 : Word16 sqBits_in_noStop, /* i : number of sqBits as determined in prev. quant. stage, w/o using stop mechanism (ie might exceed target bits) */
1411 : Word16 sqBits_in, /* i : number of sqBits as determined in prev. quant. stage, using stop mechanism (ie always <= target bits) */
1412 : Word16 tcxRateLoopOpt, /* i : turns on/off rateloop optimization */
1413 : const Word8 tcxonly,
1414 : CONTEXT_HM_CONFIG *hm_cfg /* i : configuration of the context-based harmonic model */
1415 : )
1416 : {
1417 634 : const Word16 iter_max = 4;
1418 : Word16 sqBits;
1419 : Word16 stopFlag;
1420 : Word8 ubfound, lbfound;
1421 : Word16 ub, ub_e, lb, lb_e;
1422 : Word16 shift, shiftInv;
1423 : Word16 iter;
1424 : Word16 sqGain, sqGain_e;
1425 : Word16 w_lb, w_ub;
1426 634 : const Word16 kDampen = 10;
1427 : Word16 old_stopFlag;
1428 : Word16 old_nEncoded;
1429 : Word16 old_sqBits;
1430 : Word16 mod_adjust0, mod_adjust1;
1431 : Word16 inv_target, inv_target_e;
1432 634 : const Word16 kMargin = 0x7AE1; /* 0.96 */
1433 634 : const Word16 kMarginInv = 0x42AB; /* 1/0.96 (1Q14) */
1434 : Word16 tmp, fac1, fac2;
1435 : Word32 tmp32;
1436 : Word16 lastnz;
1437 634 : move16();
1438 634 : move16();
1439 634 : move16();
1440 634 : move16();
1441 :
1442 :
1443 : /* Init */
1444 634 : sqGain = *gain;
1445 634 : move16();
1446 634 : sqGain_e = *gain_e;
1447 634 : move16();
1448 634 : stopFlag = *stop;
1449 634 : move16();
1450 634 : ubfound = 0;
1451 634 : move16();
1452 634 : lbfound = 0;
1453 634 : move16();
1454 634 : shift = 0x41DE; /* 10^(1/80), 1Q14 */
1455 634 : move16();
1456 634 : shiftInv = 0x78D7; /* 10^(-1/40) */
1457 634 : move16();
1458 634 : lb = lb_e = 0;
1459 634 : move16();
1460 634 : ub = ub_e = 0;
1461 634 : move16();
1462 634 : w_lb = 0;
1463 634 : move16();
1464 634 : w_ub = 0;
1465 634 : move16();
1466 634 : lastnz = *lastnz_out;
1467 634 : move16();
1468 634 : old_stopFlag = stopFlag;
1469 634 : move16();
1470 634 : old_nEncoded = *nEncoded;
1471 634 : move16();
1472 634 : old_sqBits = sqBits_in_noStop;
1473 634 : move16();
1474 :
1475 634 : sqBits = sqBits_in;
1476 634 : move16();
1477 :
1478 634 : mod_adjust0 = extract_l( L_shr( L_max( 0x10000, L_sub( 0x24CCD, L_mult( 0x0052, target ) ) ), 3 ) ); /* 2Q13 */
1479 634 : mod_adjust1 = div_s( 0x2000, mod_adjust0 ); /* 0Q15 */
1480 :
1481 634 : inv_target_e = 15;
1482 634 : move16();
1483 634 : inv_target = Inv16( target, &inv_target_e );
1484 :
1485 634 : fac1 = shl( mult( mult( kMarginInv, mod_adjust0 ), inv_target ), 1 ); /* 2Q13 */
1486 634 : fac2 = mult( mult( kMargin, mod_adjust1 ), inv_target );
1487 :
1488 : /* Loop */
1489 3170 : FOR( iter = 0; iter < iter_max; iter++ )
1490 : {
1491 2536 : IF( EQ_16( tcxRateLoopOpt, 2 ) )
1492 : {
1493 : /* Ajust sqGain */
1494 0 : IF( stopFlag != 0 )
1495 : {
1496 0 : lbfound = 1;
1497 0 : move16();
1498 0 : lb = sqGain;
1499 0 : move16();
1500 0 : lb_e = sqGain_e;
1501 0 : move16();
1502 0 : w_lb = add( sub( stopFlag, target ), kDampen );
1503 :
1504 0 : IF( ubfound != 0 )
1505 : {
1506 : /* common exponent for addition */
1507 0 : sqGain_e = s_max( lb_e, ub_e );
1508 :
1509 : /* multiply and add */
1510 0 : tmp32 = L_shr( L_mult( lb, w_ub ), sub( sqGain_e, lb_e ) );
1511 0 : tmp32 = L_add( tmp32, L_shr( L_mult( ub, w_lb ), sub( sqGain_e, ub_e ) ) );
1512 :
1513 : /* convert to normalized 16 bit */
1514 0 : tmp = norm_l( tmp32 );
1515 0 : sqGain = round_fx_sat( L_shl( tmp32, tmp ) );
1516 0 : sqGain_e = sub( sqGain_e, tmp );
1517 :
1518 : /* divide */
1519 0 : sqGain = BASOP_Util_Divide1616_Scale( sqGain, add( w_ub, w_lb ), &tmp );
1520 0 : sqGain_e = add( sqGain_e, tmp );
1521 : }
1522 : ELSE
1523 : {
1524 0 : tmp = round_fx( L_shl( L_mult( stopFlag, fac1 ), add( inv_target_e, 15 ) ) );
1525 0 : sqGain = mult( sqGain, sub( tmp, sub( mod_adjust0, 0x2000 ) ) );
1526 0 : sqGain = normalize16( sqGain, &sqGain_e );
1527 0 : sqGain_e = add( sqGain_e, 2 );
1528 : }
1529 : }
1530 : ELSE
1531 : {
1532 0 : ubfound = 1;
1533 0 : move16();
1534 0 : ub = sqGain;
1535 0 : move16();
1536 0 : ub_e = sqGain_e;
1537 0 : move16();
1538 0 : w_ub = add( sub( target, sqBits ), kDampen );
1539 :
1540 0 : IF( lbfound != 0 )
1541 : {
1542 : /* common exponent for addition */
1543 0 : sqGain_e = s_max( lb_e, ub_e );
1544 :
1545 : /* multiply and add */
1546 0 : tmp32 = L_shr( L_mult( lb, w_ub ), sub( sqGain_e, lb_e ) );
1547 0 : tmp32 = L_add( tmp32, L_shr( L_mult( ub, w_lb ), sub( sqGain_e, ub_e ) ) );
1548 :
1549 : /* convert to normalized 16 bit */
1550 0 : tmp = norm_l( tmp32 );
1551 0 : sqGain = round_fx_sat( L_shl_sat( tmp32, tmp ) );
1552 0 : sqGain_e = sub( sqGain_e, tmp );
1553 :
1554 : /* divide */
1555 0 : sqGain = BASOP_Util_Divide1616_Scale( sqGain, add( w_ub, w_lb ), &tmp );
1556 0 : sqGain_e = add( sqGain_e, tmp );
1557 : }
1558 : ELSE
1559 : {
1560 0 : tmp = round_fx( L_shl( L_mult( sqBits, fac2 ), add( inv_target_e, 15 ) ) );
1561 0 : sqGain = mult( sqGain, sub( tmp, add( mod_adjust1, (Word16) 0x8000 ) ) );
1562 0 : sqGain = normalize16( sqGain, &sqGain_e );
1563 : }
1564 : }
1565 : }
1566 : ELSE /* tcxRateLoopOpt != 2 */
1567 : {
1568 :
1569 : /* Ajust sqGain */
1570 2536 : IF( stopFlag != 0 )
1571 : {
1572 1070 : lbfound = 1;
1573 1070 : move16();
1574 1070 : lb = sqGain;
1575 1070 : move16();
1576 1070 : lb_e = sqGain_e;
1577 1070 : move16();
1578 :
1579 1070 : IF( ubfound != 0 )
1580 : {
1581 720 : sqGain = mult( lb, ub );
1582 720 : sqGain_e = add( lb_e, ub_e );
1583 720 : sqGain = Sqrt16( sqGain, &sqGain_e );
1584 : }
1585 : ELSE
1586 : {
1587 350 : shift = shl( mult( shift, shift ), 1 );
1588 350 : shiftInv = mult( shiftInv, shiftInv );
1589 :
1590 350 : sqGain = mult( sqGain, shift );
1591 350 : sqGain = normalize16( sqGain, &sqGain_e );
1592 350 : sqGain_e = add( sqGain_e, 1 );
1593 : }
1594 : }
1595 : ELSE
1596 : {
1597 1466 : ubfound = 1;
1598 1466 : move16();
1599 1466 : ub = sqGain;
1600 1466 : move16();
1601 1466 : ub_e = sqGain_e;
1602 1466 : move16();
1603 :
1604 1466 : IF( lbfound != 0 )
1605 : {
1606 575 : sqGain = mult( lb, ub );
1607 575 : sqGain_e = add( lb_e, ub_e );
1608 575 : sqGain = Sqrt16( sqGain, &sqGain_e );
1609 : }
1610 : ELSE
1611 : {
1612 891 : sqGain = mult( sqGain, shiftInv );
1613 891 : sqGain = normalize16( sqGain, &sqGain_e );
1614 :
1615 891 : shift = shl( mult( shift, shift ), 1 );
1616 891 : shiftInv = mult( shiftInv, shiftInv );
1617 : }
1618 : }
1619 : }
1620 :
1621 : /* Quantize spectrum */
1622 2536 : tcx_scalar_quantization_fx( x, x_e, xq, L_frame, sqGain, sqGain_e, offset, memQuantZeros_fx, tcxonly );
1623 :
1624 : /* Estimate bitrate */
1625 2536 : stopFlag = 1;
1626 2536 : move16();
1627 2536 : if ( tcxRateLoopOpt > 0 )
1628 : {
1629 2536 : stopFlag = 0;
1630 2536 : move16();
1631 : }
1632 :
1633 2536 : sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( xq, L_frame,
1634 : &lastnz,
1635 : nEncoded, target, &stopFlag,
1636 : hm_cfg );
1637 :
1638 2536 : IF( tcxRateLoopOpt > 0 )
1639 : {
1640 2536 : test();
1641 2536 : test();
1642 2536 : test();
1643 2536 : test();
1644 2536 : test();
1645 2536 : test();
1646 2536 : IF( ( ( GE_16( *nEncoded, old_nEncoded ) ) && ( GE_16( stopFlag, old_stopFlag ) ) ) ||
1647 : ( ( GT_16( *nEncoded, old_nEncoded ) ) && ( ( stopFlag == 0 ) && ( old_stopFlag > 0 ) ) ) ||
1648 : ( ( stopFlag == 0 ) && ( old_stopFlag == 0 ) ) )
1649 : {
1650 1363 : *gain = sqGain;
1651 1363 : move16();
1652 1363 : *gain_e = sqGain_e;
1653 1363 : move16();
1654 1363 : old_nEncoded = *nEncoded;
1655 1363 : move16();
1656 1363 : old_stopFlag = stopFlag;
1657 1363 : move16();
1658 1363 : old_sqBits = sqBits;
1659 1363 : move16();
1660 1363 : *lastnz_out = lastnz;
1661 1363 : move16();
1662 : }
1663 : }
1664 : } /* for ( iter=0 ; iter<iter_max ; iter++ ) */
1665 :
1666 634 : IF( tcxRateLoopOpt > 0 )
1667 : {
1668 : /* Quantize spectrum */
1669 634 : tcx_scalar_quantization_fx( x, x_e, xq, L_frame, *gain, *gain_e, offset, memQuantZeros_fx, tcxonly );
1670 :
1671 : /* Output */
1672 634 : *nEncoded = old_nEncoded;
1673 634 : move16();
1674 634 : sqBits = old_sqBits;
1675 634 : move16();
1676 634 : *stop = old_stopFlag;
1677 634 : move16();
1678 : }
1679 : ELSE
1680 : {
1681 : /* Output */
1682 0 : *gain = sqGain;
1683 0 : move16();
1684 0 : *gain_e = sqGain_e;
1685 0 : move16();
1686 0 : *stop = stopFlag;
1687 0 : move16();
1688 0 : *lastnz_out = lastnz;
1689 0 : move16();
1690 : }
1691 :
1692 :
1693 634 : return sqBits;
1694 : }
1695 :
1696 876812 : Word16 tcx_scalar_quantization_rateloop_ivas_fx(
1697 : Word32 *x, /* i : input coefficients Q = 31 - x_e*/
1698 : Word16 x_e, /* i : exponent Q0*/
1699 : Word16 *xq, /* o : quantized coefficients Q0*/
1700 : Word16 L_frame, /* i : frame length Q0*/
1701 : Word16 *gain, /* i/o: quantization gain Q = gaine_e*/
1702 : Word16 *gain_e, /* i/o: gain exponent Q0*/
1703 : Word16 offset, /* i : rounding offset (deadzone) Q0*/
1704 : Word8 const *memQuantZeros_fx, /* i : coefficients to be set to 0 Q0*/
1705 : Word16 *lastnz_out, /* i/o: last nonzero coeff index Q0*/
1706 : Word16 target, /* i : target number of bits Q0*/
1707 : Word16 *nEncoded, /* o : number of encoded coeff Q0*/
1708 : Word16 *stop, /* i/o: stop param Q0*/
1709 : Word16 sqBits_in_noStop, /* i : number of sqBits as determined in prev. quant. stage, w/o using stop mechanism (ie might exceed target bits) Q0*/
1710 : Word16 sqBits_in, /* i : number of sqBits as determined in prev. quant. stage, using stop mechanism (ie always <= target bits) Q0*/
1711 : Word16 tcxRateLoopOpt, /* i : turns on/off rateloop optimization */
1712 : const Word16 tcxonly,
1713 : CONTEXT_HM_CONFIG *hm_cfg, /* i : configuration of the context-based harmonic model */
1714 : const Word16 iter_max,
1715 : const Word16 element_mode )
1716 : {
1717 : Word16 sqBits;
1718 : Word16 stopFlag;
1719 : Word8 ubfound, lbfound;
1720 : Word16 ub, ub_e, lb, lb_e;
1721 : Word16 shift, shiftInv;
1722 : Word16 iter;
1723 : Word16 sqGain, sqGain_e;
1724 : Word16 w_lb, w_ub;
1725 876812 : const Word16 kDampen = 10;
1726 876812 : move16();
1727 : Word16 old_stopFlag;
1728 : Word16 old_nEncoded;
1729 : Word16 old_sqBits;
1730 : Word16 mod_adjust0, mod_adjust1;
1731 : Word16 inv_target, inv_target_e;
1732 876812 : const Word16 kMargin = 0x7AE1; /* 0.96 */
1733 876812 : move16();
1734 876812 : const Word16 kMarginInv = 0x42AB; /* 1/0.96 (1Q14) */
1735 876812 : move16();
1736 : Word16 tmp, fac1, fac2;
1737 : Word32 tmp32;
1738 876812 : Word16 lastnz, saturated, minSqGain = 0;
1739 876812 : move16();
1740 :
1741 :
1742 : /* Init */
1743 876812 : saturated = 0;
1744 876812 : move16();
1745 : /* minSqGain = (float) sqrt( (float) NORM_MDCT_FACTOR / (float) L_frame ); in Q14*/
1746 876812 : SWITCH( L_frame )
1747 : {
1748 0 : case 80:
1749 0 : minSqGain = 23170;
1750 0 : BREAK;
1751 0 : case 100:
1752 0 : minSqGain = 20724;
1753 0 : BREAK;
1754 2446 : case 160:
1755 2446 : minSqGain = 16384;
1756 2446 : BREAK;
1757 0 : case 200:
1758 0 : minSqGain = 14654;
1759 0 : BREAK;
1760 0 : case 240:
1761 0 : minSqGain = 13377;
1762 0 : BREAK;
1763 0 : case 300:
1764 0 : minSqGain = 11965;
1765 0 : BREAK;
1766 77618 : case 320:
1767 77618 : minSqGain = 11585;
1768 77618 : BREAK;
1769 444 : case 400:
1770 444 : minSqGain = 10362;
1771 444 : BREAK;
1772 23156 : case 480:
1773 23156 : minSqGain = 9459;
1774 23156 : BREAK;
1775 0 : case 600:
1776 0 : minSqGain = 8461;
1777 0 : BREAK;
1778 215105 : case 640:
1779 215105 : minSqGain = 8192;
1780 215105 : BREAK;
1781 3155 : case 800:
1782 3155 : minSqGain = 7327;
1783 3155 : BREAK;
1784 550877 : case 960:
1785 550877 : minSqGain = 6689;
1786 550877 : BREAK;
1787 4011 : case 1200:
1788 4011 : minSqGain = 5983;
1789 4011 : BREAK;
1790 0 : case 1440:
1791 0 : minSqGain = 5461;
1792 0 : BREAK;
1793 0 : case 1800:
1794 0 : minSqGain = 4885;
1795 0 : BREAK;
1796 0 : case 2048:
1797 0 : minSqGain = 4579;
1798 0 : BREAK;
1799 0 : default:
1800 0 : assert( 0 );
1801 : }
1802 876812 : move16();
1803 876812 : sqGain = *gain;
1804 876812 : move16();
1805 876812 : sqGain_e = *gain_e;
1806 876812 : move16();
1807 876812 : stopFlag = *stop;
1808 876812 : move16();
1809 876812 : ubfound = 0;
1810 876812 : move16();
1811 876812 : lbfound = 0;
1812 876812 : move16();
1813 876812 : shift = 0x41DE; /* 10^(1/80), 1Q14 */
1814 876812 : move16();
1815 876812 : shiftInv = 0x78D7; /* 10^(-1/40) */
1816 876812 : move16();
1817 876812 : lb = lb_e = 0;
1818 876812 : move16();
1819 876812 : ub = ub_e = 0;
1820 876812 : move16();
1821 876812 : w_lb = 0;
1822 876812 : move16();
1823 876812 : w_ub = 0;
1824 876812 : move16();
1825 876812 : lastnz = *lastnz_out;
1826 876812 : move16();
1827 876812 : old_stopFlag = stopFlag;
1828 876812 : move16();
1829 876812 : old_nEncoded = *nEncoded;
1830 876812 : move16();
1831 876812 : old_sqBits = sqBits_in_noStop;
1832 876812 : move16();
1833 :
1834 876812 : sqBits = sqBits_in;
1835 876812 : move16();
1836 :
1837 876812 : mod_adjust0 = extract_l( L_shr( L_max( 0x10000, L_sub( 0x24CCD, L_mult( 0x0052, target ) ) ), 3 ) ); /* 2Q13 */
1838 876812 : mod_adjust1 = div_s( 0x2000, mod_adjust0 ); /* 0Q15 */
1839 :
1840 876812 : inv_target_e = 15;
1841 876812 : move16();
1842 876812 : inv_target = Inv16( target, &inv_target_e );
1843 :
1844 876812 : fac1 = shl( mult( mult( kMarginInv, mod_adjust0 ), inv_target ), 1 ); /* 2Q13 */
1845 876812 : fac2 = mult( mult( kMargin, mod_adjust1 ), inv_target );
1846 :
1847 : /* Loop */
1848 3060665 : FOR( iter = 0; iter < iter_max; iter++ )
1849 : {
1850 2195754 : IF( GE_16( tcxRateLoopOpt, 2 ) )
1851 : {
1852 : /* Ajust sqGain */
1853 1747286 : IF( stopFlag != 0 )
1854 : {
1855 830186 : lbfound = 1;
1856 830186 : move16();
1857 830186 : lb = sqGain;
1858 830186 : move16();
1859 830186 : lb_e = sqGain_e;
1860 830186 : move16();
1861 830186 : w_lb = add( sub( stopFlag, target ), kDampen );
1862 830186 : saturated = 0;
1863 830186 : move16();
1864 830186 : IF( ubfound != 0 )
1865 : {
1866 : /* common exponent for addition */
1867 382665 : sqGain_e = s_max( lb_e, ub_e );
1868 :
1869 : /* multiply and add */
1870 382665 : tmp32 = L_shr( L_mult( lb, w_ub ), sub( sqGain_e, lb_e ) );
1871 382665 : tmp32 = L_add( tmp32, L_shr( L_mult( ub, w_lb ), sub( sqGain_e, ub_e ) ) );
1872 :
1873 : /* convert to normalized 16 bit */
1874 382665 : tmp = norm_l( tmp32 );
1875 382665 : sqGain = round_fx_sat( L_shl( tmp32, tmp ) );
1876 382665 : sqGain_e = sub( sqGain_e, tmp );
1877 :
1878 : /* divide */
1879 382665 : sqGain = BASOP_Util_Divide1616_Scale( sqGain, add( w_ub, w_lb ), &tmp );
1880 382665 : sqGain_e = add( sqGain_e, tmp );
1881 : }
1882 : ELSE
1883 : {
1884 447521 : tmp = round_fx_sat( L_shl_sat( L_mult( stopFlag, fac1 ), add( inv_target_e, 15 ) ) );
1885 447521 : sqGain = mult( sqGain, sub( tmp, sub( mod_adjust0, 0x2000 ) ) );
1886 447521 : sqGain = normalize16( sqGain, &sqGain_e );
1887 447521 : sqGain_e = add( sqGain_e, 2 );
1888 : }
1889 : }
1890 917100 : ELSE IF( saturated == 0 )
1891 : {
1892 905199 : ubfound = 1;
1893 905199 : move16();
1894 905199 : ub = sqGain;
1895 905199 : move16();
1896 905199 : ub_e = sqGain_e;
1897 905199 : move16();
1898 905199 : w_ub = add( sub( target, sqBits ), kDampen );
1899 :
1900 905199 : IF( lbfound != 0 )
1901 : {
1902 : /* common exponent for addition */
1903 453521 : sqGain_e = s_max( lb_e, ub_e );
1904 :
1905 : /* multiply and add */
1906 453521 : tmp32 = L_shr( L_mult( lb, w_ub ), sub( sqGain_e, lb_e ) );
1907 453521 : tmp32 = L_add( tmp32, L_shr( L_mult( ub, w_lb ), sub( sqGain_e, ub_e ) ) );
1908 :
1909 : /* convert to normalized 16 bit */
1910 453521 : tmp = norm_l( tmp32 );
1911 453521 : sqGain = round_fx_sat( L_shl_sat( tmp32, tmp ) );
1912 453521 : sqGain_e = sub( sqGain_e, tmp );
1913 :
1914 : /* divide */
1915 453521 : sqGain = BASOP_Util_Divide1616_Scale( sqGain, add( w_ub, w_lb ), &tmp );
1916 453521 : sqGain_e = add( sqGain_e, tmp );
1917 : }
1918 : ELSE
1919 : {
1920 451678 : tmp = round_fx( L_shl( L_mult( sqBits, fac2 ), add( inv_target_e, 15 ) ) );
1921 451678 : sqGain = mult( sqGain, sub( tmp, add( mod_adjust1, (Word16) 0x8000 ) ) );
1922 451678 : sqGain = normalize16( sqGain, &sqGain_e );
1923 : }
1924 :
1925 905199 : Word16 shift_tmp = s_max( sqGain_e, 1 );
1926 905199 : move16();
1927 905199 : test();
1928 905199 : IF( LT_16( shl( sqGain, sub( sqGain_e, shift_tmp ) ), shl( minSqGain, sub( 1, shift_tmp ) ) ) && EQ_16( tcxRateLoopOpt, 3 ) )
1929 : {
1930 12500 : sqGain = minSqGain;
1931 12500 : move16();
1932 12500 : sqGain_e = 1;
1933 12500 : move16();
1934 12500 : saturated = 1;
1935 12500 : move16();
1936 : }
1937 : }
1938 : ELSE
1939 : {
1940 11901 : break; /* we cannot go any lower anyway*/
1941 : }
1942 : }
1943 : ELSE /* tcxRateLoopOpt != 2 */
1944 : {
1945 :
1946 : /* Ajust sqGain */
1947 448468 : IF( stopFlag != 0 )
1948 : {
1949 181979 : lbfound = 1;
1950 181979 : move16();
1951 181979 : lb = sqGain;
1952 181979 : move16();
1953 181979 : lb_e = sqGain_e;
1954 181979 : move16();
1955 :
1956 181979 : IF( ubfound != 0 )
1957 : {
1958 131483 : sqGain = mult( lb, ub );
1959 131483 : sqGain_e = add( lb_e, ub_e );
1960 131483 : sqGain = Sqrt16( sqGain, &sqGain_e );
1961 : }
1962 : ELSE
1963 : {
1964 50496 : shift = shl( mult( shift, shift ), 1 );
1965 50496 : shiftInv = mult( shiftInv, shiftInv );
1966 :
1967 50496 : sqGain = mult( sqGain, shift );
1968 50496 : sqGain = normalize16( sqGain, &sqGain_e );
1969 50496 : sqGain_e = add( sqGain_e, 1 );
1970 : }
1971 : }
1972 : ELSE
1973 : {
1974 266489 : ubfound = 1;
1975 266489 : move16();
1976 266489 : ub = sqGain;
1977 266489 : move16();
1978 266489 : ub_e = sqGain_e;
1979 266489 : move16();
1980 :
1981 266489 : IF( lbfound != 0 )
1982 : {
1983 96700 : sqGain = mult( lb, ub );
1984 96700 : sqGain_e = add( lb_e, ub_e );
1985 96700 : sqGain = Sqrt16( sqGain, &sqGain_e );
1986 : }
1987 : ELSE
1988 : {
1989 169789 : sqGain = mult( sqGain, shiftInv );
1990 169789 : sqGain = normalize16( sqGain, &sqGain_e );
1991 :
1992 169789 : shift = shl( mult( shift, shift ), 1 );
1993 169789 : shiftInv = mult( shiftInv, shiftInv );
1994 : }
1995 : }
1996 : }
1997 :
1998 : /* Quantize spectrum */
1999 2183853 : tcx_scalar_quantization_ivas_fx( x, x_e, xq, L_frame, sqGain, sqGain_e, offset, memQuantZeros_fx, tcxonly );
2000 :
2001 : /* Estimate bitrate */
2002 2183853 : stopFlag = 1;
2003 2183853 : move16();
2004 2183853 : if ( tcxRateLoopOpt > 0 )
2005 : {
2006 2183853 : stopFlag = 0;
2007 2183853 : move16();
2008 : }
2009 :
2010 2183853 : IF( GT_16( element_mode, EVS_MONO ) )
2011 : {
2012 2183853 : sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( xq, L_frame, &lastnz, nEncoded, target, &stopFlag, 0, hm_cfg );
2013 : }
2014 : ELSE
2015 : {
2016 0 : sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( xq, L_frame,
2017 : &lastnz,
2018 : nEncoded, target, &stopFlag,
2019 : hm_cfg );
2020 : }
2021 :
2022 2183853 : IF( GE_16( tcxRateLoopOpt, 1 ) )
2023 : {
2024 2183853 : test();
2025 2183853 : test();
2026 2183853 : test();
2027 2183853 : test();
2028 2183853 : test();
2029 2183853 : test();
2030 2183853 : IF( ( ( GE_16( *nEncoded, old_nEncoded ) ) && ( GE_16( stopFlag, old_stopFlag ) ) ) ||
2031 : ( ( GT_16( *nEncoded, old_nEncoded ) ) && ( ( stopFlag == 0 ) && ( old_stopFlag > 0 ) ) ) ||
2032 : ( ( stopFlag == 0 ) && ( old_stopFlag == 0 ) ) )
2033 : {
2034 1191622 : *gain = sqGain;
2035 1191622 : move16();
2036 1191622 : *gain_e = sqGain_e;
2037 1191622 : move16();
2038 1191622 : old_nEncoded = *nEncoded;
2039 1191622 : move16();
2040 1191622 : old_stopFlag = stopFlag;
2041 1191622 : move16();
2042 1191622 : old_sqBits = sqBits;
2043 1191622 : move16();
2044 1191622 : *lastnz_out = lastnz;
2045 1191622 : move16();
2046 : }
2047 : }
2048 : } /* for ( iter=0 ; iter<iter_max ; iter++ ) */
2049 :
2050 876812 : IF( GE_16( tcxRateLoopOpt, 1 ) )
2051 : {
2052 : /* Quantize spectrum */
2053 876812 : tcx_scalar_quantization_ivas_fx( x, x_e, xq, L_frame, *gain, *gain_e, offset, memQuantZeros_fx, tcxonly );
2054 :
2055 : /* Output */
2056 876812 : *nEncoded = old_nEncoded;
2057 876812 : move16();
2058 876812 : sqBits = old_sqBits;
2059 876812 : move16();
2060 876812 : *stop = old_stopFlag;
2061 876812 : move16();
2062 : }
2063 : ELSE
2064 : {
2065 : /* Output */
2066 0 : *gain = sqGain;
2067 0 : move16();
2068 0 : *gain_e = sqGain_e;
2069 0 : move16();
2070 0 : *stop = stopFlag;
2071 0 : move16();
2072 0 : *lastnz_out = lastnz;
2073 0 : move16();
2074 : }
2075 :
2076 :
2077 876812 : return sqBits;
2078 : }
2079 :
2080 894871 : void QuantizeGain( Word16 n, Word16 *pGain, Word16 *pGain_e, Word16 *pQuantizedGain )
2081 : {
2082 : Word16 ener, ener_e, enerInv, enerInv_e, gain, gain_e;
2083 : Word16 quantizedGain;
2084 : Word32 tmp32;
2085 :
2086 894871 : ener = mult_r( shl_sat( n, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
2087 894871 : ener_e = 15 - 5 - 7;
2088 894871 : move16();
2089 894871 : IF( GE_16( n, 1024 ) )
2090 : {
2091 : /*reduce precision for avoiding overflow*/
2092 4011 : ener = mult_r( shl( n, 4 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
2093 4011 : ener_e = 15 - 4 - 7;
2094 4011 : move16();
2095 : }
2096 894871 : BASOP_Util_Sqrt_InvSqrt_MantExp( ener, ener_e, &ener, &ener_e, &enerInv, &enerInv_e );
2097 :
2098 894871 : gain = mult( *pGain, ener );
2099 894871 : gain_e = add( *pGain_e, ener_e );
2100 :
2101 894871 : assert( gain > 0 );
2102 :
2103 : /* quantize gain with step of 0.714 dB */
2104 894871 : quantizedGain = add( round_fx( BASOP_Util_Log2( L_deposit_h( gain ) ) ), shl( gain_e, 9 ) ); /* 6Q9 */
2105 894871 : quantizedGain = mult( quantizedGain, 0x436E ); /* 10Q5; 0x436E -> 28/log2(10) (4Q11) */
2106 894871 : quantizedGain = shr( add( quantizedGain, 0x10 ), 5 ); /* round */
2107 :
2108 894871 : if ( quantizedGain < 0 )
2109 : {
2110 1979 : quantizedGain = 0;
2111 1979 : move16();
2112 : }
2113 :
2114 894871 : if ( GT_16( quantizedGain, 127 ) )
2115 : {
2116 52 : quantizedGain = 127;
2117 52 : move16();
2118 : }
2119 :
2120 894871 : *pQuantizedGain = quantizedGain;
2121 894871 : move16();
2122 :
2123 894871 : tmp32 = L_shl( L_mult0( quantizedGain, 0x797D ), 7 ); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
2124 894871 : gain_e = add( extract_l( L_shr( tmp32, 25 ) ), 1 ); /* get exponent */
2125 894871 : gain = round_fx( BASOP_Util_InvLog2( L_or( tmp32, 0xFE000000 ) ) );
2126 :
2127 894871 : *pGain = mult( gain, enerInv );
2128 894871 : move16();
2129 894871 : *pGain_e = add( gain_e, enerInv_e );
2130 894871 : move16();
2131 894871 : }
2132 :
2133 634 : void tcx_noise_factor_fx(
2134 : Word32 *x_orig, /* i: unquantized mdct coefficients */
2135 : Word16 x_orig_e, /* i: exponent */
2136 : Word32 *sqQ, /* i: quantized mdct coefficients */
2137 : Word16 iFirstLine, /* i: first coefficient to be considered */
2138 : Word16 lowpassLine, /* i: last nonzero coefficients after low-pass */
2139 : Word16 nTransWidth, /* i: minimum size of hole to be checked */
2140 : Word16 L_frame, /* i: frame length */
2141 : Word16 gain_tcx, /* i: tcx gain */
2142 : Word16 gain_tcx_e, /* i: gain exponent */
2143 : Word16 tiltCompFactor, /* i: LPC tilt compensation factor */
2144 : Word16 *fac_ns, /* o: noise factor */
2145 : Word16 *quantized_fac_ns /* o: quantized noise factor */
2146 : )
2147 : {
2148 : Word16 i, k, maxK, segmentOffset;
2149 : Word32 sqErrorNrg, n;
2150 : Word16 inv_gain2, inv_gain2_e, tilt_factor, nTransWidth_1;
2151 : Word32 accu1, accu2, tmp32;
2152 : Word16 tmp1, tmp2, s;
2153 : Word16 c1, c2;
2154 : Word16 att; /* noise level attenuation factor for transient windows */
2155 : Word32 xMax;
2156 :
2157 :
2158 634 : assert( nTransWidth <= 16 );
2159 :
2160 634 : c1 = sub( shl( nTransWidth, 1 ), 4 );
2161 634 : c2 = mult( 9216 /*0.28125f Q15*/, inv_int[nTransWidth] );
2162 634 : nTransWidth_1 = sub( nTransWidth, 1 );
2163 :
2164 : /*Adjust noise filling level*/
2165 634 : sqErrorNrg = L_deposit_l( 0 );
2166 634 : n = L_deposit_l( 0 );
2167 :
2168 : /* get inverse frame length */
2169 634 : tmp1 = getInvFrameLen( L_frame );
2170 :
2171 : /* tilt_factor = 1.0f /(float)pow(max(0.375f, tiltCompFactor), 1.0f/(float)L_frame); */
2172 634 : tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */
2173 634 : tmp32 = L_shr( Mpy_32_16_1( tmp32, negate( tmp1 ) ), 6 );
2174 634 : tilt_factor = round_fx( BASOP_Util_InvLog2( L_sub( tmp32, 0x2000000 ) ) ); /* 1Q14 */
2175 :
2176 : /* inv_gain2 = 1.0f / ((float)(nTransWidth * nTransWidth) * gain_tcx); */
2177 634 : tmp32 = L_mult( imult1616( nTransWidth, nTransWidth ), gain_tcx ); /* 15Q16 */
2178 634 : tmp1 = norm_l( tmp32 );
2179 634 : inv_gain2 = round_fx( L_shl( tmp32, tmp1 ) );
2180 634 : inv_gain2_e = add( sub( 15, tmp1 ), gain_tcx_e );
2181 634 : inv_gain2 = Inv16( inv_gain2, &inv_gain2_e );
2182 634 : inv_gain2 = shr( inv_gain2, 2 ); /* 2 bits headroom */
2183 634 : inv_gain2_e = add( inv_gain2_e, 2 );
2184 :
2185 : /* find last nonzero line below iFirstLine, use it as start offset */
2186 634 : tmp1 = shr( iFirstLine, 1 );
2187 2810 : FOR( i = iFirstLine; i > tmp1; i-- )
2188 : {
2189 2804 : IF( sqQ[i] != 0 )
2190 : {
2191 628 : BREAK;
2192 : }
2193 : }
2194 : /* inv_gain2 *= (float)pow(tilt_factor, (float)i); */
2195 29642 : FOR( k = 0; k < i; k++ )
2196 : {
2197 29008 : inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 );
2198 : }
2199 :
2200 : /* initialize left (k) and right (maxK) non-zero neighbor pointers */
2201 634 : k = 0;
2202 634 : move16();
2203 3282 : FOR( maxK = 1; maxK < nTransWidth; maxK++ )
2204 : {
2205 3014 : IF( sqQ[i + maxK] != 0 )
2206 : {
2207 366 : BREAK;
2208 : }
2209 : }
2210 634 : i = add( i, 1 );
2211 634 : segmentOffset = i;
2212 634 : move16();
2213 :
2214 634 : IF( LE_16( nTransWidth, 3 ) )
2215 : {
2216 0 : accu1 = L_deposit_l( 0 );
2217 0 : accu2 = L_deposit_l( 0 );
2218 0 : xMax = L_deposit_l( 0 );
2219 :
2220 0 : FOR( k = s_and( i, (Word16) 0xFFFE ); k < lowpassLine; k++ )
2221 : {
2222 0 : xMax = L_max( xMax, L_abs( x_orig[k] ) );
2223 : }
2224 0 : s = sub( norm_l( xMax ), 4 );
2225 :
2226 0 : FOR( k = s_and( i, (Word16) 0xFFFE ); k < lowpassLine; k += 2 )
2227 : {
2228 : /* even-index bins, left sub-win */
2229 0 : tmp1 = round_fx( L_shl( x_orig[k], s ) );
2230 0 : accu1 = L_mac0( accu1, tmp1, tmp1 );
2231 :
2232 : /* odd-index bins, right sub-win */
2233 0 : tmp1 = round_fx( L_shl( x_orig[k + 1], s ) );
2234 0 : accu2 = L_mac0( accu2, tmp1, tmp1 );
2235 : }
2236 0 : k = 0;
2237 0 : move16();
2238 :
2239 0 : IF( accu1 == 0 )
2240 : {
2241 0 : accu1 = L_deposit_l( 1 );
2242 : }
2243 0 : IF( accu2 == 0 )
2244 : {
2245 0 : accu2 = L_deposit_l( 1 );
2246 : }
2247 :
2248 0 : att = BASOP_Util_Divide3232_Scale( L_shl( L_min( accu1, accu2 ), 1 ), L_add( accu1, accu2 ), &s );
2249 0 : att = Sqrt16( att, &s );
2250 : BASOP_SATURATE_WARNING_OFF_EVS; /* att is always <= 1.0 */
2251 0 : att = shl_sat( att, s );
2252 : BASOP_SATURATE_WARNING_ON_EVS;
2253 : }
2254 : ELSE
2255 : {
2256 634 : att = 0x7FFF;
2257 634 : move16();
2258 : }
2259 :
2260 634 : accu1 = L_deposit_l( 0 );
2261 :
2262 634 : tmp1 = sub( lowpassLine, nTransWidth );
2263 118875 : FOR( ; i <= tmp1; i++ )
2264 : {
2265 118241 : inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 );
2266 :
2267 118241 : IF( EQ_16( maxK, 1 ) ) /* current line is not zero, so reset pointers */
2268 : {
2269 17737 : k = sub( i, segmentOffset );
2270 :
2271 17737 : IF( k > 0 ) /* add segment sum to sum of segment magnitudes */
2272 : {
2273 11538 : IF( LE_16( nTransWidth, 3 ) )
2274 : {
2275 0 : tmp2 = sub( k, c1 );
2276 0 : IF( tmp2 > 0 )
2277 : {
2278 0 : n = L_msu( n, k, (Word16) 0x8000 );
2279 : }
2280 0 : IF( tmp2 > 0 )
2281 : {
2282 0 : n = L_mac( n, nTransWidth_1, (Word16) 0x8000 );
2283 : }
2284 0 : IF( tmp2 <= 0 )
2285 : {
2286 0 : n = L_mac( n, int_sqr[k], c2 );
2287 : }
2288 : }
2289 : ELSE
2290 : {
2291 11538 : tmp2 = sub( k, 12 );
2292 11538 : IF( tmp2 > 0 )
2293 : {
2294 1643 : n = L_msu( n, k, (Word16) 0x8000 );
2295 : }
2296 11538 : IF( tmp2 > 0 )
2297 : {
2298 1643 : n = L_sub( n, 0x70000 );
2299 : }
2300 11538 : IF( tmp2 <= 0 )
2301 : {
2302 9895 : n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ );
2303 : }
2304 : }
2305 11538 : sqErrorNrg = L_add( sqErrorNrg, accu1 );
2306 11538 : accu1 = L_deposit_l( 0 ); /* segment ended here, so reset segment sum */
2307 11538 : k = 0;
2308 11538 : move16();
2309 : }
2310 :
2311 64819 : FOR( ; maxK < nTransWidth; maxK++ )
2312 : {
2313 60898 : IF( sqQ[i + maxK] != 0 )
2314 : {
2315 13816 : BREAK;
2316 : }
2317 : }
2318 17737 : segmentOffset = add( i, 1 ); /* new segment might start at next line */
2319 : }
2320 : ELSE /* current line is zero, so update pointers & segment sum */
2321 : {
2322 100504 : IF( LT_16( k, nTransWidth ) )
2323 : {
2324 52640 : k = add( k, 1 );
2325 : }
2326 :
2327 100504 : tmp2 = sub( maxK, nTransWidth );
2328 100504 : IF( tmp2 < 0 )
2329 : {
2330 42339 : maxK = sub( maxK, 1 );
2331 : }
2332 :
2333 100504 : test();
2334 100504 : IF( ( tmp2 >= 0 ) && ( sqQ[i + sub( nTransWidth, 1 )] != 0 ) )
2335 : {
2336 3726 : maxK = sub( nTransWidth, 1 );
2337 : }
2338 :
2339 : /* update segment sum: magnitudes scaled by smoothing function */
2340 : /*accu1 += (float)fabs(x_orig[i]) * inv_gain2 * (float)(k * maxK);*/
2341 100504 : tmp2 = mult( inv_gain2, shl( imult1616( k, maxK ), 8 ) );
2342 100504 : accu1 = L_add( accu1, L_abs( Mpy_32_16_1( x_orig[i], tmp2 ) ) );
2343 : }
2344 : }
2345 :
2346 5072 : FOR( ; i < lowpassLine; i++ )
2347 : {
2348 4438 : inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 );
2349 :
2350 4438 : IF( EQ_16( maxK, 1 ) ) /* current line is not zero, so reset pointers */
2351 : {
2352 773 : k = sub( i, segmentOffset );
2353 :
2354 773 : IF( k > 0 ) /* add segment sum to sum of segment magnitudes */
2355 : {
2356 161 : IF( LE_16( nTransWidth, 3 ) )
2357 : {
2358 0 : tmp2 = sub( k, c1 );
2359 0 : IF( tmp2 > 0 )
2360 : {
2361 0 : n = L_msu( n, k, (Word16) 0x8000 );
2362 : }
2363 0 : IF( tmp2 > 0 )
2364 : {
2365 0 : n = L_mac( n, nTransWidth_1, (Word16) 0x8000 );
2366 : }
2367 0 : IF( tmp2 <= 0 )
2368 : {
2369 0 : n = L_mac( n, int_sqr[k], c2 );
2370 : }
2371 : }
2372 : ELSE
2373 : {
2374 161 : tmp2 = sub( k, 12 );
2375 161 : IF( tmp2 > 0 )
2376 : {
2377 54 : n = L_msu( n, k, (Word16) 0x8000 );
2378 : }
2379 161 : IF( tmp2 > 0 )
2380 : {
2381 54 : n = L_sub( n, 0x70000 );
2382 : }
2383 161 : IF( tmp2 <= 0 )
2384 : {
2385 107 : n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ );
2386 : }
2387 : }
2388 161 : sqErrorNrg = L_add( sqErrorNrg, accu1 );
2389 : }
2390 773 : segmentOffset = add( i, 1 ); /* no new segments since maxK remains 1 */
2391 : }
2392 : ELSE /* current line is zero, so update pointers & energy sum */
2393 : {
2394 3665 : IF( LT_16( k, nTransWidth ) )
2395 : {
2396 716 : k = add( k, 1 );
2397 : }
2398 3665 : IF( LT_16( maxK, nTransWidth ) )
2399 : {
2400 424 : maxK = sub( maxK, 1 );
2401 : }
2402 :
2403 : /* update segment sum: magnitudes scaled by smoothing function */
2404 : /*accu1 += (float)fabs(x_orig[i]) * inv_gain2 * (float)(k * maxK);*/
2405 3665 : tmp2 = mult( inv_gain2, shl( imult1616( k, maxK ), 8 ) );
2406 3665 : accu1 = L_add( accu1, L_abs( Mpy_32_16_1( x_orig[i], tmp2 ) ) );
2407 : }
2408 : }
2409 :
2410 634 : k = sub( i, segmentOffset );
2411 634 : IF( k > 0 ) /* add last segment sum to sum of segment magnitudes */
2412 : {
2413 463 : IF( LE_16( nTransWidth, 3 ) )
2414 : {
2415 0 : tmp2 = sub( k, c1 );
2416 0 : IF( tmp2 > 0 )
2417 : {
2418 0 : n = L_msu( n, k, (Word16) 0x8000 );
2419 : }
2420 0 : IF( tmp2 > 0 )
2421 : {
2422 0 : n = L_mac( n, nTransWidth_1, (Word16) 0x8000 );
2423 : }
2424 0 : IF( tmp2 <= 0 )
2425 : {
2426 0 : n = L_mac( n, int_sqr[k], c2 );
2427 : }
2428 : }
2429 : ELSE
2430 : {
2431 463 : tmp2 = sub( k, 12 );
2432 463 : IF( tmp2 > 0 )
2433 : {
2434 379 : n = L_msu( n, k, (Word16) 0x8000 );
2435 : }
2436 463 : IF( tmp2 > 0 )
2437 : {
2438 379 : n = L_sub( n, 0x70000 );
2439 : }
2440 463 : IF( tmp2 <= 0 )
2441 : {
2442 84 : n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ );
2443 : }
2444 : }
2445 463 : sqErrorNrg = L_add( sqErrorNrg, accu1 );
2446 : }
2447 :
2448 : /* noise level factor: average of segment magnitudes of noise bins */
2449 634 : IF( n > 0 )
2450 : {
2451 634 : tmp1 = BASOP_Util_Divide3232_Scale( Mpy_32_16_1( sqErrorNrg, att ), n, &s );
2452 634 : s = add( add( add( s, x_orig_e ), inv_gain2_e ), 7 - 15 );
2453 : BASOP_SATURATE_WARNING_OFF_EVS;
2454 634 : tmp1 = shl_sat( tmp1, s );
2455 : BASOP_SATURATE_WARNING_ON_EVS;
2456 : }
2457 : ELSE
2458 : {
2459 0 : tmp1 = 0;
2460 0 : move16();
2461 : }
2462 :
2463 : /* quantize, dequantize noise level factor (range 0.09375 - 0.65625) */
2464 634 : tmp2 = round_fx( L_shr( L_mult( tmp1, 22016 /*1.34375f Q14*/ ), 14 - NBITS_NOISE_FILL_LEVEL ) );
2465 :
2466 634 : if ( GT_16( tmp2, ( 1 << NBITS_NOISE_FILL_LEVEL ) - 1 ) )
2467 : {
2468 0 : tmp2 = ( 1 << NBITS_NOISE_FILL_LEVEL ) - 1;
2469 0 : move16();
2470 : }
2471 :
2472 634 : *quantized_fac_ns = tmp2;
2473 634 : move16();
2474 :
2475 634 : *fac_ns = extract_l( L_mult0( *quantized_fac_ns, shr( 24576 /*0.75f Q15*/, NBITS_NOISE_FILL_LEVEL ) ) );
2476 634 : }
2477 :
2478 :
2479 856649 : void tcx_noise_factor_ivas_fx(
2480 : Word32 *x_orig, /* i: unquantized mdct coefficients */
2481 : Word16 x_orig_e, /* i: exponent */
2482 : Word32 *sqQ, /* i: quantized mdct coefficients, exponent = x_orig_e */
2483 : Word16 iFirstLine, /* i: first coefficient to be considered */
2484 : Word16 lowpassLine, /* i: last nonzero coefficients after low-pass */
2485 : Word16 nTransWidth, /* i: minimum size of hole to be checked */
2486 : Word16 L_frame, /* i: frame length */
2487 : Word16 gain_tcx, /* i: tcx gain */
2488 : Word16 gain_tcx_e, /* i: gain exponent */
2489 : Word16 tiltCompFactor, /* i: LPC tilt compensation factor */
2490 : Word16 *fac_ns, /* o: noise factor, Q15 */
2491 : Word16 *quantized_fac_ns, /* o: quantized noise factor, Q0 */
2492 : Word16 element_mode /* i: element mode */
2493 : )
2494 : {
2495 : Word16 i, k, win, segmentOffset, j;
2496 856649 : Word32 sqErrorNrg = 0, n;
2497 856649 : move32();
2498 : Word32 inv_gain2, tilt_factor;
2499 856649 : Word16 inv_gain2_e, nTransWidth_1, exp_sqErrorNrg = 0;
2500 856649 : move16();
2501 : Word32 accu1, accu2, tmp32;
2502 : Word16 tmp1, tmp2, s;
2503 : Word16 c1, c2;
2504 : Word16 att; /* noise level attenuation factor for transient windows */
2505 : Word32 xMax;
2506 : Word16 exp_spQ[N_MAX];
2507 : #if !defined( ISSUE_1867_replace_overflow_libenc )
2508 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2509 : Flag Overflow = 0;
2510 : move32();
2511 : #endif
2512 : #endif
2513 :
2514 856649 : assert( nTransWidth <= 16 );
2515 :
2516 856649 : set16_fx( exp_spQ, x_orig_e, N_MAX );
2517 856649 : c1 = sub( shl( nTransWidth, 1 ), 4 );
2518 856649 : c2 = mult( 9216 /*0.28125f Q15*/, inv_int[nTransWidth] );
2519 856649 : nTransWidth_1 = sub( nTransWidth, 1 );
2520 :
2521 : /*Adjust noise filling level*/
2522 856649 : n = 0;
2523 856649 : move32();
2524 :
2525 : /* get inverse frame length */
2526 856649 : tmp1 = getInvFrameLen( L_frame );
2527 :
2528 : /* tilt_factor = 1.0f /(float)pow(max(0.375f, tiltCompFactor), 1.0f/(float)L_frame); */
2529 856649 : tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */
2530 856649 : tmp32 = L_shr( Mpy_32_16_1( tmp32, negate( tmp1 ) ), 6 );
2531 856649 : tilt_factor = BASOP_Util_InvLog2( L_sub( tmp32, 0x2000000 ) ); /* 1Q30 */
2532 :
2533 : /* inv_gain2 = 1.0f / ((float)(nTransWidth * nTransWidth) * gain_tcx); */
2534 856649 : tmp32 = L_mult( imult1616( nTransWidth, nTransWidth ), gain_tcx ); /* 15Q16 */
2535 856649 : inv_gain2 = BASOP_Util_Divide3232_Scale_newton( MAX_32, tmp32, &inv_gain2_e );
2536 856649 : inv_gain2_e = add( inv_gain2_e, sub( 0, add( 15, gain_tcx_e ) ) );
2537 856649 : inv_gain2 = L_shr( inv_gain2, 2 ); /* 2 bits headroom */
2538 856649 : inv_gain2_e = add( inv_gain2_e, 2 );
2539 :
2540 : /* find last nonzero line below iFirstLine, use it as start offset */
2541 856649 : i = iFirstLine;
2542 856649 : move16();
2543 :
2544 856649 : IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */
2545 : {
2546 636298 : segmentOffset = i;
2547 636298 : move16();
2548 : }
2549 : ELSE
2550 : {
2551 : /* find last nonzero line below iFirstLine, use it as start offset */
2552 220351 : tmp1 = shr( iFirstLine, 1 );
2553 658827 : FOR( ; i > tmp1; i-- )
2554 : {
2555 657312 : IF( sqQ[i] != 0 )
2556 : {
2557 218836 : BREAK;
2558 : }
2559 : }
2560 : /* inv_gain2 *= (float)pow(tilt_factor, (float)i); */
2561 15078109 : FOR( k = 0; k < i; k++ )
2562 : {
2563 14857758 : inv_gain2 = L_shl( Mpy_32_32( inv_gain2, tilt_factor ), 1 );
2564 : }
2565 :
2566 220351 : i = add( i, 1 );
2567 220351 : segmentOffset = i;
2568 220351 : move16();
2569 : }
2570 :
2571 856649 : IF( LE_16( nTransWidth, 3 ) )
2572 : {
2573 32028 : accu1 = 0;
2574 32028 : move32();
2575 32028 : accu2 = 0;
2576 32028 : move32();
2577 32028 : xMax = 0;
2578 32028 : move32();
2579 :
2580 6748258 : FOR( k = i & 0xFFFE; k < lowpassLine; k++ )
2581 : {
2582 6716230 : xMax = L_max( xMax, L_abs( x_orig[k] ) );
2583 : }
2584 32028 : s = sub( norm_l( xMax ), 4 );
2585 :
2586 3390143 : FOR( k = i & 0xFFFE; k < lowpassLine; k += 2 )
2587 : {
2588 : /* even-index bins, left sub-win */
2589 3358115 : tmp1 = round_fx( L_shl( x_orig[k], s ) );
2590 3358115 : accu1 = L_mac0( accu1, tmp1, tmp1 );
2591 :
2592 : /* odd-index bins, right sub-win */
2593 3358115 : tmp1 = round_fx( L_shl( x_orig[k + 1], s ) );
2594 3358115 : accu2 = L_mac0( accu2, tmp1, tmp1 );
2595 : }
2596 32028 : k = 0;
2597 32028 : move16();
2598 :
2599 32028 : if ( accu1 == 0 )
2600 : {
2601 6 : accu1 = 1;
2602 6 : move32();
2603 : }
2604 32028 : if ( accu2 == 0 )
2605 : {
2606 4 : accu2 = 1;
2607 4 : move32();
2608 : }
2609 :
2610 32028 : att = BASOP_Util_Divide3232_Scale( L_shl( L_min( accu1, accu2 ), 1 ), L_add( accu1, accu2 ), &s );
2611 32028 : att = Sqrt16( att, &s );
2612 : BASOP_SATURATE_WARNING_OFF_EVS; /* att is always <= 1.0 */
2613 32028 : att = shl_sat( att, s );
2614 : BASOP_SATURATE_WARNING_ON_EVS;
2615 : }
2616 : ELSE
2617 : {
2618 824621 : att = 0x7FFF;
2619 824621 : move16();
2620 : }
2621 :
2622 856649 : win = 0;
2623 856649 : move16();
2624 :
2625 334870751 : FOR( ; i < lowpassLine; i++ )
2626 : {
2627 334014102 : inv_gain2 = L_shl( Mpy_32_32( inv_gain2, tilt_factor ), 1 );
2628 :
2629 334014102 : IF( sqQ[i] != 0 ) /* current line is not zero, so reset pointers */
2630 : {
2631 80017420 : IF( win > 0 )
2632 : {
2633 37193561 : k = sub( i, segmentOffset );
2634 :
2635 37193561 : IF( LE_16( nTransWidth, 3 ) )
2636 : {
2637 828414 : tmp2 = sub( k, c1 );
2638 828414 : if ( tmp2 > 0 )
2639 : {
2640 329629 : n = L_msu( n, k, (Word16) 0x8000 );
2641 : }
2642 828414 : if ( tmp2 > 0 )
2643 : {
2644 329629 : n = L_mac( n, nTransWidth_1, (Word16) 0x8000 );
2645 : }
2646 828414 : if ( tmp2 <= 0 )
2647 : {
2648 498785 : n = L_mac( n, int_sqr[k], c2 );
2649 : }
2650 : }
2651 : ELSE
2652 : {
2653 36365147 : tmp2 = sub( k, 12 );
2654 36365147 : if ( tmp2 > 0 )
2655 : {
2656 2573734 : n = L_msu( n, k, (Word16) 0x8000 );
2657 : }
2658 36365147 : if ( tmp2 > 0 )
2659 : {
2660 2573734 : n = L_sub( n, 0x70000 );
2661 : }
2662 36365147 : if ( tmp2 <= 0 )
2663 : {
2664 33791413 : n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ );
2665 : }
2666 : }
2667 95289626 : FOR( k = segmentOffset; k < i - win; k++ )
2668 : {
2669 58096065 : tmp1 = norm_l( sqQ[k] );
2670 58096065 : sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), nTransWidth ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg );
2671 58096065 : sqQ[k] = 0;
2672 58096065 : move32();
2673 58096065 : exp_spQ[k] = 0;
2674 58096065 : move16();
2675 : }
2676 146991036 : FOR( ; win > 0; win-- )
2677 : {
2678 109797475 : tmp1 = norm_l( sqQ[k] );
2679 109797475 : sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), win ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg );
2680 109797475 : exp_spQ[k] = 0;
2681 109797475 : move16();
2682 109797475 : sqQ[k++] = 0;
2683 109797475 : move32();
2684 : }
2685 : }
2686 80017420 : segmentOffset = add( i, 1 ); /* new segment might start at next line */
2687 : }
2688 : ELSE /* current line is zero, so update pointers & segment sum */
2689 : {
2690 253996682 : if ( LT_16( win, nTransWidth ) )
2691 : {
2692 115037213 : win = add( win, 1 );
2693 : }
2694 : /* update segment sum: magnitudes scaled by smoothing function */
2695 253996682 : sqQ[i] = Mpy_32_32( imult3216( L_abs( x_orig[i] ), win ), inv_gain2 );
2696 253996682 : exp_spQ[i] = add( x_orig_e, inv_gain2_e );
2697 253996682 : move16();
2698 : }
2699 : }
2700 856649 : IF( win > 0 ) /* add last segment sum to sum of segment magnitudes */
2701 : {
2702 790593 : k = sub( i, segmentOffset );
2703 790593 : IF( LE_16( nTransWidth, 3 ) )
2704 : {
2705 29061 : tmp2 = sub( k, c1 );
2706 29061 : if ( tmp2 > 0 )
2707 : {
2708 26194 : n = L_msu( n, k, (Word16) 0x8000 );
2709 : }
2710 29061 : if ( tmp2 > 0 )
2711 : {
2712 26194 : n = L_mac( n, nTransWidth_1, (Word16) 0x8000 );
2713 : }
2714 29061 : if ( tmp2 <= 0 )
2715 : {
2716 2867 : n = L_mac( n, int_sqr[k], c2 );
2717 : }
2718 : }
2719 : ELSE
2720 : {
2721 761532 : tmp2 = sub( k, 12 );
2722 761532 : if ( tmp2 > 0 )
2723 : {
2724 577538 : n = L_msu( n, k, (Word16) 0x8000 );
2725 : }
2726 761532 : if ( tmp2 > 0 )
2727 : {
2728 577538 : n = L_sub( n, 0x70000 );
2729 : }
2730 761532 : if ( tmp2 <= 0 )
2731 : {
2732 183994 : n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ );
2733 : }
2734 : }
2735 81653997 : FOR( k = segmentOffset; k < i - win; k++ )
2736 : {
2737 80863404 : tmp1 = norm_l( sqQ[k] );
2738 80863404 : sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), nTransWidth ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg );
2739 80863404 : exp_spQ[k] = 0;
2740 80863404 : move16();
2741 80863404 : sqQ[k] = 0;
2742 80863404 : move32();
2743 : }
2744 6030331 : FOR( ; win > 0; win-- )
2745 : {
2746 5239738 : tmp1 = norm_l( sqQ[k] );
2747 5239738 : sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), win ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg );
2748 5239738 : exp_spQ[k] = 0;
2749 5239738 : move16();
2750 5239738 : sqQ[k++] = 0;
2751 5239738 : move32();
2752 : }
2753 : }
2754 : Word32 tmp4;
2755 : /* noise level factor: average of segment magnitudes of noise bins */
2756 856649 : IF( n > 0 )
2757 : {
2758 856649 : tmp4 = BASOP_Util_Divide3232_Scale_newton( Mpy_32_16_1( sqErrorNrg, att ), n, &s );
2759 856649 : s = add( add( exp_sqErrorNrg, -15 ), s );
2760 : BASOP_SATURATE_WARNING_OFF_EVS;
2761 : #ifdef ISSUE_1867_replace_overflow_libenc
2762 856649 : tmp4 = L_shl_sat( tmp4, s );
2763 : #else
2764 : tmp4 = L_shl_o( tmp4, s, &Overflow );
2765 : #endif
2766 : BASOP_SATURATE_WARNING_ON_EVS;
2767 : }
2768 : ELSE
2769 : {
2770 0 : tmp4 = 0;
2771 0 : move16();
2772 : }
2773 1028835449 : FOR( j = 0; j < N_MAX; j++ )
2774 : {
2775 1027978800 : sqQ[j] = L_shl( sqQ[j], sub( x_orig_e, exp_spQ[j] ) );
2776 1027978800 : move32();
2777 : }
2778 : /* quantize, dequantize noise level factor (range 0.09375 - 0.65625) */
2779 856649 : tmp2 = round_fx( L_shr( Mpy_32_16_1( tmp4, 22016 /*1.34375f Q14*/ ), 14 - NBITS_NOISE_FILL_LEVEL ) );
2780 856649 : if ( GT_16( tmp2, ( 1 << NBITS_NOISE_FILL_LEVEL ) - 1 ) )
2781 : {
2782 40323 : tmp2 = ( 1 << NBITS_NOISE_FILL_LEVEL ) - 1;
2783 40323 : move16();
2784 : }
2785 :
2786 856649 : *quantized_fac_ns = tmp2;
2787 856649 : move16();
2788 :
2789 856649 : *fac_ns = extract_l( L_mult0( *quantized_fac_ns, shr( 24576 /*0.75f Q15*/, NBITS_NOISE_FILL_LEVEL ) ) );
2790 856649 : move16();
2791 856649 : }
2792 :
2793 :
2794 634 : void tcx_encoder_memory_update_fx(
2795 : Word16 *wsig, /* i : target weighted signal */
2796 : Word16 *xn_buf, /* i/o: mdct output buffer/time domain weigthed synthesis */
2797 : Word16 L_frame_glob, /* i: global frame length */
2798 : const Word16 *Ai, /* i: Unquantized (interpolated) LPC coefficients */
2799 : const Word16 *A, /* i: Quantized LPC coefficients */
2800 : Word16 preemph, /* i: preemphasis factor */
2801 : LPD_state *LPDmem, /* i/o: coder memory state */
2802 : Encoder_State *st,
2803 : Word16 *synthout,
2804 : Word16 Q_new,
2805 : Word16 shift )
2806 : {
2807 : Word16 tmp;
2808 : Word16 buf[1 + M + LFAC + L_FRAME_PLUS];
2809 : Word16 *synth;
2810 :
2811 :
2812 : /* Output synth */
2813 634 : Copy( xn_buf, synthout, L_frame_glob );
2814 :
2815 :
2816 : /* Update synth */
2817 634 : synth = buf + M + 1;
2818 634 : Copy( LPDmem->syn, buf, M + 1 );
2819 :
2820 634 : Copy( xn_buf, synth, L_frame_glob );
2821 634 : Copy( synth + sub( L_frame_glob, M + 1 ), LPDmem->syn, M + 1 );
2822 :
2823 634 : IF( st->tcxonly == 0 )
2824 : {
2825 : /* Update weighted synthesis */
2826 634 : Residu3_fx( Ai + ( st->nb_subfr - 1 ) * ( M + 1 ), synth + sub( L_frame_glob, 1 ), &tmp, 1, Q_new + shift - 1 );
2827 634 : LPDmem->mem_w0 = sub( wsig[sub( L_frame_glob, 1 )], tmp );
2828 634 : move16();
2829 634 : LPDmem->mem_w0 = shr_sat( LPDmem->mem_w0, shift ); /*Qnew-1*/
2830 634 : move16();
2831 : }
2832 :
2833 :
2834 : /* Emphasis of synth -> synth_pe */
2835 634 : tmp = synth[-( M + 1 )];
2836 634 : move16();
2837 634 : E_UTIL_f_preemph2( Q_new - 1, synth - M, preemph, add( M, L_frame_glob ), &tmp );
2838 :
2839 634 : Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn, M );
2840 634 : Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn2, M );
2841 634 : Copy( synth + sub( L_frame_glob, L_SYN_MEM ), LPDmem->mem_syn_r, L_SYN_MEM );
2842 :
2843 634 : test();
2844 634 : IF( st->tcxonly == 0 || LE_16( L_frame_glob, L_FRAME16k ) )
2845 : {
2846 : /* Update excitation */
2847 634 : IF( LT_16( L_frame_glob, L_EXC_MEM ) )
2848 : {
2849 262 : Copy( LPDmem->old_exc + L_frame_glob, LPDmem->old_exc, sub( L_EXC_MEM, L_frame_glob ) );
2850 262 : Residu3_fx( A, synth, LPDmem->old_exc + sub( L_EXC_MEM, L_frame_glob ), L_frame_glob, 1 );
2851 : }
2852 : ELSE
2853 : {
2854 372 : Residu3_fx( A, synth + sub( L_frame_glob, L_EXC_MEM ), LPDmem->old_exc, L_EXC_MEM, 1 );
2855 : }
2856 : }
2857 634 : }
2858 :
2859 236431 : void tcx_encoder_memory_update_ivas_fx(
2860 : Word16 *wsig, /* i : target weighted signal, Q_new */
2861 : Word16 *xn_buf, /* i/o: mdct output buffer/time domain weigthed synthesis, Q_new */
2862 : Word16 L_frame_glob, /* i: global frame length */
2863 : const Word16 *Ai, /* i: Unquantized (interpolated) LPC coefficients, Q12 */
2864 : const Word16 *A, /* i: Quantized LPC coefficients, Q = 14 - norm_s(A[0]) */
2865 : Word16 preemph, /* i: preemphasis factor, Q15 */
2866 : LPD_state *LPDmem, /* i/o: coder memory state */
2867 : Encoder_State *st,
2868 : Word16 *synthout, /* Q_new */
2869 : Word16 Q_new )
2870 : {
2871 : Word16 tmp;
2872 : Word16 buf[1 + M + LFAC + L_FRAME_PLUS];
2873 : Word16 *synth;
2874 :
2875 :
2876 : /* Output synth */
2877 236431 : Copy( xn_buf, synthout, L_frame_glob );
2878 :
2879 :
2880 : /* Update synth */
2881 236431 : synth = buf + M + 1;
2882 236431 : Copy( LPDmem->syn, buf, M + 1 );
2883 :
2884 236431 : Copy( xn_buf, synth, L_frame_glob );
2885 236431 : Copy( synth + sub( L_frame_glob, M + 1 ), LPDmem->syn, M + 1 );
2886 236431 : LPDmem->q_lpd_syn = Q_new;
2887 236431 : move16();
2888 :
2889 236431 : IF( st->tcxonly == 0 )
2890 : {
2891 : /* Update weighted synthesis */
2892 129542 : Residu3_fx( Ai + imult1616( sub( st->nb_subfr, 1 ), ( M + 1 ) ), synth + sub( L_frame_glob, 1 ), &tmp, 1, 0 );
2893 129542 : LPDmem->mem_w0 = sub_sat( wsig[L_frame_glob - 1], tmp );
2894 129542 : move16();
2895 : }
2896 :
2897 :
2898 : /* Emphasis of synth -> synth_pe */
2899 236431 : tmp = synth[-( M + 1 )];
2900 236431 : move16();
2901 236431 : E_UTIL_f_preemph2( 0, synth - M, preemph, add( M, L_frame_glob ), &tmp ); // Q_new
2902 :
2903 236431 : Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn, M );
2904 236431 : Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn2, M );
2905 236431 : Copy( synth + sub( L_frame_glob, L_SYN_MEM ), LPDmem->mem_syn_r, L_SYN_MEM );
2906 :
2907 : /* Aligning the Q-factor of the remaining synthesis memory buffers */
2908 236431 : Scale_sig( LPDmem->mem_syn1_fx, M, sub( Q_new, LPDmem->q_mem_syn ) );
2909 236431 : Scale_sig( LPDmem->mem_syn3, M, sub( Q_new, LPDmem->q_mem_syn ) );
2910 :
2911 236431 : LPDmem->q_mem_syn = Q_new; // resultant q of synth after E_UTIL_f_preemph2
2912 236431 : move16();
2913 :
2914 236431 : test();
2915 236431 : IF( st->tcxonly == 0 || LE_16( L_frame_glob, L_FRAME16k ) )
2916 : {
2917 : /* Update excitation */
2918 130042 : IF( LT_16( L_frame_glob, L_EXC_MEM ) )
2919 : {
2920 54577 : Word16 shift = norm_arr( LPDmem->old_exc + L_frame_glob, sub( L_EXC_MEM, L_frame_glob ) );
2921 54577 : IF( LT_16( shift, sub( Q_new, LPDmem->q_lpd_old_exc ) ) )
2922 : {
2923 0 : Copy_Scale_sig( LPDmem->old_exc + L_frame_glob, LPDmem->old_exc, sub( L_EXC_MEM, L_frame_glob ), shift );
2924 0 : LPDmem->q_lpd_old_exc = add( LPDmem->q_lpd_old_exc, shift );
2925 0 : move16();
2926 0 : Residu3_fx( A, synth, LPDmem->old_exc + sub( L_EXC_MEM, L_frame_glob ), L_frame_glob, sub( LPDmem->q_lpd_old_exc, Q_new ) ); // LPDmem->q_lpd_old_exc
2927 : }
2928 : ELSE
2929 : {
2930 54577 : Copy_Scale_sig( LPDmem->old_exc + L_frame_glob, LPDmem->old_exc, sub( L_EXC_MEM, L_frame_glob ), sub( Q_new, LPDmem->q_lpd_old_exc ) );
2931 54577 : Residu3_fx( A, synth, LPDmem->old_exc + sub( L_EXC_MEM, L_frame_glob ), L_frame_glob, 0 ); // Q_new
2932 54577 : LPDmem->q_lpd_old_exc = Q_new;
2933 54577 : move16();
2934 : }
2935 : }
2936 : ELSE
2937 : {
2938 75465 : Residu3_fx( A, synth + sub( L_frame_glob, L_EXC_MEM ), LPDmem->old_exc, L_EXC_MEM, 0 ); // Q_new
2939 75465 : LPDmem->q_lpd_old_exc = Q_new;
2940 75465 : move16();
2941 : }
2942 : }
2943 236431 : }
2944 :
2945 :
2946 : /*---------------------------------------------------------------
2947 : * Residual Quantization
2948 : *--------------------------------------------------------------*/
2949 :
2950 : /* Returns: number of bits used (including "bits") Q0 */
2951 0 : Word16 tcx_ari_res_Q_spec_fx(
2952 : const Word32 x_orig[], /* i: original spectrum Q31-e */
2953 : Word16 x_orig_e, /* i: original spectrum exponent Q0 */
2954 : const Word16 signs[], /* i: signs (x_orig[.]<0) Q0 */
2955 : Word32 x_Q[], /* i/o: quantized spectrum Q31-e */
2956 : Word16 x_Q_e, /* i: quantized spectrum exponent Q0 */
2957 : Word16 L_frame, /* i: number of lines Q0 */
2958 : Word16 gain, /* i: TCX gain Q15-e */
2959 : Word16 gain_e, /* i: TCX gain exponent Q0 */
2960 : Word16 prm[], /* o: bit-stream Q0 */
2961 : Word16 target_bits, /* i: number of bits available Q0 */
2962 : Word16 bits, /* i: number of bits used so far Q0 */
2963 : Word16 deadzone, /* i: quantizer deadzone Q15 */
2964 : const Word16 x_fac[] /* i: spectrum post-quantization factors Q14 */
2965 : )
2966 : {
2967 : Word16 i, j, num_zeros;
2968 : Word16 zeros[L_FRAME_PLUS];
2969 : Word16 fac_p, sign;
2970 : Word32 thres, x_Q_m, x_Q_p;
2971 : Word32 L_tmp, L_tmp2;
2972 : Word16 s, s2;
2973 :
2974 :
2975 : /* Limit the number of residual bits */
2976 0 : target_bits = s_min( target_bits, NPRM_RESQ );
2977 :
2978 :
2979 : /* Requantize the spectrum line-by-line */
2980 : /* fac_m = deadzone * 0.5f;
2981 : fac_p = 0.5f - fac_m; */
2982 0 : num_zeros = 0;
2983 0 : move16();
2984 :
2985 0 : s = sub( add( gain_e, x_Q_e ), x_orig_e );
2986 0 : FOR( i = 0; i < L_frame; i++ )
2987 : {
2988 0 : IF( GE_16( bits, target_bits ) ) /* no bits left */
2989 : {
2990 0 : BREAK;
2991 : }
2992 :
2993 0 : IF( x_Q[i] != 0 )
2994 : {
2995 0 : sign = x_fac[i];
2996 0 : move16();
2997 0 : IF( signs[i] != 0 )
2998 : {
2999 0 : sign = negate( sign );
3000 : }
3001 :
3002 : /* x_Q_m = x_Q[i] - sign*fac_m;
3003 : x_Q_p = x_Q[i] + sign*fac_p; */
3004 :
3005 0 : L_tmp = L_mult( sign, deadzone ); /* sign*deadzone/2 in Q31 */
3006 0 : x_Q_m = L_sub( x_Q[i], L_shr( L_tmp, x_Q_e ) );
3007 :
3008 0 : L_tmp = L_mac( L_tmp, sign, (Word16) 0x8000 ); /* sign*(deadzone-1)/2 in Q31 */
3009 0 : x_Q_p = L_sub( x_Q[i], L_shr( L_tmp, x_Q_e ) );
3010 :
3011 : /* if (fabs(x_orig[i] - gain * x_Q_m) < fabs(x_orig[i] - gain * x_Q_p)) */
3012 0 : L_tmp = L_abs( L_sub( x_orig[i], L_shl( Mpy_32_16_1( x_Q_m, gain ), s ) ) );
3013 0 : L_tmp2 = L_abs( L_sub( x_orig[i], L_shl( Mpy_32_16_1( x_Q_p, gain ), s ) ) );
3014 :
3015 0 : IF( LT_32( L_tmp, L_tmp2 ) ) /* Decrease magnitude */
3016 : {
3017 0 : x_Q[i] = x_Q_m;
3018 0 : move32();
3019 0 : prm[bits] = 0;
3020 0 : move16();
3021 : }
3022 : ELSE /* Increase magnitude */
3023 : {
3024 0 : x_Q[i] = x_Q_p;
3025 0 : move32();
3026 0 : prm[bits] = 1;
3027 0 : move16();
3028 : }
3029 0 : bits = add( bits, 1 );
3030 : }
3031 : ELSE
3032 : {
3033 0 : zeros[num_zeros] = i;
3034 0 : move16();
3035 0 : num_zeros = add( num_zeros, 1 );
3036 : }
3037 : }
3038 :
3039 : /* Requantize zeroed-lines of the spectrum */
3040 0 : fac_p = msu_r( 1417339264l /*2*0.33f Q31*/, deadzone, 21627 /*2*0.33f Q15*/ ); /* Q16 */
3041 0 : target_bits = sub( target_bits, 1 ); /* reserve 1 bit for the check below */
3042 :
3043 0 : s = sub( gain_e, x_orig_e );
3044 0 : s2 = sub( x_Q_e, 1 );
3045 0 : FOR( j = 0; j < num_zeros; j++ )
3046 : {
3047 0 : IF( GE_16( bits, target_bits ) ) /* 1 or 0 bits left */
3048 : {
3049 0 : BREAK;
3050 : }
3051 :
3052 0 : i = zeros[j];
3053 0 : move16();
3054 :
3055 0 : thres = L_mult( fac_p, x_fac[i] ); /* Q31 */
3056 :
3057 0 : IF( GT_32( L_abs( x_orig[i] ), L_shl( Mpy_32_16_1( thres, gain ), s ) ) )
3058 : {
3059 0 : prm[bits] = 1;
3060 0 : move16();
3061 0 : bits = add( bits, 1 );
3062 :
3063 0 : prm[bits] = sub( 1, signs[i] );
3064 0 : move16();
3065 0 : bits = add( bits, 1 );
3066 :
3067 0 : L_tmp = L_shr( thres, s2 );
3068 0 : IF( signs[i] )
3069 : {
3070 0 : L_tmp = L_negate( L_tmp );
3071 : }
3072 0 : x_Q[i] = L_tmp;
3073 0 : move32();
3074 : }
3075 : ELSE
3076 : {
3077 0 : prm[bits] = 0;
3078 0 : move16();
3079 0 : bits = add( bits, 1 );
3080 : }
3081 : }
3082 :
3083 :
3084 0 : return bits;
3085 : }
3086 :
3087 17425 : Word16 tcx_ari_res_Q_spec_ivas_fx(
3088 : const Word32 x_orig[], /* i: original spectrum Q31-e */
3089 : Word16 x_orig_e, /* i: original spectrum exponent Q0 */
3090 : const Word16 signs[], /* i: signs (x_orig[.]<0) Q0 */
3091 : Word32 x_Q[], /* i/o: quantized spectrum Q31-e */
3092 : Word16 x_Q_e, /* i: quantized spectrum exponent Q0 */
3093 : Word16 L_frame, /* i: number of lines Q0 */
3094 : Word16 gain, /* i: TCX gain Q15-e */
3095 : Word16 gain_e, /* i: TCX gain exponent Q0 */
3096 : Word16 prm[], /* o: bit-stream Q0 */
3097 : Word16 target_bits, /* i: number of bits available Q0 */
3098 : Word16 bits, /* i: number of bits used so far Q0 */
3099 : Word16 deadzone, /* i: quantizer deadzone Q15 */
3100 : const Word16 x_fac[] /* i: spectrum post-quantization factors Q14 */
3101 : )
3102 : {
3103 : Word16 i, j, num_zeros;
3104 : Word16 zeros[L_FRAME_PLUS];
3105 : Word16 fac_p, sign;
3106 : Word32 thres, x_Q_m, x_Q_p;
3107 : Word32 L_tmp, L_tmp2;
3108 : Word16 s, s2;
3109 :
3110 :
3111 : /* Limit the number of residual bits */
3112 17425 : target_bits = s_min( target_bits, NPRM_RESQ );
3113 :
3114 :
3115 : /* Requantize the spectrum line-by-line */
3116 : /* fac_m = deadzone * 0.5f;
3117 : fac_p = 0.5f - fac_m; */
3118 17425 : num_zeros = 0;
3119 17425 : move16();
3120 17425 : s = sub( add( gain_e, x_Q_e ), x_orig_e );
3121 17425 : IF( x_fac == NULL )
3122 : {
3123 0 : FOR( i = 0; i < L_frame; ++i )
3124 : {
3125 0 : IF( GE_16( bits, target_bits ) ) /* no bits left */
3126 : {
3127 0 : BREAK;
3128 : }
3129 :
3130 0 : IF( x_Q[i] != 0 )
3131 : {
3132 0 : sign = shl( sub( 1, shl( signs[i], 1 ) ), Q14 );
3133 0 : move16();
3134 :
3135 : /* x_Q_m = x_Q[i] - sign*fac_m;
3136 : x_Q_p = x_Q[i] + sign*fac_p; */
3137 :
3138 0 : L_tmp = L_mult( sign, deadzone ); /* sign*deadzone/2 in Q31 */
3139 0 : x_Q_m = L_sub( x_Q[i], L_shr( L_tmp, x_Q_e ) );
3140 :
3141 0 : L_tmp = L_mac( L_tmp, sign, (Word16) 0x8000 ); /* sign*(deadzone-1)/2 in Q31 */
3142 0 : x_Q_p = L_sub( x_Q[i], L_shr( L_tmp, x_Q_e ) );
3143 :
3144 : /* if (fabs(x_orig[i] - gain * x_Q_m) < fabs(x_orig[i] - gain * x_Q_p)) */
3145 0 : L_tmp = L_abs( L_sub( x_orig[i], L_shl( Mpy_32_16_1( x_Q_m, gain ), s ) ) );
3146 0 : L_tmp2 = L_abs( L_sub( x_orig[i], L_shl( Mpy_32_16_1( x_Q_p, gain ), s ) ) );
3147 :
3148 0 : IF( LT_32( L_tmp, L_tmp2 ) ) /* Decrease magnitude */
3149 : {
3150 0 : x_Q[i] = x_Q_m;
3151 0 : move32();
3152 0 : prm[bits] = 0;
3153 0 : move16();
3154 : }
3155 : ELSE /* Increase magnitude */
3156 : {
3157 0 : x_Q[i] = x_Q_p;
3158 0 : move32();
3159 0 : prm[bits] = 1;
3160 0 : move16();
3161 : }
3162 0 : bits = add( bits, 1 );
3163 : }
3164 : ELSE
3165 : {
3166 0 : zeros[num_zeros] = i;
3167 0 : move16();
3168 0 : num_zeros = add( num_zeros, 1 );
3169 : }
3170 : }
3171 :
3172 : /* Requantize zeroed-lines of the spectrum */
3173 0 : fac_p = msu_r( 1417339264l /*2*0.33f Q31*/, deadzone, 21627 /*2*0.33f Q15*/ ); /* Q16 */
3174 0 : target_bits = sub( target_bits, 1 ); /* reserve 1 bit for the check below */
3175 :
3176 0 : s = sub( gain_e, x_orig_e );
3177 0 : s2 = sub( x_Q_e, 1 );
3178 0 : FOR( j = 0; j < num_zeros; j++ )
3179 : {
3180 0 : IF( GE_16( bits, target_bits ) ) /* 1 or 0 bits left */
3181 : {
3182 0 : BREAK;
3183 : }
3184 :
3185 0 : i = zeros[j];
3186 0 : move16();
3187 :
3188 0 : thres = L_shl( fac_p, Q15 ); /* Q31 */
3189 :
3190 0 : IF( GT_32( L_abs( x_orig[i] ), L_shl( Mpy_32_16_1( thres, gain ), s ) ) )
3191 : {
3192 0 : prm[bits] = 1;
3193 0 : move16();
3194 0 : bits = add( bits, 1 );
3195 :
3196 0 : prm[bits] = sub( 1, signs[i] );
3197 0 : move16();
3198 0 : bits = add( bits, 1 );
3199 :
3200 0 : L_tmp = L_shr( thres, s2 );
3201 0 : IF( signs[i] )
3202 : {
3203 0 : L_tmp = L_negate( L_tmp );
3204 : }
3205 0 : x_Q[i] = L_tmp;
3206 0 : move32();
3207 : }
3208 : ELSE
3209 : {
3210 0 : prm[bits] = 0;
3211 0 : move16();
3212 0 : bits = add( bits, 1 );
3213 : }
3214 : }
3215 :
3216 0 : return bits;
3217 : }
3218 :
3219 17425 : s = sub( add( gain_e, x_Q_e ), x_orig_e );
3220 749952 : FOR( i = 0; i < L_frame; i++ )
3221 : {
3222 748809 : IF( GE_16( bits, target_bits ) ) /* no bits left */
3223 : {
3224 16282 : BREAK;
3225 : }
3226 :
3227 732527 : IF( x_Q[i] != 0 )
3228 : {
3229 15515 : sign = x_fac[i];
3230 15515 : move16();
3231 15515 : IF( signs[i] != 0 )
3232 : {
3233 7742 : sign = negate( sign );
3234 : }
3235 :
3236 : /* x_Q_m = x_Q[i] - sign*fac_m;
3237 : x_Q_p = x_Q[i] + sign*fac_p; */
3238 :
3239 15515 : L_tmp = L_mult( sign, deadzone ); /* sign*deadzone/2 in Q31 */
3240 15515 : x_Q_m = L_sub( x_Q[i], L_shr( L_tmp, x_Q_e ) );
3241 :
3242 15515 : L_tmp = L_mac( L_tmp, sign, (Word16) 0x8000 ); /* sign*(deadzone-1)/2 in Q31 */
3243 15515 : x_Q_p = L_sub( x_Q[i], L_shr( L_tmp, x_Q_e ) );
3244 :
3245 : /* if (fabs(x_orig[i] - gain * x_Q_m) < fabs(x_orig[i] - gain * x_Q_p)) */
3246 15515 : L_tmp = L_abs( L_sub( x_orig[i], L_shl( Mpy_32_16_1( x_Q_m, gain ), s ) ) );
3247 15515 : L_tmp2 = L_abs( L_sub( x_orig[i], L_shl( Mpy_32_16_1( x_Q_p, gain ), s ) ) );
3248 :
3249 15515 : IF( LT_32( L_tmp, L_tmp2 ) ) /* Decrease magnitude */
3250 : {
3251 9758 : x_Q[i] = x_Q_m;
3252 9758 : move32();
3253 9758 : prm[bits] = 0;
3254 9758 : move16();
3255 : }
3256 : ELSE /* Increase magnitude */
3257 : {
3258 5757 : x_Q[i] = x_Q_p;
3259 5757 : move32();
3260 5757 : prm[bits] = 1;
3261 5757 : move16();
3262 : }
3263 15515 : bits = add( bits, 1 );
3264 : }
3265 : ELSE
3266 : {
3267 717012 : zeros[num_zeros] = i;
3268 717012 : move16();
3269 717012 : num_zeros = add( num_zeros, 1 );
3270 : }
3271 : }
3272 :
3273 : /* Requantize zeroed-lines of the spectrum */
3274 17425 : fac_p = msu_r( 1417339264l /*2*0.33f Q31*/, deadzone, 21627 /*2*0.33f Q15*/ ); /* Q16 */
3275 17425 : target_bits = sub( target_bits, 1 ); /* reserve 1 bit for the check below */
3276 :
3277 17425 : s = sub( gain_e, x_orig_e );
3278 17425 : s2 = sub( x_Q_e, 1 );
3279 54825 : FOR( j = 0; j < num_zeros; j++ )
3280 : {
3281 39027 : IF( GE_16( bits, target_bits ) ) /* 1 or 0 bits left */
3282 : {
3283 1627 : BREAK;
3284 : }
3285 :
3286 37400 : i = zeros[j];
3287 37400 : move16();
3288 :
3289 37400 : thres = L_mult( fac_p, x_fac[i] ); /* Q31 */
3290 :
3291 37400 : IF( GT_32( L_abs( x_orig[i] ), L_shl( Mpy_32_16_1( thres, gain ), s ) ) )
3292 : {
3293 8858 : prm[bits] = 1;
3294 8858 : move16();
3295 8858 : bits = add( bits, 1 );
3296 :
3297 8858 : prm[bits] = sub( 1, signs[i] );
3298 8858 : move16();
3299 8858 : bits = add( bits, 1 );
3300 :
3301 8858 : L_tmp = L_shr( thres, s2 );
3302 8858 : IF( signs[i] )
3303 : {
3304 4570 : L_tmp = L_negate( L_tmp );
3305 : }
3306 8858 : x_Q[i] = L_tmp;
3307 8858 : move32();
3308 : }
3309 : ELSE
3310 : {
3311 28542 : prm[bits] = 0;
3312 28542 : move16();
3313 28542 : bits = add( bits, 1 );
3314 : }
3315 : }
3316 :
3317 :
3318 17425 : return bits;
3319 : }
3320 :
3321 : #define kMaxEstimatorOvershoot 5
3322 : #define kMaxEstimatorUndershoot 0
3323 :
3324 379242 : Word16 tcx_res_Q_gain_fx(
3325 : Word16 sqGain,
3326 : Word16 sqGain_e,
3327 : Word16 *gain_tcx,
3328 : Word16 *gain_tcx_e,
3329 : Word16 *prm,
3330 : Word16 sqTargetBits )
3331 : {
3332 : Word16 bits;
3333 : Word16 gain_reQ, gain_reQ_e;
3334 :
3335 : /*Refine the gain quantization : Normal greedy gain coding */
3336 :
3337 379242 : gain_reQ = *gain_tcx;
3338 379242 : move16();
3339 379242 : gain_reQ_e = *gain_tcx_e;
3340 379242 : move16();
3341 :
3342 : /* make sure we have a bit of headroom */
3343 379242 : IF( GT_16( gain_reQ, 0x7000 ) )
3344 : {
3345 18968 : gain_reQ = shr( gain_reQ, 1 );
3346 18968 : gain_reQ_e = add( gain_reQ_e, 1 );
3347 : }
3348 :
3349 : /* bring sqGain to same exponent */
3350 379242 : sqGain = shr_sat( sqGain, sub( gain_reQ_e, sqGain_e ) );
3351 1516968 : FOR( bits = 0; bits < TCX_RES_Q_BITS_GAIN; bits++ )
3352 : {
3353 1137726 : IF( LT_16( sqGain, gain_reQ ) )
3354 : {
3355 581773 : prm[bits] = 0;
3356 581773 : move16();
3357 581773 : gain_reQ = mult_r( gain_reQ, gain_corr_inv_fac[bits] );
3358 : }
3359 : ELSE
3360 : {
3361 555953 : prm[bits] = 1;
3362 555953 : move16();
3363 555953 : gain_reQ = shl( mult_r( gain_reQ, gain_corr_fac[bits] ), 1 );
3364 : }
3365 :
3366 1137726 : IF( LT_16( bits, sqTargetBits ) )
3367 : {
3368 890682 : *gain_tcx = gain_reQ;
3369 890682 : move16();
3370 890682 : *gain_tcx_e = gain_reQ_e;
3371 890682 : move16();
3372 : }
3373 : }
3374 :
3375 :
3376 379242 : return bits;
3377 : }
3378 :
3379 634 : Word16 tcx_res_Q_spec_fx(
3380 : Word32 *x_orig,
3381 : Word16 x_orig_e,
3382 : Word32 *x_Q,
3383 : Word16 x_Q_e,
3384 : Word16 L_frame,
3385 : Word16 sqGain,
3386 : Word16 sqGain_e,
3387 : Word16 *prm,
3388 : Word16 sqTargetBits,
3389 : Word16 bits,
3390 : Word16 sq_round,
3391 : const Word16 lf_deemph_factors[] /* 1Q14 */
3392 : )
3393 : {
3394 : Word16 i;
3395 : Word16 fac_m, fac_p;
3396 : Word32 tmp1, tmp2;
3397 : Word16 s, s2, lf_deemph_factor;
3398 : Word16 c;
3399 : Word32 thres;
3400 :
3401 :
3402 : /* Limit the number of residual bits */
3403 634 : sqTargetBits = s_min( sqTargetBits, NPRM_RESQ );
3404 :
3405 : /* Requantize the spectrum line-by-line */
3406 634 : fac_m = shr( sq_round, 1 );
3407 634 : fac_p = sub( 0x4000, fac_m );
3408 :
3409 : /* exponent difference of x_orig and x_Q * sqGain */
3410 634 : s = sub( x_orig_e, add( x_Q_e, sqGain_e ) );
3411 :
3412 634 : lf_deemph_factor = 0x4000;
3413 634 : move16();
3414 634 : s2 = sub( x_Q_e, 1 );
3415 :
3416 41694 : FOR( i = 0; i < L_frame; i++ )
3417 : {
3418 41652 : IF( GE_16( bits, sub( sqTargetBits, kMaxEstimatorUndershoot ) ) )
3419 : {
3420 10900 : fac_m = 0;
3421 10900 : move16();
3422 10900 : fac_p = 0;
3423 10900 : move16();
3424 :
3425 10900 : IF( GE_16( bits, s_min( NPRM_RESQ, add( sqTargetBits, kMaxEstimatorOvershoot ) ) ) )
3426 : {
3427 592 : BREAK;
3428 : }
3429 : }
3430 :
3431 41060 : test();
3432 41060 : test();
3433 41060 : IF( ( x_Q[i] != 0 ) && ( ( lf_deemph_factors == NULL ) || ( GT_16( lf_deemph_factors[i], 0x2000 ) ) ) )
3434 : {
3435 5654 : tmp1 = L_add( x_orig[i], 0 );
3436 5654 : tmp2 = Mpy_32_16_1( x_Q[i], sqGain );
3437 5654 : IF( s > 0 )
3438 : {
3439 2294 : tmp2 = L_shr( tmp2, s );
3440 : }
3441 5654 : IF( s < 0 )
3442 : {
3443 3056 : tmp1 = L_shl( tmp1, s );
3444 : }
3445 :
3446 5654 : if ( lf_deemph_factors != NULL )
3447 : {
3448 5654 : lf_deemph_factor = lf_deemph_factors[i];
3449 5654 : move16();
3450 : }
3451 :
3452 5654 : IF( LT_32( tmp1, tmp2 ) )
3453 : {
3454 2813 : prm[bits] = 0;
3455 2813 : move16();
3456 2813 : bits = add( bits, 1 );
3457 :
3458 2813 : IF( x_Q[i] > 0 )
3459 : {
3460 1438 : tmp1 = L_mult( fac_m, lf_deemph_factor );
3461 : }
3462 2813 : IF( x_Q[i] < 0 )
3463 : {
3464 1375 : tmp1 = L_mult( fac_p, lf_deemph_factor );
3465 : }
3466 2813 : x_Q[i] = L_sub( x_Q[i], L_shr( tmp1, s2 ) );
3467 2813 : move32();
3468 : }
3469 : ELSE
3470 : {
3471 2841 : prm[bits] = 1;
3472 2841 : move16();
3473 2841 : bits = add( bits, 1 );
3474 :
3475 2841 : IF( x_Q[i] > 0 )
3476 : {
3477 1375 : tmp1 = L_mult( fac_p, lf_deemph_factor );
3478 : }
3479 2841 : IF( x_Q[i] < 0 )
3480 : {
3481 1466 : tmp1 = L_mult( fac_m, lf_deemph_factor );
3482 : }
3483 2841 : x_Q[i] = L_add( x_Q[i], L_shr( tmp1, s2 ) );
3484 2841 : move32();
3485 : }
3486 : }
3487 : }
3488 :
3489 : /*Quantize zeroed-line of the spectrum*/
3490 634 : c = sub( 21627 /*0.66f Q15*/, mult_r( sq_round, 21627 /*0.66f Q15*/ ) );
3491 :
3492 2190 : FOR( i = 0; i < L_frame; i++ )
3493 : {
3494 2190 : IF( GE_16( bits, sub( sqTargetBits, 2 ) ) )
3495 : {
3496 634 : BREAK;
3497 : }
3498 :
3499 1556 : test();
3500 1556 : test();
3501 1556 : IF( ( x_Q[i] == 0 ) && ( ( lf_deemph_factors == NULL ) || ( GT_16( lf_deemph_factors[i], 0x2000 ) ) ) )
3502 : {
3503 752 : if ( lf_deemph_factors != NULL )
3504 : {
3505 752 : lf_deemph_factor = lf_deemph_factors[i];
3506 752 : move16();
3507 : }
3508 :
3509 752 : thres = L_mult( c, lf_deemph_factor );
3510 752 : tmp1 = L_shl( Mpy_32_16_1( thres, sqGain ), sub( sqGain_e, x_orig_e ) );
3511 :
3512 752 : IF( GT_32( x_orig[i], tmp1 ) )
3513 : {
3514 238 : prm[bits] = 1;
3515 238 : move16();
3516 238 : bits = add( bits, 1 );
3517 :
3518 238 : prm[bits] = 1;
3519 238 : move16();
3520 238 : bits = add( bits, 1 );
3521 :
3522 238 : x_Q[i] = L_shl( thres, sub( 1, x_Q_e ) );
3523 238 : move32();
3524 : }
3525 514 : ELSE IF( L_add( x_orig[i], tmp1 ) < 0 )
3526 : {
3527 210 : prm[bits] = 1;
3528 210 : move16();
3529 210 : bits = add( bits, 1 );
3530 :
3531 210 : prm[bits] = 0;
3532 210 : move16();
3533 210 : bits = add( bits, 1 );
3534 :
3535 210 : x_Q[i] = L_shl( L_negate( thres ), sub( 1, x_Q_e ) );
3536 210 : move32();
3537 : }
3538 : ELSE
3539 : {
3540 304 : prm[bits] = 0;
3541 304 : move16();
3542 304 : bits = add( bits, 1 );
3543 : }
3544 : }
3545 : }
3546 :
3547 : /*Be sure that every possible bits are initialized*/
3548 55278 : FOR( i = bits; i < NPRM_RESQ; i++ )
3549 : {
3550 54644 : prm[i] = 0;
3551 54644 : move16();
3552 : }
3553 :
3554 :
3555 634 : return bits;
3556 : }
3557 :
3558 378608 : Word16 tcx_res_Q_spec_ivas_fx(
3559 : Word32 *x_orig,
3560 : Word16 x_orig_e,
3561 : Word32 *x_Q,
3562 : Word16 x_Q_e,
3563 : Word16 L_frame,
3564 : Word16 sqGain,
3565 : Word16 sqGain_e,
3566 : Word16 *prm,
3567 : Word16 sqTargetBits,
3568 : Word16 bits,
3569 : Word16 sq_round,
3570 : const Word16 lf_deemph_factors[] /* 1Q14 */
3571 : )
3572 : {
3573 : Word16 i;
3574 : Word16 fac_m, fac_p;
3575 : Word32 tmp1, tmp2;
3576 : Word16 s, s2, lf_deemph_factor;
3577 : Word16 c;
3578 : Word32 thres;
3579 : Word16 cmp_1, cmp_2;
3580 : Word32 tmp32_1, tmp32_2;
3581 :
3582 : /* Limit the number of residual bits */
3583 378608 : sqTargetBits = s_min( sqTargetBits, NPRM_RESQ );
3584 :
3585 : /* Requantize the spectrum line-by-line */
3586 378608 : fac_m = shr( sq_round, 1 );
3587 378608 : fac_p = sub( 0x4000, fac_m );
3588 :
3589 : /* exponent difference of x_orig and x_Q * sqGain */
3590 378608 : s = sub( x_orig_e, add( x_Q_e, sqGain_e ) );
3591 :
3592 378608 : lf_deemph_factor = 0x4000;
3593 378608 : move16();
3594 378608 : s2 = sub( x_Q_e, 1 );
3595 :
3596 378608 : cmp_1 = sub( sqTargetBits, kMaxEstimatorUndershoot );
3597 378608 : cmp_2 = s_min( NPRM_RESQ, add( sqTargetBits, kMaxEstimatorOvershoot ) );
3598 19134155 : FOR( i = 0; i < L_frame; i++ )
3599 : {
3600 19117123 : IF( GE_16( bits, cmp_1 ) )
3601 : {
3602 5390993 : fac_m = 0;
3603 5390993 : move16();
3604 5390993 : fac_p = 0;
3605 5390993 : move16();
3606 :
3607 5390993 : IF( GE_16( bits, cmp_2 ) )
3608 : {
3609 361576 : BREAK;
3610 : }
3611 : }
3612 :
3613 18755547 : test();
3614 18755547 : test();
3615 18755547 : IF( ( x_Q[i] != 0 ) && ( ( lf_deemph_factors == NULL ) || ( GT_16( lf_deemph_factors[i], 0x2000 ) ) ) )
3616 : {
3617 3817485 : tmp1 = L_add( x_orig[i], 0 );
3618 3817485 : tmp2 = Mpy_32_16_1( x_Q[i], sqGain );
3619 3817485 : if ( s > 0 )
3620 : {
3621 567 : tmp2 = L_shr( tmp2, s );
3622 : }
3623 3817485 : if ( s < 0 )
3624 : {
3625 3816576 : tmp1 = L_shl( tmp1, s );
3626 : }
3627 :
3628 3817485 : if ( lf_deemph_factors != NULL )
3629 : {
3630 925746 : lf_deemph_factor = lf_deemph_factors[i];
3631 925746 : move16();
3632 : }
3633 :
3634 3817485 : IF( LT_32( tmp1, tmp2 ) )
3635 : {
3636 1906951 : prm[bits] = 0;
3637 1906951 : move16();
3638 1906951 : bits = add( bits, 1 );
3639 :
3640 1906951 : if ( x_Q[i] > 0 )
3641 : {
3642 950033 : tmp1 = L_mult( fac_m, lf_deemph_factor );
3643 : }
3644 1906951 : if ( x_Q[i] < 0 )
3645 : {
3646 956918 : tmp1 = L_mult( fac_p, lf_deemph_factor );
3647 : }
3648 1906951 : x_Q[i] = L_sub( x_Q[i], L_shr( tmp1, s2 ) );
3649 1906951 : move32();
3650 : }
3651 : ELSE
3652 : {
3653 1910534 : prm[bits] = 1;
3654 1910534 : move16();
3655 1910534 : bits = add( bits, 1 );
3656 :
3657 1910534 : if ( x_Q[i] > 0 )
3658 : {
3659 967456 : tmp1 = L_mult( fac_p, lf_deemph_factor );
3660 : }
3661 1910534 : if ( x_Q[i] < 0 )
3662 : {
3663 943078 : tmp1 = L_mult( fac_m, lf_deemph_factor );
3664 : }
3665 1910534 : x_Q[i] = L_add( x_Q[i], L_shr( tmp1, s2 ) );
3666 1910534 : move32();
3667 : }
3668 : }
3669 : }
3670 :
3671 : /*Quantize zeroed-line of the spectrum*/
3672 378608 : c = sub( 21627 /*0.66f Q15*/, mult_r( sq_round, 21627 /*0.66f Q15*/ ) );
3673 :
3674 1021170 : FOR( i = 0; ( i < L_frame ) && ( bits < ( sqTargetBits - 2 ) ); i++ )
3675 : {
3676 :
3677 642562 : test();
3678 642562 : test();
3679 642562 : IF( ( x_Q[i] == 0 ) && ( ( lf_deemph_factors == NULL ) || ( GT_16( lf_deemph_factors[i], 0x2000 ) ) ) )
3680 : {
3681 466543 : if ( lf_deemph_factors != NULL )
3682 : {
3683 328312 : lf_deemph_factor = lf_deemph_factors[i];
3684 328312 : move16();
3685 : }
3686 :
3687 466543 : thres = L_mult( c, lf_deemph_factor ); // Q31
3688 466543 : Word16 shift_tmp = s_max( sqGain_e, x_orig_e );
3689 :
3690 466543 : tmp1 = Mpy_32_16_1( thres, sqGain );
3691 :
3692 466543 : tmp32_1 = L_shl( x_orig[i], sub( x_orig_e, shift_tmp ) );
3693 466543 : tmp32_2 = L_shl( tmp1, sub( sqGain_e, shift_tmp ) );
3694 466543 : IF( GT_32( tmp32_1, tmp32_2 ) )
3695 : {
3696 90381 : prm[bits] = 1;
3697 90381 : move16();
3698 90381 : bits = add( bits, 1 );
3699 :
3700 90381 : prm[bits] = 1;
3701 90381 : move16();
3702 90381 : bits = add( bits, 1 );
3703 :
3704 90381 : x_Q[i] = L_shl( thres, sub( 1, x_Q_e ) );
3705 90381 : move32();
3706 : }
3707 376162 : ELSE IF( L_add( tmp32_1, tmp32_2 ) < 0 )
3708 : {
3709 90761 : prm[bits] = 1;
3710 90761 : move16();
3711 90761 : bits = add( bits, 1 );
3712 :
3713 90761 : prm[bits] = 0;
3714 90761 : move16();
3715 90761 : bits = add( bits, 1 );
3716 :
3717 90761 : x_Q[i] = L_shl( L_negate( thres ), sub( 1, x_Q_e ) );
3718 90761 : move32();
3719 : }
3720 : ELSE
3721 : {
3722 285401 : prm[bits] = 0;
3723 285401 : move16();
3724 285401 : bits = add( bits, 1 );
3725 : }
3726 : }
3727 : }
3728 :
3729 : /*Be sure that every possible bits are initialized*/
3730 32638414 : FOR( i = bits; i < NPRM_RESQ; i++ )
3731 : {
3732 32259806 : prm[i] = 0;
3733 32259806 : move16();
3734 : }
3735 :
3736 378608 : return bits;
3737 : }
3738 :
3739 634 : void ProcessIGF_fx(
3740 : IGF_ENC_INSTANCE_HANDLE const hInstance, /**< in: instance handle of IGF Encoder */
3741 : Encoder_State *st, /**< in: Encoder state */
3742 : Word32 pMDCTSpectrum[], /**< in: MDCT spectrum */
3743 : Word16 *pMDCTSpectrum_e,
3744 : Word32 pPowerSpectrum[], /**< in: MDCT^2 + MDST^2 spectrum, or estimate */
3745 : Word16 *pPowerSpectrum_e,
3746 : Word16 isTCX20, /**< in: flag indicating if the input is TCX20 or TCX10/2xTCX5 */
3747 : Word16 isTNSActive, /**< in: flag indicating if the TNS is active */
3748 : Word16 isTransition, /**< in: flag indicating if the input is the transition from from ACELP to TCX20/TCX10 */
3749 : Word16 frameno /**< in: flag indicating index of current subframe */
3750 : )
3751 : {
3752 : Word16 igfGridIdx;
3753 : Word16 isIndepFlag;
3754 : Word16 bsBits;
3755 : Word16 pBsStart;
3756 634 : BSTR_ENC_HANDLE hBstr = st->hBstr;
3757 634 : IGF_ENC_INSTANCE_HANDLE hIGFEnc = st->hIGFEnc;
3758 :
3759 :
3760 634 : isIndepFlag = 1;
3761 634 : move16();
3762 634 : test();
3763 634 : IF( isTransition && isTCX20 )
3764 : {
3765 38 : igfGridIdx = IGF_GRID_LB_TRAN;
3766 38 : move16();
3767 : }
3768 : ELSE
3769 : {
3770 596 : IF( isTCX20 )
3771 : {
3772 596 : igfGridIdx = IGF_GRID_LB_NORM;
3773 596 : move16();
3774 : }
3775 : ELSE
3776 : {
3777 : /* It is short block */
3778 0 : igfGridIdx = IGF_GRID_LB_SHORT;
3779 0 : move16();
3780 0 : if ( EQ_16( frameno, 1 ) )
3781 : {
3782 0 : isIndepFlag = 0;
3783 0 : move16();
3784 : }
3785 : }
3786 : }
3787 :
3788 :
3789 634 : IGFEncApplyMono_fx( hInstance, /**< in: instance handle of IGF Encoder */
3790 : igfGridIdx, /**< in: IGF grid index */
3791 : st, /**< in: Encoder state */
3792 : pMDCTSpectrum, /**< in: MDCT spectrum */
3793 634 : *pMDCTSpectrum_e,
3794 : pPowerSpectrum, /**< in: MDCT^2 + MDST^2 spectrum, or estimate */
3795 634 : *pPowerSpectrum_e,
3796 : isTCX20, /**< in: flag indicating if the input is TCX20 or TCX10/2xTCX5 */
3797 : isTNSActive, /**< in: flag indicating if the TNS is active */
3798 634 : ( st->last_core == ACELP_CORE ) );
3799 : {
3800 634 : const Word32 tns_predictionGain = st->hIGFEnc->tns_predictionGain;
3801 634 : const Word16 startLine = st->hIGFEnc->infoStartLine;
3802 634 : const Word16 endLine = st->hIGFEnc->infoStopLine;
3803 634 : const Word16 maxOrder = 8;
3804 634 : const Word32 *spec_before = st->hIGFEnc->spec_be_igf;
3805 634 : Word16 curr_order = 0;
3806 : Word16 A[ITF_MAX_FILTER_ORDER + 1];
3807 : Word16 Q_A;
3808 634 : Word16 predictionGain = 0;
3809 634 : Word16 *flatteningTrigger = &( st->hIGFEnc->flatteningTrigger );
3810 :
3811 :
3812 634 : move32();
3813 634 : move16();
3814 634 : move16();
3815 634 : move16();
3816 634 : move32();
3817 634 : move16();
3818 634 : move16();
3819 :
3820 634 : ITF_Detect_fx( spec_before, startLine, endLine, maxOrder, A, &Q_A, &predictionGain, &curr_order, shl( st->hIGFEnc->spec_be_igf_e, 1 ) );
3821 634 : *flatteningTrigger = 0;
3822 634 : move16();
3823 634 : test();
3824 634 : IF( LT_32( tns_predictionGain, 9646899l /*1.15 Q23*/ ) &&
3825 : LT_16( predictionGain, 147 /*1.15 Q7*/ ) )
3826 : {
3827 564 : *flatteningTrigger = 1;
3828 564 : move16();
3829 : }
3830 : }
3831 :
3832 634 : move16();
3833 634 : hInstance->infoTotalBitsPerFrameWritten = 0;
3834 634 : move16();
3835 634 : IF( isTCX20 )
3836 : {
3837 634 : IGFEncWriteBitstream_fx( hInstance, NULL, &hInstance->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag );
3838 : }
3839 : ELSE
3840 : {
3841 0 : pBsStart = hBstr->nb_ind_tot;
3842 0 : move16();
3843 :
3844 0 : IGFEncWriteBitstream_ivas_fx( hIGFEnc, hBstr, &hIGFEnc->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag );
3845 :
3846 0 : bsBits = sub( hBstr->nb_ind_tot, pBsStart );
3847 0 : IGFEncConcatenateBitstream_ivas_fx( hIGFEnc, bsBits, hBstr );
3848 : }
3849 634 : }
3850 :
3851 0 : void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum )
3852 : {
3853 : Word16 i, length, att;
3854 :
3855 0 : length = idiv1616U( L_frame, 20 );
3856 :
3857 0 : att = 21627 /*0.66f Q15*/;
3858 0 : move16();
3859 0 : if ( EQ_16( length, 8 ) )
3860 : {
3861 0 : att = 19661 /*0.6f Q15*/;
3862 0 : move16();
3863 : }
3864 :
3865 0 : spectrum += sub( L_frame, length );
3866 0 : FOR( i = 0; i < length; i++ )
3867 : {
3868 0 : spectrum[i] = Mpy_32_16_1( spectrum[i], att );
3869 0 : move32();
3870 0 : att = mult_r( att, att );
3871 : }
3872 0 : }
3873 :
3874 : /*---------------------------------------------------------------------*
3875 : * ProcessIGF_ivas_fx()
3876 : *
3877 : *
3878 : *---------------------------------------------------------------------*/
3879 510753 : void ProcessIGF_ivas_fx(
3880 : Encoder_State *st, /* i : Encoder state */
3881 : Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */
3882 : Word32 *pMDCTSpectrum, /* i : MDCT spectrum (*q_spectrum) */
3883 : Word16 *q_spectrum, /* i/o: Q of spectrum */
3884 : const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */
3885 : const Word16 q_ITFMDCTSpectrum, /* i : Q of MDCT spectrum fir ITF */
3886 : Word32 *pPowerSpectrum, /* i : MDCT^2 + MDST^2 spectrum, or estimate (*q_powerSpec) */
3887 : Word16 *exp_powerSpec, /* i/o: Q of power spectrum */
3888 : const Word16 isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */
3889 : const Word16 frameno, /* i : flag indicating index of current subframe */
3890 : const Word16 sp_aud_decision0, /* i : first stage switching decision */
3891 : const Word16 vad_hover_flag /* i : VAD hangover flag */
3892 : )
3893 : {
3894 : Word16 igfGridIdx, isIndepFlag, bsBits, pBsStart, curr_order;
3895 : Word16 predictionGain;
3896 : Word16 A[ITF_MAX_FILTER_ORDER + 1];
3897 : Word16 q_A;
3898 :
3899 510753 : IGF_ENC_INSTANCE_HANDLE hIGFEnc = st->hIGFEnc;
3900 510753 : BSTR_ENC_HANDLE hBstr = st->hBstr;
3901 :
3902 510753 : isIndepFlag = 1;
3903 510753 : move16();
3904 510753 : test();
3905 510753 : IF( st->last_core == ACELP_CORE && isTCX20 )
3906 : {
3907 8528 : igfGridIdx = IGF_GRID_LB_TRAN;
3908 8528 : move16();
3909 : }
3910 502225 : ELSE IF( isTCX20 )
3911 : {
3912 483111 : igfGridIdx = IGF_GRID_LB_NORM;
3913 483111 : move16();
3914 : }
3915 : ELSE
3916 : {
3917 : /* It is short block */
3918 19114 : igfGridIdx = IGF_GRID_LB_SHORT;
3919 19114 : move16();
3920 19114 : if ( EQ_16( frameno, 1 ) )
3921 : {
3922 9608 : isIndepFlag = 0;
3923 9608 : move16();
3924 : }
3925 : }
3926 :
3927 510753 : IGFSaveSpectrumForITF_ivas_fx( hIGFEnc, igfGridIdx, pITFMDCTSpectrum, sub( Q31, q_ITFMDCTSpectrum ) );
3928 :
3929 510753 : IGFEncApplyMono_ivas_fx( st, powerSpec_len, igfGridIdx, pMDCTSpectrum, sub( Q31, *q_spectrum ), pPowerSpectrum, exp_powerSpec, isTCX20, st->hTcxEnc->fUseTns[frameno], sp_aud_decision0, vad_hover_flag );
3930 :
3931 510753 : curr_order = 0;
3932 510753 : move16();
3933 510753 : predictionGain = 0;
3934 510753 : move16();
3935 510753 : q_A = 0;
3936 510753 : move16();
3937 :
3938 510753 : ITF_Detect_ivas_fx( hIGFEnc->spec_be_igf, hIGFEnc->infoStartLine, hIGFEnc->infoStopLine, 8 /*maxOrder*/, A, &q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc->spec_be_igf_e ) );
3939 :
3940 510753 : test();
3941 510753 : IF( LT_16( hIGFEnc->tns_predictionGain, ONE_POINT_ONE_FIVE_Q7 ) && LT_16( predictionGain, ONE_POINT_ONE_FIVE_Q7 ) )
3942 : {
3943 491808 : hIGFEnc->flatteningTrigger = 1;
3944 491808 : move16();
3945 : }
3946 : ELSE
3947 : {
3948 18945 : hIGFEnc->flatteningTrigger = 0;
3949 18945 : move16();
3950 : }
3951 :
3952 510753 : hIGFEnc->infoTotalBitsPerFrameWritten = 0;
3953 510753 : move16();
3954 :
3955 510753 : IF( isTCX20 )
3956 : {
3957 491639 : IGFEncWriteBitstream_ivas_fx( hIGFEnc, NULL, &hIGFEnc->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag );
3958 : }
3959 : ELSE
3960 : {
3961 19114 : pBsStart = hBstr->nb_ind_tot;
3962 19114 : move16();
3963 :
3964 19114 : IGFEncWriteBitstream_ivas_fx( hIGFEnc, hBstr, &hIGFEnc->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag );
3965 :
3966 19114 : bsBits = sub( hBstr->nb_ind_tot, pBsStart );
3967 19114 : IGFEncConcatenateBitstream_ivas_fx( hIGFEnc, bsBits, hBstr );
3968 : }
3969 :
3970 510753 : return;
3971 : }
3972 :
3973 : /*---------------------------------------------------------------------*
3974 : * ProcessStereoIGF()
3975 : *
3976 : *
3977 : *---------------------------------------------------------------------*/
3978 :
3979 51473 : void ProcessStereoIGF_fx(
3980 : STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct,
3981 : Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */
3982 : Word16 ms_mask[2][MAX_SFB], /* i : bandwise MS mask */
3983 : Word32 *pITFMDCTSpectrum_fx[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */
3984 : Word16 q_pITFMDCTSpectrum_1,
3985 : Word16 q_pITFMDCTSpectrum_2,
3986 : Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */
3987 : Word16 *exp_pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrum_fx */
3988 : Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */
3989 : Word16 *q_pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i/o: Q of pPowerSpectrumMsInv_fx */
3990 : Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */
3991 : Word16 exp_inv_spectrum_fx[CPE_CHANNELS], /* i/o: exp of inv_spectrum_fx */
3992 : const Word16 frameno, /* i : flag indicating index of current subfr. */
3993 : const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */
3994 : const Word32 element_brate, /* i : element bitrate */
3995 : const Word16 mct_on )
3996 : {
3997 : Word16 ch, igfGridIdx, isIndepFlag, bsBits, pBsStart, curr_order;
3998 : Word16 predictionGain;
3999 : Word16 A[ITF_MAX_FILTER_ORDER + 1];
4000 : Word16 Q_A;
4001 : IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS];
4002 : BSTR_ENC_HANDLE hBstr;
4003 51473 : hIGFEnc[0] = sts[0]->hIGFEnc;
4004 51473 : hIGFEnc[1] = sts[1]->hIGFEnc;
4005 :
4006 51473 : isIndepFlag = 1;
4007 51473 : move16();
4008 :
4009 51473 : test();
4010 51473 : IF( sts[0]->last_core == ACELP_CORE && EQ_16( sts[0]->core, TCX_20_CORE ) )
4011 : {
4012 0 : igfGridIdx = IGF_GRID_LB_TRAN;
4013 : }
4014 51473 : ELSE IF( EQ_16( sts[0]->core, TCX_20_CORE ) )
4015 : {
4016 49266 : igfGridIdx = IGF_GRID_LB_NORM;
4017 : }
4018 : ELSE
4019 : {
4020 : /* It is short block */
4021 2207 : igfGridIdx = IGF_GRID_LB_SHORT;
4022 2207 : if ( EQ_16( frameno, 1 ) )
4023 : {
4024 1078 : isIndepFlag = 0;
4025 1078 : move16();
4026 : }
4027 : }
4028 51473 : move16();
4029 :
4030 51473 : IGFSaveSpectrumForITF_ivas_fx( hIGFEnc[0], igfGridIdx, pITFMDCTSpectrum_fx[0][frameno], sub( Q31, q_pITFMDCTSpectrum_1 ) );
4031 :
4032 51473 : IGFSaveSpectrumForITF_ivas_fx( hIGFEnc[1], igfGridIdx, pITFMDCTSpectrum_fx[1][frameno], sub( Q31, q_pITFMDCTSpectrum_2 ) );
4033 :
4034 :
4035 51473 : IGFEncApplyStereo_fx( hStereoMdct, ms_mask, hIGFEnc, igfGridIdx, sts, pPowerSpectrum_fx, exp_pPowerSpectrum_fx, pPowerSpectrumMsInv_fx, q_pPowerSpectrumMsInv_fx,
4036 : inv_spectrum_fx, exp_inv_spectrum_fx, frameno, sp_aud_decision0, element_brate, mct_on );
4037 :
4038 154419 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
4039 : {
4040 102946 : curr_order = 0;
4041 102946 : move16();
4042 :
4043 102946 : Q_A = 0;
4044 102946 : move16();
4045 :
4046 102946 : predictionGain = 0;
4047 102946 : move16();
4048 :
4049 102946 : ITF_Detect_ivas_fx( hIGFEnc[ch]->spec_be_igf, hIGFEnc[ch]->infoStartLine, hIGFEnc[ch]->infoStopLine, 8 /*maxOrder*/, A, &Q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc[ch]->spec_be_igf_e ) );
4050 :
4051 102946 : test();
4052 102946 : hIGFEnc[ch]->flatteningTrigger = LT_16( hIGFEnc[ch]->tns_predictionGain, ONE_POINT_ONE_FIVE_Q7 ) && LT_16( predictionGain, ONE_POINT_ONE_FIVE_Q7 );
4053 102946 : move16();
4054 :
4055 102946 : hIGFEnc[ch]->infoTotalBitsPerFrameWritten = 0;
4056 102946 : move16();
4057 :
4058 102946 : IF( EQ_16( sts[ch]->core, TCX_20_CORE ) )
4059 : {
4060 98532 : IGFEncWriteBitstream_ivas_fx( hIGFEnc[ch], NULL, &hIGFEnc[ch]->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag );
4061 : }
4062 : ELSE
4063 : {
4064 4414 : hBstr = sts[ch]->hBstr;
4065 4414 : pBsStart = hBstr->nb_ind_tot;
4066 4414 : move16();
4067 :
4068 4414 : if ( ch > 0 )
4069 : {
4070 2207 : hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
4071 : }
4072 4414 : IGFEncWriteBitstream_ivas_fx( hIGFEnc[ch], hBstr, &hIGFEnc[ch]->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag );
4073 :
4074 4414 : bsBits = sub( hBstr->nb_ind_tot, pBsStart );
4075 4414 : IGFEncConcatenateBitstream_ivas_fx( hIGFEnc[ch], bsBits, hBstr );
4076 : }
4077 : }
4078 51473 : return;
4079 : }
|