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