Commit b7970294 authored by gaoyuy's avatar gaoyuy
Browse files

Update IVAS SBA 768kbps

parent b0dfce1f
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -99,7 +99,13 @@ int32_t get_delay(
                /* compensate for filterbank delay */
                delay += IVAS_FB_DEC_DELAY_NS;
            }

#ifdef IVAS_SBA_MP_768KBPS
            else if ( !hCldfb && ivas_format == SBA_FORMAT )
            {
                /* compensate 5ms of time domain circular delay buffer for SBA 768kbps */
                delay += IVAS_FB_DEC_DELAY_NS;
            }
#endif
            /* compensate for binauralization delay */
            delay += binaural_latency_ns;
        }
+13 −1
Original line number Diff line number Diff line
@@ -1090,6 +1090,13 @@ enum
/*----------------------------------------------------------------------------------*
 * MP constants
 *----------------------------------------------------------------------------------*/
typedef enum 
{
    MP_SYNTHESISE_BYPASS = 0,
    MP_SYNTHESISE_PANNING_HOA3,
    MP_SYNTHESISE_HOA3
} MP_Synthesis_Cfg;

#define MP_ORDER2CH( order )                    ( int16_t )( ( ( int16_t )( order ) + 1 ) * ( ( int16_t )( order ) + 1))
#define MP_ORDER2SH( order )                    ( int16_t )( ( ( int16_t )( order ) + 1 ) * ( ( int16_t )( order ) + 1))

@@ -1102,14 +1109,18 @@ enum
#define MP_CHANNELS_HOA3                        MP_ORDER2CH( SBA_HOA3_ORDER )

#define MP_MAX_CHANNELS                         MAX_INPUT_CHANNELS
#define MP_MAX_CHANNELS_TRANSPORT               ( MP_CHANNELS_HOA2 + 1 )
#define MP_MAX_CHANNELS_TRANSPORT               MP_CHANNELS_HOA2
#define MP_MAX_NBANDS                           DIRAC_MAX_NBANDS
#define MP_VL_NBANDS                            45
#define MP_DELAY_PARAM_DEC_SFR                  1
#define MP_MAX_AVERG_ENERGY_SLOTS               32
#define MP_MAX_GROUP_TRANSPORT_CFG              4
#define MP_MAX_GROUP_TRANSPORT                  2

#define MP_MIN_DIRECTIONS                       2
#define MP_MAX_DIRECTIONS                       4
#define MP_NB_HIS_DIRECTIONS                    10

#define MP_MAX_NB_COEFFS                        MP_ORDER2SH( SBA_HOA3_ORDER ) 
#define MP_MAX_BASIS_ROWS                       MP_MAX_NB_COEFFS
#define MP_MAX_SVD_CLOS                         MP_ORDER2SH( SBA_HOA3_ORDER )
@@ -1119,6 +1130,7 @@ enum
#define MP_COLS_R2                              32
#define MP_FIXED_DIR_ROWS                       1024
#define MP_MIN_ANGLE_RAD                        ( 4.f * EVS_PI / MP_FIXED_DIR_ROWS )
#define MP_MIN_ANGLE_INDEX                      548

#define MP_NBITS_DIR                            2
#define MP_NBITS_VL                             10
+3 −0
Original line number Diff line number Diff line
@@ -70,6 +70,9 @@ typedef enum
    IVAS_ERR_UNEXPECTED_NULL_POINTER,
    IVAS_ERR_METADATA_NOT_EXPECTED,
    IVAS_ERR_INVALID_SPAR_CONFIG,
#ifdef IVAS_SBA_MP_768KBPS
    IVAS_ERR_INVALID_MP_CONFIG,
#endif
    IVAS_ERR_WRONG_PARAMS,
    IVAS_ERR_INIT_ERROR,
    IVAS_ERR_DECODER_ERROR,
+241 −0
Original line number Diff line number Diff line
@@ -46,6 +46,247 @@
#define MIN_SAFETY_BITS_LFE 30
#define MIN_SAFETY_BITS_MC  5

