LCOV - code coverage report
Current view: top level - lib_enc - hf_cod_amrwb_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 8 82 9.8 %
Date: 2025-09-15 02:22:33 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             : #ifndef ISSUE_1867_replace_overflow_libenc
      90             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      91             :     Flag Overflow = 0;
      92             : #endif
      93             : #endif
      94             : 
      95             :     /* Original speech signal as reference for high band gain quantisation */
      96           0 :     Copy( speech16k_fx, HF_SP_fx, L_SUBFR16k );
      97             : 
      98             :     /*-----------------------------------------------------------------*
      99             :      * generate white noise vector
     100             :      *-----------------------------------------------------------------*/
     101             : 
     102           0 :     Random_Fill( seed2_enc_fx, L_SUBFR16k, HF_fx, 3 ); /*Q(-3) */
     103             : 
     104             :     /*-----------------------------------------------------------------*
     105             :      * calculate energy scaling factor so that white noise would have the
     106             :      * same energy as exc12k8
     107             :      *-----------------------------------------------------------------*/
     108             : 
     109           0 :     ener_exc_fx = dot_prod_satcontr( exc_fx, exc_fx, Q_exc, Q_exc, &q1, L_SUBFR );
     110           0 :     ener_hf_fx = dot_prod_satcontr( HF_fx, HF_fx, -3, -3, &q2, L_SUBFR16k );
     111             : 
     112           0 :     scale_fx = div_s( shl( 1, 14 ), ener_exc_fx ); /*Q(29-q1) */
     113           0 :     L_tmp = L_mult( ener_hf_fx, scale_fx );        /*30-q1+q2 */
     114           0 :     q2 = sub( q1, q2 );                            /*30-q2 */
     115             : #ifdef ISSUE_1867_replace_overflow_libenc
     116           0 :     scale_fx = round_fx( Isqrt( L_shl_sat( L_tmp, sub( q2, 26 ) ) ) ); /*Q13 */
     117             : #else
     118             :     scale_fx = round_fx( Isqrt( L_shl_o( L_tmp, sub( q2, 26 ), &Overflow ) ) );            /*Q13 */
     119             : #endif
     120             : 
     121             : 
     122           0 :     pt1 = HF_fx;
     123           0 :     FOR( i = 0; i < L_SUBFR16k; i++ )
     124             :     {
     125           0 :         *pt1 = round_fx( L_shl( L_mult( ( *pt1 ), scale_fx ), 5 ) ); /*Q0 */
     126           0 :         pt1++;
     127             :     }
     128             : 
     129             :     /*-----------------------------------------------------------------*
     130             :      * calculate energy scaling factor to respect tilt of synth12k8
     131             :      * (tilt: 1=voiced, -1=unvoiced)
     132             :      *-----------------------------------------------------------------*/
     133             : 
     134           0 :     hp400_12k8_fx( synth_fx, L_SUBFR, mem_hp400_enc_fx ); /*synth_fx: Q(Q_syn-4) */
     135             : 
     136           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 ) );
     137           0 :     tmp_fx = dot_prod_satcontr( &synth_fx[1], synth_fx, sub( Q_syn, 4 ), sub( Q_syn, 4 ), &q2, sub( L_SUBFR, 1 ) );
     138             : 
     139           0 :     IF( GE_16( abs_s( tmp_fx ), ener_fx ) )
     140             :     {
     141           0 :         tmp_fx = shr( tmp_fx, 1 );
     142           0 :         q2 = sub( q2, 1 );
     143             :     }
     144             : 
     145           0 :     sign = 0;
     146           0 :     move16();
     147           0 :     IF( tmp_fx < 0 )
     148             :     {
     149           0 :         tmp_fx = abs_s( tmp_fx );
     150           0 :         sign = 1;
     151           0 :         move16();
     152             :     }
     153             : 
     154           0 :     fac_fx = div_s( tmp_fx, ener_fx ); /*Q(15+q2-q1) */
     155           0 :     shift = sub( q1, add( q2, 5 ) );
     156           0 :     fac_fx = shl( fac_fx, shift ); /*Q10 */
     157           0 :     IF( sign )
     158             :     {
     159           0 :         fac_fx = s_xor( fac_fx, -1 );
     160             :     }
     161             : 
     162           0 :     HF_est_gain_fx = sub( 1024, fac_fx ); /*Q12 */
     163             : 
     164           0 :     test();
     165           0 :     IF( EQ_32( core_brate_fx, SID_1k75 ) || core_brate_fx == FRAME_NO_DATA )
     166             :     {
     167           0 :         HF_est_gain_fx = round_fx( L_shl( L_mult( HF_est_gain_fx, 20480 ), 1 ) ); /*Q10 */
     168             :     }
     169             : 
     170           0 :     HF_est_gain_fx = s_max( HF_est_gain_fx, 102 );
     171           0 :     HF_est_gain_fx = s_min( HF_est_gain_fx, 1024 );
     172             : 
     173             :     /*-----------------------------------------------------------------*
     174             :      * synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz
     175             :      *-----------------------------------------------------------------*/
     176             : 
     177           0 :     weight_a_lc_fx( Aq_fx, Ap_fx, Gamma_19661_Tbl_fx, M );
     178           0 :     Syn_filt_s( 0, Ap_fx, M, HF_fx, HF_syn_fx, L_SUBFR16k, mem_syn_hf_enc_fx, 1 ); /*Q0 */
     179             : 
     180             :     /*-----------------------------------------------------------------*
     181             :      * high pass filtering (0.9375ms of delay = 15 samples@16k)
     182             :      *-----------------------------------------------------------------*/
     183             : 
     184           0 :     fir_fx( HF_syn_fx, fir_6k_8k_fx, HF_syn_fx, mem_hf1_enc_fx, L_SUBFR16k, L_FIR - 1, 1, 0 );
     185           0 :     fir_fx( HF_SP_fx, fir_6k_8k_fx, HF_SP_fx, mem_hf2_enc_fx, L_SUBFR16k, L_FIR - 1, 1, 0 );
     186             : 
     187             :     /* check the gain difference */
     188             : 
     189           0 :     ener_hf_fx = dot_prod_satcontr( HF_syn_fx, HF_syn_fx, 0, 0, &q2, L_SUBFR16k );
     190           0 :     ener_input_fx = dot_prod_satcontr( HF_SP_fx, HF_SP_fx, 0, 0, &q1, L_SUBFR16k );
     191             : 
     192           0 :     HF_calc_gain_fx = div_s( shl( 1, 14 ), ener_input_fx ); /*Q(29-q1) */
     193           0 :     L_tmp = L_mult( ener_hf_fx, HF_calc_gain_fx );          /*30-q1+q2 */
     194           0 :     q2 = sub( q1, q2 );                                     /*30-q2 */
     195             : #ifdef ISSUE_1867_replace_overflow_libenc
     196           0 :     HF_calc_gain_fx = round_fx_sat( Isqrt( L_shl_sat( L_tmp, sub( q2, 20 ) ) ) ); /*Q10  */
     197             : #else
     198             :     HF_calc_gain_fx = round_fx_o( Isqrt( L_shl_sat( L_tmp, sub( q2, 20 ) ) ), &Overflow ); /*Q10  */
     199             : #endif
     200             : 
     201             : 
     202             :     /* set energy of HF synthesis to energy of original HF:
     203             :        cross-fade between HF levels in active and inactive frame in hangover period */
     204             : 
     205           0 :     IF( GT_16( 4, dtxHangoverCount_fx ) )
     206             :     {
     207           0 :         *gain_alpha_fx = 16384;
     208           0 :         move16();
     209             :     }
     210             :     ELSE
     211             :     {
     212           0 :         L_tmp = L_shl( L_mult( sub( 10, dtxHangoverCount_fx ), 4681 ), 15 ); /*Q31 */
     213           0 :         L_tmp = Mult_32_16( L_tmp, *gain_alpha_fx );                         /*Q30 */
     214           0 :         *gain_alpha_fx = round_fx( L_tmp );                                  /*Q14 */
     215             :     }
     216           0 :     L_tmp = L_mult( sub( 16384, *gain_alpha_fx ), HF_est_gain_fx ); /*Q25 */
     217           0 :     L_tmp = L_mac( L_tmp, *gain_alpha_fx, HF_calc_gain_fx );        /*Q25  */
     218           0 :     IF( GE_32( L_tmp, 67108863 ) )
     219             :     {
     220           0 :         L_tmp = 67108863;
     221           0 :         move32();
     222             :     }
     223           0 :     L_tmp = L_shl( L_tmp, 5 );
     224           0 :     HF_corr_gain_fx = extract_h( L_tmp ); /*Q14; HF_corr_gain_fx/2 in Q15 */
     225             : 
     226             :     /* Quantize the correction gain */
     227           0 :     dist_min_fx = 2147483647;
     228           0 :     move32();
     229           0 :     HF_gain_ind_fx = 0;
     230           0 :     move16();
     231           0 :     pt2 = HP_gain_fx;
     232           0 :     FOR( i = 0; i < 16; i++ )
     233             :     {
     234           0 :         dist_fx = L_mult( sub( HF_corr_gain_fx, *pt2 ), sub( HF_corr_gain_fx, *pt2 ) );
     235           0 :         pt2++;
     236           0 :         IF( GT_32( dist_min_fx, dist_fx ) )
     237             :         {
     238           0 :             dist_min_fx = L_add( dist_fx, 0 );
     239           0 :             HF_gain_ind_fx = i;
     240           0 :             move16();
     241             :         }
     242             :     }
     243           0 :     *hf_gain_fx = HF_gain_ind_fx;
     244           0 :     move16();
     245             : 
     246           0 :     return;
     247             : }

Generated by: LCOV version 1.14