Commit 3ca319e1 authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Merge branch 'fxd_sub_funcs_integration_7' into 'main'

Integration of fixed point sub-functions 7

See merge request !232
parents c7ca9d3e a4e00205
Loading
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1512,6 +1512,8 @@ enum
#define SHB_GAIN_QDELTA                     0.15f                   /* SHB gain scalar quantizer stepsize */
#define SHB_GAIN_QLOW_1k75                  0.0f                    /* SHB gain lowest scalar quantizer value */
#define SHB_GAIN_QDELTA_1k75                0.08f                   /* SHB gain scalar quantizer stepsize */
#define SHB_GAIN_QLOW_1k75_FX                  0                    /* SHB gain lowest scalar quantizer value */
#define SHB_GAIN_QDELTA_1k75_FX                10486                   /* SHB gain scalar quantizer stepsize Q17 */
#define SHB_GAIN_QLOW_FX                      -262144              /* Q18*/   /* SHB gain lowest scalar quantizer value */
#define SHB_GAIN_QLOW_FX_16                   -65536               /* SHB gain lowest scalar quantizer value */
#define SHB_GAIN_QDELTA_FX_15                 4915                 /* SHB gain scalar quantizer step size */
+186 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include "ivas_cnst.h"
#include "ivas_prot.h"
#include "prot.h"
#include "prot_fx1.h"
#include "wmc_auto.h"
#include <assert.h>

@@ -52,7 +53,7 @@
 *
 * split available TCX bits among channels
 *-------------------------------------------------------------------*/

