Commit 8ae2c103 authored by multrus's avatar multrus
Browse files

[cleanup] accept FIX_2455_HARMONIZE_generate_comfort_noise_enc

parent 7edce461
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -84,7 +84,6 @@
#define TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR      /* FhG: Temporary workaround for incorrect implementation of decoder flush with split rendering */
#define NONBE_1122_KEEP_EVS_MODE_UNCHANGED              /* FhG: Disables fix for issue 1122 in EVS mode to keep BE tests green. This switch should be removed once the 1122 fix is added to EVS via a CR.  */
#define HARM_HQ_CORE_KEEP_BE                            /* hack to keep all BE after HQ core functions harmonization; pending resolving issues #2450, #2451, #2452 */
#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_2452_HQ_CORE_PEAQ_AVR_RATIO_HARM            /* Eri: Basop issue 2453: Fix alignment of peak_avrg_ratio_fx */
+0 −8
Original line number Diff line number Diff line
@@ -362,11 +362,7 @@ ivas_error acelp_core_enc_fx(
                    st->hDtxEnc->last_CNG_L_frame = st->L_frame;
                    move16();
                }
#ifdef FIX_2455_HARMONIZE_generate_comfort_noise_enc
                generate_comfort_noise_enc_fx( st, Q_new, 1, st->element_mode );
#else
                generate_comfort_noise_enc_fx( st, Q_new, 1 );
#endif

                FdCng_exc( st->hFdCngEnc->hFdCngCom, &st->hDtxEnc->CNG_mode, st->L_frame, st->lsp_old_fx,
                           st->hDtxEnc->first_CNG, st->hDtxEnc->lspCNG_fx, Aq, lsp_new, lsf_new_fx, exc_fx, exc2_fx, bwe_exc_fx );
