LCOV - code coverage report
Current view: top level - lib_com - tcx_utils_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ da9cc8ead0679b4682d329fdff98cf1616159273 Lines: 1055 1113 94.8 %
Date: 2025-10-13 22:24:20 Functions: 22 22 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include <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     3302886 : Word16 getInvFrameLen( /* returns 1/L_frame in Q21 format */
      21             :                        const Word16 L_frame )
      22             : {
      23             :     Word16 idx, s;
      24             : 
      25     3302886 :     s = norm_s( L_frame );
      26     3302886 :     idx = shl( L_frame, s );
      27             : 
      28     3302886 :     assert( ( idx == 0x4000 ) || ( idx == 0x4B00 ) || ( idx == 0x5000 ) || ( idx == 0x5A00 ) || ( idx == 0x6000 ) || ( idx == 0x6400 ) || ( idx == 0x7800 ) );
      29             : 
      30     3302886 :     idx = mult_r( idx, 0x10 ); /* idx = shr(add(idx, 0x0400), 11); */
      31     3302886 :     idx = s_and( idx, 7 );
      32             : 
      33             : 
      34     3302886 :     return shl( L_frame_inv[idx], sub( s, 7 ) );
      35             : }
      36             : /*-------------------------------------------------------------------*
      37             :  *tcx_get_windows()
      38             :  *
      39             :  *
      40             :  * ------------------------------------------------------------------ - */
      41      479128 : 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      479128 :     IF( fullband == 0 )
      53             :     {
      54             :         /* Left part */
      55      108948 :         SWITCH( left_mode )
      56             :         {
      57         322 :             case TRANSITION_OVERLAP:                                   /* ACELP->TCX transition */
      58         322 :                 *left_overlap = hTcxCfg->tcx_mdct_window_trans_length; /*Q0*/
      59         322 :                 move16();
      60         322 :                 *left_win = hTcxCfg->tcx_mdct_window_trans; /*Q15*/
      61         322 :                 BREAK;
      62        2171 :             case MIN_OVERLAP:
      63        2171 :                 *left_overlap = hTcxCfg->tcx_mdct_window_min_length; /*Q0*/
      64        2171 :                 move16();
      65        2171 :                 *left_win = hTcxCfg->tcx_mdct_window_minimum; /*Q15*/
      66        2171 :                 BREAK;
      67        1711 :             case HALF_OVERLAP:
      68        1711 :                 *left_overlap = hTcxCfg->tcx_mdct_window_half_length; /*Q0*/
      69        1711 :                 move16();
      70        1711 :                 *left_win = hTcxCfg->tcx_mdct_window_half; /*Q15*/
      71        1711 :                 BREAK;
      72      104744 :             case FULL_OVERLAP:
      73      104744 :                 *left_overlap = hTcxCfg->tcx_mdct_window_length; /*Q0*/
      74      104744 :                 move16();
      75      104744 :                 *left_win = hTcxCfg->tcx_aldo_window_1_trunc; /*Q15*/
      76      104744 :                 BREAK;
      77           0 :             default:
      78           0 :                 assert( !"Not supported overlap" );
      79             :         }
      80             : 
      81             :         /* Right part */
      82      108948 :         SWITCH( right_mode )
      83             :         {
      84        2185 :             case MIN_OVERLAP:
      85        2185 :                 *right_overlap = hTcxCfg->tcx_mdct_window_min_length; /*Q0*/
      86        2185 :                 move16();
      87        2185 :                 *right_win = hTcxCfg->tcx_mdct_window_minimum; /*Q15*/
      88        2185 :                 BREAK;
      89        1714 :             case HALF_OVERLAP:
      90        1714 :                 *right_overlap = hTcxCfg->tcx_mdct_window_half_length; /*Q0*/
      91        1714 :                 move16();
      92        1714 :                 *right_win = hTcxCfg->tcx_mdct_window_half; /*Q15*/
      93        1714 :                 BREAK;
      94      105049 :             case FULL_OVERLAP:
      95      105049 :                 *right_overlap = hTcxCfg->tcx_mdct_window_delay; /*Q0*/
      96      105049 :                 move16();
      97      105049 :                 *right_win = hTcxCfg->tcx_aldo_window_2; /*Q15*/
      98      105049 :                 BREAK;
      99           0 :             default:
     100           0 :                 assert( !"Not supported overlap" );
     101             :         }
     102             :     }
     103             :     ELSE
     104             :     {
     105             :         /* Left part */
     106      370180 :         SWITCH( left_mode )
     107             :         {
     108       10830 :             case TRANSITION_OVERLAP:                                     /* ACELP->TCX transition */
     109       10830 :                 *left_overlap = hTcxCfg->tcx_mdct_window_trans_lengthFB; /*Q0*/
     110       10830 :                 move16();
     111       10830 :                 *left_win = hTcxCfg->tcx_mdct_window_transFB; /*Q15*/
     112       10830 :                 BREAK;
     113       58764 :             case MIN_OVERLAP:
     114       58764 :                 *left_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB; /*Q0*/
     115       58764 :                 move16();
     116       58764 :                 *left_win = hTcxCfg->tcx_mdct_window_minimumFB; /*Q15*/
     117       58764 :                 BREAK;
     118       14676 :             case HALF_OVERLAP:
     119       14676 :                 *left_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB; /*Q0*/
     120       14676 :                 move16();
     121       14676 :                 *left_win = hTcxCfg->tcx_mdct_window_halfFB; /*Q15*/
     122       14676 :                 BREAK;
     123       32838 :             case RECTANGULAR_OVERLAP:
     124       32838 :                 *left_overlap = 0;
     125       32838 :                 move16();
     126       32838 :                 *left_win = NULL;
     127       32838 :                 BREAK;
     128      253072 :             case FULL_OVERLAP:
     129      253072 :                 *left_overlap = hTcxCfg->tcx_mdct_window_lengthFB; /*Q0*/
     130      253072 :                 move16();
     131      253072 :                 *left_win = hTcxCfg->tcx_aldo_window_1_FB_trunc; /*Q15*/
     132      253072 :                 BREAK;
     133           0 :             default:
     134           0 :                 assert( !"Not supported overlap" );
     135             :         }
     136             : 
     137             :         /* Right part */
     138      370180 :         SWITCH( right_mode )
     139             :         {
     140       61788 :             case MIN_OVERLAP:
     141       61788 :                 *right_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB; /*Q0*/
     142       61788 :                 move16();
     143       61788 :                 *right_win = hTcxCfg->tcx_mdct_window_minimumFB; /*Q15*/
     144       61788 :                 BREAK;
     145       15170 :             case HALF_OVERLAP:
     146       15170 :                 *right_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB; /*Q0*/
     147       15170 :                 move16();
     148       15170 :                 *right_win = hTcxCfg->tcx_mdct_window_halfFB; /*Q15*/
     149       15170 :                 BREAK;
     150       32819 :             case RECTANGULAR_OVERLAP:
     151       32819 :                 *right_overlap = 0;
     152       32819 :                 move16();
     153       32819 :                 *right_win = NULL;
     154       32819 :                 BREAK;
     155      260403 :             case FULL_OVERLAP:
     156      260403 :                 *right_overlap = hTcxCfg->tcx_mdct_window_delayFB; /*Q0*/
     157      260403 :                 move16();
     158      260403 :                 *right_win = hTcxCfg->tcx_aldo_window_2_FB; /*Q15*/
     159      260403 :                 BREAK;
     160           0 :             default:
     161           0 :                 assert( !"Not supported overlap" );
     162             :         }
     163             :     }
     164      479128 : }
     165             : 
     166      479097 : 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      479097 :     n = shr( left_overlap, 1 ); /*Q0*/
     180    68548319 :     FOR( w = 0; w < n; w++ )
     181             :     {
     182    68069222 :         *output++ = mult_r( *signal++, left_win[w].v.im ); /*Qx*/
     183    68069222 :         move16();
     184             :     }
     185    68548319 :     FOR( w = 0; w < n; w++ )
     186             :     {
     187    68069222 :         *output++ = mult_r( *signal++, left_win[n - 1 - w].v.re ); /*Qx*/
     188    68069222 :         move16();
     189             :     }
     190             : 
     191             :     /* Non overlapping region */
     192      479097 :     n = sub( L_frame, shr( add( left_overlap, right_overlap ), 1 ) ); /*Q0*/
     193   194454557 :     FOR( w = 0; w < n; w++ )
     194             :     {
     195   193975460 :         *output++ = *signal++; /*Qx*/
     196   193975460 :         move16();
     197             :     }
     198             : 
     199             :     /* Right overlap */
     200      479097 :     n = shr( right_overlap, 1 ); /*Q0*/
     201    69852207 :     FOR( w = 0; w < n; w++ )
     202             :     {
     203    69373110 :         *output++ = mult_r( *signal++, right_win[w].v.re ); /*Qx*/
     204    69373110 :         move16();
     205             :     }
     206    69852207 :     FOR( w = 0; w < n; w++ )
     207             :     {
     208    69373110 :         *output++ = mult_r( *signal++, right_win[n - 1 - w].v.im ); /*Qx*/
     209    69373110 :         move16();
     210             :     }
     211      479097 : }
     212             : /*-------------------------------------------------------------------*
     213             :  * WindowSignal()
     214             :  *
     215             :  *
     216             :  *-------------------------------------------------------------------*/
     217      479097 : 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      479097 :     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      479097 :     IF( EQ_16( left_overlap_mode, TRANSITION_OVERLAP ) )
     246             :     {
     247             :         /* Increase frame size for 5ms */
     248       11152 :         IF( fullband == 0 )
     249             :         {
     250         322 :             *L_frame = add( *L_frame, hTcxCfg->tcx5Size ); /*Q0*/
     251         322 :             move16();
     252         322 :             offset = negate( shr( hTcxCfg->tcx_mdct_window_trans_length, 1 ) ); /*Q0*/
     253             :         }
     254             :         ELSE
     255             :         {
     256       10830 :             *L_frame = add( *L_frame, hTcxCfg->tcx5SizeFB ); /*Q0*/
     257       10830 :             move16();
     258       10830 :             offset = negate( shr( hTcxCfg->tcx_mdct_window_trans_lengthFB, 1 ) ); /*Q0*/
     259             :         }
     260             :     }
     261             : 
     262             :     /*-----------------------------------------------------------*
     263             :      * Windowing                                                 *
     264             :      *-----------------------------------------------------------*/
     265             : 
     266      479097 :     tcx_windowing_analysis( in - sub( shr( l, 1 ), offset ), *L_frame, l, left_win, r, right_win, out );
     267      479097 :     test();
     268      479097 :     test();
     269      479097 :     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      334565 :         p = hTcxCfg->tcx_mdct_window_minimum;                /*Q15*/
     276      334565 :         tmp = shr( hTcxCfg->tcx_mdct_window_min_length, 1 ); /*Q0*/
     277      334565 :         IF( fullband != 0 )
     278             :         {
     279      229821 :             p = hTcxCfg->tcx_mdct_window_minimumFB;                /*Q15*/
     280      229821 :             tmp = shr( hTcxCfg->tcx_mdct_window_min_lengthFB, 1 ); /*Q0*/
     281             :         }
     282             : 
     283     8983987 :         FOR( i = 0; i < tmp; i++ )
     284             :         {
     285     8649422 :             out[i] = mult_r( out[i], p[i].v.im ); /*Qx*/
     286     8649422 :             move16();
     287             :         }
     288     8983987 :         FOR( i = 0; i < tmp; i++ )
     289             :         {
     290     8649422 :             out[i + tmp] = mult_r( out[i + tmp], p[tmp - 1 - i].v.re ); /*Qx*/
     291     8649422 :             move16();
     292             :         }
     293             :     }
     294             : 
     295      479097 :     *left_overlap_length = l;
     296      479097 :     move16();
     297      479097 :     *right_overlap_length = r;
     298      479097 :     move16();
     299      479097 : }
     300             : /*-------------------------------------------------------------------*
     301             :  * tcx_windowing_synthesis_current_frame()
     302             :  *
     303             :  *
     304             :  *-------------------------------------------------------------------*/
     305             : 
     306      129873 : 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      129873 :     overlap = shr( window_length, 1 ); /*Q0*/
     335             : 
     336             :     /* Past-frame is TCX concealed as CNG and current-frame is TCX */
     337      129873 :     test();
     338      129873 :     test();
     339      129873 :     test();
     340      129873 :     test();
     341      129873 :     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      129873 :     ELSE IF( EQ_16( left_rect, 1 ) && last_core_bfi == ACELP_CORE )
     364             :     {
     365       25316 :         tmp = sub( overlap, acelp_mem_len );
     366     2404088 :         FOR( i = 0; i < tmp; i++ )
     367             :         {
     368     2378772 :             move16();
     369     2378772 :             signal[i] = 0;
     370             :         }
     371             : 
     372       25316 :         IF( fullbandScale == 0 )
     373             :         {
     374             : 
     375       16744 :             tmp = shl( acelp_mem_len, 1 ); /*Qx*/
     376             : 
     377             :             /*OLA with ACELP*/
     378      185126 :             FOR( i = 0; i < acelp_mem_len; i++ )
     379             :             {
     380             : 
     381             :                 /*window decoded TCX with aliasing*/
     382      168382 :                 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      168382 :                 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      168382 :                 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      168382 :                 move16();
     390      168382 :                 signal[i + overlap - acelp_mem_len] = tmp2; /*Qx*/
     391             :             }
     392      185126 :             FOR( ; i < tmp; i++ )
     393             :             {
     394             : 
     395             :                 /*window decoded TCX with aliasing*/
     396      168382 :                 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      168382 :                 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      168382 :                 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      168382 :                 move16();
     403      168382 :                 signal[i + overlap - acelp_mem_len] = tmp2; /*Qx*/
     404             :             }
     405             : 
     406      284648 :             FOR( i = 0; i < M; i++ )
     407             :             {
     408      267904 :                 move16();
     409      267904 :                 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       25316 :         move16();
     414       25316 :         acelp_zir_len = 64;
     415             : 
     416       25316 :         IF( fullbandScale == 0 )
     417             :         {
     418       16744 :             set16_fx( acelp_zir, 0, acelp_zir_len );
     419       16744 :             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        8572 :             tmp = extract_l( L_shr( L_mult0( acelp_zir_len, fullbandScale ), LD_FSCALE_DENOM ) ); /*Q0*/
     424        8572 :             lerp( acelp_zir, tmp_buf, tmp, acelp_zir_len );
     425        8572 :             acelp_zir_len = tmp; /*Q0*/
     426        8572 :             move16();
     427        8572 :             acelp_zir = tmp_buf; /*Qx*/
     428             : 
     429             : 
     430        8572 :             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     1283234 :                 FOR( i = 2; i < acelp_zir_len; i++ )
     434             :                 {
     435     1276724 :                     L_tmp = L_mult( acelp_zir[i - 2], 8192 /*0.25 in Q15*/ );
     436     1276724 :                     L_tmp = L_mac( L_tmp, acelp_zir[i - 1], 11469 /*0.35 in Q15*/ );
     437     1276724 :                     acelp_zir[i] = mac_r( L_tmp, acelp_zir[i], 13107 /*0.40 in Q15*/ ); /*Qx*/
     438     1276724 :                     move16();
     439             :                 }
     440             : 
     441        6510 :                 L_tmp = L_mult( acelp_zir[acelp_zir_len - 1], 13107 /*0.40 in Q15*/ );
     442        6510 :                 L_tmp = L_mac( L_tmp, acelp_zir[acelp_zir_len - 1], 11469 /*0.35 in Q15*/ );
     443        6510 :                 acelp_zir[acelp_zir_len - 1] = mac_r( L_tmp, acelp_zir[acelp_zir_len - 2], 8192 /*0.25 in Q15*/ ); /*Qx*/
     444        6510 :                 move16();
     445        6510 :                 L_tmp = L_mult( acelp_zir[acelp_zir_len - 2], 13107 );
     446        6510 :                 L_tmp = L_mac( L_tmp, acelp_zir[acelp_zir_len - 1], 11469 );
     447        6510 :                 acelp_zir[acelp_zir_len - 2] = mac_r( L_tmp, acelp_zir[acelp_zir_len - 1], 8192 ); /*Qx*/
     448        6510 :                 move16();
     449     1283234 :                 FOR( i = acelp_zir_len - 3; i >= 0; i-- )
     450             :                 {
     451     1276724 :                     L_tmp = L_mult( acelp_zir[i], 13107 );
     452     1276724 :                     L_tmp = L_mac( L_tmp, acelp_zir[i + 1], 11469 );
     453     1276724 :                     acelp_zir[i] = mac_r( L_tmp, acelp_zir[i + 2], 8192 ); /*Qx*/
     454     1276724 :                     move16();
     455             :                 }
     456             :             }
     457             :         }
     458             : 
     459     2577308 :         FOR( i = 0; i < acelp_zir_len; i++ )
     460             :         {
     461             :             /*remove reconstructed ZIR and add ACELP ZIR*/
     462     2551992 :             move16();
     463     2551992 :             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      104557 :     ELSE IF( left_rect == 1 && last_core_bfi != ACELP_CORE )
     468             :     {
     469         312 :         n = add( overlap, acelp_mem_len ); /*q0*/
     470       39064 :         FOR( i = 0; i < n; i++ )
     471             :         {
     472       38752 :             move16();
     473       38752 :             signal[i] = 0;
     474             :         }
     475             : 
     476         312 :         n = shr( window_length, 1 ); /*q0*/
     477       34220 :         FOR( i = 0; i < n; i++ )
     478             :         {
     479       33908 :             move16();
     480       33908 :             signal[i + overlap + acelp_mem_len] = mult_r( signal[i + overlap + acelp_mem_len], window[i].v.im ); /*Qx*/
     481             :         }
     482       34220 :         FOR( ; i < window_length; i++ )
     483             :         {
     484       33908 :             move16();
     485       33908 :             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      104245 :     ELSE IF( left_rect != 1 && last_core_bfi == ACELP_CORE )
     490             :     {
     491             : 
     492          16 :         n = shr( window_length, 1 ); /*q0*/
     493        2438 :         FOR( i = 0; i < n; i++ )
     494             :         {
     495        2422 :             move16();
     496        2422 :             signal[i] = mult_r( signal[i], window[i].v.im ); /*Qx*/
     497             :         }
     498        2438 :         FOR( ; i < window_length; i++ )
     499             :         {
     500        2422 :             move16();
     501        2422 :             signal[i] = mult_r( signal[i], window[window_length - 1 - i].v.re ); /*Qx*/
     502             :         }
     503             : 
     504        4860 :         FOR( i = 0; i < window_length /*acelp_zir_len*/; i++ )
     505             :         {
     506        4844 :             move16();
     507        4844 :             signal[i] = add( signal[i], syn_overl[i] ); /*Qx*/
     508             :         }
     509             :     }
     510             :     /* Normal window (past-frame is TCX) */
     511             :     ELSE
     512             :     {
     513      104229 :         IF( EQ_16( left_mode, 2 ) ) /* min. overlap */
     514             :         {
     515       62647 :             n = shr( sub( window_length, window_min_length ), 1 ); /*q0*/
     516     2872719 :             FOR( i = 0; i < n; i++ )
     517             :             {
     518     2810072 :                 *signal++ = 0;
     519     2810072 :                 move16();
     520             :             }
     521             : 
     522       62647 :             n = shr( window_min_length, 1 ); /*q0*/
     523     1399887 :             FOR( i = 0; i < n; i++ )
     524             :             {
     525     1337240 :                 *signal = mult_r( *signal, window_min[i].v.im ); /*Qx*/
     526     1337240 :                 move16();
     527     1337240 :                 signal++;
     528             :             }
     529     1399887 :             FOR( i = 0; i < n; i++ )
     530             :             {
     531     1337240 :                 *signal = mult_r( *signal, window_min[n - 1 - i].v.re ); /*Qx*/
     532     1337240 :                 move16();
     533     1337240 :                 signal++;
     534             :             }
     535             :         }
     536       41582 :         ELSE IF( EQ_16( left_mode, 3 ) ) /* half OL */
     537             :         {
     538             :             Word16 w;
     539             : 
     540       15059 :             n = shr( sub( window_length, window_half_length ), 1 );
     541      363419 :             FOR( i = 0; i < n; i++ )
     542             :             {
     543      348360 :                 move16();
     544      348360 :                 signal[i] = 0;
     545             :             }
     546       15059 :             n = shr( window_half_length, 1 );
     547      977081 :             FOR( w = 0; w < n; w++ )
     548             :             {
     549      962022 :                 move16();
     550      962022 :                 signal[i] = mult_r( signal[i], window_half[w].v.im ); /*Qx*/
     551      962022 :                 i = add( i, 1 );
     552             :             }
     553      977081 :             FOR( w = 0; w < n; w++ )
     554             :             {
     555      962022 :                 move16();
     556      962022 :                 signal[i] = mult_r( signal[i], window_half[window_half_length / 2 - 1 - w].v.re ); /*Qx*/
     557      962022 :                 i = add( i, 1 );
     558             :             }
     559             :         }
     560             :         ELSE
     561             :         { /* normal full/maximum overlap */
     562             : 
     563       26523 :             n = shr( window_length, 1 );
     564     4019071 :             FOR( i = 0; i < n; i++ )
     565             :             {
     566     3992548 :                 move16();
     567     3992548 :                 signal[i] = mult_r( signal[i], window[i].v.im ); /*Qx*/
     568             :             }
     569     4019071 :             FOR( ; i < window_length; i++ )
     570             :             {
     571     3992548 :                 move16();
     572     3992548 :                 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      129873 : }
     579             : /*-------------------------------------------------------------------*
     580             :  * tcx_windowing_synthesis_past_frame()
     581             :  *
     582             :  *
     583             :  *-------------------------------------------------------------------*/
     584      131300 : 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      131300 :     IF( EQ_16( right_mode, 2 ) ) /* min. overlap */
     599             :     {
     600       66544 :         signal += shr( sub( window_length, window_min_length ), 1 ); /*Qx*/
     601             : 
     602       66544 :         n = shr( window_min_length, 1 );
     603     1490252 :         FOR( i = 0; i < n; i++ )
     604             :         {
     605     1423708 :             *signal = mult_r( *signal, window_min[i].v.re ); /*Qx*/
     606     1423708 :             move16();
     607     1423708 :             signal++;
     608             :         }
     609     1490252 :         FOR( i = 0; i < n; i++ )
     610             :         {
     611     1423708 :             *signal = mult_r( *signal, window_min[n - 1 - i].v.im ); /*Qx*/
     612     1423708 :             move16();
     613     1423708 :             signal++;
     614             :         }
     615             : 
     616       66544 :         n = shr( sub( window_length, window_min_length ), 1 ); /*Q0*/
     617     4509504 :         FOR( i = 0; i < n; i++ )
     618             :         {
     619     4442960 :             *signal = 0;
     620     4442960 :             move16();
     621     4442960 :             signal++;
     622             :         }
     623             :     }
     624       64756 :     ELSE IF( EQ_16( right_mode, 3 ) ) /* half OL */
     625             :     {
     626             :         Word16 w;
     627             : 
     628       17106 :         i = shr( sub( window_length, window_half_length ), 1 ); /*Q0*/
     629       17106 :         n = shr( window_half_length, 1 );                       /*Q0*/
     630     1095930 :         FOR( w = 0; w < n; w++ )
     631             :         {
     632     1078824 :             signal[i] = mult_r( signal[i], window_half[w].v.re ); /*Qx*/
     633     1078824 :             move16();
     634     1078824 :             i = add( i, 1 );
     635             :         }
     636     1095930 :         FOR( w = 0; w < n; w++ )
     637             :         {
     638     1078824 :             signal[i] = mult_r( signal[i], window_half[window_half_length / 2 - 1 - w].v.im ); /*Qx*/
     639     1078824 :             move16();
     640     1078824 :             i = add( i, 1 );
     641             :         }
     642     1455538 :         FOR( ; i < window_length; i++ )
     643             :         {
     644     1438432 :             move16();
     645     1438432 :             signal[i] = 0;
     646             :         }
     647             :     }
     648             :     ELSE /* normal full/maximum overlap */
     649             :     {
     650             : 
     651       47650 :         n = shr( window_length, 1 ); /*Q0*/
     652     6177424 :         FOR( i = 0; i < n; i++ )
     653             :         {
     654     6129774 :             move16();
     655     6129774 :             signal[i] = mult_r( signal[i], window[i].v.re ); /*Qx*/
     656     6129774 :             move16();
     657     6129774 :             signal[window_length - 1 - i] = mult_r( signal[window_length - 1 - i], window[i].v.im ); /*Qx*/
     658             :         }
     659             :     }
     660      131300 : }
     661             : /*-------------------------------------------------------------------*
     662             :  * lpc2mdct()
     663             :  *
     664             :  *
     665             :  *-------------------------------------------------------------------*/
     666             : 
     667      275727 : 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      275727 :     assert( length <= FDNS_NPTS );
     689      275727 :     sizeN = shl( length, 1 ); /*Q0*/
     690             : 
     691      275727 :     BASOP_getTables( NULL, &ptwiddle, &step, sizeN );
     692             :     /*ODFT*/
     693      275727 :     assert( lpcOrder < FDNS_NPTS );
     694             :     /* pre-twiddle */
     695     4980530 :     FOR( i = 0; i <= lpcOrder; i++ )
     696             :     {
     697     4704803 :         ComplexData[2 * i] = L_mult( lpcCoeffs[i], ptwiddle->v.re ); /*Q12*/
     698     4704803 :         move32();
     699     4704803 :         ComplexData[2 * i + 1] = L_negate( L_mult( lpcCoeffs[i], ptwiddle->v.im ) ); /*Q12*/
     700     4704803 :         move32();
     701     4704803 :         ptwiddle += step;
     702             :     }
     703             :     /* zero padding */
     704    13217452 :     FOR( ; i < FDNS_NPTS; i++ )
     705             :     {
     706    12941725 :         ComplexData[2 * i] = L_deposit_l( 0 );
     707    12941725 :         move32();
     708    12941725 :         ComplexData[2 * i + 1] = L_deposit_l( 0 );
     709    12941725 :         move32();
     710             :     }
     711             : 
     712      275727 :     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      275727 :         scale = add( norm_s( lpcCoeffs[0] ), 1 );
     732      275727 :         BASOP_cfft( (cmplx *) ComplexData, FDNS_NPTS, &scale, workBuffer ); /*Q31 - scale*/
     733             :         /*Get amplitude*/
     734      275727 :         j = sub( length, 1 );
     735      275727 :         k = 0;
     736     9098991 :         FOR( i = 0; i < length / 2; i++ )
     737             :         {
     738     8823264 :             s = sub( norm_l( L_max( L_abs( ComplexData[2 * i] ), L_abs( ComplexData[2 * i + 1] ) ) ), 1 );
     739     8823264 :             tmp16 = extract_h( L_shl( ComplexData[2 * i], s ) );     /*Q15 - scale + s*/
     740     8823264 :             tmp32 = L_mult( tmp16, tmp16 );                          /*Q15 - 2*(scale - s)*/
     741     8823264 :             tmp16 = extract_h( L_shl( ComplexData[2 * i + 1], s ) ); /*Q15 - scale + s*/
     742     8823264 :             tmp16 = mac_r( tmp32, tmp16, tmp16 );                    /*Q15 - 2*(scale - s)*/
     743     8823264 :             s = shl( sub( scale, s ), 1 );
     744     8823264 :             if ( tmp16 == 0 )
     745             :             {
     746           0 :                 s = -16;
     747           0 :                 move16();
     748             :             }
     749     8823264 :             if ( tmp16 == 0 )
     750             :             {
     751           0 :                 tmp16 = 1;
     752           0 :                 move16();
     753             :             }
     754     8823264 :             BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e ); /*Q15 - ig_e*/
     755     8823264 :             if ( mdct_gains != 0 )
     756             :             {
     757     8244768 :                 mdct_gains[k] = g; /*Q15 - g_e*/
     758     8244768 :                 move16();
     759             :             }
     760     8823264 :             if ( mdct_gains_exp != 0 )
     761             :             {
     762     8244768 :                 mdct_gains_exp[k] = g_e;
     763     8244768 :                 move16();
     764             :             }
     765     8823264 :             if ( mdct_inv_gains != 0 )
     766             :             {
     767     8231456 :                 mdct_inv_gains[k] = ig; /*Q15 - ig_e*/
     768     8231456 :                 move16();
     769             :             }
     770     8823264 :             if ( mdct_inv_gains_exp != 0 )
     771             :             {
     772     8231456 :                 mdct_inv_gains_exp[k] = ig_e;
     773     8231456 :                 move16();
     774             :             }
     775     8823264 :             k = add( k, 1 );
     776     8823264 :             s = sub( norm_l( L_max( L_abs( ComplexData[2 * j] ), L_abs( ComplexData[2 * j + 1] ) ) ), 1 );
     777     8823264 :             tmp16 = extract_h( L_shl( ComplexData[2 * j], s ) );     /*Q15 - scale + s*/
     778     8823264 :             tmp32 = L_mult( tmp16, tmp16 );                          /*Q15 - 2*(scale - s)*/
     779     8823264 :             tmp16 = extract_h( L_shl( ComplexData[2 * j + 1], s ) ); /*Q15 - scale + s*/
     780     8823264 :             tmp16 = mac_r( tmp32, tmp16, tmp16 );                    /*Q15 - 2*(scale - s)*/
     781     8823264 :             s = shl( sub( scale, s ), 1 );
     782     8823264 :             if ( tmp16 == 0 )
     783             :             {
     784           0 :                 s = -16;
     785           0 :                 move16();
     786             :             }
     787     8823264 :             if ( tmp16 == 0 )
     788             :             {
     789           0 :                 tmp16 = 1;
     790           0 :                 move16();
     791             :             }
     792     8823264 :             BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     793     8823264 :             if ( mdct_gains != 0 )
     794             :             {
     795     8244768 :                 mdct_gains[k] = g; /*Q15 - g_e*/
     796     8244768 :                 move16();
     797             :             }
     798     8823264 :             if ( mdct_gains_exp != 0 )
     799             :             {
     800     8244768 :                 mdct_gains_exp[k] = g_e;
     801     8244768 :                 move16();
     802             :             }
     803     8823264 :             if ( mdct_inv_gains != 0 )
     804             :             {
     805     8231456 :                 mdct_inv_gains[k] = ig; /*Q15 - ig_e*/
     806     8231456 :                 move16();
     807             :             }
     808     8823264 :             if ( mdct_inv_gains_exp != 0 )
     809             :             {
     810     8231456 :                 mdct_inv_gains_exp[k] = ig_e;
     811     8231456 :                 move16();
     812             :             }
     813     8823264 :             j = sub( j, 1 );
     814     8823264 :             k = add( k, 1 );
     815             :         }
     816             :     }
     817      275727 : }
     818             : 
     819      221261 : 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      221261 :     assert( length <= FDNS_NPTS );
     835      221261 :     sizeN = shl( length, 1 ); /*Q0*/
     836             : 
     837      221261 :     BASOP_getTables( NULL, &ptwiddle, &step, sizeN );
     838             : 
     839             :     /* ODFT */
     840     3982698 :     FOR( i = 0; i < lpcOrder + 1; i++ )
     841             :     {
     842     3761437 :         RealData_fx[i] = L_mult( lpcCoeffs[i], ptwiddle->v.re ); /*Q12*/
     843     3761437 :         move32();
     844     3761437 :         ImagData_fx[i] = L_negate( L_mult( lpcCoeffs[i], ptwiddle->v.im ) ); /*Q12*/
     845     3761437 :         move32();
     846     3761437 :         ptwiddle += step;
     847             :     }
     848             : 
     849    24781232 :     FOR( ; i < sizeN; i++ )
     850             :     {
     851    24559971 :         RealData_fx[i] = L_deposit_l( 0 );
     852    24559971 :         move32();
     853    24559971 :         ImagData_fx[i] = L_deposit_l( 0 );
     854    24559971 :         move32();
     855             :     }
     856             : 
     857             :     /* half length FFT */
     858      221261 :     scale = add( norm_s( lpcCoeffs[0] ), 1 );
     859      221261 :     BASOP_cfft_ivas( RealData_fx, ImagData_fx, 1, &scale ); /*Q31 - scale*/
     860             : 
     861             :     /*Get amplitude*/
     862      221261 :     j = sub( FDNS_NPTS, 1 );
     863      221261 :     move16();
     864      221261 :     k = 0;
     865      221261 :     move16();
     866             : 
     867     7301613 :     FOR( i = 0; i < FDNS_NPTS / 2; i++ )
     868             :     {
     869     7080352 :         s = sub( norm_l( L_max( L_abs( RealData_fx[i] ), L_abs( ImagData_fx[i] ) ) ), 1 );
     870             : 
     871     7080352 :         tmp16 = extract_h( L_shl( RealData_fx[i], s ) ); /*Q15 - scale + s*/
     872     7080352 :         tmp32 = L_mult( tmp16, tmp16 );                  /*Q15 - 2*(scale - s)*/
     873             : 
     874     7080352 :         tmp16 = extract_h( L_shl( ImagData_fx[i], s ) ); /*Q15 - scale + s*/
     875     7080352 :         tmp16 = mac_r( tmp32, tmp16, tmp16 );            /*Q15 - 2*(scale - s)*/
     876             : 
     877     7080352 :         s = shl( sub( scale, s ), 1 );
     878             : 
     879     7080352 :         if ( tmp16 == 0 )
     880             :         {
     881           0 :             s = -16;
     882           0 :             move16();
     883             :         }
     884     7080352 :         if ( tmp16 == 0 )
     885             :         {
     886           0 :             tmp16 = 1;
     887           0 :             move16();
     888             :         }
     889             : 
     890     7080352 :         BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     891             : 
     892     7080352 :         if ( mdct_gains_fx != NULL )
     893             :         {
     894           0 :             mdct_gains_fx[k] = g; /*Q15 - g_e*/
     895           0 :             move16();
     896             :         }
     897             : 
     898     7080352 :         if ( mdct_gains_e != NULL )
     899             :         {
     900           0 :             mdct_gains_e[k] = g_e;
     901           0 :             move16();
     902             :         }
     903             : 
     904     7080352 :         if ( mdct_inv_gains_fx != NULL )
     905             :         {
     906     7080352 :             mdct_inv_gains_fx[k] = ig; /*Q15 - ig_e*/
     907     7080352 :             move16();
     908             :         }
     909             : 
     910     7080352 :         if ( mdct_inv_gains_e != NULL )
     911             :         {
     912     7080352 :             mdct_inv_gains_e[k] = ig_e;
     913     7080352 :             move16();
     914             :         }
     915             : 
     916     7080352 :         k = add( k, 1 );
     917             : 
     918             : 
     919     7080352 :         s = sub( norm_l( L_max( L_abs( RealData_fx[j] ), L_abs( ImagData_fx[j] ) ) ), 1 );
     920             : 
     921     7080352 :         tmp16 = extract_h( L_shl( RealData_fx[j], s ) ); /*Q15 - scale + s*/
     922     7080352 :         tmp32 = L_mult( tmp16, tmp16 );                  /*Q15 - 2*(scale - s)*/
     923             : 
     924     7080352 :         tmp16 = extract_h( L_shl( ImagData_fx[j], s ) ); /*Q15 - scale + s*/
     925     7080352 :         tmp16 = mac_r( tmp32, tmp16, tmp16 );            /*Q15 - 2*(scale - s)*/
     926             : 
     927     7080352 :         s = shl( sub( scale, s ), 1 );
     928             : 
     929     7080352 :         if ( tmp16 == 0 )
     930             :         {
     931           0 :             s = -16;
     932           0 :             move16();
     933             :         }
     934     7080352 :         if ( tmp16 == 0 )
     935             :         {
     936           0 :             tmp16 = 1;
     937           0 :             move16();
     938             :         }
     939             : 
     940     7080352 :         BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     941             : 
     942     7080352 :         if ( mdct_gains_fx != NULL )
     943             :         {
     944           0 :             mdct_gains_fx[k] = g;
     945           0 :             move16();
     946             :         }
     947             : 
     948     7080352 :         if ( mdct_gains_e != NULL )
     949             :         {
     950           0 :             mdct_gains_e[k] = g_e;
     951           0 :             move16();
     952             :         }
     953             : 
     954     7080352 :         if ( mdct_inv_gains_fx != NULL )
     955             :         {
     956     7080352 :             mdct_inv_gains_fx[k] = ig;
     957     7080352 :             move16();
     958             :         }
     959             : 
     960     7080352 :         if ( mdct_inv_gains_e != NULL )
     961             :         {
     962     7080352 :             mdct_inv_gains_e[k] = ig_e;
     963     7080352 :             move16();
     964             :         }
     965             : 
     966     7080352 :         j = sub( j, 1 );
     967     7080352 :         k = add( k, 1 );
     968             :     }
     969             : 
     970      221261 :     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      582268 : 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      582268 :     Word32 *px = x; /*Qx*/
     992      582268 :     Word16 const *pgains = gains;
     993      582268 :     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      582268 :     k = shr( lg, 6 ); /*Q0*/
    1002      582268 :     m = s_and( lg, 0x3F );
    1003             : 
    1004      582268 :     IF( m != 0 )
    1005             :     {
    1006       19264 :         IF( LE_16( m, FDNS_NPTS / 2 ) )
    1007             :         {
    1008       19264 :             n = idiv1616U( FDNS_NPTS, m ); /*Q0*/
    1009       19264 :             k1 = k;
    1010       19264 :             move16();
    1011       19264 :             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       19264 :         i = 0;
    1022       19264 :         move16();
    1023       19264 :         j = 0;
    1024       19264 :         move16();
    1025             : 
    1026     1252160 :         WHILE( LT_16( i, lg ) )
    1027             :         {
    1028             : 
    1029     1232896 :             k = k2;
    1030     1232896 :             move16();
    1031     1232896 :             if ( j != 0 )
    1032             :             {
    1033      920592 :                 k = k1;
    1034      920592 :                 move16();
    1035             :             }
    1036             : 
    1037     1232896 :             j = add( j, 1 );
    1038     1232896 :             if ( EQ_16( j, n ) )
    1039             :             {
    1040      312304 :                 j = 0;
    1041      312304 :                 move16();
    1042             :             }
    1043             : 
    1044             :             /* Limit number of loops, if end is reached */
    1045     1232896 :             k = s_min( k, sub( lg, i ) );
    1046             : 
    1047     9022576 :             FOR( l = 0; l < k; l++ )
    1048             :             {
    1049             : #ifdef ISSUE_1836_replace_overflow_libcom
    1050     7789680 :                 *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     7789680 :                 move32();
    1055     7789680 :                 x++;
    1056             :             }
    1057     1232896 :             i = add( i, k );
    1058             : 
    1059     1232896 :             gains++;
    1060     1232896 :             gains_exp++;
    1061             :         }
    1062             :     }
    1063             :     ELSE
    1064             :     {
    1065     3617533 :         FOR( l = 0; l < k; l++ )
    1066             :         {
    1067     3054529 :             x = &px[l]; /*Qx*/
    1068     3054529 :             gains = pgains;
    1069     3054529 :             gains_exp = pgainsexp;
    1070   198544385 :             FOR( i = 0; i < FDNS_NPTS; i++ )
    1071             :             {
    1072             : #ifdef ISSUE_1836_replace_overflow_libcom
    1073   195489856 :                 *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   195489856 :                 move32();
    1078   195489856 :                 x += k;
    1079   195489856 :                 gains++;
    1080   195489856 :                 gains_exp++;
    1081             :             }
    1082             :         }
    1083             :     }
    1084      582268 : }
    1085             : 
    1086         724 : 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         724 :     Word16 const *pgains = gains;
    1100             :     Word16 gains_exp_loc[FDNS_NPTS];
    1101             :     Word16 const *pgains_exp;
    1102             : 
    1103             :     /* FDNS_NPTS = 64 */
    1104         724 :     k = shr( lg, 6 ); /*Q0*/
    1105         724 :     m = s_and( lg, 0x3F );
    1106             : 
    1107         724 :     assert( m == 0 );
    1108             :     {
    1109       47060 :         FOR( i = 0; i < FDNS_NPTS; i++ )
    1110             :         {
    1111       46336 :             gains_exp_loc[i] = sub( gains_exp[i], gains_max_exp );
    1112       46336 :             move16();
    1113             :         }
    1114        5199 :         FOR( l = 0; l < k; l++ )
    1115             :         {
    1116        4475 :             px = &x[l];     /*Qx*/
    1117        4475 :             py = &y[l];     /*Qx*/
    1118        4475 :             pgains = gains; /*15 - gains_exp*/
    1119        4475 :             pgains_exp = gains_exp_loc;
    1120      290875 :             FOR( i = 0; i < FDNS_NPTS; i++ )
    1121             :             {
    1122      286400 :                 *py = L_shl( L_mult( *px, *pgains ), *pgains_exp ); /*Qx*/
    1123      286400 :                 move32();
    1124      286400 :                 px += k;
    1125      286400 :                 py += k;
    1126      286400 :                 pgains++;
    1127      286400 :                 pgains_exp++;
    1128             :             }
    1129             :         }
    1130             :     }
    1131             : 
    1132         724 :     gain_exp = sub( gains_exp[FDNS_NPTS - 1], gains_max_exp );
    1133       19998 :     FOR( i = lg; i < lg_total; i++ )
    1134             :     {
    1135       19274 :         y[i] = L_shl( L_mult( x[i], gains[FDNS_NPTS - 1] ), gain_exp ); /*Qx*/
    1136       19274 :         move32();
    1137             :     }
    1138         724 : }
    1139             : 
    1140      773981 : 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      773981 :     j = 0;
    1153      773981 :     move16();
    1154             :     /* FDNS_NPTS = 64 */
    1155      773981 :     k = shr( lg, 6 ); /*Q0*/
    1156      773981 :     m = s_and( lg, 0x3F );
    1157             : 
    1158      773981 :     Word16 max_e = MIN16B;
    1159      773981 :     move16();
    1160    50308765 :     FOR( i = 0; i < FDNS_NPTS; i++ )
    1161             :     {
    1162    49534784 :         max_e = s_max( max_e, add( *x_e, gains_exp[i] ) );
    1163             :     }
    1164             : 
    1165      773981 :     IF( m != 0 )
    1166             :     {
    1167        8246 :         IF( LE_16( m, FDNS_NPTS / 2 ) )
    1168             :         {
    1169        8246 :             n = idiv1616U( FDNS_NPTS, m ); /*Q0*/
    1170        8246 :             k1 = k;
    1171        8246 :             move16();
    1172        8246 :             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        8246 :         i = 0;
    1183        8246 :         move16();
    1184        8246 :         j = 0;
    1185        8246 :         move16();
    1186             : 
    1187      535990 :         WHILE( LT_16( i, lg ) )
    1188             :         {
    1189      527744 :             IF( j % n != 0 )
    1190             :             {
    1191      387696 :                 k = k1;
    1192      387696 :                 move16();
    1193             :             }
    1194             :             ELSE
    1195             :             {
    1196      140048 :                 k = k2;
    1197      140048 :                 move16();
    1198             :             }
    1199             : 
    1200             :             /* Limit number of loops, if end is reached */
    1201      527744 :             k = s_min( k, sub( lg, i ) );
    1202             : 
    1203     3993104 :             FOR( l = 0; l < k; l++ )
    1204             :             {
    1205     3465360 :                 x_fx[i] = Mpy_32_16_1( x_fx[i], gains_fx[j] ); /*Q31 - x_e*/
    1206     3465360 :                 move32();
    1207     3465360 :                 x_fx[i] = L_shr( x_fx[i], sub( max_e, add( *x_e, gains_exp[j] ) ) ); /*Q31 - max_e*/
    1208     3465360 :                 move32();
    1209     3465360 :                 i = add( i, 1 );
    1210             :             }
    1211      527744 :             j = add( j, 1 );
    1212             :         }
    1213             :     }
    1214             :     ELSE
    1215             :     {
    1216    49772775 :         FOR( i = 0; i < lg; )
    1217             :         {
    1218   337562880 :             FOR( l = 0; l < k; l++ )
    1219             :             {
    1220   288555840 :                 x_fx[i] = Mpy_32_16_1( x_fx[i], gains_fx[j] ); /*Q31 - x_e*/
    1221   288555840 :                 move32();
    1222   288555840 :                 x_fx[i] = L_shr( x_fx[i], sub( max_e, add( *x_e, gains_exp[j] ) ) ); /*Q31 - max_e*/
    1223   288555840 :                 move32();
    1224   288555840 :                 i = add( i, 1 );
    1225             :             }
    1226    49007040 :             j = add( j, 1 );
    1227             :         }
    1228             :     }
    1229             : 
    1230      773981 :     *x_e = max_e;
    1231      773981 :     move16();
    1232             : 
    1233      773981 :     return;
    1234             : }
    1235             : 
    1236             : 
    1237       17444 : 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       17444 :     assert( lg % FDNS_NPTS == 0 );
    1248       17444 :     k = shr( lg, 6 ); /* FDNS_NPTS = 64 Q0*/
    1249             : 
    1250       17444 :     IF( gains )
    1251             :     {
    1252             :         /* Linear interpolation */
    1253       17444 :         IF( EQ_16( k, 4 ) )
    1254             :         {
    1255       15794 :             jp = 0;
    1256       15794 :             move16();
    1257       15794 :             j = 0;
    1258       15794 :             move16();
    1259       15794 :             jn = 1;
    1260       15794 :             move16();
    1261             : 
    1262     1026610 :             FOR( i = 0; i < lg; i += 4 )
    1263             :             {
    1264     1010816 :                 pg = gains[jp]; /*Q15 - gains_exp*/
    1265     1010816 :                 move16();
    1266     1010816 :                 g = gains[j]; /*Q15 - gains_exp*/
    1267     1010816 :                 move16();
    1268     1010816 :                 ng = gains[jn]; /*Q15 - gains_exp*/
    1269     1010816 :                 move16();
    1270             : 
    1271             :                 /* common exponent for pg and g */
    1272     1010816 :                 tmp = sub( gains_exp[j], gains_exp[jp] );
    1273     1010816 :                 if ( tmp > 0 )
    1274      110930 :                     pg = shr( pg, tmp );
    1275     1010816 :                 if ( tmp < 0 )
    1276       66439 :                     g = shl( g, tmp );
    1277     1010816 :                 e = s_max( gains_exp[j], gains_exp[jp] );
    1278             : 
    1279     1010816 :                 tmp = mac_r( L_mult( pg, 12288 /*0.375f Q15*/ ), g, 20480 /*0.625f Q15*/ ); /*Q15 - gains_exp*/
    1280     1010816 :                 x[i] = L_shl( Mpy_32_16_1( x[i], tmp ), e );                                /*Qx*/
    1281     1010816 :                 move32();
    1282             : 
    1283     1010816 :                 tmp = mac_r( L_mult( pg, 4096 /*0.125f Q15*/ ), g, 28672 /*0.875f Q15*/ ); /*Q15 - gains_exp*/
    1284     1010816 :                 x[i + 1] = L_shl( Mpy_32_16_1( x[i + 1], tmp ), e );                       /*Qx*/
    1285     1010816 :                 move32();
    1286             : 
    1287             :                 /* common exponent for g and ng */
    1288     1010816 :                 g = gains[j]; /*Q15 - gains_exp*/
    1289     1010816 :                 move16();
    1290     1010816 :                 tmp = sub( gains_exp[j], gains_exp[jn] );
    1291     1010816 :                 if ( tmp > 0 )
    1292       66439 :                     ng = shr( ng, tmp );
    1293     1010816 :                 if ( tmp < 0 )
    1294      110930 :                     g = shl( g, tmp );
    1295     1010816 :                 e = s_max( gains_exp[j], gains_exp[jn] );
    1296             : 
    1297     1010816 :                 tmp = mac_r( L_mult( g, 28672 /*0.875f Q15*/ ), ng, 4096 /*0.125f Q15*/ ); /*Q15 - gains_exp*/
    1298     1010816 :                 x[i + 2] = L_shl( Mpy_32_16_1( x[i + 2], tmp ), e );                       /*Qx*/
    1299     1010816 :                 move32();
    1300             : 
    1301     1010816 :                 tmp = mac_r( L_mult( g, 20480 /*0.625f Q15*/ ), ng, 12288 /*0.375f Q15*/ ); /*Q15 - gains_exp*/
    1302     1010816 :                 x[i + 3] = L_shl( Mpy_32_16_1( x[i + 3], tmp ), e );                        /*Qx*/
    1303     1010816 :                 move32();
    1304             : 
    1305     1010816 :                 jp = j;
    1306     1010816 :                 move16();
    1307     1010816 :                 j = jn;
    1308     1010816 :                 move16();
    1309     1010816 :                 jn = s_min( add( jn, 1 ), FDNS_NPTS - 1 );
    1310             :             }
    1311             :         }
    1312        1650 :         ELSE IF( EQ_16( k, 5 ) )
    1313             :         {
    1314        1650 :             jp = 0;
    1315        1650 :             move16();
    1316        1650 :             j = 0;
    1317        1650 :             move16();
    1318        1650 :             jn = 1;
    1319        1650 :             move16();
    1320             : 
    1321      107250 :             FOR( i = 0; i < lg; i += 5 )
    1322             :             {
    1323      105600 :                 pg = gains[jp]; /*Q15 - gains_exp*/
    1324      105600 :                 move16();
    1325      105600 :                 g = gains[j]; /*Q15 - gains_exp*/
    1326      105600 :                 move16();
    1327      105600 :                 ng = gains[jn]; /*Q15 - gains_exp*/
    1328      105600 :                 move16();
    1329             : 
    1330             :                 /* common exponent for pg and g */
    1331      105600 :                 tmp = sub( gains_exp[j], gains_exp[jp] );
    1332      105600 :                 if ( tmp > 0 )
    1333       11197 :                     pg = shr( pg, tmp );
    1334      105600 :                 if ( tmp < 0 )
    1335        6554 :                     g = shl( g, tmp );
    1336      105600 :                 e = s_max( gains_exp[j], gains_exp[jp] );
    1337             : 
    1338      105600 :                 tmp = mac_r( L_mult( pg, 13107 /*0.40f Q15*/ ), g, 19661 /*0.60f Q15*/ ); /*Q15 - gains_exp*/
    1339      105600 :                 x[i] = L_shl( Mpy_32_16_1( x[i], tmp ), e );                              /*Qx*/
    1340      105600 :                 move32();
    1341             : 
    1342      105600 :                 tmp = mac_r( L_mult( pg, 6554 /*0.20f Q15*/ ), g, 26214 /*0.80f Q15*/ ); /*Q15 - gains_exp*/
    1343      105600 :                 x[i + 1] = L_shl( Mpy_32_16_1( x[i + 1], tmp ), e );                     /*Qx*/
    1344      105600 :                 move32();
    1345             : 
    1346             : 
    1347      105600 :                 x[i + 2] = L_shl( Mpy_32_16_1( x[i + 2], gains[j] ), gains_exp[j] ); /*Qx*/
    1348      105600 :                 move32();
    1349             : 
    1350             :                 /* common exponent for g and ng */
    1351      105600 :                 g = gains[j]; /*Q15 - gains_exp*/
    1352      105600 :                 move16();
    1353      105600 :                 tmp = sub( gains_exp[j], gains_exp[jn] );
    1354      105600 :                 if ( tmp > 0 )
    1355        6554 :                     ng = shr( ng, tmp );
    1356      105600 :                 if ( tmp < 0 )
    1357       11197 :                     g = shl( g, tmp );
    1358      105600 :                 e = s_max( gains_exp[j], gains_exp[jn] );
    1359             : 
    1360      105600 :                 tmp = mac_r( L_mult( g, 26214 /*0.80f Q15*/ ), ng, 6554 /*0.20f Q15*/ ); /*Q15 - gains_exp*/
    1361      105600 :                 x[i + 3] = L_shl( Mpy_32_16_1( x[i + 3], tmp ), e );                     /*Qx*/
    1362      105600 :                 move32();
    1363             : 
    1364      105600 :                 tmp = mac_r( L_mult( g, 19661 /*0.60f Q15*/ ), ng, 13107 /*0.40f Q15*/ ); /*Q15 - gains_exp*/
    1365      105600 :                 x[i + 4] = L_shl( Mpy_32_16_1( x[i + 4], tmp ), e );                      /*Qx*/
    1366      105600 :                 move32();
    1367             : 
    1368      105600 :                 jp = j;
    1369      105600 :                 move16();
    1370      105600 :                 j = jn;
    1371      105600 :                 move16();
    1372      105600 :                 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       17444 : }
    1392             : 
    1393       56333 : 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       56333 :     assert( lpcGains[0] >= 0x4000 );
    1410             : 
    1411       56333 :     max_val = lpcGains[0]; /*Q15 - lpcGains_e*/
    1412       56333 :     move16();
    1413       56333 :     max_e = lpcGains_e[0];
    1414       56333 :     move16();
    1415       56333 :     min = lpcGains[0]; /*Q15 - lpcGains_e*/
    1416       56333 :     move16();
    1417       56333 :     min_e = lpcGains_e[0];
    1418       56333 :     move16();
    1419             : 
    1420             :     /* find minimum (min) and maximum (max_val) of LPC gains in low frequencies */
    1421      506997 :     FOR( i = 1; i < 9; i++ )
    1422             :     {
    1423      450664 :         IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], min, min_e ) < 0 )
    1424             :         {
    1425      333414 :             min = lpcGains[i]; /*Q15 - lpcGains_e*/
    1426      333414 :             move16();
    1427      333414 :             min_e = lpcGains_e[i];
    1428      333414 :             move16();
    1429             :         }
    1430             : 
    1431      450664 :         IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], max_val, max_e ) > 0 )
    1432             :         {
    1433       82499 :             max_val = lpcGains[i]; /*Q15 - lpcGains_e*/
    1434       82499 :             move16();
    1435       82499 :             max_e = lpcGains_e[i];
    1436       82499 :             move16();
    1437             :         }
    1438             :     }
    1439             : 
    1440       56333 :     min_e = add( min_e, 5 ); /* min *= 32.0f; */
    1441             : 
    1442       56333 :     test();
    1443       56333 :     IF( ( compMantExp16Unorm( max_val, max_e, min, min_e ) < 0 ) && ( min > 0 ) )
    1444             :     {
    1445             :         /* fac = tmp = (float)pow(max_val / min, 0.0078125f); */
    1446       56333 :         tmp_e = min_e;
    1447       56333 :         move16();
    1448       56333 :         tmp = Inv16( min, &tmp_e ); /*Q15 - tmp_e*/
    1449             : #ifdef FIX_1984_SAT_IN_PSYCHAD
    1450       56333 :         L_tmp = L_shl_sat( L_mult_sat( tmp, max_val ), add( tmp_e, max_e ) ); /* Q31 */
    1451             : #else
    1452             :         L_tmp = L_shl( L_mult( tmp, max_val ), add( tmp_e, max_e ) );                     /* Q31 */
    1453             : #endif
    1454       56333 :         L_tmp = BASOP_Util_Log2( L_tmp );    /* Q25 */
    1455       56333 :         L_tmp = L_shr( L_tmp, 7 );           /* 0.0078125f = 1.f/(1<<7) */
    1456       56333 :         L_tmp = BASOP_Util_InvLog2( L_tmp ); /* Q31 */
    1457             : #ifdef ISSUE_1836_replace_overflow_libcom
    1458       56333 :         tmp = round_fx_sat( L_tmp ); /* Q15 */
    1459             : #else
    1460             :         tmp = round_fx_o( L_tmp, &Overflow );                                             /* Q15 */
    1461             : #endif
    1462       56333 :         fac = tmp; /* Q15 */
    1463       56333 :         move16();
    1464             : 
    1465             :         /* gradual lowering of lowest 32 bins; DC is lowered by (max_val/tmp)^1/4 */
    1466     1858989 :         FOR( i = 31; i >= 0; i-- )
    1467             :         {
    1468     1802656 :             x[i] = Mpy_32_16_1( x[i], fac );
    1469     1802656 :             move32();
    1470     1802656 :             if ( lf_deemph_factors != NULL )
    1471             :             {
    1472     1007552 :                 lf_deemph_factors[i] = mult_r( lf_deemph_factors[i], fac );
    1473     1007552 :                 move16();
    1474             :             }
    1475     1802656 :             fac = mult_r( fac, tmp ); /* Q15 */
    1476             :         }
    1477             :     }
    1478       56333 : }
    1479             : 
    1480      264359 : void AdaptLowFreqDeemph(
    1481             :     Word32 x[], /*Q31 - x_e*/
    1482             :     Word16 x_e,
    1483             :     Word16 tcx_lpc_shaped_ari, /*Q0*/
    1484             :     Word16 lpcGains[],         /*Q15 - lpcGains_e*/
    1485             :     Word16 lpcGains_e[],
    1486             :     const Word16 lg, /*Q0*/
    1487             :     Word16 lf_deemph_factors[] /*Q15*/ )
    1488             : {
    1489             : 
    1490             :     Word16 i, i_max, i_max_old, lg_4;
    1491             :     Word32 v2, v4, tmp32;
    1492             : 
    1493      264359 :     tmp32 = 0; /* to avoid compilation warnings */
    1494      264359 :     move32();
    1495             : 
    1496      264359 :     IF( tcx_lpc_shaped_ari == 0 )
    1497             :     {
    1498      215429 :         v2 = L_shl( 2, sub( 31, x_e ) ); /* 2.0 */
    1499      215429 :         v4 = L_shl( v2, 1 );             /* 4.0 */
    1500      215429 :         lg_4 = shr( lg, 2 );             /* lg/4 */
    1501             : 
    1502             :         /* 1. find first magnitude maximum in lower quarter of spectrum */
    1503      215429 :         i_max = -1;
    1504      215429 :         move16();
    1505             : 
    1506     1259123 :         FOR( i = 0; i < lg_4; i++ )
    1507             :         {
    1508     1251884 :             IF( GE_32( L_abs( x[i] ), v4 ) )
    1509             :             {
    1510             : 
    1511             :                 /* Debug initialization to catch illegal x[i] values. */
    1512      208190 :                 tmp32 = 0;
    1513      208190 :                 move32();
    1514             : 
    1515      208190 :                 if ( x[i] < 0 )
    1516      103932 :                     tmp32 = L_add( x[i], v2 ); /*Q31 - x_e*/
    1517      208190 :                 if ( x[i] > 0 )
    1518      104258 :                     tmp32 = L_sub( x[i], v2 ); /*Q31 - x_e*/
    1519             : 
    1520      208190 :                 assert( tmp32 != 0 );
    1521             : 
    1522      208190 :                 x[i] = tmp32; /*Q31 - x_e*/
    1523      208190 :                 move32();
    1524      208190 :                 i_max = i;
    1525      208190 :                 move16();
    1526      208190 :                 BREAK;
    1527             :             }
    1528             :         }
    1529             : 
    1530             :         /* 2. expand value range of all xi up to i_max: two extra steps */
    1531      716243 :         FOR( i = 0; i < i_max; i++ )
    1532             :         {
    1533      500814 :             x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1534      500814 :             move32();
    1535      500814 :             lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1536      500814 :             move16();
    1537             :         }
    1538             : 
    1539             :         /* 3. find first magnitude maximum in lower quarter of spectrum */
    1540      215429 :         i_max_old = i_max; /*Q0*/
    1541      215429 :         move16();
    1542             : 
    1543      215429 :         IF( i_max_old >= 0 )
    1544             :         {
    1545      208190 :             i_max = -1;
    1546      208190 :             move16();
    1547             : 
    1548     1048750 :             FOR( i = 0; i < lg_4; i++ )
    1549             :             {
    1550     1048738 :                 IF( GE_32( L_abs( x[i] ), v4 ) )
    1551             :                 {
    1552      208178 :                     assert( x[i] != 0 );
    1553      208178 :                     if ( x[i] < 0 )
    1554      104463 :                         tmp32 = L_add( x[i], v2 ); /*Q31 - x_e*/
    1555      208178 :                     if ( x[i] >= 0 )
    1556      103715 :                         tmp32 = L_sub( x[i], v2 ); /*Q31 - x_e*/
    1557      208178 :                     x[i] = tmp32;                  /*Q31 - x_e*/
    1558      208178 :                     move32();
    1559      208178 :                     i_max = i;
    1560      208178 :                     move16();
    1561      208178 :                     BREAK;
    1562             :                 }
    1563             :             }
    1564             :         }
    1565             : 
    1566             :         /* 4. expand value range of all xi up to i_max: two extra steps */
    1567     1055189 :         FOR( i = 0; i < i_max; i++ )
    1568             :         {
    1569      839760 :             x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1570      839760 :             move32();
    1571      839760 :             lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1572      839760 :             move16();
    1573             :         }
    1574             : 
    1575             :         /* 5. always expand two lines; lines could be at index 0 and 1! */
    1576      215429 :         i_max = s_max( i_max, i_max_old ); /*Q0*/
    1577      215429 :         i = add( i_max, 1 );
    1578             : 
    1579      215429 :         IF( x[i] < 0 )
    1580             :         {
    1581       95575 :             tmp32 = L_sub( x[i], L_negate( v4 ) );
    1582             : 
    1583       95575 :             if ( tmp32 > 0 )
    1584             :             {
    1585       34013 :                 lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1586       34013 :                 move16();
    1587             :             }
    1588       95575 :             if ( tmp32 <= 0 )
    1589             :             {
    1590       61562 :                 x[i] = L_add( x[i], v2 ); /*Q31 - x_e*/
    1591       61562 :                 move32();
    1592             :             }
    1593       95575 :             if ( tmp32 > 0 )
    1594             :             {
    1595       34013 :                 x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1596       34013 :                 move32();
    1597             :             }
    1598             :         }
    1599             :         ELSE
    1600             :         {
    1601      119854 :             tmp32 = L_sub( x[i], v4 );
    1602             : 
    1603      119854 :             if ( tmp32 < 0 )
    1604             :             {
    1605       56422 :                 lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1606       56422 :                 move16();
    1607             :             }
    1608      119854 :             if ( tmp32 >= 0 )
    1609             :             {
    1610       63432 :                 x[i] = L_sub( x[i], v2 ); /*Q31 - x_e*/
    1611       63432 :                 move32();
    1612             :             }
    1613      119854 :             if ( tmp32 < 0 )
    1614             :             {
    1615       56422 :                 x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1616       56422 :                 move32();
    1617             :             }
    1618             :         }
    1619      215429 :         i = add( i, 1 );
    1620             : 
    1621      215429 :         IF( x[i] < 0 )
    1622             :         {
    1623       92028 :             tmp32 = L_sub( x[i], L_negate( v4 ) );
    1624             : 
    1625       92028 :             if ( tmp32 > 0 )
    1626             :             {
    1627       35995 :                 lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1628       35995 :                 move16();
    1629             :             }
    1630       92028 :             if ( tmp32 <= 0 )
    1631             :             {
    1632       56033 :                 x[i] = L_add( x[i], v2 ); /*Q31 - x_e*/
    1633       56033 :                 move32();
    1634             :             }
    1635       92028 :             if ( tmp32 > 0 )
    1636             :             {
    1637       35995 :                 x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1638       35995 :                 move32();
    1639             :             }
    1640             :         }
    1641             :         ELSE
    1642             :         {
    1643      123401 :             tmp32 = L_sub( x[i], v4 );
    1644             : 
    1645      123401 :             if ( tmp32 < 0 )
    1646             :             {
    1647       67511 :                 lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1648       67511 :                 move16();
    1649             :             }
    1650      123401 :             if ( tmp32 >= 0 )
    1651             :             {
    1652       55890 :                 x[i] = L_sub( x[i], v2 ); /*Q31 - x_e*/
    1653       55890 :                 move32();
    1654             :             }
    1655      123401 :             if ( tmp32 < 0 )
    1656             :             {
    1657       67511 :                 x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1658       67511 :                 move32();
    1659             :             }
    1660             :         }
    1661             :     }
    1662             :     ELSE /*if(!tcx_lpc_shaped_ari)*/
    1663             :     {
    1664       48930 :         PsychAdaptLowFreqDeemph( x, lpcGains, lpcGains_e, lf_deemph_factors );
    1665             :     } /*if(!tcx_lpc_shaped_ari)*/
    1666      264359 : }
    1667             : 
    1668      221178 : void tcx_noise_filling(
    1669             :     Word32 *Q, /*Q31 - Q_e*/
    1670             :     Word16 Q_e,
    1671             :     Word16 seed,
    1672             :     const Word16 iFirstLine,     /*Q0*/
    1673             :     const Word16 lowpassLine,    /*Q0*/
    1674             :     const Word16 nTransWidth,    /*Q0*/
    1675             :     const Word16 L_frame,        /*Q0*/
    1676             :     const Word16 tiltCompFactor, /*Q15*/
    1677             :     Word16 fac_ns,               /*Q15*/
    1678             :     Word16 *infoTCXNoise,        /*Q0*/
    1679             :     const Word16 element_mode    /* i  : IVAS element mode   Q0*/
    1680             : )
    1681             : {
    1682             :     Word16 i, m, segmentOffset;
    1683             :     Word16 win; /* window coefficient */
    1684             :     Word16 tilt_factor;
    1685             :     Word32 nrg;
    1686             :     Word16 tmp1, tmp2, s;
    1687             :     Word32 tmp32;
    1688             : 
    1689             : 
    1690             :     /* get inverse frame length */
    1691      221178 :     tmp1 = getInvFrameLen( L_frame ); /*Q21*/
    1692             : 
    1693             :     /* tilt_factor = (float)pow(max_val(0.375f, tiltCompFactor), 1.0f/(float)L_frame); */
    1694      221178 :     tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */
    1695      221178 :     tmp32 = L_shr( Mpy_32_16_1( tmp32, tmp1 ), 6 );                            /*Q25*/
    1696             :     BASOP_SATURATE_WARNING_OFF_EVS;
    1697      221178 :     tilt_factor = round_fx_sat( BASOP_Util_InvLog2( tmp32 ) ); /*Q15*/
    1698             :     BASOP_SATURATE_WARNING_ON_EVS;
    1699             : 
    1700             :     /* find last nonzero line below iFirstLine, use it as start offset */
    1701      221178 :     i = iFirstLine;
    1702      221178 :     move16();
    1703      221178 :     tmp1 = shr( iFirstLine, 1 );               /*Q0*/
    1704      221178 :     IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */
    1705             :     {
    1706           0 :         segmentOffset = i;
    1707           0 :         move16();
    1708             :     }
    1709             :     ELSE
    1710             :     {
    1711      657831 :         FOR( ; i > tmp1; i-- )
    1712             :         {
    1713      656549 :             IF( Q[i] != 0 )
    1714             :             {
    1715      219896 :                 BREAK;
    1716             :             }
    1717             :         }
    1718             :         /* fac_ns *= (float)pow(tilt_factor, (float)i); */
    1719    15124497 :         FOR( m = 0; m < i; m++ )
    1720             :         {
    1721    14903319 :             fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
    1722             :         }
    1723      221178 :         i = add( i, 1 );
    1724      221178 :         segmentOffset = i;
    1725             :     }
    1726      221178 :     nrg = L_deposit_l( 1 );
    1727      221178 :     win = 0;
    1728      221178 :     move16();
    1729             : 
    1730    66645995 :     FOR( ; i < lowpassLine; i++ )
    1731             :     {
    1732    66424817 :         fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
    1733             : 
    1734    66424817 :         IF( Q[i] != 0 )
    1735             :         {
    1736    18815257 :             IF( win > 0 )
    1737             :             {
    1738             :                 /* RMS-normalize current noise-filled segment */
    1739     9441726 :                 tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( i, segmentOffset ), &s ); /* mean */
    1740     9441726 :                 s = add( s, 9 - 15 );                                                   /* scaling */
    1741     9441726 :                 tmp1 = ISqrt16( tmp1, &s );                                             /* 1/RMS Q15 - s*/
    1742     9441726 :                 tmp1 = mult_r( tmp1, inv_int[nTransWidth] );                            /* compensate win Q15 - s*/
    1743     9441726 :                 s = add( s, sub( 16, Q_e ) );                                           /* scaling */
    1744             : 
    1745     9441726 :                 tmp2 = sub( i, win );
    1746     9441726 :                 IF( LT_16( segmentOffset, tmp2 ) )
    1747             :                 {
    1748    10011092 :                     FOR( m = segmentOffset; m < tmp2; m++ )
    1749             :                     {
    1750     8807711 :                         Q[m] = L_shl( Mpy_32_16_1( Q[m], tmp1 ), s ); /*Q31 - Q_e*/
    1751     8807711 :                         move32();
    1752             :                     }
    1753             :                 }
    1754             : 
    1755     9441726 :                 tmp2 = mult( tmp1, inv_int[nTransWidth] );
    1756     9441726 :                 tmp1 = extract_l( L_mult0( tmp2, win ) );
    1757    36404104 :                 FOR( m = sub( i, win ); m < i; m++ )
    1758             :                 {
    1759    26962378 :                     Q[m] = L_shl( Mpy_32_16_1( Q[m], tmp1 ), s ); /*Q31 - Q_e*/
    1760    26962378 :                     move32();
    1761    26962378 :                     win = sub( win, 1 );
    1762    26962378 :                     tmp1 = sub( tmp1, tmp2 );
    1763             :                 }
    1764             : 
    1765     9441726 :                 nrg = L_deposit_l( 1 ); /* start new segment: reset noise segment energy */
    1766             :             }
    1767    18815257 :             segmentOffset = add( i, 1 );
    1768             :         }
    1769             :         ELSE /* line is zero, so fill line and update window and energy */
    1770             :         {
    1771    47609560 :             if ( LT_16( win, nTransWidth ) )
    1772             :             {
    1773    28283660 :                 win = add( win, 1 );
    1774             :             }
    1775             : 
    1776    47609560 :             Random( &seed );
    1777    47609560 :             Q[i] = L_mult0( mult( seed, fac_ns ), win ); /*Q31 - Q_e*/
    1778    47609560 :             move32();
    1779             : 
    1780    47609560 :             tmp1 = shr( seed, 4 );
    1781    47609560 :             nrg = L_mac0( nrg, tmp1, tmp1 ); /* sum up energy of current noise segment */
    1782             : 
    1783    47609560 :             if ( infoTCXNoise ) /* set noiseflags for IGF */
    1784             :             {
    1785      116660 :                 infoTCXNoise[i] = 1;
    1786      116660 :                 move16();
    1787             :             }
    1788             :         }
    1789             :     }
    1790             : 
    1791      221178 :     IF( win > 0 )
    1792             :     {
    1793             :         /* RMS-normalize uppermost noise-filled segment */
    1794      205185 :         tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( lowpassLine, segmentOffset ), &s ); /* mean */
    1795      205185 :         s = add( s, 9 - 15 );                                                             /* compensate energy scaling */
    1796      205185 :         tmp1 = ISqrt16( tmp1, &s );                                                       /* 1/RMS Q15 - s*/
    1797      205185 :         tmp1 = mult_r( tmp1, inv_int[nTransWidth] );                                      /* compensate win Q15 - s*/
    1798      205185 :         s = add( s, sub( 16, Q_e ) );                                                     /* compensate noise scaling */
    1799             : 
    1800    12044656 :         FOR( m = segmentOffset; m < lowpassLine; m++ )
    1801             :         {
    1802    11839471 :             Q[m] = L_shl( Mpy_32_16_1( Q[m], tmp1 ), s ); /*Q31 - Q_e*/
    1803    11839471 :             move32();
    1804             :         }
    1805             :     }
    1806      221178 : }
    1807             : 
    1808      808896 : void tcx_noise_filling_with_shift(
    1809             :     Word32 *Q, /*Q31 - Q_e*/
    1810             :     Word16 *Q_e,
    1811             :     Word16 seed,                 /*Q0*/
    1812             :     const Word16 iFirstLine,     /*Q0*/
    1813             :     const Word16 lowpassLine,    /*Q0*/
    1814             :     const Word16 nTransWidth,    /*Q0*/
    1815             :     const Word16 L_frame,        /*Q0*/
    1816             :     const Word16 tiltCompFactor, /*Q0*/
    1817             :     Word16 fac_ns,               /*Q15*/
    1818             :     Word16 *infoTCXNoise,        /*Q0*/
    1819             :     const Word16 element_mode    /* i  : IVAS element mode   Q0*/
    1820             : )
    1821             : {
    1822             :     Word16 i, m, segmentOffset;
    1823             :     Word16 win; /* window coefficient */
    1824             :     Word16 tilt_factor;
    1825             :     Word32 nrg;
    1826             :     Word16 tmp1, tmp2, s;
    1827             :     Word32 tmp32;
    1828             :     Word16 new_Q_e[N_MAX];
    1829             : 
    1830      808896 :     set16_fx( new_Q_e, *Q_e, N_MAX );
    1831             : 
    1832             :     /* get inverse frame length */
    1833      808896 :     tmp1 = getInvFrameLen( L_frame ); /*Q21*/
    1834             : 
    1835             :     /* tilt_factor = (float)pow(max_val(0.375f, tiltCompFactor), 1.0f/(float)L_frame); */
    1836      808896 :     tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */
    1837      808896 :     tmp32 = L_shr( Mpy_32_16_1( tmp32, tmp1 ), 6 );                            /*Q25*/
    1838             :     BASOP_SATURATE_WARNING_OFF_EVS;
    1839      808896 :     tilt_factor = round_fx_sat( BASOP_Util_InvLog2( tmp32 ) ); /*Q15*/
    1840             :     BASOP_SATURATE_WARNING_ON_EVS;
    1841             : 
    1842             :     /* find last nonzero line below iFirstLine, use it as start offset */
    1843      808896 :     i = iFirstLine;
    1844      808896 :     move16();
    1845      808896 :     tmp1 = shr( iFirstLine, 1 );
    1846      808896 :     IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */
    1847             :     {
    1848      603311 :         segmentOffset = i;
    1849      603311 :         move16();
    1850             :     }
    1851             :     ELSE
    1852             :     {
    1853      594390 :         FOR( ; i > tmp1; i-- )
    1854             :         {
    1855      593251 :             IF( Q[i] != 0 )
    1856             :             {
    1857      204446 :                 BREAK;
    1858             :             }
    1859             :         }
    1860             :         /* fac_ns *= (float)pow(tilt_factor, (float)i); */
    1861    14449067 :         FOR( m = 0; m < i; m++ )
    1862             :         {
    1863    14243482 :             fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
    1864             :         }
    1865      205585 :         i = add( i, 1 );
    1866      205585 :         segmentOffset = i;
    1867      205585 :         move16();
    1868             :     }
    1869      808896 :     nrg = L_deposit_l( 1 );
    1870      808896 :     win = 0;
    1871      808896 :     move16();
    1872             : 
    1873   360697679 :     FOR( ; i < lowpassLine; i++ )
    1874             :     {
    1875   359888783 :         fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
    1876             : 
    1877   359888783 :         IF( Q[i] != 0 )
    1878             :         {
    1879    84875016 :             IF( win > 0 )
    1880             :             {
    1881             :                 /* RMS-normalize current noise-filled segment */
    1882    39466260 :                 tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( i, segmentOffset ), &s ); /* mean */
    1883             :                 // Q-factor of nrg is -8. exp = 31-(-8) = 39
    1884    39466260 :                 s = add( s, 39 - 15 );                       /* scaling */
    1885    39466260 :                 tmp1 = ISqrt16( tmp1, &s );                  /* 1/RMS Q15 - s*/
    1886    39466260 :                 tmp1 = mult_r( tmp1, inv_int[nTransWidth] ); /* compensate win Q15 - s*/
    1887             : 
    1888    39466260 :                 tmp2 = sub( i, win );
    1889    39466260 :                 IF( LT_16( segmentOffset, tmp2 ) )
    1890             :                 {
    1891    69883587 :                     FOR( m = segmentOffset; m < tmp2; m++ )
    1892             :                     {
    1893    64475615 :                         Word16 nrm = 31;
    1894    64475615 :                         move16();
    1895    64475615 :                         Q[m] = Mpy_32_16_1( Q[m], tmp1 ); /*Q31 - Q_e*/
    1896    64475615 :                         move32();
    1897    64475615 :                         IF( Q[m] )
    1898             :                         {
    1899    64469316 :                             nrm = norm_l( Q[m] );
    1900             :                         }
    1901    64475615 :                         Q[m] = L_shl( Q[m], nrm ); /*Q31 - Q_e + nrm*/
    1902    64475615 :                         move32();
    1903    64475615 :                         new_Q_e[m] = sub( add( new_Q_e[m], s ), nrm );
    1904    64475615 :                         move32();
    1905             :                     }
    1906             :                 }
    1907             : 
    1908    39466260 :                 tmp2 = mult( tmp1, inv_int[nTransWidth] ); /*Q15 - s*/
    1909    39466260 :                 tmp1 = extract_l( L_mult0( tmp2, win ) );  /*Q15 - s*/
    1910   155134333 :                 FOR( m = sub( i, win ); m < i; m++ )
    1911             :                 {
    1912   115668073 :                     Word16 nrm = 31;
    1913             : 
    1914   115668073 :                     Q[m] = Mpy_32_16_1( Q[m], tmp1 ); /*Q31 - Q_e*/
    1915   115668073 :                     move32();
    1916   115668073 :                     IF( Q[m] )
    1917             :                     {
    1918   115657965 :                         nrm = norm_l( Q[m] );
    1919             :                     }
    1920   115668073 :                     Q[m] = L_shl( Q[m], nrm ); /*Q31 - Q_e*/
    1921   115668073 :                     move32();
    1922   115668073 :                     new_Q_e[m] = sub( add( new_Q_e[m], s ), nrm );
    1923   115668073 :                     move32();
    1924   115668073 :                     win = sub( win, 1 );
    1925   115668073 :                     tmp1 = sub( tmp1, tmp2 );
    1926             :                 }
    1927             : 
    1928    39466260 :                 nrg = L_deposit_l( 1 ); /* start new segment: reset noise segment energy */
    1929             :             }
    1930    84875016 :             segmentOffset = add( i, 1 );
    1931             :         }
    1932             :         ELSE /* line is zero, so fill line and update window and energy */
    1933             :         {
    1934   275013767 :             IF( LT_16( win, nTransWidth ) )
    1935             :             {
    1936   120794935 :                 win = add( win, 1 );
    1937             :             }
    1938             : 
    1939   275013767 :             Word16 nrm = 31;
    1940   275013767 :             move16();
    1941             : 
    1942   275013767 :             Random( &seed );
    1943   275013767 :             Q[i] = L_mult0( mult( seed, fac_ns ), win );
    1944   275013767 :             move32();
    1945   275013767 :             IF( Q[i] )
    1946             :             {
    1947   274984908 :                 nrm = norm_l( Q[i] );
    1948             :             }
    1949   275013767 :             Q[i] = L_shl( Q[i], nrm ); /*Q31 - Q_e*/
    1950   275013767 :             move32();
    1951   275013767 :             new_Q_e[i] = sub( 31, nrm );
    1952             : 
    1953   275013767 :             tmp1 = shr( seed, 4 );
    1954   275013767 :             nrg = L_mac0( nrg, tmp1, tmp1 ); /* sum up energy of current noise segment Q-8*/
    1955             : 
    1956   275013767 :             IF( infoTCXNoise ) /* set noiseflags for IGF */
    1957             :             {
    1958   159418629 :                 infoTCXNoise[i] = 1;
    1959   159418629 :                 move16();
    1960             :             }
    1961             :         }
    1962             :     }
    1963             : 
    1964      808896 :     IF( win > 0 )
    1965             :     {
    1966             :         /* RMS-normalize uppermost noise-filled segment */
    1967      751613 :         tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( lowpassLine, segmentOffset ), &s ); /* mean */
    1968             :         // Q-factor of nrg is -8. exp = 31-(-8) = 39
    1969      751613 :         s = add( s, 39 - 15 );                       /* compensate energy scaling */
    1970      751613 :         tmp1 = ISqrt16( tmp1, &s );                  /* 1/RMS Q15 - s*/
    1971      751613 :         tmp1 = mult_r( tmp1, inv_int[nTransWidth] ); /* compensate win Q15 - s*/
    1972             : 
    1973    95621692 :         FOR( m = segmentOffset; m < lowpassLine; m++ )
    1974             :         {
    1975    94870079 :             Word16 nrm = 31;
    1976    94870079 :             move16();
    1977             :             /*
    1978             :                 at this point:
    1979             :                 - flt Q[m] = (Q[m] * 2^(new_Q_e[m] - 31)) / (nTransWidth*nTransWidth)
    1980             :                 - flt tmp1 = (tmp1 * 2^(s - 15)) * (nTransWidth*nTransWidth)
    1981             :              */
    1982    94870079 :             Q[m] = Mpy_32_16_1( Q[m], tmp1 ); /*Q15 - Q_e - s*/
    1983    94870079 :             move32();
    1984    94870079 :             IF( Q[m] )
    1985             :             {
    1986    94857627 :                 nrm = norm_l( Q[m] );
    1987             :             }
    1988    94870079 :             Q[m] = L_shl( Q[m], nrm ); /*Q15 - Q_e - s + nrm*/
    1989    94870079 :             move32();
    1990    94870079 :             new_Q_e[m] = add( new_Q_e[m], s - nrm );
    1991    94870079 :             move32();
    1992             :         }
    1993             :     }
    1994             : 
    1995      808896 :     Word16 max_e = 0;
    1996      808896 :     move16();
    1997   430138364 :     FOR( i = 0; i < lowpassLine; i++ )
    1998             :     {
    1999   429329468 :         max_e = s_max( max_e, new_Q_e[i] );
    2000             :     }
    2001             : 
    2002   430138364 :     FOR( i = 0; i < lowpassLine; i++ )
    2003             :     {
    2004   429329468 :         Q[i] = L_shr( Q[i], sub( max_e, new_Q_e[i] ) ); /*Q31 - Q_e*/
    2005   429329468 :         move32();
    2006             :     }
    2007             : 
    2008      808896 :     *Q_e = max_e;
    2009      808896 :     move16();
    2010      808896 : }
    2011             : 
    2012             : 
    2013             : /*---------------------------------------------------------------
    2014             :  * InitTnsConfigs()
    2015             :  *--------------------------------------------------------------*/
    2016             : 
    2017             : 
    2018       18151 : void InitTnsConfigs(
    2019             :     const Word16 bwidth,  /*Q0*/
    2020             :     const Word16 L_frame, /*Q0*/
    2021             :     STnsConfig tnsConfig[2][2],
    2022             :     const Word16 igfStopFreq,  /*Q0*/
    2023             :     const Word32 total_brate,  /*Q0*/
    2024             :     const Word16 element_mode, /*Q0*/
    2025             :     const Word16 MCT_flag /*Q0*/ )
    2026             : {
    2027       18151 :     IF( GT_32( total_brate, ACELP_32k ) )
    2028             :     {
    2029       14766 :         InitTnsConfiguration( bwidth, shr( L_frame, 1 ), &tnsConfig[0][0], igfStopFreq, total_brate, element_mode, MCT_flag );
    2030             :     }
    2031       18151 :     InitTnsConfiguration( bwidth, L_frame, &tnsConfig[1][0], igfStopFreq, total_brate, element_mode, MCT_flag );
    2032       18151 :     InitTnsConfiguration( bwidth, add( L_frame, shr( L_frame, 2 ) ), &tnsConfig[1][1], igfStopFreq, total_brate, element_mode, MCT_flag );
    2033       18151 : }
    2034             : 
    2035       32618 : void InitTnsConfigs_ivas_fx(
    2036             :     const Word16 bwidth,  /*Q0*/
    2037             :     const Word16 L_frame, /*Q0*/
    2038             :     STnsConfig tnsConfig[2][2],
    2039             :     const Word16 igfStopFreq,  /*Q0*/
    2040             :     const Word32 total_brate,  /*Q0*/
    2041             :     const Word16 element_mode, /*Q0*/
    2042             :     const Word16 MCT_flag /*Q0*/ )
    2043             : {
    2044       32618 :     IF( GT_32( total_brate, ACELP_32k ) )
    2045             :     {
    2046       22649 :         InitTnsConfiguration_ivas_fx( bwidth, shr( L_frame, 1 ), &tnsConfig[0][0], igfStopFreq, total_brate, element_mode, MCT_flag );
    2047             :     }
    2048       32618 :     InitTnsConfiguration_ivas_fx( bwidth, L_frame, &tnsConfig[1][0], igfStopFreq, total_brate, element_mode, MCT_flag );
    2049       32618 :     InitTnsConfiguration_ivas_fx( bwidth, add( L_frame, shr( L_frame, 2 ) ), &tnsConfig[1][1], igfStopFreq, total_brate, element_mode, MCT_flag );
    2050       32618 : }
    2051             : 
    2052             : 
    2053     1850408 : void SetTnsConfig(
    2054             :     TCX_CONFIG_HANDLE hTcxCfg, /* i  : configuration of TCX               */
    2055             :     const Word16 isTCX20,      /*Q0*/
    2056             :     const Word16 isAfterACELP /*Q0*/ )
    2057             : {
    2058     1850408 :     move16();
    2059     1850408 :     hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[isTCX20][isAfterACELP];
    2060     1850408 :     assert( hTcxCfg->pCurrentTnsConfig != NULL );
    2061     1850408 : }
    2062             : #define IVAS_CODE_TCX_UTIL
    2063             : #ifdef IVAS_CODE_TCX_UTIL
    2064             : /*-------------------------------------------------------------------*
    2065             :  *  SetAllowTnsOnWhite
    2066             :  *
    2067             :  *  set TNS config flag for possible application of TNS in the whitened domain
    2068             :  *-------------------------------------------------------------------*/
    2069             : 
    2070       50690 : void SetAllowTnsOnWhite(
    2071             :     STnsConfig tnsConfig[2][2], /* o  : updated TNS configurations */
    2072             :     const Word8 allowTnsOnWhite /* i  : flag for TNS in whiteded domain mode Q0*/
    2073             : )
    2074             : {
    2075       50690 :     tnsConfig[0][0].allowTnsOnWhite = allowTnsOnWhite; /*Q0*/
    2076       50690 :     move16();
    2077       50690 :     tnsConfig[0][1].allowTnsOnWhite = allowTnsOnWhite;
    2078       50690 :     move16();
    2079       50690 :     tnsConfig[1][0].allowTnsOnWhite = allowTnsOnWhite;
    2080       50690 :     move16();
    2081       50690 :     tnsConfig[1][1].allowTnsOnWhite = allowTnsOnWhite;
    2082       50690 :     move16();
    2083       50690 :     return;
    2084             : }
    2085             : #endif
    2086             : #undef IVAS_CODE_TCX_UTIL
    2087             : 
    2088      897934 : void tcx_get_gain(
    2089             :     Word32 *x,      /* i: spectrum 1 Q31 - x_e*/
    2090             :     Word16 x_e,     /* i: spectrum 1 exponent */
    2091             :     Word32 *y,      /* i: spectrum 2 Q31 - y_e*/
    2092             :     Word16 y_e,     /* i: spectrum 2 exponent */
    2093             :     Word16 n,       /* i: length Q0*/
    2094             :     Word16 *gain,   /* o: gain Q15 - gain_e*/
    2095             :     Word16 *gain_e, /* o: gain exponent */
    2096             :     Word32 *en_y,   /* o: energy of y (optional)  Q31 - en_y_e*/
    2097             :     Word16 *en_y_e  /* o: energy of y exponent (optional) */
    2098             : )
    2099             : {
    2100             :     Word32 maxX, minX, maxY, minY;
    2101             :     Word32 corr, ener;
    2102             :     Word16 sx, sy, corr_e, ener_e;
    2103             :     Word16 i, tmp;
    2104             : #ifndef ISSUE_1836_replace_overflow_libcom
    2105             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    2106             :     Flag Overflow = 0;
    2107             : #endif
    2108             : #endif
    2109             : 
    2110      897934 :     maxX = L_deposit_l( 1 );
    2111      897934 :     maxY = L_deposit_l( 1 );
    2112      897934 :     minX = L_deposit_l( -1 );
    2113      897934 :     minY = L_deposit_l( -1 );
    2114   725579534 :     FOR( i = 0; i < n; i++ )
    2115             :     {
    2116   724681600 :         if ( x[i] > 0 )
    2117   236975260 :             maxX = L_max( maxX, x[i] ); /*Q31 - x_e*/
    2118   724681600 :         if ( x[i] < 0 )
    2119   237017887 :             minX = L_min( minX, x[i] ); /*Q31 - x_e*/
    2120             : 
    2121   724681600 :         if ( y[i] > 0 )
    2122    74366108 :             maxY = L_max( maxY, y[i] ); /*Q31 - y_e*/
    2123   724681600 :         if ( y[i] < 0 )
    2124    74527847 :             minY = L_min( minY, y[i] ); /*Q31 - y_e*/
    2125             :     }
    2126      897934 :     sx = s_min( norm_l( maxX ), norm_l( minX ) );
    2127      897934 :     sy = s_min( norm_l( maxY ), norm_l( minY ) );
    2128      897934 :     sx = sub( sx, 4 );
    2129      897934 :     sy = sub( sy, 4 );
    2130             : 
    2131      897934 :     ener = L_deposit_l( 0 );
    2132      897934 :     corr = L_deposit_l( 0 );
    2133   725579534 :     FOR( i = 0; i < n; i++ )
    2134             :     {
    2135   724681600 :         tmp = round_fx( L_shl( y[i], sy ) );                       /*Q15 - y_e + sy*/
    2136   724681600 :         ener = L_mac0( ener, tmp, tmp );                           /*Q30 - 2*(y_e - sy)*/
    2137   724681600 :         corr = L_mac0( corr, tmp, round_fx( L_shl( x[i], sx ) ) ); /*Q30 - 2*(x_e - sx + y_e - sy)*/
    2138             :     }
    2139             : 
    2140      897934 :     if ( ener == 0 )
    2141        2383 :         ener = L_deposit_l( 1 );
    2142             : 
    2143      897934 :     ener_e = add( shl( sub( y_e, sy ), 1 ), 1 );
    2144      897934 :     corr_e = add( sub( add( x_e, y_e ), add( sx, sy ) ), 1 );
    2145             : 
    2146      897934 :     tmp = sub( norm_l( corr ), 1 );
    2147      897934 :     corr = L_shl( corr, tmp ); /*Q31 - corr_e + tmp*/
    2148      897934 :     corr_e = sub( corr_e, tmp );
    2149             : 
    2150      897934 :     tmp = norm_l( ener );
    2151      897934 :     ener = L_shl( ener, tmp ); /*Q31 - ener_e + tmp*/
    2152      897934 :     ener_e = sub( ener_e, tmp );
    2153             : 
    2154             : #ifdef ISSUE_1836_replace_overflow_libcom
    2155      897934 :     tmp = div_s( abs_s( round_fx_sat( corr ) ), round_fx_sat( ener ) ); /*Q15 - (corr_e - ener_e)*/
    2156             : #else
    2157             :     tmp = div_s( abs_s( round_fx_o( corr, &Overflow ) ), round_fx_o( ener, &Overflow ) ); /*Q15 - (corr_e - ener_e)*/
    2158             : #endif
    2159      897934 :     if ( corr < 0 )
    2160           0 :         tmp = negate( tmp );
    2161             : 
    2162      897934 :     *gain = tmp;
    2163      897934 :     move16();
    2164      897934 :     *gain_e = sub( corr_e, ener_e );
    2165      897934 :     move16();
    2166             : 
    2167      897934 :     if ( en_y != NULL )
    2168             :     {
    2169      897934 :         *en_y = ener; /*Q31 - ener_e*/
    2170      897934 :         move32();
    2171             :     }
    2172      897934 :     if ( en_y_e != NULL )
    2173             :     {
    2174      897934 :         *en_y_e = ener_e;
    2175      897934 :         move16();
    2176             :     }
    2177      897934 : }
    2178         129 : void init_TCX_config(
    2179             :     TCX_CONFIG_HANDLE hTcxCfg,
    2180             :     Word16 L_frame,    /*Q0*/
    2181             :     Word16 fscale,     /*Q0*/
    2182             :     Word16 L_frameTCX, /*Q0*/
    2183             :     Word16 fscaleFB /*Q0*/ )
    2184             : {
    2185             :     /* Initialize the TCX MDCT windows */
    2186         129 :     hTcxCfg->tcx_mdct_window_length = extract_l( L_shr( L_mult0( L_LOOK_12k8, fscale ), LD_FSCALE_DENOM ) ); /*Q0*/
    2187         129 :     move16();
    2188         129 :     hTcxCfg->tcx_mdct_window_delay = hTcxCfg->tcx_mdct_window_length; /*Q0*/
    2189         129 :     move16();
    2190             : 
    2191         129 :     hTcxCfg->tcx_mdct_window_half_length = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA( 12800, 5000000L ), fscale ), LD_FSCALE_DENOM ) );
    2192         129 :     move16();
    2193         129 :     hTcxCfg->tcx_mdct_window_min_length = shr( L_frame, 4 ); /* 1.25ms Q0*/
    2194         129 :     move16();
    2195         129 :     hTcxCfg->tcx_mdct_window_trans_length = shr( L_frame, 4 ); /* 1.25ms Q0*/
    2196         129 :     move16();
    2197         129 :     hTcxCfg->tcx5Size = shr( L_frame, 2 ); /* 5ms Q0*/
    2198         129 :     move16();
    2199         129 :     hTcxCfg->tcx_mdct_window_lengthFB = extract_l( L_shr( L_mult0( L_LOOK_12k8, fscaleFB ), LD_FSCALE_DENOM ) ); /*Q0*/
    2200         129 :     move16();
    2201         129 :     hTcxCfg->tcx_mdct_window_delayFB = hTcxCfg->tcx_mdct_window_lengthFB; /*Q0*/
    2202         129 :     move16();
    2203             : 
    2204         129 :     hTcxCfg->tcx_mdct_window_half_lengthFB = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA( 12800, 5000000L ), fscaleFB ), LD_FSCALE_DENOM ) ); /*Q0*/
    2205         129 :     move16();
    2206         129 :     hTcxCfg->tcx_mdct_window_min_lengthFB = shr( L_frameTCX, 4 ); /* 1.25ms Q0*/
    2207         129 :     move16();
    2208         129 :     hTcxCfg->tcx_mdct_window_trans_lengthFB = shr( L_frameTCX, 4 ); /* 1.25ms Q0*/
    2209         129 :     move16();
    2210         129 :     hTcxCfg->tcx5SizeFB = shr( L_frameTCX, 2 ); /* 5ms Q0*/
    2211         129 :     move16();
    2212         129 :     mdct_window_sine( hTcxCfg->tcx_mdct_window, hTcxCfg->tcx_mdct_window_length );
    2213         129 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_half_length );
    2214         129 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_min_length );
    2215         129 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_trans_length );
    2216             : 
    2217         129 :     mdct_window_sine( hTcxCfg->tcx_mdct_windowFB, hTcxCfg->tcx_mdct_window_lengthFB );
    2218         129 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_half_lengthFB );
    2219         129 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_min_lengthFB );
    2220         129 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_trans_lengthFB );
    2221             : 
    2222             :     /*ALDO windows for MODE2*/
    2223         129 :     mdct_window_aldo( hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, L_frame );
    2224         129 :     mdct_window_aldo( hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, L_frameTCX );
    2225         129 : }

Generated by: LCOV version 1.14