LCOV - code coverage report
Current view: top level - lib_com - stat_noise_uv_mod_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 188 313 60.1 %
Date: 2025-08-23 01:22:27 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include "options.h" /* Compilation switches                   */
       7             : #include "prot_fx.h" /* Function prototypes                    */
       8             : #include "cnst.h"    /* Function prototypes                    */
       9             : 
      10             : /*---------------------------------------------------------------------*
      11             :  * Local function prototypes
      12             :  *---------------------------------------------------------------------*/
      13             : 
      14             : #define TILT_COMP_LIM_FX 24576 /* 0.75 in Q15 */
      15             : #define GE_SHIFT         6
      16             : #define P1               ( 32768 - ISP_SMOOTHING_QUANT_A1_FX - 1 )
      17             : #define P9               ( 32767 - P1 )
      18             : 
      19             : /*---------------------------------------------------------*
      20             :  * Local functions
      21             :  *---------------------------------------------------------*/
      22             : 
      23             : static Word16 calc_tilt_fx( const Word16 *x, const Word16 Q_shift, const Word16 len );
      24             : Word32 L_Sqrt_Q0( const Word32 x );
      25             : /*--------------------------------------------------------------------*
      26             :  * stat_noise_uv_mod()
      27             :  *
      28             :  * Modifies excitation signal in stationary noise segments
      29             :  *--------------------------------------------------------------------*/
      30             : 
      31        4369 : void stat_noise_uv_mod_fx(
      32             :     const Word16 coder_type, /* i  : Coder type                                                                    */
      33             :     Word16 noisiness,        /* i  : noisiness parameter                          Q0 */
      34             :     const Word16 *lsp_old,   /* i  : old LSP vector at 4th sfr                    Q15 */
      35             :     const Word16 *lsp_new,   /* i  : LSP vector at 4th sfr                                                Q15 */
      36             :     const Word16 *lsp_mid,   /* i  : LSP vector at 2nd sfr                                                Q15 */
      37             :     Word16 *Aq,              /* o  : A(z)   quantized for the 4 subframes                 Q12 */
      38             :     Word16 *exc2,            /* i/o: excitation buffer                                                    Q_exc */
      39             :     Word16 Q_exc,            /* i  : Q of exc2 excitation buffer [11..-1] expected */
      40             :     const Word16 bfi,        /* i  : Bad frame indicator                                                   */
      41             :     Word32 *ge_sm,           /* i/o: smoothed excitation gain                    Q_ge  */
      42             :     Word16 *uv_count,        /* i/o: unvoiced counter                                                      */
      43             :     Word16 *act_count,       /* i/o: activation counter                                                    */
      44             :     Word16 lspold_s[],       /* i/o: old LSP                                                                      Q15 */
      45             :     Word16 *noimix_seed,     /* i/o: mixture seed                                                                 Q0 */
      46             :     Word16 *st_min_alpha,    /* i/o: minimum alpha                                                                Q15 */
      47             :     Word16 *exc_pe,          /* i/o: scale Q_stat_noise                                                   Q_stat_noise */
      48             :     const Word32 bitrate,    /* i  : core bitrate                                  */
      49             :     const Word16 bwidth_fx,  /* i  : input bandwidth                                */
      50             :     Word16 *Q_stat_noise,    /* i/o: noise scaling                                  */
      51             :     Word16 *Q_stat_noise_ge  /* i/o: noise scaling                                  */
      52             : )
      53             : {
      54             :     Word16 exctilt;     /* Q15 */
      55             :     Word32 vare;        /* Q31 */
      56             :     Word16 randval;     /* Q?? */
      57             :     Word16 alpha;       /* Q15 */
      58             :     Word16 alpha_m1;    /* (1-alpha) Q15 */
      59             :     Word16 min_alpha;   /* Q15 */
      60             :     Word16 lspnew_s[M]; /* Same for all LSP (Q15) */
      61             :     Word16 oldlsp_mix[M];
      62             :     Word16 midlsp_mix[M];
      63             :     Word16 newlsp_mix[M];
      64             :     Word16 beta;         /* Q15 */
      65             :     Word16 Noimix_fract; /* (noimix_fac - 1.0) in  Q15 */
      66             :     /* noimix_fax * x <-> x + Noimix_fract * x */
      67             :     Word16 i_subfr;
      68             :     Word16 i, k;
      69             : 
      70             :     /* Work variables for div and sqrt */
      71             :     Word16 tmp_nom, tmp_den, tmp_shift, tmp_res;
      72             :     Word16 Qdiff, Q_local; /* new Q to be used for states Exc_pe and Ge_sm, and Exc2_local */
      73             :     Word32 L_tmp_res, L_tmp, L_tmp3, L_Ge;
      74             : 
      75             :     Word16 En_shift, Tmp;
      76             :     Word16 Exc2_local[L_FRAME]; /* local_copy in scaled Q_local*/
      77             : #ifndef ISSUE_1836_replace_overflow_libcom
      78             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      79             :     Flag Overflow = 0;
      80             :     move32();
      81             : #endif
      82             : #endif
      83             : 
      84             :     /*---------------------------------------------------------*
      85             :      * Init local variables
      86             :      *---------------------------------------------------------*/
      87        4369 :     alpha = 32767;
      88        4369 :     move16();
      89        4369 :     min_alpha = 16384;
      90        4369 :     move16();
      91             : 
      92        4369 :     test();
      93        4369 :     test();
      94        4369 :     test();
      95        4369 :     IF( EQ_16( coder_type, INACTIVE ) && ( EQ_32( bitrate, ACELP_9k60 ) || ( LT_32( bitrate, ACELP_9k60 ) && GT_16( bwidth_fx, NB ) ) ) )
      96             :     {
      97           0 :         min_alpha = *st_min_alpha;
      98           0 :         move16();
      99             :         /*---------------------------------------------------------*
     100             :          * decode noisiness parameter
     101             :          *---------------------------------------------------------*/
     102           0 :         IF( bfi == 0 )
     103             :         {
     104           0 :             tmp_den = 31;
     105           0 :             move16();
     106           0 :             tmp_shift = norm_s( tmp_den );
     107           0 :             move16();
     108           0 :             L_tmp_res = L_deposit_h( noisiness );
     109           0 :             L_tmp_res = L_shl( L_tmp_res, sub( tmp_shift, 1 ) );
     110           0 :             tmp_den = shl( tmp_den, tmp_shift );
     111           0 :             move16();
     112           0 :             tmp_res = div_l( L_tmp_res, tmp_den );
     113           0 :             move16();
     114             : #ifdef ISSUE_1836_replace_overflow_libcom
     115           0 :             min_alpha = add_sat( tmp_res, 16384 );
     116             : #else
     117             :             min_alpha = add_o( tmp_res, 16384, &Overflow );
     118             : #endif
     119           0 :             move16();
     120             : 
     121             :             /**st_min_alpha = sub(*st_min_alpha, 1638); move16();*/
     122           0 :             min_alpha = s_max( min_alpha, sub( *st_min_alpha, 1638 ) );
     123             : 
     124           0 :             *st_min_alpha = min_alpha;
     125           0 :             move16();
     126             :         }
     127             :     }
     128             : 
     129             :     /*---------------------------------------------------------*
     130             :      * Mix excitation signal with random noise
     131             :      *---------------------------------------------------------*/
     132        4369 :     test();
     133        4369 :     test();
     134        4369 :     test();
     135        4369 :     IF( EQ_16( coder_type, INACTIVE ) && ( EQ_32( bitrate, ACELP_9k60 ) || ( LT_32( bitrate, ACELP_9k60 ) && GT_16( bwidth_fx, NB ) ) ) )
     136             :     {
     137             :         /* use a local working copy for scaling and filtering, not needed if input Q-range is fixed */
     138           0 :         Copy( exc2, Exc2_local, L_FRAME );
     139             : 
     140             :         /* bound Q for internal use, optimization possible */
     141           0 :         Q_local = s_min( 11, s_max( -1, Q_exc ) );
     142             :         /* local excitation Q and incoming excitation Q*/
     143           0 :         Qdiff = sub( Q_local, Q_exc );
     144             :         /* only shift if incoming Q is outside [11..-1] shift is done in energy calculations aswell */
     145           0 :         Scale_sig( Exc2_local, L_FRAME, Qdiff );
     146             :         /* current excitation Q and previous stat_noise states Q */
     147           0 :         Qdiff = sub( Q_local, *Q_stat_noise );
     148             : 
     149           0 :         *Q_stat_noise_ge = GE_SHIFT;
     150           0 :         move16(); /* assign the fixed Q for Ge_sm */
     151             : 
     152           0 :         IF( Qdiff != 0 )
     153             :         {
     154           0 :             Scale_sig( exc_pe, 1, Qdiff );
     155             :         }
     156             : 
     157           0 :         En_shift = 0;
     158           0 :         move16();
     159           0 :         if ( GT_16( Q_local, 3 ) )
     160             :         {
     161             :             /* increase margin for energy accumulation in calc_tilt and vare accumulation */
     162           0 :             En_shift = sub( Q_local, 3 );
     163             :         }
     164             : 
     165           0 :         IF( LT_16( min_alpha, TILT_COMP_LIM_FX ) )
     166             :         {
     167           0 :             FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR )
     168             :             {
     169           0 :                 exctilt = calc_tilt_fx( &Exc2_local[i_subfr], En_shift, L_SUBFR ); /*Q15 */
     170             : #ifdef ISSUE_1836_replace_overflow_libcom
     171           0 :                 exctilt = mult( shl_sat( sub( TILT_COMP_LIM_FX, min_alpha ), 2 ), exctilt ); /*Q15  */ //??Sat
     172             : #else
     173             :                 exctilt = mult( shl_o( sub( TILT_COMP_LIM_FX, min_alpha ), 2, &Overflow ), exctilt ); /*Q15  */
     174             : #endif
     175             : 
     176           0 :                 PREEMPH_FX( &Exc2_local[i_subfr], exctilt, L_SUBFR, exc_pe );
     177             :             }
     178             :         }
     179             : 
     180           0 :         ( *uv_count )++;
     181             : 
     182           0 :         IF( LE_16( *uv_count, START_NG ) )
     183             :         {
     184           0 :             alpha = 32767;
     185           0 :             move16();
     186           0 :             *act_count = 3;
     187           0 :             move16();
     188           0 :             Copy( lsp_new, lspold_s, M );
     189             :         }
     190             :         ELSE
     191             :         {
     192           0 :             *uv_count = s_min( *uv_count, FULL_NG );
     193           0 :             move16();
     194           0 :             tmp_nom = sub( *uv_count, START_NG );
     195           0 :             tmp_den = sub( FULL_NG, START_NG );
     196           0 :             tmp_shift = norm_s( tmp_den );
     197           0 :             tmp_den = shl( tmp_den, tmp_shift );
     198           0 :             tmp_res = div_s( tmp_nom, tmp_den );
     199             : #ifdef ISSUE_1836_replace_overflow_libcom
     200           0 :             tmp_res = shl_sat( tmp_res, tmp_shift ); //??Sat
     201             : #else
     202             :             tmp_res = shl_o( tmp_res, tmp_shift, &Overflow );
     203             : #endif
     204           0 :             alpha = add( 32767, mult( tmp_res, sub( min_alpha, 32767 ) ) );
     205             : 
     206           0 :             *act_count = 0;
     207           0 :             move16();
     208             :         }
     209             : 
     210             :         /*---------------------------------------------------------*
     211             :          * calculate lowpass filtered excitation gain
     212             :          *---------------------------------------------------------*/
     213           0 :         Tmp = shr( Exc2_local[0], En_shift );
     214           0 :         vare = L_mult( Tmp, Tmp ); /* positive accumulation only */
     215           0 :         FOR( i = 1; i < L_FRAME; i++ )
     216             :         {
     217           0 :             Tmp = shr( Exc2_local[i], En_shift );
     218           0 :             vare = L_mac_sat( vare, Tmp, Tmp ); /* positive accumulation only */
     219             :         }
     220             : 
     221             :         /* obtain Ge in Q_local with safety saturation */
     222           0 :         L_Ge = L_shl( L_Sqrt_Q0( L_shr( vare, 1 ) ), add( sub( *Q_stat_noise_ge, 4 ), En_shift ) ); /* L_Ge in Q_local*/
     223             : 
     224             :         /* st->ge_sm = ISP_SMOOTHING_QUANT_A1 * st->ge_sm + (1.0f-ISP_SMOOTHING_QUANT_A1) * ge */
     225             : 
     226           0 :         IF( EQ_16( *uv_count, 1 ) )
     227             :         {
     228           0 :             *ge_sm = L_shr( L_Ge, Q_local );
     229           0 :             move32();
     230             :         }
     231             :         ELSE
     232             :         {
     233           0 :             L_tmp = Mult_32_16( L_Ge, P1 );    /* 0.1*ge still in Q local */
     234           0 :             L_tmp3 = Mult_32_16( *ge_sm, P9 ); /* 0.9*ge_sm still in Q_ge  */
     235             : 
     236           0 :             *ge_sm = L_add( L_shr( L_tmp, Q_local ), L_tmp3 );
     237           0 :             move32(); /* addition in  Q_ge domain*/
     238             :         }
     239             : 
     240             :         /*--------------------------------------------------------------------*
     241             :          * generate mixture of excitation and noise
     242             :          * float:
     243             :          *    noimix_fac = 1.0f/(float)sqrt(alpha*alpha + (1-alpha)*(1-alpha))
     244             :          *--------------------------------------------------------------------*/
     245             : 
     246           0 :         beta = shl( sub( alpha, 16384 ), 1 );
     247           0 :         alpha_m1 = sub( 32767, alpha );
     248           0 :         L_tmp_res = L_mac( 0, alpha, alpha );
     249           0 :         L_tmp_res = L_mac( L_tmp_res, alpha_m1, alpha_m1 );
     250           0 :         tmp_den = round_fx( L_Frac_sqrtQ31( L_tmp_res ) );
     251             : 
     252           0 :         tmp_nom = sub( 32767, tmp_den );
     253           0 :         tmp_shift = norm_s( tmp_den );
     254           0 :         tmp_den = shl( tmp_den, tmp_shift );
     255           0 :         tmp_res = div_s( tmp_nom, tmp_den );
     256             : 
     257           0 :         Noimix_fract = shr( tmp_res, tmp_shift ); /* float value is in range 0.0 to 0.42 */
     258             : 
     259             :         /* L_Ge might be 0 in unvoiced WB */
     260           0 :         L_Ge = L_max( L_Ge, 1 );
     261           0 :         tmp_shift = norm_l( L_Ge );
     262           0 :         tmp_den = extract_h( L_shl( L_Ge, tmp_shift ) );                                             /* Q_local+Q_ge+tmp_shift-16 */
     263           0 :         tmp_res = div_s( 1 << 14, tmp_den );                                                         /* 15+14-Q_local-tmp_shift-Q_ge+16 */
     264           0 :         L_tmp_res = Mult_32_16( *ge_sm, tmp_res );                                                   /* Q_stat_noise_ge+45-Q_local-Q_ge-tmp_shift-15 */
     265           0 :         L_tmp_res = Mult_32_16( L_tmp_res, sub( 32767, beta ) );                                     /*30-Q_local-tmp_shift+15-15         */
     266           0 :         L_tmp_res = L_add_sat( L_shl_sat( L_tmp_res, sub( add( Q_local, tmp_shift ), 15 ) ), beta ); /* Q15 */
     267             : #ifdef ISSUE_1836_replace_overflow_libcom
     268           0 :         tmp_res = extract_h( L_shl_sat( L_tmp_res, 15 ) ); /* 15+15-16=14 */
     269             : #else
     270             :         tmp_res = extract_h( L_shl_o( L_tmp_res, 15, &Overflow ) ); /* 15+15-16=14 */
     271             : #endif
     272             : 
     273           0 :         Noimix_fract = extract_l( Mult_32_16( L_tmp_res, Noimix_fract ) ); /*15+15-15 */
     274             : 
     275           0 :         FOR( i = 0; i < L_FRAME; i++ )
     276             :         {
     277             :             /*--------------------------------------------------------------------*
     278             :              *  flt: exc2[i] = noimix_fac*exc2[i] * alpha           + st->ge_sm*Rnd*((1.0f)-alpha)
     279             :              *  flt: exc2[i] = (noimix_fract*exc2[i]+exc2 )* alpha  + st->ge_sm*Rnd*((1.0f)-alpha)
     280             :              *  NB: currently uses 32bit accumulation for best low level performance,
     281             :              *       possibly overkill if input is always up-scaled
     282             :              *--------------------------------------------------------------------*/
     283             : 
     284             :             /* (1-alpha)*(float)sqrt(12.0f) * ((float)own_random(&(st->noimix_seed))/65536.0f) */
     285           0 :             randval = Random( noimix_seed );                                                   /* +/-32767 */
     286           0 :             randval = mult_r( 28378, randval ); /* Q downscaled by 2 bits ends up in Q14 */    /*sqrt(12.0f) in Q13*/
     287           0 :             randval = extract_l( L_shl( Mult_32_16( L_Ge, randval ), 1 - *Q_stat_noise_ge ) ); /*Q_local+Q_ge+14-15+1-Q_ge=Q_local */
     288             : 
     289           0 :             L_tmp = L_mult( Exc2_local[i], alpha );                                    /* Q_local + 16 */
     290           0 :             L_tmp = L_mac( L_tmp, randval, alpha_m1 );                                 /* Q_local + 16 */
     291           0 :             L_tmp3 = Mult_32_16( L_tmp, Noimix_fract );                                /* Q_local+16+15-15 */
     292           0 :             L_tmp = L_add_sat( L_tmp3, L_shl_sat( Mult_32_16( L_tmp, tmp_res ), 1 ) ); /* Q_local+16+14-15+1 */
     293           0 :             Exc2_local[i] = extract_h( L_tmp );                                        /*Q_local */
     294           0 :             move16();
     295             :         }
     296           0 :         *Q_stat_noise = Q_local; /* update for next call, routine can only be called once every frame */
     297           0 :         move16();
     298           0 :         Qdiff = sub( Q_exc, Q_local ); /* local excitation and incoming excitation */
     299           0 :         Scale_sig( Exc2_local, L_FRAME, Qdiff );
     300           0 :         Copy( Exc2_local, exc2, L_FRAME );
     301             : 
     302             :         /*--------------------------------------------------------------------*
     303             :          * Generate low-pass filtered version of ISP coefficients
     304             :          *--------------------------------------------------------------------*/
     305           0 :         FOR( k = 0; k < M; k++ )
     306             :         {
     307           0 :             move16();
     308           0 :             lspnew_s[k] = add(
     309           0 :                 mult( ISP_SMOOTHING_QUANT_A1_FX, lspold_s[k] ),
     310           0 :                 mult( 32767 - ISP_SMOOTHING_QUANT_A1_FX, lsp_new[k] ) );
     311             :         }
     312             : 
     313             :         /*--------------------------------------------------------------------*
     314             :          * replace LPC coefficients
     315             :          *--------------------------------------------------------------------*/
     316             : 
     317             :         /*--------------------------------------------------------------------*
     318             :          * pre-calculation of (1-beta)
     319             :          *--------------------------------------------------------------------*/
     320           0 :         FOR( i = 0; i < M; i++ )
     321             :         {
     322           0 :             move16();
     323           0 :             move16();
     324           0 :             move16();
     325           0 :             oldlsp_mix[i] = add( mult( beta, lsp_old[i] ),
     326           0 :                                  mult( sub( 32767, beta ), lspold_s[i] ) );
     327             : 
     328           0 :             midlsp_mix[i] = add( mult( beta, lsp_mid[i] ),
     329           0 :                                  mult( sub( 32767, beta ), add( shr( lspold_s[i], 1 ),
     330           0 :                                                                 shr( lspnew_s[i], 1 ) ) ) );
     331             : 
     332           0 :             newlsp_mix[i] = add( mult( beta, lsp_new[i] ),
     333           0 :                                  mult( sub( 32767, beta ), lspnew_s[i] ) );
     334             :         }
     335             : 
     336           0 :         int_lsp4_fx( L_FRAME, oldlsp_mix, midlsp_mix, newlsp_mix, Aq, M, 0 );
     337           0 :         Copy( lspnew_s, lspold_s, M );
     338             :     }
     339             :     ELSE /* (unvoiced_vad != 0) */
     340             :     {
     341        4369 :         ( *act_count )++;
     342        4369 :         IF( GT_16( *act_count, 3 ) )
     343             :         {
     344        4369 :             *act_count = 3;
     345        4369 :             move16();
     346        4369 :             *uv_count = 0;
     347        4369 :             move16();
     348             :         }
     349             :     }
     350        4369 : }
     351             : /*--------------------------------------------------------------------*
     352             :  * stat_noise_uv_mod()
     353             :  *
     354             :  * Modifies excitation signal in stationary noise segments
     355             :  *--------------------------------------------------------------------*/
     356             : 
     357      130777 : void stat_noise_uv_mod_ivas_fx(
     358             :     const Word16 coder_type, /* i  : Coder type                                                                                 */
     359             :     Word16 noisiness,        /* i  : noisiness parameter                                                        Q=0     */
     360             :     const Word16 *lsp_old,   /* i  : old LSP vector at 4th sfr                                          Q=15*/
     361             :     const Word16 *lsp_new,   /* i  : LSP vector at 4th sfr                                                      Q=15*/
     362             :     const Word16 *lsp_mid,   /* i  : LSP vector at 2nd sfr                                                      Q=15*/
     363             :     Word16 *Aq,              /* o  : A(z)   quantized for the 4 subframes                       Q=12*/
     364             :     Word16 *exc2,            /* i/o: excitation buffer                                                   Q=Q_exc*/
     365             :     Word16 *Q_exc,           /* i  : Q of exc2 excitation buffer [11..-1] expected              */
     366             :     const Word16 bfi,        /* i  : Bad frame indicator                                                                */
     367             :     Word32 *ge_sm,           /* i/o: smoothed excitation gain      Q=Q_stat_noise_ge (6)*/
     368             :     Word16 *uv_count,        /* i/o: unvoiced counter                                                   */
     369             :     Word16 *act_count,       /* i/o: activation counter                                                         */
     370             :     Word16 lspold_s[],       /* i/o: old LSP                                                                            Q=15*/
     371             :     Word16 *noimix_seed,     /* i/o: mixture seed                                                                       Q0      */
     372             :     Word16 *st_min_alpha,    /* i/o: minimum alpha                                                                      Q=15*/
     373             :     Word16 *exc_pe,          /* i/o: scale Q_stat_noise                   Q=Q_stat_noise*/
     374             :     const Word32 bitrate,    /* i  : core bitrate                                                                   */
     375             :     const Word16 bwidth_fx,  /* i  : i   bandwidth                                                                              */
     376             :     Word16 *Q_stat_noise,    /* i/o: noise scaling                                                                              */
     377             :     Word16 *Q_stat_noise_ge  /* i/o: noise scaling                                                                              */
     378             : )
     379             : {
     380             :     Word16 exctilt;     /* Q15 */
     381             :     Word32 vare;        /* Q31 */
     382             :     Word16 randval;     /* Q?? */
     383             :     Word16 alpha;       /* Q15 */
     384             :     Word16 alpha_m1;    /* (1-alpha) Q15 */
     385             :     Word16 min_alpha;   /* Q15 */
     386             :     Word16 lspnew_s[M]; /* Same for all LSP (Q15) */
     387             :     Word16 oldlsp_mix[M];
     388             :     Word16 midlsp_mix[M];
     389             :     Word16 newlsp_mix[M];
     390             :     Word16 beta;           /* Q15 */
     391             :     Word16 Noimix_fract;   /* (noimix_fac - 1.0) in  Q15 */
     392             :     Word32 L_Noimix_fract; /* (noimix_fac - 1.0) in  Q15 */
     393             :     /* noimix_fax * x <-> x + Noimix_fract * x */
     394             :     Word16 i_subfr;
     395             :     Word16 i, k;
     396             : 
     397             :     /* Work variables for div and sqrt */
     398             :     Word16 tmp_nom, tmp_den, tmp_shift, tmp_res;
     399             :     Word16 Qdiff, Q_local; /* new Q to be used for states Exc_pe and Ge_sm, and Exc2_local */
     400             :     Word32 L_tmp_res, L_tmp, L_tmp3, L_Ge;
     401             : 
     402             :     Word16 En_shift, Tmp;
     403             :     Word16 Exc2_local[L_FRAME];   /* local_copy in scaled Q_local*/
     404             :     Word32 L_Exc2_local[L_FRAME]; /* local_copy in scaled Q_local*/
     405             : #ifndef ISSUE_1836_replace_overflow_libcom
     406             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     407             :     Flag Overflow = 0;
     408             :     move32();
     409             : #endif
     410             : #endif
     411             : 
     412             :     /*---------------------------------------------------------*
     413             :      * Init local variables
     414             :      *---------------------------------------------------------*/
     415      130777 :     alpha = 32767;
     416      130777 :     move16();
     417      130777 :     min_alpha = 16384;
     418      130777 :     move16();
     419             : 
     420      130777 :     test();
     421      130777 :     test();
     422      130777 :     test();
     423      130777 :     IF( EQ_16( coder_type, INACTIVE ) && ( EQ_32( bitrate, ACELP_9k60 ) || ( LT_32( bitrate, ACELP_9k60 ) && GT_16( bwidth_fx, NB ) ) ) )
     424             :     {
     425         358 :         min_alpha = *st_min_alpha;
     426         358 :         move16();
     427             :         /*---------------------------------------------------------*
     428             :          * decode noisiness parameter
     429             :          *---------------------------------------------------------*/
     430         358 :         IF( bfi == 0 )
     431             :         {
     432         358 :             tmp_den = 31;
     433         358 :             move16();
     434         358 :             tmp_shift = norm_s( tmp_den );
     435         358 :             L_tmp_res = L_deposit_h( noisiness );
     436         358 :             L_tmp_res = L_shl( L_tmp_res, sub( tmp_shift, 1 ) );
     437         358 :             tmp_den = shl( tmp_den, tmp_shift );
     438         358 :             tmp_res = div_l( L_tmp_res, tmp_den );
     439             : #ifdef ISSUE_1836_replace_overflow_libcom
     440         358 :             min_alpha = add_sat( tmp_res, 16384 );
     441             : #else
     442             :             min_alpha = add_o( tmp_res, 16384, &Overflow );
     443             : #endif
     444             : 
     445             :             /**st_min_alpha = sub(*st_min_alpha, 1638); move16();*/
     446         358 :             min_alpha = s_max( min_alpha, sub( *st_min_alpha, 1638 ) );
     447             : 
     448         358 :             *st_min_alpha = min_alpha;
     449         358 :             move16();
     450             :         }
     451             :     }
     452             : 
     453             :     /*---------------------------------------------------------*
     454             :      * Mix excitation signal with random noise
     455             :      *---------------------------------------------------------*/
     456      130777 :     test();
     457      130777 :     test();
     458      130777 :     test();
     459      130777 :     IF( EQ_16( coder_type, INACTIVE ) && ( EQ_32( bitrate, ACELP_9k60 ) || ( LT_32( bitrate, ACELP_9k60 ) && GT_16( bwidth_fx, NB ) ) ) )
     460         358 :     {
     461             :         /* use a local working copy for scaling and filtering, not needed if input Q-range is fixed */
     462         358 :         Copy( exc2, Exc2_local, L_FRAME );
     463             : 
     464             :         /* bound Q for internal use, optimization possible */
     465         358 :         Q_local = s_min( 11, s_max( -1, *Q_exc ) );
     466             :         /* local excitation Q and incoming excitation Q*/
     467         358 :         Qdiff = sub( Q_local, *Q_exc );
     468             :         /* only shift if incoming Q is outside [11..-1] shift is done in energy calculations aswell */
     469         358 :         Scale_sig( Exc2_local, L_FRAME, Qdiff );
     470             :         /* current excitation Q and previous stat_noise states Q */
     471         358 :         Qdiff = sub( Q_local, *Q_stat_noise );
     472             : 
     473         358 :         *Q_stat_noise_ge = GE_SHIFT;
     474         358 :         move16(); /* assign the fixed Q for Ge_sm */
     475             : 
     476         358 :         IF( Qdiff != 0 )
     477             :         {
     478         133 :             Scale_sig( exc_pe, 1, Qdiff );
     479             :         }
     480             : 
     481         358 :         En_shift = 0;
     482         358 :         move16();
     483         358 :         if ( GT_16( Q_local, 3 ) )
     484             :         {
     485             :             /* increase margin for energy accumulation in calc_tilt and vare accumulation */
     486         240 :             En_shift = sub( Q_local, 3 );
     487             :         }
     488             : 
     489         358 :         IF( LT_16( min_alpha, TILT_COMP_LIM_FX ) )
     490             :         {
     491         605 :             FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR )
     492             :             {
     493         484 :                 exctilt = calc_tilt_fx( &Exc2_local[i_subfr], En_shift, L_SUBFR ); /*Q15 */
     494             : #ifdef ISSUE_1836_replace_overflow_libcom
     495         484 :                 exctilt = mult( shl_sat( sub( TILT_COMP_LIM_FX, min_alpha ), 2 ), exctilt ); /*Q15  */
     496             : #else
     497             :                 exctilt = mult( shl_o( sub( TILT_COMP_LIM_FX, min_alpha ), 2, &Overflow ), exctilt ); /*Q15  */
     498             : #endif
     499             : 
     500         484 :                 PREEMPH_FX( &Exc2_local[i_subfr], exctilt, L_SUBFR, exc_pe );
     501             :             }
     502             :         }
     503             : 
     504         358 :         ( *uv_count )++;
     505             : 
     506         358 :         IF( LE_16( *uv_count, START_NG ) )
     507             :         {
     508         280 :             alpha = 32767;
     509         280 :             move16();
     510         280 :             *act_count = 3;
     511         280 :             move16();
     512         280 :             Copy( lsp_new, lspold_s, M );
     513             :         }
     514             :         ELSE
     515             :         {
     516          78 :             *uv_count = s_min( *uv_count, FULL_NG );
     517          78 :             move16();
     518          78 :             tmp_nom = sub( *uv_count, START_NG );
     519          78 :             tmp_den = sub( FULL_NG, START_NG );
     520          78 :             tmp_shift = norm_s( tmp_den );
     521          78 :             tmp_den = shl( tmp_den, tmp_shift );
     522          78 :             tmp_res = div_s( tmp_nom, tmp_den );
     523             : #ifdef ISSUE_1836_replace_overflow_libcom
     524          78 :             tmp_res = shl_sat( tmp_res, tmp_shift );
     525             : #else
     526             :             tmp_res = shl_o( tmp_res, tmp_shift, &Overflow );
     527             : #endif
     528          78 :             alpha = add( 32767, mult( tmp_res, sub( min_alpha, 32767 ) ) );
     529             : 
     530          78 :             *act_count = 0;
     531          78 :             move16();
     532             :         }
     533             : 
     534             :         /*---------------------------------------------------------*
     535             :          * calculate lowpass filtered excitation gain
     536             :          *---------------------------------------------------------*/
     537         358 :         Tmp = shr( Exc2_local[0], En_shift );
     538         358 :         vare = L_mult( Tmp, Tmp ); /* positive accumulation only */
     539       91648 :         FOR( i = 1; i < L_FRAME; i++ )
     540             :         {
     541       91290 :             Tmp = shr( Exc2_local[i], En_shift );
     542       91290 :             vare = L_mac_sat( vare, Tmp, Tmp ); /* positive accumulation only */
     543             :         }
     544             : 
     545             :         /* obtain Ge in Q_local with safety saturation */
     546         358 :         L_Ge = L_shl( L_Sqrt_Q0( L_shr( vare, 1 ) ), add( sub( *Q_stat_noise_ge, 4 ), En_shift ) ); /* L_Ge in Q_local*/
     547             : 
     548             :         /* st->ge_sm = ISP_SMOOTHING_QUANT_A1 * st->ge_sm + (1.0f-ISP_SMOOTHING_QUANT_A1) * ge */
     549             : 
     550         358 :         IF( EQ_16( *uv_count, 1 ) )
     551             :         {
     552         125 :             *ge_sm = L_shr( L_Ge, Q_local );
     553         125 :             move32();
     554             :         }
     555             :         ELSE
     556             :         {
     557         233 :             L_tmp = Mult_32_16( L_Ge, P1 );    /* 0.1*ge still in Q local */
     558         233 :             L_tmp3 = Mult_32_16( *ge_sm, P9 ); /* 0.9*ge_sm still in Q_ge  */
     559             : 
     560         233 :             *ge_sm = L_add( L_shr( L_tmp, Q_local ), L_tmp3 );
     561         233 :             move32(); /* addition in  Q_ge domain*/
     562             :         }
     563             : 
     564             :         /*--------------------------------------------------------------------*
     565             :          * generate mixture of excitation and noise
     566             :          * float:
     567             :          *    noimix_fac = 1.0f/(float)sqrt(alpha*alpha + (1-alpha)*(1-alpha))
     568             :          *--------------------------------------------------------------------*/
     569             : 
     570         358 :         beta = shl( sub( alpha, 16384 ), 1 );
     571         358 :         alpha_m1 = sub( 32767, alpha );
     572         358 :         L_tmp_res = L_mac( 0, alpha, alpha );
     573         358 :         L_tmp_res = L_mac( L_tmp_res, alpha_m1, alpha_m1 );
     574         358 :         tmp_den = round_fx( L_Frac_sqrtQ31( L_tmp_res ) );
     575         358 :         Word16 exp_sqr = 0;
     576         358 :         move16();
     577         358 :         tmp_res = BASOP_Util_Divide1616_Scale( 32767, tmp_den, &exp_sqr ); // 15-exp_sqr
     578         358 :         Noimix_fract = tmp_res;                                            // 15-exp_sqr
     579         358 :         move16();
     580             :         /* L_Ge might be 0 in unvoiced WB */
     581         358 :         L_Ge = L_max( L_Ge, 1 );
     582         358 :         tmp_shift = norm_l( L_Ge );
     583         358 :         tmp_den = extract_h( L_shl( L_Ge, tmp_shift ) );                                             /* Q_local+Q_ge+tmp_shift-16 */
     584         358 :         tmp_res = div_s( 1 << 14, tmp_den );                                                         /* 15+14-Q_local-tmp_shift-Q_ge+16 */
     585         358 :         L_tmp_res = Mult_32_16( *ge_sm, tmp_res );                                                   /* Q_stat_noise_ge+45-Q_local-Q_ge-tmp_shift-15 */
     586         358 :         L_tmp_res = Mult_32_16( L_tmp_res, sub( 32767, beta ) );                                     /*30-Q_local-tmp_shift+15-15         */
     587         358 :         L_tmp_res = L_add_sat( L_shl_sat( L_tmp_res, sub( add( Q_local, tmp_shift ), 15 ) ), beta ); /* Q15 */
     588         358 :         L_Noimix_fract = Mult_32_16( L_tmp_res, Noimix_fract );                                      /*15+15-exp_sqr-15  =15-exp_sqr */
     589             : 
     590       92006 :         FOR( i = 0; i < L_FRAME; i++ )
     591             :         {
     592             :             /*--------------------------------------------------------------------*
     593             :              *  flt: exc2[i] = noimix_fac*exc2[i] * alpha           + st->ge_sm*Rnd*((1.0f)-alpha)
     594             :              *  flt: exc2[i] = (noimix_fract*exc2[i]+exc2 )* alpha  + st->ge_sm*Rnd*((1.0f)-alpha)
     595             :              *  NB: currently uses 32bit accumulation for best low level performance,
     596             :              *       possibly overkill if input is always up-scaled
     597             :              *--------------------------------------------------------------------*/
     598             : 
     599             :             /* (1-alpha)*(float)sqrt(12.0f) * ((float)own_random(&(st->noimix_seed))/65536.0f) */
     600       91648 :             randval = Random( noimix_seed );                                                         /* +/-32767 */
     601       91648 :             randval = mult_r( 28378, randval ); /* Q downscaled by 2 bits ends up in Q14 */          /*sqrt(12.0f) in Q13*/
     602       91648 :             randval = extract_l( L_shl( Mult_32_16( L_Ge, randval ), sub( 1, *Q_stat_noise_ge ) ) ); /*Q_local+Q_ge+14-15+1-Q_ge=Q_local */
     603             : 
     604       91648 :             L_tmp = L_mult( Exc2_local[i], alpha );                                       /* Q_local + 16 */
     605       91648 :             L_tmp = L_mac( L_tmp, randval, alpha_m1 );                                    /* Q_local + 16 */
     606       91648 :             L_tmp3 = Mult_32_32( L_tmp, L_Noimix_fract );                                 /* Q_local+16+15-exp_sqr-15 =Q_local +1 */
     607       91648 :             L_Exc2_local[i] = L_add( L_shr( L_tmp3, 1 ), Mpy_32_32( L_tmp, L_tmp_res ) ); // Q_local + 16 +15 -31 = Q_local
     608       91648 :             move32();
     609             :         }
     610             :         Word32 max_val;
     611         358 :         maximum_abs_32_fx( L_Exc2_local, L_FRAME, &max_val );
     612         358 :         Word16 shift = 0;
     613         358 :         move16();
     614         358 :         IF( GT_32( max_val, ONE_IN_Q15 ) )
     615             :         {
     616           0 :             shift = norm_l( max_val );
     617           0 :             shift = sub( Q31 - Q15, shift );
     618           0 :             *Q_exc = sub( Q_local, shift ); // Q_exc = Q_local -shift
     619           0 :             move16();
     620             :         }
     621         358 :         *Q_stat_noise = Q_local; /* update for next call, routine can only be called once every frame */
     622         358 :         move16();
     623             : 
     624         358 :         Copy_Scale_sig_32_16( L_Exc2_local, exc2, L_FRAME, negate( shift ) ); // Q_exc
     625             : 
     626             :         /*--------------------------------------------------------------------*
     627             :          * Generate low-pass filtered version of ISP coefficients
     628             :          *--------------------------------------------------------------------*/
     629        6086 :         FOR( k = 0; k < M; k++ )
     630             :         {
     631        5728 :             move16();
     632        5728 :             lspnew_s[k] = add(
     633        5728 :                 mult( ISP_SMOOTHING_QUANT_A1_FX, lspold_s[k] ),
     634        5728 :                 mult( 32767 - ISP_SMOOTHING_QUANT_A1_FX, lsp_new[k] ) );
     635             :         }
     636             : 
     637             :         /*--------------------------------------------------------------------*
     638             :          * replace LPC coefficients
     639             :          *--------------------------------------------------------------------*/
     640             : 
     641             :         /*--------------------------------------------------------------------*
     642             :          * pre-calculation of (1-beta)
     643             :          *--------------------------------------------------------------------*/
     644        6086 :         FOR( i = 0; i < M; i++ )
     645             :         {
     646        5728 :             move16();
     647        5728 :             move16();
     648        5728 :             move16();
     649        5728 :             oldlsp_mix[i] = add( mult( beta, lsp_old[i] ),
     650        5728 :                                  mult( sub( 32767, beta ), lspold_s[i] ) );
     651             : 
     652        5728 :             midlsp_mix[i] = add( mult( beta, lsp_mid[i] ),
     653        5728 :                                  mult( sub( 32767, beta ), add( shr( lspold_s[i], 1 ),
     654        5728 :                                                                 shr( lspnew_s[i], 1 ) ) ) );
     655             : 
     656        5728 :             newlsp_mix[i] = add( mult( beta, lsp_new[i] ),
     657        5728 :                                  mult( sub( 32767, beta ), lspnew_s[i] ) );
     658             :         }
     659             : 
     660         358 :         int_lsp4_ivas_fx( L_FRAME, oldlsp_mix, midlsp_mix, newlsp_mix, Aq, M, 0 );
     661         358 :         Copy( lspnew_s, lspold_s, M );
     662             :     }
     663             :     ELSE /* (unvoiced_vad != 0) */
     664             :     {
     665      130419 :         ( *act_count )++;
     666      130419 :         IF( GT_16( *act_count, 3 ) )
     667             :         {
     668      130410 :             *act_count = 3;
     669      130410 :             move16();
     670      130410 :             *uv_count = 0;
     671      130410 :             move16();
     672             :         }
     673             :     }
     674      130777 : }
     675             : 
     676             : /*---------------------------------------------------------------------------*
     677             :  * calc_tilt()
     678             :  *
     679             :  * Calculate spectral tilt by means of 1st-order LP analysis
     680             :  *---------------------------------------------------------------------------*/
     681             : 
     682         484 : static Word16 calc_tilt_fx(                       /* o  : Excitation tilt  Q15*/
     683             :                             const Word16 *x,      /* i  : Signal input    Q_shift*/
     684             :                             const Word16 Q_shift, /* i  : input scaling   */
     685             :                             const Word16 len      /* i  : length          */
     686             : )
     687             : {
     688             :     Word16 i;
     689             :     Word16 tmp_shift;
     690             :     Word32 L_tmp_res;
     691             :     Word16 tmp_sign, xi, xi_p1;
     692             :     Word32 r0, r1;
     693             : 
     694         484 :     r0 = L_deposit_l( 0 );
     695         484 :     r1 = L_deposit_l( 0 );
     696         484 :     xi = shr( x[0], Q_shift );
     697             : 
     698       30976 :     FOR( i = 0; i < len - 1; i++ )
     699             :     {
     700             :         /* r0 = L_mac(r0,x[i],x[i])                                        */
     701             :         /* r1 = L_mac(r1,x[i],x[i+1]) -> correlation loop can be optimized */
     702       30492 :         r0 = L_mac_sat( r0, xi, xi );
     703       30492 :         xi_p1 = shr( x[i + 1], Q_shift );
     704       30492 :         r1 = L_mac_sat( r1, xi, xi_p1 );
     705       30492 :         xi = xi_p1;
     706       30492 :         move16();
     707             :     }
     708             : 
     709         484 :     if ( r0 == 0 )
     710             :     {
     711           0 :         r0 = L_shl( 327, 16 );
     712             :     }
     713             : 
     714         484 :     tmp_shift = norm_l( r0 );
     715         484 :     r0 = L_shl( r0, tmp_shift );
     716         484 :     tmp_sign = 1;
     717         484 :     move16();
     718         484 :     if ( r1 >= 0 )
     719             :     {
     720         437 :         tmp_sign = 0;
     721         437 :         move16();
     722             :     }
     723         484 :     r1 = L_abs( r1 );
     724             : 
     725         484 :     L_tmp_res = Div_32( r1, extract_h( r0 ), extract_l( r0 ) );
     726         484 :     L_tmp_res = L_shl_sat( L_tmp_res, tmp_shift ); /*Q31 */
     727         484 :     if ( tmp_sign != 0 )
     728             :     {
     729          47 :         L_tmp_res = L_negate( L_tmp_res ); /*Q31 */
     730             :     }
     731             : 
     732         484 :     return extract_h( L_tmp_res ); /*Q15 */
     733             : }
     734             : 
     735             : /*---------------------------------------------------------------------------*
     736             :  * L_Sqrt_Q0
     737             :  *
     738             :  * Calculate square root from fractional values (Q0 -> Q0)
     739             :  * Uses 32 bit internal representation for precision
     740             :  *---------------------------------------------------------------------------*/
     741         358 : Word32 L_Sqrt_Q0(                /* o  : Square root of input Q0*/
     742             :                   const Word32 x /* i  : Input               Qx */
     743             : )
     744             : {
     745             :     Word32 log2_work;
     746             : 
     747             :     Word16 log2_int;
     748             :     Word16 log2_frac;
     749             : 
     750         358 :     IF( x > 0 )
     751             :     {
     752         358 :         log2_int = norm_l( x );
     753         358 :         log2_frac = Log2_norm_lc( L_shl( x, log2_int ) );
     754             : 
     755         358 :         log2_work = L_mac0( 30 * 32768L, log2_frac, 1 );
     756         358 :         log2_work = L_msu( log2_work, log2_int, 16384 );
     757         358 :         log2_frac = L_Extract_lc( log2_work, &log2_int );
     758             : 
     759         358 :         return Pow2( log2_int, log2_frac );
     760             :     }
     761           0 :     return 0;
     762             : }

Generated by: LCOV version 1.14