#ifndef IVAS_FLOAT_FIXED
void splitAvailableBitsMCT(
    void **sts,                                  /* i/o: encoder/decoder state structure     */
    const int16_t total_bits,                    /* i  : total number of available bits      */
@@ -192,3 +193,187 @@ void splitAvailableBitsMCT(

    return;
}

#else

void splitAvailableBitsMCT(
    void **sts,                                 /* i/o: encoder/decoder state structure     */
    const Word16 total_bits,                    /* i  : total number of available bits      */
    const Word16 split_ratio[MCT_MAX_CHANNELS], /* i  : ratio for splitting the bits        */
    const Word16 enc_dec,                       /* i  : encoder or decoder flag             */
    const Word16 nchan                          /* i  : number of channels                  */
)
{
    Word16 i, k, nSubframes, diff, bits_split, max_chn, tmp;
    Word16 *bits_frame_channel;
    Word16 min_chan_bits[MCT_MAX_CHANNELS], min_bits_tot, remaining_bits;
    Word16 core[MCT_MAX_CHANNELS];
    MCT_CHAN_MODE mct_chan_mode[MCT_MAX_CHANNELS];
    min_bits_tot = 0;

    FOR( i = 0; i < nchan; i++ )
    {
        IF( enc_dec == ENC )
        {
            mct_chan_mode[i] = ( (Encoder_State *) sts[i] )->mct_chan_mode;
            move16();
            core[i] = ( (Encoder_State *) sts[i] )->core;
            move16();
        }
        ELSE
        {
            mct_chan_mode[i] = ( (Decoder_State *) sts[i] )->mct_chan_mode;
            move16();
            core[i] = ( (Decoder_State *) sts[i] )->core;
            move16();
        }
    }

    FOR( i = 0; i < nchan; i++ )
    {
        IF(mct_chan_mode[i] != MCT_CHAN_MODE_IGNORE )
        {
            min_chan_bits[i] = 0;
            move16();
            nSubframes = ( core[i] == TCX_20_CORE ) ? 1 : NB_DIV;
            move16();
            FOR( k = 0; k < nSubframes; k++ )
            {
                min_chan_bits[i] += SMDCT_MINIMUM_ARITH_BITS + MIN_SAFETY_BITS_MC;
                move16();
            }
            min_bits_tot += min_chan_bits[i];
            move16();
        }
    }

    remaining_bits = total_bits - min_bits_tot;
    move16();

    /*initial value of bits already given*/
    bits_split = 0;
    move16();

    tmp = 0;
    move16();
    max_chn = 0;
    move16();
    FOR( i = 0; i < nchan; i++ )
    {
        IF( enc_dec == ENC )
        {
            bits_frame_channel = &( (Encoder_State *) sts[i] )->bits_frame_channel;
            move16();
        }
        ELSE /* DEC */
        {
            bits_frame_channel = &( (Decoder_State *) sts[i] )->bits_frame_channel;
            move16();
        }

        IF(
            mct_chan_mode[i] != MCT_CHAN_MODE_IGNORE )
        {
            assert( split_ratio[i] >= 1 && split_ratio[i] < BITRATE_MCT_RATIO_RANGE );
            *bits_frame_channel = (Word16)L_shr((Word32)split_ratio[i]* remaining_bits, NBBITS_MCT_RATIO) + min_chan_bits[i];
            move16();
            bits_split += *bits_frame_channel;
            move16();

            /*determine channel with most bits (energy)*/
            IF( *bits_frame_channel > tmp )
            {
                tmp = *bits_frame_channel;
                move16();
                max_chn = i;
                move16();
            }
        }
    }

    /*if bits distributed are more than available bits, substract the proportional amount of bits from all channels*/
    IF( bits_split != total_bits )
    {
        diff = bits_split - total_bits;
        move16();

        /*re-count bits distributed to each channel*/
        bits_split = 0;
        move16();

        FOR( i = 0; i < nchan; i++ )
        {
            IF( enc_dec == ENC )
            {
                bits_frame_channel = &( (Encoder_State *) sts[i] )->bits_frame_channel;
                move16();
            }
            ELSE /* DEC */
            {
                bits_frame_channel = &( (Decoder_State *) sts[i] )->bits_frame_channel;
                move16();
            }

            IF( mct_chan_mode[i] != MCT_CHAN_MODE_IGNORE )
            {
                Word32 temp_res = (Word32) diff * split_ratio[i];
                IF( temp_res < 0 )
                {
                    temp_res = -temp_res;
                    move16();
                    temp_res = L_shr( temp_res, NBBITS_MCT_RATIO );
                    move16();
                    temp_res = -temp_res;
                    move16();
                }
                ELSE
                {
                    temp_res = L_shr( temp_res, NBBITS_MCT_RATIO );
                    move16();
                }
                *bits_frame_channel -= (Word16)temp_res;
                move16();
                *bits_frame_channel = max( min_chan_bits[i], *bits_frame_channel );
                move16();
                bits_split += *bits_frame_channel;
                move16();
            }
        }
    }

    /*if there any bits left assign them to the channel with the maximum energy (or more bits)*/
    IF( total_bits != bits_split )
    {
        IF( enc_dec == ENC )
        {
            bits_frame_channel = &( (Encoder_State *) sts[max_chn] )->bits_frame_channel;
            move16();
        }
        ELSE /* DEC */
        {
            bits_frame_channel = &( (Decoder_State *) sts[max_chn] )->bits_frame_channel;
            move16();
        }

        *bits_frame_channel += ( total_bits - bits_split );
        move16();

        /*if all channels are silent assign bits to ch 0*/
        IF( enc_dec == ENC )
        {
            IF( ( (Encoder_State *) sts[max_chn] )->mct_chan_mode == MCT_CHAN_MODE_IGNORE )
            {
                assert( bits_split == 0 );

                ( (Encoder_State *) sts[max_chn] )->mct_chan_mode = MCT_CHAN_MODE_REGULAR;
                ( (Encoder_State *) sts[max_chn] )->side_bits_frame_channel = ( ( (Encoder_State *) sts[max_chn] )->core ) * ( NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL );
                *bits_frame_channel -= ( (Encoder_State *) sts[max_chn] )->side_bits_frame_channel;
                move16();
            }
        }
    }

    return;
}

#endif
 No newline at end of file
+14 −1
Original line number Diff line number Diff line
@@ -5986,7 +5986,12 @@ void ivas_binaural_add_LFE(
    float *input_f[],                                           /* i  : transport channels                                      */
    float *output_f[]                                           /* o  : synthesized core-coder transport channels/DirAC output  */
);

void ivas_binaural_add_LFE_fix(
  Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure                                 */
  Word16 output_frame,    /* i  : length of input frame                                  */
  Word32 *input_fx[],        /* i  : transport channels                                     */
  Word32 *output_fx[]       /* o  : synthesized core-coder transport channels/DirAC output */
);

/*----------------------------------------------------------------------------------*
 * renderer prototypes
@@ -6251,6 +6256,14 @@ void lls_interp_n(
    const int16_t upd                                           /* i  : use 1 to update x[] with the interpolated output*/
);

