Commit 7969c8cc authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Merge branch 'tcx_mdxt_inv_fxd' into 'main'

Converted TCX_MDXT_inv, TCX_MDST_inv and edxt_fx

See merge request !139
parents 991344dd f3c85617
Loading
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -210,6 +210,7 @@ enum{

#define INV_LOG_2                       1.442695040888963f /* 1/log(2)  */
#define INV_SQRT_2                      0.70710676908493f  /* 1/sqrt(2) */
#define INV_SQRT_2_Q15                  23170  /* 1/sqrt(2) in Q15 */

#define MAX_V_MULT_MAT                  100             /* maximum array length for the function v_mult_mat() */

@@ -2926,6 +2927,7 @@ enum
#define INV_MAX_LT_FX                        (Word16)((1.0f/MAX_LT)*32768)

#define EVS_PI                               3.14159265358979323846264338327950288f
#define EVS_PI_FX                            25736    /* pi in Q13 */

#define LG10                                 24660    /*  10*log10(2)  in Q13 */

+280 −0
Original line number Diff line number Diff line
@@ -14,6 +14,44 @@

#include "math_32.h"

static Word16 get_edxt_factor( Word16 length ) /* Returns value of sqrtf(2.f/length) in Q15 */
{
    Word16 factor = 0; /*Q15*/
    IF( EQ_16( length, 512 ) )
    {
        factor = 2048;
    }
    ELSE IF( EQ_16( length, 256 ) )
    {
        factor = 2896;
    }
    ELSE IF( EQ_16( length, 128 ) )
    {
        factor = 4096;
    }
    ELSE IF( EQ_16( length, 640 ) )
    {
        factor = 1832;
    }
    ELSE IF( EQ_16( length, 320 ) )
    {
        factor = 2590;
    }
    ELSE IF( EQ_16( length, 160 ) )
    {
        factor = 3663;
    }
    ELSE IF( EQ_16( length, 80 ) )
    {
        factor = 5181;
    }
    ELSE IF( EQ_16( length, 960 ) )
    {
        factor = 1496;
    }
    return factor;
}

static Word16 const * get_edct_table(Word16 length, Word16 *q)
{
    Word16 const * edct_table = NULL;
@@ -455,3 +493,245 @@ void iedct_short_fx(

    return;
}

#define FAST_EDXT /* optimized FFT-based DCT/DST algorithm */
/*-------------------------------------------------------------------------*
 * edxt_fx()
 *
 * DCT/DST-II or III transform (currently also calculates DCT-IV and DST-IV)
 *-------------------------------------------------------------------------*/

void edxt_fx(
    const Word32 *x,          /* i  : input signal        */
    Word32 *y,                /* o  : output transform    */
    const Word16 length,      /* i  : length              */
    const UWord16 kernelType, /* i  : kernel type (0 - 3) */
    const UWord16 synthesis   /* i  : nonzero for inverse */
)
{
    Word16 k, m, fac = 0;
    const Word16 *cosPtr = NULL, *sinPtr = NULL;
    Word16 n = 0;

    IF( EQ_16( length, 512 ) )
    {
        cosPtr = cos_scale_tbl_512;
        sinPtr = sin_scale_tbl_512;
        n = 1;
    }
    ELSE IF( EQ_16( length, 256 ) )
    {
        cosPtr = cos_scale_tbl_512;
        sinPtr = sin_scale_tbl_512;
        n = 2;
    }
    ELSE IF( EQ_16( length, 128 ) )
    {
        cosPtr = cos_scale_tbl_512;
        sinPtr = sin_scale_tbl_512;
        n = 4;
    }
    ELSE IF( EQ_16( length, 640 ) )
    {
        cosPtr = cos_scale_tbl_640;
        sinPtr = sin_scale_tbl_640;
        n = 1;
    }
    ELSE IF( EQ_16( length, 320 ) )
    {
        cosPtr = cos_scale_tbl_640;
        sinPtr = sin_scale_tbl_640;
        n = 2;
    }
    ELSE IF( EQ_16( length, 160 ) )
    {
        cosPtr = cos_scale_tbl_640;
        sinPtr = sin_scale_tbl_640;
        n = 4;
    }
    ELSE IF( EQ_16( length, 80 ) )
    {
        cosPtr = cos_scale_tbl_640;
        sinPtr = sin_scale_tbl_640;
        n = 8;
    }
    ELSE IF( EQ_16( length, 960 ) )
    {
        cosPtr = cos_scale_tbl_960;
        sinPtr = sin_scale_tbl_960;
        n = 1;
    }

#ifdef FAST_EDXT
    IF( EQ_16( kernelType, MDST_II ) || EQ_16( kernelType, MDCT_II ) )
    {
        const Word16 Nm1 = sub( length, 1 );
        const Word16 xSign = sub( kernelType, 1 );
        Word32 re[L_FRAME_PLUS];
        Word32 im[L_FRAME_PLUS];

        IF( !synthesis )
        {
            FOR( k = shr( Nm1, 1 ); k >= 0; k-- ) /* pre-modulation of audio input */
            {
                re[k] = x[2 * k];
                re[Nm1 - k] = Mpy_32_16_1( x[2 * k + 1], xSign );
                im[k] = im[Nm1 - k] = 0;
            }

            IF( EQ_16( length, 512 ) )
            {
                DoRTFTn_fx( re, im, 512 );
            }
            ELSE /* fft() doesn't support 512 */
            {
                fft_fx( re, im, length, 1 );
            }

            IF( shr( kernelType, 1 ) )
            {
                FOR( k = shr( Nm1, 1 ); k > 0; k-- )
                {
                    // const float wRe = cosf( scale * k );
                    // const float wIm = sinf( scale * k );
                    const Word16 wRe = cosPtr[k * n];
                    const Word16 wIm = sinPtr[k * n];

                    y[k] /*pt 1*/ = L_add( Mpy_32_16_1( re[k], wRe ), Mpy_32_16_1( im[k], wIm ) );
                    y[length - k] = L_sub( Mpy_32_16_1( re[k], wIm ), Mpy_32_16_1( im[k], wRe ) );
                }
                y[shr( length, 1 )] = Mpy_32_16_1( re[shr( length, 1 )], INV_SQRT_2_Q15 );
            }
            ELSE /* forw. DST-II */
            {
                FOR( k = shr( Nm1, 1 ); k > 0; k-- )
                {
                    // const float wRe = cosf( scale * k );
                    // const float wIm = sinf( scale * k );
                    const Word16 wRe = cosPtr[k * n];
                    const Word16 wIm = sinPtr[k * n];

                    y[Nm1 - k] = L_add( Mpy_32_16_1( re[k], wRe ), Mpy_32_16_1( im[k], wIm ) );
                    y[k - 1] = L_sub( Mpy_32_16_1( re[k], wIm ), Mpy_32_16_1( im[k], wRe ) );
                }
                y[shr( Nm1, 1 )] = Mpy_32_16_1( re[shr( length, 1 )], INV_SQRT_2_Q15 );
            }

            y[Nm1 - Nm1 * (kernelType >> 1)] = L_shr( re[0], 1 );
        }
        ELSE /* inverse II = III */
        {
            IF( shr( kernelType, 1 ) )
            {
                FOR( k = shr( Nm1, 1 ); k > 0; k-- )
                {
                    // const float wRe = cosf( scale * k ) * 0.5f;
                    // const float wIm = sinf( scale * k ) * 0.5f;
                    const Word16 wRe = shr( cosPtr[k * n], 1 );
                    const Word16 wIm = shr( sinPtr[k * n], 1 );

                    re[k] = L_add( Mpy_32_16_1( x[k], wRe ), Mpy_32_16_1( x[length - k], wIm ) );
                    im[k] = L_sub( Mpy_32_16_1( x[length - k], wRe ), Mpy_32_16_1( x[k], wIm ) );
                }
                re[shr( length, 1 )] = Mpy_32_16_1(x[shr( length, 1 )], INV_SQRT_2_Q15);
            }
            ELSE /* DST type III */
            {
                FOR( k = shr( Nm1, 1 ); k > 0; k-- )
                {
                    // const float wRe = cosf( scale * k ) * 0.5f;
                    // const float wIm = sinf( scale * k ) * 0.5f;
                    const Word16 wRe = shr( cosPtr[k * n], 1 );
                    const Word16 wIm = shr( sinPtr[k * n], 1 );

                    re[k] = L_add( Mpy_32_16_1( x[Nm1 - k], wRe ), Mpy_32_16_1( x[k - 1], wIm ) );
                    im[k] = L_sub( Mpy_32_16_1( x[k - 1], wRe ), Mpy_32_16_1( x[Nm1 - k], wIm ) );
                }
                re[shr( length, 1 )] = Mpy_32_16_1(x[shr( Nm1, 1 )], INV_SQRT_2_Q15);
            }

            re[0] = x[Nm1 - Nm1 * shr(kernelType, 1)];
            im[0] = im[shr( length, 1 )] = 0;
            FOR( k = shr( Nm1, 1 ); k > 0; k-- )
            {
                re[length - k] = re[k];
                im[length - k] = L_negate( im[k] );
            }

            IF( EQ_16( length, 512 ) )
            {
                DoRTFTn_fx( re, im, 512 );
            }
            ELSE /* fft() doesn't support 512 */
            {
                fft_fx( re, im, length, 1 );
            }

            FOR( k = shr( Nm1, 1 ); k >= 0; k-- ) /* post-modulation of FFT output */
            {
                y[2 * k] = re[k];
                IF( NE_16( xSign, 0 ) )
                {
                    y[2 * k + 1] = re[sub( Nm1, k )];
                }
                ELSE
                {
                    y[2 * k + 1] = 0;
                }
            }
        }
    }
#endif
#ifdef IVAS_FLOAT_FIXED_TO_BE_DONE
    ELSE
      /* TODO: below IF and ELSE blocks are unreachable, verified on code coverage report */
    IF( s_and( kernelType, 1 ) ) /* DST */
    {
        const float offK = (kernelType == MDST_II && synthesis ? 0.5f : 1.0f - 0.5f * (kernelType >> 1));
        const float offM = (kernelType == MDST_II && synthesis ? 1.0f : 0.5f);

        FOR( k = 0; k < length; k++ )
        {
            y[k] = 0.f;
            FOR( m = 0; m < length; m++ )
            {
                y[k] += x[m] * sinf( pi_len * ( m + offM ) * ( k + offK ) );
            }
        }
        IF( offK == 1.f )
        {
            y[length - 1] *= 0.5f; /* scale Nyquist sample */
        }
    }
    ELSE /* kernelType 0, 2: DCT */
    {
        const float offK = ( EQ_16( kernelType, MDCT_II ) && synthesis ? 0.5f : 0.5f - shr( shr( kernelType, 1 ), 1 ) );
        const float offM = ( EQ_16( kernelType, MDCT_II ) && synthesis ? 0.0f : 0.5f );

        FOR( k = 0; k < length; k++ )
        {
            y[k] = 0.f;
            FOR( m = 0; m < length; m++ )
            {
                y[k] += x[m] * cosf( pi_len * ( m + offM ) * ( k + offK ) );
            }
        }
        IF( offK == 0.f )
        {
            y[0] *= 0.5f; /* scale lowest (i.e. DC) sample */
        }
    }
#endif //IVAS_FLOAT_FIXED_TO_BE_DONE
    /*v_multc(y, (kernelType == MDCT_II ? -1.f : 1.f) * sqrtf(2.f / length), y, length);*/
    fac = get_edxt_factor( length ); /* Q15 */
    IF( EQ_16( kernelType, MDCT_II ) )
    {
        fac = negate( fac );
    }

    FOR( m = 0; m < length; m++ )
    {
        y[m] = Mpy_32_16_1( y[m], fac );
    }
    return;
}
+26 −0
Original line number Diff line number Diff line
@@ -3816,6 +3816,24 @@ void TCX_MDCT_Inverse(
  const  Word16 r,
  const  Word16 element_mode
);

void TCX_MDST_Inverse_fx(
    Word32 *x,
    Word16 x_e,
    Word16 *y,
    const Word16 l,
    const Word16 m,
    const Word16 r );

void TCX_MDXT_Inverse_fx(
    const Word32 *x,
    Word16 x_e,
    Word16 *y,
    const Word16 l,
    const Word16 m,
    const Word16 r,
    const UWord16 kernel_type );

//edct_fx.c
#define EDCT_FACTOR_SCALE 2
void edct_fx(
@@ -3847,6 +3865,14 @@ void iedct_short_fx(
  const Word16 segment_length     /* i  : length              */
);

void edxt_fx(
    const Word32 *x,          /* i  : input signal        */
    Word32 *y,                /* o  : output transform    */
    const Word16 length,      /* i  : length              */
    const UWord16 kernelType, /* i  : kernel type (0 - 3) */
    const UWord16 synthesis   /* i  : nonzero for inverse */
);

//fft_evs.c
void fft16(Word32 *re, Word32 *im, Word16 s, Word16 bScale);
void BASOP_cfft(cmplx *pComplexBuf, Word16 sizeOfFft, Word16 *scale, Word32 workBuffer[2 * BASOP_CFFT_MAX_LENGTH]);
+873 −0

File changed.

Preview size limit exceeded, changes collapsed.

+8 −0
Original line number Diff line number Diff line
@@ -2116,4 +2116,12 @@ extern const Word32 tbl_two_pow_shift_by_4[35]; /* Q30 */
extern const Word16 ivas_tan_panning_gain_tbl_fx[601];
extern const Word16 ivas_sine_panning_tbl_fx[601];
extern const Word16 ivas_sin_az_fx[361];

//edct_fx.c
extern const Word16 sin_scale_tbl_960[960];
extern const Word16 cos_scale_tbl_960[960];
extern const Word16 cos_scale_tbl_640[640];
extern const Word16 sin_scale_tbl_640[640];
extern const Word16 sin_scale_tbl_512[512];
extern const Word16 cos_scale_tbl_512[512];
#endif
Loading