Commit ce1ed6e6 authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Merge branch 'MLD_improvements_7' into 'main'

MLD improvements

See merge request !559
parents 798b61c5 8b4587b0
Loading
Loading
Loading
Loading
Loading
+240 −1
Original line number Diff line number Diff line
@@ -520,7 +520,7 @@ void enhancer_ivas_fx(
        {
            /* tmp = 0.150 * (1.0 + voice_fac) */
            /* 0.30=voiced, 0=unvoiced */
            tmp = mac_r( 0x10000000L, voice_fac, 4915 ); /*Q15 */
            tmp = mac_r( 0x13333333L, voice_fac, 4915 ); /*Q15 */
        }
        ELSE
        {
@@ -581,6 +581,245 @@ void enhancer_ivas_fx(
    }
}

void enhancer_ivas_fx2(
    const Word32 core_brate,  /* i  : decoder bitrate                          */
    const Word16 Opt_AMR_WB,  /* i  : flag indicating AMR-WB IO mode           */
    const Word16 coder_type,  /* i  : coder type                               */
    const Word16 i_subfr,     /* i  : subframe number                          */
    const Word16 L_frame,     /* i  : frame size                               */
    const Word16 voice_fac,   /* i  : subframe voicing estimation         Q15  */
    const Word16 stab_fac,    /* i  : LP filter stablility measure        Q15  */
    Word32 norm_gain_code,    /* i  : normalised innovative cb. gain   Q16  */
    const Word16 gain_inov,   /* i  : gain of the unscaled innovation     Q12  */
    Word32 *gc_threshold,     /* i/o: gain code threshold                 Q16  */
    Word16 *code,             /* i/o: innovation                          Q12  */
    Word16 *exc2,             /* i/o: adapt. excitation/total exc.        Q_exc*/
    const Word16 gain_pit,    /* i  : quantized pitch gain                Q14  */
    struct dispMem_fx *dm_fx, /* i/o: phase dispersion algorithm memory        */
    const Word16 Q_exc        /* i  : Q of the excitation                      */
)
{
    Word16 tmp, fac, *pt_exc2;
    Word16 i;
    Word32 L_tmp;
    Word16 gain_code_hi;
    Word16 pit_sharp, tmp16;
    Word16 excp[L_SUBFR], sc;


    pit_sharp = gain_pit;
    move16(); /* to remove gcc warning */
    pt_exc2 = exc2 + i_subfr;

    /*------------------------------------------------------------*
     * Phase dispersion to enhance noise at low bit rate
     *------------------------------------------------------------*/

    i = 2;
    move16(); /* no dispersion */
    IF( Opt_AMR_WB )
    {
        IF( LE_32( core_brate, ACELP_6k60 ) )
        {
            i = 0;
            move16(); /* high dispersion  */
        }
        ELSE if ( LE_32( core_brate, ACELP_8k85 ) )
        {
            i = 1;
            move16(); /* low dispersion  */
        }
    }
    ELSE IF( NE_16( coder_type, UNVOICED ) )

    {
        test();
        test();
        test();
        test();
        IF( LE_32( core_brate, ACELP_7k20 ) )
        {
            i = 0;
            move16(); /* high dispersion  */
        }
        ELSE if ( ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, TRANSITION ) || EQ_16( coder_type, AUDIO ) || coder_type == INACTIVE ) && LE_32( core_brate, ACELP_9k60 ) )
        {
            i = 1;
            move16(); /* low dispersion  */
        }
    }

    phase_dispersion_fx( norm_gain_code, gain_pit, code, i, dm_fx );

    /*------------------------------------------------------------
     * noise enhancer
     *
     * - Enhance excitation on noise. (modify gain of code)
     *   If signal is noisy and LPC filter is stable, move gain
     *   of code 1.5 dB toward gain of code threshold.
     *   This decreases by 3 dB noise energy variation.
     *-----------------------------------------------------------*/

    /* tmp = 0.5f * (1.0f - voice_fac) */
#ifdef BASOP_NOGLOB
    tmp = msu_r_sat( 0x40000000, voice_fac, 16384 ); /*Q15 */ /* 1=unvoiced, 0=voiced */
#else
    tmp = msu_r( 0x40000000, voice_fac, 16384 ); /*Q15 */ /* 1=unvoiced, 0=voiced */