void lls_interp_n_fx(
    Word16 x_fx[],    /* i/o: input/output vector                               */
    const Word16 N,  /* i  : length of the input vector                        */
    Word16 *a_fx,     /* o  : calculated slope                                  */
    Word16 *b_fx,     /* o  : calculated offset                                 */
    const Word16 upd /* i  : use 1 to update x[] with the interpolated output  */
);

void computeReferencePower_enc(
    const int16_t *band_grouping,                               /* i  : Band grouping for estimation                    */
    float Cldfb_RealBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i  : Real part of input signal               */
+0 −1
Original line number Diff line number Diff line
@@ -1037,7 +1037,6 @@ void stereo_dft_dec_res_fx(
    CPE_DEC_HANDLE hCPE,            /* i/o: decoder CPE handle */
    Word32 res_buf[STEREO_DFT_N_8k], /* i  : residual buffer                     */
    Word16 q_res,                   /* i  : q fact of residural buffer             */
    Word16 q_output,                   /* i  : q factor of output buffer             */
    Word32 *output                   /* o  : output             */
);

+374 −1
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@
 *
 * Bitbudget distribution between Primary and Secondary channel in TD stereo
 *-------------------------------------------------------------------*/

#ifndef IVAS_FLOAT_FIXED
void tdm_bit_alloc(
    const int16_t ivas_format,           /* i  : IVAS format                         */
    const int16_t ism_mode,              /* i  : ISM mode in combined format         */
@@ -433,7 +433,380 @@ void tdm_bit_alloc(
    return;
}

#else
void tdm_bit_alloc(
    const Word16 ivas_format,            /* i  : IVAS format                         */
    const Word16 ism_mode,               /* i  : ISM mode in combined format         */
    const int32_t element_brate_wo_meta, /* i  : element bitrate without metadata    */
    const Word16 tdm_lp_reuse_flag,      /* i  : LPC reusage flag                    */
    Word32 *total_brate_pri,             /* o  : Allocated primary channel bitrate   */
    Word32 *total_brate_sec,             /* o  : Allocated secondary channel bitrate */
    Word16 *tdm_low_rate_mode,           /* o  : secondary channel low rate mode flag*/
    const Word16 coder_type,             /* i  : secondary channel coder type        */
    const Word16 ener_ratio_idx,         /* i  : correlation ratio indexe            */
    const Word16 tdm_Pitch_reuse_flag,   /* i  : primary channel pitch reuse flag    */
    const Word16 bwidth_pri,             /* i  : bandwidth of the primary channel    */
    const Word16 bwidth_sec,             /* i  : bandwidth of the secondary channel  */
    const Word16 flag_ACELP16k_pri,      /* i  : ACELP@16kHz core flag, primary chan.*/
    const Word16 tdm_LRTD_flag,          /* i  : LRTD stereo mode flag               */
    const Word16 coder_type0,            /* i  : coder type (temporary in the encoder, from bitstream in decoder) */
    const Word16 tdm_inst_ratio_idx_ref  /* i  : instantaneous correlation ratio idx */
)
{
    Word16 idx, four_subfr_fcb, two_subfr_fcb;
    Word32 bit_rate_diff_fx;
    Word16 BWE_brate, tmp_bits;
    Word16 tdm_inst_ratio_idx = tdm_inst_ratio_idx_ref;
    IF( tdm_inst_ratio_idx == TDM_NQ )
    {
        tdm_inst_ratio_idx = LRTD_STEREO_MID_IS_PRIM; /* Bit rate almost split half and half*/
    }

    /* Decision on using the low rate mode or the normal mode */
    /* default is using the low rate mode for the secondary channel coding*/
    /* UC and IC are automatically coded with low rate mode */
    *tdm_low_rate_mode = 1;

    /* Allocating different bitrate to channels */
    idx = 0;
    IF( element_brate_wo_meta <= IVAS_13k2 )
    {
        idx = 0;
    }
    ELSE IF( element_brate_wo_meta <= IVAS_16k4 )
    {
        idx = 1;
    }
    ELSE IF( element_brate_wo_meta <= IVAS_24k4 )
    {
        idx = 2;
    }
    ELSE IF( element_brate_wo_meta <= IVAS_32k )
    {
        idx = 3;
    }
    ELSE IF( element_brate_wo_meta <= IVAS_48k )
    {
        idx = 4;
    }

    IF( coder_type == UNVOICED && tdm_bit_allc_tbl[idx][coder_type] >= 4200 )
    {
        *tdm_low_rate_mode = 0;
    }

    /* Secondary channel based bitrate allocation */
    *total_brate_sec = tdm_bit_allc_tbl[idx][coder_type];

    /* secondary channel bitrate allocation based on the energy scaling ratio */
    IF( ( ( ivas_format != MASA_ISM_FORMAT || ism_mode == ISM_MODE_NONE ) && ( ( coder_type != UNVOICED ) || tdm_LRTD_flag == 1 ) ) || ( ivas_format == MASA_ISM_FORMAT && ism_mode != ISM_MODE_NONE && coder_type > UNVOICED ) )
    {
        bit_rate_diff_fx = ( element_brate_wo_meta - 2 * *total_brate_sec );

        IF( tdm_LRTD_flag == 1 ) /* >  element_brate > STEREO_22k or CT0 not used */
        {
            /* further adjustment in function of the energy/correlation ratio */
            IF( coder_type == INACTIVE )
            {
                Word32 res_fix = 0;
                res_fix = Mpy_32_32(644245094, ( element_brate_wo_meta - 500 ) );
                res_fix = ( ( res_fix / 100 ) * 100 );
                *total_brate_sec = max( *total_brate_sec, res_fix );

                //*total_brate_sec = max(*total_brate_sec, (int16_t)(0.3f * (element_brate_wo_meta - 500) / 100) * 100);
                tmp_bits = (Word16) ( -abs( tdm_inst_ratio_idx - 16 ) * 200 * idx );
            }
            ELSE
            {
                Word32 res_fix = 0;
                res_fix = Mpy_32_32(1073741824, ( element_brate_wo_meta - 500 ) );
                res_fix = ( ( res_fix / 100 ) * 100 );
                *total_brate_sec = max(*total_brate_sec, res_fix );

                //*total_brate_sec = max(*total_brate_sec, (int16_t)(0.5f * (element_brate_wo_meta - 500) / 100) * 100);
                /* tmp_bits = -abs(tdm_inst_ratio_idx-16)*200*idx; */
                tmp_bits = (Word16) ( -abs( tdm_inst_ratio_idx - 16 ) * 100 * idx );
            }

            /* tmp_bits should be subtract from the secondary channel bitrate */
            /* IF the primary channel doesn't correspond to the channel having the highest correlation to the mono- inverse the bitrate compensation */
            IF( ( ener_ratio_idx >= LRTD_STEREO_MID_IS_PRIM && tdm_inst_ratio_idx < LRTD_STEREO_MID_IS_PRIM ) || ( ener_ratio_idx < LRTD_STEREO_MID_IS_PRIM && tdm_inst_ratio_idx >= LRTD_STEREO_MID_IS_PRIM ) )
            {
                tmp_bits *= -1;
            }
            bit_rate_diff_fx = tmp_bits;
        }
        ELSE{
            IF( ener_ratio_idx < LRTD_STEREO_MID_IS_PRIM )
            {

                bit_rate_diff_fx = ( LRTD_STEREO_MID_IS_PRIM - ener_ratio_idx ) * bit_rate_diff_fx;
                bit_rate_diff_fx = L_shr( bit_rate_diff_fx, 1 );
                bit_rate_diff_fx = bit_rate_diff_fx / 10; // basop gives very minor deviation
            }
            ELSE
            {
                bit_rate_diff_fx = ( ener_ratio_idx - LRTD_STEREO_MID_IS_PRIM ) * bit_rate_diff_fx;
                bit_rate_diff_fx = L_shr(bit_rate_diff_fx, 1);
                bit_rate_diff_fx = bit_rate_diff_fx / 10; // basop gives very minor deviation
            }
        }
/*bit_rate_diff2 = ((Word16)(10.f*(-0.5f*ener_ratio_LR+0.5f)*bit_rate_diff)/100)*100;*/
*total_brate_sec += ( (Word16) ( bit_rate_diff_fx / 100 ) * 100 );
*total_brate_sec = max( *total_brate_sec, tdm_bit_allc_tbl[idx][coder_type] );

IF( coder_type == INACTIVE && tdm_LRTD_flag == 0 )
{
    *total_brate_sec = min( *total_brate_sec, MIN_BRATE_SWB_BWE );
}

IF( ( ener_ratio_idx <= 1 || ener_ratio_idx >= 29 ) && coder_type >= UNVOICED )
{
    Word16 delta_brate = 0;

    IF( bwidth_pri > WB )
    {
        delta_brate = 600; /* To slightly compensate for SWB BWE instead of WB BWE */
        IF( element_brate_wo_meta <= IVAS_16k4 )
        {
            delta_brate = 1250; /* To compensate for SWB BWE instead of WB BWE */
        }
    }

    IF( element_brate_wo_meta <= IVAS_13k2 )
    {
        *total_brate_sec = max( *total_brate_sec, 5600 + delta_brate ); /* ~42-47 % of the total bitrate */
    }
    ELSE IF( element_brate_wo_meta <= IVAS_16k4 )
    {
        *total_brate_sec = max( *total_brate_sec, 6500 + delta_brate ); /* ~40-43 % of the total bitrate */
    }
    ELSE IF( element_brate_wo_meta <= IVAS_24k4 )
    {
        *total_brate_sec = max( *total_brate_sec, 9000 + delta_brate ); /* ~37-39 % of the total bitrate */
    }
    ELSE
    {
        *total_brate_sec = max( *total_brate_sec, 9600 + delta_brate ); /* ~30-32% of the total bitrate */
    }
}
ELSE
{
    *total_brate_sec = min(*total_brate_sec, Mpy_32_32(9663677, element_brate_wo_meta)* 100);    
}

*total_brate_sec = min( *total_brate_sec, 18000 );
}
ELSE IF( coder_type == UNVOICED )
{
    IF( tdm_lp_reuse_flag == 0 )
    {
        *total_brate_sec += ( 31 + 5 ) * FRAMES_PER_SEC;
    }
}

IF( coder_type <= UNVOICED )
{
    *total_brate_sec = min( *total_brate_sec, MAX_TDM_UC_BRATE );

    IF( *total_brate_sec >= TDM_UC_NORMAL_MODE_MBRATE && tdm_lp_reuse_flag == 0 )
    {
        *tdm_low_rate_mode = 0;
    }
    ELSE IF( *total_brate_sec >= TDM_UC_NORMAL_MODE_MBRATE_LP_R )
    {
        *tdm_low_rate_mode = 0;
    }
    ELSE IF( ( tdm_lp_reuse_flag == 0 && *total_brate_sec < TDM_UC_NORMAL_MODE_MINBR_LP_R && coder_type == UNVOICED ) || ( tdm_lp_reuse_flag == 0 && *total_brate_sec < ( tdm_bit_allc_tbl[idx][0] + MID_LP_BRATE ) ) )
    {
        *total_brate_sec += MID_LP_BRATE;
    }
}

/* verify that primary channel bitrate is higher than the minimum supported bitrate */
IF( flag_ACELP16k_pri )
{
    BWE_brate = SWB_TBE_1k75;
    IF( element_brate_wo_meta < IVAS_24k4 )
    {
        BWE_brate = SWB_TBE_1k10;
    }

    IF( bwidth_pri > WB && tdm_LRTD_flag == 0 )
    {
        BWE_brate += ( STEREO_BITS_ICBWE + STEREO_ICBWE_MSFLAG_BITS ) * FRAMES_PER_SEC;
    }
    IF( bwidth_pri > SWB && tdm_LRTD_flag == 1 )
    {
        BWE_brate += 300;
    }

    IF( bwidth_pri == FB )
    {
        BWE_brate += ( FB_TBE_1k8 - SWB_TBE_1k75 );
    }

    IF( element_brate_wo_meta - *total_brate_sec - BWE_brate < 14000 )
    {
        *total_brate_sec = element_brate_wo_meta - 14000 - BWE_brate;
    }
}
ELSE
{
    BWE_brate = SWB_TBE_1k75;
    IF( bwidth_pri == WB )
    {
        BWE_brate = WB_BWE_0k35;
        IF( tdm_LRTD_flag == 0 )
        {
            BWE_brate += 250; /* ICA Brate */
        }
    }
    ELSE IF( tdm_LRTD_flag == 0 )
    {
        BWE_brate += 350; /* ICA Brate */
    }
}

IF( coder_type0 == TRANSITION )
{
    IF( element_brate_wo_meta > IVAS_13k2 )
    {
        *total_brate_sec = min( *total_brate_sec, element_brate_wo_meta - ( ACELP_8k00 + BWE_brate ) );
    }
    ELSE
    {
        *total_brate_sec = min( *total_brate_sec, element_brate_wo_meta - ( ACELP_7k20 + BWE_brate ) );
    }
}
ELSE
{
    *total_brate_sec = min( *total_brate_sec, element_brate_wo_meta - ( 5900 + BWE_brate ) );
}

IF( coder_type == INACTIVE )
{
    *total_brate_sec = max( *total_brate_sec, tdm_bit_allc_tbl[0][0] ); /* sanity check to ensure the secondary channel always gets the minimal bitrate it needs */
}
ELSE
{
    *total_brate_sec = max( *total_brate_sec, 3500 ); /* sanity check to ensure the secondary channel always gets the minimal bitrate it needs */
}

/* Secondary channel bitrate adjusment                                                      */
/* First, adjust the bitrate depending of what is transmitted                               */
/* Second, choose the number of subframe for ACELP core depending of the targetted bitratre */
/* Finally, verify that the concordance between the number of subframe, the parameters sent and the bitrate available */
IF( coder_type == GENERIC /* || coder_type == AUDIO*/ )
{
    /* Adjust the bitrate depending of what is transmitted */
    /* IF LPC are transmitted, ensure enough bits are used */
    IF( tdm_lp_reuse_flag == 0 )
    {
        /* Pitch is transmitted as well, further increase the bitrate */
        IF( tdm_Pitch_reuse_flag == 0 )
        {
            *total_brate_sec = max( *total_brate_sec, MIN_FCB_SECRATE2 + MIN_SEC_ACB_RATE + MIN_SEC_LPC_RATE + MIN_SIGN_RATE );

            IF( tdm_LRTD_flag == 1 && bwidth_sec == SWB )
            {
                /* ensure that there are enough bits to code SWB TBE_1k10 as well */
                *total_brate_sec = max( *total_brate_sec, MIN_FCB_SECRATE2 + MIN_SEC_ACB_RATE + MIN_SEC_LPC_RATE + MIN_SIGN_RATE + SWB_TBE_1k10 );
            }
        }
        ELSE /* only LPC is tranmitted -> IF ( *total_brate_sec  < MIN_SEC_BRATE+MIN_SEC_LPC_RATE ) */
        {
            *total_brate_sec = max( *total_brate_sec, MIN_FCB_SECRATE2 + MIN_SEC_LPC_RATE + MIN_SIGN_RATE );
        }
    }
    ELSE IF( /*tdm_lp_reuse_flag == 1*/ tdm_Pitch_reuse_flag == 0 )
    {
        *total_brate_sec = max( *total_brate_sec, MIN_FCB_SECRATE2 + MIN_SEC_ACB_RATE + MIN_SIGN_RATE );
    }

    /* Choose between 2 and 4 subfr, depending of the bitrate available and prevent the gap between the 2 atlernative */
    IF( tdm_LRTD_flag == 1 )
    {
        four_subfr_fcb = (Word16) ( *total_brate_sec - ( TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS - STEREO_BITS_TCA + 1 + 4 * MIN_GAIN_BITS ) * FRAMES_PER_SEC );
        two_subfr_fcb = (Word16) ( *total_brate_sec - ( TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS - STEREO_BITS_TCA + 1 + 2 * MIN_GAIN_BITS ) * FRAMES_PER_SEC );
    }
    ELSE
    {
        four_subfr_fcb = (Word16) ( *total_brate_sec - ( TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + 1 + 4 * MIN_GAIN_BITS ) * FRAMES_PER_SEC );
        two_subfr_fcb = (Word16) ( *total_brate_sec - ( TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + 1 + 2 * MIN_GAIN_BITS ) * FRAMES_PER_SEC );
    }

    IF( tdm_lp_reuse_flag == 0 )
    {
        four_subfr_fcb -= MIN_SEC_LPC_RATE;
        two_subfr_fcb -= MIN_SEC_LPC_RATE;
    }

    IF( tdm_Pitch_reuse_flag == 0 )
    {
        four_subfr_fcb -= ( MIN_SEC_ACB_RATE + 10 * FRAMES_PER_SEC );
        two_subfr_fcb -= MIN_SEC_ACB_RATE;
    }

    /* Too much bits for the 2 subfr model but not enough for the the 4 subfr model -> slightly reduce the 2nd channel bitrate */
    IF( two_subfr_fcb > 2 * MAX_SC_FCB_RATE * FRAMES_PER_SEC && four_subfr_fcb < MIN_4SUBFR_FCB_RATE * FRAMES_PER_SEC )
    {
        IF( tdm_LRTD_flag == 1 )
        {
            *total_brate_sec = 2 * MAX_SC_FCB_RATE * FRAMES_PER_SEC + ( TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS - STEREO_BITS_TCA + 1 + 2 * MIN_GAIN_BITS ) * FRAMES_PER_SEC;
        }
        ELSE
        {
            *total_brate_sec = 2 * MAX_SC_FCB_RATE * FRAMES_PER_SEC + ( TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + 1 + 2 * MIN_GAIN_BITS ) * FRAMES_PER_SEC;
        }

        IF( tdm_lp_reuse_flag == 0 )
        {
            *total_brate_sec += MIN_SEC_LPC_RATE;
        }

        IF( tdm_Pitch_reuse_flag == 0 )
        {
            *total_brate_sec += MIN_SEC_ACB_RATE;
        }
    }
    ELSE IF( four_subfr_fcb >= ( 40 ) * FRAMES_PER_SEC ) /* Enough bits to have minimally 2 x 12 + 2*7 bits FCB  */
    {
        *tdm_low_rate_mode = 0; /* Use normal rate mode */
    }
    ELSE /* Possible slight increase of secondary channel bit budget to compensate for FCB limited flexibility */
    {
        Word16 tmp_rate, i;
        tmp_rate = two_subfr_fcb;
        idx = NB_RATE_POSS - 2;

        for ( i = 0; i < NB_RATE_POSS; i++ )
        {
            IF( tmp_rate <= fast_FCB_rates_2sfr[i] )
            {
                idx = i;
                break;
            }
        }
        *total_brate_sec += ( fast_FCB_rates_2sfr[idx] - tmp_rate );
    }
    /* To prevent 13.2 kb/s for primary channel as some bitstream issues arrise with it */
    IF( element_brate_wo_meta - *total_brate_sec == ACELP_13k20 )
    {
        *total_brate_sec += 100;
    }
}
/* prevent 2.4 kb/s and 2.8 kb/s as they are reserved bitrates for DTX and VBR */
IF( *total_brate_sec == PPP_NELP_2k80 || *total_brate_sec == SID_2k40 )
{
    *total_brate_sec -= 100;
}

*total_brate_pri = element_brate_wo_meta - *total_brate_sec;

return;
}
#endif
/*-------------------------------------------------------------------*
 * td_stereo_param_updt()
 *
Loading