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

Generated by: LCOV version 1.14