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