Loading lib_com/delay_comp.c +7 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading lib_com/ivas_cnst.h +13 −1 Original line number Diff line number Diff line Loading @@ -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)) Loading @@ -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 ) Loading @@ -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 Loading lib_com/ivas_error.h +3 −0 Original line number Diff line number Diff line Loading @@ -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, Loading lib_com/ivas_mct_com.c +241 −0 Original line number Diff line number Diff line Loading @@ -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() Loading lib_com/ivas_mp_com.c +138 −87 Original line number Diff line number Diff line Loading @@ -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 ) { Loading @@ -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; Loading @@ -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 ) { Loading @@ -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++ ) { Loading @@ -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++ ) { Loading @@ -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 ) { Loading @@ -269,6 +320,7 @@ void ivas_mp_metadata_close( free( hQMetadata->q_reference_gain ); hQMetadata->q_reference_gain = NULL; } } return; } Loading @@ -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 Loading
lib_com/delay_comp.c +7 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading
lib_com/ivas_cnst.h +13 −1 Original line number Diff line number Diff line Loading @@ -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)) Loading @@ -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 ) Loading @@ -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 Loading
lib_com/ivas_error.h +3 −0 Original line number Diff line number Diff line Loading @@ -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, Loading
lib_com/ivas_mct_com.c +241 −0 Original line number Diff line number Diff line Loading @@ -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() Loading
lib_com/ivas_mp_com.c +138 −87 Original line number Diff line number Diff line Loading @@ -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 ) { Loading @@ -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; Loading @@ -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 ) { Loading @@ -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++ ) { Loading @@ -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++ ) { Loading @@ -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 ) { Loading @@ -269,6 +320,7 @@ void ivas_mp_metadata_close( free( hQMetadata->q_reference_gain ); hQMetadata->q_reference_gain = NULL; } } return; } Loading @@ -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