Commit 10275bfc authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Integration of some ACELP Sub-functions

parent 4f3af045
Loading
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -6797,6 +6797,14 @@ void init_tcx_cfg_fx(
     Decoder_State *stdec
   );

void generate_comfort_noise_dec_hf_ivas_fx(
     Word32 **bufferReal,         /* o   : matrix to real part of input bands */
     Word32 **bufferImag,         /* o   : matrix to imaginary part of input bands */
     Word16 *bufferScale,         /* o   : pointer to scalefactor for real and imaginary part of input bands */
     HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables  */
     const Word16 cng_coh_flag    /* i  : CNG Flag for coherence handling                        */
 );

 /* Generate the comfort noise based on the target noise level */
 void generate_masking_noise(Word16 *timeDomainBuffer,        /* i/o: time-domain signal */
   Word16 Q,
+82 −1
Original line number Diff line number Diff line
@@ -45,6 +45,10 @@
#include "ivas_prot.h"
#include "ivas_rom_com.h"
#include "wmc_auto.h"
#ifdef IVAS_FLOAT_FIXED
#include "prot_fx2.h"
#endif
#include "math.h"

/*-------------------------------------------------------------------*
 * acelp_core_dec()
@@ -1623,8 +1627,29 @@ ivas_error acelp_core_dec(
    /* check if the CLDFB works on the right sample rate */
    if ( ( st->cldfbAna->no_channels * st->cldfbAna->no_col ) != st->L_frame )
    {
#ifdef IVAS_FLOAT_FIXED
        Word16 old_len_ana, old_len_bpf;
        Word16 new_len;

        // The following lines are to calculate the length of the buffers before and
        // after calling the function for fixed pt conversion. The calculations are taken
        // based on the logic used in resampleCldfb_ivas_fx
        old_len_ana = st->cldfbAna->p_filter_length - st->cldfbAna->no_channels;
        old_len_bpf = st->cldfbBPF->p_filter_length - st->cldfbBPF->no_channels;
        new_len = 9 * (int16_t)(st->L_frame * FRAMES_PER_SEC * INV_CLDFB_BANDWIDTH + 0.5f);

        floatToFixed_arrL(st->cldfbAna->cldfb_state, st->cldfbAna->cldfb_state_fx, Q11, old_len_ana);
        floatToFixed_arrL(st->cldfbBPF->cldfb_state, st->cldfbBPF->cldfb_state_fx, Q10, old_len_bpf);

        resampleCldfb_ivas_fx( st->cldfbAna, st->L_frame * FRAMES_PER_SEC );
        resampleCldfb_ivas_fx( st->cldfbBPF, st->L_frame * FRAMES_PER_SEC );

        fixedToFloat_arrL(st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_state, Q11, new_len);
        fixedToFloat_arrL(st->cldfbBPF->cldfb_state_fx, st->cldfbBPF->cldfb_state, Q10, new_len);
#else
        resampleCldfb_ivas( st->cldfbAna, st->L_frame * FRAMES_PER_SEC );
        resampleCldfb_ivas( st->cldfbBPF, st->L_frame * FRAMES_PER_SEC );
#endif

        if ( st->ini_frame > 0 )
        {
@@ -1655,6 +1680,41 @@ ivas_error acelp_core_dec(

    if ( !( st->element_mode == IVAS_CPE_MDCT && st->bpf_off ) )
    {
#ifdef IVAS_FLOAT_FIXED
        /////////////////////////////////////////////////////////////////////////////
        Word16 pst_old_syn_exp;
        Word16 tmp_syn_exp;
        Word16 tmp_syn_fx[1];   // temporary. just one element because retro_interp4_5 only accesses syn[0]

        // Get exponents.
        f2me_buf_16(st->hBPF->pst_old_syn, st->hBPF->pst_old_syn_fx, &pst_old_syn_exp, NBPSF_PIT_MAX);
        f2me_16(syn[0], &tmp_syn_fx[0], &tmp_syn_exp);
        tmp_syn_exp = s_max(tmp_syn_exp, pst_old_syn_exp);  // max exp btween syn and pst_old_syn

        // Float to fix
        for (i = 0; i < NBPSF_PIT_MAX; i++)
        {
            st->hBPF->pst_old_syn_fx[i] = (Word16)(st->hBPF->pst_old_syn[i] * pow(2, 15 - tmp_syn_exp));
        }
        tmp_syn_fx[0] = (Word16)(syn[0] * pow(2, 15 - tmp_syn_exp));
        /////////////////////////////////////////////////////////////////////////////

        test();
        IF ( NE_16( st->L_frame, st->last_L_frame ) && NE_16( st->last_codec_mode, MODE2 ) )
        {
            IF ( EQ_16( st->L_frame, L_FRAME ) )
            {
                retro_interp5_4_fx( st->hBPF->pst_old_syn_fx );
            }
            ELSE IF ( EQ_16( st->L_frame, L_FRAME16k ) )
            {
                retro_interp4_5_fx( tmp_syn_fx, st->hBPF->pst_old_syn_fx );
            }
        }

        // Fixed to float
        me2f_buf_16(st->hBPF->pst_old_syn_fx, tmp_syn_exp, st->hBPF->pst_old_syn, NBPSF_PIT_MAX);
#else
        if ( st->L_frame != st->last_L_frame && st->last_codec_mode != MODE2 )
        {
            if ( st->L_frame == L_FRAME )
@@ -1666,7 +1726,7 @@ ivas_error acelp_core_dec(
                retro_interp4_5( syn, st->hBPF->pst_old_syn );
            }
        }

#endif
        /* bass post-filter */
        bass_psfilter( st->hBPF, st->Opt_AMR_WB, syn, st->L_frame, pitch_buf, st->bpf_off, st->stab_fac, &st->stab_fac_smooth, st->coder_type, bpf_error_signal );
    }
@@ -1709,7 +1769,28 @@ ivas_error acelp_core_dec(
            /*WB/SWB-FD_CNG*/
            if ( ( st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40 ) && ( st->cng_type == FD_CNG ) && ( st->hFdCngDec->hFdCngCom->numCoreBands < st->cldfbSyn->no_channels ) )
            {
#ifdef IVAS_FLOAT_FIXED
                /* Float to fixed */
                f2me_buf(st->hFdCngDec->hFdCngCom->cngNoiseLevel_flt, st->hFdCngDec->hFdCngCom->cngNoiseLevel, &st->hFdCngDec->hFdCngCom->cngNoiseLevelExp, FFTCLDFBLEN);

                // NOTE: this should be removed later.
                st->hFdCngDec->hFdCngCom->q_cngNoiseLevel = 31 - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp;

                Word16 tmpBufferScale = 0;
                generate_comfort_noise_dec_hf_ivas_fx( realBuffer_fx, imagBuffer_fx, /*realBuffer, imagBuffer,*/ &tmpBufferScale, st->hFdCngDec->hFdCngCom, st->cng_ism_flag );
                
                /* Fixed to float */
                FOR(i = 0; i < st->hFdCngDec->hFdCngCom->numSlots; i++)
                {
                    FOR(Word16 j = st->hFdCngDec->hFdCngCom->numCoreBands; j < st->hFdCngDec->hFdCngCom->regularStopBand; j++)
                    {
                        realBuffer[i][j] = me2f(realBuffer_fx[i][j], tmpBufferScale + 15);
                        imagBuffer[i][j] = me2f(imagBuffer_fx[i][j], tmpBufferScale + 15);
                    }
                }
#else
                generate_comfort_noise_dec_hf_flt( realBuffer, imagBuffer, st->hFdCngDec->hFdCngCom, st->cng_ism_flag );
#endif

                if ( st->hFdCngDec->hFdCngCom->regularStopBand < st->cldfbSyn->no_channels )
                {
+129 −0
Original line number Diff line number Diff line
@@ -3547,6 +3547,135 @@ generate_comfort_noise_dec_hf (
}


void generate_comfort_noise_dec_hf_ivas_fx(
    Word32 **bufferReal,         /* o   : matrix to real part of input bands */
    Word32 **bufferImag,         /* o   : matrix to imaginary part of input bands */
    Word16 *bufferScale,         /* o   : pointer to scalefactor for real and imaginary part of input bands */
    HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables  */
    const Word16 cng_coh_flag    /* i  : CNG Flag for coherence handling                        */
)
{
    Word16 i, j, s, sc, sn;
    Word16 scaleCLDFB;
    Word32 sqrtNoiseLevel;
    Word16 randGaussExp;
    Word16 cngNoiseLevelExp;
    Word16 *seed;
    Word16 *seed2;
    Word16 c1, c2;
    Word32 *ptr_level;
    Word32 *cngNoiseLevel;
    Word32 tmp1, tmp2;

    cngNoiseLevel = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand;
    cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
    move16();
    ptr_level = cngNoiseLevel;

    seed = &( hFdCngCom->seed );

    /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
    scaleCLDFB = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING );

    seed2 = &( hFdCngCom->seed );

    c1 = 0;
    move16();
    c2 = 0;
    move16();
    sc = 0;
    move16();

    IF( cng_coh_flag )
    {
        seed2 = &( hFdCngCom->seed2 );

        s = 0;
        move16();

        c1 = Sqrt16( hFdCngCom->coherence_fx, &s );
        c1 = shl( c1, s ); // Q15

        s = 0;
        move16();
        c2 = Sqrt16( sub( MAX16B, hFdCngCom->coherence_fx ), &s );
        c2 = shl( c2, s ); // Q15
    }

    sn = 0;
    move16();
    IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
    {
        sn = add( sn, 1 );
        cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
        move16();
    }

    randGaussExp = CNG_RAND_GAUSS_SHIFT;
    move16();

    /*
      Generate Gaussian random noise in real and imaginary parts of the CLDFB bands
      Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each band
    */
    IF( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) )
    {
        sc = add( shr( add( cngNoiseLevelExp, CLDFBinvScalingFactor_EXP + 1 - 1 ), 1 ), randGaussExp );
        move16();
        assert( ( ( cngNoiseLevelExp + CLDFBinvScalingFactor_EXP + 1 - 1 ) & 1 ) == 0 );

        FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
        {
            FOR( i = 0; i < hFdCngCom->numSlots; i++ )
            {
                /* scaleCLDFB:  CLDFBinvScalingFactor_EXP + 1 */
                s = 0;
                move16();
                sqrtNoiseLevel = Sqrt32( L_shr( Mpy_32_16_1( *ptr_level, scaleCLDFB ), sn ), &s );

                IF( cng_coh_flag )
                {
                    tmp1 = rand_gauss( seed );
                    move16();
                    tmp2 = rand_gauss( seed2 );
                    move16();

                    bufferReal[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) );
                    move32();
                    bufferReal[i][j] = L_shl( Mpy_32_32( bufferReal[i][j], sqrtNoiseLevel ), s );
                    move32();

                    tmp1 = rand_gauss( seed );
                    move16();
                    tmp2 = rand_gauss( seed2 );
                    move16();

                    bufferImag[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) );
                    move32();
                    bufferImag[i][j] = L_shl( Mpy_32_32( bufferImag[i][j], sqrtNoiseLevel ), s );
                    move32();
                }
                ELSE
                {
                    /* Real part in CLDFB band */
                    bufferReal[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
                    move32();

                    /* Imaginary part in CLDFB band */
                    bufferImag[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
                    move32();
                }
            }
            ptr_level = ptr_level + 1;
        }
        *bufferScale = sub( sc, 15 );
    }

    return;
}



/*
    generate_masking_noise