Commit 598b2736 authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Merge branch 'enc_funcs_fxd_2' into 'main'

acelp_core, mdct_core sub functions converted to fixed point

See merge request !603
parents 9044ab55 89009261
Loading
Loading
Loading
Loading
Loading
+130 −0
Original line number Diff line number Diff line
@@ -776,6 +776,136 @@ void cng_params_postupd_fx(
    return;
}

void cng_params_postupd_ivas_fx(
    const Word16 ho_circ_ptr,          /* i  : pointer for CNG averaging buffers                  Q0    */
    Word16 *cng_buf_cnt,               /* i/o: counter for CNG store buffers                      Q0    */
    const Word16 *const cng_exc2_buf,  /* i  : Excitation buffer                                  Q_exc */
    const Word16 *const cng_Qexc_buf,  /* i  : Q_exc buffer                                       Q0    */
    const Word32 *const cng_brate_buf, /* i  : bit rate buffer                                    Q0    */
    Word32 ho_env_circ[],              /* i/o: Envelope buffer                                          */
    const Word16 element_mode,         /* i  : Element mode                        */
    const Word16 bwidth                /* i  : Audio bandwidth                     */
)
{
    Word16 i, j;
    Word16 Q_exc;
    const Word16 *exc2;
    Word16 fft_io[L_FFT];
    Word32 sp[129];
    Word16 *ptR, *ptI;
    Word32 env[NUM_ENV_CNG];
    Word32 L_tmp;
    Word16 tmp;
    Word16 temp_lo_fx, temp_hi_fx;
    Word16 exp_pow;
    Word16 exp1;
    Word16 CNG_mode;
    Word16 ptr;
    Word32 last_active_brate;
#ifdef BASOP_NOGLOB_DECLARE_LOCAL
    Flag Overflow = 0;
    move32();
#endif

    ptr = add( sub( ho_circ_ptr, *cng_buf_cnt ), 1 );
    if ( ptr < 0 )
    {
        ptr = add( ptr, HO_HIST_SIZE );
    }

    FOR( j = 0; j < *cng_buf_cnt; j++ )
    {
        exc2 = &cng_exc2_buf[ptr * L_FFT];
        Q_exc = cng_Qexc_buf[ptr];
        move16();
        last_active_brate = cng_brate_buf[ptr];
        move32();

        /* calculate the spectrum of residual signal */
        Copy( exc2, fft_io, L_FFT );

        fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );

        ptR = &fft_io[1];
        ptI = &fft_io[L_FFT - 1];
        FOR( i = 0; i < NUM_ENV_CNG; i++ )
        {
            /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
#ifdef BASOP_NOGLOB
            L_tmp = L_mult_o( *ptR, *ptR, &Overflow );                              /* 2*Q_exc+1 */
            L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */
            L_tmp = L_add_o( L_tmp, L_tmp, &Overflow );                             /* 2*Q_exc+1 */
#else                                                                               /* BASOP_NOGLOB */
            L_tmp = L_mult( *ptR, *ptR );                    /* 2*Q_exc+1 */
            L_tmp = L_add( L_tmp, L_mult( *ptI, *ptI ) );    /* 2*Q_exc+1 */
            L_tmp = L_add( L_tmp, L_tmp );                   /* 2*Q_exc+1 */
#endif                                                                              /* BASOP_NOGLOB */
            L_tmp = Mult_32_16( L_tmp, 128 );                                       /* 2*Q_exc+1 */
            tmp = add( add( Q_exc, Q_exc ), 1 );
            sp[i] = L_shr( L_tmp, sub( tmp, 6 ) );
            move32(); /* Q6 */

            ptR++;
            ptI--;
        }

        Copy32( sp, env, NUM_ENV_CNG );

        test();
        IF( EQ_16( element_mode, IVAS_SCE ) || EQ_16( element_mode, IVAS_CPE_DFT ) )
        {
            Word32 att_fx = 0;
            move32();
            tmp = 0;
            move16();
            apply_scale( &att_fx, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
            att_fx = L_shr( Mpy_32_16_1( att_fx, 26214 ), 3 ); /* 26214 = 0.1f in Q18 */
            att_fx = BASOP_Util_fPow( 1342177280 /* 10 in Q27 */, 4, att_fx, 8, &tmp );
            tmp = extract_h( L_shl( att_fx, tmp ) );
        }
        ELSE
        {

            CNG_mode = get_cng_mode( last_active_brate );

            /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
            L_tmp = L_shl( L_deposit_l( ENR_ATT_fx[CNG_mode] ), 8 ); /* 16 */
            temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );

            exp_pow = sub( 14, temp_hi_fx );
            L_tmp = Pow2( 14, temp_lo_fx );             /* Qexp_pow */
            L_tmp = L_shl( L_tmp, sub( 13, exp_pow ) ); /* Q13 */
            tmp = extract_l( L_tmp );                   /* Q13 */

            exp1 = norm_s( tmp );
            tmp = shl( tmp, exp1 );           /*Q(exp1+13) */
            tmp = div_s( 16384, tmp );        /*Q(15+14-exp1-13) */
            tmp = shr( tmp, sub( 1, exp1 ) ); /* Q15 */
        }

        FOR( i = 0; i < NUM_ENV_CNG; i++ )
        {
            env[i] = Mult_32_16( env[i], tmp );
            move32();
        }

        /* update the circular buffer of old residual envelope */
        Copy32( env, &( ho_env_circ[(ptr) *NUM_ENV_CNG] ), NUM_ENV_CNG );

        ptr = add( ptr, 1 );
        if ( EQ_16( ptr, HO_HIST_SIZE ) )
        {
            ptr = 0;
            move16();
        }
    }

    *cng_buf_cnt = 0;
    move16();

    return;
}


