LCOV - code coverage report
Current view: top level - lib_lc3plus - util.h (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 0 71 0.0 %
Date: 2025-05-23 08:37:30 Functions: 0 22 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 UTIL_H
      11             : #define UTIL_H
      12             : 
      13             : #include "options.h"
      14             : #include "wmc_auto.h"
      15             : #include "clib.h"
      16             : #include "math.h"
      17             : 
      18             : #ifdef _MSC_VER
      19             : /* strcasecmp is not available on visual studio */
      20             : static LC3_INT strcasecmp(const char* a, const char* b) {
      21             :   return _stricmp(a,b);
      22             : }
      23             : #endif
      24             : 
      25             : /* restrict is not available on visual studio */
      26             : #ifdef _MSC_VER
      27             : #define restrict __restrict
      28             : /* inline is not recognized in visual studio 13 required by matlab r2015a in win10 */
      29             : #define inline __inline
      30             : #endif
      31             : 
      32             : /* number of elements in array */
      33             : #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
      34             : 
      35             : /* min max with no side effects */
      36           0 : static inline LC3_INT imin(LC3_INT a, LC3_INT b) { return a < b ? a : b; }
      37             : static inline LC3_INT imax(LC3_INT a, LC3_INT b) { return a > b ? a : b; }
      38             : 
      39             : /* restrict x to range [min, max] */
      40             : static inline LC3_INT iclamp(LC3_INT min, LC3_INT x, LC3_INT max) {
      41             :   return x < min ? min : x > max ? max : x;
      42             : }
      43             : static inline double fcmamp(double min, double x, double max) {
      44             :   return x < min ? min : x > max ? max : x;
      45             : }
      46           0 : static inline LC3_FLOAT fclampf(LC3_FLOAT min, LC3_FLOAT x, LC3_FLOAT max) {
      47           0 :   return x < min ? min : x > max ? max : x;
      48             : }
      49             : 
      50             : /* x² */
      51           0 : static inline LC3_FLOAT sqrf(LC3_FLOAT x) { return x * x; }
      52             : 
      53             : /* convenience wrappers around memmove */
      54           0 : static inline void move_float(LC3_FLOAT *dst, const LC3_FLOAT *src, LC3_INT len) {
      55             : #ifdef WMOPS
      56             :     LC3_INT i;
      57             :     for (i = 0; i < len; i++)
      58             :     {
      59             :         dst[i] = src[i];
      60             :     }
      61             : #else
      62           0 :   memmove(dst, src, len * sizeof(LC3_FLOAT));
      63             : #endif
      64           0 : }
      65           0 : static inline void move_int(LC3_INT *dst, const LC3_INT *src, LC3_INT len) {
      66             : #ifdef WMOPS
      67             :     LC3_INT i;
      68             :     for (i = 0; i < len; i++)
      69             :     {
      70             :         dst[i] = src[i];
      71             :     }
      72             : #else
      73           0 :   memmove(dst, src, len * sizeof(LC3_INT));
      74             : #endif
      75           0 : }
      76             : 
      77             : /* convenience wrappers around memset */
      78           0 : static inline void zero_float(LC3_FLOAT *x, LC3_INT len) {
      79             : #ifdef WMOPS
      80             :     LC3_INT i;
      81             :     for (i = 0; i < len; i++)
      82             :     {
      83             :         x[i] = 0;
      84             :     }
      85             : #else
      86           0 :   memset(x, 0, len * sizeof(LC3_FLOAT));
      87             : #endif
      88           0 : }
      89           0 : static inline void zero_int(LC3_INT *x, LC3_INT len) {
      90             : #ifdef WMOPS
      91             :     LC3_INT i;
      92             :     for (i = 0; i < len; i++)
      93             :     {
      94             :         x[i] = 0;
      95             :     }
      96             : #else
      97           0 :   memset(x, 0, len * sizeof(LC3_INT));
      98             : #endif
      99           0 : }
     100             : 
     101             : /* multiply float vectors element by element, in-place */
     102           0 : static inline void mult_vec(LC3_FLOAT *a, const LC3_FLOAT *b,
     103             :                             LC3_INT len) {
     104           0 :   LC3_INT i = 0;
     105           0 :   for (i = 0; i < len; i++) {
     106           0 :     a[i] *= b[i];
     107             :   }
     108           0 : }
     109             : 
     110             : /* multiply float vector with constant, in-place */
     111           0 : static inline void mult_const(LC3_FLOAT *a, LC3_FLOAT b, LC3_INT len) {
     112           0 :   LC3_INT i = 0;
     113           0 :   for (i = 0; i < len; i++) {
     114           0 :     a[i] *= b;
     115             :   }
     116           0 : }
     117             : 
     118             : /* sum of vector */
     119           0 : static inline LC3_FLOAT sum_vec(const LC3_FLOAT *x, LC3_INT len) {
     120           0 :   LC3_FLOAT sum = 0;
     121           0 :   LC3_INT i = 0;
     122           0 :   for (i = 0; i < len; i++) {
     123           0 :     sum += x[i];
     124             :   }
     125           0 :   return sum;
     126             : }
     127             : 
     128             : /* complex constructor */
     129           0 : static inline Complex cmplx(LC3_FLOAT r, LC3_FLOAT i) { return (Complex){r, i}; }
     130             : 
     131             : /* complex a + b */
     132           0 : static inline Complex cadd(Complex a, Complex b) {
     133           0 :   return cmplx(a.r + b.r, a.i + b.i);
     134             : }
     135             : 
     136             : /* complex a * b */
     137           0 : static inline Complex cmul(Complex a, Complex b) {
     138           0 :   return cmplx(a.r * b.r - a.i * b.i, a.i * b.r + a.r * b.i);
     139             : }
     140             : 
     141             : /* mac operator */
     142           0 : static inline LC3_FLOAT mac_loop(const LC3_FLOAT *array1, const LC3_FLOAT *array2, LC3_INT len)
     143             : {
     144             :     LC3_INT i;
     145           0 :     LC3_FLOAT sum = 0.0;
     146             : 
     147           0 :     for (i = 0; i < len; i++)
     148             :     {
     149           0 :         sum += (*array1++) * (*array2++);
     150             :     }
     151             : 
     152           0 :     return sum;
     153             : }
     154             : 
     155             : /* complex eᶦˣ */
     156           0 : static inline Complex cexpi(LC3_FLOAT x) { return cmplx(LC3_COS(x), LC3_SIN(x)); }
     157             : 
     158             : /* complex -x */
     159             : static inline Complex cneg(Complex x) { return cmplx(-x.r, -x.i); }
     160             : 
     161             : /* convert string to number. return true on success */
     162             : static inline bool str_to_int(const char *str, LC3_INT *value) {
     163             :   char *end = NULL;
     164             :   long v = str ? strtol(str, &end, 0) : 0;
     165             :   *value = (LC3_INT)v;
     166             :   return str && *end == 0 && v >= INT_MIN && v <= INT_MAX;
     167             : }
     168             : 
     169             : /* returns true if str ends with str ends with suffix. ignoring case. str may be
     170             :  * NULL */
     171             : static inline bool str_ends_with(const char *str, const char *suffix) {
     172             :   char *tmp = str ? strrchr(str, suffix[0]) : NULL;
     173             :   return tmp && !strcasecmp(tmp, suffix);
     174             : }
     175             : 
     176             : /* complex a - b */
     177           0 : static inline Complex csub(Complex a, Complex b) {
     178           0 :   return cmplx(a.r - b.r, a.i - b.i);
     179             : }
     180             : 
     181           0 : static inline void move_cmplx(Complex *dst, const Complex  *src, LC3_INT32 len) {
     182           0 :   if (len > 0) {
     183           0 :     memmove(dst, src, len * sizeof(Complex));
     184           0 :     assert(src[len - 1].r == dst[len - 1].r && src[len - 1].i == dst[len - 1].i); /*check that Cmplx is stored contiguously*/
     185           0 :     assert(src[0].r == dst[0].r && src[0].i == dst[0].i); /*check that Cmplx is stored contiguously*/
     186             :   }
     187           0 : }
     188             : 
     189           0 : static inline void zero_cmplx(Complex *x, LC3_INT32 len) {
     190           0 :    if(len > 0) {
     191           0 :      memset(x, 0, len * sizeof(Complex));
     192           0 :      assert(x[0].r == 0 && x[0].i == 0 &&  x[len-1].r == 0 && x[len-1].i == 0);
     193             :    }  
     194           0 : }
     195             : 
     196           0 : static inline Complex realtoc(LC3_FLOAT r) { return cmplx(r, 0); }
     197             : 
     198             : /* set float vector to constant */
     199           0 : static inline void set_vec(const LC3_FLOAT c, LC3_FLOAT *x, LC3_INT32 len) {
     200           0 :     LC3_INT32 i = 0;
     201           0 :     for (i = 0; i < len; i++) {
     202           0 :         x[i] = c;
     203             :     }
     204           0 : }
     205             : 
     206             : /* set float vector to constant */
     207           0 : static inline void set_vec_int(const LC3_INT32 c, LC3_INT32 *x, LC3_INT32 len) {
     208           0 :     LC3_INT32 i = 0;
     209           0 :     for (i = 0; i < len; i++) {
     210           0 :         x[i] = c;
     211             :     }
     212           0 : }
     213             : 
     214           0 : static inline LC3_INT32 clz_func(LC3_INT32 inp)
     215             : {
     216             : #if defined(__clang__) || defined(__GNUC__)
     217           0 :     if (inp == 0)
     218             :     {
     219           0 :         return 0;
     220             :     }
     221           0 :     return __builtin_clz(inp);
     222             : 
     223             : #elif defined(_WIN32) || defined(_WIN64)
     224             :     LC3_INT32 leading_zero = 0;
     225             :    
     226             :     if (_BitScanReverse(&leading_zero, inp))
     227             :     {
     228             :         return 31 - leading_zero;
     229             :     }
     230             :     else
     231             :         return 0;
     232             :     
     233             : #else
     234             :     LC3_INT32 i = 0;
     235             :     int64_t x = inp;
     236             :     
     237             :     if (inp == 0)
     238             :     {
     239             :         return 0;
     240             :     }
     241             :     
     242             :     inp = (inp < 0) ? ~inp : inp;
     243             : 
     244             :     while (x < (int64_t)0x80000000L)
     245             :     {
     246             :         inp <<= 1;
     247             :         i += 1;
     248             :     }
     249             : 
     250             :     return i;
     251             : #endif
     252             : }
     253             : 
     254             : 
     255             : #endif

Generated by: LCOV version 1.14