LCOV - code coverage report
Current view: top level - lib_dec - ivas_lfe_plc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ f4104b811e982d2a75d42ab9f366302fa8564693 Lines: 462 504 91.7 %
Date: 2025-11-13 02:39:34 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include "options.h"
      35             : #include "prot_fx.h"
      36             : #include "ivas_rom_com.h"
      37             : #include <math.h>
      38             : #include "wmc_auto.h"
      39             : #include "ivas_prot_fx.h"
      40             : 
      41             : /*------------------------------------------------------------------------------------------*
      42             :  * Local constants
      43             :  *------------------------------------------------------------------------------------------*/
      44             : 
      45             : #define LFE_PLC_DSF           ( 48000 / LFE_PLC_FS )
      46             : #define LFE_PLC_LPCORD        ( MAX_LP_FILTER_ORDER )
      47             : #define LFE_PLC_MAXITER       ( 10 )
      48             : #define LFE_PLC_RECLEN_48K    ( ( IVAS_LFE_NUM_COEFFS_IN_SUBGRP + 1 ) * L_FRAME48k / IVAS_LFE_NUM_COEFFS_IN_SUBGRP + LFE_PLC_FDEL )
      49             : #define LFE_PLC_RECLEN        ( ( LFE_PLC_RECLEN_48K / LFE_PLC_DSF ) )
      50             : #define LFE_PLC_MUTE_THR      ( 10 )
      51             : #define MAX_LEN_LP            960
      52             : #define POW_THR_Q50           ( 11258999 )
      53             : #define EPS_STOP_Q31          ( 21475 )
      54             : #define LFE_PLC_BURST_ATT_Q31 ( 2124429696 )
      55             : 
      56             : /*------------------------------------------------------------------------------------------*
      57             :  * Static function declarations
      58             :  *
      59             :  * Note (DLB): the local double precision functions defined below are replica of corresponding
      60             :  * float functions defined in tools.c, lpc_tools.c and syn_filt.c.
      61             :  * Double precision arithmetic is required for proper functioning of the lfe_plc.
      62             :  *------------------------------------------------------------------------------------------*/
      63             : /*---------------------------------------------------------------------*
      64             :  * autocorr_fx()
      65             :  *
      66             :  * Compute autocorrelations of input signal
      67             :  *---------------------------------------------------------------------*/
      68             : 
      69         220 : static void d_autocorr_fx(
      70             :     const Word32 *x_fx, /* i  : input signal               */
      71             :     Word16 x_q_fx,
      72             :     Word32 *r_fx, /* o  : autocorrelations vector    */
      73             :     Word16 *r_q_fx,
      74             :     const Word16 m,         /* i  : order of LP filter         */
      75             :     const Word16 len,       /* i  : window size                */
      76             :     const UWord32 *wind_fx, /* i  : window                     */
      77             :     const Word16 rev_flag,  /* i  : flag to reverse window     */
      78             :     const Word16 sym_flag,  /* i  : symmetric window flag      */
      79             :     const Word16 no_thr     /* i  : flag to avoid thresholding */
      80             : )
      81             : {
      82             :     Word16 i, j;
      83             :     Word32 t_fx[MAX_LEN_LP];
      84             :     Word64 s_fx;
      85             :     Word32 temp;
      86             :     Word16 tmp_q, exp1, exp2;
      87             : 
      88             :     /* Windowing of signal */
      89         220 :     IF( EQ_16( rev_flag, 1 ) )
      90             :     {
      91             :         /* time reversed window */
      92           0 :         FOR( i = 0; i < len; i++ )
      93             :         {
      94           0 :             t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[len - i - 1] ); // Q = x_q_fx
      95           0 :             move32();
      96             :         }
      97             :     }
      98         220 :     ELSE IF( EQ_16( sym_flag, 1 ) )
      99             :     {
     100             :         /* symmetric window of even length */
     101       26620 :         FOR( i = 0; i < len / 2; i++ )
     102             :         {
     103       26400 :             t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[i] ); // Q = x_q_fx
     104       26400 :             move32();
     105             :         }
     106             : 
     107       26620 :         FOR( ; i < len; i++ )
     108             :         {
     109       26400 :             t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[len - 1 - i] ); // Q = x_q_fx
     110       26400 :             move32();
     111             :         }
     112             :     }
     113             :     ELSE /* assymetric window */
     114             :     {
     115           0 :         FOR( i = 0; i < len; i++ )
     116             :         {
     117           0 :             t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[i] ); // Q = x_q_fx
     118           0 :             move32();
     119             :         }
     120             :     }
     121             : 
     122             :     /* Compute r[1] to r[m] */
     123        4840 :     FOR( i = 0; i <= m; i++ )
     124             :     {
     125        4620 :         exp1 = norm_l( t_fx[0] );
     126        4620 :         exp2 = norm_l( t_fx[i] );
     127        4620 :         s_fx = W_deposit32_l( Mpy_32_32( L_shl( t_fx[0], exp1 ), L_shl( t_fx[i], exp2 ) ) );
     128        4620 :         r_q_fx[i] = sub( add( add( x_q_fx, exp1 ), add( x_q_fx, exp2 ) ), 31 );
     129        4620 :         move16();
     130     1062600 :         FOR( j = 1; j < len - i; j++ )
     131             :         {
     132     1057980 :             exp1 = norm_l( t_fx[j] );
     133     1057980 :             exp2 = norm_l( t_fx[i + j] );
     134     1057980 :             temp = Mpy_32_32( L_shl( t_fx[j], exp1 ), L_shl( t_fx[i + j], exp2 ) );
     135     1057980 :             tmp_q = sub( add( add( x_q_fx, exp1 ), add( x_q_fx, exp2 ) ), 31 );
     136             : 
     137     1057980 :             IF( LT_16( tmp_q, r_q_fx[i] ) )
     138             :             {
     139        3011 :                 s_fx = W_add( W_shr( s_fx, sub( r_q_fx[i], tmp_q ) ), W_deposit32_l( temp ) );
     140        3011 :                 r_q_fx[i] = tmp_q;
     141        3011 :                 move16();
     142             :             }
     143             :             ELSE
     144             :             {
     145     1054969 :                 s_fx = W_add( s_fx, W_shr( temp, sub( tmp_q, r_q_fx[i] ) ) );
     146             :             }
     147             :         }
     148        4620 :         exp1 = W_norm( s_fx );
     149        4620 :         r_fx[i] = W_extract_h( W_shl( s_fx, exp1 ) );
     150        4620 :         move32();
     151        4620 :         r_q_fx[i] = sub( add( r_q_fx[i], exp1 ), 32 );
     152        4620 :         move16();
     153             :     }
     154             : 
     155             :     // 2097152000 = 1000 in Q21
     156         220 :     IF( LT_16( r_q_fx[0], Q21 ) )
     157             :     {
     158         220 :         IF( L_and( LT_32( r_fx[0], L_shr( 2097152000, sub( Q21, r_q_fx[0] ) ) ), EQ_16( no_thr, 0 ) ) )
     159             :         {
     160           0 :             r_fx[0] = 2097152000;
     161           0 :             move32();
     162           0 :             r_q_fx[0] = Q21;
     163           0 :             move16();
     164             :         }
     165             :     }
     166             :     ELSE
     167             :     {
     168           0 :         IF( L_and( LT_32( L_shr( r_fx[0], sub( r_q_fx[0], Q21 ) ), 2097152000 ), EQ_16( no_thr, 0 ) ) )
     169             :         {
     170           0 :             r_fx[0] = 2097152000;
     171           0 :             move32();
     172           0 :             r_q_fx[0] = Q21;
     173           0 :             move16();
     174             :         }
     175             :     }
     176             : 
     177         220 :     return;
     178             : }
     179             : 
     180             : /*---------------------------------------------------------------------*
     181             :  * lfeplc_lev_dur()
     182             :  *
     183             :  * Wiener-Levinson-Durbin algorithm to compute LP parameters from the autocorrelations
     184             :  * of input signal
     185             :  *---------------------------------------------------------------------*/
     186             : 
     187             : /*! r: stability flag */
     188          30 : static Word16 lfeplc_lev_dur_fx(
     189             :     Word32 *a_out_fx, /* o  : LP coefficients (a[0] = 1.0) */
     190             :     Word16 *a_out_q_fx,
     191             :     Word32 *r_fx, /* i  : vector of autocorrelations   */
     192             :     Word16 *r_q_fx,
     193             :     const Word16 m )
     194             : {
     195             :     Word16 i, j, l;
     196             :     Word32 buf_fx[TCXLTP_LTP_ORDER];
     197             :     Word16 rc_q_fx[TCXLTP_LTP_ORDER];
     198             :     Word32 *rc_fx; /* reflection coefficients  0,...,m-1 */
     199             :     Word32 temp1, temp2, err_fx, at_fx, s;
     200             :     Word16 temp_q1, temp_q2, s_q_fx, err_q_fx, exp1, exp2;
     201             :     Word64 s_fx;
     202             :     Word32 a_fx[LFE_PLC_LPCORD + 1];
     203             :     Word16 a_q_fx[LFE_PLC_LPCORD + 1];
     204             : 
     205          30 :     set32_fx( a_fx, 0, LFE_PLC_LPCORD + 1 );
     206          30 :     set16_fx( a_q_fx, 31, LFE_PLC_LPCORD + 1 );
     207          30 :     set32_fx( a_out_fx, 0, LFE_PLC_LPCORD + 1 );
     208          30 :     set16_fx( a_out_q_fx, 31, LFE_PLC_LPCORD + 1 );
     209             : 
     210          30 :     s_q_fx = 0;
     211          30 :     move16();
     212             : 
     213          30 :     rc_fx = &buf_fx[0];
     214          30 :     a_fx[0] = ONE_IN_Q30;
     215          30 :     move32();
     216          30 :     a_q_fx[0] = 30;
     217          30 :     move16();
     218          30 :     err_fx = r_fx[0];
     219          30 :     move32();
     220          30 :     err_q_fx = r_q_fx[0];
     221          30 :     move16();
     222          30 :     a_out_fx[0] = a_fx[0];
     223          30 :     move32();
     224          30 :     a_out_q_fx[0] = 30;
     225          30 :     move16();
     226             : 
     227          30 :     rc_fx[0] = BASOP_Util_Divide3232_Scale_newton( -r_fx[1], r_fx[0], &temp_q2 );
     228          30 :     move32();
     229          30 :     rc_q_fx[0] = add( sub( r_q_fx[1], r_q_fx[0] ), sub( 31, temp_q2 ) );
     230          30 :     move16();
     231             : 
     232          30 :     s = r_fx[1];
     233          30 :     s_q_fx = r_q_fx[1];
     234          30 :     move32();
     235          30 :     move16();
     236             : 
     237          30 :     a_fx[1] = rc_fx[0];
     238          30 :     move32();
     239          30 :     a_q_fx[1] = rc_q_fx[0];
     240          30 :     move32();
     241             : 
     242          30 :     a_out_fx[1] = a_fx[1];
     243          30 :     move32();
     244          30 :     a_out_q_fx[1] = a_q_fx[1];
     245          30 :     move32();
     246             : 
     247          30 :     i = 1;
     248          30 :     move16();
     249         600 :     WHILE( LT_16( i, m ) )
     250             :     {
     251        3270 :         FOR( j = 1; j <= i / 2; j++ )
     252             :         {
     253        2700 :             l = sub( i, j );
     254        2700 :             exp1 = sub( norm_l( rc_fx[i - 1] ), 1 );
     255        2700 :             exp2 = sub( norm_l( a_fx[l] ), 1 );
     256        2700 :             rc_fx[i - 1] = L_shl( rc_fx[i - 1], exp1 );
     257        2700 :             move32();
     258        2700 :             rc_q_fx[i - 1] = add( rc_q_fx[i - 1], exp1 );
     259        2700 :             move16();
     260        2700 :             a_fx[l] = L_shl( a_fx[l], exp2 );
     261        2700 :             move32();
     262        2700 :             a_q_fx[l] = add( a_q_fx[l], exp2 );
     263        2700 :             move16();
     264             : 
     265        2700 :             exp2 = sub( norm_l( a_fx[j] ), 1 );
     266        2700 :             a_fx[j] = L_shl( a_fx[j], exp2 );
     267        2700 :             move32();
     268        2700 :             a_q_fx[j] = add( a_q_fx[j], exp2 );
     269        2700 :             move16();
     270             : 
     271        2700 :             temp2 = Mpy_32_32( rc_fx[i - 1], a_fx[l] );
     272        2700 :             temp_q2 = sub( add( rc_q_fx[i - 1], a_q_fx[l] ), 31 );
     273        2700 :             if ( temp2 == 0 )
     274             :             {
     275           0 :                 temp_q2 = 31;
     276           0 :                 move16();
     277             :             }
     278             : 
     279        2700 :             IF( LT_16( temp_q2, a_q_fx[j] ) )
     280             :             {
     281          81 :                 at_fx = L_add( L_shr( a_fx[j], sub( a_q_fx[j], temp_q2 ) ), temp2 ); // Q(temp_q2)
     282          81 :                 temp_q1 = temp_q2;
     283          81 :                 move16();
     284             :             }
     285             :             ELSE
     286             :             {
     287        2619 :                 at_fx = L_add( a_fx[j], L_shr( temp2, sub( temp_q2, a_q_fx[j] ) ) ); // Q(a_q_fx)
     288        2619 :                 temp_q1 = a_q_fx[j];
     289        2619 :                 move16();
     290             :             }
     291             : 
     292        2700 :             temp2 = Mpy_32_32( rc_fx[i - 1], a_fx[j] );
     293        2700 :             temp_q2 = sub( add( rc_q_fx[i - 1], a_q_fx[j] ), 31 );
     294        2700 :             if ( temp2 == 0 )
     295             :             {
     296           0 :                 temp_q2 = 31;
     297           0 :                 move16();
     298             :             }
     299             : 
     300        2700 :             IF( LT_16( temp_q2, a_q_fx[l] ) )
     301             :             {
     302        1396 :                 a_fx[l] = L_add( L_shr( a_fx[l], sub( a_q_fx[l], temp_q2 ) ), temp2 );
     303        1396 :                 move32();
     304        1396 :                 a_q_fx[l] = temp_q2;
     305        1396 :                 move16();
     306             :             }
     307             :             ELSE
     308             :             {
     309        1304 :                 a_fx[l] = L_add( a_fx[l], L_shr( temp2, sub( temp_q2, a_q_fx[l] ) ) );
     310        1304 :                 move16();
     311             :             }
     312        2700 :             a_fx[j] = at_fx;
     313        2700 :             move32();
     314        2700 :             a_q_fx[j] = temp_q1;
     315        2700 :             move16();
     316             :         }
     317             : 
     318         570 :         a_fx[i] = rc_fx[i - 1];
     319         570 :         move32();
     320         570 :         a_q_fx[i] = rc_q_fx[i - 1];
     321         570 :         move16();
     322             : 
     323         570 :         exp1 = sub( norm_l( rc_fx[i - 1] ), 1 );
     324         570 :         exp2 = norm_l( s );
     325         570 :         temp1 = Mpy_32_32( L_shl( rc_fx[i - 1], exp1 ), L_shl( s, exp2 ) );
     326         570 :         temp_q1 = sub( add( add( rc_q_fx[i - 1], exp1 ), add( s_q_fx, exp2 ) ), 31 );
     327         570 :         if ( temp1 == 0 )
     328             :         {
     329           0 :             temp_q1 = 31;
     330           0 :             move16();
     331             :         }
     332             : 
     333         570 :         IF( LT_16( temp_q1, err_q_fx ) )
     334             :         {
     335          18 :             err_fx = L_add( L_shr( err_fx, sub( err_q_fx, temp_q1 ) ), temp1 );
     336          18 :             err_q_fx = temp_q1;
     337          18 :             move16();
     338             :         }
     339             :         ELSE
     340             :         {
     341         552 :             err_fx = L_add( err_fx, L_shr( temp1, sub( temp_q1, err_q_fx ) ) );
     342             :         }
     343             : 
     344         570 :         s_fx = 0;
     345         570 :         move32();
     346         570 :         s_q_fx = 0;
     347         570 :         move16();
     348         570 :         i = add( i, 1 );
     349         570 :         s_fx = 0;
     350         570 :         move64();
     351             : 
     352        6840 :         FOR( j = 0; j < i; j++ )
     353             :         {
     354        6270 :             exp1 = norm_l( r_fx[i - j] );
     355        6270 :             exp2 = norm_l( a_fx[j] );
     356        6270 :             temp1 = Mpy_32_32( L_shl( r_fx[i - j], exp1 ), L_shl( a_fx[j], exp2 ) );
     357        6270 :             temp_q1 = sub( add( add( r_q_fx[i - j], exp1 ), add( a_q_fx[j], exp2 ) ), 31 );
     358        6270 :             if ( temp1 == 0 )
     359             :             {
     360           0 :                 temp_q1 = 31;
     361           0 :                 move16();
     362             :             }
     363             : 
     364        6270 :             IF( j == 0 )
     365             :             {
     366         570 :                 s_fx = W_deposit32_l( temp1 );
     367         570 :                 s_q_fx = temp_q1;
     368         570 :                 move16();
     369             :             }
     370             :             ELSE
     371             :             {
     372        5700 :                 IF( LT_16( temp_q1, s_q_fx ) )
     373             :                 {
     374         611 :                     s_fx = W_add( W_shr( s_fx, sub( s_q_fx, temp_q1 ) ), W_deposit32_l( temp1 ) );
     375         611 :                     s_q_fx = temp_q1;
     376         611 :                     move16();
     377             :                 }
     378             :                 ELSE
     379             :                 {
     380        5089 :                     s_fx = W_add( s_fx, W_shr( W_deposit32_l( temp1 ), sub( temp_q1, s_q_fx ) ) );
     381             :                 }
     382             :             }
     383             :         }
     384             : 
     385         570 :         exp1 = W_norm( s_fx );
     386         570 :         s = W_extract_h( W_shl( s_fx, exp1 ) );
     387         570 :         s_q_fx = sub( add( s_q_fx, exp1 ), 32 );
     388             : 
     389         570 :         rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_newton( L_negate( s ), err_fx, &temp_q2 ), 1 );
     390         570 :         move32();
     391         570 :         rc_q_fx[i - 1] = sub( add( sub( s_q_fx, err_q_fx ), sub( 31, temp_q2 ) ), 1 );
     392         570 :         move16();
     393             : 
     394         570 :         IF( LT_16( rc_q_fx[i - 1], 31 ) )
     395             :         {
     396             : 
     397         118 :             IF( GT_32( L_abs( rc_fx[i - 1] ), L_shr( 2146302532, sub( 31, rc_q_fx[i - 1] ) ) ) ) // 2146302532 = 0.99945f in Q31
     398             :             {
     399           0 :                 return 1;
     400             :             }
     401             :             ELSE
     402             :             {
     403        2596 :                 FOR( j = 0; j <= m; j++ )
     404             :                 {
     405        2478 :                     a_out_fx[j] = a_fx[j];
     406        2478 :                     a_out_q_fx[j] = a_q_fx[j];
     407        2478 :                     move32();
     408        2478 :                     move32();
     409             :                 }
     410             :             }
     411             :         }
     412             :         ELSE
     413             :         {
     414         452 :             IF( GT_32( L_abs( L_shr( rc_fx[i - 1], sub( rc_q_fx[i - 1], 31 ) ) ), 2146302532 ) ) // 2146302532 = 0.00045f in Q31
     415             :             {
     416           0 :                 return 1;
     417             :             }
     418             :             ELSE
     419             :             {
     420        9944 :                 FOR( j = 0; j <= m; j++ )
     421             :                 {
     422        9492 :                     a_out_fx[j] = a_fx[j];
     423        9492 :                     a_out_q_fx[j] = a_q_fx[j];
     424        9492 :                     move32();
     425        9492 :                     move32();
     426             :                 }
     427             :             }
     428             :         }
     429             :     }
     430          30 :     return 0;
     431             : }
     432             : /*-------------------------------------------------------------------*
     433             :  * a2rc_fx()
     434             :  *
     435             :  * Convert from LPC to reflection coeff
     436             :  *-------------------------------------------------------------------*/
     437             : 
     438         378 : static Word16 d_a2rc_fx(
     439             :     const Word32 *a_fx, /* i  : LPC coefficients            */
     440             :     Word16 *a_q_fx,
     441             :     Word32 *refl_fx,      /* o  : Reflection co-efficients    */
     442             :     const Word16 lpcorder /* i  : LPC order                   */
     443             : )
     444             : {
     445             :     Word16 m, j, n;
     446             :     Word32 ff_fx[LFE_PLC_LPCORD];
     447             :     Word32 km_fx, denom_fx, temp1, temp2, temp;
     448             :     Word16 ff_q_fx[LFE_PLC_LPCORD], temp_q1, temp_q2, denom_q_fx, km_q_fx, temp_q;
     449             :     Word16 exp1, exp2;
     450             : 
     451        7938 :     FOR( m = 0; m < lpcorder; m++ )
     452             :     {
     453        7560 :         ff_fx[m] = L_negate( a_fx[m] );
     454        7560 :         move32();
     455        7560 :         ff_q_fx[m] = a_q_fx[m];
     456        7560 :         move32();
     457             :     }
     458             : 
     459             :     /* Initialization */
     460        7399 :     FOR( m = lpcorder - 1; m >= 0; m-- )
     461             :     {
     462        7208 :         km_fx = ff_fx[m];
     463        7208 :         move32();
     464        7208 :         km_q_fx = ff_q_fx[m];
     465        7208 :         move16();
     466        7208 :         IF( GE_64( W_shr( L_abs( km_fx ), sub( ff_q_fx[m], Q30 ) ), W_deposit32_l( ONE_IN_Q30 ) ) )
     467             :         {
     468        3927 :             FOR( j = 0; j < lpcorder; j++ )
     469             :             {
     470        3740 :                 refl_fx[j] = 0;
     471        3740 :                 move32();
     472             :             }
     473         187 :             return 0;
     474             :         }
     475             : 
     476        7021 :         refl_fx[m] = L_negate( km_fx ); // Q(km_q_Fx)
     477        7021 :         move32();
     478             : 
     479        7021 :         exp1 = norm_l( km_fx );
     480        7021 :         temp1 = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( km_fx, exp1 ) );
     481        7021 :         temp_q1 = sub( add( add( km_q_fx, exp1 ), add( km_q_fx, exp1 ) ), 31 );
     482        7021 :         temp1 = L_sub( ONE_IN_Q30, L_shr( temp1, sub( temp_q1, 30 ) ) );
     483        7021 :         denom_fx = L_deposit_l( BASOP_Util_Divide3232_Scale( ONE_IN_Q30, temp1, &temp_q1 ) );
     484        7021 :         denom_q_fx = sub( 15, temp_q1 );
     485             : 
     486       40548 :         FOR( j = 0; j < m / 2; j++ )
     487             :         {
     488       33527 :             n = sub( sub( m, 1 ), j );
     489             : 
     490       33527 :             exp1 = norm_l( denom_fx );
     491       33527 :             exp2 = sub( norm_l( ff_fx[j] ), 1 );
     492       33527 :             temp1 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[j], exp2 ) );
     493       33527 :             temp_q1 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[j], exp2 ) ), 31 );
     494             : 
     495       33527 :             exp2 = sub( norm_l( ff_fx[n] ), 1 );
     496       33527 :             temp2 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[n], exp2 ) );
     497       33527 :             temp_q2 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[n], exp2 ) ), 31 );
     498             : 
     499       33527 :             exp1 = norm_l( km_fx );
     500       33527 :             exp2 = sub( norm_l( temp2 ), 1 );
     501       33527 :             temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp2, exp2 ) );
     502       33527 :             temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q2, exp2 ) ), 31 );
     503       33527 :             if ( temp == 0 )
     504             :             {
     505        3402 :                 temp_q = 31;
     506        3402 :                 move16();
     507             :             }
     508       33527 :             IF( LT_16( temp_q, temp_q1 ) )
     509             :             {
     510         727 :                 ff_fx[j] = L_add( L_shr( temp1, sub( temp_q1, temp_q ) ), temp );
     511         727 :                 move32();
     512         727 :                 ff_q_fx[j] = temp_q;
     513         727 :                 move16();
     514             :             }
     515             :             ELSE
     516             :             {
     517       32800 :                 ff_fx[j] = L_add( temp1, L_shr( temp, sub( temp_q, temp_q1 ) ) );
     518       32800 :                 move32();
     519       32800 :                 ff_q_fx[j] = temp_q1;
     520       32800 :                 move16();
     521             :             }
     522             : 
     523       33527 :             exp1 = norm_l( km_fx );
     524       33527 :             exp2 = sub( norm_l( temp1 ), 1 );
     525       33527 :             temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp1, exp2 ) );
     526       33527 :             temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q1, exp2 ) ), 31 );
     527       33527 :             if ( temp == 0 )
     528             :             {
     529        3402 :                 temp_q = 31;
     530        3402 :                 move16();
     531             :             }
     532       33527 :             IF( LT_16( temp_q, temp_q2 ) )
     533             :             {
     534        8124 :                 ff_fx[n] = L_add( L_shr( temp2, sub( temp_q2, temp_q ) ), temp );
     535        8124 :                 move32();
     536        8124 :                 ff_q_fx[n] = temp_q;
     537        8124 :                 move16();
     538             :             }
     539             :             ELSE
     540             :             {
     541       25403 :                 ff_fx[n] = L_add( temp2, L_shr( temp, sub( temp_q, temp_q2 ) ) );
     542       25403 :                 move32();
     543       25403 :                 ff_q_fx[n] = temp_q2;
     544       25403 :                 move16();
     545             :             }
     546             :         }
     547             : 
     548        7021 :         IF( s_and( m, 1 ) )
     549             :         {
     550        3527 :             exp1 = norm_l( denom_fx );
     551        3527 :             exp2 = sub( norm_l( ff_fx[j] ), 1 );
     552        3527 :             temp1 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[j], exp2 ) );
     553        3527 :             temp_q1 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[j], exp2 ) ), 31 );
     554             : 
     555        3527 :             exp1 = norm_l( km_fx );
     556        3527 :             exp2 = sub( norm_l( temp1 ), 1 );
     557        3527 :             temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp1, exp2 ) );
     558        3527 :             temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q1, exp2 ) ), 31 );
     559        3527 :             if ( temp == 0 )
     560             :             {
     561         378 :                 temp_q = 31;
     562         378 :                 move16();
     563             :             }
     564        3527 :             IF( LT_16( temp_q, temp_q1 ) )
     565             :             {
     566         189 :                 ff_fx[j] = L_add( L_shr( temp1, sub( temp_q1, temp_q ) ), temp );
     567         189 :                 move32();
     568         189 :                 ff_q_fx[j] = temp_q;
     569         189 :                 move16();
     570             :             }
     571             :             ELSE
     572             :             {
     573        3338 :                 ff_fx[j] = L_add( temp1, L_shr( temp, sub( temp_q, temp_q1 ) ) );
     574        3338 :                 move32();
     575        3338 :                 ff_q_fx[j] = temp_q1;
     576        3338 :                 move16();
     577             :             }
     578             :         }
     579             :     }
     580             : 
     581         191 :     return 1;
     582             : }
     583             : 
     584          30 : static void d_syn_filt_fx(
     585             :     const Word32 *a_fx, /* i  : LP filter coefficients                     */
     586             :     Word16 *a_q_fx,
     587             :     const Word16 m,     /* i  : order of LP filter                         */
     588             :     const Word32 *x_fx, /* i  : input signal                               */
     589             :     Word32 *y_fx,       /* o  : output signal                              */
     590             :     Word16 *y_q_fx,
     591             :     const Word16 l,       /* i  : size of filtering                          */
     592             :     const Word32 *mem_fx, /* i  : initial filter states                      */
     593             :     Word16 mem_q_fx )
     594             : {
     595             :     Word16 i, j;
     596             :     Word32 buf_fx[LFE_PLC_LPCORD + LFE_PLC_RECLEN]; /* temporary synthesis buffer */
     597             :     Word32 *yy_fx, temp;
     598             :     Word64 s_fx;
     599             :     Word16 tmp;
     600             :     Word16 yy_q_fx[LFE_PLC_LPCORD + LFE_PLC_RECLEN], exp1, exp2, s_q_fx, temp_q;
     601             : 
     602          30 :     yy_fx = &buf_fx[0];
     603             : 
     604             :     /*------------------------------------------------------------------*
     605             :      * copy initial filter states into synthesis buffer and do synthesis
     606             :      *------------------------------------------------------------------*/
     607         630 :     FOR( i = 0; i < m; i++ )
     608             :     {
     609         600 :         *yy_fx++ = mem_fx[i];
     610         600 :         move32();
     611         600 :         yy_q_fx[i] = mem_q_fx;
     612         600 :         move16();
     613             :     }
     614             : 
     615             :     /*-----------------------------------------------------------------------*
     616             :      * Do the filtering
     617             :      *-----------------------------------------------------------------------*/
     618             : 
     619        1770 :     FOR( i = 0; i < l; i++ )
     620             :     {
     621        1740 :         s_fx = x_fx[i];
     622        1740 :         move64();
     623        1740 :         s_q_fx = Q31;
     624        1740 :         move16();
     625       36540 :         FOR( j = 1; j <= m; j++ )
     626             :         {
     627       34800 :             exp1 = sub( norm_l( a_fx[j] ), 1 );
     628       34800 :             exp2 = sub( norm_l( yy_fx[i - j] ), 1 );
     629       34800 :             IF( GT_16( j, i ) )
     630             :             {
     631        6300 :                 temp_q = mem_q_fx;
     632        6300 :                 move16();
     633             :             }
     634             :             ELSE
     635             :             {
     636       28500 :                 temp_q = yy_q_fx[i - j];
     637       28500 :                 move16();
     638             :             }
     639       34800 :             temp = Mpy_32_32( L_shl( a_fx[j], exp1 ), L_shl( yy_fx[i - j], exp2 ) );
     640       34800 :             temp_q = sub( add( add( a_q_fx[j], exp1 ), add( temp_q, exp2 ) ), 31 );
     641             : 
     642       34800 :             IF( LT_16( s_q_fx, temp_q ) )
     643             :             {
     644       30747 :                 s_fx = W_sub( s_fx, L_shr( temp, sub( temp_q, s_q_fx ) ) );
     645             :             }
     646             :             ELSE
     647             :             {
     648        4053 :                 s_fx = W_sub( W_shr( s_fx, s_min( 63, sub( s_q_fx, temp_q ) ) ), temp );
     649        4053 :                 s_q_fx = temp_q;
     650        4053 :                 move16();
     651             :             }
     652             :         }
     653        1740 :         tmp = W_norm( s_fx );
     654        1740 :         s_fx = W_shl( s_fx, tmp );
     655        1740 :         s_q_fx = add( s_q_fx, tmp );
     656        1740 :         yy_fx[i] = W_extract_h( s_fx );
     657        1740 :         move32();
     658        1740 :         yy_q_fx[i] = sub( s_q_fx, 32 );
     659        1740 :         move16();
     660        1740 :         y_fx[i] = W_extract_l( W_shr( s_fx, sub( s_q_fx, Q5 ) ) );
     661        1740 :         move32();
     662             :     }
     663          30 :     *y_q_fx = Q5;
     664          30 :     move16();
     665             : 
     666          30 :     return;
     667             : }
     668             : 
     669             : /*-----------------------------------------------------------------------------------------*
     670             :  * Function check_stab_fx()
     671             :  *
     672             :  * LPC filter stability check applying given sharpening value delta
     673             :  *-----------------------------------------------------------------------------------------*/
     674             : 
     675         378 : static Word16 check_stab_fx(
     676             :     Word32 *a_fx,
     677             :     Word16 *a_q_fx,
     678             :     Word32 delta_fx,
     679             :     Word16 delta_q_fx )
     680             : {
     681             :     Word16 i;
     682             :     Word16 stable;
     683             : 
     684             :     Word32 amod_fx[LFE_PLC_LPCORD], refl_fx[LFE_PLC_LPCORD];
     685             :     Word16 fac_q_fx, fac1_q_fx, amod_q_fx[LFE_PLC_LPCORD];
     686             :     Word16 exp1, exp2;
     687             :     Word32 fac_fx, fac1_fx;
     688             : 
     689         378 :     exp1 = norm_l( delta_fx );
     690         378 :     delta_fx = L_shl( delta_fx, exp1 );
     691         378 :     delta_q_fx = add( delta_q_fx, exp1 );
     692             : 
     693         378 :     IF( LT_16( delta_q_fx, 29 ) )
     694             :     {
     695           0 :         fac_fx = L_add( L_shr( ONE_IN_Q29, sub( 29, delta_q_fx ) ), delta_fx );
     696           0 :         fac_q_fx = delta_q_fx;
     697           0 :         move16();
     698             :     }
     699             :     ELSE
     700             :     {
     701         378 :         fac_fx = L_add( ONE_IN_Q29, L_shr( delta_fx, sub( delta_q_fx, 29 ) ) );
     702         378 :         fac_q_fx = Q29;
     703         378 :         move16();
     704             :     }
     705         378 :     fac1_fx = fac_fx;
     706         378 :     move32();
     707         378 :     fac1_q_fx = fac_q_fx;
     708         378 :     move16();
     709             : 
     710        7938 :     FOR( i = 0; i < LFE_PLC_LPCORD; i++ )
     711             :     {
     712        7560 :         exp1 = norm_l( a_fx[i] );
     713        7560 :         exp2 = norm_l( fac_fx );
     714        7560 :         amod_fx[i] = Mpy_32_32( L_shl( a_fx[i], exp1 ), L_shl( fac_fx, exp2 ) );
     715        7560 :         move32();
     716        7560 :         amod_q_fx[i] = sub( add( add( a_q_fx[i], exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     717        7560 :         move16();
     718        7560 :         if ( amod_fx[i] == 0 )
     719             :         {
     720         378 :             amod_q_fx[i] = 31;
     721         378 :             move16();
     722             :         }
     723        7560 :         exp1 = norm_l( fac_fx );
     724        7560 :         exp2 = norm_l( fac1_fx );
     725        7560 :         fac_fx = Mpy_32_32( L_shl( fac_fx, exp1 ), L_shl( fac1_fx, exp2 ) );
     726        7560 :         fac_q_fx = sub( add( add( fac_q_fx, exp1 ), add( fac1_q_fx, exp2 ) ), 31 );
     727        7560 :         if ( fac_fx == 0 )
     728             :         {
     729           0 :             fac_q_fx = 0;
     730           0 :             move16();
     731             :         }
     732             :     }
     733         378 :     stable = d_a2rc_fx( amod_fx, amod_q_fx, refl_fx, LFE_PLC_LPCORD );
     734             : 
     735         378 :     return stable;
     736             : }
     737             : 
     738             : /*-----------------------------------------------------------------------------------------*
     739             :  * Function find_max_delta_fx()
     740             :  *
     741             :  * Find maximum LPC filter sharpening by iteration to get a filter that is almost instable
     742             :  *-----------------------------------------------------------------------------------------*/
     743             : 
     744          30 : static Word32 find_max_delta_fx(
     745             :     Word32 *a_fx,
     746             :     Word16 *a_q_fx,
     747             :     Word16 *delta_q_fx )
     748             : {
     749             :     Word16 stable;
     750             :     Word16 eps_q_fx, fac_q_fx, exp1, exp2;
     751             :     Word32 delta_fx, fac_fx, eps_fx, temp;
     752             : 
     753          30 :     delta_fx = 0;
     754          30 :     move32();
     755          30 :     eps_fx = 21474836; // 0.01 in Q31
     756          30 :     move32();
     757          30 :     fac_fx = 1073741824; // 2 in Q29
     758          30 :     move32();
     759          30 :     eps_q_fx = Q31;
     760          30 :     move16();
     761          30 :     fac_q_fx = Q29;
     762          30 :     move16();
     763             : 
     764          30 :     stable = FALSE;
     765          30 :     move16();
     766             : 
     767          56 :     WHILE( check_stab_fx( a_fx, a_q_fx, eps_fx, eps_q_fx ) )
     768             :     {
     769          26 :         exp1 = norm_l( eps_fx );
     770          26 :         exp2 = norm_l( fac_fx );
     771          26 :         eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
     772          26 :         eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     773          26 :         stable = TRUE;
     774          26 :         move16();
     775             :     }
     776          30 :     fac_fx = 1073741824; // 0.5 in Q31
     777          30 :     move32();
     778          30 :     fac_q_fx = Q31;
     779          30 :     move16();
     780             : 
     781          30 :     IF( stable )
     782             :     {
     783          15 :         exp1 = norm_l( eps_fx );
     784          15 :         exp2 = norm_l( fac_fx );
     785          15 :         eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
     786          15 :         eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     787             :     }
     788             : 
     789          55 :     WHILE( !stable )
     790             :     {
     791          25 :         exp1 = norm_l( eps_fx );
     792          25 :         exp2 = norm_l( fac_fx );
     793          25 :         eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
     794          25 :         eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     795             : 
     796          25 :         stable = check_stab_fx( a_fx, a_q_fx, eps_fx, eps_q_fx );
     797             :     }
     798             : 
     799             :     /* must be stable with current eps */
     800          30 :     *delta_q_fx = sub( norm_l( eps_fx ), 1 );
     801          30 :     delta_fx = L_shl( eps_fx, *delta_q_fx );
     802          30 :     *delta_q_fx = add( eps_q_fx, *delta_q_fx );
     803          30 :     move16();
     804          30 :     move16();
     805             : 
     806          30 :     exp1 = norm_l( eps_fx );
     807          30 :     exp2 = norm_l( fac_fx );
     808          30 :     eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
     809          30 :     eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     810             : 
     811             :     WHILE( 1 )
     812             :     {
     813         297 :         IF( LT_16( *delta_q_fx, eps_q_fx ) )
     814             :         {
     815         297 :             delta_fx = L_add( delta_fx, L_shr( eps_fx, sub( eps_q_fx, *delta_q_fx ) ) );
     816             :         }
     817             :         ELSE
     818             :         {
     819           0 :             delta_fx = L_add( L_shr( delta_fx, sub( *delta_q_fx, eps_q_fx ) ), eps_fx );
     820           0 :             *delta_q_fx = eps_q_fx;
     821           0 :             move16();
     822             :         }
     823         297 :         stable = check_stab_fx( a_fx, a_q_fx, delta_fx, *delta_q_fx );
     824             : 
     825         297 :         IF( !stable )
     826             :         {
     827         147 :             temp = L_abs( eps_fx );
     828         147 :             IF( GT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) )
     829             :             {
     830         136 :                 exp1 = norm_l( -temp );
     831         136 :                 exp2 = norm_l( fac_fx );
     832         136 :                 eps_fx = Mpy_32_32( L_shl( -temp, exp1 ), L_shl( fac_fx, exp2 ) );
     833         136 :                 eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     834             :             }
     835             :             ELSE
     836             :             {
     837          11 :                 eps_fx = L_negate( L_abs( eps_fx ) );
     838             :             }
     839             :         }
     840             :         ELSE
     841             :         {
     842         150 :             temp = L_abs( eps_fx );
     843         150 :             if ( LT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) )
     844             :             {
     845          30 :                 BREAK;
     846             :             }
     847             : 
     848         120 :             exp1 = norm_l( temp );
     849         120 :             exp1 = norm_l( fac_fx );
     850         120 :             eps_fx = Mpy_32_32( L_shl( temp, exp1 ), L_shl( fac_fx, exp2 ) );
     851         120 :             eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     852             :         }
     853             :     }
     854             : 
     855          30 :     return delta_fx;
     856             : }
     857             : 
     858             : /*-----------------------------------------------------------------------------------------*
     859             :  * Function recover_samples_fx()
     860             :  *
     861             :  * recover lost samples by extrapolation of signal buffer
     862             :  *-----------------------------------------------------------------------------------------*/
     863             : 
     864         220 : static void recover_samples_fx(
     865             :     const Word16 bfi_count,
     866             :     const Word32 *outbuf_fx,
     867             :     Word16 outbuf_q_fx,
     868             :     Word32 *rec_frame_fx,
     869             :     Word16 *rec_frame_q_fx )
     870             : {
     871             :     Word16 i;
     872             :     Word32 d_outbuf_fx[LFE_PLC_BUFLEN], d_a_fx[LFE_PLC_LPCORD + 1];
     873             :     Word16 d_r_q_fx[LFE_PLC_LPCORD + 1], d_a_q_fx[LFE_PLC_LPCORD + 1];
     874             :     Word32 d_r_fx[LFE_PLC_LPCORD + 1], zeroes_fx[LFE_PLC_RECLEN];
     875             :     Word32 delta_fx, fac_fx, att_fx, temp;
     876             :     Word16 delta_q_fx, fac_q_fx, temp_q, exp1, exp2;
     877             : 
     878         220 :     Copy32( outbuf_fx, d_outbuf_fx, LFE_PLC_BUFLEN );
     879             : 
     880         220 :     d_autocorr_fx( d_outbuf_fx, outbuf_q_fx, d_r_fx, d_r_q_fx, LFE_PLC_LPCORD, LFE_PLC_BUFLEN, d_hamm_lfe_plc_fx, 0, 1, 1 );
     881             : 
     882         220 :     IF( LT_64( W_shr( d_r_fx[0], sub( d_r_q_fx[0], Q19 ) ), W_deposit32_l( Mpy_32_32( POW_THR_Q50, LFE_PLC_BUFLEN ) ) ) )
     883             :     {
     884         190 :         set_zero_fx( rec_frame_fx, LFE_PLC_RECLEN );
     885         190 :         return;
     886             :     }
     887             : 
     888          30 :     lfeplc_lev_dur_fx( d_a_fx, d_a_q_fx, d_r_fx, d_r_q_fx, LFE_PLC_LPCORD );
     889             : 
     890          30 :     delta_fx = find_max_delta_fx( d_a_fx + 1, d_a_q_fx + 1, &delta_q_fx );
     891             : 
     892          30 :     IF( LT_16( delta_q_fx, Q29 ) )
     893             :     {
     894           0 :         fac_fx = L_add( L_shr( ONE_IN_Q29, sub( Q29, delta_q_fx ) ), delta_fx );
     895           0 :         fac_q_fx = delta_q_fx;
     896           0 :         move16();
     897             :     }
     898             :     ELSE
     899             :     {
     900          30 :         fac_fx = L_add( ONE_IN_Q29, L_shr( delta_fx, sub( delta_q_fx, Q29 ) ) );
     901          30 :         fac_q_fx = Q29;
     902          30 :         move16();
     903             :     }
     904          30 :     att_fx = ONE_IN_Q31;
     905          30 :     move32();
     906             : 
     907          30 :     IF( GE_16( bfi_count, LFE_PLC_MUTE_THR ) )
     908             :     {
     909           0 :         att_fx = LFE_PLC_BURST_ATT_Q31;
     910           0 :         move32();
     911           0 :         fac_fx = Mpy_32_32( fac_fx, att_fx );
     912             :     }
     913             : 
     914         630 :     FOR( i = 1; i <= LFE_PLC_LPCORD; i++ )
     915             :     {
     916         600 :         d_a_fx[i] = Mpy_32_32( d_a_fx[i], fac_fx );
     917         600 :         move32();
     918         600 :         d_a_q_fx[i] = sub( add( d_a_q_fx[i], fac_q_fx ), 31 );
     919         600 :         move16();
     920         600 :         if ( d_a_fx[i] == 0 )
     921             :         {
     922          30 :             d_a_q_fx[i] = 31;
     923          30 :             move16();
     924             :         }
     925         600 :         IF( LT_16( delta_q_fx, Q30 ) )
     926             :         {
     927           0 :             temp = L_add( L_shr( ONE_IN_Q30, sub( Q30, delta_q_fx ) ), delta_fx );
     928           0 :             temp_q = delta_q_fx;
     929           0 :             move16();
     930             :         }
     931             :         ELSE
     932             :         {
     933         600 :             temp = L_add( ONE_IN_Q30, L_shr( delta_fx, sub( delta_q_fx, Q30 ) ) );
     934         600 :             temp_q = Q30;
     935         600 :             move16();
     936             :         }
     937         600 :         exp2 = norm_l( temp );
     938         600 :         temp = Mpy_32_32( att_fx, L_shl( temp, exp2 ) );
     939         600 :         temp_q = add( temp_q, exp2 );
     940             : 
     941         600 :         exp1 = norm_l( fac_fx );
     942         600 :         exp2 = norm_l( temp );
     943         600 :         fac_fx = Mpy_32_32( L_shl( fac_fx, exp1 ), L_shl( temp, exp2 ) );
     944         600 :         fac_q_fx = sub( add( add( fac_q_fx, exp1 ), add( temp_q, exp2 ) ), 31 );
     945             :     }
     946             : 
     947          30 :     set_zero_fx( zeroes_fx, LFE_PLC_RECLEN );
     948             : 
     949          30 :     d_syn_filt_fx( d_a_fx, d_a_q_fx, LFE_PLC_LPCORD, zeroes_fx, rec_frame_fx, rec_frame_q_fx, LFE_PLC_RECLEN, outbuf_fx + LFE_PLC_BUFLEN - LFE_PLC_LPCORD, outbuf_q_fx );
     950             : 
     951          30 :     return;
     952             : }
     953             : /*-----------------------------------------------------------------------------------------*
     954             :  * Function ivas_lfe_tdplc_fx()
     955             :  *
     956             :  * MDCT interface recover lost samples by extrapolation of signal buffer
     957             :  *-----------------------------------------------------------------------------------------*/
     958             : 
     959         220 : void ivas_lfe_tdplc_fx(
     960             :     LFE_DEC_HANDLE hLFE,      /* i/o: LFE decoder handle           */
     961             :     const Word32 *prevsynth,  /* i  : previous frame synthesis     */
     962             :     Word32 *ytda,             /* o  : output time-domain buffer    */
     963             :     const Word16 output_frame /* i  : output frame length          */
     964             : )
     965             : {
     966             :     Word32 rec_frame_us_fx[LFE_PLC_RECLEN_48K], input_tda_fx[L_FRAME48k];
     967             :     Word32 rec_frame_fx[LFE_PLC_RECLEN], prevsynth_fx[LFE_PLC_BUFLEN];
     968             :     Word16 rec_frame_us_16_fx[LFE_PLC_RECLEN_48K], mem_fx[2 * LFE_PLC_FDEL / LFE_PLC_DSF], rec_frame_16_fx[LFE_PLC_RECLEN];
     969             :     Word16 prevsynth_16_fx[LFE_PLC_BUFLEN];
     970             :     const Word32 *pWindow_coeffs_fx;
     971             :     Word32 output_Fs;
     972             :     Word16 i, fade_len, full_len, dct_len, zero_pad_len, plc_fdel, rec_frame_len;
     973             :     Word16 prevsynth_q_fx, rec_frame_q, temp_q, idx, exp;
     974             : 
     975         220 :     output_Fs = L_mult0( output_frame, FRAMES_PER_SEC );
     976         220 :     fade_len = hLFE->pWindow_state->fade_len;
     977         220 :     move16();
     978         220 :     full_len = hLFE->pWindow_state->full_len;
     979         220 :     move16();
     980         220 :     dct_len = hLFE->pWindow_state->dct_len;
     981         220 :     move16();
     982         220 :     zero_pad_len = hLFE->pWindow_state->zero_pad_len;
     983         220 :     move16();
     984         220 :     pWindow_coeffs_fx = hLFE->pWindow_state->pWindow_coeffs_fx;
     985             : 
     986             :     /* plc_fdel = (int16_t) ( LFE_PLC_FDEL * output_Fs / 48000 ); */
     987         220 :     plc_fdel = extract_l( Mpy_32_32( output_Fs, 13421773 /* ( LFE_PLC_FDEL / 48000 ) in Q31 */ ) );
     988             :     /* rec_frame_len = (int16_t) ( LFE_PLC_RECLEN_48K * output_Fs / 48000 ); */
     989         220 :     rec_frame_len = extract_l( Mpy_32_32_r( output_Fs, 77846282 /* LFE_PLC_RECLEN_48K / 48000 in Q31 */ ) );
     990             : 
     991         220 :     Copy32( prevsynth, prevsynth_fx, LFE_PLC_BUFLEN );
     992         220 :     exp = L_norm_arr( prevsynth_fx, LFE_PLC_BUFLEN );
     993         220 :     scale_sig32( prevsynth_fx, LFE_PLC_BUFLEN, exp );
     994         220 :     prevsynth_q_fx = add( Q9, exp );
     995         220 :     move16();
     996             : 
     997         220 :     recover_samples_fx( hLFE->bfi_count, prevsynth_fx, prevsynth_q_fx, rec_frame_fx, &rec_frame_q );
     998             : 
     999         220 :     set16_fx( mem_fx, 0, 2 * LFE_PLC_FDEL / LFE_PLC_DSF );
    1000             : 
    1001         220 :     Copy_Scale_sig_32_16( prevsynth_fx, prevsynth_16_fx, LFE_PLC_BUFLEN, -prevsynth_q_fx ); // Q0
    1002         220 :     Copy_Scale_sig_32_16( rec_frame_fx, rec_frame_16_fx, LFE_PLC_RECLEN, -Q5 );             // Q0
    1003             : 
    1004             :     Word16 Q_new_inp, mem_decim_size, size_modified;
    1005         220 :     size_modified = modify_Fs_ivas_fx( prevsynth_16_fx + LFE_PLC_BUFLEN - LFE_PLC_FDEL / LFE_PLC_DSF, LFE_PLC_FDEL / LFE_PLC_DSF, LFE_PLC_FS, rec_frame_us_16_fx, 48000, mem_fx, 0, &Q_new_inp, &mem_decim_size );
    1006         220 :     Scale_sig( rec_frame_us_16_fx, size_modified, negate( Q_new_inp ) ); /* scaling back to Q0 */
    1007             : 
    1008         220 :     size_modified = modify_Fs_ivas_fx( rec_frame_16_fx, LFE_PLC_RECLEN, LFE_PLC_FS, rec_frame_us_16_fx, 48000, mem_fx, 0, &Q_new_inp, &mem_decim_size );
    1009         220 :     Scale_sig( rec_frame_us_16_fx, size_modified, negate( Q_new_inp ) ); /* scaling back to Q0 */
    1010             : 
    1011             :     /*samples are generated with 48k sampling rate
    1012             :     and then converted to required sampling rate by simple decimation
    1013             :     as signal is already bandlimited*/
    1014             : 
    1015             :     /*decimation to correct sampling rate*/
    1016         220 :     IF( NE_32( output_Fs, 48000 ) )
    1017             :     {
    1018        4644 :         FOR( i = 0; i < rec_frame_len; i++ )
    1019             :         {
    1020        4640 :             idx = BASOP_Util_Divide3232_Scale( Mpy_32_32( L_shl( i, 16 ), L_shl( 44100, 15 ) ), output_Fs, &temp_q );
    1021        4640 :             idx = shr( idx, add( sub( 15, temp_q ), 1 ) );
    1022        4640 :             rec_frame_us_16_fx[i] = rec_frame_us_16_fx[idx];
    1023        4640 :             move16();
    1024             :         }
    1025             :     }
    1026             : 
    1027         220 :     Copy_Scale_sig_16_32_DEPREC( rec_frame_us_16_fx, rec_frame_us_fx, LFE_PLC_RECLEN_48K, 10 ); // Q10 = rec_frame_q + 5
    1028             : 
    1029         660 :     FOR( i = 0; i < 2; i++ )
    1030             :     {
    1031         440 :         ivas_dct_windowing_fx( fade_len, full_len, dct_len, zero_pad_len, pWindow_coeffs_fx, output_frame, input_tda_fx, rec_frame_us_fx + plc_fdel, rec_frame_us_fx + add( add( plc_fdel, fade_len ), i_mult( i, dct_len ) ) );
    1032         440 :         ivas_tda_fx( input_tda_fx, ytda + imult1616( i, dct_len ), dct_len );
    1033             :     }
    1034             : 
    1035         220 :     return;
    1036             : }

Generated by: LCOV version 1.14