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

Generated by: LCOV version 1.14