LCOV - code coverage report
Current view: top level - lib_dec - gaus_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 15 106 14.2 %
Date: 2025-05-03 01:55:50 Functions: 1 4 25.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             : 
      11             : /*---------------------------------------------------------------------*
      12             :  * Local function prototypes
      13             :  *---------------------------------------------------------------------*/
      14             : 
      15             : void gaus_dec2v_fx( Decoder_State *st_fx, Word16 *code, const Word16 lg, const Word16 nb_bits );
      16             : static void dec_2pos_fx( Word16 index, Word16 *ind1, Word16 *ind2, Word16 *sign1, Word16 *sign2, Word16 log2_n );
      17             : 
      18             : /*---------------------------------------------------------------------*
      19             :  * gaus_dec()
      20             :  *
      21             :  * no adaptive excitation constructed
      22             :  * - decode the codebook indices,
      23             :  * - find the excitation
      24             :  *---------------------------------------------------------------------*/
      25           0 : void gaus_dec_fx(
      26             :     Decoder_State *st_fx,     /* i/o: decoder static memory                                */
      27             :     const Word16 i_subfr,     /* i              : subframe index                                  */
      28             :     Word16 *code,             /* o              : unvoiced excitation                        Q12  */
      29             :     Word32 *L_norm_gain_code, /* o              : gain of normalized gaussian excitation     Q16  */
      30             :     Word16 *lp_gainp,         /* i/o            : lp filtered pitch gain(FER)                Q14  */
      31             :     Word16 *lp_gainc,         /* i/o            : lp filtered code gain (FER)                Q3   */
      32             :     Word16 *inv_gain_inov,    /* o              : unscaled innovation gain                   Q12  */
      33             :     Word16 *tilt_code,        /* o              : synthesis excitation spectrum tilt         Q15  */
      34             :     Word16 *voice_fac,        /* o              : estimated voicing factor                   Q15  */
      35             :     Word16 *gain_pit,         /* o              : pitch gain                                 Q14  */
      36             :     Word16 *pt_pitch_1,       /* o              : floating pitch buffer                                          Q6   */
      37             :     Word16 *exc,              /* o              : excitation signal frame                         */
      38             :     Word32 *L_gain_code,      /* o              : gain of the gaussian excitation            Q16  */
      39             :     Word16 *exc2,             /* o              : Scaled excitation signal frame                  */
      40             :     Word16 *bwe_exc_fx,
      41             :     Word16 *sQ_exc, /* i/o              : Excitation scaling factor (Decoder state)       */
      42             :     Word16 *sQsubfr /* i/o              : Past excitation scaling factors (Decoder State) */
      43             : )
      44             : {
      45             :     Word16 i, exp, gain_code;
      46             :     Word16 idx, nb_bits;
      47             :     Word32 L_tmp;
      48             :     GSC_DEC_HANDLE hGSCDec;
      49           0 :     hGSCDec = st_fx->hGSCDec;
      50             :     MUSIC_POSTFILT_HANDLE hMusicPF;
      51           0 :     hMusicPF = st_fx->hMusicPF;
      52             : 
      53             :     /*------------------------------------------------------------------------------------------*
      54             :      * Unvoiced : Gaussian codebook
      55             :      *------------------------------------------------------------------------------------------*/
      56           0 :     nb_bits = st_fx->acelp_cfg.fixed_cdk_index[( i_subfr / 64 )];
      57           0 :     move16();
      58             : 
      59           0 :     gaus_dec2v_fx( st_fx, code, L_SUBFR, shr( nb_bits, 1 ) );
      60             : 
      61             :     /*------------------------------------------------------------------------------------------*
      62             :      * - Gain of Gaussian excitation and normalized Gaussian excitation
      63             :      *------------------------------------------------------------------------------------------*/
      64             :     /* gain_inov = 1.0f / (float)sqrt((dot_product(code, code, L_SUBFR) + 0.01f) / L_SUBFR) */
      65           0 :     L_tmp = Dot_product12( code, code, L_SUBFR, &exp );
      66           0 :     exp = sub( exp, 18 /*24*/ + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
      67           0 :     L_tmp = Isqrt_lc( L_tmp, &exp );
      68           0 :     *inv_gain_inov = extract_h( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /* inv_gain_inov in Q12 */
      69           0 :     move16();
      70             : 
      71           0 :     nb_bits = st_fx->acelp_cfg.gains_mode[( i_subfr / 64 )];
      72           0 :     move16();
      73           0 :     idx = (Word16) get_next_indice_fx( st_fx, nb_bits );
      74           0 :     move16();
      75             : 
      76             :     /* safety check in case of bit errors */
      77           0 :     test();
      78           0 :     IF( GT_16( idx, 78 ) && st_fx->element_mode == EVS_MONO )
      79             :     {
      80           0 :         idx = 78;
      81           0 :         move16();
      82           0 :         st_fx->BER_detect = 1;
      83           0 :         move16();
      84             :     }
      85             : 
      86           0 :     *L_gain_code = gain_dec_gaus_fx( idx, nb_bits, -30, 190, *inv_gain_inov, L_norm_gain_code ); /*Q16*/
      87           0 :     move32();
      88             : 
      89             :     /* update LP filtered gains for the case of frame erasures */
      90           0 :     IF( st_fx->element_mode == EVS_MONO )
      91             :     {
      92           0 :         lp_gain_updt_fx( i_subfr, 0, *L_norm_gain_code, lp_gainp, lp_gainc, L_FRAME ); /* supposes that gain_dec_gaus() is used for ACELP@12k8 only */
      93             :     }
      94             :     ELSE
      95             :     {
      96           0 :         lp_gain_updt_ivas_fx( i_subfr, 0, *L_norm_gain_code, lp_gainp, lp_gainc, L_FRAME ); /* supposes that gain_dec_gaus() is used for ACELP@12k8 only */
      97             :     }
      98             : 
      99             :     /*------------------------------------------------------------------------------------------*
     100             :      * Updates
     101             :      *------------------------------------------------------------------------------------------*/
     102             : 
     103           0 :     *tilt_code = 0;
     104           0 :     move16();
     105           0 :     *voice_fac = -32768; /* only unvoiced             Q15 */
     106           0 :     move16();
     107           0 :     *gain_pit = 0; /* needed for BASS postfitler */
     108           0 :     move16();
     109           0 :     *pt_pitch_1 = 4096; /* floating pitch buffer  Q6    */
     110           0 :     move16();
     111             : 
     112             :     /*------------------------------------------------------------------------------------------*
     113             :      * Construct scaled excitation
     114             :      *------------------------------------------------------------------------------------------*/
     115             : 
     116           0 :     set16_fx( &exc[i_subfr], 0, L_SUBFR );
     117           0 :     set16_fx( &exc2[i_subfr], 0, L_SUBFR );
     118             : 
     119           0 :     IF( EQ_16( st_fx->L_frame, L_FRAME ) )
     120             :     {
     121           0 :         Rescale_exc( hMusicPF->dct_post_old_exc_fx, &exc[i_subfr], &bwe_exc_fx[i_subfr * HIBND_ACB_L_FAC], hGSCDec->last_exc_dct_in_fx,
     122             :                      L_SUBFR, L_SUBFR * HIBND_ACB_L_FAC, *L_gain_code, sQ_exc, sQsubfr, exc2, i_subfr, UNVOICED );
     123             :     }
     124             :     ELSE
     125             :     {
     126           0 :         Rescale_exc( hMusicPF->dct_post_old_exc_fx, &exc[i_subfr], &bwe_exc_fx[i_subfr * 2], hGSCDec->last_exc_dct_in_fx,
     127             :                      L_SUBFR, L_SUBFR * 2, *L_gain_code, sQ_exc, sQsubfr, exc2, i_subfr, UNVOICED );
     128             :     }
     129             : 
     130           0 :     gain_code = round_fx( L_shl( *L_gain_code, *sQ_exc ) ); /*sQ_exc*/
     131           0 :     FOR( i = 0; i < L_SUBFR; i++ )
     132             :     {
     133           0 :         L_tmp = L_shl( L_mult( gain_code, code[i] ), 6 /*3*/ );
     134           0 :         exc[( i + i_subfr )] = round_fx( L_tmp ); /*sQ_exc+3*/
     135           0 :         move16();
     136             :     }
     137             : 
     138           0 :     return;
     139             : }
     140             : 
     141             : 
     142             : /*-----------------------------------------------------*
     143             :  * gaus_dec2v()
     144             :  *
     145             :  * decoder of Gaussian Codebook for unvoiced
     146             :  * consisting of addition of 2 Gaussian vectors
     147             :  *
     148             :  * One Gaussian vector of 190 values
     149             :  *-----------------------------------------------------*/
     150             : 
     151           0 : void gaus_dec2v_fx(
     152             :     Decoder_State *st_fx, /* i/o: decoder state structure           */
     153             :     Word16 *code,         /* o  : decoded gaussian vector   Q12-exp */
     154             :     const Word16 lg,      /* i  : codevector length         Q0      */
     155             :     const Word16 nb_bits  /* i  : nb ob bits per track (max 6)      */
     156             : )
     157             : {
     158             :     Word16 i, ind1, ind2, idx;
     159             :     Word16 step;
     160             :     Word16 sign1, sign2;
     161             :     Word16 delta, delta2, inv_delta;
     162             :     Word16 gaus_dico2_fx[190];
     163             :     Word16 tmp16;
     164             :     const Word16 *pt1, *pt2;
     165             :     Word16 index_delta;
     166             : 
     167           0 :     step = shr( 0x80, nb_bits ); /*Q0*/
     168             : 
     169           0 :     idx = (Word16) get_next_indice_fx( st_fx, add( shl( nb_bits, 1 ), 1 ) ); /*Q0*/
     170           0 :     index_delta = (Word16) get_next_indice_fx( st_fx, 3 );                   /*Q0*/
     171           0 :     move16();
     172           0 :     move16();
     173             : 
     174           0 :     dec_2pos_fx( idx, &ind1, &ind2, &sign1, &sign2, nb_bits );
     175             : 
     176           0 :     delta = shl( index_delta, STEP_DELTA_FX );
     177           0 :     delta2 = mac_r( 16384 * 65536, shr( delta, 1 ), delta );
     178           0 :     inv_delta = div_s( 16384, delta2 ); /*Q15*/
     179             : 
     180           0 :     IF( delta > 0 )
     181             :     {
     182           0 :         gaus_dico2_fx[0] = gaus_dico_fx[0];
     183           0 :         move16(); /*Q12             */
     184           0 :         FOR( i = 1; i < 190; i++ )
     185             :         {
     186             :             /* gaus_dico2[i] = (gaus_dico_fx[i] - delta*gaus_dico_fx[i-1])/(1+delta*delta) */
     187           0 :             tmp16 = msu_r( L_deposit_h( gaus_dico_fx[i] ), delta, gaus_dico_fx[i - 1] ); /*Q12*/
     188           0 :             gaus_dico2_fx[i] = mult_r( tmp16, inv_delta );                               /*Q12*/
     189           0 :             move16();
     190             :         }
     191             :     }
     192             :     ELSE
     193             :     {
     194           0 :         FOR( i = 0; i < 190; i++ )
     195             :         {
     196           0 :             gaus_dico2_fx[i] = gaus_dico_fx[i];
     197           0 :             move16(); /*Q12 */
     198             :         }
     199             :     }
     200             : 
     201           0 :     pt1 = &gaus_dico2_fx[( ind1 * step )]; /*Q12*/
     202           0 :     pt2 = &gaus_dico2_fx[( ind2 * step )]; /*Q12*/
     203             : 
     204           0 :     FOR( i = 0; i < lg; i++ )
     205             :     {
     206             :         /* code is Q9, Gaussian codebook is Q12 */
     207             :         /* code[i] = pt1[i] * sign1 + pt2[i] * sign2 */
     208           0 :         code[i] = add( mult( pt1[i], sign1 ), mult( pt2[i], sign2 ) ); /*Q12-exp*/
     209           0 :         move16();
     210             :     }
     211             : 
     212           0 :     return;
     213             : }
     214             : 
     215             : 
     216             : /*-----------------------------------------------------*
     217             :  * dec_2pos()
     218             :  *
     219             :  * Decode the codevectors positions and signs
     220             :  *-----------------------------------------------------*/
     221           0 : static void dec_2pos_fx(
     222             :     Word16 index,  /* i  : quantization index      Q0  */
     223             :     Word16 *ind1,  /* o  : 1st vector index        Q0 */
     224             :     Word16 *ind2,  /* o  : 2nd vector index        Q0 */
     225             :     Word16 *sign1, /* o  : 1st vector sign         Q0 */
     226             :     Word16 *sign2, /* o  : 2nd vector sign         Q0 */
     227             :     Word16 log2_n  /* i  : Log2(number of vector)  Q0  */
     228             : )
     229             : {
     230             :     Word16 i;
     231             : 
     232           0 :     i = s_and( index, 1 );
     233           0 :     *sign1 = ( -32768 ); /* -1 (Q15) */
     234           0 :     move16();
     235           0 :     if ( i == 0 )
     236             :     {
     237           0 :         *sign1 = MAX_16; /* 1 (Q15) */
     238           0 :         move16();
     239             :     }
     240           0 :     *sign1 = shr( *sign1, 3 );
     241           0 :     move16(); /* To have code dec in Q9 instead of Q12 */
     242             : 
     243           0 :     index = shr( index, 1 );
     244             : 
     245           0 :     *ind1 = shr( index, log2_n ); /*Q0*/
     246           0 :     move16();
     247           0 :     *ind2 = sub( index, shl( *ind1, log2_n ) ); /*Q0*/
     248           0 :     move16();
     249           0 :     *sign2 = *sign1;
     250           0 :     move16();
     251           0 :     IF( GT_16( *ind1, *ind2 ) )
     252             :     {
     253           0 :         *sign2 = negate( *sign1 );
     254           0 :         move16();
     255             :     }
     256           0 :     return;
     257             : }
     258             : 
     259             : 
     260             : /*-----------------------------------------------------*
     261             :  * gaus_L2_dec :
     262             :  *
     263             :  * decoder of Gaussian Codebook for unvoiced as Layer 2
     264             :  *
     265             :  * One Gaussian vector
     266             :  *-----------------------------------------------------*/
     267        5496 : void gaus_L2_dec(
     268             :     Word16 *code,       /* o  : decoded gaussian codevector     Q9  */
     269             :     Word16 tilt_code,   /* i  : tilt of code                    Q15 */
     270             :     const Word16 *A,    /* i  : quantized LPCs                  Q12 */
     271             :     Word16 formant_enh, /* i  : formant enhancement factor      Q15 */
     272             :     Word16 *seed_acelp  /*i/o : random seed                     Q0  */
     273             : )
     274             : {
     275             :     Word16 i, seed;
     276             :     Word32 tmp32;
     277             : 
     278             :     /*Generate white gaussian noise using central limit theorem method (N only 4 as E_util_random is not purely uniform)*/
     279        5496 :     seed = *seed_acelp; /*Q0*/
     280        5496 :     move16();
     281      357240 :     FOR( i = 0; i < L_SUBFR; i++ )
     282             :     {
     283      351744 :         Random( &seed );
     284      351744 :         tmp32 = L_mac( 0, seed, 1 << 9 ); /*Q9*/
     285             : 
     286      351744 :         Random( &seed );
     287      351744 :         tmp32 = L_mac( tmp32, seed, 1 << 9 ); /*Q9*/
     288             : 
     289      351744 :         Random( &seed );
     290      351744 :         code[i] = mac_r( tmp32, seed, 1 << 9 ); /*Q9*/
     291      351744 :         move16();
     292             :     }
     293        5496 :     *seed_acelp = seed; /*Q0*/
     294        5496 :     move16();
     295             : 
     296             :     /*Shape the gaussian excitation*/
     297        5496 :     cb_shape_fx( 1, 0, 0, 1, 0, formant_enh, FORMANT_SHARPENING_G2, A, code, tilt_code, 0, 1, L_SUBFR );
     298             : 
     299             : 
     300        5496 :     return;
     301             : }

Generated by: LCOV version 1.14