LCOV - code coverage report
Current view: top level - lib_enc - gp_clip_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 141 178 79.2 %
Date: 2025-09-14 03:13:15 Functions: 6 7 85.7 %

          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 "options.h"     /* Compilation switches                   */
      39             : #include "cnst.h"        /* Common constants                       */
      40             : #include "prot_fx.h"     /* Function prototypes                    */
      41             : #include "prot_fx_enc.h" /* Function prototypes                    */
      42             : #include "basop_util.h"
      43             : 
      44             : /*-------------------------------------------------------------------*
      45             :  * Local constants
      46             :  *-------------------------------------------------------------------*/
      47             : 
      48             : #define DIST_ISF_MAX_IO 384   /* 150 Hz (6400Hz=16384) */
      49             : #define DIST_ISF_MAX    307   /* 120 Hz (6400Hz=16384) */
      50             : #define DIST_ISF_THRES  154   /* 60     (6400Hz=16384) */
      51             : #define GAIN_PIT_THRES  14746 /* 0.9 in Q14 */
      52             : #define GAIN_PIT_MIN    9830  /* 0.6 in Q14 */
      53             : 
      54             : #define ALPHA1         32113 /* 0.98f */
      55             : #define ALPHA4         32440 /* 0.99f */
      56             : #define WINDOW_SIZE    50
      57             : #define THRESH_TYPE    13926 /* 0.85f in Q14 */
      58             : #define THRESH_VOICING 14090 /* 0.86f in Q14 */
      59             : 
      60             : #define GPCLIP_E ( 6 + 2 )
      61             : 
      62             : #define ALPHA1_M1 21474836l /*1.0f-0.98 Q30*/
      63             : #define ALPHA4_M1 10737408l /*1.0f-0.99f Q30*/
      64             : 
      65             : /*-------------------------------------------------------------------*
      66             :  * init_gp_clip
      67             :  *
      68             :  * Pitch Gain clipping initializations
      69             :  *-------------------------------------------------------------------*/
      70       32374 : void init_gp_clip_fx(
      71             :     Word16 mem[] /* o  : memory of gain of pitch clipping algorithm             [2.56x,Q14,Q8,Q0,Q14,Q14]*/
      72             : )
      73             : {
      74       32374 :     mem[0] = DIST_ISF_MAX;
      75       32374 :     move16(); /* Q0 */
      76       32374 :     mem[1] = GAIN_PIT_MIN;
      77       32374 :     move16(); /* 1Q14 */
      78       32374 :     mem[2] = 0;
      79       32374 :     move16(); /* 8Q7 */ /* old energy of target (dB) */
      80       32374 :     mem[3] = 0;
      81       32374 :     move16(); /* Q0 */
      82       32374 :     mem[4] = 0;
      83       32374 :     move16();       /* Q14 */
      84       32374 :     mem[5] = 13107; /*0.8*/
      85       32374 :     move16();       /* Q14 */
      86             : 
      87       32374 :     return;
      88             : }
      89             : 
      90             : /*-------------------------------------------------------------------*
      91             :  * Function gp_clip
      92             :  *
      93             :  * The gain needs to be limited (gain pitch < 1.0) when one of the
      94             :  * following cases occurs:
      95             :  * - a resonance on LPC filter (lp_disp < 60 Hz)  AND a good pitch
      96             :  *   prediction (lp_gp > 0.9)
      97             :  * - target energy drops by 6 dB AND a good pitch prediction (lp_gp>1.0)
      98             :  *-------------------------------------------------------------------*/
      99             : 
     100      613414 : Word16 gp_clip_fx(
     101             :     const Word16 element_mode, /* i  : element mode                               Q0*/
     102             :     const Word32 core_brate,   /* i  : core bitrate                               Q0*/
     103             :     const Word16 *voicing,     /* i  : normalized correlations (from OL pitch)    Q15*/
     104             :     const Word16 i_subfr,      /* i  : subframe index                             Q0*/
     105             :     const Word16 coder_type,   /* i  : type of coder                              Q0*/
     106             :     const Word16 xn[],         /* i  : target vector                              Q_new*/
     107             :     Word16 mem[],              /* i/o: memory of gain of pitch clipping algorithm [2.56x,Q14,Q8,Q0,Q14,Q14]*/
     108             :     const Word16 Q_new         /* i  : scaling factor                             */
     109             : )
     110             : {
     111             :     Word16 clip;
     112             :     Word16 i, wener;
     113             :     Word16 e_ener, f_ener;
     114             :     Word32 ener;
     115             :     Word32 L_tmp;
     116             :     Word16 thres;
     117             : #ifndef ISSUE_1867_replace_overflow_libenc
     118             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     119             :     Flag Overflow = 0;
     120             :     move32();
     121             : #endif
     122             : #endif
     123             : 
     124      613414 :     clip = 0;
     125      613414 :     move16();
     126      613414 :     test();
     127      613414 :     test();
     128      613414 :     IF( EQ_32( core_brate, ACELP_6k60 ) || EQ_32( core_brate, ACELP_8k85 ) || element_mode > EVS_MONO )
     129             :     {
     130      607136 :         thres = add( 14746 /* 0.9 in Q14 */, mult( 1638 /* 0.1 in Q14 */, extract_l( L_mult( mem[0], (Word16) ( 16384 / DIST_ISF_MAX_IO ) ) ) ) ); /* clipping is activated when filtered pitch gain > threshold (0.94 to 1 in Q14) */
     131      607136 :         if ( GT_16( mem[1], thres ) )
     132             :         {
     133           0 :             clip = 1;
     134           0 :             move16();
     135             :         }
     136             :     }
     137             :     ELSE
     138             :     {
     139        6278 :         test();
     140        6278 :         if ( LT_16( mem[0], DIST_ISF_THRES ) && GT_16( mem[1], GAIN_PIT_THRES ) )
     141             :         {
     142          16 :             clip = 1;
     143          16 :             move16();
     144             :         }
     145             :     }
     146             : 
     147             : #ifdef ISSUE_1867_replace_overflow_libenc
     148      613414 :     ener = L_mac_sat( 1L, xn[0], xn[0] );
     149             : #else
     150             :     ener = L_mac_o( 1L, xn[0], xn[0], &Overflow );
     151             : #endif
     152    39258496 :     FOR( i = 1; i < L_SUBFR; i++ )
     153             :     {
     154             : #ifdef ISSUE_1867_replace_overflow_libenc
     155    38645082 :         ener = L_mac_sat( ener, xn[i], xn[i] );
     156             : #else
     157             :         ener = L_mac_o( ener, xn[i], xn[i], &Overflow );
     158             : #endif
     159             :     }
     160             : 
     161             :     /* ener = 10.0f*(float)log10(ener) */
     162      613414 :     e_ener = norm_l( ener );
     163      613414 :     f_ener = Log2_norm_lc( L_shl( ener, e_ener ) );
     164      613414 :     e_ener = sub( 30, e_ener );
     165      613414 :     IF( element_mode > EVS_MONO )
     166             :     {
     167      607136 :         e_ener = sub( e_ener, Q_new * 2 + 1 );
     168             :     }
     169             :     ELSE
     170             :     {
     171        6278 :         e_ener = sub( e_ener, Q_new );
     172             :     }
     173      613414 :     ener = Mpy_32_16( e_ener, f_ener, LG10 ); /* Q14 */
     174      613414 :     wener = round_fx( L_shl( ener, 10 ) );    /* Q8 */
     175             : 
     176      613414 :     test();
     177      613414 :     if ( LT_16( wener, sub( mem[2], 1536 /* 6.0f in Q8 */ ) ) && GT_16( mem[1], 16384 /* 1 in Q14 */ ) )
     178             :     {
     179           0 :         clip = 1;
     180           0 :         move16();
     181             :     }
     182             : 
     183      613414 :     mem[2] = wener; /* Q8 */
     184      613414 :     move16();
     185             : 
     186      613414 :     L_tmp = L_mult( ALPHA1, mem[4] ); /* Q30 */
     187             : 
     188      613414 :     test();
     189      613414 :     test();
     190      613414 :     if ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, TRANSITION ) || EQ_16( coder_type, INACTIVE ) )
     191             :     {
     192             :         /* mem[4] = (1-ALPHA1) + ALPHA1 * mem[4], if branch taken */
     193             :         /* mem[4] = ALPHA1 * mem[4], otherwise */
     194      548802 :         L_tmp = L_add( L_tmp, 32768L * ( 32768 - ALPHA1 ) ); /* Q30 */
     195             :     }
     196      613414 :     mem[4] = round_fx( L_tmp ); /* Q14 */
     197             : 
     198      613414 :     L_tmp = L_mult( ALPHA4, mem[5] );
     199      613414 :     IF( i_subfr == 0 )
     200             :     {
     201             :         /* mem[5] = (1-ALPHA4) * voicing[0] + ALPHA4 * mem[5] */
     202      141020 :         mem[5] = mac_r( L_tmp, ( 32768 - ALPHA4 ) / 2, voicing[0] );
     203      141020 :         move16(); /* /2 to put voicing from Q15 to Q14 */
     204             :     }
     205             : 
     206      613414 :     IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
     207             :     {
     208             :         /* mem[5] = (1-ALPHA4) * voicing[1] + ALPHA4 * mem[5] */
     209      135947 :         mem[5] = mac_r( L_tmp, ( 32768 - ALPHA4 ) / 2, voicing[1] );
     210      135947 :         move16(); /* /2 to put voicing from Q15 to Q14 */
     211             :     }
     212             : 
     213      613414 :     IF( GT_16( mem[3], WINDOW_SIZE ) )
     214             :     {
     215      427918 :         test();
     216      427918 :         if ( GT_16( mem[4], THRESH_TYPE ) && GT_16( mem[5], THRESH_VOICING ) )
     217             :         {
     218        6109 :             clip = 1;
     219        6109 :             move16();
     220             :         }
     221             :     }
     222             :     ELSE
     223             :     {
     224      185496 :         mem[3] = add( mem[3], 1 ); /* Q0 */
     225      185496 :         move16();
     226             :     }
     227             : 
     228      613414 :     return ( clip );
     229             : }
     230             : 
     231             : /*-------------------------------------------------------------------*
     232             :  * gp_clip_test_lsf()
     233             :  *
     234             :  * check the minimum distance of LSFs for pitch gain clipping flag
     235             :  *-------------------------------------------------------------------*/
     236             : 
     237           0 : void gp_clip_test_isf_fx(
     238             :     const Word16 element_mode, /* i  : element mode                               Q0*/
     239             :     const Word32 core_brate,   /* i  : core bitrate                               Q0*/
     240             :     const Word16 isf[],        /* i  : isf values (in frequency domain)           Q2.56*/
     241             :     Word16 mem[],              /* i/o: memory of gain of pitch clipping algorithm Q15*/
     242             :     const Word16 Opt_AMR_WB    /* i  : flag indicating AMR-WB IO mode             Q0*/
     243             : )
     244             : {
     245             :     Word16 i, dist, dist_min, m;
     246             : 
     247           0 :     dist_min = sub( isf[1], isf[0] ); /* Q2.56 */
     248             : 
     249           0 :     m = M;
     250           0 :     move16();
     251           0 :     if ( EQ_16( Opt_AMR_WB, 1 ) )
     252             :     {
     253           0 :         m = M - 1;
     254           0 :         move16();
     255             :     }
     256             : 
     257           0 :     move16(); /* ptr init*/
     258           0 :     FOR( i = 2; i < m; i++ )
     259             :     {
     260           0 :         dist = sub( isf[i], isf[i - 1] );   /* Q2.56 */
     261           0 :         dist_min = s_min( dist, dist_min ); /* Q2.56 */
     262             :     }
     263             : 
     264           0 :     dist = extract_h( L_mac( L_mult( 26214 /* 0.8f in Q15 */, mem[0] ), 6554 /* 0.2f in Q15 */, dist_min ) ); /* Q15 */
     265             : 
     266           0 :     test();
     267           0 :     test();
     268           0 :     IF( EQ_32( core_brate, ACELP_6k60 ) || EQ_32( core_brate, ACELP_8k85 ) || element_mode > EVS_MONO )
     269             :     {
     270           0 :         dist = s_min( dist, DIST_ISF_MAX_IO );
     271             :     }
     272             :     ELSE
     273             :     {
     274           0 :         dist = s_min( dist, DIST_ISF_MAX );
     275             :     }
     276           0 :     mem[0] = dist; /* Q15 */
     277           0 :     move16();
     278             : 
     279           0 :     return;
     280             : }
     281             : 
     282             : /*-------------------------------------------------------------------*
     283             :  * gp_clip_test_gain_pit()
     284             :  *
     285             :  * low-pass filtering of the pitch gain for pitch gain clipping flag
     286             :  *-------------------------------------------------------------------*/
     287             : 
     288      645417 : void gp_clip_test_gain_pit_fx(
     289             :     const Word16 element_mode, /* i  : element mode                                                                     Q0*/
     290             :     const Word32 core_brate,   /* i  : core bitrate                                                                     Q0*/
     291             :     const Word16 gain_pit,     /* i  : gain of quantized pitch                                          Q14*/
     292             :     Word16 mem[]               /* i/o: memory of gain of pitch clipping algorithm       1Q14*/
     293             : )
     294             : {
     295             :     Word16 gain;
     296             :     Word32 L_tmp;
     297             : 
     298      645417 :     test();
     299      645417 :     test();
     300      645417 :     IF( EQ_32( core_brate, ACELP_6k60 ) || EQ_32( core_brate, ACELP_8k85 ) || element_mode > EVS_MONO )
     301             :     {
     302      635982 :         L_tmp = L_mult( 32113 /* 0.98 in Q15 */, mem[1] ); /* long term LTP gain average (>250ms) */
     303      635982 :         L_tmp = L_mac( L_tmp, 655 /* 0.02 in Q15 */, gain_pit );
     304             :     }
     305             :     ELSE
     306             :     {
     307        9435 :         L_tmp = L_mult( 29491 /* 0.9 in Q15 */, mem[1] );
     308        9435 :         L_tmp = L_mac( L_tmp, 3277 /* 0.1 in Q15 */, gain_pit );
     309             :     }
     310      645417 :     gain = extract_h( L_tmp );
     311      645417 :     gain = s_max( gain, GAIN_PIT_MIN );
     312      645417 :     mem[1] = gain; /* Q14 */
     313      645417 :     move16();
     314             : 
     315      645417 :     return;
     316             : }
     317             : 
     318             : 
     319             : /*-------------------------------------------------------------------*
     320             :  * Function gp_clip
     321             :  *
     322             :  * The gain needs to be limited (gain pitch < 1.0) when one of the
     323             :  * following cases occurs:
     324             :  * - a resonance on LPC filter (lp_disp < 60 Hz)  AND a good pitch
     325             :  *   prediction (lp_gp > 0.9)
     326             :  * - target energy drops by 6 dB AND a good pitch prediction (lp_gp>1.0)
     327             :  *-------------------------------------------------------------------*/
     328       11120 : Word16 Mode2_gp_clip_fx(
     329             :     const Word16 *voicing,   /* i  : normalized correlations from OL pitch  Q15 */
     330             :     const Word16 i_subfr,    /* i  : subframe index                         Q0  */
     331             :     const Word16 coder_type, /* i  : type of coder                          Q0  */
     332             :     const Word16 xn[],       /* i  : target vector                         Q_xn */
     333             :     Word16 mem[],            /* i/o: memory of gain of pitch clipping algorithm */
     334             :     /*      mem[0]:      Q0                            */
     335             :     /*      mem[1]:     1Q14                           */
     336             :     /*      mem[2]:     8Q7                            */
     337             :     /*      mem[3]:      Q0   (integer)                */
     338             :     /*      mem[4]:      Q14                           */
     339             :     /*      mem[5]:      Q14                           */
     340             :     const Word16 L_subfr, /* Q0 */
     341             :     const Word16 Q_xn     /* i  : scaling factor of vector xn[]              */
     342             : )
     343             : {
     344             :     Word16 clip, tmp, exp_xn;
     345             :     Word16 i;
     346             :     Word32 wener, Ltmp;
     347             : #ifndef ISSUE_1867_replace_overflow_libenc
     348             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     349             :     Flag Overflow = 0;
     350             :     move32();
     351             : #endif
     352             : #endif
     353       11120 :     move16();
     354       11120 :     clip = 0;
     355             : 
     356       11120 :     test();
     357       11120 :     if ( ( LT_16( mem[0], DIST_ISF_THRES ) ) && ( GT_16( mem[1], GAIN_PIT_THRES ) ) )
     358             :     {
     359           0 :         move16();
     360           0 :         clip = 1;
     361             :     }
     362             : 
     363             :     /*ener_exp = exp_xn * 2 + 1*/
     364       11120 :     exp_xn = add( shl( sub( 15, Q_xn ), 1 ), 1 );
     365       11120 :     wener = L_shr( 21474836l /*0.01f Q31*/, s_min( 31, exp_xn ) );
     366       11120 :     wener = L_max( 1, wener );
     367             : 
     368      722800 :     FOR( i = 0; i < L_subfr; i++ )
     369             :     {
     370             : #ifdef ISSUE_1867_replace_overflow_libenc
     371      711680 :         wener = L_mac0_sat( wener, xn[i], xn[i] );
     372             : #else
     373             :         wener = L_mac0_o( wener, xn[i], xn[i], &Overflow );
     374             : #endif
     375             :     }
     376             : 
     377             :     /*wener = 10.0f*(float)log10(wener);*/
     378       11120 :     wener = BASOP_Util_Log2( wener );
     379       11120 :     wener = L_add( wener, L_shl( exp_xn, 31 - LD_DATA_SCALE ) );
     380       11120 :     wener = Mpy_32_16_1( wener, LG10 ); /* wener in 8Q7 */
     381             : #if ( GPCLIP_E != 6 + 2 )
     382             :     wener = shl( wener, GPCLIP_E - ( 6 + 2 ) );
     383             : #endif
     384       11120 :     tmp = round_fx( wener );
     385             :     /* exponent of wener = 6+2 */
     386             : 
     387       11120 :     test();
     388       12067 :     if ( LT_16( tmp, sub( mem[2], 768 /*6.0f Q7*/ ) ) &&
     389         947 :          GT_16( mem[1], 16384 /*1.0f Q14*/ ) )
     390             :     {
     391           0 :         move16();
     392           0 :         clip = 1;
     393             :     }
     394             : 
     395       11120 :     move16();
     396       11120 :     mem[2] = tmp;                         /* wener  in 8Q7 format */
     397       11120 :     Ltmp = Mpy_32_16_1( ALPHA1, mem[4] ); /* mem[4] in Q14 format, Ltmp in Q14 */
     398             : 
     399       11120 :     if ( s_or( (Word16) EQ_16( coder_type, GENERIC ), (Word16) EQ_16( coder_type, TRANSITION ) ) )
     400             :     {
     401        1575 :         Ltmp = L_add( Ltmp, ALPHA1_M1 ); /* Q30 */
     402             :     }
     403       11120 :     mem[4] = round_fx( Ltmp ); /* Q14 */
     404             : 
     405       11120 :     Ltmp = Mpy_32_16_1( ALPHA4, mem[5] ); /* mem[5] in Q14 format, Ltmp in Q14 */
     406       11120 :     IF( i_subfr == 0 )
     407             :     {
     408        2627 :         move16();                                                                 /* voicing: Q15 */
     409        2627 :         mem[5] = round_fx( L_add( Mpy_32_16_1( ALPHA4_M1, voicing[0] ), Ltmp ) ); /* Q14 */
     410             :     }
     411        8493 :     ELSE IF( EQ_16( i_subfr, shl( L_subfr, 1 ) ) )
     412             :     {
     413        2627 :         move16();
     414        2627 :         mem[5] = round_fx( L_add( Mpy_32_16_1( ALPHA4_M1, voicing[1] ), Ltmp ) ); /* Q14 */
     415             :     }
     416             : 
     417       11120 :     IF( GT_16( mem[3], WINDOW_SIZE ) )
     418             :     {
     419        7691 :         test();
     420        7691 :         if ( ( GT_16( mem[4], THRESH_TYPE ) ) && ( GT_16( mem[5], THRESH_VOICING ) ) )
     421             :         {
     422           0 :             move16();
     423           0 :             clip = 1;
     424             :         }
     425             :     }
     426             :     ELSE
     427             :     {
     428        3429 :         move16();
     429        3429 :         mem[3] = add( mem[3], 1 ); /* Q0 */
     430             :     }
     431             : 
     432             : 
     433       11120 :     return ( clip );
     434             : }
     435             : 
     436             : /*-------------------------------------------------------------------*
     437             :  * gp_clip_test_lsf:
     438             :  *
     439             :  * check the minimum distance of LSFs for pitch gain clipping flag
     440             :  *-------------------------------------------------------------------*/
     441        2669 : void gp_clip_test_lsf_fx(
     442             :     const Word16 element_mode, /* i  : element mode                                                                     Q0*/
     443             :     const Word16 lsf[],        /* i  : lsf values (in frequency domain)                         14Q1*1.28*/
     444             :     Word16 mem[],              /* i/o: memory of gain of pitch clipping algorithm       [2.56x,Q14,Q8,Q0,Q14,Q14]*/
     445             :     const Word16 m             /* i  : dimension of lsf                                                         Q0*/
     446             : )
     447             : {
     448             :     Word16 i;
     449             :     Word16 dist, dist_min, dist_max;
     450             : 
     451        2669 :     dist_max = DIST_ISF_MAX;
     452        2669 :     move16();
     453        2669 :     if ( element_mode > EVS_MONO )
     454             :     {
     455           0 :         dist_max = DIST_ISF_MAX_IO;
     456           0 :         move16();
     457             :     }
     458        2669 :     dist_min = sub( lsf[1], lsf[0] ); /* 14Q1*1.28 */
     459             : 
     460       18867 :     FOR( i = 2; i < m - 1; i++ )
     461             :     {
     462       16198 :         dist = sub( lsf[i], lsf[i - 1] ); /* 14Q1*1.28 */
     463       16198 :         dist_min = s_min( dist, dist_min );
     464             :     }
     465             :     /*dist = 0.8f*mem[0] + 0.2f*dist_min;*/
     466        2669 :     dist = s_min( dist_max, mac_r( L_mult( 26214 /*0.8f Q15*/, mem[0] ), 6554 /*0.2f Q15*/, dist_min ) ); /* x2.56 */
     467             : 
     468        2669 :     mem[0] = dist; /* x2.56 */
     469        2669 :     move16();
     470             : 
     471             : 
     472        2669 :     return;
     473             : }
     474             : 
     475      174472 : void gp_clip_test_lsf_ivas_fx(
     476             :     const Word16 element_mode, /* i  : element mode                               Q0*/
     477             :     const Word32 core_brate,   /* i  : core bitrate                               Q0*/
     478             :     const Word16 lsf[],        /* i  : LSF vector                                 14Q1*1.28*/
     479             :     Word16 mem[],              /* i/o: memory of gain of pitch clipping algorithm [2.56x,Q14,Q8,Q0,Q14,Q14]*/
     480             :     const Word16 Opt_AMR_WB    /* i  : flag indicating AMR-WB IO mode             Q0*/
     481             : )
     482             : {
     483             :     Word16 i;
     484             :     Word16 m;
     485             :     Word16 dist, dist_min;
     486             : 
     487      174472 :     dist_min = sub( lsf[1], lsf[0] ); /* 14Q1*1.28 */
     488             : 
     489      174472 :     IF( Opt_AMR_WB )
     490             :     {
     491           0 :         m = M - 1;
     492           0 :         move16();
     493             :     }
     494             :     ELSE
     495             :     {
     496      174472 :         m = M;
     497      174472 :         move16();
     498             :     }
     499             : 
     500     2617080 :     FOR( i = 2; i < m; i++ )
     501             :     {
     502     2442608 :         dist = sub( lsf[i], lsf[i - 1] ); /* 14Q1*1.28 */
     503     2442608 :         dist_min = s_min( dist, dist_min );
     504             :     }
     505             : 
     506             :     // dist = 0.8f * mem[0] + 0.2f * dist_min;
     507      174472 :     dist = mac_r( L_mult( 26214 /*0.8f Q15*/, mem[0] ), 6554 /*0.2f Q15*/, dist_min ); /* 2.56x */
     508             : 
     509      174472 :     test();
     510      174472 :     test();
     511      174472 :     IF( EQ_32( core_brate, ACELP_6k60 ) || EQ_32( core_brate, ACELP_8k85 ) || ( element_mode > EVS_MONO ) )
     512             :     {
     513      174472 :         if ( GT_16( dist, DIST_ISF_MAX_IO ) )
     514             :         {
     515       74076 :             dist = DIST_ISF_MAX_IO;
     516       74076 :             move16();
     517             :         }
     518             :     }
     519           0 :     ELSE IF( GT_16( dist, DIST_ISF_MAX ) )
     520             :     {
     521           0 :         dist = DIST_ISF_MAX;
     522           0 :         move16();
     523             :     }
     524             : 
     525      174472 :     mem[0] = dist; /* 2.56x */
     526      174472 :     move16();
     527             : 
     528      174472 :     return;
     529             : }

Generated by: LCOV version 1.14