LCOV - code coverage report
Current view: top level - lib_dec - dec_tran_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ da9cc8ead0679b4682d329fdff98cf1616159273 Lines: 111 111 100.0 %
Date: 2025-10-13 22:24:20 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 "cnst.h"    /* Common constants                       */
       7             : #include "prot_fx.h" /* Function prototypes                    */
       8             : 
       9             : #define Q3_4   ( 4 << Q3 )
      10             : #define Q3_17  ( 17 << Q3 )
      11             : #define Q16_8  ( 8 << Q16 )
      12             : #define Q16_30 ( 30 << Q16 )
      13             : 
      14             : /*======================================================================*/
      15             : /* FUNCTION : decod_tran_fx()                                                                               */
      16             : /*----------------------------------------------------------------------*/
      17             : /* PURPOSE : Decode transition (TC) frames                                      */
      18             : /*                                                                                                                                              */
      19             : /*----------------------------------------------------------------------*/
      20             : /* GLOBAL INPUT ARGUMENTS :                                                                                             */
      21             : /* _ (Struct)   st_fx                   : decoder static memory                                 */
      22             : /* _ (Word16) L_frame_fx                : length of the frame           Q0                      */
      23             : /* _ (Word16[]) Aq_fx                   : LP filter coefficient         Q12                     */
      24             : /* _ (Word16) coder_type                : coding type                           Q12                     */
      25             : /* _ (Word16) Es_pred_fx                : predicted scaled innov. energy Q8             */
      26             : /* _ (Word16[]) pitch_buf_fx    : floating pitch values for each subframe Q6*/
      27             : /* _ (Word16[]) voice_factors_fx: frame error rate                              Q15             */
      28             : /*-----------------------------------------------------------------------*/
      29             : /* OUTPUT ARGUMENTS :                                                                                                    */
      30             : /* _ (Word16[]) exc_fx                  : adapt. excitation exc (Q_exc)                  */
      31             : /* _ (Word16[]) exc2_fx                 : adapt. excitation/total exc (Q_exc)    */
      32             : /*-----------------------------------------------------------------------*/
      33             : 
      34             : 
      35             : /*-----------------------------------------------------------------------*/
      36             : /* RETURN ARGUMENTS :                                                                                                    */
      37             : /* _ None                                                                                                                                */
      38             : /*=======================================================================*/
      39             : 
      40       13057 : void decod_tran_fx(
      41             :     Decoder_State *st_fx,     /* i/o: decoder static memory                  */
      42             :     const Word16 L_frame_fx,  /* i  : length of the frame                    */
      43             :     const Word16 tc_subfr_fx, /* i  : TC subframe index                      */
      44             :     const Word16 *Aq_fx,      /* i  : LP filter coefficient                  */
      45             :     const Word16 Es_pred_fx,  /* i  : predicted scaled innov. energy         */
      46             :     Word16 *pitch_buf_fx,     /* o  : floating pitch values for each subframe*/
      47             :     Word16 *voice_factors_fx, /* o  : voicing factors                        */
      48             :     Word16 *exc_fx,           /* i/o: adapt. excitation exc                  */
      49             :     Word16 *exc2_fx,          /* i/o: adapt. excitation/total exc            */
      50             :     Word16 *bwe_exc_fx,       /* i/o: excitation for SWB TBE                 */
      51             :     Word16 *unbits,           /* i/o: number of unused bits                  */
      52             :     const Word16 sharpFlag,   /* i  : formant sharpening flag                */
      53             :     Word16 *gain_buf          /* o  : floating pitch gain for each subframe  */
      54             : )
      55             : {
      56             :     Word16 T0, T0_frac, T0_min, T0_max; /* integer pitch variables                     */
      57             :     Word32 gain_code_fx;                /* Quantized algebraic codeebook gain          */
      58             :     Word32 norm_gain_code_fx;           /* normalized algebraic codeebook gain         */
      59             :     Word16 gain_pit_fx;                 /* Quantized pitch gain                        */
      60             :     Word16 voice_fac_fx;                /* Voicing factor                              */
      61             :     Word16 gain_inov_fx;                /* inovation gain                              */
      62             :     Word16 code_fx[L_SUBFR];            /* algebraic codevector                        */
      63             :     const Word16 *p_Aq_fx;              /* pointer to lp filter coefficient            */
      64             :     Word16 *pt_pitch_fx;                /* pointer to floating pitch                   */
      65             :     Word16 i_subfr, i;                  /* tmp variables                               */
      66             :     Word16 position;                    /* TC related flag                             */
      67             :     Word16 gain_preQ_fx;                /* Gain of prequantizer excitation             */
      68             :     Word16 code_preQ_fx[L_SUBFR];       /* Prequantizer excitation                     */
      69             :     Word16 Jopt_flag;                   /* flag indicating zero adaptive contribtuion  */
      70             :     Word32 norm_gain_preQ_fx;
      71             :     Word16 gain_code16;
      72             :     Word32 L_tmp;
      73             :     Word16 tmp16, tmp1_fx, tmp_fx;
      74             : #ifdef FIX_2010_PREP_TBE_EXC
      75             :     Word16 Q_code_preQ;
      76             : #endif
      77             :     GSC_DEC_HANDLE hGSCDec;
      78       13057 :     hGSCDec = st_fx->hGSCDec;
      79             :     MUSIC_POSTFILT_HANDLE hMusicPF;
      80       13057 :     hMusicPF = st_fx->hMusicPF;
      81             : 
      82             : 
      83       13057 :     gain_code_fx = 0; /* Quantized algebraic codeebook gain          */
      84       13057 :     move32();
      85       13057 :     norm_gain_code_fx = 0; /* normalized algebraic codeebook gain Q16        */
      86       13057 :     move32();
      87       13057 :     gain_pit_fx = 0; /* Quantized pitch gain Q14                        */
      88       13057 :     move16();
      89       13057 :     gain_inov_fx = 0; /* inovation gain                              */
      90       13057 :     move16();
      91       13057 :     gain_preQ_fx = 0; /* Gain of prequantizer excitation Q2            */
      92       13057 :     move16();
      93             : 
      94       13057 :     set16_fx( code_preQ_fx, 0, L_SUBFR ); // Q10
      95             :     /*----------------------------------------------------------------*
      96             :      * ACELP subframe loop
      97             :      *----------------------------------------------------------------*/
      98             : 
      99       13057 :     p_Aq_fx = Aq_fx;            // Q12
     100       13057 :     pt_pitch_fx = pitch_buf_fx; // Q6
     101       13057 :     Jopt_flag = 0;
     102       13057 :     move16();
     103       13057 :     norm_gain_preQ_fx = 0;
     104       13057 :     move16();
     105             : 
     106       71690 :     FOR( i_subfr = 0; i_subfr < L_frame_fx; i_subfr += L_SUBFR )
     107             :     {
     108             :         /*------------------------------------------------------------*
     109             :          * TC : subframe determination &
     110             :          * adaptive/glottal part of excitation construction
     111             :          *------------------------------------------------------------*/
     112             : 
     113       58633 :         test();
     114       58633 :         IF( i_subfr == 0 && GT_16( st_fx->Q_exc, 2 ) )
     115             :         {
     116        7989 :             tmp16 = sub( 2, st_fx->Q_exc );
     117        7989 :             Scale_sig( exc_fx - L_EXC_MEM, L_EXC_MEM, tmp16 );               // Q2
     118        7989 :             Scale_sig( bwe_exc_fx - PIT16k_MAX * 2, PIT16k_MAX * 2, tmp16 ); // Q2
     119        7989 :             Scale_sig( hGSCDec->last_exc_dct_in_fx, L_FRAME, tmp16 );        // Q2
     120        7989 :             st_fx->Q_exc = add( st_fx->Q_exc, tmp16 );
     121        7989 :             move16();
     122             :         }
     123             : 
     124       58633 :         transition_dec_fx( st_fx, 0, L_frame_fx, i_subfr, tc_subfr_fx, &Jopt_flag, exc_fx,
     125             :                            &T0, &T0_frac, &T0_min, &T0_max, &pt_pitch_fx, &position, bwe_exc_fx, &st_fx->Q_exc );
     126             :         /*-----------------------------------------------------------------*
     127             :          * Transform domain contribution decoding - active frames
     128             :          *-----------------------------------------------------------------*/
     129       58633 :         IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) )
     130             :         {
     131        5835 :             gain_code_fx = 0;
     132        5835 :             move16();
     133        5835 :             transf_cdbk_dec_fx( st_fx, 0, i_subfr, Es_pred_fx, gain_code_fx, &gain_preQ_fx, &norm_gain_preQ_fx, code_preQ_fx, unbits );
     134             :         }
     135             : 
     136             :         /*-----------------------------------------------------------------*
     137             :          * ACELP codebook search + pitch sharpening
     138             :          *-----------------------------------------------------------------*/
     139             : 
     140       58633 :         inov_decode_fx( st_fx, st_fx->core_brate, 0, L_frame_fx, sharpFlag, i_subfr, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_SUBFR );
     141             : 
     142             :         /*-----------------------------------------------------------------*
     143             :          * De-quantize the gains
     144             :          * Update tilt of code: 0.0 (unvoiced) to 0.5 (voiced)
     145             :          *-----------------------------------------------------------------*/
     146             : 
     147       58633 :         IF( Jopt_flag == 0 )
     148             :         {
     149             :             /* 2/3-bit decoding */
     150       18191 :             IF( st_fx->element_mode == EVS_MONO )
     151             :             {
     152          90 :                 gain_dec_tc_fx( st_fx, code_fx, i_subfr, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx );
     153             :             }
     154             :             ELSE
     155             :             {
     156       18101 :                 gain_dec_tc_ivas_fx( st_fx, code_fx, i_subfr, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx );
     157             :             }
     158             :         }
     159             :         ELSE
     160             :         {
     161             :             /* 5-bit decoding */
     162       40442 :             IF( GT_32( st_fx->core_brate, ACELP_32k ) )
     163             :             {
     164        2747 :                 gain_dec_SQ_fx( st_fx, i_subfr, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx );
     165             :             }
     166             :             ELSE
     167             :             {
     168       37695 :                 gain_dec_mless_fx( st_fx, L_frame_fx, st_fx->coder_type, i_subfr, tc_subfr_fx, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx );
     169             :             }
     170             :         }
     171             : 
     172             :         /* update LP filtered gains for the case of frame erasures */
     173       58633 :         IF( st_fx->element_mode == EVS_MONO )
     174             :         {
     175         546 :             lp_gain_updt_fx( i_subfr, gain_pit_fx, L_add( norm_gain_code_fx, norm_gain_preQ_fx ), &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_frame_fx );
     176             : 
     177         546 :             st_fx->tilt_code_fx = est_tilt_fx( exc_fx + i_subfr, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, st_fx->Q_exc );
     178         546 :             move16();
     179             :         }
     180             :         ELSE
     181             :         {
     182       58087 :             lp_gain_updt_ivas_fx( i_subfr, gain_pit_fx, L_add( norm_gain_code_fx, norm_gain_preQ_fx ), &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_frame_fx );
     183             : 
     184       58087 :             st_fx->tilt_code_fx = est_tilt_ivas_fx( exc_fx + i_subfr, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, st_fx->Q_exc, L_SUBFR, 0 );
     185       58087 :             move16();
     186             :         }
     187             : 
     188             :         /*----------------------------------------------------------------------*
     189             :          * Find the total excitation
     190             :          *----------------------------------------------------------------------*/
     191       58633 :         test();
     192       58633 :         test();
     193       58633 :         test();
     194       58633 :         IF( st_fx->element_mode > EVS_MONO && ( GE_16( add( i_subfr, L_SUBFR ), tc_subfr_fx ) && LT_16( i_subfr, tc_subfr_fx ) && GT_16( st_fx->Q_subfr[0], 4 ) ) )
     195             :         {
     196        4830 :             test();
     197        4830 :             test();
     198        4830 :             test();
     199        4830 :             IF( GE_16( st_fx->Q_subfr[0], 7 ) && LE_32( st_fx->lp_gainc_fx, Q3_4 ) && LE_32( norm_gain_code_fx, Q16_8 ) )
     200             :             {
     201        1418 :                 st_fx->Q_subfr[0] = s_min( st_fx->Q_subfr[0], 4 );
     202        1418 :                 move16();
     203             :             }
     204        3412 :             ELSE IF( LE_32( st_fx->lp_gainc_fx, Q3_17 ) && LE_32( L_sub( gain_code_fx, norm_gain_code_fx ), Q16_30 ) )
     205             :             {
     206        2077 :                 st_fx->Q_subfr[0] = s_min( 4, sub( st_fx->Q_subfr[0], 2 ) );
     207        2077 :                 move16();
     208             :             }
     209             :         }
     210       58633 :         IF( EQ_16( L_frame_fx, L_FRAME ) ) /* Rescaling for 12.8k core */
     211             :         {
     212       26608 :             Rescale_exc( hMusicPF->dct_post_old_exc_fx, &exc_fx[i_subfr], &bwe_exc_fx[( ( i_subfr * 2 * HIBND_ACB_L_FAC ) >> 1 )], hGSCDec->last_exc_dct_in_fx,
     213       26608 :                          L_SUBFR, L_SUBFR * HIBND_ACB_L_FAC, gain_code_fx, &( st_fx->Q_exc ), st_fx->Q_subfr, exc2_fx, i_subfr, st_fx->coder_type );
     214             :         }
     215             :         ELSE /* Rescaling for 16k core */
     216             :         {
     217       32025 :             Rescale_exc( hMusicPF->dct_post_old_exc_fx, &exc_fx[i_subfr], &bwe_exc_fx[i_subfr * 2], hGSCDec->last_exc_dct_in_fx,
     218       32025 :                          L_SUBFR, L_SUBFR * 2, gain_code_fx, &( st_fx->Q_exc ), st_fx->Q_subfr, exc2_fx, i_subfr, st_fx->coder_type );
     219             :         }
     220             : 
     221       58633 :         gain_code16 = round_fx( L_shl( gain_code_fx, st_fx->Q_exc ) ); /*Q_exc*/
     222       58633 :         Acelp_dec_total_exc( exc_fx, exc2_fx, gain_code16, gain_pit_fx, i_subfr, code_fx, L_SUBFR );
     223             : 
     224             :         /*-----------------------------------------------------------------*
     225             :          * Add the ACELP pre-quantizer contribution
     226             :          *-----------------------------------------------------------------*/
     227       58633 :         IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) )
     228             :         {
     229        5835 :             IF( ( st_fx->element_mode == EVS_MONO ) )
     230             :             {
     231         250 :                 tmp1_fx = add( 15 - Q_AVQ_OUT_DEC - 2, st_fx->Q_exc );
     232             :             }
     233             :             ELSE
     234             :             {
     235        5585 :                 tmp1_fx = add( 15 - Q_AVQ_OUT - 2, st_fx->Q_exc );
     236             :             }
     237      379275 :             FOR( i = 0; i < L_SUBFR; i++ )
     238             :             {
     239      373440 :                 L_tmp = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /* Q2 + Q10 -> Q13*/
     240      373440 :                 L_tmp = L_shl_sat( L_tmp, tmp1_fx );             /* Q16 + Q_exc      */
     241      373440 :                 tmp_fx = round_fx_sat( L_tmp );
     242      373440 :                 exc2_fx[i + i_subfr] = add_sat( exc2_fx[i + i_subfr], tmp_fx );
     243      373440 :                 move16();
     244      373440 :                 exc_fx[i + i_subfr] = add_sat( exc_fx[i + i_subfr], tmp_fx );
     245      373440 :                 move16();
     246             :             }
     247             :         }
     248             : 
     249             :         /*-----------------------------------------------------------------*
     250             :          * Prepare TBE excitation
     251             :          *-----------------------------------------------------------------*/
     252             :         Word16 tmp_idx_2;
     253       58633 :         tmp_idx_2 = 0;
     254       58633 :         move16();
     255       58633 :         if ( i_subfr != 0 )
     256             :         {
     257       45576 :             tmp_idx_2 = idiv1616( i_subfr, L_SUBFR );
     258             :         }
     259             : 
     260             : #ifdef FIX_2010_PREP_TBE_EXC
     261             :         /*
     262             :           2025-09-15 multrus:
     263             :           TODO:
     264             :           check with vaillancourt
     265             :           - where this difference between EVS and IVAS comes from
     266             :           - where Q_code_preQ could be derived
     267             :           - whether any of the above calculations need to be adjusted
     268             :          */
     269       58633 :         Q_code_preQ = Q6;
     270       58633 :         move16();
     271       58633 :         if ( EQ_16( st_fx->element_mode, EVS_MONO ) )
     272             :         {
     273         546 :             Q_code_preQ = Q10;
     274         546 :             move16();
     275             :         }
     276             : 
     277       58633 :         prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx,
     278       58633 :                          &voice_factors_fx[tmp_idx_2], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_code_preQ,
     279       58633 :                          st_fx->Q_exc, T0, T0_frac, st_fx->coder_type, st_fx->core_brate,
     280       58633 :                          st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag );
     281             : #else
     282             :         prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx,
     283             :                          &voice_factors_fx[tmp_idx_2], bwe_exc_fx, gain_preQ_fx, code_preQ_fx,
     284             :                          st_fx->Q_exc, T0, T0_frac, st_fx->coder_type, st_fx->core_brate,
     285             :                          st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag );
     286             : #endif
     287             : 
     288             :         /*----------------------------------------------------------------*
     289             :          * Excitation enhancements (update of total excitation signal)
     290             :          *----------------------------------------------------------------*/
     291             : 
     292       58633 :         IF( GT_32( st_fx->core_brate, ACELP_32k ) )
     293             :         {
     294        4010 :             Copy( exc_fx + i_subfr, exc2_fx + i_subfr, L_SUBFR );
     295             :         }
     296             :         ELSE
     297             :         {
     298       54623 :             enhancer_fx( st_fx->core_brate, 0, st_fx->coder_type, i_subfr, L_frame_fx, voice_fac_fx, st_fx->stab_fac_fx,
     299       54623 :                          norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc );
     300             :         }
     301             : 
     302             :         Word16 tmp_idx;
     303       58633 :         tmp_idx = 0;
     304       58633 :         move16();
     305       58633 :         if ( i_subfr != 0 )
     306             :         {
     307       45576 :             tmp_idx = idiv1616( i_subfr, L_SUBFR );
     308             :         }
     309       58633 :         p_Aq_fx += ( M + 1 );
     310       58633 :         pt_pitch_fx++;
     311       58633 :         st_fx->tilt_code_dec_fx[tmp_idx] = st_fx->tilt_code_fx; // Q15
     312       58633 :         move16();
     313       58633 :         gain_buf[tmp_idx] = gain_pit_fx; // Q14
     314       58633 :         move16();
     315             :     }
     316             : 
     317             :     /* SC-VBR */
     318       13057 :     st_fx->prev_gain_pit_dec_fx = gain_pit_fx;
     319       13057 :     move16(); /*Q14*/
     320             : 
     321       13057 :     return;
     322             : }

Generated by: LCOV version 1.14