LCOV - code coverage report
Current view: top level - lib_com - enhancer_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 288 430 67.0 %
Date: 2025-05-03 01:55:50 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <stdint.h>
       5             : #include "options.h" /* Compilation switches                   */
       6             : #include "cnst.h"    /* Common constants                       */
       7             : #include "prot_fx.h" /* Function prototypes                    */
       8             : #include "rom_com.h" /* Static table prototypes                */
       9             : #include "basop_util.h"
      10             : 
      11             : /*---------------------------------------------------------------------*
      12             :  * Local constants
      13             :  *---------------------------------------------------------------------*/
      14             : #define pitch_0_9  14746 /* 0.9 in Q14 */
      15             : #define pitch_0_6  9830  /* 0.6 in Q14 */
      16             : #define SIZE       64
      17             : #define SIZE2      32
      18             : #define NUM_STAGES 5
      19             : 
      20             : /*---------------------------------------------------------------------*
      21             :  * Local functions
      22             :  *---------------------------------------------------------------------*/
      23             : static void phase_dispersion_fx( Word32 gain_code, Word16 gain_pit, Word16 code[], Word16 mode, struct dispMem_fx *dm_fx );
      24             : static void agc2_fx( const Word16 *sig_in, Word16 *sig_out, const Word16 l_trm );
      25             : 
      26             : /*======================================================================================*/
      27             : /* FUNCTION : enhancer_fx()                                                                */
      28             : /*--------------------------------------------------------------------------------------*/
      29             : /* PURPOSE : Enhancement of the excitation signal before synthesis                        */
      30             : /*--------------------------------------------------------------------------------------*/
      31             : /* INPUT ARGUMENTS :                                                                    */
      32             : /* _ (Word32) core_brate : decoder bitrate                                                */
      33             : /* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode                                */
      34             : /* _ (Word16) coder_type : coder type                                                    */
      35             : /* _ (Word16) i_subfr : subframe number                                                    */
      36             : /* _ (Word16) voice_fac : subframe voicing estimation  (Q15)                            */
      37             : /* _ (Word16) stab_fac : LP filter stablility measure  (Q15)                            */
      38             : /* _ (Word32) norm_gain_code : normalised innovative cb. gain  (Q16)                    */
      39             : /* _ (Word16) gain_inov : gain of the unscaled innovation (Q12)                         */
      40             : /* _ (Word16) gain_pit_fx : Pitch gain            (Q14)                                    */
      41             : /* _ (Word16) Q_exc : Q of the excitation                                                */
      42             : /* _ (Word16) Enc : Encoder  = 1; decoder = 0                                             */
      43             : /*--------------------------------------------------------------------------------------*/
      44             : /* OUTPUT ARGUMENTS :                                                                    */
      45             : /* _ (Word16*) voice_factors_fx : TBE voicing factor (Q15)                                */
      46             : /*--------------------------------------------------------------------------------------*/
      47             : /* INPUT/OUTPUT ARGUMENTS :                                                                */
      48             : /* _ (Word32*) gc_threshold : gain code threshold  (Q16)                                */
      49             : /* _ (Word16*[]) code : innovation (Q12)                                                */
      50             : /* _ (Word16*[]) exc2 : adapt. excitation/total exc (Q0)                                */
      51             : /* _ (struct dispMem_fx*) dm_fx : phase dispersion algorithm memory                        */
      52             : /*                                 (a[0]->Q0,a[1]->Q16,a[2-7]->Q14)                        */
      53             : /*--------------------------------------------------------------------------------------*/
      54             : 
      55             : /* _ None                                                                                */
      56             : /*--------------------------------------------------------------------------------------*/
      57             : /* RETURN ARGUMENTS :                                                                    */
      58             : /* _ None                                                                                */
      59             : /*======================================================================================*/
      60       55563 : void enhancer_fx(
      61             :     const Word32 core_brate,  /* i  : decoder bitrate                          */
      62             :     const Word16 Opt_AMR_WB,  /* i  : flag indicating AMR-WB IO mode           */
      63             :     const Word16 coder_type,  /* i  : coder type                               */
      64             :     const Word16 i_subfr,     /* i  : subframe number                          */
      65             :     const Word16 L_frame,     /* i  : frame size                               */
      66             :     const Word16 voice_fac,   /* i  : subframe voicing estimation         Q15  */
      67             :     const Word16 stab_fac,    /* i  : LP filter stablility measure        Q15  */
      68             :     Word32 norm_gain_code,    /* i  : normalised innovative cb. gain   Q16  */
      69             :     const Word16 gain_inov,   /* i  : gain of the unscaled innovation     Q12  */
      70             :     Word32 *gc_threshold,     /* i/o: gain code threshold                 Q16  */
      71             :     Word16 *code,             /* i/o: innovation                          Q12  */
      72             :     Word16 *exc2,             /* i/o: adapt. excitation/total exc.        Q_exc*/
      73             :     const Word16 gain_pit,    /* i  : quantized pitch gain                Q14  */
      74             :     struct dispMem_fx *dm_fx, /* i/o: phase dispersion algorithm memory        */
      75             :     const Word16 Q_exc        /* i  : Q of the excitation                      */
      76             : )
      77             : {
      78             :     Word16 tmp, fac, *pt_exc2;
      79             :     Word16 i;
      80             :     Word32 L_tmp;
      81             :     Word16 gain_code_hi;
      82             :     Word16 pit_sharp, tmp16;
      83             :     Word16 excp[L_SUBFR], sc;
      84             : 
      85             : 
      86       55563 :     pit_sharp = gain_pit;
      87       55563 :     move16(); /* to remove gcc warning */
      88       55563 :     pt_exc2 = exc2 + i_subfr;
      89             : 
      90             :     /*------------------------------------------------------------*
      91             :      * Phase dispersion to enhance noise at low bit rate
      92             :      *------------------------------------------------------------*/
      93             : 
      94       55563 :     i = 2;
      95       55563 :     move16(); /* no dispersion */
      96       55563 :     IF( Opt_AMR_WB )
      97             :     {
      98           0 :         IF( LE_32( core_brate, ACELP_6k60 ) )
      99             :         {
     100           0 :             i = 0;
     101           0 :             move16(); /* high dispersion  */
     102             :         }
     103           0 :         ELSE IF( LE_32( core_brate, ACELP_8k85 ) )
     104             :         {
     105           0 :             i = 1;
     106           0 :             move16(); /* low dispersion  */
     107             :         }
     108             :     }
     109       55563 :     ELSE IF( NE_16( coder_type, UNVOICED ) )
     110             : 
     111             :     {
     112       55563 :         test();
     113       55563 :         test();
     114       55563 :         test();
     115       55563 :         test();
     116       55563 :         IF( LE_32( core_brate, ACELP_7k20 ) )
     117             :         {
     118         280 :             i = 0;
     119         280 :             move16(); /* high dispersion  */
     120             :         }
     121       55283 :         ELSE IF( ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, TRANSITION ) || EQ_16( coder_type, AUDIO ) || coder_type == INACTIVE ) && LE_32( core_brate, ACELP_9k60 ) )
     122             :         {
     123        5088 :             i = 1;
     124        5088 :             move16(); /* low dispersion  */
     125             :         }
     126             :     }
     127             : 
     128       55563 :     phase_dispersion_fx( norm_gain_code, gain_pit, code, i, dm_fx );
     129             : 
     130             :     /*------------------------------------------------------------
     131             :      * noise enhancer
     132             :      *
     133             :      * - Enhance excitation on noise. (modify gain of code)
     134             :      *   If signal is noisy and LPC filter is stable, move gain
     135             :      *   of code 1.5 dB toward gain of code threshold.
     136             :      *   This decreases by 3 dB noise energy variation.
     137             :      *-----------------------------------------------------------*/
     138             : 
     139             :     /* tmp = 0.5f * (1.0f - voice_fac) */
     140       55563 :     tmp = msu_r_sat( 0x40000000 /*0.5.Q31*/, voice_fac, 16384 /*0.5.Q15*/ ); /*Q15 */ /* 1=unvoiced, 0=voiced */
     141             :     /* fac = stab_fac * tmp */
     142       55563 :     fac = mult( stab_fac, tmp ); /*Q15*/
     143             : 
     144       55563 :     IF( LT_32( norm_gain_code, *gc_threshold ) )
     145             :     {
     146       22766 :         L_tmp = Madd_32_16( norm_gain_code, norm_gain_code, 6226 /*0.19.Q15*/ ); /*Q16 */
     147       22766 :         L_tmp = L_min( L_tmp, *gc_threshold );                                   /*Q16 */
     148             :     }
     149             :     ELSE
     150             :     {
     151       32797 :         L_tmp = Mult_32_16( norm_gain_code, 27536 /*0.84.Q15*/ ); /*Q16 */
     152       32797 :         L_tmp = L_max( L_tmp, *gc_threshold );                    /*Q16 */
     153             :     }
     154       55563 :     *gc_threshold = L_tmp;
     155       55563 :     move32(); /*Q16 */
     156             : 
     157             :     /* gain_code = (fac * tmp) + (1.0 - fac) * gain_code ==> fac * (tmp - gain_code) + gain_code */
     158       55563 :     L_tmp = L_sub( L_tmp, norm_gain_code );                    /*Q16 */
     159       55563 :     norm_gain_code = Madd_32_16( norm_gain_code, L_tmp, fac ); /*Q16 */
     160             : 
     161             :     /* gain_code *= gain_inov - Inverse the normalization */
     162       55563 :     L_tmp = Mult_32_16( norm_gain_code, gain_inov ); /*Q13*/ /* gain_inov in Q12 */
     163             : 
     164       55563 :     sc = 6;
     165       55563 :     move16();
     166             : 
     167       55563 :     gain_code_hi = round_fx( L_shl( L_tmp, add( Q_exc, 3 ) ) ); /* in Q_exc */
     168             : 
     169             :     /*------------------------------------------------------------*
     170             :      * pitch enhancer
     171             :      *
     172             :      * - Enhance excitation on voiced. (HP filtering of code)
     173             :      *   On voiced signal, filtering of code by a smooth fir HP
     174             :      *   filter to decrease energy of code at low frequency.
     175             :      *------------------------------------------------------------*/
     176       55563 :     test();
     177       55563 :     IF( !Opt_AMR_WB && EQ_16( coder_type, UNVOICED ) )
     178             :     {
     179             :         /* Copy(code, exc2, L_SUBFR) */
     180           0 :         FOR( i = 0; i < L_SUBFR; i++ )
     181             :         {
     182           0 :             pt_exc2[i] = round_fx( L_shl( L_mult( gain_code_hi, code[i] ), sc ) ); /*Q0 */ /* code in Q12 (Q9 for encoder) */
     183           0 :             move16();
     184             :         }
     185             :     }
     186             :     ELSE
     187             :     {
     188       55563 :         test();
     189       55563 :         test();
     190       55563 :         IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
     191             :         {
     192           0 :             pit_sharp = shl_sat( gain_pit, 1 ); /* saturation can occur here Q14 -> Q15 */
     193             :             /* saturation takes care of "if (pit_sharp > 1.0) { pit_sharp=1.0; }" */
     194           0 :             IF( GT_16( pit_sharp, 16384 /*0.5.Q15*/ ) )
     195             :             {
     196           0 :                 tmp16 = mult( pit_sharp, 8192 /*0.25.Q15*/ );
     197           0 :                 FOR( i = 0; i < L_SUBFR; i++ )
     198             :                 {
     199             :                     /* excp[i] = pt_exc2[i] * pit_sharp * 0.25 */
     200           0 :                     excp[i] = mult_r( pt_exc2[i], tmp16 );
     201           0 :                     move16();
     202             :                 }
     203             :             }
     204             :         }
     205             : 
     206       55563 :         IF( EQ_16( L_frame, L_FRAME16k ) )
     207             :         {
     208             :             /* tmp = 0.150 * (1.0 + voice_fac) */
     209             :             /* 0.30=voiced, 0=unvoiced */
     210       26955 :             tmp = mac_r( 0x10000000L, voice_fac, 4915 /*0.15.Q15*/ ); /*Q15 */
     211             :         }
     212             :         ELSE
     213             :         {
     214             :             /* tmp = 0.125 * (1.0 + voice_fac) */
     215             :             /* 0.25=voiced, 0=unvoiced */
     216       28608 :             tmp = mac_r( 0x10000000L /*0.125.Q31*/, voice_fac, 4096 ); /*Q15 */
     217             :         }
     218             : 
     219             :         /*-----------------------------------------------------------------
     220             :          * Do a simple noncasual "sharpening": effectively an FIR
     221             :          * filter with coefs [-tmp 1.0 -tmp] where tmp=0...0.25.
     222             :          * This is applied to code and add_fxed to exc2
     223             :          *-----------------------------------------------------------------*/
     224             :         /* pt_exc2[0] += code[0] - tmp * code[1] */
     225       55563 :         L_tmp = L_deposit_h( code[0] );       /* if Enc :Q9 * Q15 -> Q25 */
     226       55563 :         L_tmp = L_msu( L_tmp, code[1], tmp ); /* Q12 * Q15 -> Q28 */
     227       55563 :         L_tmp = L_shl_sat( L_mult( gain_code_hi, extract_h( L_tmp ) ), sc );
     228       55563 :         pt_exc2[0] = msu_r_sat( L_tmp, -32768, pt_exc2[0] );
     229       55563 :         move16();
     230             : 
     231     3500469 :         FOR( i = 1; i < L_SUBFR - 1; i++ )
     232             :         {
     233             :             /* pt_exc2[i] += code[i] - tmp * code[i-1] - tmp * code[i+1] */
     234     3444906 :             L_tmp = L_msu( -32768, code[i], -32768 );
     235     3444906 :             L_tmp = L_msu( L_tmp, code[i + 1], tmp );
     236     3444906 :             tmp16 = msu_r_sat( L_tmp, code[i - 1], tmp );
     237     3444906 :             L_tmp = L_shl_sat( L_mult( gain_code_hi, tmp16 ), sc );
     238     3444906 :             pt_exc2[i] = msu_r_sat( L_tmp, -32768, pt_exc2[i] );
     239     3444906 :             move16();
     240             :         }
     241             : 
     242             :         /* pt_exc2[L_SUBFR-1] += code[L_SUBFR-1] - tmp * code[L_SUBFR-2] */
     243       55563 :         L_tmp = L_deposit_h( code[L_SUBFR - 1] );       /*Q28 */
     244       55563 :         L_tmp = L_msu( L_tmp, code[L_SUBFR - 2], tmp ); /*Q28 */
     245       55563 :         L_tmp = L_shl( L_mult( gain_code_hi, extract_h( L_tmp ) ), sc );
     246       55563 :         pt_exc2[L_SUBFR - 1] = msu_r_sat( L_tmp, -32768, pt_exc2[L_SUBFR - 1] );
     247       55563 :         move16();
     248       55563 :         test();
     249       55563 :         test();
     250       55563 :         IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
     251             :         {
     252           0 :             IF( GT_16( pit_sharp, 16384 /*0.5.Q115*/ ) )
     253             :             {
     254           0 :                 FOR( i = 0; i < L_SUBFR; i++ )
     255             :                 {
     256             :                     /* excp[i] += pt_exc2[i] */
     257           0 :                     excp[i] = add_sat( excp[i], pt_exc2[i] );
     258           0 :                     move16();
     259             :                 }
     260           0 :                 agc2_fx( pt_exc2, excp, L_SUBFR );
     261           0 :                 Copy( excp, pt_exc2, L_SUBFR );
     262             :             }
     263             :         }
     264             :     }
     265       55563 : }
     266             : 
     267             : 
     268             : /*======================================================================================*/
     269             : /* FUNCTION : enhancer_fx()                                                                */
     270             : /*--------------------------------------------------------------------------------------*/
     271             : /* PURPOSE : Enhancement of the excitation signal before synthesis                        */
     272             : /*--------------------------------------------------------------------------------------*/
     273             : /* INPUT ARGUMENTS :                                                                    */
     274             : /* _ (Word32) core_brate : decoder bitrate                                                */
     275             : /* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode                                */
     276             : /* _ (Word16) coder_type : coder type                                                    */
     277             : /* _ (Word16) i_subfr : subframe number                                                    */
     278             : /* _ (Word16) voice_fac : subframe voicing estimation  (Q15)                            */
     279             : /* _ (Word16) stab_fac : LP filter stablility measure  (Q15)                            */
     280             : /* _ (Word32) norm_gain_code : normalised innovative cb. gain  (Q16)                    */
     281             : /* _ (Word16) gain_inov : gain of the unscaled innovation (Q12)                         */
     282             : /* _ (Word16) gain_pit_fx : Pitch gain            (Q14)                                    */
     283             : /* _ (Word16) Q_exc : Q of the excitation                                                */
     284             : /* _ (Word16) Enc : Encoder  = 1; decoder = 0                                             */
     285             : /*--------------------------------------------------------------------------------------*/
     286             : /* OUTPUT ARGUMENTS :                                                                    */
     287             : /* _ (Word16*) voice_factors_fx : TBE voicing factor (Q15)                                */
     288             : /*--------------------------------------------------------------------------------------*/
     289             : /* INPUT/OUTPUT ARGUMENTS :                                                                */
     290             : /* _ (Word32*) gc_threshold : gain code threshold  (Q16)                                */
     291             : /* _ (Word16*[]) code : innovation (Q12)                                                */
     292             : /* _ (Word16*[]) exc2 : adapt. excitation/total exc (Q0)                                */
     293             : /* _ (struct dispMem_fx*) dm_fx : phase dispersion algorithm memory                        */
     294             : /*                                 (a[0]->Q0,a[1]->Q16,a[2-7]->Q14)                        */
     295             : /*--------------------------------------------------------------------------------------*/
     296             : 
     297             : /* _ None                                                                                */
     298             : /*--------------------------------------------------------------------------------------*/
     299             : /* RETURN ARGUMENTS :                                                                    */
     300             : /* _ None                                                                                */
     301             : /*======================================================================================*/
     302        5496 : void enhancer_ivas_fx(
     303             :     const Word16 codec_mode,  /* i  : flag indicating Codec Mode              */
     304             :     const Word32 core_brate,  /* i  : decoder bitrate                          */
     305             :     const Word16 cbk_index,   /* i  :                                         */
     306             :     const Word16 Opt_AMR_WB,  /* i  : flag indicating AMR-WB IO mode           */
     307             :     const Word16 coder_type,  /* i  : coder type                               */
     308             :     const Word16 i_subfr,     /* i  : subframe number                          */
     309             :     const Word16 L_frame,     /* i  : frame size                               */
     310             :     const Word16 voice_fac,   /* i  : subframe voicing estimation         Q15  */
     311             :     const Word16 stab_fac,    /* i  : LP filter stablility measure        Q15  */
     312             :     Word32 norm_gain_code,    /* i  : normalised innovative cb. gain   Q16  */
     313             :     const Word16 gain_inov,   /* i  : gain of the unscaled innovation     Q12  */
     314             :     Word32 *gc_threshold,     /* i/o: gain code threshold                 Q16  */
     315             :     Word16 *code,             /* i/o: innovation                          Q12  */
     316             :     Word16 *exc2,             /* i/o: adapt. excitation/total exc.        Q_exc*/
     317             :     const Word16 gain_pit,    /* i  : quantized pitch gain                Q14  */
     318             :     struct dispMem_fx *dm_fx, /* i/o: phase dispersion algorithm memory        */
     319             :     const Word16 Q_exc        /* i  : Q of the excitation                      */
     320             : )
     321             : {
     322             :     Word16 tmp, fac, *pt_exc2;
     323             :     Word16 i;
     324             :     Word32 L_tmp;
     325             :     Word16 gain_code_hi;
     326             :     Word16 pit_sharp, tmp16;
     327             :     Word16 excp[L_SUBFR], sc;
     328             : 
     329             : 
     330        5496 :     pit_sharp = gain_pit;
     331        5496 :     move16(); /* to remove gcc warning */
     332        5496 :     pt_exc2 = exc2 + i_subfr;
     333             : 
     334             :     /*------------------------------------------------------------*
     335             :      * Phase dispersion to enhance noise at low bit rate
     336             :      *------------------------------------------------------------*/
     337             : 
     338        5496 :     i = 2;
     339        5496 :     move16(); /* no dispersion */
     340        5496 :     test();
     341        5496 :     test();
     342        5496 :     test();
     343        5496 :     IF( Opt_AMR_WB )
     344             :     {
     345           0 :         IF( LE_32( core_brate, ACELP_6k60 ) )
     346             :         {
     347           0 :             i = 0;
     348           0 :             move16(); /* high dispersion  */
     349             :         }
     350           0 :         ELSE IF( LE_32( core_brate, ACELP_8k85 ) )
     351             :         {
     352           0 :             i = 1;
     353           0 :             move16(); /* low dispersion  */
     354             :         }
     355             :     }
     356        5496 :     ELSE IF( EQ_16( codec_mode, MODE1 ) && NE_16( coder_type, UNVOICED ) )
     357             : 
     358             :     {
     359           0 :         test();
     360           0 :         test();
     361           0 :         test();
     362           0 :         test();
     363           0 :         IF( LE_32( core_brate, ACELP_7k20 ) )
     364             :         {
     365           0 :             i = 0;
     366           0 :             move16(); /* high dispersion  */
     367             :         }
     368           0 :         ELSE IF( ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, TRANSITION ) || EQ_16( coder_type, AUDIO ) || coder_type == INACTIVE ) && LE_32( core_brate, ACELP_9k60 ) )
     369             :         {
     370           0 :             i = 1;
     371           0 :             move16(); /* low dispersion  */
     372             :         }
     373             :     }
     374        5496 :     ELSE IF( EQ_16( codec_mode, MODE2 ) )
     375             :     {
     376           0 :         test();
     377           0 :         test();
     378           0 :         test();
     379           0 :         test();
     380           0 :         test();
     381           0 :         test();
     382           0 :         test();
     383           0 :         test();
     384           0 :         IF( ( NE_16( coder_type, VOICED ) && LE_16( cbk_index, 2 ) ) || ( EQ_16( coder_type, UNVOICED ) && EQ_16( L_frame, L_FRAME ) && LE_16( cbk_index, 10 ) ) || ( EQ_16( coder_type, UNVOICED ) && EQ_16( L_frame, L_FRAME16k ) && LE_16( cbk_index, 14 ) ) )
     385             :         {
     386           0 :             i = 0; /* high dispersion  */
     387           0 :             move16();
     388             :         }
     389           0 :         ELSE IF( NE_16( coder_type, VOICED ) && LE_16( cbk_index, 7 ) )
     390             :         {
     391           0 :             i = 1; /* low dispersion  */
     392           0 :             move16();
     393             :         }
     394             :     }
     395        5496 :     ELSE IF( EQ_16( codec_mode, MODE1 ) && EQ_16( coder_type, UNVOICED ) && cbk_index /*uc_two_stage_flag*/ )
     396             :     {
     397        5496 :         i = 0; /* high dispersion  */
     398        5496 :         move16();
     399             :     }
     400             : 
     401        5496 :     phase_dispersion_fx( norm_gain_code, gain_pit, code, i, dm_fx );
     402             : 
     403             :     /*------------------------------------------------------------
     404             :      * noise enhancer
     405             :      *
     406             :      * - Enhance excitation on noise. (modify gain of code)
     407             :      *   If signal is noisy and LPC filter is stable, move gain
     408             :      *   of code 1.5 dB toward gain of code threshold.
     409             :      *   This decreases by 3 dB noise energy variation.
     410             :      *-----------------------------------------------------------*/
     411             : 
     412             :     /* tmp = 0.5f * (1.0f - voice_fac) */
     413        5496 :     tmp = msu_r_sat( 0x40000000 /*0.5.Q31*/, voice_fac, 16384 /*0.5.Q14*/ ); /*Q15 */ /* 1=unvoiced, 0=voiced */
     414             :     /* fac = stab_fac * tmp */
     415        5496 :     fac = mult( stab_fac, tmp ); /*Q15*/
     416             : 
     417        5496 :     IF( LT_32( norm_gain_code, *gc_threshold ) )
     418             :     {
     419        2713 :         L_tmp = Madd_32_16( norm_gain_code, norm_gain_code, 6226 /*0.19.Q15*/ ); /*Q16 */
     420        2713 :         L_tmp = L_min( L_tmp, *gc_threshold );                                   /*Q16 */
     421             :     }
     422             :     ELSE
     423             :     {
     424        2783 :         L_tmp = Mult_32_16( norm_gain_code, 27536 /*0.84.Q15*/ ); /*Q16 */
     425        2783 :         L_tmp = L_max( L_tmp, *gc_threshold );                    /*Q16 */
     426             :     }
     427        5496 :     *gc_threshold = L_tmp;
     428        5496 :     move32(); /*Q16 */
     429             : 
     430             :     /* gain_code = (fac * tmp) + (1.0 - fac) * gain_code ==> fac * (tmp - gain_code) + gain_code */
     431        5496 :     L_tmp = L_sub( L_tmp, norm_gain_code );                    /*Q16 */
     432        5496 :     norm_gain_code = Madd_32_16( norm_gain_code, L_tmp, fac ); /*Q16 */
     433             : 
     434             :     /* gain_code *= gain_inov - Inverse the normalization */
     435        5496 :     L_tmp = Mult_32_16( norm_gain_code, gain_inov ); /*Q13*/ /* gain_inov in Q12 */
     436             : 
     437        5496 :     sc = 6;
     438        5496 :     move16();
     439             : 
     440        5496 :     gain_code_hi = round_fx( L_shl( L_tmp, add( Q_exc, 3 ) ) ); /* in Q_exc */
     441             : 
     442             :     /*------------------------------------------------------------*
     443             :      * pitch enhancer
     444             :      *
     445             :      * - Enhance excitation on voiced. (HP filtering of code)
     446             :      *   On voiced signal, filtering of code by a smooth fir HP
     447             :      *   filter to decrease energy of code at low frequency.
     448             :      *------------------------------------------------------------*/
     449        5496 :     test();
     450        5496 :     IF( !Opt_AMR_WB && EQ_16( coder_type, UNVOICED ) )
     451             :     {
     452             :         /* Copy(code, exc2, L_SUBFR) */
     453      357240 :         FOR( i = 0; i < L_SUBFR; i++ )
     454             :         {
     455      351744 :             pt_exc2[i] = round_fx( L_shl( L_mult( gain_code_hi, code[i] ), sc ) ); /*Q0 */ /* code in Q12 (Q9 for encoder) */
     456      351744 :             move16();
     457             :         }
     458             :     }
     459             :     ELSE
     460             :     {
     461           0 :         test();
     462           0 :         test();
     463           0 :         IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
     464             :         {
     465           0 :             pit_sharp = shl_sat( gain_pit, 1 ); /* saturation can occur here Q14 -> Q15 */
     466             :             /* saturation takes care of "if (pit_sharp > 1.0) { pit_sharp=1.0; }" */
     467           0 :             IF( GT_16( pit_sharp, 16384 /*0.5.Q15*/ ) )
     468             :             {
     469           0 :                 tmp16 = mult( pit_sharp, 8192 /*0.25.Q15*/ );
     470           0 :                 FOR( i = 0; i < L_SUBFR; i++ )
     471             :                 {
     472             :                     /* excp[i] = pt_exc2[i] * pit_sharp * 0.25 */
     473           0 :                     excp[i] = mult_r( pt_exc2[i], tmp16 );
     474           0 :                     move16();
     475             :                 }
     476             :             }
     477             :         }
     478             : 
     479           0 :         IF( EQ_16( L_frame, L_FRAME16k ) )
     480             :         {
     481             :             /* tmp = 0.150 * (1.0 + voice_fac) */
     482             :             /* 0.30=voiced, 0=unvoiced */
     483           0 :             tmp = mac_r( 0x13333333L /*0.150.Q31*/, voice_fac, 4915 /*0.150.Q15*/ ); /*Q15 */
     484             :         }
     485             :         ELSE
     486             :         {
     487             :             /* tmp = 0.125 * (1.0 + voice_fac) */
     488             :             /* 0.25=voiced, 0=unvoiced */
     489           0 :             tmp = mac_r( 0x10000000L /*0.125.Q31*/, voice_fac, 4096 ); /*Q15 */
     490             :         }
     491             : 
     492             :         /*-----------------------------------------------------------------
     493             :          * Do a simple noncasual "sharpening": effectively an FIR
     494             :          * filter with coefs [-tmp 1.0 -tmp] where tmp=0...0.25.
     495             :          * This is applied to code and add_fxed to exc2
     496             :          *-----------------------------------------------------------------*/
     497             :         /* pt_exc2[0] += code[0] - tmp * code[1] */
     498           0 :         L_tmp = L_deposit_h( code[0] );       /* if Enc :Q9 * Q15 -> Q25 */
     499           0 :         L_tmp = L_msu( L_tmp, code[1], tmp ); /* Q12 * Q15 -> Q28 */
     500           0 :         L_tmp = L_shl( L_mult( gain_code_hi, extract_h( L_tmp ) ), sc );
     501           0 :         pt_exc2[0] = msu_r( L_tmp, -32768, pt_exc2[0] );
     502           0 :         move16(); /* in Q_exc */
     503             : 
     504           0 :         FOR( i = 1; i < L_SUBFR - 1; i++ )
     505             :         {
     506             :             /* pt_exc2[i] += code[i] - tmp * code[i-1] - tmp * code[i+1] */
     507           0 :             L_tmp = L_msu( -32768, code[i], -32768 );
     508           0 :             L_tmp = L_msu( L_tmp, code[i + 1], tmp );
     509           0 :             tmp16 = msu_r( L_tmp, code[i - 1], tmp );
     510           0 :             L_tmp = L_shl( L_mult( gain_code_hi, tmp16 ), sc );
     511           0 :             pt_exc2[i] = msu_r_sat( L_tmp, -32768, pt_exc2[i] );
     512           0 :             move16(); /* in Q_exc */
     513             :         }
     514             : 
     515             :         /* pt_exc2[L_SUBFR-1] += code[L_SUBFR-1] - tmp * code[L_SUBFR-2] */
     516           0 :         L_tmp = L_deposit_h( code[L_SUBFR - 1] );       /*Q28 */
     517           0 :         L_tmp = L_msu( L_tmp, code[L_SUBFR - 2], tmp ); /*Q28 */
     518           0 :         L_tmp = L_shl( L_mult( gain_code_hi, extract_h( L_tmp ) ), sc );
     519           0 :         pt_exc2[L_SUBFR - 1] = msu_r( L_tmp, -32768, pt_exc2[L_SUBFR - 1] );
     520           0 :         move16(); /* in Q_exc */
     521           0 :         test();
     522           0 :         test();
     523           0 :         IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
     524             :         {
     525           0 :             IF( GT_16( pit_sharp, 16384 /*0.5.Q14*/ ) )
     526             :             {
     527           0 :                 FOR( i = 0; i < L_SUBFR; i++ )
     528             :                 {
     529             :                     /* excp[i] += pt_exc2[i] */
     530           0 :                     excp[i] = add( excp[i], pt_exc2[i] );
     531           0 :                     move16();
     532             :                 }
     533           0 :                 agc2_fx( pt_exc2, excp, L_SUBFR );
     534           0 :                 Copy( excp, pt_exc2, L_SUBFR );
     535             :             }
     536             :         }
     537             :     }
     538        5496 : }
     539             : 
     540      436537 : void enhancer_ivas_fx2(
     541             :     const Word32 core_brate,  /* i  : decoder bitrate                          */
     542             :     const Word16 Opt_AMR_WB,  /* i  : flag indicating AMR-WB IO mode           */
     543             :     const Word16 coder_type,  /* i  : coder type                               */
     544             :     const Word16 i_subfr,     /* i  : subframe number                          */
     545             :     const Word16 L_frame,     /* i  : frame size                               */
     546             :     const Word16 voice_fac,   /* i  : subframe voicing estimation         Q15  */
     547             :     const Word16 stab_fac,    /* i  : LP filter stablility measure        Q15  */
     548             :     Word32 norm_gain_code,    /* i  : normalised innovative cb. gain   Q16  */
     549             :     const Word16 gain_inov,   /* i  : gain of the unscaled innovation     Q12  */
     550             :     Word32 *gc_threshold,     /* i/o: gain code threshold                 Q16  */
     551             :     Word16 *code,             /* i/o: innovation                          Q12  */
     552             :     Word16 *exc2,             /* i/o: adapt. excitation/total exc.        Q_exc*/
     553             :     const Word16 gain_pit,    /* i  : quantized pitch gain                Q14  */
     554             :     struct dispMem_fx *dm_fx, /* i/o: phase dispersion algorithm memory        */
     555             :     const Word16 Q_exc        /* i  : Q of the excitation                      */
     556             : )
     557             : {
     558             :     Word16 tmp, fac, *pt_exc2;
     559             :     Word16 i;
     560             :     Word32 L_tmp;
     561             :     Word32 L_tmp1, L_tmp2;
     562             :     Word16 gain_code_hi;
     563             :     Word16 pit_sharp, tmp16;
     564             :     Word16 excp[L_SUBFR], sc;
     565             :     Word64 w_temp;
     566             : 
     567             : 
     568      436537 :     pit_sharp = gain_pit;
     569      436537 :     move16(); /* to remove gcc warning */
     570      436537 :     pt_exc2 = exc2 + i_subfr;
     571             : 
     572             :     /*------------------------------------------------------------*
     573             :      * Phase dispersion to enhance noise at low bit rate
     574             :      *------------------------------------------------------------*/
     575             : 
     576      436537 :     i = 2;
     577      436537 :     move16(); /* no dispersion */
     578      436537 :     IF( Opt_AMR_WB )
     579             :     {
     580           0 :         IF( LE_32( core_brate, ACELP_6k60 ) )
     581             :         {
     582           0 :             i = 0;
     583           0 :             move16(); /* high dispersion  */
     584             :         }
     585           0 :         ELSE IF( LE_32( core_brate, ACELP_8k85 ) )
     586             :         {
     587           0 :             i = 1;
     588           0 :             move16(); /* low dispersion  */
     589             :         }
     590             :     }
     591      436537 :     ELSE IF( NE_16( coder_type, UNVOICED ) )
     592             : 
     593             :     {
     594      436537 :         test();
     595      436537 :         test();
     596      436537 :         test();
     597      436537 :         test();
     598      436537 :         IF( LE_32( core_brate, ACELP_7k20 ) )
     599             :         {
     600        4700 :             i = 0;
     601        4700 :             move16(); /* high dispersion  */
     602             :         }
     603      431837 :         ELSE IF( ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, TRANSITION ) || EQ_16( coder_type, AUDIO ) || coder_type == INACTIVE ) && LE_32( core_brate, ACELP_9k60 ) )
     604             :         {
     605       31928 :             i = 1;
     606       31928 :             move16(); /* low dispersion  */
     607             :         }
     608             :     }
     609             : 
     610      436537 :     phase_dispersion_fx( norm_gain_code, gain_pit, code, i, dm_fx );
     611             : 
     612             :     /*------------------------------------------------------------
     613             :      * noise enhancer
     614             :      *
     615             :      * - Enhance excitation on noise. (modify gain of code)
     616             :      *   If signal is noisy and LPC filter is stable, move gain
     617             :      *   of code 1.5 dB toward gain of code threshold.
     618             :      *   This decreases by 3 dB noise energy variation.
     619             :      *-----------------------------------------------------------*/
     620             : 
     621             :     /* tmp = 0.5f * (1.0f - voice_fac) */
     622      436537 :     tmp = msu_r_sat( 0x40000000 /*0.5.Q31*/, voice_fac, 16384 /*0.5.Q15*/ ); /*Q15 */ /* 1=unvoiced, 0=voiced */
     623             :     /* fac = stab_fac * tmp */
     624      436537 :     fac = mult( stab_fac, tmp ); /*Q15*/
     625             : 
     626      436537 :     IF( LT_32( norm_gain_code, *gc_threshold ) )
     627             :     {
     628      227722 :         L_tmp = Madd_32_16( norm_gain_code, norm_gain_code, 6226 /*0.19.Q15*/ ); /*Q16 */
     629      227722 :         L_tmp = L_min( L_tmp, *gc_threshold );                                   /*Q16 */
     630             :     }
     631             :     ELSE
     632             :     {
     633      208815 :         L_tmp = Mult_32_16( norm_gain_code, 27536 /*0.84.Q15*/ ); /*Q16 */
     634      208815 :         L_tmp = L_max( L_tmp, *gc_threshold );                    /*Q16 */
     635             :     }
     636      436537 :     *gc_threshold = L_tmp;
     637      436537 :     move32(); /*Q16 */
     638             : 
     639             :     /* gain_code = (fac * tmp) + (1.0 - fac) * gain_code ==> fac * (tmp - gain_code) + gain_code */
     640      436537 :     L_tmp = L_sub( L_tmp, norm_gain_code );                    /*Q16 */
     641      436537 :     norm_gain_code = Madd_32_16( norm_gain_code, L_tmp, fac ); /*Q16 */
     642             : 
     643             :     /* gain_code *= gain_inov - Inverse the normalization */
     644      436537 :     L_tmp = Mult_32_16( norm_gain_code, gain_inov ); /*Q13*/ /* gain_inov in Q12 */
     645             : 
     646      436537 :     sc = 6;
     647      436537 :     move16();
     648             : 
     649      436537 :     gain_code_hi = round_fx( L_shl( L_tmp, add( Q_exc, 3 ) ) ); /* in Q_exc */
     650             : 
     651             :     /*------------------------------------------------------------*
     652             :      * pitch enhancer
     653             :      *
     654             :      * - Enhance excitation on voiced. (HP filtering of code)
     655             :      *   On voiced signal, filtering of code by a smooth fir HP
     656             :      *   filter to decrease energy of code at low frequency.
     657             :      *------------------------------------------------------------*/
     658      436537 :     test();
     659      436537 :     IF( !Opt_AMR_WB && EQ_16( coder_type, UNVOICED ) )
     660             :     {
     661             :         /* Copy(code, exc2, L_SUBFR) */
     662           0 :         FOR( i = 0; i < L_SUBFR; i++ )
     663             :         {
     664           0 :             pt_exc2[i] = round_fx( L_shl( L_mult( gain_code_hi, code[i] ), sc ) ); /*Q0 */ /* code in Q12 (Q9 for encoder) */
     665           0 :             move16();
     666             :         }
     667             :     }
     668             :     ELSE
     669             :     {
     670      436537 :         test();
     671      436537 :         test();
     672      436537 :         IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
     673             :         {
     674           0 :             pit_sharp = shl_sat( gain_pit, 1 ); /* saturation can occur here Q14 -> Q15 */
     675             :             /* saturation takes care of "if (pit_sharp > 1.0) { pit_sharp=1.0; }" */
     676           0 :             IF( GT_16( pit_sharp, 16384 /*0.5.Q15*/ ) )
     677             :             {
     678           0 :                 tmp16 = mult( pit_sharp, 8192 /*0.25.Q15*/ );
     679           0 :                 FOR( i = 0; i < L_SUBFR; i++ )
     680             :                 {
     681             :                     /* excp[i] = pt_exc2[i] * pit_sharp * 0.25 */
     682           0 :                     excp[i] = mult_r( pt_exc2[i], tmp16 );
     683           0 :                     move16();
     684             :                 }
     685             :             }
     686             :         }
     687             : 
     688      436537 :         IF( EQ_16( L_frame, L_FRAME16k ) )
     689             :         {
     690             :             /* tmp = 0.150 * (1.0 + voice_fac) */
     691             :             /* 0.30=voiced, 0=unvoiced */
     692      249485 :             tmp = mac_r( 0x13333333L /*0.150.Q31*/, voice_fac, 4915 /*0.150.Q15*/ ); /*Q15 */
     693             :         }
     694             :         ELSE
     695             :         {
     696             :             /* tmp = 0.125 * (1.0 + voice_fac) */
     697             :             /* 0.25=voiced, 0=unvoiced */
     698      187052 :             tmp = mac_r( 0x10000000L /*0.125.Q31*/, voice_fac, 4096 /*0.125.Q15*/ ); /*Q15 */
     699             :         }
     700             : 
     701             :         /*-----------------------------------------------------------------
     702             :          * Do a simple noncasual "sharpening": effectively an FIR
     703             :          * filter with coefs [-tmp 1.0 -tmp] where tmp=0...0.25.
     704             :          * This is applied to code and add_fxed to exc2
     705             :          *-----------------------------------------------------------------*/
     706             : 
     707      436537 :         L_tmp1 = L_deposit_h( gain_code_hi ); // Q = 16 + Q_exc, gain_code
     708      436537 :         L_tmp2 = L_mult( tmp, gain_code_hi ); // Q = 16 + Q_exc, gain_code * temp
     709             : 
     710             :         /* pt_exc2[0] += code[0] - tmp * code[1] */
     711      436537 :         w_temp = W_msu_32_16( W_mult_32_16( L_tmp1, code[0] ), L_tmp2, code[1] ); // Q = 32 + Q_exc - sc (16+Q_exc+15-sc+1)
     712      436537 :         w_temp = W_shl( w_temp, sc );                                             // Q = 32 + Q_exc
     713      436537 :         pt_exc2[0] = W_round32_s( W_msu_32_16( w_temp, MIN_32, pt_exc2[0] ) );    // Q = Q_exc
     714      436537 :         move16();
     715             : 
     716    27501831 :         FOR( i = 1; i < L_SUBFR - 1; i++ )
     717             :         {
     718             :             /* pt_exc2[i] += (code[i] - tmp * code[i-1] - tmp * code[i+1]) * gain_code */
     719    27065294 :             w_temp = W_msu_32_16( W_mult_32_16( L_tmp1, code[i] ), L_tmp2, code[i - 1] ); // Q = 32 + Q_exc - sc (16+Q_exc+15-sc+1)
     720    27065294 :             w_temp = W_msu_32_16( w_temp, L_tmp2, code[i + 1] );                          // Q = 32 + Q_exc - sc (16+Q_exc+15-sc+1)
     721    27065294 :             w_temp = W_shl( w_temp, sc );                                                 // Q = 32 + Q_exc
     722    27065294 :             pt_exc2[i] = W_round32_s( W_msu_32_16( w_temp, MIN_32, pt_exc2[i] ) );        // Q = Q_exc
     723    27065294 :             move16();
     724             :         }
     725             : 
     726             :         /* pt_exc2[L_SUBFR-1] += code[L_SUBFR-1] - tmp * code[L_SUBFR-2] */
     727      436537 :         w_temp = W_msu_32_16( W_mult_32_16( L_tmp1, code[L_SUBFR - 1] ), L_tmp2, code[L_SUBFR - 2] ); // Q = 32 + Q_exc - sc (16+Q_exc+15-sc+1)
     728      436537 :         w_temp = W_shl( w_temp, sc );                                                                 // Q = 32 + Q_exc
     729      436537 :         pt_exc2[L_SUBFR - 1] = W_round32_s( W_msu_32_16( w_temp, MIN_32, pt_exc2[L_SUBFR - 1] ) );    // Q = Q_exc
     730      436537 :         move16();
     731             : 
     732      436537 :         test();
     733      436537 :         test();
     734      436537 :         IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
     735             :         {
     736           0 :             IF( GT_16( pit_sharp, 16384 /*0.5.Q15*/ ) )
     737             :             {
     738           0 :                 FOR( i = 0; i < L_SUBFR; i++ )
     739             :                 {
     740             :                     /* excp[i] += pt_exc2[i] */
     741           0 :                     excp[i] = add_sat( excp[i], pt_exc2[i] );
     742           0 :                     move16();
     743             :                 }
     744           0 :                 agc2_fx( pt_exc2, excp, L_SUBFR );
     745           0 :                 Copy( excp, pt_exc2, L_SUBFR );
     746             :             }
     747             :         }
     748             :     }
     749      436537 : }
     750             : 
     751             : /*---------------------------------------------------------*
     752             :  * Enhancement of the excitation signal before synthesis
     753             :  *---------------------------------------------------------*/
     754             : 
     755        6070 : Word16 E_UTIL_enhancer(
     756             :     Word16 voice_fac,       /* i  : subframe voicing estimation         Q15 */
     757             :     Word16 stab_fac,        /* i  : LP filter stability measure         Q15 */
     758             :     Word32 gain_code,       /* i  : innovative cb. gain               15Q16 */
     759             :     Word16 gain_inov,       /* i  : gain of the unscaled innovation     Q11 */
     760             :     Word32 *gc_threshold,   /* i/o: gain code threshold               15Q16 */
     761             :     Word16 *code,           /* i/o: innovation(in: Q9)             code_exp */
     762             :     Word16 *exc2,           /* i/o: adapt. excitation/total exc.            */
     763             :     Word16 gain_pit,        /* i  : Quantized pitch gain               1Q14 */
     764             :     Word32 *prev_gain_code, /* i/o: previous codebook gain            15Q16 */
     765             :     Word16 prev_gain_pit[], /* i/o: previous pitch gain, size=6        1Q14 */
     766             :     Word16 *prev_state,     /* i/o: Phase dispersion algorithm memory    Q0 */
     767             :     Word16 coder_type,      /* i  : coder type                              */
     768             :     Word16 cdk_index,       /* i  :                                         */
     769             :     Word16 L_subfr,         /* i  : length of subframe                      */
     770             :     Word16 L_frame,         /* i  : frame size                              */
     771             :     Word16 Q_new )
     772             : {
     773             :     Word16 disp_mode, i;
     774             :     Word16 tmp, fac, gain;
     775             :     Word32 L_tmp;
     776             :     Word16 code_exp, exc2_exp;
     777             :     Word16 max_cdk_index_uv;
     778             : 
     779        6070 :     move16();
     780        6070 :     code_exp = 15 - 9;
     781        6070 :     exc2_exp = sub( 15, Q_new );
     782        6070 :     gain_inov = shr( gain_inov, 1 );
     783             :     /*-----------------------------------------------------------------*
     784             :      * Phase dispersion to enhance noise at low bit rates
     785             :      *-----------------------------------------------------------------*/
     786             : 
     787        6070 :     max_cdk_index_uv = 10;
     788        6070 :     move16();
     789        6070 :     if ( EQ_16( L_frame, L_FRAME16k ) )
     790             :     {
     791        6070 :         max_cdk_index_uv = 14;
     792        6070 :         move16();
     793             :     }
     794        6070 :     disp_mode = 2; /* any=off */
     795        6070 :     move16();
     796        6070 :     test();
     797        6070 :     test();
     798        6070 :     test();
     799        6070 :     test();
     800        6070 :     IF( ( ( NE_16( coder_type, VOICED ) ) && ( LE_16( cdk_index, 2 ) ) ) || ( ( EQ_16( coder_type, UNVOICED ) ) && ( LE_16( cdk_index, max_cdk_index_uv ) ) ) )
     801             :     {
     802           0 :         disp_mode = 0; /* high */
     803           0 :         move16();
     804             :     }
     805        6070 :     ELSE IF( ( NE_16( coder_type, VOICED ) ) && ( LE_16( cdk_index, 7 ) ) )
     806             :     {
     807           0 :         disp_mode = 1; /* low  */
     808           0 :         move16();
     809             :     }
     810             : 
     811        6070 :     phase_dispersion( gain_code, gain_pit, code, &code_exp, disp_mode, prev_gain_code, prev_gain_pit, prev_state, L_subfr );
     812             : 
     813             :     /*------------------------------------------------------------*
     814             :      * noise enhancer                                             *
     815             :      * ~~~~~~~~~~~~~~                                             *
     816             :      * - Enhance excitation on noise. (modify gain of code)       *
     817             :      *   If signal is noisy and LPC filter is stable, move gain   *
     818             :      *   of code 1.5 dB toward gain of code threshold.            *
     819             :      *   This decrease by 3 dB noise energy variation.            *
     820             :      *------------------------------------------------------------*/
     821        6070 :     fac = 0;
     822        6070 :     move16();
     823             : 
     824             :     /* if gain_code is computed function of energy, noise enhancer is by-passed.*/
     825             :     BASOP_SATURATE_WARNING_OFF_EVS
     826        6070 :     tmp = msu_r_sat( 1073741824l /*0.5f Q31*/, 16384 /*0.5f Q15*/, voice_fac ); /* 1=unvoiced, 0=voiced */
     827             :     BASOP_SATURATE_WARNING_ON_EVS
     828        6070 :     fac = mult_r( stab_fac, tmp ); /* fac in Q15 */
     829             : 
     830        6070 :     L_tmp = gain_code; /* L_tmp in 15Q16 */
     831        6070 :     move32();
     832             : 
     833        6070 :     IF( LT_32( L_tmp, *gc_threshold ) )
     834             :     {
     835        3376 :         L_tmp = L_shl( Mpy_32_32( L_tmp, 1277752832l /*1.19f/2.0f Q31*/ ), 1 );
     836        3376 :         L_tmp = L_min( L_tmp, *gc_threshold );
     837             :     }
     838             :     ELSE
     839             :     {
     840        2694 :         L_tmp = Mpy_32_32( L_tmp, 1804608000l /*1.0f/1.19f Q31*/ );
     841        2694 :         L_tmp = L_max( L_tmp, *gc_threshold );
     842             :     }
     843             : 
     844        6070 :     *gc_threshold = L_tmp; /* in 15Q16 */
     845        6070 :     move32();
     846             : 
     847             :     /* gain = ( (fac * L_tmp) + (gain_code - fac*gain_code) ) * gain_inov */
     848             :     /* exponent of L_tmp: 31-16 + 15-11 */
     849        6070 :     L_tmp = Mpy_32_16_1( L_add( Mpy_32_16_1( L_tmp, fac ), L_sub( gain_code, Mpy_32_16_1( gain_code, fac ) ) ), gain_inov );
     850             : 
     851             :     /* exponent gain: 31-16 + 15-11 - tmp */
     852        6070 :     tmp = norm_l( L_tmp );
     853             : 
     854             :     /* exponent of code: 31-16 + 15-11 - tmp + code_exp */
     855        6070 :     code_exp = sub( add( 31 - 16 + 15 - 11, code_exp ), tmp );
     856             : 
     857        6070 :     L_tmp = L_shl_sat( L_tmp, tmp );
     858        6070 :     gain = round_fx_sat( L_tmp );
     859             : 
     860      394550 :     FOR( i = 0; i < L_subfr; i++ )
     861             :     {
     862      388480 :         code[i] = mult_r( code[i], gain );
     863      388480 :         move16();
     864             :     }
     865             : 
     866             :     /*------------------------------------------------------------*
     867             :      * pitch enhancer                                             *
     868             :      * ~~~~~~~~~~~~~~                                             *
     869             :      * - Enhance excitation on voice. (HP filtering of code)      *
     870             :      *   On voiced signal, filtering of code by a smooth fir HP   *
     871             :      *   filter to decrease energy of code in low frequency.      *
     872             :      *------------------------------------------------------------*/
     873             : 
     874             :     /* exponent difference of code and exc2. +1 accounts for headroom required below. */
     875        6070 :     gain = add( sub( code_exp, exc2_exp ), 1 );
     876             : 
     877        6070 :     tmp = mac_r( 268435456l /*0.125f Q31*/, 4096 /*0.125f Q15*/, voice_fac ); /* 0.25=voiced, 0=unvoiced */
     878        6070 :     IF( EQ_16( L_frame, L_FRAME16k ) )
     879             :     {
     880        6070 :         tmp = mac_r( 322122560l /*0.150f Q31*/, 4915 /*0.150f Q15*/, voice_fac ); /* 0.30=voiced, 0=unvoiced */
     881             :     }
     882             : 
     883             :     /* exc2[0]         = exc2[0]         + code[0]         - tmp*code[1]; */
     884        6070 :     L_tmp = L_mult( code[0], 16384 );
     885        6070 :     L_tmp = L_msu0( L_tmp, tmp, code[1] );
     886        6070 :     IF( gain )
     887             :     {
     888        5909 :         L_tmp = L_shl_sat( L_tmp, gain );
     889             :     }
     890        6070 :     exc2[0] = msu_r_sat( L_tmp, -32768, exc2[0] );
     891        6070 :     move16();
     892             : 
     893      382410 :     FOR( i = 1; i < L_subfr - 1; i++ )
     894             :     {
     895             :         /* exc2[i]         = exc2[i]         + code[i]         - tmp*(code[i+1]+code[i-1]); */
     896      376340 :         L_tmp = L_mult( code[i], 16384 );
     897      376340 :         L_tmp = L_msu0_sat( L_tmp, tmp, code[i - 1] );
     898      376340 :         L_tmp = L_msu0_sat( L_tmp, tmp, code[i + 1] );
     899      376340 :         IF( gain )
     900             :         {
     901      366358 :             L_tmp = L_shl_sat( L_tmp, gain );
     902             :         }
     903      376340 :         exc2[i] = msu_r_sat( L_tmp, -32768, exc2[i] );
     904      376340 :         move16();
     905             :     }
     906             :     /* exc2[L_subfr-1] = exc2[L_subfr-1] + code[L_subfr-1] - tmp*code[L_subfr-2]; */
     907        6070 :     L_tmp = L_mult( code[i], 16384 );
     908        6070 :     L_tmp = L_msu0_sat( L_tmp, tmp, code[i - 1] );
     909        6070 :     IF( gain )
     910             :     {
     911        5909 :         L_tmp = L_shl_sat( L_tmp, gain );
     912             :     }
     913        6070 :     exc2[i] = msu_r_sat( L_tmp, -32768, exc2[i] );
     914        6070 :     move16();
     915             : 
     916        6070 :     return code_exp;
     917             : }
     918             : 
     919             : 
     920             : /*-----------------------------------------------------------------------*
     921             :  * Phase_dispersion:
     922             :  *
     923             :  * post-processing to enhance noise in low bit rate.
     924             :  *-----------------------------------------------------------------------*/
     925             : /*======================================================================================*/
     926             : /* FUNCTION : phase_dispersion_fx()                                                        */
     927             : /*--------------------------------------------------------------------------------------*/
     928             : /* PURPOSE : post-processing to enhance noise in low bit rate.                            */
     929             : /*--------------------------------------------------------------------------------------*/
     930             : /* INPUT ARGUMENTS :                                                                    */
     931             : /* _ (Word32) gain_code : gain of code  Q16                                                */
     932             : /* _ (Word16) gain_pit : gain of pitch    Q14                                                */
     933             : /* _ (Word16) mode : level, 0=hi, 1=lo, 2=off                                            */
     934             : /*--------------------------------------------------------------------------------------*/
     935             : /* OUTPUT ARGUMENTS :                                                                    */
     936             : /* _ None                                                                                */
     937             : /*--------------------------------------------------------------------------------------*/
     938             : /* INPUT/OUTPUT ARGUMENTS :                                                                */
     939             : /* _ (Word16[]) code : code vector (Q12)                                                */
     940             : /* _ (struct dispMem_fx*) dm_fx : static memory (size = 8)                                */
     941             : /*                                 (a[0]->Q0,a[1]->Q16,a[2-7]->Q14)                        */
     942             : /*--------------------------------------------------------------------------------------*/
     943             : 
     944             : /* _ None                                                                                */
     945             : /*--------------------------------------------------------------------------------------*/
     946             : /* RETURN ARGUMENTS :                                                                    */
     947             : /* _ None                                                                                */
     948             : /*======================================================================================*/
     949      497596 : static void phase_dispersion_fx(
     950             :     Word32 gain_code,        /* i  : gain of code              Q16  */
     951             :     Word16 gain_pit,         /* i  : gain of pitch            Q14  */
     952             :     Word16 code[],           /* i/o: code vector                   */
     953             :     Word16 mode,             /* i  : level, 0=hi, 1=lo, 2=off      */
     954             :     struct dispMem_fx *dm_fx /* i/o: static memory (size = 8)      */
     955             : )
     956             : {
     957             :     Word16 i, j, state;
     958             :     Word16 *prev_gain_pit, *prev_state;
     959             :     Word32 *prev_gain_code;
     960             :     Word16 *code2_real, *code2_imag;
     961             :     Word16 *code_real, *code_imag;
     962             :     const Word16 *h_real, *h_imag;
     963             : 
     964             :     Word16 code2[2 * L_SUBFR];
     965             : 
     966      497596 :     prev_state = &( dm_fx->prev_state );
     967      497596 :     prev_gain_code = &( dm_fx->prev_gain_code );
     968      497596 :     prev_gain_pit = dm_fx->prev_gain_pit;
     969             : 
     970      497596 :     state = 2;
     971      497596 :     move16();
     972      497596 :     if ( LT_16( gain_pit, pitch_0_9 ) )
     973             :     {
     974      358600 :         state = 1;
     975      358600 :         move16();
     976             :     }
     977             : 
     978      497596 :     if ( LT_16( gain_pit, pitch_0_6 ) )
     979             :     {
     980      196962 :         state = 0;
     981      196962 :         move16();
     982             :     }
     983             : 
     984     2985576 :     FOR( i = 5; i > 0; i-- )
     985             :     {
     986     2487980 :         prev_gain_pit[i] = prev_gain_pit[i - 1];
     987     2487980 :         move16();
     988             :     }
     989      497596 :     prev_gain_pit[0] = gain_pit;
     990      497596 :     move16();
     991             : 
     992      497596 :     IF( GT_32( L_sub_sat( gain_code, *prev_gain_code ), L_shl_sat( *prev_gain_code, 1 ) ) )
     993             :     {
     994       15275 :         state = s_min( add( state, 1 ), 2 );
     995             :     }
     996             :     ELSE
     997             :     {
     998      482321 :         j = 0;
     999      482321 :         move16();
    1000             : 
    1001     3376247 :         FOR( i = 0; i < 6; i++ )
    1002             :         {
    1003     2893926 :             j = sub( j, shr( sub( prev_gain_pit[i], pitch_0_6 ), 15 ) );
    1004             :         }
    1005             : 
    1006      482321 :         if ( GT_16( j, 2 ) )
    1007             :         {
    1008      230091 :             state = 0;
    1009      230091 :             move16();
    1010             :         }
    1011             : 
    1012      482321 :         if ( GT_16( sub( state, *prev_state ), 1 ) )
    1013             :         {
    1014       18181 :             state = sub( state, 1 );
    1015             :         }
    1016             :     }
    1017             : 
    1018      497596 :     *prev_gain_code = gain_code;
    1019      497596 :     move32();
    1020      497596 :     *prev_state = state;
    1021      497596 :     move16();
    1022             : 
    1023             :     /*-----------------------------------------------------------------*
    1024             :      * circular convolution
    1025             :      *-----------------------------------------------------------------*/
    1026             : 
    1027      497596 :     state = add( state, mode ); /* level of dispersion */
    1028             : 
    1029      497596 :     IF( LT_16( state, 2 ) )
    1030             :     {
    1031       31129 :         r_fft_fx_lc( phs_tbl_dec, SIZE, SIZE2, NUM_STAGES, code, code2, 1 );
    1032             : 
    1033       31129 :         h_real = Mid_H_phasedisp;
    1034       31129 :         if ( state == 0 )
    1035             :         {
    1036        7416 :             h_real = Low_H_phasedisp;
    1037             :         }
    1038             : 
    1039             :         /* FFT Coefs are in code2 */
    1040       31129 :         code2_real = code2;
    1041       31129 :         code2_imag = code2 + L_SUBFR - 1;
    1042             : 
    1043       31129 :         code_real = code;
    1044       31129 :         code_imag = code + L_SUBFR - 1;
    1045             : 
    1046       31129 :         h_imag = h_real + L_SUBFR - 1;
    1047             : 
    1048       31129 :         *code_real++ = mult( *code2_real++, *h_real++ );
    1049       31129 :         move16(); /* DC */
    1050             : 
    1051      996128 :         FOR( i = 1; i < L_SUBFR / 2; i++ )
    1052             :         {
    1053      964999 :             *code_real++ = msu_r( L_mult( *code2_real, *h_real ), *code2_imag, *h_imag );
    1054      964999 :             move16();
    1055      964999 :             *code_imag-- = mac_r( L_mult( *code2_real, *h_imag ), *code2_imag, *h_real );
    1056      964999 :             move16();
    1057             : 
    1058      964999 :             code2_real++;
    1059      964999 :             h_imag--;
    1060      964999 :             h_real++;
    1061      964999 :             code2_imag--;
    1062             :         }
    1063       31129 :         *code_real++ = mult( *code2_real++, *h_real++ );
    1064       31129 :         move16(); /* DC */
    1065             : 
    1066       31129 :         r_fft_fx_lc( phs_tbl_dec, SIZE, SIZE2, NUM_STAGES, code, code2, 0 );
    1067             : 
    1068     2023385 :         FOR( i = 0; i < L_SUBFR; i++ )
    1069             :         {
    1070             :             /* saturation can occur here */
    1071     1992256 :             code[i] = shl( code2[i], 1 ); /*Q12 */
    1072     1992256 :             move16();
    1073             :         }
    1074             :     }
    1075      497596 : }
    1076             : 
    1077             : /*======================================================================================*/
    1078             : /* FUNCTION : agc2_fx()                                                                    */
    1079             : /*--------------------------------------------------------------------------------------*/
    1080             : /* PURPOSE : AGC post-processing for lower G722.2 modes                                    */
    1081             : /*--------------------------------------------------------------------------------------*/
    1082             : /* INPUT ARGUMENTS :                                                                    */
    1083             : /* _ (Word16*[]) sig_in : postfilter input signal        (Q0)                            */
    1084             : /* _ (Word16) l_trm : subframe size                                                        */
    1085             : /*--------------------------------------------------------------------------------------*/
    1086             : /* OUTPUT ARGUMENTS :                                                                    */
    1087             : /* _ None                                                                                */
    1088             : /*--------------------------------------------------------------------------------------*/
    1089             : /* INPUT/OUTPUT ARGUMENTS :                                                                */
    1090             : /* _ (Word16*[]) sig_out : postfilter output signal        (Q0)                            */
    1091             : /*--------------------------------------------------------------------------------------*/
    1092             : 
    1093             : /* _ None                                                                                */
    1094             : /*--------------------------------------------------------------------------------------*/
    1095             : /* RETURN ARGUMENTS :                                                                    */
    1096             : /* _ None                                                                                */
    1097             : /*======================================================================================*/
    1098           0 : static void agc2_fx(
    1099             :     const Word16 *sig_in, /* i  : postfilter input signal  */
    1100             :     Word16 *sig_out,      /* i/o: postfilter output signal */
    1101             :     const Word16 l_trm    /* i  : subframe size            */
    1102             : )
    1103             : {
    1104             : 
    1105             :     Word16 i, exp;
    1106             :     Word16 gain_in, gain_out, g0;
    1107             :     Word32 s;
    1108             : 
    1109             :     Word16 temp;
    1110             : 
    1111             :     /* calculate gain_out with exponent */
    1112           0 :     temp = shr( sig_out[0], 2 );
    1113           0 :     s = L_mult0( temp, temp );
    1114           0 :     FOR( i = 1; i < l_trm; i++ )
    1115             :     {
    1116           0 :         temp = shr( sig_out[i], 2 );
    1117           0 :         s = L_mac0_sat( s, temp, temp );
    1118             :     }
    1119           0 :     IF( s != 0 )
    1120             :     {
    1121           0 :         exp = sub( norm_l( s ), 1 );
    1122           0 :         gain_out = round_fx( L_shl( s, exp ) );
    1123             : 
    1124             :         /* calculate gain_in with exponent */
    1125           0 :         temp = shr( sig_in[0], 2 );
    1126           0 :         s = L_mult0( temp, temp );
    1127           0 :         FOR( i = 1; i < l_trm; i++ )
    1128             :         {
    1129           0 :             temp = shr( sig_in[i], 2 );
    1130           0 :             s = L_mac0_sat( s, temp, temp );
    1131             :         }
    1132             : 
    1133           0 :         g0 = 0;
    1134           0 :         move16();
    1135           0 :         IF( s != 0 )
    1136             :         {
    1137           0 :             i = norm_l( s );
    1138           0 :             gain_in = round_fx_sat( L_shl_sat( s, i ) );
    1139           0 :             exp = sub( exp, i );
    1140             : 
    1141             :             /*---------------------------------------------------*
    1142             :              *  g0 = sqrt(gain_in / gain_out)
    1143             :              *---------------------------------------------------*/
    1144           0 :             s = L_mult0( 128, div_s( gain_out, gain_in ) ); /* s = gain_out / gain_in */
    1145           0 :             s = L_shr( s, exp );                            /* add exponent */
    1146             : 
    1147           0 :             s = Isqrt( s );
    1148           0 :             g0 = round_fx_sat( L_shl_sat( s, 9 ) );
    1149             :         }
    1150             : 
    1151             :         /* sig_out(n) = gain(n) sig_out(n) */
    1152           0 :         FOR( i = 0; i < l_trm; i++ )
    1153             :         {
    1154           0 :             sig_out[i] = round_fx_sat( L_shl_sat( L_mac( -8192, sig_out[i], g0 ), 2 ) );
    1155           0 :             move16();
    1156             :         }
    1157             :     }
    1158           0 : }

Generated by: LCOV version 1.14