LCOV - code coverage report
Current view: top level - lib_com - stab_est_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 96 96 100.0 %
Date: 2025-05-03 01:55:50 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             : /*-------------------------------------------------------------------*
      10             :  * Local constants
      11             :  *-------------------------------------------------------------------*/
      12             : 
      13             : #define BIN_4000    80 /* The frequency bin corresponding to 4kHz */
      14             : #define MAX_BANDEXC 20
      15             : 
      16             : #define NB_TH3_MIN 30
      17             : #define NB_TH1_MIN 30
      18             : 
      19             : #define TH_0_MAX_FX 9600 /* Q11 -> 1.5*3.125  */
      20             : #define TH_1_MAX_FX 8640 /* Q11 -> 1.5*2.8125 */
      21             : #define TH_2_MAX_FX 6720 /* Q11 -> 1.5*2.1875 */
      22             : #define TH_3_MAX_FX 5760 /* Q11 -> 1.5*1.875  */
      23             : 
      24             : #define TH_UP_FX 320 /* Q11 -> 0.15625  */
      25             : #define TH_DW_FX 320 /* Q11 -> 0.15625  */
      26             : 
      27             : /*------------------------------------------------------------------------*
      28             :  * stab_est()
      29             :  *
      30             :  * Signal stability estimation based on energy variation
      31             :  *------------------------------------------------------------------------*/
      32             : 
      33      425176 : Word16 stab_est_fx(
      34             :     Word16 etot,             /* i   : Total energy of the current frame   Q8*/
      35             :     Word16 *lt_diff_etot,    /* i/o : Long term total energy variation    Q8*/
      36             :     Word16 *mem_etot,        /* i/o : Total energy memory                 Q8*/
      37             :     Word16 *nb_thr_3,        /* i/o : Number of consecutives frames of level 3 */
      38             :     Word16 *nb_thr_1,        /* i/o : Number of consecutives frames of level 1 */
      39             :     Word16 *thresh,          /* i/o : Detection thresold                 Q11*/
      40             :     Word16 *last_music_flag, /* i/o : Previous music detection ouptut    */
      41             :     const Word16 vad_flag    /* i  : VAD flag                                  */
      42             : )
      43             : {
      44             :     Word16 i, music_flag2, tmp16, exp1, exp2;
      45             :     Word16 mean_diff;
      46             :     Word16 dev;
      47             :     Word32 L_tmp;
      48             : 
      49             :     /*------------------------------------------------------------------------*
      50             :      * Find mean of the past MAX_LT frames energy variation
      51             :      *------------------------------------------------------------------------*/
      52             : 
      53      425176 :     L_tmp = L_deposit_l( 0 );
      54    17007040 :     FOR( i = 1; i < MAX_LT; i++ )
      55             :     {
      56             :         /*mean_diff += lt_diff_etot[i-1] * INV_MAX_LT;  divide by MAX_LT */
      57    16581864 :         L_tmp = L_mac( L_tmp, lt_diff_etot[i - 1], INV_MAX_LT_FX );
      58    16581864 :         lt_diff_etot[i - 1] = lt_diff_etot[i];
      59    16581864 :         move16();
      60             :     }
      61             :     /*mean_diff += lt_diff_etot[i-1] * INV_MAX_LT; */ /* divide by MAX_LT */
      62      425176 :     L_tmp = L_mac( L_tmp, lt_diff_etot[i - 1], INV_MAX_LT_FX );
      63      425176 :     mean_diff = round_fx( L_tmp ); /*Q8 */
      64             : 
      65             :     /*------------------------------------------------------------------------*
      66             :      * Find statistical deviation of the energy variation history
      67             :      * against the last 15 frames
      68             :      *------------------------------------------------------------------------*/
      69             : 
      70      425176 :     tmp16 = sub( lt_diff_etot[MAX_LT - 15], mean_diff );
      71      425176 :     L_tmp = L_mult0( tmp16, tmp16 );
      72     6377640 :     FOR( i = MAX_LT - 15 + 1; i < MAX_LT; i++ )
      73             :     {
      74             :         /*fcorr += ftmp_c*ftmp_c;*/
      75     5952464 :         tmp16 = sub( lt_diff_etot[i], mean_diff );
      76     5952464 :         L_tmp = L_mac0_sat( L_tmp, tmp16, tmp16 );
      77             :     }
      78             :     /*------------------------------------------------------------------------*
      79             :      * Update
      80             :      *------------------------------------------------------------------------*/
      81      425176 :     lt_diff_etot[i - 1] = sub( etot, *mem_etot );
      82      425176 :     move16();
      83      425176 :     *mem_etot = etot;
      84      425176 :     move16();
      85             : 
      86             :     /*------------------------------------------------------------------------*
      87             :      * Compute statistical deviation
      88             :      *------------------------------------------------------------------------*/
      89             : 
      90             :     /*  dev = (float)0.7745967f*sqrt(fcorr / 15); */
      91      425176 :     L_tmp = Mpy_32_16_1( L_tmp, 1311 ); /*-> 1/25 (1/(MAX_LT-15))*/
      92             : 
      93      425176 :     exp1 = norm_l( L_tmp );
      94      425176 :     L_tmp = L_shl( L_tmp, exp1 );
      95      425176 :     tmp16 = round_fx_sat( L_tmp );
      96      425176 :     exp2 = sub( 31, exp1 );
      97      425176 :     L_tmp = Isqrt_lc( L_tmp, &exp2 );
      98      425176 :     L_tmp = Mpy_32_16_1( L_tmp, tmp16 );      /* we now have sqrt(L_corr) Q24 (8+16)*/
      99      425176 :     exp2 = sub( 31 - 15, sub( exp1, exp2 ) ); /* for Q8 (because of -8^2 from Etot)*/
     100             : 
     101      425176 :     L_tmp = L_shl( L_tmp, exp2 );             /* Q8 + Q16*/
     102      425176 :     dev = extract_h( L_shl_sat( L_tmp, 3 ) ); /* Q(24+3-16) -> Q11 */
     103             : 
     104             :     /*------------------------------------------------------------------------*
     105             :      * State machine to decide level of inter-harmonic noise reduction and
     106             :      * (only if this frame is GOOD or if we are already far from NB_BFI_THR)
     107             :      * (if music_flag2 is 0, the spectral modification is deactivated, otherwise, it is activated)
     108             :      *------------------------------------------------------------------------*/
     109             : 
     110      425176 :     music_flag2 = 0;
     111      425176 :     move16(); /* deactivate spectral modification (if music_flag2 != 0 is activated) */
     112             :     /*--------------------------------------------------------------------*
     113             :      * statistical deviation < thresh3 and last signal category type  >= 3
     114             :      * (last category was "tonal" and the new one is "very tonal")
     115             :      *--------------------------------------------------------------------*/
     116      425176 :     test();
     117      425176 :     test();
     118      425176 :     test();
     119      425176 :     IF( ( LT_16( dev, thresh[3] ) ) && ( GE_16( *last_music_flag, 3 ) ) )
     120             :     {
     121      137334 :         music_flag2 = 4;
     122      137334 :         move16();
     123      137334 :         *nb_thr_3 += 1;
     124      137334 :         move16();
     125      137334 :         *nb_thr_1 = 0;
     126      137334 :         move16();
     127             :     }
     128             : 
     129             :     /*--------------------------------------------------------------------*
     130             :      * statistical deviation < thresh2 and last signal category type  >= 2
     131             :      * (last category was "moderatly tonal" and the new one is a "tonal" )
     132             :      *--------------------------------------------------------------------*/
     133      287842 :     ELSE IF( ( LT_16( dev, thresh[2] ) ) && ( GE_16( *last_music_flag, 2 ) ) )
     134             :     {
     135       15291 :         music_flag2 = 3;
     136       15291 :         move16();
     137       15291 :         *nb_thr_3 += 1;
     138       15291 :         move16();
     139       15291 :         *nb_thr_1 = 0;
     140       15291 :         move16();
     141             :     }
     142             : 
     143             :     /*--------------------------------------------------------------------*
     144             :      * statistical deviation < thresh1 and last signal category type  >= 1
     145             :      * (last category was "slightly tonal" and the new one is a "moderatly tonal")
     146             :      *--------------------------------------------------------------------*/
     147      272551 :     ELSE IF( ( LT_16( dev, thresh[1] ) ) && ( GE_16( *last_music_flag, 1 ) ) )
     148             :     {
     149       25807 :         music_flag2 = 2;
     150       25807 :         move16();
     151             :     }
     152             : 
     153             :     /*--------------------------------------------------------------------*
     154             :      * statistical deviation < thresh0
     155             :      * (last category was "not tonal" and the new one is "slightly tonal")
     156             :      *--------------------------------------------------------------------*/
     157      246744 :     ELSE IF( ( LT_16( dev, thresh[0] ) ) )
     158             :     {
     159       62416 :         music_flag2 = 1;
     160       62416 :         move16(); /* [2000, 4000] Hz */
     161             :     }
     162             : 
     163             :     /*--------------------------------------------------------------------*
     164             :      * statistical deviation > thresh0
     165             :      * (Statistical deviation is high: the new tonal category is not tonal)
     166             :      *--------------------------------------------------------------------*/
     167             :     ELSE
     168             :     {
     169      184328 :         *nb_thr_1 = add( *nb_thr_1, 1 );
     170      184328 :         *nb_thr_3 = 0;
     171      184328 :         move16();
     172      184328 :         move16();
     173             :     }
     174             : 
     175             :     /*------------------------------------------------------------------------*
     176             :      * Update the thresholds
     177             :      *------------------------------------------------------------------------*/
     178      425176 :     IF( GT_16( *nb_thr_3, NB_TH3_MIN ) )
     179             :     {
     180             : 
     181             :         /* the number of consecutive categories type 3 or 4 (most tonal and tonal) */
     182             :         /* is greater than 30 frames ->increase the deviations thresholds to allow more variation */
     183      125815 :         thresh[0] = add( thresh[0], TH_UP_FX );
     184      125815 :         move16(); /*Q11 */
     185      125815 :         thresh[1] = add( thresh[1], TH_UP_FX );
     186      125815 :         move16();
     187      125815 :         thresh[2] = add( thresh[2], TH_UP_FX );
     188      125815 :         move16();
     189      125815 :         thresh[3] = add( thresh[3], TH_UP_FX );
     190      125815 :         move16();
     191             :     }
     192      299361 :     ELSE IF( GT_16( *nb_thr_1, NB_TH1_MIN ) )
     193             :     {
     194             :         /* the number of consecutive categories type 0 (non tonal frames) */
     195             :         /* is greater than 30 frames -> decrease the deviations thresholds to allow less variation */
     196      159364 :         thresh[0] = sub( thresh[0], TH_DW_FX );
     197      159364 :         move16(); /*Q11 */
     198      159364 :         thresh[1] = sub( thresh[1], TH_DW_FX );
     199      159364 :         move16();
     200      159364 :         thresh[2] = sub( thresh[2], TH_DW_FX );
     201      159364 :         move16();
     202      159364 :         thresh[3] = sub( thresh[3], TH_DW_FX );
     203      159364 :         move16();
     204             :     }
     205             : 
     206             :     /* limitation of the threshold (this local macro stores the highest of the two and it also
     207             :         counts the # of operations) */
     208             : 
     209      425176 :     move16();
     210      425176 :     move16();
     211      425176 :     move16();
     212      425176 :     thresh[0] = s_max( thresh[0], TH_0_MIN2_FX );
     213      425176 :     thresh[1] = s_max( thresh[1], TH_1_MIN2_FX );
     214      425176 :     thresh[2] = s_max( thresh[2], TH_2_MIN2_FX );
     215             : 
     216      425176 :     move16();
     217      425176 :     move16();
     218      425176 :     move16();
     219      425176 :     thresh[0] = s_min( thresh[0], TH_0_MAX_FX );
     220      425176 :     thresh[1] = s_min( thresh[1], TH_1_MAX_FX );
     221      425176 :     thresh[2] = s_min( thresh[2], TH_2_MAX_FX );
     222      425176 :     move16();
     223      425176 :     move16();
     224      425176 :     thresh[3] = s_max( thresh[3], TH_3_MIN2_FX );
     225      425176 :     thresh[3] = s_min( thresh[3], TH_3_MAX_FX );
     226             :     /*------------------------------------------------------------------------*
     227             :      * Final update
     228             :      *------------------------------------------------------------------------*/
     229             : 
     230      425176 :     *last_music_flag = music_flag2;
     231      425176 :     move16();
     232      425176 :     if ( vad_flag == 0 )
     233             :     {
     234             : 
     235       61152 :         music_flag2 = 0;
     236       61152 :         move16();
     237             :     }
     238             : 
     239      425176 :     return music_flag2;
     240             : }

Generated by: LCOV version 1.14