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 @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 171 171 100.0 %
Date: 2025-05-03 01:55:50 Functions: 7 7 100.0 %

          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      695138 : static Word16 TCX_MDCT_GetScaleFactor(
      12             :     const Word16 L,  /* Q0 */
      13             :     Word16 *factor_e /* Q0 */
      14             : )
      15             : {
      16             : 
      17             :     Word16 factor;
      18             : 
      19      695138 :     IF( EQ_16( L, NORM_MDCT_FACTOR ) )
      20             :     {
      21       33994 :         factor = 32767;
      22       33994 :         move16();
      23       33994 :         *factor_e = 0;
      24       33994 :         move16();
      25             :     }
      26      661144 :     ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
      27             :     {
      28      123118 :         factor = 23170;
      29      123118 :         move16();
      30      123118 :         *factor_e = 0;
      31      123118 :         move16();
      32             :     }
      33      538026 :     ELSE IF( EQ_16( L, shl( NORM_MDCT_FACTOR, 2 ) ) )
      34             :     {
      35       18586 :         factor = 16384;
      36       18586 :         move16();
      37       18586 :         *factor_e = 0;
      38       18586 :         move16();
      39             :     }
      40             :     ELSE
      41             :     {
      42             : 
      43      519440 :         factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
      44      519440 :         *factor_e = 4;
      45      519440 :         move16();
      46             : 
      47      519440 :         factor = ISqrt16( factor, factor_e );
      48             :     }
      49             : 
      50      695138 :     return factor;
      51             : }
      52             : 
      53      137016 : static Word16 TCX_MDCT_Inverse_GetScaleFactor(
      54             :     const Word16 L,  /* Q0 */
      55             :     Word16 *factor_e /* Q0 */
      56             : )
      57             : {
      58             : 
      59             :     Word16 factor;
      60             : 
      61      137016 :     IF( EQ_16( L, NORM_MDCT_FACTOR ) )
      62             :     {
      63       46508 :         factor = 32767;
      64       46508 :         move16();
      65       46508 :         *factor_e = 0;
      66       46508 :         move16();
      67             :     }
      68       90508 :     ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
      69             :     {
      70       19134 :         factor = 23170;
      71       19134 :         move16();
      72       19134 :         *factor_e = 1;
      73       19134 :         move16();
      74             :     }
      75       71374 :     ELSE IF( EQ_16( L, 4 * NORM_MDCT_FACTOR ) )
      76             :     {
      77        1107 :         factor = 32767;
      78        1107 :         move16();
      79        1107 :         *factor_e = 1;
      80        1107 :         move16();
      81             :     }
      82             :     ELSE
      83             :     {
      84       70267 :         factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
      85       70267 :         *factor_e = 4;
      86       70267 :         move16();
      87             : 
      88       70267 :         factor = Sqrt16( factor, factor_e );
      89             :     }
      90             : 
      91      137016 :     return factor;
      92             : }
      93             : 
      94             : 
      95      417441 : 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             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     111      417441 :     Flag Overflow = 0;
     112      417441 :     move32();
     113             : #endif
     114      417441 :     factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e );
     115      417441 :     *y_e = add( *y_e, factor_e );
     116      417441 :     move16();
     117             : 
     118      417441 :     neg_factor = negate( factor );
     119             : 
     120             : 
     121             :     /* Init */
     122    39107235 :     FOR( i = 0; i < m / 2; i++ )
     123             :     {
     124    38689794 :         y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
     125    38689794 :         move32();
     126             :     }
     127    22730189 :     FOR( i = 0; i < l / 2; i++ )
     128             :     {
     129    22312748 :         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) */
     130    22312748 :         move32();
     131             :     }
     132    39107235 :     FOR( i = 0; i < m / 2; i++ )
     133             :     {
     134    38689794 :         y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
     135    38689794 :         move32();
     136             :     }
     137    25221569 :     FOR( i = 0; i < r / 2; i++ )
     138             :     {
     139    24804128 :         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) */
     140    24804128 :         move32();
     141             :     }
     142             : 
     143      417441 :     *y_e = sub( 15, *y_e );
     144      417441 :     move16();
     145      417441 :     edct_fx( y, y, l / 2 + m + r / 2, y_e );
     146      417441 :     *y_e = sub( 15 - 1, *y_e );
     147      417441 :     move16();
     148      417441 :     return;
     149             : }
     150             : 
     151      277697 : void TCX_MDST(
     152             :     const Word16 *x, /* Qx */
     153             :     Word32 *y,       /* exp(y_e) */
     154             :     Word16 *y_e,
     155             :     const Word16 l,           /* Q0 */
     156             :     const Word16 m,           /* Q0 */
     157             :     const Word16 r,           /* Q0 */
     158             :     const Word16 element_mode /* Q0 */
     159             : )
     160             : {
     161             : 
     162             :     Word16 i;
     163             :     Word16 factor, neg_factor;
     164             :     Word16 factor_e;
     165             :     (void) element_mode;
     166             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     167      277697 :     Flag Overflow = 0;
     168      277697 :     move32();
     169             : #endif
     170      277697 :     factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e ); /* exp(factor_e) */
     171      277697 :     *y_e = add( *y_e, factor_e );
     172      277697 :     move16();
     173             : 
     174      277697 :     neg_factor = negate( factor );
     175             : 
     176             : 
     177             :     /* Init */
     178    67169537 :     FOR( i = 0; i < m / 2; i++ )
     179             :     {
     180    66891840 :         y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
     181    66891840 :         move32();
     182             :     }
     183    47289117 :     FOR( i = 0; i < l / 2; i++ )
     184             :     {
     185    47011420 :         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) */
     186    47011420 :         move32();
     187             :     }
     188    67169537 :     FOR( i = 0; i < m / 2; i++ )
     189             :     {
     190    66891840 :         y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
     191    66891840 :         move32();
     192             :     }
     193    49750597 :     FOR( i = 0; i < r / 2; i++ )
     194             :     {
     195    49472900 :         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) */
     196    49472900 :         move32();
     197             :     }
     198             : 
     199      277697 :     *y_e = sub( 15, *y_e );
     200      277697 :     move16();
     201             : 
     202      277697 :     edst_fx( y, y, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), y_e );
     203             : 
     204      277697 :     *y_e = sub( 15 - 1, *y_e );
     205      277697 :     move16();
     206             : 
     207      277697 :     return;
     208             : }
     209             : 
     210      136934 : void TCX_MDCT_Inverse(
     211             :     Word32 *x, // Q( 31 - x_e )
     212             :     Word16 x_e,
     213             :     Word16 *y,                /* Qy */
     214             :     const Word16 l,           /* Q0 */
     215             :     const Word16 m,           /* Q0 */
     216             :     const Word16 r,           /* Q0 */
     217             :     const Word16 element_mode /* Q0 */
     218             : )
     219             : {
     220             : 
     221             :     Word16 i, fac, negfac, s;
     222      136934 :     Word16 L2 = l, R2 = r;
     223             :     Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
     224             :     Word16 fac_e;
     225             :     (void) element_mode;
     226      136934 :     L2 = shr( l, 1 );
     227      136934 :     R2 = shr( r, 1 );
     228             : 
     229      136934 :     x_e = sub( 15, x_e );
     230      136934 :     edct_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
     231      136934 :     x_e = sub( 15, x_e );
     232             : 
     233      136934 :     fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e ); /* exp(fac_e) */
     234      136934 :     x_e = add( x_e, fac_e );
     235             : 
     236      136934 :     negfac = negate( fac );
     237             : 
     238      136934 :     s = x_e;
     239      136934 :     move16();
     240             : 
     241    10244244 :     FOR( i = 0; i < R2; i++ )
     242             :     {
     243    10107310 :         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)*/
     244             : 
     245    10107310 :         move16();
     246             :     }
     247             : 
     248     9941492 :     FOR( i = 0; i < L2; i++ )
     249             :     {
     250     9804558 :         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)*/
     251     9804558 :         move16();
     252             :     }
     253             : 
     254    20042926 :     FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
     255             :     {
     256             :         Word16 f;
     257             : 
     258    19905992 :         f = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
     259    19905992 :         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)*/
     260    19905992 :         move16();
     261    19905992 :         y[l + m + R2 - 1 - i] = f;
     262    19905992 :         move16();
     263             :     }
     264      136934 : }
     265             : 
     266          20 : void TCX_MDST_Inverse_fx(
     267             :     Word32 *x, /* exp(x_e) */
     268             :     Word16 x_e,
     269             :     Word16 *y,      /* Qx */
     270             :     const Word16 l, /* Q0 */
     271             :     const Word16 m, /* Q0 */
     272             :     const Word16 r  /* Q0 */
     273             : )
     274             : {
     275             : 
     276             :     Word16 i, fac, negfac, s;
     277          20 :     Word16 L2 = l, R2 = r;
     278          20 :     move16();
     279          20 :     move16();
     280             :     Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
     281             :     Word16 fac_e;
     282             : 
     283          20 :     L2 = shr( l, 1 );
     284          20 :     R2 = shr( r, 1 );
     285             : 
     286          20 :     x_e = sub( 15, x_e );
     287          20 :     edst_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
     288          20 :     x_e = sub( 15, x_e );
     289             : 
     290          20 :     fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e );
     291          20 :     x_e = add( x_e, fac_e );
     292             : 
     293          20 :     negfac = negate( fac );
     294             : 
     295          20 :     s = x_e;
     296          20 :     move16();
     297             : 
     298         934 :     FOR( i = 0; i < R2; i++ )
     299             :     {
     300         914 :         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)*/
     301         914 :         move16();
     302             :     }
     303             : 
     304         934 :     FOR( i = 0; i < L2; i++ )
     305             :     {
     306         914 :         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)*/
     307         914 :         move16();
     308             :     }
     309             : 
     310        1556 :     FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
     311             :     {
     312             :         Word16 f;
     313        1536 :         f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], fac ), s ) );
     314             : 
     315        1536 :         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)*/
     316        1536 :         move16();
     317             : 
     318        1536 :         y[l + m + R2 - 1 - i] = negate( f );
     319        1536 :         move16();
     320             :     }
     321          20 : }
     322             : 
     323             : /*-------------------------------------------------------------------*
     324             :  * TCX_MDXT_Inverse_fx()
     325             :  *
     326             :  *
     327             :  *-------------------------------------------------------------------*/
     328             : 
     329          62 : void TCX_MDXT_Inverse_fx(
     330             :     const Word32 *x, /* exp(x_e) */
     331             :     Word16 x_e,
     332             :     Word16 *y,                /* Qx */
     333             :     const Word16 l,           /* Q0 */
     334             :     const Word16 m,           /* Q0 */
     335             :     const Word16 r,           /* Q0 */
     336             :     const UWord16 kernel_type /* Q0 */
     337             : )
     338             : {
     339             :     Word16 signLeft;
     340             :     Word16 signRight;
     341             :     Word16 i, fac, negfac, s, fac_e;
     342          62 :     const Word16 L2 = shr( l, 1 ), R2 = shr( r, 1 );
     343             :     Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
     344             :     Word16 f;
     345             : 
     346          62 :     set32_fx( tmp_buf, 0, N_MAX + L_MDCT_OVLP_MAX / 2 );
     347             : 
     348          62 :     edxt_fx( x, tmp_buf + L2, add( add( L2, m ), R2 ), kernel_type, TRUE );
     349             : 
     350          62 :     fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e );
     351          62 :     x_e = add( x_e, fac_e );
     352             : 
     353          62 :     negfac = negate( fac );
     354          62 :     IF( GE_16( kernel_type, MDCT_II ) )
     355             :     {
     356          46 :         signLeft = negfac;
     357             :     }
     358             :     ELSE
     359             :     {
     360          16 :         signLeft = fac;
     361             :     }
     362             :     // signRight = ( kernel_type & 1 ? fac : negfac );
     363          62 :     IF( L_and( kernel_type, 1 ) )
     364             :     {
     365          16 :         signRight = fac;
     366             :     }
     367             :     ELSE
     368             :     {
     369          46 :         signRight = negfac;
     370             :     }
     371             : 
     372          62 :     s = x_e;
     373          62 :     move16();
     374             : 
     375        3424 :     FOR( i = 0; i < L2; i++ )
     376             :     {
     377        3362 :         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)*/
     378             :     }
     379             : 
     380        3464 :     FOR( i = 0; i < R2; i++ )
     381             :     {
     382        3402 :         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)*/
     383        3402 :         move16();
     384             :     }
     385             : 
     386        4750 :     FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
     387             :     {
     388             : 
     389        4688 :         f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
     390             : 
     391        4688 :         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)*/
     392        4688 :         move16();
     393             : 
     394        4688 :         y[l + m + R2 - 1 - i] = f;
     395        4688 :         move16();
     396             :     }
     397             : 
     398          62 :     return;
     399             : }

Generated by: LCOV version 1.14