#ifdef IVAS_SBA_MP_768KBPS
void splitAvailableBitsSBA(
    void **sts,                                  /* i/o: encoder/decoder state structure         */
    const int16_t total_bits,                    /* i  : total number of available bits          */
    const int16_t split_ratio[MCT_MAX_CHANNELS], /* i  : ratio for splitting the bits            */
    const int16_t enc_dec,                       /* i  : encoder or decoder flag                 */
    const int16_t nchan,                         /* i  : number of channels                      */
    const int16_t sba_order,
    const int32_t total_bitrate )
{
    int16_t k, nSubframes, ch, ch_idx, group_idx, diff, bits_split, max_chn, tmp;
    int16_t *bits_frame_channel;
    int16_t min_chan_bits[MCT_MAX_CHANNELS], min_bits_tot, remaining_bits;
    int16_t core[MCT_MAX_CHANNELS];
    MCT_CHAN_MODE mct_chan_mode[MCT_MAX_CHANNELS];
    MP_TCS_DMX_CONFIG tcs_cfg;
    int16_t nchan_active;
    int16_t nchan_overflow_mask[MCT_MAX_CHANNELS];
    int16_t group_bits_frame_channel[MP_MAX_GROUP_TRANSPORT];
    int16_t nchan_overflow, all_overflow_flag;
    int16_t target_max_bits_frame, max_bits_frame;

    min_bits_tot = 0;
    nchan_active = 0;
    set_s( nchan_overflow_mask, 0, MCT_MAX_CHANNELS );
    target_max_bits_frame = 0;
    nchan_overflow = 0;
    all_overflow_flag = 0;

    tcs_cfg = ivas_mp_get_transport_group_config( sba_order, total_bitrate, nchan );
    max_bits_frame = ( int16_t )( tcs_cfg.max_bitrate / FRAMES_PER_SEC );

    for ( ch = 0; ch < nchan; ch++ )
    {
        if ( enc_dec == ENC )
        {
            mct_chan_mode[ch] = ( (Encoder_State *) sts[ch] )->mct_chan_mode;
            core[ch] = ( (Encoder_State *) sts[ch] )->core;
        }
        else
        {
            mct_chan_mode[ch] = ( (Decoder_State *) sts[ch] )->mct_chan_mode;
            core[ch] = ( (Decoder_State *) sts[ch] )->core;
        }

        if ( mct_chan_mode[ch] != MCT_CHAN_MODE_IGNORE )
        {
            nchan_active++;
        }

        assert( mct_chan_mode[ch] != MCT_CHAN_MODE_LFE );
    }
    assert( nchan_active <= nchan );

    for ( ch = 0; ch < nchan; ch++ )
    {
        if ( mct_chan_mode[ch] != MCT_CHAN_MODE_IGNORE )
        {
            min_chan_bits[ch] = 0;

            nSubframes = ( core[ch] == TCX_20_CORE ) ? 1 : NB_DIV;

            for ( k = 0; k < nSubframes; k++ )
            {
                min_chan_bits[ch] += SMDCT_MINIMUM_ARITH_BITS + MIN_SAFETY_BITS_MC;
            }
            min_bits_tot += min_chan_bits[ch];
        }
    }

    remaining_bits = total_bits - min_bits_tot;
    bits_split = 0;
    diff = 0;
    tmp = 0;
    max_chn = 0;

    if ( nchan_active > 1 && nchan_active < nchan )
    {
        all_overflow_flag = 0;
        target_max_bits_frame = ( int16_t )( remaining_bits / nchan_active );
        if ( max_bits_frame < target_max_bits_frame )
        {
            max_bits_frame = target_max_bits_frame;
            all_overflow_flag = 1;
        }
    }

    /* split bits by group ratio */
    for ( ch_idx = 0, group_idx = 0; group_idx < tcs_cfg.nb_group; group_idx++ )
    {
        group_bits_frame_channel[group_idx] = ( int16_t )( remaining_bits * tcs_cfg.group_split_ratio[group_idx] );

        for ( ch = 0; ch < tcs_cfg.nb_chan_group[group_idx]; ch++ )
        {
            if ( enc_dec == ENC )
            {
                bits_frame_channel = &( (Encoder_State *) sts[ch_idx] )->bits_frame_channel;
            }
            else /* DEC */
            {
                bits_frame_channel = &( (Decoder_State *) sts[ch_idx] )->bits_frame_channel;
            }

            if ( mct_chan_mode[ch_idx] != MCT_CHAN_MODE_IGNORE )
            {
                assert( split_ratio[ch_idx] >= 1 && split_ratio[ch_idx] < BITRATE_MCT_RATIO_RANGE );
                
                *bits_frame_channel = split_ratio[ch_idx] * group_bits_frame_channel[group_idx] / BITRATE_MCT_RATIO_RANGE + min_chan_bits[ch_idx];
                bits_split += *bits_frame_channel;

                /*determine channel with most bits (energy)*/
                if ( *bits_frame_channel > tmp )
                {
                    tmp = *bits_frame_channel;
                    max_chn = ch_idx;
                }
            }

            ch_idx++;
        }
    }

    if ( bits_split != total_bits )
    {
        diff = bits_split - total_bits;
        bits_split = 0;

        for ( ch_idx = 0, group_idx = 0; group_idx < tcs_cfg.nb_group; group_idx++ )
        {
            for ( ch = 0; ch < tcs_cfg.nb_chan_group[group_idx]; ch++ )
            {
                if ( enc_dec == ENC )
                {
                    bits_frame_channel = &( (Encoder_State *) sts[ch_idx] )->bits_frame_channel;
                }
                else /* DEC */
                {
                    bits_frame_channel = &( (Decoder_State *) sts[ch_idx] )->bits_frame_channel;
                }

                if ( mct_chan_mode[ch_idx] != MCT_CHAN_MODE_IGNORE )
                {
                    *bits_frame_channel -= diff * split_ratio[ch_idx] / ( BITRATE_MCT_RATIO_RANGE * tcs_cfg.nb_group );
                    *bits_frame_channel = max( min_chan_bits[ch_idx], *bits_frame_channel );
                    bits_split += *bits_frame_channel;

                    if ( *bits_frame_channel > max_bits_frame && all_overflow_flag )
                    {
                        nchan_overflow_mask[ch_idx] = 1;
                        nchan_overflow++;
                    }
                }

                ch_idx++;
            }
        }
    }

    if ( all_overflow_flag )
    {
        bits_split = 0;
        for ( ch = 0; ch < nchan; ch++ )
        {
            if ( enc_dec == ENC )
            {
                bits_frame_channel = &( (Encoder_State *) sts[ch] )->bits_frame_channel;
            }
            else /* DEC */
            {
                bits_frame_channel = &( (Decoder_State *) sts[ch] )->bits_frame_channel;
            }

            if ( mct_chan_mode[ch] != MCT_CHAN_MODE_IGNORE )
            {
                if ( nchan_overflow_mask[ch] )
                {
                    *bits_frame_channel = max_bits_frame;
                    *bits_frame_channel = max( min_chan_bits[ch], *bits_frame_channel );
                }

                bits_split += *bits_frame_channel;
            }
        }

        diff = total_bits - bits_split;
        assert( diff >= 0 );
        assert( nchan_active >= 1 );
        diff = ( int16_t )( diff / max( 1, nchan_active ) );
        bits_split = 0;

        for ( ch = 0; ch < nchan; ch++ )
        {
            if ( enc_dec == ENC )
            {
                bits_frame_channel = &( (Encoder_State *) sts[ch] )->bits_frame_channel;
            }
            else /* DEC */
            {
                bits_frame_channel = &( (Decoder_State *) sts[ch] )->bits_frame_channel;
            }

            if ( mct_chan_mode[ch] != MCT_CHAN_MODE_IGNORE )
            {

                *bits_frame_channel += diff;
                *bits_frame_channel = max( min_chan_bits[ch], *bits_frame_channel );
                bits_split += *bits_frame_channel;
            }
        }
    }

    if ( total_bits != bits_split )
    {
        if ( enc_dec == ENC )
        {
            bits_frame_channel = &( (Encoder_State *) sts[max_chn] )->bits_frame_channel;
        }
        else /* DEC */
        {
            bits_frame_channel = &( (Decoder_State *) sts[max_chn] )->bits_frame_channel;
        }

        *bits_frame_channel += ( total_bits - bits_split );

        /*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;
            }
        }
    }

    return;
}
#endif

/*-------------------------------------------------------------------*
 * splitAvailableBitsMCT()
+138 −87
Original line number Diff line number Diff line
@@ -57,7 +57,6 @@ void debug_ivas_mp_write_pcm(
    int16_t *data_s = NULL;

    assert( nchan_output > 0 );
    assert( output_frame == L_FRAME48k || output_frame == ( L_FRAME48k / 2 ) );

    if ( ( data_s = (int16_t *) malloc( sizeof( int16_t ) * output_frame * nchan_output ) ) == NULL )
    {
@@ -77,109 +76,151 @@ void debug_ivas_mp_write_pcm(
}
#endif /* DEBUG_IVAS_SBA_MP_768KBPS */

int16_t ivas_mp_get_transoprt_channels(
MP_TCS_DMX_CONFIG ivas_mp_get_transport_group_config(
    const int16_t sba_order,
    const int32_t total_bitrate,
    const int16_t sba_order_input )
    const int16_t nchannels
)
{
    int16_t nchan_transport;

    nchan_transport = MP_ORDER2CH( sba_order_input );
    int16_t i, idx;

    if ( sba_order_input == SBA_HOA3_ORDER )
    idx = 0;
    for ( i = 0; i < MP_MAX_GROUP_TRANSPORT_CFG; i++ )
    {
        switch ( total_bitrate )
        if ( ( sba_order == ivas_mp_TCs_dmx_cfg_table[i].sba_order ) &&
             ( total_bitrate == ivas_mp_TCs_dmx_cfg_table[i].total_bitrate ) &&
             nchannels == ivas_mp_TCs_dmx_cfg_table[i].total_channels )
        {
            case IVAS_768k:
                nchan_transport = MP_ORDER2CH( SBA_HOA2_ORDER ) + 1;
                break;
            default:
            idx = i;
            break;
        }

        idx++;
    }

    return nchan_transport;
    return ivas_mp_TCs_dmx_cfg_table[idx];
}

int16_t ivas_mp_get_internal_sba_order(
int16_t ivas_mp_get_transport_channels(
    const int32_t total_bitrate,
    const int16_t sba_order_input,
    const int16_t enc_or_dec
)
    const int16_t sba_order_input )
{
    int16_t internal_sba_order;
    int16_t nchan_transport;

    internal_sba_order = sba_order_input;
    if ( sba_order_input == SBA_HOA3_ORDER )
    {
        if ( enc_or_dec == ENC )
        {
            internal_sba_order = SBA_HOA2_ORDER;
        }
        else if ( enc_or_dec == DEC )
    nchan_transport = MP_ORDER2CH( sba_order_input );

    if ( total_bitrate == IVAS_768k )
    {
            switch ( total_bitrate )
        switch ( sba_order_input )
        {
                case IVAS_768k:
                    internal_sba_order = SBA_HOA2_ORDER;
            case SBA_FOA_ORDER:
                nchan_transport = MP_ORDER2CH( SBA_FOA_ORDER );
                break;
            case SBA_HOA2_ORDER:
                nchan_transport = MP_ORDER2CH( SBA_HOA2_ORDER );
                break;
            case SBA_HOA3_ORDER:
                nchan_transport = MP_ORDER2CH( SBA_HOA2_ORDER );
                break;
            default:
                break;
        }
    }
    }

    return internal_sba_order;
    return nchan_transport;
}

void ivas_get_transport_channels_map(
int16_t ivas_mp_get_internal_analysis_sba_order(
    const int32_t total_bitrate,
    const int16_t sba_order_input,
    int16_t *transport_channels_map,
    const int16_t nchan_transport
)
    const int16_t enc_or_dec )
{
    int16_t ch;
    int16_t internal_sba_order;

    for ( ch = 0; ch < nchan_transport; ch++ )
    internal_sba_order = sba_order_input;
    if ( enc_or_dec == ENC )
    {
        transport_channels_map[ch] = ch;
        if ( total_bitrate == IVAS_768k )
        {
            internal_sba_order = SBA_FOA_ORDER;
        }

    if ( sba_order_input == SBA_HOA3_ORDER )
    }
    else if ( enc_or_dec == DEC )
    {
        if ( total_bitrate == IVAS_768k )
        {
            mvs2s( ivas_mp_transport_channels_10, transport_channels_map, nchan_transport );
            internal_sba_order = SBA_FOA_ORDER;
        }
    }

    return;
    return internal_sba_order;
}

void ivas_mp_config_open(
    MP_CONFIG_DATA_HANDLE hConfig,
    const int16_t nchan_input,
    const int32_t total_bitrate,
    const int16_t sba_order_input )
    const int16_t sba_order_input,
    const int32_t sr 
)
{
    int16_t i;

    hConfig->nchan_transport = ivas_mp_get_transoprt_channels( total_bitrate, sba_order_input );
    hConfig->nchan_transport = ivas_mp_get_transport_channels( total_bitrate, sba_order_input );
    hConfig->nchan_reconstruction = nchan_input - hConfig->nchan_transport;

    hConfig->nb_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
    hConfig->mp_dirac_band_factor = ( NS2SA( 48000, MP_OVERLAP_5MS_NS ) / NS2SA( 48000, DIRAC_SLOT_NS ) );
    hConfig->mp_dirac_band_factor = ( NS2SA( sr, MP_OVERLAP_5MS_NS ) / NS2SA( sr, DIRAC_SLOT_NS ) );

    hConfig->nb_subbands = MP_MAX_NBANDS;
    mvs2s( ivas_mp_dirac_band_group, hConfig->band_grouping, hConfig->nb_subbands + 1 );
    if ( sr == 48000 )
    {
        mvs2s( ivas_mp_dirac_band_group_48kHz, hConfig->band_grouping, hConfig->nb_subbands + 1 );
    }
    else if ( sr == 32000 )
    {
        mvs2s( ivas_mp_dirac_band_group_32kHz, hConfig->band_grouping, hConfig->nb_subbands + 1 );
    }
    else
    {
        // sr == 16000 / 8000
        mvs2s( ivas_mp_dirac_band_group_16kHz, hConfig->band_grouping, hConfig->nb_subbands + 1 );
    }

    for ( i = 0; i < hConfig->nb_subbands + 1; i++ )
    {
        hConfig->band_grouping_240[i] = hConfig->band_grouping[i] * hConfig->mp_dirac_band_factor;
    }

    hConfig->channels_mask_table = ivas_mp_channels_deci_mask_table;
    hConfig->channels_mask_table = ivas_mp_direction_component_mask_table;

    ivas_get_transport_channels_map( total_bitrate, sba_order_input, hConfig->transport_channels_map, hConfig->nchan_transport );
    mvs2s( ivas_mp_transport_channels_HOA2_table, hConfig->transport_channels_map, MP_MAX_CHANNELS_TRANSPORT );

    if ( total_bitrate == IVAS_768k )
    {
        if ( sba_order_input == SBA_FOA_ORDER )
        {
            mvs2s( ivas_mp_transport_channels_FOA_table, hConfig->transport_channels_map, MP_MAX_CHANNELS_TRANSPORT );
        }
        else if ( sba_order_input == SBA_HOA2_ORDER )
        {
            mvs2s( ivas_mp_transport_channels_HOA2_table, hConfig->transport_channels_map, MP_MAX_CHANNELS_TRANSPORT );
        }
        else if ( sba_order_input == SBA_HOA3_ORDER )
        {
            if ( hConfig->nchan_transport == 9 )
            {
                mvs2s( ivas_mp_transport_channels_HOA2_table, hConfig->transport_channels_map, MP_MAX_CHANNELS_TRANSPORT );
            }
#ifdef IVAS_SBA_MP_768KBPS_BR_SWITCHING
            else if ( hConfig->nchan_transport == 8 )
            {
                /* for bitrate switching */
                mvs2s( ivas_mp_transport_channels_8_HOA3_table, hConfig->transport_channels_map, MP_MAX_CHANNELS_TRANSPORT );
            }
#endif
        }
    }

    /* Huffman coding */
    hConfig->q_gain_table_size = MP_Q_GAIN_TABLE_SIZE;
@@ -192,24 +233,28 @@ void ivas_mp_config_open(

int16_t ivas_mp_metadata_open(
    MP_META_DATA_HANDLE hQMetadata,
    const int16_t nchan_reconstruction,
    const int16_t nchan_reference_gain,
    const int32_t total_bitrate )
{
    ivas_error error;
    int16_t i, j, ch;

    error = IVAS_ERR_OK;
    hQMetadata->nb_total_bits = ( int16_t )( total_bitrate / 50 );
    hQMetadata->nb_total_bits = ( int16_t )( total_bitrate / FRAMES_PER_SEC );
    hQMetadata->nb_bits_used = 0;
    hQMetadata->nb_directions = MP_MAX_DIRECTIONS;

    set_s( hQMetadata->frame_basis_idx, 0, MP_MAX_DIRECTIONS );

    if ( ( hQMetadata->q_reference_gain = (int16_t ***) malloc( nchan_reconstruction * sizeof( int16_t ** ) ) ) == NULL )
    hQMetadata->nchan_reference_gain = nchan_reference_gain;

    if ( nchan_reference_gain > 0 )
    {
        if ( ( hQMetadata->q_reference_gain = (int16_t ***) malloc( nchan_reference_gain * sizeof( int16_t ** ) ) ) == NULL )
        {
            return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MP metadata structure!\n" ) );
        }
    for ( ch = 0; ch < nchan_reconstruction; ch++ )
        for ( ch = 0; ch < nchan_reference_gain; ch++ )
        {
            if ( ( hQMetadata->q_reference_gain[ch] = (int16_t **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t * ) ) ) == NULL )
            {
@@ -224,7 +269,7 @@ int16_t ivas_mp_metadata_open(
            }
        }

    for ( ch = 0; ch < nchan_reconstruction; ch++ )
        for ( ch = 0; ch < nchan_reference_gain; ch++ )
        {
            for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
            {
@@ -234,16 +279,22 @@ int16_t ivas_mp_metadata_open(
                }
            }
        }
    }

    return error;
}

void ivas_mp_metadata_close(
    MP_META_DATA_HANDLE hQMetadata,
    const int16_t nchan_reconstruction )
    MP_META_DATA_HANDLE hQMetadata
)
{
    int16_t i, ch;
    int16_t nchan_reference_gain;

    for ( ch = 0; ch < nchan_reconstruction; ch++ )
    nchan_reference_gain = hQMetadata->nchan_reference_gain;
    if ( nchan_reference_gain > 0 )
    {
        for ( ch = 0; ch < nchan_reference_gain; ch++ )
        {
            for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
            {
@@ -255,7 +306,7 @@ void ivas_mp_metadata_close(
            }
        }

    for ( ch = 0; ch < nchan_reconstruction; ch++ )
        for ( ch = 0; ch < nchan_reference_gain; ch++ )
        {
            if ( hQMetadata->q_reference_gain[ch] != NULL )
            {
@@ -269,6 +320,7 @@ void ivas_mp_metadata_close(
            free( hQMetadata->q_reference_gain );
            hQMetadata->q_reference_gain = NULL;
        }
    }

    return;
}
@@ -277,8 +329,7 @@ void ivas_mp_getSH(
    float az,
    float ele,
    float *res,
    const int16_t len
)
    const int16_t len )
{
    float saz = (float) sin( az );
    float caz = (float) cos( az );
Loading