LCOV - code coverage report
Current view: top level - lib_dec - ivas_lfe_plc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 57b3a0619c6acf2354f43c9b971cc11e014725cb Lines: 462 504 91.7 %
Date: 2025-10-22 22:22:21 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         217 : 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         217 :     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         217 :     ELSE IF( EQ_16( sym_flag, 1 ) )
      99             :     {
     100             :         /* symmetric window of even length */
     101       26257 :         FOR( i = 0; i < len / 2; i++ )
     102             :         {
     103       26040 :             t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[i] ); // Q = x_q_fx
     104       26040 :             move32();
     105             :         }
     106             : 
     107       26257 :         FOR( ; i < len; i++ )
     108             :         {
     109       26040 :             t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[len - 1 - i] ); // Q = x_q_fx
     110       26040 :             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        4774 :     FOR( i = 0; i <= m; i++ )
     124             :     {
     125        4557 :         exp1 = norm_l( t_fx[0] );
     126        4557 :         exp2 = norm_l( t_fx[i] );
     127        4557 :         s_fx = W_deposit32_l( Mpy_32_32( L_shl( t_fx[0], exp1 ), L_shl( t_fx[i], exp2 ) ) );
     128        4557 :         r_q_fx[i] = sub( add( add( x_q_fx, exp1 ), add( x_q_fx, exp2 ) ), 31 );
     129        4557 :         move16();
     130     1048110 :         FOR( j = 1; j < len - i; j++ )
     131             :         {
     132     1043553 :             exp1 = norm_l( t_fx[j] );
     133     1043553 :             exp2 = norm_l( t_fx[i + j] );
     134     1043553 :             temp = Mpy_32_32( L_shl( t_fx[j], exp1 ), L_shl( t_fx[i + j], exp2 ) );
     135     1043553 :             tmp_q = sub( add( add( x_q_fx, exp1 ), add( x_q_fx, exp2 ) ), 31 );
     136             : 
     137     1043553 :             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     1040542 :                 s_fx = W_add( s_fx, W_shr( temp, sub( tmp_q, r_q_fx[i] ) ) );
     146             :             }
     147             :         }
     148        4557 :         exp1 = W_norm( s_fx );
     149        4557 :         r_fx[i] = W_extract_h( W_shl( s_fx, exp1 ) );
     150        4557 :         move32();
     151        4557 :         r_q_fx[i] = sub( add( r_q_fx[i], exp1 ), 32 );
     152        4557 :         move16();
     153             :     }
     154             : 
     155             :     // 2097152000 = 1000 in Q21
     156         217 :     IF( LT_16( r_q_fx[0], Q21 ) )
     157             :     {
     158         217 :         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         217 :     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          28 : 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          28 :     set32_fx( a_fx, 0, LFE_PLC_LPCORD + 1 );
     206          28 :     set16_fx( a_q_fx, 31, LFE_PLC_LPCORD + 1 );
     207          28 :     set32_fx( a_out_fx, 0, LFE_PLC_LPCORD + 1 );
     208          28 :     set16_fx( a_out_q_fx, 31, LFE_PLC_LPCORD + 1 );
     209             : 
     210          28 :     s_q_fx = 0;
     211          28 :     move16();
     212             : 
     213          28 :     rc_fx = &buf_fx[0];
     214          28 :     a_fx[0] = ONE_IN_Q30;
     215          28 :     move32();
     216          28 :     a_q_fx[0] = 30;
     217          28 :     move16();
     218          28 :     err_fx = r_fx[0];
     219          28 :     move32();
     220          28 :     err_q_fx = r_q_fx[0];
     221          28 :     move16();
     222          28 :     a_out_fx[0] = a_fx[0];
     223          28 :     move32();
     224          28 :     a_out_q_fx[0] = 30;
     225          28 :     move16();
     226             : 
     227          28 :     rc_fx[0] = BASOP_Util_Divide3232_Scale_newton( -r_fx[1], r_fx[0], &temp_q2 );
     228          28 :     move32();
     229          28 :     rc_q_fx[0] = add( sub( r_q_fx[1], r_q_fx[0] ), sub( 31, temp_q2 ) );
     230          28 :     move16();
     231             : 
     232          28 :     s = r_fx[1];
     233          28 :     s_q_fx = r_q_fx[1];
     234          28 :     move32();
     235          28 :     move16();
     236             : 
     237          28 :     a_fx[1] = rc_fx[0];
     238          28 :     move32();
     239          28 :     a_q_fx[1] = rc_q_fx[0];
     240          28 :     move32();
     241             : 
     242          28 :     a_out_fx[1] = a_fx[1];
     243          28 :     move32();
     244          28 :     a_out_q_fx[1] = a_q_fx[1];
     245          28 :     move32();
     246             : 
     247          28 :     i = 1;
     248          28 :     move16();
     249         560 :     WHILE( LT_16( i, m ) )
     250             :     {
     251        3052 :         FOR( j = 1; j <= i / 2; j++ )
     252             :         {
     253        2520 :             l = sub( i, j );
     254        2520 :             exp1 = sub( norm_l( rc_fx[i - 1] ), 1 );
     255        2520 :             exp2 = sub( norm_l( a_fx[l] ), 1 );
     256        2520 :             rc_fx[i - 1] = L_shl( rc_fx[i - 1], exp1 );
     257        2520 :             move32();
     258        2520 :             rc_q_fx[i - 1] = add( rc_q_fx[i - 1], exp1 );
     259        2520 :             move16();
     260        2520 :             a_fx[l] = L_shl( a_fx[l], exp2 );
     261        2520 :             move32();
     262        2520 :             a_q_fx[l] = add( a_q_fx[l], exp2 );
     263        2520 :             move16();
     264             : 
     265        2520 :             exp2 = sub( norm_l( a_fx[j] ), 1 );
     266        2520 :             a_fx[j] = L_shl( a_fx[j], exp2 );
     267        2520 :             move32();
     268        2520 :             a_q_fx[j] = add( a_q_fx[j], exp2 );
     269        2520 :             move16();
     270             : 
     271        2520 :             temp2 = Mpy_32_32( rc_fx[i - 1], a_fx[l] );
     272        2520 :             temp_q2 = sub( add( rc_q_fx[i - 1], a_q_fx[l] ), 31 );
     273        2520 :             if ( temp2 == 0 )
     274             :             {
     275           0 :                 temp_q2 = 31;
     276           0 :                 move16();
     277             :             }
     278             : 
     279        2520 :             IF( LT_16( temp_q2, a_q_fx[j] ) )
     280             :             {
     281          75 :                 at_fx = L_add( L_shr( a_fx[j], sub( a_q_fx[j], temp_q2 ) ), temp2 ); // Q(temp_q2)
     282          75 :                 temp_q1 = temp_q2;
     283          75 :                 move16();
     284             :             }
     285             :             ELSE
     286             :             {
     287        2445 :                 at_fx = L_add( a_fx[j], L_shr( temp2, sub( temp_q2, a_q_fx[j] ) ) ); // Q(a_q_fx)
     288        2445 :                 temp_q1 = a_q_fx[j];
     289        2445 :                 move16();
     290             :             }
     291             : 
     292        2520 :             temp2 = Mpy_32_32( rc_fx[i - 1], a_fx[j] );
     293        2520 :             temp_q2 = sub( add( rc_q_fx[i - 1], a_q_fx[j] ), 31 );
     294        2520 :             if ( temp2 == 0 )
     295             :             {
     296           0 :                 temp_q2 = 31;
     297           0 :                 move16();
     298             :             }
     299             : 
     300        2520 :             IF( LT_16( temp_q2, a_q_fx[l] ) )
     301             :             {
     302        1308 :                 a_fx[l] = L_add( L_shr( a_fx[l], sub( a_q_fx[l], temp_q2 ) ), temp2 );
     303        1308 :                 move32();
     304        1308 :                 a_q_fx[l] = temp_q2;
     305        1308 :                 move16();
     306             :             }
     307             :             ELSE
     308             :             {
     309        1212 :                 a_fx[l] = L_add( a_fx[l], L_shr( temp2, sub( temp_q2, a_q_fx[l] ) ) );
     310        1212 :                 move16();
     311             :             }
     312        2520 :             a_fx[j] = at_fx;
     313        2520 :             move32();
     314        2520 :             a_q_fx[j] = temp_q1;
     315        2520 :             move16();
     316             :         }
     317             : 
     318         532 :         a_fx[i] = rc_fx[i - 1];
     319         532 :         move32();
     320         532 :         a_q_fx[i] = rc_q_fx[i - 1];
     321         532 :         move16();
     322             : 
     323         532 :         exp1 = sub( norm_l( rc_fx[i - 1] ), 1 );
     324         532 :         exp2 = norm_l( s );
     325         532 :         temp1 = Mpy_32_32( L_shl( rc_fx[i - 1], exp1 ), L_shl( s, exp2 ) );
     326         532 :         temp_q1 = sub( add( add( rc_q_fx[i - 1], exp1 ), add( s_q_fx, exp2 ) ), 31 );
     327         532 :         if ( temp1 == 0 )
     328             :         {
     329           0 :             temp_q1 = 31;
     330           0 :             move16();
     331             :         }
     332             : 
     333         532 :         IF( LT_16( temp_q1, err_q_fx ) )
     334             :         {
     335          16 :             err_fx = L_add( L_shr( err_fx, sub( err_q_fx, temp_q1 ) ), temp1 );
     336          16 :             err_q_fx = temp_q1;
     337          16 :             move16();
     338             :         }
     339             :         ELSE
     340             :         {
     341         516 :             err_fx = L_add( err_fx, L_shr( temp1, sub( temp_q1, err_q_fx ) ) );
     342             :         }
     343             : 
     344         532 :         s_fx = 0;
     345         532 :         move32();
     346         532 :         s_q_fx = 0;
     347         532 :         move16();
     348         532 :         i = add( i, 1 );
     349         532 :         s_fx = 0;
     350         532 :         move64();
     351             : 
     352        6384 :         FOR( j = 0; j < i; j++ )
     353             :         {
     354        5852 :             exp1 = norm_l( r_fx[i - j] );
     355        5852 :             exp2 = norm_l( a_fx[j] );
     356        5852 :             temp1 = Mpy_32_32( L_shl( r_fx[i - j], exp1 ), L_shl( a_fx[j], exp2 ) );
     357        5852 :             temp_q1 = sub( add( add( r_q_fx[i - j], exp1 ), add( a_q_fx[j], exp2 ) ), 31 );
     358        5852 :             if ( temp1 == 0 )
     359             :             {
     360           0 :                 temp_q1 = 31;
     361           0 :                 move16();
     362             :             }
     363             : 
     364        5852 :             IF( j == 0 )
     365             :             {
     366         532 :                 s_fx = W_deposit32_l( temp1 );
     367         532 :                 s_q_fx = temp_q1;
     368         532 :                 move16();
     369             :             }
     370             :             ELSE
     371             :             {
     372        5320 :                 IF( LT_16( temp_q1, s_q_fx ) )
     373             :                 {
     374         564 :                     s_fx = W_add( W_shr( s_fx, sub( s_q_fx, temp_q1 ) ), W_deposit32_l( temp1 ) );
     375         564 :                     s_q_fx = temp_q1;
     376         564 :                     move16();
     377             :                 }
     378             :                 ELSE
     379             :                 {
     380        4756 :                     s_fx = W_add( s_fx, W_shr( W_deposit32_l( temp1 ), sub( temp_q1, s_q_fx ) ) );
     381             :                 }
     382             :             }
     383             :         }
     384             : 
     385         532 :         exp1 = W_norm( s_fx );
     386         532 :         s = W_extract_h( W_shl( s_fx, exp1 ) );
     387         532 :         s_q_fx = sub( add( s_q_fx, exp1 ), 32 );
     388             : 
     389         532 :         rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_newton( L_negate( s ), err_fx, &temp_q2 ), 1 );
     390         532 :         move32();
     391         532 :         rc_q_fx[i - 1] = sub( add( sub( s_q_fx, err_q_fx ), sub( 31, temp_q2 ) ), 1 );
     392         532 :         move16();
     393             : 
     394         532 :         IF( LT_16( rc_q_fx[i - 1], 31 ) )
     395             :         {
     396             : 
     397         108 :             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        2376 :                 FOR( j = 0; j <= m; j++ )
     404             :                 {
     405        2268 :                     a_out_fx[j] = a_fx[j];
     406        2268 :                     a_out_q_fx[j] = a_q_fx[j];
     407        2268 :                     move32();
     408        2268 :                     move32();
     409             :                 }
     410             :             }
     411             :         }
     412             :         ELSE
     413             :         {
     414         424 :             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        9328 :                 FOR( j = 0; j <= m; j++ )
     421             :                 {
     422        8904 :                     a_out_fx[j] = a_fx[j];
     423        8904 :                     a_out_q_fx[j] = a_q_fx[j];
     424        8904 :                     move32();
     425        8904 :                     move32();
     426             :                 }
     427             :             }
     428             :         }
     429             :     }
     430          28 :     return 0;
     431             : }
     432             : /*-------------------------------------------------------------------*
     433             :  * a2rc_fx()
     434             :  *
     435             :  * Convert from LPC to reflection coeff
     436             :  *-------------------------------------------------------------------*/
     437             : 
     438         352 : 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        7392 :     FOR( m = 0; m < lpcorder; m++ )
     452             :     {
     453        7040 :         ff_fx[m] = L_negate( a_fx[m] );
     454        7040 :         move32();
     455        7040 :         ff_q_fx[m] = a_q_fx[m];
     456        7040 :         move32();
     457             :     }
     458             : 
     459             :     /* Initialization */
     460        6888 :     FOR( m = lpcorder - 1; m >= 0; m-- )
     461             :     {
     462        6708 :         km_fx = ff_fx[m];
     463        6708 :         move32();
     464        6708 :         km_q_fx = ff_q_fx[m];
     465        6708 :         move16();
     466        6708 :         IF( GE_64( W_shr( L_abs( km_fx ), sub( ff_q_fx[m], Q30 ) ), W_deposit32_l( ONE_IN_Q30 ) ) )
     467             :         {
     468        3612 :             FOR( j = 0; j < lpcorder; j++ )
     469             :             {
     470        3440 :                 refl_fx[j] = 0;
     471        3440 :                 move32();
     472             :             }
     473         172 :             return 0;
     474             :         }
     475             : 
     476        6536 :         refl_fx[m] = L_negate( km_fx ); // Q(km_q_Fx)
     477        6536 :         move32();
     478             : 
     479        6536 :         exp1 = norm_l( km_fx );
     480        6536 :         temp1 = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( km_fx, exp1 ) );
     481        6536 :         temp_q1 = sub( add( add( km_q_fx, exp1 ), add( km_q_fx, exp1 ) ), 31 );
     482        6536 :         temp1 = L_sub( ONE_IN_Q30, L_shr( temp1, sub( temp_q1, 30 ) ) );
     483        6536 :         denom_fx = L_deposit_l( BASOP_Util_Divide3232_Scale( ONE_IN_Q30, temp1, &temp_q1 ) );
     484        6536 :         denom_q_fx = sub( 15, temp_q1 );
     485             : 
     486       37729 :         FOR( j = 0; j < m / 2; j++ )
     487             :         {
     488       31193 :             n = sub( sub( m, 1 ), j );
     489             : 
     490       31193 :             exp1 = norm_l( denom_fx );
     491       31193 :             exp2 = sub( norm_l( ff_fx[j] ), 1 );
     492       31193 :             temp1 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[j], exp2 ) );
     493       31193 :             temp_q1 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[j], exp2 ) ), 31 );
     494             : 
     495       31193 :             exp2 = sub( norm_l( ff_fx[n] ), 1 );
     496       31193 :             temp2 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[n], exp2 ) );
     497       31193 :             temp_q2 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[n], exp2 ) ), 31 );
     498             : 
     499       31193 :             exp1 = norm_l( km_fx );
     500       31193 :             exp2 = sub( norm_l( temp2 ), 1 );
     501       31193 :             temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp2, exp2 ) );
     502       31193 :             temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q2, exp2 ) ), 31 );
     503       31193 :             if ( temp == 0 )
     504             :             {
     505        3168 :                 temp_q = 31;
     506        3168 :                 move16();
     507             :             }
     508       31193 :             IF( LT_16( temp_q, temp_q1 ) )
     509             :             {
     510         701 :                 ff_fx[j] = L_add( L_shr( temp1, sub( temp_q1, temp_q ) ), temp );
     511         701 :                 move32();
     512         701 :                 ff_q_fx[j] = temp_q;
     513         701 :                 move16();
     514             :             }
     515             :             ELSE
     516             :             {
     517       30492 :                 ff_fx[j] = L_add( temp1, L_shr( temp, sub( temp_q, temp_q1 ) ) );
     518       30492 :                 move32();
     519       30492 :                 ff_q_fx[j] = temp_q1;
     520       30492 :                 move16();
     521             :             }
     522             : 
     523       31193 :             exp1 = norm_l( km_fx );
     524       31193 :             exp2 = sub( norm_l( temp1 ), 1 );
     525       31193 :             temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp1, exp2 ) );
     526       31193 :             temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q1, exp2 ) ), 31 );
     527       31193 :             if ( temp == 0 )
     528             :             {
     529        3168 :                 temp_q = 31;
     530        3168 :                 move16();
     531             :             }
     532       31193 :             IF( LT_16( temp_q, temp_q2 ) )
     533             :             {
     534        7528 :                 ff_fx[n] = L_add( L_shr( temp2, sub( temp_q2, temp_q ) ), temp );
     535        7528 :                 move32();
     536        7528 :                 ff_q_fx[n] = temp_q;
     537        7528 :                 move16();
     538             :             }
     539             :             ELSE
     540             :             {
     541       23665 :                 ff_fx[n] = L_add( temp2, L_shr( temp, sub( temp_q, temp_q2 ) ) );
     542       23665 :                 move32();
     543       23665 :                 ff_q_fx[n] = temp_q2;
     544       23665 :                 move16();
     545             :             }
     546             :         }
     547             : 
     548        6536 :         IF( s_and( m, 1 ) )
     549             :         {
     550        3284 :             exp1 = norm_l( denom_fx );
     551        3284 :             exp2 = sub( norm_l( ff_fx[j] ), 1 );
     552        3284 :             temp1 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[j], exp2 ) );
     553        3284 :             temp_q1 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[j], exp2 ) ), 31 );
     554             : 
     555        3284 :             exp1 = norm_l( km_fx );
     556        3284 :             exp2 = sub( norm_l( temp1 ), 1 );
     557        3284 :             temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp1, exp2 ) );
     558        3284 :             temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q1, exp2 ) ), 31 );
     559        3284 :             if ( temp == 0 )
     560             :             {
     561         352 :                 temp_q = 31;
     562         352 :                 move16();
     563             :             }
     564        3284 :             IF( LT_16( temp_q, temp_q1 ) )
     565             :             {
     566         180 :                 ff_fx[j] = L_add( L_shr( temp1, sub( temp_q1, temp_q ) ), temp );
     567         180 :                 move32();
     568         180 :                 ff_q_fx[j] = temp_q;
     569         180 :                 move16();
     570             :             }
     571             :             ELSE
     572             :             {
     573        3104 :                 ff_fx[j] = L_add( temp1, L_shr( temp, sub( temp_q, temp_q1 ) ) );
     574        3104 :                 move32();
     575        3104 :                 ff_q_fx[j] = temp_q1;
     576        3104 :                 move16();
     577             :             }
     578             :         }
     579             :     }
     580             : 
     581         180 :     return 1;
     582             : }
     583             : 
     584          28 : 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          28 :     yy_fx = &buf_fx[0];
     603             : 
     604             :     /*------------------------------------------------------------------*
     605             :      * copy initial filter states into synthesis buffer and do synthesis
     606             :      *------------------------------------------------------------------*/
     607         588 :     FOR( i = 0; i < m; i++ )
     608             :     {
     609         560 :         *yy_fx++ = mem_fx[i];
     610         560 :         move32();
     611         560 :         yy_q_fx[i] = mem_q_fx;
     612         560 :         move16();
     613             :     }
     614             : 
     615             :     /*-----------------------------------------------------------------------*
     616             :      * Do the filtering
     617             :      *-----------------------------------------------------------------------*/
     618             : 
     619        1652 :     FOR( i = 0; i < l; i++ )
     620             :     {
     621        1624 :         s_fx = x_fx[i];
     622        1624 :         move64();
     623        1624 :         s_q_fx = Q31;
     624        1624 :         move16();
     625       34104 :         FOR( j = 1; j <= m; j++ )
     626             :         {
     627       32480 :             exp1 = sub( norm_l( a_fx[j] ), 1 );
     628       32480 :             exp2 = sub( norm_l( yy_fx[i - j] ), 1 );
     629       32480 :             IF( GT_16( j, i ) )
     630             :             {
     631        5880 :                 temp_q = mem_q_fx;
     632        5880 :                 move16();
     633             :             }
     634             :             ELSE
     635             :             {
     636       26600 :                 temp_q = yy_q_fx[i - j];
     637       26600 :                 move16();
     638             :             }
     639       32480 :             temp = Mpy_32_32( L_shl( a_fx[j], exp1 ), L_shl( yy_fx[i - j], exp2 ) );
     640       32480 :             temp_q = sub( add( add( a_q_fx[j], exp1 ), add( temp_q, exp2 ) ), 31 );
     641             : 
     642       32480 :             IF( LT_16( s_q_fx, temp_q ) )
     643             :             {
     644       28711 :                 s_fx = W_sub( s_fx, L_shr( temp, sub( temp_q, s_q_fx ) ) );
     645             :             }
     646             :             ELSE
     647             :             {
     648        3769 :                 s_fx = W_sub( W_shr( s_fx, s_min( 63, sub( s_q_fx, temp_q ) ) ), temp );
     649        3769 :                 s_q_fx = temp_q;
     650        3769 :                 move16();
     651             :             }
     652             :         }
     653        1624 :         tmp = W_norm( s_fx );
     654        1624 :         s_fx = W_shl( s_fx, tmp );
     655        1624 :         s_q_fx = add( s_q_fx, tmp );
     656        1624 :         yy_fx[i] = W_extract_h( s_fx );
     657        1624 :         move32();
     658        1624 :         yy_q_fx[i] = sub( s_q_fx, 32 );
     659        1624 :         move16();
     660        1624 :         y_fx[i] = W_extract_l( W_shr( s_fx, sub( s_q_fx, Q5 ) ) );
     661        1624 :         move32();
     662             :     }
     663          28 :     *y_q_fx = Q5;
     664          28 :     move16();
     665             : 
     666          28 :     return;
     667             : }
     668             : 
     669             : /*-----------------------------------------------------------------------------------------*
     670             :  * Function check_stab_fx()
     671             :  *
     672             :  * LPC filter stability check applying given sharpening value delta
     673             :  *-----------------------------------------------------------------------------------------*/
     674             : 
     675         352 : 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         352 :     exp1 = norm_l( delta_fx );
     690         352 :     delta_fx = L_shl( delta_fx, exp1 );
     691         352 :     delta_q_fx = add( delta_q_fx, exp1 );
     692             : 
     693         352 :     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         352 :         fac_fx = L_add( ONE_IN_Q29, L_shr( delta_fx, sub( delta_q_fx, 29 ) ) );
     702         352 :         fac_q_fx = Q29;
     703         352 :         move16();
     704             :     }
     705         352 :     fac1_fx = fac_fx;
     706         352 :     move32();
     707         352 :     fac1_q_fx = fac_q_fx;
     708         352 :     move16();
     709             : 
     710        7392 :     FOR( i = 0; i < LFE_PLC_LPCORD; i++ )
     711             :     {
     712        7040 :         exp1 = norm_l( a_fx[i] );
     713        7040 :         exp2 = norm_l( fac_fx );
     714        7040 :         amod_fx[i] = Mpy_32_32( L_shl( a_fx[i], exp1 ), L_shl( fac_fx, exp2 ) );
     715        7040 :         move32();
     716        7040 :         amod_q_fx[i] = sub( add( add( a_q_fx[i], exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     717        7040 :         move16();
     718        7040 :         if ( amod_fx[i] == 0 )
     719             :         {
     720         352 :             amod_q_fx[i] = 31;
     721         352 :             move16();
     722             :         }
     723        7040 :         exp1 = norm_l( fac_fx );
     724        7040 :         exp2 = norm_l( fac1_fx );
     725        7040 :         fac_fx = Mpy_32_32( L_shl( fac_fx, exp1 ), L_shl( fac1_fx, exp2 ) );
     726        7040 :         fac_q_fx = sub( add( add( fac_q_fx, exp1 ), add( fac1_q_fx, exp2 ) ), 31 );
     727        7040 :         if ( fac_fx == 0 )
     728             :         {
     729           0 :             fac_q_fx = 0;
     730           0 :             move16();
     731             :         }
     732             :     }
     733         352 :     stable = d_a2rc_fx( amod_fx, amod_q_fx, refl_fx, LFE_PLC_LPCORD );
     734             : 
     735         352 :     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          28 : 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          28 :     delta_fx = 0;
     754          28 :     move32();
     755          28 :     eps_fx = 21474836; // 0.01 in Q31
     756          28 :     move32();
     757          28 :     fac_fx = 1073741824; // 2 in Q29
     758          28 :     move32();
     759          28 :     eps_q_fx = Q31;
     760          28 :     move16();
     761          28 :     fac_q_fx = Q29;
     762          28 :     move16();
     763             : 
     764          28 :     stable = FALSE;
     765          28 :     move16();
     766             : 
     767          52 :     WHILE( check_stab_fx( a_fx, a_q_fx, eps_fx, eps_q_fx ) )
     768             :     {
     769          24 :         exp1 = norm_l( eps_fx );
     770          24 :         exp2 = norm_l( fac_fx );
     771          24 :         eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
     772          24 :         eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     773          24 :         stable = TRUE;
     774          24 :         move16();
     775             :     }
     776          28 :     fac_fx = 1073741824; // 0.5 in Q31
     777          28 :     move32();
     778          28 :     fac_q_fx = Q31;
     779          28 :     move16();
     780             : 
     781          28 :     IF( stable )
     782             :     {
     783          13 :         exp1 = norm_l( eps_fx );
     784          13 :         exp2 = norm_l( fac_fx );
     785          13 :         eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
     786          13 :         eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     787             :     }
     788             : 
     789          53 :     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          28 :     *delta_q_fx = sub( norm_l( eps_fx ), 1 );
     801          28 :     delta_fx = L_shl( eps_fx, *delta_q_fx );
     802          28 :     *delta_q_fx = add( eps_q_fx, *delta_q_fx );
     803          28 :     move16();
     804          28 :     move16();
     805             : 
     806          28 :     exp1 = norm_l( eps_fx );
     807          28 :     exp2 = norm_l( fac_fx );
     808          28 :     eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
     809          28 :     eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     810             : 
     811             :     WHILE( 1 )
     812             :     {
     813         275 :         IF( LT_16( *delta_q_fx, eps_q_fx ) )
     814             :         {
     815         275 :             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         275 :         stable = check_stab_fx( a_fx, a_q_fx, delta_fx, *delta_q_fx );
     824             : 
     825         275 :         IF( !stable )
     826             :         {
     827         134 :             temp = L_abs( eps_fx );
     828         134 :             IF( GT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) )
     829             :             {
     830         125 :                 exp1 = norm_l( -temp );
     831         125 :                 exp2 = norm_l( fac_fx );
     832         125 :                 eps_fx = Mpy_32_32( L_shl( -temp, exp1 ), L_shl( fac_fx, exp2 ) );
     833         125 :                 eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     834             :             }
     835             :             ELSE
     836             :             {
     837           9 :                 eps_fx = L_negate( L_abs( eps_fx ) );
     838             :             }
     839             :         }
     840             :         ELSE
     841             :         {
     842         141 :             temp = L_abs( eps_fx );
     843         141 :             if ( LT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) )
     844             :             {
     845          28 :                 BREAK;
     846             :             }
     847             : 
     848         113 :             exp1 = norm_l( temp );
     849         113 :             exp1 = norm_l( fac_fx );
     850         113 :             eps_fx = Mpy_32_32( L_shl( temp, exp1 ), L_shl( fac_fx, exp2 ) );
     851         113 :             eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     852             :         }
     853             :     }
     854             : 
     855          28 :     return delta_fx;
     856             : }
     857             : 
     858             : /*-----------------------------------------------------------------------------------------*
     859             :  * Function recover_samples_fx()
     860             :  *
     861             :  * recover lost samples by extrapolation of signal buffer
     862             :  *-----------------------------------------------------------------------------------------*/
     863             : 
     864         217 : 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         217 :     Copy32( outbuf_fx, d_outbuf_fx, LFE_PLC_BUFLEN );
     879             : 
     880         217 :     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         217 :     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         189 :         set_zero_fx( rec_frame_fx, LFE_PLC_RECLEN );
     885         189 :         return;
     886             :     }
     887             : 
     888          28 :     lfeplc_lev_dur_fx( d_a_fx, d_a_q_fx, d_r_fx, d_r_q_fx, LFE_PLC_LPCORD );
     889             : 
     890          28 :     delta_fx = find_max_delta_fx( d_a_fx + 1, d_a_q_fx + 1, &delta_q_fx );
     891             : 
     892          28 :     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          28 :         fac_fx = L_add( ONE_IN_Q29, L_shr( delta_fx, sub( delta_q_fx, Q29 ) ) );
     901          28 :         fac_q_fx = Q29;
     902          28 :         move16();
     903             :     }
     904          28 :     att_fx = ONE_IN_Q31;
     905          28 :     move32();
     906             : 
     907          28 :     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         588 :     FOR( i = 1; i <= LFE_PLC_LPCORD; i++ )
     915             :     {
     916         560 :         d_a_fx[i] = Mpy_32_32( d_a_fx[i], fac_fx );
     917         560 :         move32();
     918         560 :         d_a_q_fx[i] = sub( add( d_a_q_fx[i], fac_q_fx ), 31 );
     919         560 :         move16();
     920         560 :         if ( d_a_fx[i] == 0 )
     921             :         {
     922          28 :             d_a_q_fx[i] = 31;
     923          28 :             move16();
     924             :         }
     925         560 :         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         560 :             temp = L_add( ONE_IN_Q30, L_shr( delta_fx, sub( delta_q_fx, Q30 ) ) );
     934         560 :             temp_q = Q30;
     935         560 :             move16();
     936             :         }
     937         560 :         exp2 = norm_l( temp );
     938         560 :         temp = Mpy_32_32( att_fx, L_shl( temp, exp2 ) );
     939         560 :         temp_q = add( temp_q, exp2 );
     940             : 
     941         560 :         exp1 = norm_l( fac_fx );
     942         560 :         exp2 = norm_l( temp );
     943         560 :         fac_fx = Mpy_32_32( L_shl( fac_fx, exp1 ), L_shl( temp, exp2 ) );
     944         560 :         fac_q_fx = sub( add( add( fac_q_fx, exp1 ), add( temp_q, exp2 ) ), 31 );
     945             :     }
     946             : 
     947          28 :     set_zero_fx( zeroes_fx, LFE_PLC_RECLEN );
     948             : 
     949          28 :     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          28 :     return;
     952             : }
     953             : /*-----------------------------------------------------------------------------------------*
     954             :  * Function ivas_lfe_tdplc_fx()
     955             :  *
     956             :  * MDCT interface recover lost samples by extrapolation of signal buffer
     957             :  *-----------------------------------------------------------------------------------------*/
     958             : 
     959         217 : 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         217 :     output_Fs = L_mult0( output_frame, FRAMES_PER_SEC );
     976         217 :     fade_len = hLFE->pWindow_state->fade_len;
     977         217 :     move16();
     978         217 :     full_len = hLFE->pWindow_state->full_len;
     979         217 :     move16();
     980         217 :     dct_len = hLFE->pWindow_state->dct_len;
     981         217 :     move16();
     982         217 :     zero_pad_len = hLFE->pWindow_state->zero_pad_len;
     983         217 :     move16();
     984         217 :     pWindow_coeffs_fx = hLFE->pWindow_state->pWindow_coeffs_fx;
     985             : 
     986             :     /* plc_fdel = (int16_t) ( LFE_PLC_FDEL * output_Fs / 48000 ); */
     987         217 :     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         217 :     rec_frame_len = extract_l( Mpy_32_32_r( output_Fs, 77846282 /* LFE_PLC_RECLEN_48K / 48000 in Q31 */ ) );
     990             : 
     991         217 :     Copy32( prevsynth, prevsynth_fx, LFE_PLC_BUFLEN );
     992         217 :     exp = L_norm_arr( prevsynth_fx, LFE_PLC_BUFLEN );
     993         217 :     scale_sig32( prevsynth_fx, LFE_PLC_BUFLEN, exp );
     994         217 :     prevsynth_q_fx = add( Q9, exp );
     995         217 :     move16();
     996             : 
     997         217 :     recover_samples_fx( hLFE->bfi_count, prevsynth_fx, prevsynth_q_fx, rec_frame_fx, &rec_frame_q );
     998             : 
     999         217 :     set16_fx( mem_fx, 0, 2 * LFE_PLC_FDEL / LFE_PLC_DSF );
    1000             : 
    1001         217 :     Copy_Scale_sig_32_16( prevsynth_fx, prevsynth_16_fx, LFE_PLC_BUFLEN, -prevsynth_q_fx ); // Q0
    1002         217 :     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         217 :     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         217 :     Scale_sig( rec_frame_us_16_fx, size_modified, negate( Q_new_inp ) ); /* scaling back to Q0 */
    1007             : 
    1008         217 :     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         217 :     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         217 :     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         217 :     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         651 :     FOR( i = 0; i < 2; i++ )
    1030             :     {
    1031         434 :         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         434 :         ivas_tda_fx( input_tda_fx, ytda + imult1616( i, dct_len ), dct_len );
    1033             :     }
    1034             : 
    1035         217 :     return;
    1036             : }

Generated by: LCOV version 1.14