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

Generated by: LCOV version 1.14