LCOV - code coverage report
Current view: top level - lib_com - hvq_pvq_bitalloc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 4c82f1d24d39d0296b18d775f18a006f4c7d024b Lines: 81 84 96.4 %
Date: 2025-05-17 01:59:02 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <stdint.h>
       5             : #include "options.h" /* Compilation switches                   */
       6             : #include "rom_com.h"
       7             : 
       8             : #include "prot_fx.h" /* Function prototypes                    */
       9             : #include "cnst.h"    /* Common constants                       */
      10             : 
      11             : /*--------------------------------------------------------------------------*/
      12             : /*  Function  hvq_pvq_bitalloc                                              */
      13             : /*  ~~~~~~~~~~~~~~~~~~~~~~~~                                                */
      14             : /*                                                                          */
      15             : /*  Calculate the number of PVQ bands to code and allocate bits based on    */
      16             : /*  the number of available bits.                                           */
      17             : /*--------------------------------------------------------------------------*/
      18        1229 : Word16 hvq_pvq_bitalloc_fx(
      19             :     Word16 num_bits,         /* i/o: Number of available bits (including gain bits) */
      20             :     const Word32 core_brate, /* i  : core bitrate                     */
      21             :     const Word16 bwidth_fx,  /* i  : Encoded bandwidth           */
      22             :     const Word16 *ynrm,      /* i  : Envelope coefficients       */
      23             :     const Word32 manE_peak,  /* i  : Peak energy mantissa        */
      24             :     const Word16 expE_peak,  /* i  : Peak energy exponent        */
      25             :     Word16 *Rk,              /* Q3 o  : bit allocation for concatenated vector */
      26             :     Word16 *R,               /* Q0 i/o: Global bit allocation       */
      27             :     Word16 *sel_bands,       /* Q0 o  : Selected bands for encoding */
      28             :     Word16 *n_sel_bands      /* Q0 o  : No. of selected bands for encoding */
      29             : )
      30             : {
      31             :     Word16 num_bands, band_max_bits;
      32             :     Word16 one_over_band_max_bits;
      33             :     Word16 k;
      34             :     Word16 reciprocal, envSum, expo, align, m, n, indx;
      35             :     Word16 k_max;
      36             :     Word16 k_start;
      37             :     Word32 E_max, E_max5;
      38             :     Word32 tmp, acc;
      39             :     Word32 env_mean;
      40             :     UWord16 lsb;
      41             :     Word16 num_sfm;
      42             : 
      43        1229 :     IF( EQ_16( bwidth_fx, FB ) )
      44             :     {
      45        1051 :         num_sfm = SFM_N_HARM_FB;
      46             :     }
      47             :     ELSE
      48             :     {
      49         178 :         num_sfm = SFM_N_HARM;
      50             :     }
      51        1229 :     move16();
      52             : 
      53        1229 :     IF( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
      54             :     {
      55         708 :         band_max_bits = HVQ_BAND_MAX_BITS_24k; /*Q0*/
      56         708 :         move16();
      57         708 :         one_over_band_max_bits = ONE_OVER_HVQ_BAND_MAX_BITS_24k_FX; /*Q15*/
      58         708 :         move16();
      59         708 :         k_start = HVQ_THRES_SFM_24k; /*Q0*/
      60         708 :         move16();
      61         708 :         IF( EQ_16( bwidth_fx, FB ) )
      62             :         {
      63         536 :             reciprocal = 2731; /* Q15, 1/(SFM_N_HARM_FB + 1 - k_start) */
      64         536 :             move16();
      65             :         }
      66             :         ELSE
      67             :         {
      68         172 :             reciprocal = 3277; /* Q15, 1/(SFM_N_HARM + 1 - k_start) */
      69         172 :             move16();
      70             :         }
      71             :     }
      72             :     ELSE
      73             :     {
      74         521 :         band_max_bits = HVQ_BAND_MAX_BITS_32k; /*Q0*/
      75         521 :         move16();
      76         521 :         one_over_band_max_bits = ONE_OVER_HVQ_BAND_MAX_BITS_32k_FX; /*Q15*/
      77         521 :         move16();
      78         521 :         k_start = HVQ_THRES_SFM_32k; /*Q0*/
      79         521 :         move16();
      80         521 :         IF( EQ_16( bwidth_fx, FB ) )
      81             :         {
      82         515 :             reciprocal = 3641; /* Q15, 1/(SFM_N_HARM_FB + 1 - k_start) */
      83         515 :             move16();
      84             :         }
      85             :         ELSE
      86             :         {
      87           6 :             reciprocal = 4681; /* Q15, 1/(SFM_N_HARM + 1 - k_start) */
      88           6 :             move16();
      89             :         }
      90             :     }
      91             : 
      92        1229 :     num_bands = mult( num_bits, one_over_band_max_bits );           /* Q0 */
      93        1229 :     num_bits = sub( num_bits, i_mult( num_bands, band_max_bits ) ); /* Q0 */
      94             : 
      95        1229 :     IF( GE_16( num_bits, HVQ_NEW_BAND_BIT_THR ) )
      96             :     {
      97         677 :         num_bands = add( num_bands, 1 );
      98             :     }
      99             :     ELSE
     100             :     {
     101         552 :         num_bits = add( num_bits, band_max_bits );
     102             :     }
     103             : 
     104             :     /* safety check in case of bit errors */
     105        1229 :     IF( LT_16( num_bands, 1 ) )
     106             :     {
     107           7 :         return 0;
     108             :     }
     109             : 
     110        1222 :     *n_sel_bands = 0;
     111        1222 :     move16();
     112        1222 :     envSum = 0;
     113        1222 :     move16();
     114        1222 :     E_max = L_deposit_l( 0 );
     115        1222 :     k_max = k_start;
     116        1222 :     move16();
     117       12745 :     FOR( k = k_start; k < num_sfm; k++ )
     118             :     {
     119       11523 :         indx = ynrm[k];
     120       11523 :         move16();
     121       11523 :         tmp = dicn_fx[indx]; /* Q14 */
     122       11523 :         move32();
     123       11523 :         envSum = add( envSum, indx ); /* Since the size of dicn_fx = 40, ynrm[k] must be less than 41. 16 bits are enough for envSum.*/
     124       11523 :         IF( GT_32( tmp, E_max ) )
     125             :         {
     126        2377 :             E_max = tmp;
     127        2377 :             move32();
     128        2377 :             k_max = k;
     129        2377 :             move16();
     130             :         }
     131             :     }
     132        1222 :     env_mean = L_mult( envSum, reciprocal );                               /* env_mean in Q16 */
     133        1222 :     IF( GT_32( L_sub( env_mean, L_deposit_h( ynrm[k_max] ) ), 0x30000L ) ) /* condition: env_mean - ynrm[k_max] > 3 */
     134             :     {
     135         752 :         expo = norm_l( E_max );
     136         752 :         E_max = L_shl( E_max, expo );
     137         752 :         Mpy_32_16_ss( E_max, 0x7a12, &E_max5, &lsb ); /* NB: 5.0e5 = 0x7a12(Q15) x 2^19. */
     138             :         /* True floating point value of E_max*5e5 = E_max5 x 2^(19 - expo - 14).
     139             :          *    In this context, the 32-bit E_max5 is in Q0, and
     140             :          *    -14 is due to Emax in Q14.
     141             :          * True floating point value of E_peak = manE_peak x 2^(31 - expE_peak - 2*12). See peak_vq_enc_fx().
     142             :          */
     143             : 
     144             :         /* Align the Q-points of the floating point Emax*5e5 and E_peak. */
     145         752 :         align = sub( expo, expE_peak );
     146         752 :         align = add( align, ( 19 - 14 ) - ( 31 - 2 * 12 ) );
     147         752 :         IF( align < 0 )
     148             :         {
     149         752 :             acc = L_sub( E_max5, L_shl( manE_peak, align ) );
     150             :         }
     151             :         ELSE
     152             :         {
     153           0 :             acc = L_sub( L_shr( E_max5, align ), manE_peak );
     154             :         }
     155             : 
     156         752 :         IF( acc > 0 ) /* condition: E_max*5.e5 > E_peak */
     157             :         {
     158         752 :             IF( EQ_16( band_len_harm[k_max], 96 ) )
     159             :             {
     160           0 :                 n = 61;
     161           0 :                 move16();
     162             :             }
     163             :             ELSE
     164             :             {
     165         752 :                 QuantaPerDsDirac_fx( band_len_harm[k_max], 1, hBitsN, &n );
     166             :             }
     167         752 :             m = shl( sub( num_bits, HVQ_PVQ_GAIN_BITS ), 3 ); /*Q3*/
     168         752 :             IF( GE_16( m, n ) )
     169             :             {
     170         752 :                 IF( GT_16( num_bands, 1 ) ) /* condition: num_bands > 1 */
     171             :                 {
     172         325 :                     sel_bands[*n_sel_bands] = k_max; /*Q0*/
     173         325 :                     move16();
     174         325 :                     *n_sel_bands = add( *n_sel_bands, 1 ); /*Q0*/
     175         325 :                     move16();
     176         325 :                     R[k_max] = 1; /* Mark that the band has been encoded for fill_spectrum */
     177         325 :                     move16();
     178             :                 }
     179             :             }
     180             :         }
     181             :     }
     182             : 
     183             :     /* Allocate bits */
     184        1222 :     tmp = sub( num_bands, 1 );
     185        2435 :     FOR( k = 0; k < tmp; k++ )
     186             :     {
     187        1213 :         Rk[k] = shl( sub( band_max_bits, HVQ_PVQ_GAIN_BITS ), 3 ); /*Q3*/
     188        1213 :         move16();
     189             :     }
     190             :     /* NB: When it exits the above loop, k = num_bands - 1. */
     191        1222 :     Rk[k] = shl( sub( num_bits, HVQ_PVQ_GAIN_BITS ), 3 ); /*Q3*/
     192        1222 :     move16();
     193             : 
     194        1222 :     return num_bands;
     195             : }

Generated by: LCOV version 1.14