LCOV - code coverage report
Current view: top level - lib_com - hp50_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 57b3a0619c6acf2354f43c9b971cc11e014725cb Lines: 298 326 91.4 %
Date: 2025-10-22 22:22:21 Functions: 6 6 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             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <stdint.h>
      38             : #include <math.h>
      39             : #include "options.h"
      40             : #include "prot_fx.h"
      41             : #include "wmc_auto.h"
      42             : 
      43             : #define HP20_COEFF_SCALE    ( 2 )
      44             : #define HP20_FX_COEFF_SCALE ( 1 )
      45             : /*
      46             :  * hp20
      47             :  *
      48             :  * Function:
      49             :  *    2nd order high pass filter with nominal cut off frequency at 20 Hz.
      50             :  *
      51             :  * Returns:
      52             :  *    void
      53             :  */
      54             : 
      55    15821400 : static Word32 HP50_Mode2_Mpy_32_16_fix( Word32 a, Word16 b )
      56             : {
      57    15821400 :     Word32 result = Mpy_32_16_1( a, b );
      58             :     /* perform rounding towards lower value for negative results */
      59    15821400 :     if ( result < 0 )
      60     7830017 :         result = L_add( result, 1 );
      61    15821400 :     return result;
      62             : }
      63             : 
      64    10578600 : static Word32 HP50_Mpy_32_32_fix( Word32 a, Word32 b )
      65             : {
      66    10578600 :     Word32 result = Mpy_32_32( a, b );
      67             :     /* perform rounding towards lower value for negative results */
      68    10578600 :     if ( result < 0 )
      69     5288099 :         result = L_add( result, 1 );
      70    10578600 :     return result;
      71             : }
      72             : 
      73             : 
      74        6200 : static void filter_2nd_order(
      75             :     Word16 signal[],
      76             :     const Word16 stride,
      77             :     const Word16 prescale,
      78             :     const Word16 lg,
      79             :     Word32 mem[4],
      80             :     Word32 a1,
      81             :     Word32 a2,
      82             :     Word32 b1,
      83             :     Word32 b2 )
      84             : {
      85             : 
      86             :     Word16 i;
      87             :     Word16 x2, x1;
      88             :     Word32 L_sum, L_y1, L_y2;
      89             : 
      90             :     /*
      91             :      * Saturation: The states of the filter, namely L_y1 and L_y2 shall
      92             :      * never saturate, because that causes error in the filter feedback.
      93             :      * The final output written into signal[] might saturate because of
      94             :      * unavoidable filter overshoot.
      95             :      */
      96             : 
      97             :     /* Execute first 2 iterations with 32-bit x anx y memory values */
      98             :     BASOP_SATURATE_ERROR_ON_EVS
      99        6200 :     L_sum = HP50_Mpy_32_32_fix( b2, mem[2] );                 /* b2*x2 */
     100        6200 :     L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( b1, mem[3] ) ); /* b1*x1 */
     101        6200 :     x2 = shr( signal[0], prescale );
     102        6200 :     L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x2 ) ); /* b2*x0 */
     103        6200 :     L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[0], a2 ) );   /* y2*a2 */
     104        6200 :     L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[1], a1 ) );   /* y1*a1 */
     105             : 
     106        6200 :     L_y2 = L_shl_sat( L_sum, HP20_COEFF_SCALE );
     107             :     BASOP_SATURATE_ERROR_OFF_EVS
     108             :     BASOP_SATURATE_WARNING_OFF_EVS
     109        6200 :     signal[0] = round_fx_sat( L_shl_sat( L_y2, prescale ) );
     110             : 
     111             :     BASOP_SATURATE_WARNING_ON_EVS
     112             : 
     113             :     BASOP_SATURATE_ERROR_ON_EVS
     114        6200 :     L_sum = HP50_Mpy_32_32_fix( b2, mem[3] );                   /* b2*x2 */
     115        6200 :     L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b1, x2 ) ); /* b1*x1 */
     116        6200 :     x1 = shr( signal[stride], prescale );
     117        6200 :     L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x1 ) ); /* b2*x0 */
     118        6200 :     L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[1], a2 ) );   /* y2*a2 */
     119        6200 :     L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a1 ) );     /* y1*a1 */
     120             : 
     121        6200 :     L_y1 = L_shl_sat( L_sum, HP20_COEFF_SCALE );
     122             :     BASOP_SATURATE_ERROR_OFF_EVS
     123             :     BASOP_SATURATE_WARNING_OFF_EVS
     124        6200 :     signal[stride] = round_fx_sat( L_shl_sat( L_y1, prescale ) );
     125             :     BASOP_SATURATE_WARNING_ON_EVS
     126        6200 :     move16();
     127             : 
     128             :     /* New we use a trick and toggle x1/x2 and L_y1/L_y2 to save a few cycles unrolling the loop by 2 */
     129     2640000 :     FOR( i = 2; i < lg; i += 2 )
     130             :     {
     131             :         /* y[i+0] = b2*x[i-2] + b1*x[i-1] + b2*x[i-0] + a2*y[i-2] + a1*y[i-1];  */
     132             :         BASOP_SATURATE_ERROR_ON_EVS
     133     2633800 :         L_sum = HP50_Mode2_Mpy_32_16_fix( b2, x2 );
     134     2633800 :         L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b1, x1 ) );
     135     2633800 :         x2 = shr( signal[i * stride], prescale );
     136     2633800 :         L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x2 ) );
     137     2633800 :         L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a2 ) );
     138     2633800 :         L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y1, a1 ) );
     139             : 
     140     2633800 :         L_y2 = L_shl_sat( L_sum, HP20_COEFF_SCALE );
     141             :         BASOP_SATURATE_ERROR_OFF_EVS
     142             :         BASOP_SATURATE_WARNING_OFF_EVS
     143     2633800 :         signal[i_mult( i, stride )] = round_fx_sat( L_shl_sat( L_y2, prescale ) );
     144             :         BASOP_SATURATE_WARNING_ON_EVS
     145             :         /* y[i+1] = b2*x[i-1] + b1*x[i-0] + b2*x[i+1] + a2*y[i-1] + a1*y[i+0];  */
     146             :         BASOP_SATURATE_ERROR_ON_EVS
     147     2633800 :         L_sum = HP50_Mode2_Mpy_32_16_fix( b2, x1 );
     148     2633800 :         L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b1, x2 ) );
     149     2633800 :         x1 = shr( signal[( i + 1 ) * stride], prescale );
     150     2633800 :         L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x1 ) );
     151     2633800 :         L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y1, a2 ) );
     152     2633800 :         L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a1 ) );
     153             : 
     154     2633800 :         L_y1 = L_shl_sat( L_sum, HP20_COEFF_SCALE );
     155             :         BASOP_SATURATE_ERROR_OFF_EVS
     156             :         BASOP_SATURATE_WARNING_OFF_EVS
     157     2633800 :         signal[i_mult( add( i, 1 ), stride )] = round_fx_sat( L_shl_sat( L_y1, prescale ) );
     158             :         BASOP_SATURATE_WARNING_ON_EVS
     159     2633800 :         move16();
     160             :     }
     161             :     /* update static filter memory from variables */
     162        6200 :     mem[0] = L_y2;
     163        6200 :     move32();
     164        6200 :     mem[1] = L_y1;
     165        6200 :     move32();
     166        6200 :     mem[2] = L_deposit_h( x2 );
     167        6200 :     move32();
     168        6200 :     mem[3] = L_deposit_h( x1 );
     169        6200 :     move32();
     170             : 
     171             : 
     172        6200 :     return;
     173             : }
     174             : 
     175             : 
     176        6200 : void hp20( Word16 signal[],     /* i/o: signal to filter                   any */
     177             :            const Word16 stride, /* i  : stride to be applied accessing signal  */
     178             :            const Word16 lg,     /* i  : length of signal (integer)          Q0 */
     179             :            Word32 mem[5],       /* i/o: static filter memory with this layout: */
     180             :            /*      mem[0]: y[-2] (32-bit)                 */
     181             :            /*      mem[1]; y[-1] (32-bit)                 */
     182             :            /*      mem[2]: x[-2] << 16                    */
     183             :            /*      mem[3]: x[-1] << 16                    */
     184             :            /* Note: mem[0..3] need to be scaled per frame */
     185             :            /*      mem[4]: states scale                   */
     186             :            const Word32 sFreq ) /* i  : input sampling rate                 Q0 */
     187             : {
     188             :     Word32 a1, b1, a2, b2;
     189             :     Word16 prescale, prescaleOld, diff;
     190             : 
     191        6200 :     prescale = getScaleFactor16( signal, lg );
     192        6200 :     prescaleOld = extract_l( mem[4] );
     193        6200 :     diff = norm_l( L_shl_sat( mem[2], prescaleOld ) );
     194        6200 :     if ( mem[2] != 0 )
     195             :     {
     196        6163 :         prescale = s_min( prescale, diff );
     197             :     }
     198        6200 :     diff = norm_l( L_shl_sat( mem[3], prescaleOld ) );
     199        6200 :     if ( mem[3] != 0 )
     200             :     {
     201        6164 :         prescale = s_min( prescale, diff );
     202             :     }
     203             :     /* Take into account the left shift performed into the loop + 1 bit headroom*/
     204        6200 :     prescale = s_max( -12, sub( 1 + HP20_COEFF_SCALE, prescale ) );
     205        6200 :     IF( prescale != prescaleOld )
     206             :     {
     207        2598 :         diff = sub( prescale, prescaleOld );
     208        2598 :         mem[0] = L_shr_sat( mem[0], diff );
     209        2598 :         move32();
     210        2598 :         mem[1] = L_shr_sat( mem[1], diff );
     211        2598 :         move32();
     212        2598 :         mem[2] = L_shr_sat( mem[2], diff );
     213        2598 :         move32();
     214        2598 :         mem[3] = L_shr_sat( mem[3], diff ); //?sat
     215        2598 :         move32();
     216        2598 :         mem[4] = L_deposit_l( prescale );
     217             :     }
     218             : 
     219        6200 :     IF( EQ_32( sFreq, 8000 ) )
     220             :     {
     221             :         /* hp filter 20Hz at 3dB for 8000 Hz input sampling rate
     222             :            [b,a] = butter(2, 20.0/4000.0, 'high');
     223             :            b = [0.988954248067140  -1.977908496134280   0.988954248067140]
     224             :            a = [1.000000000000000  -1.977786483776764   0.978030508491796]*/
     225           0 :         a1 = 1061816033l /* 1.977786483776764 Q29*/;
     226           0 :         move32();
     227           0 :         a2 = -525076131l /*-0.978030508491796 Q29*/;
     228           0 :         move32();
     229           0 :         b1 = -1061881538l /*-1.977908496134280 Q29*/;
     230           0 :         move32();
     231           0 :         b2 = 530940769l /* 0.988954248067140 Q29*/;
     232           0 :         move32();
     233             :     }
     234        6200 :     ELSE IF( EQ_32( sFreq, 16000 ) )
     235             :     {
     236             :         /* hp filter 20Hz at 3dB for 16000KHz sampling rate
     237             :            [b,a] = butter(2, 20.0/8000.0, 'high');
     238             :            b = [0.994461788958195  -1.988923577916390   0.994461788958195]
     239             :            a = [1.000000000000000  -1.988892905899653   0.988954249933127] */
     240           0 :         a1 = 1067778748l /* 1.988892905899653 Q29*/;
     241           0 :         move32();
     242           0 :         a2 = -530940770l /*-0.988954249933127 Q29*/;
     243           0 :         move32();
     244           0 :         b1 = -1067795215l /*-1.988923577916390 Q29*/;
     245           0 :         move32();
     246           0 :         b2 = 533897608l /* 0.994461788958195 Q29*/;
     247           0 :         move32();
     248             :     }
     249        6200 :     ELSE IF( EQ_32( sFreq, 32000 ) )
     250             :     {
     251             :         /* hp filter 20Hz at 3dB for 32000KHz sampling rate
     252             :            [b,a] = butter(2, 20.0/16000.0, 'high');
     253             :            b = [0.997227049904470  -1.994454099808940   0.997227049904470]
     254             :            a = [1.000000000000000  -1.994446410541927   0.994461789075954]*/
     255        2100 :         a1 = 1070760263l /* 1.994446410541927 Q29*/;
     256        2100 :         move32();
     257        2100 :         a2 = -533897608l /*-0.994461789075954 Q29*/;
     258        2100 :         move32();
     259        2100 :         b1 = -1070764392l /*-1.994454099808940 Q29*/;
     260        2100 :         move32();
     261        2100 :         b2 = 535382196l /* 0.997227049904470 Q29*/;
     262        2100 :         move32();
     263             :     }
     264             :     ELSE
     265             :     {
     266        4100 :         assert( sFreq == 48000 );
     267             :         /* hp filter 20Hz at 3dB for 48000KHz sampling rate
     268             :            [b,a] = butter(2, 20.0/24000.0, 'high');
     269             :            b =[0.998150511190452  -1.996301022380904   0.998150511190452]
     270             :            a =[1.000000000000000  -1.996297601769122   0.996304442992686]*/
     271        4100 :         a1 = 1071754114l /* 1.996297601769122 Q29*/;
     272        4100 :         move32();
     273        4100 :         a2 = -534886875l /*-0.996304442992686 Q29*/;
     274        4100 :         move32();
     275        4100 :         b1 = -1071755951l /*-1.996301022380904 Q29*/;
     276        4100 :         move32();
     277        4100 :         b2 = 535877975l /* 0.998150511190452 Q29*/;
     278        4100 :         move32();
     279             :     }
     280             : 
     281             : 
     282        6200 :     filter_2nd_order( signal, stride, prescale, lg,
     283             :                       mem, a1, a2, b1, b2 );
     284             : 
     285        6200 :     return;
     286             : }
     287             : 
     288             : 
     289     1096060 : void hp20_fx_32_opt(
     290             :     Word32 signal_fx[],
     291             :     const Word16 lg,
     292             :     Word32 mem_fx[],
     293             :     const Word32 Fs )
     294             : {
     295             :     Word32 i;
     296             :     Word32 a1_fx, a2_fx, b1_fx, b2_fx;
     297             :     Word16 prescale, prescaleOld, prescale_current_frame, diff;
     298             :     Word32 tmp_mem[4];
     299             : 
     300     1096060 :     prescale = L_norm_arr( signal_fx, lg );
     301     1096060 :     prescale_current_frame = sub( 1 + HP20_FX_COEFF_SCALE, prescale );
     302             : 
     303     1096060 :     prescaleOld = extract_l( mem_fx[4] );
     304             : 
     305     1096060 :     tmp_mem[0] = L_shl_sat( mem_fx[0], prescaleOld );
     306     1096060 :     tmp_mem[1] = L_shl_sat( mem_fx[1], prescaleOld );
     307     1096060 :     tmp_mem[2] = L_shl_sat( mem_fx[2], prescaleOld );
     308     1096060 :     tmp_mem[3] = L_shl_sat( mem_fx[3], prescaleOld );
     309     1096060 :     move32();
     310     1096060 :     move32();
     311     1096060 :     move32();
     312     1096060 :     move32();
     313             : 
     314     1096060 :     diff = L_norm_arr( tmp_mem, 4 );
     315             : 
     316     1096060 :     prescale = s_min( prescale, diff );
     317             : 
     318     1096060 :     prescale = sub( 1 + HP20_FX_COEFF_SCALE, prescale );
     319             : 
     320     1096060 :     if ( EQ_16( prescale_current_frame, 1 + HP20_FX_COEFF_SCALE - 31 ) ) // signal_fx buffer contains only zeros, so use the mem_fx scale_factor instead
     321             :     {
     322        9456 :         prescale_current_frame = prescale;
     323             :     }
     324             : 
     325     1096060 :     diff = sub( prescale, prescaleOld );
     326     1096060 :     mem_fx[0] = L_shr_sat( mem_fx[0], diff );
     327     1096060 :     mem_fx[1] = L_shr_sat( mem_fx[1], diff );
     328     1096060 :     mem_fx[2] = L_shr_sat( mem_fx[2], diff );
     329     1096060 :     mem_fx[3] = L_shr_sat( mem_fx[3], diff );
     330     1096060 :     move32();
     331     1096060 :     move32();
     332     1096060 :     move32();
     333     1096060 :     move32();
     334     1096060 :     mem_fx[4] = L_deposit_l( prescale_current_frame );
     335     1096060 :     move32();
     336             : 
     337     1096060 :     IF( EQ_32( Fs, 8000 ) )
     338             :     {
     339             :         /* hp filter 20Hz at 3dB for 8000KHz input sampling rate
     340             :            [b,a] = butter(2, 20.0/4000.0, 'high');
     341             :            b = [0.988954248067140  -1.977908496134280   0.988954248067140]
     342             :            a =[1.000000000000000  -1.977786483776764   0.978030508491796]*/
     343           0 :         a1_fx = 2123632067 /* 1.977786483776764 Q30*/;
     344           0 :         a2_fx = -1050152262 /*-0.978030508491796 Q30*/;
     345           0 :         b1_fx = -2123763076 /*-1.977908496134280 Q30*/;
     346           0 :         b2_fx = 1061881538 /* 0.988954248067140 Q30*/;
     347             :     }
     348     1096060 :     ELSE IF( EQ_32( Fs, 16000 ) )
     349             :     {
     350             :         /* hp filter 20Hz at 3dB for 16000KHz sampling rate
     351             :            [b,a] = butter(2, 20.0/8000.0, 'high');
     352             :            b =[ 0.994461788958195  -1.988923577916390   0.994461788958195]
     353             :            a =[1.000000000000000  -1.988892905899653   0.988954249933127] */
     354      101093 :         a1_fx = 2135557497 /* 1.988892905899653 Q30*/;
     355      101093 :         a2_fx = -1061881540 /*-0.988954249933127 Q30*/;
     356      101093 :         b1_fx = -2135590430 /*-1.988923577916390 Q30*/;
     357      101093 :         b2_fx = 1067795215 /* 0.994461788958195 Q30*/;
     358             :     }
     359      994967 :     ELSE IF( EQ_32( Fs, 32000 ) )
     360             :     {
     361             :         /* hp filter 20Hz at 3dB for 32000KHz sampling rate
     362             :            [b,a] = butter(2, 20.0/16000.0, 'high');
     363             :            b =[0.997227049904470  -1.994454099808940   0.997227049904470]
     364             :            a =[1.000000000000000  -1.994446410541927   0.994461789075954]*/
     365      238576 :         a1_fx = 2141520527 /* 1.994446410541927 Q30*/;
     366      238576 :         a2_fx = -1067795215 /*-0.994461789075954 Q30*/;
     367      238576 :         b1_fx = -2141528783 /*-1.994454099808940 Q30*/;
     368      238576 :         b2_fx = 1070764392 /* 0.997227049904470 Q30*/;
     369             :     }
     370             :     ELSE
     371             :     {
     372             :         /* hp filter 20Hz at 3dB for 48000KHz sampling rate
     373             :            [b,a] = butter(2, 20.0/24000.0, 'high');
     374             :            b =[ 0.998150511190452  -1.996301022380904   0.998150511190452]
     375             :            a =[1.000000000000000  -1.996297601769122   0.996304442992686]*/
     376      756391 :         a1_fx = 2143508228 /* 1.996297601769122 Q30*/;
     377      756391 :         a2_fx = -1069773750 /*-0.996304442992686 Q30*/;
     378      756391 :         b1_fx = -2143511901 /*-1.996301022380904 Q30*/;
     379      756391 :         b2_fx = 1071755951 /* 0.998150511190452 Q30*/;
     380             :     }
     381     1096060 :     move32();
     382     1096060 :     move32();
     383     1096060 :     move32();
     384     1096060 :     move32();
     385             :     Word64 W_sum, W_y0, W_y1, W_y2;
     386             :     Word32 x0, x1, x2;
     387             : 
     388     1096060 :     W_sum = W_mult0_32_32( b2_fx, mem_fx[2] );                 /* b2*x2 */
     389     1096060 :     W_sum = W_add( W_sum, W_mult0_32_32( b1_fx, mem_fx[3] ) ); /* b1*x1 */
     390     1096060 :     x2 = L_shr( signal_fx[0], prescale );
     391     1096060 :     W_sum = W_add( W_sum, W_mult0_32_32( b2_fx, x2 ) );        /* b2*x0 */
     392     1096060 :     W_sum = W_add( W_sum, W_mult0_32_32( mem_fx[0], a2_fx ) ); /* y2*a2 */
     393     1096060 :     W_sum = W_add( W_sum, W_mult0_32_32( mem_fx[1], a1_fx ) ); /* y1*a1 */
     394     1096060 :     W_y2 = W_shl( W_sum, 1 + HP20_FX_COEFF_SCALE );
     395     1096060 :     signal_fx[0] = W_round64_L( W_shl( W_y2, prescale ) );
     396     1096060 :     move32();
     397             : 
     398     1096060 :     W_sum = W_mult0_32_32( b2_fx, mem_fx[3] );          /* b2*x2 */
     399     1096060 :     W_sum = W_add( W_sum, W_mult0_32_32( b1_fx, x2 ) ); /* b1*x1 */
     400     1096060 :     x1 = L_shr( signal_fx[1], prescale );
     401     1096060 :     W_sum = W_add( W_sum, W_mult0_32_32( b2_fx, x1 ) );                  /* b2*x0 */
     402     1096060 :     W_sum = W_add( W_sum, W_mult0_32_32( mem_fx[1], a2_fx ) );           /* y2*a2 */
     403     1096060 :     W_sum = W_add( W_sum, W_mult0_32_32( W_round64_L( W_y2 ), a1_fx ) ); /* y1*a1 */
     404     1096060 :     W_y1 = W_shl( W_sum, 1 + HP20_FX_COEFF_SCALE );
     405     1096060 :     signal_fx[1] = W_round64_L( W_shl( W_y1, prescale ) );
     406     1096060 :     move32();
     407             : 
     408     1096060 :     diff = sub( prescale_current_frame, prescale );
     409     1096060 :     W_y1 = W_shr( W_y1, diff );
     410     1096060 :     W_y2 = W_shr( W_y2, diff );
     411     1096060 :     x2 = L_shr( x2, diff );
     412     1096060 :     x1 = L_shr( x1, diff );
     413             : 
     414   910077700 :     FOR( i = 2; i < lg; i++ )
     415             :     {
     416   908981640 :         W_sum = W_mult0_32_32( b2_fx, x2 );                 /* b2*x2 */
     417   908981640 :         W_sum = W_add( W_sum, W_mult0_32_32( b1_fx, x1 ) ); /* b1*x1 */
     418   908981640 :         x0 = L_shr( signal_fx[i], prescale_current_frame );
     419   908981640 :         W_sum = W_add( W_sum, W_mult0_32_32( b2_fx, x0 ) );                  /* b2*x0 */
     420   908981640 :         W_sum = W_add( W_sum, W_mult0_32_32( W_round64_L( W_y2 ), a2_fx ) ); /* y2*a2 */
     421   908981640 :         W_sum = W_add( W_sum, W_mult0_32_32( W_round64_L( W_y1 ), a1_fx ) ); /* y1*a1 */
     422   908981640 :         W_y0 = W_shl( W_sum, 1 + HP20_FX_COEFF_SCALE );
     423             : 
     424   908981640 :         signal_fx[i] = W_round64_L( W_shl( W_y0, prescale_current_frame ) );
     425   908981640 :         move32();
     426             : 
     427   908981640 :         x2 = x1;
     428   908981640 :         x1 = x0;
     429   908981640 :         W_y2 = W_y1;
     430   908981640 :         W_y1 = W_y0;
     431             : 
     432   908981640 :         move32();
     433   908981640 :         move32();
     434   908981640 :         move64();
     435   908981640 :         move64();
     436             :     }
     437             : 
     438     1096060 :     mem_fx[0] = W_round64_L( W_y2 );
     439     1096060 :     mem_fx[1] = W_round64_L( W_y1 );
     440     1096060 :     mem_fx[2] = x2;
     441     1096060 :     mem_fx[3] = x1;
     442             : 
     443     1096060 :     move32();
     444     1096060 :     move32();
     445     1096060 :     move32();
     446     1096060 :     move32();
     447             : 
     448     1096060 :     return;
     449             : }
     450             : 
     451             : 
     452     1771760 : void hp20_fx_32(
     453             :     Word32 signal_fx[],
     454             :     const Word16 lg,
     455             :     Word32 mem_fx[],
     456             :     const Word32 Fs )
     457             : {
     458             :     Word16 i;
     459             :     Word32 a1_fx, a2_fx, b1_fx, b2_fx;
     460             :     Word16 Qx0, Qx1, Qx2, Qy1, Qprev_y1, Qy2, Qprev_y2, Qmin;
     461             :     Word64 x0_fx64, x1_fx64, x2_fx64, y0_fx64, y1_fx64, y2_fx64, R1, R2, R3, R4, R5;
     462             : 
     463     1771760 :     IF( EQ_32( Fs, 8000 ) )
     464             :     {
     465             :         /* hp filter 20Hz at 3dB for 8000KHz input sampling rate
     466             :            [b,a] = butter(2, 20.0/4000.0, 'high');
     467             :            b = [0.988954248067140  -1.977908496134280   0.988954248067140]
     468             :            a =[1.000000000000000  -1.977786483776764   0.978030508491796]*/
     469           0 :         a1_fx = 1061816033l /* 1.977786483776764 Q29*/;
     470           0 :         a2_fx = -525076131l /*-0.978030508491796 Q29*/;
     471           0 :         b1_fx = -1061881538l /*-1.977908496134280 Q29*/;
     472           0 :         b2_fx = 530940769l /* 0.988954248067140 Q29*/;
     473             :     }
     474     1771760 :     ELSE IF( EQ_32( Fs, 16000 ) )
     475             :     {
     476             :         /* hp filter 20Hz at 3dB for 16000KHz sampling rate
     477             :            [b,a] = butter(2, 20.0/8000.0, 'high');
     478             :            b =[ 0.994461788958195  -1.988923577916390   0.994461788958195]
     479             :            a =[1.000000000000000  -1.988892905899653   0.988954249933127] */
     480      101250 :         a1_fx = 1067778748l /* 1.988892905899653 Q29*/;
     481      101250 :         a2_fx = -530940770l /*-0.988954249933127 Q29*/;
     482      101250 :         b1_fx = -1067795215l /*-1.988923577916390 Q29*/;
     483      101250 :         b2_fx = 533897608l /* 0.994461788958195 Q29*/;
     484             :     }
     485     1670510 :     ELSE IF( EQ_32( Fs, 32000 ) )
     486             :     {
     487             :         /* hp filter 20Hz at 3dB for 32000KHz sampling rate
     488             :            [b,a] = butter(2, 20.0/16000.0, 'high');
     489             :            b =[0.997227049904470  -1.994454099808940   0.997227049904470]
     490             :            a =[1.000000000000000  -1.994446410541927   0.994461789075954]*/
     491      407748 :         a1_fx = 1070760263l /* 1.994446410541927 Q29*/;
     492      407748 :         a2_fx = -533897608l /*-0.994461789075954 Q29*/;
     493      407748 :         b1_fx = -1070764392l /*-1.994454099808940 Q29*/;
     494      407748 :         b2_fx = 535382196l /* 0.997227049904470 Q29*/;
     495             :     }
     496             :     ELSE
     497             :     {
     498             :         /* hp filter 20Hz at 3dB for 48000KHz sampling rate
     499             :            [b,a] = butter(2, 20.0/24000.0, 'high');
     500             :            b =[ 0.998150511190452  -1.996301022380904   0.998150511190452]
     501             :            a =[1.000000000000000  -1.996297601769122   0.996304442992686]*/
     502     1262762 :         a1_fx = 1071754114l /* 1.996297601769122 Q29*/;
     503     1262762 :         a2_fx = -534886875l /*-0.996304442992686 Q29*/;
     504     1262762 :         b1_fx = -1071755951l /*-1.996301022380904 Q29*/;
     505     1262762 :         b2_fx = 535877975l /* 0.998150511190452 Q29*/;
     506             :     }
     507     1771760 :     move32();
     508     1771760 :     move32();
     509     1771760 :     move32();
     510     1771760 :     move32();
     511             : 
     512     1771760 :     Qprev_y1 = extract_l( mem_fx[4] );
     513     1771760 :     Qprev_y2 = extract_l( mem_fx[5] );
     514     1771760 :     y1_fx64 = W_deposit32_l( mem_fx[0] );
     515     1771760 :     y2_fx64 = W_deposit32_l( mem_fx[1] );
     516     1771760 :     x0_fx64 = W_deposit32_l( mem_fx[2] );
     517     1771760 :     x1_fx64 = W_deposit32_l( mem_fx[3] );
     518             : 
     519  1507382000 :     FOR( i = 0; i < lg; i++ )
     520             :     {
     521  1505610240 :         x2_fx64 = x1_fx64;
     522  1505610240 :         move64();
     523  1505610240 :         x1_fx64 = x0_fx64;
     524  1505610240 :         move64();
     525  1505610240 :         x0_fx64 = W_deposit32_l( signal_fx[i] );
     526             : 
     527  1505610240 :         Qy1 = W_norm( y1_fx64 );
     528  1505610240 :         if ( y1_fx64 == 0 )
     529             :         {
     530      288559 :             Qy1 = 62;
     531      288559 :             move16();
     532             :         }
     533  1505610240 :         Qy1 = sub( Qy1, 34 );
     534  1505610240 :         R1 = W_mult0_32_32( W_shl_sat_l( y1_fx64, Qy1 ), a1_fx );
     535  1505610240 :         Qy1 = add( Qy1, Qprev_y1 );
     536             : 
     537  1505610240 :         Qy2 = W_norm( y2_fx64 );
     538  1505610240 :         if ( y2_fx64 == 0 )
     539             :         {
     540      293426 :             Qy2 = 62;
     541      293426 :             move16();
     542             :         }
     543  1505610240 :         Qy2 = sub( Qy2, 34 );
     544  1505610240 :         R2 = W_mult0_32_32( W_shl_sat_l( y2_fx64, Qy2 ), a2_fx );
     545  1505610240 :         Qy2 = add( Qy2, Qprev_y2 );
     546             : 
     547  1505610240 :         Qx0 = W_norm( x0_fx64 );
     548  1505610240 :         if ( x0_fx64 == 0 )
     549             :         {
     550    58191885 :             Qx0 = 62;
     551    58191885 :             move16();
     552             :         }
     553  1505610240 :         Qx0 = sub( Qx0, 34 );
     554  1505610240 :         R3 = W_mult0_32_32( W_shl_sat_l( x0_fx64, Qx0 ), b2_fx );
     555             : 
     556  1505610240 :         Qx1 = W_norm( x1_fx64 );
     557  1505610240 :         if ( x1_fx64 == 0 )
     558             :         {
     559    58194182 :             Qx1 = 62;
     560    58194182 :             move16();
     561             :         }
     562  1505610240 :         Qx1 = sub( Qx1, 34 );
     563  1505610240 :         R4 = W_mult0_32_32( W_shl_sat_l( x1_fx64, Qx1 ), b1_fx );
     564             : 
     565  1505610240 :         Qx2 = W_norm( x2_fx64 );
     566  1505610240 :         if ( x2_fx64 == 0 )
     567             :         {
     568    58196507 :             Qx2 = 62;
     569    58196507 :             move16();
     570             :         }
     571  1505610240 :         Qx2 = sub( Qx2, 34 );
     572  1505610240 :         R5 = W_mult0_32_32( W_shl_sat_l( x2_fx64, Qx2 ), b2_fx );
     573             : 
     574  1505610240 :         Qmin = s_min( Qy1, Qy2 );
     575             : 
     576  1505610240 :         y0_fx64 = W_add( W_shr( R1, sub( Qy1, Qmin ) ), W_shr( R2, sub( Qy2, Qmin ) ) );
     577             : 
     578  1505610240 :         Qmin = s_min( Qmin, Qx0 );
     579  1505610240 :         Qmin = s_min( Qmin, Qx1 );
     580  1505610240 :         Qmin = s_min( Qmin, Qx2 );
     581             : 
     582  1505610240 :         y0_fx64 = W_add( W_shr( y0_fx64, sub( s_min( Qy1, Qy2 ), Qmin ) ), W_add( W_shr( R3, sub( Qx0, Qmin ) ), W_add( W_shr( R4, sub( Qx1, Qmin ) ), W_shr( R5, sub( Qx2, Qmin ) ) ) ) );
     583             : 
     584  1505610240 :         y0_fx64 = W_shr( y0_fx64, 29 );
     585             : 
     586  1505610240 :         signal_fx[i] = W_extract_l( W_shr( y0_fx64, Qmin ) );
     587  1505610240 :         move32();
     588  1505610240 :         IF( signal_fx[i] < 0 )
     589             :         {
     590   753936679 :             signal_fx[i] = L_add( signal_fx[i], 1 );
     591   753936679 :             move32();
     592             :         }
     593             : 
     594  1505610240 :         y2_fx64 = y1_fx64;
     595  1505610240 :         y1_fx64 = y0_fx64;
     596  1505610240 :         Qprev_y2 = Qprev_y1;
     597  1505610240 :         Qprev_y1 = Qmin;
     598  1505610240 :         move64();
     599  1505610240 :         move64();
     600  1505610240 :         move16();
     601  1505610240 :         move16();
     602             :     }
     603             : 
     604     1771760 :     Qy1 = W_norm( y1_fx64 );
     605     1771760 :     test();
     606     1771760 :     IF( y1_fx64 != 0 && LT_16( Qy1, 32 ) )
     607             :     {
     608           0 :         y1_fx64 = W_shr( y1_fx64, sub( 32, Qy1 ) );
     609           0 :         Qprev_y1 = sub( Qprev_y1, sub( 32, Qy1 ) );
     610             :     }
     611             : 
     612     1771760 :     Qy2 = W_norm( y2_fx64 );
     613     1771760 :     test();
     614     1771760 :     IF( y2_fx64 != 0 && LT_16( Qy2, 32 ) )
     615             :     {
     616           0 :         y2_fx64 = W_shr( y2_fx64, sub( 32, Qy2 ) );
     617           0 :         Qprev_y2 = sub( Qprev_y2, sub( 32, Qy2 ) );
     618             :     }
     619             : 
     620     1771760 :     mem_fx[0] = W_extract_l( y1_fx64 );
     621     1771760 :     mem_fx[1] = W_extract_l( y2_fx64 );
     622     1771760 :     mem_fx[2] = W_extract_l( x0_fx64 );
     623     1771760 :     mem_fx[3] = W_extract_l( x1_fx64 );
     624     1771760 :     mem_fx[4] = Qprev_y1;
     625     1771760 :     mem_fx[5] = Qprev_y2;
     626             : 
     627     1771760 :     move32();
     628     1771760 :     move32();
     629     1771760 :     move32();
     630     1771760 :     move32();
     631     1771760 :     move32();
     632     1771760 :     move32();
     633             : 
     634     1771760 :     return;
     635             : }

Generated by: LCOV version 1.14