LCOV - code coverage report
Current view: top level - lib_com - tcx_mdct_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e70d960493906e094628337ac73d3c408863a5e6 Lines: 113 167 67.7 %
Date: 2025-09-17 02:22:58 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      702911 : static Word16 TCX_MDCT_GetScaleFactor(
      12             :     const Word16 L,  /* Q0 */
      13             :     Word16 *factor_e /* Q0 */
      14             : )
      15             : {
      16             : 
      17             :     Word16 factor;
      18             : 
      19      702911 :     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      668271 :     ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
      27             :     {
      28      124374 :         factor = 23170;
      29      124374 :         move16();
      30      124374 :         *factor_e = 0;
      31      124374 :         move16();
      32             :     }
      33      543897 :     ELSE IF( EQ_16( L, shl( NORM_MDCT_FACTOR, 2 ) ) )
      34             :     {
      35       19176 :         factor = 16384;
      36       19176 :         move16();
      37       19176 :         *factor_e = 0;
      38       19176 :         move16();
      39             :     }
      40             :     ELSE
      41             :     {
      42             : 
      43      524721 :         factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
      44      524721 :         *factor_e = 4;
      45      524721 :         move16();
      46             : 
      47      524721 :         factor = ISqrt16( factor, factor_e );
      48             :     }
      49             : 
      50      702911 :     return factor;
      51             : }
      52             : 
      53       31899 : static Word16 TCX_MDCT_Inverse_GetScaleFactor(
      54             :     const Word16 L,  /* Q0 */
      55             :     Word16 *factor_e /* Q0 */
      56             : )
      57             : {
      58             : 
      59             :     Word16 factor;
      60             : 
      61       31899 :     IF( EQ_16( L, NORM_MDCT_FACTOR ) )
      62             :     {
      63       21330 :         factor = 32767;
      64       21330 :         move16();
      65       21330 :         *factor_e = 0;
      66       21330 :         move16();
      67             :     }
      68       10569 :     ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
      69             :     {
      70        5621 :         factor = 23170;
      71        5621 :         move16();
      72        5621 :         *factor_e = 1;
      73        5621 :         move16();
      74             :     }
      75        4948 :     ELSE IF( EQ_16( L, 4 * NORM_MDCT_FACTOR ) )
      76             :     {
      77          95 :         factor = 32767;
      78          95 :         move16();
      79          95 :         *factor_e = 1;
      80          95 :         move16();
      81             :     }
      82             :     ELSE
      83             :     {
      84        4853 :         factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
      85        4853 :         *factor_e = 4;
      86        4853 :         move16();
      87             : 
      88        4853 :         factor = Sqrt16( factor, factor_e );
      89             :     }
      90             : 
      91       31899 :     return factor;
      92             : }
      93             : 
      94             : 
      95      421289 : 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             : #ifndef ISSUE_1836_replace_overflow_libcom
     111             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     112             :     Flag Overflow = 0;
     113             :     move32();
     114             : #endif
     115             : #endif
     116      421289 :     factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e );
     117      421289 :     *y_e = add( *y_e, factor_e );
     118      421289 :     move16();
     119             : 
     120      421289 :     neg_factor = negate( factor );
     121             : 
     122             : 
     123             :     /* Init */
     124    39508061 :     FOR( i = 0; i < m / 2; i++ )
     125             :     {
     126    39086772 :         y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
     127    39086772 :         move32();
     128             :     }
     129    22889227 :     FOR( i = 0; i < l / 2; i++ )
     130             :     {
     131             : #ifdef ISSUE_1836_replace_overflow_libcom
     132    22467938 :         y[m / 2 + r / 2 + m / 2 + i] = L_msu_sat( L_mult( x[i], factor ), x[l - 1 - i], factor ); /* exp(y_e) */
     133             : #else
     134             :         y[m / 2 + r / 2 + m / 2 + i] = L_msu_o( L_mult( x[i], factor ), x[l - 1 - i], factor, &Overflow );                             /* exp(y_e) */
     135             : #endif
     136    22467938 :         move32();
     137             :     }
     138    39508061 :     FOR( i = 0; i < m / 2; i++ )
     139             :     {
     140    39086772 :         y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
     141    39086772 :         move32();
     142             :     }
     143    25487327 :     FOR( i = 0; i < r / 2; i++ )
     144             :     {
     145             : #ifdef ISSUE_1836_replace_overflow_libcom
     146    25066038 :         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) */
     147             : #else
     148             :         y[m / 2 + r / 2 - 1 - m / 2 - i] = L_mac_o( L_mult( x[l + m + i], neg_factor ), x[l + m + r - 1 - i], neg_factor, &Overflow ); /* exp(y_e) */
     149             : #endif
     150    25066038 :         move32();
     151             :     }
     152             : 
     153      421289 :     *y_e = sub( 15, *y_e );
     154      421289 :     move16();
     155      421289 :     edct_fx( y, y, l / 2 + m + r / 2, y_e );
     156      421289 :     *y_e = sub( 15 - 1, *y_e );
     157      421289 :     move16();
     158      421289 :     return;
     159             : }
     160             : 
     161      281622 : void TCX_MDST(
     162             :     const Word16 *x, /* Qx */
     163             :     Word32 *y,       /* exp(y_e) */
     164             :     Word16 *y_e,
     165             :     const Word16 l,           /* Q0 */
     166             :     const Word16 m,           /* Q0 */
     167             :     const Word16 r,           /* Q0 */
     168             :     const Word16 element_mode /* Q0 */
     169             : )
     170             : {
     171             : 
     172             :     Word16 i;
     173             :     Word16 factor, neg_factor;
     174             :     Word16 factor_e;
     175             :     (void) element_mode;
     176             : #ifndef ISSUE_1836_replace_overflow_libcom
     177             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     178             :     Flag Overflow = 0;
     179             :     move32();
     180             : #endif
     181             : #endif
     182      281622 :     factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e ); /* exp(factor_e) */
     183      281622 :     *y_e = add( *y_e, factor_e );
     184      281622 :     move16();
     185             : 
     186      281622 :     neg_factor = negate( factor );
     187             : 
     188             : 
     189             :     /* Init */
     190    67636112 :     FOR( i = 0; i < m / 2; i++ )
     191             :     {
     192    67354490 :         y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
     193    67354490 :         move32();
     194             :     }
     195    47489202 :     FOR( i = 0; i < l / 2; i++ )
     196             :     {
     197             : #ifdef ISSUE_1836_replace_overflow_libcom
     198    47207580 :         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) */
     199             : #else
     200             :         y[m / 2 + r / 2 + m / 2 + i] = L_msu_o( L_mult( x[i], neg_factor ), x[l - 1 - i], factor, &Overflow );                         /* exp(y_e) */
     201             : #endif
     202    47207580 :         move32();
     203             :     }
     204    67636112 :     FOR( i = 0; i < m / 2; i++ )
     205             :     {
     206    67354490 :         y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
     207    67354490 :         move32();
     208             :     }
     209    50057142 :     FOR( i = 0; i < r / 2; i++ )
     210             :     {
     211    49775520 :         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) */
     212    49775520 :         move32();
     213             :     }
     214             : 
     215      281622 :     *y_e = sub( 15, *y_e );
     216      281622 :     move16();
     217             : 
     218      281622 :     edst_fx( y, y, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), y_e );
     219             : 
     220      281622 :     *y_e = sub( 15 - 1, *y_e );
     221      281622 :     move16();
     222             : 
     223      281622 :     return;
     224             : }
     225             : 
     226       31899 : void TCX_MDCT_Inverse(
     227             :     Word32 *x, // Q( 31 - x_e )
     228             :     Word16 x_e,
     229             :     Word16 *y,                /* Qy */
     230             :     const Word16 l,           /* Q0 */
     231             :     const Word16 m,           /* Q0 */
     232             :     const Word16 r,           /* Q0 */
     233             :     const Word16 element_mode /* Q0 */
     234             : )
     235             : {
     236             : 
     237             :     Word16 i, fac, negfac, s;
     238       31899 :     Word16 L2 = l, R2 = r;
     239             :     Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
     240             :     Word16 fac_e;
     241             :     (void) element_mode;
     242       31899 :     L2 = shr( l, 1 );
     243       31899 :     R2 = shr( r, 1 );
     244             : 
     245       31899 :     x_e = sub( 15, x_e );
     246       31899 :     edct_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
     247       31899 :     x_e = sub( 15, x_e );
     248             : 
     249       31899 :     fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e ); /* exp(fac_e) */
     250       31899 :     x_e = add( x_e, fac_e );
     251             : 
     252       31899 :     negfac = negate( fac );
     253             : 
     254       31899 :     s = x_e;
     255       31899 :     move16();
     256             : 
     257     1644943 :     FOR( i = 0; i < R2; i++ )
     258             :     {
     259     1613044 :         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)*/
     260             : 
     261     1613044 :         move16();
     262             :     }
     263             : 
     264     1633083 :     FOR( i = 0; i < L2; i++ )
     265             :     {
     266     1601184 :         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)*/
     267     1601184 :         move16();
     268             :     }
     269             : 
     270     3752979 :     FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
     271             :     {
     272             :         Word16 f;
     273             : 
     274     3721080 :         f = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
     275     3721080 :         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)*/
     276     3721080 :         move16();
     277     3721080 :         y[l + m + R2 - 1 - i] = f;
     278     3721080 :         move16();
     279             :     }
     280       31899 : }
     281             : 
     282           0 : void TCX_MDST_Inverse_fx(
     283             :     Word32 *x, /* exp(x_e) */
     284             :     Word16 x_e,
     285             :     Word16 *y,      /* Qx */
     286             :     const Word16 l, /* Q0 */
     287             :     const Word16 m, /* Q0 */
     288             :     const Word16 r  /* Q0 */
     289             : )
     290             : {
     291             : 
     292             :     Word16 i, fac, negfac, s;
     293           0 :     Word16 L2 = l, R2 = r;
     294           0 :     move16();
     295           0 :     move16();
     296             :     Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
     297             :     Word16 fac_e;
     298             : 
     299           0 :     L2 = shr( l, 1 );
     300           0 :     R2 = shr( r, 1 );
     301             : 
     302           0 :     x_e = sub( 15, x_e );
     303           0 :     edst_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
     304           0 :     x_e = sub( 15, x_e );
     305             : 
     306           0 :     fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e );
     307           0 :     x_e = add( x_e, fac_e );
     308             : 
     309           0 :     negfac = negate( fac );
     310             : 
     311           0 :     s = x_e;
     312           0 :     move16();
     313             : 
     314           0 :     FOR( i = 0; i < R2; i++ )
     315             :     {
     316           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)*/
     317           0 :         move16();
     318             :     }
     319             : 
     320           0 :     FOR( i = 0; i < L2; i++ )
     321             :     {
     322           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)*/
     323           0 :         move16();
     324             :     }
     325             : 
     326           0 :     FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
     327             :     {
     328             :         Word16 f;
     329           0 :         f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], fac ), s ) );
     330             : 
     331           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)*/
     332           0 :         move16();
     333             : 
     334           0 :         y[l + m + R2 - 1 - i] = negate( f );
     335           0 :         move16();
     336             :     }
     337           0 : }
     338             : 
     339             : /*-------------------------------------------------------------------*
     340             :  * TCX_MDXT_Inverse_fx()
     341             :  *
     342             :  *
     343             :  *-------------------------------------------------------------------*/
     344             : 
     345           0 : void TCX_MDXT_Inverse_fx(
     346             :     const Word32 *x, /* exp(x_e) */
     347             :     Word16 x_e,
     348             :     Word16 *y,                /* Qx */
     349             :     const Word16 l,           /* Q0 */
     350             :     const Word16 m,           /* Q0 */
     351             :     const Word16 r,           /* Q0 */
     352             :     const UWord16 kernel_type /* Q0 */
     353             : )
     354             : {
     355             :     Word16 signLeft;
     356             :     Word16 signRight;
     357             :     Word16 i, fac, negfac, s, fac_e;
     358           0 :     const Word16 L2 = shr( l, 1 ), R2 = shr( r, 1 );
     359             :     Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
     360             :     Word16 f;
     361             : 
     362           0 :     set32_fx( tmp_buf, 0, N_MAX + L_MDCT_OVLP_MAX / 2 );
     363             : 
     364           0 :     edxt_fx( x, tmp_buf + L2, add( add( L2, m ), R2 ), kernel_type, TRUE );
     365             : 
     366           0 :     fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e );
     367           0 :     x_e = add( x_e, fac_e );
     368             : 
     369           0 :     negfac = negate( fac );
     370           0 :     IF( GE_16( kernel_type, MDCT_II ) )
     371             :     {
     372           0 :         signLeft = negfac;
     373             :     }
     374             :     ELSE
     375             :     {
     376           0 :         signLeft = fac;
     377             :     }
     378             :     // signRight = ( kernel_type & 1 ? fac : negfac );
     379           0 :     IF( L_and( kernel_type, 1 ) )
     380             :     {
     381           0 :         signRight = fac;
     382             :     }
     383             :     ELSE
     384             :     {
     385           0 :         signRight = negfac;
     386             :     }
     387             : 
     388           0 :     s = x_e;
     389           0 :     move16();
     390             : 
     391           0 :     FOR( i = 0; i < L2; i++ )
     392             :     {
     393           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)*/
     394             :     }
     395             : 
     396           0 :     FOR( i = 0; i < R2; i++ )
     397             :     {
     398           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)*/
     399           0 :         move16();
     400             :     }
     401             : 
     402           0 :     FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
     403             :     {
     404             : 
     405           0 :         f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
     406             : 
     407           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)*/
     408           0 :         move16();
     409             : 
     410           0 :         y[l + m + R2 - 1 - i] = f;
     411           0 :         move16();
     412             :     }
     413             : 
     414           0 :     return;
     415             : }

Generated by: LCOV version 1.14