Commit 7a4790ad authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Functions in ivas_ism_dtx_dec converted to fixed point.

parent 7fddf5c0
Loading
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -1219,6 +1219,12 @@ int16_t ivas_ism_dtx_enc(
    int16_t md_diff_flag[],                                     /* o  : metadata differential flag                  */
    int16_t *sid_flag                                           /* o  : indication of SID frame                     */
);
#ifdef IVAS_FLOAT_FIXED
void ivas_ism_dtx_dec_fx(
    Decoder_Struct *st_ivas,                                    /* i/o: IVAS decoder structure                      */
    Word16 *nb_bits_metadata                                   /* o  : number of metadata bits                     */
);
#endif // IVAS_FLOAT_FIXED

void ivas_ism_dtx_dec(
    Decoder_Struct *st_ivas,                                    /* i/o: IVAS decoder structure                      */
@@ -1284,6 +1290,14 @@ void ivas_get_ism_sid_quan_bitbudget(
    int16_t *nBits_coh,                                         /* o  : number of Q bits for coherence              */
    int16_t *nBits_sce_id                                       /* o  : number of Q bits for sce_id_dtx             */
);
#ifdef IVAS_FLOAT_FIXED
void ivas_ism_dtx_limit_noise_energy_for_near_silence_fx(
    SCE_DEC_HANDLE hSCE[],        /* i/o: SCE decoder structures          */
    const Word16 sce_id_dtx,     /* i  : SCE DTX ID                      */
    const Word16 nchan_transport, /* i  : number of transport channels    */
    Word16 *Q_cngNoiseLevel
);
#endif // IVAS_FLOAT_FIXED

void ivas_ism_dtx_limit_noise_energy_for_near_silence(
    SCE_DEC_HANDLE hSCE[],                                      /* i/o: SCE decoder structures                      */
+7 −0
Original line number Diff line number Diff line
@@ -5427,6 +5427,13 @@ Word32 dotp_fixed(
    const Word16 n    /* i  : vector length                                   */
);

/*! r: dot product of x[] and y[] in case of overflow*/
Word32 dotp_fixed_o(
    const Word32 x[],    /* i  : vector x[]                    */
    const Word32 y[],    /* i  : vector y[]                    */
    const Word16 n,      /* i  : vector length                 */
    const Word16 log_len, /* i  : max factor added to result q after dot product (equal to log2(n))                 */
    Word16 *res_q );
void lsf_end_dec_fx(
  Decoder_State* st,              /* i/o: decoder state structure                 */
  Word16 mode2_flag,
+26 −0
Original line number Diff line number Diff line
@@ -863,6 +863,32 @@ Word32 dotp_fixed(
}


/*To calculate dot product of two 32 bit arrays in case of overflow*/
Word32 dotp_fixed_o(
    const Word32 x[],     /* i  : vector x[]                    */
    const Word32 y[],     /* i  : vector y[]                    */
    const Word16 n,       /* i  : vector length                 */
    const Word16 log_len, /* i  : max factor added to result q after dot product (equal to log2(n))                 */
    Word16 *res_q         /*stores resultant Q*/
)
{
    Word16 i;
    Word64 suma; /*resultant q= q(x)+q(y)-9-x such that q<=31*/

    suma = W_shr( W_mult_32_32( x[0], y[0] ), log_len);

    FOR( i = 1; i < n; i++ )
    {
        suma = W_add( suma, W_shr( W_mult_32_32( x[i], y[i] ), log_len) );
    }
    *res_q = add(sub(*res_q , log_len) , 1);
    WHILE( GT_64(suma , MAX_32) || GT_16(*res_q,31))
    {
        suma = W_shr( suma, 1 );
        *res_q= sub(*res_q,1);
    }
    return (Word32) suma;
}
/*---------------------------------------------------------------------*
 * inv_sqrt()
 *
+153 −14
Original line number Diff line number Diff line
@@ -37,23 +37,116 @@
#include "ivas_prot_fx.h"
#include "prot.h"
#include "wmc_auto.h"
#include "ivas_prot_fx.h"

#ifdef IVAS_FLOAT_FIXED
static Word16 float_to_fix16(float number, Word16 Q);
static float fix16_to_float(Word16 number, Word16 Q);
#include "prot_fx2.h"

#endif
/*-------------------------------------------------------------------*
 * ivas_ism_dtx_dec_fx()
 *
 * ISM DTX Metadata decoding routine
 *-------------------------------------------------------------------*/
#ifdef IVAS_FLOAT_FIXED
void ivas_ism_dtx_dec_fx(
    Decoder_Struct *st_ivas,  /* i/o: IVAS decoder structure    */
    Word16 *nb_bits_metadata /* o  : number of metadata bits   */
)
{
    Word16 ch, nchan_ism, nchan_ism_prev;
    Word32 ivas_total_brate;
    Word16 md_diff_flag[MAX_NUM_OBJECTS];
    Word16 flag_noisy_speech, sce_id_dtx;
    Decoder_State *st;

    ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
    move32();

    nchan_ism_prev = st_ivas->nchan_ism;
    move16();

    IF ( !st_ivas->bfi && EQ_32(ivas_total_brate , IVAS_SID_5k2) )
    {
        /* 'nchan_ism' was read in ivas_dec_setup() */
        nchan_ism = st_ivas->nchan_ism;

        /* ism_mode was read in ivas_dec_setup() as well as reconfiguration ivas_ism_dec_config() */
    }
    ELSE
    {
        nchan_ism = nchan_ism_prev;
    }
    move16();

static Word16 float_to_fix16(float number, Word16 Q){
    Word16 ret=(Word16)(number * ((UWord16)1 << Q));
    return ret;
    /* Metadata decoding and dequantization  */
    ivas_ism_metadata_sid_dec_fx( st_ivas->hSCE, ivas_total_brate, st_ivas->bfi, nchan_ism, st_ivas->nchan_transport, st_ivas->ism_mode,
                                  &flag_noisy_speech, &sce_id_dtx, st_ivas->hIsmMetaData, nb_bits_metadata );

    IF ( EQ_32(ivas_total_brate , IVAS_SID_5k2) && !st_ivas->bfi )
    {
        IF ( st_ivas->hParamIsmDec != NULL )
        {
            st_ivas->hParamIsmDec->hParamIsm->flag_noisy_speech = flag_noisy_speech;
            move16();
        }

static float fix16_to_float(Word16 number, Word16 Q){
    float ret=(float) number / ((UWord16)1 << Q);
    return ret;
        st_ivas->hISMDTX.sce_id_dtx = sce_id_dtx;
        move16();
    }

#endif
    set16_fx( md_diff_flag, 1, nchan_ism );

    IF ( EQ_16(st_ivas->ism_mode , ISM_MODE_PARAM) )
    {
        FOR ( ch = 0; ch < nchan_ism; ch++ )
        {
            st_ivas->hParamIsmDec->azimuth_values_fx[ch] = st_ivas->hIsmMetaData[ch]->azimuth_fx;
            st_ivas->hParamIsmDec->elevation_values_fx[ch] = st_ivas->hIsmMetaData[ch]->elevation_fx;
            move32();
            move32();
        }
    }
    /* synch common seed between SCEs */
    IF ( EQ_16(st_ivas->ism_mode , ISM_MODE_DISC) )
    {
        FOR ( ch = 0; ch < nchan_ism; ++ch )
        {
            st_ivas->hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed = st_ivas->hSCE[st_ivas->hISMDTX.sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed;
            move16();
        }
    }

    update_last_metadata_fx( nchan_ism, st_ivas->hIsmMetaData, md_diff_flag );

    st_ivas->hISMDTX.ism_dtx_hangover_cnt = 0;
    move16();

    IF ( EQ_32(ivas_total_brate , IVAS_SID_5k2) && !st_ivas->bfi )
    {
        FOR ( ch = 0; ch < st_ivas->nchan_transport; ch++ )
        {
            nb_bits_metadata[ch] = nb_bits_metadata[sce_id_dtx];
            move16();
        }
    }

    IF ( !st_ivas->bfi )
    {
        FOR ( ch = 0; ch < st_ivas->nchan_transport; ch++ )
        {
            st = st_ivas->hSCE[ch]->hCoreCoder[0];
            st->bit_stream = st_ivas->hSCE[0]->hCoreCoder[0]->bit_stream;
            st->next_bit_pos = 0; /* note: needed in paramISM -> discISM switching */
            st->cng_ism_flag = 1;
            move16();
            move16();
            st->L_frame = s_min( st->L_frame, L_FRAME16k ); /* note: needed for switching from active frame with L_frame=640 to CNG in object with no SID */
        }
    }

    return;
}
#endif // IVAS_FLOAT_FIXED

/*-------------------------------------------------------------------*
 * ivas_ism_dtx_dec()
@@ -163,8 +256,8 @@ void ivas_ism_dtx_dec(
    {
        if ( EQ_16(md_diff_flag[ch], 1 ) )
        {
            st_ivas->hIsmMetaData[ch]->last_azimuth = fix16_to_float(st_ivas->hIsmMetaData[ch]->last_azimuth_fx, 7 );
            st_ivas->hIsmMetaData[ch]->last_elevation = fix16_to_float(st_ivas->hIsmMetaData[ch]->last_elevation_fx, 8);
            st_ivas->hIsmMetaData[ch]->last_azimuth = fixedToFloat(st_ivas->hIsmMetaData[ch]->last_azimuth_fx, 7 );
            st_ivas->hIsmMetaData[ch]->last_elevation = fixedToFloat(st_ivas->hIsmMetaData[ch]->last_elevation_fx, 8);
        }
    }
#else
@@ -203,6 +296,52 @@ void ivas_ism_dtx_dec(
 * for DTX frames where the energy of the sent noise estimate of the dominant object
 * is near silence, limit the other objects CNG energies to the same level
 *-------------------------------------------------------------------*/
#ifdef IVAS_FLOAT_FIXED
void ivas_ism_dtx_limit_noise_energy_for_near_silence_fx(
    SCE_DEC_HANDLE hSCE[],        /* i/o: SCE decoder structures          */
    const Word16 sce_id_dtx,      /* i  : SCE DTX ID                      */
    const Word16 nchan_transport, /* i  : number of transport channels    */
    Word16 *Q_cngNoiseLevel       /* i  : stores Q factor of hFdCngCom->cngNoiseLevel for various channels*/
)
{
    Word32 fac_fx, cng_noise_nrg_obj_fx, cng_noise_nrg_dominant_fx, Q_fac;
    Word16 ch, cng_noise_level_len, Q_cng_noise_nrg_dominant;
    HANDLE_FD_CNG_COM hFdCngCom;
    hFdCngCom = hSCE[sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom;
    cng_noise_level_len = sub(hFdCngCom->stopFFTbin , hFdCngCom->startBand);
    Q_cng_noise_nrg_dominant = add(Q_cngNoiseLevel[sce_id_dtx] , Q_cngNoiseLevel[sce_id_dtx]);/*stores Q for cng_noise_nrg_dominant_fx*/
    cng_noise_nrg_dominant_fx = dotp_fixed_o( hFdCngCom->cngNoiseLevel, hFdCngCom->cngNoiseLevel, cng_noise_level_len, 9 /*log2(len(hFdCngCom->cngNoiseLevel))*/, &Q_cng_noise_nrg_dominant );/*Resultant Q_cng_noise_nrg_dominant= (Q_cng_noise_nrg_dominant-x)<=31*/
    IF ( LT_32(cng_noise_nrg_dominant_fx , L_shl_sat(1, Q_cng_noise_nrg_dominant)))/*cng_noise_nrg_dominant<1.f*/
    {
        FOR ( ch = 0; ch < nchan_transport; ch++ )
        {
            IF ( EQ_16(ch , sce_id_dtx) )
            {
                continue;
            }
            hFdCngCom = hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom;
            cng_noise_level_len = sub(hFdCngCom->stopFFTbin , hFdCngCom->startBand);
            Word16 Q_cng_noise_nrg_obj = add(Q_cngNoiseLevel[ch] , Q_cngNoiseLevel[ch]);/*Stores Q-factor of cng_noise_nrg_obj*/
            cng_noise_nrg_obj_fx = dotp_fixed_o( hFdCngCom->cngNoiseLevel, hFdCngCom->cngNoiseLevel, cng_noise_level_len, 9, &Q_cng_noise_nrg_obj );/*Resultant Q_cng_noise_nrg_obj= (Q_cng_noise_nrg_obj-x)<=31*/
            IF( GT_32(cng_noise_nrg_obj_fx , cng_noise_nrg_dominant_fx) )
            {
                Word32 temp = divide3232( L_shr( cng_noise_nrg_dominant_fx, 1 ), cng_noise_nrg_obj_fx );/*Stores value of cng_noise_nrg_dominant_fx/cng_noise_nrg_obj_fx*/
                Word16 Q_temp = Q_cng_noise_nrg_dominant - 1 - Q_cng_noise_nrg_obj + 15;/*Stores resultant Q after divide3232 operation above*/
                IF (Q_temp % 2 == 1 )/*Making Q_temp even for sqrt function*/
                {
                    Q_temp = sub(Q_temp , 1);
                    temp = L_shr( temp, 1 );
                }
                fac_fx = getSqrtWord32(temp);/*Resultant Q=Q_temp/2*/
                Q_fac = shr( Q_temp, 1 );
                v_multc_fixed( hFdCngCom->cngNoiseLevel, fac_fx, hFdCngCom->cngNoiseLevel, cng_noise_level_len );/*Resultant Q of cngNoiseLevel is Q_cngNoiseLevel for ch*/
                scale_sig32( hFdCngCom->cngNoiseLevel, cng_noise_level_len, negate(31 - Q_fac) );/*Restoring Q of hFdCngCom->cngNoiseLevel to Q_cngNoiseLevel */
            }
        }
    }
    return;
}
#endif // IVAS_FLOAT_FIXED

void ivas_ism_dtx_limit_noise_energy_for_near_silence(
    SCE_DEC_HANDLE hSCE[],        /* i/o: SCE decoder structures          */
+80 −0
Original line number Diff line number Diff line
@@ -220,7 +220,57 @@ ivas_error ivas_jbm_dec_tc(
        /* Metadata decoding and configuration */
        if ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA )
        {
#ifdef IVAS_FLOAT_FIXED
#if 1/*Cleanup changes: float to fixed*/
            FOR( Word16 ind = 0; ind < st_ivas->nchan_ism; ind++ )
            {
                st_ivas->hIsmMetaData[ind]->azimuth_fx = (Word32) ( st_ivas->hIsmMetaData[ind]->azimuth * ( 1 << 22 ) );
                st_ivas->hIsmMetaData[ind]->elevation_fx = (Word32) ( st_ivas->hIsmMetaData[ind]->elevation * ( 1 << 22 ) );
                st_ivas->hIsmMetaData[ind]->last_azimuth_fx = (Word32) ( st_ivas->hIsmMetaData[ind]->last_azimuth * ( 1 << 22 ) );
                st_ivas->hIsmMetaData[ind]->last_elevation_fx = (Word32) ( st_ivas->hIsmMetaData[ind]->last_elevation * ( 1 << 22 ) );
                st_ivas->hIsmMetaData[ind]->last_true_azimuth_fx = (Word32) ( st_ivas->hIsmMetaData[ind]->last_true_azimuth * ( 1 << 22 ) );
                st_ivas->hIsmMetaData[ind]->last_true_elevation_fx = (Word32) ( st_ivas->hIsmMetaData[ind]->last_true_elevation * ( 1 << 22 ) );
            }
            FOR( Word16 ind = 0; ind < st_ivas->nchan_transport; ind++ )
            st_ivas->hSCE[ind]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = (Word16) ( st_ivas->hSCE[ind]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_flt * 32767 );
            IF( st_ivas->hParamIsmDec )
            {
                floatToFixed_arrL( st_ivas->hParamIsmDec->azimuth_values, st_ivas->hParamIsmDec->azimuth_values_fx, 22, st_ivas->nchan_ism );
                floatToFixed_arrL( st_ivas->hParamIsmDec->elevation_values, st_ivas->hParamIsmDec->elevation_values_fx, 22, st_ivas->nchan_ism );
            }
            FOR( Word16 ch = 0; ch < st_ivas->nchan_ism; ch++ )
            {
                st_ivas->hIsmMetaData[ch]->last_azimuth_fx = floatToFixed( st_ivas->hIsmMetaData[ch]->last_azimuth, 22 );
                st_ivas->hIsmMetaData[ch]->last_elevation_fx = floatToFixed( st_ivas->hIsmMetaData[ch]->last_elevation, 22 );
            }
#endif
            ivas_ism_dtx_dec_fx( st_ivas, nb_bits_metadata );
#if 1/*Cleanup changes: fixed to float*/
            FOR( Word16 ind = 0; ind < st_ivas->nchan_ism; ind++ )
            {
                st_ivas->hIsmMetaData[ind]->azimuth = (float) ( st_ivas->hIsmMetaData[ind]->azimuth_fx ) / (float) ( 1 << 22 );
                st_ivas->hIsmMetaData[ind]->elevation = (float) ( st_ivas->hIsmMetaData[ind]->elevation_fx ) / (float) ( 1 << 22 );
                st_ivas->hIsmMetaData[ind]->last_azimuth = (float) ( st_ivas->hIsmMetaData[ind]->last_azimuth_fx ) / (float) ( 1 << 22 );
                st_ivas->hIsmMetaData[ind]->last_elevation = (float) ( st_ivas->hIsmMetaData[ind]->last_elevation_fx ) / (float) ( 1 << 22 );
                st_ivas->hIsmMetaData[ind]->last_true_azimuth = (float) ( st_ivas->hIsmMetaData[ind]->last_true_azimuth_fx ) / (float) ( 1 << 22 );
                st_ivas->hIsmMetaData[ind]->last_true_elevation = (float) ( st_ivas->hIsmMetaData[ind]->last_true_elevation_fx ) / (float) ( 1 << 22 );
            }
            FOR( Word16 ind = 0; ind < st_ivas->nchan_transport; ind++ )
            st_ivas->hSCE[ind]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_flt = (float) ( st_ivas->hSCE[ind]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx ) / 32767.f;
            IF( st_ivas->hParamIsmDec )
            {
                fixedToFloat_arrL( st_ivas->hParamIsmDec->azimuth_values_fx, st_ivas->hParamIsmDec->azimuth_values, 22, st_ivas->nchan_ism);
                fixedToFloat_arrL( st_ivas->hParamIsmDec->elevation_values_fx, st_ivas->hParamIsmDec->elevation_values, 22, st_ivas->nchan_ism);
            }
            FOR(Word16 ch = 0; ch < st_ivas->nchan_ism; ch++ )
            {
                st_ivas->hIsmMetaData[ch]->last_azimuth = fixedToFloat( st_ivas->hIsmMetaData[ch]->last_azimuth_fx, 22 );
                st_ivas->hIsmMetaData[ch]->last_elevation = fixedToFloat( st_ivas->hIsmMetaData[ch]->last_elevation_fx, 22 );
            }
#endif
#else
            ivas_ism_dtx_dec( st_ivas, nb_bits_metadata );
#endif // IVAS_FLOAT_FIXED

#ifdef IVAS_FLOAT_FIXED
            Word32 *output_fx[1];
@@ -254,7 +304,37 @@ ivas_error ivas_jbm_dec_tc(
            }
#endif // IVAS_FLOAT_FIXED

#ifdef IVAS_FLOAT_FIXED
#if 1
			Word16 Q_cngNoiseLevel[MAX_SCE];
			Word16 cng_noise_level_len, ch;
			HANDLE_FD_CNG_COM hFdCngCom;
			FOR(ch = 0; ch < 4; ch++)
			{
				IF(st_ivas->hSCE[ch] != NULL)
				{
					hFdCngCom = st_ivas->hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom;
					cng_noise_level_len = sub(hFdCngCom->stopFFTbin, hFdCngCom->startBand);
					Q_cngNoiseLevel[ch] = Q_factor_arrL(hFdCngCom->cngNoiseLevel_flt, cng_noise_level_len);
					floatToFixed_arrL(hFdCngCom->cngNoiseLevel_flt, hFdCngCom->cngNoiseLevel, Q_cngNoiseLevel[ch], cng_noise_level_len);
				}
			}
#endif
            ivas_ism_dtx_limit_noise_energy_for_near_silence_fx( st_ivas->hSCE, st_ivas->hISMDTX.sce_id_dtx, st_ivas->nchan_transport , Q_cngNoiseLevel);
#if 1
			FOR(ch = 0; ch < 4; ch++)
			{
				IF(st_ivas->hSCE[ch] != NULL)
				{
					hFdCngCom = st_ivas->hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom;
					cng_noise_level_len = sub(hFdCngCom->stopFFTbin, hFdCngCom->startBand);
					fixedToFloat_arrL(hFdCngCom->cngNoiseLevel, hFdCngCom->cngNoiseLevel_flt, Q_cngNoiseLevel[ch], cng_noise_level_len);
				}
			}
#endif
#else
            ivas_ism_dtx_limit_noise_energy_for_near_silence( st_ivas->hSCE, st_ivas->hISMDTX.sce_id_dtx, st_ivas->nchan_transport );
#endif // IVAS_FLOAT_FIXED
        }
        else if ( st_ivas->ism_mode == ISM_MODE_PARAM )
        {
Loading