LCOV - code coverage report
Current view: top level - lib_lc3plus - imdct_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 0 121 0.0 %
Date: 2025-08-23 01:22:27 Functions: 0 2 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             : #include "functions.h"
      11             : 
      12           0 : void ProcessingIMDCT(
      13             :     Word32       y[],       /* i:   spectra data */
      14             :     Word16 *     y_e,       /* i:   spectral data exponent */
      15             : #ifdef ENABLE_HR_MODE
      16             :     const Word32 w[],       /* i:   window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
      17             :     Word32       mem[],     /* i/o: overlap add memory */
      18             : #else
      19             :     const Word16 w[],       /* i:   window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
      20             :     Word16       mem[],     /* i/o: overlap add memory */
      21             : #endif
      22             :     Word16 *     mem_e,     /* i/o: overlap add exponent */
      23             : #ifdef ENABLE_HR_MODE
      24             :     Word32       x[],       /* o:   time signal out */
      25             : #else
      26             :     Word16       x[],       /* o:   time signal out */
      27             : #endif
      28             :     Word16       wLen,      /* i:   window length */
      29             :     Word16       N,         /* i:   block size */
      30             :     Word16       memLen,    /* i:   overlap add buffer size */
      31             :     Word16       frame_dms, /* i:   frame size in ms */
      32             :     Word16     concealMethod,     /* i:   concealment method */
      33             :     Word16     bfi,               /* i:   bad frame indicator */
      34             :     Word16     prev_bfi,          /* i:   previous bad frame indicator */
      35             :     Word16     nbLostFramesInRow, /* i: number of consecutive lost frames */
      36             :     AplcSetup *plcAd,             /* i: advanced plc struct */
      37             :     Word8 *scratchBuffer
      38             : #ifdef ENABLE_HR_MODE
      39             :     , Word16 hrmode
      40             : #endif
      41             : )
      42             : {
      43             :     Counter i;
      44             :     Word16  o, z, m, s;
      45             :     Word16  y_s, mem_s, max_bw;
      46             :     Word32  L_tmp;
      47             :     Word32 *workBuffer;
      48             : 
      49             : #ifdef DYNMEM_COUNT
      50             :     struct _dynmem
      51             :     {
      52             :         Word16  o, z, m, s;
      53             :         Word16  y_s, mem_s, max_bw;
      54             :         Word32  L_tmp;
      55             :         Counter i;
      56             :         Word32 *workBuffer;
      57             :         Word16 mem_i_win;
      58             :         Word16 w_taper_win;
      59             :     };
      60             :     Dyn_Mem_In("ProcessingIMDCT", sizeof(struct _dynmem));
      61             : #endif
      62             : 
      63             : 
      64           0 :     test(); test(); test();
      65           0 :     IF (sub(bfi, 1) != 0 || sub(concealMethod, LC3_CON_TEC_NS_STD) == 0 || sub(concealMethod, LC3_CON_TEC_NS_ADV) == 0 || sub(concealMethod, LC3_CON_TEC_FREQ_MUTING) == 0)
      66             :     {
      67           0 :         workBuffer = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LEN bytes */
      68             : 
      69             :         /* Init (constant per sample rate) */
      70           0 :         z      = 2 * N - wLen; /* number of leading zeros in window */
      71           0 :         m      = N >> 1;       /* half block size */
      72           0 :         o      = m - z;
      73           0 :         max_bw = 0;
      74             : 
      75             : #ifdef ENABLE_HR_MODE
      76           0 :         if (hrmode)
      77             :         {
      78           0 :             max_bw = N;
      79             :         }
      80             :         else
      81             : #endif
      82             :         {
      83           0 :             SWITCH (frame_dms)
      84             :             {
      85           0 :             case 25:
      86           0 :                 max_bw = MAX_BW >> 2; move16();
      87           0 :                 BREAK;
      88           0 :             case 50:
      89           0 :                 max_bw = MAX_BW >> 1; move16();
      90           0 :                 BREAK;
      91           0 :             case 75:
      92           0 :                 max_bw = (MAX_BW >> 2) * 3; move16();
      93           0 :                 BREAK;
      94           0 :             case 100:
      95           0 :                 max_bw = MAX_BW; move16();
      96           0 :                 BREAK;
      97             :             }
      98           0 :         }
      99             :         
     100           0 :         if (N > max_bw)
     101           0 :             basop_memset(&y[max_bw], 0, (N - max_bw) * sizeof(*y));
     102             : 
     103             :         /* Start Processing */
     104           0 :         y_s = getScaleFactor32_0(y, N);
     105           0 :         IF (sub(y_s, 32) < 0)
     106             :         {
     107           0 :             FOR (i = 0; i < N; i++)
     108             :             {
     109           0 :                 y[i] = L_shl(y[i], y_s);
     110             :             }
     111           0 :             *y_e = sub(*y_e, y_s);
     112             : #ifdef ENABLE_HR_MODE
     113           0 :             dct_IV(y, y_e, N, 
     114             :             hrmode, 
     115             :             workBuffer);
     116             : #else
     117             :             dct_IV(y, y_e, N, workBuffer);
     118             : #endif
     119           0 :             y_s  = getScaleFactor32_lc3plus(y, N);
     120           0 :             y_s  = sub(y_s, 1);
     121           0 :             *y_e = sub(*y_e, y_s + 3); /* mdct window is scaled by pow(2,x) */
     122             :             /* N<=20 only happens for 2.5ms frames in NB */
     123           0 :             if (sub(N, 20) <= 0)
     124             :             {
     125           0 :                 *y_e = add(*y_e, 2);
     126             :             }
     127           0 :             else if (sub(N, 120) <= 0)
     128             :             {
     129           0 :                 *y_e = add(*y_e, 1);
     130             :             }
     131             :         }
     132             :         ELSE
     133             :         {
     134           0 :             *y_e = 0;  move16();
     135             :         }
     136             : 
     137             : #ifdef ENABLE_HR_MODE
     138           0 :         mem_s = getScaleFactor32_0(mem, memLen);
     139             : #else
     140             :         mem_s = getScaleFactor16_0(mem, memLen);
     141             : #endif
     142             : 
     143             : #ifdef ENABLE_HR_MODE
     144           0 :         IF (sub(mem_s, 32) < 0)
     145             : #else
     146             :         IF (sub(mem_s, 16) < 0)
     147             : #endif
     148             :         {
     149           0 :             mem_s  = sub(mem_s, 1);
     150           0 :             *mem_e = sub(*mem_e, mem_s);
     151             :         }
     152             :         ELSE
     153             :         {
     154           0 :             *mem_e = *y_e;  move16();
     155             :         }
     156             : 
     157           0 :         s = sub(*mem_e, *y_e);
     158             : 
     159           0 :     IF (s > 0)
     160             :     {
     161           0 :         y_s  = sub(y_s, s);
     162           0 :         *y_e = add(*y_e, s);
     163             :     }
     164             :     ELSE
     165             :     {
     166           0 :         mem_s  = add(mem_s, s);
     167           0 :         *mem_e = sub(*mem_e, s);
     168             :     }
     169             : 
     170           0 :         mem_s = s_max(mem_s, -31);
     171           0 :         y_s   = s_max(y_s, -31);
     172             : 
     173           0 :     if (sub(y_s, 32) >= 0)
     174             :     {
     175           0 :         y_s = 0; move16();
     176             :     }
     177             : #ifdef ENABLE_HR_MODE
     178           0 :     if (sub(mem_s, 32) >= 0)
     179             :     {
     180           0 :         mem_s = 0; move16();
     181             :     }
     182             : #else
     183             :     if (sub(mem_s, 16) >= 0)
     184             :     {
     185             :         mem_s = 0; move16();
     186             :     }
     187             : #endif
     188             : 
     189             :         UNUSED(prev_bfi);
     190             :         UNUSED(nbLostFramesInRow);
     191             :         UNUSED(plcAd);
     192             : 
     193             :         { /* regular operation */
     194           0 :             FOR (i = 0; i < o; i++)
     195             :             {
     196             : #ifdef ENABLE_HR_MODE
     197           0 :                 L_tmp = L_sub(L_shl(mem[i], mem_s), Mpy_32_32_lc3plus(L_shl(y[m + i + z], y_s), w[4 * m - 1 - i - z]));
     198           0 :                 x[i]  = L_tmp;
     199           0 :                 move32();
     200             : #else
     201             :                 L_tmp = L_sub(L_shl(L_deposit_h(mem[i]), mem_s), Mpy_32_16_lc3plus(L_shl(y[m + i + z], y_s), w[4 * m - 1 - i - z]));
     202             :                 x[i] = round_fx(L_tmp);
     203             :                 move16();
     204             : #endif
     205             :             }
     206           0 :             FOR (i = 0; i < m; i++)
     207             :             {
     208             : #ifdef ENABLE_HR_MODE
     209           0 :                 L_tmp    = L_add(L_shl(mem[i + o], mem_s), Mpy_32_32_lc3plus(L_shl(y[2 * m - 1 - i], y_s), w[3 * m - 1 - i]));
     210           0 :                 x[i + o] = L_tmp;
     211           0 :                 move32();
     212             : #else
     213             :                 L_tmp = L_add(L_shl(L_deposit_h(mem[i + o]), mem_s), Mpy_32_16_lc3plus(L_shl(y[2 * m - 1 - i], y_s), w[3 * m - 1 - i]));
     214             :                 x[i + o] = round_fx(L_tmp);
     215             :                 move16();
     216             : #endif
     217             :             }
     218             :         }
     219             : 
     220           0 :         FOR (i = 0; i < m; i++)
     221             :         {
     222             : #ifdef ENABLE_HR_MODE
     223           0 :             L_tmp            = L_negate(Mpy_32_32_lc3plus(L_shl(y[i], y_s), w[m - 1 - i]));
     224           0 :             x[3 * m - z + i] = L_tmp;
     225           0 :             move32();
     226             : #else
     227             :             L_tmp            = L_negate(Mpy_32_16_lc3plus(L_shl(y[i], y_s), w[m - 1 - i]));
     228             :             x[3 * m - z + i] = round_fx(L_tmp);
     229             :             move16();
     230             : #endif
     231             :         }
     232             : 
     233           0 :         FOR (i = 0; i < m; i++)
     234             :         {
     235             : #ifdef ENABLE_HR_MODE
     236           0 :             L_tmp                = L_negate(Mpy_32_32_lc3plus(L_shl(y[i], y_s), w[m + i]));
     237           0 :             x[3 * m - z - 1 - i] = L_tmp;
     238           0 :             move32();
     239             : #else
     240             :             L_tmp                = L_negate(Mpy_32_16_lc3plus(L_shl(y[i], y_s), w[m + i]));
     241             :             x[3 * m - z - 1 - i] = round_fx(L_tmp);
     242             :             move16();
     243             : #endif
     244             :         }
     245             : 
     246             : #ifdef ENABLE_HR_MODE
     247           0 :         basop_memmove(mem, &x[N], memLen * sizeof(Word32));
     248             : #else
     249             :         basop_memmove(mem, &x[N], memLen * sizeof(Word16));
     250             : #endif
     251             : 
     252           0 :         *mem_e = *y_e;  move16();
     253             :     }
     254             : 
     255             : #ifdef DYNMEM_COUNT
     256             :     Dyn_Mem_Out();
     257             : #endif
     258           0 : }
     259             : /* End Processing */
     260             : 
     261           0 : void Processing_ITDA_WIN_OLA(
     262             :     Word32       L_x_tda[], /* i:     X_TDA buffer data   =  "y"  DCT-IV output */
     263             :     Word16 *     y_e,       /* i/o:   x_tda  input exponent "y_e"   ,   x output exponent */
     264             : #ifdef ENABLE_HR_MODE
     265             :     const Word32 w[],       /* i:     window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
     266             : #else
     267             :     const Word16 w[],       /* i:     window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
     268             : #endif
     269             :     Word16       mem[],     /* i/o:  overlap add memory */
     270             :     Word16 *     mem_e,     /* i/o:  overlap add exponent */
     271             :     Word16       x[],       /* o:   time signal out */
     272             :     Word16       wLen,      /* i:   window length */
     273             :     Word16       N,         /* i:   block size */
     274             :     Word16       memLen     /* i:   overlap add buffer size */
     275             :     )
     276             : {
     277             :     /* Declarations */
     278             :     Word16  i, o, z, m, s;
     279             :     Word16  y_s, mem_s;
     280             :     Word32  L_tmp;
     281             :     Word32 *L_y;
     282             :     Word16 fs_idx, tmp_w, w_factor;
     283           0 :     Word16 factorITDA[5]= { 25905 ,      18318   ,    22435   ,    25905   ,    31727};
     284             : 
     285             : #ifdef DYNMEM_COUNT
     286             :     Dyn_Mem_In("Processing_ITDA_WIN_OLA", sizeof(struct {
     287             :                    Word16  i, o, z, m, s;
     288             :                    Word16  y_s, mem_s;
     289             :                    Word32  L_tmp;
     290             :                    Word32 *L_y;
     291             :                }));
     292             : #endif
     293             : 
     294             : 
     295             :     /* Init (constants  per sample rate) */
     296           0 :     z = 2 * N - wLen; /* number of leading zeros in window */
     297           0 :     m = N >> 1;       /* half block size */
     298           0 :     o = m - z;
     299             : 
     300             : 
     301           0 :     L_y = L_x_tda; /* use same variables naming as in IMDCT for DCT-IV output  signal y */
     302             :    
     303           0 :     y_s = getScaleFactor32_lc3plus(L_y, N);        
     304             : 
     305           0 :     y_s = sub(y_s, 1); /*  add 1 bit margin  , y_s is now initial tda upscaling factor */
     306             : 
     307             : 
     308           0 :     *y_e = sub(add(*y_e,1),y_s); /*  handle W scale down by 2^(3) , as mdct synthesis window  was upscaled by  pow(2,x)  x=2 for NB otherwise 3  */
     309             : 
     310             :    
     311             : 
     312           0 :     mem_s = getScaleFactor16_0(mem, memLen);
     313             : 
     314           0 :     IF (sub(mem_s, 16) < 0)
     315             :     {
     316           0 :         mem_s  = sub(mem_s, 1);      /* one bit margin */
     317           0 :         *mem_e = sub(*mem_e, mem_s); /*adjusted mem exponent due to new scale */
     318             :     }
     319             :     ELSE
     320             :     {
     321           0 :         *mem_e = 0;  move16();
     322             :     }
     323             : 
     324           0 :     s = sub(*mem_e, *y_e); /*  */
     325             : 
     326           0 :     IF (s > 0)
     327             :     {
     328           0 :         y_s  = sub(y_s, s);     /*  new , reduced upshift of TDA  in window application  loop */
     329           0 :         *y_e = add(*y_e, s);    /*  resulting new exp y_e  for output signal  */
     330             :     }
     331             :     ELSE
     332             :     {
     333           0 :         mem_s  = add(mem_s, s);   /*  s negative or zero,  new , decreased upshift of OLAmem   in loop */
     334           0 :         *mem_e = sub(*mem_e, s);   /*   resulting new exp mem_e  for OLA_mem output signal  */
     335             :     }
     336             : 
     337           0 :     fs_idx = mult(N,(Word16)(32768.0/99.0)); /* truncation needed , i.e no rounding can be applied here */  
     338           0 :     w_factor = factorITDA[fs_idx]; move16();
     339           0 :     y_s = s_max(s_min(y_s, 31), -31);
     340             :     
     341           0 :     FOR (i = 0; i < o; i++)
     342             :     {   
     343           0 :         tmp_w = mult_r(extractW16(w[4 * m - 1 - i - z]), w_factor);
     344           0 :         L_tmp = L_sub(L_shl_sat(L_deposit_h(mem[i]), mem_s), Mpy_32_16_lc3plus(L_shl(L_y[m + i + z], y_s), tmp_w));
     345           0 :         x[i]  = round_fx_sat(L_tmp);
     346           0 :         move16();
     347             :     }
     348             : 
     349           0 :     FOR (i = 0; i < m; i++)
     350             :     {   
     351           0 :         tmp_w    = mult_r(extractW16(w[3 * m - 1 - i]), w_factor);
     352           0 :         L_tmp    = L_add(L_shl_sat(L_deposit_h(mem[i + o]), mem_s), Mpy_32_16_lc3plus(L_shl(L_y[2 * m - 1 - i], y_s), tmp_w));
     353           0 :         x[i + o] = round_fx_sat(L_tmp);
     354           0 :         move16();
     355             :     }
     356             : 
     357           0 :     FOR (i = 0; i < m; i++)
     358             :     {
     359           0 :         tmp_w            = mult_r(extractW16(w[m - 1 - i]), w_factor);
     360           0 :         L_tmp            = L_negate(Mpy_32_16_lc3plus(L_shl(L_y[i], y_s), tmp_w));
     361           0 :         x[3 * m - z + i] = round_fx(L_tmp);  move16();
     362             :     }
     363             : 
     364           0 :     FOR (i = 0; i < m; i++)
     365             :     {
     366           0 :         tmp_w                = mult_r(extractW16(w[m + i]), w_factor);
     367           0 :         L_tmp                = L_negate(Mpy_32_16_lc3plus(L_shl(L_y[i], y_s), tmp_w ));
     368           0 :         x[3 * m - z - 1 - i] = round_fx(L_tmp);  move16();
     369             :     }
     370             : 
     371           0 :     FOR (i = 0; i < memLen; i++)
     372             :     {
     373           0 :         mem[i] = x[N + i];  move16();
     374             :     }
     375           0 :     *mem_e = *y_e;  move16(); /* set OLA mem  exp to  x_Fx exponent*/
     376             : 
     377             : 
     378             : 
     379             : #ifdef DYNMEM_COUNT
     380             :     Dyn_Mem_Out();
     381             : #endif
     382           0 : }
     383             : 

Generated by: LCOV version 1.14