LCOV - code coverage report
Current view: top level - lib_com - tcx_utils_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 818 1113 73.5 %
Date: 2025-08-23 01:22:27 Functions: 19 22 86.4 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include <assert.h>
       7             : #include "options.h"
       8             : #include "prot_fx.h"
       9             : #include "rom_com.h"
      10             : #include "rom_basop_util.h"
      11             : #include "basop_util.h"
      12             : 
      13             : #define inv_int InvIntTable
      14             : 
      15             : /*-------------------------------------------------------------------*
      16             :  * getInvFrameLen()
      17             :  *
      18             :  *
      19             :  *-------------------------------------------------------------------*/
      20     1778209 : Word16 getInvFrameLen( /* returns 1/L_frame in Q21 format */
      21             :                        const Word16 L_frame )
      22             : {
      23             :     Word16 idx, s;
      24             : 
      25     1778209 :     s = norm_s( L_frame );
      26     1778209 :     idx = shl( L_frame, s );
      27             : 
      28     1778209 :     assert( ( idx == 0x4000 ) || ( idx == 0x4B00 ) || ( idx == 0x5000 ) || ( idx == 0x5A00 ) || ( idx == 0x6000 ) || ( idx == 0x6400 ) || ( idx == 0x7800 ) );
      29             : 
      30     1778209 :     idx = mult_r( idx, 0x10 ); /* idx = shr(add(idx, 0x0400), 11); */
      31     1778209 :     idx = s_and( idx, 7 );
      32             : 
      33             : 
      34     1778209 :     return shl( L_frame_inv[idx], sub( s, 7 ) );
      35             : }
      36             : /*-------------------------------------------------------------------*
      37             :  *tcx_get_windows()
      38             :  *
      39             :  *
      40             :  * ------------------------------------------------------------------ - */
      41        2994 : void tcx_get_windows(
      42             :     TCX_CONFIG_HANDLE hTcxCfg, /* i  : TCX configuration                   */
      43             :     const Word16 left_mode,    /* i: overlap mode of left window half          Q0*/
      44             :     const Word16 right_mode,   /* i: overlap mode of right window half         Q0*/
      45             :     Word16 *left_overlap,      /* o: left overlap length                       Q0*/
      46             :     const PWord16 **left_win,  /* o: left overlap window                       Q15*/
      47             :     Word16 *right_overlap,     /* o: right overlap length                      Q0*/
      48             :     const PWord16 **right_win, /* o: right overlap window                      Q15*/
      49             :     const Word8 fullband       /* i: fullband flag                             Q0*/
      50             : )
      51             : { /* LFE is only FULL_OVERLAP*/
      52        2994 :     IF( fullband == 0 )
      53             :     {
      54             :         /* Left part */
      55           0 :         SWITCH( left_mode )
      56             :         {
      57           0 :             case TRANSITION_OVERLAP:                                   /* ACELP->TCX transition */
      58           0 :                 *left_overlap = hTcxCfg->tcx_mdct_window_trans_length; /*Q0*/
      59           0 :                 move16();
      60           0 :                 *left_win = hTcxCfg->tcx_mdct_window_trans; /*Q15*/
      61           0 :                 BREAK;
      62           0 :             case MIN_OVERLAP:
      63           0 :                 *left_overlap = hTcxCfg->tcx_mdct_window_min_length; /*Q0*/
      64           0 :                 move16();
      65           0 :                 *left_win = hTcxCfg->tcx_mdct_window_minimum; /*Q15*/
      66           0 :                 BREAK;
      67           0 :             case HALF_OVERLAP:
      68           0 :                 *left_overlap = hTcxCfg->tcx_mdct_window_half_length; /*Q0*/
      69           0 :                 move16();
      70           0 :                 *left_win = hTcxCfg->tcx_mdct_window_half; /*Q15*/
      71           0 :                 BREAK;
      72           0 :             case FULL_OVERLAP:
      73           0 :                 *left_overlap = hTcxCfg->tcx_mdct_window_length; /*Q0*/
      74           0 :                 move16();
      75           0 :                 *left_win = hTcxCfg->tcx_aldo_window_1_trunc; /*Q15*/
      76           0 :                 BREAK;
      77           0 :             default:
      78           0 :                 assert( !"Not supported overlap" );
      79             :         }
      80             : 
      81             :         /* Right part */
      82           0 :         SWITCH( right_mode )
      83             :         {
      84           0 :             case MIN_OVERLAP:
      85           0 :                 *right_overlap = hTcxCfg->tcx_mdct_window_min_length; /*Q0*/
      86           0 :                 move16();
      87           0 :                 *right_win = hTcxCfg->tcx_mdct_window_minimum; /*Q15*/
      88           0 :                 BREAK;
      89           0 :             case HALF_OVERLAP:
      90           0 :                 *right_overlap = hTcxCfg->tcx_mdct_window_half_length; /*Q0*/
      91           0 :                 move16();
      92           0 :                 *right_win = hTcxCfg->tcx_mdct_window_half; /*Q15*/
      93           0 :                 BREAK;
      94           0 :             case FULL_OVERLAP:
      95           0 :                 *right_overlap = hTcxCfg->tcx_mdct_window_delay; /*Q0*/
      96           0 :                 move16();
      97           0 :                 *right_win = hTcxCfg->tcx_aldo_window_2; /*Q15*/
      98           0 :                 BREAK;
      99           0 :             default:
     100           0 :                 assert( !"Not supported overlap" );
     101             :         }
     102             :     }
     103             :     ELSE
     104             :     {
     105             :         /* Left part */
     106        2994 :         SWITCH( left_mode )
     107             :         {
     108           0 :             case TRANSITION_OVERLAP:                                     /* ACELP->TCX transition */
     109           0 :                 *left_overlap = hTcxCfg->tcx_mdct_window_trans_lengthFB; /*Q0*/
     110           0 :                 move16();
     111           0 :                 *left_win = hTcxCfg->tcx_mdct_window_transFB; /*Q15*/
     112           0 :                 BREAK;
     113           0 :             case MIN_OVERLAP:
     114           0 :                 *left_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB; /*Q0*/
     115           0 :                 move16();
     116           0 :                 *left_win = hTcxCfg->tcx_mdct_window_minimumFB; /*Q15*/
     117           0 :                 BREAK;
     118           0 :             case HALF_OVERLAP:
     119           0 :                 *left_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB; /*Q0*/
     120           0 :                 move16();
     121           0 :                 *left_win = hTcxCfg->tcx_mdct_window_halfFB; /*Q15*/
     122           0 :                 BREAK;
     123           0 :             case RECTANGULAR_OVERLAP:
     124           0 :                 *left_overlap = 0;
     125           0 :                 move16();
     126           0 :                 *left_win = NULL;
     127           0 :                 BREAK;
     128        2994 :             case FULL_OVERLAP:
     129        2994 :                 *left_overlap = hTcxCfg->tcx_mdct_window_lengthFB; /*Q0*/
     130        2994 :                 move16();
     131        2994 :                 *left_win = hTcxCfg->tcx_aldo_window_1_FB_trunc; /*Q15*/
     132        2994 :                 BREAK;
     133           0 :             default:
     134           0 :                 assert( !"Not supported overlap" );
     135             :         }
     136             : 
     137             :         /* Right part */
     138        2994 :         SWITCH( right_mode )
     139             :         {
     140           0 :             case MIN_OVERLAP:
     141           0 :                 *right_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB; /*Q0*/
     142           0 :                 move16();
     143           0 :                 *right_win = hTcxCfg->tcx_mdct_window_minimumFB; /*Q15*/
     144           0 :                 BREAK;
     145           0 :             case HALF_OVERLAP:
     146           0 :                 *right_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB; /*Q0*/
     147           0 :                 move16();
     148           0 :                 *right_win = hTcxCfg->tcx_mdct_window_halfFB; /*Q15*/
     149           0 :                 BREAK;
     150           0 :             case RECTANGULAR_OVERLAP:
     151           0 :                 *right_overlap = 0;
     152           0 :                 move16();
     153           0 :                 *right_win = NULL;
     154           0 :                 BREAK;
     155        2994 :             case FULL_OVERLAP:
     156        2994 :                 *right_overlap = hTcxCfg->tcx_mdct_window_delayFB; /*Q0*/
     157        2994 :                 move16();
     158        2994 :                 *right_win = hTcxCfg->tcx_aldo_window_2_FB; /*Q15*/
     159        2994 :                 BREAK;
     160           0 :             default:
     161           0 :                 assert( !"Not supported overlap" );
     162             :         }
     163             :     }
     164        2994 : }
     165             : 
     166        2994 : static void tcx_windowing_analysis(
     167             :     Word16 const *signal,     /* i: signal vector                              Qx*/
     168             :     Word16 L_frame,           /* i: frame length                               Q0*/
     169             :     Word16 left_overlap,      /* i: left overlap length                        Q0*/
     170             :     PWord16 const *left_win,  /* i: left overlap window                        Q15*/
     171             :     Word16 right_overlap,     /* i: right overlap length                       Q0*/
     172             :     PWord16 const *right_win, /* i: right overlap window                       Q15*/
     173             :     Word16 *output            /* o: windowed signal vector                     Qx*/
     174             : )
     175             : {
     176             :     Word16 w, n;
     177             : 
     178             :     /* Left overlap */
     179        2994 :     n = shr( left_overlap, 1 ); /*Q0*/
     180      514834 :     FOR( w = 0; w < n; w++ )
     181             :     {
     182      511840 :         *output++ = mult_r( *signal++, left_win[w].v.im ); /*Qx*/
     183      511840 :         move16();
     184             :     }
     185      514834 :     FOR( w = 0; w < n; w++ )
     186             :     {
     187      511840 :         *output++ = mult_r( *signal++, left_win[n - 1 - w].v.re ); /*Qx*/
     188      511840 :         move16();
     189             :     }
     190             : 
     191             :     /* Non overlapping region */
     192        2994 :     n = sub( L_frame, shr( add( left_overlap, right_overlap ), 1 ) ); /*Q0*/
     193     1319154 :     FOR( w = 0; w < n; w++ )
     194             :     {
     195     1316160 :         *output++ = *signal++; /*Qx*/
     196     1316160 :         move16();
     197             :     }
     198             : 
     199             :     /* Right overlap */
     200        2994 :     n = shr( right_overlap, 1 ); /*Q0*/
     201      514834 :     FOR( w = 0; w < n; w++ )
     202             :     {
     203      511840 :         *output++ = mult_r( *signal++, right_win[w].v.re ); /*Qx*/
     204      511840 :         move16();
     205             :     }
     206      514834 :     FOR( w = 0; w < n; w++ )
     207             :     {
     208      511840 :         *output++ = mult_r( *signal++, right_win[n - 1 - w].v.im ); /*Qx*/
     209      511840 :         move16();
     210             :     }
     211        2994 : }
     212             : /*-------------------------------------------------------------------*
     213             :  * WindowSignal()
     214             :  *
     215             :  *
     216             :  *-------------------------------------------------------------------*/
     217        2994 : void WindowSignal(
     218             :     TCX_CONFIG_HANDLE hTcxCfg,      /* i  :   configuration of TCX              */
     219             :     Word16 offset,                  /* i  :   left folding point offset relative to the input signal pointer Q0*/
     220             :     const Word16 left_overlap_mode, /* i  :   overlap mode of left window half  Q0*/
     221             :     Word16 right_overlap_mode,      /* i  :   overlap mode of right window half Q0*/
     222             :     Word16 *left_overlap_length,    /* o  :   TCX window left overlap length    Q0*/
     223             :     Word16 *right_overlap_length,   /* o  :   TCX window right overlap length   Q0*/
     224             :     const Word16 in[],              /* i  :   input signal                      Qx*/
     225             :     Word16 *L_frame,                /* i/o:   frame length                      Q0*/
     226             :     Word16 out[],                   /* o  :   output windowed signal            Qx*/
     227             :     const Word16 truncate_aldo,     /* i  : nonzero to truncate long ALDO slope Q0*/
     228             :     const Word8 fullband            /* i  :   fullband flag                     Q0*/
     229             : )
     230             : {
     231             :     Word16 l, r;
     232             :     PWord16 const *left_win;
     233             :     PWord16 const *right_win;
     234             : 
     235             : 
     236             :     /*-----------------------------------------------------------*
     237             :      * Init                                                      *
     238             :      *-----------------------------------------------------------*/
     239             : 
     240        2994 :     tcx_get_windows( hTcxCfg, left_overlap_mode, right_overlap_mode, &l, &left_win, &r, &right_win, fullband );
     241             : 
     242             :     /* Init lengths */
     243             : 
     244             :     /* if past frame is ACELP */
     245        2994 :     IF( EQ_16( left_overlap_mode, TRANSITION_OVERLAP ) )
     246             :     {
     247             :         /* Increase frame size for 5ms */
     248           0 :         IF( fullband == 0 )
     249             :         {
     250           0 :             *L_frame = add( *L_frame, hTcxCfg->tcx5Size ); /*Q0*/
     251           0 :             move16();
     252           0 :             offset = negate( shr( hTcxCfg->tcx_mdct_window_trans_length, 1 ) ); /*Q0*/
     253             :         }
     254             :         ELSE
     255             :         {
     256           0 :             *L_frame = add( *L_frame, hTcxCfg->tcx5SizeFB ); /*Q0*/
     257           0 :             move16();
     258           0 :             offset = negate( shr( hTcxCfg->tcx_mdct_window_trans_lengthFB, 1 ) ); /*Q0*/
     259             :         }
     260             :     }
     261             : 
     262             :     /*-----------------------------------------------------------*
     263             :      * Windowing                                                 *
     264             :      *-----------------------------------------------------------*/
     265             : 
     266        2994 :     tcx_windowing_analysis( in - sub( shr( l, 1 ), offset ), *L_frame, l, left_win, r, right_win, out );
     267        2994 :     test();
     268        2994 :     test();
     269        2994 :     IF( EQ_16( left_overlap_mode, FULL_OVERLAP ) && truncate_aldo )
     270             :     {
     271             :         /* fade truncated ALDO window to avoid discontinuities */
     272             :         Word16 i, tmp;
     273             :         const PWord16 *p;
     274             : 
     275        2994 :         p = hTcxCfg->tcx_mdct_window_minimum;                /*Q15*/
     276        2994 :         tmp = shr( hTcxCfg->tcx_mdct_window_min_length, 1 ); /*Q0*/
     277        2994 :         IF( fullband != 0 )
     278             :         {
     279        2994 :             p = hTcxCfg->tcx_mdct_window_minimumFB;                /*Q15*/
     280        2994 :             tmp = shr( hTcxCfg->tcx_mdct_window_min_lengthFB, 1 ); /*Q0*/
     281             :         }
     282             : 
     283       76114 :         FOR( i = 0; i < tmp; i++ )
     284             :         {
     285       73120 :             out[i] = mult_r( out[i], p[i].v.im ); /*Qx*/
     286       73120 :             move16();
     287             :         }
     288       76114 :         FOR( i = 0; i < tmp; i++ )
     289             :         {
     290       73120 :             out[i + tmp] = mult_r( out[i + tmp], p[tmp - 1 - i].v.re ); /*Qx*/
     291       73120 :             move16();
     292             :         }
     293             :     }
     294             : 
     295        2994 :     *left_overlap_length = l;
     296        2994 :     move16();
     297        2994 :     *right_overlap_length = r;
     298        2994 :     move16();
     299        2994 : }
     300             : /*-------------------------------------------------------------------*
     301             :  * tcx_windowing_synthesis_current_frame()
     302             :  *
     303             :  *
     304             :  *-------------------------------------------------------------------*/
     305             : 
     306      115738 : void tcx_windowing_synthesis_current_frame(
     307             :     Word16 *signal,                  /* i/o: signal vector                            Qx*/
     308             :     const PWord16 *window,           /* i: TCX window vector                          Q15*/
     309             :     const PWord16 *window_half,      /* i: TCX window vector for half-overlap window  Q15*/
     310             :     const PWord16 *window_min,       /* i: TCX minimum overlap window                 Q15*/
     311             :     const Word16 window_length,      /* i: TCX window length                          Q0*/
     312             :     const Word16 window_half_length, /* i: TCX half window length                     Q0*/
     313             :     const Word16 window_min_length,  /* i: TCX minimum overlap length                 Q0*/
     314             :     const Word16 left_rect,          /* i: left part is rectangular                   Q0*/
     315             :     const Word16 left_mode,          /* i: overlap mode of left window half           Q0*/
     316             :     Word16 *acelp_zir,               /* i: acelp ZIR                                  Qx*/
     317             :     const Word16 *old_syn,           /*Qx*/
     318             :     const Word16 *syn_overl,         /*Qx*/
     319             :     const Word16 *A_zir,             /*Q12*/
     320             :     const PWord16 *window_trans,     /*Q15*/
     321             :     Word16 acelp_zir_len,            /*Q0*/
     322             :     const Word16 acelp_mem_len,      /*Q0*/
     323             :     const Word16 last_core_bfi,      /* i :  last core Q0*/
     324             :     const Word8 last_is_cng,         /*Q0*/
     325             :     const Word16 fullbandScale /*Q0*/ )
     326             : {
     327             : 
     328             :     Word16 i, overlap, n, tmp, tmp2;
     329             :     Word16 tmp_buf[L_FRAME_MAX / 2];
     330             :     Word32 L_tmp;
     331             : 
     332             :     /* Init */
     333             : 
     334      115738 :     overlap = shr( window_length, 1 ); /*Q0*/
     335             : 
     336             :     /* Past-frame is TCX concealed as CNG and current-frame is TCX */
     337      115738 :     test();
     338      115738 :     test();
     339      115738 :     test();
     340      115738 :     test();
     341      115738 :     IF( EQ_16( last_is_cng, 1 ) && left_rect == 0 )
     342             :     {
     343           0 :         IF( !fullbandScale )
     344             :         {
     345           0 :             set16_fx( acelp_zir, 0, acelp_zir_len );
     346           0 :             E_UTIL_synthesis( 0, A_zir, acelp_zir, acelp_zir, acelp_zir_len, signal + overlap + acelp_mem_len - M, 0, M );
     347             :         }
     348             :         ELSE
     349             :         {
     350           0 :             lerp( acelp_zir, tmp_buf, acelp_zir_len, idiv1616U( shl_sat( acelp_zir_len, LD_FSCALE_DENOM ), fullbandScale ) );
     351           0 :             acelp_zir = tmp_buf; /*Qx*/
     352             :         }
     353             : 
     354           0 :         FOR( i = 0; i < acelp_zir_len; i++ )
     355             :         {
     356             :             /*signal[i] *= (float)(i)/(float)(acelp_zir_len);
     357             :             signal[i] += acelp_zir[i]*(float)(acelp_zir_len-i)/(float)(acelp_zir_len);*/
     358           0 :             signal[i] = add( mult_r( signal[i], div_s( i, acelp_zir_len ) ), mult_r( acelp_zir[i], div_s( sub( acelp_zir_len, i ), acelp_zir_len ) ) ); /*Qx*/
     359           0 :             move16();
     360             :         }
     361             :     }
     362             :     /* Rectangular window (past-frame is ACELP) */
     363      115738 :     ELSE IF( EQ_16( left_rect, 1 ) && last_core_bfi == ACELP_CORE )
     364             :     {
     365       17260 :         tmp = sub( overlap, acelp_mem_len );
     366     1940908 :         FOR( i = 0; i < tmp; i++ )
     367             :         {
     368     1923648 :             move16();
     369     1923648 :             signal[i] = 0;
     370             :         }
     371             : 
     372       17260 :         IF( fullbandScale == 0 )
     373             :         {
     374             : 
     375        8630 :             tmp = shl( acelp_mem_len, 1 ); /*Qx*/
     376             : 
     377             :             /*OLA with ACELP*/
     378      100668 :             FOR( i = 0; i < acelp_mem_len; i++ )
     379             :             {
     380             : 
     381             :                 /*window decoded TCX with aliasing*/
     382       92038 :                 tmp2 = mult_r( signal[i + overlap - acelp_mem_len], window_trans[i].v.im ); /*Qx*/
     383             : 
     384             :                 /*Time TDAC: 1)forward part of ACELP*/
     385       92038 :                 tmp2 = add_sat( tmp2, mult_r( old_syn[acelp_zir_len - tmp + i], mult_r( window_trans[i].v.re, window_trans[i].v.re ) ) ); /*Qx*/
     386             : 
     387             :                 /*Time TDAC: 1)reward part of ACELP*/
     388       92038 :                 tmp2 = add_sat( tmp2, mult_r( old_syn[acelp_zir_len - i - 1], mult_r( window_trans[i].v.im, window_trans[i].v.re ) ) ); /*Qx*/
     389       92038 :                 move16();
     390       92038 :                 signal[i + overlap - acelp_mem_len] = tmp2; /*Qx*/
     391             :             }
     392      100668 :             FOR( ; i < tmp; i++ )
     393             :             {
     394             : 
     395             :                 /*window decoded TCX with aliasing*/
     396       92038 :                 tmp2 = mult_r( signal[i + overlap - acelp_mem_len], window_trans[tmp - 1 - i].v.re ); /*Qx*/
     397             : 
     398             :                 /*Time TDAC: 1)forward part of ACELP*/
     399       92038 :                 tmp2 = add_sat( tmp2, mult_r( old_syn[acelp_zir_len - tmp + i], mult_r( window_trans[tmp - 1 - i].v.im, window_trans[tmp - 1 - i].v.im ) ) ); /*Qx*/
     400             :                 /*Time TDAC: 1)reward part of ACELP*/
     401       92038 :                 tmp2 = add_sat( tmp2, mult_r( old_syn[acelp_zir_len - i - 1], mult_r( window_trans[tmp - 1 - i].v.re, window_trans[tmp - 1 - i].v.im ) ) ); /*Qx*/
     402       92038 :                 move16();
     403       92038 :                 signal[i + overlap - acelp_mem_len] = tmp2; /*Qx*/
     404             :             }
     405             : 
     406      146710 :             FOR( i = 0; i < M; i++ )
     407             :             {
     408      138080 :                 move16();
     409      138080 :                 signal[overlap + acelp_mem_len - M + i] = sub_sat( signal[overlap + acelp_mem_len - M + i], old_syn[acelp_zir_len - M + i] ); /*Qx*/
     410             :             }
     411             :         }
     412             :         /* ZIR at the end of the ACELP frame */
     413       17260 :         move16();
     414       17260 :         acelp_zir_len = 64;
     415             : 
     416       17260 :         IF( fullbandScale == 0 )
     417             :         {
     418        8630 :             set16_fx( acelp_zir, 0, acelp_zir_len );
     419        8630 :             E_UTIL_synthesis( 0, A_zir, acelp_zir, acelp_zir, acelp_zir_len, signal + overlap + acelp_mem_len - M, 0, M );
     420             :         }
     421             :         ELSE
     422             :         {
     423        8630 :             tmp = extract_l( L_shr( L_mult0( acelp_zir_len, fullbandScale ), LD_FSCALE_DENOM ) ); /*Q0*/
     424        8630 :             lerp( acelp_zir, tmp_buf, tmp, acelp_zir_len );
     425        8630 :             acelp_zir_len = tmp; /*Q0*/
     426        8630 :             move16();
     427        8630 :             acelp_zir = tmp_buf; /*Qx*/
     428             : 
     429             : 
     430        8630 :             IF( GE_16( acelp_zir_len, 2 * 64 ) )
     431             :             {
     432             :                 /* apply a simple low-pass to the ZIR, to avoid potentially unmasked HF content */
     433     1276637 :                 FOR( i = 2; i < acelp_zir_len; i++ )
     434             :                 {
     435     1270138 :                     L_tmp = L_mult( acelp_zir[i - 2], 8192 /*0.25 in Q15*/ );
     436     1270138 :                     L_tmp = L_mac( L_tmp, acelp_zir[i - 1], 11469 /*0.35 in Q15*/ );
     437     1270138 :                     acelp_zir[i] = mac_r( L_tmp, acelp_zir[i], 13107 /*0.40 in Q15*/ ); /*Qx*/
     438     1270138 :                     move16();
     439             :                 }
     440             : 
     441        6499 :                 L_tmp = L_mult( acelp_zir[acelp_zir_len - 1], 13107 /*0.40 in Q15*/ );
     442        6499 :                 L_tmp = L_mac( L_tmp, acelp_zir[acelp_zir_len - 1], 11469 /*0.35 in Q15*/ );
     443        6499 :                 acelp_zir[acelp_zir_len - 1] = mac_r( L_tmp, acelp_zir[acelp_zir_len - 2], 8192 /*0.25 in Q15*/ ); /*Qx*/
     444        6499 :                 move16();
     445        6499 :                 L_tmp = L_mult( acelp_zir[acelp_zir_len - 2], 13107 );
     446        6499 :                 L_tmp = L_mac( L_tmp, acelp_zir[acelp_zir_len - 1], 11469 );
     447        6499 :                 acelp_zir[acelp_zir_len - 2] = mac_r( L_tmp, acelp_zir[acelp_zir_len - 1], 8192 ); /*Qx*/
     448        6499 :                 move16();
     449     1276637 :                 FOR( i = acelp_zir_len - 3; i >= 0; i-- )
     450             :                 {
     451     1270138 :                     L_tmp = L_mult( acelp_zir[i], 13107 );
     452     1270138 :                     L_tmp = L_mac( L_tmp, acelp_zir[i + 1], 11469 );
     453     1270138 :                     acelp_zir[i] = mac_r( L_tmp, acelp_zir[i + 2], 8192 ); /*Qx*/
     454     1270138 :                     move16();
     455             :                 }
     456             :             }
     457             :         }
     458             : 
     459     2049604 :         FOR( i = 0; i < acelp_zir_len; i++ )
     460             :         {
     461             :             /*remove reconstructed ZIR and add ACELP ZIR*/
     462     2032344 :             move16();
     463     2032344 :             signal[i + overlap + acelp_mem_len] = sub_sat( signal[i + overlap + acelp_mem_len], mult_r_sat( acelp_zir[i], div_s( sub_sat( acelp_zir_len, i ), acelp_zir_len ) ) ); /*Qx*/
     464             :         }
     465             :     }
     466             :     /* Rectangular window (past-frame is TCX) */
     467       98478 :     ELSE IF( left_rect == 1 && last_core_bfi != ACELP_CORE )
     468             :     {
     469         460 :         n = add( overlap, acelp_mem_len ); /*q0*/
     470       66300 :         FOR( i = 0; i < n; i++ )
     471             :         {
     472       65840 :             move16();
     473       65840 :             signal[i] = 0;
     474             :         }
     475             : 
     476         460 :         n = shr( window_length, 1 ); /*q0*/
     477       58070 :         FOR( i = 0; i < n; i++ )
     478             :         {
     479       57610 :             move16();
     480       57610 :             signal[i + overlap + acelp_mem_len] = mult_r( signal[i + overlap + acelp_mem_len], window[i].v.im ); /*Qx*/
     481             :         }
     482       58070 :         FOR( ; i < window_length; i++ )
     483             :         {
     484       57610 :             move16();
     485       57610 :             signal[i + overlap + acelp_mem_len] = mult_r( signal[i + overlap + acelp_mem_len], window[window_length - 1 - i].v.re ); /*Qx*/
     486             :         }
     487             :     }
     488             :     /* Normal window (past-frame is ACELP) */
     489       98018 :     ELSE IF( left_rect != 1 && last_core_bfi == ACELP_CORE )
     490             :     {
     491             : 
     492          20 :         n = shr( window_length, 1 ); /*q0*/
     493        3086 :         FOR( i = 0; i < n; i++ )
     494             :         {
     495        3066 :             move16();
     496        3066 :             signal[i] = mult_r( signal[i], window[i].v.im ); /*Qx*/
     497             :         }
     498        3086 :         FOR( ; i < window_length; i++ )
     499             :         {
     500        3066 :             move16();
     501        3066 :             signal[i] = mult_r( signal[i], window[window_length - 1 - i].v.re ); /*Qx*/
     502             :         }
     503             : 
     504        6152 :         FOR( i = 0; i < window_length /*acelp_zir_len*/; i++ )
     505             :         {
     506        6132 :             move16();
     507        6132 :             signal[i] = add( signal[i], syn_overl[i] ); /*Qx*/
     508             :         }
     509             :     }
     510             :     /* Normal window (past-frame is TCX) */
     511             :     ELSE
     512             :     {
     513       97998 :         IF( EQ_16( left_mode, 2 ) ) /* min. overlap */
     514             :         {
     515       58868 :             n = shr( sub( window_length, window_min_length ), 1 ); /*q0*/
     516     2737936 :             FOR( i = 0; i < n; i++ )
     517             :             {
     518     2679068 :                 *signal++ = 0;
     519     2679068 :                 move16();
     520             :             }
     521             : 
     522       58868 :             n = shr( window_min_length, 1 ); /*q0*/
     523     1320826 :             FOR( i = 0; i < n; i++ )
     524             :             {
     525     1261958 :                 *signal = mult_r( *signal, window_min[i].v.im ); /*Qx*/
     526     1261958 :                 move16();
     527     1261958 :                 signal++;
     528             :             }
     529     1320826 :             FOR( i = 0; i < n; i++ )
     530             :             {
     531     1261958 :                 *signal = mult_r( *signal, window_min[n - 1 - i].v.re ); /*Qx*/
     532     1261958 :                 move16();
     533     1261958 :                 signal++;
     534             :             }
     535             :         }
     536       39130 :         ELSE IF( EQ_16( left_mode, 3 ) ) /* half OL */
     537             :         {
     538             :             Word16 w;
     539             : 
     540       14102 :             n = shr( sub( window_length, window_half_length ), 1 );
     541      344542 :             FOR( i = 0; i < n; i++ )
     542             :             {
     543      330440 :                 move16();
     544      330440 :                 signal[i] = 0;
     545             :             }
     546       14102 :             n = shr( window_half_length, 1 );
     547      920114 :             FOR( w = 0; w < n; w++ )
     548             :             {
     549      906012 :                 move16();
     550      906012 :                 signal[i] = mult_r( signal[i], window_half[w].v.im ); /*Qx*/
     551      906012 :                 i = add( i, 1 );
     552             :             }
     553      920114 :             FOR( w = 0; w < n; w++ )
     554             :             {
     555      906012 :                 move16();
     556      906012 :                 signal[i] = mult_r( signal[i], window_half[window_half_length / 2 - 1 - w].v.re ); /*Qx*/
     557      906012 :                 i = add( i, 1 );
     558             :             }
     559             :         }
     560             :         ELSE
     561             :         { /* normal full/maximum overlap */
     562             : 
     563       25028 :             n = shr( window_length, 1 );
     564     3809452 :             FOR( i = 0; i < n; i++ )
     565             :             {
     566     3784424 :                 move16();
     567     3784424 :                 signal[i] = mult_r( signal[i], window[i].v.im ); /*Qx*/
     568             :             }
     569     3809452 :             FOR( ; i < window_length; i++ )
     570             :             {
     571     3784424 :                 move16();
     572     3784424 :                 signal[i] = mult_r( signal[i], window[window_length - 1 - i].v.re ); /*Qx*/
     573             :             }
     574             :         }
     575             :     }
     576             : 
     577             :     /* Right part asymmetric window : with ALDO do nothing->can be skipped*/
     578      115738 : }
     579             : /*-------------------------------------------------------------------*
     580             :  * tcx_windowing_synthesis_past_frame()
     581             :  *
     582             :  *
     583             :  *-------------------------------------------------------------------*/
     584      117108 : void tcx_windowing_synthesis_past_frame(
     585             :     Word16 *signal,                  /* i/o: signal vector                            Qx*/
     586             :     const PWord16 *window,           /* i: TCX window vector                          Q15*/
     587             :     const PWord16 *window_half,      /* i: TCX window vector for half-overlap window  Q15*/
     588             :     const PWord16 *window_min,       /* i: TCX minimum overlap window                 Q15*/
     589             :     const Word16 window_length,      /* i: TCX window length                          Q0*/
     590             :     const Word16 window_half_length, /* i: TCX half window length                     Q0*/
     591             :     const Word16 window_min_length,  /* i: TCX minimum overlap length                 Q0*/
     592             :     const Word16 right_mode          /* i: overlap mode (left_mode of current frame)  Q0*/
     593             : )
     594             : {
     595             : 
     596             :     Word16 i, n;
     597             : 
     598      117108 :     IF( EQ_16( right_mode, 2 ) ) /* min. overlap */
     599             :     {
     600       62446 :         signal += shr( sub( window_length, window_min_length ), 1 ); /*Qx*/
     601             : 
     602       62446 :         n = shr( window_min_length, 1 );
     603     1404718 :         FOR( i = 0; i < n; i++ )
     604             :         {
     605     1342272 :             *signal = mult_r( *signal, window_min[i].v.re ); /*Qx*/
     606     1342272 :             move16();
     607     1342272 :             signal++;
     608             :         }
     609     1404718 :         FOR( i = 0; i < n; i++ )
     610             :         {
     611     1342272 :             *signal = mult_r( *signal, window_min[n - 1 - i].v.im ); /*Qx*/
     612     1342272 :             move16();
     613     1342272 :             signal++;
     614             :         }
     615             : 
     616       62446 :         n = shr( sub( window_length, window_min_length ), 1 ); /*Q0*/
     617     4242618 :         FOR( i = 0; i < n; i++ )
     618             :         {
     619     4180172 :             *signal = 0;
     620     4180172 :             move16();
     621     4180172 :             signal++;
     622             :         }
     623             :     }
     624       54662 :     ELSE IF( EQ_16( right_mode, 3 ) ) /* half OL */
     625             :     {
     626             :         Word16 w;
     627             : 
     628       15944 :         i = shr( sub( window_length, window_half_length ), 1 ); /*Q0*/
     629       15944 :         n = shr( window_half_length, 1 );                       /*Q0*/
     630     1028888 :         FOR( w = 0; w < n; w++ )
     631             :         {
     632     1012944 :             signal[i] = mult_r( signal[i], window_half[w].v.re ); /*Qx*/
     633     1012944 :             move16();
     634     1012944 :             i = add( i, 1 );
     635             :         }
     636     1028888 :         FOR( w = 0; w < n; w++ )
     637             :         {
     638     1012944 :             signal[i] = mult_r( signal[i], window_half[window_half_length / 2 - 1 - w].v.im ); /*Qx*/
     639     1012944 :             move16();
     640     1012944 :             i = add( i, 1 );
     641             :         }
     642     1366536 :         FOR( ; i < window_length; i++ )
     643             :         {
     644     1350592 :             move16();
     645     1350592 :             signal[i] = 0;
     646             :         }
     647             :     }
     648             :     ELSE /* normal full/maximum overlap */
     649             :     {
     650             : 
     651       38718 :         n = shr( window_length, 1 ); /*Q0*/
     652     5513656 :         FOR( i = 0; i < n; i++ )
     653             :         {
     654     5474938 :             move16();
     655     5474938 :             signal[i] = mult_r( signal[i], window[i].v.re ); /*Qx*/
     656     5474938 :             move16();
     657     5474938 :             signal[window_length - 1 - i] = mult_r( signal[window_length - 1 - i], window[i].v.im ); /*Qx*/
     658             :         }
     659             :     }
     660      117108 : }
     661             : /*-------------------------------------------------------------------*
     662             :  * lpc2mdct()
     663             :  *
     664             :  *
     665             :  *-------------------------------------------------------------------*/
     666             : 
     667         646 : void lpc2mdct(
     668             :     Word16 *lpcCoeffs,     /*Q12*/
     669             :     const Word16 lpcOrder, /*Q0*/
     670             :     Word16 *mdct_gains,    /*Q15 - mdct_gains_exp*/
     671             :     Word16 *mdct_gains_exp,
     672             :     Word16 *mdct_inv_gains, /*Q15 - mdct_inv_gains_exp*/
     673             :     Word16 *mdct_inv_gains_exp,
     674             :     const Word16 length, /*Q0*/
     675             :     const Word16 noInverse /*Q0*/ )
     676             : {
     677             :     Word32 ComplexData[2 * FDNS_NPTS];
     678             :     Word16 i, j, k, sizeN, step, scale, s, tmp16;
     679             :     Word16 g, g_e, ig, ig_e;
     680             :     Word32 tmp32;
     681             :     const PWord16 *ptwiddle;
     682             :     Word32 workBuffer[2 * BASOP_CFFT_MAX_LENGTH];
     683             : 
     684             : #ifndef IVAS_CODE_TCX_UTIL
     685             :     (void) noInverse;
     686             : #endif
     687             : 
     688         646 :     assert( length <= FDNS_NPTS );
     689         646 :     sizeN = shl( length, 1 ); /*Q0*/
     690             : 
     691         646 :     BASOP_getTables( NULL, &ptwiddle, &step, sizeN );
     692             :     /*ODFT*/
     693         646 :     assert( lpcOrder < FDNS_NPTS );
     694             :     /* pre-twiddle */
     695       11628 :     FOR( i = 0; i <= lpcOrder; i++ )
     696             :     {
     697       10982 :         ComplexData[2 * i] = L_mult( lpcCoeffs[i], ptwiddle->v.re ); /*Q12*/
     698       10982 :         move32();
     699       10982 :         ComplexData[2 * i + 1] = L_negate( L_mult( lpcCoeffs[i], ptwiddle->v.im ) ); /*Q12*/
     700       10982 :         move32();
     701       10982 :         ptwiddle += step;
     702             :     }
     703             :     /* zero padding */
     704       31008 :     FOR( ; i < FDNS_NPTS; i++ )
     705             :     {
     706       30362 :         ComplexData[2 * i] = L_deposit_l( 0 );
     707       30362 :         move32();
     708       30362 :         ComplexData[2 * i + 1] = L_deposit_l( 0 );
     709       30362 :         move32();
     710             :     }
     711             : 
     712         646 :     move16();
     713             : #ifdef IVAS_CODE_TCX_UTIL
     714             :     if ( noInverse )
     715             :     {
     716             :         /* half length FFT */
     717             :         scale = add( norm_s( lpcCoeffs[0] ), 1 );
     718             :         BASOP_cfft( (cmplx *) ComplexData, FDNS_NPTS, &scale, workBuffer ); // tbv -> In float the fft type changes as well
     719             :         /*Get amplitude*/
     720             :         j = sub( length, 1 );
     721             :         k = 0;
     722             :         for ( i = 0; i < length; i++ )
     723             :         {
     724             :             mdct_gains[i] = (float) ( sqrt( RealData[i] * RealData[i] + ImagData[i] * ImagData[i] ) );
     725             :         }
     726             :     }
     727             :     else
     728             : #endif
     729             :     {
     730             :         /* half length FFT */
     731         646 :         scale = add( norm_s( lpcCoeffs[0] ), 1 );
     732         646 :         BASOP_cfft( (cmplx *) ComplexData, FDNS_NPTS, &scale, workBuffer ); /*Q31 - scale*/
     733             :         /*Get amplitude*/
     734         646 :         j = sub( length, 1 );
     735         646 :         k = 0;
     736       21318 :         FOR( i = 0; i < length / 2; i++ )
     737             :         {
     738       20672 :             s = sub( norm_l( L_max( L_abs( ComplexData[2 * i] ), L_abs( ComplexData[2 * i + 1] ) ) ), 1 );
     739       20672 :             tmp16 = extract_h( L_shl( ComplexData[2 * i], s ) );     /*Q15 - scale + s*/
     740       20672 :             tmp32 = L_mult( tmp16, tmp16 );                          /*Q15 - 2*(scale - s)*/
     741       20672 :             tmp16 = extract_h( L_shl( ComplexData[2 * i + 1], s ) ); /*Q15 - scale + s*/
     742       20672 :             tmp16 = mac_r( tmp32, tmp16, tmp16 );                    /*Q15 - 2*(scale - s)*/
     743       20672 :             s = shl( sub( scale, s ), 1 );
     744       20672 :             if ( tmp16 == 0 )
     745             :             {
     746           0 :                 s = -16;
     747           0 :                 move16();
     748             :             }
     749       20672 :             if ( tmp16 == 0 )
     750             :             {
     751           0 :                 tmp16 = 1;
     752           0 :                 move16();
     753             :             }
     754       20672 :             BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e ); /*Q15 - ig_e*/
     755       20672 :             if ( mdct_gains != 0 )
     756             :             {
     757           0 :                 mdct_gains[k] = g; /*Q15 - g_e*/
     758           0 :                 move16();
     759             :             }
     760       20672 :             if ( mdct_gains_exp != 0 )
     761             :             {
     762           0 :                 mdct_gains_exp[k] = g_e;
     763           0 :                 move16();
     764             :             }
     765       20672 :             if ( mdct_inv_gains != 0 )
     766             :             {
     767       20672 :                 mdct_inv_gains[k] = ig; /*Q15 - ig_e*/
     768       20672 :                 move16();
     769             :             }
     770       20672 :             if ( mdct_inv_gains_exp != 0 )
     771             :             {
     772       20672 :                 mdct_inv_gains_exp[k] = ig_e;
     773       20672 :                 move16();
     774             :             }
     775       20672 :             k = add( k, 1 );
     776       20672 :             s = sub( norm_l( L_max( L_abs( ComplexData[2 * j] ), L_abs( ComplexData[2 * j + 1] ) ) ), 1 );
     777       20672 :             tmp16 = extract_h( L_shl( ComplexData[2 * j], s ) );     /*Q15 - scale + s*/
     778       20672 :             tmp32 = L_mult( tmp16, tmp16 );                          /*Q15 - 2*(scale - s)*/
     779       20672 :             tmp16 = extract_h( L_shl( ComplexData[2 * j + 1], s ) ); /*Q15 - scale + s*/
     780       20672 :             tmp16 = mac_r( tmp32, tmp16, tmp16 );                    /*Q15 - 2*(scale - s)*/
     781       20672 :             s = shl( sub( scale, s ), 1 );
     782       20672 :             if ( tmp16 == 0 )
     783             :             {
     784           0 :                 s = -16;
     785           0 :                 move16();
     786             :             }
     787       20672 :             if ( tmp16 == 0 )
     788             :             {
     789           0 :                 tmp16 = 1;
     790           0 :                 move16();
     791             :             }
     792       20672 :             BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     793       20672 :             if ( mdct_gains != 0 )
     794             :             {
     795           0 :                 mdct_gains[k] = g; /*Q15 - g_e*/
     796           0 :                 move16();
     797             :             }
     798       20672 :             if ( mdct_gains_exp != 0 )
     799             :             {
     800           0 :                 mdct_gains_exp[k] = g_e;
     801           0 :                 move16();
     802             :             }
     803       20672 :             if ( mdct_inv_gains != 0 )
     804             :             {
     805       20672 :                 mdct_inv_gains[k] = ig; /*Q15 - ig_e*/
     806       20672 :                 move16();
     807             :             }
     808       20672 :             if ( mdct_inv_gains_exp != 0 )
     809             :             {
     810       20672 :                 mdct_inv_gains_exp[k] = ig_e;
     811       20672 :                 move16();
     812             :             }
     813       20672 :             j = sub( j, 1 );
     814       20672 :             k = add( k, 1 );
     815             :         }
     816             :     }
     817         646 : }
     818             : 
     819      220416 : void lpc2mdct_2(
     820             :     Word16 *lpcCoeffs,      /*Q12*/
     821             :     const Word16 lpcOrder,  /*Q0*/
     822             :     Word16 mdct_gains_fx[], /*Q15 - mdct_gains_e*/
     823             :     Word16 mdct_gains_e[],
     824             :     Word16 mdct_inv_gains_fx[], /*Q15 - mdct_inv_gains_e*/
     825             :     Word16 mdct_inv_gains_e[],
     826             :     const Word16 length /*Q0*/ )
     827             : {
     828             :     Word16 i, sizeN, j, k, step, scale, s, tmp16;
     829             :     Word16 g, g_e, ig, ig_e;
     830             :     Word32 tmp32;
     831             :     Word32 RealData_fx[2 * FDNS_NPTS], ImagData_fx[2 * FDNS_NPTS];
     832             :     const PWord16 *ptwiddle;
     833             : 
     834      220416 :     assert( length <= FDNS_NPTS );
     835      220416 :     sizeN = shl( length, 1 ); /*Q0*/
     836             : 
     837      220416 :     BASOP_getTables( NULL, &ptwiddle, &step, sizeN );
     838             : 
     839             :     /* ODFT */
     840     3967488 :     FOR( i = 0; i < lpcOrder + 1; i++ )
     841             :     {
     842     3747072 :         RealData_fx[i] = L_mult( lpcCoeffs[i], ptwiddle->v.re ); /*Q12*/
     843     3747072 :         move32();
     844     3747072 :         ImagData_fx[i] = L_negate( L_mult( lpcCoeffs[i], ptwiddle->v.im ) ); /*Q12*/
     845     3747072 :         move32();
     846     3747072 :         ptwiddle += step;
     847             :     }
     848             : 
     849    24686592 :     FOR( ; i < sizeN; i++ )
     850             :     {
     851    24466176 :         RealData_fx[i] = L_deposit_l( 0 );
     852    24466176 :         move32();
     853    24466176 :         ImagData_fx[i] = L_deposit_l( 0 );
     854    24466176 :         move32();
     855             :     }
     856             : 
     857             :     /* half length FFT */
     858      220416 :     scale = add( norm_s( lpcCoeffs[0] ), 1 );
     859      220416 :     BASOP_cfft_ivas( RealData_fx, ImagData_fx, 1, &scale ); /*Q31 - scale*/
     860             : 
     861             :     /*Get amplitude*/
     862      220416 :     j = sub( FDNS_NPTS, 1 );
     863      220416 :     move16();
     864      220416 :     k = 0;
     865      220416 :     move16();
     866             : 
     867     7273728 :     FOR( i = 0; i < FDNS_NPTS / 2; i++ )
     868             :     {
     869     7053312 :         s = sub( norm_l( L_max( L_abs( RealData_fx[i] ), L_abs( ImagData_fx[i] ) ) ), 1 );
     870             : 
     871     7053312 :         tmp16 = extract_h( L_shl( RealData_fx[i], s ) ); /*Q15 - scale + s*/
     872     7053312 :         tmp32 = L_mult( tmp16, tmp16 );                  /*Q15 - 2*(scale - s)*/
     873             : 
     874     7053312 :         tmp16 = extract_h( L_shl( ImagData_fx[i], s ) ); /*Q15 - scale + s*/
     875     7053312 :         tmp16 = mac_r( tmp32, tmp16, tmp16 );            /*Q15 - 2*(scale - s)*/
     876             : 
     877     7053312 :         s = shl( sub( scale, s ), 1 );
     878             : 
     879     7053312 :         if ( tmp16 == 0 )
     880             :         {
     881           0 :             s = -16;
     882           0 :             move16();
     883             :         }
     884     7053312 :         if ( tmp16 == 0 )
     885             :         {
     886           0 :             tmp16 = 1;
     887           0 :             move16();
     888             :         }
     889             : 
     890     7053312 :         BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     891             : 
     892     7053312 :         if ( mdct_gains_fx != NULL )
     893             :         {
     894           0 :             mdct_gains_fx[k] = g; /*Q15 - g_e*/
     895           0 :             move16();
     896             :         }
     897             : 
     898     7053312 :         if ( mdct_gains_e != NULL )
     899             :         {
     900           0 :             mdct_gains_e[k] = g_e;
     901           0 :             move16();
     902             :         }
     903             : 
     904     7053312 :         if ( mdct_inv_gains_fx != NULL )
     905             :         {
     906     7053312 :             mdct_inv_gains_fx[k] = ig; /*Q15 - ig_e*/
     907     7053312 :             move16();
     908             :         }
     909             : 
     910     7053312 :         if ( mdct_inv_gains_e != NULL )
     911             :         {
     912     7053312 :             mdct_inv_gains_e[k] = ig_e;
     913     7053312 :             move16();
     914             :         }
     915             : 
     916     7053312 :         k = add( k, 1 );
     917             : 
     918             : 
     919     7053312 :         s = sub( norm_l( L_max( L_abs( RealData_fx[j] ), L_abs( ImagData_fx[j] ) ) ), 1 );
     920             : 
     921     7053312 :         tmp16 = extract_h( L_shl( RealData_fx[j], s ) ); /*Q15 - scale + s*/
     922     7053312 :         tmp32 = L_mult( tmp16, tmp16 );                  /*Q15 - 2*(scale - s)*/
     923             : 
     924     7053312 :         tmp16 = extract_h( L_shl( ImagData_fx[j], s ) ); /*Q15 - scale + s*/
     925     7053312 :         tmp16 = mac_r( tmp32, tmp16, tmp16 );            /*Q15 - 2*(scale - s)*/
     926             : 
     927     7053312 :         s = shl( sub( scale, s ), 1 );
     928             : 
     929     7053312 :         if ( tmp16 == 0 )
     930             :         {
     931           0 :             s = -16;
     932           0 :             move16();
     933             :         }
     934     7053312 :         if ( tmp16 == 0 )
     935             :         {
     936           0 :             tmp16 = 1;
     937           0 :             move16();
     938             :         }
     939             : 
     940     7053312 :         BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     941             : 
     942     7053312 :         if ( mdct_gains_fx != NULL )
     943             :         {
     944           0 :             mdct_gains_fx[k] = g;
     945           0 :             move16();
     946             :         }
     947             : 
     948     7053312 :         if ( mdct_gains_e != NULL )
     949             :         {
     950           0 :             mdct_gains_e[k] = g_e;
     951           0 :             move16();
     952             :         }
     953             : 
     954     7053312 :         if ( mdct_inv_gains_fx != NULL )
     955             :         {
     956     7053312 :             mdct_inv_gains_fx[k] = ig;
     957     7053312 :             move16();
     958             :         }
     959             : 
     960     7053312 :         if ( mdct_inv_gains_e != NULL )
     961             :         {
     962     7053312 :             mdct_inv_gains_e[k] = ig_e;
     963     7053312 :             move16();
     964             :         }
     965             : 
     966     7053312 :         j = sub( j, 1 );
     967     7053312 :         k = add( k, 1 );
     968             :     }
     969             : 
     970      220416 :     return;
     971             : }
     972             : /**
     973             :  * \brief Perform mdct shaping. In the floating point software there are two functions,
     974             :  *        mdct_noiseShaping and mdct_preShaping, which are combined here into a single function.
     975             :  * \param x spectrum mantissas
     976             :  * \param lg spectrum length
     977             :  * \param gains shaping gains mantissas
     978             :  * \param gains_exp shaping gains exponents
     979             :  */
     980         872 : void mdct_shaping(
     981             :     Word32 x[],           /*Qx*/
     982             :     const Word16 lg,      /*Q0*/
     983             :     const Word16 gains[], /*Q15 - gains_exp*/
     984             :     const Word16 gains_exp[]
     985             :     /*const Word16 nBands*/ /*Parameter added in IVAS, but always equal to FDNS_NPTS */
     986             : )
     987             : {
     988             : 
     989             :     Word16 i, k, l;
     990             :     Word16 m, n, k1, k2, j;
     991         872 :     Word32 *px = x; /*Qx*/
     992         872 :     Word16 const *pgains = gains;
     993         872 :     Word16 const *pgainsexp = gains_exp;
     994             : #ifndef ISSUE_1836_replace_overflow_libcom
     995             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     996             :     Flag Overflow = 0;
     997             : #endif
     998             : #endif
     999             : 
    1000             :     /* FDNS_NPTS = 64 */
    1001         872 :     k = shr( lg, 6 ); /*Q0*/
    1002         872 :     m = s_and( lg, 0x3F );
    1003             : 
    1004         872 :     IF( m != 0 )
    1005             :     {
    1006          22 :         IF( LE_16( m, FDNS_NPTS / 2 ) )
    1007             :         {
    1008          22 :             n = idiv1616U( FDNS_NPTS, m ); /*Q0*/
    1009          22 :             k1 = k;
    1010          22 :             move16();
    1011          22 :             k2 = add( k, 1 );
    1012             :         }
    1013             :         ELSE
    1014             :         {
    1015           0 :             n = idiv1616U( FDNS_NPTS, sub( FDNS_NPTS, m ) ); /*Q0*/
    1016           0 :             k1 = add( k, 1 );
    1017           0 :             k2 = k;
    1018           0 :             move16();
    1019             :         }
    1020             : 
    1021          22 :         i = 0;
    1022          22 :         move16();
    1023          22 :         j = 0;
    1024          22 :         move16();
    1025             : 
    1026        1430 :         WHILE( LT_16( i, lg ) )
    1027             :         {
    1028             : 
    1029        1408 :             k = k2;
    1030        1408 :             move16();
    1031        1408 :             if ( j != 0 )
    1032             :             {
    1033        1056 :                 k = k1;
    1034        1056 :                 move16();
    1035             :             }
    1036             : 
    1037        1408 :             j = add( j, 1 );
    1038        1408 :             if ( EQ_16( j, n ) )
    1039             :             {
    1040         352 :                 j = 0;
    1041         352 :                 move16();
    1042             :             }
    1043             : 
    1044             :             /* Limit number of loops, if end is reached */
    1045        1408 :             k = s_min( k, sub( lg, i ) );
    1046             : 
    1047       10208 :             FOR( l = 0; l < k; l++ )
    1048             :             {
    1049             : #ifdef ISSUE_1836_replace_overflow_libcom
    1050        8800 :                 *x = L_shl_sat( Mpy_32_16_r( *x, *gains ), *gains_exp ); /*Qx*/
    1051             : #else
    1052             :                 *x = L_shl_o( Mpy_32_16_r( *x, *gains ), *gains_exp, &Overflow );         /*Qx*/
    1053             : #endif
    1054        8800 :                 move32();
    1055        8800 :                 x++;
    1056             :             }
    1057        1408 :             i = add( i, k );
    1058             : 
    1059        1408 :             gains++;
    1060        1408 :             gains_exp++;
    1061             :         }
    1062             :     }
    1063             :     ELSE
    1064             :     {
    1065        5035 :         FOR( l = 0; l < k; l++ )
    1066             :         {
    1067        4185 :             x = &px[l]; /*Qx*/
    1068        4185 :             gains = pgains;
    1069        4185 :             gains_exp = pgainsexp;
    1070      272025 :             FOR( i = 0; i < FDNS_NPTS; i++ )
    1071             :             {
    1072             : #ifdef ISSUE_1836_replace_overflow_libcom
    1073      267840 :                 *x = L_shl_sat( Mpy_32_16_r( *x, *gains ), *gains_exp ); /*Qx*/
    1074             : #else
    1075             :                 *x = L_shl_o( Mpy_32_16_r( *x, *gains ), *gains_exp, &Overflow );         /*Qx*/
    1076             : #endif
    1077      267840 :                 move32();
    1078      267840 :                 x += k;
    1079      267840 :                 gains++;
    1080      267840 :                 gains_exp++;
    1081             :             }
    1082             :         }
    1083             :     }
    1084         872 : }
    1085             : 
    1086         706 : void mdct_shaping_16(
    1087             :     const Word16 x[],      /*Qx*/
    1088             :     const Word16 lg,       /*Q0*/
    1089             :     const Word16 lg_total, /*Q0*/
    1090             :     const Word16 gains[],  /*15 - gains_exp*/
    1091             :     const Word16 gains_exp[],
    1092             :     Word16 gains_max_exp,
    1093             :     Word32 y[] /*Qx*/ )
    1094             : {
    1095             :     Word16 i, k, l;
    1096             :     Word16 m, gain_exp;
    1097             :     Word16 const *px;
    1098             :     Word32 *py;
    1099         706 :     Word16 const *pgains = gains;
    1100             :     Word16 gains_exp_loc[FDNS_NPTS];
    1101             :     Word16 const *pgains_exp;
    1102             : 
    1103             :     /* FDNS_NPTS = 64 */
    1104         706 :     k = shr( lg, 6 ); /*Q0*/
    1105         706 :     m = s_and( lg, 0x3F );
    1106             : 
    1107         706 :     assert( m == 0 );
    1108             :     {
    1109       45890 :         FOR( i = 0; i < FDNS_NPTS; i++ )
    1110             :         {
    1111       45184 :             gains_exp_loc[i] = sub( gains_exp[i], gains_max_exp );
    1112       45184 :             move16();
    1113             :         }
    1114        5104 :         FOR( l = 0; l < k; l++ )
    1115             :         {
    1116        4398 :             px = &x[l];     /*Qx*/
    1117        4398 :             py = &y[l];     /*Qx*/
    1118        4398 :             pgains = gains; /*15 - gains_exp*/
    1119        4398 :             pgains_exp = gains_exp_loc;
    1120      285870 :             FOR( i = 0; i < FDNS_NPTS; i++ )
    1121             :             {
    1122      281472 :                 *py = L_shl( L_mult( *px, *pgains ), *pgains_exp ); /*Qx*/
    1123      281472 :                 move32();
    1124      281472 :                 px += k;
    1125      281472 :                 py += k;
    1126      281472 :                 pgains++;
    1127      281472 :                 pgains_exp++;
    1128             :             }
    1129             :         }
    1130             :     }
    1131             : 
    1132         706 :     gain_exp = sub( gains_exp[FDNS_NPTS - 1], gains_max_exp );
    1133       19275 :     FOR( i = lg; i < lg_total; i++ )
    1134             :     {
    1135       18569 :         y[i] = L_shl( L_mult( x[i], gains[FDNS_NPTS - 1] ), gain_exp ); /*Qx*/
    1136       18569 :         move32();
    1137             :     }
    1138         706 : }
    1139             : 
    1140      220608 : void mdct_noiseShaping_ivas_fx(
    1141             :     Word32 x_fx[], /*Q31 - x_e*/
    1142             :     Word16 *x_e,
    1143             :     const Word16 lg,         /*Q0*/
    1144             :     const Word16 gains_fx[], /*Q15 - gains_exp*/
    1145             :     const Word16 gains_exp[]
    1146             :     /*const Word16 nBands*/ /*Parameter added in IVAS, but always equal to FDNS_NPTS */
    1147             : )
    1148             : {
    1149             :     Word16 i, j, k, l;
    1150             :     Word16 m, n, k1, k2;
    1151             : 
    1152      220608 :     j = 0;
    1153      220608 :     move16();
    1154             :     /* FDNS_NPTS = 64 */
    1155      220608 :     k = shr( lg, 6 ); /*Q0*/
    1156      220608 :     m = s_and( lg, 0x3F );
    1157             : 
    1158      220608 :     Word16 max_e = MIN16B;
    1159      220608 :     move16();
    1160    14339520 :     FOR( i = 0; i < FDNS_NPTS; i++ )
    1161             :     {
    1162    14118912 :         max_e = s_max( max_e, add( *x_e, gains_exp[i] ) );
    1163             :     }
    1164             : 
    1165      220608 :     IF( m != 0 )
    1166             :     {
    1167        4101 :         IF( LE_16( m, FDNS_NPTS / 2 ) )
    1168             :         {
    1169        4101 :             n = idiv1616U( FDNS_NPTS, m ); /*Q0*/
    1170        4101 :             k1 = k;
    1171        4101 :             move16();
    1172        4101 :             k2 = add( k, 1 );
    1173             :         }
    1174             :         ELSE
    1175             :         {
    1176           0 :             n = idiv1616U( FDNS_NPTS, sub( FDNS_NPTS, m ) ); /*Q0*/
    1177           0 :             k1 = add( k, 1 );
    1178           0 :             k2 = k;
    1179           0 :             move16();
    1180             :         }
    1181             : 
    1182        4101 :         i = 0;
    1183        4101 :         move16();
    1184        4101 :         j = 0;
    1185        4101 :         move16();
    1186             : 
    1187      266565 :         WHILE( LT_16( i, lg ) )
    1188             :         {
    1189      262464 :             IF( j % n != 0 )
    1190             :             {
    1191      192880 :                 k = k1;
    1192      192880 :                 move16();
    1193             :             }
    1194             :             ELSE
    1195             :             {
    1196       69584 :                 k = k2;
    1197       69584 :                 move16();
    1198             :             }
    1199             : 
    1200             :             /* Limit number of loops, if end is reached */
    1201      262464 :             k = s_min( k, sub( lg, i ) );
    1202             : 
    1203     1984144 :             FOR( l = 0; l < k; l++ )
    1204             :             {
    1205     1721680 :                 x_fx[i] = Mpy_32_16_1( x_fx[i], gains_fx[j] ); /*Q31 - x_e*/
    1206     1721680 :                 move32();
    1207     1721680 :                 x_fx[i] = L_shr( x_fx[i], sub( max_e, add( *x_e, gains_exp[j] ) ) ); /*Q31 - max_e*/
    1208     1721680 :                 move32();
    1209     1721680 :                 i = add( i, 1 );
    1210             :             }
    1211      262464 :             j = add( j, 1 );
    1212             :         }
    1213             :     }
    1214             :     ELSE
    1215             :     {
    1216    14072955 :         FOR( i = 0; i < lg; )
    1217             :         {
    1218   111296448 :             FOR( l = 0; l < k; l++ )
    1219             :             {
    1220    97440000 :                 x_fx[i] = Mpy_32_16_1( x_fx[i], gains_fx[j] ); /*Q31 - x_e*/
    1221    97440000 :                 move32();
    1222    97440000 :                 x_fx[i] = L_shr( x_fx[i], sub( max_e, add( *x_e, gains_exp[j] ) ) ); /*Q31 - max_e*/
    1223    97440000 :                 move32();
    1224    97440000 :                 i = add( i, 1 );
    1225             :             }
    1226    13856448 :             j = add( j, 1 );
    1227             :         }
    1228             :     }
    1229             : 
    1230      220608 :     *x_e = max_e;
    1231      220608 :     move16();
    1232             : 
    1233      220608 :     return;
    1234             : }
    1235             : 
    1236             : 
    1237           0 : void mdct_noiseShaping_interp(
    1238             :     Word32 x[],      /*Qx*/
    1239             :     const Word16 lg, /*Q0*/
    1240             :     Word16 gains[],  /*Q15 - gains_exp*/
    1241             :     Word16 gains_exp[] )
    1242             : {
    1243             :     Word16 i, j, jp, jn, k, l;
    1244             :     Word16 g, pg, ng, e, tmp;
    1245             : 
    1246             : 
    1247           0 :     assert( lg % FDNS_NPTS == 0 );
    1248           0 :     k = shr( lg, 6 ); /* FDNS_NPTS = 64 Q0*/
    1249             : 
    1250           0 :     IF( gains )
    1251             :     {
    1252             :         /* Linear interpolation */
    1253           0 :         IF( EQ_16( k, 4 ) )
    1254             :         {
    1255           0 :             jp = 0;
    1256           0 :             move16();
    1257           0 :             j = 0;
    1258           0 :             move16();
    1259           0 :             jn = 1;
    1260           0 :             move16();
    1261             : 
    1262           0 :             FOR( i = 0; i < lg; i += 4 )
    1263             :             {
    1264           0 :                 pg = gains[jp]; /*Q15 - gains_exp*/
    1265           0 :                 move16();
    1266           0 :                 g = gains[j]; /*Q15 - gains_exp*/
    1267           0 :                 move16();
    1268           0 :                 ng = gains[jn]; /*Q15 - gains_exp*/
    1269           0 :                 move16();
    1270             : 
    1271             :                 /* common exponent for pg and g */
    1272           0 :                 tmp = sub( gains_exp[j], gains_exp[jp] );
    1273           0 :                 if ( tmp > 0 )
    1274           0 :                     pg = shr( pg, tmp );
    1275           0 :                 if ( tmp < 0 )
    1276           0 :                     g = shl( g, tmp );
    1277           0 :                 e = s_max( gains_exp[j], gains_exp[jp] );
    1278             : 
    1279           0 :                 tmp = mac_r( L_mult( pg, 12288 /*0.375f Q15*/ ), g, 20480 /*0.625f Q15*/ ); /*Q15 - gains_exp*/
    1280           0 :                 x[i] = L_shl( Mpy_32_16_1( x[i], tmp ), e );                                /*Qx*/
    1281           0 :                 move32();
    1282             : 
    1283           0 :                 tmp = mac_r( L_mult( pg, 4096 /*0.125f Q15*/ ), g, 28672 /*0.875f Q15*/ ); /*Q15 - gains_exp*/
    1284           0 :                 x[i + 1] = L_shl( Mpy_32_16_1( x[i + 1], tmp ), e );                       /*Qx*/
    1285           0 :                 move32();
    1286             : 
    1287             :                 /* common exponent for g and ng */
    1288           0 :                 g = gains[j]; /*Q15 - gains_exp*/
    1289           0 :                 move16();
    1290           0 :                 tmp = sub( gains_exp[j], gains_exp[jn] );
    1291           0 :                 if ( tmp > 0 )
    1292           0 :                     ng = shr( ng, tmp );
    1293           0 :                 if ( tmp < 0 )
    1294           0 :                     g = shl( g, tmp );
    1295           0 :                 e = s_max( gains_exp[j], gains_exp[jn] );
    1296             : 
    1297           0 :                 tmp = mac_r( L_mult( g, 28672 /*0.875f Q15*/ ), ng, 4096 /*0.125f Q15*/ ); /*Q15 - gains_exp*/
    1298           0 :                 x[i + 2] = L_shl( Mpy_32_16_1( x[i + 2], tmp ), e );                       /*Qx*/
    1299           0 :                 move32();
    1300             : 
    1301           0 :                 tmp = mac_r( L_mult( g, 20480 /*0.625f Q15*/ ), ng, 12288 /*0.375f Q15*/ ); /*Q15 - gains_exp*/
    1302           0 :                 x[i + 3] = L_shl( Mpy_32_16_1( x[i + 3], tmp ), e );                        /*Qx*/
    1303           0 :                 move32();
    1304             : 
    1305           0 :                 jp = j;
    1306           0 :                 move16();
    1307           0 :                 j = jn;
    1308           0 :                 move16();
    1309           0 :                 jn = s_min( add( jn, 1 ), FDNS_NPTS - 1 );
    1310             :             }
    1311             :         }
    1312           0 :         ELSE IF( EQ_16( k, 5 ) )
    1313             :         {
    1314           0 :             jp = 0;
    1315           0 :             move16();
    1316           0 :             j = 0;
    1317           0 :             move16();
    1318           0 :             jn = 1;
    1319           0 :             move16();
    1320             : 
    1321           0 :             FOR( i = 0; i < lg; i += 5 )
    1322             :             {
    1323           0 :                 pg = gains[jp]; /*Q15 - gains_exp*/
    1324           0 :                 move16();
    1325           0 :                 g = gains[j]; /*Q15 - gains_exp*/
    1326           0 :                 move16();
    1327           0 :                 ng = gains[jn]; /*Q15 - gains_exp*/
    1328           0 :                 move16();
    1329             : 
    1330             :                 /* common exponent for pg and g */
    1331           0 :                 tmp = sub( gains_exp[j], gains_exp[jp] );
    1332           0 :                 if ( tmp > 0 )
    1333           0 :                     pg = shr( pg, tmp );
    1334           0 :                 if ( tmp < 0 )
    1335           0 :                     g = shl( g, tmp );
    1336           0 :                 e = s_max( gains_exp[j], gains_exp[jp] );
    1337             : 
    1338           0 :                 tmp = mac_r( L_mult( pg, 13107 /*0.40f Q15*/ ), g, 19661 /*0.60f Q15*/ ); /*Q15 - gains_exp*/
    1339           0 :                 x[i] = L_shl( Mpy_32_16_1( x[i], tmp ), e );                              /*Qx*/
    1340           0 :                 move32();
    1341             : 
    1342           0 :                 tmp = mac_r( L_mult( pg, 6554 /*0.20f Q15*/ ), g, 26214 /*0.80f Q15*/ ); /*Q15 - gains_exp*/
    1343           0 :                 x[i + 1] = L_shl( Mpy_32_16_1( x[i + 1], tmp ), e );                     /*Qx*/
    1344           0 :                 move32();
    1345             : 
    1346             : 
    1347           0 :                 x[i + 2] = L_shl( Mpy_32_16_1( x[i + 2], gains[j] ), gains_exp[j] ); /*Qx*/
    1348           0 :                 move32();
    1349             : 
    1350             :                 /* common exponent for g and ng */
    1351           0 :                 g = gains[j]; /*Q15 - gains_exp*/
    1352           0 :                 move16();
    1353           0 :                 tmp = sub( gains_exp[j], gains_exp[jn] );
    1354           0 :                 if ( tmp > 0 )
    1355           0 :                     ng = shr( ng, tmp );
    1356           0 :                 if ( tmp < 0 )
    1357           0 :                     g = shl( g, tmp );
    1358           0 :                 e = s_max( gains_exp[j], gains_exp[jn] );
    1359             : 
    1360           0 :                 tmp = mac_r( L_mult( g, 26214 /*0.80f Q15*/ ), ng, 6554 /*0.20f Q15*/ ); /*Q15 - gains_exp*/
    1361           0 :                 x[i + 3] = L_shl( Mpy_32_16_1( x[i + 3], tmp ), e );                     /*Qx*/
    1362           0 :                 move32();
    1363             : 
    1364           0 :                 tmp = mac_r( L_mult( g, 19661 /*0.60f Q15*/ ), ng, 13107 /*0.40f Q15*/ ); /*Q15 - gains_exp*/
    1365           0 :                 x[i + 4] = L_shl( Mpy_32_16_1( x[i + 4], tmp ), e );                      /*Qx*/
    1366           0 :                 move32();
    1367             : 
    1368           0 :                 jp = j;
    1369           0 :                 move16();
    1370           0 :                 j = jn;
    1371           0 :                 move16();
    1372           0 :                 jn = s_min( add( jn, 1 ), FDNS_NPTS - 1 );
    1373             :             }
    1374             :         }
    1375             :         ELSE /* no interpolation */
    1376             :         {
    1377           0 :             FOR( i = 0; i < FDNS_NPTS; i++ )
    1378             :             {
    1379           0 :                 FOR( l = 0; l < k; l++ )
    1380             :                 {
    1381           0 :                     *x = L_shl( Mpy_32_16_1( *x, *gains ), *gains_exp ); /*Qx*/
    1382           0 :                     move32();
    1383           0 :                     x++;
    1384             :                 }
    1385             : 
    1386           0 :                 gains++;
    1387           0 :                 gains_exp++;
    1388             :             }
    1389             :         }
    1390             :     }
    1391           0 : }
    1392             : 
    1393       17699 : void PsychAdaptLowFreqDeemph(
    1394             :     Word32 x[],              /*Qx*/
    1395             :     const Word16 lpcGains[], /*Q15 - lpcGains_e*/
    1396             :     const Word16 lpcGains_e[],
    1397             :     Word16 lf_deemph_factors[] /*Q15*/ )
    1398             : {
    1399             :     Word16 i;
    1400             :     Word16 max_val, max_e, fac, min, min_e, tmp, tmp_e;
    1401             :     Word32 L_tmp;
    1402             : #ifndef ISSUE_1836_replace_overflow_libcom
    1403             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1404             :     Flag Overflow = 0;
    1405             : #endif
    1406             : #endif
    1407             : 
    1408             : 
    1409       17699 :     assert( lpcGains[0] >= 0x4000 );
    1410             : 
    1411       17699 :     max_val = lpcGains[0]; /*Q15 - lpcGains_e*/
    1412       17699 :     move16();
    1413       17699 :     max_e = lpcGains_e[0];
    1414       17699 :     move16();
    1415       17699 :     min = lpcGains[0]; /*Q15 - lpcGains_e*/
    1416       17699 :     move16();
    1417       17699 :     min_e = lpcGains_e[0];
    1418       17699 :     move16();
    1419             : 
    1420             :     /* find minimum (min) and maximum (max_val) of LPC gains in low frequencies */
    1421      159291 :     FOR( i = 1; i < 9; i++ )
    1422             :     {
    1423      141592 :         IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], min, min_e ) < 0 )
    1424             :         {
    1425      107113 :             min = lpcGains[i]; /*Q15 - lpcGains_e*/
    1426      107113 :             move16();
    1427      107113 :             min_e = lpcGains_e[i];
    1428      107113 :             move16();
    1429             :         }
    1430             : 
    1431      141592 :         IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], max_val, max_e ) > 0 )
    1432             :         {
    1433       23997 :             max_val = lpcGains[i]; /*Q15 - lpcGains_e*/
    1434       23997 :             move16();
    1435       23997 :             max_e = lpcGains_e[i];
    1436       23997 :             move16();
    1437             :         }
    1438             :     }
    1439             : 
    1440       17699 :     min_e = add( min_e, 5 ); /* min *= 32.0f; */
    1441             : 
    1442       17699 :     test();
    1443       17699 :     IF( ( compMantExp16Unorm( max_val, max_e, min, min_e ) < 0 ) && ( min > 0 ) )
    1444             :     {
    1445             :         /* fac = tmp = (float)pow(max_val / min, 0.0078125f); */
    1446       17699 :         tmp_e = min_e;
    1447       17699 :         move16();
    1448       17699 :         tmp = Inv16( min, &tmp_e );                                   /*Q15 - tmp_e*/
    1449       17699 :         L_tmp = L_shl( L_mult( tmp, max_val ), add( tmp_e, max_e ) ); /* Q31 */
    1450       17699 :         L_tmp = BASOP_Util_Log2( L_tmp );                             /* Q25 */
    1451       17699 :         L_tmp = L_shr( L_tmp, 7 );                                    /* 0.0078125f = 1.f/(1<<7) */
    1452       17699 :         L_tmp = BASOP_Util_InvLog2( L_tmp );                          /* Q31 */
    1453             : #ifdef ISSUE_1836_replace_overflow_libcom
    1454       17699 :         tmp = round_fx_sat( L_tmp ); /* Q15 */
    1455             : #else
    1456             :         tmp = round_fx_o( L_tmp, &Overflow );                                             /* Q15 */
    1457             : #endif
    1458       17699 :         fac = tmp; /* Q15 */
    1459       17699 :         move16();
    1460             : 
    1461             :         /* gradual lowering of lowest 32 bins; DC is lowered by (max_val/tmp)^1/4 */
    1462      584067 :         FOR( i = 31; i >= 0; i-- )
    1463             :         {
    1464      566368 :             x[i] = Mpy_32_16_1( x[i], fac );
    1465      566368 :             move32();
    1466      566368 :             if ( lf_deemph_factors != NULL )
    1467             :             {
    1468      448768 :                 lf_deemph_factors[i] = mult_r( lf_deemph_factors[i], fac );
    1469      448768 :                 move16();
    1470             :             }
    1471      566368 :             fac = mult_r( fac, tmp ); /* Q15 */
    1472             :         }
    1473             :     }
    1474       17699 : }
    1475             : 
    1476      115729 : void AdaptLowFreqDeemph(
    1477             :     Word32 x[], /*Q31 - x_e*/
    1478             :     Word16 x_e,
    1479             :     Word16 tcx_lpc_shaped_ari, /*Q0*/
    1480             :     Word16 lpcGains[],         /*Q15 - lpcGains_e*/
    1481             :     Word16 lpcGains_e[],
    1482             :     const Word16 lg, /*Q0*/
    1483             :     Word16 lf_deemph_factors[] /*Q15*/ )
    1484             : {
    1485             : 
    1486             :     Word16 i, i_max, i_max_old, lg_4;
    1487             :     Word32 v2, v4, tmp32;
    1488             : 
    1489      115729 :     tmp32 = 0; /* to avoid compilation warnings */
    1490      115729 :     move32();
    1491             : 
    1492      115729 :     IF( tcx_lpc_shaped_ari == 0 )
    1493             :     {
    1494      101705 :         v2 = L_shl( 2, sub( 31, x_e ) ); /* 2.0 */
    1495      101705 :         v4 = L_shl( v2, 1 );             /* 4.0 */
    1496      101705 :         lg_4 = shr( lg, 2 );             /* lg/4 */
    1497             : 
    1498             :         /* 1. find first magnitude maximum in lower quarter of spectrum */
    1499      101705 :         i_max = -1;
    1500      101705 :         move16();
    1501             : 
    1502      620943 :         FOR( i = 0; i < lg_4; i++ )
    1503             :         {
    1504      617223 :             IF( GE_32( L_abs( x[i] ), v4 ) )
    1505             :             {
    1506             : 
    1507             :                 /* Debug initialization to catch illegal x[i] values. */
    1508       97985 :                 tmp32 = 0;
    1509       97985 :                 move32();
    1510             : 
    1511       97985 :                 if ( x[i] < 0 )
    1512       49194 :                     tmp32 = L_add( x[i], v2 ); /*Q31 - x_e*/
    1513       97985 :                 if ( x[i] > 0 )
    1514       48791 :                     tmp32 = L_sub( x[i], v2 ); /*Q31 - x_e*/
    1515             : 
    1516       97985 :                 assert( tmp32 != 0 );
    1517             : 
    1518       97985 :                 x[i] = tmp32; /*Q31 - x_e*/
    1519       97985 :                 move32();
    1520       97985 :                 i_max = i;
    1521       97985 :                 move16();
    1522       97985 :                 BREAK;
    1523             :             }
    1524             :         }
    1525             : 
    1526             :         /* 2. expand value range of all xi up to i_max: two extra steps */
    1527      339947 :         FOR( i = 0; i < i_max; i++ )
    1528             :         {
    1529      238242 :             x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1530      238242 :             move32();
    1531      238242 :             lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1532      238242 :             move16();
    1533             :         }
    1534             : 
    1535             :         /* 3. find first magnitude maximum in lower quarter of spectrum */
    1536      101705 :         i_max_old = i_max; /*Q0*/
    1537      101705 :         move16();
    1538             : 
    1539      101705 :         IF( i_max_old >= 0 )
    1540             :         {
    1541       97985 :             i_max = -1;
    1542       97985 :             move16();
    1543             : 
    1544      494425 :             FOR( i = 0; i < lg_4; i++ )
    1545             :             {
    1546      494410 :                 IF( GE_32( L_abs( x[i] ), v4 ) )
    1547             :                 {
    1548       97970 :                     assert( x[i] != 0 );
    1549       97970 :                     if ( x[i] < 0 )
    1550       49234 :                         tmp32 = L_add( x[i], v2 ); /*Q31 - x_e*/
    1551       97970 :                     if ( x[i] >= 0 )
    1552       48736 :                         tmp32 = L_sub( x[i], v2 ); /*Q31 - x_e*/
    1553       97970 :                     x[i] = tmp32;                  /*Q31 - x_e*/
    1554       97970 :                     move32();
    1555       97970 :                     i_max = i;
    1556       97970 :                     move16();
    1557       97970 :                     BREAK;
    1558             :                 }
    1559             :             }
    1560             :         }
    1561             : 
    1562             :         /* 4. expand value range of all xi up to i_max: two extra steps */
    1563      497009 :         FOR( i = 0; i < i_max; i++ )
    1564             :         {
    1565      395304 :             x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1566      395304 :             move32();
    1567      395304 :             lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1568      395304 :             move16();
    1569             :         }
    1570             : 
    1571             :         /* 5. always expand two lines; lines could be at index 0 and 1! */
    1572      101705 :         i_max = s_max( i_max, i_max_old ); /*Q0*/
    1573      101705 :         i = add( i_max, 1 );
    1574             : 
    1575      101705 :         IF( x[i] < 0 )
    1576             :         {
    1577       44957 :             tmp32 = L_sub( x[i], L_negate( v4 ) );
    1578             : 
    1579       44957 :             if ( tmp32 > 0 )
    1580             :             {
    1581       15794 :                 lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1582       15794 :                 move16();
    1583             :             }
    1584       44957 :             if ( tmp32 <= 0 )
    1585             :             {
    1586       29163 :                 x[i] = L_add( x[i], v2 ); /*Q31 - x_e*/
    1587       29163 :                 move32();
    1588             :             }
    1589       44957 :             if ( tmp32 > 0 )
    1590             :             {
    1591       15794 :                 x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1592       15794 :                 move32();
    1593             :             }
    1594             :         }
    1595             :         ELSE
    1596             :         {
    1597       56748 :             tmp32 = L_sub( x[i], v4 );
    1598             : 
    1599       56748 :             if ( tmp32 < 0 )
    1600             :             {
    1601       26512 :                 lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1602       26512 :                 move16();
    1603             :             }
    1604       56748 :             if ( tmp32 >= 0 )
    1605             :             {
    1606       30236 :                 x[i] = L_sub( x[i], v2 ); /*Q31 - x_e*/
    1607       30236 :                 move32();
    1608             :             }
    1609       56748 :             if ( tmp32 < 0 )
    1610             :             {
    1611       26512 :                 x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1612       26512 :                 move32();
    1613             :             }
    1614             :         }
    1615      101705 :         i = add( i, 1 );
    1616             : 
    1617      101705 :         IF( x[i] < 0 )
    1618             :         {
    1619       43609 :             tmp32 = L_sub( x[i], L_negate( v4 ) );
    1620             : 
    1621       43609 :             if ( tmp32 > 0 )
    1622             :             {
    1623       16861 :                 lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1624       16861 :                 move16();
    1625             :             }
    1626       43609 :             if ( tmp32 <= 0 )
    1627             :             {
    1628       26748 :                 x[i] = L_add( x[i], v2 ); /*Q31 - x_e*/
    1629       26748 :                 move32();
    1630             :             }
    1631       43609 :             if ( tmp32 > 0 )
    1632             :             {
    1633       16861 :                 x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1634       16861 :                 move32();
    1635             :             }
    1636             :         }
    1637             :         ELSE
    1638             :         {
    1639       58096 :             tmp32 = L_sub( x[i], v4 );
    1640             : 
    1641       58096 :             if ( tmp32 < 0 )
    1642             :             {
    1643       31699 :                 lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1644       31699 :                 move16();
    1645             :             }
    1646       58096 :             if ( tmp32 >= 0 )
    1647             :             {
    1648       26397 :                 x[i] = L_sub( x[i], v2 ); /*Q31 - x_e*/
    1649       26397 :                 move32();
    1650             :             }
    1651       58096 :             if ( tmp32 < 0 )
    1652             :             {
    1653       31699 :                 x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1654       31699 :                 move32();
    1655             :             }
    1656             :         }
    1657             :     }
    1658             :     ELSE /*if(!tcx_lpc_shaped_ari)*/
    1659             :     {
    1660       14024 :         PsychAdaptLowFreqDeemph( x, lpcGains, lpcGains_e, lf_deemph_factors );
    1661             :     } /*if(!tcx_lpc_shaped_ari)*/
    1662      115729 : }
    1663             : 
    1664         645 : void tcx_noise_filling(
    1665             :     Word32 *Q, /*Q31 - Q_e*/
    1666             :     Word16 Q_e,
    1667             :     Word16 seed,
    1668             :     const Word16 iFirstLine,     /*Q0*/
    1669             :     const Word16 lowpassLine,    /*Q0*/
    1670             :     const Word16 nTransWidth,    /*Q0*/
    1671             :     const Word16 L_frame,        /*Q0*/
    1672             :     const Word16 tiltCompFactor, /*Q15*/
    1673             :     Word16 fac_ns,               /*Q15*/
    1674             :     Word16 *infoTCXNoise,        /*Q0*/
    1675             :     const Word16 element_mode    /* i  : IVAS element mode   Q0*/
    1676             : )
    1677             : {
    1678             :     Word16 i, m, segmentOffset;
    1679             :     Word16 win; /* window coefficient */
    1680             :     Word16 tilt_factor;
    1681             :     Word32 nrg;
    1682             :     Word16 tmp1, tmp2, s;
    1683             :     Word32 tmp32;
    1684             : 
    1685             : 
    1686             :     /* get inverse frame length */
    1687         645 :     tmp1 = getInvFrameLen( L_frame ); /*Q21*/
    1688             : 
    1689             :     /* tilt_factor = (float)pow(max_val(0.375f, tiltCompFactor), 1.0f/(float)L_frame); */
    1690         645 :     tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */
    1691         645 :     tmp32 = L_shr( Mpy_32_16_1( tmp32, tmp1 ), 6 );                            /*Q25*/
    1692             :     BASOP_SATURATE_WARNING_OFF_EVS;
    1693         645 :     tilt_factor = round_fx_sat( BASOP_Util_InvLog2( tmp32 ) ); /*Q15*/
    1694             :     BASOP_SATURATE_WARNING_ON_EVS;
    1695             : 
    1696             :     /* find last nonzero line below iFirstLine, use it as start offset */
    1697         645 :     i = iFirstLine;
    1698         645 :     move16();
    1699         645 :     tmp1 = shr( iFirstLine, 1 );               /*Q0*/
    1700         645 :     IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */
    1701             :     {
    1702           0 :         segmentOffset = i;
    1703           0 :         move16();
    1704             :     }
    1705             :     ELSE
    1706             :     {
    1707        2850 :         FOR( ; i > tmp1; i-- )
    1708             :         {
    1709        2844 :             IF( Q[i] != 0 )
    1710             :             {
    1711         639 :                 BREAK;
    1712             :             }
    1713             :         }
    1714             :         /* fac_ns *= (float)pow(tilt_factor, (float)i); */
    1715       30073 :         FOR( m = 0; m < i; m++ )
    1716             :         {
    1717       29428 :             fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
    1718             :         }
    1719         645 :         i = add( i, 1 );
    1720         645 :         segmentOffset = i;
    1721             :     }
    1722         645 :     nrg = L_deposit_l( 1 );
    1723         645 :     win = 0;
    1724         645 :     move16();
    1725             : 
    1726      138124 :     FOR( ; i < lowpassLine; i++ )
    1727             :     {
    1728      137479 :         fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
    1729             : 
    1730      137479 :         IF( Q[i] != 0 )
    1731             :         {
    1732       18510 :             IF( win > 0 )
    1733             :             {
    1734             :                 /* RMS-normalize current noise-filled segment */
    1735       12196 :                 tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( i, segmentOffset ), &s ); /* mean */
    1736       12196 :                 s = add( s, 9 - 15 );                                                   /* scaling */
    1737       12196 :                 tmp1 = ISqrt16( tmp1, &s );                                             /* 1/RMS Q15 - s*/
    1738       12196 :                 tmp1 = mult_r( tmp1, inv_int[nTransWidth] );                            /* compensate win Q15 - s*/
    1739       12196 :                 s = add( s, sub( 16, Q_e ) );                                           /* scaling */
    1740             : 
    1741       12196 :                 tmp2 = sub( i, win );
    1742       12196 :                 IF( LT_16( segmentOffset, tmp2 ) )
    1743             :                 {
    1744       34279 :                     FOR( m = segmentOffset; m < tmp2; m++ )
    1745             :                     {
    1746       31298 :                         Q[m] = L_shl( Mpy_32_16_1( Q[m], tmp1 ), s ); /*Q31 - Q_e*/
    1747       31298 :                         move32();
    1748             :                     }
    1749             :                 }
    1750             : 
    1751       12196 :                 tmp2 = mult( tmp1, inv_int[nTransWidth] );
    1752       12196 :                 tmp1 = extract_l( L_mult0( tmp2, win ) );
    1753       64745 :                 FOR( m = sub( i, win ); m < i; m++ )
    1754             :                 {
    1755       52549 :                     Q[m] = L_shl( Mpy_32_16_1( Q[m], tmp1 ), s ); /*Q31 - Q_e*/
    1756       52549 :                     move32();
    1757       52549 :                     win = sub( win, 1 );
    1758       52549 :                     tmp1 = sub( tmp1, tmp2 );
    1759             :                 }
    1760             : 
    1761       12196 :                 nrg = L_deposit_l( 1 ); /* start new segment: reset noise segment energy */
    1762             :             }
    1763       18510 :             segmentOffset = add( i, 1 );
    1764             :         }
    1765             :         ELSE /* line is zero, so fill line and update window and energy */
    1766             :         {
    1767      118969 :             if ( LT_16( win, nTransWidth ) )
    1768             :             {
    1769       56867 :                 win = add( win, 1 );
    1770             :             }
    1771             : 
    1772      118969 :             Random( &seed );
    1773      118969 :             Q[i] = L_mult0( mult( seed, fac_ns ), win ); /*Q31 - Q_e*/
    1774      118969 :             move32();
    1775             : 
    1776      118969 :             tmp1 = shr( seed, 4 );
    1777      118969 :             nrg = L_mac0( nrg, tmp1, tmp1 ); /* sum up energy of current noise segment */
    1778             : 
    1779      118969 :             if ( infoTCXNoise ) /* set noiseflags for IGF */
    1780             :             {
    1781      118969 :                 infoTCXNoise[i] = 1;
    1782      118969 :                 move16();
    1783             :             }
    1784             :         }
    1785             :     }
    1786             : 
    1787         645 :     IF( win > 0 )
    1788             :     {
    1789             :         /* RMS-normalize uppermost noise-filled segment */
    1790         619 :         tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( lowpassLine, segmentOffset ), &s ); /* mean */
    1791         619 :         s = add( s, 9 - 15 );                                                             /* compensate energy scaling */
    1792         619 :         tmp1 = ISqrt16( tmp1, &s );                                                       /* 1/RMS Q15 - s*/
    1793         619 :         tmp1 = mult_r( tmp1, inv_int[nTransWidth] );                                      /* compensate win Q15 - s*/
    1794         619 :         s = add( s, sub( 16, Q_e ) );                                                     /* compensate noise scaling */
    1795             : 
    1796       35741 :         FOR( m = segmentOffset; m < lowpassLine; m++ )
    1797             :         {
    1798       35122 :             Q[m] = L_shl( Mpy_32_16_1( Q[m], tmp1 ), s ); /*Q31 - Q_e*/
    1799       35122 :             move32();
    1800             :         }
    1801             :     }
    1802         645 : }
    1803             : 
    1804      803199 : void tcx_noise_filling_with_shift(
    1805             :     Word32 *Q, /*Q31 - Q_e*/
    1806             :     Word16 *Q_e,
    1807             :     Word16 seed,                 /*Q0*/
    1808             :     const Word16 iFirstLine,     /*Q0*/
    1809             :     const Word16 lowpassLine,    /*Q0*/
    1810             :     const Word16 nTransWidth,    /*Q0*/
    1811             :     const Word16 L_frame,        /*Q0*/
    1812             :     const Word16 tiltCompFactor, /*Q0*/
    1813             :     Word16 fac_ns,               /*Q15*/
    1814             :     Word16 *infoTCXNoise,        /*Q0*/
    1815             :     const Word16 element_mode    /* i  : IVAS element mode   Q0*/
    1816             : )
    1817             : {
    1818             :     Word16 i, m, segmentOffset;
    1819             :     Word16 win; /* window coefficient */
    1820             :     Word16 tilt_factor;
    1821             :     Word32 nrg;
    1822             :     Word16 tmp1, tmp2, s;
    1823             :     Word32 tmp32;
    1824             :     Word16 new_Q_e[N_MAX];
    1825             : 
    1826      803199 :     set16_fx( new_Q_e, *Q_e, N_MAX );
    1827             : 
    1828             :     /* get inverse frame length */
    1829      803199 :     tmp1 = getInvFrameLen( L_frame ); /*Q21*/
    1830             : 
    1831             :     /* tilt_factor = (float)pow(max_val(0.375f, tiltCompFactor), 1.0f/(float)L_frame); */
    1832      803199 :     tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */
    1833      803199 :     tmp32 = L_shr( Mpy_32_16_1( tmp32, tmp1 ), 6 );                            /*Q25*/
    1834             :     BASOP_SATURATE_WARNING_OFF_EVS;
    1835      803199 :     tilt_factor = round_fx_sat( BASOP_Util_InvLog2( tmp32 ) ); /*Q15*/
    1836             :     BASOP_SATURATE_WARNING_ON_EVS;
    1837             : 
    1838             :     /* find last nonzero line below iFirstLine, use it as start offset */
    1839      803199 :     i = iFirstLine;
    1840      803199 :     move16();
    1841      803199 :     tmp1 = shr( iFirstLine, 1 );
    1842      803199 :     IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */
    1843             :     {
    1844      598573 :         segmentOffset = i;
    1845      598573 :         move16();
    1846             :     }
    1847             :     ELSE
    1848             :     {
    1849      590911 :         FOR( ; i > tmp1; i-- )
    1850             :         {
    1851      589808 :             IF( Q[i] != 0 )
    1852             :             {
    1853      203523 :                 BREAK;
    1854             :             }
    1855             :         }
    1856             :         /* fac_ns *= (float)pow(tilt_factor, (float)i); */
    1857    14400130 :         FOR( m = 0; m < i; m++ )
    1858             :         {
    1859    14195504 :             fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
    1860             :         }
    1861      204626 :         i = add( i, 1 );
    1862      204626 :         segmentOffset = i;
    1863      204626 :         move16();
    1864             :     }
    1865      803199 :     nrg = L_deposit_l( 1 );
    1866      803199 :     win = 0;
    1867      803199 :     move16();
    1868             : 
    1869   358649443 :     FOR( ; i < lowpassLine; i++ )
    1870             :     {
    1871   357846244 :         fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
    1872             : 
    1873   357846244 :         IF( Q[i] != 0 )
    1874             :         {
    1875    85051171 :             IF( win > 0 )
    1876             :             {
    1877             :                 /* RMS-normalize current noise-filled segment */
    1878    39542971 :                 tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( i, segmentOffset ), &s ); /* mean */
    1879             :                 // Q-factor of nrg is -8. exp = 31-(-8) = 39
    1880    39542971 :                 s = add( s, 39 - 15 );                       /* scaling */
    1881    39542971 :                 tmp1 = ISqrt16( tmp1, &s );                  /* 1/RMS Q15 - s*/
    1882    39542971 :                 tmp1 = mult_r( tmp1, inv_int[nTransWidth] ); /* compensate win Q15 - s*/
    1883             : 
    1884    39542971 :                 tmp2 = sub( i, win );
    1885    39542971 :                 IF( LT_16( segmentOffset, tmp2 ) )
    1886             :                 {
    1887    68762404 :                     FOR( m = segmentOffset; m < tmp2; m++ )
    1888             :                     {
    1889    63434018 :                         Word16 nrm = 31;
    1890    63434018 :                         move16();
    1891    63434018 :                         Q[m] = Mpy_32_16_1( Q[m], tmp1 ); /*Q31 - Q_e*/
    1892    63434018 :                         move32();
    1893    63434018 :                         IF( Q[m] )
    1894             :                         {
    1895    63427571 :                             nrm = norm_l( Q[m] );
    1896             :                         }
    1897    63434018 :                         Q[m] = L_shl( Q[m], nrm ); /*Q31 - Q_e + nrm*/
    1898    63434018 :                         move32();
    1899    63434018 :                         new_Q_e[m] = sub( add( new_Q_e[m], s ), nrm );
    1900    63434018 :                         move32();
    1901             :                     }
    1902             :                 }
    1903             : 
    1904    39542971 :                 tmp2 = mult( tmp1, inv_int[nTransWidth] ); /*Q15 - s*/
    1905    39542971 :                 tmp1 = extract_l( L_mult0( tmp2, win ) );  /*Q15 - s*/
    1906   155149860 :                 FOR( m = sub( i, win ); m < i; m++ )
    1907             :                 {
    1908   115606889 :                     Word16 nrm = 31;
    1909             : 
    1910   115606889 :                     Q[m] = Mpy_32_16_1( Q[m], tmp1 ); /*Q31 - Q_e*/
    1911   115606889 :                     move32();
    1912   115606889 :                     IF( Q[m] )
    1913             :                     {
    1914   115596272 :                         nrm = norm_l( Q[m] );
    1915             :                     }
    1916   115606889 :                     Q[m] = L_shl( Q[m], nrm ); /*Q31 - Q_e*/
    1917   115606889 :                     move32();
    1918   115606889 :                     new_Q_e[m] = sub( add( new_Q_e[m], s ), nrm );
    1919   115606889 :                     move32();
    1920   115606889 :                     win = sub( win, 1 );
    1921   115606889 :                     tmp1 = sub( tmp1, tmp2 );
    1922             :                 }
    1923             : 
    1924    39542971 :                 nrg = L_deposit_l( 1 ); /* start new segment: reset noise segment energy */
    1925             :             }
    1926    85051171 :             segmentOffset = add( i, 1 );
    1927             :         }
    1928             :         ELSE /* line is zero, so fill line and update window and energy */
    1929             :         {
    1930   272795073 :             IF( LT_16( win, nTransWidth ) )
    1931             :             {
    1932   120706883 :                 win = add( win, 1 );
    1933             :             }
    1934             : 
    1935   272795073 :             Word16 nrm = 31;
    1936   272795073 :             move16();
    1937             : 
    1938   272795073 :             Random( &seed );
    1939   272795073 :             Q[i] = L_mult0( mult( seed, fac_ns ), win );
    1940   272795073 :             move32();
    1941   272795073 :             IF( Q[i] )
    1942             :             {
    1943   272766063 :                 nrm = norm_l( Q[i] );
    1944             :             }
    1945   272795073 :             Q[i] = L_shl( Q[i], nrm ); /*Q31 - Q_e*/
    1946   272795073 :             move32();
    1947   272795073 :             new_Q_e[i] = sub( 31, nrm );
    1948             : 
    1949   272795073 :             tmp1 = shr( seed, 4 );
    1950   272795073 :             nrg = L_mac0( nrg, tmp1, tmp1 ); /* sum up energy of current noise segment Q-8*/
    1951             : 
    1952   272795073 :             IF( infoTCXNoise ) /* set noiseflags for IGF */
    1953             :             {
    1954   157458937 :                 infoTCXNoise[i] = 1;
    1955   157458937 :                 move16();
    1956             :             }
    1957             :         }
    1958             :     }
    1959             : 
    1960      803199 :     IF( win > 0 )
    1961             :     {
    1962             :         /* RMS-normalize uppermost noise-filled segment */
    1963      745256 :         tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( lowpassLine, segmentOffset ), &s ); /* mean */
    1964             :         // Q-factor of nrg is -8. exp = 31-(-8) = 39
    1965      745256 :         s = add( s, 39 - 15 );                       /* compensate energy scaling */
    1966      745256 :         tmp1 = ISqrt16( tmp1, &s );                  /* 1/RMS Q15 - s*/
    1967      745256 :         tmp1 = mult_r( tmp1, inv_int[nTransWidth] ); /* compensate win Q15 - s*/
    1968             : 
    1969    94499422 :         FOR( m = segmentOffset; m < lowpassLine; m++ )
    1970             :         {
    1971    93754166 :             Word16 nrm = 31;
    1972    93754166 :             move16();
    1973             :             /*
    1974             :                 at this point:
    1975             :                 - flt Q[m] = (Q[m] * 2^(new_Q_e[m] - 31)) / (nTransWidth*nTransWidth)
    1976             :                 - flt tmp1 = (tmp1 * 2^(s - 15)) * (nTransWidth*nTransWidth)
    1977             :              */
    1978    93754166 :             Q[m] = Mpy_32_16_1( Q[m], tmp1 ); /*Q15 - Q_e - s*/
    1979    93754166 :             move32();
    1980    93754166 :             IF( Q[m] )
    1981             :             {
    1982    93742220 :                 nrm = norm_l( Q[m] );
    1983             :             }
    1984    93754166 :             Q[m] = L_shl( Q[m], nrm ); /*Q15 - Q_e - s + nrm*/
    1985    93754166 :             move32();
    1986    93754166 :             new_Q_e[m] = add( new_Q_e[m], s - nrm );
    1987    93754166 :             move32();
    1988             :         }
    1989             :     }
    1990             : 
    1991      803199 :     Word16 max_e = 0;
    1992      803199 :     move16();
    1993   427638669 :     FOR( i = 0; i < lowpassLine; i++ )
    1994             :     {
    1995   426835470 :         max_e = s_max( max_e, new_Q_e[i] );
    1996             :     }
    1997             : 
    1998   427638669 :     FOR( i = 0; i < lowpassLine; i++ )
    1999             :     {
    2000   426835470 :         Q[i] = L_shr( Q[i], sub( max_e, new_Q_e[i] ) ); /*Q31 - Q_e*/
    2001   426835470 :         move32();
    2002             :     }
    2003             : 
    2004      803199 :     *Q_e = max_e;
    2005      803199 :     move16();
    2006      803199 : }
    2007             : 
    2008             : 
    2009             : /*---------------------------------------------------------------
    2010             :  * InitTnsConfigs()
    2011             :  *--------------------------------------------------------------*/
    2012             : 
    2013             : 
    2014       18138 : void InitTnsConfigs(
    2015             :     const Word16 bwidth,  /*Q0*/
    2016             :     const Word16 L_frame, /*Q0*/
    2017             :     STnsConfig tnsConfig[2][2],
    2018             :     const Word16 igfStopFreq,  /*Q0*/
    2019             :     const Word32 total_brate,  /*Q0*/
    2020             :     const Word16 element_mode, /*Q0*/
    2021             :     const Word16 MCT_flag /*Q0*/ )
    2022             : {
    2023       18138 :     IF( GT_32( total_brate, ACELP_32k ) )
    2024             :     {
    2025       14792 :         InitTnsConfiguration( bwidth, shr( L_frame, 1 ), &tnsConfig[0][0], igfStopFreq, total_brate, element_mode, MCT_flag );
    2026             :     }
    2027       18138 :     InitTnsConfiguration( bwidth, L_frame, &tnsConfig[1][0], igfStopFreq, total_brate, element_mode, MCT_flag );
    2028       18138 :     InitTnsConfiguration( bwidth, add( L_frame, shr( L_frame, 2 ) ), &tnsConfig[1][1], igfStopFreq, total_brate, element_mode, MCT_flag );
    2029       18138 : }
    2030             : 
    2031           0 : void InitTnsConfigs_ivas_fx(
    2032             :     const Word16 bwidth,  /*Q0*/
    2033             :     const Word16 L_frame, /*Q0*/
    2034             :     STnsConfig tnsConfig[2][2],
    2035             :     const Word16 igfStopFreq,  /*Q0*/
    2036             :     const Word32 total_brate,  /*Q0*/
    2037             :     const Word16 element_mode, /*Q0*/
    2038             :     const Word16 MCT_flag /*Q0*/ )
    2039             : {
    2040           0 :     IF( GT_32( total_brate, ACELP_32k ) )
    2041             :     {
    2042           0 :         InitTnsConfiguration_ivas_fx( bwidth, shr( L_frame, 1 ), &tnsConfig[0][0], igfStopFreq, total_brate, element_mode, MCT_flag );
    2043             :     }
    2044           0 :     InitTnsConfiguration_ivas_fx( bwidth, L_frame, &tnsConfig[1][0], igfStopFreq, total_brate, element_mode, MCT_flag );
    2045           0 :     InitTnsConfiguration_ivas_fx( bwidth, add( L_frame, shr( L_frame, 2 ) ), &tnsConfig[1][1], igfStopFreq, total_brate, element_mode, MCT_flag );
    2046           0 : }
    2047             : 
    2048             : 
    2049      862527 : void SetTnsConfig(
    2050             :     TCX_CONFIG_HANDLE hTcxCfg, /* i  : configuration of TCX               */
    2051             :     const Word16 isTCX20,      /*Q0*/
    2052             :     const Word16 isAfterACELP /*Q0*/ )
    2053             : {
    2054      862527 :     move16();
    2055      862527 :     hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[isTCX20][isAfterACELP];
    2056      862527 :     assert( hTcxCfg->pCurrentTnsConfig != NULL );
    2057      862527 : }
    2058             : #define IVAS_CODE_TCX_UTIL
    2059             : #ifdef IVAS_CODE_TCX_UTIL
    2060             : /*-------------------------------------------------------------------*
    2061             :  *  SetAllowTnsOnWhite
    2062             :  *
    2063             :  *  set TNS config flag for possible application of TNS in the whitened domain
    2064             :  *-------------------------------------------------------------------*/
    2065             : 
    2066       18124 : void SetAllowTnsOnWhite(
    2067             :     STnsConfig tnsConfig[2][2], /* o  : updated TNS configurations */
    2068             :     const Word8 allowTnsOnWhite /* i  : flag for TNS in whiteded domain mode Q0*/
    2069             : )
    2070             : {
    2071       18124 :     tnsConfig[0][0].allowTnsOnWhite = allowTnsOnWhite; /*Q0*/
    2072       18124 :     move16();
    2073       18124 :     tnsConfig[0][1].allowTnsOnWhite = allowTnsOnWhite;
    2074       18124 :     move16();
    2075       18124 :     tnsConfig[1][0].allowTnsOnWhite = allowTnsOnWhite;
    2076       18124 :     move16();
    2077       18124 :     tnsConfig[1][1].allowTnsOnWhite = allowTnsOnWhite;
    2078       18124 :     move16();
    2079       18124 :     return;
    2080             : }
    2081             : #endif
    2082             : #undef IVAS_CODE_TCX_UTIL
    2083             : 
    2084           0 : void tcx_get_gain(
    2085             :     Word32 *x,      /* i: spectrum 1 Q31 - x_e*/
    2086             :     Word16 x_e,     /* i: spectrum 1 exponent */
    2087             :     Word32 *y,      /* i: spectrum 2 Q31 - y_e*/
    2088             :     Word16 y_e,     /* i: spectrum 2 exponent */
    2089             :     Word16 n,       /* i: length Q0*/
    2090             :     Word16 *gain,   /* o: gain Q15 - gain_e*/
    2091             :     Word16 *gain_e, /* o: gain exponent */
    2092             :     Word32 *en_y,   /* o: energy of y (optional)  Q31 - en_y_e*/
    2093             :     Word16 *en_y_e  /* o: energy of y exponent (optional) */
    2094             : )
    2095             : {
    2096             :     Word32 maxX, minX, maxY, minY;
    2097             :     Word32 corr, ener;
    2098             :     Word16 sx, sy, corr_e, ener_e;
    2099             :     Word16 i, tmp;
    2100             : #ifndef ISSUE_1836_replace_overflow_libcom
    2101             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    2102             :     Flag Overflow = 0;
    2103             : #endif
    2104             : #endif
    2105             : 
    2106           0 :     maxX = L_deposit_l( 1 );
    2107           0 :     maxY = L_deposit_l( 1 );
    2108           0 :     minX = L_deposit_l( -1 );
    2109           0 :     minY = L_deposit_l( -1 );
    2110           0 :     FOR( i = 0; i < n; i++ )
    2111             :     {
    2112           0 :         if ( x[i] > 0 )
    2113           0 :             maxX = L_max( maxX, x[i] ); /*Q31 - x_e*/
    2114           0 :         if ( x[i] < 0 )
    2115           0 :             minX = L_min( minX, x[i] ); /*Q31 - x_e*/
    2116             : 
    2117           0 :         if ( y[i] > 0 )
    2118           0 :             maxY = L_max( maxY, y[i] ); /*Q31 - y_e*/
    2119           0 :         if ( y[i] < 0 )
    2120           0 :             minY = L_min( minY, y[i] ); /*Q31 - y_e*/
    2121             :     }
    2122           0 :     sx = s_min( norm_l( maxX ), norm_l( minX ) );
    2123           0 :     sy = s_min( norm_l( maxY ), norm_l( minY ) );
    2124           0 :     sx = sub( sx, 4 );
    2125           0 :     sy = sub( sy, 4 );
    2126             : 
    2127           0 :     ener = L_deposit_l( 0 );
    2128           0 :     corr = L_deposit_l( 0 );
    2129           0 :     FOR( i = 0; i < n; i++ )
    2130             :     {
    2131           0 :         tmp = round_fx( L_shl( y[i], sy ) );                       /*Q15 - y_e + sy*/
    2132           0 :         ener = L_mac0( ener, tmp, tmp );                           /*Q30 - 2*(y_e - sy)*/
    2133           0 :         corr = L_mac0( corr, tmp, round_fx( L_shl( x[i], sx ) ) ); /*Q30 - 2*(x_e - sx + y_e - sy)*/
    2134             :     }
    2135             : 
    2136           0 :     if ( ener == 0 )
    2137           0 :         ener = L_deposit_l( 1 );
    2138             : 
    2139           0 :     ener_e = add( shl( sub( y_e, sy ), 1 ), 1 );
    2140           0 :     corr_e = add( sub( add( x_e, y_e ), add( sx, sy ) ), 1 );
    2141             : 
    2142           0 :     tmp = sub( norm_l( corr ), 1 );
    2143           0 :     corr = L_shl( corr, tmp ); /*Q31 - corr_e + tmp*/
    2144           0 :     corr_e = sub( corr_e, tmp );
    2145             : 
    2146           0 :     tmp = norm_l( ener );
    2147           0 :     ener = L_shl( ener, tmp ); /*Q31 - ener_e + tmp*/
    2148           0 :     ener_e = sub( ener_e, tmp );
    2149             : 
    2150             : #ifdef ISSUE_1836_replace_overflow_libcom
    2151           0 :     tmp = div_s( abs_s( round_fx_sat( corr ) ), round_fx_sat( ener ) ); /*Q15 - (corr_e - ener_e)*/
    2152             : #else
    2153             :     tmp = div_s( abs_s( round_fx_o( corr, &Overflow ) ), round_fx_o( ener, &Overflow ) ); /*Q15 - (corr_e - ener_e)*/
    2154             : #endif
    2155           0 :     if ( corr < 0 )
    2156           0 :         tmp = negate( tmp );
    2157             : 
    2158           0 :     *gain = tmp;
    2159           0 :     move16();
    2160           0 :     *gain_e = sub( corr_e, ener_e );
    2161           0 :     move16();
    2162             : 
    2163           0 :     if ( en_y != NULL )
    2164             :     {
    2165           0 :         *en_y = ener; /*Q31 - ener_e*/
    2166           0 :         move32();
    2167             :     }
    2168           0 :     if ( en_y_e != NULL )
    2169             :     {
    2170           0 :         *en_y_e = ener_e;
    2171           0 :         move16();
    2172             :     }
    2173           0 : }
    2174          41 : void init_TCX_config(
    2175             :     TCX_CONFIG_HANDLE hTcxCfg,
    2176             :     Word16 L_frame,    /*Q0*/
    2177             :     Word16 fscale,     /*Q0*/
    2178             :     Word16 L_frameTCX, /*Q0*/
    2179             :     Word16 fscaleFB /*Q0*/ )
    2180             : {
    2181             :     /* Initialize the TCX MDCT windows */
    2182          41 :     hTcxCfg->tcx_mdct_window_length = extract_l( L_shr( L_mult0( L_LOOK_12k8, fscale ), LD_FSCALE_DENOM ) ); /*Q0*/
    2183          41 :     move16();
    2184          41 :     hTcxCfg->tcx_mdct_window_delay = hTcxCfg->tcx_mdct_window_length; /*Q0*/
    2185          41 :     move16();
    2186             : 
    2187          41 :     hTcxCfg->tcx_mdct_window_half_length = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA( 12800, 5000000L ), fscale ), LD_FSCALE_DENOM ) );
    2188          41 :     move16();
    2189          41 :     hTcxCfg->tcx_mdct_window_min_length = shr( L_frame, 4 ); /* 1.25ms Q0*/
    2190          41 :     move16();
    2191          41 :     hTcxCfg->tcx_mdct_window_trans_length = shr( L_frame, 4 ); /* 1.25ms Q0*/
    2192          41 :     move16();
    2193          41 :     hTcxCfg->tcx5Size = shr( L_frame, 2 ); /* 5ms Q0*/
    2194          41 :     move16();
    2195          41 :     hTcxCfg->tcx_mdct_window_lengthFB = extract_l( L_shr( L_mult0( L_LOOK_12k8, fscaleFB ), LD_FSCALE_DENOM ) ); /*Q0*/
    2196          41 :     move16();
    2197          41 :     hTcxCfg->tcx_mdct_window_delayFB = hTcxCfg->tcx_mdct_window_lengthFB; /*Q0*/
    2198          41 :     move16();
    2199             : 
    2200          41 :     hTcxCfg->tcx_mdct_window_half_lengthFB = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA( 12800, 5000000L ), fscaleFB ), LD_FSCALE_DENOM ) ); /*Q0*/
    2201          41 :     move16();
    2202          41 :     hTcxCfg->tcx_mdct_window_min_lengthFB = shr( L_frameTCX, 4 ); /* 1.25ms Q0*/
    2203          41 :     move16();
    2204          41 :     hTcxCfg->tcx_mdct_window_trans_lengthFB = shr( L_frameTCX, 4 ); /* 1.25ms Q0*/
    2205          41 :     move16();
    2206          41 :     hTcxCfg->tcx5SizeFB = shr( L_frameTCX, 2 ); /* 5ms Q0*/
    2207          41 :     move16();
    2208          41 :     mdct_window_sine( hTcxCfg->tcx_mdct_window, hTcxCfg->tcx_mdct_window_length );
    2209          41 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_half_length );
    2210          41 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_min_length );
    2211          41 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_trans_length );
    2212             : 
    2213          41 :     mdct_window_sine( hTcxCfg->tcx_mdct_windowFB, hTcxCfg->tcx_mdct_window_lengthFB );
    2214          41 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_half_lengthFB );
    2215          41 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_min_lengthFB );
    2216          41 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_trans_lengthFB );
    2217             : 
    2218             :     /*ALDO windows for MODE2*/
    2219          41 :     mdct_window_aldo( hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, L_frame );
    2220          41 :     mdct_window_aldo( hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, L_frameTCX );
    2221          41 : }

Generated by: LCOV version 1.14