@@ -422,11 +418,7 @@ ivas_error acelp_core_enc_fx(
                st->hFdCngEnc->hFdCngCom->cngNoiseLevelExp = sub( st->hFdCngEnc->hFdCngCom->cngNoiseLevelExp, Q_cngNoise );
                move16();

#ifdef FIX_2455_HARMONIZE_generate_comfort_noise_enc
                generate_comfort_noise_enc_fx( st, Q_new, 1, st->element_mode );
#else
                generate_comfort_noise_enc_ivas_fx( st, Q_new, 1 );
#endif
                st->hTcxEnc->q_Txnq = Q_new;
                move16();

+0 −4
Original line number Diff line number Diff line
@@ -92,11 +92,7 @@ void enc_acelp_tcx_main_fx(
        }

        /* Generate Comfort Noise */
#ifdef FIX_2455_HARMONIZE_generate_comfort_noise_enc
        generate_comfort_noise_enc_fx( st, *Q_new, 1, EVS_MONO );
#else
        generate_comfort_noise_enc_fx( st, *Q_new, 1 );
#endif

        /* Update Core Encoder */
        core_encode_update_cng_fx( st, st->hFdCngEnc->hFdCngCom->timeDomainBuffer, st->hFdCngEnc->hFdCngCom->A_cng, Aw, *Q_new, *shift );
+0 −397
Original line number Diff line number Diff line
@@ -1294,403 +1294,12 @@ void FdCng_encodeSID_fx(
    return;
}

#ifndef FIX_2455_HARMONIZE_generate_comfort_noise_enc
void generate_comfort_noise_enc_fx(
    Encoder_State *stcod,
    Word16 Q_new,
    Word16 gen_exc )
{
    Word16 i, s, sn, cnt;
    Word16 startBand2;
    Word16 stopFFTbin2;
    Word16 preemph_fac;
    Word32 sqrtNoiseLevel;
    Word16 randGaussExp;
    Word16 fftBufferExp;
    Word16 cngNoiseLevelExp;
    Word16 *seed;
    Word16 *timeDomainOutput;
    Word32 *ptr_r, *ptr_i;
    Word32 *cngNoiseLevel;
    Word32 *ptr_level;
    Word32 *fftBuffer;
    Word16 old_syn_pe_tmp[16];
    Word16 tcx_transition = 0;
    HANDLE_FD_CNG_ENC stenc = stcod->hFdCngEnc;
    HANDLE_FD_CNG_COM st = stenc->hFdCngCom;
    DTX_ENC_HANDLE hDtxEnc = stcod->hDtxEnc;
    TD_CNG_ENC_HANDLE hTdCngEnc = stcod->hTdCngEnc;

    LPD_state_HANDLE hLPDmem = stcod->hLPDmem;
    TCX_ENC_HANDLE hTcxEnc = stcod->hTcxEnc;

    /* Warning fix */
    s = 0;

    /* pointer initialization */

    cngNoiseLevel = st->cngNoiseLevel;
    cngNoiseLevelExp = st->cngNoiseLevelExp;
    ptr_level = cngNoiseLevel;
    seed = &( st->seed );
    fftBuffer = st->fftBuffer;
    timeDomainOutput = st->timeDomainBuffer;

    /*
      Generate Gaussian random noise in real and imaginary parts of the FFT bins
      Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
      scaling Gaussian random noise: format Q3.29
    */
    sn = 0;
    move16();
    IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
    {
        sn = add( sn, 1 );
        cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
        move16();
    }

    randGaussExp = CNG_RAND_GAUSS_SHIFT;
    move16();
    cnt = sub( stenc->stopFFTbinDec, stenc->startBandDec );
    IF( stenc->startBandDec == 0 )
    {
        /* DC component in FFT */
        s = 0;
        move16();
        sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s );

        fftBuffer[0] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
        move32();

        /* Nyquist frequency is discarded */
        fftBuffer[1] = L_deposit_l( 0 );

        ptr_level = ptr_level + 1;
        ptr_r = fftBuffer + 2;
        cnt = sub( cnt, 1 );
    }
    ELSE
    {
        startBand2 = shl( stenc->startBandDec, 1 );
        set32_fx( fftBuffer, 0, startBand2 );
        ptr_r = fftBuffer + startBand2;
    }

    sn = add( sn, 1 );
    ptr_i = ptr_r + 1;
    FOR( i = 0; i < cnt; i++ )
    {
        s = 0;
        move16();
        sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s );

        /* Real part in FFT bins */
        *ptr_r = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
        move32();

        /* Imaginary part in FFT bins */
        *ptr_i = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
        move32();

        ptr_r = ptr_r + 2;
        ptr_i = ptr_i + 2;
        ptr_level = ptr_level + 1;
    }

    /* Remaining FFT bins are set to zero */
    stopFFTbin2 = shl( stenc->stopFFTbinDec, 1 );
    set32_fx( fftBuffer + stopFFTbin2, 0, sub( st->fftlen, stopFFTbin2 ) );

    fftBufferExp = add( shr( cngNoiseLevelExp, 1 ), randGaussExp );

    /* If previous frame is active, reset the overlap-add buffer */
    IF( GT_32( stcod->last_core_brate, SID_2k40 ) )
    {
        set16_fx( st->olapBufferSynth, 0, st->fftlen );
        test();
        test();
        IF( ( GT_32( stcod->last_core, ACELP_CORE ) && EQ_16( stcod->codec_mode, MODE2 ) ) || EQ_16( stcod->codec_mode, MODE1 ) )
        {
            tcx_transition = 1;
            move16();
        }
    }

    /* Perform STFT synthesis */
    SynthesisSTFT( fftBuffer, fftBufferExp, timeDomainOutput, st->olapBufferSynth, st->olapWinSyn,
                   tcx_transition, st, gen_exc, &Q_new, -1, -1 );
    {
        Word32 Lener, att;
        Word16 exp;
        /* update CNG excitation energy for LP_CNG */

        /* calculate the residual signal energy */
        /*enr = dotp( st->exc_cng, st->exc_cng, st->frameSize ) / st->frameSize;*/
        Lener = Dot_productSq16HQ( 1, st->exc_cng, stcod->L_frame, &exp );
        exp = add( sub( shl( sub( 15, Q_new ), 1 ), 8 ), exp ); /*8 = log2(256)*/

        /* convert log2 of residual signal energy */
        /*(float)log10( enr + 0.1f ) / (float)log10( 2.0f );*/
        Lener = BASOP_Util_Log2( Lener );
        Lener = L_add( Lener, L_shl( L_deposit_l( exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/
        if ( EQ_16( stcod->L_frame, L_FRAME16k ) )
        {
            Lener = L_sub( Lener, 10802114l /*0.3219280949f Q25*/ ); /*log2(320) = 8.3219280949f*/
        }
        /* decrease the energy in case of WB input */
        IF( NE_16( stcod->bwidth, NB ) )
        {
            IF( EQ_16( stcod->bwidth, WB ) )
            {
                IF( hDtxEnc->CNG_mode >= 0 )
                {
                    /* Bitrate adapted attenuation */
                    att = L_shl( L_deposit_l( ENR_ATT_fx[hDtxEnc->CNG_mode] ), 17 );
                }
                ELSE
                {
                    /* Use least attenuation for higher bitrates */
                    att = L_shl( L_deposit_l( ENR_ATT_fx[4] ), 17 );
                }
            }
            ELSE
            {
                att = 384 << 17;
                move32(); /*1.5 Q8<<17=Q25*/
            }
            Lener = L_sub( Lener, att );
        }
        /*stdec->lp_ener = 0.8f * stcod->lp_ener + 0.2f * pow( 2.0f, enr );*/
        Lener = BASOP_util_Pow2( Lener, 6, &exp );
        Lener = Mult_32_16( Lener, 6554 /*0.2f Q15*/ );
        exp = sub( 25, exp );
        Lener = L_shr( Lener, exp );                                                                     /*Q6*/
        hTdCngEnc->lp_ener_fx = L_add( Mult_32_16( hTdCngEnc->lp_ener_fx, 26214 /*0.8f Q15*/ ), Lener ); /*Q6*/
    }

    /* Overlap-add when previous frame is active */
    test();
    IF( ( GT_32( stcod->last_core_brate, SID_2k40 ) ) && ( EQ_16( stcod->codec_mode, MODE2 ) ) )
    {
        Word32 old_exc_ener, gain, noise32;
        Word16 seed_loc, lpcorder, old_syn, tmp, gain16, N, N2, N4, N8;
        Word16 old_exc_ener_exp, gain_exp;
        Word16 normFacE, normShiftE, normShiftEM1;
        Word16 normFacG, normShiftG, normShiftGM1;
        Word16 noiseExp, *old_exc, old_Aq[M + 1], *old_syn_pe;
        Word16 noise[640], normShiftP2;
        Word16 Q_exc, Q_syn;

        assert( st->frameSize <= 640 );

        seed_loc = st->seed;
        move16();
        N = st->frameSize;
        move16();
        N2 = shr( st->frameSize, 1 );

        IF( GT_16( stcod->last_core, ACELP_CORE ) )
        {
            Word16 left_overlap_mode;
            left_overlap_mode = stcod->hTcxCfg->tcx_last_overlap_mode;
            move16();
            if ( EQ_16( left_overlap_mode, ALDO_WINDOW ) )
            {
                left_overlap_mode = FULL_OVERLAP;
                move16();
            }

            tcx_windowing_synthesis_current_frame( timeDomainOutput,
                                                   stcod->hTcxCfg->tcx_mdct_window, /*Keep sine windows for limiting Time modulation*/
                                                   stcod->hTcxCfg->tcx_mdct_window_half,
                                                   stcod->hTcxCfg->tcx_mdct_window_minimum,
                                                   stcod->hTcxCfg->tcx_mdct_window_length,
                                                   stcod->hTcxCfg->tcx_mdct_window_half_length,
                                                   stcod->hTcxCfg->tcx_mdct_window_min_length,
                                                   0,
                                                   left_overlap_mode,
                                                   NULL,
                                                   NULL,
                                                   NULL,
                                                   NULL,
                                                   NULL,
                                                   N / 2,
                                                   shr( sub( abs_s( stcod->hTcxCfg->tcx_offset ), stcod->hTcxCfg->tcx_offset ), 1 ), /* equivalent to: stdec->hTcxCfg->tcx_offset<0?-stdec->hTcxCfg->tcx_offset:0 */
                                                   1,
                                                   0,
                                                   0 );

            IF( stcod->hTcxCfg->last_aldo != 0 )
            {
                FOR( i = 0; i < st->frameSize; i++ )
                {
                    timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( hTcxEnc->old_out_fx[i + NS2SA_FX2( stcod->sr_core, N_ZERO_MDCT_NS )], hTcxEnc->Q_old_out ) );
                    move16();
                }
            }
            ELSE
            {
                tcx_windowing_synthesis_past_frame( hTcxEnc->Txnq,
                                                    stcod->hTcxCfg->tcx_aldo_window_1_trunc,
                                                    stcod->hTcxCfg->tcx_mdct_window_half,
                                                    stcod->hTcxCfg->tcx_mdct_window_minimum,
                                                    stcod->hTcxCfg->tcx_mdct_window_length,
                                                    stcod->hTcxCfg->tcx_mdct_window_half_length,
                                                    stcod->hTcxCfg->tcx_mdct_window_min_length,
                                                    stcod->hTcxCfg->tcx_last_overlap_mode );

                FOR( i = 0; i < N2; i++ )
                {
                    timeDomainOutput[i] = add( timeDomainOutput[i], shl( hTcxEnc->Txnq[i], TCX_IMDCT_HEADROOM ) );
                    move16();
                }
            }
        }
        ELSE
        {

            /*
              - the scaling of the LPCs (e.g. old_Aq) is always Q12 (encoder or decoder)

              - the scaling of the deemphasized signals (e.g. old_syn) is always Q0 (encoder or decoder)

              - the scaling of the excitation signals in the encoder (e.g. old_exc) is Q_new
              - the scaling of the preemphasized signals in the encoder (e.g. old_syn_pe) is Q_new-1

              - the scaling of the excitation signals in the decoder (e.g. old_exc) is Q_exc (or stdec->Q_exc)
              - the scaling of the preemphasized signals in the decoder (e.g. old_syn_pe) is Q_syn (or stdec->Q_syn)
            */

            lpcorder = M;
            move16();
            E_LPC_f_lsp_a_conversion( stcod->lsp_old_fx, old_Aq, M );
            old_exc = hLPDmem->old_exc + sub( L_EXC_MEM, N2 );
            old_syn_pe = hLPDmem->mem_syn2;
            old_syn = hLPDmem->syn[lpcorder];
            move16();
            preemph_fac = stcod->preemph_fac;
            move16();
            Q_exc = Q_new;
            Q_syn = sub( Q_new, 1 );

            /* shift to be in the range of values supported by getNormReciprocalWord16() */
            N8 = shr( N2, CNG_NORM_RECIPROCAL_RANGE_SHIFT );

            assert( N2 == ( N8 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );

            normFacE = getNormReciprocalWord16( N8 );
            normShiftE = BASOP_util_norm_s_bands2shift( N8 );
            normShiftEM1 = sub( normShiftE, 1 );
            normShiftP2 = add( normShiftE, CNG_NORM_RECIPROCAL_RANGE_SHIFT );

            old_exc_ener = L_shr( L_mult( old_exc[0], old_exc[0] ), normShiftP2 );
            FOR( i = 1; i < N2; i++ )
            {
                old_exc_ener = L_add( old_exc_ener, L_shr( L_mult( old_exc[i], old_exc[i] ), normShiftP2 ) );
            }
            old_exc_ener = L_shl( Mpy_32_16_1( old_exc_ener, shl( normFacE, normShiftEM1 ) ), 1 );

            old_exc_ener_exp = 0;
            move16();
            old_exc_ener = Sqrt32( old_exc_ener, &old_exc_ener_exp );
            old_exc_ener_exp = add( old_exc_ener_exp, ( sub( 15, Q_exc ) ) );

            /* shift to be in the range of values supported by getNormReciprocalWord16() */
            N4 = shr( N, CNG_NORM_RECIPROCAL_RANGE_SHIFT );

            assert( N == ( N4 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );

            normFacG = getNormReciprocalWord16( N4 );
            normShiftG = BASOP_util_norm_s_bands2shift( N4 );
            normShiftGM1 = sub( normShiftG, 1 );
            normShiftP2 = add( normShiftG, CNG_NORM_RECIPROCAL_RANGE_SHIFT );

            gain = L_deposit_l( 0 );
            FOR( i = 0; i < N; i++ )
            {
                noise32 = rand_gauss( &seed_loc );
                noise[i] = extract_h( noise32 );
                gain = L_add( gain, L_shr( L_mult( noise[i], noise[i] ), normShiftP2 ) );
            }
            gain = L_shl( Mpy_32_16_1( gain, shl( normFacG, normShiftGM1 ) ), 1 );

            gain_exp = 2 * CNG_RAND_GAUSS_SHIFT;
            move16();
            gain = ISqrt32( gain, &gain_exp );

            gain = Mpy_32_32( old_exc_ener, gain );
            gain16 = extract_h( gain );

            gain_exp = add( old_exc_ener_exp, gain_exp );
            noiseExp = add( CNG_RAND_GAUSS_SHIFT, gain_exp );

            s = sub( 15 - NOISE_HEADROOM, noiseExp );
            FOR( i = 0; i < N; i++ )
            {
                noise[i] = shr_sat( mult( noise[i], gain16 ), s );
                move16();
            }

            assert( lpcorder <= 16 );

            s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) );
            FOR( i = 0; i < lpcorder; i++ )
            {
                old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s );
                move16();
            }

            E_UTIL_synthesis(
                0,              /* i  : scaling to apply for a[0]                 Q0   */
                old_Aq,         /* i  : LP filter coefficients                    Q12  */
                noise,          /* i  : input signal                              Qx   */
                noise,          /* o  : output signal                             Qx-s */
                N,              /* i  : size of filtering                         Q0   */
                old_syn_pe_tmp, /* i/o: memory associated with this filtering.    Q0 */
                0,              /* i  : 0=no update, 1=update of memory.          Q0   */
                lpcorder        /* i  : order of LP filter                        Q0   */
            );

            tmp = old_syn;
            move16();

            E_UTIL_deemph2(
                NOISE_HEADROOM,
                noise,       /* I/O: signal              Qx */
                preemph_fac, /* I: deemphasis factor      Qx */
                N,           /* I: vector size              */
                &tmp         /* I/O: memory (signal[-1]) Qx */
            );

            FOR( i = 0; i < N4; i++ )
            {
                tmp = mult( noise[i], st->olapWinSyn[i].v.re );
                timeDomainOutput[i] = add( timeDomainOutput[i], tmp );
                move16();
                tmp = mult( noise[i + N4], st->olapWinSyn[N4 - 1 - i].v.im );
                timeDomainOutput[i + N4] = add( timeDomainOutput[i + N4], tmp );
                move16();
            }
        }
    }

    return;
}
#endif

