LCOV - code coverage report
Current view: top level - lib_dec - pvq_core_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 4c82f1d24d39d0296b18d775f18a006f4c7d024b Lines: 276 289 95.5 %
Date: 2025-05-17 01:59:02 Functions: 7 7 100.0 %

          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             : }

Generated by: LCOV version 1.14