LCOV - code coverage report
Current view: top level - lib_lc3plus - basop_util_lc3plus.h (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 0 10 0.0 %
Date: 2025-08-23 01:22:27 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             : *                        ETSI TS 103 634 V1.5.1                               *
       3             : *              Low Complexity Communication Codec Plus (LC3plus)              *
       4             : *                                                                             *
       5             : * Copyright licence is solely granted through ETSI Intellectual Property      *
       6             : * Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
       7             : * estoppel or otherwise.                                                      *
       8             : ******************************************************************************/
       9             : 
      10             : #ifndef __BASOP_UTIL_LC3PLUS_H__
      11             : #define __BASOP_UTIL_LC3PLUS_H__
      12             : 
      13             : #include "defines.h"
      14             : #include "functions.h"
      15             : #include <assert.h>
      16             : #include <string.h>
      17             : 
      18             : #define _LONG long
      19             : #define _SHORT short
      20             : #ifdef _WIN32
      21             : #define _INT64 __int64
      22             : #else
      23             : #define _INT64 long long
      24             : #endif
      25             : 
      26             : #define WORD32_BITS 32
      27             : #define MAXVAL_WORD32 ((signed)0x7FFFFFFF)
      28             : #define MINVAL_WORD32 ((signed)0x80000000)
      29             : #define WORD32_FIX_SCALE ((_INT64)(1) << (WORD32_BITS - 1))
      30             : 
      31             : #define WORD16_BITS 16
      32             : #define MAXVAL_WORD16 (((signed)0x7FFFFFFF) >> 16)
      33             : #define MINVAL_WORD16 (((signed)0x80000000) >> 16)
      34             : #define WORD16_FIX_SCALE ((_INT64)(1) << (WORD16_BITS - 1))
      35             : 
      36             : /*!
      37             :   \def   Macro converts a Word32 fixed point to Word16 fixed point <1 with saturation
      38             : */
      39             : #define WORD322WORD16(val)                                                                                             \
      40             :     ((((((val) >> (WORD32_BITS - WORD16_BITS - 1)) + 1) > (((_LONG)1 << WORD16_BITS) - 1)) && ((_LONG)(val) > 0))      \
      41             :          ? (Word16)(_SHORT)(((_LONG)1 << (WORD16_BITS - 1)) - 1)                                                       \
      42             :          : (Word16)(_SHORT)((((val) >> (WORD32_BITS - WORD16_BITS - 1)) + 1) >> 1))
      43             : 
      44             : 
      45             : /* Word16 Packed Type */
      46             : typedef struct
      47             : {
      48             :     struct
      49             :     {
      50             :         Word16 re;
      51             :         Word16 im;
      52             :     } v;
      53             : } PWord16;
      54             : 
      55             : #ifdef ENABLE_HR_MODE
      56             : /* Word32 Packed Type */
      57             : typedef struct
      58             : {
      59             :     struct
      60             :     {
      61             :         Word32 re;
      62             :         Word32 im;
      63             :     } v;
      64             : } PWord32;
      65             : #endif
      66             : 
      67             : #define cast16 move16
      68             : 
      69             : #define LD_DATA_SCALE (6)
      70             : #define LD_DATA_SHIFT_I5 (7)
      71             : 
      72             : /************************************************************************/
      73             : /*!
      74             :   \brief   Calculate the squareroot of a number given by mantissa and exponent
      75             : 
      76             :   Mantissa is in 16/32-bit-fractional format with values between 0 and 1. <br>
      77             :   For *norm versions mantissa has to be between 0.5 and 1. <br>
      78             :   The base for the exponent is 2.  Example:  \f$  a = a\_m * 2^{a\_e}  \f$<br>
      79             :   The exponent is addressed via pointers and will be overwritten with the result.
      80             : */
      81             : 
      82             : Word16 Sqrt16_lc3plus(                  /*!< output mantissa */
      83             :               Word16  mantissa, /*!< input mantissa */
      84             :               Word16 *exponent  /*!< pointer to exponent */
      85             : );
      86             : 
      87             : Word16 ISqrt16(                  /*!< output mantissa */
      88             :                Word16  mantissa, /*!< input mantissa */
      89             :                Word16 *exponent  /*!< pointer to exponent */
      90             : );
      91             : 
      92             : /*****************************************************************************/
      93             : /*!
      94             :   \brief   Calculate the inverse of a number given by mantissa and exponent
      95             : 
      96             :   Mantissa is in 16-bit-fractional format with values between 0 and 1. <br>
      97             :   The base for the exponent is 2.  Example:  \f$  a = a\_m * 2^{a\_e}  \f$<br>
      98             :   The operand is addressed via pointers and will be overwritten with the result.
      99             : 
     100             :   The function uses a table lookup and a newton iteration.
     101             : */
     102             : Word16 Inv16_lc3plus(                  /*!< output mantissa */
     103             :              Word16  mantissa, /*!< input mantissa */
     104             :              Word16 *exponent  /*!< pointer to exponent */
     105             : );
     106             : 
     107             : /********************************************************************/
     108             : /*!
     109             :   \brief   Calculates the scalefactor needed to normalize input array
     110             : 
     111             :     The scalefactor needed to normalize the Word16 input array is returned <br>
     112             :     If the input array contains only '0', a scalefactor 0 is returned <br>
     113             :     Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x <br>
     114             :     and   -32768 <= x <= -16384 for negative x
     115             : */
     116             : 
     117             : Word16 getScaleFactor16(                     /* o: measured headroom in range [0..15], 0 if all x[i] == 0 */
     118             :                         const Word16 *x,     /* i: array containing 16-bit data */
     119             :                         const Word16  len_x); /* i: length of the array to scan  */
     120             : 
     121             : /********************************************************************/
     122             : /*!
     123             :   \brief   Calculates the scalefactor needed to normalize input array
     124             : 
     125             :     The scalefactor needed to normalize the Word16 input array is returned <br>
     126             :     If the input array contains only '0', a scalefactor 16 is returned <br>
     127             :     Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x <br>
     128             :     and   -32768 <= x <= -16384 for negative x
     129             : */
     130             : 
     131             : Word16 getScaleFactor16_0(                     /* o: measured headroom in range [0..15], 16 if all x[i] == 0 */
     132             :                           const Word16 *x,     /* i: array containing 16-bit data */
     133             :                           const Word16  len_x); /* i: length of the array to scan  */
     134             : 
     135             : /********************************************************************/
     136             : /*!
     137             :   \brief   Calculates the scalefactor needed to normalize input array
     138             : 
     139             :     The scalefactor needed to normalize the Word32 input array is returned <br>
     140             :     If the input array contains only '0', a scalefactor 0 is returned <br>
     141             :     Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x <br>
     142             :     and   -2147483648 <= x <= -1073741824 for negative x
     143             : */
     144             : 
     145             : Word16 getScaleFactor32_lc3plus(                     /* o: measured headroom in range [0..31], 0 if all x[i] == 0 */
     146             :                         const Word32 *x,     /* i: array containing 32-bit data */
     147             :                         const Word16  len_x); /* i: length of the array to scan  */
     148             : 
     149             : /********************************************************************/
     150             : /*!
     151             :   \brief   Calculates the scalefactor needed to normalize input array
     152             : 
     153             :     The scalefactor needed to normalize the Word32 input array is returned <br>
     154             :     If the input array contains only '0', a scalefactor 32 is returned <br>
     155             :     Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x <br>
     156             :     and   -2147483648 <= x <= -1073741824 for negative x
     157             : */
     158             : 
     159             : Word16 getScaleFactor32_0(                     /* o: measured headroom in range [0..31], 32 if all x[i] == 0 */
     160             :                           const Word32 *x,     /* i: array containing 32-bit data */
     161             :                           const Word16  len_x); /* i: length of the array to scan  */
     162             : 
     163             : /****************************************************************************/
     164             : /*!
     165             :   \brief   Does fractional integer division of Word32 arg1 by Word16 arg2
     166             : 
     167             : 
     168             :   \return fractional Word16 integer z = arg1(32bits)/arg2(16bits) , z not normalized
     169             : */
     170             : Word16 BASOP_Util_Divide3216_Scale_lc3plus(Word32  x,  /*!< i  : Numerator  */
     171             :                                    Word16  y,  /*!< i  : Denominator*/
     172             :                                    Word16 *s); /*!< o  : Additional scalefactor difference*/
     173             : 
     174             : /****************************************************************************/
     175             : /*!
     176             :   \brief   Does fractional division of Word16 arg1 by Word16 arg2
     177             : 
     178             : 
     179             :   \return fractional Q15 Word16 z = arg1(Q15)/arg2(Q15)  with scaling s
     180             : */
     181             : Word16 BASOP_Util_Divide1616_Scale_lc3plus(Word16  x,  /*!< i  : Numerator*/
     182             :                                    Word16  y,  /*!< i  : Denominator*/
     183             :                                    Word16 *s); /*!< o  : Additional scalefactor difference*/
     184             : 
     185             : /************************************************************************/
     186             : /*!
     187             :   \brief     Binary logarithm with 7 iterations
     188             : 
     189             :   \param   x
     190             : 
     191             :   \return log2(x)/64
     192             :  */
     193             : /************************************************************************/
     194             : Word32 BASOP_Util_Log2_lc3plus(Word32 x);
     195             : 
     196             : /************************************************************************/
     197             : /*!
     198             :   \brief     Binary power
     199             : 
     200             :   Date: 06-JULY-2012 Arthur Tritthart, IIS Fraunhofer Erlangen
     201             : 
     202             :   Version with 3 table lookup and 1 linear interpolations
     203             : 
     204             :   Algorithm: compute power of 2, argument x is in Q7.25 format
     205             :              result = 2^(x/64)
     206             :              We split exponent (x/64) into 5 components:
     207             :              integer part:      represented by b31..b25  (exp)
     208             :              fractional part 1: represented by b24..b20  (lookup1)
     209             :              fractional part 2: represented by b19..b15  (lookup2)
     210             :              fractional part 3: represented by b14..b10  (lookup3)
     211             :              fractional part 4: represented by b09..b00  (frac)
     212             :              => result = (lookup1*lookup2*(lookup3+C1*frac)<<3)>>exp
     213             : 
     214             :   Due to the fact, that all lookup values contain a factor 0.5
     215             :   the result has to be shifted by 3 to the right also.
     216             :   Table exp2_tab_long_lc3plus contains the log2 for 0 to 1.0 in steps
     217             :   of 1/32, table exp2w_tab_long_lc3plus the log2 for 0 to 1/32 in steps
     218             :   of 1/1024, table exp2x_tab_long_lc3plus the log2 for 0 to 1/1024 in
     219             :   steps of 1/32768. Since the 2-logarithm of very very small
     220             :   negative value is rather linear, we can use interpolation.
     221             : 
     222             :   Limitations:
     223             : 
     224             :   For x <= 0, the result is fractional positive
     225             :   For x > 0, the result is integer in range 1...7FFF.FFFF
     226             :   For x < -31/64, we have to clear the result
     227             :   For x = 0, the result is ~1.0 (0x7FFF.FFFF)
     228             :   For x >= 31/64, the result is 0x7FFF.FFFF
     229             : 
     230             :   \param  x
     231             : 
     232             :   \return pow(2,(x/64))
     233             :  */
     234             : /************************************************************************/
     235             : Word32 BASOP_Util_InvLog2_lc3plus(Word32 x);
     236             : 
     237             : #ifdef ENABLE_HR_MODE
     238             : /* New function which works with positive x, BASOP_Util_InvLog2_lc3plus does not give 
     239             :    accurate results for x > 0 */
     240             : Word32 BASOP_Util_InvLog2_pos(Word32 x, Word16 *exp);
     241             : #endif
     242             : 
     243             : /**
     244             :  * \brief Compute dot product of 1 32 bit vectors with itself
     245             :  * \param x input vector 1
     246             :  * \param headroom amount of headroom bits the input vector
     247             :  * \param length the length of the input vector
     248             :  * \param result_e pointer to where the exponent of the result will be stored into
     249             :  * \return the dot product of x and x.
     250             :  */
     251             : Word32 Norm32Norm(const Word32 *x, const Word16 headroom, const Word16 length, Word16 *result_e);
     252             : 
     253             : /*!**********************************************************************
     254             :    \brief   Add two values given by mantissa and exponent.
     255             : 
     256             :    Mantissas are in 32-bit-fractional format with values between 0 and 1. <br>
     257             :    The base for exponents is 2.  Example:  \f$  a = a\_m * 2^{a\_e}  \f$<br>
     258             : 
     259             : ************************************************************************/
     260             : Word32 BASOP_Util_Add_Mant32Exp_lc3plus /*!< o: normalized result mantissa */
     261             :     (Word32  a_m,               /*!< i: Mantissa of 1st operand a  */
     262             :      Word16  a_e,               /*!< i: Exponent of 1st operand a  */
     263             :      Word32  b_m,               /*!< i: Mantissa of 2nd operand b  */
     264             :      Word16  b_e,               /*!< i: Exponent of 2nd operand b  */
     265             :      Word16 *ptr_e);            /*!< o: exponent of result         */
     266             :                                 /*!**********************************************************************
     267             :                                    \brief   Returns the comparison result of two normalized values given by mantissa and exponent.
     268             :                                             return value: -1: a < b, 0: a == b, 1; a > b
     269             : 
     270             :                                    Mantissas are in 32-bit-fractional format with values between 0 and 1. <br>
     271             :                                    The base for exponents is 2.  Example:  \f$  a = a\_m * 2^{a\_e}  \f$<br>
     272             : 
     273             :                                 ************************************************************************/
     274             : Word16 BASOP_Util_Cmp_Mant32Exp_lc3plus /*!< o: flag: result of comparison */
     275             :     (Word32 a_m,                /*!< i: Mantissa of 1st operand a  */
     276             :      Word16 a_e,                /*!< i: Exponent of 1st operand a  */
     277             :      Word32 b_m,                /*!< i: Mantissa of 2nd operand b  */
     278             :      Word16 b_e);               /*!< i: Exponent of 2nd operand b  */
     279             : 
     280             : /* compare two positive normalized 16 bit mantissa/exponent values */
     281             : /* return value: positive if first value greater, negative if second value greater, zero if equal */
     282             : Word16 compMantExp16Unorm(Word16 m1, Word16 e1, Word16 m2, Word16 e2);
     283             : 
     284             : void Scale_sig(Word16       x[], /* i/o: signal to scale                 Qx        */
     285             :                const Word16 lg,  /* i  : size of x[]                     Q0        */
     286             :                const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
     287             : );
     288             : void Copy_Scale_sig(const Word16 x[], /* i  : signal to scale input           Qx        */
     289             :                     Word16       y[], /* o  : scaled signal output            Qx        */
     290             :                     const Word16 lg,  /* i  : size of x[]                     Q0        */
     291             :                     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
     292             : );
     293             : 
     294             : #ifdef ENABLE_HR_MODE
     295             : void Copy_Scale_sig_32(const Word32 x[], /* i  : signal to scale input           Qx        */
     296             :                        Word16       y[], /* o  : scaled signal output            Qx        */
     297             :                        const Word16 lg,  /* i  : size of x[]                     Q0        */
     298             :                        const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
     299             : );
     300             : #endif
     301             : 
     302             : Word32 Isqrt_lc3plus(Word32  x,  /* (i)   Q31: normalized value (1.0 > x >= 0.5) */
     303             :              Word16 *x_e /* (i/o) Q0 : pointer to exponent */
     304             : );
     305             : 
     306             : Word16 BASOP_Util_Log2_16(Word32 x, Word16 x_e);
     307             : 
     308             : Word16 BASOP_Util_InvLog2_16(Word16 x, Word16 *y_e);
     309             : 
     310             : #ifdef ENABLE_HR_MODE
     311             : Word32 invFixp(Word32 op_m, Word16 *op_e);
     312             : #endif
     313             : 
     314             : #define BASOP_CFFT_MAX_LENGTH 480
     315             : void BASOP_cfft_lc3plus(Word32 *re, Word32 *im, Word16 sizeOfFft, Word16 s, Word16 *scale, Word32 *x);
     316             : void BASOP_rfftN(Word32 *re, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer);
     317             : void BASOP_irfftN(Word32 *re, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer);
     318             : 
     319           0 : static __inline void basop_memcpy(void *dst, const void *src, size_t n)
     320             : {
     321             : #ifdef WMOPS
     322             :     multiCounter[currCounter].move16 += (UWord32)n / 2;
     323             : #endif
     324             :     /* check for overlapping memory */
     325           0 :     assert((const char *)src + n <= (char *)dst || (char *)dst + n <= (const char *)src);
     326           0 :     memcpy(dst, src, n);
     327           0 : }
     328             : 
     329           0 : static __inline void basop_memmove(void *dst, const void *src, size_t n)
     330             : {
     331             : #ifdef WMOPS
     332             :     multiCounter[currCounter].move16 += (UWord32)n / 2;
     333             : #endif
     334           0 :     memmove(dst, src, n);
     335           0 : }
     336             : 
     337           0 : static __inline void basop_memset(void *dst, int val, size_t n)
     338             : {
     339             : #ifdef WMOPS
     340             :     multiCounter[currCounter].move16 += (UWord32)n / 2;
     341             : #endif
     342           0 :     memset(dst, val, n);
     343           0 : }
     344             : 
     345             : /* Macros around Dyn_Mem that don't require duplicate declarations. */
     346             : #ifdef DYNMEM_COUNT
     347             : /* older visual studio doesn't have __func__ */
     348             : #if defined _MSC_VER && _MSC_VER < 1900
     349             : #define __func__ __FUNCTION__
     350             : #endif
     351             : #define Dyn_Mem_Deluxe_In(...) __VA_ARGS__ Dyn_Mem_In(__func__, sizeof(struct {__VA_ARGS__}))
     352             : #define Dyn_Mem_Deluxe_Out() Dyn_Mem_Out()
     353             : #else
     354             : #define Dyn_Mem_Deluxe_In(...) __VA_ARGS__
     355             : #define Dyn_Mem_Deluxe_Out()
     356             : #endif
     357             : 
     358             : /* Macros missing from IVAS BASOP, used only in LC3plus */
     359             : #define L_shl_pos(x, y) (L_shl((x), (y)))
     360             : #define L_shr_pos(x, y) (L_shr((x), (y)))
     361             : #define L_shr_pos_pos(x, y) (L_shr((x), (y)))
     362             : 
     363             : #define L_shr_r_pos(x, shift) (L_shr_r(x, shift))
     364             : 
     365             : #define shl_pos(x, y) (shl((x), (y)))
     366             : #define shr_pos(x, y) (shr((x), (y)))
     367             : #define shr_pos_pos(x, y) (shr((x), (y)))
     368             : 
     369             : #define lshl_pos(x, y) (lshl(x, y))
     370             : #define UL_lshr_pos(x, y) (UL_lshr(x, y))
     371             : #define UL_lshl_pos(x, y) (UL_lshl(x, y))
     372             : #endif /* __BASOP_UTIL_LC3PLUS_H__ */

Generated by: LCOV version 1.14