Commit 879152dc authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

qmetadata file functions and subfuncs converted

[x] qmetadata functions and related subfunctions converted to fixed.
[x] Few functions are commented as some math functions changes are in progress.

Testing:
[x] With "ivas-codec-20231128_Update_Ittiam" as reference, prepare_pytest and run_pytest run through.
[x] The pytest results show as "242 failed, 334 passed, 373 skipped, 13 warnings, 84 errors".
For all the failed cases that were generated in param_file for DUT, MLD test was run through
after extracting mono channels from the files and resampled to 48000. The maximum loudness
difference was observed to be < 3 for all the failed cases.
parent 7aecf813
Loading
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1131,9 +1131,17 @@ enum

#define MASA_TRANSP_BITS                        1
#define NO_BITS_MASA_ISM_NO_OBJ                 2
#ifdef IVAS_FLOAT_FIXED
#define MASA2TOTAL_THR                          0.979965f // Temporary
//Maximum error in float to fixed conversion : 0.005%
//Assuming the accuracy of 99.995%
//New value = 99.995 / 100 * 0.98 = 0.979951
#else
#define MASA2TOTAL_THR                          0.98f
#endif
#define BITS_MASA2TOTTAL_DCT0                   6
#define STEP_M2T                                0.1f
#define STEP_M2T_FX                             214748364
#define MASA_HEADER_BITS                        2
#define MASA_SUBFRAME_BITS                      1
#define MASA_LOWBITRATE_MODE_BITS               1
+223 −15
Original line number Diff line number Diff line
@@ -48,6 +48,9 @@

static uint16_t deindex_sph_idx_general( const int16_t idx_sph, const int16_t no_bits, float *theta_dec, float *phi_dec, uint16_t *p_id_phi, const MC_LS_SETUP mc_format );

#ifdef IVAS_FLOAT_FIXED
static UWord16 deindex_sph_idx_general_fx( const Word16 idx_sph, const Word16 no_bits, Word32 *theta_dec_fx, Word32 *phi_dec_fx, UWord16 *p_id_phi, const MC_LS_SETUP mc_format );
#endif

/*-------------------------------------------------------------------------
 * ivas_get_hodirac_flag()
@@ -162,10 +165,8 @@ ivas_error ivas_dirac_config(
    hConfig->dec_param_estim = FALSE;
    if ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) /* skip for MASA decoder */
    {
        if ( ( error = ivas_dirac_sba_config( hQMetaData, element_mode, ivas_total_brate, sba_order, hConfig->nbands - spar_dirac_split_band
                                              ,
                                              ivas_format
                                              ) ) != IVAS_ERR_OK )
        if ( ( error = ivas_dirac_sba_config( hQMetaData, element_mode, ivas_total_brate, sba_order, hConfig->nbands - spar_dirac_split_band,
                                              ivas_format ) ) != IVAS_ERR_OK )
        {
            return error;
        }
@@ -322,10 +323,8 @@ void ivas_get_dirac_sba_max_md_bits(
    int16_t *bits_frame_nominal,
    int16_t *metadata_max_bits,
    int16_t *qmetadata_max_bit_req,
    const int16_t nbands
    ,
    IVAS_FORMAT ivas_format
)
    const int16_t nbands,
    IVAS_FORMAT ivas_format )
{
    if ( sba_total_brate <= IVAS_13k2 )
    {
@@ -402,8 +401,7 @@ ivas_error ivas_dirac_sba_config(
    const int16_t sba_order,          /* i  : Ambisonic (SBA) order                                */
    const int16_t nbands              /* i  : number of frequency bands                            */
    ,
    IVAS_FORMAT ivas_format
)
    IVAS_FORMAT ivas_format )
{
    int16_t nbands_coded;
    int16_t hodirac_flag;
@@ -465,10 +463,8 @@ ivas_error ivas_dirac_sba_config(
        }
    }

    ivas_get_dirac_sba_max_md_bits( sba_total_brate, &hQMetaData->bits_frame_nominal, &hQMetaData->metadata_max_bits, &hQMetaData->qmetadata_max_bit_req, hQMetaData->q_direction[0].cfg.nbands
                                    ,
                                    ivas_format
    );
    ivas_get_dirac_sba_max_md_bits( sba_total_brate, &hQMetaData->bits_frame_nominal, &hQMetaData->metadata_max_bits, &hQMetaData->qmetadata_max_bit_req, hQMetaData->q_direction[0].cfg.nbands,
                                    ivas_format );

    return error;
}
@@ -648,10 +644,60 @@ float deindex_azimuth(
    {
        phi_hat = companding_azimuth( phi_hat, mc_format, ( id_th * delta_theta_masa[no_bits - 3] > MC_MASA_THR_ELEVATION ), -1 );
    }

    return phi_hat;
}

