LCOV - code coverage report
Current view: top level - lib_com - hp50_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 203 227 89.4 %
Date: 2025-05-03 01:55:50 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    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     7828072 :         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     5288701 :         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             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      90        6200 :     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        6200 :     L_sum = HP50_Mpy_32_32_fix( b2, mem[2] );                 /* b2*x2 */
     104        6200 :     L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( b1, mem[3] ) ); /* b1*x1 */
     105        6200 :     x2 = shr( signal[0], prescale );
     106        6200 :     L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x2 ) ); /* b2*x0 */
     107        6200 :     L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[0], a2 ) );   /* y2*a2 */
     108        6200 :     L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[1], a1 ) );   /* y1*a1 */
     109             : 
     110        6200 :     L_y2 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow );
     111             :     BASOP_SATURATE_ERROR_OFF_EVS
     112             :     BASOP_SATURATE_WARNING_OFF_EVS
     113        6200 :     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        6200 :     L_sum = HP50_Mpy_32_32_fix( b2, mem[3] );                   /* b2*x2 */
     118        6200 :     L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b1, x2 ) ); /* b1*x1 */
     119        6200 :     x1 = shr( signal[stride], prescale );
     120        6200 :     L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x1 ) ); /* b2*x0 */
     121        6200 :     L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[1], a2 ) );   /* y2*a2 */
     122        6200 :     L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a1 ) );     /* y1*a1 */
     123             : 
     124        6200 :     L_y1 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow );
     125             :     BASOP_SATURATE_ERROR_OFF_EVS
     126             :     BASOP_SATURATE_WARNING_OFF_EVS
     127        6200 :     signal[stride] = round_fx_o( L_shl_o( L_y1, prescale, &Overflow ), &Overflow );
     128             :     BASOP_SATURATE_WARNING_ON_EVS
     129        6200 :     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     2640000 :     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     2633800 :         L_sum = HP50_Mode2_Mpy_32_16_fix( b2, x2 );
     137     2633800 :         L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b1, x1 ) );
     138     2633800 :         x2 = shr( signal[i * stride], prescale );
     139     2633800 :         L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x2 ) );
     140     2633800 :         L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a2 ) );
     141     2633800 :         L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y1, a1 ) );
     142             : 
     143     2633800 :         L_y2 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow );
     144             :         BASOP_SATURATE_ERROR_OFF_EVS
     145             :         BASOP_SATURATE_WARNING_OFF_EVS
     146     2633800 :         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     2633800 :         L_sum = HP50_Mode2_Mpy_32_16_fix( b2, x1 );
     151     2633800 :         L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b1, x2 ) );
     152     2633800 :         x1 = shr( signal[( i + 1 ) * stride], prescale );
     153     2633800 :         L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x1 ) );
     154     2633800 :         L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y1, a2 ) );
     155     2633800 :         L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a1 ) );
     156             : 
     157     2633800 :         L_y1 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow );
     158             :         BASOP_SATURATE_ERROR_OFF_EVS
     159             :         BASOP_SATURATE_WARNING_OFF_EVS
     160     2633800 :         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     2633800 :         move16();
     163             :     }
     164             :     /* update static filter memory from variables */
     165        6200 :     mem[0] = L_y2;
     166        6200 :     move32();
     167        6200 :     mem[1] = L_y1;
     168        6200 :     move32();
     169        6200 :     mem[2] = L_deposit_h( x2 );
     170        6200 :     move32();
     171        6200 :     mem[3] = L_deposit_h( x1 );
     172        6200 :     move32();
     173             : 
     174             : 
     175        6200 :     return;
     176             : }
     177             : 
     178             : 
     179        6200 : 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        6200 :     Flag Overflow = 0;
     195             : #endif
     196             : 
     197             : 
     198        6200 :     prescale = getScaleFactor16( signal, lg );
     199        6200 :     prescaleOld = extract_l( mem[4] );
     200        6200 :     diff = norm_l( L_shl_sat( mem[2], prescaleOld ) );
     201        6200 :     if ( mem[2] != 0 )
     202             :     {
     203        6163 :         prescale = s_min( prescale, diff );
     204             :     }
     205        6200 :     diff = norm_l( L_shl_o( mem[3], prescaleOld, &Overflow ) );
     206        6200 :     if ( mem[3] != 0 )
     207             :     {
     208        6165 :         prescale = s_min( prescale, diff );
     209             :     }
     210             :     /* Take into account the left shift performed into the loop + 1 bit headroom*/
     211        6200 :     prescale = s_max( -12, sub( 1 + HP20_COEFF_SCALE, prescale ) );
     212        6200 :     IF( prescale != prescaleOld )
     213             :     {
     214        2569 :         diff = sub( prescale, prescaleOld );
     215        2569 :         mem[0] = L_shr_o( mem[0], diff, &Overflow );
     216        2569 :         move32();
     217        2569 :         mem[1] = L_shr_o( mem[1], diff, &Overflow );
     218        2569 :         move32();
     219        2569 :         mem[2] = L_shr_o( mem[2], diff, &Overflow );
     220        2569 :         move32();
     221        2569 :         mem[3] = L_shr_o( mem[3], diff, &Overflow );
     222        2569 :         move32();
     223        2569 :         mem[4] = L_deposit_l( prescale );
     224             :     }
     225             : 
     226        6200 :     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        6200 :     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        6200 :     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        2100 :         a1 = 1070760263l /* 1.994446410541927 Q29*/;
     263        2100 :         move32();
     264        2100 :         a2 = -533897608l /*-0.994461789075954 Q29*/;
     265        2100 :         move32();
     266        2100 :         b1 = -1070764392l /*-1.994454099808940 Q29*/;
     267        2100 :         move32();
     268        2100 :         b2 = 535382196l /* 0.997227049904470 Q29*/;
     269        2100 :         move32();
     270             :     }
     271             :     ELSE
     272             :     {
     273        4100 :         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        4100 :         a1 = 1071754114l /* 1.996297601769122 Q29*/;
     279        4100 :         move32();
     280        4100 :         a2 = -534886875l /*-0.996304442992686 Q29*/;
     281        4100 :         move32();
     282        4100 :         b1 = -1071755951l /*-1.996301022380904 Q29*/;
     283        4100 :         move32();
     284        4100 :         b2 = 535877975l /* 0.998150511190452 Q29*/;
     285        4100 :         move32();
     286             :     }
     287             : 
     288             : 
     289        6200 :     filter_2nd_order( signal, stride, prescale, lg,
     290             :                       mem, a1, a2, b1, b2 );
     291             : 
     292        6200 :     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     2743141 : 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     2743141 :     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     2743141 :     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      197875 :         a1_fx = 1067778748l /* 1.988892905899653 Q29*/;
     482      197875 :         a2_fx = -530940770l /*-0.988954249933127 Q29*/;
     483      197875 :         b1_fx = -1067795215l /*-1.988923577916390 Q29*/;
     484      197875 :         b2_fx = 533897608l /* 0.994461788958195 Q29*/;
     485             :     }
     486     2545266 :     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      644538 :         a1_fx = 1070760263l /* 1.994446410541927 Q29*/;
     493      644538 :         a2_fx = -533897608l /*-0.994461789075954 Q29*/;
     494      644538 :         b1_fx = -1070764392l /*-1.994454099808940 Q29*/;
     495      644538 :         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     1900728 :         a1_fx = 1071754114l /* 1.996297601769122 Q29*/;
     504     1900728 :         a2_fx = -534886875l /*-0.996304442992686 Q29*/;
     505     1900728 :         b1_fx = -1071755951l /*-1.996301022380904 Q29*/;
     506     1900728 :         b2_fx = 535877975l /* 0.998150511190452 Q29*/;
     507             :     }
     508     2743141 :     move32();
     509     2743141 :     move32();
     510     2743141 :     move32();
     511     2743141 :     move32();
     512             : 
     513     2743141 :     Qprev_y1 = extract_l( mem_fx[4] );
     514     2743141 :     Qprev_y2 = extract_l( mem_fx[5] );
     515     2743141 :     y1_fx64 = W_deposit32_l( mem_fx[0] );
     516     2743141 :     y2_fx64 = W_deposit32_l( mem_fx[1] );
     517     2743141 :     x0_fx64 = W_deposit32_l( mem_fx[2] );
     518     2743141 :     x1_fx64 = W_deposit32_l( mem_fx[3] );
     519             : 
     520  2303266341 :     FOR( i = 0; i < lg; i++ )
     521             :     {
     522  2300523200 :         x2_fx64 = x1_fx64;
     523  2300523200 :         move64();
     524  2300523200 :         x1_fx64 = x0_fx64;
     525  2300523200 :         move64();
     526  2300523200 :         x0_fx64 = W_deposit32_l( signal_fx[i] );
     527             : 
     528  2300523200 :         Qy1 = W_norm( y1_fx64 );
     529  2300523200 :         if ( y1_fx64 == 0 )
     530             :         {
     531     7958142 :             Qy1 = 62;
     532     7958142 :             move16();
     533             :         }
     534  2300523200 :         Qy1 = sub( Qy1, 34 );
     535             : #ifdef OPT_STEREO_32KBPS_V1
     536  2300523200 :         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  2300523200 :         Qy1 = add( Qy1, Qprev_y1 );
     541             : 
     542  2300523200 :         Qy2 = W_norm( y2_fx64 );
     543  2300523200 :         if ( y2_fx64 == 0 )
     544             :         {
     545     7968035 :             Qy2 = 62;
     546     7968035 :             move16();
     547             :         }
     548  2300523200 :         Qy2 = sub( Qy2, 34 );
     549             : #ifdef OPT_STEREO_32KBPS_V1
     550  2300523200 :         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  2300523200 :         Qy2 = add( Qy2, Qprev_y2 );
     555             : 
     556  2300523200 :         Qx0 = W_norm( x0_fx64 );
     557  2300523200 :         if ( x0_fx64 == 0 )
     558             :         {
     559    88554842 :             Qx0 = 62;
     560    88554842 :             move16();
     561             :         }
     562  2300523200 :         Qx0 = sub( Qx0, 34 );
     563             : #ifdef OPT_STEREO_32KBPS_V1
     564  2300523200 :         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  2300523200 :         Qx1 = W_norm( x1_fx64 );
     570  2300523200 :         if ( x1_fx64 == 0 )
     571             :         {
     572    88561666 :             Qx1 = 62;
     573    88561666 :             move16();
     574             :         }
     575  2300523200 :         Qx1 = sub( Qx1, 34 );
     576             : #ifdef OPT_STEREO_32KBPS_V1
     577  2300523200 :         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  2300523200 :         Qx2 = W_norm( x2_fx64 );
     583  2300523200 :         if ( x2_fx64 == 0 )
     584             :         {
     585    88568539 :             Qx2 = 62;
     586    88568539 :             move16();
     587             :         }
     588  2300523200 :         Qx2 = sub( Qx2, 34 );
     589             : #ifdef OPT_STEREO_32KBPS_V1
     590  2300523200 :         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  2300523200 :         Qmin = s_min( Qy1, Qy2 );
     596             : 
     597  2300523200 :         y0_fx64 = W_add( W_shr( R1, sub( Qy1, Qmin ) ), W_shr( R2, sub( Qy2, Qmin ) ) );
     598             : 
     599  2300523200 :         Qmin = s_min( Qmin, Qx0 );
     600  2300523200 :         Qmin = s_min( Qmin, Qx1 );
     601  2300523200 :         Qmin = s_min( Qmin, Qx2 );
     602             : 
     603  2300523200 :         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  2300523200 :         y0_fx64 = W_shr( y0_fx64, 29 );
     606             : 
     607  2300523200 :         signal_fx[i] = W_extract_l( W_shr( y0_fx64, Qmin ) );
     608  2300523200 :         move32();
     609  2300523200 :         IF( signal_fx[i] < 0 )
     610             :         {
     611  1148437472 :             signal_fx[i] = L_add( signal_fx[i], 1 );
     612  1148437472 :             move32();
     613             :         }
     614             : 
     615  2300523200 :         y2_fx64 = y1_fx64;
     616  2300523200 :         y1_fx64 = y0_fx64;
     617  2300523200 :         Qprev_y2 = Qprev_y1;
     618  2300523200 :         Qprev_y1 = Qmin;
     619  2300523200 :         move64();
     620  2300523200 :         move64();
     621  2300523200 :         move16();
     622  2300523200 :         move16();
     623             :     }
     624             : 
     625     2743141 :     Qy1 = W_norm( y1_fx64 );
     626     2743141 :     test();
     627     2743141 :     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     2743141 :     Qy2 = W_norm( y2_fx64 );
     634     2743141 :     test();
     635     2743141 :     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     2743141 :     mem_fx[0] = W_extract_l( y1_fx64 );
     642     2743141 :     mem_fx[1] = W_extract_l( y2_fx64 );
     643     2743141 :     mem_fx[2] = W_extract_l( x0_fx64 );
     644     2743141 :     mem_fx[3] = W_extract_l( x1_fx64 );
     645     2743141 :     mem_fx[4] = Qprev_y1;
     646     2743141 :     mem_fx[5] = Qprev_y2;
     647             : 
     648     2743141 :     move32();
     649     2743141 :     move32();
     650     2743141 :     move32();
     651     2743141 :     move32();
     652     2743141 :     move32();
     653     2743141 :     move32();
     654             : 
     655     2743141 :     return;
     656             : }
     657             : #endif

Generated by: LCOV version 1.14