LCOV - code coverage report
Current view: top level - lib_com - edct_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 4c82f1d24d39d0296b18d775f18a006f4c7d024b Lines: 325 478 68.0 %
Date: 2025-05-17 01:59:02 Functions: 7 8 87.5 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdlib.h>
       6             : #include <assert.h>
       7             : #include "options.h" /* Compilation switches                   */
       8             : #include "cnst.h"    /* Common constants                       */
       9             : #include "rom_com.h" /* Static table prototypes                */
      10             : #include "prot_fx.h" /* Function prototypes                    */
      11             : #include "stl.h"
      12             : 
      13             : 
      14             : #include "math_32.h"
      15             : 
      16             : 
      17        1040 : static Word16 get_edxt_factor( Word16 length ) /* Returns value of sqrtf(2.f/length) in Q15 */
      18             : {
      19             :     Word16 factor; /*Q15*/
      20        1040 :     factor = 0;
      21        1040 :     move16();
      22        1040 :     IF( EQ_16( length, 512 ) )
      23             :     {
      24         262 :         factor = 2048; /*0.0625 in Q15*/
      25         262 :         move16();
      26             :     }
      27         778 :     ELSE IF( EQ_16( length, 256 ) )
      28             :     {
      29           5 :         factor = 2896; /*0.0883 in Q15*/
      30           5 :         move16();
      31             :     }
      32         773 :     ELSE IF( EQ_16( length, 128 ) )
      33             :     {
      34           7 :         factor = 4096; /*0.125 in Q15*/
      35           7 :         move16();
      36             :     }
      37         766 :     ELSE IF( EQ_16( length, 640 ) )
      38             :     {
      39         184 :         factor = 1832; /*0.0559 in Q15*/
      40         184 :         move16();
      41             :     }
      42         582 :     ELSE IF( EQ_16( length, 320 ) )
      43             :     {
      44         432 :         factor = 2590; /*0.079 in Q15*/
      45         432 :         move16();
      46             :     }
      47         150 :     ELSE IF( EQ_16( length, 160 ) )
      48             :     {
      49          22 :         factor = 3663; /*0.1117 in Q15*/
      50          22 :         move16();
      51             :     }
      52         128 :     ELSE IF( EQ_16( length, 80 ) )
      53             :     {
      54          22 :         factor = 5181; /*0.1581 in Q15*/
      55          22 :         move16();
      56             :     }
      57         106 :     ELSE IF( EQ_16( length, 40 ) )
      58             :     {
      59           0 :         factor = 7327; /*0.223 in Q15*/
      60           0 :         move16();
      61             :     }
      62         106 :     ELSE IF( EQ_16( length, 960 ) )
      63             :     {
      64         106 :         factor = 1496; /*0.0456 in Q15*/
      65         106 :         move16();
      66             :     }
      67           0 :     ELSE IF( EQ_16( length, 480 ) )
      68             :     {
      69           0 :         factor = 2115; /*0.0645 in Q15*/
      70           0 :         move16();
      71             :     }
      72           0 :     ELSE IF( EQ_16( length, 240 ) )
      73             :     {
      74           0 :         factor = 2991; /*0.0912 in Q15*/
      75           0 :         move16();
      76             :     }
      77           0 :     ELSE IF( EQ_16( length, 120 ) )
      78             :     {
      79           0 :         factor = 4230; /*0.1290 in Q15*/
      80           0 :         move16();
      81             :     }
      82           0 :     ELSE IF( EQ_16( length, 1200 ) )
      83             :     {
      84           0 :         factor = 1338; /*0.040 in Q15*/
      85           0 :         move16();
      86             :     }
      87           0 :     ELSE IF( EQ_16( length, 800 ) )
      88             :     {
      89           0 :         factor = 1638; /*0.05 in Q15*/
      90           0 :         move16();
      91             :     }
      92           0 :     ELSE IF( EQ_16( length, 400 ) )
      93             :     {
      94           0 :         factor = 2317; /*0.070 in Q15*/
      95           0 :         move16();
      96             :     }
      97           0 :     ELSE IF( EQ_16( length, 200 ) )
      98             :     {
      99           0 :         factor = 3277; /*0.1 in Q15*/
     100           0 :         move16();
     101             :     }
     102        1040 :     return factor; /*Q15*/
     103             : }
     104             : 
     105     1696911 : static Word16 const *get_edct_table( Word16 length /*Q0*/, Word16 *q )
     106             : {
     107             :     Word16 const *edct_table;
     108     1696911 :     edct_table = NULL;
     109     1696911 :     SWITCH( length )
     110             :     {
     111        6068 :         case 1200:
     112        6068 :             edct_table = edct_table_600_fx; /*Q17*/
     113        6068 :             *q = add( *q, 2 );
     114        6068 :             move16();
     115        6068 :             BREAK;
     116      561022 :         case 960:
     117      561022 :             edct_table = edct_table_480_fx; /*Q16*/
     118      561022 :             BREAK;
     119      556988 :         case 640:
     120      556988 :             edct_table = edct_table_320_fx; /*Q16*/
     121      556988 :             BREAK;
     122      200421 :         case 320:
     123      200421 :             edct_table = edct_table_160_fx; /*Q16*/
     124      200421 :             BREAK;
     125       49188 :         case 256:
     126       49188 :             edct_table = edct_table_128_fx; /*Q16*/
     127       49188 :             BREAK;
     128       21498 :         case 240:
     129       21498 :             edct_table = edct_table_120_fx; /*Q16*/
     130       21498 :             BREAK;
     131           0 :         case 200:
     132           0 :             edct_table = edct_table_100_fx; /*Q16*/
     133           0 :             BREAK;
     134       42634 :         case 160:
     135       42634 :             edct_table = edct_table_80_fx; /*Q16*/
     136       42634 :             BREAK;
     137           0 :         case 40:
     138           0 :             edct_table = edct_table_20_fx; /*Q16*/
     139           0 :             BREAK;
     140        2432 :         case 800:
     141        2432 :             edct_table = edct_table_400_fx; /*Q17*/
     142        2432 :             *q = add( *q, 2 );
     143        2432 :             move16();
     144        2432 :             BREAK;
     145      223107 :         case 512:
     146      223107 :             edct_table = edct_table_256_fx; /*Q16*/
     147      223107 :             BREAK;
     148        9071 :         case 480:
     149        9071 :             edct_table = edct_table_240_fx; /*Q16*/
     150        9071 :             BREAK;
     151        4529 :         case 400:
     152        4529 :             edct_table = edct_table_200_fx; /*Q16*/
     153        4529 :             BREAK;
     154       12835 :         case 128:
     155       12835 :             edct_table = edct_table_64_fx; /*Q16*/
     156       12835 :             BREAK;
     157        7118 :         case 80:
     158        7118 :             edct_table = edct_table_40_fx; /*Q16*/
     159        7118 :             BREAK;
     160           0 :         default:
     161           0 :             BREAK;
     162             :     }
     163     1696911 :     return edct_table;
     164             : }
     165             : 
     166             : /*-------------------------------------------------------------------------*
     167             :  * FUNCTION : edct_fx()
     168             :  *
     169             :  * PURPOSE : DCT transform
     170             :  *
     171             :  * INPUT ARGUMENTS :
     172             :  * _ (Word16) length             : length
     173             :  * _ (Word16*) x                 : input signal                      Qx
     174             :  * _ (Word16*) edct_table_128_fx : edct table                       Q16
     175             :  *
     176             :  * OUTPUT ARGUMENTS :
     177             :  * _ (Word16[]) y                : output transform                  Qx
     178             :  *-------------------------------------------------------------------------*/
     179     1694866 : void edct_fx(
     180             :     const Word32 *x, /* i  : input signal        Qq         */
     181             :     Word32 *y,       /* o  : output transform    Qq         */
     182             :     Word16 length,   /* i  : length                         Q0*/
     183             :     Word16 *q        /* i  : Q value of input signal        */
     184             : )
     185             : {
     186             :     Word16 i;
     187             :     Word32 re;
     188             :     Word32 im;
     189             :     const Word16 *edct_table; /*Q16 */
     190             :     Word32 complex_buf[2 * ( L_FRAME48k / 2 + 240 )];
     191             :     Word32 L_tmp;
     192             :     Word16 tmp;
     193             :     Word16 len1;
     194             : 
     195     1694866 :     edct_table = get_edct_table( length, q ); /*q*/
     196     1694866 :     len1 = shr( length, 1 );                  /*Q0*/
     197             :     /* Twiddling and Pre-rotate */
     198   558784106 :     FOR( i = 0; i < len1; i++ )
     199             :     {
     200   557089240 :         L_tmp = Mult_32_16( x[2 * i], edct_table[i] );                                                                 /*Q(q+1) */
     201   557089240 :         complex_buf[2 * i] = Madd_32_16( L_tmp, x[( length - ( 1 + ( i * 2 ) ) )], edct_table[( len1 - ( 1 + i ) )] ); /*Q(q+1) */
     202   557089240 :         move32();
     203             : 
     204   557089240 :         L_tmp = Mult_32_16( x[( length - ( 1 + ( i * 2 ) ) )], edct_table[i] ); /*Q(q+1) */
     205             : 
     206   557089240 :         complex_buf[( ( i * 2 ) + 1 )] = Msub_32_16( L_tmp, x[( i * 2 )], edct_table[( len1 - ( 1 + i ) )] ); /*Q(q+1) */
     207   557089240 :         move32();
     208             :     }
     209             : 
     210     1694866 :     *q = sub( 15, *q );
     211     1694866 :     move16();
     212     1694866 :     BASOP_cfft( (cmplx *) complex_buf, len1, q, y );
     213             : 
     214     1694866 :     tmp = div_s( 1, length );                                                     /*Q15 */
     215     1694866 :     tmp = round_fx( L_shl( L_mult( tmp, 19302 /*0.75f * EVS_PI in Q13*/ ), 2 ) ); /*Q15 */
     216   558784106 :     FOR( i = 0; i < len1; i++ )
     217             :     {
     218   557089240 :         re = Msub_32_16( complex_buf[2 * i], complex_buf[( ( i * 2 ) + 1 )], tmp );                              /*Q(q+1) */
     219   557089240 :         im = Madd_32_16( complex_buf[( ( i * 2 ) + 1 )], complex_buf[2 * i], tmp );                              /*Q(q+1) */
     220   557089240 :         y[2 * i] = L_add( Mult_32_16( re, edct_table[i] ), Mult_32_16( im, edct_table[( len1 - ( 1 + i ) )] ) ); /*Q(q+2)*/
     221   557089240 :         move32();
     222   557089240 :         y[( length - ( 1 + ( i * 2 ) ) )] = L_sub( Mult_32_16( re, edct_table[( len1 - ( 1 + i ) )] ), Mult_32_16( im, edct_table[i] ) ); /*Q(q+2)*/
     223   557089240 :         move32();
     224             :     } /*Q(q-2) */
     225             : 
     226     1694866 :     *q = sub( 15 + 2, *q );
     227     1694866 :     move16();
     228     1694866 :     return;
     229             : }
     230             : 
     231           0 : void edct_ivas_fx(
     232             :     const Word32 *x, /* i  : input signal        Qq         */
     233             :     Word32 *y,       /* o  : output transform    Qq         */
     234             :     Word16 length,   /* i  : length                         Q0*/
     235             :     Word16 *q        /* i  : Q value of input signal        */
     236             : )
     237             : {
     238             :     Word16 i;
     239             :     const Word16 *edct_table; /*Q16 */
     240             :     Word32 re[L_FRAME_PLUS / 2];
     241             :     Word32 im[L_FRAME_PLUS / 2];
     242             :     Word32 L_tmp;
     243             :     Word16 tmp;
     244             :     Word16 len1;
     245             : 
     246           0 :     edct_table = get_edct_table( length, q ); /*q*/
     247           0 :     len1 = shr( length, 1 );                  /*Q0*/
     248             :                                               /* Twiddling and Pre-rotate */
     249           0 :     FOR( i = 0; i < len1; i++ )
     250             :     {
     251           0 :         L_tmp = Mult_32_16( x[2 * i], edct_table[i] );                                                    /*Q(q+1) */
     252           0 :         re[i] = Madd_32_16( L_tmp, x[( length - ( 1 + ( i * 2 ) ) )], edct_table[( len1 - ( 1 + i ) )] ); /*Q(q+1) */
     253           0 :         move32();
     254             : 
     255           0 :         L_tmp = Mult_32_16( x[( length - ( 1 + ( i * 2 ) ) )], edct_table[i] );      /*Q(q+1) */
     256           0 :         im[i] = Msub_32_16( L_tmp, x[( i * 2 )], edct_table[( len1 - ( 1 + i ) )] ); /*Q(q+1) */
     257           0 :         move32();
     258             :     }
     259             : 
     260           0 :     *q = sub( 31, *q );
     261           0 :     move16();
     262           0 :     tmp = sub( s_min( getScaleFactor32( re, len1 ), getScaleFactor32( im, len1 ) ), find_guarded_bits_fx( len1 ) );
     263           0 :     scale_sig32( re, len1, tmp );
     264           0 :     scale_sig32( im, len1, tmp );
     265             : 
     266           0 :     fft_fx( re, im, len1, 1 );
     267           0 :     *q = sub( *q, tmp );
     268           0 :     move16();
     269             : 
     270           0 :     tmp = div_s( 4, length );                                         /*Q17 */
     271           0 :     tmp = round_fx( L_mult( tmp, 19302 /*0.75f * EVS_PI in Q13*/ ) ); /*Q15 */
     272           0 :     FOR( i = 0; i < len1; i++ )
     273             :     {
     274           0 :         L_tmp = Msub_32_16( re[i], im[i], tmp );
     275           0 :         im[i] = Madd_32_16( im[i], re[i], tmp ); /*Q(q+1) */
     276           0 :         re[i] = L_tmp;                           /*Q(q+1) */
     277           0 :         move32();
     278           0 :         move32();
     279             :     }
     280           0 :     FOR( i = 0; i < len1; i++ )
     281             :     {
     282           0 :         y[2 * i] = L_add( Mult_32_16( re[i], edct_table[i] ), Mult_32_16( im[i], edct_table[( len1 - ( 1 + i ) )] ) ); /*Q(q+2)*/
     283           0 :         move32();
     284           0 :         y[( length - ( 1 + ( i * 2 ) ) )] = L_sub( Mult_32_16( re[i], edct_table[( len1 - ( 1 + i ) )] ), Mult_32_16( im[i], edct_table[i] ) ); /*Q(q+2)*/
     285           0 :         move32();
     286             :     } /*Q(q-2) */
     287             : 
     288           0 :     *q = sub( 31 + 2, *q );
     289           0 :     move16();
     290           0 :     return;
     291             : }
     292             : /*-------------------------------------------------------------------------*
     293             :  * FUNCTION : edst_fx()
     294             :  *
     295             :  * PURPOSE : DST_IV transform
     296             :  *
     297             :  * INPUT ARGUMENTS :
     298             :  * _ (Word16) length             : length
     299             :  * _ (Word16*) x                 : input signal                      Qx
     300             :  * _ (Word16*) edct_table_128_fx : edct table                       Q16
     301             :  *
     302             :  * OUTPUT ARGUMENTS :
     303             :  * _ (Word16[]) y                : output transform                  Qx
     304             :  *-------------------------------------------------------------------------*/
     305        2045 : void edst_fx(
     306             :     const Word32 *x, /* i  : input signal        Qq         */
     307             :     Word32 *y,       /* o  : output transform    Qq         */
     308             :     Word16 length,   /* i  : length                         */
     309             :     Word16 *q        /* i  : Q value of input signal        */
     310             : )
     311             : {
     312             :     Word16 i;
     313             :     Word32 re;
     314             :     Word32 im;
     315             :     const Word16 *edct_table; /*Q16 */
     316             :     Word32 complex_buf[2 * ( L_FRAME48k / 2 + 240 )];
     317             :     Word32 L_tmp;
     318             :     Word16 tmp;
     319             :     Word16 len1;
     320             : 
     321        2045 :     edct_table = get_edct_table( length, q ); /*q*/
     322        2045 :     len1 = shr( length, 1 );                  /*Q0*/
     323             :     /* Twiddling and Pre-rotate */
     324      711421 :     FOR( i = 0; i < len1; i++ )
     325             :     {
     326      709376 :         L_tmp = Mult_32_16( x[( length - ( 1 + ( i * 2 ) ) )], edct_table[i] );               /*Qq+1*/
     327      709376 :         complex_buf[2 * i] = Madd_32_16( L_tmp, x[2 * i], edct_table[( len1 - ( 1 + i ) )] ); /*Qq+1*/
     328      709376 :         move32();
     329             : 
     330      709376 :         L_tmp = Mult_32_16( x[2 * i], edct_table[i] );                                                                             /*Qq+1*/
     331      709376 :         complex_buf[( ( i * 2 ) + 1 )] = Msub_32_16( L_tmp, x[( length - ( 1 + ( i * 2 ) ) )], edct_table[( len1 - ( 1 + i ) )] ); /*Qq+1*/
     332      709376 :         move32();
     333             :     }
     334             : 
     335        2045 :     *q = sub( 15, *q );
     336        2045 :     move16();
     337        2045 :     BASOP_cfft( (cmplx *) complex_buf, len1, q, y );
     338             : 
     339        2045 :     tmp = div_s( 1, length );                                                     /*Q15 */
     340        2045 :     tmp = round_fx( L_shl( L_mult( tmp, 19302 /*0.75f * EVS_PI in Q13*/ ), 2 ) ); /*Q15 */
     341      711421 :     FOR( i = 0; i < len1; i++ )
     342             :     {
     343      709376 :         re = Msub_32_16( complex_buf[2 * i], complex_buf[( ( i * 2 ) + 1 )], tmp );                              /*Qq+1*/
     344      709376 :         im = Madd_32_16( complex_buf[( ( i * 2 ) + 1 )], complex_buf[2 * i], tmp );                              /*Qq+1*/
     345      709376 :         y[2 * i] = L_add( Mult_32_16( re, edct_table[i] ), Mult_32_16( im, edct_table[( len1 - ( 1 + i ) )] ) ); /*Qq+2*/
     346      709376 :         move32();
     347      709376 :         y[( length - ( 1 + ( i * 2 ) ) )] = L_sub( Mult_32_16( im, edct_table[i] ), Mult_32_16( re, edct_table[( len1 - ( 1 + i ) )] ) ); /*Qq+2*/
     348      709376 :         move32();
     349             :     } /*Q(q) */
     350             : 
     351        2045 :     *q = sub( 15 + 2, *q );
     352        2045 :     move16();
     353             : 
     354        2045 :     return;
     355             : }
     356             : /*========================================================================*/
     357             : /* FUNCTION : edct_fx()                                                   */
     358             : /*------------------------------------------------------------------------*/
     359             : /* PURPOSE : DCT transform                                                */
     360             : /*------------------------------------------------------------------------*/
     361             : /* INPUT ARGUMENTS :                                                      */
     362             : /* _ (Word16) length             : length                                 */
     363             : /* _ (Word16*) x                 : input signal Qx                        */
     364             : /* _ (Word16*) edct_table_128_fx : edct table   Q15                       */
     365             : /*------------------------------------------------------------------------*/
     366             : /* INPUT/OUTPUT ARGUMENTS :                                               */
     367             : /*------------------------------------------------------------------------*/
     368             : /* OUTPUT ARGUMENTS :                                                     */
     369             : /* _ (Word16[]) y : output transform      Qx                              */
     370             : /*------------------------------------------------------------------------*/
     371             : 
     372             : /*------------------------------------------------------------------------*/
     373             : /* RETURN ARGUMENTS :                                                     */
     374             : /* _ None                                                                 */
     375             : /*========================================================================*/
     376      215100 : void edct_16fx(
     377             :     const Word16 *x, /* i  : input signal        Qx  */
     378             :     Word16 *y,       /* o  : output transform    Qx  */
     379             :     Word16 length,   /* i  : length  */
     380             :     Word16 bh,       /* bit-headroom */
     381             :     const Word16 element_mode
     382             : 
     383             : )
     384             : {
     385             :     Word16 i;
     386             :     Word16 re[L_FRAME48k / 2];
     387             :     Word16 im[L_FRAME48k / 2];
     388      215100 :     const Word16 *edct_table = NULL;
     389             :     Word16 re2[L_FRAME48k / 2];
     390             :     Word16 im2[L_FRAME48k / 2];
     391             : 
     392             :     Word32 L_tmp, Lacc, Lmax;
     393             :     Word16 tmp, fact;
     394             :     Word16 Q_edct;
     395             :     Word16 Len2, i2;
     396             :     const Word16 *px, *pt;
     397             :     Word16 *py;
     398             :     (void) element_mode;
     399             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     400             :     Flag Overflow;
     401      215100 :     Overflow = 0;
     402      215100 :     move32();
     403             : #endif
     404             :     /*COMPLETE: some eDCT sub function are missing */
     405             : 
     406      215100 :     IF( EQ_16( length, L_FRAME32k ) )
     407             :     {
     408       18626 :         edct_table = &edct_table_320_16fx[0]; /*Q15*/
     409             :     }
     410      196474 :     ELSE IF( EQ_16( length, L_FRAME ) )
     411             :     {
     412      120619 :         edct_table = &edct_table_128_16fx[0]; /*Q15*/
     413             :     }
     414       75855 :     ELSE IF( EQ_16( length, L_FRAME16k ) )
     415             :     {
     416       75855 :         edct_table = &edct_table_160_16fx[0]; /*Q15*/
     417             :     }
     418             :     ELSE
     419             :     {
     420             :     }
     421             : 
     422             :     /* Twiddling and Pre-rotate */
     423      215100 :     Lmax = L_deposit_l( 0 );
     424      215100 :     Len2 = shr( length, 1 );
     425      215100 :     px = x + sub( length, 1 );        /*Qx*/
     426      215100 :     pt = edct_table + sub( Len2, 1 ); /*Q16*/
     427    33751452 :     FOR( i = 0; i < Len2; i++ )
     428             :     {
     429    33536352 :         i2 = shl( i, 1 );
     430    33536352 :         L_tmp = L_mult( x[i2], edct_table[i] ); /*Q(Qx+16) */
     431             : 
     432    33536352 :         Lacc = L_mac( L_tmp, *px, *pt ); /*Q(Qx+16) */
     433             : 
     434    33536352 :         Lmax = L_max( Lmax, Lacc );
     435             : 
     436    33536352 :         L_tmp = L_mult( *px, edct_table[i] ); /*Q(Qx+16) */
     437    33536352 :         Lacc = L_msu( L_tmp, x[i2], *pt );    /*Q(Qx+16) */
     438    33536352 :         Lmax = L_max( Lmax, Lacc );
     439             : 
     440    33536352 :         px -= 2;
     441    33536352 :         pt--;
     442             :     }
     443             : 
     444      215100 :     tmp = 31;
     445      215100 :     move16();
     446      215100 :     if ( Lmax != 0 )
     447             :     {
     448      206798 :         tmp = norm_l( Lmax );
     449             :     }
     450      215100 :     Q_edct = sub( tmp, bh ); /*creating a bit-headroom */
     451             : 
     452      215100 :     px = x + sub( length, 1 );        /*Qx*/
     453      215100 :     pt = edct_table + sub( Len2, 1 ); /*Q15*/
     454    33751452 :     FOR( i = 0; i < Len2; i++ )
     455             :     {
     456    33536352 :         i2 = shl( i, 1 );
     457             : 
     458    33536352 :         L_tmp = L_mult( x[i2], edct_table[i] );                               /*Q(Qx+16) */
     459    33536352 :         Lacc = L_mac_o( L_tmp, *px, *pt, &Overflow );                         /*Q(Qx+16) */
     460    33536352 :         re2[i] = round_fx_o( L_shl_o( Lacc, Q_edct, &Overflow ), &Overflow ); /* Q(Qx+Q_edct) */
     461    33536352 :         move16();
     462    33536352 :         L_tmp = L_mult( *px, edct_table[i] );                                 /*Q(Qx+16) */
     463    33536352 :         Lacc = L_msu_o( L_tmp, x[i2], *pt, &Overflow );                       /*Q(Qx+16) */
     464    33536352 :         im2[i] = round_fx_o( L_shl_o( Lacc, Q_edct, &Overflow ), &Overflow ); /* Q(Qx+Q_edct) */
     465    33536352 :         move16();
     466    33536352 :         px -= 2;
     467    33536352 :         pt--;
     468             :     }
     469      215100 :     IF( EQ_16( length, L_FRAME32k ) )
     470             :     {
     471       18626 :         DoRTFT320_16fx( re2, im2 );
     472             :     }
     473      196474 :     ELSE IF( EQ_16( length, L_FRAME ) )
     474             :     {
     475      120619 :         DoRTFT128_16fx( re2, im2 );
     476             :     }
     477       75855 :     ELSE IF( EQ_16( length, L_FRAME16k ) )
     478             :     {
     479       75855 :         DoRTFT160_16fx( re2, im2 );
     480             :     }
     481             :     ELSE
     482             :     {
     483             :     }
     484      215100 :     tmp = div_s( 1, length );             /*Q15 */
     485      215100 :     L_tmp = L_mult( tmp, 19302 );         /*Q29, (3*PI/4) in Q13 */
     486      215100 :     fact = round_fx( L_shl( L_tmp, 2 ) ); /*Q15 */
     487    33751452 :     FOR( i = 0; i < shr( length, 1 ); i++ )
     488             :     {
     489    33536352 :         tmp = mult_r( im2[i], fact );            /*Q(Qx+Q_edct) */
     490    33536352 :         re[i] = sub_o( re2[i], tmp, &Overflow ); /*Q(Qx+Q_edct) */
     491    33536352 :         move16();
     492             : 
     493    33536352 :         tmp = mult_r( re2[i], fact );            /*Q(Qx+Q_edct) */
     494    33536352 :         im[i] = add_o( im2[i], tmp, &Overflow ); /*Q(Qx+Q_edct) */
     495    33536352 :         move16();
     496             :     }
     497             : 
     498             :     /* Post-rotate and obtain the output data */
     499      215100 :     py = y + sub( length, 1 );        /*Qx*/
     500      215100 :     pt = edct_table + sub( Len2, 1 ); /*Q15*/
     501    33751452 :     FOR( i = 0; i < Len2; i++ )
     502             :     {
     503    33536352 :         i2 = shl( i, 1 );
     504             : 
     505    33536352 :         L_tmp = L_mult( re[i], edct_table[i] );                              /*Q(Qx+Q_edct+16) */
     506    33536352 :         Lacc = L_mac_o( L_tmp, im[i], *pt, &Overflow );                      /*Q(Qx+Q_edct+16) */
     507    33536352 :         y[i2] = round_fx_o( L_shr_o( Lacc, Q_edct, &Overflow ), &Overflow ); /* Q(Qx) */
     508    33536352 :         move16();
     509             : 
     510    33536352 :         L_tmp = L_mult( re[i], edct_table[sub( shr( length, 1 ), add( 1, i ) )] ); /*Q(Qx+Q_edct+16) */
     511    33536352 :         Lacc = L_msu( L_tmp, im[i], edct_table[i] );                               /*Q(Qx+Q_edct+16) */
     512    33536352 :         *py = round_fx_o( L_shr_o( Lacc, Q_edct, &Overflow ), &Overflow );         /* Q(Qx) */
     513    33536352 :         move16();
     514             : 
     515    33536352 :         py -= 2;
     516    33536352 :         pt--;
     517             :     }
     518      215100 :     return;
     519             : }
     520             : 
     521             : 
     522             : /*-----------------------------------------------------------------*
     523             :  * iedct_short_fx()
     524             :  *
     525             :  * Inverse EDCT for short frames
     526             :  *-----------------------------------------------------------------*/
     527             : 
     528        4220 : void iedct_short_fx(
     529             :     const Word32 *in,           /* i  : input vector     Q*/
     530             :     Word16 *Q,                  /* i/o: Q value of input */
     531             :     Word32 *out,                /* o  : output vector    Q*/
     532             :     const Word16 segment_length /* i  : length           Q0*/
     533             : )
     534             : {
     535             :     Word32 alias[MAX_SEGMENT_LENGTH];
     536             :     Word16 seg_len_div2, seg_len_div4, seg_len_3mul_div4;
     537             :     Word16 i;
     538             :     Word16 qtmp, tmp;
     539             : 
     540        4220 :     qtmp = *Q;
     541        4220 :     move16();
     542        4220 :     tmp = 0;
     543        4220 :     move16();
     544        4220 :     seg_len_div2 = shr( segment_length, 1 ); /*Q0*/
     545        4220 :     seg_len_div4 = shr( segment_length, 2 ); /*Q0*/
     546        4220 :     seg_len_3mul_div4 = add( seg_len_div2, seg_len_div4 );
     547             : 
     548        4220 :     edct_fx( in, alias, seg_len_div2, Q );
     549        4220 :     FOR( i = 0; i < seg_len_div2; i++ )
     550             :     {
     551        4220 :         IF( alias[i] != 0 )
     552             :         {
     553        4220 :             tmp = 1;
     554        4220 :             move16();
     555        4220 :             BREAK;
     556             :         }
     557             :     }
     558        4220 :     if ( tmp == 0 )
     559             :     {
     560           0 :         *Q = qtmp;
     561           0 :         move16();
     562             :     }
     563      336860 :     FOR( i = 0; i < seg_len_div4; i++ )
     564             :     {
     565      332640 :         out[i] = alias[( seg_len_div4 + i )]; /*Q*/
     566      332640 :         move32();
     567      332640 :         out[( seg_len_div4 + i )] = L_negate( alias[( ( seg_len_div2 - 1 ) - i )] ); /*Q*/
     568      332640 :         move32();
     569      332640 :         out[( seg_len_div2 + i )] = L_negate( alias[( ( seg_len_div4 - 1 ) - i )] ); /*Q*/
     570      332640 :         move32();
     571      332640 :         out[( seg_len_3mul_div4 + i )] = L_negate( alias[i] ); /*Q*/
     572      332640 :         move32();
     573             :     }
     574             : 
     575        4220 :     return;
     576             : }
     577             : 
     578             : #define FAST_EDXT /* optimized FFT-based DCT/DST algorithm */
     579             : /*-------------------------------------------------------------------------*
     580             :  * edxt_fx()
     581             :  *
     582             :  * DCT/DST-II or III transform (currently also calculates DCT-IV and DST-IV)
     583             :  *-------------------------------------------------------------------------*/
     584             : 
     585        1040 : void edxt_fx(
     586             :     const Word32 *x,          /* i  : input signal        Qx*/
     587             :     Word32 *y,                /* o  : output transform    Qx*/
     588             :     const Word16 length,      /* i  : length              Q0*/
     589             :     const UWord16 kernelType, /* i  : kernel type (0 - 3) Q0*/
     590             :     const UWord16 synthesis   /* i  : nonzero for inverse Q0*/
     591             : )
     592             : {
     593        1040 :     Word16 k, m, fac, hdrm, tmp = 0;
     594             :     const Word16 *cosPtr, *sinPtr;
     595             :     Word16 n;
     596        1040 :     n = 0;
     597        1040 :     move16();
     598        1040 :     move16();
     599        1040 :     cosPtr = NULL;
     600        1040 :     sinPtr = NULL;
     601        1040 :     IF( EQ_16( length, 512 ) )
     602             :     {
     603         262 :         cosPtr = cos_scale_tbl_512; /*Q15*/
     604         262 :         sinPtr = sin_scale_tbl_512; /*Q15*/
     605         262 :         n = 1;
     606         262 :         move16();
     607             :     }
     608         778 :     ELSE IF( EQ_16( length, 256 ) )
     609             :     {
     610           5 :         cosPtr = cos_scale_tbl_512; /*Q15*/
     611           5 :         sinPtr = sin_scale_tbl_512; /*Q15*/
     612           5 :         n = 2;
     613           5 :         move16();
     614             :     }
     615         773 :     ELSE IF( EQ_16( length, 128 ) )
     616             :     {
     617           7 :         cosPtr = cos_scale_tbl_512; /*Q15*/
     618           7 :         sinPtr = sin_scale_tbl_512; /*Q15*/
     619           7 :         n = 4;
     620           7 :         move16();
     621             :     }
     622         766 :     ELSE IF( EQ_16( length, 640 ) )
     623             :     {
     624         184 :         cosPtr = cos_scale_tbl_640; /*Q15*/
     625         184 :         sinPtr = sin_scale_tbl_640; /*Q15*/
     626         184 :         n = 1;
     627         184 :         move16();
     628             :     }
     629         582 :     ELSE IF( EQ_16( length, 320 ) )
     630             :     {
     631         432 :         cosPtr = cos_scale_tbl_640; /*Q15*/
     632         432 :         sinPtr = sin_scale_tbl_640; /*Q15*/
     633         432 :         n = 2;
     634         432 :         move16();
     635             :     }
     636         150 :     ELSE IF( EQ_16( length, 160 ) )
     637             :     {
     638          22 :         cosPtr = cos_scale_tbl_640; /*Q15*/
     639          22 :         sinPtr = sin_scale_tbl_640; /*Q15*/
     640          22 :         n = 4;
     641          22 :         move16();
     642             :     }
     643         128 :     ELSE IF( EQ_16( length, 80 ) )
     644             :     {
     645          22 :         cosPtr = cos_scale_tbl_640; /*Q15*/
     646          22 :         sinPtr = sin_scale_tbl_640; /*Q15*/
     647          22 :         n = 8;
     648          22 :         move16();
     649             :     }
     650         106 :     ELSE IF( EQ_16( length, 40 ) )
     651             :     {
     652           0 :         cosPtr = cos_scale_tbl_640; /*Q15*/
     653           0 :         sinPtr = sin_scale_tbl_640; /*Q15*/
     654           0 :         n = 16;
     655           0 :         move16();
     656             :     }
     657         106 :     ELSE IF( EQ_16( length, 960 ) )
     658             :     {
     659         106 :         cosPtr = cos_scale_tbl_960; /*Q15*/
     660         106 :         sinPtr = sin_scale_tbl_960; /*Q15*/
     661         106 :         n = 1;
     662         106 :         move16();
     663             :     }
     664           0 :     ELSE IF( EQ_16( length, 480 ) )
     665             :     {
     666           0 :         cosPtr = cos_scale_tbl_960; /*Q15*/
     667           0 :         sinPtr = sin_scale_tbl_960; /*Q15*/
     668           0 :         n = 2;
     669           0 :         move16();
     670             :     }
     671           0 :     ELSE IF( EQ_16( length, 240 ) )
     672             :     {
     673           0 :         cosPtr = cos_scale_tbl_960; /*Q15*/
     674           0 :         sinPtr = sin_scale_tbl_960; /*Q15*/
     675           0 :         n = 4;
     676           0 :         move16();
     677             :     }
     678           0 :     ELSE IF( EQ_16( length, 120 ) )
     679             :     {
     680           0 :         cosPtr = cos_scale_tbl_960; /*Q15*/
     681           0 :         sinPtr = sin_scale_tbl_960; /*Q15*/
     682           0 :         n = 8;
     683           0 :         move16();
     684             :     }
     685           0 :     ELSE IF( EQ_16( length, 1200 ) )
     686             :     {
     687           0 :         cosPtr = cos_scale_tbl_1200; /*Q15*/
     688           0 :         sinPtr = sin_scale_tbl_1200; /*Q15*/
     689           0 :         n = 1;
     690           0 :         move16();
     691             :     }
     692           0 :     ELSE IF( EQ_16( length, 800 ) )
     693             :     {
     694           0 :         cosPtr = cos_scale_tbl_800; /*Q15*/
     695           0 :         sinPtr = sin_scale_tbl_800; /*Q15*/
     696           0 :         n = 1;
     697           0 :         move16();
     698             :     }
     699           0 :     ELSE IF( EQ_16( length, 400 ) )
     700             :     {
     701           0 :         cosPtr = cos_scale_tbl_800; /*Q15*/
     702           0 :         sinPtr = sin_scale_tbl_800; /*Q15*/
     703           0 :         n = 2;
     704           0 :         move16();
     705             :     }
     706           0 :     ELSE IF( EQ_16( length, 200 ) )
     707             :     {
     708           0 :         cosPtr = cos_scale_tbl_800; /*Q15*/
     709           0 :         sinPtr = sin_scale_tbl_800; /*Q15*/
     710           0 :         n = 4;
     711           0 :         move16();
     712             :     }
     713             : 
     714             : #ifdef FAST_EDXT
     715        1040 :     test();
     716        1040 :     IF( EQ_16( kernelType, MDST_II ) || EQ_16( kernelType, MDCT_II ) )
     717             :     {
     718        1040 :         const Word16 Nm1 = sub( length, 1 );
     719        1040 :         const Word16 xSign = sub( imult1616( 2, shr( kernelType, 1 ) ), 1 ); /*Q0*/
     720             :         Word32 re[L_FRAME_PLUS];
     721             :         Word32 im[L_FRAME_PLUS];
     722             : 
     723        1040 :         IF( !synthesis )
     724             :         {
     725           0 :             FOR( k = ( Nm1 / 2 ); k >= 0; k-- ) /* pre-modulation of audio input */
     726             :             {
     727           0 :                 re[k] = x[2 * k];                                                            /*Qx*/
     728           0 :                 re[( Nm1 - k )] = Mpy_32_16_1( x[( ( k * 2 ) + 1 )], shl_sat( xSign, 15 ) ); /*Qx*/
     729           0 :                 im[k] = im[( Nm1 - k )] = 0;
     730           0 :                 move32();
     731           0 :                 move32();
     732           0 :                 move32();
     733             :             }
     734             : 
     735           0 :             IF( EQ_16( length, 512 ) )
     736             :             {
     737             :                 /* Scaling down re and im buffers to avoid overflow in DoRTFTn_fx if the minimum headroom is less than 4 bits */
     738           0 :                 hdrm = s_min( L_norm_arr( re, 512 ), L_norm_arr( im, 512 ) );
     739           0 :                 IF( LT_16( hdrm, 4 ) )
     740             :                 {
     741           0 :                     tmp = sub( hdrm, 4 );
     742           0 :                     scale_sig32( re, 512, tmp );
     743           0 :                     scale_sig32( im, 512, tmp );
     744             :                 }
     745             : 
     746           0 :                 DoRTFTn_fx( re, im, 512 );
     747             : 
     748           0 :                 IF( LT_16( hdrm, 4 ) )
     749             :                 {
     750           0 :                     tmp = negate( tmp );
     751           0 :                     scale_sig32( re, 512, tmp );
     752           0 :                     scale_sig32( im, 512, tmp );
     753             :                 }
     754             :             }
     755             :             ELSE /* fft() doesn't support 512 */
     756             :             {
     757           0 :                 fft_fx( re, im, length, 1 );
     758             :             }
     759             : 
     760           0 :             IF( shr( kernelType, 1 ) )
     761             :             {
     762           0 :                 FOR( k = ( Nm1 / 2 ); k > 0; k-- )
     763             :                 {
     764             :                     // const float wRe = cosf( scale * k );
     765             :                     // const float wIm = sinf( scale * k );
     766           0 :                     const Word16 wRe = cosPtr[( k * n )]; /*Q15*/
     767           0 :                     const Word16 wIm = sinPtr[( k * n )]; /*Q15*/
     768             : 
     769           0 :                     y[k] /*pt 1*/ = L_add( Mpy_32_16_1( re[k], wRe ), Mpy_32_16_1( im[k], wIm ) );     /*Qx*/
     770           0 :                     y[( length - k )] = L_sub( Mpy_32_16_1( re[k], wIm ), Mpy_32_16_1( im[k], wRe ) ); /*Qx*/
     771           0 :                     move32();
     772           0 :                     move32();
     773             :                 }
     774           0 :                 y[( length / 2 )] = Mpy_32_16_1( re[( length / 2 )], INV_SQRT_2_Q15 ); /*Qx*/
     775           0 :                 move32();
     776             :             }
     777             :             ELSE /* forw. DST-II */
     778             :             {
     779           0 :                 FOR( k = ( Nm1 / 2 ); k > 0; k-- )
     780             :                 {
     781             :                     // const float wRe = cosf( scale * k );
     782             :                     // const float wIm = sinf( scale * k );
     783           0 :                     const Word16 wRe = cosPtr[( k * n )]; /*Q15*/
     784           0 :                     const Word16 wIm = sinPtr[( k * n )]; /*Q15*/
     785             : 
     786           0 :                     y[( Nm1 - k )] = L_add( Mpy_32_16_1( re[k], wRe ), Mpy_32_16_1( im[k], wIm ) ); /*Qx*/
     787           0 :                     y[k - 1] = L_sub( Mpy_32_16_1( re[k], wIm ), Mpy_32_16_1( im[k], wRe ) );       /*Qx*/
     788           0 :                     move32();
     789           0 :                     move32();
     790             :                 }
     791           0 :                 y[( Nm1 / 2 )] = Mpy_32_16_1( re[( length / 2 )], INV_SQRT_2_Q15 ); /*Qx*/
     792           0 :                 move32();
     793             :             }
     794             : 
     795           0 :             y[( Nm1 - ( Nm1 * ( kernelType / 2 ) ) )] = L_shr( re[0], 1 ); /*Qx*/
     796           0 :             move32();
     797             :         }
     798             :         ELSE /* inverse II = III */
     799             :         {
     800        1040 :             IF( shr( kernelType, 1 ) )
     801             :             {
     802      121152 :                 FOR( k = ( Nm1 / 2 ); k > 0; k-- )
     803             :                 {
     804             :                     // const float wRe = cosf( scale * k ) * 0.5f;
     805             :                     // const float wIm = sinf( scale * k ) * 0.5f;
     806      120638 :                     const Word16 wRe = shr( cosPtr[imult1616( k, n )], 1 );
     807      120638 :                     const Word16 wIm = shr( sinPtr[imult1616( k, n )], 1 );
     808             : 
     809      120638 :                     re[k] = L_add( Mpy_32_16_1( x[k], wRe ), Mpy_32_16_1( x[( length - k )], wIm ) ); /*Qx*/
     810      120638 :                     im[k] = L_sub( Mpy_32_16_1( x[( length - k )], wRe ), Mpy_32_16_1( x[k], wIm ) ); /*Qx*/
     811      120638 :                     move32();
     812      120638 :                     move32();
     813             :                 }
     814         514 :                 re[( length / 2 )] = Mpy_32_16_1( x[( length / 2 )], INV_SQRT_2_Q15 ); /*Qx*/
     815         514 :                 move32();
     816             :             }
     817             :             ELSE /* DST type III */
     818             :             {
     819      128528 :                 FOR( k = ( Nm1 / 2 ); k > 0; k-- )
     820             :                 {
     821             :                     // const float wRe = cosf( scale * k ) * 0.5f;
     822             :                     // const float wIm = sinf( scale * k ) * 0.5f;
     823      128002 :                     const Word16 wRe = shr( cosPtr[( k * n )], 1 ); /*Q15*/
     824      128002 :                     const Word16 wIm = shr( sinPtr[( k * n )], 1 ); /*Q15*/
     825             : 
     826      128002 :                     re[k] = L_add( Mpy_32_16_1( x[( Nm1 - k )], wRe ), Mpy_32_16_1( x[( k - 1 )], wIm ) ); /*Qx*/
     827      128002 :                     im[k] = L_sub( Mpy_32_16_1( x[( k - 1 )], wRe ), Mpy_32_16_1( x[( Nm1 - k )], wIm ) ); /*Qx*/
     828      128002 :                     move32();
     829      128002 :                     move32();
     830             :                 }
     831         526 :                 re[( length / 2 )] = Mpy_32_16_1( x[( Nm1 / 2 )], INV_SQRT_2_Q15 ); /*Qx*/
     832         526 :                 move32();
     833             :             }
     834             : 
     835        1040 :             re[0] = x[( Nm1 - ( Nm1 * ( kernelType / 2 ) ) )]; /*Qx*/
     836        1040 :             im[0] = im[( length / 2 )] = 0;
     837        1040 :             move32();
     838        1040 :             move32();
     839      249680 :             FOR( k = ( Nm1 / 2 ); k > 0; k-- )
     840             :             {
     841      248640 :                 re[( length - k )] = re[k];             /*Qx*/
     842      248640 :                 im[( length - k )] = L_negate( im[k] ); /*Qx*/
     843      248640 :                 move32();
     844      248640 :                 move32();
     845             :             }
     846             : 
     847        1040 :             IF( EQ_16( length, 512 ) )
     848             :             {
     849             :                 /* Scaling down re and im buffers to avoid overflow in DoRTFTn_fx if the minimum headroom is less than 4 bits */
     850         262 :                 hdrm = s_min( L_norm_arr( re, 512 ), L_norm_arr( im, 512 ) );
     851         262 :                 IF( LT_16( hdrm, 4 ) )
     852             :                 {
     853           0 :                     tmp = sub( hdrm, 4 );
     854           0 :                     scale_sig32( re, 512, tmp );
     855           0 :                     scale_sig32( im, 512, tmp );
     856             :                 }
     857             : 
     858         262 :                 DoRTFTn_fx( re, im, 512 );
     859             : 
     860         262 :                 IF( LT_16( hdrm, 4 ) )
     861             :                 {
     862           0 :                     tmp = negate( tmp );
     863           0 :                     scale_sig32( re, 512, tmp );
     864           0 :                     scale_sig32( im, 512, tmp );
     865             :                 }
     866             :             }
     867             :             ELSE /* fft() doesn't support 512 */
     868             :             {
     869         778 :                 fft_fx( re, im, length, 1 );
     870             :             }
     871             : 
     872      250720 :             FOR( k = ( Nm1 / 2 ); k >= 0; k-- ) /* post-modulation of FFT output */
     873             :             {
     874      249680 :                 y[2 * k] = re[k]; /*Qx*/
     875      249680 :                 move32();
     876      249680 :                 IF( xSign != 0 )
     877             :                 {
     878      249680 :                     y[( ( k * 2 ) + 1 )] = Mpy_32_16_1( re[( Nm1 - k )], shl_sat( xSign, 15 ) ); /*Qx*/
     879             :                 }
     880             :                 ELSE
     881             :                 {
     882           0 :                     y[( ( k * 2 ) + 1 )] = 0; /*Qx*/
     883             :                 }
     884      249680 :                 move32();
     885             :             }
     886             :         }
     887             :     }
     888             : #endif
     889             : #ifdef IVAS_FLOAT_FIXED_TO_BE_DONE
     890             :     ELSE
     891             :     /* TODO: below IF and ELSE blocks are unreachable, verified on code coverage report */
     892             :     IF( s_and( kernelType, 1 ) ) /* DST */
     893             :     {
     894             :         const float offK = ( kernelType == MDST_II && synthesis ? 0.5f : 1.0f - 0.5f * ( kernelType >> 1 ) );
     895             :         const float offM = ( kernelType == MDST_II && synthesis ? 1.0f : 0.5f );
     896             : 
     897             :         FOR( k = 0; k < length; k++ )
     898             :         {
     899             :             y[k] = 0.f;
     900             :             FOR( m = 0; m < length; m++ )
     901             :             {
     902             :                 y[k] += x[m] * sinf( pi_len * ( m + offM ) * ( k + offK ) );
     903             :             }
     904             :         }
     905             :         IF( offK == 1.f )
     906             :         {
     907             :             y[length - 1] *= 0.5f; /* scale Nyquist sample */
     908             :         }
     909             :     }
     910             :     ELSE /* kernelType 0, 2: DCT */
     911             :     {
     912             :         const float offK = ( EQ_16( kernelType, MDCT_II ) && synthesis ? 0.5f : 0.5f - shr( shr( kernelType, 1 ), 1 ) );
     913             :         const float offM = ( EQ_16( kernelType, MDCT_II ) && synthesis ? 0.0f : 0.5f );
     914             : 
     915             :         FOR( k = 0; k < length; k++ )
     916             :         {
     917             :             y[k] = 0.f;
     918             :             FOR( m = 0; m < length; m++ )
     919             :             {
     920             :                 y[k] += x[m] * cosf( pi_len * ( m + offM ) * ( k + offK ) );
     921             :             }
     922             :         }
     923             :         IF( offK == 0.f )
     924             :         {
     925             :             y[0] *= 0.5f; /* scale lowest (i.e. DC) sample */
     926             :         }
     927             :     }
     928             : #endif // IVAS_FLOAT_FIXED_TO_BE_DONE
     929             :     /*v_multc(y, (kernelType == MDCT_II ? -1.f : 1.f) * sqrtf(2.f / length), y, length);*/
     930        1040 :     fac = get_edxt_factor( length ); /* Q15 */
     931        1040 :     if ( EQ_16( kernelType, MDCT_II ) )
     932             :     {
     933         514 :         fac = negate( fac );
     934             :     }
     935             : 
     936      500400 :     FOR( m = 0; m < length; m++ )
     937             :     {
     938      499360 :         y[m] = Mpy_32_16_1( y[m], fac ); /*Qx*/
     939      499360 :         move32();
     940             :     }
     941        1040 :     return;
     942             : }

Generated by: LCOV version 1.14