#ifdef IVAS_FLOAT_FIXED
Word32 deindex_azimuth_fx(
    Word16 id_phi,              /* i  : index                                   */
    const Word16 no_bits,       /* i  : number of bits for the spherical grid   */
    const Word16 id_th,         /* i  : elevation index                         */
    const Word16 remap,         /* i  : remapping flag                          */
    const MC_LS_SETUP mc_format /* i  : channel format if in MC-mode            */
)
{
    Word16 flag_delta;
    Word32 dd_fx, delta_phi_fx;
    Word32 phi_hat_fx;
    IF( ( mc_format != MC_LS_SETUP_INVALID ) && ( no_bits == 2 ) )
    {
        IF( id_phi % 2 == 0 )
        {
            phi_hat_fx = cb_azi_chan_fx[id_phi / 2];
        }
        ELSE
        {
            phi_hat_fx = -cb_azi_chan_fx[( id_phi + 1 ) / 2];
        }
        return phi_hat_fx;
    }
    flag_delta = ( id_th % 2 == 1 );

    IF( remap )
    {
        id_phi = ivas_qmetadata_dereorder_generic( id_phi ) + ( no_phi_masa[no_bits - 1][id_th] >> 1 );
    }

    delta_phi_fx = Mpy_32_32( 1509949440, no_phi_masa_inv_fx[no_bits - 1][id_th] ); // q = 22
    IF( ( flag_delta == 1 ) && ( no_phi_masa[no_bits - 1][id_th] > 2 ) && mc_format == MC_LS_SETUP_INVALID )
    {
        dd_fx = Mpy_32_32( delta_phi_fx, 1073741824 ); // q = 22
    }
    ELSE
    {
        dd_fx = 0;
    }

    id_phi -= ( ( no_phi_masa[no_bits - 1][id_th] ) >> 1 );
    phi_hat_fx = L_add( id_phi * delta_phi_fx, dd_fx );
    IF( mc_format != MC_LS_SETUP_INVALID )
    {
        phi_hat_fx = companding_azimuth_fx( phi_hat_fx, mc_format, ( id_th * delta_theta_masa[no_bits - 3] > MC_MASA_THR_ELEVATION ), -1 );
    }
    return phi_hat_fx;
}
#endif


/*----------------------------------------------------------------
 * deindex_spherical_component()
@@ -698,6 +744,50 @@ void deindex_spherical_component(
    return;
}

#ifdef IVAS_FLOAT_FIXED
void deindex_spherical_component_fx(
    const UWord16 sph_idx,      /* i  : spherical index                         */
    Word32 *az_fx,              /* o  : decoded azimuth value                   */
    Word32 *el_fx,              /* o  : decoded elevation value                 */
    UWord16 *az_idx,            /* o  : azimuth index                           */
    UWord16 *el_idx,            /* o  : elevation index                         */
    const UWord16 no_bits,      /* i  : number of bits for the spherical grid   */
    const MC_LS_SETUP mc_format /* i  : channel format if in MC-mode            */
)
{
    Word32 az_idx_fx;
    Word16 q_az_idx;
    assert( sph_idx < ( 1 << no_bits ) );
    SWITCH( no_bits )
    {
        case 0:
            *az_fx = 0;
            *el_fx = 0;
            *az_idx = 0;
            *el_idx = 0;
            BREAK;
        case 1:
            *az_idx = sph_idx;
            q_az_idx = norm_l( *az_idx );
            az_idx_fx = L_shl( *az_idx, q_az_idx );
            *az_fx = L_shl( Mpy_32_32( az_idx_fx, L_shl( -180, 22 ) ), 31 - q_az_idx );
            *el_fx = 0;
            *el_idx = 0;
            BREAK;
        case 2:
            *el_fx = 0;
            *el_idx = 0;
            *az_idx = sph_idx;
            *az_fx = deindex_azimuth_fx( *az_idx, no_bits, 0, 0, mc_format );
            BREAK;
        default:
            *el_idx = deindex_sph_idx_general_fx( sph_idx, no_bits, el_fx, az_fx, az_idx, mc_format );
            BREAK;
    }

    return;
}
#endif

