LCOV - code coverage report
Current view: top level - lib_com - hq_bit_allocation_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 185 215 86.0 %
Date: 2025-05-03 01:55:50 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include "options.h" /* Compilation switches                   */
       6             : #include "stl.h"     /* required for wmc_tool */
       7             : #include "prot_fx.h" /* Function prototypes                    */
       8             : #include "cnst.h"    /* Common constants                       */
       9             : #include "ivas_prot_fx.h"
      10             : 
      11             : /*--------------------------------------------------------------------------*
      12             :  * hq_bit_allocation_fx()
      13             :  *
      14             :  * Assign bits for HQ fine structure coding with PVQ
      15             :  *--------------------------------------------------------------------------*/
      16             : 
      17       15146 : void ivas_hq_bit_allocation_fx(
      18             :     const Word32 core_brate,   /* i  : Core bit-rate                    Q0  */
      19             :     const Word16 length,       /* i  : Frame length                     Q0  */
      20             :     const Word16 hqswb_clas,   /* i  : HQ class                         Q0  */
      21             :     Word16 *num_bits,          /* i/o: Remaining bit budget             Q0  */
      22             :     const Word16 *normqlg2,    /* i  : Quantized norms                  Q0  */
      23             :     const Word16 nb_sfm,       /* i  : Number sub bands to be encoded   Q0  */
      24             :     const Word16 *sfmsize,     /* i  : Sub band bandwidths              Q0  */
      25             :     Word16 *noise_level,       /* o  : HVQ noise level                  Q15 */
      26             :     Word16 *R,                 /* o  : Bit allocation per sub band      Q0  */
      27             :     Word16 *Rsubband,          /* o  : Fractional bit allocation        Q3  */
      28             :     Word16 *sum,               /* o  : Sum of allocated shape bits      Q0  */
      29             :     Word16 *core_sfm,          /* o  : Last coded band in core          Q0  */
      30             :     const Word16 num_env_bands /* i  : Number sub bands to be encoded for HQ_GEN Q0  */
      31             : )
      32             : {
      33             :     Word16 i;
      34             :     Word16 idx[NB_SFM];
      35             :     Word16 wnorm[NB_SFM];
      36             :     Word16 avrg_wnorm;
      37             :     Word16 tmp, tmp2;
      38             :     Word16 E_low;
      39             :     Word16 E_hb_mean;
      40             :     Word16 E_max;
      41             :     Word16 i_max;
      42             :     /* Temp */
      43             : 
      44       15146 :     Word16 sfm_limit = nb_sfm;
      45       15146 :     move16();
      46             : 
      47       15146 :     set16_fx( R, 0, NB_SFM );
      48      580235 :     FOR( i = 0; i < nb_sfm; i++ )
      49             :     {
      50      565089 :         idx[i] = i;
      51      565089 :         move16();
      52             :     }
      53       15146 :     test();
      54       15146 :     test();
      55       15146 :     test();
      56       15146 :     IF( NE_16( hqswb_clas, HQ_TRANSIENT ) && NE_16( hqswb_clas, HQ_HVQ ) && !( EQ_16( length, L_FRAME16k ) && LE_32( core_brate, HQ_32k ) ) )
      57             :     {
      58             :         /* 'nf_idx' 2-bits index written later */
      59       10692 :         *num_bits = sub( *num_bits, 2 ); /*Q0*/
      60       10692 :         move16();
      61             :     }
      62             : 
      63       15146 :     test();
      64       15146 :     IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) )
      65             :     {
      66        5548 :         IF( GE_32( core_brate, HQ_32k ) )
      67             :         {
      68           0 :             *num_bits = sub( *num_bits, HQ_GENERIC_SWB_NBITS2 ); /*Q0*/
      69             :         }
      70             :         ELSE
      71             :         {
      72        5548 :             *num_bits = sub( *num_bits, HQ_GENERIC_SWB_NBITS ); /*Q0*/
      73             :         }
      74        5548 :         move16();
      75             : 
      76        5548 :         IF( EQ_16( length, L_SPEC48k ) )
      77             :         {
      78        4275 :             *num_bits = sub( *num_bits, HQ_GENERIC_FB_NBITS ); /*Q0*/
      79        4275 :             move16();
      80             :         }
      81             :     }
      82             : 
      83       15146 :     test();
      84       15146 :     test();
      85       15146 :     IF( ( EQ_16( length, L_SPEC48k ) ) && ( NE_16( hqswb_clas, HQ_HARMONIC ) ) && ( NE_16( hqswb_clas, HQ_HVQ ) ) )
      86             :     {
      87        8029 :         tmp = 0;
      88        8029 :         move16();
      89        8029 :         IF( EQ_16( hqswb_clas, HQ_TRANSIENT ) )
      90             :         {
      91         742 :             tmp = 1;
      92         742 :             move16();
      93             :         }
      94        8029 :         map_quant_weight_fx( normqlg2, wnorm, tmp );
      95             :     }
      96             :     ELSE
      97             :     {
      98        7117 :         Copy( normqlg2, wnorm, nb_sfm );
      99             :     }
     100             : 
     101       15146 :     IF( EQ_16( hqswb_clas, HQ_HARMONIC ) )
     102             :     {
     103             :         /* classification and limit bandwidth for bit allocation */
     104        1497 :         sfm_limit = sub( sfm_limit, 2 );
     105        1497 :         move16();
     106        1497 :         limit_band_noise_level_calc_fx( wnorm, &sfm_limit, core_brate, noise_level );
     107             : 
     108             :         /* Detect important band in high frequency region */
     109        1497 :         E_low = sum16_fx( wnorm, SFM_G1 );
     110        1497 :         i_max = 0;
     111        1497 :         move16();
     112        1497 :         E_max = MIN16B;
     113        1497 :         move16();
     114        1497 :         E_hb_mean = 0;
     115        1497 :         move16();
     116       26624 :         FOR( i = SFM_G1; i < nb_sfm; i++ )
     117             :         {
     118       25127 :             E_hb_mean = add( E_hb_mean, wnorm[i] );
     119       25127 :             IF( GT_16( wnorm[i], E_max ) )
     120             :             {
     121        3316 :                 E_max = wnorm[i];
     122        3316 :                 move16();
     123        3316 :                 i_max = i;
     124        3316 :                 move16();
     125             :             }
     126             :         }
     127        1497 :         E_hb_mean = shr( E_hb_mean, 4 ); /* Truncated division by SFM_G1 */
     128        1497 :         set16_fx( wnorm + sfm_limit, -20, sub( nb_sfm, sfm_limit ) );
     129        1497 :         IF( LE_32( L_msu0( L_deposit_l( E_low ), E_max, 15 ), 0 ) )
     130             :         {
     131         662 :             IF( LE_32( L_msu( L_deposit_h( E_hb_mean ), E_max, 21955 ), 0 ) ) /* 21955 = 0.67 (Q15) */
     132             :             {
     133         333 :                 IF( GE_16( i_max, sfm_limit ) )
     134             :                 {
     135          10 :                     wnorm[i_max] = E_max;
     136          10 :                     move16();
     137             :                 }
     138             :             }
     139             :         }
     140             :     }
     141       15146 :     test();
     142       15146 :     test();
     143       15146 :     test();
     144       15146 :     test();
     145       15146 :     IF( EQ_16( hqswb_clas, HQ_HVQ ) )
     146             :     {
     147        2692 :         *sum = 0;
     148        2692 :         move16();
     149             :     }
     150       12454 :     ELSE IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || ( EQ_16( hqswb_clas, HQ_TRANSIENT ) && EQ_16( length, L_FRAME32k ) && LE_32( core_brate, HQ_32k ) ) )
     151             :     {
     152        1427 :         *sum = BitAllocF_fx( wnorm, core_brate, *num_bits, nb_sfm, R, Rsubband, hqswb_clas, num_env_bands );
     153        1427 :         move16();
     154             :     }
     155       11027 :     ELSE IF( EQ_16( length, L_FRAME16k ) && LE_32( core_brate, HQ_32k ) )
     156             :     {
     157         846 :         IF( NE_16( hqswb_clas, HQ_TRANSIENT ) )
     158             :         {
     159         827 :             avrg_wnorm = wnorm[10];
     160         827 :             move16();
     161        6616 :             FOR( i = 11; i < 18; i++ )
     162             :             {
     163        5789 :                 avrg_wnorm = add( avrg_wnorm, wnorm[i] );
     164             :             }
     165             : 
     166         827 :             avrg_wnorm = shr( avrg_wnorm, 3 );
     167        4135 :             FOR( i = 0; i < 4; i++ ){
     168        3308 :                 IF( LT_16( wnorm[i], avrg_wnorm ) ){
     169         361 :                     wnorm[i] = avrg_wnorm;
     170         361 :             move16();
     171             :         }
     172             :     }
     173             : 
     174             :     /* Estimate number of bits per band */
     175         827 :     *sum = BitAllocWB_fx( wnorm, *num_bits, nb_sfm, R, Rsubband );
     176         827 :     move16();
     177             : }
     178             : ELSE
     179             : {
     180          19 :     reordvct_fx( wnorm, nb_sfm, idx );
     181          19 :     bitalloc_fx( wnorm, idx, *num_bits, nb_sfm, QBIT_MAX2, R, sfmsize, hqswb_clas );
     182          19 :     bitallocsum_fx( R, nb_sfm, sum, Rsubband, *num_bits, length, sfmsize );
     183             : }
     184             : }
     185             : ELSE
     186             : {
     187       10181 :     reordvct_fx( wnorm, nb_sfm, idx );
     188             : 
     189             :     /* enlarge the wnorm value so that more bits can be allocated to (sfm_limit/2 ~ sfm_limit) range */
     190       10181 :     IF( EQ_16( hqswb_clas, HQ_HARMONIC ) )
     191             :     {
     192        1497 :         tmp = shr( sfm_limit, 1 );
     193        1497 :         tmp2 = sub( tmp, 1 );
     194       21047 :         FOR( i = tmp; i < sfm_limit; i++ )
     195             :         {
     196       19550 :             wnorm[i] = wnorm[tmp2];
     197       19550 :             move16();
     198             :         }
     199             :     }
     200       10181 :     bitalloc_fx( wnorm, idx, *num_bits, nb_sfm, QBIT_MAX2, R, sfmsize, hqswb_clas );
     201       10181 :     bitallocsum_fx( R, nb_sfm, sum, Rsubband, *num_bits, length, sfmsize );
     202             : }
     203             : 
     204             : /* Find last coded core band */
     205       15146 : *core_sfm = sub( nb_sfm, 1 );
     206       15146 : move16();
     207       15146 : test();
     208       15146 : test();
     209       15146 : IF( hqswb_clas == HQ_NORMAL || EQ_16( hqswb_clas, HQ_HARMONIC ) )
     210             : {
     211        5971 :     *core_sfm = find_last_band_fx( R, nb_sfm );
     212        5971 :     move16();
     213             : }
     214        9175 : ELSE IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) )
     215             : {
     216        5548 :     *core_sfm = find_last_band_fx( R, nb_sfm );
     217        5548 :     move16();
     218        5548 :     IF( LT_16( *core_sfm, num_env_bands ) )
     219             :     {
     220        5548 :         *core_sfm = sub( num_env_bands, 1 );
     221        5548 :         move16();
     222             :     }
     223             : }
     224             : 
     225       15146 : *num_bits = sub( *num_bits, *sum );
     226       15146 : move16();
     227             : 
     228       15146 : return;
     229             : }
     230         767 : void hq_bit_allocation_fx(
     231             :     const Word32 core_brate,   /* i  : Core bit-rate                    Q0  */
     232             :     const Word16 length,       /* i  : Frame length                     Q0  */
     233             :     const Word16 hqswb_clas,   /* i  : HQ class                         Q0  */
     234             :     Word16 *num_bits,          /* i/o: Remaining bit budget             Q0  */
     235             :     const Word16 *normqlg2,    /* i  : Quantized norms                  Q0  */
     236             :     const Word16 nb_sfm,       /* i  : Number sub bands to be encoded   Q0  */
     237             :     const Word16 *sfmsize,     /* i  : Sub band bandwidths              Q0  */
     238             :     Word16 *noise_level,       /* o  : HVQ noise level                  Q15  */
     239             :     Word16 *R,                 /* o  : Bit allocation per sub band      Q0  */
     240             :     Word16 *Rsubband,          /* o  : Fractional bit allocation        Q3  */
     241             :     Word16 *sum,               /* o  : Sum of allocated shape bits      Q0  */
     242             :     Word16 *core_sfm,          /* o  : Last coded band in core          Q0  */
     243             :     const Word16 num_env_bands /* i  : Number sub bands to be encoded for HQ_GEN Q0  */
     244             : )
     245             : {
     246             :     Word16 i;
     247             :     Word16 idx[NB_SFM];
     248             :     Word16 wnorm[NB_SFM];
     249             :     Word16 avrg_wnorm;
     250             :     Word16 tmp, tmp2;
     251             :     Word16 E_low;
     252             :     Word16 E_hb_mean;
     253             :     Word16 E_max;
     254             :     Word16 i_max;
     255             :     /* Temp */
     256             : 
     257         767 :     Word16 sfm_limit = nb_sfm;
     258         767 :     move16();
     259             : 
     260         767 :     set16_fx( R, 0, NB_SFM );
     261       30424 :     FOR( i = 0; i < nb_sfm; i++ )
     262             :     {
     263       29657 :         idx[i] = i;
     264       29657 :         move16();
     265             :     }
     266         767 :     test();
     267         767 :     test();
     268         767 :     test();
     269         767 :     if ( NE_16( hqswb_clas, HQ_TRANSIENT ) && NE_16( hqswb_clas, HQ_HVQ ) && !( EQ_16( length, L_FRAME16k ) && EQ_32( core_brate, HQ_32k ) ) )
     270             :     {
     271             :         /* 'nf_idx' 2-bits index written later */
     272         697 :         *num_bits = sub( *num_bits, 2 );
     273             :     }
     274             : 
     275         767 :     test();
     276         767 :     IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) )
     277             :     {
     278          78 :         IF( EQ_32( core_brate, HQ_32k ) )
     279             :         {
     280           0 :             *num_bits = sub( *num_bits, HQ_GENERIC_SWB_NBITS2 );
     281           0 :             move16();
     282             :         }
     283             :         ELSE
     284             :         {
     285          78 :             *num_bits = sub( *num_bits, HQ_GENERIC_SWB_NBITS );
     286          78 :             move16();
     287             :         }
     288             : 
     289          78 :         if ( EQ_16( hqswb_clas, HQ_GEN_FB ) )
     290             :         {
     291           0 :             *num_bits = sub( *num_bits, HQ_GENERIC_FB_NBITS );
     292           0 :             move16();
     293             :         }
     294             :     }
     295             : 
     296         767 :     test();
     297         767 :     test();
     298         767 :     IF( ( EQ_16( length, L_FRAME48k ) ) && ( NE_16( hqswb_clas, HQ_HARMONIC ) ) && ( NE_16( hqswb_clas, HQ_HVQ ) ) )
     299             :     {
     300           0 :         tmp = 0;
     301           0 :         move16();
     302           0 :         if ( EQ_16( hqswb_clas, HQ_TRANSIENT ) )
     303             :         {
     304           0 :             tmp = 1;
     305           0 :             move16();
     306             :         }
     307           0 :         map_quant_weight_fx( normqlg2, wnorm, tmp );
     308             :     }
     309             :     ELSE
     310             :     {
     311         767 :         Copy( normqlg2, wnorm, nb_sfm );
     312             :     }
     313             : 
     314         767 :     IF( EQ_16( hqswb_clas, HQ_HARMONIC ) )
     315             :     {
     316             :         /* classification and limit bandwidth for bit allocation */
     317          32 :         sfm_limit = sub( sfm_limit, 2 );
     318          32 :         limit_band_noise_level_calc_fx( wnorm, &sfm_limit, core_brate, noise_level );
     319             : 
     320             :         /* Detect important band in high frequency region */
     321          32 :         E_low = sum16_fx( wnorm, SFM_G1 );
     322          32 :         i_max = 0;
     323          32 :         move16();
     324          32 :         E_max = MIN16B;
     325          32 :         move16();
     326          32 :         E_hb_mean = 0;
     327          32 :         move16();
     328         512 :         FOR( i = SFM_G1; i < nb_sfm; i++ )
     329             :         {
     330         480 :             E_hb_mean = add( E_hb_mean, wnorm[i] );
     331         480 :             IF( GT_16( wnorm[i], E_max ) )
     332             :             {
     333         110 :                 E_max = wnorm[i];
     334         110 :                 move16();
     335         110 :                 i_max = i;
     336         110 :                 move16();
     337             :             }
     338             :         }
     339          32 :         E_hb_mean = shr( E_hb_mean, 4 ); /* Truncated division by SFM_G1 */
     340          32 :         set16_fx( wnorm + sfm_limit, -20, sub( nb_sfm, sfm_limit ) );
     341          32 :         IF( L_msu0( L_deposit_l( E_low ), E_max, 15 ) <= 0 )
     342             :         {
     343          18 :             IF( L_msu( L_deposit_h( E_hb_mean ), E_max, 21955 ) <= 0 ) /* 21955 = 0.67 (Q15) */
     344             :             {
     345           3 :                 if ( GE_16( i_max, sfm_limit ) )
     346             :                 {
     347           0 :                     wnorm[i_max] = E_max;
     348           0 :                     move16();
     349             :                 }
     350             :             }
     351             :         }
     352             :     }
     353         767 :     test();
     354         767 :     test();
     355         767 :     test();
     356         767 :     test();
     357         767 :     IF( EQ_16( hqswb_clas, HQ_HVQ ) )
     358             :     {
     359           0 :         *sum = 0;
     360           0 :         move16();
     361             :     }
     362         767 :     ELSE IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || ( EQ_16( hqswb_clas, HQ_TRANSIENT ) && EQ_16( length, L_FRAME32k ) && LE_32( core_brate, HQ_32k ) ) )
     363             :     {
     364          78 :         *sum = BitAllocF_fx( wnorm, core_brate, *num_bits, nb_sfm, R, Rsubband, hqswb_clas, num_env_bands );
     365          78 :         move16();
     366             :     }
     367         689 :     ELSE IF( EQ_16( length, L_FRAME16k ) && EQ_32( core_brate, HQ_32k ) )
     368             :     {
     369           0 :         IF( NE_16( hqswb_clas, HQ_TRANSIENT ) )
     370             :         {
     371           0 :             avrg_wnorm = wnorm[10];
     372           0 :             move16();
     373           0 :             FOR( i = 11; i < 18; i++ )
     374             :             {
     375           0 :                 avrg_wnorm = add( avrg_wnorm, wnorm[i] );
     376             :             }
     377             : 
     378           0 :             avrg_wnorm = shr( avrg_wnorm, 3 );
     379           0 :             FOR( i = 0; i < 4; i++ )
     380             :             {
     381           0 :                 if ( LT_16( wnorm[i], avrg_wnorm ) )
     382             :                 {
     383           0 :                     wnorm[i] = avrg_wnorm;
     384           0 :                     move16();
     385             :                 }
     386             :             }
     387             : 
     388             :             /* Estimate number of bits per band */
     389           0 :             *sum = BitAllocWB_fx( wnorm, *num_bits, nb_sfm, R, Rsubband );
     390           0 :             move16();
     391             :         }
     392             :         ELSE
     393             :         {
     394           0 :             reordvct_fx( wnorm, nb_sfm, idx );
     395           0 :             bitalloc_fx( wnorm, idx, *num_bits, nb_sfm, QBIT_MAX2, R, sfmsize, hqswb_clas );
     396           0 :             bitallocsum_fx( R, nb_sfm, sum, Rsubband, *num_bits, length, sfmsize );
     397             :         }
     398             :     }
     399             :     ELSE
     400             :     {
     401         689 :         reordvct_fx( wnorm, nb_sfm, idx );
     402             : 
     403             :         /* enlarge the wnorm value so that more bits can be allocated to (sfm_limit/2 ~ sfm_limit) range */
     404         689 :         IF( EQ_16( hqswb_clas, HQ_HARMONIC ) )
     405             :         {
     406          32 :             tmp = shr( sfm_limit, 1 );
     407          32 :             tmp2 = sub( tmp, 1 );
     408         432 :             FOR( i = tmp; i < sfm_limit; i++ )
     409             :             {
     410         400 :                 wnorm[i] = wnorm[tmp2];
     411         400 :                 move16();
     412             :             }
     413             :         }
     414         689 :         bitalloc_fx( wnorm, idx, *num_bits, nb_sfm, QBIT_MAX2, R, sfmsize, hqswb_clas );
     415         689 :         bitallocsum_fx( R, nb_sfm, sum, Rsubband, *num_bits, length, sfmsize );
     416             :     }
     417             : 
     418             :     /* Find last coded core band */
     419         767 :     *core_sfm = sub( nb_sfm, 1 );
     420         767 :     move16();
     421         767 :     test();
     422         767 :     test();
     423         767 :     IF( hqswb_clas == HQ_NORMAL || EQ_16( hqswb_clas, HQ_HARMONIC ) )
     424             :     {
     425         619 :         *core_sfm = find_last_band_fx( R, nb_sfm );
     426         619 :         move16();
     427             :     }
     428         148 :     ELSE IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) )
     429             :     {
     430          78 :         *core_sfm = find_last_band_fx( R, nb_sfm );
     431          78 :         move16();
     432          78 :         IF( LT_16( *core_sfm, num_env_bands ) )
     433             :         {
     434          74 :             *core_sfm = sub( num_env_bands, 1 );
     435          74 :             move16();
     436             :         }
     437             :     }
     438             : 
     439         767 :     *num_bits = sub( *num_bits, *sum );
     440         767 :     move16();
     441             : 
     442         767 :     return;
     443             : }

Generated by: LCOV version 1.14