/*-------------------------------------------------------*
 * cng_params_upd_fx()
+1 −1
Original line number Diff line number Diff line
@@ -652,7 +652,7 @@ void tcx5SpectrumInterleaving_fx(
}

/*-------------------------------------------------------------------*
 * tcx5SpectrumDeinterleaving()
 * tcx5SpectrumDeinterleaving_fx()
 *
 *
 *-------------------------------------------------------------------*/
+5 −5
Original line number Diff line number Diff line
@@ -716,18 +716,18 @@ Word32 getCoreSamplerateMode2(
    test();
    test();
    test();
    IF( bwidth == NB )
    IF( EQ_16( bwidth, NB ) )
    {
        sr_core = INT_FS_12k8;
        move32();
    }
    ELSE IF( element_mode == EVS_MONO && ( L_and( EQ_32( bwidth, WB ), LT_32( total_brate, ACELP_13k20 ) ) ||
    ELSE IF( EQ_16( element_mode, EVS_MONO ) && ( L_and( EQ_32( bwidth, WB ), LT_32( total_brate, ACELP_13k20 ) ) ||
                                                  L_and( EQ_32( bwidth, SWB ), LE_32( total_brate, ACELP_13k20 ) ) || EQ_16( rf_mode, 1 ) ) )
    {
        sr_core = INT_FS_12k8;
        move32();
    }
    ELSE IF( element_mode > EVS_MONO && flag_ACELP16k == 0 )
    ELSE IF( GT_16( element_mode, EVS_MONO ) && flag_ACELP16k == 0 )
    {
        sr_core = INT_FS_12k8;
        move32();
@@ -752,7 +752,7 @@ Word32 getCoreSamplerateMode2(
        sr_core = 25600;
        move32();
    }
    ELSE IF( ( element_mode == EVS_MONO && ( bwd_swb_or_fb_flag && LE_32( total_brate, HQ_64k ) ) ) || ( GT_16( element_mode, IVAS_SCE ) && ( ( EQ_16( bwidth, SWB ) && LE_32( total_brate, IVAS_96k ) ) || ( EQ_16( bwidth, FB ) && LE_32( total_brate, IVAS_96k ) ) ) ) )
    ELSE IF( ( EQ_16( element_mode, EVS_MONO ) && ( bwd_swb_or_fb_flag && LE_32( total_brate, HQ_64k ) ) ) || ( GT_16( element_mode, IVAS_SCE ) && ( ( EQ_16( bwidth, SWB ) && LE_32( total_brate, IVAS_96k ) ) || ( EQ_16( bwidth, FB ) && LE_32( total_brate, IVAS_96k ) ) ) ) )
    {
        sr_core = 25600;
        move32();
+382 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#include "cnst.h"
#include "rom_com.h"
#include "prot.h"
#include "prot_fx.h"
#include "wmc_auto.h"

/*-------------------------------------------------------------------*
@@ -263,6 +264,97 @@ static void GSC_gain_DQ(
    return;
}

static void GSC_gain_DQ_fx(
    const Word16 element_mode, /* i  : element mode                            */
    const Word16 enc_dec,      /* i  : encoder/decoder flag                    */
    const Word16 coder_type,   /* i  : Coder type                              */
    const Word16 Mbands_gn,    /* i  : Number of band                          */
    const Word32 core_brate,   /* i  : Core bitrate                            */
    const Word16 mean_g,       /* i  : Average gain Q12                            */
    const Word16 *Gain_in,     /* i  : Unquantized gain vector Q12                 */
    Word16 *Gain_out           /* o  : Level adjusted unquantized gain vector Q12  */
)
{
    Word16 Gain_off;
    Word16 i;

    /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
    Gain_off = 0;
    move16();

    test();
    IF( coder_type == INACTIVE || EQ_16( coder_type, UNVOICED ) )
    {
        test();
        IF( LE_32( core_brate, ACELP_5k00 ) && EQ_16( coder_type, UNVOICED ) )
        {
            Gain_off = 1843; // 9/20 in Q12
            move16();
        }
        ELSE IF( LE_32( core_brate, ACELP_7k20 ) )
        {
            Gain_off = 1638; // 8/20 in Q12; /* 0 dB */
            move16();
        }
        ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
        {
            Gain_off = 1351; // 6.6f/20 in Q12 /* ~-3.3 dB */
            move16();
        }
        ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
        {
            Gain_off = 983; // 4.8f/20 in Q12 /* ~-2.4 dB */
            move16();
        }
        ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
        {
            Gain_off = 717; // 3.5f/20 in Q12 /* ~-2.4 dB */
            move16();
        }
        ELSE IF( LE_32( core_brate, ACELP_13k20 ) )
        {
            Gain_off = 614; // 3.0f/20 in Q12 /* ~-2.4 dB */
            move16();
        }
    }

    test();
    IF( coder_type != INACTIVE && NE_16( coder_type, UNVOICED ) )
    {
        FOR( i = 0; i < Mbands_gn; i++ )
        {
            Gain_out[i] = add( Gain_in[i], mean_g ); // Q12
            move16();
        }
    }
    ELSE
    {
        /*mimic ACELP decay of energy for low rates*/
        test();
        IF( element_mode == EVS_MONO && EQ_16( enc_dec, DEC ) )
        {
            /* This is to keep EVS mono bit-exact with the standard (there might be a small desynchronization between encoder and decoder but there is no real quality or interop. issue) */
            FOR( i = 0; i < Mbands_gn; i++ )
            {
                Gain_out[i] = add( Gain_out[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12
                move16();
                // Gain_out[i] += mean_g - i * ( Gain_off / 20.f ) / ( (float) Mbands_gn );
            }
        }
        ELSE
        {
            FOR( i = 0; i < Mbands_gn; i++ )
            {
                Gain_out[i] = add( Gain_in[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12
                move16();
                // Gain_out[i] = Gain_in[i] + mean_g - ( i * ( Gain_off / 20.f ) / ( (float) Mbands_gn ) );
            }
        }
    }

    return;
}


/*-------------------------------------------------------------------*
 * gsc_gainQ()
@@ -495,6 +587,296 @@ float gsc_gainQ(
    return mean_4g[0];
}

Word16 gsc_gainQ_ivas_fx(
    BSTR_ENC_HANDLE hBstr,      /* i/o: encoder bitstream handle     */
    const int16_t element_mode, /* i  : element mode                 */
    const int16_t idchan,       /* i  : channel ID                   */
    const Word16 y_gain4[],
    /* i  : Energy per band              */ // Q12
    Word16 y_gainQ[],
    /* o  : quantized energy per band    */ // Q12
    const int32_t core_brate,               /* i  : Core rate                    */
    const int16_t coder_type,               /* i  : coding type                  */
    const int16_t bwidth,                   /* i  : input signal bandwidth       */
    const int16_t L_frame,                  /* i  : frame length                 */
    const int16_t tdm_LRTD_flag,            /* i  : LRTD stereo mode flag        */
    const int32_t core_brate_inp            /* i  : true core bitrate            */
)
{
    Word16 y_gain_tmp[MBANDS_GN16k];
    Word16 y_gain_tmp2[MBANDS_GN16k];
    Word16 i, idx_g = 0;
    move16();
    Word16 mean_4g_fx[1], ftmp1_fx;
    Word16 Mbands_gn = MBANDS_GN;
    Word16 y_gain_tmp3[MBANDS_GN];
    Word32 L_tmp;

    IF( EQ_16( L_frame, L_FRAME16k ) )
    {
        Mbands_gn = MBANDS_GN16k;
        move16();
    }

    mean_4g_fx[0] = 0;
    move32();

    test();
    test();
    IF( ( EQ_16( coder_type, AUDIO ) || coder_type == INACTIVE ) && bwidth == NB )
    {
        L_tmp = 0;
        move32();
        FOR( i = 0; i < 10; i++ )
        {
            L_tmp = L_add( L_tmp, y_gain4[i] );
        }
        L_tmp = L_sub( Mpy_32_16_1( L_tmp, 3277 /* (1/10.0f) in Q15 */ ), 2457 /* 0.6f in Q12 */ ); // Q12
        ftmp1_fx = extract_l( L_tmp );
        FOR( i = 0; i < Mbands_gn; i++ )
        {
            IF( LT_16( y_gain4[i], ftmp1_fx ) )
            {
                y_gain_tmp2[i] = ftmp1_fx;
            }
            ELSE
            {
                y_gain_tmp2[i] = y_gain4[i];
            }
            move16();
        }

        /* Quantized mean gain without clipping */
        L_tmp = 0;
        move32();
        FOR( i = 0; i < 10; i++ )
        {
            L_tmp = L_add( L_tmp, y_gain4[i] );
        }
        L_tmp = Mpy_32_16_1( L_tmp, 3277 /* (1/10.0f) in Q15 */ ); // Q12
        mean_4g_fx[0] = extract_l( L_tmp );                        // Q12
        move16();
        idx_g = vquant_fx( mean_4g_fx, Gain_meanNB_fx, mean_4g_fx, Gain_mean_dicNB_fx, 1, 64 );
        push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );

        FOR( i = 0; i < Mbands_gn; i++ )
        {
            y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12
            move16();
        }

        IF( LT_16( y_gain_tmp[9], -1229 /* -0.3f in Q12 */ ) )
        {
            y_gain_tmp[9] = -1229; /* -0.3f in Q12 */
            move16();
        }

        set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
        idx_g = vquant_fx( y_gain_tmp, Mean_dic_NB_fx, y_gain_tmp, Gain_dic1_NB_fx, 3, 64 );
        push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );

        IF( LT_32( core_brate, ACELP_9k60 ) )
        {
            idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NB_fx, 3, 32 );
            push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );

            idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NB_fx, 4, 16 );
            push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
        }
        ELSE
        {
            idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NBHR_fx, 3, 64 );
            push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );

            idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NBHR_fx, 4, 128 );
            push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
        }

        test();
        IF( LE_32( core_brate, ACELP_9k60 ) && coder_type == INACTIVE )
        {
            /* Some energy is needed in high band for stat_noise_uv_enc() to be functional in inactive speech */
            y_gain_tmp[10] = mean_fx( y_gain_tmp + 6, 3 );
            move16();
            y_gain_tmp[11] = mean_fx( y_gain_tmp + 7, 3 );
            move16();
            y_gain_tmp[12] = mean_fx( y_gain_tmp + 8, 3 );
            move16();
            y_gain_tmp[13] = mean_fx( y_gain_tmp + 9, 3 );
            move16();
            y_gain_tmp[14] = mean_fx( y_gain_tmp + 10, 3 );
            move16();
            y_gain_tmp[15] = mean_fx( y_gain_tmp + 11, 3 );
            move16();
        }
        ELSE
        {
            set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
        }
    }
    ELSE
    {
        L_tmp = 0;
        move32();
        FOR( i = 0; i < 16; i++ )
        {
            L_tmp = L_add( L_tmp, y_gain4[i] );
        }
        L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12
        ftmp1_fx = extract_l( L_tmp );
        FOR( i = 0; i < Mbands_gn; i++ )
        {
            IF( LT_16( y_gain4[i], sub( ftmp1_fx, 2457 ) ) )
            {
                y_gain_tmp2[i] = sub( ftmp1_fx, 2457 );
            }
            ELSE IF( GT_16( y_gain4[i], add( ftmp1_fx, 2457 ) ) )
            {
                y_gain_tmp2[i] = add( ftmp1_fx, 2457 );
            }
            ELSE
            {
                y_gain_tmp2[i] = y_gain4[i];
            }
            move16();
        }

        L_tmp = 0;
        move32();
        FOR( i = 0; i < 16; i++ )
        {
            L_tmp = L_add( L_tmp, y_gain_tmp2[i] );
        }
        L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12
        mean_4g_fx[0] = extract_l( L_tmp );                       // Q12
        move16();
        idx_g = vquant_fx( mean_4g_fx, mean_m_fx, mean_4g_fx, mean_gain_dic_fx, 1, 64 );
        push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );

        /* Subtraction of the average gain */
        FOR( i = 0; i < Mbands_gn; i++ )
        {
            y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12
            move16();
        }

        IF( LT_32( core_brate, ACELP_9k60 ) )
        {
            /* prediction and quantization of the average gain */

            /*--------------------------------------------------------------------------------------*
             * Quantization of the first 8 bands
             * Keep only 4 bands out of the last 8 bands
             *--------------------------------------------------------------------------------------*/

            Copy( y_gain_tmp, y_gain_tmp2, 8 );

            y_gain_tmp2[8] = y_gain_tmp[8];
            move16();
            y_gain_tmp2[9] = y_gain_tmp[10];
            move16();
            y_gain_tmp2[10] = y_gain_tmp[12];
            move16();
            y_gain_tmp2[11] = y_gain_tmp[14];
            move16();

            idx_g = 0;
            move16();
            idx_g = vquant_fx( y_gain_tmp2, YGain_mean_LR_fx, y_gain_tmp2, YGain_dic1_LR_fx, 3, 32 );
            push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );

            test();
            test();
            test();
            IF( !( coder_type == INACTIVE && tdm_LRTD_flag == 0 && EQ_16( idchan, 1 ) ) || GT_32( core_brate_inp, GSC_LRES_GAINQ_LIMIT ) )
            {
                idx_g = vquant_fx( y_gain_tmp2 + 3, YGain_mean_LR_fx + 3, y_gain_tmp2 + 3, YGain_dic2_LR_fx, 4, 32 );
                push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );

                /*----------------------------------------------------------------------*
                 * Vector quantization of the first 8 bands + quantization of the 4 bands out of the last 8
                 * Interpolation of the last 4 bands Q to create bands 8-16
                 *----------------------------------------------------------------------*/

                idx_g = vquant_fx( y_gain_tmp2 + 7, YGain_mean_LR_fx + 7, y_gain_tmp2 + 7, YGain_dic3_LR_fx, 5, 32 );
                push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );

                set16_fx( y_gain_tmp2 + 12, 0, MBANDS_GN - 12 );

                /* Update to quantized vector */
                Copy( y_gain_tmp2, y_gain_tmp, 8 );

                Copy( y_gain_tmp2 + 8, y_gain_tmp3, 4 );
                set16_fx( y_gain_tmp + 8, 0, 8 );
                fft_rel_fx( y_gain_tmp2 + 8, 4, 2 );

                Copy( y_gain_tmp2 + 8, y_gain_tmp + 8, 3 );
                y_gain_tmp[15] = y_gain_tmp2[11];
                move16();
                ifft_rel_fx( y_gain_tmp + 8, 8, 3 );

                FOR( i = 8; i < 16; i++ )
                {
                    y_gain_tmp[i] = shl( mult( y_gain_tmp[i], 23101 ), 1 );
                    move16();
                }

                y_gain_tmp[8] = y_gain_tmp3[0];
                move16();
                y_gain_tmp[10] = y_gain_tmp3[1];
                move16();
                y_gain_tmp[12] = y_gain_tmp3[2];
                move16();
                y_gain_tmp[14] = y_gain_tmp3[3];
                move16();
            }
            ELSE
            {
                Copy( y_gain_tmp2, y_gain_tmp, 3 );
                set16_fx( y_gain_tmp + 3, 0, MBANDS_GN16k - 3 );
            }
        }
        ELSE
        {
            IF( EQ_16( L_frame, L_FRAME ) )
            {
                idx_g = vquant_fx( y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64 );
                push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );

                idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16_fx + 4, y_gain_tmp + 4, YG_dicMR_2_fx, 4, 32 );
                push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );

                idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16_fx + 8, y_gain_tmp + 8, YG_dicMR_3_fx, 4, 32 );
                push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );

                idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16_fx + 12, y_gain_tmp + 12, YG_dicMR_4_fx, 4, 16 );
                push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
            }
            ELSE
            {
                idx_g = vquant_fx( y_gain_tmp, YG_mean16HR_fx, y_gain_tmp, YG_dicHR_1_fx, 4, 128 );
                push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );

                idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16HR_fx + 4, y_gain_tmp + 4, YG_dicHR_2_fx, 4, 64 );
                push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );

                idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16HR_fx + 8, y_gain_tmp + 8, YG_dicHR_3_fx, 4, 64 );
                push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );

                idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16HR_16kHz_fx, y_gain_tmp + 12, YG_dicHR_4_16kHz_fx, 4, 64 );
                push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );

                idx_g = vquant_fx( y_gain_tmp + 16, YG_meanL2G_16kHz_fx, y_gain_tmp + 16, YG_dicL2G_16kHz_fx, 2, 8 );
                push_indice( hBstr, IND_Y_GAIN_HF, idx_g, 3 );
            }
        }
    }

    GSC_gain_DQ_fx( element_mode, ENC, coder_type, Mbands_gn, core_brate, mean_4g_fx[0], y_gain_tmp, y_gainQ );

    return mean_4g_fx[0];
}

