LCOV - code coverage report
Current view: top level - lib_com - tcx_mdct_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 4c82f1d24d39d0296b18d775f18a006f4c7d024b Lines: 167 171 97.7 %
Date: 2025-05-17 01:59:02 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        2850 : static Word16 TCX_MDCT_GetScaleFactor(
      12             :     const Word16 L,  /* Q0 */
      13             :     Word16 *factor_e /* Q0 */
      14             : )
      15             : {
      16             : 
      17             :     Word16 factor;
      18             : 
      19        2850 :     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        2850 :     ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
      27             :     {
      28         452 :         factor = 23170;
      29         452 :         move16();
      30         452 :         *factor_e = 0;
      31         452 :         move16();
      32             :     }
      33        2398 :     ELSE IF( EQ_16( L, shl( NORM_MDCT_FACTOR, 2 ) ) )
      34             :     {
      35         616 :         factor = 16384;
      36         616 :         move16();
      37         616 :         *factor_e = 0;
      38         616 :         move16();
      39             :     }
      40             :     ELSE
      41             :     {
      42             : 
      43        1782 :         factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
      44        1782 :         *factor_e = 4;
      45        1782 :         move16();
      46             : 
      47        1782 :         factor = ISqrt16( factor, factor_e );
      48             :     }
      49             : 
      50        2850 :     return factor;
      51             : }
      52             : 
      53      122602 : static Word16 TCX_MDCT_Inverse_GetScaleFactor(
      54             :     const Word16 L,  /* Q0 */
      55             :     Word16 *factor_e /* Q0 */
      56             : )
      57             : {
      58             : 
      59             :     Word16 factor;
      60             : 
      61      122602 :     IF( EQ_16( L, NORM_MDCT_FACTOR ) )
      62             :     {
      63       42128 :         factor = 32767;
      64       42128 :         move16();
      65       42128 :         *factor_e = 0;
      66       42128 :         move16();
      67             :     }
      68       80474 :     ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
      69             :     {
      70       13550 :         factor = 23170;
      71       13550 :         move16();
      72       13550 :         *factor_e = 1;
      73       13550 :         move16();
      74             :     }
      75       66924 :     ELSE IF( EQ_16( L, 4 * NORM_MDCT_FACTOR ) )
      76             :     {
      77        1015 :         factor = 32767;
      78        1015 :         move16();
      79        1015 :         *factor_e = 1;
      80        1015 :         move16();
      81             :     }
      82             :     ELSE
      83             :     {
      84       65909 :         factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
      85       65909 :         *factor_e = 4;
      86       65909 :         move16();
      87             : 
      88       65909 :         factor = Sqrt16( factor, factor_e );
      89             :     }
      90             : 
      91      122602 :     return factor;
      92             : }
      93             : 
      94             : 
      95        1425 : 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        1425 :     Flag Overflow = 0;
     112        1425 :     move32();
     113             : #endif
     114        1425 :     factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e );
     115        1425 :     *y_e = add( *y_e, factor_e );
     116        1425 :     move16();
     117             : 
     118        1425 :     neg_factor = negate( factor );
     119             : 
     120             : 
     121             :     /* Init */
     122      317775 :     FOR( i = 0; i < m / 2; i++ )
     123             :     {
     124      316350 :         y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
     125      316350 :         move32();
     126             :     }
     127      247475 :     FOR( i = 0; i < l / 2; i++ )
     128             :     {
     129      246050 :         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      246050 :         move32();
     131             :     }
     132      317775 :     FOR( i = 0; i < m / 2; i++ )
     133             :     {
     134      316350 :         y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
     135      316350 :         move32();
     136             :     }
     137      247475 :     FOR( i = 0; i < r / 2; i++ )
     138             :     {
     139      246050 :         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      246050 :         move32();
     141             :     }
     142             : 
     143        1425 :     *y_e = sub( 15, *y_e );
     144        1425 :     move16();
     145        1425 :     edct_fx( y, y, l / 2 + m + r / 2, y_e );
     146        1425 :     *y_e = sub( 15 - 1, *y_e );
     147        1425 :     move16();
     148        1425 :     return;
     149             : }
     150             : 
     151        1425 : 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        1425 :     Flag Overflow = 0;
     168        1425 :     move32();
     169             : #endif
     170        1425 :     factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e ); /* exp(factor_e) */
     171        1425 :     *y_e = add( *y_e, factor_e );
     172        1425 :     move16();
     173             : 
     174        1425 :     neg_factor = negate( factor );
     175             : 
     176             : 
     177             :     /* Init */
     178      317775 :     FOR( i = 0; i < m / 2; i++ )
     179             :     {
     180      316350 :         y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
     181      316350 :         move32();
     182             :     }
     183      247475 :     FOR( i = 0; i < l / 2; i++ )
     184             :     {
     185      246050 :         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      246050 :         move32();
     187             :     }
     188      317775 :     FOR( i = 0; i < m / 2; i++ )
     189             :     {
     190      316350 :         y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
     191      316350 :         move32();
     192             :     }
     193      247475 :     FOR( i = 0; i < r / 2; i++ )
     194             :     {
     195      246050 :         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      246050 :         move32();
     197             :     }
     198             : 
     199        1425 :     *y_e = sub( 15, *y_e );
     200        1425 :     move16();
     201             : 
     202        1425 :     edst_fx( y, y, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), y_e );
     203             : 
     204        1425 :     *y_e = sub( 15 - 1, *y_e );
     205        1425 :     move16();
     206             : 
     207        1425 :     return;
     208             : }
     209             : 
     210      122520 : 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      122520 :     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      122520 :     L2 = shr( l, 1 );
     227      122520 :     R2 = shr( r, 1 );
     228             : 
     229      122520 :     x_e = sub( 15, x_e );
     230      122520 :     edct_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
     231      122520 :     x_e = sub( 15, x_e );
     232             : 
     233      122520 :     fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e ); /* exp(fac_e) */
     234      122520 :     x_e = add( x_e, fac_e );
     235             : 
     236      122520 :     negfac = negate( fac );
     237             : 
     238      122520 :     s = x_e;
     239      122520 :     move16();
     240             : 
     241     9272994 :     FOR( i = 0; i < R2; i++ )
     242             :     {
     243     9150474 :         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     9150474 :         move16();
     246             :     }
     247             : 
     248     8982102 :     FOR( i = 0; i < L2; i++ )
     249             :     {
     250     8859582 :         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     8859582 :         move16();
     252             :     }
     253             : 
     254    17843312 :     FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
     255             :     {
     256             :         Word16 f;
     257             : 
     258    17720792 :         f = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
     259    17720792 :         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    17720792 :         move16();
     261    17720792 :         y[l + m + R2 - 1 - i] = f;
     262    17720792 :         move16();
     263             :     }
     264      122520 : }
     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