LCOV - code coverage report
Current view: top level - lib_com - trans_inv_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 629 659 95.4 %
Date: 2025-05-03 01:55:50 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <stdint.h>
       5             : #include "options.h" /* Compilation switches                   */
       6             : #include "prot_fx.h" /* Function prototypes                    */
       7             : #include "rom_com.h" /* Function prototypes                    */
       8             : #include "rom_dec.h"
       9             : 
      10             : 
      11             : /*--------------------------------------------------------------------------*
      12             :  * Local constants
      13             :  *--------------------------------------------------------------------------*/
      14             : 
      15             : #define NUMSF      8
      16             : #define NUMSF_M1   ( NUMSF - 1 )
      17             : #define NUMSF_M2   ( NUMSF - 2 )
      18             : #define NUMSF_S2   ( NUMSF / 2 )
      19             : #define LOG2_NUMSF 3
      20             : 
      21             : /*--------------------------------------------------------------------------*
      22             :  * preecho_sb()
      23             :  *
      24             :  * Time-domain sub-band based pre-echo reduction
      25             :  *--------------------------------------------------------------------------*/
      26             : 
      27        7516 : void preecho_sb_fx(
      28             :     const Word32 core_brate,  /* i   Q0  : core bit-rate                                           */
      29             :     Word32 *wtda_audio_fx,    /* i   q_sig32 : imdct signal, used to compute imdct_mem_fx when not 24400 bps */
      30             :     Word16 q_sig32,           /* i   Q value for wtda_audio_fx */
      31             :     Word16 *rec_sig_fx,       /* i   q_sig16  : reconstructed signal, output of the imdct transform     */
      32             :     Word16 q_sig16,           /* i   Q value for rec_sig_fx and imdct_mem_fx */
      33             :     const Word16 framelength, /* i   Q0  : frame length                                            */
      34             :     Word16 *memfilt_lb_fx,    /* i/o Q0  : memory                                                  */
      35             :     Word32 *mean_prev_hb_fx,  /* i/o Q0  : memory                                                  */
      36             :     Word16 *smoothmem_fx,     /* i/o Q15 : memory                                                  */
      37             :     Word32 *mean_prev_fx,     /* i/o Q0  : memory                                                  */
      38             :     Word32 *mean_prev_nc_fx,  /* i/o Q0  : memory                                                  */
      39             :     Word16 *wmold_hb_fx,      /* i/o Q15 : memory                                                  */
      40             :     Word16 *prevflag,         /* i/o Q0  : flag                                                    */
      41             :     Word16 *pastpre,          /* i/o Q0  : flag                                                    */
      42             :     const Word16 bwidth       /* i   Q0  : bandwidth                                               */
      43             : )
      44             : {
      45             :     Word16 i, j, len3xLp20;
      46             :     Word16 zcr[9];              /* 0..3 (0..7): zero crossing of the 4 (8) subframes, 4..5: (8..10) zero crossing of the future subframes */
      47             :     Word16 maxnzcr[8], cntnzcr; /* max number of samples without zero crossing  */
      48             : 
      49             :     Word16 maxind, stind, stind_hb, cnt2, cnt5, adv, advmem;
      50             :     Word16 ind2, ind3, ind4, ind5, ind6, pluslim, ind2_m1, ind2_sfl, numsf_ind2;
      51             :     Word16 subframelength, subsubframelength;
      52             :     Word16 *ptr_fx, *fxptr1, *fxptr2, *fxptr3, *fxptr4, *fxptr5, *fxptr6 /*, *fxptr7, *fxptr8*/;
      53             :     Word32 *fx32ptr1, *fx32ptr4, *fx32ptr5, *fx32ptr6;
      54             :     Word16 *sptr1, *sptr2, sptr1_loc, sptr2_loc;
      55             :     Word16 framelength_m1;
      56             :     Word16 limzcr, limmaxnzcr;
      57             :     Word16 num_subsubframes, log2_num_subsubframes;
      58             :     Word16 nb_flag, smooth_len;
      59             :     Word16 firstnzcr;
      60             :     Word16 invsmoothlenp1_fx;
      61             :     Word16 subframelength_s2, subframelength_s34;
      62             :     Word16 tmp_fx1, tmp_fx2, tmp_fx3;
      63             :     Word32 tmp_fxL1, tmp_fxL2, tmp_fxL3;
      64             :     Word32 es_mdct_fx[9];    /* 0..3 (0..7): energy of the 4 (8) subframes, 4..5: (8..10) energy of the future subframes */
      65             :     Word32 es_mdct_hb_fx[9]; /* 0..3 (0..7): energy of the 4 (8) subframes, 4..5: (8..10) energy of the future subframes */
      66             :     Word32 es_mdct_half_fx[9];
      67             :     Word32 es_mdct_quart_fx[9];
      68             :     Word32 savehalfe_fx, last2_fx, maxcrit_fx, sum_plus_es_fx, mean_plus_es_fx[65];
      69             :     Word32 savehalfe_hb_fx, last2_hb_fx;
      70             :     Word32 plus_es_mdct_fx[64], max_es_fx, max_es_hb_fx, max_plus_es_mdct_fx;
      71             :     Word16 imdct_mem_fx[L_FRAME48k];                             /* memory of the imdct transform, used in the next frame   */
      72             :     Word16 rec_sig_lb_fx[L_FRAME48k], rec_sig_hb_fx[L_FRAME48k]; /* 960 max frame length at 48 kHz */
      73             : 
      74             :     Word16 min_g_fx[13], g_fx, gt_fx[13];
      75             :     Word16 min_g_hb_fx[13], gt_hb_fx[13];
      76             :     Word16 preechogain_fx[L_FRAME48k + PREECHO_SMOOTH_LEN];
      77             :     Word16 preechogain_hb_fx[L_FRAME48k];
      78             :     Word16 pre_g_ch_tab[9];
      79             :     Word32 eshbmean2_fx, eshbmean3_fx, sxyhb2_fx, sxylb3_fx;
      80             :     Word16 wmold_fx;
      81             :     Word16 lim16_fx, lim32_fx;
      82             :     Word16 fattnext_fx;
      83             :     Word16 oldgain_fx, oldgain_hb_fx;
      84             :     UWord16 tmp_u16;
      85             :     Word32 mean_prev_hb_fx_loc, mean_prev_nc_fx_loc, mean_prev_fx_loc; /*                                                  */
      86             :     Word16 q16p1, qmemp1, qtmp;
      87             : #ifdef OPT_STEREO_32KBPS_V1
      88        7516 :     Word16 shift_q = sub( 15, q_sig32 );
      89             : #endif /* OPT_STEREO_32KBPS_V1 */
      90             : 
      91        7516 :     q16p1 = add( q_sig16, 1 );
      92        7516 :     qmemp1 = q16p1;
      93             : 
      94        7516 :     IF( LE_32( core_brate, HQ_32k ) )
      95             :     {
      96             : 
      97        4914 :         mean_prev_fx_loc = L_add( *mean_prev_fx, 0 );
      98        4914 :         mean_prev_hb_fx_loc = L_shl_sat( *mean_prev_hb_fx, shl( q_sig16, 1 ) ); /*Q0 to q_sig16*/
      99        4914 :         mean_prev_nc_fx_loc = L_add( *mean_prev_nc_fx, 0 );
     100        4914 :         framelength_m1 = sub( framelength, 1 );
     101        4914 :         nb_flag = 0;
     102        4914 :         move16();
     103        4914 :         if ( ( bwidth == NB ) )
     104             :         {
     105           0 :             nb_flag = 1;
     106           0 :             move16();
     107             :         }
     108        4914 :         limzcr = 16;
     109        4914 :         move16();
     110        4914 :         smooth_len = 4;
     111        4914 :         move16();
     112        4914 :         invsmoothlenp1_fx = 6554; /*0.2 in Q15*/
     113        4914 :         move16();
     114        4914 :         IF( EQ_16( nb_flag, 1 ) )
     115             :         {
     116           0 :             limzcr = 10;
     117           0 :             move16();
     118           0 :             smooth_len = PREECHO_SMOOTH_LEN;
     119           0 :             move16();
     120           0 :             invsmoothlenp1_fx = INV_PREECHO_SMOOTH_LENP1_FX;
     121           0 :             move16();
     122             :         }
     123             : 
     124        4914 :         limmaxnzcr = mult( framelength, 1365 ); /*1/24 in Q15*/ /*Q0*/
     125        4914 :         num_subsubframes = 8;
     126        4914 :         move16();
     127        4914 :         log2_num_subsubframes = 3;
     128        4914 :         move16();
     129             : 
     130        4914 :         IF( EQ_16( framelength, L_FRAME8k ) )
     131             :         {
     132           0 :             num_subsubframes = 4;
     133           0 :             move16();
     134           0 :             log2_num_subsubframes = 2;
     135           0 :             move16();
     136             :         }
     137             : 
     138        4914 :         len3xLp20 = mult_r( framelength, 7168 ); /*7*framelength/32;*/ /*Q0*/
     139             :         /*            len3xLp20 = framelength/2-(short)((float)framelength*N_ZERO_MDCT/FRAME_SIZE_MS); in float*/
     140             : 
     141        4914 :         fxptr1 = imdct_mem_fx;
     142             : #ifdef OPT_STEREO_32KBPS_V1
     143      914494 :         FOR( i = 0; i < len3xLp20; i++ )
     144             :         {
     145      909580 :             *fxptr1++ = negate( extract_h( L_shl_sat( wtda_audio_fx[len3xLp20 - 1 - i], shift_q ) ) ); /*Q-1*/
     146      909580 :             move16();                                                                                  /*convert to Word16 Q-1 with saturation (saturation not a problem here) */
     147             :         }
     148     2083954 :         FOR( i = 0; i < framelength >> 1; i++ )
     149             :         {
     150     2079040 :             *fxptr1++ = negate( extract_h( L_shl_sat( wtda_audio_fx[i], shift_q ) ) ); /*Q-1*/
     151     2079040 :             move16();                                                                  /*convert to Word16 Q-1 with saturation (saturation not a problem here) */
     152             :         }
     153             : #else  /* OPT_STEREO_32KBPS_V1 */
     154             :         fx32ptr1 = wtda_audio_fx + len3xLp20 - 1; /*q_sig32*/
     155             :         FOR( i = 0; i < len3xLp20; i++ )
     156             :         {
     157             :             *fxptr1++ = negate( extract_h( L_shl_sat( *fx32ptr1--, sub( 15, q_sig32 ) ) ) ); /*Q-1*/
     158             :             move16();                                                                        /*convert to Word16 Q-1 with saturation (saturation not a problem here) */
     159             :         }
     160             :         FOR( i = 0; i < L_shr( framelength, 1 ); i++ )
     161             :         {
     162             :             *fxptr1++ = negate( extract_h( L_shl_sat( wtda_audio_fx[i], sub( 15, q_sig32 ) ) ) ); /*Q-1*/
     163             :             move16();                                                                             /*convert to Word16 Q-1 with saturation (saturation not a problem here) */
     164             :         }
     165             : #endif /* OPT_STEREO_32KBPS_V1 */
     166             : 
     167        4914 :         qmemp1 = 0; /*already in q-1*/
     168        4914 :         move16();
     169             : 
     170        4914 :         subframelength = shr( framelength, LOG2_NUMSF );                  /*Q0*/
     171        4914 :         subsubframelength = shr( subframelength, log2_num_subsubframes ); /*Q0*/
     172        4914 :         wmold_fx = *smoothmem_fx;                                         /*Q15*/
     173        4914 :         move16();
     174        4914 :         subframelength_s2 = shr( subframelength, 1 );                      /*Q0*/
     175        4914 :         subframelength_s34 = mult( subframelength, 24576 /*3/4 in Q15*/ ); /*Q0*/
     176             : 
     177        4914 :         cntnzcr = -1;
     178        4914 :         move16();
     179             : 
     180        4914 :         lim16_fx = 3277; /*Q15*/
     181        4914 :         move16();
     182        4914 :         lim32_fx = 328; /*Q15*/
     183        4914 :         move16();
     184        4914 :         savehalfe_fx = L_deposit_l( 0 );
     185        4914 :         savehalfe_hb_fx = L_deposit_l( 0 );
     186             : 
     187        4914 :         IF( *pastpre == 0 )
     188             :         {
     189             :             /* if past frame mean energies are not known (no preecho_sb in the past frame), limit max attenuation to 1*/
     190         679 :             lim16_fx = 32767; /*Q15*/
     191         679 :             move16();
     192         679 :             lim32_fx = 32767; /*Q15*/
     193         679 :             move16();
     194             :         }
     195             : 
     196        4914 :         *pastpre = 2;
     197        4914 :         move16();
     198        4914 :         fxptr1 = rec_sig_lb_fx;  /*q_sig16*/
     199        4914 :         fxptr2 = rec_sig_fx;     /*q_sig16*/
     200        4914 :         fxptr3 = rec_sig_fx + 1; /*q_sig16*/
     201        4914 :         fxptr4 = rec_sig_fx + 2; /*q_sig16*/
     202             : 
     203        4914 :         tmp_fxL1 = L_mult( shl_sat( *memfilt_lb_fx, q_sig16 ), 8192 ); /* *memfilt_lb_fx in q0  */
     204        4914 :         tmp_fxL1 = L_mac( tmp_fxL1, *fxptr3, 8192 /*Q15*/ );           /*Q16*/
     205        4914 :         *fxptr1 = mac_r( tmp_fxL1, *fxptr2, 16384 /*Q15*/ );           /*Q0*/
     206        4914 :         move16();
     207        4914 :         fxptr1++;
     208             : 
     209     4153166 :         FOR( j = 2; j < framelength; j++ )
     210             :         {
     211     4148252 :             tmp_fxL1 = L_mult( *fxptr2, 8192 /*Q15*/ );          /*Q16*/
     212     4148252 :             tmp_fxL1 = L_mac( tmp_fxL1, *fxptr4, 8192 /*Q15*/ ); /*Q16*/
     213     4148252 :             *fxptr1 = mac_r( tmp_fxL1, *fxptr3, 16384 /*Q15*/ ); /*Q0*/
     214     4148252 :             move16();
     215     4148252 :             fxptr1++;
     216     4148252 :             fxptr2++;
     217     4148252 :             fxptr3++;
     218     4148252 :             fxptr4++;
     219             :         }
     220             : 
     221        4914 :         tmp_fxL1 = L_mult( *fxptr2, 8192 );          /*Q16*/
     222        4914 :         *fxptr1 = mac_r( tmp_fxL1, *fxptr3, 16384 ); /*Q0*/
     223        4914 :         move16();
     224        4914 :         fxptr1 = rec_sig_lb_fx; /*q_sig16*/
     225        4914 :         fxptr2 = rec_sig_fx;    /*q_sig16*/
     226        4914 :         fxptr3 = rec_sig_hb_fx; /*q_sig16*/
     227             : 
     228     4162994 :         FOR( j = 0; j < framelength; j++ )
     229             :         {
     230     4158080 :             *fxptr3 = sub( *fxptr2, *fxptr1 );
     231     4158080 :             move16();
     232     4158080 :             fxptr1++;
     233     4158080 :             fxptr2++;
     234     4158080 :             fxptr3++;
     235             :         }
     236             : 
     237        4914 :         fxptr2--;
     238        4914 :         *memfilt_lb_fx = shr_sat( *fxptr2, q_sig16 ); /*Q0*/
     239        4914 :         move16();                                     /* *memfilt_lb_fx in q0  */
     240             : 
     241             :         /* energy of low bands 8 present and 1 future sub-frames */
     242        4914 :         sptr1 = zcr; /*Q0*/
     243        4914 :         sptr1_loc = 0;
     244        4914 :         move16();
     245        4914 :         sptr2 = maxnzcr; /*Q0*/
     246             : 
     247        4914 :         fxptr2 = rec_sig_fx;    /*q_sig16*/
     248        4914 :         fxptr3 = rec_sig_hb_fx; /*q_sig16*/
     249        4914 :         fx32ptr1 = es_mdct_fx;
     250        4914 :         fx32ptr5 = es_mdct_half_fx;
     251        4914 :         fx32ptr6 = es_mdct_quart_fx;
     252        4914 :         fx32ptr4 = es_mdct_hb_fx;
     253        4914 :         firstnzcr = 0;
     254        4914 :         move16();
     255       44226 :         FOR( j = 0; j < NUMSF; j++ ) /* 8 present subframes */
     256             :         {
     257       39312 :             tmp_fx2 = sub( j, 1 );
     258       39312 :             tmp_fx1 = shr_sat( *fxptr2, q16p1 );            /*q-1 to avoisd saturation in energy*/
     259       39312 :             tmp_fxL1 = L_mac0_sat( 25, tmp_fx1, tmp_fx1 );  /*2*(Q-1)*/
     260       39312 :             tmp_fxL2 = L_mac0_sat( 100, *fxptr3, *fxptr3 ); /*2*(q_sig16)*/
     261       39312 :             sptr2_loc = 0;
     262       39312 :             move16();
     263             : 
     264       39312 :             fxptr2++;
     265       39312 :             fxptr3++;
     266             : 
     267     4158080 :             FOR( i = 1; i < subframelength; i++ )
     268             :             {
     269     4118768 :                 if ( EQ_16( i, subframelength_s2 ) )
     270             :                 {
     271       39312 :                     *fx32ptr5 = tmp_fxL1; /*2*(Q-1)*/
     272       39312 :                     move32();
     273             :                 }
     274             : 
     275     4118768 :                 if ( EQ_16( i, subframelength_s34 ) )
     276             :                 {
     277       39312 :                     *fx32ptr6 = tmp_fxL1; /*2*(Q-1)*/
     278       39312 :                     move32();
     279             :                 }
     280     4118768 :                 tmp_fx1 = shr_sat( *fxptr2, q16p1 );                 /*q-1 to avoisd saturation in energy*/
     281     4118768 :                 tmp_fxL1 = L_mac0_sat( tmp_fxL1, tmp_fx1, tmp_fx1 ); /*2*(Q-1)*/
     282     4118768 :                 tmp_fxL2 = L_mac0_sat( tmp_fxL2, *fxptr3, *fxptr3 ); /*2*(q_sig16)*/
     283     4118768 :                 cntnzcr = add( cntnzcr, 1 );
     284     4118768 :                 IF( L_mult0( *fxptr2, *( fxptr2 - 1 ) ) <= 0 )
     285             :                 {
     286      639957 :                     sptr1_loc = add( sptr1_loc, 1 );
     287      639957 :                     sptr2_loc = s_max( sptr2_loc, cntnzcr );
     288             : 
     289      639957 :                     test();
     290      639957 :                     if ( ( firstnzcr > 0 ) && ( GT_16( cntnzcr, maxnzcr[tmp_fx2] ) ) )
     291             :                     {
     292        8350 :                         maxnzcr[tmp_fx2] = cntnzcr; /*Q0*/
     293        8350 :                         move16();
     294             :                     }
     295             : 
     296      639957 :                     firstnzcr = 0;
     297      639957 :                     move16();
     298      639957 :                     cntnzcr = -1;
     299      639957 :                     move16();
     300             :                 }
     301     4118768 :                 fxptr2++;
     302     4118768 :                 fxptr3++;
     303             :             }
     304       39312 :             if ( LT_16( j, NUMSF_M1 ) )
     305             :             {
     306       34398 :                 cntnzcr = add( cntnzcr, 1 );
     307             :             }
     308       39312 :             sptr2_loc = s_max( sptr2_loc, cntnzcr );
     309       39312 :             *fx32ptr4 = tmp_fxL2; /*2*(q_sig16)*/
     310       39312 :             move32();
     311       39312 :             fx32ptr4++;
     312       39312 :             *sptr1 = sptr1_loc; /*Q0*/
     313       39312 :             move16();
     314       39312 :             *sptr2 = sptr2_loc; /*Q0*/
     315       39312 :             move16();
     316       39312 :             sptr1++;
     317       39312 :             sptr2++;
     318             : 
     319       39312 :             test();
     320       39312 :             if ( ( firstnzcr > 0 ) && ( GT_16( cntnzcr, maxnzcr[tmp_fx2] ) ) )
     321             :             {
     322         465 :                 maxnzcr[tmp_fx2] = cntnzcr; /*Q0*/
     323         465 :                 move16();
     324             :             }
     325             : 
     326       39312 :             sptr1_loc = 0;
     327       39312 :             move16();
     328       39312 :             test();
     329       39312 :             firstnzcr = 1;
     330       39312 :             move16();
     331       39312 :             IF( ( LT_16( j, NUMSF_M1 ) ) && ( L_mult0( *fxptr2, *( fxptr2 - 1 ) ) <= 0 ) ) /* zcr between 2 subframes */
     332             :             {
     333        5779 :                 sptr1_loc = add( sptr1_loc, 1 ); /* counts for the nexte subframe */
     334        5779 :                 cntnzcr = -1;
     335        5779 :                 move16();
     336        5779 :                 firstnzcr = 0;
     337        5779 :                 move16();
     338             :             }
     339             : 
     340       39312 :             *fx32ptr1 = tmp_fxL1; /*2*(Q-1)*/
     341       39312 :             move32();
     342       39312 :             if ( LT_32( *fx32ptr5, L_shr( *fx32ptr1, 1 ) ) )
     343             :             {
     344       19517 :                 tmp_fxL1 = L_shl_sat( L_sub_sat( *fx32ptr1, *fx32ptr5 ), 1 ); /*2*(Q-1)*/
     345             :             }
     346       39312 :             *fx32ptr5 = tmp_fxL1; /*2*(Q-1)*/
     347       39312 :             move32();
     348             : 
     349       39312 :             fx32ptr1++;
     350       39312 :             fx32ptr5++;
     351       39312 :             fx32ptr6++;
     352             :         }
     353             : 
     354        4914 :         fxptr2 = imdct_mem_fx; /* q_sig16 or q-1*/
     355        4914 :         j = NUMSF;
     356        4914 :         move16();                                  /* one future subframe but 96 samples (not 80) (enough with ALDO window) */
     357        4914 :         tmp_fx1 = shr( *fxptr2, qmemp1 );          /* q-1 shr to avoid overflow in es_mdct_fx*/
     358        4914 :         tmp_fxL1 = L_mac0( 25, tmp_fx1, tmp_fx1 ); /*2*(Q-1)*/
     359             : 
     360        4914 :         sptr1_loc = 0;
     361        4914 :         move16();
     362        4914 :         fxptr2++;
     363        4914 :         tmp_fx3 = sub( len3xLp20, 1 );
     364      909580 :         FOR( i = 1; i < len3xLp20; i++ )
     365             :         {
     366      904666 :             tmp_fx1 = shr( *fxptr2, qmemp1 );                    /*q-1 to avoisd saturation in energy*/
     367      904666 :             tmp_fxL1 = L_mac0_sat( tmp_fxL1, tmp_fx1, tmp_fx1 ); /*2*(Q-1)*/
     368      904666 :             if ( *fxptr2 * *( fxptr2 - 1 ) <= 0 )
     369             :             {
     370      158682 :                 sptr1_loc = add( sptr1_loc, 1 );
     371             :             }
     372             : 
     373      904666 :             fxptr2++;
     374             :         }
     375        4914 :         *fx32ptr1 = tmp_fxL1; /*2*(Q-1)*/
     376        4914 :         move32();
     377        4914 :         *sptr1 = sptr1_loc;                                             /*Q0*/
     378        4914 :         fxptr2 = imdct_mem_fx;                                          /*q_sig16*/
     379        4914 :         fxptr3 = imdct_mem_fx + 1;                                      /*q_sig16*/
     380        4914 :         fxptr4 = imdct_mem_fx + 2;                                      /*q_sig16*/
     381        4914 :         tmp_fxL1 = L_mult( rec_sig_fx[framelength_m1], -8192 /*Q15*/ ); /*q_sig16+Q16*/
     382        4914 :         tmp_fxL1 = L_mac( tmp_fxL1, *fxptr3, -8192 );                   /*q_sig16+Q16*/
     383        4914 :         tmp_fx1 = mac_r( tmp_fxL1, *fxptr2, 16384 /*Q15*/ );            /*q_sig16*/
     384             : 
     385        4914 :         tmp_fxL2 = L_deposit_l( 100 );
     386        4914 :         tmp_fxL2 = L_mac0( tmp_fxL2, tmp_fx1, tmp_fx1 ); /*2*(q_sig16)*/
     387             : 
     388      904666 :         FOR( j = 1; j < tmp_fx3; j++ ) /* tmp_fx3 still contains subframelength*1.2-1 */
     389             :         {
     390      899752 :             tmp_fxL1 = L_mult( *fxptr2, -8192 /*Q15*/ );             /*q_sig16+Q16*/
     391      899752 :             tmp_fxL1 = L_mac_sat( tmp_fxL1, *fxptr4, -8192 );        /*q_sig16+Q16*/
     392      899752 :             tmp_fx1 = mac_r_sat( tmp_fxL1, *fxptr3, 16384 /*Q15*/ ); /*q_sig16*/
     393             : 
     394      899752 :             tmp_fxL2 = L_mac0_sat( tmp_fxL2, tmp_fx1, tmp_fx1 ); /*2*(q_sig16)*/
     395      899752 :             fxptr2++;
     396      899752 :             fxptr3++;
     397      899752 :             fxptr4++;
     398             :         }
     399             : 
     400        4914 :         tmp_fxL1 = L_mult( *fxptr2, -8192 /*Q15*/ );                     /*q_sig16+Q16*/
     401        4914 :         tmp_fx1 = mac_r_sat( tmp_fxL1, *fxptr3, 16384 /*Q15*/ );         /*q_sig16*/
     402        4914 :         es_mdct_hb_fx[NUMSF] = L_mac0_sat( tmp_fxL2, tmp_fx1, tmp_fx1 ); /*2*(q_sig16)*/
     403        4914 :         move32();
     404             : 
     405        4914 :         max_es_hb_fx = L_add( es_mdct_hb_fx[0], 0 ); /* for memorising the max energy */
     406        4914 :         max_es_fx = L_add( es_mdct_fx[0], 0 );       /* for memorising the max energy */
     407        4914 :         maxind = 0;
     408        4914 :         move16();
     409       44226 :         FOR( i = 1; i <= NUMSF; i++ )
     410             :         {
     411             : #ifdef OPT_STEREO_32KBPS_V1
     412       39312 :             max_es_hb_fx = L_max( max_es_hb_fx, es_mdct_hb_fx[i] ); /* max energy low band, 8 present and 1 future subframes */
     413             : 
     414       39312 :             max_es_fx = L_max( max_es_fx, es_mdct_fx[i] ); /* max energy low band, 8 present and 1 future subframes */
     415             : 
     416       39312 :             if ( GE_32( es_mdct_fx[i], max_es_fx ) ) /* '='  to handle the first window*/
     417             :             {
     418        9093 :                 maxind = i;
     419        9093 :                 move16();
     420             :             }
     421             : #else  /* OPT_STEREO_32KBPS_V1 */
     422             :             IF( GE_32( es_mdct_hb_fx[i], max_es_hb_fx ) ) /* '='  to handle the first window*/
     423             :             {
     424             :                 max_es_hb_fx = L_add( es_mdct_hb_fx[i], 0 ); /* max energy low band, 8 present and 1 future subframes */
     425             :             }
     426             : 
     427             :             IF( GE_32( es_mdct_fx[i], max_es_fx ) ) /* '='  to handle the first window*/
     428             :             {
     429             :                 max_es_fx = L_add( es_mdct_fx[i], 0 ); /* max energy low band, 8 present and 1 future subframes */
     430             :                 maxind = i;
     431             :                 move16();
     432             :             }
     433             : #endif /* OPT_STEREO_32KBPS_V1 */
     434             :         }
     435             : 
     436        4914 :         cnt2 = cnt5 = 0;
     437        4914 :         move16();
     438        4914 :         move16();
     439        4914 :         test();
     440        4914 :         if ( *prevflag != 0 || LT_32( max_es_fx, L_mult0( subframelength, 2500 ) ) )
     441             :         {
     442         520 :             maxind = 0;
     443         520 :             move16();
     444             :         }
     445             : 
     446        4914 :         if ( LT_32( max_es_fx, L_shl_sat( mean_prev_fx_loc, 2 ) ) ) /*OK if saturated*/
     447             :         {
     448        4059 :             maxind = 0;
     449        4059 :             move16();
     450             :         }
     451        4914 :         *prevflag = 0;
     452        4914 :         move16();
     453             : 
     454        5877 :         FOR( i = 0; i < maxind; i++ ) /* only subbands before max energy subband are handled */
     455             :         {
     456         963 :             g_fx = 32767;        /*Q15*/
     457         963 :             move16();            /* default gain */
     458         963 :             min_g_fx[i] = 32767; /*Q15*/
     459         963 :             move16();
     460         963 :             min_g_hb_fx[i] = 32767; /*Q15*/
     461         963 :             move16();
     462             : 
     463         963 :             Mpy_32_16_ss( es_mdct_half_fx[i], 328, &tmp_fxL1, &tmp_u16 );  /* 328 for 1/100*/
     464         963 :             Mpy_32_16_ss( es_mdct_half_fx[i], 3277, &tmp_fxL2, &tmp_u16 ); /* 3277 for 1/10*/
     465         963 :             Mpy_32_16_ss( es_mdct_fx[i], 5461, &tmp_fxL3, &tmp_u16 );      /* 5461 for 1/6*/
     466         963 :             test();
     467         963 :             test();
     468         963 :             test();
     469         963 :             IF( ( GT_32( tmp_fxL1, L_add( mean_prev_nc_fx_loc, 125000 ) ) ) || /* less then 20% energy in 3/4 of the subframe -> starting onset in the last quarter */
     470             :                 ( ( GT_32( tmp_fxL2, L_add( mean_prev_nc_fx_loc, 125000 ) ) ) &&
     471             :                   ( ( LT_16( zcr[i], limzcr ) ) || ( LT_32( es_mdct_quart_fx[i], tmp_fxL3 ) ) ) ) ) /* already an offset, plosif, do not touch */
     472             :             {
     473         201 :                 maxind = i;
     474         201 :                 move16(); /* no preecho reduction after the first subframe with gain 1 */
     475         201 :                 *prevflag = 1;
     476         201 :                 move16();
     477         238 :                 FOR( j = sub( i, 1 ); j >= 0; j-- )
     478             :                 {
     479          37 :                     if ( GT_32( es_mdct_fx[j], L_shr( es_mdct_fx[i], 1 ) ) )
     480             :                     {
     481           8 :                         maxind = j;
     482           8 :                         move16();
     483             :                     }
     484             :                 }
     485             :             }
     486             :             ELSE
     487             :             {
     488         762 :                 IF( LT_32( es_mdct_fx[i], L_shr( max_es_fx, 4 ) ) )
     489             :                 {
     490         282 :                     g_fx = lim16_fx; /*Q15*/
     491         282 :                     move16();
     492         282 :                     cnt5 = add( cnt5, 1 );
     493             : 
     494         282 :                     IF( LT_32( es_mdct_fx[i], L_shr( max_es_fx, 5 ) ) )
     495             :                     {
     496          89 :                         g_fx = lim32_fx; /*Q15*/
     497          89 :                         move16();
     498          89 :                         cnt2 = add( cnt2, 1 );
     499             :                     }
     500             : 
     501         282 :                     IF( LT_32( mean_prev_fx_loc, es_mdct_fx[i] ) )
     502             :                     {
     503         169 :                         tmp_fx1 = norm_l( es_mdct_fx[i] );
     504         169 :                         tmp_fxL1 = L_shl( es_mdct_fx[i], tmp_fx1 );
     505         169 :                         tmp_fxL2 = L_shl( mean_prev_fx_loc, tmp_fx1 );
     506         169 :                         tmp_fx1 = round_fx_sat( tmp_fxL1 );
     507         169 :                         tmp_fx2 = round_fx( tmp_fxL2 );
     508         169 :                         tmp_fx3 = div_s( tmp_fx2, tmp_fx1 );
     509         169 :                         min_g_fx[i] = Frac_sqrt( tmp_fx3 );
     510         169 :                         move16();
     511             :                     }
     512             : 
     513         282 :                     IF( LT_32( mean_prev_hb_fx_loc, es_mdct_hb_fx[i] ) )
     514             :                     {
     515         210 :                         tmp_fx1 = norm_l( es_mdct_hb_fx[i] );
     516         210 :                         tmp_fxL1 = L_shl( es_mdct_hb_fx[i], tmp_fx1 );
     517         210 :                         tmp_fxL2 = L_shl( mean_prev_hb_fx_loc, tmp_fx1 );
     518         210 :                         tmp_fx1 = round_fx_sat( tmp_fxL1 );
     519         210 :                         tmp_fx2 = round_fx( tmp_fxL2 );
     520         210 :                         tmp_fx3 = div_s( tmp_fx2, tmp_fx1 );
     521         210 :                         min_g_hb_fx[i] = Frac_sqrt( tmp_fx3 );
     522         210 :                         move16();
     523             :                     }
     524         282 :                     test();
     525         282 :                     IF( ( LT_16( zcr[i], shr( limzcr, 1 ) ) ) || ( GT_16( maxnzcr[i], limmaxnzcr ) ) )
     526             :                     {
     527          35 :                         if ( LT_16( min_g_fx[i], 32767 ) ) /* *mean_prev < es_mdct[i]) */
     528             :                         {
     529          21 :                             mean_prev_fx_loc = L_add( es_mdct_fx[i], 0 );
     530             :                         }
     531          35 :                         min_g_fx[i] = 32767; /*Q15*/
     532          35 :                         move16();            /* not noise-like, do not touch the amplitude, but may do in HB*/
     533             :                     }
     534             :                 }
     535             :                 ELSE
     536             :                 {
     537         480 :                     test();
     538         480 :                     if ( i > 0 && LT_16( maxind, NUMSF ) )
     539             :                     {
     540          49 :                         *prevflag = 1;
     541          49 :                         move16();
     542             :                     }
     543         480 :                     maxind = i;
     544         480 :                     move16(); /* no preecho reduction after the first subframe with gain 1*/
     545             :                 }
     546             :             }
     547         963 :             gt_fx[i] = g_fx; /*Q15*/
     548         963 :             move16();
     549         963 :             gt_hb_fx[i] = g_fx; /*Q15*/
     550         963 :             move16();
     551             :         }
     552             : 
     553       48866 :         FOR( i = maxind; i <= NUMSF; i++ ) /* also for the first memory subframe */
     554             :         {
     555       43952 :             gt_fx[i] = 32767; /*Q15*/
     556       43952 :             move16();
     557       43952 :             min_g_fx[i] = 32767; /*Q15*/
     558       43952 :             move16();
     559       43952 :             gt_hb_fx[i] = 32767; /*Q15*/
     560       43952 :             move16();
     561       43952 :             min_g_hb_fx[i] = 32767; /*Q15*/
     562       43952 :             move16();
     563             :         }
     564             : 
     565        4914 :         ind2 = 0;
     566        4914 :         move16();
     567       44226 :         FOR( i = 0; i < NUMSF; i++ )
     568             :         {
     569       39312 :             if ( LT_16( gt_fx[i], 32767 ) ) /*gt not yet limited by min_g*/
     570             :             {
     571         192 :                 ind2 = add( i, 1 ); /* first subframe with gain = 1 after last gain < 1 --> frame with the attack*/
     572             :             }
     573             :         }
     574             : 
     575        4914 :         test();
     576        4914 :         if ( ( GT_16( wmold_fx, 16384 ) ) && ( LT_16( add( cnt2, cnt5 ), 2 ) ) ) /* mini either 1 cnt2 (and so also cnt5) or 2 cnt5 */
     577             :         {
     578             :             /* maxind = 0; false alarm, no echo reduction */
     579        4823 :             ind2 = 0;
     580        4823 :             move16();
     581             :         }
     582        4914 :         ind2_m1 = sub( ind2, 1 );
     583        4914 :         ind2_sfl = i_mult( subframelength, ind2 );
     584        4914 :         numsf_ind2 = sub( NUMSF, ind2 );
     585        4914 :         fxptr3 = gt_fx;       /*Q15*/
     586        4914 :         fxptr4 = gt_hb_fx;    /*Q15*/
     587        4914 :         fxptr5 = min_g_fx;    /*Q15*/
     588        4914 :         fxptr6 = min_g_hb_fx; /*Q15*/
     589             : 
     590        4914 :         fxptr1 = preechogain_fx + smooth_len;
     591        4914 :         pre_g_ch_tab[0] = smooth_len;
     592        4914 :         move16(); /*1st after smoothmem*/
     593        4914 :         fxptr2 = preechogain_hb_fx;
     594        5083 :         FOR( i = 0; i < ind2; i++ ) /* only subbands before max energy subband are handled*/
     595             :         {
     596         169 :             *fxptr3 = s_max( *fxptr3, *fxptr5 );
     597         169 :             move16();
     598             : 
     599         169 :             *fxptr4 = s_max( *fxptr4, *fxptr6 );
     600         169 :             move16();
     601             : 
     602       18729 :             FOR( j = 0; j < subframelength; j++ )
     603             :             {
     604       18560 :                 *fxptr1 = *fxptr3;
     605       18560 :                 move16();
     606       18560 :                 *fxptr2 = *fxptr4;
     607       18560 :                 move16();
     608       18560 :                 fxptr1++;
     609       18560 :                 fxptr2++;
     610             :             }
     611         169 :             pre_g_ch_tab[( i + 1 )] = add( pre_g_ch_tab[i], subframelength );
     612         169 :             fxptr3++;
     613         169 :             fxptr4++;
     614         169 :             fxptr5++;
     615         169 :             fxptr6++;
     616             :         }
     617             : 
     618        4914 :         max_plus_es_mdct_fx = L_deposit_l( 0 );
     619        4914 :         adv = smooth_len;
     620        4914 :         move16();     /* samples needed to have near 1 gain after smoothing at the beggining of the attack subframe*/
     621        4914 :         advmem = adv; /*Q0*/
     622        4914 :         move16();
     623             : 
     624        4914 :         test();
     625        4914 :         test();
     626        4914 :         IF( ind2 > 0 || LT_16( wmold_fx, 32767 ) || LT_16( *wmold_hb_fx, 32767 ) )
     627             :         {
     628          54 :             ptr_fx = imdct_mem_fx; /*q_sig16*/
     629          54 :             qtmp = qmemp1;
     630          54 :             pluslim = num_subsubframes;
     631          54 :             move16(); /* if ind2 == NUMSF */
     632          54 :             IF( numsf_ind2 > 0 )
     633             :             {
     634          54 :                 ptr_fx = rec_sig_fx + ind2_sfl; /*q_sig16*/
     635          54 :                 qtmp = q16p1;
     636          54 :                 move16();
     637          54 :                 pluslim = i_mult( numsf_ind2, num_subsubframes );
     638             :             }
     639             : 
     640          54 :             maxcrit_fx = L_add( mean_prev_nc_fx_loc, 0 );
     641          54 :             IF( ind2 == 0 )
     642             :             {
     643           0 :                 sum_plus_es_fx = L_add( mean_prev_nc_fx_loc, 0 ); /* 8 times mean sususb enenrgy (=maxcrit)*/
     644           0 :                 pluslim = num_subsubframes;
     645           0 :                 move16();
     646           0 :                 oldgain_fx = wmold_fx; /*Q15*/
     647           0 :                 move16();
     648           0 :                 oldgain_hb_fx = *wmold_hb_fx; /*Q15*/
     649           0 :                 move16();
     650             :             }
     651             :             ELSE /* ind2 > 0*/
     652             :             {
     653          54 :                 sum_plus_es_fx = es_mdct_fx[ind2_m1];
     654          54 :                 move32();                    /* 8 times mean sususb enenrgy (=maxcrit)*/
     655          54 :                 oldgain_fx = gt_fx[ind2_m1]; /*Q15*/
     656          54 :                 move16();
     657          54 :                 oldgain_hb_fx = gt_hb_fx[ind2_m1]; /*Q15*/
     658          54 :                 move16();
     659             : 
     660          54 :                 tmp_fx1 = mult_r( gt_fx[ind2_m1], gt_fx[ind2_m1] ); /*Q15*/
     661          54 :                 Mpy_32_16_ss( es_mdct_fx[ind2_m1], tmp_fx1, &maxcrit_fx, &tmp_u16 );
     662          54 :                 Mpy_32_16_ss( max_es_fx, 410, &tmp_fxL1, &tmp_u16 ); /* 410 for 1/80*/
     663             : 
     664          54 :                 test();
     665          54 :                 if ( ( GT_32( tmp_fxL1, maxcrit_fx ) ) && ( GT_16( zcr[ind2], limzcr ) ) )
     666             :                 {
     667          18 :                     maxcrit_fx = L_add( tmp_fxL1, 0 ); /* still 10 times smaller then mean max_es*/
     668             :                 }
     669             :             }
     670          54 :             fx32ptr1 = plus_es_mdct_fx;
     671          54 :             fx32ptr4 = mean_plus_es_fx + 1;
     672        2158 :             FOR( j = 0; j < pluslim; j++ ) /* 8  sub-subframes */
     673             :             {
     674        2104 :                 tmp_fxL1 = 100;
     675        2104 :                 move16();
     676       30904 :                 FOR( i = 0; i < subsubframelength; i++ )
     677             :                 {
     678             : 
     679       28800 :                     tmp_fx1 = shr( *ptr_fx, qtmp );                      /* q-1, to have same shift as es_mdct_.. */
     680       28800 :                     tmp_fxL1 = L_mac0_sat( tmp_fxL1, tmp_fx1, tmp_fx1 ); /*2*(Q-1)*/
     681       28800 :                     ptr_fx++;
     682             :                 }
     683        2104 :                 if ( GT_32( tmp_fxL1, max_plus_es_mdct_fx ) )
     684             :                 {
     685         378 :                     max_plus_es_mdct_fx = L_add( tmp_fxL1, 0 );
     686             :                 }
     687             : 
     688        2104 :                 sum_plus_es_fx = L_add_sat( sum_plus_es_fx, L_shl_sat( tmp_fxL1, 2 ) ); /*2*(Q-1)*/
     689        2104 :                 *fx32ptr1 = tmp_fxL1;                                                   /*2*(Q-1)*/
     690        2104 :                 fx32ptr1++;
     691        2104 :                 Mpy_32_16_ss( sum_plus_es_fx, inv_jp2[j], fx32ptr4, &tmp_u16 ); /* 410 for 1/80*/
     692        2104 :                 if ( LT_32( *fx32ptr4, maxcrit_fx ) )
     693             :                 {
     694         290 :                     *fx32ptr4 = maxcrit_fx;
     695         290 :                     move32();
     696             :                 }
     697        2104 :                 fx32ptr4++;
     698             :             }
     699          54 :             *fx32ptr4 = -1;
     700          54 :             move32();                            /*mean_plus_es_fx[pluslim] = -1; */
     701          54 :             *mean_plus_es_fx = *plus_es_mdct_fx; /*2*(Q-1)*/
     702          54 :             move32();                            /* index [0] */
     703          54 :             if ( LT_32( *mean_plus_es_fx, maxcrit_fx ) )
     704             :             {
     705          46 :                 *mean_plus_es_fx = maxcrit_fx; /*2*(Q-1)*/
     706          46 :                 move32();
     707             :             }
     708             : 
     709          54 :             j = 0;
     710          54 :             move16();
     711         282 :             WHILE( ( LT_32( plus_es_mdct_fx[j], mean_plus_es_fx[j] ) ) && ( LT_32( plus_es_mdct_fx[j], L_shr( max_plus_es_mdct_fx, 3 ) ) ) )
     712             :             {
     713         228 :                 test();
     714         228 :                 j = add( j, 1 );
     715             :             }
     716          54 :             tmp_fx3 = i_mult( j, subsubframelength );
     717          54 :             adv = sub( adv, tmp_fx3 );
     718          54 :             IF( numsf_ind2 > 0 ) /* onset not in future frame */
     719             :             {
     720          54 :                 fxptr1 = preechogain_fx + ind2_sfl + smooth_len;
     721          54 :                 fxptr2 = preechogain_hb_fx + ind2_sfl;
     722             : 
     723        3124 :                 FOR( i = 0; i < tmp_fx3; i++ )
     724             :                 {
     725        3070 :                     *fxptr1 = oldgain_fx;    /*Q15*/
     726        3070 :                     move16();                /*keep the gain of the previous subframe*/
     727        3070 :                     *fxptr2 = oldgain_hb_fx; /*Q15*/
     728        3070 :                     move16();                /*keep the gain of the previous subframe*/
     729        3070 :                     fxptr1++;
     730        3070 :                     fxptr2++;
     731             :                 }
     732             :             }
     733             :         }
     734             : 
     735        4914 :         IF( ind2 > 0 )
     736             :         {
     737             :             /* check increasing energy of preecho by regression last 3 subframes (if possible) */
     738          54 :             ind3 = add( ind2, shr( j, log2_num_subsubframes ) ); /* return (with rounding) to subframe basis */
     739          54 :             ind4 = sub( ind3, 1 );
     740          54 :             ind5 = sub( ind3, 2 );
     741          54 :             ind6 = sub( ind3, 3 );
     742          54 :             IF( ind4 > 0 )
     743             :             {
     744             :                 /* case of 3 points is simply */
     745          54 :                 eshbmean2_fx = L_add( es_mdct_hb_fx[ind4], es_mdct_hb_fx[ind5] ); /*2*(q_sig16)*/
     746             : 
     747          54 :                 sxyhb2_fx = L_sub( es_mdct_hb_fx[ind4], es_mdct_hb_fx[ind5] ); /* / eshbmean2 * 2; 04042013:  division not needed, only sign of sxyhb2 is used*/
     748             : 
     749          54 :                 IF( GT_16( ind3, 2 ) )
     750             :                 {
     751          32 :                     tmp_fxL1 = L_add( eshbmean2_fx, es_mdct_hb_fx[ind6] );        /*2*(q_sig16)*/
     752          32 :                     Mpy_32_16_ss( tmp_fxL1, 4369, &eshbmean3_fx, &tmp_u16 );      /*10922 : 1/3*/
     753          32 :                     sxylb3_fx = L_sub( es_mdct_fx[ind4], es_mdct_fx[ind6] );      /* /eslbmean3 / 2;           /2 for 3 points regression calc; 04042013:  division not needed, only sign of sxylb3 is used*/
     754          32 :                     tmp_fxL1 = L_sub( es_mdct_hb_fx[ind4], es_mdct_hb_fx[ind6] ); /*2*(q_sig16)*/
     755          32 :                     test();
     756          32 :                     IF( ( LT_32( tmp_fxL1, eshbmean3_fx ) ) || ( sxylb3_fx < 0 ) )
     757             :                     {
     758          18 :                         ind2 = 0;
     759          18 :                         move16();
     760          18 :                         ind2_sfl = 0;
     761          18 :                         move16();
     762          18 :                         adv = advmem;
     763          18 :                         move16();
     764             :                     }
     765             :                 }
     766             :                 ELSE
     767             :                 {
     768          22 :                     IF( sxyhb2_fx < 0 )
     769             :                     {
     770           0 :                         ind2 = 0;
     771           0 :                         move16();
     772           0 :                         ind2_sfl = 0;
     773           0 :                         move16();
     774           0 :                         adv = advmem;
     775           0 :                         move16(); /* 04042013: small bug corection*/
     776             :                     }
     777             :                 }
     778             : 
     779          54 :                 tmp_fxL1 = L_add( eshbmean2_fx, es_mdct_hb_fx[ind3] );   /*2*(q_sig16)*/
     780          54 :                 Mpy_32_16_ss( tmp_fxL1, 4369, &eshbmean3_fx, &tmp_u16 ); /*10922 : 1/3*/
     781             : 
     782          54 :                 tmp_fxL1 = L_sub( es_mdct_hb_fx[ind3], es_mdct_hb_fx[ind5] ); /*2*(q_sig16)*/
     783          54 :                 IF( LT_32( tmp_fxL1, eshbmean3_fx ) )
     784             :                 {
     785           8 :                     ind2 = 0;
     786           8 :                     move16();
     787           8 :                     ind2_sfl = 0;
     788           8 :                     move16();
     789           8 :                     adv = advmem;
     790           8 :                     move16();
     791             :                 }
     792             :             }
     793             :         }
     794             : 
     795        4914 :         ind2_m1 = sub( ind2, 1 ); /*ind2_m1 needs to be recomputed as ind2 could have changed since*/
     796             : 
     797        4914 :         stind = sub( ind2_sfl, adv );
     798        4914 :         stind_hb = add( stind, advmem );
     799        4914 :         if ( stind < 0 )
     800             :         {
     801        4879 :             stind = 0;
     802        4879 :             move16();
     803             :         }
     804             : 
     805        4914 :         if ( stind_hb < 0 )
     806             :         {
     807           0 :             stind_hb = 0;
     808           0 :             move16();
     809             :         }
     810             : 
     811        4914 :         tmp_fx1 = add( stind, smooth_len );
     812        4914 :         fxptr1 = preechogain_fx + tmp_fx1;     /*Q15*/
     813        4914 :         fxptr2 = preechogain_hb_fx + stind_hb; /*Q15*/
     814             : 
     815     4131523 :         FOR( i = tmp_fx1; i < framelength; i++ ) /* rest of the gains, without 4 (PREECHO_SMOOTH_LEN) 1 for fadeout */
     816             :         {
     817     4126609 :             *( fxptr1++ ) = 32767; /*Q15*/
     818     4126609 :             move16();
     819             :         }
     820        4914 :         pre_g_ch_tab[ind2] = s_min( tmp_fx1, framelength ); /*Q0*/
     821        4914 :         move16();
     822             : 
     823     4151039 :         FOR( i = stind_hb; i < framelength; i++ ) /* rest of the gains*/
     824             :         {
     825     4146125 :             *( fxptr2++ ) = 32767; /*Q15*/
     826     4146125 :             move16();
     827             :         }
     828             : 
     829        4914 :         fxptr1 = preechogain_fx; /*Q15*/
     830       24570 :         FOR( i = 0; i < smooth_len; i++ )
     831             :         {
     832       19656 :             *( fxptr1++ ) = *smoothmem_fx; /*Q15*/
     833       19656 :             move16();
     834             :         }
     835             : 
     836        4914 :         fattnext_fx = 32767; /*Q15*/
     837        4914 :         move16();
     838        4914 :         if ( GT_16( stind, framelength ) )
     839             :         {
     840           0 :             fattnext_fx = gt_fx[ind2_m1]; /*Q15*/
     841           0 :             move16();
     842             :         }
     843             : 
     844        4914 :         fxptr1 = preechogain_fx + framelength; /*Q15*/
     845       24570 :         FOR( i = 0; i < smooth_len; i++ )
     846             :         {
     847       19656 :             *( fxptr1++ ) = fattnext_fx; /*Q15*/
     848       19656 :             move16();
     849             :         }
     850             : 
     851        9916 :         FOR( i = 0; i <= ind2; i++ )
     852             :         {
     853        5002 :             tmp_fx1 = pre_g_ch_tab[i]; /*Q0*/
     854        5002 :             move16();
     855        5002 :             tmp_fx2 = sub( tmp_fx1, smooth_len );                                                           /* any index in the previous subframe*/
     856        5002 :             tmp_fx3 = mult_r( sub( preechogain_fx[tmp_fx1], preechogain_fx[tmp_fx2] ), invsmoothlenp1_fx ); /*step Q15*/
     857        5002 :             tmp_fx1 = tmp_fx3;                                                                              /*Q15*/
     858        5002 :             move16();                                                                                       /*cumulated step*/
     859        5002 :             fxptr1 = preechogain_fx + tmp_fx2;                                                              /*Q15*/
     860       25010 :             FOR( j = 0; j < smooth_len; j++ )
     861             :             {
     862       20008 :                 *fxptr1 = add_sat( *fxptr1, tmp_fx1 ); /*Q15*/
     863       20008 :                 move16();
     864       20008 :                 tmp_fx1 = add( tmp_fx1, tmp_fx3 ); /*Q15*/
     865       20008 :                 fxptr1++;
     866             :             }
     867             :         }
     868             : 
     869        4914 :         *smoothmem_fx = fattnext_fx; /*Q15*/
     870        4914 :         move16();
     871        4914 :         *wmold_hb_fx = preechogain_hb_fx[framelength_m1]; /*Q15*/
     872        4914 :         move16();
     873             : 
     874             :         /* apply gain */
     875        4914 :         fxptr1 = preechogain_fx;    /*Q15*/
     876        4914 :         fxptr2 = preechogain_hb_fx; /*Q15*/
     877        4914 :         fxptr3 = rec_sig_fx;        /*q_sig16*/
     878        4914 :         fxptr4 = rec_sig_lb_fx;     /*q_sig16*/
     879        4914 :         fxptr5 = rec_sig_hb_fx;     /*q_sig16*/
     880     4162994 :         FOR( i = 0; i < framelength; i++ )
     881             :         {
     882     4158080 :             tmp_fxL1 = L_mult( *fxptr4, *fxptr1 );         /*q_sig16 + Q16*/
     883     4158080 :             *fxptr3 = mac_r( tmp_fxL1, *fxptr5, *fxptr2 ); /*q_sig16*/
     884     4158080 :             move16();
     885     4158080 :             fxptr1++;
     886     4158080 :             fxptr2++;
     887     4158080 :             fxptr3++;
     888     4158080 :             fxptr4++;
     889     4158080 :             fxptr5++;
     890             :         }
     891             : 
     892        4914 :         mean_prev_nc_fx_loc = L_add( es_mdct_fx[0], 0 ); /* compute mean not corrected by the actual gains 2*(Q-1)*/
     893             : 
     894       39312 :         FOR( i = 1; i < NUMSF; i++ ) /* all present subbands */
     895             :         {
     896       34398 :             if ( EQ_16( i, NUMSF_S2 ) )
     897             :             {
     898        4914 :                 savehalfe_fx = L_add( mean_prev_nc_fx_loc, 0 ); /*2*(Q-1)*/
     899             :             }
     900       34398 :             mean_prev_nc_fx_loc = L_add_sat( mean_prev_nc_fx_loc, es_mdct_fx[i] ); /*2*(Q-1)*/
     901             :         }
     902             : 
     903        4914 :         if ( LT_32( savehalfe_fx, L_shr( mean_prev_nc_fx_loc, 1 ) ) )
     904             :         {
     905        2133 :             mean_prev_nc_fx_loc = L_shl_sat( L_sub_sat( mean_prev_nc_fx_loc, savehalfe_fx ), 1 ); /*2*(Q-1)*/
     906             :         }
     907        4914 :         mean_prev_nc_fx_loc = L_shr( mean_prev_nc_fx_loc, 3 ); /* >> LOG2_NUMSF in fixpoint 2*(Q-1)*/
     908             : 
     909        5002 :         FOR( i = 0; i < ind2; i++ ) /* only subbands before max energy subband are handled*/
     910             :         {
     911          88 :             tmp_fx1 = mult_r( gt_fx[i], gt_fx[i] ); /*Q15*/
     912          88 :             Mpy_32_16_ss( es_mdct_fx[i], tmp_fx1, &es_mdct_fx[i], &tmp_u16 );
     913             : 
     914          88 :             tmp_fx1 = mult_r( gt_hb_fx[i], gt_hb_fx[i] ); /*Q15*/
     915          88 :             Mpy_32_16_ss( es_mdct_hb_fx[i], tmp_fx1, &es_mdct_hb_fx[i], &tmp_u16 );
     916             :         }
     917             : 
     918        4914 :         mean_prev_fx_loc = L_shr( es_mdct_fx[0], 3 );       /* compute mean used in next frame to limit gain 2*(Q-1)*/
     919        4914 :         mean_prev_hb_fx_loc = L_shr( es_mdct_hb_fx[0], 3 ); /* compute mean used in next frame to limit gain 2*(q_sig16)*/
     920             : 
     921       39312 :         FOR( i = 1; i < NUMSF; i++ ) /* all present subbands */
     922             :         {
     923       34398 :             IF( EQ_16( i, NUMSF_S2 ) )
     924             :             {
     925        4914 :                 savehalfe_fx = L_add( mean_prev_fx_loc, 0 );       /*2*(Q-1)*/
     926        4914 :                 savehalfe_hb_fx = L_add( mean_prev_hb_fx_loc, 0 ); /*2*(q_sig16)*/
     927             :             }
     928             : 
     929       34398 :             mean_prev_fx_loc = L_add( mean_prev_fx_loc, L_shr( es_mdct_fx[i], 3 ) );          /*2*(Q-1)*/
     930       34398 :             mean_prev_hb_fx_loc = L_add( mean_prev_hb_fx_loc, L_shr( es_mdct_hb_fx[i], 3 ) ); /*2*(q_sig16)*/
     931             :         }
     932             : 
     933        4914 :         tmp_fxL1 = L_sub( mean_prev_fx_loc, savehalfe_fx ); /*2*(Q-1)*/
     934        4914 :         if ( LT_32( savehalfe_fx, L_shr( mean_prev_fx_loc, 1 ) ) )
     935             :         {
     936        2136 :             mean_prev_fx_loc = L_shl( tmp_fxL1, 1 ); /*2*(Q-1)*/
     937             :         }
     938             : 
     939        4914 :         tmp_fxL1 = L_sub( mean_prev_hb_fx_loc, savehalfe_hb_fx ); /*2*(q_sig16)*/
     940        4914 :         if ( LT_32( savehalfe_hb_fx, L_shr( mean_prev_hb_fx_loc, 1 ) ) )
     941             :         {
     942        2535 :             mean_prev_hb_fx_loc = L_shl( tmp_fxL1, 1 ); /*2*(q_sig16)*/
     943             :         }
     944             : 
     945        4914 :         last2_fx = L_shr( L_add_sat( es_mdct_fx[NUMSF_M1], es_mdct_fx[NUMSF_M2] ), 1 );          /*q_sig16*/
     946        4914 :         last2_hb_fx = L_shr( L_add_sat( es_mdct_hb_fx[NUMSF_M1], es_mdct_hb_fx[NUMSF_M2] ), 1 ); /*q_sig16*/
     947        4914 :         if ( GT_32( last2_fx, mean_prev_fx_loc ) )
     948             :         {
     949        1764 :             mean_prev_fx_loc = L_add( last2_fx, 0 );
     950             :         }
     951             : 
     952        4914 :         if ( GT_32( last2_hb_fx, mean_prev_hb_fx_loc ) )
     953             :         {
     954        2349 :             mean_prev_hb_fx_loc = L_add( last2_hb_fx, 0 ); /*2*(q_sig16)*/
     955             :         }
     956        4914 :         *mean_prev_fx = mean_prev_fx_loc; /*2*(Q-1)*/
     957        4914 :         move32();
     958        4914 :         *mean_prev_hb_fx = L_shr_sat( mean_prev_hb_fx_loc, shl_sat( q_sig16, 1 ) ); /*Q0*/
     959        4914 :         move32();                                                                   /*save in Q0*/
     960        4914 :         *mean_prev_nc_fx = mean_prev_nc_fx_loc;                                     /*2*(Q-1)*/
     961        4914 :         move32();
     962             :     }
     963             : 
     964        7516 :     return;
     965             : }
     966             : 
     967             : /*--------------------------------------------------------------------------*
     968             :  * Inverse_Transform()
     969             :  *
     970             :  * Inverse transform from the DCT domain to time domain
     971             :  *--------------------------------------------------------------------------*/
     972             : 
     973       44295 : void Inverse_Transform(
     974             :     const Word32 *in_mdct,     /* i  : input MDCT vector             Q */
     975             :     Word16 *Q,                 /* i/o: Q value of input               */
     976             :     Word32 *out,               /* o  : output vector                 Q */
     977             :     const Word16 is_transient, /* i  : transient flag                Q0 */
     978             :     const Word16 L,            /* i  : output frame length           Q0 */
     979             :     const Word16 L_inner,      /* i  : length of the transform       Q0 */
     980             :     const Word16 element_mode  /* i  : IVAS element mode             Q0  */
     981             : )
     982             : {
     983             :     Word16 ta, seg, tmp16;
     984             :     Word16 segment_length;
     985             :     const Word16 *win, *win2;
     986             :     Word32 out_alias[L_FRAME48k];
     987             :     Word32 alias[MAX_SEGMENT_LENGTH];
     988             :     Word32 in_mdct_modif[L_FRAME48k];
     989             :     Word32 *in_segment_modif;
     990             :     const Word32 *in_segment;
     991             :     Word32 *out_segment;
     992             :     Word16 segment_length_div2, segment_length_div4;
     993             :     Word16 tmp, q_out;
     994             :     Word32 L_temp;
     995             :     (void) ( element_mode );
     996             :     /* This value is used to right shift all vectors returned by 'iedct_short_fx()' */
     997             :     /* to bring them to a scaling that is equal to the 1st 'Q' returned by the 1st  */
     998             :     /* call to 'iedct_short_fx()' minus these guard bits.                           */
     999             : #define N_GUARD_BITS ( 9 + 1 ) /* 9 is enough but we put one extra bit */
    1000             : 
    1001       44295 :     IF( is_transient )
    1002             :     {
    1003        1513 :         segment_length = shr( L, 1 );
    1004        1513 :         segment_length_div2 = shr( L, 2 );
    1005        1513 :         segment_length_div4 = shr( L, 3 );
    1006             : 
    1007        1513 :         IF( EQ_16( L, L_FRAME48k ) )
    1008             :         {
    1009         446 :             win = short_window_48kHz_fx; /*Q15*/
    1010             :         }
    1011        1067 :         ELSE IF( EQ_16( L, L_FRAME32k ) )
    1012             :         {
    1013         132 :             win = short_window_32kHz_fx; /*Q15*/
    1014             :         }
    1015         935 :         ELSE IF( EQ_16( L, L_FRAME16k ) )
    1016             :         {
    1017         935 :             win = short_window_16kHz_fx; /*Q15*/
    1018             :         }
    1019             :         ELSE /* L == L_FRAME8k */
    1020             :         {
    1021           0 :             win = short_window_8kHz_fx; /*Q15*/
    1022             :         }
    1023             : 
    1024        1513 :         set32_fx( out_alias, 0, L );
    1025             : 
    1026        1513 :         in_segment = in_mdct; /*Q*/
    1027        1513 :         in_segment_modif = in_mdct_modif;
    1028             : 
    1029        1513 :         tmp16 = sub( L, L_inner );
    1030        1513 :         IF( tmp16 == 0 )
    1031             :         {
    1032         379 :             Copy32( in_mdct, in_mdct_modif, L ); /*Q*/
    1033             :         }
    1034        1134 :         ELSE IF( tmp16 > 0 )
    1035             :         {
    1036         640 :             FOR( seg = 0; seg < NUM_TIME_SWITCHING_BLOCKS; seg++ )
    1037             :             {
    1038       76352 :                 FOR( ta = 0; ta < L_inner; ta += NUM_TIME_SWITCHING_BLOCKS )
    1039             :                 {
    1040       75840 :                     *in_segment_modif++ = *in_segment++; /*Q*/
    1041       75840 :                     move32();
    1042             :                 }
    1043             : 
    1044       47552 :                 FOR( ta = 0; ta < tmp16; ta += NUM_TIME_SWITCHING_BLOCKS )
    1045             :                 {
    1046       47040 :                     *in_segment_modif++ = 0L;
    1047       47040 :                     move32();
    1048             :                 }
    1049             :             }
    1050             :         }
    1051             :         ELSE /* L < L_inner */
    1052             :         {
    1053        5030 :             FOR( seg = 0; seg < NUM_TIME_SWITCHING_BLOCKS; seg++ )
    1054             :             {
    1055      359864 :                 FOR( ta = 0; ta < segment_length_div2; ta++ )
    1056             :                 {
    1057      355840 :                     *in_segment_modif++ = *in_segment++; /*Q*/
    1058      355840 :                     move32();
    1059             :                 }
    1060        4024 :                 in_segment += shr( sub( L_inner, L ), 2 ); /*Q*/
    1061        4024 :                 move32();
    1062             :             }
    1063             :         }
    1064             : 
    1065        1513 :         out_segment = out_alias - segment_length_div4;
    1066        1513 :         in_segment = in_mdct_modif; /*Q*/
    1067             : 
    1068        1513 :         tmp = *Q;
    1069             :         /* output of 'iedct_short_fx' has up to 'output frame length'/2 # of Elements */
    1070        1513 :         iedct_short_fx( in_segment, &tmp, alias, segment_length );
    1071        1513 :         IF( GT_16( tmp, N_GUARD_BITS ) )
    1072             :         {
    1073          20 :             q_out = sub( tmp, N_GUARD_BITS );
    1074          20 :             tmp = sub( tmp, q_out );
    1075             :         }
    1076             :         ELSE
    1077             :         {
    1078        1493 :             q_out = 0;
    1079        1493 :             move16();
    1080             :         }
    1081             : 
    1082      102993 :         FOR( ta = segment_length_div4; ta < segment_length_div2; ta++ )
    1083             :         {
    1084      101480 :             out_segment[ta] = L_shr( alias[ta], tmp ); /*q_out*/
    1085      101480 :             move32();
    1086             :         }
    1087             :         /* This previous loop fills the output buffer from [0..seg_len_div4-1] */
    1088             : 
    1089        1513 :         win2 = &win[segment_length_div2]; /*Q15*/
    1090      204473 :         FOR( ta = segment_length_div2; ta < segment_length; ta++ )
    1091             :         {
    1092      202960 :             out_segment[ta] = L_shr( Mult_32_16( alias[ta], *--win2 ), tmp ); /*q_out*/
    1093      202960 :             move32();
    1094             :         }
    1095             :         /* This previous loop fills the output buffer from [seg_len_div4..seg_len-seg_len_div4-1] */
    1096             : 
    1097        1513 :         out_segment += segment_length_div2; /*q_out*/
    1098        1513 :         in_segment += segment_length_div2;  /*Q*/
    1099             : 
    1100        4539 :         FOR( seg = 1; seg < NUM_TIME_SWITCHING_BLOCKS - 1; seg++ )
    1101             :         {
    1102        3026 :             tmp = *Q;
    1103        3026 :             move16();
    1104             :             /* output of 'iedct_short_fx' has up to 'output frame length'/2 # of Elements */
    1105        3026 :             iedct_short_fx( in_segment, &tmp, alias, segment_length );
    1106        3026 :             tmp = sub( tmp, q_out );
    1107             : 
    1108      408946 :             FOR( ta = 0; ta < segment_length_div2; ta++ )
    1109             :             {
    1110      405920 :                 out_segment[ta] = L_add( out_segment[ta], L_shr( Mult_32_16( alias[ta], *win2++ ), tmp ) ); /*q_out*/
    1111      405920 :                 move32();
    1112             :             }
    1113      408946 :             FOR( ; ta < segment_length; ta++ )
    1114             :             {
    1115      405920 :                 out_segment[ta] = L_add( out_segment[ta], L_shr( Mult_32_16( alias[ta], *--win2 ), tmp ) ); /*q_out*/
    1116      405920 :                 move32();
    1117             :             }
    1118             : 
    1119        3026 :             in_segment += segment_length_div2;  /*Q*/
    1120        3026 :             out_segment += segment_length_div2; /*q_out*/
    1121             :         }
    1122             : 
    1123        1513 :         tmp = *Q;
    1124        1513 :         move16();
    1125        1513 :         iedct_short_fx( in_segment, &tmp, alias, segment_length );
    1126        1513 :         tmp = sub( tmp, q_out );
    1127             : 
    1128      204473 :         FOR( ta = 0; ta < segment_length_div2; ta++ )
    1129             :         {
    1130      202960 :             out_segment[ta] = L_add( out_segment[ta], L_shr( Mult_32_16( alias[ta], *win2++ ), tmp ) ); /*q_out*/
    1131      202960 :             move32();
    1132             :         }
    1133             : 
    1134        1513 :         seg = add( segment_length_div2, shr( segment_length_div2, 1 ) ); /* seg = 3*segment_length/4 Q0*/
    1135      102993 :         FOR( ta = segment_length_div2; ta < seg; ta++ )
    1136             :         {
    1137      101480 :             out_segment[ta] = L_shr( alias[ta], tmp ); /*q_out*/
    1138      101480 :             move32();
    1139             :         }
    1140             : 
    1141      407433 :         FOR( ta = 0; ta < segment_length; ta++ )
    1142             :         {
    1143      405920 :             L_temp = L_add( out_alias[ta], 0 );
    1144      405920 :             out[ta] = out_alias[L - 1 - ta]; /*q_out*/
    1145      405920 :             move32();
    1146      405920 :             out[L - 1 - ta] = L_temp; /*q_out*/
    1147      405920 :             move32();
    1148             :         }
    1149             : 
    1150        1513 :         *Q = q_out;
    1151        1513 :         move16();
    1152             :     }
    1153             :     ELSE
    1154             :     {
    1155       42782 :         edct_fx( in_mdct, out, L, Q );
    1156             :     }
    1157       44295 : }

Generated by: LCOV version 1.14