Commit 72341df7 authored by Archit Tamarapu's avatar Archit Tamarapu
Browse files

Merge branch 'main' of ssh://forge.3gpp.org:29419/sa4/audio/ivas-basop into...

Merge branch 'main' of ssh://forge.3gpp.org:29419/sa4/audio/ivas-basop into basop-2478-harmonize-enc_prm_hm-and-enc_prm_hm_ivas_fx
parents 3e20f69d 6c4812f3
Loading
Loading
Loading
Loading
Loading
+12 −9
Original line number Diff line number Diff line
@@ -242,7 +242,7 @@ static Word16 rate2AMRWB_IOmode(
        case ACELP_23k85:
            return AMRWB_IO_2385;
        default:
            break;
            BREAK;
    }

    return -1;
@@ -298,7 +298,7 @@ Word16 rate2EVSmode(
        case HQ_128k:
            return PRIMARY_128000;
        default:
            break;
            BREAK;
    }

    if ( is_amr_wb != NULL )
@@ -3206,12 +3206,15 @@ Word16 find_indice(
{
    Word16 i;

    for ( i = 0; i < hBstr->nb_ind_tot; i++ )
    FOR( i = 0; i < hBstr->nb_ind_tot; i++ )
    {
        if ( hBstr->ind_list[i].id == id && hBstr->ind_list[i].nb_bits > 0 )
        test();
        IF( EQ_16( hBstr->ind_list[i].id, id ) && hBstr->ind_list[i].nb_bits > 0 )
        {
            *value = hBstr->ind_list[i].value;
            *nb_bits = hBstr->ind_list[i].nb_bits;
            move16();
            move16();
            return i;
        }
    }
@@ -3273,7 +3276,7 @@ UWord16 delete_indice(
#endif
    }

    return i - j;
    return sub( i, j );
}


@@ -3949,13 +3952,13 @@ static void decoder_selectCodec(
                case 2800:
                    st->codec_mode = MODE1;
                    move16();
                    break;
                    BREAK;
                default: /* validate that total_brate (derived from RTP packet or a file header) is one of the defined bitrates  */
                    st->codec_mode = st->last_codec_mode;
                    move16();
                    st->bfi = 1;
                    move16();
                    break;
                    BREAK;
            }
        }
    }
