Commit 33b7e7d3 authored by Fabian Bauer's avatar Fabian Bauer
Browse files

added macro FIX_2489_HARMONIZE_FdCng_encodeSID, added harmonized FdCng_encodeSID_fx()

parent a6b0e09b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@
#define FIX_2455_HARMONIZE_generate_comfort_noise_enc   /* FhG: harmonize generate_comfort_noise_enc and generate_comfort_noise_enc_ivas */
#define FIX_2455_HARMONIZE_configureFdCngEnc            /* FhG: harmonize generate_comfort_noise_enc and generate_comfort_noise_enc_ivas */
#define FIX_2463_EVS_BWE_LSF                            /* VA: basop issue 2463: harmonize calling of Quant_BWE_LSF_fx() */
#define FIX_2489_HARMONIZE_FdCng_encodeSID              /* FhG: harmonize FdCng_encodeSID_fx() and FdCng_encodeSID_ivas_fx()  */


/* #################### End BE switches ################################## */
+8 −0
Original line number Diff line number Diff line
@@ -358,7 +358,11 @@ ivas_error acelp_core_enc_fx(
                test();
                IF( EQ_32( st->core_brate, SID_2k40 ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
                {
#ifdef FIX_2489_HARMONIZE_FdCng_encodeSID
                    FdCng_encodeSID_fx( st );
#else
                    FdCng_encodeSID_fx( st->hFdCngEnc, st, st->preemph_fac );
#endif
                    st->hDtxEnc->last_CNG_L_frame = st->L_frame;
                    move16();
                }
@@ -397,7 +401,11 @@ ivas_error acelp_core_enc_fx(
                test();
                IF( EQ_32( st->core_brate, SID_2k40 ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
                {
#ifdef FIX_2489_HARMONIZE_FdCng_encodeSID
                    FdCng_encodeSID_fx( st );
#else
                    FdCng_encodeSID_ivas_fx( st );
#endif
                    st->hDtxEnc->last_CNG_L_frame = st->L_frame;
                    move16();
                }
+4 −0
Original line number Diff line number Diff line
@@ -88,7 +88,11 @@ void enc_acelp_tcx_main_fx(
        /* Run SID Coder */
        IF( st->core_brate == SID_2k40 )
        {
#ifdef FIX_2489_HARMONIZE_FdCng_encodeSID
            FdCng_encodeSID_fx( st );
#else
            FdCng_encodeSID_fx( st->hFdCngEnc, st, st->preemph_fac );
#endif
        }

        /* Generate Comfort Noise */
+369 −1
Original line number Diff line number Diff line
@@ -1071,7 +1071,7 @@ static void msvq_encoder(
    return;
}


#ifndef FIX_2489_HARMONIZE_FdCng_encodeSID
/*
   FdCng_encodeSID_fx

@@ -1091,6 +1091,7 @@ static void msvq_encoder(
    Returns:
    void
*/

void FdCng_encodeSID_fx(
    HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG structure containing all buffers and variables */
    Encoder_State *corest,
@@ -1293,6 +1294,7 @@ void FdCng_encodeSID_fx(

    return;
}
#endif /*FIX_2489_HARMONIZE_FdCng_encodeSID*/

#ifndef FIX_2455_HARMONIZE_generate_comfort_noise_enc
void generate_comfort_noise_enc_fx(
@@ -2483,6 +2485,371 @@ void perform_noise_estimation_enc_ivas_fx(
 *
 * Generate a bitstream out of the partition levels
 *-------------------------------------------------------------------*/
#ifdef FIX_2489_HARMONIZE_FdCng_encodeSID
void FdCng_encodeSID_fx(
    Encoder_State *corest /* i/o: encoder state structure     */
)
{
    Word16 i, index, N;
    Word32 temp, gain_fx, e_fx;
    HANDLE_FD_CNG_ENC hFdCngEnc = corest->hFdCngEnc;
    HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
    Word16 preemph_fac = corest->preemph_fac; // Q15
    move16();
    BSTR_ENC_HANDLE hBstr = corest->hBstr;
    Word16 indices[32];
    Word32 v_fx[32];
    Word32 *E_fx;
    Word16 v_e, E_Exp;
    Word16 normFacN, normShiftN;
    Word16 normFacGain, normShiftGain;
    Word32 E_ExpLd64;

    IF( corest->element_mode > 0 )
    {
        (void) normFacN;
        (void) normShiftN;
        (void) normFacGain;
        (void) normShiftGain;
        (void) E_ExpLd64;
    }
    ELSE
    {
        (void) v_e;
    }

    /* Init */

    E_fx = hFdCngEnc->msNoiseEst_fx;
    N = hFdCngEnc->npartDec;
    move16();
    E_Exp = hFdCngEnc->msNoiseEst_fx_exp;
    move16();
    IF( corest->element_mode == 0 )
    {
        E_ExpLd64 = L_shl( E_Exp, WORD32_BITS - 1 - LD_DATA_SCALE );

        normFacN = getNormReciprocalWord16( N );
        normShiftN = BASOP_util_norm_s_bands2shift( N );

        normFacGain = getNormReciprocalWord16( N_GAIN_MAX - N_GAIN_MIN );
        normShiftGain = BASOP_util_norm_s_bands2shift( N_GAIN_MAX - N_GAIN_MIN );
    }
    ELSE
    {
        set_zero_fx( v_fx, FDCNG_VQ_MAX_LEN );
    }


    /* Convert to LOG */
    e_fx = L_deposit_l( 0 );
    IF( corest->element_mode == 0 )
    {
        /* e: Q14.23 format, v_fx: Q9.23 format */
        temp = Mpy_32_32_r( L_shl( 1, sub( 31, E_Exp ) ), 214748 ); /* 1e-4f, Q31-E_Exp */
        FOR( i = 0; i < N; i++ )
        {
            /* assert( E_fx[i] != 0 ); */
            /* constant: 0.75257498916 = 10.0 * log10(2.0)/log10(10.0) * 0.25 */
            v_fx[i] = Mpy_32_16_1( L_add( BASOP_Util_Log2( L_add( E_fx[i], L_max( 1, temp ) ) ), E_ExpLd64 ), 24660 /*0.75257498916 Q15*/ );
            move32();
            e_fx = L_add( e_fx, L_shr( v_fx[i], normShiftN ) );
        }
        e_fx = L_shl( Mpy_32_16_1( e_fx, shl( normFacN, sub( normShiftN, 1 ) ) ), 1 );
    }
    ELSE
    {
        FOR( i = 0; i < N; i++ )
        {
            IF( E_fx[i] == 0 )
            {
                /* 10 * log(1e-4) = 10 * (-4) = -40 */
                v_fx[i] = -41943040; // -40.0 in Q20
                move32();
            }
            ELSE
            {
                v_fx[i] = Mpy_32_32( 671088640 /*10 in Q26*/, BASOP_Util_Log10( E_fx[i], E_Exp ) ); // Q20 = 26+25-31
                move32();
            }
            e_fx = L_add( e_fx, L_shr( v_fx[i], 1 ) ); // Q19, add one bit headroom
        }
    }

    /* Normalize MSVQ input */

    gain_fx = 0;
    move32();
    IF( corest->element_mode == 0 )
    {
        /* gain: Q9.23 format */
        FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ )
        {
            gain_fx = L_add( gain_fx, L_shr( v_fx[i], normShiftGain ) );
        }
        gain_fx = L_shl( Mpy_32_16_1( gain_fx, shl( normFacGain, sub( normShiftGain, 1 ) ) ), 1 );
    }
    ELSE
    {
        FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ )
        {
            gain_fx = L_add( gain_fx, v_fx[i] ); // Q20
        }

        /*gain /= (float) ( N_GAIN_MAX - N_GAIN_MIN );*/
        gain_fx = Mpy_32_32( gain_fx, 165191050 /* 1/13 in Q31*/ ); // Q20

        FOR( i = 0; i < N; i++ )
        {
            v_fx[i] = L_sub( v_fx[i], gain_fx ); // Q20
            move32();
        }

        v_e = 11; // Q20
        move16();
    }

    /*MSVQ*/
    IF( corest->element_mode == 0 )
    {
        Word16 v16[32];
        FOR( i = 0; i < N; i++ )
        {
            v16[i] = extract_h( L_sub( v_fx[i], gain_fx ) );
        }

        /* MSVQ encoder */
        msvq_encoder( cdk_37bits, v16, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices );

        /* MSVQ decoder */
        msvq_decoder( cdk_37bits, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, v16 );

        FOR( i = 0; i < N; i++ )
        {
            v_fx[i] = L_deposit_h( v16[i] );
        }
    }
    ELSE
    {
        /* MSVQ encoder */
        Word16 w_fx[32];
        set_val_Word16( w_fx, ONE_IN_Q8, N );
        Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC];
        Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN];

        /* DCT domain compressed/truncated indices used for first stage  */
        /*  quantization with stage1 stored in DCT24 domain,   stages 2 through 6 directly dearched
           in FDCNG band domain
        */
        Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
        Word32 *invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled  */

        IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) )
        {
            /* truncated DCT21 analysis */
            create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31

            dctT2_N_apply_matrix_fx( v_fx /*Q20*/, dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); // Q20

            /* truncated IDCT21 extension to 24 bands  */
            extend_dctN_input_fx( v_fx, dct_target_fx, N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); // Q20

            Copy32( tot_sig_ext_fx, v_fx, FDCNG_VQ_MAX_LEN ); /*  write  extended result as input to  VQ stage #1 */ // Q20
        }

        create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31

        msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices );

        msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v_fx, NULL, 7 );

        v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) );
    }

    /* Compute gain */
    IF( corest->element_mode == 0 )
    {
        /*Q9.23 format */
        gain_fx = 0;
        FOR( i = 0; i < N; i++ )
        {
            gain_fx = L_add( gain_fx, L_shr( v_fx[i], normShiftN ) );
        }
        gain_fx = L_sub( e_fx, L_shl( Mpy_32_16_1( gain_fx, shl( normFacN, sub( normShiftN, 1 ) ) ), 1 ) );

        /* Apply bitrate-dependant scale */
        {
            apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO );
        }
    }
    ELSE
    {
        gain_fx = 0;
        move32();
        FOR( i = 0; i < N; i++ )
        {
            gain_fx = L_add( gain_fx, v_fx[i] ); // Q = 31 - v_e
        }
        e_fx = L_shl( e_fx, sub( 12, v_e ) );                           // Q = 31 - v_e
        gain_fx = Mpy_32_16_1( L_sub( e_fx, gain_fx ), div_s( 1, N ) ); // Q = 31 - v_e
        gain_fx = L_shl( gain_fx, sub( v_e, 8 ) );                      // Q23

        /* Apply bitrate-dependant scale */
        apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
    }


    /* Quantize gain */
    IF( corest->element_mode == 0 )
    {
        /*Q14.23 format */
        gain_fx = L_add( gain_fx, L_shr( gain_fx, 1 ) );
        gain_fx = L_add( gain_fx, 507510784l /*60.5 Q23*/ );
        index = extract_l( L_shr( gain_fx, WORD32_BITS - 1 - 8 ) );
    }
    ELSE
    {
        temp = Madd_32_32( L_shl( GAIN_Q_OFFSET_IVAS_FX_Q0, 22 ), gain_fx, 1610612736 /*1.5 in Q30*/ ); // Q22
        index = extract_l( L_shr( L_add( temp, ONE_IN_Q21 ), 22 ) );                                    // Q0
    }

    if ( index < 0 )
    {
        index = 0;
        move16();
    }

    if ( GT_16( index, 127 ) )
    {
        index = 127;
        move16();
    }

    /* Apply gain and undo log */
    IF( corest->element_mode == 0 )
    {
        /* gain Q14.23 format */
        gain_fx = L_shl( L_deposit_l( index ), WORD32_BITS - 1 - 8 );
        gain_fx = L_sub( gain_fx, 503316480l /*60.0 Q23*/ );
        gain_fx = Mpy_32_16_1( gain_fx, 21845 /*2.0f/3.0f Q15*/ );
        Word16 sidNoiseEst_Exp = 0;

        /* sidNoiseEst: format Q6.26, 0.66438561897 = log10(10)/log10(2.0) / 10.0 * 2.0 */

        /* calculate worst case for scaling */
        {
            Word32 maxVal = 0x80000000 /*-1.0 Q31*/;
            move32();
            FOR( i = 0; i < N; i++ )
            {
                maxVal = L_max( maxVal, v_fx[i] );
            }

            maxVal = L_add( maxVal, gain_fx );
            maxVal = L_shl( Mpy_32_16_1( maxVal, 21771 /*0.66438561897 Q15*/ ), 1 );
            move16();
            WHILE( maxVal >= 0 )
            {
                maxVal = L_sub( maxVal, 33554432l /*0.015625 Q31*/ );
                sidNoiseEst_Exp = add( sidNoiseEst_Exp, 1 );
            }
            hFdCngCom->sidNoiseEstExp = sidNoiseEst_Exp;
            move16();
            E_ExpLd64 = L_shl( sidNoiseEst_Exp, WORD32_BITS - 1 - LD_DATA_SCALE );
        }

        FOR( i = 0; i < N; i++ )
        {
            temp = L_add( v_fx[i], gain_fx );
            temp = L_shl( Mpy_32_16_1( temp, 21771 /*0.66438561897 Q15*/ ), 1 );
            temp = L_sub( temp, E_ExpLd64 );
            assert( temp < 0 );
            hFdCngCom->sidNoiseEst[i] = BASOP_Util_InvLog2( temp );
            move32();
        }
    }
    ELSE
    {
        gain_fx = L_shl( L_mult0( sub( index, GAIN_Q_OFFSET_IVAS_FX_Q0 ), 21845 /*1.5 in Q15*/ ), sub( 16, v_e ) ); // Q = 31-v_e

        Word16 exp[32];
        FOR( i = 0; i < N; i++ )
        {
            temp = Mpy_32_32( L_add( v_fx[i], gain_fx ), 214748365 /* 0.1 in Q31*/ ); // Q = 31-v_e
            hFdCngCom->sidNoiseEst[i] = BASOP_Util_fPow( 10, 31, temp, v_e, &exp[i] );
            move32();
        }

        maximum_s( exp, N, &hFdCngCom->sidNoiseEstExp );

        FOR( i = 0; i < N; i++ )
        {
            hFdCngCom->sidNoiseEst[i] = L_shr( hFdCngCom->sidNoiseEst[i], sub( hFdCngCom->sidNoiseEstExp, exp[i] ) ); // exp = hFdCngCom->sidNoiseEstExp
            move32();
        }
    }

    /* NB last band energy compensation */
    IF( EQ_16( hFdCngCom->CngBandwidth, NB ) )
    {
        hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], NB_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp)
        move32();
    }

    test();
    IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) )
    {
        hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], SWB_13k2_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp)
        move32();
    }


    /* Write bitstream */
    IF( EQ_16( corest->codec_mode, MODE2 ) )
    {
        FOR( i = 0; i < FD_CNG_stages_37bits; i++ )
        {
            push_next_indice( hBstr, indices[i], bits_37bits[i] );
        }
        push_next_indice( hBstr, index, 7 );
    }
    ELSE
    {
        Word16 is_frame_len_16k = 0;
        move16();
        Word16 IDX = IND_ACELP_16KHZ;
        move16();
        push_indice( hBstr, IND_SID_TYPE, 1, 1 );
        if ( corest->element_mode > 0 )
        {
            IDX = IND_BWIDTH;
            move16();
        }
        push_indice( hBstr, IDX, corest->bwidth, 2 );
        if ( EQ_16( corest->L_frame, L_FRAME16k ) )
        {
            is_frame_len_16k = 1;
            move16();
        }
        push_indice( hBstr, IND_ACELP_16KHZ, is_frame_len_16k, 1 );
        FOR( i = 0; i < FD_CNG_stages_37bits; i++ )
        {
            push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] );
        }

        push_indice( hBstr, IND_ENERGY, index, 7 );
    }

    /* Interpolate the bin/band-wise levels from the partition levels */
    scalebands( hFdCngCom->sidNoiseEst, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 );
    hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp;
    move16();

    lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac );

    return;
}
#else /*FIX_2489_HARMONIZE_FdCng_encodeSID*/
void FdCng_encodeSID_ivas_fx(
    Encoder_State *st /* i/o: encoder state structure     */
)
@@ -2710,6 +3077,7 @@ void FdCng_encodeSID_ivas_fx(

    return;
}
#endif /*FIX_2489_HARMONIZE_FdCng_encodeSID*/


