LCOV - code coverage report
Current view: top level - lib_com - lerp.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 158 225 70.2 %
Date: 2025-05-03 01:55:50 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.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 "options.h"
      39             : #include "prot_fx.h"
      40             : #include "wmc_auto.h"
      41             : 
      42             : /*-------------------------------------------------------------*
      43             :  * Local function prototypes
      44             :  *-------------------------------------------------------------*/
      45             : 
      46             : /*-------------------------------------------------------------*
      47             :  * procedure lerp_flt()                                            *
      48             :  *                                                             *
      49             :  *                                                             *
      50             :  *-------------------------------------------------------------*/
      51             : 
      52             : /*-------------------------------------------------------------*
      53             :  * procedure lerp_proc_flt()                                       *
      54             :  *                                                             *
      55             :  *                                                             *
      56             :  *-------------------------------------------------------------*/
      57             : 
      58             : /*-------------------------------------------------------------*
      59             :  * Local constants
      60             :  *-------------------------------------------------------------*/
      61             : 
      62             : #define shift_e ( 16 - 1 )
      63             : #define pos_e   ( 16 - 1 )
      64             : /*-------------------------------------------------------------*
      65             :  * Local function prototypes
      66             :  *-------------------------------------------------------------*/
      67             : 
      68             : static void lerp_proc( const Word16 *f, Word16 *f_out, Word16 bufferNewSize, Word16 bufferOldSize );
      69             : 
      70             : /*-------------------------------------------------------------*
      71             :  * procedure lerp()                                            *
      72             :  *                                                             *
      73             :  *                                                             *
      74             :  *-------------------------------------------------------------*/
      75             : 
      76      866336 : void lerp( const Word16 *f /*Qx*/, Word16 *f_out /*Qx*/, Word16 bufferNewSize /*Q0*/, Word16 bufferOldSize /*Q0*/ )
      77             : {
      78             :     Word16 tmp1, tmp2, tmpexp;
      79      866336 :     BASOP_Util_Divide_MantExp( bufferNewSize, 0, bufferOldSize, 0, &tmp1, &tmpexp );
      80      866336 :     tmp1 = shr( tmp1, 3 );      /*Q12*/
      81      866336 :     tmp1 = shl( tmp1, tmpexp ); /*Q12+tmpexp*/
      82             : 
      83      866336 :     BASOP_Util_Divide_MantExp( bufferOldSize, 0, bufferNewSize, 0, &tmp2, &tmpexp );
      84      866336 :     tmp2 = shr( tmp2, 3 );      /*Q12*/
      85      866336 :     tmp2 = shl( tmp2, tmpexp ); /*Q12+tmpexp*/
      86      866336 :     IF( GT_16( tmp1, 16224 /*3.9609375 in Q12*/ ) )
      87             :     {
      88           0 :         Word16 tmpNewSize = shl( bufferOldSize, 1 ); /*Q0*/
      89           0 :         WHILE( GT_16( bufferNewSize, bufferOldSize ) )
      90             :         {
      91           0 :             BASOP_Util_Divide_MantExp( bufferNewSize, 0, bufferOldSize, 0, &tmp1, &tmpexp );
      92           0 :             tmp1 = shr( tmp1, 3 );      /*Q12*/
      93           0 :             tmp1 = shl( tmp1, tmpexp ); /*Q12+tmpexp*/
      94           0 :             if ( LE_16( tmp1, 16224 /*3.9609375 in Q12*/ ) )
      95             :             {
      96           0 :                 tmpNewSize = bufferNewSize; /*Q0*/
      97           0 :                 move16();
      98             :             }
      99             : 
     100           0 :             lerp_proc( f, f_out, tmpNewSize, bufferOldSize );
     101             : 
     102           0 :             f = f_out;                  /*Qx*/
     103           0 :             bufferOldSize = tmpNewSize; /*Q0*/
     104           0 :             move16();
     105           0 :             tmpNewSize = shl( tmpNewSize, 1 ); /*Q0*/
     106             :         }
     107             :     }
     108      866336 :     ELSE IF( GT_16( tmp2, 16224 /*3.9609375 in Q12*/ ) )
     109             :     {
     110           0 :         Word16 tmpNewSize = shr( bufferOldSize, 1 );
     111           0 :         WHILE( LT_16( bufferNewSize, bufferOldSize ) )
     112             :         {
     113           0 :             BASOP_Util_Divide_MantExp( bufferOldSize, 0, bufferNewSize, 0, &tmp2, &tmpexp );
     114           0 :             tmp2 = shr( tmp2, 3 );      /*Q12*/
     115           0 :             tmp2 = shl( tmp2, tmpexp ); /*Q12+tmpexp*/
     116             : 
     117           0 :             if ( LE_16( tmp2, 16224 /*3.9609375 in Q12*/ ) )
     118             :             {
     119           0 :                 tmpNewSize = bufferNewSize; /*Q0*/
     120           0 :                 move16();
     121             :             }
     122             : 
     123           0 :             lerp_proc( f, f_out, tmpNewSize, bufferOldSize );
     124             : 
     125           0 :             f = f_out;                  /*Qx*/
     126           0 :             bufferOldSize = tmpNewSize; /*Q0*/
     127           0 :             move16();
     128           0 :             tmpNewSize = shr( tmpNewSize, 1 ); /*Q0*/
     129             :         }
     130             :     }
     131             :     ELSE
     132             :     {
     133      866336 :         lerp_proc( f, f_out, bufferNewSize, bufferOldSize );
     134             :     }
     135      866336 : }
     136             : /*-------------------------------------------------------------*
     137             :  * procedure lerp_proc()                                       *
     138             :  *                                                             *
     139             :  *                                                             *
     140             :  *-------------------------------------------------------------*/
     141      866336 : static void lerp_proc( const Word16 *f /*Qx*/, Word16 *f_out /*Qx*/, Word16 bufferNewSize /*Q0*/, Word16 bufferOldSize /*Q0*/ )
     142             : {
     143             : 
     144             :     Word16 i, idx, n;
     145             :     Word16 diff;
     146             :     Word32 pos, shift;
     147             :     Word16 buf[2 * L_FRAME_MAX];
     148             :     Word16 *ptr;
     149             : 
     150      866336 :     ptr = f_out; /*Qx*/
     151      866336 :     test();
     152      866336 :     test();
     153      866336 :     test();
     154      866336 :     if ( ( ( f <= f_out ) && ( f + bufferOldSize >= f_out ) ) || ( ( f_out <= f ) && ( f_out + bufferNewSize >= f ) ) )
     155             :     {
     156      184143 :         ptr = buf; /*Qx*/
     157             :     }
     158             : 
     159      866336 :     IF( EQ_16( bufferNewSize, bufferOldSize ) )
     160             :     {
     161       40618 :         Copy( f, f_out, bufferNewSize ); /*Qx*/
     162       40618 :         return;
     163             :     }
     164             : 
     165      825718 :     shift = L_shl( L_deposit_l( div_s( bufferOldSize, shl( bufferNewSize, 4 ) ) ), 4 - shift_e + 16 ); /*Q16*/
     166             : 
     167      825718 :     pos = L_sub( L_shr( shift, 1 ), 32768l /*0.5f Q16*/ ); /*Q16*/
     168             : 
     169             :     /* Adjust interpolation shift to avoid accessing beyond end of input buffer. */
     170      825718 :     if ( LT_32( shift, 19661l /*0.3f Q16*/ ) )
     171             :     {
     172        2392 :         pos = L_sub( pos, 8520l /*0.13f Q16*/ ); /*Q16*/
     173             :     }
     174             : 
     175             :     assert( pos_e == shift_e );
     176             : 
     177             :     /* first point of interpolation */
     178      825718 :     IF( pos < 0 )
     179             :     {
     180             : 
     181      169175 :         diff = shr( extract_l( pos ), 1 ); /*Q15*/
     182             :         /*buf[0]=f[0]+pos*(f[1]-f[0]);*/
     183      169175 :         move16();
     184      169175 :         *ptr++ = add_sat( f[0], msu_r( L_mult( diff, f[1] ), diff, f[0] ) ); /*Qx*/
     185             :     }
     186             :     ELSE
     187             :     {
     188             : 
     189      656543 :         idx = extract_h( pos ); /*Q0*/
     190             : 
     191      656543 :         diff = lshr( extract_l( pos ), 1 ); /*Q15*/
     192             : 
     193      656543 :         move16();
     194      656543 :         *ptr++ = add_sat( f[idx], msu_r_sat( L_mult( diff, f[idx + 1] ), diff, f[idx] ) ); /*Qx*/
     195             :     }
     196             : 
     197      825718 :     pos = L_add( pos, shift );
     198      825718 :     idx = s_max( 0, extract_h( pos ) );
     199             : 
     200      825718 :     n = sub( bufferNewSize, 1 );
     201   150818840 :     FOR( i = 1; i < n; i++ )
     202             :     {
     203   149993122 :         diff = lshr( extract_l( pos ), 1 ); /*Q15*/
     204   149993122 :         if ( pos < 0 )
     205             :         {
     206        4818 :             diff = sub( 16384 /*0.5f Q15*/, diff ); /*Q15*/
     207             :         }
     208   149993122 :         move16();
     209   149993122 :         *ptr++ = add_sat( f[idx], msu_r_sat( L_mult( diff, f[idx + 1] ), diff, f[idx] ) ); /*Qx*/
     210             : 
     211             : 
     212   149993122 :         pos = L_add( pos, shift );
     213   149993122 :         idx = extract_h( pos ); /*Q0*/
     214             :     }
     215             : 
     216             :     /* last point */
     217             : 
     218      825718 :     if ( GT_32( pos, L_deposit_h( sub( bufferOldSize, 1 ) ) ) )
     219             :     {
     220      167388 :         idx = sub( bufferOldSize, 2 );
     221             :     }
     222      825718 :     assert( idx <= 2 * L_FRAME_MAX );
     223             : 
     224             :     /* diff = t - point;*/
     225      825718 :     diff = lshr( extract_l( L_shr( L_sub( pos, L_deposit_h( idx ) ), 1 ) ), 1 ); /*Q15*/
     226             : 
     227      825718 :     move16();
     228      825718 :     *ptr++ = add_sat( f[idx], shl_sat( msu_r_sat( L_mult( diff, f[idx + 1] ), diff, f[idx] ), 1 ) ); /*Qx*/
     229      825718 :     test();
     230      825718 :     test();
     231      825718 :     test();
     232      825718 :     IF( ( ( f <= f_out ) && ( f + bufferOldSize >= f_out ) ) || ( ( f_out <= f ) && ( f_out + bufferNewSize >= f ) ) )
     233             :     {
     234      153223 :         Copy( buf, f_out, bufferNewSize ); /*Qx*/
     235             :     }
     236             : }
     237             : 
     238             : 
     239      157854 : static void lerp_proc32( Word32 *f /*Qx*/, Word32 *f_out /*Qx*/, Word16 bufferNewSize /*Q0*/, Word16 bufferOldSize /*Q0*/ )
     240             : {
     241             : 
     242             :     Word16 i, idx, n;
     243             :     Word16 diff;
     244             :     Word32 pos, shift;
     245             :     Word32 buf[2 * L_FRAME_MAX];
     246             :     Word32 *ptr;
     247             : 
     248      157854 :     ptr = f_out; /*Qx*/
     249      157854 :     test();
     250      157854 :     test();
     251      157854 :     test();
     252      157854 :     if ( ( ( f <= f_out ) && ( f + bufferOldSize >= f_out ) ) || ( ( f_out <= f ) && ( f_out + bufferNewSize >= f ) ) )
     253             :     {
     254       49983 :         ptr = buf; /*Qx*/
     255             :     }
     256             : 
     257      157854 :     IF( EQ_16( bufferNewSize, bufferOldSize ) )
     258             :     {
     259       37004 :         Copy32( f, f_out, bufferNewSize ); /*Qx*/
     260       37004 :         return;
     261             :     }
     262             : 
     263      120850 :     shift = L_shl( L_deposit_l( div_s( bufferOldSize, shl( bufferNewSize, 4 ) ) ), add( sub( 4, shift_e ), Q16 ) ); /*Q16*/
     264             : 
     265      120850 :     pos = L_sub( L_shr( shift, 1 ), 32768l /*0.5f Q16*/ ); /*Q16*/
     266             : 
     267             :     /* Adjust interpolation shift to avoid accessing beyond end of input buffer. */
     268      120850 :     if ( LT_32( shift, 19661l /*0.3f Q16*/ ) )
     269             :     {
     270        2183 :         pos = L_sub( pos, 8520l /*0.13f Q16*/ ); /*Q16*/
     271             :     }
     272             : 
     273             :     assert( pos_e == shift_e );
     274             : 
     275             :     /* first point of interpolation */
     276      120850 :     IF( pos < 0 )
     277             :     {
     278             : 
     279       39487 :         diff = shr( extract_l( pos ), 1 ); /*Q15*/
     280             :         /*buf[0]=f[0]+pos*(f[1]-f[0]);*/
     281       39487 :         *ptr++ = L_add_sat( f[0], Mpy_32_16_1( L_sub( f[1], f[0] ), diff ) ); /*Qx*/
     282       39487 :         move32();
     283             :     }
     284             :     ELSE
     285             :     {
     286             : 
     287       81363 :         idx = extract_h( pos );                                                             /*Q0*/
     288       81363 :         diff = lshr( extract_l( pos ), 1 );                                                 /*Q15*/
     289       81363 :         *ptr++ = L_add_sat( f[idx], Mpy_32_16_1( L_sub( f[( idx + 1 )], f[idx] ), diff ) ); /*Qx*/
     290       81363 :         move32();
     291             :     }
     292             : 
     293      120850 :     pos = L_add( pos, shift );          /*Q16*/
     294      120850 :     idx = s_max( 0, extract_h( pos ) ); /*Q0*/
     295             : 
     296      120850 :     n = sub( bufferNewSize, 1 );
     297    28042524 :     FOR( i = 1; i < n; i++ )
     298             :     {
     299    27921674 :         diff = lshr( extract_l( pos ), 1 );
     300    27921674 :         if ( pos < 0 )
     301             :         {
     302       12865 :             diff = sub( 16384 /*0.5f Q15*/, diff ); /*Q15*/
     303             :         }
     304    27921674 :         *ptr++ = L_add_sat( f[idx], L_sub( Mpy_32_16_1( f[idx + 1], diff ), Mpy_32_16_1( f[idx], diff ) ) ); /*Qx*/
     305    27921674 :         move32();
     306    27921674 :         pos = L_add( pos, shift ); /*Q16*/
     307    27921674 :         idx = extract_h( pos );
     308             :     }
     309             : 
     310             :     /* last point */
     311             : 
     312      120850 :     if ( GT_32( pos, L_deposit_h( sub( bufferOldSize, 1 ) ) ) )
     313             :     {
     314       39487 :         idx = sub( bufferOldSize, 2 );
     315             :     }
     316      120850 :     assert( idx <= 2 * L_FRAME_MAX );
     317             : 
     318             :     /* diff = t - point;*/
     319      120850 :     diff = lshr( extract_l( L_shr( L_sub( pos, L_deposit_h( idx ) ), 1 ) ), 1 ); /*Q15*/
     320             : 
     321      120850 :     *ptr++ = L_add_sat( f[idx], L_shl_sat( Mpy_32_16_1( L_sub( f[( idx + 1 )], f[idx] ), diff ), 1 ) ); /*Qx*/
     322      120850 :     move32();
     323      120850 :     test();
     324      120850 :     test();
     325      120850 :     test();
     326      120850 :     IF( ( ( f <= f_out ) && ( f + bufferOldSize >= f_out ) ) || ( ( f_out <= f ) && ( f_out + bufferNewSize >= f ) ) )
     327             :     {
     328       38806 :         Copy32( buf, f_out, bufferNewSize ); /*Qx*/
     329             :     }
     330             : }
     331             : 
     332             : 
     333             : static void L_lerp_proc_fx( const Word32 *f_fx, Word32 *f_out_fx, const Word16 bufferNewSize, const Word16 bufferOldSize );
     334             : 
     335             : /*-------------------------------------------------------------*
     336             :  * procedure lerp()                                            *
     337             :  *                                                             *
     338             :  *                                                             *
     339             :  *-------------------------------------------------------------*/
     340             : 
     341       65054 : void L_lerp_fx( Word32 *f /*q*/, Word32 *f_out /*q*/, Word16 bufferNewSize /*Q0*/, Word16 bufferOldSize /*Q0*/, Word16 *q )
     342             : {
     343             :     Word16 tmpNewSize;
     344             :     Word16 tmp1, tmp2, tmp_e;
     345       65054 :     tmp1 = BASOP_Util_Divide1616_Scale( bufferNewSize, bufferOldSize, &tmp_e ); /*Q15 - tmp_e*/
     346       65054 :     tmp1 = shr( tmp1, sub( 15, tmp_e ) );                                       /*Q0*/
     347             : 
     348       65054 :     tmp2 = BASOP_Util_Divide1616_Scale( bufferOldSize, bufferNewSize, &tmp_e ); /*Q15 - tmp_e*/
     349       65054 :     tmp2 = shr( tmp2, sub( 15, tmp_e ) );                                       /*Q0*/
     350       65054 :     Word16 guard_bits = add( s_max( tmp1, tmp2 ), 1 );
     351       65054 :     IF( LT_16( getScaleFactor32( f, bufferOldSize ), guard_bits ) )
     352             :     {
     353       62062 :         *q = sub( *q, guard_bits );
     354    16643770 :         FOR( Word16 ind = 0; ind < bufferOldSize; ind++ )
     355             :         {
     356    16581708 :             f[ind] = L_shr( f[ind], guard_bits ); /*Q(guard_bits)*/
     357    16581708 :             move32();
     358             :         }
     359             :     }
     360             : 
     361       65054 :     IF( GT_32( L_mult0( 128, bufferNewSize ), L_mult0( bufferOldSize, 507 ) ) )
     362             :     {
     363           0 :         tmpNewSize = shl( bufferOldSize, 1 ); /*Q0*/
     364           0 :         WHILE( GT_16( bufferNewSize, bufferOldSize ) )
     365             :         {
     366           0 :             if ( LE_32( L_mult0( 128, bufferNewSize ), L_mult0( bufferOldSize, 507 ) ) )
     367             :             {
     368           0 :                 tmpNewSize = bufferNewSize; /*Q0*/
     369           0 :                 move16();
     370             :             }
     371             : 
     372           0 :             L_lerp_proc_fx( f, f_out, tmpNewSize, bufferOldSize );
     373             : 
     374           0 :             f = f_out;
     375           0 :             bufferOldSize = tmpNewSize; /*Q0*/
     376           0 :             move16();
     377           0 :             tmpNewSize = shl( tmpNewSize, 1 ); /*Q0*/
     378             :         }
     379             :     }
     380       65054 :     ELSE IF( GT_32( L_mult0( 128, bufferOldSize ), L_mult0( bufferNewSize, 507 ) ) )
     381             :     {
     382           0 :         tmpNewSize = shr( bufferOldSize, 1 ); /*Q0*/
     383           0 :         WHILE( LT_16( bufferNewSize, bufferOldSize ) )
     384             :         {
     385           0 :             if ( LE_32( L_mult0( 128, bufferOldSize ), L_mult0( bufferNewSize, 507 ) ) )
     386             :             {
     387           0 :                 tmpNewSize = bufferNewSize; /*Q0*/
     388           0 :                 move16();
     389             :             }
     390             : 
     391           0 :             L_lerp_proc_fx( f, f_out, tmpNewSize, bufferOldSize );
     392             : 
     393           0 :             f = f_out;                  /*q*/
     394           0 :             bufferOldSize = tmpNewSize; /*Q0*/
     395           0 :             move16();
     396           0 :             tmpNewSize = shr( tmpNewSize, 1 ); /*Q0*/
     397             :         }
     398             :     }
     399             :     ELSE
     400             :     {
     401       65054 :         L_lerp_proc_fx( f, f_out, bufferNewSize, bufferOldSize );
     402             :     }
     403             : 
     404       65054 :     return;
     405             : }
     406      157854 : void L_lerp_fx_q11( Word32 *f /*Q11*/, Word32 *f_out /*Q11*/, Word16 bufferNewSize /*Q0*/, Word16 bufferOldSize /*Q0*/ )
     407             : {
     408             :     Word16 tmpNewSize;
     409             : 
     410      157854 :     IF( GT_32( L_mult0( 128, bufferNewSize ), L_mult0( bufferOldSize, 507 ) ) )
     411             :     {
     412           0 :         tmpNewSize = shl( bufferOldSize, 1 ); /*Q0*/
     413           0 :         WHILE( GT_16( bufferNewSize, bufferOldSize ) )
     414             :         {
     415           0 :             if ( LE_32( L_mult0( 128, bufferNewSize ), L_mult0( bufferOldSize, 507 ) ) )
     416             :             {
     417           0 :                 tmpNewSize = bufferNewSize; /*Q0*/
     418           0 :                 move16();
     419             :             }
     420             : 
     421           0 :             lerp_proc32( f, f_out, tmpNewSize, bufferOldSize );
     422             : 
     423           0 :             f = f_out;                  /*Q11*/
     424           0 :             bufferOldSize = tmpNewSize; /*Q0*/
     425           0 :             move16();
     426           0 :             tmpNewSize = shl( tmpNewSize, 1 ); /*Q0*/
     427             :         }
     428             :     }
     429      157854 :     ELSE IF( GT_32( L_mult0( 128, bufferOldSize ), L_mult0( bufferNewSize, 507 ) ) )
     430             :     {
     431           0 :         tmpNewSize = shr( bufferOldSize, 1 ); /*Q0*/
     432           0 :         WHILE( LT_16( bufferNewSize, bufferOldSize ) )
     433             :         {
     434           0 :             if ( LE_32( L_mult0( 128, bufferOldSize ), L_mult0( bufferNewSize, 507 ) ) )
     435             :             {
     436           0 :                 tmpNewSize = bufferNewSize; /*Q0*/
     437           0 :                 move16();
     438             :             }
     439             : 
     440           0 :             lerp_proc32( f, f_out, tmpNewSize, bufferOldSize );
     441             : 
     442           0 :             f = f_out;
     443           0 :             bufferOldSize = tmpNewSize; /*Q0*/
     444           0 :             move16();
     445           0 :             tmpNewSize = shr( tmpNewSize, 1 ); /*Q0*/
     446             :         }
     447             :     }
     448             :     ELSE
     449             :     {
     450      157854 :         lerp_proc32( f, f_out, bufferNewSize, bufferOldSize );
     451             :     }
     452             : 
     453      157854 :     return;
     454             : }
     455             : 
     456             : /*-------------------------------------------------------------*
     457             :  * procedure lerp_proc()                                       *
     458             :  *                                                             *
     459             :  *                                                             *
     460             :  *-------------------------------------------------------------*/
     461       65054 : static void L_lerp_proc_fx(
     462             :     const Word32 *f_fx,         /*Qx*/
     463             :     Word32 *f_out_fx,           /*Qx*/
     464             :     const Word16 bufferNewSize, /*Q0*/
     465             :     const Word16 bufferOldSize /*Q0*/ )
     466             : {
     467             :     Word16 i, idx;
     468             :     Word32 pos_fx, shift_fx, diff_fx;
     469             :     Word32 buf_fx[2 * L_FRAME_MAX];
     470             :     Word16 tmp;
     471             :     Word32 ffxsub;
     472             : 
     473       65054 :     IF( EQ_16( bufferNewSize, bufferOldSize ) )
     474             :     {
     475          12 :         Copy32( f_fx, buf_fx, bufferNewSize );     /*Qx*/
     476          12 :         Copy32( buf_fx, f_out_fx, bufferNewSize ); /*Qx*/
     477          12 :         return;
     478             :     }
     479             : 
     480             :     /* Using the basop code to avoid reading beyond end of input for bufferOldSize=320, bufferNewSize=640 */
     481       65042 :     tmp = div_s( bufferOldSize, shl( bufferNewSize, 4 ) );                        /*Q11*/
     482       65042 :     shift_fx = L_shl( L_deposit_l( tmp ), 4 - 15 + 21 );                          // q =21
     483       65042 :     pos_fx = Mpy_32_32( L_sub( shift_fx, 1 << 21 ), ONE_IN_Q30 /*0.5f in Q31*/ ); /*Q21*/
     484             : 
     485       65042 :     IF( LT_32( shift_fx, L_shr( 644245094 /*0.3 in Q31*/, 31 - 21 ) ) )
     486             :     {
     487           0 :         pos_fx = L_sub( pos_fx, L_shr( 279172874 /*0.13 in Q31*/, 31 - 21 ) ); /*Q21*/
     488             :     }
     489             : 
     490             :     /* first point of interpolation */
     491       65042 :     IF( pos_fx < 0 )
     492             :     {
     493        3922 :         buf_fx[0] = L_add( f_fx[0], L_shl( Mpy_32_32( pos_fx, L_sub( f_fx[1], f_fx[0] ) ), 31 - 21 ) ); /*Qx*/
     494        3922 :         move32();
     495             :     }
     496             :     ELSE
     497             :     {
     498       61120 :         idx = extract_l( L_shr( pos_fx, 21 ) );
     499             : 
     500       61120 :         diff_fx = L_sub( pos_fx, L_shl( idx, 21 ) );
     501       61120 :         ffxsub = L_sub( f_fx[idx + 1], f_fx[idx] );
     502             : 
     503       61120 :         Word64 f_fx64 = W_shl( f_fx[idx], 21 );
     504       61120 :         Word64 mult64 = W_mult0_32_32( diff_fx, ffxsub );
     505       61120 :         Word64 add64 = W_add( f_fx64, mult64 );
     506             : 
     507       61120 :         buf_fx[0] = W_extract_l( W_shr( add64, 21 ) );
     508       61120 :         move32();
     509             :     }
     510             : 
     511       65042 :     pos_fx = L_add( pos_fx, shift_fx ); /*Q21*/
     512             : 
     513     9882886 :     FOR( i = 1; i < bufferNewSize - 1; i++ )
     514             :     {
     515     9817844 :         idx = extract_l( L_shr( pos_fx, 21 ) );
     516     9817844 :         diff_fx = L_sub( pos_fx, L_shl( idx, 21 ) ); /*Q21*/
     517             : 
     518     9817844 :         ffxsub = L_sub( f_fx[idx + 1], f_fx[idx] );
     519             : 
     520     9817844 :         Word64 f_fx64 = W_shl( f_fx[idx], 21 );
     521     9817844 :         Word64 mult64 = W_mult0_32_32( diff_fx, ffxsub );
     522     9817844 :         Word64 add64 = W_add( f_fx64, mult64 );
     523             : 
     524     9817844 :         buf_fx[i] = W_extract_l( W_shr( add64, 21 ) );
     525     9817844 :         move32();
     526             : 
     527     9817844 :         pos_fx = L_add( pos_fx, shift_fx ); /*Q21*/
     528             :     }
     529             : 
     530             : 
     531             :     /* last point */
     532       65042 :     idx = extract_l( L_shr( pos_fx, 21 ) ); /*Q0*/
     533             : 
     534       65042 :     if ( GT_32( pos_fx, L_shl( sub( bufferOldSize, 1 ), 21 ) ) )
     535             :     {
     536        2082 :         idx = sub( bufferOldSize, 2 );
     537             :     }
     538             : 
     539       65042 :     diff_fx = L_sub( pos_fx, L_shl( idx, 21 ) ); /*Q21*/
     540             : 
     541       65042 :     buf_fx[( bufferNewSize - 1 )] = L_add( f_fx[idx], L_shl( Mpy_32_32( diff_fx, L_sub( f_fx[( idx + 1 )], f_fx[idx] ) ), 31 - 21 ) ); /*Qx*/
     542       65042 :     move32();
     543             : 
     544       65042 :     Copy32( buf_fx, f_out_fx, bufferNewSize ); /*Qx*/
     545             : 
     546       65042 :     return;
     547             : }

Generated by: LCOV version 1.14