@@ -4417,7 +4420,7 @@ void ivas_set_bitstream_pointers(
    num_bits = 0;

    /* set bitstream pointers for SCEs */
    for ( k = 0; k < st_ivas->nSCE; k++ )
    FOR( k = 0; k < st_ivas->nSCE; k++ )
    {
        sts = st_ivas->hSCE[k]->hCoreCoder;
        sts[0]->bit_stream = st_ivas->bit_stream + num_bits;
@@ -4425,7 +4428,7 @@ void ivas_set_bitstream_pointers(
    }

    /* set bitstream pointers for CPEs */
    for ( k = 0; k < st_ivas->nCPE; k++ )
    FOR( k = 0; k < st_ivas->nCPE; k++ )
    {
        sts = st_ivas->hCPE[k]->hCoreCoder;
        sts[0]->bit_stream = st_ivas->bit_stream + num_bits;
+0 −4
Original line number Diff line number Diff line
@@ -872,11 +872,7 @@ void cng_params_upd_fx(
            Word16 index = 0;
            move32();
            move16();
#ifdef HARM_2456_APPLY_SCALE
            index = apply_scale_ind( &att_fx, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
#else
            apply_scale_ivas_fx( &att_fx, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO, &index );
#endif
            att_fx = pow_10_q23[index]; // Q23
            move32();
            tmp = extract_h( att_fx ); // Q7
+2 −33
Original line number Diff line number Diff line
@@ -166,9 +166,6 @@ void initFdCngCom(

    set16_fx( hFdCngCom->coherence_fx, 16384 /* 0.5 in Q15 */, MDCT_ST_DTX_NUM_COHERENCE_BANDS );

#ifndef FIX_BASOP_2262_OLAP_BUFFER_SYNTH_SWITCHING
    set32_fx( hFdCngCom->olapBufferSynth_fx, 0, FFTLEN );
#endif
#ifndef FIX_BASOP_REMOVE_SYNTH2_FX
    set32_fx( hFdCngCom->olapBufferSynth2_fx, 0, FFTLEN );
#endif
@@ -1759,34 +1756,6 @@ Word16 apply_scale_ind(
    return i;
}

#ifndef HARM_2456_APPLY_SCALE
void apply_scale_ivas_fx(
    Word32 *scale,                 /* o  : scalefactor             */
    const Word16 bwmode,           /* i  : audio bandwidth         */
    const Word32 bitrate,          /* i  : Bit rate                */
    const SCALE_SETUP *scaleTable, /* i  : Scale table Q7             */
    const Word16 scaleTableSize,   /* i  : Size of scale table     */
    Word16 *index )
{
    Word16 i;
    FOR( i = 0; i < scaleTableSize; i++ )
    {
        cast16();
        IF( s_and( (Word16) EQ_16( bwmode, (Word16) scaleTable[i].bwmode ),
                   s_and( L_sub( bitrate, scaleTable[i].bitrateFrom ) >= 0,
                          L_sub( bitrate, scaleTable[i].bitrateTo ) < 0 ) ) )
        {
            BREAK;
        }
    }
    assert( i < scaleTableSize );

    *scale = L_add( *scale, L_deposit_h( scaleTable[i].scale ) );
    move32();
    *index = i;
    move16();
}
#endif
/*-------------------------------------------------------------------
 * bandcombinepow()
 *
@@ -3290,11 +3259,11 @@ void SynthesisSTFT_dirac_fx(
        case 640:
            fftScale = FFT_SCALING_640;
            move32();
            break;
            BREAK;
        case 512:
            fftScale = FFT_SCALING_512;
            move32();
            break;
            BREAK;
        default:
            assert( !"Not supported FFT length!" );
    }
+0 −273
Original line number Diff line number Diff line
@@ -43,7 +43,6 @@
#include "ivas_prot_fx.h"


#ifdef HARM_HQ_CORE
/*--------------------------------------------------------------------------*
 * fill_spectrum()
 *
@@ -53,9 +52,6 @@
 *--------------------------------------------------------------------------*/

void fill_spectrum_fx(
#else
void ivas_fill_spectrum_fx(
#endif
    Word16 *coeff,                    /* i/o: normalized MLT spectrum / nf spectrum                Q12 */
    Word32 *L_coeff_out,              /* i/o: Noisefilled MLT spectrum                             Q12 */
    const Word16 *R,                  /* i  : number of pulses per band                            Q0  */
@@ -265,11 +261,7 @@ void ivas_fill_spectrum_fx(
    test();
    IF( EQ_16( HQ_mode, HQ_HARMONIC ) )
    {
#ifdef HARM_HQ_CORE
        harm_bwe_fx( coeff_fine, coeff, num_sfm, sfm_start, sfm_end, last_sfm, R, prev_hq_mode, norm, noise_level, prev_noise_level, bwe_seed, L_coeff_out, element_mode );
#else
        ivas_harm_bwe_fx( coeff_fine, coeff, num_sfm, sfm_start, sfm_end, last_sfm, R, prev_hq_mode, norm, noise_level, prev_noise_level, bwe_seed, L_coeff_out, element_mode );
#endif
    }
    ELSE IF( EQ_16( HQ_mode, HQ_HVQ ) )
    {
@@ -278,11 +270,7 @@ void ivas_fill_spectrum_fx(
    }
    ELSE IF( EQ_16( HQ_mode, HQ_GEN_SWB ) || EQ_16( HQ_mode, HQ_GEN_FB ) )
    {
#ifdef HARM_HQ_CORE
        hq_bwe_fx( element_mode, HQ_mode, L_coeff_out1, hq_generic_fenv, L_coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, sfm_end, num_sfm, num_env_bands, R );
#else
        hq_bwe_ivas_fx( HQ_mode, L_coeff_out1, hq_generic_fenv, L_coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, sfm_end, num_sfm, num_env_bands, R );
#endif
    }

    /*----------------------------------------------------------------*
@@ -325,264 +313,3 @@ void ivas_fill_spectrum_fx(

    return;
}
#ifndef HARM_HQ_CORE
void fill_spectrum_fx(
    Word16 *coeff,                    /* i/o: normalized MLT spectrum / nf spectrum                Q12 */
    Word32 *L_coeff_out,              /* i/o: Noisefilled MLT spectrum                             Q12 */
    const Word16 *R,                  /* i  : number of pulses per band                            Q0  */
    const Word16 is_transient,        /* i  : transient flag                                       Q0  */
    Word16 norm[],                    /* i  : quantization indices for norms                       Q0  */
    const Word16 *hq_generic_fenv,    /* i  : HQ GENERIC envelope                                  Q1  */
    const Word16 hq_generic_offset,   /* i  : HQ GENERIC offset                                    Q0  */
    const Word16 nf_idx,              /* i  : noise fill index                                     Q0  */
    const Word16 length,              /* i  : Length of spectrum (32 or 48 kHz)                    Q0  */
    const Word16 env_stab,            /* i  : Envelope stability measure [0..1]                    Q15 */
    Word16 *no_att_hangover,          /* i/o: Frame counter for attenuation hangover               Q0  */
    Word32 *L_energy_lt,              /* i/o: Long-term energy measure for transient detection     Q13 */
    Word16 *bwe_seed,                 /* i/o: random seed for generating BWE input                 Q0  */
    const Word16 hq_generic_exc_clas, /* i  : BWE excitation class                                 Q0  */
    const Word16 core_sfm,            /* i  : index of the end band for core                       Q0  */
    const Word16 HQ_mode,             /* i  : HQ mode                                              Q0  */
    Word16 noise_level[],             /* i  : noise levels for harmonic modes                      Q15 */
    const Word32 L_core_brate,        /* i  : target bit-rate                                      Q0  */
    Word16 prev_noise_level[],        /* i/o: noise factor in previous frame                       Q15 */
    Word16 *prev_R,                   /* i/o: bit allocation info. in previous frame               Q0  */
    Word32 *prev_coeff_out,           /* i/o: decoded spectrum in previous frame                   Q12 */
    const Word16 *peak_idx,           /* i  : peak indices for hvq                                 Q0  */
    const Word16 Npeaks,              /* i  : number of peaks in hvq                               Q0  */
    const Word16 *npulses,            /* i  : number of pulses per band                            Q0  */
    const Word16 prev_is_transient,   /* i  : previous transient flag                              Q0  */
    Word32 *prev_normq,               /* i/o: previous norms                                       Q14 */
    Word32 *prev_env,                 /* i/o: previous noise envelopes                             Q(prev_env_Q) */
    const Word16 prev_bfi,            /* i  : previous bad frame indicator                         Q0  */
    const Word16 *sfmsize,            /* i  : Length of bands                                      Q0  */
    const Word16 *sfm_start,          /* i  : Start of bands                                       Q0  */
    const Word16 *sfm_end,            /* i  : End of bands                                         Q0  */
    Word16 *prev_L_swb_norm,          /* i/o: HVQ/Harmonic mode normalization length               Q0  */
    const Word16 prev_hq_mode,        /* i  : Previous HQ mode                                     Q0  */
    const Word16 num_sfm,             /* i  : Total number of bands                                Q0  */
    Word16 *prev_env_Q,
    const Word16 num_env_bands, /* i  : Number sub bands to be encoded for HQ_GEN            Q0  */
    const Word16 element_mode   /* i  : IVAS element mode */
)
{
    Word16 CodeBook[FREQ_LENGTH]; /* Q12 */
    Word16 cb_size;
    Word16 last_sfm;
    Word16 CodeBook_mod[FREQ_LENGTH]; /*Q12 */
    Word16 norm_adj[NB_SFM];          /*Q15 */
    Word16 high_sfm;
    Word16 flag_32K_env_hangover;
    Word16 bin_th;
    Word16 peak_pos[L_HARMONIC_EXC];
    Word16 bwe_peaks[L_FRAME48k];
    Word32 L_normq_v[NB_SFM];           /*Q14 */
    Word16 coeff_fine[L_SPEC48k_EXT];   /*Q15 */
    Word32 L_coeff_out1[L_SPEC48k_EXT]; /*Q12 */
    set16_fx( peak_pos, 0, L_HARMONIC_EXC );
    set16_fx( bwe_peaks, 0, L_FRAME48k );
    set16_fx( norm_adj, 32767, num_sfm ); /* 1.0, Q15 */
    cb_size = 0;
    move16();
    bin_th = 0;
    move16();
    high_sfm = 23;
    move16();

    test();
    IF( EQ_16( HQ_mode, HQ_TRANSIENT ) )
    {
        last_sfm = sub( num_sfm, 1 );
    }
    ELSE IF( EQ_16( HQ_mode, HQ_GEN_SWB ) || EQ_16( HQ_mode, HQ_GEN_FB ) )
    {
        last_sfm = s_max( core_sfm, sub( num_env_bands, 1 ) );
    }
    ELSE
    {
        last_sfm = core_sfm;
        move16();
    }

    IF( EQ_16( HQ_mode, HQ_HARMONIC ) )
    {
        /*high_sfm = (core_brate == HQ_BWE_CROSSOVER_BRATE) ? HVQ_THRES_SFM_24k-1 : HVQ_THRES_SFM_32k-3; */
        high_sfm = sub( HVQ_THRES_SFM_32k, 1 );
        if ( LT_32( L_core_brate, HQ_BWE_CROSSOVER_BRATE ) )
        {
            high_sfm = sub( HVQ_THRES_SFM_24k, 1 );
        }

        if ( LT_16( last_sfm, high_sfm ) )
        {
            last_sfm = high_sfm;
            move16();
        }
    }
    ELSE IF( EQ_16( HQ_mode, HQ_HVQ ) )
    {
        bin_th = sfm_end[last_sfm];
        move16();
    }

    /* Transient analysis for envelope stability measure */
    IF( EQ_16( length, L_FRAME32k ) )
    {
        env_stab_transient_detect_fx( is_transient, length, norm, no_att_hangover, L_energy_lt, HQ_mode, bin_th, L_coeff_out, 12 );
    }

    test();
    test();
    test();
    test();
    IF( EQ_16( length, L_FRAME16k ) ||
        ( ( EQ_16( length, L_FRAME32k ) && NE_16( HQ_mode, HQ_HARMONIC ) && NE_16( HQ_mode, HQ_HVQ ) ) && *no_att_hangover == 0 ) )
    {
        /* Norm adjustment function */
        env_adj_fx( npulses, length, last_sfm, norm_adj, env_stab, sfmsize );
    }

    /*flag_32K_env_hangover = ( length == L_FRAME32k && ( (env_stab < 0.5f && *no_att_hangover == 0) || HQ_mode == HQ_HVQ ) );   */
    flag_32K_env_hangover = 0;
    move16();
    test();
    test();
    test();
    if ( EQ_16( length, L_FRAME32k ) && ( ( LT_16( env_stab, 16384 /*0.5.Q15*/ ) && *no_att_hangover == 0 ) || EQ_16( HQ_mode, HQ_HVQ ) ) )
    {
        flag_32K_env_hangover = 1;
        move16();
    }


    /*----------------------------------------------------------------*
     * Build noise-fill codebook
     *----------------------------------------------------------------*/

    IF( NE_16( HQ_mode, HQ_HVQ ) )
    {
        cb_size = build_nf_codebook_fx( flag_32K_env_hangover, coeff, sfm_start, sfmsize, sfm_end, last_sfm, R, CodeBook, CodeBook_mod );
    }
    /*----------------------------------------------------------------*
     * Prepare fine structure for Harmonic and HVQ
     *----------------------------------------------------------------*/

    IF( EQ_16( HQ_mode, HQ_HARMONIC ) )
    {
        harm_bwe_fine_fx( R, last_sfm, high_sfm, num_sfm, norm, sfm_start, sfm_end, prev_L_swb_norm, coeff, L_coeff_out, coeff_fine );
    }
    ELSE IF( EQ_16( HQ_mode, HQ_HVQ ) )
    {
        hvq_bwe_fine_fx( last_sfm, num_sfm, sfm_end, peak_idx, Npeaks, peak_pos, prev_L_swb_norm, L_coeff_out, bwe_peaks, coeff_fine );
    }

    /*----------------------------------------------------------------*
     * Apply noise-fill
     *----------------------------------------------------------------*/

    test();
    IF( NE_16( HQ_mode, HQ_HVQ ) && cb_size > 0 )
    {
        apply_noisefill_HQ_fx( R, length, flag_32K_env_hangover, L_core_brate, last_sfm, CodeBook,
                               CodeBook_mod, cb_size, sfm_start, sfm_end, sfmsize, coeff );
    }

    /*----------------------------------------------------------------*
     * Normal mode BWE
     *----------------------------------------------------------------*/

    IF( HQ_mode == HQ_NORMAL )
    {
        hq_fold_bwe_fx( last_sfm, sfm_end, num_sfm, coeff );
    }

    /*----------------------------------------------------------------*
     * Apply noise-fill adjustment
     *----------------------------------------------------------------*/

    test();
    test();
    test();
    IF( ( GE_16( length, L_FRAME32k ) || GT_32( L_core_brate, HQ_32k ) || LT_32( L_core_brate, HQ_24k40 ) ) && NE_16( HQ_mode, HQ_HVQ ) )
    {
        apply_nf_gain_fx( nf_idx, last_sfm, R, sfm_start, sfm_end, coeff );
    }

    /*----------------------------------------------------------------*
     * Prepare fine strucutre for HQ GENERIC
     *----------------------------------------------------------------*/
    test();
    IF( EQ_16( HQ_mode, HQ_GEN_SWB ) || EQ_16( HQ_mode, HQ_GEN_FB ) )
    {
        hq_generic_fine_fx( coeff, last_sfm, sfm_start, sfm_end, bwe_seed, coeff_fine );
    }

    /*----------------------------------------------------------------*
     * Apply envelope
     *----------------------------------------------------------------*/

    test();
    IF( NE_16( HQ_mode, HQ_HARMONIC ) && NE_16( HQ_mode, HQ_HVQ ) )
    {
        apply_envelope_fx( coeff, norm, norm_adj, num_sfm, last_sfm, HQ_mode, length, sfm_start, sfm_end,
                           L_normq_v, L_coeff_out, coeff_fine, L_coeff_out1 );
    }

    /*----------------------------------------------------------------*
     * Harmonic BWE, HVQ BWE and HQ SWB BWE
     *----------------------------------------------------------------*/
    test();
    IF( EQ_16( HQ_mode, HQ_HARMONIC ) )
    {
        harm_bwe_fx( coeff_fine, coeff, num_sfm, sfm_start, sfm_end, last_sfm, R, prev_hq_mode, norm, noise_level, prev_noise_level, bwe_seed, L_coeff_out, element_mode );
    }
    ELSE IF( EQ_16( HQ_mode, HQ_HVQ ) )
    {
        hvq_bwe_fx( L_coeff_out, coeff_fine, sfm_start, sfm_end, sfmsize, last_sfm, prev_hq_mode, bwe_peaks, bin_th, num_sfm, L_core_brate, R, norm,
                    noise_level, prev_noise_level, bwe_seed, L_coeff_out, 15, 12 );
    }
    ELSE IF( EQ_16( HQ_mode, HQ_GEN_SWB ) || EQ_16( HQ_mode, HQ_GEN_FB ) )
    {
        hq_bwe_fx( HQ_mode, L_coeff_out1, hq_generic_fenv, L_coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, sfm_end, num_sfm, num_env_bands, R );
    }

    /*----------------------------------------------------------------*
     * HQ WB BWE refinements
     *----------------------------------------------------------------*/
    test();
    IF( EQ_16( length, L_FRAME16k ) && LE_32( L_core_brate, HQ_32k ) )
    {
        hq_wb_nf_bwe_fx( coeff, is_transient, prev_bfi, L_normq_v, num_sfm, sfm_start, sfm_end, sfmsize, last_sfm, R,
                         prev_is_transient, prev_normq, prev_env, bwe_seed, prev_coeff_out, prev_R, L_coeff_out, prev_env_Q );
    }

    /*----------------------------------------------------------------*
     * Update memories
     *----------------------------------------------------------------*/

    test();
    IF( NE_16( HQ_mode, HQ_HARMONIC ) && NE_16( HQ_mode, HQ_HVQ ) )
    {
        prev_noise_level[0] = 3277;
        move16(); /* 0.1 in Q15 */
        prev_noise_level[1] = 3277;
        move16(); /* 0.1 in Q15 */
    }
    test();
    IF( !( EQ_16( length, L_FRAME16k ) && LE_32( L_core_brate, HQ_32k ) ) )
    {
        set32_fx( prev_env, 0, SFM_N_WB );
        set32_fx( prev_normq, 0, SFM_N_WB );
    }

    test();
    IF( EQ_16( length, L_FRAME32k ) && LE_32( L_core_brate, HQ_32k ) )
    {
        *prev_R = R[SFM_N_WB - 1];
        move16();
        Copy32( L_coeff_out + L_FRAME16k - L_HQ_WB_BWE, prev_coeff_out, L_HQ_WB_BWE );
    }

    return;
}
#endif
+10 −103
Original line number Diff line number Diff line
@@ -16,9 +16,7 @@
 *--------------------------------------------------------------------------*/

static void subband_gain_bits_fx(
#ifdef HARM_HQ_CORE
    const Word16 element_mode, /* i  : element mode               */
#endif
    const Word16 *Rk,          /* i  : bit allocation per band Q3 */
    const Word16 N,            /* i  : number of bands         */
    Word16 *bits,              /* o  : gain bits per band      */
@@ -34,13 +32,11 @@ static void subband_gain_bits_fx(
    FOR( i = 0; i < N; i++ )
    {
        /*bps = (short)(Rk[i]*((word16)min(32767, ceil(32767.0f/sfmsize[i]);  inexact C-integer division approx. */
#ifdef HARM_HQ_CORE
        if ( element_mode > EVS_MONO )
        {
            bps = extract_l( L_shr( L_mult0( Rk[i], fg_inv_tbl_fx[sfmsize[i] >> 3] ), 18 ) ); /* 3+15 */
        }
        ELSE
#endif
        {
            bps = extract_l( L_shr( L_mult0( Rk[i], inv_tbl_fx[sfmsize[i]] ), 18 ) ); /* 3+15 */
        }
@@ -76,9 +72,7 @@ static void subband_gain_bits_fx(

/* o  : Number of assigned gain bits */
Word16 assign_gain_bits_fx(
#ifdef HARM_HQ_CORE
    const Word16 element_mode, /* i  : element mode                          */
#endif
    const Word16 core,         /* i  : HQ core                               */
    const Word16 BANDS,        /* i  : Number of bands                       */
    const Word16 *band_width,  /* i  : Sub band bandwidth                    */
@@ -93,11 +87,7 @@ Word16 assign_gain_bits_fx(
    /* Allocate gain bits for every subband used, based on bit rate and bandwidth */
    IF( EQ_16( core, HQ_CORE ) )
    {
#ifdef HARM_HQ_CORE
        subband_gain_bits_fx( element_mode, Rk, BANDS, gain_bits_array, band_width );
#else
        subband_gain_bits_fx( Rk, BANDS, gain_bits_array, band_width );
#endif
    }
    ELSE
    {
@@ -123,86 +113,3 @@ Word16 assign_gain_bits_fx(

    return gain_bits_tot;
}
#ifndef HARM_HQ_CORE
static void ivas_subband_gain_bits_fx(
    const Word16 *Rk,     /* i  : bit allocation per band Q3 */
    const Word16 N,       /* i  : number of bands         */
    Word16 *bits,         /* o  : gain bits per band      */
    const Word16 *sfmsize /* i  : Size of bands           */
)
{
    Word16 i, b, tot;
    Word16 bps;

    tot = 0;
    move16();

    FOR( i = 0; i < N; i++ )
    {
        /*bps = (short)(Rk[i]*((word16)min(32767, ceil(32767.0f/sfmsize[i]);  inexact C-integer division approx. */
        bps = extract_l( L_shr( L_mult0( Rk[i], fg_inv_tbl_fx[sfmsize[i] >> 3] ), 18 ) ); /* 3+15 */
        if ( EQ_32( L_shl( L_mult0( sfmsize[i], add( bps, 1 ) ), 3 ), Rk[i] ) )
        {
            bps = add( bps, 1 );
        }

        bps = s_min( 7, bps );
        b = fine_gain_bits[bps];
        move16();
        bits[i] = b;
        move16();
        tot = add( tot, b );
    }

    if ( tot == 0 )
    {
        /* If no gain bits were assigned, use one bit anyway for potential PVQ overage */
        bits[0] = 1;
        move16();
    }

    return;
}

Word16 ivas_assign_gain_bits_fx(                           /* o  : Number of assigned gain bits          */
                                 const Word16 core,        /* i  : HQ core                               */
                                 const Word16 BANDS,       /* i  : Number of bands                       */
                                 const Word16 *band_width, /* i  : Sub band bandwidth                    */
                                 Word16 *Rk,               /* i/o: Bit allocation/Adjusted bit alloc. Q3 */
                                 Word16 *gain_bits_array,  /* o  : Assigned gain bits                    */
                                 Word16 *Rcalc             /* o  : Bit budget for shape quantizer     Q3 */
)
{
    Word16 gain_bits_tot;
    Word16 i;

    /* Allocate gain bits for every subband used, based on bit rate and bandwidth */
    IF( EQ_16( core, HQ_CORE ) )
    {
        ivas_subband_gain_bits_fx( Rk, BANDS, gain_bits_array, band_width );
    }
    ELSE
    {
        set16_fx( gain_bits_array, 0, BANDS );
    }

    /* Re-adjust bit budget for gain quantization */
    gain_bits_tot = 0;
    move16();
    *Rcalc = 0;
    move16();
    FOR( i = 0; i < BANDS; i++ )
    {
        IF( Rk[i] > 0 )
        {
            Rk[i] = sub( Rk[i], shl( gain_bits_array[i], 3 ) );
            move16();
            gain_bits_tot = add( gain_bits_tot, gain_bits_array[i] );
            *Rcalc = add( *Rcalc, Rk[i] );
            move16();
        }
    }

    return gain_bits_tot;
}
#endif
Loading