/*----------------------------------------------------------------
 * calculate_hodirac_sector_parameters()
@@ -1022,3 +1112,121 @@ static uint16_t deindex_sph_idx_general(

    return id_th;
}

#ifdef IVAS_FLOAT_FIXED
static UWord16 deindex_sph_idx_general_fx(
    const Word16 idx_sph,       /* i  : spherical index                     */
    const Word16 no_bits,       /* i  : number of bits in the spherical grid*/
    Word32 *theta_dec_fx,       /* o  : decoded elevation value             */
    Word32 *phi_dec_fx,         /* o  : decoded azimuth value               */
    UWord16 *p_id_phi,          /* o  : decoded azimuth index               */
    const MC_LS_SETUP mc_format /* i  : channel format if in MC-mode        */
)
{
    Word16 i;
    UWord16 id_th;
    Word16 q_id_th;
    Word32 id_th_fx;
    Word16 sign_theta;
    Word16 id_phi;
    Word16 cum_n[250];
    Word16 no_th;
    const Word16 *n;

    id_th = 0;
    id_phi = 0;
    sign_theta = 1;

    no_th = no_theta_masa[no_bits - 3];
    n = no_phi_masa[no_bits - 1];
    IF( mc_format != MC_LS_SETUP_INVALID )
    {
        /* indexing */

        cum_n[0] = n[0];
        IF( idx_sph >= cum_n[0] )
        {
            FOR( i = 1; i < no_th; i++ )
            {
                cum_n[i] = cum_n[i - 1] + n[i];
                IF( idx_sph < cum_n[i] )
                {
                    id_th = i;
                    id_phi = idx_sph - cum_n[i - 1];
                    BREAK;
                }
            }
        }
    }
    ELSE
    {
        /* Starting from Equator, alternating positive and negative */
        cum_n[0] = n[0];
        IF( idx_sph >= cum_n[0] )
        {
            FOR( i = 1; i < no_th; i++ )
            {
                cum_n[2 * i - 1] = cum_n[2 * i - 2] + n[i];

                IF( idx_sph < cum_n[2 * i - 1] )
                {
                    id_th = i;
                    sign_theta = 1;
                    id_phi = idx_sph - cum_n[2 * i - 2];
                    BREAK;
                }

                cum_n[2 * i] = cum_n[2 * i - 1] + n[i];

                IF( idx_sph < cum_n[2 * i] )
                {
                    id_th = i;
                    sign_theta = -1;
                    id_phi = idx_sph - cum_n[2 * i - 1];
                    BREAK;
                }

                IF( i == ( no_th - 1 ) )
                {
                    id_th = i;
                    sign_theta = -1;
                    id_phi = 0; /* idx_sph - cum_n[2*i-1]; */
                    BREAK;
                }
            }
        }
    }

    IF( id_th == 0 )
    {
        id_phi = idx_sph;
    }
    ELSE
    {
        IF( ( id_th == no_th - 1 ) && ( no_bits > 4 ) )
        {
            id_phi = 0;
        }
    }

    q_id_th = norm_l( id_th );
    id_th_fx = L_shl( id_th, q_id_th );
    *theta_dec_fx = L_shl( Mpy_32_32( id_th_fx, delta_theta_masa_fx[no_bits - 3] ), 31 - q_id_th );

    IF( *theta_dec_fx >= L_shl( 90, 22 ) )
    {
        *theta_dec_fx = L_shl( 90, 22 ) * sign_theta;
        *phi_dec_fx = 0;
        *p_id_phi = 0;
    }
    ELSE
    {
        *theta_dec_fx *= sign_theta;

        *phi_dec_fx = deindex_azimuth_fx( id_phi, no_bits, id_th, 0, mc_format );
        *p_id_phi = id_phi;
    }

    return id_th;
}
#endif
 No newline at end of file
+146 −0
Original line number Diff line number Diff line
@@ -791,6 +791,152 @@ void deindex_sph_idx(
    return;
}

