LCOV - code coverage report
Current view: top level - lib_enc - spec_flatness_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 184 190 96.8 %
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             : 
       5             : 
       6             : #include <assert.h>
       7             : #include <stdint.h>
       8             : #include "options.h"
       9             : #include "basop_util.h"
      10             : #include "vad_basop.h"
      11             : //#include "prot_fx.h"
      12             : #include "prot_fx.h"     /* Function prototypes                    */
      13             : #include "prot_fx_enc.h" /* Function prototypes                    */
      14             : 
      15             : /*-------------------------------------------------------------------*
      16             :  * spec_flatness_fx()
      17             :  *
      18             :  *
      19             :  *-------------------------------------------------------------------*/
      20        3100 : void spec_flatness_fx(
      21             :     Word32 *spec_amp,         /* i : spectral amplitude*/
      22             :     Word32 smooth_spec_amp[], /* i : smoothed spectral amplitude*/
      23             :     Word16 sSFM[SFM_NUM]      /* o : spectral flatness rate*/
      24             : )
      25             : {
      26             :     Word32 i;
      27             :     Word32 *smooth_spec_amp32;
      28             :     Word32 prods, prods_Exp;
      29             :     Word32 sums, prods_ExpM;
      30             :     Word32 zerop1;
      31             : 
      32             :     Word16 smooth_spec_amp16;
      33             :     Word16 Qnorm_prods, Qnorm_sums;
      34             :     Word16 SFM;
      35             :     Word16 prods_s, prods_Exps;
      36             :     Word16 prods_leadingzero, prods_Expleadingzero;
      37             : 
      38             :     Word16 leadingzero_prod, leadingzero_spec_amp;
      39             :     Word16 prods_Q_last, prods_ExpQ;
      40             :     Word16 SFM_Qtmp;
      41             :     Word16 prods_Q;
      42             : 
      43             : 
      44        3100 :     smooth_spec_amp32 = smooth_spec_amp;
      45        3100 :     zerop1 = 0;
      46        3100 :     move32();
      47        3100 :     prods_Q = 0;
      48        3100 :     move16();
      49      189100 :     FOR( i = MIN_AMP_ID; i <= MAX_AMP_ID; i++ )
      50             :     {
      51      186000 :         smooth_spec_amp32[i - MIN_AMP_ID] = L_add( MUL_F( smooth_spec_amp32[i - MIN_AMP_ID], 0x5999 ), MUL_F( spec_amp[i], 0x2666 ) );
      52      186000 :         move32();
      53             :     }
      54             :     /*sSFM1*/
      55        3100 :     sums = 0;
      56        3100 :     move32();
      57        3100 :     prods = 1;
      58        3100 :     move32();
      59        3100 :     prods_Q = 0;
      60        3100 :     move16();
      61             : 
      62             : 
      63       49600 :     FOR( i = ( 5 - MIN_AMP_ID ); i < ( 20 - MIN_AMP_ID ); i++ )
      64             :     {
      65       46500 :         sums = L_add( sums, smooth_spec_amp32[i] );
      66       46500 :         leadingzero_spec_amp = norm_l( smooth_spec_amp32[i] );
      67       46500 :         smooth_spec_amp16 = extract_h( L_shl( smooth_spec_amp32[i], leadingzero_spec_amp ) );
      68       46500 :         leadingzero_prod = norm_l( prods );
      69       46500 :         prods = L_shl( prods, leadingzero_prod );
      70       46500 :         prods_s = extract_h( prods );
      71       46500 :         prods = L_mult( prods_s, smooth_spec_amp16 );
      72       46500 :         prods_Q = add( add( prods_Q, leadingzero_spec_amp ), leadingzero_prod );
      73             :     }
      74        3100 :     prods_Q = sub( prods_Q, 255 );
      75             : 
      76        3100 :     prods_Q_last = prods_Q;
      77        3100 :     move16();
      78        3100 :     prods_ExpM = L_mult( prods_Q_last, -2184 );
      79             : 
      80        3100 :     prods = VAD_Pow( prods, 0x08888888, 0, 31, &prods_Q );
      81        3100 :     prods_Exp = VAD_Pow2( prods_ExpM, 16, &prods_ExpQ );
      82             : 
      83        3100 :     prods_leadingzero = norm_l( prods );
      84        3100 :     prods_Expleadingzero = norm_l( prods_Exp );
      85        3100 :     prods_s = extract_h( L_shl( prods, prods_leadingzero ) );
      86        3100 :     prods_Exps = extract_h( L_shl( prods_Exp, prods_Expleadingzero ) );
      87             : 
      88        3100 :     prods = L_mult( prods_s, prods_Exps );
      89        3100 :     prods_Q = add( prods_Q, prods_leadingzero );
      90        3100 :     prods_Q = add( prods_Q, prods_ExpQ );
      91        3100 :     prods_Q = add( prods_Q, prods_Expleadingzero );
      92        3100 :     prods_Q = sub( prods_Q, 31 );
      93             : 
      94        3100 :     prods = L_max( prods, 0 );
      95             : 
      96        3100 :     if ( prods <= 0 )
      97             :     {
      98           0 :         prods_Q = 34;
      99           0 :         move16();
     100             :     }
     101        3100 :     sums = MUL_F( sums, 0x0888 );
     102             : 
     103             :     /*+0.1      */
     104        3100 :     IF( GE_16( prods_Q, 34 ) )
     105             :     {
     106         190 :         prods = L_shr( prods, sub( prods_Q, 33 ) );
     107         190 :         zerop1 = CNT0P1 >> 1;
     108         190 :         move32();
     109         190 :         prods_Q = 33;
     110         190 :         move16();
     111             :     }
     112             :     ELSE
     113             :     {
     114        2910 :         prods_Q = sub( prods_Q, 1 );
     115        2910 :         prods = L_shr( prods, 1 );
     116        2910 :         zerop1 = L_shr( CNT0P1, sub( 34, prods_Q ) );
     117             :     }
     118        3100 :     prods = L_add( prods, zerop1 );
     119             : 
     120        3100 :     zerop1 = CNT0P1 >> 20;
     121        3100 :     move32();
     122        3100 :     sums = L_add( sums, zerop1 );
     123             : 
     124             :     /*div*/
     125        3100 :     Qnorm_prods = sub( norm_l( prods ), 1 );
     126        3100 :     Qnorm_sums = norm_l( sums );
     127        3100 :     prods = L_shl( prods, Qnorm_prods );
     128        3100 :     sums = L_shl( sums, Qnorm_sums );
     129             : 
     130        3100 :     SFM = div_l( prods, extract_h( sums ) );
     131             : 
     132        3100 :     SFM_Qtmp = add( prods_Q, Qnorm_prods );
     133        3100 :     SFM_Qtmp = sub( SFM_Qtmp, Qnorm_sums );
     134        3100 :     SFM_Qtmp = add( SFM_Qtmp, 15 );
     135        3100 :     SFM_Qtmp = sub( SFM_Qtmp, SPEC_AMP_Q );
     136        3100 :     SFM_Qtmp = sub( SFM_Qtmp, SFM_Q );
     137             : 
     138        3100 :     sSFM[0] = add_sat( mult( sSFM[0], 0x6ccc ), shr( mult( SFM, 0x1333 ), SFM_Qtmp ) );
     139        3100 :     move16();
     140             : 
     141             :     /*sSFM2*/
     142        3100 :     sums = 0;
     143        3100 :     move32();
     144        3100 :     prods = 1;
     145        3100 :     move32();
     146        3100 :     prods_Q = 0;
     147        3100 :     move16();
     148             : 
     149       65100 :     FOR( i = ( 20 - MIN_AMP_ID ); i < ( 40 - MIN_AMP_ID ); i++ )
     150             :     {
     151       62000 :         sums = L_add( sums, smooth_spec_amp32[i] );
     152       62000 :         leadingzero_spec_amp = norm_l( smooth_spec_amp32[i] );
     153       62000 :         smooth_spec_amp16 = extract_h( L_shl( smooth_spec_amp32[i], leadingzero_spec_amp ) );
     154       62000 :         leadingzero_prod = norm_l( prods );
     155       62000 :         prods = L_shl( prods, leadingzero_prod );
     156       62000 :         prods_s = extract_h( prods );
     157       62000 :         prods = L_mult( prods_s, smooth_spec_amp16 );
     158       62000 :         prods_Q = add( add( prods_Q, leadingzero_spec_amp ), leadingzero_prod );
     159             :     }
     160        3100 :     prods_Q = sub( prods_Q, 340 );
     161             : 
     162        3100 :     prods_Q_last = prods_Q;
     163        3100 :     move16();
     164        3100 :     prods_ExpM = L_mult( prods_Q_last, -1638 );
     165             : 
     166        3100 :     prods = VAD_Pow( prods, 0x06666666, 0, 31, &prods_Q );
     167        3100 :     prods_Exp = VAD_Pow2( prods_ExpM, 16, &prods_ExpQ );
     168             : 
     169        3100 :     prods_leadingzero = norm_l( prods );
     170        3100 :     prods_Expleadingzero = norm_l( prods_Exp );
     171        3100 :     prods_s = extract_h( L_shl( prods, prods_leadingzero ) );
     172        3100 :     prods_Exps = extract_h( L_shl( prods_Exp, prods_Expleadingzero ) );
     173             : 
     174        3100 :     prods = L_mult( prods_s, prods_Exps );
     175        3100 :     prods_Q = add( prods_Q, prods_leadingzero );
     176        3100 :     prods_Q = add( prods_Q, prods_ExpQ );
     177        3100 :     prods_Q = add( prods_Q, prods_Expleadingzero );
     178        3100 :     prods_Q = sub( prods_Q, 31 );
     179             : 
     180        3100 :     prods = L_max( prods, 0 );
     181             : 
     182        3100 :     if ( prods <= 0 )
     183             :     {
     184           0 :         prods_Q = 34;
     185           0 :         move16();
     186             :     }
     187        3100 :     sums = MUL_F( sums, 0x0666 );
     188             : 
     189             :     /*+0.1      */
     190        3100 :     IF( GE_16( prods_Q, 34 ) )
     191             :     {
     192         461 :         prods = L_shr( prods, sub( prods_Q, 33 ) );
     193         461 :         zerop1 = CNT0P1 >> 1;
     194         461 :         move32();
     195         461 :         prods_Q = 33;
     196         461 :         move16();
     197             :     }
     198             :     ELSE
     199             :     {
     200        2639 :         prods_Q = sub( prods_Q, 1 );
     201        2639 :         prods = L_shr( prods, 1 );
     202        2639 :         zerop1 = L_shr( CNT0P1, sub( 34, prods_Q ) );
     203             :     }
     204        3100 :     prods = L_add( prods, zerop1 );
     205             : 
     206        3100 :     zerop1 = CNT0P1 >> 20;
     207        3100 :     move32();
     208        3100 :     sums = L_add( sums, zerop1 );
     209             : 
     210             :     /*div*/
     211        3100 :     Qnorm_prods = sub( norm_l( prods ), 1 );
     212        3100 :     Qnorm_sums = norm_l( sums );
     213        3100 :     prods = L_shl( prods, Qnorm_prods );
     214        3100 :     sums = L_shl( sums, Qnorm_sums );
     215             : 
     216        3100 :     SFM = div_l( prods, extract_h( sums ) );
     217             : 
     218        3100 :     SFM_Qtmp = add( prods_Q, Qnorm_prods );
     219        3100 :     SFM_Qtmp = sub( SFM_Qtmp, Qnorm_sums );
     220        3100 :     SFM_Qtmp = add( SFM_Qtmp, 15 );
     221        3100 :     SFM_Qtmp = sub( SFM_Qtmp, SPEC_AMP_Q );
     222        3100 :     SFM_Qtmp = sub( SFM_Qtmp, SFM_Q );
     223             : 
     224        3100 :     sSFM[1] = add_sat( mult( sSFM[1], 0x6ccc ), shr( mult( SFM, 0x1333 ), SFM_Qtmp ) );
     225             : 
     226        3100 :     move16();
     227             :     /*sSFM3*/
     228        3100 :     sums = 0;
     229        3100 :     move32();
     230        3100 :     prods = 1;
     231        3100 :     move32();
     232        3100 :     prods_Q = 0;
     233        3100 :     move16();
     234             : 
     235       80600 :     FOR( i = ( 40 - MIN_AMP_ID ); i <= ( MAX_AMP_ID - MIN_AMP_ID ); i++ )
     236             :     {
     237       77500 :         sums = L_add( sums, smooth_spec_amp32[i] );
     238       77500 :         leadingzero_spec_amp = norm_l( smooth_spec_amp32[i] );
     239       77500 :         smooth_spec_amp16 = extract_h( L_shl( smooth_spec_amp32[i], leadingzero_spec_amp ) );
     240       77500 :         leadingzero_prod = norm_l( prods );
     241       77500 :         prods = L_shl( prods, leadingzero_prod );
     242       77500 :         prods_s = extract_h( prods );
     243       77500 :         prods = L_mult( prods_s, smooth_spec_amp16 );
     244       77500 :         prods_Q = add( add( prods_Q, leadingzero_spec_amp ), leadingzero_prod );
     245             :     }
     246        3100 :     prods_Q = sub( prods_Q, 425 );
     247             : 
     248        3100 :     prods_Q_last = prods_Q;
     249        3100 :     move16();
     250        3100 :     prods_ExpM = L_mult( prods_Q_last, -1310 );
     251             : 
     252        3100 :     prods = VAD_Pow( prods, 0x051eb851, 0, 31, &prods_Q );
     253        3100 :     prods_Exp = VAD_Pow2( prods_ExpM, 16, &prods_ExpQ );
     254             : 
     255        3100 :     prods_leadingzero = norm_l( prods );
     256        3100 :     prods_Expleadingzero = norm_l( prods_Exp );
     257        3100 :     prods_s = extract_h( L_shl( prods, prods_leadingzero ) );
     258        3100 :     prods_Exps = extract_h( L_shl( prods_Exp, prods_Expleadingzero ) );
     259             : 
     260        3100 :     prods = L_mult( prods_s, prods_Exps );
     261        3100 :     prods_Q = add( prods_Q, prods_leadingzero );
     262        3100 :     prods_Q = add( prods_Q, prods_ExpQ );
     263        3100 :     prods_Q = add( prods_Q, prods_Expleadingzero );
     264        3100 :     prods_Q = sub( prods_Q, 31 );
     265             : 
     266        3100 :     prods = L_max( prods, 0 );
     267        3100 :     if ( prods <= 0 )
     268             :     {
     269           0 :         prods_Q = 34;
     270           0 :         move16();
     271             :     }
     272             : 
     273        3100 :     sums = MUL_F( sums, 0x051e );
     274             : 
     275             :     /*+0.1      */
     276        3100 :     IF( GE_16( prods_Q, 34 ) )
     277             :     {
     278         641 :         prods = L_shr( prods, sub( prods_Q, 33 ) );
     279         641 :         zerop1 = CNT0P1 >> 1;
     280         641 :         move32();
     281         641 :         prods_Q = 33;
     282         641 :         move16();
     283             :     }
     284             :     ELSE
     285             :     {
     286        2459 :         prods_Q = sub( prods_Q, 1 );
     287        2459 :         prods = L_shr( prods, 1 );
     288        2459 :         zerop1 = L_shr( CNT0P1, sub( 34, prods_Q ) );
     289             :     }
     290        3100 :     prods = L_add( prods, zerop1 );
     291             : 
     292        3100 :     zerop1 = CNT0P1 >> 20;
     293        3100 :     move32();
     294        3100 :     sums = L_add( sums, zerop1 );
     295             : 
     296             :     /*div*/
     297        3100 :     Qnorm_prods = sub( norm_l( prods ), 1 );
     298        3100 :     Qnorm_sums = norm_l( sums );
     299        3100 :     prods = L_shl( prods, Qnorm_prods );
     300        3100 :     sums = L_shl( sums, Qnorm_sums );
     301             : 
     302        3100 :     SFM = div_l( prods, extract_h( sums ) );
     303             : 
     304        3100 :     SFM_Qtmp = add( prods_Q, Qnorm_prods );
     305        3100 :     SFM_Qtmp = sub( SFM_Qtmp, Qnorm_sums );
     306        3100 :     SFM_Qtmp = add( SFM_Qtmp, 15 );
     307        3100 :     SFM_Qtmp = sub( SFM_Qtmp, SPEC_AMP_Q );
     308        3100 :     SFM_Qtmp = sub( SFM_Qtmp, SFM_Q );
     309             : 
     310        3100 :     sSFM[2] = add_sat( mult( sSFM[2], 0x6ccc ), shr_sat( mult( SFM, 0x1333 ), SFM_Qtmp ) );
     311        3100 :     move16();
     312        3100 : }

Generated by: LCOV version 1.14