#endif
    /* fac = stab_fac * tmp */
    fac = mult( stab_fac, tmp ); /*Q15*/

    IF( LT_32( norm_gain_code, *gc_threshold ) )
    {
        L_tmp = Madd_32_16( norm_gain_code, norm_gain_code, 6226 ); /*Q16 */
        L_tmp = L_min( L_tmp, *gc_threshold );                      /*Q16 */
    }
    ELSE
    {
        L_tmp = Mult_32_16( norm_gain_code, 27536 ); /*Q16 */
        L_tmp = L_max( L_tmp, *gc_threshold );       /*Q16 */
    }
    *gc_threshold = L_tmp;
    move32(); /*Q16 */

    /* gain_code = (fac * tmp) + (1.0 - fac) * gain_code ==> fac * (tmp - gain_code) + gain_code */
    L_tmp = L_sub( L_tmp, norm_gain_code );                    /*Q16 */
    norm_gain_code = Madd_32_16( norm_gain_code, L_tmp, fac ); /*Q16 */

    /* gain_code *= gain_inov - Inverse the normalization */
    L_tmp = Mult_32_16( norm_gain_code, gain_inov ); /*Q13*/ /* gain_inov in Q12 */

    sc = 6;
    move16();

    gain_code_hi = round_fx( L_shl( L_tmp, add( Q_exc, 3 ) ) ); /* in Q_exc */

    /*------------------------------------------------------------*
     * pitch enhancer
     *
     * - Enhance excitation on voiced. (HP filtering of code)
     *   On voiced signal, filtering of code by a smooth fir HP
     *   filter to decrease energy of code at low frequency.
     *------------------------------------------------------------*/
    test();
    IF( !Opt_AMR_WB && EQ_16( coder_type, UNVOICED ) )
    {
        /* Copy(code, exc2, L_SUBFR) */
        FOR( i = 0; i < L_SUBFR; i++ )
        {
            pt_exc2[i] = round_fx( L_shl( L_mult( gain_code_hi, code[i] ), sc ) ); /*Q0 */ /* code in Q12 (Q9 for encoder) */
            move16();
        }
    }
    ELSE
    {
        test();
        test();
        IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
        {
#ifdef BASOP_NOGLOB
            pit_sharp = shl_sat( gain_pit, 1 ); /* saturation can occur here Q14 -> Q15 */
#else
            pit_sharp = shl( gain_pit, 1 );               /* saturation can occur here Q14 -> Q15 */
#endif
            /* saturation takes care of "if (pit_sharp > 1.0) { pit_sharp=1.0; }" */
            IF( GT_16( pit_sharp, 16384 ) )
            {
                tmp16 = mult( pit_sharp, 8192 );
                FOR( i = 0; i < L_SUBFR; i++ )
                {
                    /* excp[i] = pt_exc2[i] * pit_sharp * 0.25 */
                    excp[i] = mult_r( pt_exc2[i], tmp16 );
                    move16();
                }
            }
        }

        IF( EQ_16( L_frame, L_FRAME16k ) )
        {
            /* tmp = 0.150 * (1.0 + voice_fac) */
            /* 0.30=voiced, 0=unvoiced */
            tmp = mac_r( 0x13333333L, voice_fac, 4915 ); /*Q15 */
        }
        ELSE
        {
            /* tmp = 0.125 * (1.0 + voice_fac) */
            /* 0.25=voiced, 0=unvoiced */
            tmp = mac_r( 0x10000000L, voice_fac, 4096 ); /*Q15 */
        }

        /*-----------------------------------------------------------------
         * Do a simple noncasual "sharpening": effectively an FIR
         * filter with coefs [-tmp 1.0 -tmp] where tmp=0...0.25.
         * This is applied to code and add_fxed to exc2
         *-----------------------------------------------------------------*/
        /* pt_exc2[0] += code[0] - tmp * code[1] */
        L_tmp = L_deposit_h( code[0] );       /* if Enc :Q9 * Q15 -> Q25 */
        L_tmp = L_msu( L_tmp, code[1], tmp ); /* Q12 * Q15 -> Q28 */
#ifdef BASOP_NOGLOB
        L_tmp = L_shl_sat( L_mult( gain_code_hi, extract_h( L_tmp ) ), sc );
        pt_exc2[0] = msu_r_sat( L_tmp, -32768, pt_exc2[0] );
        move16();
#else
        L_tmp = L_shl( L_mult( gain_code_hi, extract_h( L_tmp ) ), sc );
        pt_exc2[0] = msu_r( L_tmp, -32768, pt_exc2[0] );
        move16();
#endif
        move16(); /* in Q_exc */

        FOR( i = 1; i < L_SUBFR - 1; i++ )
        {
            /* pt_exc2[i] += code[i] - tmp * code[i-1] - tmp * code[i+1] */
            L_tmp = L_msu( -32768, code[i], -32768 );
            L_tmp = L_msu( L_tmp, code[i + 1], tmp );
#ifdef BASOP_NOGLOB
            tmp16 = msu_r_sat( L_tmp, code[i - 1], tmp );
            L_tmp = L_shl_sat( L_mult( gain_code_hi, tmp16 ), sc );
            pt_exc2[i] = msu_r_sat( L_tmp, -32768, pt_exc2[i] );
            move16();
#else
            tmp16 = msu_r( L_tmp, code[i - 1], tmp );
            L_tmp = L_shl( L_mult( gain_code_hi, tmp16 ), sc );
            pt_exc2[i] = msu_r( L_tmp, -32768, pt_exc2[i] );
#endif
            move16(); /* in Q_exc */
        }

        /* pt_exc2[L_SUBFR-1] += code[L_SUBFR-1] - tmp * code[L_SUBFR-2] */
        L_tmp = L_deposit_h( code[L_SUBFR - 1] );       /*Q28 */
        L_tmp = L_msu( L_tmp, code[L_SUBFR - 2], tmp ); /*Q28 */
        L_tmp = L_shl( L_mult( gain_code_hi, extract_h( L_tmp ) ), sc );
#ifdef BASOP_NOGLOB
        pt_exc2[L_SUBFR - 1] = msu_r_sat( L_tmp, -32768, pt_exc2[L_SUBFR - 1] );
        move16();
#else
        pt_exc2[L_SUBFR - 1] = msu_r( L_tmp, -32768, pt_exc2[L_SUBFR - 1] );
        move16();
#endif
        move16(); /* in Q_exc */
        test();
        test();
        IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
        {
            IF( GT_16( pit_sharp, 16384 ) )
            {
                FOR( i = 0; i < L_SUBFR; i++ )
                {
                    /* excp[i] += pt_exc2[i] */
#ifdef BASOP_NOGLOB
                    excp[i] = add_sat( excp[i], pt_exc2[i] );
#else
                    excp[i] = add( excp[i], pt_exc2[i] );
#endif
                    move16();
                }
                agc2_fx( pt_exc2, excp, L_SUBFR );
                Copy( excp, pt_exc2, L_SUBFR );
            }
        }
    }
}