/*-------------------------------------------------------------------*
+8 −0
Original line number Diff line number Diff line
@@ -1473,11 +1473,17 @@ void CNG_enc_fx(
    Word16 *sid_bw );

/* Generate a bitstream out of the partition levels */
#ifdef FIX_2489_HARMONIZE_FdCng_encodeSID
void FdCng_encodeSID_fx(
    HANDLE_FD_CNG_ENC st /* i/o: FD_CNG structure containing all buffers and variables */
);
#else
void FdCng_encodeSID_fx(
    HANDLE_FD_CNG_ENC st, /* i/o: FD_CNG structure containing all buffers and variables */
    Encoder_State *corest,
    Word16 preemph_fac /* i  : preemphase factor */
);
#endif

#ifdef FIX_2455_HARMONIZE_generate_comfort_noise_enc
/* Generate the comfort noise based on the target noise level */
@@ -1647,9 +1653,11 @@ Word16 AdjustFirstSID_fx(
    Encoder_State *stcod          /* i  : pointer to Coder_State_Plus structure        */
);

#ifndef FIX_2489_HARMONIZE_FdCng_encodeSID
void FdCng_encodeSID_ivas_fx(
    Encoder_State *st /* i/o: encoder state structure                                    */
);
#endif

void resetFdCngEnc_fx(
    Encoder_State *st );