#ifdef IVAS_FLOAT_FIXED
// void deindex_sph_idx(
//     const UWord16 sphIndex,             /* i  : Spherical index            */
//     const SPHERICAL_GRID_DATA *gridData, /* i  : Prepared spherical grid    */
//     Word32 *theta_fx,                        /* o  : Elevation                  */
//     Word32 *phi_fx                           /* o  : Azimuth                    */
//)
//{
//     Word32 ba_crt_fx, del_crt_fx, div_crt_fx, a4_crt_fx;
//     Word32 estim;
//     Word32 base_low, base_up;
//     Word16 n_crt;
//     Word16 id_th;
//     Word16 sign_theta;
//     Word16 id_phi;
//     Word16 no_th = gridData->no_theta;
//     const Word16 *n = gridData->no_phi;
//	const Word32 ba_fx[3] = { 109465, 63736, 62894 }; // q = 9
//	const Word32 del_fx[3] = { 409511008, 666052608, 729124992 }; // q = 9
//	const Word32 div_fx[3] = { -121, -51, -47 }; // q = 9
//	const Word32 a4_fx[3] = { -4308, -10144, -11124 }; // q = 9
//     const UWord16 limit_index1 = 64964, limit_index2 = 47870;
//
//     if ( sphIndex >= limit_index1 )
//     {
//         ba_crt_fx = ba_fx[2];
//         div_crt_fx = div_fx[2];
//         a4_crt_fx = a4_fx[2];
//         del_crt_fx = del_fx[2];
//     }
//     else if ( sphIndex >= limit_index2 )
//     {
//         ba_crt_fx = ba_fx[1];
//         div_crt_fx = div_fx[1];
//         a4_crt_fx = a4_fx[1];
//         del_crt_fx = del_fx[1];
//     }
//     else
//     {
//         ba_crt_fx = ba_fx[0];
//         div_crt_fx = div_fx[0];
//         a4_crt_fx = a4_fx[0];
//         del_crt_fx = del_fx[0];
//     }
//     estim = ba_crt_fx + div_crt_fx * sqrtf( del_crt + a4_crt * sphIndex );
//
//     if ( estim > MASA_NO_CIRCLES )
//     {
//         estim = MASA_NO_CIRCLES;
//     }
//
//     assert( estim > 0 );
//     id_th = (int16_t) roundf( estim ) - 1;
//     if ( id_th < 0 )
//     {
//         id_th = 0;
//     }
//
//     if ( id_th == 0 )
//     {
//         base_low = 0;
//         base_up = n[0];
//     }
//     else
//     {
//         estim = MASA_ANGLE_AT_EQUATOR * (float) ( id_th - 0.5f );
//         base_low = n[0];
//         if ( id_th >= 2 )
//         {
//             if ( id_th == 2 )
//             {
//                 base_low += 2 * (int16_t) ceilf( MASA_NTOT2_FAC * ( sinf( estim ) - MASA_ASIN_OFFSET ) );
//             }
//             else
//             {
//                 base_low += 2 * (int16_t) roundf( MASA_NTOT2_FAC * ( sinf( estim ) - MASA_ASIN_OFFSET ) );
//             }
//         }
//         base_up = base_low + 2 * n[id_th];
//     }
//
//     sign_theta = 1;
//
//     n_crt = n[id_th];
//     if ( sphIndex < base_low )
//     {
//         id_th--;
//         n_crt = n[id_th];
//         if ( id_th == 0 )
//         {
//             base_low = 0;
//             base_up = n_crt;
//         }
//         else
//         {
//             base_up = base_low;
//             base_low -= 2 * n[id_th];
//         }
//         assert( sphIndex >= base_low );
//     }
//     else if ( sphIndex >= base_up )
//     {
//         id_th++;
//         n_crt = n[id_th];
//         base_low = base_up;
//         base_up += 2 * n_crt;
//         assert( sphIndex < base_up );
//     }
//
//     id_phi = (int16_t) ( sphIndex - base_low );
//     if ( sphIndex - base_low >= n_crt )
//     {
//         id_phi -= n_crt;
//         sign_theta = -1;
//     }
//
//     if ( id_th == 0 )
//     {
//         *theta = 0.f;
//         *phi = (float) sphIndex * 360 / (float) n_crt - 180;
//     }
//     else
//     {
//         if ( id_th == no_th - 1 )
//         {
//             id_phi = 0;
//             *phi = -180;
//             *theta = 90 * (float) sign_theta;
//         }
//         else
//         {
//             *theta = id_th * MASA_ANGLE_AT_EQUATOR_DEG * (float) sign_theta;
//             if ( id_th % 2 == 0 )
//             {
//                 *phi = (float) id_phi * 360 / (float) n_crt - 180;
//             }
//             else
//             {
//                 *phi = ( (float) id_phi + 0.5f ) * 360 / (float) n_crt - 180;
//             }
//         }
//     }
//
//     return;
// }
#endif

