Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include <assert.h>
7 : #include "options.h"
8 : #include "cnst.h"
9 : #include "prot_fx.h" /* Function prototypes */
10 : #include "prot_fx_enc.h" /* Function prototypes */
11 : #include "basop_util.h"
12 : #include "rom_com.h"
13 :
14 :
15 : /*-------------------------------------------------------------------*
16 : * Local constants
17 : *-------------------------------------------------------------------*/
18 :
19 : #define kMaxNumHeapElems 10
20 : #define LOG2_E 23637 /*1.44269504089f Q14*/
21 :
22 : typedef struct HeapElem
23 : {
24 : Word32 mScore; /* Sort key */
25 : Word16 mIndex; /* Original index */
26 : } HeapElem;
27 :
28 : typedef struct Heap
29 : {
30 : HeapElem mElem[2 * kMaxNumHeapElems + 1];
31 : Word16 mSize;
32 : } Heap;
33 :
34 : /*-------------------------------------------------------------------*
35 : * tcx_arith_estimate_scale()
36 : *
37 : *
38 : * Returns: estimated SQ scale Q15-e
39 : *-------------------------------------------------------------------*/
40 17425 : static Word16 tcx_arith_estimate_scale(
41 : const Word32 abs_spectrum[], /* i: absolute MDCT coefficients Q31-e */
42 : const Word16 abs_spectrum_e, /* i: MDCT exponent Q0 */
43 : const Word16 L_frame, /* i: number of spectral lines Q0 */
44 : const Word16 envelope[], /* i: scaled envelope Q15-e */
45 : const Word16 envelope_e, /* i: scaled envelope exponent Q0 */
46 : Word16 *scale_e /* o: scale exponent Q0 */
47 : )
48 : {
49 : Word16 scale, tmp, k, s, s1;
50 : Word32 L_tmp, accu;
51 : #ifndef ISSUE_1867_replace_overflow_libenc
52 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
53 : Flag Overflow = 0;
54 : move32();
55 : #endif
56 : #endif
57 :
58 :
59 : /* compute normalised standard deviation and determine approximate scale */
60 17425 : accu = L_deposit_l( 0 );
61 17425 : s = 30;
62 17425 : move16();
63 :
64 11014225 : FOR( k = 0; k < L_frame; k++ )
65 : {
66 : /* tmp = abs_spectrum[k] * envelope[k];
67 : scale += tmp * tmp; */
68 :
69 : /* normalize, multiply, square */
70 10996800 : s1 = 30;
71 10996800 : move16();
72 10996800 : if ( abs_spectrum[k] != 0 )
73 : {
74 3635541 : s1 = norm_l( abs_spectrum[k] );
75 : }
76 :
77 : #ifdef ISSUE_1867_replace_overflow_libenc
78 10996800 : tmp = mult_r( round_fx_sat( L_shl( abs_spectrum[k], s1 ) ), envelope[k] );
79 : #else
80 : tmp = mult_r( round_fx_o( L_shl( abs_spectrum[k], s1 ), &Overflow ), envelope[k] );
81 : #endif
82 10996800 : L_tmp = L_mult0( tmp, tmp );
83 10996800 : tmp = sub( shl( s1, 1 ), 1 );
84 :
85 : /* adjust accu scaling */
86 10996800 : s1 = s;
87 10996800 : move16();
88 10996800 : if ( L_and( accu, 0x40000000 ) != 0 )
89 20 : s = sub( s, 1 );
90 10996800 : s = s_min( s, tmp );
91 :
92 10996800 : s1 = sub( s1, s );
93 10996800 : if ( s1 != 0 )
94 55910 : accu = L_shr( accu, s1 );
95 :
96 : /* scale and accumulate */
97 : BASOP_SATURATE_WARNING_OFF_EVS;
98 10996800 : accu = L_add_sat( accu, L_shr( L_tmp, sub( tmp, s ) ) );
99 : BASOP_SATURATE_WARNING_ON_EVS;
100 : }
101 17425 : s = sub( shl( add( abs_spectrum_e, envelope_e ), 1 ), s );
102 17425 : if ( accu == 0 )
103 0 : accu = L_deposit_l( 1 );
104 :
105 : /* scale = (float)sqrt((L_frame * 65536.0f*65536.0f*4.0f) / scale); */
106 17425 : scale = BASOP_Util_Divide3216_Scale( accu, shl( L_frame, 2 ), &tmp );
107 17425 : s = sub( add( s, tmp ), 15 );
108 17425 : scale = ISqrt16( scale, &s );
109 17425 : *scale_e = s;
110 :
111 17425 : return scale;
112 : }
113 :
114 : /*-------------------------------------------------------------------*
115 : * MinHeapify_i()
116 : *
117 : *
118 : *-------------------------------------------------------------------*/
119 691004 : static void MinHeapify_i( Heap *H, Word16 i )
120 : {
121 : Word16 left, right, largest;
122 : HeapElem T;
123 :
124 691004 : left = add( shl( i, 1 ), 1 );
125 691004 : right = add( left, 1 );
126 691004 : largest = i;
127 691004 : move16();
128 :
129 691004 : if ( LT_32( H->mElem[left].mScore, H->mElem[largest].mScore ) )
130 : {
131 597224 : largest = left;
132 597224 : move16();
133 : }
134 :
135 691004 : if ( LT_32( H->mElem[right].mScore, H->mElem[largest].mScore ) )
136 : {
137 223181 : largest = right;
138 223181 : move16();
139 : }
140 :
141 2067432 : WHILE( NE_16( largest, i ) )
142 : {
143 1376428 : T.mIndex = H->mElem[i].mIndex;
144 1376428 : move16();
145 1376428 : T.mScore = L_add( H->mElem[i].mScore, 0 );
146 :
147 1376428 : H->mElem[i].mIndex = H->mElem[largest].mIndex;
148 1376428 : move16();
149 1376428 : H->mElem[i].mScore = H->mElem[largest].mScore;
150 1376428 : move32();
151 :
152 1376428 : H->mElem[largest].mIndex = T.mIndex;
153 1376428 : move16();
154 1376428 : H->mElem[largest].mScore = T.mScore;
155 1376428 : move32();
156 :
157 1376428 : i = largest;
158 1376428 : move16();
159 :
160 1376428 : left = add( shl( i, 1 ), 1 );
161 1376428 : right = add( left, 1 );
162 :
163 1376428 : if ( LT_32( H->mElem[left].mScore, H->mElem[largest].mScore ) )
164 : {
165 631230 : largest = left;
166 631230 : move16();
167 : }
168 :
169 1376428 : if ( LT_32( H->mElem[right].mScore, H->mElem[largest].mScore ) )
170 : {
171 293300 : largest = right;
172 293300 : move16();
173 : }
174 : }
175 691004 : }
176 : /*-------------------------------------------------------------------*
177 : * tcx_arith_find_max_scale()
178 : *
179 : *
180 : *-------------------------------------------------------------------*/
181 17425 : static Word16 tcx_arith_find_max_scale( /* Q15-e */
182 : const Word32 abs_spectrum[], /* i: absolute MDCT coefficients Q31-e */
183 : const Word16 abs_spectrum_e, /* i: MDCT exponent Q0 */
184 : const Word16 L_frame, /* i: number of spectral lines Q0 */
185 : const Word16 envelope[], /* i: scaled envelope Q15-e */
186 : const Word16 envelope_e, /* i: scaled envelope exponent Q0 */
187 : const Word16 exps[], /* i: expfp(-(int)envelope[]/2) Q15 */
188 : const Word16 deadzone, /* i: deadzone (0.5f = no deadzone) Q15 */
189 : Word16 *scale_e /* o: scale exponent Q0 */
190 : )
191 : {
192 : Word16 i, k, q, scale, tmp, s;
193 : Word32 p, L_tmp;
194 17425 : Heap heap = { { { 0, 0 } }, 0 }; /* silence a compiler warning */
195 : Word16 tmpi1, tmpi2;
196 17425 : const Word32 limit = -325614240l /*-9.70406052784f Q25*/; /* = ln(1/16384): log of smallest allowed probability */
197 17425 : move32();
198 : /* Find the top most offending lines according to probability estimates */
199 191675 : FOR( i = 0; i < kMaxNumHeapElems; i++ )
200 : {
201 174250 : heap.mElem[i].mIndex = 0;
202 174250 : move16();
203 174250 : heap.mElem[i].mScore = L_deposit_l( 0 );
204 174250 : move32();
205 : }
206 :
207 17425 : tmp = add( shl( kMaxNumHeapElems, 1 ), 1 );
208 209100 : FOR( ; i < tmp; i++ )
209 : {
210 191675 : heap.mElem[i].mScore = L_deposit_h( 0x7FFF );
211 191675 : move32();
212 : }
213 :
214 11014225 : FOR( k = 0; k < L_frame; k++ )
215 : {
216 10996800 : p = Mpy_32_16_1( abs_spectrum[k], envelope[k] );
217 :
218 10996800 : IF( GT_32( p, heap.mElem[0].mScore ) )
219 : {
220 691004 : heap.mElem[0].mScore = p;
221 691004 : move32();
222 691004 : heap.mElem[0].mIndex = k;
223 691004 : move16();
224 691004 : MinHeapify_i( &heap, 0 );
225 : }
226 : }
227 :
228 : /* Make sure the scale is limited so that the offending lines don't cause probability underflow. */
229 : /* Also limit scale to avoiding saturation of the gain quantizer */
230 : /* scale = 1.0f/(float)sqrt(L_frame*0.5f); */
231 17425 : tmp = 15 - 1;
232 17425 : scale = ISqrt16( L_frame, &tmp );
233 17425 : move16();
234 17425 : *scale_e = tmp;
235 17425 : move16();
236 :
237 191675 : FOR( i = 0; i < kMaxNumHeapElems; i++ )
238 : {
239 174250 : k = heap.mElem[i].mIndex;
240 174250 : move16();
241 :
242 : /* Get approximate maximum allowed magnitude */
243 : /* q = (int)ceil(((limit - log(1.0f - (exps[k]/65536.0) * (exps[k]/65536.0))) / (-(int)envelope[k]/2/65536.0) - 1) / 2.0f); */
244 174250 : L_tmp = L_sub( 0x7FFFFFFF, L_mult( exps[k], exps[k] ) );
245 174250 : L_tmp = Mpy_32_16_1( BASOP_Util_Log2( L_tmp ), 22713 ); /* Q25; 22713 -> 1/log2(e) */
246 174250 : L_tmp = L_sub( limit, L_tmp );
247 174250 : tmp = negate( BASOP_Util_Divide3216_Scale( L_tmp, envelope[k], &s ) );
248 174250 : s = sub( add( s, 6 ), sub( envelope_e, 1 ) );
249 174250 : L_tmp = L_shl( L_deposit_h( tmp ), sub( s, 15 + 1 ) ); /* Q16 */
250 174250 : L_tmp = L_sub( L_tmp, 0x8000 );
251 174250 : q = extract_h( L_add( L_tmp, 0xFFFF ) ); /* ceil */
252 :
253 : /* Refinement: get the exact q */
254 174250 : powfp_odd2( exps[k], q, &tmpi1, &tmpi2 );
255 :
256 174250 : IF( GE_16( sub( tmpi1, tmpi2 ), 2 ) ) /* q may be too low */
257 : {
258 174200 : powfp_odd2( exps[k], add( q, 1 ), &tmpi1, &tmpi2 );
259 :
260 197325 : WHILE( GE_16( sub( tmpi1, tmpi2 ), 2 ) )
261 : {
262 23125 : q = add( q, 1 );
263 23125 : powfp_odd2( exps[k], add( q, 1 ), &tmpi1, &tmpi2 );
264 : }
265 : }
266 : ELSE /* q is too high */
267 : {
268 50 : q = sub( q, 1 );
269 50 : powfp_odd2( exps[k], q, &tmpi1, &tmpi2 );
270 :
271 50 : WHILE( LT_16( sub( tmpi1, tmpi2 ), 2 ) )
272 : {
273 0 : q = sub( q, 1 );
274 0 : powfp_odd2( exps[k], q, &tmpi1, &tmpi2 );
275 : }
276 : }
277 :
278 : /* Find the largest scale so that the quantized magnitude is at most q */
279 : /* p = (q+0.99f-deadzone)/(abs_spectrum[k] + 0.000001f); */
280 174250 : L_tmp = L_add( L_deposit_h( q ), L_mult( sub( 32440 /*0.99f Q15*/, deadzone ), 1 ) ); /* Q16 */
281 174250 : tmp = BASOP_Util_Divide3232_Scale( L_tmp, L_add( abs_spectrum[k], 1 ), &s );
282 174250 : s = sub( add( s, 15 ), abs_spectrum_e );
283 :
284 174250 : k = norm_s( tmp );
285 174250 : tmp = shl( tmp, k );
286 174250 : s = sub( s, k );
287 :
288 : /* assert((int)(abs_spectrum[k] * p + deadzone) <= q); */
289 :
290 : /* scale = min(scale, p); */
291 174250 : IF( compMantExp16Unorm( tmp, s, scale, *scale_e ) < 0 )
292 : {
293 54755 : scale = tmp;
294 54755 : move16();
295 54755 : *scale_e = s;
296 54755 : move16();
297 : }
298 : }
299 :
300 :
301 17425 : return scale;
302 : }
303 : /*-------------------------------------------------------------------*
304 : * tcx_arith_find_kMax()
305 : *
306 : *
307 : * Returns: index of highest freq. nonzero line (-1 if all zeros)
308 : *-------------------------------------------------------------------*/
309 285581 : static Word16 tcx_arith_find_kMax(
310 : const Word32 abs_spectrum[], /* i: absolute MDCT coefficients Q31-e */
311 : const Word16 abs_spectrum_e, /* i: MDCT exponent Q0 */
312 : const Word16 L_frame, /* i: number of spectral lines Q0 */
313 : const Word16 scale, /* i: scalar quantizer scale Q15-e */
314 : const Word16 scale_e, /* i: scale exponent Q0 */
315 : const Word16 deadzone, /* i: deadzone (0.5f = no deadzone) Q15 */
316 : const Word8 deadzone_flags[] /* i: line-wise deadzone control */
317 : )
318 : {
319 : Word16 kMax;
320 : Word32 tmp[2];
321 :
322 :
323 285581 : move32();
324 285581 : move32();
325 285581 : tmp[0] = L_shr( L_mac( 0x7FFFFFFF, deadzone, (Word16) 0x8000 ), abs_spectrum_e ); /* 1.0f - deadzone scaled to MDCT exponent */
326 285581 : tmp[1] = L_shr( 0x7FFFFFFF, abs_spectrum_e ); /* 1.0f scaled to MDCT exponent */
327 :
328 144431985 : FOR( kMax = sub( L_frame, 1 ); kMax >= 0; kMax-- )
329 : {
330 144430995 : IF( GE_32( L_shl( Mpy_32_16_1( abs_spectrum[kMax], scale ), scale_e ), tmp[deadzone_flags[kMax]] ) )
331 : {
332 284591 : BREAK;
333 : }
334 : }
335 :
336 :
337 285581 : return kMax;
338 : }
339 :
340 : /*-------------------------------------------------------------------*
341 : * tcx_arith_rateloop()
342 : *
343 : *
344 : * Returns: best scale Q15-e
345 : *-------------------------------------------------------------------*/
346 17425 : static Word16 tcx_arith_rateloop(
347 : const Word32 abs_spectrum[], /* i: absolute MDCT coefficients Q31-e */
348 : const Word16 abs_spectrum_e, /* i: MDCT exponent Q0 */
349 : const Word16 L_frame, /* i: number of spectral lines Q0 */
350 : const Word16 envelope[], /* i: scaled envelope Q15-e */
351 : const Word16 envelope_e, /* i: scaled envelope exponent Q0 */
352 : const Word16 exps[], /* i: expfp(-(int)envelope[]/2) Q15 */
353 : const Word16 target_bits, /* i: target bit budget Q0 */
354 : const Word16 deadzone, /* i: deadzone (0.5f = no deadzone) Q15 */
355 : const Word8 deadzone_flags[], /* i: line-wise deadzone control Q0 */
356 : Word16 *target_bits_fac, /* i/o: scale estimator compensation Q14 */
357 : Word16 *scale_e /* o: scale exponent Q0 */
358 : )
359 : {
360 : Word16 k, kMax, q;
361 : Word16 s, adjust;
362 : Word16 fixed_bits[2][N_MAX_ARI];
363 : Word32 max_complexity;
364 : Word16 iter; /* rate loop iteration counter */
365 : Word16 scale; /* SQ scale factor to try next */
366 : Word16 scale_best; /* best SQ scale factor */
367 : Word16 scale_max; /* maximum allowable scale factor */
368 : Word16 lob; /* lower bound of SQ scale factor */
369 : Word16 hib; /* upper bound of SQ scale factor */
370 : Word16 flag; /* 1:bit surplus, -1:bit deficit, 0:unknown */
371 : Word32 complexity; /* cumulative rate loop complexity */
372 : Word32 bits; /* number of bits (approximate) Q9 */
373 : Word32 L_tmp;
374 : Word16 tmp, tmp3;
375 : Word32 tmp2;
376 : #ifndef ISSUE_1867_replace_overflow_libenc
377 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
378 : Flag Overflow = 0;
379 : move32();
380 : #endif
381 : #endif
382 :
383 :
384 17425 : scale = tcx_arith_estimate_scale( abs_spectrum, abs_spectrum_e, L_frame, envelope, envelope_e, &tmp );
385 17425 : scale = mult_r( scale, *target_bits_fac );
386 17425 : tmp = add( tmp, 1 );
387 :
388 17425 : scale_max = tcx_arith_find_max_scale( abs_spectrum, abs_spectrum_e, L_frame, envelope, envelope_e, exps, deadzone, scale_e );
389 :
390 17425 : scale = shl_sat( scale, sub( tmp, *scale_e ) );
391 17425 : scale = s_min( scale, scale_max );
392 :
393 17425 : scale_best = scale;
394 17425 : move16();
395 17425 : lob = 0;
396 17425 : move16();
397 17425 : hib = 0;
398 17425 : move16();
399 17425 : flag = 0;
400 17425 : move16();
401 17425 : complexity = L_deposit_l( 0 );
402 17425 : bits = L_deposit_l( 0 );
403 17425 : iter = 0;
404 17425 : move16();
405 :
406 17425 : max_complexity = L_mult0( 96, L_frame );
407 :
408 : /* Precalculate fixed bit costs */
409 11014225 : FOR( k = 0; k < L_frame; k++ )
410 : {
411 : /* fixed_bits[0][k] = -log2f(1 - exps[k] / 65536.0f); */
412 10996800 : L_tmp = L_mac( 0x7FFFFFFF, exps[k], (Word16) 0x8000 ); /* Q31 */
413 10996800 : L_tmp = L_negate( BASOP_Util_Log2( L_tmp ) ); /* Q25 */
414 10996800 : fixed_bits[0][k] = round_fx( L_tmp ); /* Q9 */
415 10996800 : move16();
416 : /* fixed_bits[1][k] = 1 - s*0.5f*LOG2_E - log2f(1 - (exps[k]/65536.0f) * (exps[k]/65536.0f)); */
417 10996800 : L_tmp = L_msu( 0x7FFFFFFF, exps[k], exps[k] ); /* Q31 */
418 10996800 : L_tmp = BASOP_Util_Log2( L_tmp ); /* Q25 */
419 10996800 : L_tmp = L_sub( 1 << 25, L_tmp );
420 10996800 : L_tmp = L_sub( L_tmp, L_shl( L_mult0( mult_r( envelope[k], LOG2_E ), 1 << 10 ), envelope_e ) );
421 10996800 : fixed_bits[1][k] = round_fx( L_tmp ); /* Q9 */
422 10996800 : move16();
423 : }
424 :
425 17425 : tmp2 = L_msu0( L_sub( max_complexity, 48 ), L_frame, 11 );
426 285581 : WHILE( LT_32( complexity, tmp2 ) )
427 : {
428 268156 : kMax = tcx_arith_find_kMax( abs_spectrum, abs_spectrum_e, L_frame, scale, *scale_e, deadzone, deadzone_flags );
429 :
430 268156 : complexity = L_mac0( L_mac0( L_add( complexity, 16 + 2 ), sub( L_frame, kMax ), 5 ), kMax, 2 );
431 :
432 268156 : bits = /*estimator_undershoot * kMax +*/ L_deposit_l( 1 << 9 ); /* Q9 */
433 :
434 268156 : L_tmp = L_mult( deadzone, 1 ); /* Q16 */
435 268156 : tmp = add( sub( abs_spectrum_e, 15 ), *scale_e );
436 268156 : tmp3 = add( 2 + 9, envelope_e );
437 34773724 : FOR( k = 0; k <= kMax; k++ )
438 : {
439 34505568 : q = extract_h( L_add( L_shl( Mpy_32_16_1( abs_spectrum[k], scale ), tmp ), L_tmp ) );
440 34505568 : bits = L_mac0( bits, fixed_bits[s_min( 1, q )][k], 1 ); /* Q9 */
441 34505568 : bits = L_mac0( bits, round_fx( L_shl( L_mult0( mult_r( envelope[k], LOG2_E ), q ), tmp3 ) ), 1 );
442 : }
443 268156 : complexity = L_mac0( L_add( complexity, 32 ), 6, kMax );
444 :
445 268156 : IF( iter == 0 ) /* First rate loop iteration */
446 : {
447 17425 : IF( LT_16( scale, scale_max ) ) /* Only update in non-degenerate case */
448 : {
449 : /* Update estimator temporal compensation factor */
450 4925 : tmp = BASOP_Util_Divide3232_Scale( L_mult0( target_bits, 1 << 9 ), bits, &s );
451 4925 : tmp = shl_sat( mult_r( *target_bits_fac, tmp ), s );
452 4925 : tmp = s_min( tmp, 20480 /*1.25f Q14*/ );
453 4925 : tmp = s_max( tmp, 12288 /*0.75f Q14*/ );
454 4925 : *target_bits_fac = tmp;
455 4925 : move16();
456 : }
457 : }
458 :
459 268156 : IF( LE_32( bits, L_mult0( target_bits, 1 << 9 ) ) ) /* Bits leftover => scale is too small */
460 : {
461 158463 : test();
462 158463 : IF( flag <= 0 || GE_16( scale, scale_best ) )
463 : {
464 158463 : scale_best = scale;
465 158463 : move16();
466 158463 : flag = 1;
467 158463 : move16();
468 : }
469 :
470 158463 : lob = scale;
471 158463 : move16();
472 :
473 158463 : IF( hib > 0 ) /* Bisection search */
474 : {
475 121942 : scale = add( shr( lob, 1 ), shr( hib, 1 ) );
476 : }
477 : ELSE /* Initial scale adaptation */
478 : {
479 : /* adjust = 1.25f * target_bits / (float)bits; */
480 36521 : tmp = BASOP_Util_Divide3232_Scale( L_mult0( target_bits, 0x280 ), bits, &s );
481 36521 : adjust = shl_sat( tmp, sub( s, 1 ) ); /* Q14 */
482 36521 : scale = shl_sat( mult_r( scale, adjust ), 1 );
483 36521 : scale = s_min( scale, scale_max );
484 : }
485 : }
486 : ELSE /* Ran out of bits => scale is too large */
487 : {
488 109693 : hib = scale;
489 109693 : move16();
490 :
491 109693 : IF( lob > 0 ) /* Bisection search */
492 : {
493 93881 : scale = add( shr( lob, 1 ), shr( hib, 1 ) );
494 : }
495 : ELSE
496 : { /* Initial scale adaptation */
497 : /* adjust = 0.8f * target_bits / (float)bits; */
498 15812 : tmp = BASOP_Util_Divide3232_Scale( L_mult0( target_bits, 0x19A ), bits, &s );
499 15812 : adjust = shl( tmp, s ); /* Q15 */
500 15812 : adjust = s_max( adjust, 16384 /*0.5f Q15*/ );
501 15812 : scale = mult_r( scale, adjust );
502 : }
503 :
504 109693 : IF( flag <= 0 )
505 : {
506 15812 : scale_best = scale;
507 15812 : move16();
508 15812 : flag = 0;
509 15812 : move16();
510 : }
511 : }
512 268156 : iter = add( iter, 1 );
513 : }
514 :
515 :
516 17425 : return scale_best;
517 : }
518 : /*-------------------------------------------------------------------*
519 : * tcx_arith_encode()
520 : *
521 : *
522 : * Returns: number of bits consumed
523 : *-------------------------------------------------------------------*/
524 17425 : static Word16 tcx_arith_encode(
525 : Word16 q_abs_spectrum[], /* i/o: scalar quantized absolute spectrum Q0 */
526 : const Word16 signs[], /* i: signs */
527 : const Word16 kMax, /* i: number of nonzero spectral lines to code Q0 */
528 : Word16 L_frame, /* i: nominal number of spectral lines Q0 */
529 : const Word16 exps[], /* i: expfp(-(int)envelope[]/2) Q15 */
530 : Word16 target_bits, /* i: target bit budget Q0 */
531 : Word16 prm[] /* o: bit-stream Q0 */
532 : )
533 : {
534 : TastatEnc as, as_lastgood;
535 : Word16 bp, bp_lastgood;
536 : Word16 k;
537 : Word16 kEncoded;
538 : Word16 tmpi1, tmpi2;
539 :
540 :
541 : /* Final coding */
542 17425 : ari_start_encoding_14bits_fx( &as );
543 17425 : ari_copy_states_fx( &as, &as_lastgood );
544 17425 : bp = 0;
545 17425 : move16();
546 17425 : bp_lastgood = 0;
547 17425 : move16();
548 17425 : kEncoded = kMax;
549 17425 : move16();
550 :
551 2227303 : FOR( k = 0; k <= kMax; k++ )
552 : {
553 2209948 : IF( q_abs_spectrum[k] == 0 )
554 : {
555 1705509 : assert( exps[k] >= 2 );
556 1705509 : bp = ari_encode_14bits_range_fx( prm, bp, target_bits, &as, shr( exps[k], 1 ), 16384 );
557 : }
558 : ELSE /* q_abs_spectrum[k] != 0 */
559 : {
560 504439 : powfp_odd2( exps[k], q_abs_spectrum[k], &tmpi1, &tmpi2 );
561 :
562 504439 : WHILE( LT_16( tmpi1, add( tmpi2, 2 ) ) )
563 : {
564 0 : q_abs_spectrum[k] = sub( q_abs_spectrum[k], 1 );
565 0 : move16();
566 0 : powfp_odd2( exps[k], q_abs_spectrum[k], &tmpi1, &tmpi2 );
567 : }
568 :
569 504439 : bp = ari_encode_14bits_range_fx( prm, bp, target_bits, &as, shr( tmpi2, 1 ), shr( tmpi1, 1 ) );
570 504439 : bp = ari_encode_14bits_sign_fx( prm, bp, target_bits, &as, signs[k] );
571 : }
572 : /* Check bit budget status */
573 2209948 : IF( ari_encode_overflow_fx( &as ) ) /* no bits left */
574 : {
575 : /* printf("\noverflow at %d\n\n", k); */
576 :
577 70 : IF( GT_16( q_abs_spectrum[k], 1 ) ) /* Lower magnitude is still > 0 */
578 : {
579 : /* Restore state */
580 10 : ari_copy_states_fx( &as_lastgood, &as );
581 10 : bp = bp_lastgood;
582 10 : move16();
583 :
584 : /* Quantize to lower magnitude */
585 10 : q_abs_spectrum[k] = sub( q_abs_spectrum[k], 1 );
586 10 : move16();
587 :
588 : /* Retry encoding */
589 10 : powfp_odd2( exps[k], q_abs_spectrum[k], &tmpi1, &tmpi2 );
590 :
591 10 : bp = ari_encode_14bits_range_fx( prm, bp, target_bits, &as, shr( tmpi2, 1 ), shr( tmpi1, 1 ) );
592 10 : bp = ari_encode_14bits_sign_fx( prm, bp, target_bits, &as, signs[k] );
593 :
594 10 : IF( !ari_encode_overflow_fx( &as ) ) /* Success */
595 : {
596 10 : ari_copy_states_fx( &as, &as_lastgood );
597 10 : bp_lastgood = bp;
598 10 : move16();
599 10 : kEncoded = k;
600 10 : move16();
601 :
602 10 : set16_fx( q_abs_spectrum + k + 1, 0, sub( kMax, k ) );
603 10 : BREAK;
604 : }
605 : }
606 60 : ari_copy_states_fx( &as_lastgood, &as );
607 60 : bp = bp_lastgood;
608 60 : move16();
609 60 : kEncoded = sub( k, 1 );
610 :
611 60 : set16_fx( q_abs_spectrum + k, 0, sub( kMax, kEncoded ) );
612 60 : BREAK;
613 : }
614 : ELSE
615 : {
616 2209878 : ari_copy_states_fx( &as, &as_lastgood );
617 2209878 : bp_lastgood = bp;
618 2209878 : move16();
619 : }
620 : }
621 :
622 : /* Send zeros until L_frame */
623 17425 : tmpi1 = add( kEncoded, 1 );
624 17425 : kEncoded = sub( L_frame, 1 );
625 8631084 : FOR( k = tmpi1; k < L_frame; k++ )
626 : {
627 8614088 : assert( exps[k] >= 1 );
628 :
629 8614088 : bp = ari_encode_14bits_range_fx( prm, bp, target_bits, &as, shr( exps[k], 1 ), 16384 );
630 : /* Check bit budget status */
631 8614088 : IF( ari_encode_overflow_fx( &as ) ) /* no bits left */
632 : {
633 429 : ari_copy_states_fx( &as_lastgood, &as );
634 429 : bp = bp_lastgood;
635 429 : move16();
636 429 : kEncoded = sub( k, 1 );
637 429 : BREAK;
638 : }
639 : ELSE
640 : {
641 8613659 : ari_copy_states_fx( &as, &as_lastgood );
642 8613659 : bp_lastgood = bp;
643 8613659 : move16();
644 : }
645 : }
646 :
647 17425 : IF( EQ_16( kEncoded, sub( L_frame, 1 ) ) ) /* RESQ bits possibly available */
648 : {
649 : /* Limit target bits to actually needed bits */
650 16996 : target_bits = add( add( bp, 16 ), extract_l( as.value ) );
651 : }
652 17425 : return ari_done_cbr_encoding_14bits_fx( prm, bp, target_bits, &as );
653 : }
654 : /*-------------------------------------------------------------------*
655 : * tcx_arith_encode_envelope_fx()
656 : *
657 : *
658 : *-------------------------------------------------------------------*/
659 0 : void tcx_arith_encode_envelope_fx(
660 : Word32 spectrum[], /* i/o: MDCT coefficients Q31-e */
661 : Word16 *spectrum_e, /* i/o: MDCT exponent Q0 */
662 : Word16 signs[], /* o: signs (spectrum[.]<0) Q0 */
663 : const Word16 L_frame, /* i: frame or MDCT length Q0 */
664 : const Word16 L_spec, /* i: frame or MDCT length Q0 */
665 : Encoder_State *st, /* i/o: coder state */
666 : const Word16 A_ind[], /* i: quantised LPC coefficients Q12 */
667 : Word16 target_bits, /* i: number of available bits Q0 */
668 : Word16 prm[], /* o: bitstream parameters Q0 */
669 : const Word8 use_hm, /* i: use HM in current frame? */
670 : Word16 prm_hm[], /* o: HM parameter area Q0 */
671 : const Word16 tcxltp_pitch, /* i: TCX LTP pitch in FD, -1 if n/a Q0*/
672 : Word16 *arith_bits, /* o: bits used for ari. coding Q0 */
673 : Word16 *signaling_bits, /* o: bits used for signaling Q0 */
674 : Word16 *nf_seed, /* o: noise filling seed Q0 */
675 : const Word16 low_complexity /* i: low-complexity flag Q0 */
676 : )
677 : {
678 : Word32 env[N_MAX_ARI]; /* unscaled envelope (Q16) */
679 : Word16 *envelope; /* scaled envelope (Q15-e) */
680 : Word16 envelope_e;
681 : Word16 exponents[N_MAX_ARI]; /* Q15 */
682 : Word16 L_spec_core;
683 : Word16 *q_spectrum;
684 : TCX_CONFIG_HANDLE hTcxCfg;
685 : Word16 scale, scale_e;
686 : Word16 k, kMax;
687 : Word16 deadzone;
688 : const Word8 *deadzone_flags;
689 : Word16 gamma_w, gamma_uw;
690 : Word16 hm_bits;
691 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
692 : Word32 L_tmp, L_tmp2;
693 : #else
694 : Word32 L_tmp;
695 : Word64 W_tmp2;
696 : #endif
697 : Word16 tmp;
698 0 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
699 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
700 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
701 : Flag Overflow = 0;
702 : Flag Carry = 0;
703 : move32();
704 : move32();
705 : #endif
706 : #endif
707 :
708 0 : assert( L_spec <= N_MAX_ARI );
709 :
710 0 : hTcxCfg = st->hTcxCfg;
711 0 : deadzone = hTcxCfg->sq_rounding;
712 0 : move16();
713 0 : deadzone_flags = hTcxEnc->memQuantZeros;
714 0 : *signaling_bits = 0;
715 0 : move16();
716 :
717 0 : assert( st->enableTcxLpc );
718 0 : gamma_w = 32767 /*1.0f Q15*/;
719 0 : move16();
720 0 : gamma_uw = st->inv_gamma;
721 0 : move16();
722 :
723 0 : tcx_arith_render_envelope( A_ind, L_frame, L_spec, hTcxCfg->preemph_fac, gamma_w, gamma_uw, env );
724 :
725 0 : FOR( k = 0; k < L_spec; k++ )
726 : {
727 0 : signs[k] = extract_l( L_lshr( spectrum[k], 31 ) );
728 0 : move16();
729 0 : if ( spectrum[k] < 0 )
730 : {
731 0 : spectrum[k] = L_abs( spectrum[k] );
732 0 : move32();
733 : }
734 : }
735 :
736 0 : IF( use_hm != 0 )
737 : {
738 0 : tcx_hm_analyse_fx( spectrum, spectrum_e, L_spec, env, target_bits, hTcxCfg->coder_type, prm_hm, tcxltp_pitch, hTcxEnc->tcxltp_gain, &hm_bits );
739 :
740 0 : target_bits = sub( target_bits, hm_bits );
741 0 : *signaling_bits = add( *signaling_bits, hm_bits );
742 0 : move16();
743 : }
744 : ELSE
745 : {
746 0 : prm_hm[0] = 0; /* just to be sure */
747 0 : move16();
748 0 : hm_bits = 0;
749 0 : move16();
750 : }
751 :
752 0 : L_spec_core = L_spec;
753 0 : move16();
754 0 : if ( st->igf )
755 : {
756 0 : L_spec_core = s_min( L_spec_core, st->hIGFEnc->infoStartLine );
757 : }
758 0 : envelope = (Word16 *) env;
759 :
760 0 : tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e );
761 :
762 0 : tmp = sub( envelope_e, 1 + 15 );
763 0 : FOR( k = 0; k < L_spec; k++ )
764 : {
765 0 : exponents[k] = round_fx( expfp( envelope[k], tmp ) );
766 0 : move16();
767 : }
768 :
769 0 : scale = tcx_arith_rateloop( spectrum, *spectrum_e, L_spec, envelope, envelope_e, exponents, target_bits, deadzone, deadzone_flags, &( hTcxEnc->tcx_target_bits_fac ), &scale_e );
770 :
771 : /* Final quantization */
772 0 : kMax = tcx_arith_find_kMax( spectrum, *spectrum_e, L_spec, scale, scale_e, deadzone, deadzone_flags );
773 :
774 0 : q_spectrum = (Word16 *) env; /* Reuse buffer */
775 :
776 0 : L_tmp = L_mult( deadzone, 1 ); /* Q16 */
777 0 : tmp = add( sub( *spectrum_e, 15 ), scale_e );
778 0 : FOR( k = 0; k <= kMax; k++ )
779 : {
780 : /* quantise using dead-zone */
781 0 : q_spectrum[k] = extract_h( L_add( L_shl( Mpy_32_16_1( spectrum[k], scale ), tmp ), L_tmp ) );
782 0 : move16();
783 : }
784 :
785 : /* Final encoding */
786 0 : *arith_bits = tcx_arith_encode( q_spectrum, signs, kMax, L_spec, exponents, target_bits, prm );
787 0 : move16();
788 :
789 : /* Multiply back the signs */
790 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
791 : L_tmp2 = L_deposit_l( 0 );
792 : #else
793 0 : W_tmp2 = 0;
794 : #endif
795 0 : FOR( k = 0; k <= kMax; k++ )
796 : {
797 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
798 : L_tmp2 = L_macNs_co( L_tmp2, q_spectrum[k], k, &Carry, &Overflow );
799 : #else
800 0 : W_tmp2 = W_mac_16_16( W_tmp2, q_spectrum[k], k );
801 : #endif
802 :
803 0 : if ( signs[k] != 0 )
804 0 : L_tmp = L_mult( q_spectrum[k], -( 1 << ( 30 - SPEC_EXP_DEC ) ) );
805 0 : if ( signs[k] == 0 )
806 0 : L_tmp = L_mult( q_spectrum[k], 1 << ( 30 - SPEC_EXP_DEC ) );
807 0 : spectrum[k] = L_tmp;
808 0 : move32();
809 : }
810 0 : *spectrum_e = SPEC_EXP_DEC;
811 0 : move16();
812 0 : set32_fx( spectrum + k, 0, sub( s_max( L_frame, L_spec ), k ) );
813 :
814 : /* noise filling seed */
815 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
816 : *nf_seed = extract_l( L_tmp2 );
817 : #else
818 0 : *nf_seed = extract_l( W_extract_l( W_tmp2 ) );
819 : #endif
820 0 : move16();
821 0 : }
822 :
823 17425 : void tcx_arith_encode_envelope_ivas_fx(
824 : Word32 spectrum[], /* i/o: MDCT coefficients Q31-e */
825 : Word16 *spectrum_e, /* i/o: MDCT exponent Q0 */
826 : Word16 signs[], /* o: signs (spectrum[.]<0) Q0 */
827 : const Word16 L_frame, /* i: frame or MDCT length Q0 */
828 : const Word16 L_spec, /* i: frame or MDCT length Q0 */
829 : Encoder_State *st, /* i/o: coder state */
830 : const Word16 A_ind[], /* i: quantised LPC coefficients Q12 */
831 : Word16 target_bits, /* i: number of available bits Q0 */
832 : Word16 prm[], /* o: bitstream parameters Q0 */
833 : const Word8 use_hm, /* i: use HM in current frame? */
834 : Word16 prm_hm[], /* o: HM parameter area Q0 */
835 : const Word16 tcxltp_pitch, /* i: TCX LTP pitch in FD, -1 if n/a Q0*/
836 : Word16 *arith_bits, /* o: bits used for ari. coding Q0 */
837 : Word16 *signaling_bits, /* o: bits used for signaling Q0 */
838 : const Word16 low_complexity /* i: low-complexity flag Q0 */
839 : )
840 : {
841 : Word32 env[N_MAX_ARI]; /* unscaled envelope (Q16) */
842 : Word16 *envelope; /* scaled envelope (Q15-e) */
843 : Word16 envelope_e;
844 : Word16 exponents[N_MAX_ARI]; /* Q15 */
845 : Word16 L_spec_core;
846 : Word16 *q_spectrum;
847 : TCX_CONFIG_HANDLE hTcxCfg;
848 : Word16 scale, scale_e;
849 : Word16 k, kMax;
850 : Word16 deadzone;
851 : const Word8 *deadzone_flags;
852 : Word16 gamma_w, gamma_uw;
853 : Word16 hm_bits;
854 : Word32 L_tmp;
855 : Word16 tmp;
856 17425 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
857 :
858 17425 : assert( L_spec <= N_MAX_ARI );
859 :
860 17425 : hTcxCfg = st->hTcxCfg;
861 17425 : deadzone = hTcxCfg->sq_rounding;
862 17425 : move16();
863 17425 : deadzone_flags = hTcxEnc->memQuantZeros;
864 17425 : *signaling_bits = 0;
865 17425 : move16();
866 :
867 17425 : assert( st->enableTcxLpc );
868 17425 : gamma_w = 32767 /*1.0f Q15*/;
869 17425 : move16();
870 17425 : gamma_uw = st->inv_gamma;
871 17425 : move16();
872 :
873 17425 : tcx_arith_render_envelope( A_ind, L_frame, L_spec, hTcxCfg->preemph_fac, gamma_w, gamma_uw, env );
874 :
875 11014225 : FOR( k = 0; k < L_spec; k++ )
876 : {
877 10996800 : signs[k] = extract_l( L_lshr( spectrum[k], 31 ) );
878 10996800 : move16();
879 10996800 : if ( spectrum[k] < 0 )
880 : {
881 1816350 : spectrum[k] = L_abs( spectrum[k] );
882 1816350 : move32();
883 : }
884 : }
885 :
886 17425 : IF( use_hm != 0 )
887 : {
888 15775 : tcx_hm_analyse_fx( spectrum, spectrum_e, L_spec, env, target_bits, hTcxCfg->coder_type, prm_hm, tcxltp_pitch, hTcxEnc->tcxltp_gain, &hm_bits );
889 :
890 15775 : target_bits = sub( target_bits, hm_bits );
891 15775 : *signaling_bits = add( *signaling_bits, hm_bits );
892 15775 : move16();
893 : }
894 : ELSE
895 : {
896 1650 : prm_hm[0] = 0; /* just to be sure */
897 1650 : move16();
898 1650 : hm_bits = 0;
899 1650 : move16();
900 : }
901 :
902 17425 : L_spec_core = L_spec;
903 17425 : move16();
904 17425 : if ( st->igf )
905 : {
906 17425 : L_spec_core = s_min( L_spec_core, st->hIGFEnc->infoStartLine );
907 : }
908 17425 : envelope = (Word16 *) env;
909 :
910 17425 : tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e );
911 :
912 17425 : tmp = sub( envelope_e, 1 + 15 );
913 11014225 : FOR( k = 0; k < L_spec; k++ )
914 : {
915 10996800 : exponents[k] = round_fx( expfp( envelope[k], tmp ) );
916 10996800 : move16();
917 : }
918 :
919 17425 : scale = tcx_arith_rateloop( spectrum, *spectrum_e, L_spec, envelope, envelope_e, exponents, target_bits, deadzone, deadzone_flags, &( hTcxEnc->tcx_target_bits_fac ), &scale_e );
920 :
921 : /* Final quantization */
922 17425 : kMax = tcx_arith_find_kMax( spectrum, *spectrum_e, L_spec, scale, scale_e, deadzone, deadzone_flags );
923 :
924 17425 : q_spectrum = (Word16 *) env; /* Reuse buffer */
925 :
926 17425 : L_tmp = L_mult( deadzone, 1 ); /* Q16 */
927 17425 : tmp = add( sub( *spectrum_e, 15 ), scale_e );
928 2227373 : FOR( k = 0; k <= kMax; k++ )
929 : {
930 : /* quantise using dead-zone */
931 2209948 : q_spectrum[k] = extract_h( L_add( L_shl( Mpy_32_16_1( spectrum[k], scale ), tmp ), L_tmp ) );
932 2209948 : move16();
933 : }
934 :
935 : /* Final encoding */
936 17425 : *arith_bits = tcx_arith_encode( q_spectrum, signs, kMax, L_spec, exponents, target_bits, prm );
937 17425 : move16();
938 :
939 : /* Multiply back the signs */
940 2227373 : FOR( k = 0; k <= kMax; k++ )
941 : {
942 2209948 : if ( signs[k] != 0 )
943 1071578 : L_tmp = L_mult( q_spectrum[k], -( 1 << ( 30 - SPEC_EXP_DEC ) ) );
944 2209948 : if ( signs[k] == 0 )
945 1138370 : L_tmp = L_mult( q_spectrum[k], 1 << ( 30 - SPEC_EXP_DEC ) );
946 2209948 : spectrum[k] = L_tmp;
947 2209948 : move32();
948 : }
949 17425 : *spectrum_e = SPEC_EXP_DEC;
950 17425 : move16();
951 17425 : set32_fx( spectrum + k, 0, sub( s_max( L_frame, L_spec ), k ) );
952 17425 : }
|