LCOV - code coverage report
Current view: top level - lib_com - tcx_mdct_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ ca3146eb9de8185ed0247945c643267826a32a94 Lines: 105 167 62.9 %
Date: 2025-08-26 01:31:27 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        2994 : static Word16 TCX_MDCT_GetScaleFactor(
      12             :     const Word16 L,  /* Q0 */
      13             :     Word16 *factor_e /* Q0 */
      14             : )
      15             : {
      16             : 
      17             :     Word16 factor;
      18             : 
      19        2994 :     IF( EQ_16( L, NORM_MDCT_FACTOR ) )
      20             :     {
      21           0 :         factor = 32767;
      22           0 :         move16();
      23           0 :         *factor_e = 0;
      24           0 :         move16();
      25             :     }
      26        2994 :     ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
      27             :     {
      28         526 :         factor = 23170;
      29         526 :         move16();
      30         526 :         *factor_e = 0;
      31         526 :         move16();
      32             :     }
      33        2468 :     ELSE IF( EQ_16( L, shl( NORM_MDCT_FACTOR, 2 ) ) )
      34             :     {
      35         618 :         factor = 16384;
      36         618 :         move16();
      37         618 :         *factor_e = 0;
      38         618 :         move16();
      39             :     }
      40             :     ELSE
      41             :     {
      42             : 
      43        1850 :         factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
      44        1850 :         *factor_e = 4;
      45        1850 :         move16();
      46             : 
      47        1850 :         factor = ISqrt16( factor, factor_e );
      48             :     }
      49             : 
      50        2994 :     return factor;
      51             : }
      52             : 
      53       17473 : static Word16 TCX_MDCT_Inverse_GetScaleFactor(
      54             :     const Word16 L,  /* Q0 */
      55             :     Word16 *factor_e /* Q0 */
      56             : )
      57             : {
      58             : 
      59             :     Word16 factor;
      60             : 
      61       17473 :     IF( EQ_16( L, NORM_MDCT_FACTOR ) )
      62             :     {
      63       17017 :         factor = 32767;
      64       17017 :         move16();
      65       17017 :         *factor_e = 0;
      66       17017 :         move16();
      67             :     }
      68         456 :     ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
      69             :     {
      70          16 :         factor = 23170;
      71          16 :         move16();
      72          16 :         *factor_e = 1;
      73          16 :         move16();
      74             :     }
      75         440 :     ELSE IF( EQ_16( L, 4 * NORM_MDCT_FACTOR ) )
      76             :     {
      77           0 :         factor = 32767;
      78           0 :         move16();
      79           0 :         *factor_e = 1;
      80           0 :         move16();
      81             :     }
      82             :     ELSE
      83             :     {
      84         440 :         factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
      85         440 :         *factor_e = 4;
      86         440 :         move16();
      87             : 
      88         440 :         factor = Sqrt16( factor, factor_e );
      89             :     }
      90             : 
      91       17473 :     return factor;
      92             : }
      93             : 
      94             : 
      95        1497 : 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        1497 :     factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e );
     117        1497 :     *y_e = add( *y_e, factor_e );
     118        1497 :     move16();
     119             : 
     120        1497 :     neg_factor = negate( factor );
     121             : 
     122             : 
     123             :     /* Init */
     124      330537 :     FOR( i = 0; i < m / 2; i++ )
     125             :     {
     126      329040 :         y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
     127      329040 :         move32();
     128             :     }
     129      257417 :     FOR( i = 0; i < l / 2; i++ )
     130             :     {
     131             : #ifdef ISSUE_1836_replace_overflow_libcom
     132      255920 :         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      255920 :         move32();
     137             :     }
     138      330537 :     FOR( i = 0; i < m / 2; i++ )
     139             :     {
     140      329040 :         y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
     141      329040 :         move32();
     142             :     }
     143      257417 :     FOR( i = 0; i < r / 2; i++ )
     144             :     {
     145             : #ifdef ISSUE_1836_replace_overflow_libcom
     146      255920 :         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      255920 :         move32();
     151             :     }
     152             : 
     153        1497 :     *y_e = sub( 15, *y_e );
     154        1497 :     move16();
     155        1497 :     edct_fx( y, y, l / 2 + m + r / 2, y_e );
     156        1497 :     *y_e = sub( 15 - 1, *y_e );
     157        1497 :     move16();
     158        1497 :     return;
     159             : }
     160             : 
     161        1497 : 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        1497 :     factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e ); /* exp(factor_e) */
     183        1497 :     *y_e = add( *y_e, factor_e );
     184        1497 :     move16();
     185             : 
     186        1497 :     neg_factor = negate( factor );
     187             : 
     188             : 
     189             :     /* Init */
     190      330537 :     FOR( i = 0; i < m / 2; i++ )
     191             :     {
     192      329040 :         y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
     193      329040 :         move32();
     194             :     }
     195      257417 :     FOR( i = 0; i < l / 2; i++ )
     196             :     {
     197             : #ifdef ISSUE_1836_replace_overflow_libcom
     198      255920 :         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      255920 :         move32();
     203             :     }
     204      330537 :     FOR( i = 0; i < m / 2; i++ )
     205             :     {
     206      329040 :         y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
     207      329040 :         move32();
     208             :     }
     209      257417 :     FOR( i = 0; i < r / 2; i++ )
     210             :     {
     211      255920 :         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      255920 :         move32();
     213             :     }
     214             : 
     215        1497 :     *y_e = sub( 15, *y_e );
     216        1497 :     move16();
     217             : 
     218        1497 :     edst_fx( y, y, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), y_e );
     219             : 
     220        1497 :     *y_e = sub( 15 - 1, *y_e );
     221        1497 :     move16();
     222             : 
     223        1497 :     return;
     224             : }
     225             : 
     226       17473 : 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       17473 :     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       17473 :     L2 = shr( l, 1 );
     243       17473 :     R2 = shr( r, 1 );
     244             : 
     245       17473 :     x_e = sub( 15, x_e );
     246       17473 :     edct_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
     247       17473 :     x_e = sub( 15, x_e );
     248             : 
     249       17473 :     fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e ); /* exp(fac_e) */
     250       17473 :     x_e = add( x_e, fac_e );
     251             : 
     252       17473 :     negfac = negate( fac );
     253             : 
     254       17473 :     s = x_e;
     255       17473 :     move16();
     256             : 
     257      669194 :     FOR( i = 0; i < R2; i++ )
     258             :     {
     259      651721 :         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      651721 :         move16();
     262             :     }
     263             : 
     264      669194 :     FOR( i = 0; i < L2; i++ )
     265             :     {
     266      651721 :         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      651721 :         move16();
     268             :     }
     269             : 
     270     1539193 :     FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
     271             :     {
     272             :         Word16 f;
     273             : 
     274     1521720 :         f = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
     275     1521720 :         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     1521720 :         move16();
     277     1521720 :         y[l + m + R2 - 1 - i] = f;
     278     1521720 :         move16();
     279             :     }
     280       17473 : }
     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