LCOV - code coverage report
Current view: top level - lib_dec - ivas_lfe_plc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 462 504 91.7 %
Date: 2025-08-23 01:22:27 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         151 : 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         151 :     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         151 :     ELSE IF( EQ_16( sym_flag, 1 ) )
     100             :     {
     101             :         /* symmetric window of even length */
     102       18271 :         FOR( i = 0; i < len / 2; i++ )
     103             :         {
     104       18120 :             t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[i] ); // Q = x_q_fx
     105       18120 :             move32();
     106             :         }
     107             : 
     108       18271 :         FOR( ; i < len; i++ )
     109             :         {
     110       18120 :             t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[len - 1 - i] ); // Q = x_q_fx
     111       18120 :             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        3322 :     FOR( i = 0; i <= m; i++ )
     125             :     {
     126        3171 :         exp1 = norm_l( t_fx[0] );
     127        3171 :         exp2 = norm_l( t_fx[i] );
     128        3171 :         s_fx = W_deposit32_l( Mpy_32_32( L_shl( t_fx[0], exp1 ), L_shl( t_fx[i], exp2 ) ) );
     129        3171 :         r_q_fx[i] = sub( add( add( x_q_fx, exp1 ), add( x_q_fx, exp2 ) ), 31 );
     130        3171 :         move16();
     131      729330 :         FOR( j = 1; j < len - i; j++ )
     132             :         {
     133      726159 :             exp1 = norm_l( t_fx[j] );
     134      726159 :             exp2 = norm_l( t_fx[i + j] );
     135      726159 :             temp = Mpy_32_32( L_shl( t_fx[j], exp1 ), L_shl( t_fx[i + j], exp2 ) );
     136      726159 :             tmp_q = sub( add( add( x_q_fx, exp1 ), add( x_q_fx, exp2 ) ), 31 );
     137             : 
     138      726159 :             IF( LT_16( tmp_q, r_q_fx[i] ) )
     139             :             {
     140        3050 :                 s_fx = W_add( W_shr( s_fx, sub( r_q_fx[i], tmp_q ) ), W_deposit32_l( temp ) );
     141        3050 :                 r_q_fx[i] = tmp_q;
     142        3050 :                 move16();
     143             :             }
     144             :             ELSE
     145             :             {
     146      723109 :                 s_fx = W_add( s_fx, W_shr( temp, sub( tmp_q, r_q_fx[i] ) ) );
     147             :             }
     148             :         }
     149        3171 :         exp1 = W_norm( s_fx );
     150        3171 :         r_fx[i] = W_extract_h( W_shl( s_fx, exp1 ) );
     151        3171 :         move32();
     152        3171 :         r_q_fx[i] = sub( add( r_q_fx[i], exp1 ), 32 );
     153        3171 :         move16();
     154             :     }
     155             : 
     156             :     // 2097152000 = 1000 in Q21
     157         151 :     IF( LT_16( r_q_fx[0], Q21 ) )
     158             :     {
     159         151 :         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         151 :     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          24 : 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          24 :     set32_fx( a_fx, 0, LFE_PLC_LPCORD + 1 );
     207          24 :     set16_fx( a_q_fx, 31, LFE_PLC_LPCORD + 1 );
     208          24 :     set32_fx( a_out_fx, 0, LFE_PLC_LPCORD + 1 );
     209          24 :     set16_fx( a_out_q_fx, 31, LFE_PLC_LPCORD + 1 );
     210             : 
     211          24 :     s_q_fx = 0;
     212          24 :     move16();
     213             : 
     214          24 :     rc_fx = &buf_fx[0];
     215          24 :     a_fx[0] = ONE_IN_Q30;
     216          24 :     move32();
     217          24 :     a_q_fx[0] = 30;
     218          24 :     move16();
     219          24 :     err_fx = r_fx[0];
     220          24 :     move32();
     221          24 :     err_q_fx = r_q_fx[0];
     222          24 :     move16();
     223          24 :     a_out_fx[0] = a_fx[0];
     224          24 :     move32();
     225          24 :     a_out_q_fx[0] = 30;
     226          24 :     move16();
     227             : 
     228          24 :     rc_fx[0] = BASOP_Util_Divide3232_Scale_newton( -r_fx[1], r_fx[0], &temp_q2 );
     229          24 :     move32();
     230          24 :     rc_q_fx[0] = add( sub( r_q_fx[1], r_q_fx[0] ), sub( 31, temp_q2 ) );
     231          24 :     move16();
     232             : 
     233          24 :     s = r_fx[1];
     234          24 :     s_q_fx = r_q_fx[1];
     235          24 :     move32();
     236          24 :     move16();
     237             : 
     238          24 :     a_fx[1] = rc_fx[0];
     239          24 :     move32();
     240          24 :     a_q_fx[1] = rc_q_fx[0];
     241          24 :     move32();
     242             : 
     243          24 :     a_out_fx[1] = a_fx[1];
     244          24 :     move32();
     245          24 :     a_out_q_fx[1] = a_q_fx[1];
     246          24 :     move32();
     247             : 
     248          24 :     i = 1;
     249          24 :     move16();
     250         480 :     WHILE( LT_16( i, m ) )
     251             :     {
     252        2616 :         FOR( j = 1; j <= i / 2; j++ )
     253             :         {
     254        2160 :             l = sub( i, j );
     255        2160 :             exp1 = sub( norm_l( rc_fx[i - 1] ), 1 );
     256        2160 :             exp2 = sub( norm_l( a_fx[l] ), 1 );
     257        2160 :             rc_fx[i - 1] = L_shl( rc_fx[i - 1], exp1 );
     258        2160 :             move32();
     259        2160 :             rc_q_fx[i - 1] = add( rc_q_fx[i - 1], exp1 );
     260        2160 :             move16();
     261        2160 :             a_fx[l] = L_shl( a_fx[l], exp2 );
     262        2160 :             move32();
     263        2160 :             a_q_fx[l] = add( a_q_fx[l], exp2 );
     264        2160 :             move16();
     265             : 
     266        2160 :             exp2 = sub( norm_l( a_fx[j] ), 1 );
     267        2160 :             a_fx[j] = L_shl( a_fx[j], exp2 );
     268        2160 :             move32();
     269        2160 :             a_q_fx[j] = add( a_q_fx[j], exp2 );
     270        2160 :             move16();
     271             : 
     272        2160 :             temp2 = Mpy_32_32( rc_fx[i - 1], a_fx[l] );
     273        2160 :             temp_q2 = sub( add( rc_q_fx[i - 1], a_q_fx[l] ), 31 );
     274        2160 :             if ( temp2 == 0 )
     275             :             {
     276           0 :                 temp_q2 = 31;
     277           0 :                 move16();
     278             :             }
     279             : 
     280        2160 :             IF( LT_16( temp_q2, a_q_fx[j] ) )
     281             :             {
     282          72 :                 at_fx = L_add( L_shr( a_fx[j], sub( a_q_fx[j], temp_q2 ) ), temp2 ); // Q(temp_q2)
     283          72 :                 temp_q1 = temp_q2;
     284          72 :                 move16();
     285             :             }
     286             :             ELSE
     287             :             {
     288        2088 :                 at_fx = L_add( a_fx[j], L_shr( temp2, sub( temp_q2, a_q_fx[j] ) ) ); // Q(a_q_fx)
     289        2088 :                 temp_q1 = a_q_fx[j];
     290        2088 :                 move16();
     291             :             }
     292             : 
     293        2160 :             temp2 = Mpy_32_32( rc_fx[i - 1], a_fx[j] );
     294        2160 :             temp_q2 = sub( add( rc_q_fx[i - 1], a_q_fx[j] ), 31 );
     295        2160 :             if ( temp2 == 0 )
     296             :             {
     297           0 :                 temp_q2 = 31;
     298           0 :                 move16();
     299             :             }
     300             : 
     301        2160 :             IF( LT_16( temp_q2, a_q_fx[l] ) )
     302             :             {
     303        1076 :                 a_fx[l] = L_add( L_shr( a_fx[l], sub( a_q_fx[l], temp_q2 ) ), temp2 );
     304        1076 :                 move32();
     305        1076 :                 a_q_fx[l] = temp_q2;
     306        1076 :                 move16();
     307             :             }
     308             :             ELSE
     309             :             {
     310        1084 :                 a_fx[l] = L_add( a_fx[l], L_shr( temp2, sub( temp_q2, a_q_fx[l] ) ) );
     311        1084 :                 move16();
     312             :             }
     313        2160 :             a_fx[j] = at_fx;
     314        2160 :             move32();
     315        2160 :             a_q_fx[j] = temp_q1;
     316        2160 :             move16();
     317             :         }
     318             : 
     319         456 :         a_fx[i] = rc_fx[i - 1];
     320         456 :         move32();
     321         456 :         a_q_fx[i] = rc_q_fx[i - 1];
     322         456 :         move16();
     323             : 
     324         456 :         exp1 = sub( norm_l( rc_fx[i - 1] ), 1 );
     325         456 :         exp2 = norm_l( s );
     326         456 :         temp1 = Mpy_32_32( L_shl( rc_fx[i - 1], exp1 ), L_shl( s, exp2 ) );
     327         456 :         temp_q1 = sub( add( add( rc_q_fx[i - 1], exp1 ), add( s_q_fx, exp2 ) ), 31 );
     328         456 :         if ( temp1 == 0 )
     329             :         {
     330           0 :             temp_q1 = 31;
     331           0 :             move16();
     332             :         }
     333             : 
     334         456 :         IF( LT_16( temp_q1, err_q_fx ) )
     335             :         {
     336          18 :             err_fx = L_add( L_shr( err_fx, sub( err_q_fx, temp_q1 ) ), temp1 );
     337          18 :             err_q_fx = temp_q1;
     338          18 :             move16();
     339             :         }
     340             :         ELSE
     341             :         {
     342         438 :             err_fx = L_add( err_fx, L_shr( temp1, sub( temp_q1, err_q_fx ) ) );
     343             :         }
     344             : 
     345         456 :         s_fx = 0;
     346         456 :         move32();
     347         456 :         s_q_fx = 0;
     348         456 :         move16();
     349         456 :         i = add( i, 1 );
     350         456 :         s_fx = 0;
     351         456 :         move64();
     352             : 
     353        5472 :         FOR( j = 0; j < i; j++ )
     354             :         {
     355        5016 :             exp1 = norm_l( r_fx[i - j] );
     356        5016 :             exp2 = norm_l( a_fx[j] );
     357        5016 :             temp1 = Mpy_32_32( L_shl( r_fx[i - j], exp1 ), L_shl( a_fx[j], exp2 ) );
     358        5016 :             temp_q1 = sub( add( add( r_q_fx[i - j], exp1 ), add( a_q_fx[j], exp2 ) ), 31 );
     359        5016 :             if ( temp1 == 0 )
     360             :             {
     361           0 :                 temp_q1 = 31;
     362           0 :                 move16();
     363             :             }
     364             : 
     365        5016 :             IF( j == 0 )
     366             :             {
     367         456 :                 s_fx = W_deposit32_l( temp1 );
     368         456 :                 s_q_fx = temp_q1;
     369         456 :                 move16();
     370             :             }
     371             :             ELSE
     372             :             {
     373        4560 :                 IF( LT_16( temp_q1, s_q_fx ) )
     374             :                 {
     375         520 :                     s_fx = W_add( W_shr( s_fx, sub( s_q_fx, temp_q1 ) ), W_deposit32_l( temp1 ) );
     376         520 :                     s_q_fx = temp_q1;
     377         520 :                     move16();
     378             :                 }
     379             :                 ELSE
     380             :                 {
     381        4040 :                     s_fx = W_add( s_fx, W_shr( W_deposit32_l( temp1 ), sub( temp_q1, s_q_fx ) ) );
     382             :                 }
     383             :             }
     384             :         }
     385             : 
     386         456 :         exp1 = W_norm( s_fx );
     387         456 :         s = W_extract_h( W_shl( s_fx, exp1 ) );
     388         456 :         s_q_fx = sub( add( s_q_fx, exp1 ), 32 );
     389             : 
     390         456 :         rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_newton( L_negate( s ), err_fx, &temp_q2 ), 1 );
     391         456 :         move32();
     392         456 :         rc_q_fx[i - 1] = sub( add( sub( s_q_fx, err_q_fx ), sub( 31, temp_q2 ) ), 1 );
     393         456 :         move16();
     394             : 
     395         456 :         IF( LT_16( rc_q_fx[i - 1], 31 ) )
     396             :         {
     397             : 
     398          94 :             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        2068 :                 FOR( j = 0; j <= m; j++ )
     405             :                 {
     406        1974 :                     a_out_fx[j] = a_fx[j];
     407        1974 :                     a_out_q_fx[j] = a_q_fx[j];
     408        1974 :                     move32();
     409        1974 :                     move32();
     410             :                 }
     411             :             }
     412             :         }
     413             :         ELSE
     414             :         {
     415         362 :             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        7964 :                 FOR( j = 0; j <= m; j++ )
     422             :                 {
     423        7602 :                     a_out_fx[j] = a_fx[j];
     424        7602 :                     a_out_q_fx[j] = a_q_fx[j];
     425        7602 :                     move32();
     426        7602 :                     move32();
     427             :                 }
     428             :             }
     429             :         }
     430             :     }
     431          24 :     return 0;
     432             : }
     433             : /*-------------------------------------------------------------------*
     434             :  * a2rc_fx()
     435             :  *
     436             :  * Convert from LPC to reflection coeff
     437             :  *-------------------------------------------------------------------*/
     438             : 
     439         306 : 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        6426 :     FOR( m = 0; m < lpcorder; m++ )
     453             :     {
     454        6120 :         ff_fx[m] = L_negate( a_fx[m] );
     455        6120 :         move32();
     456        6120 :         ff_q_fx[m] = a_q_fx[m];
     457        6120 :         move32();
     458             :     }
     459             : 
     460             :     /* Initialization */
     461        6024 :     FOR( m = lpcorder - 1; m >= 0; m-- )
     462             :     {
     463        5877 :         km_fx = ff_fx[m];
     464        5877 :         move32();
     465        5877 :         km_q_fx = ff_q_fx[m];
     466        5877 :         move16();
     467        5877 :         IF( GE_64( W_shr( L_abs( km_fx ), sub( ff_q_fx[m], Q30 ) ), W_deposit32_l( ONE_IN_Q30 ) ) )
     468             :         {
     469        3339 :             FOR( j = 0; j < lpcorder; j++ )
     470             :             {
     471        3180 :                 refl_fx[j] = 0;
     472        3180 :                 move32();
     473             :             }
     474         159 :             return 0;
     475             :         }
     476             : 
     477        5718 :         refl_fx[m] = L_negate( km_fx ); // Q(km_q_Fx)
     478        5718 :         move32();
     479             : 
     480        5718 :         exp1 = norm_l( km_fx );
     481        5718 :         temp1 = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( km_fx, exp1 ) );
     482        5718 :         temp_q1 = sub( add( add( km_q_fx, exp1 ), add( km_q_fx, exp1 ) ), 31 );
     483        5718 :         temp1 = L_sub( ONE_IN_Q30, L_shr( temp1, sub( temp_q1, 30 ) ) );
     484        5718 :         denom_fx = L_deposit_l( BASOP_Util_Divide3232_Scale( ONE_IN_Q30, temp1, &temp_q1 ) );
     485        5718 :         denom_q_fx = sub( 15, temp_q1 );
     486             : 
     487       33057 :         FOR( j = 0; j < m / 2; j++ )
     488             :         {
     489       27339 :             n = sub( sub( m, 1 ), j );
     490             : 
     491       27339 :             exp1 = norm_l( denom_fx );
     492       27339 :             exp2 = sub( norm_l( ff_fx[j] ), 1 );
     493       27339 :             temp1 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[j], exp2 ) );
     494       27339 :             temp_q1 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[j], exp2 ) ), 31 );
     495             : 
     496       27339 :             exp2 = sub( norm_l( ff_fx[n] ), 1 );
     497       27339 :             temp2 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[n], exp2 ) );
     498       27339 :             temp_q2 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[n], exp2 ) ), 31 );
     499             : 
     500       27339 :             exp1 = norm_l( km_fx );
     501       27339 :             exp2 = sub( norm_l( temp2 ), 1 );
     502       27339 :             temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp2, exp2 ) );
     503       27339 :             temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q2, exp2 ) ), 31 );
     504       27339 :             if ( temp == 0 )
     505             :             {
     506        2754 :                 temp_q = 31;
     507        2754 :                 move16();
     508             :             }
     509       27339 :             IF( LT_16( temp_q, temp_q1 ) )
     510             :             {
     511         594 :                 ff_fx[j] = L_add( L_shr( temp1, sub( temp_q1, temp_q ) ), temp );
     512         594 :                 move32();
     513         594 :                 ff_q_fx[j] = temp_q;
     514         594 :                 move16();
     515             :             }
     516             :             ELSE
     517             :             {
     518       26745 :                 ff_fx[j] = L_add( temp1, L_shr( temp, sub( temp_q, temp_q1 ) ) );
     519       26745 :                 move32();
     520       26745 :                 ff_q_fx[j] = temp_q1;
     521       26745 :                 move16();
     522             :             }
     523             : 
     524       27339 :             exp1 = norm_l( km_fx );
     525       27339 :             exp2 = sub( norm_l( temp1 ), 1 );
     526       27339 :             temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp1, exp2 ) );
     527       27339 :             temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q1, exp2 ) ), 31 );
     528       27339 :             if ( temp == 0 )
     529             :             {
     530        2754 :                 temp_q = 31;
     531        2754 :                 move16();
     532             :             }
     533       27339 :             IF( LT_16( temp_q, temp_q2 ) )
     534             :             {
     535        6299 :                 ff_fx[n] = L_add( L_shr( temp2, sub( temp_q2, temp_q ) ), temp );
     536        6299 :                 move32();
     537        6299 :                 ff_q_fx[n] = temp_q;
     538        6299 :                 move16();
     539             :             }
     540             :             ELSE
     541             :             {
     542       21040 :                 ff_fx[n] = L_add( temp2, L_shr( temp, sub( temp_q, temp_q2 ) ) );
     543       21040 :                 move32();
     544       21040 :                 ff_q_fx[n] = temp_q2;
     545       21040 :                 move16();
     546             :             }
     547             :         }
     548             : 
     549        5718 :         IF( s_and( m, 1 ) )
     550             :         {
     551        2879 :             exp1 = norm_l( denom_fx );
     552        2879 :             exp2 = sub( norm_l( ff_fx[j] ), 1 );
     553        2879 :             temp1 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[j], exp2 ) );
     554        2879 :             temp_q1 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[j], exp2 ) ), 31 );
     555             : 
     556        2879 :             exp1 = norm_l( km_fx );
     557        2879 :             exp2 = sub( norm_l( temp1 ), 1 );
     558        2879 :             temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp1, exp2 ) );
     559        2879 :             temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q1, exp2 ) ), 31 );
     560        2879 :             if ( temp == 0 )
     561             :             {
     562         306 :                 temp_q = 31;
     563         306 :                 move16();
     564             :             }
     565        2879 :             IF( LT_16( temp_q, temp_q1 ) )
     566             :             {
     567         168 :                 ff_fx[j] = L_add( L_shr( temp1, sub( temp_q1, temp_q ) ), temp );
     568         168 :                 move32();
     569         168 :                 ff_q_fx[j] = temp_q;
     570         168 :                 move16();
     571             :             }
     572             :             ELSE
     573             :             {
     574        2711 :                 ff_fx[j] = L_add( temp1, L_shr( temp, sub( temp_q, temp_q1 ) ) );
     575        2711 :                 move32();
     576        2711 :                 ff_q_fx[j] = temp_q1;
     577        2711 :                 move16();
     578             :             }
     579             :         }
     580             :     }
     581             : 
     582         147 :     return 1;
     583             : }
     584             : 
     585          24 : 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          24 :     yy_fx = &buf_fx[0];
     604             : 
     605             :     /*------------------------------------------------------------------*
     606             :      * copy initial filter states into synthesis buffer and do synthesis
     607             :      *------------------------------------------------------------------*/
     608         504 :     FOR( i = 0; i < m; i++ )
     609             :     {
     610         480 :         *yy_fx++ = mem_fx[i];
     611         480 :         move32();
     612         480 :         yy_q_fx[i] = mem_q_fx;
     613         480 :         move16();
     614             :     }
     615             : 
     616             :     /*-----------------------------------------------------------------------*
     617             :      * Do the filtering
     618             :      *-----------------------------------------------------------------------*/
     619             : 
     620        1416 :     FOR( i = 0; i < l; i++ )
     621             :     {
     622        1392 :         s_fx = x_fx[i];
     623        1392 :         move64();
     624        1392 :         s_q_fx = Q31;
     625        1392 :         move16();
     626       29232 :         FOR( j = 1; j <= m; j++ )
     627             :         {
     628       27840 :             exp1 = sub( norm_l( a_fx[j] ), 1 );
     629       27840 :             exp2 = sub( norm_l( yy_fx[i - j] ), 1 );
     630       27840 :             IF( GT_16( j, i ) )
     631             :             {
     632        5040 :                 temp_q = mem_q_fx;
     633        5040 :                 move16();
     634             :             }
     635             :             ELSE
     636             :             {
     637       22800 :                 temp_q = yy_q_fx[i - j];
     638       22800 :                 move16();
     639             :             }
     640       27840 :             temp = Mpy_32_32( L_shl( a_fx[j], exp1 ), L_shl( yy_fx[i - j], exp2 ) );
     641       27840 :             temp_q = sub( add( add( a_q_fx[j], exp1 ), add( temp_q, exp2 ) ), 31 );
     642             : 
     643       27840 :             IF( LT_16( s_q_fx, temp_q ) )
     644             :             {
     645       24530 :                 s_fx = W_sub( s_fx, L_shr( temp, sub( temp_q, s_q_fx ) ) );
     646             :             }
     647             :             ELSE
     648             :             {
     649             : #ifdef FIX_ISSUE_1811_EXCEEDING_W_SHIFTS
     650        3310 :                 s_fx = W_sub( W_shr( s_fx, s_min( 63, sub( s_q_fx, temp_q ) ) ), temp );
     651             : #else
     652             :                 s_fx = W_sub( W_shr( s_fx, sub( s_q_fx, temp_q ) ), temp );
     653             : #endif
     654        3310 :                 s_q_fx = temp_q;
     655        3310 :                 move16();
     656             :             }
     657             :         }
     658        1392 :         tmp = W_norm( s_fx );
     659        1392 :         s_fx = W_shl( s_fx, tmp );
     660        1392 :         s_q_fx = add( s_q_fx, tmp );
     661        1392 :         yy_fx[i] = W_extract_h( s_fx );
     662        1392 :         move32();
     663        1392 :         yy_q_fx[i] = sub( s_q_fx, 32 );
     664        1392 :         move16();
     665        1392 :         y_fx[i] = W_extract_l( W_shr( s_fx, sub( s_q_fx, Q5 ) ) );
     666        1392 :         move32();
     667             :     }
     668          24 :     *y_q_fx = Q5;
     669          24 :     move16();
     670             : 
     671          24 :     return;
     672             : }
     673             : 
     674             : /*-----------------------------------------------------------------------------------------*
     675             :  * Function check_stab_fx()
     676             :  *
     677             :  * LPC filter stability check applying given sharpening value delta
     678             :  *-----------------------------------------------------------------------------------------*/
     679             : 
     680         306 : static Word16 check_stab_fx(
     681             :     Word32 *a_fx,
     682             :     Word16 *a_q_fx,
     683             :     Word32 delta_fx,
     684             :     Word16 delta_q_fx )
     685             : {
     686             :     Word16 i;
     687             :     Word16 stable;
     688             : 
     689             :     Word32 amod_fx[LFE_PLC_LPCORD], refl_fx[LFE_PLC_LPCORD];
     690             :     Word16 fac_q_fx, fac1_q_fx, amod_q_fx[LFE_PLC_LPCORD];
     691             :     Word16 exp1, exp2;
     692             :     Word32 fac_fx, fac1_fx;
     693             : 
     694         306 :     exp1 = norm_l( delta_fx );
     695         306 :     delta_fx = L_shl( delta_fx, exp1 );
     696         306 :     delta_q_fx = add( delta_q_fx, exp1 );
     697             : 
     698         306 :     IF( LT_16( delta_q_fx, 29 ) )
     699             :     {
     700           0 :         fac_fx = L_add( L_shr( ONE_IN_Q29, sub( 29, delta_q_fx ) ), delta_fx );
     701           0 :         fac_q_fx = delta_q_fx;
     702           0 :         move16();
     703             :     }
     704             :     ELSE
     705             :     {
     706         306 :         fac_fx = L_add( ONE_IN_Q29, L_shr( delta_fx, sub( delta_q_fx, 29 ) ) );
     707         306 :         fac_q_fx = Q29;
     708         306 :         move16();
     709             :     }
     710         306 :     fac1_fx = fac_fx;
     711         306 :     move32();
     712         306 :     fac1_q_fx = fac_q_fx;
     713         306 :     move16();
     714             : 
     715        6426 :     FOR( i = 0; i < LFE_PLC_LPCORD; i++ )
     716             :     {
     717        6120 :         exp1 = norm_l( a_fx[i] );
     718        6120 :         exp2 = norm_l( fac_fx );
     719        6120 :         amod_fx[i] = Mpy_32_32( L_shl( a_fx[i], exp1 ), L_shl( fac_fx, exp2 ) );
     720        6120 :         move32();
     721        6120 :         amod_q_fx[i] = sub( add( add( a_q_fx[i], exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     722        6120 :         move16();
     723        6120 :         if ( amod_fx[i] == 0 )
     724             :         {
     725         306 :             amod_q_fx[i] = 31;
     726         306 :             move16();
     727             :         }
     728        6120 :         exp1 = norm_l( fac_fx );
     729        6120 :         exp2 = norm_l( fac1_fx );
     730        6120 :         fac_fx = Mpy_32_32( L_shl( fac_fx, exp1 ), L_shl( fac1_fx, exp2 ) );
     731        6120 :         fac_q_fx = sub( add( add( fac_q_fx, exp1 ), add( fac1_q_fx, exp2 ) ), 31 );
     732        6120 :         if ( fac_fx == 0 )
     733             :         {
     734           0 :             fac_q_fx = 0;
     735           0 :             move16();
     736             :         }
     737             :     }
     738         306 :     stable = d_a2rc_fx( amod_fx, amod_q_fx, refl_fx, LFE_PLC_LPCORD );
     739             : 
     740         306 :     return stable;
     741             : }
     742             : 
     743             : /*-----------------------------------------------------------------------------------------*
     744             :  * Function find_max_delta_fx()
     745             :  *
     746             :  * Find maximum LPC filter sharpening by iteration to get a filter that is almost instable
     747             :  *-----------------------------------------------------------------------------------------*/
     748             : 
     749          24 : static Word32 find_max_delta_fx(
     750             :     Word32 *a_fx,
     751             :     Word16 *a_q_fx,
     752             :     Word16 *delta_q_fx )
     753             : {
     754             :     Word16 stable;
     755             :     Word16 eps_q_fx, fac_q_fx, exp1, exp2;
     756             :     Word32 delta_fx, fac_fx, eps_fx, temp;
     757             : 
     758          24 :     delta_fx = 0;
     759          24 :     move32();
     760          24 :     eps_fx = 21474836; // 0.01 in Q31
     761          24 :     move32();
     762          24 :     fac_fx = 1073741824; // 2 in Q29
     763          24 :     move32();
     764          24 :     eps_q_fx = Q31;
     765          24 :     move16();
     766          24 :     fac_q_fx = Q29;
     767          24 :     move16();
     768             : 
     769          24 :     stable = FALSE;
     770          24 :     move16();
     771             : 
     772          44 :     WHILE( check_stab_fx( a_fx, a_q_fx, eps_fx, eps_q_fx ) )
     773             :     {
     774          20 :         exp1 = norm_l( eps_fx );
     775          20 :         exp2 = norm_l( fac_fx );
     776          20 :         eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
     777          20 :         eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     778          20 :         stable = TRUE;
     779          20 :         move16();
     780             :     }
     781          24 :     fac_fx = 1073741824; // 0.5 in Q31
     782          24 :     move32();
     783          24 :     fac_q_fx = Q31;
     784          24 :     move16();
     785             : 
     786          24 :     IF( stable )
     787             :     {
     788          10 :         exp1 = norm_l( eps_fx );
     789          10 :         exp2 = norm_l( fac_fx );
     790          10 :         eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
     791          10 :         eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     792             :     }
     793             : 
     794          48 :     WHILE( !stable )
     795             :     {
     796          24 :         exp1 = norm_l( eps_fx );
     797          24 :         exp2 = norm_l( fac_fx );
     798          24 :         eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
     799          24 :         eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     800             : 
     801          24 :         stable = check_stab_fx( a_fx, a_q_fx, eps_fx, eps_q_fx );
     802             :     }
     803             : 
     804             :     /* must be stable with current eps */
     805          24 :     *delta_q_fx = sub( norm_l( eps_fx ), 1 );
     806          24 :     delta_fx = L_shl( eps_fx, *delta_q_fx );
     807          24 :     *delta_q_fx = add( eps_q_fx, *delta_q_fx );
     808          24 :     move16();
     809          24 :     move16();
     810             : 
     811          24 :     exp1 = norm_l( eps_fx );
     812          24 :     exp2 = norm_l( fac_fx );
     813          24 :     eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
     814          24 :     eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     815             : 
     816             :     WHILE( 1 )
     817             :     {
     818         238 :         IF( LT_16( *delta_q_fx, eps_q_fx ) )
     819             :         {
     820         238 :             delta_fx = L_add( delta_fx, L_shr( eps_fx, sub( eps_q_fx, *delta_q_fx ) ) );
     821             :         }
     822             :         ELSE
     823             :         {
     824           0 :             delta_fx = L_add( L_shr( delta_fx, sub( *delta_q_fx, eps_q_fx ) ), eps_fx );
     825           0 :             *delta_q_fx = eps_q_fx;
     826           0 :             move16();
     827             :         }
     828         238 :         stable = check_stab_fx( a_fx, a_q_fx, delta_fx, *delta_q_fx );
     829             : 
     830         238 :         IF( !stable )
     831             :         {
     832         125 :             temp = L_abs( eps_fx );
     833         125 :             IF( GT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) )
     834             :             {
     835         113 :                 exp1 = norm_l( -temp );
     836         113 :                 exp2 = norm_l( fac_fx );
     837         113 :                 eps_fx = Mpy_32_32( L_shl( -temp, exp1 ), L_shl( fac_fx, exp2 ) );
     838         113 :                 eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     839             :             }
     840             :             ELSE
     841             :             {
     842          12 :                 eps_fx = L_negate( L_abs( eps_fx ) );
     843             :             }
     844             :         }
     845             :         ELSE
     846             :         {
     847         113 :             temp = L_abs( eps_fx );
     848         113 :             if ( LT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) )
     849             :             {
     850          24 :                 BREAK;
     851             :             }
     852             : 
     853          89 :             exp1 = norm_l( temp );
     854          89 :             exp1 = norm_l( fac_fx );
     855          89 :             eps_fx = Mpy_32_32( L_shl( temp, exp1 ), L_shl( fac_fx, exp2 ) );
     856          89 :             eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
     857             :         }
     858             :     }
     859             : 
     860          24 :     return delta_fx;
     861             : }
     862             : 
     863             : /*-----------------------------------------------------------------------------------------*
     864             :  * Function recover_samples_fx()
     865             :  *
     866             :  * recover lost samples by extrapolation of signal buffer
     867             :  *-----------------------------------------------------------------------------------------*/
     868             : 
     869         151 : static void recover_samples_fx(
     870             :     const Word16 bfi_count,
     871             :     const Word32 *outbuf_fx,
     872             :     Word16 outbuf_q_fx,
     873             :     Word32 *rec_frame_fx,
     874             :     Word16 *rec_frame_q_fx )
     875             : {
     876             :     Word16 i;
     877             :     Word32 d_outbuf_fx[LFE_PLC_BUFLEN], d_a_fx[LFE_PLC_LPCORD + 1];
     878             :     Word16 d_r_q_fx[LFE_PLC_LPCORD + 1], d_a_q_fx[LFE_PLC_LPCORD + 1];
     879             :     Word32 d_r_fx[LFE_PLC_LPCORD + 1], zeroes_fx[LFE_PLC_RECLEN];
     880             :     Word32 delta_fx, fac_fx, att_fx, temp;
     881             :     Word16 delta_q_fx, fac_q_fx, temp_q, exp1, exp2;
     882             : 
     883         151 :     Copy32( outbuf_fx, d_outbuf_fx, LFE_PLC_BUFLEN );
     884             : 
     885         151 :     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 );
     886             : 
     887         151 :     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 ) ) ) )
     888             :     {
     889         127 :         set_zero_fx( rec_frame_fx, LFE_PLC_RECLEN );
     890         127 :         return;
     891             :     }
     892             : 
     893          24 :     lfeplc_lev_dur_fx( d_a_fx, d_a_q_fx, d_r_fx, d_r_q_fx, LFE_PLC_LPCORD );
     894             : 
     895          24 :     delta_fx = find_max_delta_fx( d_a_fx + 1, d_a_q_fx + 1, &delta_q_fx );
     896             : 
     897          24 :     IF( LT_16( delta_q_fx, Q29 ) )
     898             :     {
     899           0 :         fac_fx = L_add( L_shr( ONE_IN_Q29, sub( Q29, delta_q_fx ) ), delta_fx );
     900           0 :         fac_q_fx = delta_q_fx;
     901           0 :         move16();
     902             :     }
     903             :     ELSE
     904             :     {
     905          24 :         fac_fx = L_add( ONE_IN_Q29, L_shr( delta_fx, sub( delta_q_fx, Q29 ) ) );
     906          24 :         fac_q_fx = Q29;
     907          24 :         move16();
     908             :     }
     909          24 :     att_fx = ONE_IN_Q31;
     910          24 :     move32();
     911             : 
     912          24 :     IF( GE_16( bfi_count, LFE_PLC_MUTE_THR ) )
     913             :     {
     914           0 :         att_fx = LFE_PLC_BURST_ATT_Q31;
     915           0 :         move32();
     916           0 :         fac_fx = Mpy_32_32( fac_fx, att_fx );
     917             :     }
     918             : 
     919         504 :     FOR( i = 1; i <= LFE_PLC_LPCORD; i++ )
     920             :     {
     921         480 :         d_a_fx[i] = Mpy_32_32( d_a_fx[i], fac_fx );
     922         480 :         move32();
     923         480 :         d_a_q_fx[i] = sub( add( d_a_q_fx[i], fac_q_fx ), 31 );
     924         480 :         move16();
     925         480 :         if ( d_a_fx[i] == 0 )
     926             :         {
     927          24 :             d_a_q_fx[i] = 31;
     928          24 :             move16();
     929             :         }
     930         480 :         IF( LT_16( delta_q_fx, Q30 ) )
     931             :         {
     932           0 :             temp = L_add( L_shr( ONE_IN_Q30, sub( Q30, delta_q_fx ) ), delta_fx );
     933           0 :             temp_q = delta_q_fx;
     934           0 :             move16();
     935             :         }
     936             :         ELSE
     937             :         {
     938         480 :             temp = L_add( ONE_IN_Q30, L_shr( delta_fx, sub( delta_q_fx, Q30 ) ) );
     939         480 :             temp_q = Q30;
     940         480 :             move16();
     941             :         }
     942         480 :         exp2 = norm_l( temp );
     943         480 :         temp = Mpy_32_32( att_fx, L_shl( temp, exp2 ) );
     944         480 :         temp_q = add( temp_q, exp2 );
     945             : 
     946         480 :         exp1 = norm_l( fac_fx );
     947         480 :         exp2 = norm_l( temp );
     948         480 :         fac_fx = Mpy_32_32( L_shl( fac_fx, exp1 ), L_shl( temp, exp2 ) );
     949         480 :         fac_q_fx = sub( add( add( fac_q_fx, exp1 ), add( temp_q, exp2 ) ), 31 );
     950             :     }
     951             : 
     952          24 :     set_zero_fx( zeroes_fx, LFE_PLC_RECLEN );
     953             : 
     954          24 :     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 );
     955             : 
     956          24 :     return;
     957             : }
     958             : /*-----------------------------------------------------------------------------------------*
     959             :  * Function ivas_lfe_tdplc_fx()
     960             :  *
     961             :  * MDCT interface recover lost samples by extrapolation of signal buffer
     962             :  *-----------------------------------------------------------------------------------------*/
     963             : 
     964         151 : void ivas_lfe_tdplc_fx(
     965             :     LFE_DEC_HANDLE hLFE,      /* i/o: LFE decoder handle           */
     966             :     const Word32 *prevsynth,  /* i  : previous frame synthesis     */
     967             :     Word32 *ytda,             /* o  : output time-domain buffer    */
     968             :     const Word16 output_frame /* i  : output frame length          */
     969             : )
     970             : {
     971             :     Word32 rec_frame_us_fx[LFE_PLC_RECLEN_48K], input_tda_fx[L_FRAME48k];
     972             :     Word32 rec_frame_fx[LFE_PLC_RECLEN], prevsynth_fx[LFE_PLC_BUFLEN];
     973             :     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];
     974             :     Word16 prevsynth_16_fx[LFE_PLC_BUFLEN];
     975             :     const Word32 *pWindow_coeffs_fx;
     976             :     Word32 output_Fs;
     977             :     Word16 i, fade_len, full_len, dct_len, zero_pad_len, plc_fdel, rec_frame_len;
     978             :     Word16 prevsynth_q_fx, rec_frame_q, temp_q, idx, exp;
     979             : 
     980         151 :     output_Fs = L_mult0( output_frame, FRAMES_PER_SEC );
     981         151 :     fade_len = hLFE->pWindow_state->fade_len;
     982         151 :     move16();
     983         151 :     full_len = hLFE->pWindow_state->full_len;
     984         151 :     move16();
     985         151 :     dct_len = hLFE->pWindow_state->dct_len;
     986         151 :     move16();
     987         151 :     zero_pad_len = hLFE->pWindow_state->zero_pad_len;
     988         151 :     move16();
     989         151 :     pWindow_coeffs_fx = hLFE->pWindow_state->pWindow_coeffs_fx;
     990             : 
     991             :     /* plc_fdel = (int16_t) ( LFE_PLC_FDEL * output_Fs / 48000 ); */
     992         151 :     plc_fdel = extract_l( Mpy_32_32( output_Fs, 13421773 /* ( LFE_PLC_FDEL / 48000 ) in Q31 */ ) );
     993             :     /* rec_frame_len = (int16_t) ( LFE_PLC_RECLEN_48K * output_Fs / 48000 ); */
     994         151 :     rec_frame_len = extract_l( Mpy_32_32_r( output_Fs, 77846282 /* LFE_PLC_RECLEN_48K / 48000 in Q31 */ ) );
     995             : 
     996         151 :     Copy32( prevsynth, prevsynth_fx, LFE_PLC_BUFLEN );
     997         151 :     exp = L_norm_arr( prevsynth_fx, LFE_PLC_BUFLEN );
     998         151 :     scale_sig32( prevsynth_fx, LFE_PLC_BUFLEN, exp );
     999         151 :     prevsynth_q_fx = add( Q9, exp );
    1000         151 :     move16();
    1001             : 
    1002         151 :     recover_samples_fx( hLFE->bfi_count, prevsynth_fx, prevsynth_q_fx, rec_frame_fx, &rec_frame_q );
    1003             : 
    1004         151 :     set16_fx( mem_fx, 0, 2 * LFE_PLC_FDEL / LFE_PLC_DSF );
    1005             : 
    1006         151 :     Copy_Scale_sig_32_16( prevsynth_fx, prevsynth_16_fx, LFE_PLC_BUFLEN, -prevsynth_q_fx ); // Q0
    1007         151 :     Copy_Scale_sig_32_16( rec_frame_fx, rec_frame_16_fx, LFE_PLC_RECLEN, -Q5 );             // Q0
    1008             : 
    1009             :     Word16 Q_new_inp, mem_decim_size, size_modified;
    1010         151 :     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 );
    1011         151 :     Scale_sig( rec_frame_us_16_fx, size_modified, negate( Q_new_inp ) ); /* scaling back to Q0 */
    1012             : 
    1013         151 :     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 );
    1014         151 :     Scale_sig( rec_frame_us_16_fx, size_modified, negate( Q_new_inp ) ); /* scaling back to Q0 */
    1015             : 
    1016             :     /*samples are generated with 48k sampling rate
    1017             :     and then converted to required sampling rate by simple decimation
    1018             :     as signal is already bandlimited*/
    1019             : 
    1020             :     /*decimation to correct sampling rate*/
    1021         151 :     IF( NE_32( output_Fs, 48000 ) )
    1022             :     {
    1023        5805 :         FOR( i = 0; i < rec_frame_len; i++ )
    1024             :         {
    1025        5800 :             idx = BASOP_Util_Divide3232_Scale( Mpy_32_32( L_shl( i, 16 ), L_shl( 44100, 15 ) ), output_Fs, &temp_q );
    1026        5800 :             idx = shr( idx, add( sub( 15, temp_q ), 1 ) );
    1027        5800 :             rec_frame_us_16_fx[i] = rec_frame_us_16_fx[idx];
    1028        5800 :             move16();
    1029             :         }
    1030             :     }
    1031             : 
    1032         151 :     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
    1033             : 
    1034         453 :     FOR( i = 0; i < 2; i++ )
    1035             :     {
    1036         302 :         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 ) ) );
    1037         302 :         ivas_tda_fx( input_tda_fx, ytda + imult1616( i, dct_len ), dct_len );
    1038             :     }
    1039             : 
    1040         151 :     return;
    1041             : }

Generated by: LCOV version 1.14