/*---------------------------------------------------------*
 * Enhancement of the excitation signal before synthesis
 *---------------------------------------------------------*/
+18 −0
Original line number Diff line number Diff line
@@ -5193,6 +5193,24 @@ void enhancer_ivas_fx(
    const Word16 Q_exc        /* i  : Q of the excitation                      */
);

void enhancer_ivas_fx2(
    const Word32 core_brate,  /* i  : decoder bitrate                          */
    const Word16 Opt_AMR_WB,  /* i  : flag indicating AMR-WB IO mode           */
    const Word16 coder_type,  /* i  : coder type                               */
    const Word16 i_subfr,     /* i  : subframe number                          */
    const Word16 L_frame,     /* i  : frame size                               */
    const Word16 voice_fac,   /* i  : subframe voicing estimation         Q15  */
    const Word16 stab_fac,    /* i  : LP filter stablility measure        Q15  */
    Word32 norm_gain_code,    /* i  : normalised innovative cb. gain   Q16  */
    const Word16 gain_inov,   /* i  : gain of the unscaled innovation     Q12  */
    Word32 *gc_threshold,     /* i/o: gain code threshold                 Q16  */
    Word16 *code,             /* i/o: innovation                          Q12  */
    Word16 *exc2,             /* i/o: adapt. excitation/total exc.        Q_exc*/
    const Word16 gain_pit,    /* i  : quantized pitch gain                Q14  */
    struct dispMem_fx *dm_fx, /* i/o: phase dispersion algorithm memory        */
    const Word16 Q_exc        /* i  : Q of the excitation                      */
);

