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 "options.h" /* Compilation switches */
7 : #include "cnst.h" /* Common constants */
8 : #include "rom_com.h" /* Static table prototypes */
9 : #include "prot_fx.h" /* Function prototypes */
10 : #include "ivas_prot_fx.h"
11 :
12 : /*-------------------------------------------------------------------*
13 : * Local prototypes
14 : *
15 : *-------------------------------------------------------------------*/
16 : static Word16 get_pvq_splits_fx( Decoder_State *st_fx, PVQ_DEC_HANDLE hPVQ, const Word16 band_bits, const Word16 sfmsize, Word16 *bits );
17 : static void densitySymbolIndexDecode_fx( Decoder_State *st_fx, PVQ_DEC_HANDLE hPVQ, const Word16 density, const Word16 opp_sz, const Word16 near_sz, Word16 *index_phi );
18 : /*-------------------------------------------------------------------*
19 : * pvq_decode_band()
20 : *
21 : *-------------------------------------------------------------------*/
22 270372 : static void pvq_decode_band_fx(
23 : Decoder_State *st_fx, /* i/o: Decoder state */
24 : PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */
25 : Word16 *pulse_vector, /* i/o: decoded integer shape vector */
26 : Word16 *npulses, /* i/o: number of pulses */
27 : Word16 *coefs_quant, /* i/o: decoded coefficients buffer Qx */
28 : const Word16 sfmsize, /* i : band length */
29 : const Word16 band_bits, /* i : assigned bit budget */
30 : Word16 *bits_left, /* i/o: number of bits / bits remaining */
31 : const Word16 strict_bits /* i : Conservative rounding flag */
32 : )
33 : {
34 :
35 : Word16 K_val;
36 :
37 : Word16 j, Np;
38 : Word16 part_start[MAX_SPLITS + 1], dim_part[MAX_SPLITS + 1], bits_part[MAX_SPLITS + 1];
39 : Word16 pool_tot, pool_part, dim_parts;
40 : Word16 g_part[MAX_SPLITS];
41 : Word16 g_part_neg[MAX_SPLITS];
42 : Word16 sg_part[MAX_SPLITS + 1];
43 : Word16 idx_sort[MAX_SPLITS + 1];
44 : Word16 js, band_bits_tot, split_bit;
45 :
46 270372 : Np = get_pvq_splits_fx( st_fx, hPVQ, band_bits, sfmsize, &split_bit );
47 270372 : band_bits_tot = sub( band_bits, split_bit );
48 :
49 270372 : dim_parts = extract_h( L_mult( negate( sfmsize ), lim_neg_inv_tbl_fx[Np] ) );
50 270372 : set16_fx( dim_part, dim_parts, sub( Np, 1 ) );
51 270372 : dim_part[Np - 1] = sub( sfmsize, i_mult2( dim_parts, sub( Np, 1 ) ) );
52 270372 : move16();
53 :
54 270372 : part_start[0] = 0;
55 270372 : move16();
56 300657 : FOR( j = 1; j < Np; j++ )
57 : {
58 30285 : part_start[j] = add( part_start[j - 1], dim_part[j - 1] );
59 30285 : move16();
60 : }
61 :
62 : /* Encode energies */
63 270372 : set16_fx( g_part_neg, -32768, Np );
64 270372 : IF( GT_16( Np, 1 ) )
65 : {
66 27046 : decode_energies_fx( st_fx, hPVQ, Np, dim_part, bits_part, g_part_neg, band_bits_tot, bits_left, sfmsize, strict_bits );
67 : }
68 : ELSE
69 : {
70 243326 : bits_part[0] = band_bits_tot;
71 243326 : move16();
72 : }
73 :
74 270372 : pool_tot = 0;
75 270372 : move16();
76 270372 : pool_part = 0;
77 270372 : move16();
78 : BASOP_SATURATE_WARNING_OFF_EVS
79 571029 : FOR( j = 0; j < Np; j++ )
80 : {
81 300657 : g_part[j] = negate( g_part_neg[j] );
82 300657 : move16();
83 : }
84 : BASOP_SATURATE_WARNING_ON_EVS
85 270372 : srt_vec_ind16_fx( g_part, sg_part, idx_sort, Np );
86 571029 : FOR( j = 0; j < Np; j++ )
87 : {
88 300657 : js = idx_sort[Np - 1 - j];
89 300657 : pool_part = shrtCDivSignedApprox( pool_tot, sub( Np, j ) );
90 300657 : bits_part[js] = s_max( 0, s_min( add( bits_part[js], pool_part ), 256 ) );
91 300657 : move16();
92 :
93 300657 : conservativeL1Norm_fx( dim_part[js], bits_part[js], strict_bits, *bits_left, pool_tot, *npulses, /* inputs */
94 : &K_val, bits_left, &pool_tot, npulses ); /* outputs */
95 :
96 300657 : IF( K_val > 0 )
97 : {
98 :
99 273683 : pvq_decode_fx( st_fx, hPVQ, coefs_quant + part_start[js], pulse_vector + part_start[js],
100 273683 : K_val, dim_part[js], g_part_neg[js] );
101 : }
102 : ELSE
103 : {
104 26974 : set16_fx( coefs_quant + part_start[js], 0, dim_part[js] );
105 26974 : set16_fx( pulse_vector + part_start[js], 0, dim_part[js] );
106 : }
107 : }
108 :
109 270372 : return;
110 : }
111 :
112 28288 : void pvq_decode_frame_fx(
113 : Decoder_State *st_fx,
114 : Word16 *coefs_quant, /* o : quantized coefficients Qx */
115 : Word16 *npulses, /* o : number of pulses per band */
116 : Word16 *pulse_vector, /* o : non-normalized pulse shapes */
117 : const Word16 *sfm_start, /* i : indices of first coefficients in the bands */
118 : const Word16 *sfm_end, /* i : indices of last coefficients in the bands */
119 : const Word16 *sfmsize, /* i : band sizes */
120 : const Word16 nb_sfm, /* i : total number of bands */
121 : const Word16 *R, /* i : bitallocation per band Q3 */
122 : const Word16 pvq_bits, /* i : number of bits avaiable */
123 : const Word16 core /* i : core */
124 : )
125 : {
126 : Word16 i, j;
127 : Word16 band_bits, bits_left;
128 28288 : Word16 bit_pool = 0;
129 : Word16 coded_bands, bands_to_code;
130 : Word16 bits;
131 : Word16 R_sort[NB_SFM];
132 : Word16 is, i_sort[NB_SFM];
133 : Word16 strict_bits;
134 : PVQ_DEC_DATA pvq_dec;
135 28288 : PVQ_DEC_HANDLE hPVQ = &pvq_dec;
136 28288 : move16();
137 :
138 28288 : rc_dec_init_fx( st_fx, hPVQ, pvq_bits );
139 :
140 28288 : bits = shl( sub( pvq_bits, RC_BITS_RESERVED ), 3 );
141 :
142 28288 : bands_to_code = 0;
143 28288 : move16();
144 437860 : FOR( i = 0; i < nb_sfm; i++ )
145 : {
146 409572 : if ( R[i] > 0 )
147 : {
148 270372 : bands_to_code = add( bands_to_code, 1 );
149 : }
150 : }
151 :
152 28288 : IF( core == ACELP_CORE )
153 : {
154 20560 : strict_bits = PVQ_CONS;
155 20560 : move16();
156 20560 : srt_vec_ind16_fx( R, R_sort, i_sort, nb_sfm );
157 : }
158 : ELSE
159 : {
160 7728 : strict_bits = PVQ_NEAREST;
161 7728 : move16();
162 270548 : FOR( i = 0; i < nb_sfm; i++ )
163 : {
164 262820 : i_sort[i] = i;
165 262820 : move16();
166 : }
167 : }
168 :
169 28288 : coded_bands = 0;
170 28288 : move16();
171 437860 : FOR( i = 0; i < nb_sfm; i++ )
172 : {
173 409572 : is = i_sort[i];
174 409572 : move16();
175 409572 : IF( R[is] > 0 )
176 : {
177 270372 : bandBitsAdjustment_fx( hPVQ->rc_num_bits, hPVQ->rc_range, bits, bands_to_code, sub( bands_to_code, coded_bands ), sfmsize[is], R[is], bit_pool, /* inputs */
178 : &band_bits, &bits_left, &bit_pool ); /* outputs */
179 :
180 270372 : pvq_decode_band_fx( st_fx, hPVQ, &pulse_vector[sfm_start[is]], &npulses[is],
181 270372 : &coefs_quant[sfm_start[is]], sfmsize[is], band_bits,
182 : &bits_left, strict_bits );
183 :
184 : /* Updates */
185 270372 : coded_bands = add( coded_bands, 1 );
186 : }
187 : ELSE
188 : {
189 3342706 : FOR( j = sfm_start[is]; j < sfm_end[is]; j++ )
190 : {
191 3203506 : coefs_quant[j] = 0;
192 3203506 : move16();
193 3203506 : pulse_vector[j] = 0;
194 3203506 : move16();
195 : }
196 : }
197 : }
198 :
199 28288 : rc_dec_finish_fx( st_fx, hPVQ );
200 28288 : }
201 :
202 : /*-------------------------------------------------------------------*
203 : * pvq_core_dec()
204 : *
205 : *-------------------------------------------------------------------*/
206 :
207 6102 : Word16 ivas_pvq_core_dec_fx(
208 : Decoder_State *st_fx,
209 : const Word16 *sfm_start,
210 : const Word16 *sfm_end,
211 : const Word16 *sfmsize,
212 : Word16 coefs_quant[], /* o : output MDCT, Q_coefs */
213 : Word16 *Q_coefs,
214 : Word16 bits_tot,
215 : Word16 nb_sfm,
216 : Word16 *R, /* Q3 */
217 : Word16 *Rs,
218 : Word16 *npulses,
219 : Word16 *maxpulse,
220 : const Word16 core )
221 : {
222 : Word16 i;
223 : Word16 R_upd;
224 : Word16 ord[NB_SFM_MAX];
225 : Word16 pulse_vector[L_SPEC48k_EXT];
226 : Word16 pvq_bits;
227 : Word16 gain_bits_array[NB_SFM];
228 : Word16 fg_pred[NB_SFM_MAX];
229 :
230 6102 : if ( st_fx->hHQ_core != NULL )
231 : {
232 6102 : st_fx->hHQ_core->ber_occured_in_pvq = 0;
233 6102 : move16();
234 : }
235 :
236 6102 : R_upd = shl( bits_tot, 3 ); // Q0 -> Q3
237 6102 : ivas_assign_gain_bits_fx( core, nb_sfm, sfmsize, R, gain_bits_array, &R_upd );
238 :
239 6102 : pvq_bits = shr( R_upd, 3 ); // Q3 -> Q0
240 :
241 6102 : pvq_decode_frame_fx( st_fx, coefs_quant, npulses, pulse_vector, sfm_start,
242 : sfm_end, sfmsize, nb_sfm, R, pvq_bits, core );
243 :
244 6102 : IF( Rs != NULL )
245 : {
246 251164 : FOR( i = 0; i < nb_sfm; i++ )
247 : {
248 245062 : IF( ( npulses[i] <= 0 ) )
249 : {
250 117939 : Rs[i] = 0;
251 117939 : move16(); /* Update Rs in case no pulses were assigned */
252 : }
253 : }
254 : }
255 :
256 251164 : FOR( i = 0; i < nb_sfm; i++ )
257 : {
258 245062 : ord[i] = i;
259 245062 : move16();
260 245062 : if ( ( npulses[i] <= 0 ) )
261 : {
262 117939 : R[i] = 0;
263 117939 : move16(); /* Update in case no pulses were assigned */
264 : }
265 : }
266 :
267 6102 : get_max_pulses_fx( sfm_start, sfm_end, ord, npulses, nb_sfm, pulse_vector, maxpulse );
268 :
269 6102 : ivas_fine_gain_pred_fx( sfm_start, sfm_end, sfmsize, ord, npulses, maxpulse, R,
270 : nb_sfm, coefs_quant, pulse_vector, fg_pred, core );
271 :
272 6102 : fine_gain_dec_fx( st_fx, ord, nb_sfm, gain_bits_array, fg_pred );
273 6102 : IF( st_fx->hHQ_core != NULL )
274 : {
275 6102 : IF( ( st_fx->hHQ_core->ber_occured_in_pvq != 0 ) )
276 : {
277 0 : set16_fx( fg_pred, 1, nb_sfm ); /* low complex ECU action in case of detetected BER in PVQ decoding */
278 : }
279 : }
280 6102 : apply_gain_fx( ord, sfm_start, sfm_end, nb_sfm, fg_pred, coefs_quant );
281 6102 : *Q_coefs = 12;
282 6102 : move16();
283 :
284 6102 : return bits_tot;
285 : }
286 :
287 20957 : Word16 pvq_core_dec_fx(
288 : Decoder_State *st_fx,
289 : const Word16 *sfm_start,
290 : const Word16 *sfm_end,
291 : const Word16 *sfmsize,
292 : Word16 coefs_quant[], /* o : output MDCT */
293 : Word16 *Q_coefs,
294 : Word16 bits_tot,
295 : Word16 nb_sfm,
296 : Word16 *R, /* Q3 */
297 : Word16 *Rs,
298 : Word16 *npulses,
299 : Word16 *maxpulse,
300 : const Word16 core )
301 : {
302 : Word16 i;
303 : Word16 R_upd;
304 : Word16 ord[NB_SFM_MAX];
305 : Word16 pulse_vector[L_FRAME48k];
306 : Word16 pvq_bits;
307 : Word16 gain_bits_array[NB_SFM];
308 : Word16 fg_pred[NB_SFM_MAX];
309 :
310 20957 : if ( st_fx->hHQ_core != NULL )
311 : {
312 20930 : st_fx->hHQ_core->ber_occured_in_pvq = 0;
313 20930 : move16();
314 : }
315 :
316 20957 : R_upd = shl( bits_tot, 3 ); // Q0 -> Q3
317 20957 : assign_gain_bits_fx( core, nb_sfm, sfmsize, R, gain_bits_array, &R_upd );
318 :
319 20957 : pvq_bits = shr( R_upd, 3 ); // Q3 -> Q0
320 :
321 20957 : pvq_decode_frame_fx( st_fx, coefs_quant, npulses, pulse_vector, sfm_start,
322 : sfm_end, sfmsize, nb_sfm, R, pvq_bits, core );
323 :
324 20957 : IF( Rs != NULL )
325 : {
326 15720 : FOR( i = 0; i < nb_sfm; i++ )
327 : {
328 15323 : if ( npulses[i] <= 0 )
329 : {
330 2308 : Rs[i] = 0;
331 2308 : move16(); /* Update Rs in case no pulses were assigned */
332 : }
333 : }
334 : }
335 :
336 183032 : FOR( i = 0; i < nb_sfm; i++ )
337 : {
338 162075 : ord[i] = i;
339 162075 : move16();
340 162075 : if ( npulses[i] <= 0 )
341 : {
342 48090 : R[i] = 0;
343 48090 : move16(); /* Update in case no pulses were assigned */
344 : }
345 : }
346 :
347 20957 : get_max_pulses_fx( sfm_start, sfm_end, ord, npulses, nb_sfm, pulse_vector, maxpulse );
348 :
349 20957 : fine_gain_pred_fx( sfm_start, sfm_end, sfmsize, ord, npulses, maxpulse, R,
350 : nb_sfm, coefs_quant, pulse_vector, fg_pred, core );
351 :
352 20957 : fine_gain_dec_fx( st_fx, ord, nb_sfm, gain_bits_array, fg_pred );
353 20957 : IF( st_fx->hHQ_core != NULL )
354 : {
355 20930 : IF( st_fx->hHQ_core->ber_occured_in_pvq != 0 )
356 : {
357 0 : set16_fx( fg_pred, 1, nb_sfm ); /* low complex ECU action in case of detetected BER in PVQ decoding */
358 : }
359 : }
360 20957 : apply_gain_fx( ord, sfm_start, sfm_end, nb_sfm, fg_pred, coefs_quant );
361 20957 : *Q_coefs = 12;
362 20957 : move16();
363 :
364 20957 : return bits_tot;
365 : }
366 :
367 : /*-------------------------------------------------------------------*
368 : * decode_energies()
369 : *
370 : *-------------------------------------------------------------------*/
371 30285 : void decode_energies_fx(
372 : Decoder_State *st_fx,
373 : PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */
374 : Word16 Np,
375 : Word16 *dim_part,
376 : Word16 *bits_part,
377 : Word16 *g_part, /* Q15 */
378 : Word16 qband,
379 : Word16 *bits_left,
380 : Word16 dim,
381 : const Word16 strict_bits )
382 : {
383 : Word16 density;
384 : Word16 i, l_Np, r_Np;
385 : Word16 l_bits, r_bits, l_dim, r_dim;
386 : Word16 il, ir;
387 : Word16 oppRQ3, qzero;
388 : Word16 l_gain, r_gain;
389 30285 : Word16 index_phi = -1;
390 30285 : move16();
391 :
392 30285 : l_Np = shr( Np, 1 );
393 30285 : r_Np = sub( Np, l_Np );
394 :
395 30285 : l_bits = 0;
396 30285 : move16();
397 30285 : l_dim = 0;
398 30285 : move16();
399 60814 : FOR( i = 0; i < l_Np; i++ )
400 : {
401 30529 : l_dim = add( l_dim, dim_part[i] );
402 : }
403 30285 : r_dim = sub( dim, l_dim );
404 :
405 30285 : obtainEnergyQuantizerDensity_fx( dim, qband, &density );
406 30285 : rangeCoderFinalizationFBits_fx( hPVQ->rc_num_bits, hPVQ->rc_range, &qzero );
407 :
408 30285 : densitySymbolIndexDecode_fx( st_fx, hPVQ, density, r_dim, l_dim, &index_phi );
409 30285 : densityAngle2RmsProjDec_fx( density, index_phi, &ir, &il, &oppRQ3 );
410 :
411 :
412 30285 : l_gain = il; /* Q15 */
413 30285 : move16();
414 30285 : r_gain = ir; /* Q15 */
415 30285 : move16();
416 :
417 60814 : FOR( i = 0; i < l_Np; i++ )
418 : {
419 30529 : g_part[i] = mult_r( l_gain, g_part[i] );
420 30529 : move16();
421 : }
422 :
423 63624 : FOR( i = l_Np; i < Np; i++ )
424 : {
425 33339 : g_part[i] = mult_r( r_gain, g_part[i] );
426 33339 : move16();
427 : }
428 :
429 30285 : NearOppSplitAdjustment_fx( qband, qzero, hPVQ->rc_num_bits, hPVQ->rc_range, *bits_left,
430 30285 : strict_bits, Np, dim_part[0], dim_part[Np - 1],
431 : l_dim, r_dim, oppRQ3,
432 : &l_bits, &r_bits, bits_left );
433 :
434 :
435 30285 : IF( GT_16( l_Np, 1 ) )
436 : {
437 237 : decode_energies_fx( st_fx, hPVQ, l_Np, dim_part, bits_part, g_part, l_bits, bits_left, l_dim, strict_bits );
438 : }
439 : ELSE
440 : {
441 30048 : bits_part[0] = l_bits;
442 30048 : move16();
443 : }
444 :
445 30285 : IF( GT_16( r_Np, 1 ) )
446 : {
447 3002 : decode_energies_fx( st_fx, hPVQ, r_Np, &dim_part[l_Np], &bits_part[l_Np], &g_part[l_Np], r_bits, bits_left, r_dim, strict_bits );
448 : }
449 : ELSE
450 : {
451 27283 : bits_part[1] = r_bits;
452 27283 : move16();
453 : }
454 :
455 30285 : return;
456 : }
457 :
458 : /*-------------------------------------------------------------------*
459 : * densitySymbolIndexDecode()
460 : *
461 : *-------------------------------------------------------------------*/
462 30285 : static void densitySymbolIndexDecode_fx(
463 : Decoder_State *st_fx,
464 : PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */
465 : const Word16 density,
466 : const Word16 opp_sz,
467 : const Word16 near_sz,
468 : Word16 *index_phi )
469 : {
470 : Word16 density1, density2;
471 : Word32 tmp1;
472 : Word16 tmp2;
473 : Word16 c, density_alpha, density_c;
474 : Word32 sym_freq, cum_freq, tot, dec_freq;
475 : Word16 angle, expo, r;
476 : UWord16 lsb;
477 : Word32 acc;
478 30285 : Word16 alpha = 0;
479 30285 : move16();
480 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
481 30285 : Flag Overflow = 0;
482 30285 : move16();
483 : #endif
484 30285 : IF( s_and( (Word16) 0xFFFE, density ) == 0 )
485 : {
486 : /* odd density exit */
487 157 : *index_phi = -1;
488 157 : move16();
489 157 : return;
490 : }
491 :
492 30128 : sym_freq = L_deposit_l( 1 );
493 :
494 30128 : angle = atan2_fx( SQRT_DIM_fx[opp_sz], SQRT_DIM_fx[near_sz] ); // Q13
495 30128 : angle = shl_o( angle, 1, &Overflow );
496 30128 : angle = mult_r( angle, 20861 );
497 30128 : c = mult_r( density, angle );
498 30128 : density_c = sub( density, c );
499 :
500 30128 : tot = L_mac0( 1L, density, add( density, 1 ) );
501 30128 : IF( c == 0 )
502 : {
503 0 : dec_freq = rc_decode_fx( &st_fx->BER_detect, hPVQ, tot );
504 :
505 0 : density1 = add( density, 1 );
506 0 : acc = L_mult0( density1, density1 );
507 0 : acc = L_sub( acc, dec_freq );
508 0 : alpha = add( getSqrtWord32( acc ), density1 );
509 0 : sym_freq = L_mac( 1L, sub( density, alpha ), 1 );
510 0 : cum_freq = L_mac0( L_mult( alpha, density ), alpha, 1 );
511 : }
512 30128 : ELSE IF( EQ_16( c, density ) )
513 : {
514 0 : dec_freq = rc_decode_fx( &st_fx->BER_detect, hPVQ, tot );
515 :
516 0 : alpha = getSqrtWord32( dec_freq );
517 0 : sym_freq = L_add( L_shl( alpha, 1 ), 1 );
518 0 : cum_freq = L_mult0( alpha, alpha );
519 : }
520 : ELSE
521 : {
522 30128 : acc = L_mult0( density, c );
523 30128 : Mpy_32_16_ss( acc, density_c, &acc, &lsb );
524 30128 : acc = L_or( L_shl( acc, 16 ), L_and( lsb, 0xffffL ) ); /* Concatenate acc and lsb forming 48 bits; upshift 16 bits; keep 32 MSB. */
525 30128 : acc = L_shr( acc, 1 ); /* Compensate fractional mode multiply (Mpy_32_16_ss) */
526 30128 : tot = L_add( L_add( acc, L_deposit_l( density ) ), 1L );
527 :
528 30128 : dec_freq = rc_decode_fx( &st_fx->BER_detect, hPVQ, tot );
529 :
530 30128 : acc = L_mult0( sub( density_c, 1 ), density_c );
531 30128 : Mpy_32_16_ss( acc, c, &acc, &lsb );
532 30128 : acc = L_or( L_shl( acc, 16 ), L_and( lsb, 0xffffL ) ); /* Concatenate acc and lsb forming 48 bits; upshift 16 bits; keep 32 MSB. */
533 30128 : acc = L_shr( acc, 1 ); /* Compensate fractional mode multiply (Mpy_32_16_ss) */
534 30128 : acc = L_add( acc, L_add( density, 1 ) );
535 30128 : acc = L_sub( acc, L_add( c, 1 ) );
536 30128 : acc = L_sub( tot, acc );
537 30128 : IF( LT_32( dec_freq, acc ) )
538 : {
539 17207 : acc = L_add( (Word32) density_c, L_shl( dec_freq, 2 ) );
540 17207 : acc = L_sub( acc, 2 );
541 17207 : Mpy_32_16_ss( acc, density_c, &acc, &lsb );
542 17207 : acc = L_or( L_shl( acc, 16 ), L_and( lsb, 0xffffL ) ); /* Concatenate acc and lsb forming 48 bits; upshift 16 bits; keep 32 MSB. */
543 17207 : acc = L_shr( acc, 1 ); /* Compensate fractional mode multiply (Mpy_32_16_ss) */
544 17207 : acc = L_add( acc, 1 );
545 17207 : tmp2 = getSqrtWord32( acc );
546 17207 : acc = L_add( density_c, tmp2 );
547 17207 : acc = L_sub( acc, 1 );
548 17207 : r = ratio( acc, L_shl( density_c, 1 ), &expo );
549 17207 : alpha = shr( r, add( 14, expo ) );
550 :
551 17207 : acc = L_mult( alpha, density_c );
552 17207 : sym_freq = L_add( acc, 1 );
553 17207 : acc = L_mult0( sub( alpha, 1 ), density_c );
554 17207 : acc = L_add( acc, 1 );
555 17207 : cum_freq = L_mult0( alpha, extract_l( acc ) );
556 : }
557 : ELSE
558 : {
559 12921 : density1 = add( density, 1 );
560 12921 : density2 = add( shl( density, 1 ), 1 );
561 :
562 12921 : acc = L_mult0( density, density1 );
563 12921 : Mpy_32_16_ss( acc, c, &acc, &lsb );
564 12921 : acc = L_or( L_shl( acc, 16 ), L_and( lsb, 0xffffL ) ); /* Concatenate acc and lsb forming 48-bit; upshift 16 bits; keep 32 MSB. */
565 12921 : acc = L_shr( acc, 1 ); /* Compensate fractional mode multiply (Mpy_32_16_ss) */
566 12921 : acc = L_add( density1, acc );
567 12921 : acc = L_add( dec_freq, acc );
568 12921 : acc = L_sub( tot, acc );
569 12921 : Mpy_32_16_ss( acc, c, &acc, &lsb );
570 12921 : acc = L_or( L_shl( acc, 16 ), L_and( lsb, 0xffffL ) );
571 12921 : acc = L_shr( acc, 1 - 2 );
572 :
573 12921 : tmp2 = extract_l( L_mac0( 1L, c, density2 ) );
574 12921 : tmp1 = L_mult0( tmp2, tmp2 );
575 12921 : tmp1 = L_add( tmp1, acc );
576 12921 : tmp2 = getSqrtWord32( tmp1 ); /* floor */
577 12921 : IF( L_msu0( tmp1, tmp2, tmp2 ) != 0 )
578 : {
579 12440 : tmp2 = add( tmp2, 1 ); /* convert to ceil */
580 : }
581 :
582 12921 : acc = L_mult0( c, density2 );
583 12921 : acc = L_add( acc, 1 );
584 12921 : acc = L_sub( acc, tmp2 );
585 12921 : r = ratio( acc, L_shl( c, 1 ), &expo );
586 12921 : alpha = shr( r, add( 14, expo ) );
587 :
588 12921 : density_alpha = sub( density, alpha );
589 12921 : sym_freq = L_mac( 1L, density_alpha, c );
590 12921 : acc = L_mult0( density_alpha, add( density_alpha, 1 ) );
591 12921 : Mpy_32_16_ss( acc, c, &acc, &lsb );
592 12921 : acc = L_or( L_shl( acc, 16 ), L_and( lsb, 0xffffL ) ); /* Concatenate acc and lsb forming 48-bit; upshift 16 bits; keep 32 MSB. */
593 12921 : acc = L_shr( acc, 1 ); /* Compensate fractional mode multiply (Mpy_32_16_ss) */
594 12921 : acc = L_sub( acc, alpha );
595 12921 : acc = L_add( acc, density1 );
596 12921 : cum_freq = L_sub( tot, acc );
597 : }
598 : }
599 :
600 30128 : rc_dec_update_fx( st_fx, hPVQ, cum_freq, sym_freq );
601 30128 : *index_phi = alpha;
602 30128 : move16();
603 30128 : return;
604 : }
605 :
606 :
607 : /*--------------------------------------------------------------------------*
608 : * get_pvq_splits()
609 : *
610 : * Retrieve the number of segments
611 : *--------------------------------------------------------------------------*/
612 :
613 270372 : static Word16 get_pvq_splits_fx( /* o : Number of segments */
614 : Decoder_State *st_fx, /* i/o: Decoder state */
615 : PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */
616 : const Word16 band_bits, /* i : Band bit budget */
617 : const Word16 sfmsize, /* i : Band width */
618 : Word16 *bits /* o : Used bits */
619 : )
620 : {
621 : Word16 Np, i;
622 : Word32 acc, flag;
623 :
624 270372 : IF( band_bits == 0 )
625 : {
626 92 : Np = 1;
627 92 : move16();
628 : }
629 : ELSE
630 : {
631 270280 : acc = L_mult0( band_bits, 0x7a44 );
632 270280 : Np = extract_l( L_shr( acc, 23 ) ); /* Get integer part. */
633 270280 : if ( L_and( acc, 0x7fffffL ) != 0 ) /* If fractional part != 0, add 1. */
634 : {
635 270280 : Np = add( Np, 1 ); /* ceiling operation */
636 : }
637 : }
638 270372 : *bits = 0;
639 270372 : move16();
640 270372 : IF( LT_16( Np, MAX_SPLITS ) )
641 : {
642 270372 : acc = L_mult0( 8 * THR_ADD_SPLIT, sfmsize );
643 270372 : IF( GT_32( band_bits, acc ) )
644 : {
645 70 : flag = rc_dec_bits_fx( st_fx, hPVQ, 1 );
646 70 : *bits = 8;
647 70 : move16();
648 70 : if ( flag != 0 )
649 : {
650 16 : Np = add( Np, 1 );
651 : }
652 : }
653 : }
654 : /* Check constraints for number of splits */
655 : /* The following code assumes that PVQ_MAX_BAND_SIZE is 64 */
656 270372 : i = shr( sfmsize, 6 ); /* 6 = log2(64) = log2(PVQ_MAX_BAND_SIZE) */
657 270372 : if ( s_and( sfmsize, 0x3f ) != 0 )
658 : {
659 270372 : i = add( i, 1 ); /* ceiling operation */
660 : }
661 :
662 270372 : Np = s_max( i, Np );
663 270372 : Np = s_min( MAX_SPLITS, Np );
664 270372 : Np = s_min( sfmsize, Np ); /* The code line assumes that MIN_BAND_SIZE is 1 */
665 270372 : return Np;
666 : }
|