LCOV - code coverage report
Current view: top level - lib_com - stab_est_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 4c82f1d24d39d0296b18d775f18a006f4c7d024b Lines: 94 96 97.9 %
Date: 2025-05-17 01:59:02 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        9313 : 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        9313 :     L_tmp = L_deposit_l( 0 );
      54      372520 :     FOR( i = 1; i < MAX_LT; i++ )
      55             :     {
      56             :         /*mean_diff += lt_diff_etot[i-1] * INV_MAX_LT;  divide by MAX_LT */
      57      363207 :         L_tmp = L_mac( L_tmp, lt_diff_etot[i - 1], INV_MAX_LT_FX );
      58      363207 :         lt_diff_etot[i - 1] = lt_diff_etot[i];
      59      363207 :         move16();
      60             :     }
      61             :     /*mean_diff += lt_diff_etot[i-1] * INV_MAX_LT; */ /* divide by MAX_LT */
      62        9313 :     L_tmp = L_mac( L_tmp, lt_diff_etot[i - 1], INV_MAX_LT_FX );
      63        9313 :     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        9313 :     tmp16 = sub( lt_diff_etot[MAX_LT - 15], mean_diff );
      71        9313 :     L_tmp = L_mult0( tmp16, tmp16 );
      72      139695 :     FOR( i = MAX_LT - 15 + 1; i < MAX_LT; i++ )
      73             :     {
      74             :         /*fcorr += ftmp_c*ftmp_c;*/
      75      130382 :         tmp16 = sub( lt_diff_etot[i], mean_diff );
      76      130382 :         L_tmp = L_mac0_sat( L_tmp, tmp16, tmp16 );
      77             :     }
      78             :     /*------------------------------------------------------------------------*
      79             :      * Update
      80             :      *------------------------------------------------------------------------*/
      81        9313 :     lt_diff_etot[i - 1] = sub( etot, *mem_etot );
      82        9313 :     move16();
      83        9313 :     *mem_etot = etot;
      84        9313 :     move16();
      85             : 
      86             :     /*------------------------------------------------------------------------*
      87             :      * Compute statistical deviation
      88             :      *------------------------------------------------------------------------*/
      89             : 
      90             :     /*  dev = (float)0.7745967f*sqrt(fcorr / 15); */
      91        9313 :     L_tmp = Mpy_32_16_1( L_tmp, 1311 ); /*-> 1/25 (1/(MAX_LT-15))*/
      92             : 
      93        9313 :     exp1 = norm_l( L_tmp );
      94        9313 :     L_tmp = L_shl( L_tmp, exp1 );
      95        9313 :     tmp16 = round_fx_sat( L_tmp );
      96        9313 :     exp2 = sub( 31, exp1 );
      97        9313 :     L_tmp = Isqrt_lc( L_tmp, &exp2 );
      98        9313 :     L_tmp = Mpy_32_16_1( L_tmp, tmp16 );      /* we now have sqrt(L_corr) Q24 (8+16)*/
      99        9313 :     exp2 = sub( 31 - 15, sub( exp1, exp2 ) ); /* for Q8 (because of -8^2 from Etot)*/
     100             : 
     101        9313 :     L_tmp = L_shl( L_tmp, exp2 );             /* Q8 + Q16*/
     102        9313 :     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        9313 :     music_flag2 = 0;
     111        9313 :     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        9313 :     test();
     117        9313 :     test();
     118        9313 :     test();
     119        9313 :     IF( ( LT_16( dev, thresh[3] ) ) && ( GE_16( *last_music_flag, 3 ) ) )
     120             :     {
     121        3227 :         music_flag2 = 4;
     122        3227 :         move16();
     123        3227 :         *nb_thr_3 += 1;
     124        3227 :         move16();
     125        3227 :         *nb_thr_1 = 0;
     126        3227 :         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        6086 :     ELSE IF( ( LT_16( dev, thresh[2] ) ) && ( GE_16( *last_music_flag, 2 ) ) )
     134             :     {
     135         384 :         music_flag2 = 3;
     136         384 :         move16();
     137         384 :         *nb_thr_3 += 1;
     138         384 :         move16();
     139         384 :         *nb_thr_1 = 0;
     140         384 :         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        5702 :     ELSE IF( ( LT_16( dev, thresh[1] ) ) && ( GE_16( *last_music_flag, 1 ) ) )
     148             :     {
     149         432 :         music_flag2 = 2;
     150         432 :         move16();
     151             :     }
     152             : 
     153             :     /*--------------------------------------------------------------------*
     154             :      * statistical deviation < thresh0
     155             :      * (last category was "not tonal" and the new one is "slightly tonal")
     156             :      *--------------------------------------------------------------------*/
     157        5270 :     ELSE IF( ( LT_16( dev, thresh[0] ) ) )
     158             :     {
     159        1065 :         music_flag2 = 1;
     160        1065 :         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        4205 :         *nb_thr_1 = add( *nb_thr_1, 1 );
     170        4205 :         *nb_thr_3 = 0;
     171        4205 :         move16();
     172        4205 :         move16();
     173             :     }
     174             : 
     175             :     /*------------------------------------------------------------------------*
     176             :      * Update the thresholds
     177             :      *------------------------------------------------------------------------*/
     178        9313 :     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        2559 :         thresh[0] = add( thresh[0], TH_UP_FX );
     184        2559 :         move16(); /*Q11 */
     185        2559 :         thresh[1] = add( thresh[1], TH_UP_FX );
     186        2559 :         move16();
     187        2559 :         thresh[2] = add( thresh[2], TH_UP_FX );
     188        2559 :         move16();
     189        2559 :         thresh[3] = add( thresh[3], TH_UP_FX );
     190        2559 :         move16();
     191             :     }
     192        6754 :     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        1867 :         thresh[0] = sub( thresh[0], TH_DW_FX );
     197        1867 :         move16(); /*Q11 */
     198        1867 :         thresh[1] = sub( thresh[1], TH_DW_FX );
     199        1867 :         move16();
     200        1867 :         thresh[2] = sub( thresh[2], TH_DW_FX );
     201        1867 :         move16();
     202        1867 :         thresh[3] = sub( thresh[3], TH_DW_FX );
     203        1867 :         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        9313 :     move16();
     210        9313 :     move16();
     211        9313 :     move16();
     212        9313 :     thresh[0] = s_max( thresh[0], TH_0_MIN2_FX );
     213        9313 :     thresh[1] = s_max( thresh[1], TH_1_MIN2_FX );
     214        9313 :     thresh[2] = s_max( thresh[2], TH_2_MIN2_FX );
     215             : 
     216        9313 :     move16();
     217        9313 :     move16();
     218        9313 :     move16();
     219        9313 :     thresh[0] = s_min( thresh[0], TH_0_MAX_FX );
     220        9313 :     thresh[1] = s_min( thresh[1], TH_1_MAX_FX );
     221        9313 :     thresh[2] = s_min( thresh[2], TH_2_MAX_FX );
     222        9313 :     move16();
     223        9313 :     move16();
     224        9313 :     thresh[3] = s_max( thresh[3], TH_3_MIN2_FX );
     225        9313 :     thresh[3] = s_min( thresh[3], TH_3_MAX_FX );
     226             :     /*------------------------------------------------------------------------*
     227             :      * Final update
     228             :      *------------------------------------------------------------------------*/
     229             : 
     230        9313 :     *last_music_flag = music_flag2;
     231        9313 :     move16();
     232        9313 :     if ( vad_flag == 0 )
     233             :     {
     234             : 
     235           0 :         music_flag2 = 0;
     236           0 :         move16();
     237             :     }
     238             : 
     239        9313 :     return music_flag2;
     240             : }

Generated by: LCOV version 1.14