LCOV - code coverage report
Current view: top level - lib_dec - d_gain2p_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 62 141 44.0 %
Date: 2025-05-03 01:55:50 Functions: 5 7 71.4 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include <assert.h>
       7             : #include "prot_fx.h"
       8             : #include "basop_util.h"
       9             : #include "stl.h"
      10             : #include "rom_com.h"
      11             : /*-------------------------------------------------------------------*
      12             :  * Decoding of pitch and codebook gains  (see q_gain2_plus.c)        *
      13             :  *-------------------------------------------------------------------*/
      14             : 
      15             : /*********************
      16             :  * private functions *
      17             :  *********************/
      18        3050 : static Word32 calc_gcode0_fx(
      19             :     Word16 *gcode0,    // Q8
      20             :     Word16 *exp_gcode0 // Q0
      21             : )
      22             : {
      23             :     Word32 L_tmp;
      24             : 
      25             :     /*gcode0 = (float)pow(10.0,(gcode0)*0.05);*/ /* predicted gain */
      26             : 
      27        3050 :     L_tmp = L_mult( *gcode0, 5443 /*0.166096f Q15*/ );       // Q24
      28        3050 :     *exp_gcode0 = add( 1, extract_l( L_shr( L_tmp, 24 ) ) ); // Q0
      29        3050 :     move16();
      30        3050 :     L_tmp = L_lshl( L_tmp, 7 );         // Q31
      31        3050 :     L_tmp = L_and( 0x7FFFFFFF, L_tmp ); // 0x7FFFFFFF-> 1 in Q31
      32             : 
      33        3050 :     L_tmp = Pow2( 30, round_fx( L_tmp ) );
      34        3050 :     *gcode0 = round_fx( L_tmp );
      35        3050 :     move16();
      36             : 
      37        3050 :     return L_tmp;
      38             : }
      39             : 
      40        3050 : static Word32 calc_gain_code_fx( Word16 g_code, Word16 gcode0, Word16 exp_gcode0 )
      41             : {
      42             :     Word32 L_tmp;
      43             : 
      44        3050 :     L_tmp = L_mult( g_code, gcode0 ); /* Q11*Q15 -> Q27 */
      45        3050 :     exp_gcode0 = add( exp_gcode0, -11 );
      46        3050 :     L_tmp = L_shl_sat( L_tmp, exp_gcode0 ); /*   Q27 -> Q16 */
      47             : 
      48        3050 :     return L_tmp;
      49             : }
      50             : 
      51             : /*--------------------------------------------------------------------------*
      52             :  * Mode2_gain_dec_mless_fx
      53             :  *
      54             :  * Decoding of pitch and codebook gains without updating long term energies
      55             :  *-------------------------------------------------------------------------*/
      56             : 
      57        3050 : static void Mode2_gain_dec_mless_fx(
      58             :     Word16 index,       /* i  : Quantization index vector        Q0  */
      59             :     Word16 *code,       /* i  : algebraic code excitation        Q9  */
      60             :     Word16 lcode,       /* i  : Subframe size                    Q0  */
      61             :     Word16 *gain_pit,   /* o  : Quantized pitch gain            1Q14 */
      62             :     Word32 *gain_code,  /* o  : Quantized codebook gain          Q16 */
      63             :     Word16 mean_ener,   /* i  : mean_ener defined in open-loop   Q8  */
      64             :     Word16 *past_gpit,  /* i/o: past gain of pitch              1Q14 */
      65             :     Word32 *past_gcode, /* i/o: past energy of code              Q16 */
      66             :     Word16 *gain_inov,  /* o  : unscaled innovation gain        3Q12 */
      67             :     Word16 coder_type   /* i  : coder type for number of bits        */
      68             : )
      69             : {
      70             : 
      71             :     Word16 ener_code;
      72             :     const Word16 *t_qua_gain;
      73             :     Word16 exp_L_tmp1;
      74             :     Word16 gcode0, exp_gcode0;
      75             :     Word32 L_tmp, L_tmp1;
      76             : 
      77             : 
      78             :     /**gain_inov = 1.0f / (float)sqrt( ( dot_product( code, code, lcode ) + 0.01f ) / lcode);*/
      79        3050 :     L_tmp = calc_gain_inov( code, lcode, &L_tmp1, &exp_L_tmp1 );
      80        3050 :     *gain_inov = round_fx_sat( L_shl_sat( L_tmp, 15 - 3 ) ); /* gain_inov in Q12 */
      81        3050 :     move16();
      82             :     /*-----------------------------------------------------------------*
      83             :      * Select the gains quantization table
      84             :      *-----------------------------------------------------------------*/
      85        3050 :     t_qua_gain = E_ROM_qua_gain7b_const;
      86        3050 :     move16();
      87        3050 :     if ( coder_type == 0 )
      88             :     {
      89           0 :         t_qua_gain = E_ROM_qua_gain5b_const;
      90           0 :         move16();
      91             :     }
      92             : 
      93        3050 :     if ( EQ_16( coder_type, 1 ) )
      94             :     {
      95         130 :         t_qua_gain = E_ROM_qua_gain6b_const;
      96         130 :         move16();
      97             :     }
      98             : 
      99             :     /*-----------------------------------------------------------------*
     100             :      * decode pitch gain
     101             :      *-----------------------------------------------------------------*/
     102        3050 :     *gain_pit = t_qua_gain[shl( index, 1 )];
     103        3050 :     move16();
     104             :     /*-----------------------------------------------------------------*
     105             :      * calculate the predicted gain code
     106             :      *-----------------------------------------------------------------*/
     107             :     /*ener_code = 10 * log10((dot_product(code, code, lcode) + 0.01) / lcode) */
     108        3050 :     L_tmp = BASOP_Util_Log2( L_tmp1 );
     109        3050 :     L_tmp = L_add( L_tmp, L_shl( L_deposit_l( exp_L_tmp1 ), 31 - LD_DATA_SCALE ) );
     110             : 
     111        3050 :     L_tmp = Mpy_32_16_1( L_tmp, 24660 /*(10.0f/3.3219280948873623478703194294894f)/4.0f Q15*/ );
     112             :     /* exponent of L_tmp = 6+2 */
     113        3050 :     ener_code = round_fx( L_shl( L_tmp, 6 + 2 - 7 ) ); /* Q8 */
     114             : 
     115             :     /* predicted codebook gain */
     116        3050 :     gcode0 = sub( mean_ener, ener_code ); /* Q8 */
     117             : 
     118             :     /*gcode0 = (float)pow(10.0,(gcode0)*0.05);*/ /* predicted gain */
     119             : 
     120        3050 :     calc_gcode0_fx( &gcode0, &exp_gcode0 );
     121             : 
     122             :     /*-----------------------------------------------------------------*
     123             :      * decode normalized codebook gain
     124             :      *-----------------------------------------------------------------*/
     125             :     /* *gain_code = t_qua_gain[index*2+1] * gcode0;*/
     126             :     Word16 tmp_idx;
     127        3050 :     tmp_idx = add( shl( index, 1 ), 1 );
     128        3050 :     L_tmp = calc_gain_code_fx( t_qua_gain[tmp_idx], gcode0, exp_gcode0 );
     129             : 
     130        3050 :     *gain_code = L_tmp;
     131        3050 :     move32();
     132        3050 :     *past_gpit = *gain_pit;
     133        3050 :     move16();
     134             :     /**past_gcode = *gain_code / *gain_inov;   */
     135             :     /* Q16/Q12 => Q5 */
     136        3050 :     L_tmp1 = L_deposit_h( BASOP_Util_Divide3216_Scale( L_tmp, *gain_inov, &exp_L_tmp1 ) );
     137        3050 :     *past_gcode = L_shl( L_tmp1, sub( exp_L_tmp1, 15 - 12 ) );
     138        3050 :     move32();
     139             : 
     140             : 
     141        3050 :     return;
     142             : }
     143             : 
     144             : /*---------------------------------------------------------------------*
     145             :  * gain_dec_uv_fx
     146             :  *
     147             :  * Decoding of pitch and codebook gains for Unvoiced mode
     148             :  *---------------------------------------------------------------------*/
     149             : 
     150           0 : static void gain_dec_uv_fx(
     151             :     Word16 index,       /* i  : Quantization index vector        Q0  */
     152             :     Word16 *code,       /* i  : algebraic code excitation        Q9  */
     153             :     Word16 lcode,       /* i  : Subframe size                    Q0  */
     154             :     Word16 *gain_pit,   /* o  : Quantized pitch gain            1Q14 */
     155             :     Word32 *gain_code,  /* o  : Quantized codebook gain          Q16 */
     156             :     Word16 *past_gpit,  /* i/o: past gain of pitch              1Q14 */
     157             :     Word32 *past_gcode, /* i/o: past energy of code              Q16 */
     158             :     Word16 *gain_inov   /* o  : unscaled innovation gain        3Q12 */
     159             : )
     160             : {
     161             :     Word16 i, exp_L_tmp1;
     162             :     Word32 L_tmp, L_tmp1;
     163             : 
     164             : 
     165             :     /*-----------------------------------------------------------------*
     166             :      * Innovation energy (without gain)
     167             :      *-----------------------------------------------------------------*/
     168             :     /* *gain_inov = 1.0f / (float)sqrt( ( dot_product( code, code, lcode ) + 0.01f ) / lcode );*/
     169           0 :     L_tmp = calc_gain_inov( code, lcode, &L_tmp1, &exp_L_tmp1 );
     170           0 :     *gain_inov = round_fx( L_shl( L_tmp, 15 - 3 ) ); /* gain_inov in Q12 */
     171           0 :     move16();
     172             :     /*-----------------------------------------------------------------*
     173             :      * Decode pitch gain
     174             :      *-----------------------------------------------------------------*/
     175           0 :     *gain_pit = 0;
     176           0 :     move16();
     177             : 
     178             :     /*-----------------------------------------------------------------*
     179             :      * Decode codebook gain
     180             :      *-----------------------------------------------------------------*/
     181             :     /* *gain_code= (float)pow(10.f,(((index*1.9f)-30.f)/20.f));*/
     182           0 :     L_tmp = L_mac( -167197708l /*-0.166096*30.0f Q25*/, shl( index, 16 - 7 ), 10341 /*0.166096f*1.9f Q15*/ );
     183           0 :     i = add( 1, extract_l( L_shr( L_tmp, 25 ) ) );
     184           0 :     L_tmp = L_lshl( L_tmp, 6 );
     185           0 :     L_tmp = L_and( 0x7FFFFFFF, L_tmp ); //  0x7FFFFFFF ->1 in Q31
     186             : 
     187           0 :     L_tmp = Pow2( 30, round_fx( L_tmp ) );
     188           0 :     L_tmp = L_shl( L_tmp, sub( i, ( 31 - 16 ) ) ); /* Q16 */
     189             : 
     190             : 
     191             :     /*-----------------------------------------------------------------*
     192             :      * past gains for error concealment
     193             :      *-----------------------------------------------------------------*/
     194           0 :     *past_gpit = *gain_pit;
     195           0 :     move16();
     196           0 :     *past_gcode = L_tmp;
     197           0 :     move32();
     198           0 :     L_tmp = L_shl_sat( Mpy_32_16_1( L_tmp, *gain_inov ), 3 ); /* Q16*Q12 -> Q13 -> Q16 */
     199           0 :     *gain_code = L_tmp;
     200           0 :     move32();
     201             : 
     202             : 
     203           0 :     return;
     204             : }
     205             : 
     206             : /*---------------------------------------------------------------------*
     207             :  * gain_dec_gacelp_uv_fx
     208             :  *
     209             :  * Decoding of pitch and codebook gains for Unvoiced mode
     210             :  *---------------------------------------------------------------------*/
     211             : 
     212           0 : static void gain_dec_gacelp_uv_fx(
     213             :     Word16 index,       /* i  : Quantization index vector        Q0  */
     214             :     Word16 *code,       /* i  : algebraic code excitation        Q9  */
     215             :     Word16 *code2,      /* i  : algebraic code excitation        Q9  */
     216             :     Word16 mean_ener,   /* i  :                                 Q8  */
     217             :     Word16 lcode,       /* i  : Subframe size                    Q0  */
     218             :     Word16 *gain_pit,   /* o  : Quantized pitch gain            1Q14 */
     219             :     Word32 *gain_code,  /* o  : Quantized codebook gain          Q16 */
     220             :     Word32 *gain_code2, /* o  : Quantized codebook gain          Q16 */
     221             :     Word16 *past_gpit,  /* i/o: past gain of pitch              1Q14 */
     222             :     Word32 *past_gcode, /* i/o: past energy of code              Q16 */
     223             :     Word16 *gain_inov   /* o  : unscaled innovation gain        3Q12 */
     224             : )
     225             : {
     226             :     Word16 i, exp_L_tmp1;
     227             :     Word16 exp_gcode;
     228             :     Word16 g_code;
     229             :     Word32 L_tmp, L_tmp1;
     230             :     Word32 pred_nrg_frame;
     231             :     Word16 exp_gcode2, g_code2, norm_code2;
     232             :     Word16 index2, s;
     233             : 
     234             : 
     235             :     /* pred_nrg_frame = (float)pow(10.0,mean_ener/20.0); */
     236           0 :     L_tmp = L_mult( mean_ener, 10885 /*0.166096f * 2 Q15*/ );                       /* 6Q25 */
     237           0 :     pred_nrg_frame = BASOP_Util_InvLog2( L_sub( L_tmp, 503316480l /*15.f Q25*/ ) ); /* 15Q16 */
     238             : 
     239             :     /*-----------------------------------------------------------------*
     240             :      * Prediction gains
     241             :      *-----------------------------------------------------------------*/
     242             :     /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     243           0 :     L_tmp = calc_gain_inov( code, lcode, NULL, NULL );
     244           0 :     *gain_inov = round_fx( L_shl( L_tmp, 15 - 3 ) ); /* gain_inov in Q12 */
     245           0 :     move16();
     246             : 
     247             :     /* gcode = pred_nrg_frame * (*gain_inov); */
     248           0 :     L_tmp = Mpy_32_16_1( pred_nrg_frame, *gain_inov ); /* 18Q13 */
     249           0 :     i = norm_l( L_tmp );
     250           0 :     g_code = round_fx( L_shl( L_tmp, i ) );
     251           0 :     exp_gcode = sub( 18, i );
     252             : 
     253             :     /* norm_code2 = 1.0f / sqrt((dot_product(code2, code2, lcode) + 0.01f) / lcode); */
     254           0 :     L_tmp = calc_gain_inov( code2, lcode, NULL, NULL );
     255           0 :     norm_code2 = round_fx( L_shl( L_tmp, 15 - 3 ) ); /* Q12 */
     256             : 
     257             :     /* g_code2 = pred_nrg_frame * norm_code2; */
     258           0 :     L_tmp = Mpy_32_16_1( pred_nrg_frame, norm_code2 ); /* 18Q13 */
     259           0 :     i = norm_l( L_tmp );
     260           0 :     g_code2 = round_fx_sat( L_shl_sat( L_tmp, i ) );
     261           0 :     exp_gcode2 = sub( 18, i );
     262             : 
     263             :     /*-----------------------------------------------------------------*
     264             :      * Decode pitch gain
     265             :      *-----------------------------------------------------------------*/
     266           0 :     *gain_pit = 0;
     267           0 :     move16();
     268           0 :     *past_gpit = *gain_pit;
     269           0 :     move16();
     270             : 
     271             :     /*-----------------------------------------------------------------*
     272             :      * past gains for error concealment
     273             :      *-----------------------------------------------------------------*/
     274           0 :     index2 = shr( index, 5 );
     275           0 :     index = s_and( index, 0x1F ); // 0x1F -> 31
     276             : 
     277             :     /**gain_code= (float)pow(10.f,(((index*1.25f)-20.f)/20.f))*gcode;*/
     278             : 
     279           0 :     L_tmp = L_mac( -111465139l /*-0.166096*20.0f Q25*/, shl( index, 16 - 7 ), 6803 /*0.166096f*1.25f Q15*/ );
     280             : 
     281           0 :     i = add( 1, extract_l( L_shr( L_tmp, 25 ) ) );
     282           0 :     L_tmp = L_lshl( L_tmp, 6 );
     283           0 :     L_tmp = L_and( 0x7FFFFFFF, L_tmp ); // 0x7FFFFFFF-> 1 in Q31
     284             : 
     285           0 :     L_tmp = Pow2( 30, round_fx( L_tmp ) );
     286           0 :     L_tmp = L_shl( L_tmp, sub( i, ( 31 - 16 ) ) ); /* Q16 */
     287             : 
     288             :     /* *past_gcode = L_tmp * pred_nrg_frame; */
     289           0 :     i = norm_l( L_tmp );
     290           0 :     L_tmp1 = L_shl( L_tmp, i );
     291           0 :     exp_L_tmp1 = sub( 15, i );
     292             : 
     293           0 :     i = norm_l( pred_nrg_frame );
     294           0 :     L_tmp1 = Mpy_32_32( L_tmp1, L_shl( pred_nrg_frame, i ) );
     295           0 :     exp_L_tmp1 = add( exp_L_tmp1, sub( 15, i ) );
     296             : 
     297           0 :     *past_gcode = L_shl( L_tmp1, sub( exp_L_tmp1, 15 ) ); /* Q16 */
     298           0 :     move32();
     299             : 
     300           0 :     *gain_code = L_shl_sat( Mpy_32_16_1( *past_gcode, *gain_inov ), 3 );
     301           0 :     move32();
     302             : 
     303             : 
     304           0 :     L_tmp = Mpy_32_16_1( *gain_code, BASOP_Util_Divide1616_Scale( g_code2, g_code, &s ) );
     305           0 :     L_tmp = L_shl( L_tmp, sub( sub( add( s, exp_gcode2 ), exp_gcode ), 2 ) ); /* Q16 */
     306           0 :     L_tmp1 = L_add( L_tmp, 0 );
     307           0 :     FOR( i = 0; i < index2; i++ )
     308             :     {
     309           0 :         L_tmp1 = L_add( L_tmp1, L_tmp );
     310             :     }
     311           0 :     *gain_code2 = L_tmp1;
     312           0 :     move32();
     313             : 
     314             : 
     315           0 :     return;
     316             : }
     317             : 
     318             : /*********************
     319             :  * public functions  *
     320             :  *********************/
     321             : 
     322        3050 : void decode_acelp_gains_fx(
     323             :     Word16 *code, /* i  : algebraic code excitation        Q9  */
     324             :     Word16 gains_mode,
     325             :     Word16 mean_ener_code, /* i  : mean_ener defined in open-loop   Q8  */
     326             :     Word16 *gain_pit,      /* o  : Quantized pitch gain            1Q14 */
     327             :     Word32 *gain_code,     /* o  : Quantized codebook gain          Q16 */
     328             :     Word16 **pt_indice,
     329             :     Word16 *past_gpit,  /* i/o: past gain of pitch              1Q14 */
     330             :     Word32 *past_gcode, /* i/o: past energy of code              Q16 */
     331             :     Word16 *gain_inov,  /* o  : unscaled innovation gain        3Q12 */
     332             :     Word16 L_subfr,     /* i  : Subframe size                    Q0  */
     333             :     Word16 *code2,      /* i  : algebraic code excitation        Q9  */
     334             :     Word32 *gain_code2  /* o  : Quantized codebook gain          Q16 */
     335             : )
     336             : {
     337        3050 :     Word16 index = 0;
     338        3050 :     move16();
     339             : 
     340        3050 :     index = **pt_indice;
     341        3050 :     ( *pt_indice )++;
     342             : 
     343        3050 :     IF( s_and( gains_mode > 0, (Word16) LT_16( gains_mode, 4 ) ) )
     344             :     {
     345             :         /* ACELP gains quantizer (5bits/subfr) */
     346        3050 :         Mode2_gain_dec_mless_fx( index, code, L_subfr, gain_pit, gain_code, mean_ener_code, past_gpit, past_gcode, gain_inov, gains_mode - 1 );
     347             :     }
     348           0 :     ELSE IF( s_or( (Word16) EQ_16( gains_mode, 4 ), (Word16) EQ_16( gains_mode, 5 ) ) )
     349             :     {
     350             :         /* AMR-WB gains quantizer (6bits/subfr (mode 2) or 7bits/subfr (mode 3)) */
     351           0 :         assert( 0 );
     352             :     }
     353           0 :     ELSE IF( EQ_16( gains_mode, 6 ) )
     354             :     {
     355             :         /* UV gains quantizer (6bits/subfr) */
     356           0 :         gain_dec_uv_fx( index, code, L_subfr, gain_pit, gain_code, past_gpit, past_gcode, gain_inov );
     357             :     }
     358           0 :     ELSE IF( EQ_16( gains_mode, 7 ) )
     359             :     {
     360             :         /* GACELP_UV gains quantizer (7=5-2bits/subfr) */
     361           0 :         gain_dec_gacelp_uv_fx( index, code, code2, mean_ener_code, L_subfr, gain_pit, gain_code, gain_code2, past_gpit, past_gcode, gain_inov );
     362             :     }
     363             :     ELSE
     364             :     {
     365           0 :         IVAS_ERROR( IVAS_ERR_INTERNAL, "invalid gains coding for acelp!" );
     366             :     }
     367        3050 : }
     368             : 
     369             : 
     370             : /*---------------------------------------------------------------------*
     371             :  * d_gain_pred_fx :
     372             :  *
     373             :  * decode the predicted value for the scaled
     374             :  * innovation energy in all subframes
     375             :  *---------------------------------------------------------------------*/
     376         610 : void d_gain_pred_fx(
     377             :     Word16 nrg_mode,   /* i  : NRG moe                                   */
     378             :     Word16 *Es_pred,   /* o  : predicted scaled innovation energy    Q8  */
     379             :     Word16 **pt_indice /* i/o: pointer to the buffer of indices          */
     380             : )
     381             : {
     382             :     Word16 indice;
     383             : 
     384         610 :     indice = ( Word16 ) * *pt_indice;
     385         610 :     ( *pt_indice )++;
     386             : 
     387         610 :     *Es_pred = 0;
     388         610 :     move16();
     389             : 
     390         610 :     if ( EQ_16( nrg_mode, 1 ) )
     391             :     {
     392         610 :         *Es_pred = Es_pred_qua[indice];
     393         610 :         move16();
     394             :     }
     395             : 
     396         610 :     if ( EQ_16( nrg_mode, 2 ) )
     397             :     {
     398           0 :         *Es_pred = Es_pred_qua_2[indice];
     399           0 :         move16();
     400             :     }
     401             : 
     402         610 :     IF( GT_16( nrg_mode, 2 ) )
     403             :     {
     404           0 :         *Es_pred = extract_l( L_mac( -335544320l /* -20.f Q24*/, indice, 224 /* 1.75f Q7*/ ) ); /*(Q8 - ((Q0*Q7)=Q8))*/
     405           0 :         move16();
     406             :     }
     407             : 
     408         610 :     return;
     409             : }

Generated by: LCOV version 1.14