LCOV - code coverage report
Current view: top level - lib_enc - hf_cod_amrwb_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 8c2c66c735e1c8ef166473ecb3aee5dd03cf9eca Lines: 8 82 9.8 %
Date: 2025-09-19 03:28:21 Functions: 1 2 50.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 "cnst.h"
       9             : #include "rom_com.h"     /* Common constants                       */
      10             : #include "prot_fx.h"     /* Function prototypes                    */
      11             : #include "prot_fx_enc.h" /* Function prototypes                    */
      12             : #include "basop_util.h"  /* Function prototypes                    */
      13             : 
      14             : 
      15             : /*---------------------------------------------------------------------*
      16             :  * hf_cod_init()
      17             :  *
      18             :  *
      19             :  *---------------------------------------------------------------------*/
      20             : 
      21           3 : void hf_cod_init_fx(
      22             :     Word16 *mem_hp400_enc,  /* o: memory of hp 400 Hz filter   */
      23             :     Word16 *mem_hf1_enc,    /* o: HF band-pass filter memory   */
      24             :     Word16 *mem_syn_hf_enc, /* o: HF synthesis memory          */
      25             :     Word16 *mem_hf2_enc,    /* o: HF band-pass filter memory   */
      26             :     Word16 *gain_alpha_fx   /* o: smoothing gain for transitions between active and inactive frames */
      27             : )
      28             : {
      29           3 :     set16_fx( mem_hp400_enc, 0, 6 );
      30           3 :     set16_fx( mem_hf1_enc, 0, L_FIR - 1 );
      31           3 :     set16_fx( mem_syn_hf_enc, 0, M );
      32           3 :     set16_fx( mem_hf2_enc, 0, L_FIR - 1 );
      33             : 
      34           3 :     *gain_alpha_fx = 16384;
      35           3 :     move16();
      36             : 
      37           3 :     return;
      38             : }
      39             : 
      40             : /*---------------------------------------------------------------------*
      41             :  * hf_cod()
      42             :  *
      43             :  *
      44             :  *---------------------------------------------------------------------*/
      45             : 
      46           0 : void hf_cod_fx(
      47             :     const Word32 core_brate_fx, /* i  : core bitrate                 */
      48             :     const Word16 *speech16k_fx, /* i  : original speech at 16 kHz    */
      49             :     const Word16 Aq_fx[],       /* i  : quantized Aq                 */
      50             :     const Word16 exc_fx[],      /* i  : excitation at 12.8 kHz       */
      51             :     Word16 synth_fx[],          /* i  : 12.8kHz synthesis signal     */
      52             :     Word16 *seed2_enc_fx,       /* i/o: random seed for HF noise gen */
      53             :     Word16 *mem_hp400_enc_fx,   /* i/o: memory of hp 400 Hz filter   */
      54             :     Word16 *mem_syn_hf_enc_fx,  /* i/o: HF synthesis memory          */
      55             :     Word16 *mem_hf1_enc_fx,     /* i/o: HF band-pass filter memory   */
      56             :     Word16 *mem_hf2_enc_fx,     /* i/o: HF band-pass filter memory   */
      57             :     const Word16 dtxHangoverCount_fx,
      58             :     Word16 *gain_alpha_fx, /* i/o: smoothing gain for transitions between active and inactive frames */
      59             :     Word16 *hf_gain_fx,    /* o  :  HF gain to be transmitted to decoder */
      60             :     Word16 Q_exc,
      61             :     Word16 Q_syn )
      62             : {
      63             :     /*------------------------Scaling-------------------------------------------------
      64             :     speech16k - Q0
      65             :     Aq - Q12
      66             :     exc - Q_exc
      67             :     synth - Q_syn
      68             :     mem_hp400_enc - Q_syn
      69             :     mem_syn_hf_enc - Q0
      70             :     mem_hf1_enc - Q0
      71             :     mem_hf2_enc - Q0
      72             :     gain_alpha_fx - Q14
      73             :     ener - all dynamic
      74             :     fac, scale - Q12
      75             :     Ap - Q12
      76             :     HF_SP - Q0
      77             :     ---------------------------------------------------------------------------------*/
      78             : 
      79             :     Word16 i, q1, q2, sign;
      80             :     Word16 shift;
      81             :     Word16 ener_hf_fx, ener_exc_fx, ener_input_fx, fac_fx, tmp_fx, ener_fx, scale_fx;
      82             :     Word16 Ap_fx[M + 1];
      83             :     Word16 HF_SP_fx[L_SUBFR16k];
      84             :     Word16 HF_est_gain_fx, HF_calc_gain_fx, HF_corr_gain_fx, HF_gain_ind_fx;
      85             :     Word32 dist_min_fx, dist_fx;
      86             :     Word16 HF_fx[L_SUBFR16k], HF_syn_fx[L_SUBFR16k]; /* o  : HF excitation                */
      87             :     Word32 L_tmp;
      88             :     Word16 *pt1;
      89             :     const Word16 *pt2;
      90             : #ifndef ISSUE_1867_replace_overflow_libenc
      91             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      92             :     Flag Overflow = 0;
      93             : #endif
      94             : #endif
      95             : 
      96             :     /* Original speech signal as reference for high band gain quantisation */
      97           0 :     Copy( speech16k_fx, HF_SP_fx, L_SUBFR16k );
      98             : 
      99             :     /*-----------------------------------------------------------------*
     100             :      * generate white noise vector
     101             :      *-----------------------------------------------------------------*/
     102             : 
     103           0 :     Random_Fill( seed2_enc_fx, L_SUBFR16k, HF_fx, 3 ); /*Q(-3) */
     104             : 
     105             :     /*-----------------------------------------------------------------*
     106             :      * calculate energy scaling factor so that white noise would have the
     107             :      * same energy as exc12k8
     108             :      *-----------------------------------------------------------------*/
     109             : 
     110           0 :     ener_exc_fx = dot_prod_satcontr( exc_fx, exc_fx, Q_exc, Q_exc, &q1, L_SUBFR );
     111           0 :     ener_hf_fx = dot_prod_satcontr( HF_fx, HF_fx, -3, -3, &q2, L_SUBFR16k );
     112             : 
     113           0 :     scale_fx = div_s( shl( 1, 14 ), ener_exc_fx ); /*Q(29-q1) */
     114           0 :     L_tmp = L_mult( ener_hf_fx, scale_fx );        /*30-q1+q2 */
     115           0 :     q2 = sub( q1, q2 );                            /*30-q2 */
     116             : #ifdef ISSUE_1867_replace_overflow_libenc
     117           0 :     scale_fx = round_fx( Isqrt( L_shl_sat( L_tmp, sub( q2, 26 ) ) ) ); /*Q13 */
     118             : #else
     119             :     scale_fx = round_fx( Isqrt( L_shl_o( L_tmp, sub( q2, 26 ), &Overflow ) ) );            /*Q13 */
     120             : #endif
     121             : 
     122             : 
     123           0 :     pt1 = HF_fx;
     124           0 :     FOR( i = 0; i < L_SUBFR16k; i++ )
     125             :     {
     126           0 :         *pt1 = round_fx( L_shl( L_mult( ( *pt1 ), scale_fx ), 5 ) ); /*Q0 */
     127           0 :         pt1++;
     128             :     }
     129             : 
     130             :     /*-----------------------------------------------------------------*
     131             :      * calculate energy scaling factor to respect tilt of synth12k8
     132             :      * (tilt: 1=voiced, -1=unvoiced)
     133             :      *-----------------------------------------------------------------*/
     134             : 
     135           0 :     hp400_12k8_fx( synth_fx, L_SUBFR, mem_hp400_enc_fx ); /*synth_fx: Q(Q_syn-4) */
     136             : 
     137           0 :     ener_fx = dot_prod_satcontr( &synth_fx[1], &synth_fx[1], sub( Q_syn, 4 ), sub( Q_syn, 4 ), &q1, sub( L_SUBFR, 1 ) );
     138           0 :     tmp_fx = dot_prod_satcontr( &synth_fx[1], synth_fx, sub( Q_syn, 4 ), sub( Q_syn, 4 ), &q2, sub( L_SUBFR, 1 ) );
     139             : 
     140           0 :     IF( GE_16( abs_s( tmp_fx ), ener_fx ) )
     141             :     {
     142           0 :         tmp_fx = shr( tmp_fx, 1 );
     143           0 :         q2 = sub( q2, 1 );
     144             :     }
     145             : 
     146           0 :     sign = 0;
     147           0 :     move16();
     148           0 :     IF( tmp_fx < 0 )
     149             :     {
     150           0 :         tmp_fx = abs_s( tmp_fx );
     151           0 :         sign = 1;
     152           0 :         move16();
     153             :     }
     154             : 
     155           0 :     fac_fx = div_s( tmp_fx, ener_fx ); /*Q(15+q2-q1) */
     156           0 :     shift = sub( q1, add( q2, 5 ) );
     157           0 :     fac_fx = shl( fac_fx, shift ); /*Q10 */
     158           0 :     IF( sign )
     159             :     {
     160           0 :         fac_fx = s_xor( fac_fx, -1 );
     161             :     }
     162             : 
     163           0 :     HF_est_gain_fx = sub( 1024, fac_fx ); /*Q12 */
     164             : 
     165           0 :     test();
     166           0 :     IF( EQ_32( core_brate_fx, SID_1k75 ) || core_brate_fx == FRAME_NO_DATA )
     167             :     {
     168           0 :         HF_est_gain_fx = round_fx( L_shl( L_mult( HF_est_gain_fx, 20480 ), 1 ) ); /*Q10 */
     169             :     }
     170             : 
     171           0 :     HF_est_gain_fx = s_max( HF_est_gain_fx, 102 );
     172           0 :     HF_est_gain_fx = s_min( HF_est_gain_fx, 1024 );
     173             : 
     174             :     /*-----------------------------------------------------------------*
     175             :      * synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz
     176             :      *-----------------------------------------------------------------*/
     177             : 
     178           0 :     weight_a_lc_fx( Aq_fx, Ap_fx, Gamma_19661_Tbl_fx, M );
     179           0 :     Syn_filt_s( 0, Ap_fx, M, HF_fx, HF_syn_fx, L_SUBFR16k, mem_syn_hf_enc_fx, 1 ); /*Q0 */
     180             : 
     181             :     /*-----------------------------------------------------------------*
     182             :      * high pass filtering (0.9375ms of delay = 15 samples@16k)
     183             :      *-----------------------------------------------------------------*/
     184             : 
     185           0 :     fir_fx( HF_syn_fx, fir_6k_8k_fx, HF_syn_fx, mem_hf1_enc_fx, L_SUBFR16k, L_FIR - 1, 1, 0 );
     186           0 :     fir_fx( HF_SP_fx, fir_6k_8k_fx, HF_SP_fx, mem_hf2_enc_fx, L_SUBFR16k, L_FIR - 1, 1, 0 );
     187             : 
     188             :     /* check the gain difference */
     189             : 
     190           0 :     ener_hf_fx = dot_prod_satcontr( HF_syn_fx, HF_syn_fx, 0, 0, &q2, L_SUBFR16k );
     191           0 :     ener_input_fx = dot_prod_satcontr( HF_SP_fx, HF_SP_fx, 0, 0, &q1, L_SUBFR16k );
     192             : 
     193           0 :     HF_calc_gain_fx = div_s( shl( 1, 14 ), ener_input_fx ); /*Q(29-q1) */
     194           0 :     L_tmp = L_mult( ener_hf_fx, HF_calc_gain_fx );          /*30-q1+q2 */
     195           0 :     q2 = sub( q1, q2 );                                     /*30-q2 */
     196             : #ifdef ISSUE_1867_replace_overflow_libenc
     197           0 :     HF_calc_gain_fx = round_fx_sat( Isqrt( L_shl_sat( L_tmp, sub( q2, 20 ) ) ) ); /*Q10  */
     198             : #else
     199             :     HF_calc_gain_fx = round_fx_o( Isqrt( L_shl_sat( L_tmp, sub( q2, 20 ) ) ), &Overflow ); /*Q10  */
     200             : #endif
     201             : 
     202             : 
     203             :     /* set energy of HF synthesis to energy of original HF:
     204             :        cross-fade between HF levels in active and inactive frame in hangover period */
     205             : 
     206           0 :     IF( GT_16( 4, dtxHangoverCount_fx ) )
     207             :     {
     208           0 :         *gain_alpha_fx = 16384;
     209           0 :         move16();
     210             :     }
     211             :     ELSE
     212             :     {
     213           0 :         L_tmp = L_shl( L_mult( sub( 10, dtxHangoverCount_fx ), 4681 ), 15 ); /*Q31 */
     214           0 :         L_tmp = Mult_32_16( L_tmp, *gain_alpha_fx );                         /*Q30 */
     215           0 :         *gain_alpha_fx = round_fx( L_tmp );                                  /*Q14 */
     216             :     }
     217           0 :     L_tmp = L_mult( sub( 16384, *gain_alpha_fx ), HF_est_gain_fx ); /*Q25 */
     218           0 :     L_tmp = L_mac( L_tmp, *gain_alpha_fx, HF_calc_gain_fx );        /*Q25  */
     219           0 :     IF( GE_32( L_tmp, 67108863 ) )
     220             :     {
     221           0 :         L_tmp = 67108863;
     222           0 :         move32();
     223             :     }
     224           0 :     L_tmp = L_shl( L_tmp, 5 );
     225           0 :     HF_corr_gain_fx = extract_h( L_tmp ); /*Q14; HF_corr_gain_fx/2 in Q15 */
     226             : 
     227             :     /* Quantize the correction gain */
     228           0 :     dist_min_fx = 2147483647;
     229           0 :     move32();
     230           0 :     HF_gain_ind_fx = 0;
     231           0 :     move16();
     232           0 :     pt2 = HP_gain_fx;
     233           0 :     FOR( i = 0; i < 16; i++ )
     234             :     {
     235           0 :         dist_fx = L_mult( sub( HF_corr_gain_fx, *pt2 ), sub( HF_corr_gain_fx, *pt2 ) );
     236           0 :         pt2++;
     237           0 :         IF( GT_32( dist_min_fx, dist_fx ) )
     238             :         {
     239           0 :             dist_min_fx = L_add( dist_fx, 0 );
     240           0 :             HF_gain_ind_fx = i;
     241           0 :             move16();
     242             :         }
     243             :     }
     244           0 :     *hf_gain_fx = HF_gain_ind_fx;
     245           0 :     move16();
     246             : 
     247           0 :     return;
     248             : }

Generated by: LCOV version 1.14