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