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