LCOV - code coverage report
Current view: top level - lib_com - tcx_utils_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 1058 1116 94.8 %
Date: 2025-05-03 01:55:50 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     3144764 : Word16 getInvFrameLen( /* returns 1/L_frame in Q21 format */
      21             :                        const Word16 L_frame )
      22             : {
      23             :     Word16 idx, s;
      24             : 
      25     3144764 :     s = norm_s( L_frame );
      26     3144764 :     idx = shl( L_frame, s );
      27             : 
      28     3144764 :     assert( ( idx == 0x4000 ) || ( idx == 0x4B00 ) || ( idx == 0x5000 ) || ( idx == 0x5A00 ) || ( idx == 0x6000 ) || ( idx == 0x6400 ) || ( idx == 0x7800 ) );
      29             : 
      30     3144764 :     idx = mult_r( idx, 0x10 ); /* idx = shr(add(idx, 0x0400), 11); */
      31     3144764 :     idx = s_and( idx, 7 );
      32             : 
      33             : 
      34     3144764 :     return shl( L_frame_inv[idx], sub( s, 7 ) );
      35             : }
      36             : /*-------------------------------------------------------------------*
      37             :  *tcx_get_windows()
      38             :  *
      39             :  *
      40             :  * ------------------------------------------------------------------ - */
      41      469465 : 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      469465 :     IF( fullband == 0 )
      53             :     {
      54             :         /* Left part */
      55      108933 :         SWITCH( left_mode )
      56             :         {
      57         316 :             case TRANSITION_OVERLAP:                                   /* ACELP->TCX transition */
      58         316 :                 *left_overlap = hTcxCfg->tcx_mdct_window_trans_length; /*Q0*/
      59         316 :                 move16();
      60         316 :                 *left_win = hTcxCfg->tcx_mdct_window_trans; /*Q15*/
      61         316 :                 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      104735 :             case FULL_OVERLAP:
      73      104735 :                 *left_overlap = hTcxCfg->tcx_mdct_window_length; /*Q0*/
      74      104735 :                 move16();
      75      104735 :                 *left_win = hTcxCfg->tcx_aldo_window_1_trunc; /*Q15*/
      76      104735 :                 BREAK;
      77           0 :             default:
      78           0 :                 assert( !"Not supported overlap" );
      79             :         }
      80             : 
      81             :         /* Right part */
      82      108933 :         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      105034 :             case FULL_OVERLAP:
      95      105034 :                 *right_overlap = hTcxCfg->tcx_mdct_window_delay; /*Q0*/
      96      105034 :                 move16();
      97      105034 :                 *right_win = hTcxCfg->tcx_aldo_window_2; /*Q15*/
      98      105034 :                 BREAK;
      99           0 :             default:
     100           0 :                 assert( !"Not supported overlap" );
     101             :         }
     102             :     }
     103             :     ELSE
     104             :     {
     105             :         /* Left part */
     106      360532 :         SWITCH( left_mode )
     107             :         {
     108       10821 :             case TRANSITION_OVERLAP:                                     /* ACELP->TCX transition */
     109       10821 :                 *left_overlap = hTcxCfg->tcx_mdct_window_trans_lengthFB; /*Q0*/
     110       10821 :                 move16();
     111       10821 :                 *left_win = hTcxCfg->tcx_mdct_window_transFB; /*Q15*/
     112       10821 :                 BREAK;
     113       54743 :             case MIN_OVERLAP:
     114       54743 :                 *left_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB; /*Q0*/
     115       54743 :                 move16();
     116       54743 :                 *left_win = hTcxCfg->tcx_mdct_window_minimumFB; /*Q15*/
     117       54743 :                 BREAK;
     118       14033 :             case HALF_OVERLAP:
     119       14033 :                 *left_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB; /*Q0*/
     120       14033 :                 move16();
     121       14033 :                 *left_win = hTcxCfg->tcx_mdct_window_halfFB; /*Q15*/
     122       14033 :                 BREAK;
     123       30642 :             case RECTANGULAR_OVERLAP:
     124       30642 :                 *left_overlap = 0;
     125       30642 :                 move16();
     126       30642 :                 *left_win = NULL;
     127       30642 :                 BREAK;
     128      250293 :             case FULL_OVERLAP:
     129      250293 :                 *left_overlap = hTcxCfg->tcx_mdct_window_lengthFB; /*Q0*/
     130      250293 :                 move16();
     131      250293 :                 *left_win = hTcxCfg->tcx_aldo_window_1_FB_trunc; /*Q15*/
     132      250293 :                 BREAK;
     133           0 :             default:
     134           0 :                 assert( !"Not supported overlap" );
     135             :         }
     136             : 
     137             :         /* Right part */
     138      360532 :         SWITCH( right_mode )
     139             :         {
     140       57544 :             case MIN_OVERLAP:
     141       57544 :                 *right_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB; /*Q0*/
     142       57544 :                 move16();
     143       57544 :                 *right_win = hTcxCfg->tcx_mdct_window_minimumFB; /*Q15*/
     144       57544 :                 BREAK;
     145       14536 :             case HALF_OVERLAP:
     146       14536 :                 *right_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB; /*Q0*/
     147       14536 :                 move16();
     148       14536 :                 *right_win = hTcxCfg->tcx_mdct_window_halfFB; /*Q15*/
     149       14536 :                 BREAK;
     150       30623 :             case RECTANGULAR_OVERLAP:
     151       30623 :                 *right_overlap = 0;
     152       30623 :                 move16();
     153       30623 :                 *right_win = NULL;
     154       30623 :                 BREAK;
     155      257829 :             case FULL_OVERLAP:
     156      257829 :                 *right_overlap = hTcxCfg->tcx_mdct_window_delayFB; /*Q0*/
     157      257829 :                 move16();
     158      257829 :                 *right_win = hTcxCfg->tcx_aldo_window_2_FB; /*Q15*/
     159      257829 :                 BREAK;
     160           0 :             default:
     161           0 :                 assert( !"Not supported overlap" );
     162             :         }
     163             :     }
     164      469465 : }
     165             : 
     166      469434 : 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      469434 :     n = shr( left_overlap, 1 ); /*Q0*/
     180    67882500 :     FOR( w = 0; w < n; w++ )
     181             :     {
     182    67413066 :         *output++ = mult_r( *signal++, left_win[w].v.im ); /*Qx*/
     183    67413066 :         move16();
     184             :     }
     185    67882500 :     FOR( w = 0; w < n; w++ )
     186             :     {
     187    67413066 :         *output++ = mult_r( *signal++, left_win[n - 1 - w].v.re ); /*Qx*/
     188    67413066 :         move16();
     189             :     }
     190             : 
     191             :     /* Non overlapping region */
     192      469434 :     n = sub( L_frame, shr( add( left_overlap, right_overlap ), 1 ) ); /*Q0*/
     193   192196586 :     FOR( w = 0; w < n; w++ )
     194             :     {
     195   191727152 :         *output++ = *signal++; /*Qx*/
     196   191727152 :         move16();
     197             :     }
     198             : 
     199             :     /* Right overlap */
     200      469434 :     n = shr( right_overlap, 1 ); /*Q0*/
     201    69215600 :     FOR( w = 0; w < n; w++ )
     202             :     {
     203    68746166 :         *output++ = mult_r( *signal++, right_win[w].v.re ); /*Qx*/
     204    68746166 :         move16();
     205             :     }
     206    69215600 :     FOR( w = 0; w < n; w++ )
     207             :     {
     208    68746166 :         *output++ = mult_r( *signal++, right_win[n - 1 - w].v.im ); /*Qx*/
     209    68746166 :         move16();
     210             :     }
     211      469434 : }
     212             : /*-------------------------------------------------------------------*
     213             :  * WindowSignal()
     214             :  *
     215             :  *
     216             :  *-------------------------------------------------------------------*/
     217      469434 : 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      469434 :     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      469434 :     IF( EQ_16( left_overlap_mode, TRANSITION_OVERLAP ) )
     246             :     {
     247             :         /* Increase frame size for 5ms */
     248       11137 :         IF( fullband == 0 )
     249             :         {
     250         316 :             *L_frame = add( *L_frame, hTcxCfg->tcx5Size ); /*Q0*/
     251         316 :             move16();
     252         316 :             offset = negate( shr( hTcxCfg->tcx_mdct_window_trans_length, 1 ) ); /*Q0*/
     253             :         }
     254             :         ELSE
     255             :         {
     256       10821 :             *L_frame = add( *L_frame, hTcxCfg->tcx5SizeFB ); /*Q0*/
     257       10821 :             move16();
     258       10821 :             offset = negate( shr( hTcxCfg->tcx_mdct_window_trans_lengthFB, 1 ) ); /*Q0*/
     259             :         }
     260             :     }
     261             : 
     262             :     /*-----------------------------------------------------------*
     263             :      * Windowing                                                 *
     264             :      *-----------------------------------------------------------*/
     265             : 
     266      469434 :     tcx_windowing_analysis( in - sub( shr( l, 1 ), offset ), *L_frame, l, left_win, r, right_win, out );
     267      469434 :     test();
     268      469434 :     test();
     269      469434 :     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      333629 :         p = hTcxCfg->tcx_mdct_window_minimum;                /*Q15*/
     276      333629 :         tmp = shr( hTcxCfg->tcx_mdct_window_min_length, 1 ); /*Q0*/
     277      333629 :         IF( fullband != 0 )
     278             :         {
     279      228894 :             p = hTcxCfg->tcx_mdct_window_minimumFB;                /*Q15*/
     280      228894 :             tmp = shr( hTcxCfg->tcx_mdct_window_min_lengthFB, 1 ); /*Q0*/
     281             :         }
     282             : 
     283     8964837 :         FOR( i = 0; i < tmp; i++ )
     284             :         {
     285     8631208 :             out[i] = mult_r( out[i], p[i].v.im ); /*Qx*/
     286     8631208 :             move16();
     287             :         }
     288     8964837 :         FOR( i = 0; i < tmp; i++ )
     289             :         {
     290     8631208 :             out[i + tmp] = mult_r( out[i + tmp], p[tmp - 1 - i].v.re ); /*Qx*/
     291     8631208 :             move16();
     292             :         }
     293             :     }
     294             : 
     295      469434 :     *left_overlap_length = l;
     296      469434 :     move16();
     297      469434 :     *right_overlap_length = r;
     298      469434 :     move16();
     299      469434 : }
     300             : /*-------------------------------------------------------------------*
     301             :  * tcx_windowing_synthesis_current_frame()
     302             :  *
     303             :  *
     304             :  *-------------------------------------------------------------------*/
     305             : 
     306      120186 : 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      120186 :     overlap = shr( window_length, 1 ); /*Q0*/
     335             : 
     336             :     /* Past-frame is TCX concealed as CNG and current-frame is TCX */
     337      120186 :     test();
     338      120186 :     test();
     339      120186 :     test();
     340      120186 :     test();
     341      120186 :     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      120186 :     ELSE IF( EQ_16( left_rect, 1 ) && last_core_bfi == ACELP_CORE )
     364             :     {
     365       24727 :         tmp = sub( overlap, acelp_mem_len );
     366     2333287 :         FOR( i = 0; i < tmp; i++ )
     367             :         {
     368     2308560 :             move16();
     369     2308560 :             signal[i] = 0;
     370             :         }
     371             : 
     372       24727 :         IF( fullbandScale == 0 )
     373             :         {
     374             : 
     375       16413 :             tmp = shl( acelp_mem_len, 1 ); /*Qx*/
     376             : 
     377             :             /*OLA with ACELP*/
     378      181363 :             FOR( i = 0; i < acelp_mem_len; i++ )
     379             :             {
     380             : 
     381             :                 /*window decoded TCX with aliasing*/
     382      164950 :                 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      164950 :                 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      164950 :                 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      164950 :                 move16();
     390      164950 :                 signal[i + overlap - acelp_mem_len] = tmp2; /*Qx*/
     391             :             }
     392      181363 :             FOR( ; i < tmp; i++ )
     393             :             {
     394             : 
     395             :                 /*window decoded TCX with aliasing*/
     396      164950 :                 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      164950 :                 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      164950 :                 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      164950 :                 move16();
     403      164950 :                 signal[i + overlap - acelp_mem_len] = tmp2; /*Qx*/
     404             :             }
     405             : 
     406      279021 :             FOR( i = 0; i < M; i++ )
     407             :             {
     408      262608 :                 move16();
     409      262608 :                 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       24727 :         move16();
     414       24727 :         acelp_zir_len = 64;
     415             : 
     416       24727 :         IF( fullbandScale == 0 )
     417             :         {
     418       16413 :             set16_fx( acelp_zir, 0, acelp_zir_len );
     419       16413 :             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        8314 :             tmp = extract_l( L_shr( L_mult0( acelp_zir_len, fullbandScale ), LD_FSCALE_DENOM ) ); /*Q0*/
     424        8314 :             lerp( acelp_zir, tmp_buf, tmp, acelp_zir_len );
     425        8314 :             acelp_zir_len = tmp; /*Q0*/
     426        8314 :             move16();
     427        8314 :             acelp_zir = tmp_buf; /*Qx*/
     428             : 
     429             : 
     430        8314 :             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     1233787 :                 FOR( i = 2; i < acelp_zir_len; i++ )
     434             :                 {
     435     1227510 :                     L_tmp = L_mult( acelp_zir[i - 2], 8192 /*0.25 in Q15*/ );
     436     1227510 :                     L_tmp = L_mac( L_tmp, acelp_zir[i - 1], 11469 /*0.35 in Q15*/ );
     437     1227510 :                     acelp_zir[i] = mac_r( L_tmp, acelp_zir[i], 13107 /*0.40 in Q15*/ ); /*Qx*/
     438     1227510 :                     move16();
     439             :                 }
     440             : 
     441        6277 :                 L_tmp = L_mult( acelp_zir[acelp_zir_len - 1], 13107 /*0.40 in Q15*/ );
     442        6277 :                 L_tmp = L_mac( L_tmp, acelp_zir[acelp_zir_len - 1], 11469 /*0.35 in Q15*/ );
     443        6277 :                 acelp_zir[acelp_zir_len - 1] = mac_r( L_tmp, acelp_zir[acelp_zir_len - 2], 8192 /*0.25 in Q15*/ ); /*Qx*/
     444        6277 :                 move16();
     445        6277 :                 L_tmp = L_mult( acelp_zir[acelp_zir_len - 2], 13107 );
     446        6277 :                 L_tmp = L_mac( L_tmp, acelp_zir[acelp_zir_len - 1], 11469 );
     447        6277 :                 acelp_zir[acelp_zir_len - 2] = mac_r( L_tmp, acelp_zir[acelp_zir_len - 1], 8192 ); /*Qx*/
     448        6277 :                 move16();
     449     1233787 :                 FOR( i = acelp_zir_len - 3; i >= 0; i-- )
     450             :                 {
     451     1227510 :                     L_tmp = L_mult( acelp_zir[i], 13107 );
     452     1227510 :                     L_tmp = L_mac( L_tmp, acelp_zir[i + 1], 11469 );
     453     1227510 :                     acelp_zir[i] = mac_r( L_tmp, acelp_zir[i + 2], 8192 ); /*Qx*/
     454     1227510 :                     move16();
     455             :                 }
     456             :             }
     457             :         }
     458             : 
     459     2502607 :         FOR( i = 0; i < acelp_zir_len; i++ )
     460             :         {
     461             :             /*remove reconstructed ZIR and add ACELP ZIR*/
     462     2477880 :             move16();
     463     2477880 :             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       95459 :     ELSE IF( left_rect == 1 && last_core_bfi != ACELP_CORE )
     468             :     {
     469         460 :         n = add( overlap, acelp_mem_len ); /*q0*/
     470       66300 :         FOR( i = 0; i < n; i++ )
     471             :         {
     472       65840 :             move16();
     473       65840 :             signal[i] = 0;
     474             :         }
     475             : 
     476         460 :         n = shr( window_length, 1 ); /*q0*/
     477       58070 :         FOR( i = 0; i < n; i++ )
     478             :         {
     479       57610 :             move16();
     480       57610 :             signal[i + overlap + acelp_mem_len] = mult_r( signal[i + overlap + acelp_mem_len], window[i].v.im ); /*Qx*/
     481             :         }
     482       58070 :         FOR( ; i < window_length; i++ )
     483             :         {
     484       57610 :             move16();
     485       57610 :             signal[i + overlap + acelp_mem_len] = mult_r( signal[i + overlap + acelp_mem_len], window[window_length - 1 - i].v.re ); /*Qx*/
     486             :         }
     487             :     }
     488             :     /* Normal window (past-frame is ACELP) */
     489       94999 :     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       94983 :         IF( EQ_16( left_mode, 2 ) ) /* min. overlap */
     514             :         {
     515       56989 :             n = shr( sub( window_length, window_min_length ), 1 ); /*q0*/
     516     2590297 :             FOR( i = 0; i < n; i++ )
     517             :             {
     518     2533308 :                 *signal++ = 0;
     519     2533308 :                 move16();
     520             :             }
     521             : 
     522       56989 :             n = shr( window_min_length, 1 ); /*q0*/
     523     1276191 :             FOR( i = 0; i < n; i++ )
     524             :             {
     525     1219202 :                 *signal = mult_r( *signal, window_min[i].v.im ); /*Qx*/
     526     1219202 :                 move16();
     527     1219202 :                 signal++;
     528             :             }
     529     1276191 :             FOR( i = 0; i < n; i++ )
     530             :             {
     531     1219202 :                 *signal = mult_r( *signal, window_min[n - 1 - i].v.re ); /*Qx*/
     532     1219202 :                 move16();
     533     1219202 :                 signal++;
     534             :             }
     535             :         }
     536       37994 :         ELSE IF( EQ_16( left_mode, 3 ) ) /* half OL */
     537             :         {
     538             :             Word16 w;
     539             : 
     540       14077 :             n = shr( sub( window_length, window_half_length ), 1 );
     541      333309 :             FOR( i = 0; i < n; i++ )
     542             :             {
     543      319232 :                 move16();
     544      319232 :                 signal[i] = 0;
     545             :             }
     546       14077 :             n = shr( window_half_length, 1 );
     547      912559 :             FOR( w = 0; w < n; w++ )
     548             :             {
     549      898482 :                 move16();
     550      898482 :                 signal[i] = mult_r( signal[i], window_half[w].v.im ); /*Qx*/
     551      898482 :                 i = add( i, 1 );
     552             :             }
     553      912559 :             FOR( w = 0; w < n; w++ )
     554             :             {
     555      898482 :                 move16();
     556      898482 :                 signal[i] = mult_r( signal[i], window_half[window_half_length / 2 - 1 - w].v.re ); /*Qx*/
     557      898482 :                 i = add( i, 1 );
     558             :             }
     559             :         }
     560             :         ELSE
     561             :         { /* normal full/maximum overlap */
     562             : 
     563       23917 :             n = shr( window_length, 1 );
     564     3639669 :             FOR( i = 0; i < n; i++ )
     565             :             {
     566     3615752 :                 move16();
     567     3615752 :                 signal[i] = mult_r( signal[i], window[i].v.im ); /*Qx*/
     568             :             }
     569     3639669 :             FOR( ; i < window_length; i++ )
     570             :             {
     571     3615752 :                 move16();
     572     3615752 :                 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      120186 : }
     579             : /*-------------------------------------------------------------------*
     580             :  * tcx_windowing_synthesis_past_frame()
     581             :  *
     582             :  *
     583             :  *-------------------------------------------------------------------*/
     584      121599 : 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      121599 :     IF( EQ_16( right_mode, 2 ) ) /* min. overlap */
     599             :     {
     600       60578 :         signal += shr( sub( window_length, window_min_length ), 1 ); /*Qx*/
     601             : 
     602       60578 :         n = shr( window_min_length, 1 );
     603     1359176 :         FOR( i = 0; i < n; i++ )
     604             :         {
     605     1298598 :             *signal = mult_r( *signal, window_min[i].v.re ); /*Qx*/
     606     1298598 :             move16();
     607     1298598 :             signal++;
     608             :         }
     609     1359176 :         FOR( i = 0; i < n; i++ )
     610             :         {
     611     1298598 :             *signal = mult_r( *signal, window_min[n - 1 - i].v.im ); /*Qx*/
     612     1298598 :             move16();
     613     1298598 :             signal++;
     614             :         }
     615             : 
     616       60578 :         n = shr( sub( window_length, window_min_length ), 1 ); /*Q0*/
     617     4113466 :         FOR( i = 0; i < n; i++ )
     618             :         {
     619     4052888 :             *signal = 0;
     620     4052888 :             move16();
     621     4052888 :             signal++;
     622             :         }
     623             :     }
     624       61021 :     ELSE IF( EQ_16( right_mode, 3 ) ) /* half OL */
     625             :     {
     626             :         Word16 w;
     627             : 
     628       16201 :         i = shr( sub( window_length, window_half_length ), 1 ); /*Q0*/
     629       16201 :         n = shr( window_half_length, 1 );                       /*Q0*/
     630     1037347 :         FOR( w = 0; w < n; w++ )
     631             :         {
     632     1021146 :             signal[i] = mult_r( signal[i], window_half[w].v.re ); /*Qx*/
     633     1021146 :             move16();
     634     1021146 :             i = add( i, 1 );
     635             :         }
     636     1037347 :         FOR( w = 0; w < n; w++ )
     637             :         {
     638     1021146 :             signal[i] = mult_r( signal[i], window_half[window_half_length / 2 - 1 - w].v.im ); /*Qx*/
     639     1021146 :             move16();
     640     1021146 :             i = add( i, 1 );
     641             :         }
     642     1377729 :         FOR( ; i < window_length; i++ )
     643             :         {
     644     1361528 :             move16();
     645     1361528 :             signal[i] = 0;
     646             :         }
     647             :     }
     648             :     ELSE /* normal full/maximum overlap */
     649             :     {
     650             : 
     651       44820 :         n = shr( window_length, 1 ); /*Q0*/
     652     5774040 :         FOR( i = 0; i < n; i++ )
     653             :         {
     654     5729220 :             move16();
     655     5729220 :             signal[i] = mult_r( signal[i], window[i].v.re ); /*Qx*/
     656     5729220 :             move16();
     657     5729220 :             signal[window_length - 1 - i] = mult_r( signal[window_length - 1 - i], window[i].v.im ); /*Qx*/
     658             :         }
     659             :     }
     660      121599 : }
     661             : /*-------------------------------------------------------------------*
     662             :  * lpc2mdct()
     663             :  *
     664             :  *
     665             :  *-------------------------------------------------------------------*/
     666             : 
     667      275178 : 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      275178 :     assert( length <= FDNS_NPTS );
     689      275178 :     sizeN = shl( length, 1 ); /*Q0*/
     690             : 
     691      275178 :     BASOP_getTables( NULL, &ptwiddle, &step, sizeN );
     692             :     /*ODFT*/
     693      275178 :     assert( lpcOrder < FDNS_NPTS );
     694             :     /* pre-twiddle */
     695     4970699 :     FOR( i = 0; i <= lpcOrder; i++ )
     696             :     {
     697     4695521 :         ComplexData[2 * i] = L_mult( lpcCoeffs[i], ptwiddle->v.re ); /*Q12*/
     698     4695521 :         move32();
     699     4695521 :         ComplexData[2 * i + 1] = L_negate( L_mult( lpcCoeffs[i], ptwiddle->v.im ) ); /*Q12*/
     700     4695521 :         move32();
     701     4695521 :         ptwiddle += step;
     702             :     }
     703             :     /* zero padding */
     704    13191049 :     FOR( ; i < FDNS_NPTS; i++ )
     705             :     {
     706    12915871 :         ComplexData[2 * i] = L_deposit_l( 0 );
     707    12915871 :         move32();
     708    12915871 :         ComplexData[2 * i + 1] = L_deposit_l( 0 );
     709    12915871 :         move32();
     710             :     }
     711             : 
     712      275178 :     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      275178 :         scale = add( norm_s( lpcCoeffs[0] ), 1 );
     732      275178 :         BASOP_cfft( (cmplx *) ComplexData, FDNS_NPTS, &scale, workBuffer ); /*Q31 - scale*/
     733             :         /*Get amplitude*/
     734      275178 :         j = sub( length, 1 );
     735      275178 :         k = 0;
     736     9080874 :         FOR( i = 0; i < length / 2; i++ )
     737             :         {
     738     8805696 :             s = sub( norm_l( L_max( L_abs( ComplexData[2 * i] ), L_abs( ComplexData[2 * i + 1] ) ) ), 1 );
     739     8805696 :             tmp16 = extract_h( L_shl( ComplexData[2 * i], s ) );     /*Q15 - scale + s*/
     740     8805696 :             tmp32 = L_mult( tmp16, tmp16 );                          /*Q15 - 2*(scale - s)*/
     741     8805696 :             tmp16 = extract_h( L_shl( ComplexData[2 * i + 1], s ) ); /*Q15 - scale + s*/
     742     8805696 :             tmp16 = mac_r( tmp32, tmp16, tmp16 );                    /*Q15 - 2*(scale - s)*/
     743     8805696 :             s = shl( sub( scale, s ), 1 );
     744     8805696 :             if ( tmp16 == 0 )
     745             :             {
     746           0 :                 s = -16;
     747           0 :                 move16();
     748             :             }
     749     8805696 :             if ( tmp16 == 0 )
     750             :             {
     751           0 :                 tmp16 = 1;
     752           0 :                 move16();
     753             :             }
     754     8805696 :             BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e ); /*Q15 - ig_e*/
     755     8805696 :             if ( mdct_gains != 0 )
     756             :             {
     757     8225440 :                 mdct_gains[k] = g; /*Q15 - g_e*/
     758     8225440 :                 move16();
     759             :             }
     760     8805696 :             if ( mdct_gains_exp != 0 )
     761             :             {
     762     8225440 :                 mdct_gains_exp[k] = g_e;
     763     8225440 :                 move16();
     764             :             }
     765     8805696 :             if ( mdct_inv_gains != 0 )
     766             :             {
     767     8212256 :                 mdct_inv_gains[k] = ig; /*Q15 - ig_e*/
     768     8212256 :                 move16();
     769             :             }
     770     8805696 :             if ( mdct_inv_gains_exp != 0 )
     771             :             {
     772     8212256 :                 mdct_inv_gains_exp[k] = ig_e;
     773     8212256 :                 move16();
     774             :             }
     775     8805696 :             k = add( k, 1 );
     776     8805696 :             s = sub( norm_l( L_max( L_abs( ComplexData[2 * j] ), L_abs( ComplexData[2 * j + 1] ) ) ), 1 );
     777     8805696 :             tmp16 = extract_h( L_shl( ComplexData[2 * j], s ) );     /*Q15 - scale + s*/
     778     8805696 :             tmp32 = L_mult( tmp16, tmp16 );                          /*Q15 - 2*(scale - s)*/
     779     8805696 :             tmp16 = extract_h( L_shl( ComplexData[2 * j + 1], s ) ); /*Q15 - scale + s*/
     780     8805696 :             tmp16 = mac_r( tmp32, tmp16, tmp16 );                    /*Q15 - 2*(scale - s)*/
     781     8805696 :             s = shl( sub( scale, s ), 1 );
     782     8805696 :             if ( tmp16 == 0 )
     783             :             {
     784           0 :                 s = -16;
     785           0 :                 move16();
     786             :             }
     787     8805696 :             if ( tmp16 == 0 )
     788             :             {
     789           0 :                 tmp16 = 1;
     790           0 :                 move16();
     791             :             }
     792     8805696 :             BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     793     8805696 :             if ( mdct_gains != 0 )
     794             :             {
     795     8225440 :                 mdct_gains[k] = g; /*Q15 - g_e*/
     796     8225440 :                 move16();
     797             :             }
     798     8805696 :             if ( mdct_gains_exp != 0 )
     799             :             {
     800     8225440 :                 mdct_gains_exp[k] = g_e;
     801     8225440 :                 move16();
     802             :             }
     803     8805696 :             if ( mdct_inv_gains != 0 )
     804             :             {
     805     8212256 :                 mdct_inv_gains[k] = ig; /*Q15 - ig_e*/
     806     8212256 :                 move16();
     807             :             }
     808     8805696 :             if ( mdct_inv_gains_exp != 0 )
     809             :             {
     810     8212256 :                 mdct_inv_gains_exp[k] = ig_e;
     811     8212256 :                 move16();
     812             :             }
     813     8805696 :             j = sub( j, 1 );
     814     8805696 :             k = add( k, 1 );
     815             :         }
     816             :     }
     817      275178 : }
     818             : 
     819      216113 : 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      216113 :     assert( length <= FDNS_NPTS );
     835      216113 :     sizeN = shl( length, 1 ); /*Q0*/
     836             : 
     837      216113 :     BASOP_getTables( NULL, &ptwiddle, &step, sizeN );
     838             : 
     839             :     /* ODFT */
     840     3890034 :     FOR( i = 0; i < lpcOrder + 1; i++ )
     841             :     {
     842     3673921 :         RealData_fx[i] = L_mult( lpcCoeffs[i], ptwiddle->v.re ); /*Q12*/
     843     3673921 :         move32();
     844     3673921 :         ImagData_fx[i] = L_negate( L_mult( lpcCoeffs[i], ptwiddle->v.im ) ); /*Q12*/
     845     3673921 :         move32();
     846     3673921 :         ptwiddle += step;
     847             :     }
     848             : 
     849    24204656 :     FOR( ; i < sizeN; i++ )
     850             :     {
     851    23988543 :         RealData_fx[i] = L_deposit_l( 0 );
     852    23988543 :         move32();
     853    23988543 :         ImagData_fx[i] = L_deposit_l( 0 );
     854    23988543 :         move32();
     855             :     }
     856             : 
     857             :     /* half length FFT */
     858      216113 :     scale = add( norm_s( lpcCoeffs[0] ), 1 );
     859      216113 :     BASOP_cfft_ivas( RealData_fx, ImagData_fx, 1, &scale ); /*Q31 - scale*/
     860             : 
     861             :     /*Get amplitude*/
     862      216113 :     j = sub( FDNS_NPTS, 1 );
     863      216113 :     move16();
     864      216113 :     k = 0;
     865      216113 :     move16();
     866             : 
     867     7131729 :     FOR( i = 0; i < FDNS_NPTS / 2; i++ )
     868             :     {
     869     6915616 :         s = sub( norm_l( L_max( L_abs( RealData_fx[i] ), L_abs( ImagData_fx[i] ) ) ), 1 );
     870             : 
     871     6915616 :         tmp16 = extract_h( L_shl( RealData_fx[i], s ) ); /*Q15 - scale + s*/
     872     6915616 :         tmp32 = L_mult( tmp16, tmp16 );                  /*Q15 - 2*(scale - s)*/
     873             : 
     874     6915616 :         tmp16 = extract_h( L_shl( ImagData_fx[i], s ) ); /*Q15 - scale + s*/
     875     6915616 :         tmp16 = mac_r( tmp32, tmp16, tmp16 );            /*Q15 - 2*(scale - s)*/
     876             : 
     877     6915616 :         s = shl( sub( scale, s ), 1 );
     878             : 
     879     6915616 :         if ( tmp16 == 0 )
     880             :         {
     881           0 :             s = -16;
     882           0 :             move16();
     883             :         }
     884     6915616 :         if ( tmp16 == 0 )
     885             :         {
     886           0 :             tmp16 = 1;
     887           0 :             move16();
     888             :         }
     889             : 
     890     6915616 :         BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     891             : 
     892     6915616 :         if ( mdct_gains_fx != NULL )
     893             :         {
     894           0 :             mdct_gains_fx[k] = g; /*Q15 - g_e*/
     895           0 :             move16();
     896             :         }
     897             : 
     898     6915616 :         if ( mdct_gains_e != NULL )
     899             :         {
     900           0 :             mdct_gains_e[k] = g_e;
     901           0 :             move16();
     902             :         }
     903             : 
     904     6915616 :         if ( mdct_inv_gains_fx != NULL )
     905             :         {
     906     6915616 :             mdct_inv_gains_fx[k] = ig; /*Q15 - ig_e*/
     907     6915616 :             move16();
     908             :         }
     909             : 
     910     6915616 :         if ( mdct_inv_gains_e != NULL )
     911             :         {
     912     6915616 :             mdct_inv_gains_e[k] = ig_e;
     913     6915616 :             move16();
     914             :         }
     915             : 
     916     6915616 :         k = add( k, 1 );
     917             : 
     918             : 
     919     6915616 :         s = sub( norm_l( L_max( L_abs( RealData_fx[j] ), L_abs( ImagData_fx[j] ) ) ), 1 );
     920             : 
     921     6915616 :         tmp16 = extract_h( L_shl( RealData_fx[j], s ) ); /*Q15 - scale + s*/
     922     6915616 :         tmp32 = L_mult( tmp16, tmp16 );                  /*Q15 - 2*(scale - s)*/
     923             : 
     924     6915616 :         tmp16 = extract_h( L_shl( ImagData_fx[j], s ) ); /*Q15 - scale + s*/
     925     6915616 :         tmp16 = mac_r( tmp32, tmp16, tmp16 );            /*Q15 - 2*(scale - s)*/
     926             : 
     927     6915616 :         s = shl( sub( scale, s ), 1 );
     928             : 
     929     6915616 :         if ( tmp16 == 0 )
     930             :         {
     931           0 :             s = -16;
     932           0 :             move16();
     933             :         }
     934     6915616 :         if ( tmp16 == 0 )
     935             :         {
     936           0 :             tmp16 = 1;
     937           0 :             move16();
     938             :         }
     939             : 
     940     6915616 :         BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     941             : 
     942     6915616 :         if ( mdct_gains_fx != NULL )
     943             :         {
     944           0 :             mdct_gains_fx[k] = g;
     945           0 :             move16();
     946             :         }
     947             : 
     948     6915616 :         if ( mdct_gains_e != NULL )
     949             :         {
     950           0 :             mdct_gains_e[k] = g_e;
     951           0 :             move16();
     952             :         }
     953             : 
     954     6915616 :         if ( mdct_inv_gains_fx != NULL )
     955             :         {
     956     6915616 :             mdct_inv_gains_fx[k] = ig;
     957     6915616 :             move16();
     958             :         }
     959             : 
     960     6915616 :         if ( mdct_inv_gains_e != NULL )
     961             :         {
     962     6915616 :             mdct_inv_gains_e[k] = ig_e;
     963     6915616 :             move16();
     964             :         }
     965             : 
     966     6915616 :         j = sub( j, 1 );
     967     6915616 :         k = add( k, 1 );
     968             :     }
     969             : 
     970      216113 :     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      581160 : 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      581160 :     Word32 *px = x; /*Qx*/
     992      581160 :     Word16 const *pgains = gains;
     993      581160 :     Word16 const *pgainsexp = gains_exp;
     994             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     995      581160 :     Flag Overflow = 0;
     996             : #endif
     997             : 
     998             :     /* FDNS_NPTS = 64 */
     999      581160 :     k = shr( lg, 6 ); /*Q0*/
    1000      581160 :     m = s_and( lg, 0x3F );
    1001             : 
    1002      581160 :     IF( m != 0 )
    1003             :     {
    1004       19743 :         IF( LE_16( m, FDNS_NPTS / 2 ) )
    1005             :         {
    1006       19743 :             n = idiv1616U( FDNS_NPTS, m ); /*Q0*/
    1007       19743 :             k1 = k;
    1008       19743 :             move16();
    1009       19743 :             k2 = add( k, 1 );
    1010             :         }
    1011             :         ELSE
    1012             :         {
    1013           0 :             n = idiv1616U( FDNS_NPTS, sub( FDNS_NPTS, m ) ); /*Q0*/
    1014           0 :             k1 = add( k, 1 );
    1015           0 :             k2 = k;
    1016           0 :             move16();
    1017             :         }
    1018             : 
    1019       19743 :         i = 0;
    1020       19743 :         move16();
    1021       19743 :         j = 0;
    1022       19743 :         move16();
    1023             : 
    1024     1283295 :         WHILE( LT_16( i, lg ) )
    1025             :         {
    1026             : 
    1027     1263552 :             k = k2;
    1028     1263552 :             move16();
    1029     1263552 :             if ( j != 0 )
    1030             :             {
    1031      943632 :                 k = k1;
    1032      943632 :                 move16();
    1033             :             }
    1034             : 
    1035     1263552 :             j = add( j, 1 );
    1036     1263552 :             if ( EQ_16( j, n ) )
    1037             :             {
    1038      319920 :                 j = 0;
    1039      319920 :                 move16();
    1040             :             }
    1041             : 
    1042             :             /* Limit number of loops, if end is reached */
    1043     1263552 :             k = s_min( k, sub( lg, i ) );
    1044             : 
    1045     9243632 :             FOR( l = 0; l < k; l++ )
    1046             :             {
    1047     7980080 :                 *x = L_shl_o( Mpy_32_16_r( *x, *gains ), *gains_exp, &Overflow ); /*Qx*/
    1048     7980080 :                 move32();
    1049     7980080 :                 x++;
    1050             :             }
    1051     1263552 :             i = add( i, k );
    1052             : 
    1053     1263552 :             gains++;
    1054     1263552 :             gains_exp++;
    1055             :         }
    1056             :     }
    1057             :     ELSE
    1058             :     {
    1059     3608180 :         FOR( l = 0; l < k; l++ )
    1060             :         {
    1061     3046763 :             x = &px[l]; /*Qx*/
    1062     3046763 :             gains = pgains;
    1063     3046763 :             gains_exp = pgainsexp;
    1064   198039595 :             FOR( i = 0; i < FDNS_NPTS; i++ )
    1065             :             {
    1066   194992832 :                 *x = L_shl_o( Mpy_32_16_r( *x, *gains ), *gains_exp, &Overflow ); /*Qx*/
    1067   194992832 :                 move32();
    1068   194992832 :                 x += k;
    1069   194992832 :                 gains++;
    1070   194992832 :                 gains_exp++;
    1071             :             }
    1072             :         }
    1073             :     }
    1074      581160 : }
    1075             : 
    1076         697 : void mdct_shaping_16(
    1077             :     const Word16 x[],      /*Qx*/
    1078             :     const Word16 lg,       /*Q0*/
    1079             :     const Word16 lg_total, /*Q0*/
    1080             :     const Word16 gains[],  /*15 - gains_exp*/
    1081             :     const Word16 gains_exp[],
    1082             :     Word16 gains_max_exp,
    1083             :     Word32 y[] /*Qx*/ )
    1084             : {
    1085             :     Word16 i, k, l;
    1086             :     Word16 m, gain_exp;
    1087             :     Word16 const *px;
    1088             :     Word32 *py;
    1089         697 :     Word16 const *pgains = gains;
    1090             :     Word16 gains_exp_loc[FDNS_NPTS];
    1091             :     Word16 const *pgains_exp;
    1092             : 
    1093             :     /* FDNS_NPTS = 64 */
    1094         697 :     k = shr( lg, 6 ); /*Q0*/
    1095         697 :     m = s_and( lg, 0x3F );
    1096             : 
    1097         697 :     assert( m == 0 );
    1098             :     {
    1099       45305 :         FOR( i = 0; i < FDNS_NPTS; i++ )
    1100             :         {
    1101       44608 :             gains_exp_loc[i] = sub( gains_exp[i], gains_max_exp );
    1102       44608 :             move16();
    1103             :         }
    1104        5059 :         FOR( l = 0; l < k; l++ )
    1105             :         {
    1106        4362 :             px = &x[l];     /*Qx*/
    1107        4362 :             py = &y[l];     /*Qx*/
    1108        4362 :             pgains = gains; /*15 - gains_exp*/
    1109        4362 :             pgains_exp = gains_exp_loc;
    1110      283530 :             FOR( i = 0; i < FDNS_NPTS; i++ )
    1111             :             {
    1112      279168 :                 *py = L_shl( L_mult( *px, *pgains ), *pgains_exp ); /*Qx*/
    1113      279168 :                 move32();
    1114      279168 :                 px += k;
    1115      279168 :                 py += k;
    1116      279168 :                 pgains++;
    1117      279168 :                 pgains_exp++;
    1118             :             }
    1119             :         }
    1120             :     }
    1121             : 
    1122         697 :     gain_exp = sub( gains_exp[FDNS_NPTS - 1], gains_max_exp );
    1123       19173 :     FOR( i = lg; i < lg_total; i++ )
    1124             :     {
    1125       18476 :         y[i] = L_shl( L_mult( x[i], gains[FDNS_NPTS - 1] ), gain_exp ); /*Qx*/
    1126       18476 :         move32();
    1127             :     }
    1128         697 : }
    1129             : 
    1130      767661 : void mdct_noiseShaping_ivas_fx(
    1131             :     Word32 x_fx[], /*Q31 - x_e*/
    1132             :     Word16 *x_e,
    1133             :     const Word16 lg,         /*Q0*/
    1134             :     const Word16 gains_fx[], /*Q15 - gains_exp*/
    1135             :     const Word16 gains_exp[]
    1136             :     /*const Word16 nBands*/ /*Parameter added in IVAS, but always equal to FDNS_NPTS */
    1137             : )
    1138             : {
    1139             :     Word16 i, j, k, l;
    1140             :     Word16 m, n, k1, k2;
    1141             : 
    1142      767661 :     j = 0;
    1143      767661 :     move16();
    1144             :     /* FDNS_NPTS = 64 */
    1145      767661 :     k = shr( lg, 6 ); /*Q0*/
    1146      767661 :     m = s_and( lg, 0x3F );
    1147             : 
    1148      767661 :     Word16 max_e = MIN16B;
    1149      767661 :     move16();
    1150    49897965 :     FOR( i = 0; i < FDNS_NPTS; i++ )
    1151             :     {
    1152    49130304 :         max_e = s_max( max_e, add( *x_e, gains_exp[i] ) );
    1153             :     }
    1154             : 
    1155      767661 :     IF( m != 0 )
    1156             :     {
    1157        8021 :         IF( LE_16( m, FDNS_NPTS / 2 ) )
    1158             :         {
    1159        8021 :             n = idiv1616U( FDNS_NPTS, m ); /*Q0*/
    1160        8021 :             k1 = k;
    1161        8021 :             move16();
    1162        8021 :             k2 = add( k, 1 );
    1163             :         }
    1164             :         ELSE
    1165             :         {
    1166           0 :             n = idiv1616U( FDNS_NPTS, sub( FDNS_NPTS, m ) ); /*Q0*/
    1167           0 :             k1 = add( k, 1 );
    1168           0 :             k2 = k;
    1169           0 :             move16();
    1170             :         }
    1171             : 
    1172        8021 :         i = 0;
    1173        8021 :         move16();
    1174        8021 :         j = 0;
    1175        8021 :         move16();
    1176             : 
    1177      521365 :         WHILE( LT_16( i, lg ) )
    1178             :         {
    1179      513344 :             IF( j % n != 0 )
    1180             :             {
    1181      377040 :                 k = k1;
    1182      377040 :                 move16();
    1183             :             }
    1184             :             ELSE
    1185             :             {
    1186      136304 :                 k = k2;
    1187      136304 :                 move16();
    1188             :             }
    1189             : 
    1190             :             /* Limit number of loops, if end is reached */
    1191      513344 :             k = s_min( k, sub( lg, i ) );
    1192             : 
    1193     3885104 :             FOR( l = 0; l < k; l++ )
    1194             :             {
    1195     3371760 :                 x_fx[i] = Mpy_32_16_1( x_fx[i], gains_fx[j] ); /*Q31 - x_e*/
    1196     3371760 :                 move32();
    1197     3371760 :                 x_fx[i] = L_shr( x_fx[i], sub( max_e, add( *x_e, gains_exp[j] ) ) ); /*Q31 - max_e*/
    1198     3371760 :                 move32();
    1199     3371760 :                 i = add( i, 1 );
    1200             :             }
    1201      513344 :             j = add( j, 1 );
    1202             :         }
    1203             :     }
    1204             :     ELSE
    1205             :     {
    1206    49376600 :         FOR( i = 0; i < lg; )
    1207             :         {
    1208   335128448 :             FOR( l = 0; l < k; l++ )
    1209             :             {
    1210   286511488 :                 x_fx[i] = Mpy_32_16_1( x_fx[i], gains_fx[j] ); /*Q31 - x_e*/
    1211   286511488 :                 move32();
    1212   286511488 :                 x_fx[i] = L_shr( x_fx[i], sub( max_e, add( *x_e, gains_exp[j] ) ) ); /*Q31 - max_e*/
    1213   286511488 :                 move32();
    1214   286511488 :                 i = add( i, 1 );
    1215             :             }
    1216    48616960 :             j = add( j, 1 );
    1217             :         }
    1218             :     }
    1219             : 
    1220      767661 :     *x_e = max_e;
    1221      767661 :     move16();
    1222             : 
    1223      767661 :     return;
    1224             : }
    1225             : 
    1226             : 
    1227       17495 : void mdct_noiseShaping_interp(
    1228             :     Word32 x[],      /*Qx*/
    1229             :     const Word16 lg, /*Q0*/
    1230             :     Word16 gains[],  /*Q15 - gains_exp*/
    1231             :     Word16 gains_exp[] )
    1232             : {
    1233             :     Word16 i, j, jp, jn, k, l;
    1234             :     Word16 g, pg, ng, e, tmp;
    1235             : 
    1236             : 
    1237       17495 :     assert( lg % FDNS_NPTS == 0 );
    1238       17495 :     k = shr( lg, 6 ); /* FDNS_NPTS = 64 Q0*/
    1239             : 
    1240       17495 :     IF( gains )
    1241             :     {
    1242             :         /* Linear interpolation */
    1243       17495 :         IF( EQ_16( k, 4 ) )
    1244             :         {
    1245       15849 :             jp = 0;
    1246       15849 :             move16();
    1247       15849 :             j = 0;
    1248       15849 :             move16();
    1249       15849 :             jn = 1;
    1250       15849 :             move16();
    1251             : 
    1252     1030185 :             FOR( i = 0; i < lg; i += 4 )
    1253             :             {
    1254     1014336 :                 pg = gains[jp]; /*Q15 - gains_exp*/
    1255     1014336 :                 move16();
    1256     1014336 :                 g = gains[j]; /*Q15 - gains_exp*/
    1257     1014336 :                 move16();
    1258     1014336 :                 ng = gains[jn]; /*Q15 - gains_exp*/
    1259     1014336 :                 move16();
    1260             : 
    1261             :                 /* common exponent for pg and g */
    1262     1014336 :                 tmp = sub( gains_exp[j], gains_exp[jp] );
    1263     1014336 :                 if ( tmp > 0 )
    1264      111291 :                     pg = shr( pg, tmp );
    1265     1014336 :                 if ( tmp < 0 )
    1266       66597 :                     g = shl( g, tmp );
    1267     1014336 :                 e = s_max( gains_exp[j], gains_exp[jp] );
    1268             : 
    1269     1014336 :                 tmp = mac_r( L_mult( pg, 12288 /*0.375f Q15*/ ), g, 20480 /*0.625f Q15*/ ); /*Q15 - gains_exp*/
    1270     1014336 :                 x[i] = L_shl( Mpy_32_16_1( x[i], tmp ), e );                                /*Qx*/
    1271     1014336 :                 move32();
    1272             : 
    1273     1014336 :                 tmp = mac_r( L_mult( pg, 4096 /*0.125f Q15*/ ), g, 28672 /*0.875f Q15*/ ); /*Q15 - gains_exp*/
    1274     1014336 :                 x[i + 1] = L_shl( Mpy_32_16_1( x[i + 1], tmp ), e );                       /*Qx*/
    1275     1014336 :                 move32();
    1276             : 
    1277             :                 /* common exponent for g and ng */
    1278     1014336 :                 g = gains[j]; /*Q15 - gains_exp*/
    1279     1014336 :                 move16();
    1280     1014336 :                 tmp = sub( gains_exp[j], gains_exp[jn] );
    1281     1014336 :                 if ( tmp > 0 )
    1282       66597 :                     ng = shr( ng, tmp );
    1283     1014336 :                 if ( tmp < 0 )
    1284      111291 :                     g = shl( g, tmp );
    1285     1014336 :                 e = s_max( gains_exp[j], gains_exp[jn] );
    1286             : 
    1287     1014336 :                 tmp = mac_r( L_mult( g, 28672 /*0.875f Q15*/ ), ng, 4096 /*0.125f Q15*/ ); /*Q15 - gains_exp*/
    1288     1014336 :                 x[i + 2] = L_shl( Mpy_32_16_1( x[i + 2], tmp ), e );                       /*Qx*/
    1289     1014336 :                 move32();
    1290             : 
    1291     1014336 :                 tmp = mac_r( L_mult( g, 20480 /*0.625f Q15*/ ), ng, 12288 /*0.375f Q15*/ ); /*Q15 - gains_exp*/
    1292     1014336 :                 x[i + 3] = L_shl( Mpy_32_16_1( x[i + 3], tmp ), e );                        /*Qx*/
    1293     1014336 :                 move32();
    1294             : 
    1295     1014336 :                 jp = j;
    1296     1014336 :                 move16();
    1297     1014336 :                 j = jn;
    1298     1014336 :                 move16();
    1299     1014336 :                 jn = s_min( add( jn, 1 ), FDNS_NPTS - 1 );
    1300             :             }
    1301             :         }
    1302        1646 :         ELSE IF( EQ_16( k, 5 ) )
    1303             :         {
    1304        1646 :             jp = 0;
    1305        1646 :             move16();
    1306        1646 :             j = 0;
    1307        1646 :             move16();
    1308        1646 :             jn = 1;
    1309        1646 :             move16();
    1310             : 
    1311      106990 :             FOR( i = 0; i < lg; i += 5 )
    1312             :             {
    1313      105344 :                 pg = gains[jp]; /*Q15 - gains_exp*/
    1314      105344 :                 move16();
    1315      105344 :                 g = gains[j]; /*Q15 - gains_exp*/
    1316      105344 :                 move16();
    1317      105344 :                 ng = gains[jn]; /*Q15 - gains_exp*/
    1318      105344 :                 move16();
    1319             : 
    1320             :                 /* common exponent for pg and g */
    1321      105344 :                 tmp = sub( gains_exp[j], gains_exp[jp] );
    1322      105344 :                 if ( tmp > 0 )
    1323       11181 :                     pg = shr( pg, tmp );
    1324      105344 :                 if ( tmp < 0 )
    1325        6544 :                     g = shl( g, tmp );
    1326      105344 :                 e = s_max( gains_exp[j], gains_exp[jp] );
    1327             : 
    1328      105344 :                 tmp = mac_r( L_mult( pg, 13107 /*0.40f Q15*/ ), g, 19661 /*0.60f Q15*/ ); /*Q15 - gains_exp*/
    1329      105344 :                 x[i] = L_shl( Mpy_32_16_1( x[i], tmp ), e );                              /*Qx*/
    1330      105344 :                 move32();
    1331             : 
    1332      105344 :                 tmp = mac_r( L_mult( pg, 6554 /*0.20f Q15*/ ), g, 26214 /*0.80f Q15*/ ); /*Q15 - gains_exp*/
    1333      105344 :                 x[i + 1] = L_shl( Mpy_32_16_1( x[i + 1], tmp ), e );                     /*Qx*/
    1334      105344 :                 move32();
    1335             : 
    1336             : 
    1337      105344 :                 x[i + 2] = L_shl( Mpy_32_16_1( x[i + 2], gains[j] ), gains_exp[j] ); /*Qx*/
    1338      105344 :                 move32();
    1339             : 
    1340             :                 /* common exponent for g and ng */
    1341      105344 :                 g = gains[j]; /*Q15 - gains_exp*/
    1342      105344 :                 move16();
    1343      105344 :                 tmp = sub( gains_exp[j], gains_exp[jn] );
    1344      105344 :                 if ( tmp > 0 )
    1345        6544 :                     ng = shr( ng, tmp );
    1346      105344 :                 if ( tmp < 0 )
    1347       11181 :                     g = shl( g, tmp );
    1348      105344 :                 e = s_max( gains_exp[j], gains_exp[jn] );
    1349             : 
    1350      105344 :                 tmp = mac_r( L_mult( g, 26214 /*0.80f Q15*/ ), ng, 6554 /*0.20f Q15*/ ); /*Q15 - gains_exp*/
    1351      105344 :                 x[i + 3] = L_shl( Mpy_32_16_1( x[i + 3], tmp ), e );                     /*Qx*/
    1352      105344 :                 move32();
    1353             : 
    1354      105344 :                 tmp = mac_r( L_mult( g, 19661 /*0.60f Q15*/ ), ng, 13107 /*0.40f Q15*/ ); /*Q15 - gains_exp*/
    1355      105344 :                 x[i + 4] = L_shl( Mpy_32_16_1( x[i + 4], tmp ), e );                      /*Qx*/
    1356      105344 :                 move32();
    1357             : 
    1358      105344 :                 jp = j;
    1359      105344 :                 move16();
    1360      105344 :                 j = jn;
    1361      105344 :                 move16();
    1362      105344 :                 jn = s_min( add( jn, 1 ), FDNS_NPTS - 1 );
    1363             :             }
    1364             :         }
    1365             :         ELSE /* no interpolation */
    1366             :         {
    1367           0 :             FOR( i = 0; i < FDNS_NPTS; i++ )
    1368             :             {
    1369           0 :                 FOR( l = 0; l < k; l++ )
    1370             :                 {
    1371           0 :                     *x = L_shl( Mpy_32_16_1( *x, *gains ), *gains_exp ); /*Qx*/
    1372           0 :                     move32();
    1373           0 :                     x++;
    1374             :                 }
    1375             : 
    1376           0 :                 gains++;
    1377           0 :                 gains_exp++;
    1378             :             }
    1379             :         }
    1380             :     }
    1381       17495 : }
    1382             : 
    1383       56365 : void PsychAdaptLowFreqDeemph(
    1384             :     Word32 x[],              /*Qx*/
    1385             :     const Word16 lpcGains[], /*Q15 - lpcGains_e*/
    1386             :     const Word16 lpcGains_e[],
    1387             :     Word16 lf_deemph_factors[] /*Q15*/ )
    1388             : {
    1389             :     Word16 i;
    1390             :     Word16 max_val, max_e, fac, min, min_e, tmp, tmp_e;
    1391             :     Word32 L_tmp;
    1392             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1393       56365 :     Flag Overflow = 0;
    1394             : #endif
    1395             : 
    1396             : 
    1397       56365 :     assert( lpcGains[0] >= 0x4000 );
    1398             : 
    1399       56365 :     max_val = lpcGains[0]; /*Q15 - lpcGains_e*/
    1400       56365 :     move16();
    1401       56365 :     max_e = lpcGains_e[0];
    1402       56365 :     move16();
    1403       56365 :     min = lpcGains[0]; /*Q15 - lpcGains_e*/
    1404       56365 :     move16();
    1405       56365 :     min_e = lpcGains_e[0];
    1406       56365 :     move16();
    1407             : 
    1408             :     /* find minimum (min) and maximum (max_val) of LPC gains in low frequencies */
    1409      507285 :     FOR( i = 1; i < 9; i++ )
    1410             :     {
    1411      450920 :         IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], min, min_e ) < 0 )
    1412             :         {
    1413      333520 :             min = lpcGains[i]; /*Q15 - lpcGains_e*/
    1414      333520 :             move16();
    1415      333520 :             min_e = lpcGains_e[i];
    1416      333520 :             move16();
    1417             :         }
    1418             : 
    1419      450920 :         IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], max_val, max_e ) > 0 )
    1420             :         {
    1421       82813 :             max_val = lpcGains[i]; /*Q15 - lpcGains_e*/
    1422       82813 :             move16();
    1423       82813 :             max_e = lpcGains_e[i];
    1424       82813 :             move16();
    1425             :         }
    1426             :     }
    1427             : 
    1428       56365 :     min_e = add( min_e, 5 ); /* min *= 32.0f; */
    1429             : 
    1430       56365 :     test();
    1431       56365 :     IF( ( compMantExp16Unorm( max_val, max_e, min, min_e ) < 0 ) && ( min > 0 ) )
    1432             :     {
    1433             :         /* fac = tmp = (float)pow(max_val / min, 0.0078125f); */
    1434       56365 :         tmp_e = min_e;
    1435       56365 :         move16();
    1436       56365 :         tmp = Inv16( min, &tmp_e );                                   /*Q15 - tmp_e*/
    1437       56365 :         L_tmp = L_shl( L_mult( tmp, max_val ), add( tmp_e, max_e ) ); /* Q31 */
    1438       56365 :         L_tmp = BASOP_Util_Log2( L_tmp );                             /* Q25 */
    1439       56365 :         L_tmp = L_shr( L_tmp, 7 );                                    /* 0.0078125f = 1.f/(1<<7) */
    1440       56365 :         L_tmp = BASOP_Util_InvLog2( L_tmp );                          /* Q31 */
    1441       56365 :         tmp = round_fx_o( L_tmp, &Overflow );                         /* Q15 */
    1442       56365 :         fac = tmp;                                                    /* Q15 */
    1443       56365 :         move16();
    1444             : 
    1445             :         /* gradual lowering of lowest 32 bins; DC is lowered by (max_val/tmp)^1/4 */
    1446     1860045 :         FOR( i = 31; i >= 0; i-- )
    1447             :         {
    1448     1803680 :             x[i] = Mpy_32_16_1( x[i], fac );
    1449     1803680 :             move32();
    1450     1803680 :             if ( lf_deemph_factors != NULL )
    1451             :             {
    1452     1007488 :                 lf_deemph_factors[i] = mult_r( lf_deemph_factors[i], fac );
    1453     1007488 :                 move16();
    1454             :             }
    1455     1803680 :             fac = mult_r( fac, tmp ); /* Q15 */
    1456             :         }
    1457             :     }
    1458       56365 : }
    1459             : 
    1460      258898 : void AdaptLowFreqDeemph(
    1461             :     Word32 x[], /*Q31 - x_e*/
    1462             :     Word16 x_e,
    1463             :     Word16 tcx_lpc_shaped_ari, /*Q0*/
    1464             :     Word16 lpcGains[],         /*Q15 - lpcGains_e*/
    1465             :     Word16 lpcGains_e[],
    1466             :     const Word16 lg, /*Q0*/
    1467             :     Word16 lf_deemph_factors[] /*Q15*/ )
    1468             : {
    1469             : 
    1470             :     Word16 i, i_max, i_max_old, lg_4;
    1471             :     Word32 v2, v4, tmp32;
    1472             : 
    1473      258898 :     tmp32 = 0; /* to avoid compilation warnings */
    1474      258898 :     move32();
    1475             : 
    1476      258898 :     IF( tcx_lpc_shaped_ari == 0 )
    1477             :     {
    1478      209919 :         v2 = L_shl( 2, sub( 31, x_e ) ); /* 2.0 */
    1479      209919 :         v4 = L_shl( v2, 1 );             /* 4.0 */
    1480      209919 :         lg_4 = shr( lg, 2 );             /* lg/4 */
    1481             : 
    1482             :         /* 1. find first magnitude maximum in lower quarter of spectrum */
    1483      209919 :         i_max = -1;
    1484      209919 :         move16();
    1485             : 
    1486     1241984 :         FOR( i = 0; i < lg_4; i++ )
    1487             :         {
    1488     1234851 :             IF( GE_32( L_abs( x[i] ), v4 ) )
    1489             :             {
    1490             : 
    1491             :                 /* Debug initialization to catch illegal x[i] values. */
    1492      202786 :                 tmp32 = 0;
    1493      202786 :                 move32();
    1494             : 
    1495      202786 :                 if ( x[i] < 0 )
    1496      101465 :                     tmp32 = L_add( x[i], v2 ); /*Q31 - x_e*/
    1497      202786 :                 if ( x[i] > 0 )
    1498      101321 :                     tmp32 = L_sub( x[i], v2 ); /*Q31 - x_e*/
    1499             : 
    1500      202786 :                 assert( tmp32 != 0 );
    1501             : 
    1502      202786 :                 x[i] = tmp32; /*Q31 - x_e*/
    1503      202786 :                 move32();
    1504      202786 :                 i_max = i;
    1505      202786 :                 move16();
    1506      202786 :                 BREAK;
    1507             :             }
    1508             :         }
    1509             : 
    1510             :         /* 2. expand value range of all xi up to i_max: two extra steps */
    1511      707544 :         FOR( i = 0; i < i_max; i++ )
    1512             :         {
    1513      497625 :             x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1514      497625 :             move32();
    1515      497625 :             lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1516      497625 :             move16();
    1517             :         }
    1518             : 
    1519             :         /* 3. find first magnitude maximum in lower quarter of spectrum */
    1520      209919 :         i_max_old = i_max; /*Q0*/
    1521      209919 :         move16();
    1522             : 
    1523      209919 :         IF( i_max_old >= 0 )
    1524             :         {
    1525      202786 :             i_max = -1;
    1526      202786 :             move16();
    1527             : 
    1528     1035191 :             FOR( i = 0; i < lg_4; i++ )
    1529             :             {
    1530     1035170 :                 IF( GE_32( L_abs( x[i] ), v4 ) )
    1531             :                 {
    1532      202765 :                     assert( x[i] != 0 );
    1533      202765 :                     if ( x[i] < 0 )
    1534      101790 :                         tmp32 = L_add( x[i], v2 ); /*Q31 - x_e*/
    1535      202765 :                     if ( x[i] >= 0 )
    1536      100975 :                         tmp32 = L_sub( x[i], v2 ); /*Q31 - x_e*/
    1537      202765 :                     x[i] = tmp32;                  /*Q31 - x_e*/
    1538      202765 :                     move32();
    1539      202765 :                     i_max = i;
    1540      202765 :                     move16();
    1541      202765 :                     BREAK;
    1542             :                 }
    1543             :             }
    1544             :         }
    1545             : 
    1546             :         /* 4. expand value range of all xi up to i_max: two extra steps */
    1547     1040788 :         FOR( i = 0; i < i_max; i++ )
    1548             :         {
    1549      830869 :             x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1550      830869 :             move32();
    1551      830869 :             lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1552      830869 :             move16();
    1553             :         }
    1554             : 
    1555             :         /* 5. always expand two lines; lines could be at index 0 and 1! */
    1556      209919 :         i_max = s_max( i_max, i_max_old ); /*Q0*/
    1557      209919 :         i = add( i_max, 1 );
    1558             : 
    1559      209919 :         IF( x[i] < 0 )
    1560             :         {
    1561       93095 :             tmp32 = L_sub( x[i], L_negate( v4 ) );
    1562             : 
    1563       93095 :             if ( tmp32 > 0 )
    1564             :             {
    1565       33351 :                 lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1566       33351 :                 move16();
    1567             :             }
    1568       93095 :             if ( tmp32 <= 0 )
    1569             :             {
    1570       59744 :                 x[i] = L_add( x[i], v2 ); /*Q31 - x_e*/
    1571       59744 :                 move32();
    1572             :             }
    1573       93095 :             if ( tmp32 > 0 )
    1574             :             {
    1575       33351 :                 x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1576       33351 :                 move32();
    1577             :             }
    1578             :         }
    1579             :         ELSE
    1580             :         {
    1581      116824 :             tmp32 = L_sub( x[i], v4 );
    1582             : 
    1583      116824 :             if ( tmp32 < 0 )
    1584             :             {
    1585       55199 :                 lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1586       55199 :                 move16();
    1587             :             }
    1588      116824 :             if ( tmp32 >= 0 )
    1589             :             {
    1590       61625 :                 x[i] = L_sub( x[i], v2 ); /*Q31 - x_e*/
    1591       61625 :                 move32();
    1592             :             }
    1593      116824 :             if ( tmp32 < 0 )
    1594             :             {
    1595       55199 :                 x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1596       55199 :                 move32();
    1597             :             }
    1598             :         }
    1599      209919 :         i = add( i, 1 );
    1600             : 
    1601      209919 :         IF( x[i] < 0 )
    1602             :         {
    1603       89674 :             tmp32 = L_sub( x[i], L_negate( v4 ) );
    1604             : 
    1605       89674 :             if ( tmp32 > 0 )
    1606             :             {
    1607       35340 :                 lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1608       35340 :                 move16();
    1609             :             }
    1610       89674 :             if ( tmp32 <= 0 )
    1611             :             {
    1612       54334 :                 x[i] = L_add( x[i], v2 ); /*Q31 - x_e*/
    1613       54334 :                 move32();
    1614             :             }
    1615       89674 :             if ( tmp32 > 0 )
    1616             :             {
    1617       35340 :                 x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1618       35340 :                 move32();
    1619             :             }
    1620             :         }
    1621             :         ELSE
    1622             :         {
    1623      120245 :             tmp32 = L_sub( x[i], v4 );
    1624             : 
    1625      120245 :             if ( tmp32 < 0 )
    1626             :             {
    1627       66288 :                 lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
    1628       66288 :                 move16();
    1629             :             }
    1630      120245 :             if ( tmp32 >= 0 )
    1631             :             {
    1632       53957 :                 x[i] = L_sub( x[i], v2 ); /*Q31 - x_e*/
    1633       53957 :                 move32();
    1634             :             }
    1635      120245 :             if ( tmp32 < 0 )
    1636             :             {
    1637       66288 :                 x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
    1638       66288 :                 move32();
    1639             :             }
    1640             :         }
    1641             :     }
    1642             :     ELSE /*if(!tcx_lpc_shaped_ari)*/
    1643             :     {
    1644       48979 :         PsychAdaptLowFreqDeemph( x, lpcGains, lpcGains_e, lf_deemph_factors );
    1645             :     } /*if(!tcx_lpc_shaped_ari)*/
    1646      258898 : }
    1647             : 
    1648      220495 : void tcx_noise_filling(
    1649             :     Word32 *Q, /*Q31 - Q_e*/
    1650             :     Word16 Q_e,
    1651             :     Word16 seed,
    1652             :     const Word16 iFirstLine,     /*Q0*/
    1653             :     const Word16 lowpassLine,    /*Q0*/
    1654             :     const Word16 nTransWidth,    /*Q0*/
    1655             :     const Word16 L_frame,        /*Q0*/
    1656             :     const Word16 tiltCompFactor, /*Q15*/
    1657             :     Word16 fac_ns,               /*Q15*/
    1658             :     Word16 *infoTCXNoise,        /*Q0*/
    1659             :     const Word16 element_mode    /* i  : IVAS element mode   Q0*/
    1660             : )
    1661             : {
    1662             :     Word16 i, m, segmentOffset;
    1663             :     Word16 win; /* window coefficient */
    1664             :     Word16 tilt_factor;
    1665             :     Word32 nrg;
    1666             :     Word16 tmp1, tmp2, s;
    1667             :     Word32 tmp32;
    1668             : 
    1669             : 
    1670             :     /* get inverse frame length */
    1671      220495 :     tmp1 = getInvFrameLen( L_frame ); /*Q21*/
    1672             : 
    1673             :     /* tilt_factor = (float)pow(max_val(0.375f, tiltCompFactor), 1.0f/(float)L_frame); */
    1674      220495 :     tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */
    1675      220495 :     tmp32 = L_shr( Mpy_32_16_1( tmp32, tmp1 ), 6 );                            /*Q25*/
    1676             :     BASOP_SATURATE_WARNING_OFF_EVS;
    1677      220495 :     tilt_factor = round_fx_sat( BASOP_Util_InvLog2( tmp32 ) ); /*Q15*/
    1678             :     BASOP_SATURATE_WARNING_ON_EVS;
    1679             : 
    1680             :     /* find last nonzero line below iFirstLine, use it as start offset */
    1681      220495 :     i = iFirstLine;
    1682      220495 :     move16();
    1683      220495 :     tmp1 = shr( iFirstLine, 1 );               /*Q0*/
    1684      220495 :     IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */
    1685             :     {
    1686           0 :         segmentOffset = i;
    1687           0 :         move16();
    1688             :     }
    1689             :     ELSE
    1690             :     {
    1691      656069 :         FOR( ; i > tmp1; i-- )
    1692             :         {
    1693      654791 :             IF( Q[i] != 0 )
    1694             :             {
    1695      219217 :                 BREAK;
    1696             :             }
    1697             :         }
    1698             :         /* fac_ns *= (float)pow(tilt_factor, (float)i); */
    1699    15087268 :         FOR( m = 0; m < i; m++ )
    1700             :         {
    1701    14866773 :             fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
    1702             :         }
    1703      220495 :         i = add( i, 1 );
    1704      220495 :         segmentOffset = i;
    1705             :     }
    1706      220495 :     nrg = L_deposit_l( 1 );
    1707      220495 :     win = 0;
    1708      220495 :     move16();
    1709             : 
    1710    66421881 :     FOR( ; i < lowpassLine; i++ )
    1711             :     {
    1712    66201386 :         fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
    1713             : 
    1714    66201386 :         IF( Q[i] != 0 )
    1715             :         {
    1716    18797467 :             IF( win > 0 )
    1717             :             {
    1718             :                 /* RMS-normalize current noise-filled segment */
    1719     9430721 :                 tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( i, segmentOffset ), &s ); /* mean */
    1720     9430721 :                 s = add( s, 9 - 15 );                                                   /* scaling */
    1721     9430721 :                 tmp1 = ISqrt16( tmp1, &s );                                             /* 1/RMS Q15 - s*/
    1722     9430721 :                 tmp1 = mult_r( tmp1, inv_int[nTransWidth] );                            /* compensate win Q15 - s*/
    1723     9430721 :                 s = add( s, sub( 16, Q_e ) );                                           /* scaling */
    1724             : 
    1725     9430721 :                 tmp2 = sub( i, win );
    1726     9430721 :                 IF( LT_16( segmentOffset, tmp2 ) )
    1727             :                 {
    1728     9984835 :                     FOR( m = segmentOffset; m < tmp2; m++ )
    1729             :                     {
    1730     8783123 :                         Q[m] = L_shl( Mpy_32_16_1( Q[m], tmp1 ), s ); /*Q31 - Q_e*/
    1731     8783123 :                         move32();
    1732             :                     }
    1733             :                 }
    1734             : 
    1735     9430721 :                 tmp2 = mult( tmp1, inv_int[nTransWidth] );
    1736     9430721 :                 tmp1 = extract_l( L_mult0( tmp2, win ) );
    1737    36356261 :                 FOR( m = sub( i, win ); m < i; m++ )
    1738             :                 {
    1739    26925540 :                     Q[m] = L_shl( Mpy_32_16_1( Q[m], tmp1 ), s ); /*Q31 - Q_e*/
    1740    26925540 :                     move32();
    1741    26925540 :                     win = sub( win, 1 );
    1742    26925540 :                     tmp1 = sub( tmp1, tmp2 );
    1743             :                 }
    1744             : 
    1745     9430721 :                 nrg = L_deposit_l( 1 ); /* start new segment: reset noise segment energy */
    1746             :             }
    1747    18797467 :             segmentOffset = add( i, 1 );
    1748             :         }
    1749             :         ELSE /* line is zero, so fill line and update window and energy */
    1750             :         {
    1751    47403919 :             if ( LT_16( win, nTransWidth ) )
    1752             :             {
    1753    28241703 :                 win = add( win, 1 );
    1754             :             }
    1755             : 
    1756    47403919 :             Random( &seed );
    1757    47403919 :             Q[i] = L_mult0( mult( seed, fac_ns ), win ); /*Q31 - Q_e*/
    1758    47403919 :             move32();
    1759             : 
    1760    47403919 :             tmp1 = shr( seed, 4 );
    1761    47403919 :             nrg = L_mac0( nrg, tmp1, tmp1 ); /* sum up energy of current noise segment */
    1762             : 
    1763    47403919 :             if ( infoTCXNoise ) /* set noiseflags for IGF */
    1764             :             {
    1765      116746 :                 infoTCXNoise[i] = 1;
    1766      116746 :                 move16();
    1767             :             }
    1768             :         }
    1769             :     }
    1770             : 
    1771      220495 :     IF( win > 0 )
    1772             :     {
    1773             :         /* RMS-normalize uppermost noise-filled segment */
    1774      204483 :         tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( lowpassLine, segmentOffset ), &s ); /* mean */
    1775      204483 :         s = add( s, 9 - 15 );                                                             /* compensate energy scaling */
    1776      204483 :         tmp1 = ISqrt16( tmp1, &s );                                                       /* 1/RMS Q15 - s*/
    1777      204483 :         tmp1 = mult_r( tmp1, inv_int[nTransWidth] );                                      /* compensate win Q15 - s*/
    1778      204483 :         s = add( s, sub( 16, Q_e ) );                                                     /* compensate noise scaling */
    1779             : 
    1780    11899739 :         FOR( m = segmentOffset; m < lowpassLine; m++ )
    1781             :         {
    1782    11695256 :             Q[m] = L_shl( Mpy_32_16_1( Q[m], tmp1 ), s ); /*Q31 - Q_e*/
    1783    11695256 :             move32();
    1784             :         }
    1785             :     }
    1786      220495 : }
    1787             : 
    1788      750780 : void tcx_noise_filling_with_shift(
    1789             :     Word32 *Q, /*Q31 - Q_e*/
    1790             :     Word16 *Q_e,
    1791             :     Word16 seed,                 /*Q0*/
    1792             :     const Word16 iFirstLine,     /*Q0*/
    1793             :     const Word16 lowpassLine,    /*Q0*/
    1794             :     const Word16 nTransWidth,    /*Q0*/
    1795             :     const Word16 L_frame,        /*Q0*/
    1796             :     const Word16 tiltCompFactor, /*Q0*/
    1797             :     Word16 fac_ns,               /*Q15*/
    1798             :     Word16 *infoTCXNoise,        /*Q0*/
    1799             :     const Word16 element_mode    /* i  : IVAS element mode   Q0*/
    1800             : )
    1801             : {
    1802             :     Word16 i, m, segmentOffset;
    1803             :     Word16 win; /* window coefficient */
    1804             :     Word16 tilt_factor;
    1805             :     Word32 nrg;
    1806             :     Word16 tmp1, tmp2, s;
    1807             :     Word32 tmp32;
    1808             :     Word16 new_Q_e[N_MAX];
    1809             : 
    1810      750780 :     set16_fx( new_Q_e, *Q_e, N_MAX );
    1811             : 
    1812             :     /* get inverse frame length */
    1813      750780 :     tmp1 = getInvFrameLen( L_frame ); /*Q21*/
    1814             : 
    1815             :     /* tilt_factor = (float)pow(max_val(0.375f, tiltCompFactor), 1.0f/(float)L_frame); */
    1816      750780 :     tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */
    1817      750780 :     tmp32 = L_shr( Mpy_32_16_1( tmp32, tmp1 ), 6 );                            /*Q25*/
    1818             :     BASOP_SATURATE_WARNING_OFF_EVS;
    1819      750780 :     tilt_factor = round_fx_sat( BASOP_Util_InvLog2( tmp32 ) ); /*Q15*/
    1820             :     BASOP_SATURATE_WARNING_ON_EVS;
    1821             : 
    1822             :     /* find last nonzero line below iFirstLine, use it as start offset */
    1823      750780 :     i = iFirstLine;
    1824      750780 :     move16();
    1825      750780 :     tmp1 = shr( iFirstLine, 1 );
    1826      750780 :     IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */
    1827             :     {
    1828      550116 :         segmentOffset = i;
    1829      550116 :         move16();
    1830             :     }
    1831             :     ELSE
    1832             :     {
    1833      575915 :         FOR( ; i > tmp1; i-- )
    1834             :         {
    1835      574951 :             IF( Q[i] != 0 )
    1836             :             {
    1837      199700 :                 BREAK;
    1838             :             }
    1839             :         }
    1840             :         /* fac_ns *= (float)pow(tilt_factor, (float)i); */
    1841    14192808 :         FOR( m = 0; m < i; m++ )
    1842             :         {
    1843    13992144 :             fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
    1844             :         }
    1845      200664 :         i = add( i, 1 );
    1846      200664 :         segmentOffset = i;
    1847      200664 :         move16();
    1848             :     }
    1849      750780 :     nrg = L_deposit_l( 1 );
    1850      750780 :     win = 0;
    1851      750780 :     move16();
    1852             : 
    1853   334272584 :     FOR( ; i < lowpassLine; i++ )
    1854             :     {
    1855   333521804 :         fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
    1856             : 
    1857   333521804 :         IF( Q[i] != 0 )
    1858             :         {
    1859    80960270 :             IF( win > 0 )
    1860             :             {
    1861             :                 /* RMS-normalize current noise-filled segment */
    1862    37679781 :                 tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( i, segmentOffset ), &s ); /* mean */
    1863             :                 // Q-factor of nrg is -8. exp = 31-(-8) = 39
    1864    37679781 :                 s = add( s, 39 - 15 );                       /* scaling */
    1865    37679781 :                 tmp1 = ISqrt16( tmp1, &s );                  /* 1/RMS Q15 - s*/
    1866    37679781 :                 tmp1 = mult_r( tmp1, inv_int[nTransWidth] ); /* compensate win Q15 - s*/
    1867             : 
    1868    37679781 :                 tmp2 = sub( i, win );
    1869    37679781 :                 IF( LT_16( segmentOffset, tmp2 ) )
    1870             :                 {
    1871    64052917 :                     FOR( m = segmentOffset; m < tmp2; m++ )
    1872             :                     {
    1873    59023541 :                         Word16 nrm = 31;
    1874    59023541 :                         move16();
    1875    59023541 :                         Q[m] = Mpy_32_16_1( Q[m], tmp1 ); /*Q31 - Q_e*/
    1876    59023541 :                         move32();
    1877    59023541 :                         IF( Q[m] )
    1878             :                         {
    1879    59017541 :                             nrm = norm_l( Q[m] );
    1880             :                         }
    1881    59023541 :                         Q[m] = L_shl( Q[m], nrm ); /*Q31 - Q_e + nrm*/
    1882    59023541 :                         move32();
    1883    59023541 :                         new_Q_e[m] = sub( add( new_Q_e[m], s ), nrm );
    1884    59023541 :                         move32();
    1885             :                     }
    1886             :                 }
    1887             : 
    1888    37679781 :                 tmp2 = mult( tmp1, inv_int[nTransWidth] ); /*Q15 - s*/
    1889    37679781 :                 tmp1 = extract_l( L_mult0( tmp2, win ) );  /*Q15 - s*/
    1890   147393331 :                 FOR( m = sub( i, win ); m < i; m++ )
    1891             :                 {
    1892   109713550 :                     Word16 nrm = 31;
    1893             : 
    1894   109713550 :                     Q[m] = Mpy_32_16_1( Q[m], tmp1 ); /*Q31 - Q_e*/
    1895   109713550 :                     move32();
    1896   109713550 :                     IF( Q[m] )
    1897             :                     {
    1898   109703673 :                         nrm = norm_l( Q[m] );
    1899             :                     }
    1900   109713550 :                     Q[m] = L_shl( Q[m], nrm ); /*Q31 - Q_e*/
    1901   109713550 :                     move32();
    1902   109713550 :                     new_Q_e[m] = sub( add( new_Q_e[m], s ), nrm );
    1903   109713550 :                     move32();
    1904   109713550 :                     win = sub( win, 1 );
    1905   109713550 :                     tmp1 = sub( tmp1, tmp2 );
    1906             :                 }
    1907             : 
    1908    37679781 :                 nrg = L_deposit_l( 1 ); /* start new segment: reset noise segment energy */
    1909             :             }
    1910    80960270 :             segmentOffset = add( i, 1 );
    1911             :         }
    1912             :         ELSE /* line is zero, so fill line and update window and energy */
    1913             :         {
    1914   252561534 :             IF( LT_16( win, nTransWidth ) )
    1915             :             {
    1916   114456180 :                 win = add( win, 1 );
    1917             :             }
    1918             : 
    1919   252561534 :             Word16 nrm = 31;
    1920   252561534 :             move16();
    1921             : 
    1922   252561534 :             Random( &seed );
    1923   252561534 :             Q[i] = L_mult0( mult( seed, fac_ns ), win );
    1924   252561534 :             move32();
    1925   252561534 :             IF( Q[i] )
    1926             :             {
    1927   252535542 :                 nrm = norm_l( Q[i] );
    1928             :             }
    1929   252561534 :             Q[i] = L_shl( Q[i], nrm ); /*Q31 - Q_e*/
    1930   252561534 :             move32();
    1931   252561534 :             new_Q_e[i] = sub( 31, nrm );
    1932             : 
    1933   252561534 :             tmp1 = shr( seed, 4 );
    1934   252561534 :             nrg = L_mac0( nrg, tmp1, tmp1 ); /* sum up energy of current noise segment Q-8*/
    1935             : 
    1936   252561534 :             IF( infoTCXNoise ) /* set noiseflags for IGF */
    1937             :             {
    1938   145796905 :                 infoTCXNoise[i] = 1;
    1939   145796905 :                 move16();
    1940             :             }
    1941             :         }
    1942             :     }
    1943             : 
    1944      750780 :     IF( win > 0 )
    1945             :     {
    1946             :         /* RMS-normalize uppermost noise-filled segment */
    1947      695175 :         tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( lowpassLine, segmentOffset ), &s ); /* mean */
    1948             :         // Q-factor of nrg is -8. exp = 31-(-8) = 39
    1949      695175 :         s = add( s, 39 - 15 );                       /* compensate energy scaling */
    1950      695175 :         tmp1 = ISqrt16( tmp1, &s );                  /* 1/RMS Q15 - s*/
    1951      695175 :         tmp1 = mult_r( tmp1, inv_int[nTransWidth] ); /* compensate win Q15 - s*/
    1952             : 
    1953    84519618 :         FOR( m = segmentOffset; m < lowpassLine; m++ )
    1954             :         {
    1955    83824443 :             Word16 nrm = 31;
    1956    83824443 :             move16();
    1957             :             /*
    1958             :                 at this point:
    1959             :                 - flt Q[m] = (Q[m] * 2^(new_Q_e[m] - 31)) / (nTransWidth*nTransWidth)
    1960             :                 - flt tmp1 = (tmp1 * 2^(s - 15)) * (nTransWidth*nTransWidth)
    1961             :              */
    1962    83824443 :             Q[m] = Mpy_32_16_1( Q[m], tmp1 ); /*Q15 - Q_e - s*/
    1963    83824443 :             move32();
    1964    83824443 :             IF( Q[m] )
    1965             :             {
    1966    83814328 :                 nrm = norm_l( Q[m] );
    1967             :             }
    1968    83824443 :             Q[m] = L_shl( Q[m], nrm ); /*Q15 - Q_e - s + nrm*/
    1969    83824443 :             move32();
    1970    83824443 :             new_Q_e[m] = add( new_Q_e[m], s - nrm );
    1971    83824443 :             move32();
    1972             :         }
    1973             :     }
    1974             : 
    1975      750780 :     Word16 max_e = 0;
    1976      750780 :     move16();
    1977   398855086 :     FOR( i = 0; i < lowpassLine; i++ )
    1978             :     {
    1979   398104306 :         max_e = s_max( max_e, new_Q_e[i] );
    1980             :     }
    1981             : 
    1982   398855086 :     FOR( i = 0; i < lowpassLine; i++ )
    1983             :     {
    1984   398104306 :         Q[i] = L_shr( Q[i], sub( max_e, new_Q_e[i] ) ); /*Q31 - Q_e*/
    1985   398104306 :         move32();
    1986             :     }
    1987             : 
    1988      750780 :     *Q_e = max_e;
    1989      750780 :     move16();
    1990      750780 : }
    1991             : 
    1992             : 
    1993             : /*---------------------------------------------------------------
    1994             :  * InitTnsConfigs()
    1995             :  *--------------------------------------------------------------*/
    1996             : 
    1997             : 
    1998       16180 : void InitTnsConfigs(
    1999             :     const Word16 bwidth,  /*Q0*/
    2000             :     const Word16 L_frame, /*Q0*/
    2001             :     STnsConfig tnsConfig[2][2],
    2002             :     const Word16 igfStopFreq,  /*Q0*/
    2003             :     const Word32 total_brate,  /*Q0*/
    2004             :     const Word16 element_mode, /*Q0*/
    2005             :     const Word16 MCT_flag /*Q0*/ )
    2006             : {
    2007       16180 :     IF( GT_32( total_brate, ACELP_32k ) )
    2008             :     {
    2009       12996 :         InitTnsConfiguration( bwidth, shr( L_frame, 1 ), &tnsConfig[0][0], igfStopFreq, total_brate, element_mode, MCT_flag );
    2010             :     }
    2011       16180 :     InitTnsConfiguration( bwidth, L_frame, &tnsConfig[1][0], igfStopFreq, total_brate, element_mode, MCT_flag );
    2012       16180 :     InitTnsConfiguration( bwidth, add( L_frame, shr( L_frame, 2 ) ), &tnsConfig[1][1], igfStopFreq, total_brate, element_mode, MCT_flag );
    2013       16180 : }
    2014             : 
    2015       30763 : void InitTnsConfigs_ivas_fx(
    2016             :     const Word16 bwidth,  /*Q0*/
    2017             :     const Word16 L_frame, /*Q0*/
    2018             :     STnsConfig tnsConfig[2][2],
    2019             :     const Word16 igfStopFreq,  /*Q0*/
    2020             :     const Word32 total_brate,  /*Q0*/
    2021             :     const Word16 element_mode, /*Q0*/
    2022             :     const Word16 MCT_flag /*Q0*/ )
    2023             : {
    2024       30763 :     IF( GT_32( total_brate, ACELP_32k ) )
    2025             :     {
    2026       20835 :         InitTnsConfiguration_ivas_fx( bwidth, shr( L_frame, 1 ), &tnsConfig[0][0], igfStopFreq, total_brate, element_mode, MCT_flag );
    2027             :     }
    2028       30763 :     InitTnsConfiguration_ivas_fx( bwidth, L_frame, &tnsConfig[1][0], igfStopFreq, total_brate, element_mode, MCT_flag );
    2029       30763 :     InitTnsConfiguration_ivas_fx( bwidth, add( L_frame, shr( L_frame, 2 ) ), &tnsConfig[1][1], igfStopFreq, total_brate, element_mode, MCT_flag );
    2030       30763 : }
    2031             : 
    2032             : 
    2033     1750761 : void SetTnsConfig(
    2034             :     TCX_CONFIG_HANDLE hTcxCfg, /* i  : configuration of TCX               */
    2035             :     const Word16 isTCX20,      /*Q0*/
    2036             :     const Word16 isAfterACELP /*Q0*/ )
    2037             : {
    2038     1750761 :     move16();
    2039     1750761 :     hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[isTCX20][isAfterACELP];
    2040     1750761 :     assert( hTcxCfg->pCurrentTnsConfig != NULL );
    2041     1750761 : }
    2042             : #define IVAS_CODE_TCX_UTIL
    2043             : #ifdef IVAS_CODE_TCX_UTIL
    2044             : /*-------------------------------------------------------------------*
    2045             :  *  SetAllowTnsOnWhite
    2046             :  *
    2047             :  *  set TNS config flag for possible application of TNS in the whitened domain
    2048             :  *-------------------------------------------------------------------*/
    2049             : 
    2050       46886 : void SetAllowTnsOnWhite(
    2051             :     STnsConfig tnsConfig[2][2], /* o  : updated TNS configurations */
    2052             :     const Word8 allowTnsOnWhite /* i  : flag for TNS in whiteded domain mode Q0*/
    2053             : )
    2054             : {
    2055       46886 :     tnsConfig[0][0].allowTnsOnWhite = allowTnsOnWhite; /*Q0*/
    2056       46886 :     move16();
    2057       46886 :     tnsConfig[0][1].allowTnsOnWhite = allowTnsOnWhite;
    2058       46886 :     move16();
    2059       46886 :     tnsConfig[1][0].allowTnsOnWhite = allowTnsOnWhite;
    2060       46886 :     move16();
    2061       46886 :     tnsConfig[1][1].allowTnsOnWhite = allowTnsOnWhite;
    2062       46886 :     move16();
    2063       46886 :     return;
    2064             : }
    2065             : #endif
    2066             : #undef IVAS_CODE_TCX_UTIL
    2067             : 
    2068      862103 : void tcx_get_gain(
    2069             :     Word32 *x,      /* i: spectrum 1 Q31 - x_e*/
    2070             :     Word16 x_e,     /* i: spectrum 1 exponent */
    2071             :     Word32 *y,      /* i: spectrum 2 Q31 - y_e*/
    2072             :     Word16 y_e,     /* i: spectrum 2 exponent */
    2073             :     Word16 n,       /* i: length Q0*/
    2074             :     Word16 *gain,   /* o: gain Q15 - gain_e*/
    2075             :     Word16 *gain_e, /* o: gain exponent */
    2076             :     Word32 *en_y,   /* o: energy of y (optional)  Q31 - en_y_e*/
    2077             :     Word16 *en_y_e  /* o: energy of y exponent (optional) */
    2078             : )
    2079             : {
    2080             :     Word32 maxX, minX, maxY, minY;
    2081             :     Word32 corr, ener;
    2082             :     Word16 sx, sy, corr_e, ener_e;
    2083             :     Word16 i, tmp;
    2084             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    2085      862103 :     Flag Overflow = 0;
    2086             : #endif
    2087             : 
    2088      862103 :     maxX = L_deposit_l( 1 );
    2089      862103 :     maxY = L_deposit_l( 1 );
    2090      862103 :     minX = L_deposit_l( -1 );
    2091      862103 :     minY = L_deposit_l( -1 );
    2092   699463223 :     FOR( i = 0; i < n; i++ )
    2093             :     {
    2094   698601120 :         if ( x[i] > 0 )
    2095   228444084 :             maxX = L_max( maxX, x[i] ); /*Q31 - x_e*/
    2096   698601120 :         if ( x[i] < 0 )
    2097   228498921 :             minX = L_min( minX, x[i] ); /*Q31 - x_e*/
    2098             : 
    2099   698601120 :         if ( y[i] > 0 )
    2100    73868394 :             maxY = L_max( maxY, y[i] ); /*Q31 - y_e*/
    2101   698601120 :         if ( y[i] < 0 )
    2102    74017975 :             minY = L_min( minY, y[i] ); /*Q31 - y_e*/
    2103             :     }
    2104      862103 :     sx = s_min( norm_l( maxX ), norm_l( minX ) );
    2105      862103 :     sy = s_min( norm_l( maxY ), norm_l( minY ) );
    2106      862103 :     sx = sub( sx, 4 );
    2107      862103 :     sy = sub( sy, 4 );
    2108             : 
    2109      862103 :     ener = L_deposit_l( 0 );
    2110      862103 :     corr = L_deposit_l( 0 );
    2111   699463223 :     FOR( i = 0; i < n; i++ )
    2112             :     {
    2113   698601120 :         tmp = round_fx( L_shl( y[i], sy ) );                       /*Q15 - y_e + sy*/
    2114   698601120 :         ener = L_mac0( ener, tmp, tmp );                           /*Q30 - 2*(y_e - sy)*/
    2115   698601120 :         corr = L_mac0( corr, tmp, round_fx( L_shl( x[i], sx ) ) ); /*Q30 - 2*(x_e - sx + y_e - sy)*/
    2116             :     }
    2117             : 
    2118      862103 :     if ( ener == 0 )
    2119        2289 :         ener = L_deposit_l( 1 );
    2120             : 
    2121      862103 :     ener_e = add( shl( sub( y_e, sy ), 1 ), 1 );
    2122      862103 :     corr_e = add( sub( add( x_e, y_e ), add( sx, sy ) ), 1 );
    2123             : 
    2124      862103 :     tmp = sub( norm_l( corr ), 1 );
    2125      862103 :     corr = L_shl( corr, tmp ); /*Q31 - corr_e + tmp*/
    2126      862103 :     corr_e = sub( corr_e, tmp );
    2127             : 
    2128      862103 :     tmp = norm_l( ener );
    2129      862103 :     ener = L_shl( ener, tmp ); /*Q31 - ener_e + tmp*/
    2130      862103 :     ener_e = sub( ener_e, tmp );
    2131             : 
    2132      862103 :     tmp = div_s( abs_s( round_fx_o( corr, &Overflow ) ), round_fx_o( ener, &Overflow ) ); /*Q15 - (corr_e - ener_e)*/
    2133      862103 :     if ( corr < 0 )
    2134           0 :         tmp = negate( tmp );
    2135             : 
    2136      862103 :     *gain = tmp;
    2137      862103 :     move16();
    2138      862103 :     *gain_e = sub( corr_e, ener_e );
    2139      862103 :     move16();
    2140             : 
    2141      862103 :     if ( en_y != NULL )
    2142             :     {
    2143      862103 :         *en_y = ener; /*Q31 - ener_e*/
    2144      862103 :         move32();
    2145             :     }
    2146      862103 :     if ( en_y_e != NULL )
    2147             :     {
    2148      862103 :         *en_y_e = ener_e;
    2149      862103 :         move16();
    2150             :     }
    2151      862103 : }
    2152         101 : void init_TCX_config(
    2153             :     TCX_CONFIG_HANDLE hTcxCfg,
    2154             :     Word16 L_frame,    /*Q0*/
    2155             :     Word16 fscale,     /*Q0*/
    2156             :     Word16 L_frameTCX, /*Q0*/
    2157             :     Word16 fscaleFB /*Q0*/ )
    2158             : {
    2159             :     /* Initialize the TCX MDCT windows */
    2160         101 :     hTcxCfg->tcx_mdct_window_length = extract_l( L_shr( L_mult0( L_LOOK_12k8, fscale ), LD_FSCALE_DENOM ) ); /*Q0*/
    2161         101 :     move16();
    2162         101 :     hTcxCfg->tcx_mdct_window_delay = hTcxCfg->tcx_mdct_window_length; /*Q0*/
    2163         101 :     move16();
    2164             : 
    2165         101 :     hTcxCfg->tcx_mdct_window_half_length = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA( 12800, 5000000L ), fscale ), LD_FSCALE_DENOM ) );
    2166         101 :     move16();
    2167         101 :     hTcxCfg->tcx_mdct_window_min_length = shr( L_frame, 4 ); /* 1.25ms Q0*/
    2168         101 :     move16();
    2169         101 :     hTcxCfg->tcx_mdct_window_trans_length = shr( L_frame, 4 ); /* 1.25ms Q0*/
    2170         101 :     move16();
    2171         101 :     hTcxCfg->tcx5Size = shr( L_frame, 2 ); /* 5ms Q0*/
    2172         101 :     move16();
    2173         101 :     hTcxCfg->tcx_mdct_window_lengthFB = extract_l( L_shr( L_mult0( L_LOOK_12k8, fscaleFB ), LD_FSCALE_DENOM ) ); /*Q0*/
    2174         101 :     move16();
    2175         101 :     hTcxCfg->tcx_mdct_window_delayFB = hTcxCfg->tcx_mdct_window_lengthFB; /*Q0*/
    2176         101 :     move16();
    2177             : 
    2178         101 :     hTcxCfg->tcx_mdct_window_half_lengthFB = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA( 12800, 5000000L ), fscaleFB ), LD_FSCALE_DENOM ) ); /*Q0*/
    2179         101 :     move16();
    2180         101 :     hTcxCfg->tcx_mdct_window_min_lengthFB = shr( L_frameTCX, 4 ); /* 1.25ms Q0*/
    2181         101 :     move16();
    2182         101 :     hTcxCfg->tcx_mdct_window_trans_lengthFB = shr( L_frameTCX, 4 ); /* 1.25ms Q0*/
    2183         101 :     move16();
    2184         101 :     hTcxCfg->tcx5SizeFB = shr( L_frameTCX, 2 ); /* 5ms Q0*/
    2185         101 :     move16();
    2186         101 :     mdct_window_sine( hTcxCfg->tcx_mdct_window, hTcxCfg->tcx_mdct_window_length );
    2187         101 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_half_length );
    2188         101 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_min_length );
    2189         101 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_trans_length );
    2190             : 
    2191         101 :     mdct_window_sine( hTcxCfg->tcx_mdct_windowFB, hTcxCfg->tcx_mdct_window_lengthFB );
    2192         101 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_half_lengthFB );
    2193         101 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_min_lengthFB );
    2194         101 :     mdct_window_sine( hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_trans_lengthFB );
    2195             : 
    2196             :     /*ALDO windows for MODE2*/
    2197         101 :     mdct_window_aldo( hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, L_frame );
    2198         101 :     mdct_window_aldo( hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, L_frameTCX );
    2199         101 : }

Generated by: LCOV version 1.14