LCOV - code coverage report
Current view: top level - lib_com - tcx_mdct_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 61b27367e0d19b9fc53332787af331bed7af66b1 Lines: 113 167 67.7 %
Date: 2025-10-21 02:53:18 Functions: 5 7 71.4 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include "options.h"
       7             : #include "cnst.h"
       8             : #include "prot_fx.h"
       9             : #include "basop_util.h"
      10             : 
      11      703730 : static Word16 TCX_MDCT_GetScaleFactor(
      12             :     const Word16 L,  /* Q0 */
      13             :     Word16 *factor_e /* Q0 */
      14             : )
      15             : {
      16             : 
      17             :     Word16 factor;
      18             : 
      19      703730 :     IF( EQ_16( L, NORM_MDCT_FACTOR ) )
      20             :     {
      21       34640 :         factor = 32767;
      22       34640 :         move16();
      23       34640 :         *factor_e = 0;
      24       34640 :         move16();
      25             :     }
      26      669090 :     ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
      27             :     {
      28      124611 :         factor = 23170;
      29      124611 :         move16();
      30      124611 :         *factor_e = 0;
      31      124611 :         move16();
      32             :     }
      33      544479 :     ELSE IF( EQ_16( L, shl( NORM_MDCT_FACTOR, 2 ) ) )
      34             :     {
      35       19324 :         factor = 16384;
      36       19324 :         move16();
      37       19324 :         *factor_e = 0;
      38       19324 :         move16();
      39             :     }
      40             :     ELSE
      41             :     {
      42             : 
      43      525155 :         factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
      44      525155 :         *factor_e = 4;
      45      525155 :         move16();
      46             : 
      47      525155 :         factor = ISqrt16( factor, factor_e );
      48             :     }
      49             : 
      50      703730 :     return factor;
      51             : }
      52             : 
      53       31678 : static Word16 TCX_MDCT_Inverse_GetScaleFactor(
      54             :     const Word16 L,  /* Q0 */
      55             :     Word16 *factor_e /* Q0 */
      56             : )
      57             : {
      58             : 
      59             :     Word16 factor;
      60             : 
      61       31678 :     IF( EQ_16( L, NORM_MDCT_FACTOR ) )
      62             :     {
      63       21109 :         factor = 32767;
      64       21109 :         move16();
      65       21109 :         *factor_e = 0;
      66       21109 :         move16();
      67             :     }
      68       10569 :     ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
      69             :     {
      70        5624 :         factor = 23170;
      71        5624 :         move16();
      72        5624 :         *factor_e = 1;
      73        5624 :         move16();
      74             :     }
      75        4945 :     ELSE IF( EQ_16( L, 4 * NORM_MDCT_FACTOR ) )
      76             :     {
      77          97 :         factor = 32767;
      78          97 :         move16();
      79          97 :         *factor_e = 1;
      80          97 :         move16();
      81             :     }
      82             :     ELSE
      83             :     {
      84        4848 :         factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
      85        4848 :         *factor_e = 4;
      86        4848 :         move16();
      87             : 
      88        4848 :         factor = Sqrt16( factor, factor_e );
      89             :     }
      90             : 
      91       31678 :     return factor;
      92             : }
      93             : 
      94             : 
      95      421683 : void TCX_MDCT(
      96             :     const Word16 *x, /* Qx */
      97             :     Word32 *y,       /* exp(y_e) */
      98             :     Word16 *y_e,
      99             :     const Word16 l,           /* Q0 */
     100             :     const Word16 m,           /* Q0 */
     101             :     const Word16 r,           /* Q0 */
     102             :     const Word16 element_mode /* Q0 */
     103             : )
     104             : {
     105             : 
     106             :     Word16 i;
     107             :     Word16 factor, neg_factor;
     108             :     Word16 factor_e;
     109             :     (void) element_mode;
     110             : 
     111      421683 :     factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e );
     112      421683 :     *y_e = add( *y_e, factor_e );
     113      421683 :     move16();
     114             : 
     115      421683 :     neg_factor = negate( factor );
     116             : 
     117             :     /* Init */
     118    39570335 :     FOR( i = 0; i < m / 2; i++ )
     119             :     {
     120    39148652 :         y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
     121    39148652 :         move32();
     122             :     }
     123    22934521 :     FOR( i = 0; i < l / 2; i++ )
     124             :     {
     125    22512838 :         y[m / 2 + r / 2 + m / 2 + i] = L_msu_sat( L_mult( x[i], factor ), x[l - 1 - i], factor ); /* exp(y_e) */
     126    22512838 :         move32();
     127             :     }
     128    39570335 :     FOR( i = 0; i < m / 2; i++ )
     129             :     {
     130    39148652 :         y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
     131    39148652 :         move32();
     132             :     }
     133    25533701 :     FOR( i = 0; i < r / 2; i++ )
     134             :     {
     135    25112018 :         y[m / 2 + r / 2 - 1 - m / 2 - i] = L_mac_sat( L_mult( x[l + m + i], neg_factor ), x[l + m + r - 1 - i], neg_factor ); /* exp(y_e) */
     136    25112018 :         move32();
     137             :     }
     138             : 
     139      421683 :     *y_e = sub( 15, *y_e );
     140      421683 :     move16();
     141      421683 :     edct_fx( y, y, l / 2 + m + r / 2, y_e );
     142      421683 :     *y_e = sub( 15 - 1, *y_e );
     143      421683 :     move16();
     144      421683 :     return;
     145             : }
     146             : 
     147      282047 : void TCX_MDST(
     148             :     const Word16 *x, /* Qx */
     149             :     Word32 *y,       /* exp(y_e) */
     150             :     Word16 *y_e,
     151             :     const Word16 l,           /* Q0 */
     152             :     const Word16 m,           /* Q0 */
     153             :     const Word16 r,           /* Q0 */
     154             :     const Word16 element_mode /* Q0 */
     155             : )
     156             : {
     157             : 
     158             :     Word16 i;
     159             :     Word16 factor, neg_factor;
     160             :     Word16 factor_e;
     161             :     (void) element_mode;
     162             : 
     163      282047 :     factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e ); /* exp(factor_e) */
     164      282047 :     *y_e = add( *y_e, factor_e );
     165      282047 :     move16();
     166             : 
     167      282047 :     neg_factor = negate( factor );
     168             : 
     169             : 
     170             :     /* Init */
     171    67705827 :     FOR( i = 0; i < m / 2; i++ )
     172             :     {
     173    67423780 :         y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
     174    67423780 :         move32();
     175             :     }
     176    47539917 :     FOR( i = 0; i < l / 2; i++ )
     177             :     {
     178    47257870 :         y[m / 2 + r / 2 + m / 2 + i] = L_msu_sat( L_mult( x[i], neg_factor ), x[l - 1 - i], factor ); /* exp(y_e) */
     179    47257870 :         move32();
     180             :     }
     181    67705827 :     FOR( i = 0; i < m / 2; i++ )
     182             :     {
     183    67423780 :         y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
     184    67423780 :         move32();
     185             :     }
     186    50108937 :     FOR( i = 0; i < r / 2; i++ )
     187             :     {
     188    49826890 :         y[m / 2 + r / 2 - 1 - m / 2 - i] = L_mac_sat( L_mult( x[l + m + i], neg_factor ), x[l + m + r - 1 - i], factor ); /* exp(y_e) */
     189    49826890 :         move32();
     190             :     }
     191             : 
     192      282047 :     *y_e = sub( 15, *y_e );
     193      282047 :     move16();
     194             : 
     195      282047 :     edst_fx( y, y, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), y_e );
     196             : 
     197      282047 :     *y_e = sub( 15 - 1, *y_e );
     198      282047 :     move16();
     199             : 
     200      282047 :     return;
     201             : }
     202             : 
     203       31678 : void TCX_MDCT_Inverse(
     204             :     Word32 *x, // Q( 31 - x_e )
     205             :     Word16 x_e,
     206             :     Word16 *y,                /* Qy */
     207             :     const Word16 l,           /* Q0 */
     208             :     const Word16 m,           /* Q0 */
     209             :     const Word16 r,           /* Q0 */
     210             :     const Word16 element_mode /* Q0 */
     211             : )
     212             : {
     213             : 
     214             :     Word16 i, fac, negfac, s;
     215       31678 :     Word16 L2 = l, R2 = r;
     216             :     Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
     217             :     Word16 fac_e;
     218             :     (void) element_mode;
     219       31678 :     L2 = shr( l, 1 );
     220       31678 :     R2 = shr( r, 1 );
     221             : 
     222       31678 :     x_e = sub( 15, x_e );
     223       31678 :     edct_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
     224       31678 :     x_e = sub( 15, x_e );
     225             : 
     226       31678 :     fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e ); /* exp(fac_e) */
     227       31678 :     x_e = add( x_e, fac_e );
     228             : 
     229       31678 :     negfac = negate( fac );
     230             : 
     231       31678 :     s = x_e;
     232       31678 :     move16();
     233             : 
     234     1636987 :     FOR( i = 0; i < R2; i++ )
     235             :     {
     236     1605309 :         y[l + m + R2 + i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) ); /* fold out right end of DCT        exp(fac_e)*/
     237             : 
     238     1605309 :         move16();
     239             :     }
     240             : 
     241     1625127 :     FOR( i = 0; i < L2; i++ )
     242             :     {
     243     1593449 :         y[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + m + R2 + i], fac ), s ) ); /* negate, fold out left end of DCT        exp(fac_e)*/
     244     1593449 :         move16();
     245             :     }
     246             : 
     247     3734678 :     FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
     248             :     {
     249             :         Word16 f;
     250             : 
     251     3703000 :         f = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
     252     3703000 :         y[L2 + i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[l + m + R2 - 1 - i], negfac ), s ) ); /* time-reverse mid of DCT      exp(fac_e)*/
     253     3703000 :         move16();
     254     3703000 :         y[l + m + R2 - 1 - i] = f;
     255     3703000 :         move16();
     256             :     }
     257       31678 : }
     258             : 
     259           0 : void TCX_MDST_Inverse_fx(
     260             :     Word32 *x, /* exp(x_e) */
     261             :     Word16 x_e,
     262             :     Word16 *y,      /* Qx */
     263             :     const Word16 l, /* Q0 */
     264             :     const Word16 m, /* Q0 */
     265             :     const Word16 r  /* Q0 */
     266             : )
     267             : {
     268             : 
     269             :     Word16 i, fac, negfac, s;
     270           0 :     Word16 L2 = l, R2 = r;
     271           0 :     move16();
     272           0 :     move16();
     273             :     Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
     274             :     Word16 fac_e;
     275             : 
     276           0 :     L2 = shr( l, 1 );
     277           0 :     R2 = shr( r, 1 );
     278             : 
     279           0 :     x_e = sub( 15, x_e );
     280           0 :     edst_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
     281           0 :     x_e = sub( 15, x_e );
     282             : 
     283           0 :     fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e );
     284           0 :     x_e = add( x_e, fac_e );
     285             : 
     286           0 :     negfac = negate( fac );
     287             : 
     288           0 :     s = x_e;
     289           0 :     move16();
     290             : 
     291           0 :     FOR( i = 0; i < R2; i++ )
     292             :     {
     293           0 :         y[l + m + R2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], fac ), s ) ); /* fold out right end of DCT           exp(fac_e)*/
     294           0 :         move16();
     295             :     }
     296             : 
     297           0 :     FOR( i = 0; i < L2; i++ )
     298             :     {
     299           0 :         y[i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + m + R2 + i], negfac ), s ) ); /* negate, fold out left end of DCT             exp(fac_e)*/
     300           0 :         move16();
     301             :     }
     302             : 
     303           0 :     FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
     304             :     {
     305             :         Word16 f;
     306           0 :         f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], fac ), s ) );
     307             : 
     308           0 :         y[L2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[l + m + R2 - 1 - i], negfac ), s ) ); /* time-reverse mid of DCT  exp(fac_e)*/
     309           0 :         move16();
     310             : 
     311           0 :         y[l + m + R2 - 1 - i] = negate( f );
     312           0 :         move16();
     313             :     }
     314           0 : }
     315             : 
     316             : /*-------------------------------------------------------------------*
     317             :  * TCX_MDXT_Inverse_fx()
     318             :  *
     319             :  *
     320             :  *-------------------------------------------------------------------*/
     321             : 
     322           0 : void TCX_MDXT_Inverse_fx(
     323             :     const Word32 *x, /* exp(x_e) */
     324             :     Word16 x_e,
     325             :     Word16 *y,                /* Qx */
     326             :     const Word16 l,           /* Q0 */
     327             :     const Word16 m,           /* Q0 */
     328             :     const Word16 r,           /* Q0 */
     329             :     const UWord16 kernel_type /* Q0 */
     330             : )
     331             : {
     332             :     Word16 signLeft;
     333             :     Word16 signRight;
     334             :     Word16 i, fac, negfac, s, fac_e;
     335           0 :     const Word16 L2 = shr( l, 1 ), R2 = shr( r, 1 );
     336             :     Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
     337             :     Word16 f;
     338             : 
     339           0 :     set32_fx( tmp_buf, 0, N_MAX + L_MDCT_OVLP_MAX / 2 );
     340             : 
     341           0 :     edxt_fx( x, tmp_buf + L2, add( add( L2, m ), R2 ), kernel_type, TRUE );
     342             : 
     343           0 :     fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e );
     344           0 :     x_e = add( x_e, fac_e );
     345             : 
     346           0 :     negfac = negate( fac );
     347           0 :     IF( GE_16( kernel_type, MDCT_II ) )
     348             :     {
     349           0 :         signLeft = negfac;
     350             :     }
     351             :     ELSE
     352             :     {
     353           0 :         signLeft = fac;
     354             :     }
     355             :     // signRight = ( kernel_type & 1 ? fac : negfac );
     356           0 :     IF( L_and( kernel_type, 1 ) )
     357             :     {
     358           0 :         signRight = fac;
     359             :     }
     360             :     ELSE
     361             :     {
     362           0 :         signRight = negfac;
     363             :     }
     364             : 
     365           0 :     s = x_e;
     366           0 :     move16();
     367             : 
     368           0 :     FOR( i = 0; i < L2; i++ )
     369             :     {
     370           0 :         y[i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + m + R2 + i], signLeft ), s ) ); /* fold out the left end      exp(fac_e)*/
     371             :     }
     372             : 
     373           0 :     FOR( i = 0; i < R2; i++ )
     374             :     {
     375           0 :         y[l + m + R2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], signRight ), s ) ); /* ...and right end      exp(fac_e)*/
     376           0 :         move16();
     377             :     }
     378             : 
     379           0 :     FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
     380             :     {
     381             : 
     382           0 :         f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
     383             : 
     384           0 :         y[L2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[l + m + R2 - 1 - i], negfac ), s ) ); /* time-reverse mid of DCT      exp(fac_e)*/
     385           0 :         move16();
     386             : 
     387           0 :         y[l + m + R2 - 1 - i] = f;
     388           0 :         move16();
     389             :     }
     390             : 
     391           0 :     return;
     392             : }

Generated by: LCOV version 1.14