/*-------------------------------------------------------------------*
 * gsc_gaindec()
 *
+115 −0
Original line number Diff line number Diff line
@@ -387,6 +387,121 @@ void Ener_per_band_comp_ivas_fx(

    return;
}
void Ener_per_band_comp_ivas_fx_2(
    const Word16 exc_diff[], /* i  : target signal  Q_exc              */
    Word16 y_gain4[],        /* o  : Energy per band to quantize Q12  */
    const Word16 Q_exc,
    const Word16 Mband,  /* i  : Max band                    */
    const Word16 Eflag,  /* i  : flag of highest band        */
    const Word16 L_frame /* i  : frame length                */
)
{
    Word32 etmp, L_tmp;
    Word16 etmp_e;
    const Word16 *pt;
    Word16 i, j, tmp;
    tmp = add( shl( sub( Q15, Q_exc ), 1 ), 1 );

    pt = exc_diff;
    FOR( j = 0; j < 2; j++ )
    {
        y_gain4[j] = 0;
        move16();
        etmp = 42949673; /* 0.02 in Q31 */
        move32();
        etmp_e = 0;
        move16();

        pt = exc_diff + shl( j, 3 );
        FOR( i = 0; i < 8; i++ )
        {
            etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
            pt++;
        }

        /* normalized to 16 bins to easy the quantization */
        etmp_e = add( etmp_e, 1 );
        etmp = Sqrt32( etmp, &etmp_e );
        etmp = BASOP_Util_Log10( etmp, etmp_e );    // Q25
        y_gain4[j] = extract_h( L_shl( etmp, 3 ) ); // Q12
        move16();
    }

    FOR( j = 1; j < Mband - 2; j++ )
    {
        etmp = 21474836; /* 0.01 in Q31 */
        move32();
        etmp_e = 0;
        move16();

        pt = exc_diff + shl( j, 4 );
        FOR( i = 0; i < 16; i++ )
        {
            etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
            pt++;
        }

        etmp = Sqrt32( etmp, &etmp_e );
        etmp = BASOP_Util_Log10( etmp, etmp_e );        // Q25
        y_gain4[j + 1] = extract_h( L_shl( etmp, 3 ) ); // Q12
        move16();
    }

    IF( EQ_16( Eflag, 1 ) )
    {
        etmp = 21474836; /* 0.01 in Q31 */
        move32();
        etmp_e = 0;
        move16();

        pt = exc_diff + shl( j, 4 );
        FOR( i = 0; i < 32; i++ )
        {
            etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
            pt++;
        }

        etmp_e = sub( etmp_e, 1 );
        etmp = Sqrt32( etmp, &etmp_e );
        etmp = BASOP_Util_Log10( etmp, etmp_e );        // Q25
        y_gain4[j + 1] = extract_h( L_shl( etmp, 3 ) ); // Q12
        move16();
    }

    IF( EQ_16( L_frame, L_FRAME16k ) )
    {
        etmp = 21474836; /* 0.01 in Q31 */
        move32();
        etmp_e = 0;
        move16();

        FOR( i = 0; i < 32; i++ )
        {
            etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
            pt++;
        }

        Word16 tmp2 = sub( etmp_e, 1 );
        L_tmp = Sqrt32( etmp, &tmp2 );
        L_tmp = BASOP_Util_Log10( L_tmp, tmp2 );         // Q25
        y_gain4[j + 2] = extract_h( L_shl( L_tmp, 3 ) ); // Q12
        move16();

        FOR( i = 0; i < 32; i++ )
        {
            etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
            pt++;
        }

        etmp_e = sub( etmp_e, 1 );
        etmp = Sqrt32( etmp, &etmp_e );
        etmp = BASOP_Util_Log10( etmp, etmp_e );        // Q25
        y_gain4[j + 3] = extract_h( L_shl( etmp, 3 ) ); // Q12
        move16();
    }

    return;
}

/*-------------------------------------------------------------------*
 * gsc_gainQ()
Loading