#ifdef FIX_2455_HARMONIZE_generate_comfort_noise_enc
void generate_comfort_noise_enc_fx(
    Encoder_State *stcod,
    Word16 Q_new,
    Word16 gen_exc,
    Word16 element_mode )
#else
void generate_comfort_noise_enc_ivas_fx(
    Encoder_State *stcod,
    Word16 Q_new,
    Word16 gen_exc )
#endif
{
    Word16 i, s, sn, cnt;
    Word16 startBand2;
@@ -1813,7 +1422,6 @@ void generate_comfort_noise_enc_ivas_fx(
    }

    /* Perform STFT synthesis */
#ifdef FIX_2455_HARMONIZE_generate_comfort_noise_enc
    IF( EQ_16( element_mode, EVS_MONO ) )
    {
        SynthesisSTFT( fftBuffer, fftBufferExp, timeDomainOutput, st->olapBufferSynth, st->olapWinSyn,
@@ -1825,11 +1433,6 @@ void generate_comfort_noise_enc_ivas_fx(
                                   tcx_transition, st, gen_exc, &Q_new, -1, -1 );
    }
    IF( ( ( hTdCngEnc != NULL ) && ( NE_16( element_mode, EVS_MONO ) ) ) || EQ_16( element_mode, EVS_MONO ) )
#else
    SynthesisSTFT_enc_ivas_fx( fftBuffer, fftBufferExp, timeDomainOutput, st->olapBufferSynth, st->olapWinSyn,
                               tcx_transition, st, gen_exc, &Q_new, -1, -1 );
    IF( hTdCngEnc != NULL )
#endif
    {
        Word32 Lener, att;
        Word16 exp;
+0 −14
Original line number Diff line number Diff line
@@ -1479,20 +1479,12 @@ void FdCng_encodeSID_fx(
    Word16 preemph_fac /* i  : preemphase factor */
);

#ifdef FIX_2455_HARMONIZE_generate_comfort_noise_enc
/* Generate the comfort noise based on the target noise level */
void generate_comfort_noise_enc_fx(
    Encoder_State *stcod,
    Word16 Q_new,
    Word16 gen_exc,
    Word16 element_mode );
#else
/* Generate the comfort noise based on the target noise level */
void generate_comfort_noise_enc_fx(
    Encoder_State *stcod,
    Word16 Q_new,
    Word16 gen_exc );
#endif

Word16 cng_energy_fx(
    const Word16 element_mode, /* i  : element mode                 Q0*/
@@ -3871,12 +3863,6 @@ Word16 cng_energy_ivas_fx(
    const Word16 Q_new         /* i  : Input scaling                  */
);

#ifndef FIX_2455_HARMONIZE_generate_comfort_noise_enc
void generate_comfort_noise_enc_ivas_fx(
    Encoder_State *stcod,
    Word16 Q_new,
    Word16 gen_exc );
#endif

void SynthesisSTFT_enc_ivas_fx(
    Word32 *fftBuffer,        /* i    : pointer to FFT bins */