LCOV - code coverage report
Current view: top level - lib_dec - waveadjust_fec_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 0 862 0.0 %
Date: 2025-05-03 01:55:50 Functions: 0 36 0.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdlib.h>
       6             : #include <stdio.h>
       7             : #include <assert.h>
       8             : #include <string.h>
       9             : #include "prot_fx.h"
      10             : #include "basop_util.h"
      11             : #include "stat_com.h"
      12             : #include "rom_com.h"
      13             : #include "stl.h" /* FOR wmc_tool */
      14             : #include "vad_basop.h"
      15             : 
      16             : void get_maxConv_and_pitch_x( Word16 *s_LP, Word16 s, Word16 e, Word16 N, Word32 *maxConv, Word16 *maxConv_bits, Word16 *pitch );
      17             : Word16 get_voicing_x( Word16 *s_LP, Word16 pitch, Word32 covMax, Word16 maxConv_bits, Word16 Framesize );
      18             : Word32 con_Log10( Word32 i_s32Val, Word16 i_s16Q );
      19             : Word16 Spl_GetScalingSquare_x( const Word16 *in_vector, const Word16 in_vector_length, Word16 times );
      20             : 
      21           0 : Word16 vadmin( Word16 a, Word16 b ) /*i/o: Qx */
      22             : {
      23           0 :     return s_min( a, b );
      24             : }
      25             : 
      26           0 : void set_state( Word16 *state, Word16 num, Word16 N ) /*i/o: Qx */
      27             : {
      28             :     Word16 i, tmp;
      29             : 
      30           0 :     tmp = sub( N, 1 );
      31           0 :     FOR( i = 0; i < tmp; i++ )
      32             :     {
      33           0 :         state[i] = state[i + 1];
      34           0 :         move16();
      35             :     }
      36           0 :     state[tmp] = num;
      37           0 :     move16();
      38             : 
      39           0 :     return;
      40             : }
      41             : 
      42           0 : void concealment_update_x(
      43             :     const Word16 bfi,
      44             :     const Word16 core,
      45             :     const Word16 tonality,
      46             :     Word32 *invkoef /*Qinvkoef_scale*/,
      47             :     Word16 *invkoef_scale,
      48             :     T_PLCInfo_HANDLE hPlcInfo )
      49             : {
      50           0 :     Word32 *data_reci2 = hPlcInfo->data_reci2_fx;
      51           0 :     Word16 *tcx_tonality = hPlcInfo->TCX_Tonality;
      52           0 :     Word16 L_frameTCX = hPlcInfo->L_frameTCX;
      53           0 :     Word16 subframe = hPlcInfo->subframe_fx;
      54             :     Word16 i;
      55           0 :     move16();
      56           0 :     move16();
      57             : 
      58           0 :     IF( EQ_16( core, TCX_20_CORE ) )
      59             :     {
      60           0 :         set_state( hPlcInfo->Transient, core, MAX_POST_LEN );
      61             : 
      62           0 :         FOR( i = 0; i < L_frameTCX; i++ )
      63             :         {
      64           0 :             data_reci2[i] = invkoef[i];
      65           0 :             move32();
      66             :         }
      67           0 :         hPlcInfo->data_reci2_scale = *invkoef_scale;
      68           0 :         move16();
      69           0 :         IF( !bfi )
      70             :         {
      71           0 :             set_state( tcx_tonality, tonality, DEC_STATE_LEN );
      72             :         }
      73             :     }
      74             :     ELSE
      75             :     {
      76             : 
      77           0 :         IF( subframe == 0 )
      78             :         {
      79           0 :             set_state( hPlcInfo->Transient, core, MAX_POST_LEN );
      80             : 
      81           0 :             IF( !bfi )
      82             :             {
      83           0 :                 set_state( tcx_tonality, tonality, DEC_STATE_LEN );
      84             :             }
      85             :         }
      86             :         /* don't store the second subframe during frameloss; in
      87             :            pitch_search_fx(), low_freq_rate is derived on the last good
      88             :            TCX-10 spectrum */
      89           0 :         test();
      90           0 :         IF( !bfi || subframe == 0 )
      91             :         {
      92             : 
      93           0 :             Word32 *ptr = data_reci2 + subframe;
      94           0 :             Word16 FrameSize2 = shr( L_frameTCX, 1 );
      95             : 
      96           0 :             FOR( i = 0; i < FrameSize2; i++ )
      97             :             {
      98           0 :                 ptr[i] = invkoef[i];
      99           0 :                 move32();
     100             :             }
     101             : 
     102           0 :             hPlcInfo->data_reci2_scale = *invkoef_scale;
     103           0 :             move16();
     104             :         }
     105             :     }
     106             : 
     107           0 :     return;
     108             : }
     109             : 
     110             : 
     111           0 : static Word16 zero_pass_w32_x( const Word16 *s, const Word16 N ) /* i: Qx*/ /* o: 2*Qx-31*/
     112             : {
     113             :     Word16 i;
     114           0 :     Word32 temp, zp = L_deposit_l( 0 );
     115             : 
     116           0 :     FOR( i = 1; i < N; i++ )
     117             :     {
     118           0 :         temp = L_mac0( -1L, s[i], s[i - 1] ); // 2*Qx
     119           0 :         zp = L_sub( zp, L_shr( temp, 31 ) );  // 2*Qx-31
     120             :     }
     121           0 :     return extract_l( zp );
     122             : }
     123             : 
     124           0 : Word16 Sqrt_x_fast( Word32 value /*Qvalue*/ ) /*o : Q11-(2*norm+1)*/
     125             : {
     126             :     Word16 norm;
     127             :     Word16 result, index;
     128             : 
     129           0 :     norm = sub( 23, norm_l( value ) );
     130           0 :     index = extract_l( L_shr_r( value, add( norm, s_and( norm, 1 ) ) ) );
     131           0 :     result = shr( sqrt_table_pitch_search[index], sub( 11, shr( add( norm, 1 ), 1 ) ) ); // Q11-(2*norm+1)
     132           0 :     return result;
     133             : }
     134             : 
     135           0 : Word32 dot_w32_accuracy_x( Word16 *s1 /*Qs1*/, Word16 *s2 /*Qs2*/, Word16 nbits, Word16 N )
     136             : {
     137             :     Word16 i;
     138           0 :     Word32 eng = L_deposit_l( 0 ), temp;
     139             : 
     140           0 :     FOR( i = 0; i < N; i++ )
     141             :     {
     142           0 :         temp = L_mult0( s1[i], s2[i] );           /*Qs1+ Qs2*/
     143           0 :         eng = L_add( eng, L_shr( temp, nbits ) ); /*Qs1+ Qs2-nbits*/
     144             :     }
     145             : 
     146           0 :     return eng;
     147             : }
     148             : 
     149             : 
     150           0 : Word16 int_div_s_x( Word16 a, Word16 b ) /*i/o : Q0*/
     151             : {
     152           0 :     Word16 result = 0;
     153           0 :     Word16 norm, left = 0, i;
     154           0 :     move16();
     155           0 :     move16();
     156           0 :     test();
     157           0 :     IF( LT_16( a, b ) || b == 0 )
     158             :     {
     159           0 :         return 0;
     160             :     }
     161             :     ELSE
     162             :     {
     163           0 :         a = add( a, shr( b, 1 ) );
     164           0 :         norm = sub( norm_s( b ), norm_s( a ) );
     165             : 
     166           0 :         FOR( i = norm; i >= 0; i-- )
     167             :         {
     168           0 :             left = shr( a, i );
     169           0 :             result = shl( result, 1 );
     170           0 :             IF( GE_16( left, b ) )
     171             :             {
     172           0 :                 result = add( result, 1 );
     173           0 :                 left = sub( left, b );
     174           0 :                 a = add( shl( left, i ), s_and( a, sub( shl( 1, i ), 1 ) ) );
     175             :             }
     176             :         }
     177             :     }
     178             : 
     179           0 :     return result;
     180             : }
     181             : 
     182           0 : Word16 GetW32Norm_x( Word32 *s, Word16 N ) /*i : Qx, o: Q0*/
     183             : {
     184           0 :     Word32 smax = L_deposit_l( 0 );
     185             :     Word16 smax_norm, i;
     186             : 
     187           0 :     FOR( i = 0; i < N; i++ )
     188             :     {
     189           0 :         smax = L_or( smax, L_abs( s[i] ) );
     190             :     }
     191             : 
     192           0 :     smax_norm = norm_l( smax );
     193             : 
     194           0 :     return smax_norm;
     195             : }
     196             : 
     197           0 : Word16 harmo_x( Word32 *X, Word16 Framesize, Word16 pitch ) /*i : Qx, o: Q15*/
     198             : {
     199           0 :     Word16 h, k, result = 0;
     200           0 :     Word32 ener = L_deposit_l( 0 ), ener_harmo = L_deposit_l( 0 );
     201             :     Word16 norm1, d1, d2;
     202             :     Word16 ener_w, ener_harmo_w;
     203           0 :     Word16 nbits = sub( 15, norm_s( Framesize ) );
     204           0 :     move16();
     205           0 :     norm1 = GetW32Norm_x( X, Framesize );
     206             : 
     207           0 :     FOR( k = 1; k < 9; k++ )
     208             :     {
     209           0 :         h = sub( int_div_s_x( extract_l( L_mult( k, Framesize ) ), pitch ), 1 );
     210             : 
     211           0 :         d1 = extract_h( L_shl( X[h], norm1 ) );
     212           0 :         d2 = extract_h( L_shl( X[h + 1], norm1 ) );
     213             : 
     214           0 :         ener_harmo = L_add( ener_harmo,
     215             :                             L_shr( L_mac0( L_mult0( d1, d1 ), d2, d2 ), nbits ) );
     216             :     }
     217             : 
     218           0 :     FOR( k = 0; k < Framesize; k++ )
     219             :     {
     220           0 :         d1 = extract_h( L_shl( X[k], norm1 ) );
     221           0 :         ener = L_add( ener, L_shr( L_mult0( d1, d1 ), nbits ) );
     222             :     }
     223             : 
     224           0 :     norm1 = norm_l( ener );
     225           0 :     ener_w = extract_h( L_shl( ener, norm1 ) );
     226           0 :     ener_harmo_w = extract_h( L_shl( ener_harmo, norm1 ) );
     227             : 
     228           0 :     IF( GE_32( ener_harmo, ener ) )
     229             :     {
     230           0 :         return 32767;
     231             :     }
     232           0 :     test();
     233           0 :     IF( ( ener_harmo_w <= 0 ) || ( ener_w <= 0 ) )
     234             :     {
     235           0 :         return 0;
     236             :     }
     237           0 :     result = div_s( ener_harmo_w, ener_w );
     238           0 :     return result;
     239             : }
     240             : 
     241           0 : static Word16 get_low_freq_eng_rate_x( Word32 *mdct_data, /*i: Qx*/ /*o: Q0*/
     242             :                                        Word16 curr_mode,
     243             :                                        Word16 N )
     244             : {
     245             :     Word16 N1, N2, i;
     246           0 :     Word32 low_eng = L_deposit_l( 0 ), eng = L_deposit_l( 0 ), smax = L_deposit_l( 0 );
     247           0 :     Word16 nbits, temp, norm = 0;
     248           0 :     move16();
     249           0 :     N1 = 30;
     250           0 :     N2 = N;
     251           0 :     move16();
     252           0 :     move16();
     253           0 :     IF( EQ_16( 2, curr_mode ) )
     254             :     {
     255           0 :         N1 = shr( 30, 1 );
     256           0 :         N2 = shr( N, 1 );
     257             :     }
     258             : 
     259           0 :     nbits = sub( 15, norm_s( N2 ) );
     260             : 
     261           0 :     FOR( i = 0; i < N2; i++ )
     262             :     {
     263           0 :         smax = L_or( smax, L_abs( mdct_data[i] ) );
     264             :     }
     265             : 
     266           0 :     norm = norm_l( smax );
     267             : 
     268           0 :     FOR( i = 0; i < N1; i++ )
     269             :     {
     270           0 :         temp = extract_h( L_shl( mdct_data[i], norm ) );
     271           0 :         low_eng = L_add( low_eng, L_shr( L_mult0( temp, temp ), nbits ) );
     272             :     }
     273             : 
     274           0 :     FOR( i = N1; i < N2; i++ )
     275             :     {
     276           0 :         temp = extract_h( L_shl( mdct_data[i], norm ) );
     277           0 :         eng = L_add( eng, L_shr( L_mult0( temp, temp ), nbits ) );
     278             :     }
     279           0 :     eng = L_add( low_eng, eng );
     280             : 
     281             :     /* IF (low_eng<(eng+EPSILON)*0.02) return 1;ELSE return 0; */
     282             :     /* smax=eng*0.02 */
     283           0 :     smax = L_shr( Mpy_32_16_1( eng, 5243 ), 3 );
     284             : 
     285           0 :     return ( L_sub( low_eng, smax ) <= 0 );
     286             : }
     287             : 
     288           0 : void LpFilter2_x( Word16 *x, Word16 *y, Word16 N ) /*i/o : Qx*/
     289             : {
     290             :     Word16 i;
     291             :     Word16 smax, norm;
     292           0 :     Word16 a1 = 5898;  /* W16(0.18f); */
     293           0 :     Word16 a2 = 20971; /* W16(0.64f); */
     294           0 :     move16();
     295           0 :     move16();
     296           0 :     smax = 0;
     297           0 :     move16();
     298           0 :     FOR( i = 0; i < N; i++ )
     299             :     {
     300           0 :         smax = s_or( smax, abs_s( x[i] ) );
     301             :     }
     302           0 :     norm = norm_s( smax );
     303             : 
     304           0 :     y[0] = mult( shl( x[0], norm ), a1 );
     305           0 :     move16();
     306           0 :     y[1] = add( mult( y[0], a2 ), mult( shl( x[1], norm ), a1 ) );
     307           0 :     move16();
     308             : 
     309           0 :     FOR( i = 2; i < N; i++ )
     310             :     {
     311             :         /* 5898*2+20971=32767 -->no overflow */
     312           0 :         y[i] = add( mult( y[i - 2], a1 ), add( mult( y[i - 1], a2 ), mult( shl( x[i], norm ), a1 ) ) );
     313           0 :         move16();
     314             :     }
     315           0 : }
     316             : 
     317           0 : void sig_tilt_x( Word16 *s /*Qx*/, Word16 FrameSize, Word32 *enr1 /*2*Qx-nbits*/, Word32 *enr2 /*2*Qx-nbits*/ )
     318             : {
     319             :     Word16 subFrameSize, shIFt;
     320             :     Word16 *p1, *p2;
     321             :     Word16 nbits;
     322             : 
     323           0 :     subFrameSize = shr( FrameSize, 2 );
     324           0 :     p1 = s + subFrameSize;
     325           0 :     p2 = s + sub( subFrameSize, 2 );
     326             : 
     327           0 :     shIFt = sub( FrameSize, subFrameSize );
     328           0 :     nbits = sub( 15, norm_s( shIFt ) );
     329           0 :     *enr1 = dot_w32_accuracy_x( p1, p2, nbits, shIFt );
     330           0 :     move32();
     331           0 :     *enr2 = dot_w32_accuracy_x( p1, p1, nbits, shIFt );
     332           0 :     move32();
     333           0 : }
     334             : 
     335           0 : void get_maxConv_and_pitch_x( Word16 *s_LP /*Qx*/, Word16 s /*Q0*/, Word16 e /*Q0*/, Word16 N, Word32 *maxConv /*2*Qx-nbits*/, Word16 *maxConv_bits, Word16 *pitch /*Q0*/ )
     336             : {
     337           0 :     Word16 t, cov_size, size = N;
     338           0 :     Word32 tmp_sigma = L_deposit_l( 0 ), cov_max_sigma = L_deposit_l( 0 );
     339           0 :     Word16 nbits, tmp_pitch = 0;
     340             :     Word32 r1_high, r2_high;
     341             :     UWord16 r1_low, r2_low;
     342           0 :     Word32 tmp_sigma_last = L_deposit_l( 0 ); /* not needed, just to avoid compiler warning */
     343           0 :     Word16 cov_size_last = N;                 /* not needed, just to avoid compiler warning */
     344           0 :     Word32 cov_max_sigma_tmp = L_deposit_l( 0 );
     345           0 :     Word16 size_tmp = N;
     346           0 :     move16();
     347           0 :     move16();
     348           0 :     move16();
     349           0 :     move16();
     350           0 :     nbits = sub( 15, norm_s( sub( N, s ) ) );
     351             : 
     352           0 :     FOR( t = s; t < e; t++ )
     353             :     {
     354           0 :         cov_size = sub( N, t );
     355           0 :         tmp_sigma = dot_w32_accuracy_x( s_LP, s_LP + t, nbits, cov_size );
     356             : 
     357           0 :         IF( GT_16( t, s ) ) /* don't use the first value */
     358             :         {
     359           0 :             Mpy_32_16_ss( tmp_sigma, cov_size_last, &r1_high, &r1_low );
     360           0 :             Mpy_32_16_ss( tmp_sigma_last, cov_size, &r2_high, &r2_low );
     361             :             /* tmp_sigma > tmp_sigma_last */
     362           0 :             test();
     363           0 :             test();
     364           0 :             move16();
     365           0 :             move16(); /* moves are for the (Word32) casts */
     366           0 :             IF( ( GT_32( r1_high, r2_high ) ) ||
     367             :                 ( EQ_32( r1_high, r2_high ) && GT_32( (Word32) r1_low, (Word32) r2_low ) ) )
     368             :             {
     369             :                 /* store the current cov, if it is larger than the last one */
     370           0 :                 cov_max_sigma_tmp = tmp_sigma;
     371           0 :                 move32();
     372           0 :                 size_tmp = cov_size;
     373           0 :                 move16();
     374             :             }
     375             :             ELSE
     376             :             {
     377           0 :                 Mpy_32_16_ss( cov_max_sigma, size_tmp, &r1_high, &r1_low );
     378           0 :                 Mpy_32_16_ss( cov_max_sigma_tmp, size, &r2_high, &r2_low );
     379             :                 /* cov_max_sigma < cov_max_sigma_tmp */
     380           0 :                 test();
     381           0 :                 test();
     382           0 :                 move16();
     383           0 :                 move16(); /* moves are for the (Word32) casts */
     384           0 :                 IF( ( LT_32( r1_high, r2_high ) ) ||
     385             :                     ( EQ_32( r1_high, r2_high ) && LT_32( (Word32) r1_low, (Word32) r2_low ) ) )
     386             :                 {
     387             :                     /* otherwise */
     388             :                     /* use the last value of cov, being a max */
     389           0 :                     cov_max_sigma = cov_max_sigma_tmp;
     390           0 :                     move32();
     391           0 :                     size = cov_size;
     392           0 :                     move16();
     393             :                     /* and use the last index as pitch */
     394           0 :                     tmp_pitch = sub( t, 1 );
     395             :                 }
     396             :             }
     397             :         }
     398           0 :         tmp_sigma_last = tmp_sigma;
     399           0 :         move32();
     400           0 :         cov_size_last = cov_size;
     401           0 :         move16();
     402             :     }
     403           0 :     *pitch = tmp_pitch;
     404           0 :     move16();
     405           0 :     *maxConv = cov_max_sigma;
     406           0 :     move32();
     407           0 :     *maxConv_bits = nbits;
     408           0 :     move16();
     409           0 : }
     410             : 
     411           0 : Word16 get_voicing_x( Word16 *s_LP /*Qx*/, Word16 pitch /*Q0*/, Word32 covMax /*2*Qx-nbits*/, Word16 maxConv_bits, Word16 Framesize ) /*o : Q15*/
     412             : {
     413           0 :     Word32 eng1 = L_deposit_l( 0 ), eng2 = L_deposit_l( 0 );
     414             :     Word16 voicing, norm;
     415             :     Word16 tmpLen, nbits;
     416             :     Word16 eng1_w, eng2_w;
     417             : 
     418           0 :     IF( covMax <= 0 )
     419             :     {
     420           0 :         return 0;
     421             :     }
     422             :     ELSE
     423             :     {
     424           0 :         tmpLen = sub( Framesize, pitch );
     425           0 :         nbits = maxConv_bits;
     426           0 :         move16();
     427             : 
     428           0 :         eng1 = dot_w32_accuracy_x( s_LP, s_LP, nbits, tmpLen );
     429           0 :         eng2 = dot_w32_accuracy_x( s_LP + pitch, s_LP + pitch, nbits, tmpLen );
     430             : 
     431           0 :         norm = sub( norm_l( L_or( eng1, L_or( eng2, covMax ) ) ), 1 );
     432           0 :         eng1 = L_shl( eng1, norm );
     433           0 :         eng2 = L_shl( eng2, norm );
     434           0 :         covMax = L_shl( covMax, norm );
     435             : 
     436           0 :         eng1_w = Sqrt_x_fast( eng1 );
     437           0 :         eng2_w = Sqrt_x_fast( eng2 );
     438             : 
     439           0 :         eng1 = L_mult0( eng1_w, eng2_w );
     440           0 :         norm = norm_l( eng1 );
     441           0 :         eng1_w = extract_h( L_shl( eng1, norm ) );
     442           0 :         eng2_w = extract_h( L_shl( covMax, norm ) );
     443             : 
     444           0 :         IF( GE_32( covMax, eng1 ) )
     445             :         {
     446           0 :             return 32767;
     447             :         }
     448           0 :         test();
     449           0 :         IF( ( eng2_w <= 0 ) || ( eng1_w <= 0 ) )
     450             :         {
     451           0 :             return 0;
     452             :         }
     453           0 :         voicing = div_s( eng2_w, eng1_w );
     454             : 
     455           0 :         return voicing;
     456             :     }
     457             : }
     458             : 
     459           0 : void pitch_modify_x( Word16 *s_LP /*Qx*/, Word16 *voicing /*Q15*/, Word16 *pitch /*Q0*/, Word16 FrameSize )
     460             : {
     461             :     Word32 eng1, eng2, eng3;
     462           0 :     Word16 shIFt = shr( *pitch, 1 );
     463             :     Word16 tmpLen, nbits, norm, voicing2;
     464             :     Word16 eng1_w, eng2_w;
     465             : 
     466           0 :     tmpLen = sub( FrameSize, shIFt );
     467           0 :     nbits = sub( 15, norm_s( tmpLen ) );
     468             : 
     469           0 :     eng1 = dot_w32_accuracy_x( s_LP + shIFt, s_LP + shIFt, nbits, tmpLen );
     470           0 :     eng2 = dot_w32_accuracy_x( s_LP, s_LP, nbits, tmpLen );
     471           0 :     eng3 = dot_w32_accuracy_x( s_LP + shIFt, s_LP, nbits, tmpLen );
     472             : 
     473           0 :     IF( eng3 <= 0 )
     474             :     {
     475           0 :         return;
     476             :     }
     477             : 
     478           0 :     norm = sub( norm_l( L_or( eng1, L_or( eng2, eng3 ) ) ), 1 );
     479           0 :     eng1 = L_shl( eng1, norm );
     480           0 :     eng2 = L_shl( eng2, norm );
     481           0 :     eng3 = L_shl( eng3, norm );
     482             : 
     483           0 :     eng1_w = Sqrt_x_fast( eng1 );
     484           0 :     eng2_w = Sqrt_x_fast( eng2 );
     485             : 
     486           0 :     eng1 = L_mult0( eng1_w, eng2_w );
     487             : 
     488           0 :     norm = norm_l( eng1 );
     489           0 :     eng1_w = extract_h( L_shl_sat( eng1, norm ) );
     490           0 :     eng2_w = extract_h( L_shl_sat( eng3, norm ) );
     491             : 
     492           0 :     IF( GE_32( eng3, eng1 ) )
     493             :     {
     494           0 :         voicing2 = 32767;
     495           0 :         move16();
     496             :     }
     497             :     ELSE
     498             :     {
     499           0 :         test();
     500           0 :         IF( ( eng2_w <= 0 ) || ( eng1_w <= 0 ) )
     501             :         {
     502           0 :             voicing2 = 0;
     503           0 :             move16();
     504             :         }
     505             :         ELSE
     506             :         {
     507           0 :             voicing2 = div_s( eng2_w, eng1_w );
     508             :         }
     509             :     }
     510             : 
     511           0 :     IF( GT_16( voicing2, *voicing ) )
     512             :     {
     513           0 :         *pitch = shIFt;
     514           0 :         move16();
     515           0 :         *voicing = voicing2;
     516           0 :         move16();
     517             :     }
     518             : }
     519             : 
     520           0 : Word16 Is_Periodic_x( Word32 *mdct_data /*Qx*/, Word16 cov_max /*Q15*/, Word16 zp, Word32 ener /*Q8*/, Word32 ener_mean /*Q8*/, Word16 pitch /*Q0*/, Word16 Framesize ) /*o: Q0*/
     521             : {
     522           0 :     Word16 flag = 0;
     523             :     Word16 harm;
     524           0 :     move16();
     525           0 :     test();
     526           0 :     test();
     527           0 :     test();
     528           0 :     IF( LT_32( ener, L_shl( 50, 8 ) ) || ( LT_32( ener, L_sub( ener_mean, L_shl( 8, 8 ) ) ) && LT_16( cov_max, 29491 ) ) )
     529             :     {
     530           0 :         flag = 0;
     531           0 :         move16();
     532             :     }
     533           0 :     ELSE IF( GT_16( cov_max, 26214 ) )
     534             :     {
     535           0 :         flag = 1;
     536           0 :         move16();
     537             :     }
     538           0 :     ELSE IF( GT_16( zp, 100 ) )
     539             :     {
     540           0 :         flag = 0;
     541           0 :         move16();
     542             :     }
     543           0 :     ELSE IF( LT_32( ener, L_sub( ener_mean, L_shl( 6, 8 ) ) ) )
     544             :     {
     545           0 :         flag = 0;
     546           0 :         move16();
     547             :     }
     548           0 :     ELSE IF( GT_32( ener, L_add( ener_mean, L_shl( 1, 8 ) ) ) && GT_16( cov_max, 19661 ) )
     549             :     {
     550           0 :         flag = 1;
     551           0 :         move16();
     552             :     }
     553             :     ELSE
     554             :     {
     555           0 :         harm = harmo_x( mdct_data, Framesize, pitch );
     556           0 :         flag = 1;
     557           0 :         move16();
     558           0 :         if ( LT_16( harm, 22938 ) )
     559             :         {
     560           0 :             flag = 0;
     561           0 :             move16();
     562             :         }
     563             :     }
     564             : 
     565           0 :     return flag;
     566             : }
     567             : 
     568           0 : Word16 get_conv_relation_x( Word16 *s_LP /*Qx*/, Word16 shIFt, Word16 N ) /*o :Q0*/
     569             : {
     570             :     Word32 eng1, eng2, eng3;
     571             :     Word16 eng1_w, eng2_w;
     572             :     Word16 tmp, norm, nbits;
     573             : 
     574           0 :     nbits = sub( 15, norm_s( N ) );
     575           0 :     eng3 = dot_w32_accuracy_x( s_LP, s_LP + shIFt, nbits, N );
     576             : 
     577           0 :     IF( eng3 <= 0 )
     578             :     {
     579           0 :         return 0;
     580             :     }
     581             : 
     582           0 :     eng1 = dot_w32_accuracy_x( s_LP + shIFt, s_LP + shIFt, nbits, N );
     583           0 :     eng2 = dot_w32_accuracy_x( s_LP, s_LP, nbits, N );
     584             : 
     585           0 :     norm = sub( norm_l( L_or( eng1, L_or( eng2, eng3 ) ) ), 1 );
     586           0 :     eng1 = L_shl( eng1, norm );
     587           0 :     eng2 = L_shl( eng2, norm );
     588           0 :     eng3 = L_shl( eng3, norm );
     589             : 
     590           0 :     eng1_w = Sqrt_x_fast( eng1 );
     591           0 :     eng2_w = Sqrt_x_fast( eng2 );
     592             : 
     593           0 :     eng1 = L_mult0( eng1_w, eng2_w );
     594             : 
     595           0 :     norm = norm_l( eng1 );
     596           0 :     eng1_w = extract_h( L_shl( eng1, norm ) );
     597           0 :     eng2_w = extract_h( L_shl( eng3, norm ) );
     598             : 
     599           0 :     IF( GE_32( eng3, eng1 ) )
     600             :     {
     601           0 :         return 32767;
     602             :     }
     603           0 :     test();
     604           0 :     IF( ( eng2_w <= 0 ) || ( eng1_w <= 0 ) )
     605             :     {
     606           0 :         return 0;
     607             :     }
     608             : 
     609           0 :     tmp = div_s( eng2_w, eng1_w );
     610             : 
     611           0 :     return tmp;
     612             : }
     613             : 
     614             : 
     615           0 : static Word16 pitch_search_fx(
     616             :     Word16 *s /*Qs*/, /* lastPcmOut */
     617             :     Word16 *outx_new /*Qoutx_new*/,
     618             :     Word16 Framesize,
     619             :     Word16 *voicing /*Q15*/,
     620             :     Word16 zp, /*Q0*/
     621             :     Word32 ener /*Q8*/,
     622             :     Word32 ener_mean /*Q8*/,
     623             :     Word32 *mdct_data /*Qmdct*/,
     624             :     Word16 curr_mode )
     625             : {
     626           0 :     Word16 pitch = 0;
     627           0 :     Word32 cov_max = L_deposit_l( 0 ), tilt_enr1, tilt_enr2;
     628             :     Word16 s_LP[L_FRAME_MAX];
     629             :     Word16 start_pos, end_pos;
     630             :     Word16 low_freq_rate_result;
     631           0 :     Word16 flag = 0, zp_current;
     632             :     Word32 *mdctPtr;
     633             :     Word16 curr_frmsize;
     634           0 :     Word16 cov_max_bits = 0;
     635             :     Word16 i;
     636           0 :     move16();
     637           0 :     move16();
     638           0 :     move16();
     639           0 :     *voicing = 0;
     640           0 :     move16();
     641           0 :     curr_frmsize = Framesize;
     642           0 :     move16();
     643           0 :     if ( EQ_16( 2, curr_mode ) )
     644             :     {
     645           0 :         curr_frmsize = shr( Framesize, 1 );
     646             :     }
     647             : 
     648           0 :     zp_current = zero_pass_w32_x( outx_new, curr_frmsize );
     649             : 
     650           0 :     if ( EQ_16( 2, curr_mode ) )
     651             :     {
     652           0 :         zp_current = shl( zp_current, 1 );
     653             :     }
     654           0 :     IF( LE_16( Framesize, 256 ) )
     655             :     {
     656           0 :         IF( GT_16( zp_current, 70 ) )
     657             :         {
     658           0 :             return 0;
     659             :         }
     660             :     }
     661             :     ELSE
     662             :     {
     663           0 :         IF( GT_16( zp_current, 105 ) )
     664             :         {
     665           0 :             return 0;
     666             :         }
     667             :     }
     668             : 
     669           0 :     mdctPtr = mdct_data;
     670           0 :     if ( EQ_16( 2, curr_mode ) )
     671             :     {
     672           0 :         mdctPtr = mdct_data + shr( Framesize, 1 );
     673             :     }
     674             : 
     675           0 :     low_freq_rate_result = get_low_freq_eng_rate_x( mdctPtr,
     676             :                                                     curr_mode,
     677             :                                                     Framesize );
     678             : 
     679           0 :     IF( low_freq_rate_result )
     680             :     {
     681           0 :         return 0;
     682             :     }
     683             : 
     684           0 :     LpFilter2_x( s, s_LP, Framesize );
     685           0 :     sig_tilt_x( s_LP, Framesize, &tilt_enr1, &tilt_enr2 );
     686           0 :     IF( LE_16( Framesize, 320 ) )
     687             :     {
     688           0 :         test();
     689           0 :         IF( ( 0 == tilt_enr2 ) ||
     690             :             ( LT_32( tilt_enr1, L_shr( tilt_enr2, 1 ) ) ) )
     691             :         {
     692           0 :             return 0;
     693             :         }
     694             :     }
     695             :     ELSE
     696             :     {
     697           0 :         test();
     698           0 :         IF( ( 0 == tilt_enr2 ) ||
     699             :             ( LT_32( tilt_enr1, Mpy_32_16_1( tilt_enr2, 22938 ) ) ) )
     700             :         {
     701           0 :             return 0;
     702             :         }
     703             :     }
     704             : 
     705           0 :     IF( LE_16( Framesize, 320 ) )
     706             :     {
     707           0 :         start_pos = extract_l( L_shr( L_mac0( 0x80, 34, Framesize ), 8 ) );
     708           0 :         end_pos = extract_l( L_shr( L_mac0( 0x2, 3, Framesize ), 2 ) );
     709           0 :         get_maxConv_and_pitch_x( s_LP, start_pos, end_pos, Framesize, &cov_max, &cov_max_bits, &pitch );
     710           0 :         *voicing = get_voicing_x( s_LP, pitch, cov_max, cov_max_bits, Framesize );
     711           0 :         move16();
     712           0 :         pitch_modify_x( s_LP, voicing, &pitch, Framesize );
     713             :     }
     714             :     ELSE
     715             :     {
     716             :         Word16 s_tmp[L_FRAME_MAX];
     717             :         Word16 Framesize_tmp;
     718             :         Word16 pitch_tmp[3];
     719             :         Word16 cov_size;
     720             : 
     721           0 :         Framesize_tmp = shr( Framesize, 1 );
     722           0 :         FOR( i = 0; i < Framesize_tmp; i++ )
     723             :         {
     724           0 :             s_tmp[i] = s_LP[2 * i];
     725           0 :             move16();
     726             :         }
     727             : 
     728           0 :         start_pos = extract_l( L_shr( L_mac0( 0x80, 34, Framesize_tmp ), 8 ) );
     729           0 :         end_pos = extract_l( L_shr( L_mac0( 0x2, 3, Framesize_tmp ), 2 ) );
     730             : 
     731           0 :         cov_max = L_deposit_l( 0 );
     732           0 :         pitch = 0;
     733           0 :         move16();
     734           0 :         get_maxConv_and_pitch_x( s_tmp, start_pos, end_pos, Framesize_tmp, &cov_max, &cov_max_bits, &pitch );
     735             : 
     736           0 :         IF( pitch > 0 )
     737             :         {
     738           0 :             pitch_tmp[0] = 0;
     739           0 :             move16();
     740           0 :             if ( GT_16( shl( pitch, 1 ), 1 ) )
     741             :             {
     742           0 :                 pitch_tmp[0] = sub( shl( pitch, 1 ), 1 );
     743           0 :                 move16();
     744             :             }
     745           0 :             pitch_tmp[1] = shl( pitch, 1 );
     746           0 :             move16();
     747           0 :             pitch_tmp[2] = add( shl( pitch, 1 ), 1 );
     748           0 :             move16();
     749           0 :             start_pos = 0;
     750           0 :             move16();
     751           0 :             pitch = 0;
     752           0 :             move16();
     753           0 :             FOR( i = 0; i < 3; i++ )
     754             :             {
     755           0 :                 cov_size = sub( Framesize, pitch_tmp[i] );
     756           0 :                 end_pos = get_conv_relation_x( s_LP, pitch_tmp[i], cov_size );
     757           0 :                 IF( GT_16( end_pos, start_pos ) )
     758             :                 {
     759           0 :                     start_pos = end_pos;
     760           0 :                     move16();
     761           0 :                     pitch = pitch_tmp[i];
     762           0 :                     move16();
     763             :                 }
     764             :             }
     765           0 :             *voicing = start_pos;
     766           0 :             move16();
     767             :         }
     768             :     }
     769             : 
     770           0 :     IF( pitch > 0 )
     771             :     {
     772           0 :         flag = Is_Periodic_x( mdct_data, *voicing, zp, ener, ener_mean, pitch, Framesize );
     773             :     }
     774           0 :     if ( flag == 0 )
     775             :     {
     776           0 :         pitch = 0;
     777           0 :         move16();
     778             :     }
     779           0 :     return pitch;
     780             : }
     781             : 
     782           0 : void concealment_init_x(
     783             :     const Word16 L_frameTCX,
     784             :     T_PLCInfo_HANDLE hPlcInfo )
     785             : {
     786             :     Word16 i;
     787             : 
     788           0 :     hPlcInfo->L_frameTCX = L_frameTCX;
     789           0 :     move16();
     790           0 :     hPlcInfo->Pitch_fx = 0;
     791           0 :     move16();
     792           0 :     hPlcInfo->T_bfi_fx = 0;
     793           0 :     move16();
     794           0 :     hPlcInfo->outx_new_n1_fx = 0;
     795           0 :     move16();
     796           0 :     hPlcInfo->nsapp_gain_fx = 0;
     797           0 :     move16();
     798           0 :     hPlcInfo->nsapp_gain_n_fx = 0;
     799           0 :     move16();
     800           0 :     hPlcInfo->ener_mean_fx = L_deposit_l( 15213 ); /*Q8 59.4260f*256*/
     801           0 :     hPlcInfo->ener_fx = L_deposit_l( 0 );
     802           0 :     hPlcInfo->zp_fx = L_frameTCX;
     803           0 :     move16();
     804           0 :     hPlcInfo->recovery_gain = 0;
     805           0 :     move16();
     806           0 :     hPlcInfo->step_concealgain_fx = 0;
     807           0 :     move16();
     808           0 :     hPlcInfo->concealment_method = TCX_NONTONAL;
     809           0 :     move16();
     810           0 :     hPlcInfo->subframe_fx = 0;
     811           0 :     move16();
     812           0 :     hPlcInfo->nbLostCmpt = (Word16) L_deposit_l( 0 );
     813           0 :     move16();
     814           0 :     hPlcInfo->seed = 21845;
     815           0 :     move16();
     816             : 
     817           0 :     FOR( i = 0; i < TCX_TONALITY_INIT_CNT; i++ )
     818             :     {
     819           0 :         hPlcInfo->TCX_Tonality[i] = 1;
     820           0 :         move16();
     821             :     }
     822           0 :     FOR( i = TCX_TONALITY_INIT_CNT; i < DEC_STATE_LEN; i++ )
     823             :     {
     824           0 :         hPlcInfo->TCX_Tonality[i] = 0;
     825           0 :         move16();
     826             :     }
     827             : 
     828           0 :     FOR( i = 0; i < MAX_POST_LEN; i++ )
     829             :     {
     830           0 :         hPlcInfo->Transient[i] = 1;
     831           0 :         move16();
     832             :     }
     833             : 
     834           0 :     FOR( i = 0; i < L_FRAME_MAX; i++ )
     835             :     {
     836           0 :         hPlcInfo->data_reci2_fx[i] = L_deposit_l( 0 );
     837             :     }
     838             : 
     839           0 :     return;
     840             : }
     841             : 
     842             : 
     843           0 : void concealment_init_ivas_fx(
     844             :     const Word16 L_frameTCX,
     845             :     T_PLCInfo_HANDLE hPlcInfo )
     846             : {
     847             :     Word16 i;
     848             : 
     849           0 :     hPlcInfo->L_frameTCX = L_frameTCX;
     850           0 :     move16();
     851           0 :     hPlcInfo->Pitch_fx = 0;
     852           0 :     move16();
     853           0 :     hPlcInfo->T_bfi_fx = 0;
     854           0 :     move16();
     855           0 :     hPlcInfo->outx_new_n1_fx = 0;
     856           0 :     move16();
     857           0 :     hPlcInfo->nsapp_gain_fx = 0;
     858           0 :     move16();
     859           0 :     hPlcInfo->nsapp_gain_n_fx = 0;
     860           0 :     move16();
     861           0 :     hPlcInfo->ener_mean_fx = L_deposit_l( 15213 );
     862           0 :     hPlcInfo->ener_fx = L_deposit_l( 0 );
     863           0 :     hPlcInfo->zp_fx = L_frameTCX;
     864           0 :     move16();
     865           0 :     hPlcInfo->recovery_gain = 0;
     866           0 :     move16();
     867           0 :     hPlcInfo->step_concealgain_fx = 0;
     868           0 :     move16();
     869           0 :     hPlcInfo->concealment_method = TCX_NONTONAL;
     870           0 :     move16();
     871           0 :     hPlcInfo->subframe_fx = 0;
     872           0 :     move16();
     873           0 :     hPlcInfo->nbLostCmpt = (Word16) L_deposit_l( 0 );
     874           0 :     move16();
     875           0 :     hPlcInfo->seed = RANDOM_INITSEED;
     876           0 :     move16();
     877             : 
     878           0 :     FOR( i = 0; i < TCX_TONALITY_INIT_CNT; i++ )
     879             :     {
     880           0 :         hPlcInfo->TCX_Tonality[i] = 1;
     881           0 :         move16();
     882             :     }
     883           0 :     FOR( i = TCX_TONALITY_INIT_CNT; i < DEC_STATE_LEN; i++ )
     884             :     {
     885           0 :         hPlcInfo->TCX_Tonality[i] = 0;
     886           0 :         move16();
     887             :     }
     888           0 :     FOR( i = 0; i < MAX_POST_LEN; i++ )
     889             :     {
     890           0 :         hPlcInfo->Transient[i] = 1;
     891           0 :         move16();
     892             :     }
     893             : 
     894           0 :     FOR( i = 0; i < L_FRAME_MAX; i++ )
     895             :     {
     896           0 :         hPlcInfo->data_reci2_fx[i] = L_deposit_l( 0 );
     897           0 :         move32();
     898             :     }
     899           0 :     return;
     900             : }
     901             : 
     902           0 : static Word16 own_random_fix(              /* o  : output random value */
     903             :                               Word16 *seed /* i/o: random seed   Q0      */
     904             : )
     905             : {
     906           0 :     *seed = extract_l( L_mac0( 13849L, *seed, 31821 ) );
     907           0 :     return ( *seed );
     908             : }
     909             : 
     910           0 : void concealment_decode_fix(
     911             :     Word16 curr_mode,
     912             :     Word32 *invkoef /*Qinvkoef_scale*/,
     913             :     Word16 *invkoef_scale,
     914             :     T_PLCInfo_HANDLE hPlcInfo )
     915             : {
     916             :     Word16 i;
     917           0 :     Word16 N = hPlcInfo->L_frameTCX;
     918           0 :     Word16 *seed = &( hPlcInfo->seed );
     919             :     Word16 sign;
     920           0 :     move16();
     921             : 
     922           0 :     IF( hPlcInfo->concealment_method == TCX_NONTONAL ) /* #define TCX_NONTONAL 0 */
     923             :     {
     924           0 :         IF( EQ_16( curr_mode, 1 ) )
     925             :         {
     926             :             /* copy the data of the last frame */
     927           0 :             MVR2R_WORD32( hPlcInfo->data_reci2_fx, invkoef, N );
     928           0 :             *invkoef_scale = hPlcInfo->data_reci2_scale;
     929           0 :             move16();
     930             :             /* sign randomization */
     931           0 :             FOR( i = 0; i < N; i++ )
     932             :             {
     933           0 :                 sign = add( shl( shr( own_random_fix( seed ), 15 ), 1 ), 1 );
     934           0 :                 if ( EQ_16( sign, -1 ) )
     935             :                 {
     936           0 :                     invkoef[i] = L_negate( invkoef[i] );
     937           0 :                     move32();
     938             :                 }
     939             :             }
     940             :         }
     941             :     }
     942             : 
     943           0 :     return;
     944             : }
     945             : 
     946             : 
     947           0 : Word16 Spl_GetScalingSquare_x( const Word16 *in_vector /*Qin_vector*/, const Word16 in_vector_length, Word16 times ) /*o : Q0*/
     948             : {
     949           0 :     Word16 nbits = sub( 15, norm_s( times ) ) /*Spl_GetSizeInBits_x(times)*/;
     950             :     Word16 i;
     951           0 :     Word16 smax = -1;
     952             :     Word16 sabs;
     953           0 :     const Word16 *sptr = in_vector;
     954             :     Word16 t;
     955           0 :     move16();
     956           0 :     FOR( i = in_vector_length; i > 0; i-- )
     957             :     {
     958             : 
     959           0 :         sabs = abs_s( *sptr );
     960           0 :         sptr++;
     961           0 :         smax = s_max( sabs, smax );
     962             :     }
     963             : 
     964           0 :     t = norm_l( L_mult0( smax, smax ) );
     965             : 
     966           0 :     IF( smax == 0 )
     967             :     {
     968           0 :         return 0; /* Since norm(0) returns 0 */
     969             :     }
     970             :     ELSE
     971             :     {
     972           0 :         nbits = sub( nbits, t );
     973           0 :         nbits = s_max( 0, nbits );
     974             : 
     975           0 :         return nbits;
     976             :     }
     977             : }
     978             : 
     979             : 
     980           0 : Word32 Spl_Energy_x( const Word16 *vector /*Qvector*/, const Word16 vector_length, Word16 *scale_factor )
     981             : {
     982           0 :     Word32 en = L_deposit_l( 0 );
     983             :     Word32 i;
     984           0 :     Word16 scaling = Spl_GetScalingSquare_x( vector, vector_length, vector_length );
     985             : 
     986           0 :     FOR( i = 0; i < vector_length; i++ )
     987             :     {
     988           0 :         en = L_add( en, L_shr( L_mult0( vector[i], vector[i] ), scaling ) );
     989             :     }
     990             : 
     991           0 :     move32();
     992           0 :     *scale_factor = scaling;
     993             : 
     994           0 :     return en;
     995             : }
     996             : 
     997           0 : void Log10OfEnergy_x( const Word16 *s /* Qs */, Word32 *enerlogval /* Q8 */, const Word16 len )
     998             : {
     999           0 :     Word32 energy = L_deposit_l( 0 ), tmp2 = L_deposit_l( 0 );
    1000           0 :     Word16 shfts = 0;
    1001           0 :     Word32 Log10_energy = L_deposit_l( 0 ), Log10_len = L_deposit_l( 0 );
    1002           0 :     move16();
    1003           0 :     energy = Spl_Energy_x( s, len, &shfts ); /* Q:-shfts */
    1004           0 :     IF( energy > 0 )
    1005             :     {
    1006           0 :         Log10_energy = con_Log10( energy, negate( shfts ) ); /* Q25 */
    1007           0 :         Log10_len = con_Log10( L_deposit_l( len ), 0 );      /* Q25 */
    1008           0 :         tmp2 = L_sub( Log10_energy, Log10_len );             /* Q25 */
    1009           0 :         tmp2 = Mpy_32_16_1( tmp2, 20480 );                   /* Q11->10   Q=25+11-15=21 */
    1010           0 :         *enerlogval = L_shr( tmp2, 13 );                     /* Q8 */
    1011           0 :         move32();
    1012             :     }
    1013             :     ELSE
    1014             :     {
    1015           0 :         *enerlogval = -25600;
    1016           0 :         move32();
    1017             :     }
    1018           0 : }
    1019             : 
    1020           0 : static Word32 fnLog2( Word32 L_Input /*QL_Input*/ ) /*o :Q26*/
    1021             : {
    1022             : 
    1023           0 :     Word16 swC0 = -0x2b2a, swC1 = 0x7fc5, swC2 = -0x54d0;
    1024             :     Word16 siShIFtCnt, swInSqrd, swIn;
    1025             :     Word32 LwIn;
    1026           0 :     move16();
    1027           0 :     move16();
    1028           0 :     move16();
    1029             :     /*_________________________________________________________________________
    1030             :      |                                                                         |
    1031             :      |                              Executable Code                            |
    1032             :      |_________________________________________________________________________|
    1033             :     */
    1034             : 
    1035             :     /* normalize input and store shIFts required */
    1036             :     /* ----------------------------------------- */
    1037             : 
    1038           0 :     siShIFtCnt = norm_l( L_Input );
    1039           0 :     LwIn = L_shl( L_Input, siShIFtCnt );
    1040           0 :     siShIFtCnt = add( siShIFtCnt, 1 );
    1041           0 :     siShIFtCnt = negate( siShIFtCnt );
    1042             : 
    1043             :     /* calculate x*x*c0 */
    1044             :     /* ---------------- */
    1045             : 
    1046           0 :     swIn = extract_h( LwIn );
    1047           0 :     swInSqrd = mult_r( swIn, swIn );
    1048           0 :     LwIn = L_mult( swInSqrd, swC0 );
    1049             : 
    1050             :     /* add x*c1 */
    1051             :     /* --------- */
    1052             : 
    1053           0 :     LwIn = L_mac( LwIn, swIn, swC1 );
    1054             : 
    1055             :     /* add c2 */
    1056             :     /* ------ */
    1057             : 
    1058           0 :     LwIn = L_add( LwIn, L_deposit_h( swC2 ) );
    1059             : 
    1060             :     /* apply *(4/32) */
    1061             :     /* ------------- */
    1062             : 
    1063           0 :     LwIn = L_shr( LwIn, 3 );
    1064           0 :     LwIn = L_and( LwIn, 0x03ffffff );
    1065           0 :     siShIFtCnt = shl( siShIFtCnt, 10 );
    1066           0 :     LwIn = L_add( LwIn, L_deposit_h( siShIFtCnt ) );
    1067             : 
    1068             :     /* return log2 */
    1069             :     /* ----------- */
    1070             : 
    1071           0 :     return ( LwIn );
    1072             : }
    1073             : 
    1074           0 : static Word32 fnLog10( Word32 L_Input /*QL_Input*/ ) /*o :Q26*/
    1075             : {
    1076             : 
    1077           0 :     Word16 Scale = 9864; /* 0.30103 = log10(2) */
    1078             :     Word32 LwIn;
    1079           0 :     move16();
    1080             :     /*_________________________________________________________________________
    1081             :      |                                                                         |
    1082             :      |                              Executable Code                            |
    1083             :      |_________________________________________________________________________|
    1084             :     */
    1085             : 
    1086             :     /* 0.30103*log2(x) */
    1087             :     /* ------------------- */
    1088             : 
    1089           0 :     LwIn = fnLog2( L_Input );
    1090           0 :     LwIn = Mpy_32_16_1( LwIn, Scale );
    1091             : 
    1092           0 :     return ( LwIn );
    1093             : }
    1094             : 
    1095           0 : Word32 con_Log10( Word32 i_s32Val /*Qi_s32Val*/, Word16 i_s16Q /*Q0*/ ) /*o; Q26*/
    1096             : {
    1097             :     Word32 s32Out;
    1098             :     Word32 s32Correct;               /* corrected (31-q)*log10(2) */
    1099           0 :     const Word16 s16Log10_2 = 19728; /* log10(2)~Q16 */
    1100           0 :     move16();
    1101             : 
    1102           0 :     IF( 0 == i_s32Val )
    1103             :     {
    1104           0 :         return EVS_LW_MIN;
    1105             :     }
    1106             : 
    1107           0 :     s32Out = fnLog10( i_s32Val ); /* (2^26)*log10(a) */
    1108             : 
    1109           0 :     s32Correct = L_mult( sub( 31, i_s16Q ), s16Log10_2 ); /* q = 17 */
    1110           0 :     s32Correct = L_shl( s32Correct, 8 );                  /* q = 25 */
    1111           0 :     s32Out = L_shr( s32Out, 1 );                          /* q = 25 */
    1112             : 
    1113           0 :     s32Out = L_add( s32Out, s32Correct );
    1114             : 
    1115           0 :     return s32Out;
    1116             : }
    1117             : 
    1118           0 : void concealment_update2_x(
    1119             :     const Word16 *outx_new /*Qoutx_new*/,
    1120             :     T_PLCInfo_HANDLE hPlcInfo,
    1121             :     const Word16 FrameSize )
    1122             : {
    1123           0 :     hPlcInfo->zp_fx = zero_pass_w32_x( outx_new, FrameSize );
    1124           0 :     move16();
    1125             : 
    1126           0 :     Log10OfEnergy_x( outx_new, &hPlcInfo->ener_fx, FrameSize ); /* Q8 */
    1127           0 :     test();
    1128           0 :     IF( LT_16( hPlcInfo->zp_fx, 100 ) && GT_32( hPlcInfo->ener_fx, L_shl( 50, 8 ) ) )
    1129             :     {
    1130           0 :         hPlcInfo->ener_mean_fx = L_add( Mpy_32_16_1( hPlcInfo->ener_mean_fx, 32112 /* 0.98 Q15 */ ),
    1131             :                                         Mpy_32_16_1( hPlcInfo->ener_fx, 655 /* 0.02 Q15 */ ) );
    1132           0 :         move32();
    1133             :     }
    1134             : 
    1135           0 :     return;
    1136             : }
    1137             : 
    1138           0 : static Word16 array_max_indx_fx(
    1139             :     Word16 *s /*Qs*/,
    1140             :     Word16 N )
    1141             : {
    1142           0 :     Word16 i, indx = 0;
    1143           0 :     move16();
    1144           0 :     FOR( i = 0; i < N; i++ )
    1145             :     {
    1146           0 :         if ( GT_16( s[i], s[indx] ) )
    1147             :         {
    1148           0 :             indx = i;
    1149           0 :             move16();
    1150             :         }
    1151             :     }
    1152           0 :     return indx;
    1153             : }
    1154             : 
    1155           0 : Word16 ffr_getSfWord16(                /* o: measured headroom in range [0..15], 0 IF all x[i] == 0 */
    1156             :                         Word16 *x,     /* i: array containing 16-bit data Qx*/
    1157             :                         Word16 len_x ) /* i: length of the array to scan  */
    1158             : {
    1159             :     Word16 i, i_min, i_max;
    1160             :     Word16 x_min, x_max;
    1161             : 
    1162             : 
    1163           0 :     x_max = 0;
    1164           0 :     move16();
    1165           0 :     x_min = 0;
    1166           0 :     move16();
    1167           0 :     FOR( i = 0; i < len_x; i++ )
    1168             :     {
    1169           0 :         if ( x[i] >= 0 )
    1170             :         {
    1171           0 :             x_max = s_max( x_max, x[i] );
    1172             :         }
    1173           0 :         if ( x[i] < 0 )
    1174             :         {
    1175           0 :             x_min = s_min( x_min, x[i] );
    1176             :         }
    1177             :     }
    1178             : 
    1179           0 :     i_max = 0x10;
    1180           0 :     move16();
    1181           0 :     i_min = 0x10;
    1182           0 :     move16();
    1183             : 
    1184           0 :     if ( x_max != 0 )
    1185             :     {
    1186           0 :         i_max = norm_s( x_max );
    1187             :     }
    1188             : 
    1189           0 :     if ( x_min != 0 )
    1190             :     {
    1191           0 :         i_min = norm_s( x_min );
    1192             :     }
    1193             : 
    1194           0 :     i = s_and( s_min( i_max, i_min ), 0xF );
    1195             : 
    1196             : 
    1197           0 :     return i;
    1198             : }
    1199             : 
    1200           0 : static Word16 OverlapAdd_fx( Word16 *pitch125_data /*Qx*/, Word16 *sbuf /*Qx*/, Word16 n, Word16 pitch /*Q0*/, Word16 Framesize )
    1201             : {
    1202             :     Word16 n1, n2, s, s16MaxCoefNorm, s16MaxCoefNorm2, tmp16;
    1203             :     Word16 i;
    1204           0 :     Word16 pitch125 = extract_l( L_shr( L_add( L_add( L_deposit_h( pitch ), L_mult( pitch, 8192 ) ), 32768 ), 16 ) );
    1205           0 :     Word16 Loverlap = sub( pitch125, pitch );
    1206           0 :     Word16 Framesize_sub_n = sub( Framesize, n );
    1207             : 
    1208           0 :     n1 = Framesize_sub_n;
    1209           0 :     move16();
    1210           0 :     n2 = Framesize_sub_n;
    1211           0 :     move16();
    1212           0 :     if ( LT_16( Loverlap, Framesize_sub_n ) )
    1213             :     {
    1214           0 :         n1 = Loverlap;
    1215           0 :         move16();
    1216             :     }
    1217           0 :     if ( LT_16( pitch125, Framesize_sub_n ) )
    1218             :     {
    1219           0 :         n2 = pitch125;
    1220           0 :         move16();
    1221             :     }
    1222           0 :     s16MaxCoefNorm = sub( ffr_getSfWord16( sbuf + n, n1 ), 1 );
    1223           0 :     s16MaxCoefNorm2 = ffr_getSfWord16( pitch125_data, n1 );
    1224           0 :     Loverlap = s_max( 1, Loverlap );
    1225           0 :     tmp16 = BASOP_Util_Divide1616_Scale( 1, Loverlap, &s );
    1226           0 :     FOR( i = 0; i < n1; i++ )
    1227             :     {
    1228             :         Word16 tmp;
    1229             :         Word16 dat;
    1230           0 :         dat = shl( sbuf[add( n, i )], s16MaxCoefNorm );
    1231           0 :         tmp = extract_l( L_shl( L_mult0( i, tmp16 ), s ) ); /* q15 */
    1232           0 :         sbuf[add( n, i )] = round_fx( L_add( L_shr( L_mult( dat, sub( 32767, tmp ) ), s16MaxCoefNorm ),
    1233           0 :                                              L_shr( L_mult( shl( pitch125_data[i], s16MaxCoefNorm2 ), tmp ), s16MaxCoefNorm2 ) ) );
    1234             :     }
    1235             : 
    1236           0 :     FOR( i = n1; i < n2; i++ )
    1237             :     {
    1238           0 :         sbuf[add( n, i )] = pitch125_data[i];
    1239           0 :         move16();
    1240             :     }
    1241             : 
    1242           0 :     pitch = add( n, pitch );
    1243             : 
    1244           0 :     return pitch;
    1245             : }
    1246             : 
    1247           0 : static void add_noise( Word16 *const sbuf,            /*Qsbuf*/
    1248             :                        Word16 *const outx_new_n1,     /*Q0*/
    1249             :                        Word16 const *const noise_seg, /*Q0*/
    1250             :                        Word16 const Len,
    1251             :                        Word16 *const gain,         /*Q15*/
    1252             :                        Word16 const *const gain_n, /*Q15*/
    1253             :                        Word8 const firstFrame )
    1254             : {
    1255             :     Word16 i;
    1256             :     Word16 temp_OUT;
    1257             : 
    1258           0 :     IF( !firstFrame )
    1259             :     {
    1260           0 :         temp_OUT = sub_sat( noise_seg[0], mult( ( *outx_new_n1 ), 22282 /* 0.68 Q15 */ ) );
    1261           0 :         sbuf[0] = add_sat( sbuf[0], mult( ( temp_OUT ), *gain ) );
    1262           0 :         move16();
    1263           0 :         *gain = mac_r_sat( L_mult_sat( 32439 /* 0.99 Q15 */, *gain ), 328 /* 0.01 Q15 */, *gain_n );
    1264             :     }
    1265             : 
    1266           0 :     FOR( i = 1; i < Len; i++ )
    1267             :     {
    1268           0 :         temp_OUT = sub_sat( noise_seg[i], mult( ( noise_seg[i - 1] ), 22282 /* 0.68 Q15 */ ) );
    1269           0 :         sbuf[i] = add_sat( sbuf[i], mult( ( temp_OUT ), *gain ) );
    1270           0 :         move16();
    1271           0 :         *gain = mac_r_sat( L_mult( 32439 /* 0.99 Q15 */, *gain ), 328 /* 0.01 Q15 */, *gain_n );
    1272             :     }
    1273             : 
    1274           0 :     *outx_new_n1 = noise_seg[i - 1]; /*q0*/
    1275           0 :     move16();
    1276             : 
    1277           0 :     return;
    1278             : }
    1279             : 
    1280           0 : static Word16 waveform_adj_fix(
    1281             :     T_PLCInfo_HANDLE hPlcInfo,
    1282             :     Word16 *overlapbuf, /*Qoverlapbuf*/
    1283             :     Word16 *outdata2,   /*Qoutdata2*/
    1284             :     Word16 *outx_new,   /*Qoutx_new*/
    1285             :     const Word16 Framesize,
    1286             :     const Word16 voicing, /*Q15*/
    1287             :     const Word16 core )
    1288             : {
    1289             :     Word16 i, zp1, zp2, Framesizediv2, s16MaxCoefNorm, pitch;
    1290             :     Word16 sbuf[L_FRAME_MAX];
    1291             :     Word16 tmp;
    1292             : 
    1293           0 :     Framesizediv2 = shr( Framesize, 1 );
    1294           0 :     zp1 = zero_pass_w32_x( outdata2, Framesizediv2 );
    1295           0 :     zp2 = zero_pass_w32_x( outdata2 + Framesizediv2, Framesizediv2 );
    1296             : 
    1297           0 :     pitch = hPlcInfo->Pitch_fx;
    1298             : 
    1299             :     /* judge if the pitch is usable */
    1300           0 :     tmp = 1;
    1301           0 :     move16();
    1302           0 :     if ( GT_16( zp1, 1 ) )
    1303             :     {
    1304           0 :         tmp = zp1;
    1305           0 :         move16();
    1306             :     }
    1307           0 :     IF( LT_16( shl( tmp, 2 ), zp2 ) )
    1308             :     {
    1309           0 :         move16();
    1310           0 :         return 0;
    1311             :     }
    1312             : 
    1313             :     /* adjust the pitch value */
    1314           0 :     test();
    1315           0 :     test();
    1316           0 :     test();
    1317           0 :     IF( hPlcInfo->T_bfi_fx && ( LE_16( pitch, Framesizediv2 ) ) && ( GT_16( Framesize, 256 ) ) && ( EQ_16( core, 1 ) ) )
    1318             :     {
    1319           0 :         Word16 i1 = 0, i2 = 0;
    1320             :         Word16 pos1, pos2, pos3;
    1321           0 :         move16();
    1322           0 :         move16();
    1323           0 :         i1 = add( 1, array_max_indx_fx( outx_new, pitch ) );
    1324           0 :         i2 = add( 1, array_max_indx_fx( outx_new + pitch, pitch ) );
    1325             : 
    1326           0 :         pos1 = add( i2, sub( pitch, i1 ) );
    1327           0 :         pos3 = add( pos1, mult( pos1, 8192 /* 0.25 Q15 */ ) );
    1328           0 :         pos2 = add( pitch, mult( pitch, 8192 /* 0.25 Q15 */ ) );
    1329             : 
    1330           0 :         test();
    1331           0 :         test();
    1332           0 :         if ( ( LT_16( pos1, pos2 ) ) && ( GT_16( pos3, pitch ) ) && ( LT_16( pos1, Framesizediv2 ) ) )
    1333             :         {
    1334           0 :             pitch = add( i2, sub( pitch, i1 ) );
    1335             :         }
    1336             :     }
    1337             : 
    1338             :     {
    1339           0 :         Word16 pitch125 = 0, Loverlap = 0, n = 0;
    1340             :         Word16 pitch125_data[L_FRAME_MAX];
    1341           0 :         move16();
    1342           0 :         move16();
    1343           0 :         move16();
    1344           0 :         pitch125 = extract_l( ( L_shr( L_add( L_add( L_deposit_h( pitch ), L_mult( pitch, 8192 ) ), 32768 ), 16 ) ) );
    1345           0 :         Loverlap = sub( pitch125, pitch );
    1346           0 :         FOR( i = 0; i < pitch; i++ )
    1347             :         {
    1348           0 :             pitch125_data[i] = outdata2[add( sub( Framesize, pitch ), i )];
    1349           0 :             move16();
    1350             :         }
    1351           0 :         FOR( i = 0; i < Loverlap; i++ )
    1352             :         {
    1353           0 :             pitch125_data[add( pitch, i )] = outx_new[i];
    1354           0 :             move16();
    1355             :         }
    1356           0 :         FOR( i = 0; i < Framesize; i++ )
    1357             :         {
    1358           0 :             sbuf[i] = outx_new[i];
    1359           0 :             move16();
    1360             :         }
    1361             : 
    1362             :         {
    1363             :             Word16 pitch125a1;
    1364           0 :             Word16 tmp_buf[2 * L_FRAME_MAX], *p_tmp = tmp_buf + 1;
    1365             : 
    1366           0 :             FOR( i = 0; i < pitch125; i++ )
    1367             :             {
    1368           0 :                 p_tmp[i] = pitch125_data[i];
    1369           0 :                 move16();
    1370             :             }
    1371             : 
    1372           0 :             p_tmp[-1] = outdata2[sub( sub( Framesize, pitch ), 1 )];
    1373           0 :             move16();
    1374           0 :             p_tmp[pitch125] = outx_new[Loverlap];
    1375           0 :             move16();
    1376           0 :             pitch125a1 = add( pitch125, 1 );
    1377           0 :             s16MaxCoefNorm = sub( ffr_getSfWord16( p_tmp - 1, pitch125a1 ), 1 );
    1378           0 :             FOR( i = 0; i < pitch125a1; i++ )
    1379             :             {
    1380           0 :                 p_tmp[i - 1] = shl( p_tmp[i - 1], s16MaxCoefNorm );
    1381           0 :                 move16();
    1382             :             }
    1383           0 :             FOR( i = 0; i < pitch125; i++ )
    1384             :             {
    1385           0 :                 pitch125_data[i] = round_fx_sat( L_shr_sat( L_add_sat( ( L_mult( p_tmp[i], 20972 ) ), L_mac_sat( L_mult( p_tmp[i - 1], 5898 ), p_tmp[i + 1], 5898 ) ), s16MaxCoefNorm ) );
    1386           0 :                 move16();
    1387             :             }
    1388             :         }
    1389             : 
    1390           0 :         WHILE( LT_16( n, Framesize ) ) /* periodical extension */
    1391             :         {
    1392           0 :             n = OverlapAdd_fx( pitch125_data, sbuf, n, pitch, Framesize );
    1393             :         }
    1394             : 
    1395             :         /* maximum pitch lag is 3/4 Framesize; pitch125_data is reused for
    1396             :            temporary storage, since outdata2 (holding the pcm data of the
    1397             :            last good frame) is still needed and overlapbuf overlaps outdata2 */
    1398           0 :         Copy( &sbuf[Framesize / 4], pitch125_data, shr( imult1616( 3, Framesize ), 2 ) );
    1399             : 
    1400           0 :         hPlcInfo->nsapp_gain_fx = 0;
    1401           0 :         move16();
    1402           0 :         hPlcInfo->nsapp_gain_n_fx = sub( 32767, shr( voicing, 1 ) ); /* q15 */
    1403           0 :         tmp = Framesize;
    1404           0 :         move16();
    1405             : 
    1406             :         /* use last good signal for noise generation */
    1407           0 :         add_noise( sbuf, &( hPlcInfo->outx_new_n1_fx ), outdata2, tmp, &( hPlcInfo->nsapp_gain_fx ), &( hPlcInfo->nsapp_gain_n_fx ), 1 );
    1408             : 
    1409             :         /* save current (noisy) output from IMDCT */
    1410           0 :         MVR2R_WORD16( outx_new, hPlcInfo->data_noise, tmp );
    1411             : 
    1412             :         /* overlapbuf can now be filled with sbuf, needed for subsequently lost frames */
    1413           0 :         Copy( pitch125_data, &overlapbuf[Framesize / 4], shr( imult1616( 3, Framesize ), 2 ) );
    1414             :     }
    1415           0 :     FOR( i = 0; i < Framesize; i++ )
    1416             :     {
    1417           0 :         outx_new[i] = sbuf[i];
    1418           0 :         move16();
    1419             :     }
    1420             : 
    1421           0 :     return pitch;
    1422             : }
    1423             : 
    1424             : 
    1425           0 : void waveform_adj2_fix(
    1426             :     T_PLCInfo_HANDLE hPlcInfo,
    1427             :     Word16 *overlapbuf, /*Qoverlapbuf*/
    1428             :     Word16 *outx_new,   /*Qoutx_new*/
    1429             :     const Word16 delay,
    1430             :     const Word16 bfi_cnt,
    1431             :     const Word16 bfi )
    1432             : {
    1433             :     Word16 i, n, tablescale, ratio, dat, Framesizesubn, Framesizesubp, tmp16, s, ptable, temp_OUT, s16MaxCoefNorm, s16MaxCoefNorm2;
    1434             :     Word16 sbuf[L_FRAME_MAX];
    1435             :     Word16 pitch, L_frameTCX;
    1436             : 
    1437           0 :     pitch = hPlcInfo->Pitch_fx;
    1438           0 :     move16();
    1439           0 :     L_frameTCX = hPlcInfo->L_frameTCX;
    1440           0 :     move16();
    1441           0 :     n = 0;
    1442           0 :     move16();
    1443           0 :     Framesizesubn = sub( L_frameTCX, n );
    1444           0 :     Framesizesubp = sub( L_frameTCX, pitch );
    1445           0 :     IF( pitch > 0 )
    1446             :     {
    1447           0 :         WHILE( Framesizesubn > 0 )
    1448             :         {
    1449             :             /* periodical extension */
    1450           0 :             Word16 tmp = vadmin( pitch, Framesizesubn );
    1451           0 :             FOR( i = 0; i < tmp; i++ )
    1452             :             {
    1453           0 :                 sbuf[add( n, i )] = overlapbuf[add( Framesizesubp, i )];
    1454           0 :                 move16();
    1455             :             }
    1456           0 :             n = add( n, pitch );
    1457           0 :             Framesizesubn = sub( L_frameTCX, n );
    1458             :         }
    1459             : 
    1460           0 :         FOR( i = 0; i < L_frameTCX; i++ )
    1461             :         {
    1462           0 :             overlapbuf[i] = sbuf[i];
    1463           0 :             move16();
    1464             :         }
    1465             : 
    1466             :         {
    1467           0 :             Word16 size = L_frameTCX;
    1468           0 :             Word16 *noise_ptr = hPlcInfo->data_noise;
    1469           0 :             move16();
    1470             :             /* use last (noisy) output from IMDCT for noise generation */
    1471           0 :             add_noise( sbuf, &( hPlcInfo->outx_new_n1_fx ), noise_ptr, size, &( hPlcInfo->nsapp_gain_fx ), &( hPlcInfo->nsapp_gain_n_fx ), 0 );
    1472             : 
    1473             :             /* save current (noisy) output from IMDCT */
    1474           0 :             IF( bfi )
    1475             :             {
    1476           0 :                 MVR2R_WORD16( outx_new, noise_ptr, size );
    1477             :             }
    1478             :         }
    1479           0 :         test();
    1480           0 :         IF( EQ_16( bfi_cnt, 4 ) || bfi == 0 )
    1481             :         {
    1482           0 :             SWITCH( L_frameTCX )
    1483             :             {
    1484           0 :                 case 160:
    1485             :                 {
    1486           0 :                     tablescale = 8;
    1487           0 :                     move16();
    1488           0 :                     ptable = 26214; /* (Word16)(32767*256/160.0+0.5); q7+15 */
    1489           0 :                     move16();
    1490           0 :                     BREAK;
    1491             :                 }
    1492           0 :                 case 320:
    1493             :                 {
    1494           0 :                     tablescale = 9;
    1495           0 :                     move16();
    1496           0 :                     ptable = 26214; /* (Word16)(32767*256/320.0+0.5); q8+15 */
    1497           0 :                     move16();
    1498           0 :                     BREAK;
    1499             :                 }
    1500           0 :                 case 512:
    1501             :                 {
    1502           0 :                     tablescale = 10;
    1503           0 :                     move16();
    1504           0 :                     ptable = 32767; /* q9+15 */
    1505           0 :                     move16();
    1506           0 :                     BREAK;
    1507             :                 }
    1508           0 :                 case 640:
    1509             :                 {
    1510           0 :                     tablescale = 10;
    1511           0 :                     move16();
    1512           0 :                     ptable = 26214; /* (Word16)(32767*512/640.0+0.5); q9+15 */
    1513           0 :                     move16();
    1514           0 :                     BREAK;
    1515             :                 }
    1516           0 :                 default: /* 960  */
    1517             :                 {
    1518           0 :                     tablescale = 10;
    1519           0 :                     move16();
    1520           0 :                     ptable = 17456; /* (Word16)(32767*512/960.0); q9+15    */
    1521           0 :                     move16();
    1522           0 :                     BREAK;
    1523             :                 }
    1524             :             }
    1525           0 :             IF( bfi == 0 ) /* overlap-and-add */
    1526             :             {
    1527           0 :                 Word16 gain_zero_start = 10000;
    1528           0 :                 move16();
    1529             : 
    1530           0 :                 IF( hPlcInfo->step_concealgain_fx > 0 )
    1531             :                 {
    1532           0 :                     gain_zero_start = BASOP_Util_Divide1616_Scale( hPlcInfo->recovery_gain, hPlcInfo->step_concealgain_fx, &s );
    1533           0 :                     gain_zero_start = shl( gain_zero_start, sub( s, 14 ) ); /* q0 */
    1534           0 :                     gain_zero_start = add( gain_zero_start, 1 );
    1535             :                 }
    1536             : 
    1537           0 :                 if ( delay > 0 )
    1538             :                 {
    1539           0 :                     L_frameTCX = sub( L_frameTCX, delay );
    1540             :                 }
    1541             : 
    1542           0 :                 s16MaxCoefNorm = sub( ffr_getSfWord16( sbuf, L_frameTCX ), 1 );
    1543           0 :                 s16MaxCoefNorm2 = ffr_getSfWord16( outx_new, L_frameTCX );
    1544           0 :                 tmp16 = vadmin( gain_zero_start, L_frameTCX );
    1545           0 :                 FOR( i = 0; i < tmp16; i++ )
    1546             :                 {
    1547           0 :                     ratio = extract_l( L_shr( L_mult( i, ptable ), tablescale ) );
    1548           0 :                     dat = shl( sbuf[i], s16MaxCoefNorm );
    1549           0 :                     temp_OUT = mult( hPlcInfo->recovery_gain, sub( 32767, ratio ) );
    1550           0 :                     outx_new[i] = round_fx_sat( L_add_sat( L_shr_sat( L_mult( temp_OUT, dat ), sub( s16MaxCoefNorm, 1 ) ), L_shr_sat( L_mult( shl( outx_new[i], s16MaxCoefNorm2 ), ratio ), s16MaxCoefNorm2 ) ) );
    1551           0 :                     move16();
    1552           0 :                     hPlcInfo->recovery_gain = sub_sat( hPlcInfo->recovery_gain, shr_r( hPlcInfo->step_concealgain_fx, 1 ) ); /* q14 */
    1553             :                 }
    1554           0 :                 FOR( i = gain_zero_start; i < L_frameTCX; i++ )
    1555             :                 {
    1556           0 :                     ratio = extract_l( L_shr( L_mult( i, ptable ), tablescale ) );
    1557           0 :                     outx_new[i] = round_fx_sat( L_shr_sat( L_mult( shl( outx_new[i], s16MaxCoefNorm2 ), ratio ), s16MaxCoefNorm2 ) );
    1558           0 :                     move16();
    1559             :                 }
    1560             : 
    1561           0 :                 if ( hPlcInfo->recovery_gain < 0 )
    1562             :                 {
    1563           0 :                     hPlcInfo->recovery_gain = 0;
    1564           0 :                     move16();
    1565             :                 }
    1566             :             }
    1567             :             ELSE
    1568             :             {
    1569             :                 /* overlap-and-add */
    1570             :                 Word16 tmp;
    1571           0 :                 s16MaxCoefNorm = sub( ffr_getSfWord16( sbuf, L_frameTCX ), 1 );
    1572           0 :                 s16MaxCoefNorm2 = ffr_getSfWord16( outx_new, L_frameTCX );
    1573           0 :                 FOR( i = 0; i < L_frameTCX; i++ )
    1574             :                 {
    1575           0 :                     dat = shl( sbuf[i], s16MaxCoefNorm );
    1576           0 :                     tmp = extract_l( L_shr( L_mult( i, ptable ), tablescale ) );
    1577           0 :                     outx_new[i] = round_fx( L_add( L_shr( L_mult( dat, sub( 32767, tmp ) ), s16MaxCoefNorm ), L_shr( L_mult( shl( outx_new[i], s16MaxCoefNorm2 ), tmp ), s16MaxCoefNorm2 ) ) );
    1578           0 :                     move16();
    1579             :                 }
    1580             :             }
    1581             :         }
    1582             :         ELSE
    1583             :         {
    1584           0 :             FOR( i = 0; i < L_frameTCX; i++ )
    1585             :             {
    1586           0 :                 outx_new[i] = sbuf[i];
    1587           0 :                 move16();
    1588             :             }
    1589             :         }
    1590             :     }
    1591           0 :     return;
    1592             : }
    1593             : 
    1594           0 : void concealment_signal_tuning_fx(
    1595             :     Decoder_State *st,
    1596             :     const Word16 bfi,
    1597             :     Word16 *outx_new_fx /*Qoutx_new_fx*/,
    1598             :     const Word16 past_core )
    1599             : {
    1600           0 :     T_PLCInfo_HANDLE hPlcInfo = st->hPlcInfo;
    1601           0 :     Word16 L_frameTCX = hPlcInfo->L_frameTCX;
    1602           0 :     Word16 voicing_fx = 0;
    1603           0 :     Word16 *OverlapBuf_fx = st->hTonalMDCTConc->secondLastPcmOut;
    1604           0 :     Word16 *outdata2_fx = st->hTonalMDCTConc->lastPcmOut;
    1605           0 :     move16();
    1606           0 :     move16();
    1607           0 :     move16();
    1608           0 :     move16();
    1609             : 
    1610           0 :     IF( bfi )
    1611             :     {
    1612           0 :         test();
    1613           0 :         IF( st->enablePlcWaveadjust && hPlcInfo->concealment_method == TCX_NONTONAL ) /* #define TCX_NONTONAL 0 */
    1614             :         {
    1615           0 :             IF( EQ_16( st->nbLostCmpt, 1 ) )
    1616             :             {
    1617           0 :                 hPlcInfo->Pitch_fx = pitch_search_fx( outdata2_fx, outx_new_fx, L_frameTCX, &voicing_fx, hPlcInfo->zp_fx, ( hPlcInfo->ener_fx ), ( hPlcInfo->ener_mean_fx ), hPlcInfo->data_reci2_fx, st->core );
    1618           0 :                 move16();
    1619             : 
    1620           0 :                 IF( hPlcInfo->Pitch_fx ) /* waveform adjustment for the first lost frame */
    1621             :                 {
    1622           0 :                     hPlcInfo->Pitch_fx = waveform_adj_fix( hPlcInfo, OverlapBuf_fx, outdata2_fx, outx_new_fx, L_frameTCX, voicing_fx, st->core );
    1623           0 :                     move16();
    1624             :                 }
    1625             :             }
    1626           0 :             ELSE IF( LT_16( st->nbLostCmpt, 5 ) ) /* waveform adjustment for the 2nd~4th lost frame */
    1627             :             {
    1628           0 :                 waveform_adj2_fix( hPlcInfo, OverlapBuf_fx, outx_new_fx, 0, st->nbLostCmpt, bfi );
    1629             :             }
    1630             :         }
    1631           0 :         hPlcInfo->T_bfi_fx = 1;
    1632           0 :         move16();
    1633             :     }
    1634             :     ELSE
    1635             :     {
    1636           0 :         test();
    1637           0 :         test();
    1638           0 :         test();
    1639           0 :         IF( st->prev_bfi &&
    1640             :             past_core != ACELP_CORE &&
    1641             :             GE_32( st->last_total_brate, 48000 ) &&
    1642             :             EQ_16( st->last_codec_mode, MODE2 ) )
    1643             :         {
    1644           0 :             IF( hPlcInfo->concealment_method == TCX_NONTONAL ) /* #define TCX_NONTONAL 0 */
    1645             :             {
    1646           0 :                 IF( LT_32( hPlcInfo->nbLostCmpt, 4 ) ) /* smoothing of the concealed signal with the good signal */
    1647             :                 {
    1648           0 :                     waveform_adj2_fix( hPlcInfo, OverlapBuf_fx, outx_new_fx, 0, add( extract_l( hPlcInfo->nbLostCmpt ), 1 ), bfi );
    1649             :                 }
    1650             :             }
    1651             :         }
    1652             :         ELSE
    1653             :         {
    1654           0 :             hPlcInfo->T_bfi_fx = 0;
    1655           0 :             move16();
    1656             :         }
    1657             :     }
    1658           0 :     return;
    1659             : }

Generated by: LCOV version 1.14