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

Generated by: LCOV version 1.14