Word16 E_UTIL_enhancer(
    Word16 voice_fac,       /* i  : subframe voicing estimation         Q15 */
    Word16 stab_fac,        /* i  : LP filter stability measure         Q15 */
+2 −2
Original line number Diff line number Diff line
@@ -856,7 +856,7 @@ ivas_error decod_gen_voic_ivas_fx(
        }
        ELSE
        {
            enhancer_fx( st_fx->core_brate, 0, st_fx->coder_type, i_subfr_fx, L_frame, voice_fac_fx, st_fx->stab_fac_fx,
            enhancer_ivas_fx2( st_fx->core_brate, 0, st_fx->coder_type, i_subfr_fx, L_frame, voice_fac_fx, st_fx->stab_fac_fx,
                               norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc );
        }

+8 −8
Original line number Diff line number Diff line
@@ -747,8 +747,8 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx(
    const Word16 nchan_in                                                           /* i  : number of input channels                              */
)
{
    Word16 cx_init_e[PARAM_MC_MAX_PARAMETER_BANDS];
    Word16 cx_init_imag_e[PARAM_MC_MAX_PARAMETER_BANDS];
    Word16 cx_init_e;
    Word16 cx_init_imag_e;
    Word16 band_idx, ch_idx;
    Word16 brange[2];
    Word32 real_in_buffer_fx[PARAM_MC_MAX_BANDS_IN_PARAMETER_BAND * MAX_TRANSPORT_CHANNELS];
@@ -809,9 +809,9 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx(
    v_add_fixed_me( cx_fx, *cx_e, real_buffer_fx, output_e, cx_fx, &tmp1_e, imult1616( nchan_in, nchan_in ), 1 );

    v_add_fixed_me( cx_imag_fx, *cx_imag_e, imag_buffer_fx, output_e, cx_imag_fx, &tmp2_e, imult1616( nchan_in, nchan_in ), 1 );
    cx_init_e[0] = tmp1_e;
    cx_init_e = tmp1_e;
    move16();
    cx_init_imag_e[0] = tmp2_e;
    cx_init_imag_e = tmp2_e;
    move16();

    // normalizing both the matrices to a common exponent for a better precision
@@ -822,18 +822,18 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx(

    FOR( j = 0; j < PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS; j++ )
    {
        L_tmp = BASOP_Util_Add_Mant32Exp( cx_fx[j], cx_init_e[0], 0, 0, &tmp1_e );
        L_tmp = BASOP_Util_Add_Mant32Exp( cx_imag_fx[j], cx_init_imag_e[0], 0, 0, &tmp2_e );
        L_tmp = BASOP_Util_Add_Mant32Exp( cx_fx[j], cx_init_e, 0, 0, &tmp1_e );
        L_tmp = BASOP_Util_Add_Mant32Exp( cx_imag_fx[j], cx_init_imag_e, 0, 0, &tmp2_e );
        tmp1 = s_max( tmp1, tmp1_e );
        tmp2 = s_max( tmp2, tmp2_e );
    }

    FOR( j = 0; j < PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS; j++ )
    {
        L_tmp = BASOP_Util_Add_Mant32Exp( cx_fx[j], cx_init_e[0], 0, 0, &tmp1_e );
        L_tmp = BASOP_Util_Add_Mant32Exp( cx_fx[j], cx_init_e, 0, 0, &tmp1_e );
        cx_fx[j] = L_shr( L_tmp, sub( tmp1, tmp1_e ) );
        move32();
        L_tmp = BASOP_Util_Add_Mant32Exp( cx_imag_fx[j], cx_init_imag_e[0], 0, 0, &tmp2_e );
        L_tmp = BASOP_Util_Add_Mant32Exp( cx_imag_fx[j], cx_init_imag_e, 0, 0, &tmp2_e );
        cx_imag_fx[j] = L_shr( L_tmp, sub( tmp2, tmp2_e ) );
        move32();
    }
+37 −21
Original line number Diff line number Diff line
@@ -2968,9 +2968,10 @@ void ivas_param_mc_dec_digest_tc_fx(
    Word32 cx_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS];
    Word32 cx_imag_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS];

    Word16 cx_buff_e[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS];
    Word16 cx_buff_e[2][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS];
    Word16 cx_e;
    Word16 cx_imag_e, tmp_e;
    Word16 cx_imag_next_band_e, cx_next_band_e;
    Word16 qout = 0;
    move16();

@@ -3055,9 +3056,10 @@ void ivas_param_mc_dec_digest_tc_fx(
        move16();
        cx_imag_e = 0;
        move16();
        // cldfb_slots = DEFAULT_JBM_CLDFB_TIMESLOTS;
        cx_next_band_e = 0;
        move16();
        cx_imag_next_band_e = 0;
        move16();

        /* slot loop for gathering the input data */
        FOR( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ )
        {
@@ -3099,9 +3101,9 @@ void ivas_param_mc_dec_digest_tc_fx(
                                                                                      &hParamMC->Cldfb_ImagBuffer_tc_fx[L_mult0( imult1616( slot_idx, hParamMC->num_freq_bands ), nchan_transport )],
                                                                                      /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6,
                                                                                      cx_next_band_fx,
                                                                                      &cx_e,
                                                                                      &cx_next_band_e,
                                                                                      cx_imag_next_band_fx,
                                                                                      &cx_imag_e,
                                                                                      &cx_imag_next_band_e,
                                                                                      hParamMC,
                                                                                      add( param_band_idx, is_next_band ),
                                                                                      nchan_transport );
@@ -3124,6 +3126,7 @@ void ivas_param_mc_dec_digest_tc_fx(
            }
        }

        Word16 tmp_cx_e, tmp_cx_imag_e;
        /* map from complex input covariance to real values */
        FOR( is_next_band = 0; is_next_band < 2; is_next_band++ )
        {
@@ -3137,11 +3140,15 @@ void ivas_param_mc_dec_digest_tc_fx(
            {
                pCx = &cx_next_band_fx[0];
                pCx_imag = &cx_imag_next_band_fx[0];
                tmp_cx_e = cx_next_band_e;
                tmp_cx_imag_e = cx_imag_next_band_e;
            }
            ELSE
            {
                pCx = &cx_fx[0];
                pCx_imag = &cx_imag_fx[0];
                tmp_cx_e = cx_e;
                tmp_cx_imag_e = cx_imag_e;
            }

            FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ )
@@ -3150,51 +3157,60 @@ void ivas_param_mc_dec_digest_tc_fx(
                imag_part_fx = pCx_imag[i];
                move32();
                move32();
                cx_buff_e[i] = cx_e;
                cx_buff_e[is_next_band][i] = tmp_cx_e;
                move16();
                /* (a-ib)(c+id) = ac + bd + i(ad-bc) */
                IF( LT_16( param_band_idx, hParamMC->max_param_band_abs_cov ) )
                {
                    L_tmp1 = Mpy_32_32( real_part_fx, real_part_fx );
                    L_tmp2 = Mpy_32_32( imag_part_fx, imag_part_fx );
                    L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp1, add( cx_e, cx_e ), L_tmp2, add( cx_imag_e, cx_imag_e ), &tmp_e );
                    L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp1, add( tmp_cx_e, tmp_cx_e ), L_tmp2, add( tmp_cx_imag_e, tmp_cx_imag_e ), &tmp_e );
                    pCx[i] = Sqrt32( L_tmp1, &tmp_e );
                    cx_fx[i] = Sqrt32( L_tmp1, &tmp_e );
                    move32();
                    cx_buff_e[i] = tmp_e;
                    cx_buff_e[is_next_band][i] = tmp_e;
                    move16();
                }
                ELSE
                {
                    pCx[i] = real_part_fx;
                    move32();
                    cx_buff_e[i] = cx_e;
                    cx_buff_e[is_next_band][i] = tmp_cx_e;
                    move16();
                }
            }
        }

        max_e = cx_buff_e[0];
        max_e = cx_buff_e[0][0];
        move16();

        /* Cx for transport channels */
        FOR( is_next_band = 0; is_next_band < 2; is_next_band++ )
        {
            FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ )
            {

            IF( LT_16( max_e, cx_buff_e[i] ) )
                IF( LT_16( max_e, cx_buff_e[is_next_band][i] ) )
                {
                max_e = cx_buff_e[i];
                    max_e = cx_buff_e[is_next_band][i];
                }
            }
        }

        /* Cx for transport channels */
        FOR( is_next_band = 0; is_next_band < 2; is_next_band++ )
        {
            FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ )
            {

            cx_fx[i] = L_shr( cx_fx[i], sub( max_e, cx_buff_e[i] ) );
                if ( is_next_band )
                {
                    cx_fx[i] = L_shr( cx_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) );
                }
                else
                {
                    cx_next_band_fx[i] = L_shr( cx_next_band_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) );
                }
                move32();
            }

        }
        cx_e = max_e;
        move16();

Loading