/*---------------------------------------------------------------
 * valid_ratio_index()
+83 −0
Original line number Diff line number Diff line
@@ -745,6 +745,12 @@ int16_t get_igf_startline(
float rand_triangular_signed(
    int16_t *seed );

Word64 var_32_fx(
	const Word32 *x,   /* i  : input vector                          */
	const int16_t len, /* i  : length of inputvector                 */
	Word16 q		   /* q	 : q-factor for the array				 */
);

void dtx_read_padding_bits(
    DEC_CORE_HANDLE st,
    const int16_t num_bits 
@@ -3292,6 +3298,15 @@ float companding_azimuth(
    const int16_t direction                                     /* i  : direction of companding (direct or inverse)*/
);

#ifdef IVAS_FLOAT_FIXED
Word32 companding_azimuth_fx(
    const Word32 azi_fx,                                            /* i  : input azimuth value                        */
    const MC_LS_SETUP mc_format,                                /* i  : input channel format                       */
    const Word16 theta_flag,                                   /* i  : zero/non zero elevation flag               */
    const Word16 direction                                     /* i  : direction of companding (direct or inverse)*/
);
#endif

/*! r: index azimuth */
int16_t quantize_phi_chan_lbr(
    const float phi,                                            /* i  : azimuth value                           */
@@ -3338,6 +3353,14 @@ float deindex_elevation(
    const MC_LS_SETUP mc_format                                 /* i  : channel format if in MC-mode            */
);

#ifdef IVAS_FLOAT_FIXED
Word32 deindex_elevation_fx(
    UWord16 *id_th,                                            /* i  : input index                             */
    const Word16 no_bits,                                      /* i  : number of bits for the spherical grid   */
    const MC_LS_SETUP mc_format                                 /* i  : channel format if in MC-mode            */
);
#endif

float deindex_azimuth(
    int16_t id_phi,                                             /* i  : index                                   */
    const int16_t no_bits,                                      /* i  : number of bits for the spherical grid   */
@@ -3346,6 +3369,25 @@ float deindex_azimuth(
    const MC_LS_SETUP mc_format                                 /* i  : channel format if in MC-mode            */
);

#ifdef IVAS_FLOAT_FIXED
Word32 deindex_azimuth_fx(
    Word16 id_phi,                                             /* i  : index                                   */
    const Word16 no_bits,                                      /* i  : number of bits for the spherical grid   */
    const Word16 id_th,                                        /* i  : elevation index                         */
    const Word16 remap,                                        /* i  : remapping flag                          */
    const MC_LS_SETUP mc_format                                 /* i  : channel format if in MC-mode            */
);
void deindex_spherical_component_fx(
    const UWord16 sph_idx,                                     /* i  : spherical index                         */
    Word32 *az_fx,                                                  /* o  : decoded azimuth value                   */
    Word32 *el_fx,                                                  /* o  : decoded elevation value                 */
    UWord16 *az_idx,                                           /* o  : azimuth index                           */
    UWord16 *el_idx,                                           /* o  : elevation index                         */
    const UWord16 no_bits,                                     /* i  : number of bits for the spherical grid   */
    const MC_LS_SETUP mc_format                                 /* i  : channel format if in MC-mode            */
);
#endif

void deindex_spherical_component(
    const uint16_t sph_idx,                                     /* i  : spherical index                         */
    float *az,                                                  /* o  : decoded azimuth value                   */
@@ -3871,6 +3913,20 @@ int16_t matrix_product(
    float *Z                                                    /* o  : resulting matrix after the matrix multiplication                                       */
);

#ifdef IVAS_FLOAT_FIXED
Word16 matrix_product_fx(
    const Word32 *X_fx,                                             /* i  : left hand matrix                                                                       */
    const Word16 rowsX,                                        /* i  : number of rows of the left hand matrix                                                 */
    const Word16 colsX,                                        /* i  : number of columns of the left hand matrix                                              */
    const Word16 transpX,                                      /* i  : flag indicating the transposition of the left hand matrix prior to the multiplication  */
    const Word32 *Y_fx,                                             /* i  : right hand matrix                                                                      */
    const Word16 rowsY,                                        /* i  : number of rows of the right hand matrix                                                */
    const Word16 colsY,                                        /* i  : number of columns of the right hand matrix                                             */
    const Word16 transpY,                                      /* i  : flag indicating the transposition of the right hand matrix prior to the multiplication */
    Word32 *Z_fx                                                    /* o  : resulting matrix after the matrix multiplication                                       */
);
#endif

void mat2svdMat(
    const float *mat,                                           /* i  : matrix as column ordered vector */
    float svdMat[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS],     /* o  : matrix as two-dimensional arry  */
@@ -4966,12 +5022,21 @@ void distribute_evenly_ism(
    const int16_t nchan_ism
);

#ifdef IVAS_FLOAT_FIXED
Word16 ivas_qmetadata_DecodeExtendedGR(
    UWord16* bitstream,
    Word16* index,
    const Word16 alph_size,
    const Word16 gr_param
);
#else
int16_t ivas_qmetadata_DecodeExtendedGR(
    uint16_t* bitstream,
    int16_t* index,
    const int16_t alph_size,
    const int16_t gr_param
);
#endif

int16_t ivas_qmetadata_encode_extended_gr_length(
    const uint16_t value,
@@ -5081,6 +5146,14 @@ void invdct4_transform(
    uint8_t *invdct_v                                           /* o  : transformed vector                              */
);

#ifdef IVAS_FLOAT_FIXED
void invdct4_transform_fx(
    Word32 *v_fx,                                                   /* i  : input vector                                    */
    UWord8 *invdct_v,                                           /* o  : transformed vector                              */
	Word16 q
);
#endif

void update_bits_next_block(
    IVAS_QDIRECTION *q_direction,                               /* i/o: qdirection                                      */
    int16_t *p_diff,                                            /* i/o: bits to be transferred                          */
@@ -5752,6 +5825,16 @@ void ivas_omasa_decode_masa_to_total(
    const int16_t nblocks
);

#ifdef IVAS_FLOAT_FIXED
void ivas_omasa_decode_masa_to_total_fx(
	UWord16 *bit_stream,
	Word16 *index,
	Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
	const Word16 nbands,
	const Word16 nblocks,
	Word16 *q);
#endif

void ivas_omasa_modify_masa_energy_ratios(
    IVAS_QMETADATA_HANDLE hQMetaData,                           /* i/o: q_metadata handle                       */
    float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_MAXIMUM_CODING_SUBBANDS]
+38 −0
Original line number Diff line number Diff line
@@ -486,6 +486,44 @@ void invdct4_transform(
    return;
}

#ifdef IVAS_FLOAT_FIXED
void invdct4_transform_fx(
    Word32 *v_fx,     /* i  : input vector                */
    UWord8 *invdct_v, /* o  : inverse transformed vector  */
    Word16 q )
{
    Word32 a_fx, b_fx, c_fx, d_fx;
    int16_t i;
    Word32 f_invdct_v_fx[4];

    a_fx = L_add( v_fx[0], v_fx[2] );
    b_fx = L_sub( v_fx[0], v_fx[2] );
    c_fx = L_shl( L_add( Mpy_32_32( 1402911360, v_fx[1] ), Mpy_32_32( 581104896, v_fx[3] ) ), 31 - 30 );
    d_fx = L_shl( L_sub( Mpy_32_32( 581104896, v_fx[1] ), Mpy_32_32( 1402911360, v_fx[3] ) ), 31 - 30 );
    f_invdct_v_fx[0] = L_shl( L_add( a_fx, c_fx ), 7 );
    f_invdct_v_fx[1] = L_shl( L_add( b_fx, d_fx ), 7 );
    f_invdct_v_fx[2] = L_shl( L_sub( b_fx, d_fx ), 7 );
    f_invdct_v_fx[3] = L_shl( L_sub( a_fx, c_fx ), 7 );

    FOR( i = 0; i < 4; i++ )
    {
        IF( f_invdct_v_fx[i] < 0 )
        {
            invdct_v[i] = 0;
        }
        ELSE
        {
            IF( f_invdct_v_fx[i] > L_shl( 255, q ) )
            {
                f_invdct_v_fx[i] = L_shl( 255, q );
            }
            invdct_v[i] = (uint8_t) L_shr( f_invdct_v_fx[i], q );
        }
    }

    return;
}
#endif

/*---------------------------------------------------------------
 * masa_compensate_two_dir_energy_ratio_index()
Loading