diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 8e3558bbada99a810636136e7abd2643ce88db89..ff23fb7ebf04df04dc9b29e02c882ee1404fcbf8 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3028,6 +3028,10 @@ void ivas_dirac_param_est_enc( float **pp_fr_real, float **pp_fr_imag, const int16_t input_frame +#ifdef SBA_HOA_HBR_IMPROV + , + const SBA_MODE sba_mode +#endif ); /*----------------------------------------------------------------------------------* @@ -3087,6 +3091,14 @@ int16_t ivas_sba_get_nchan_metadata( const int16_t sba_order /* i : Ambisonic (SBA) order */ ); +#ifdef SBA_HOA_HBR_IMPROV +/*! r: get the flag to code SPAR HOA MD for all band */ +int16_t ivas_sba_get_spar_hoa_md_flag( + const int16_t sba_order, /* i : Ambisonic (SBA) order */ + const int32_t ivas_total_brate /* i : IVAS total bitrate */ +); +#endif + void ivas_sba_zero_vert_comp( float sba_data[][L_FRAME48k], /* i/o: SBA data frame */ const int16_t sba_order, /* i : Ambisonic (SBA) order */ @@ -3974,6 +3986,10 @@ ivas_error ivas_spar_md_dec_open( ivas_spar_md_dec_state_t **hMdDec_out, /* i/o: SPAR MD decoder handle */ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ const int16_t num_channels /* i : number of internal channels */ +#ifdef SBA_HOA_HBR_IMPROV + , + const int16_t sba_order /* i : flag to send HOA MD for all bands */ +#endif ); void ivas_spar_md_dec_close( @@ -4821,6 +4837,10 @@ void computeReferencePower_enc( float *reference_power, /* o : Estimated power */ const int16_t enc_param_start_band, /* i : first band to process */ const int16_t num_freq_bands /* i : Number of frequency bands */ +#ifdef SBA_HOA_HBR_IMPROV + , + const SBA_MODE sba_mode /* i : SBA mode */ +#endif ); diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config.c index 37d9e58accc657f0cb4c299e797a6eaed1ac8ed8..d7e47960b09673e0b9db4776b84c853d26bbb841 100644 --- a/lib_com/ivas_sba_config.c +++ b/lib_com/ivas_sba_config.c @@ -281,6 +281,31 @@ int16_t ivas_sba_get_nchan_metadata( return ( nb_channels ); } +#ifdef SBA_HOA_HBR_IMPROV +/*-------------------------------------------------------------------* + * ivas_sba_get_spar_hoa_md_flag() + * + * et the flag to code SPAR HOA MD for all band + *-------------------------------------------------------------------*/ + +/*! r: get the flag to code SPAR HOA MD for all band */ +int16_t ivas_sba_get_spar_hoa_md_flag( + const int16_t sba_order, /* i : Ambisonic (SBA) order */ + const int32_t ivas_total_brate /* i : IVAS total bitrate */ +) +{ + int16_t spar_hoa_md_flag = 0; + if ( sba_order > 1 && ivas_total_brate >= IVAS_256k ) + { + spar_hoa_md_flag = 1; + } + else + { + spar_hoa_md_flag = 0; + } + return spar_hoa_md_flag; +} +#endif /*-------------------------------------------------------------------* * ivas_sba_zero_vert_comp() diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index a93326ec9cc793a9e2e03394fe2239278130219d..b5821e4632c2f60be4ca7b67ee6522a5efe7df62 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -1737,10 +1737,11 @@ void ivas_get_spar_md_from_dirac( /*SPAR from DirAC*/ set_f( response_avg, 0.0f, MAX_OUTPUT_CHANNELS ); +#ifndef SBA_HOA_HBR_IMPROV set_f( hSpar_md->band_coeffs[band + i_ts * IVAS_MAX_NUM_BANDS].pred_re, 0.0f, IVAS_SPAR_MAX_CH - 1 ); set_f( &hSpar_md->band_coeffs[band + i_ts * IVAS_MAX_NUM_BANDS].C_re[0][0], 0.0f, ( IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS ) * ( IVAS_SPAR_MAX_DMX_CHS - 1 ) ); set_f( &hSpar_md->band_coeffs[band + i_ts * IVAS_MAX_NUM_BANDS].P_re[0], 0.0f, ( IVAS_SPAR_MAX_CH - 1 ) ); - +#endif if ( n_ts > 1 ) { ivas_dirac_dec_get_response( (int16_t) azi_dirac[band][i_ts], (int16_t) ele_dirac[band][i_ts], response_avg, order ); diff --git a/lib_com/options.h b/lib_com/options.h old mode 100755 new mode 100644 index 1c21e85d2dad86a3ec25b9758961948093c1df86..b988fcb581dd99ec968794076c1d2445f96ea7ef --- a/lib_com/options.h +++ b/lib_com/options.h @@ -151,7 +151,7 @@ #define SBA_SPAR_HARM /* Issue 92: maintenance of the SBA SPAR functions */ #define FIX_155_HP20_ISSUE /* Issue 155: apply hp20 on all input channels instead of just 2 channels */ #define EFAP_FIX_POLY /* Issue 167: fix bug in EFAP polygon selection */ - +#define SBA_HOA_HBR_IMPROV /* issue 91: Improvements to SBA high bitrate HOA3 coding */ /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index c7a3fcff20633dc2ba1dc751b27dea4be4245ec5..7a0590e6c1d1f9e9d083647ea7ab0ce8732b52e3 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -89,7 +89,12 @@ ivas_error ivas_spar_dec_open( } /* MD handle */ - if ( ( error = ivas_spar_md_dec_open( &hSpar->hMdDec, st_ivas->hDecoderConfig, num_channels_internal ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_spar_md_dec_open( &hSpar->hMdDec, st_ivas->hDecoderConfig, num_channels_internal +#ifdef SBA_HOA_HBR_IMPROV + , + sba_order_internal +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -645,7 +650,16 @@ static void ivas_spar_dec_MD( { ivas_parse_spar_header( hDecoderConfig->ivas_total_brate, sba_order, st0, &table_idx ); - hSpar->hMdDec->spar_md.num_bands = min( SPAR_DIRAC_SPLIT_START_BAND, IVAS_MAX_NUM_BANDS ); +#ifdef SBA_HOA_HBR_IMPROV + if ( hSpar->hMdDec->spar_hoa_md_flag ) + { + hSpar->hMdDec->spar_md.num_bands = IVAS_MAX_NUM_BANDS; + } + else +#endif + { + hSpar->hMdDec->spar_md.num_bands = min( SPAR_DIRAC_SPLIT_START_BAND, IVAS_MAX_NUM_BANDS ); + } if ( hSpar->hMdDec->table_idx != table_idx ) { @@ -788,7 +802,12 @@ void ivas_spar_get_parameters( weight = ivas_spar_get_cldfb_slot_gain( hSpar, hDecoderConfig, ts, &ts0, &ts1, &weight_20ms ); +#ifdef SBA_HOA_HBR_IMPROV + split_band = hSpar->hMdDec->spar_md.num_bands; +#else split_band = SPAR_DIRAC_SPLIT_START_BAND; +#endif + for ( spar_band = 0; spar_band < num_spar_bands; spar_band++ ) { for ( out_ch = 0; out_ch < num_ch_out; out_ch++ ) diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index f192228e81c085c759d91fb093269ca7b8a46dbb..3d5f03b2087cde099c7f145eb6d8fe0f53cbe6c8 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -250,6 +250,10 @@ ivas_error ivas_spar_md_dec_open( ivas_spar_md_dec_state_t **hMdDec_out, /* i/o: SPAR MD decoder handle */ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ const int16_t num_channels /* i : number of internal channels */ +#ifdef SBA_HOA_HBR_IMPROV + , + const int16_t sba_order /* i : SBA order */ +#endif ) { ivas_spar_md_dec_state_t *hMdDec; @@ -267,6 +271,9 @@ ivas_error ivas_spar_md_dec_open( return error; } +#ifdef SBA_HOA_HBR_IMPROV + hMdDec->spar_hoa_md_flag = ivas_sba_get_spar_hoa_md_flag( sba_order, hDecoderConfig->ivas_total_brate ); +#endif hMdDec->table_idx = 0; /* just to initialize state variables*/ if ( ( error = ivas_spar_md_dec_init( hMdDec, hDecoderConfig, num_channels ) ) != IVAS_ERR_OK ) @@ -438,7 +445,20 @@ ivas_error ivas_spar_md_dec_init( float pFC[IVAS_MAX_NUM_BANDS], PR_minmax[2]; hMdDec->spar_md_cfg.gen_bs = 1; // VE2DB : always 1 - can it be removed? - ivas_spar_set_bitrate_config( &hMdDec->spar_md_cfg, hMdDec->table_idx, min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ) ); + +#ifdef SBA_HOA_HBR_IMPROV + hMdDec->spar_md.num_bands = ( hMdDec->spar_hoa_md_flag ) ? IVAS_MAX_NUM_BANDS : min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); +#else + hMdDec->spar_md.num_bands = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); +#endif + + ivas_spar_set_bitrate_config( &hMdDec->spar_md_cfg, hMdDec->table_idx, +#ifdef SBA_HOA_HBR_IMPROV + hMdDec->spar_md.num_bands +#else + min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ) +#endif + ); nchan_transport = hMdDec->spar_md_cfg.nchan_transport; @@ -523,7 +543,6 @@ ivas_error ivas_spar_md_dec_init( ivas_clear_band_coeff_idx( hMdDec->spar_md_prev.band_coeffs_idx_mapped, IVAS_MAX_NUM_BANDS ); hMdDec->spar_md.dtx_vad = 0; - hMdDec->spar_md.num_bands = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); hMdDec->td_decorr_flag = 1; set_f( hMdDec->spar_md.en_ratio_slow, 0.0f, IVAS_MAX_NUM_BANDS ); @@ -687,7 +706,11 @@ void ivas_spar_md_dec_process( /* expand DirAC MD to all time slots */ for ( i_ts = 1; i_ts < MAX_PARAM_SPATIAL_SUBFRAMES; i_ts++ ) { +#ifdef SBA_HOA_HBR_IMPROV + for ( b = 0; b < hMdDec->spar_md.num_bands; b++ ) +#else for ( b = 0; b < min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); b++ ) +#endif { for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) { @@ -1768,6 +1791,15 @@ static void ivas_decode_arith_bs( ndec = hMdDec->spar_md_cfg.num_decorr_per_band[bands_bw * i]; pred_cell_dims[i].dim1 = ndm + ndec - 1; +#ifdef SBA_HOA_HBR_IMPROV + if ( hMdDec->spar_hoa_md_flag ) + { + if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) + { + pred_cell_dims[i].dim1 -= ( FOA_CHANNELS - 1 ); + } + } +#endif pred_cell_dims[i].dim2 = 1; drct_cell_dims[i].dim1 = ndec; drct_cell_dims[i].dim2 = ndm - 1; @@ -1788,6 +1820,23 @@ static void ivas_decode_arith_bs( if ( any_diff == 1 ) { +#ifdef SBA_HOA_HBR_IMPROV + if ( hMdDec->spar_hoa_md_flag ) + { + int16_t j; + for ( i = 0; i < nB; i++ ) + { + if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) + { + for ( j = 0; j < pred_cell_dims[i].dim1; j++ ) + { + hMdDec->spar_md_prev.band_coeffs_idx_mapped[i].pred_index_re[j] = + hMdDec->spar_md_prev.band_coeffs_idx_mapped[i].pred_index_re[j + ( FOA_CHANNELS - 1 )]; + } + } + } + } +#endif ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, pred_cell_dims, PRED_COEFF, planarCP ); } @@ -1796,6 +1845,28 @@ static void ivas_decode_arith_bs( ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, pred_cell_dims, PRED_COEFF, planarCP ); +#ifdef SBA_HOA_HBR_IMPROV + if ( hMdDec->spar_hoa_md_flag ) + { + int16_t j; + for ( i = 0; i < nB; i++ ) + { + if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) + { + for ( j = pred_cell_dims[i].dim1 - 1; j >= 0; j-- ) + { + hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j + ( FOA_CHANNELS - 1 )] = + hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j]; + } + for ( j = 0; j < FOA_CHANNELS - 1; j++ ) + { + hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j] = 0; + } + } + } + } +#endif + if ( any_diff == 1 ) { ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, drct_cell_dims, DRCT_COEFF, planarCP ); @@ -2035,7 +2106,7 @@ static void ivas_decode_huffman_bs( for ( i = 0; i < nB; i++ ) { int16_t ndm, ndec; - int16_t pred_dim, drct_dim, decd_dim; + int16_t pred_dim, drct_dim, decd_dim, pred_offset; ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; ndec = hMdDec->spar_md_cfg.num_decorr_per_band[bands_bw * i]; @@ -2043,13 +2114,36 @@ static void ivas_decode_huffman_bs( pred_dim = ndec + ndm - 1; drct_dim = ndec * ( ndm - 1 ); decd_dim = ndec; + pred_offset = 0; +#ifdef SBA_HOA_HBR_IMPROV + if ( hMdDec->spar_hoa_md_flag ) + { + if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) + { + pred_offset = FOA_CHANNELS - 1; + } + } +#endif - for ( j = 0; j < pred_dim; j++ ) + for ( j = pred_offset; j < pred_dim; j++ ) { ivas_huffman_decode( &hMdDec->huff_coeffs.pred_huff_re[qsi], st0, &hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j] ); } +#ifdef SBA_HOA_HBR_IMPROV + if ( hMdDec->spar_hoa_md_flag ) + { + if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) + { + for ( j = 0; j < pred_offset; j++ ) + { + hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j] = 0; + } + } + } +#endif + for ( j = 0; j < drct_dim; j++ ) { if ( planarCP && !keep_planar[(int16_t) floor( j / ( ndm - 1 ) )] ) @@ -2701,7 +2795,13 @@ void ivas_spar_to_dirac( if ( hMdDec->spar_md_cfg.nchan_transport > 1 ) { ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, - end_band, num_bands_out, sba_order_internal, dtx_vad, NULL ); + end_band, num_bands_out, +#ifdef SBA_HOA_HBR_IMPROV + ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, +#else + sba_order_internal, +#endif + dtx_vad, NULL ); /* temporarily copy frame-wise prediction coefficients in DirAC bands*/ for ( pred_idx = 0; pred_idx < FOA_CHANNELS - 1; pred_idx++ ) @@ -2714,7 +2814,13 @@ void ivas_spar_to_dirac( } ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, MAX_PARAM_SPATIAL_SUBFRAMES, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, - end_band, num_bands_out, sba_order_internal, dtx_vad, NULL ); + end_band, num_bands_out, +#ifdef SBA_HOA_HBR_IMPROV + ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, +#else + sba_order_internal, +#endif + dtx_vad, NULL ); /* expand DirAC TC 20ms MD for residual channels to all subframes*/ for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 8c0ea336c329012c2d7068f812a226cdd3371911..925fa5dfd7267acdcff3b351763d7a47f21b9f39 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -807,7 +807,9 @@ typedef struct ivas_spar_md_dec_state_t ivas_huff_coeffs_t huff_coeffs; int16_t table_idx; int16_t dtx_vad; - +#ifdef SBA_HOA_HBR_IMPROV + int16_t spar_hoa_md_flag; +#endif } ivas_spar_md_dec_state_t; diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index 9484aa273737299fd0a5114551abaedf47db7dfa..063ec02d8f29f10222c53f9a468c878267341702 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -334,7 +334,12 @@ void ivas_dirac_enc( set_zero( data_f[2], input_frame ); } - ivas_dirac_param_est_enc( hDirAC, &( hQMetaData->q_direction[0] ), hQMetaData->useLowerRes, data_f, NULL, NULL, input_frame ); + ivas_dirac_param_est_enc( hDirAC, &( hQMetaData->q_direction[0] ), hQMetaData->useLowerRes, data_f, NULL, NULL, input_frame +#ifdef SBA_HOA_HBR_IMPROV + , + SBA_MODE_DIRAC +#endif + ); /* encode parameters */ if ( sba_planar || hQMetaData->useLowerRes ) { @@ -508,18 +513,38 @@ void computeReferencePower_enc( float *reference_power, /* o : Estimated power */ const int16_t enc_param_start_band, /* i : first band to process */ const int16_t num_freq_bands /* i : Number of frequency bands */ +#ifdef SBA_HOA_HBR_IMPROV + , + const SBA_MODE sba_mode +#endif ) { int16_t brange[2]; int16_t ch_idx, i, j; +#ifdef SBA_HOA_HBR_IMPROV + float reference_power_W[DIRAC_MAX_NBANDS]; +#endif + for ( i = 0; i < num_freq_bands; i++ ) { brange[0] = band_grouping[i + enc_param_start_band]; brange[1] = band_grouping[i + enc_param_start_band + 1]; reference_power[i] = 0; +#ifdef SBA_HOA_HBR_IMPROV + reference_power_W[i] = 0; + for ( j = brange[0]; j < brange[1]; j++ ) + { + reference_power_W[i] += ( Cldfb_RealBuffer[0][j] * Cldfb_RealBuffer[0][j] ) + ( Cldfb_ImagBuffer[0][j] * Cldfb_ImagBuffer[0][j] ); + } + reference_power[i] += reference_power_W[i]; +#endif +#ifdef SBA_HOA_HBR_IMPROV + for ( ch_idx = 1; ch_idx < DIRAC_MAX_ANA_CHANS; ch_idx++ ) +#else for ( ch_idx = 0; ch_idx < DIRAC_MAX_ANA_CHANS; ch_idx++ ) +#endif { /* abs()^2 */ for ( j = brange[0]; j < brange[1]; j++ ) @@ -530,6 +555,15 @@ void computeReferencePower_enc( } v_multc( reference_power, 0.5f, reference_power, num_freq_bands ); +#ifdef SBA_HOA_HBR_IMPROV + if ( sba_mode == SBA_MODE_SPAR ) + { + for ( i = 0; i < num_freq_bands; i++ ) + { + reference_power[i] = max( reference_power[i], reference_power_W[i] ); + } + } +#endif return; } @@ -548,7 +582,12 @@ void ivas_dirac_param_est_enc( float data_f[][L_FRAME48k], float **pp_fr_real, float **pp_fr_imag, - const int16_t input_frame ) + const int16_t input_frame +#ifdef SBA_HOA_HBR_IMPROV + , + const SBA_MODE sba_mode +#endif +) { int16_t i, d, ts, index, l_ts, num_freq_bands; int16_t band_m_idx, block_m_idx; @@ -646,7 +685,12 @@ void ivas_dirac_param_est_enc( Cldfb_ImagBuffer, reference_power[ts], hDirAC->hConfig->enc_param_start_band, - num_freq_bands ); + num_freq_bands +#ifdef SBA_HOA_HBR_IMPROV + , + sba_mode +#endif + ); computeIntensityVector_enc( hDirAC, diff --git a/lib_enc/ivas_entropy_coder.c b/lib_enc/ivas_entropy_coder.c index 1c1d1d564fa6aff9052e2ad4ba37009851db4e0f..7f5ab7b996377bfbf38fb605194570e6afaed33a 100644 --- a/lib_enc/ivas_entropy_coder.c +++ b/lib_enc/ivas_entropy_coder.c @@ -316,11 +316,17 @@ void ivas_arith_encode_cmplx_cell_array( int16_t input[IVAS_MAX_INPUT_LEN]; ivas_cell_dim_t cell_dim[IVAS_MAX_NUM_BANDS], cell_dim_diff[IVAS_MAX_NUM_BANDS]; int16_t len, idx, i, j, idx1; +#ifdef SBA_HOA_HBR_IMPROV + int16_t total_len; +#endif idx1 = 0; if ( any_diff == 1 ) { idx = 0; +#ifdef SBA_HOA_HBR_IMPROV + total_len = 0; +#endif for ( i = 0; i < nB; i++ ) { len = ( pCell_dims[i].dim1 * pCell_dims[i].dim2 ); @@ -328,8 +334,13 @@ void ivas_arith_encode_cmplx_cell_array( { for ( j = 0; j < len; j++ ) { +#ifdef SBA_HOA_HBR_IMPROV + input_old[idx] = pSymbol_old_re[total_len + j]; + input_new[idx++] = pSymbol_re[total_len + j]; +#else input_old[idx] = pSymbol_old_re[i * len + j]; input_new[idx++] = pSymbol_re[i * len + j]; +#endif } cell_dim_diff[i].dim1 = pCell_dims[i].dim1; cell_dim_diff[i].dim2 = pCell_dims[i].dim2; @@ -340,13 +351,20 @@ void ivas_arith_encode_cmplx_cell_array( { for ( j = 0; j < len; j++ ) { +#ifdef SBA_HOA_HBR_IMPROV + input[idx1++] = pSymbol_re[total_len + j]; +#else input[idx1++] = pSymbol_re[i * len + j]; +#endif } cell_dim_diff[i].dim1 = 0; cell_dim_diff[i].dim2 = 0; cell_dim[i].dim1 = pCell_dims[i].dim1; cell_dim[i].dim2 = pCell_dims[i].dim2; } +#ifdef SBA_HOA_HBR_IMPROV + total_len += len; +#endif } #ifdef SPAR_HOA_DBG /*if ( 0 )*/ /*(pCell_dims[0].dim1 == 12)*/ diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc.c index a281ec4760f04279d30f5f4a6d6e17683d5ad6fe..1329e572ae694805eefad324fa3159ec9dfbfd08 100644 --- a/lib_enc/ivas_mcmasa_enc.c +++ b/lib_enc/ivas_mcmasa_enc.c @@ -892,7 +892,12 @@ void ivas_mcmasa_param_est_enc( intensity_even_real ); computeReferencePower_enc( hMcMasa->band_grouping, FoaEven_RealBuffer, FoaEven_ImagBuffer, reference_power[ts], 0, - num_freq_bands ); + num_freq_bands +#ifdef SBA_HOA_HBR_IMPROV + , + SBA_MODE_NONE +#endif + ); /* Fill buffers of length "averaging_length" time slots for intensity and energy */ hMcMasa->index_buffer_intensity = ( hMcMasa->index_buffer_intensity % hMcMasa->no_col_avg_diff ) + 1; /* averaging_length = 32 */ diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc.c index d2397d587a75619f08d88cc599ead8452f2d8e5b..f682a380f75bf69512075841b4c85f2db915a897 100644 --- a/lib_enc/ivas_mct_core_enc.c +++ b/lib_enc/ivas_mct_core_enc.c @@ -139,11 +139,11 @@ static void AdjustChannelRatios( ivas_spar_bitrate_dist( temp_brs, nAvailBits, , sba_order, 3 ); sum_ratio = 0.0f; - for ( i = 0; i < nchan; i++ ) + for ( i = 0; i < nChannels; i++ ) { sum_ratio += (float) temp_brs[i]; } - for ( i = 0; i < nchan; i++ ) + for ( i = 0; i < nChannels; i++ ) { cur_ratio = temp_brs[i] / sum_ratio; force_ch_bit_ratios[i] = min( BITRATE_MCT_RATIO_RANGE - 1, max( 1, (uint16_t) ( BITRATE_MCT_RATIO_RANGE * cur_ratio + 0.5f ) ) ); @@ -178,14 +178,14 @@ static void AdjustChannelRatios( } chBitRatios[1] += ratio_diff; -#ifdef FIX_I1_113 +#ifdef SBA_HOA_HBR_IMPROV /* make sure final ratios are within range*/ sum_ratio = 0.0f; for ( i = 0; i < nChannels; i++ ) { sum_ratio += (float) chBitRatios[i]; } - for ( i = 0; i < nchan; i++ ) + for ( i = 0; i < nChannels; i++ ) { cur_ratio = chBitRatios[i] / sum_ratio; chBitRatios[i] = min( BITRATE_MCT_RATIO_RANGE - 1, max( 1, (uint16_t) ( BITRATE_MCT_RATIO_RANGE * cur_ratio + 0.5f ) ) ); diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index 988a8fa01398ff7fbf93cb5d2cd67598a6162935..bbf1c332b599ac6a702c8e0843e9f393c6c81b76 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -538,12 +538,23 @@ static ivas_error ivas_spar_enc_process( #ifdef SBA_SPAR_HARM ivas_dirac_param_est_enc( st_ivas->hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes, - data_f, ppIn_FR_real, ppIn_FR_imag, input_frame ); + data_f, ppIn_FR_real, ppIn_FR_imag, input_frame +#ifdef SBA_HOA_HBR_IMPROV + , + st_ivas->sba_mode +#endif + ); #else ivas_dirac_param_est_enc( st_ivas->hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes, - data_f, cov_in_buf.ppIn_FR_real, cov_in_buf.ppIn_FR_imag, input_frame ); + data_f, cov_in_buf.ppIn_FR_real, cov_in_buf.ppIn_FR_imag, input_frame +#ifdef SBA_HOA_HBR_IMPROV + , + st_ivas->sba_mode +#endif + ); #endif + if ( hQMetaData->q_direction->cfg.nbands > 0 ) { orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands; @@ -675,7 +686,13 @@ static ivas_error ivas_spar_enc_process( if ( hSpar->hMdEnc->table_idx != table_idx ) { hSpar->hMdEnc->table_idx = table_idx; - ivas_spar_set_bitrate_config( &hSpar->hMdEnc->spar_md_cfg, table_idx, SPAR_DIRAC_SPLIT_START_BAND ); + ivas_spar_set_bitrate_config( &hSpar->hMdEnc->spar_md_cfg, table_idx, +#ifdef SBA_HOA_HBR_IMPROV + ( hSpar->hMdEnc->spar_hoa_md_flag ) ? IVAS_MAX_NUM_BANDS : SPAR_DIRAC_SPLIT_START_BAND +#else + SPAR_DIRAC_SPLIT_START_BAND +#endif + ); } #ifdef SBA_SPAR_HARM @@ -689,7 +706,12 @@ static ivas_error ivas_spar_enc_process( *-----------------------------------------------------------------------------------------*/ #ifdef SBA_SPAR_HARM - ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, hMetaData, dtx_vad, nchan_inp, sba_order ); +#ifdef SBA_HOA_HBR_IMPROV + if ( hSpar->hMdEnc->spar_hoa_md_flag == 0 ) +#endif + { + ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, hMetaData, dtx_vad, nchan_inp, sba_order ); + } #else num_bands_bw = ivas_get_num_bands_from_bw_idx( bwidth ); @@ -723,11 +745,21 @@ static ivas_error ivas_spar_enc_process( } md_in_buf.num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW ); - md_in_buf.num_bands = min( md_in_buf.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); +#ifdef SBA_HOA_HBR_IMPROV + if ( hSpar->hMdEnc->spar_hoa_md_flag == 0 ) +#endif + { + md_in_buf.num_bands = min( md_in_buf.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); + } md_in_buf.dtx_vad = dtx_vad; - ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, &md_in_buf, hMetaData, dtx_silence_mode, sba_order ); +#ifdef SBA_HOA_HBR_IMPROV + if ( hSpar->hMdEnc->spar_hoa_md_flag == 0 ) +#endif + { + ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, &md_in_buf, hMetaData, dtx_silence_mode, sba_order ); + } #endif #ifndef SBA_SPAR_HARM @@ -776,9 +808,22 @@ static ivas_error ivas_spar_enc_process( Wscale_d[b] = min( 2.0f, max( Wscale_d[b], 1.0f ) ); } - ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, hSpar->hMdEnc->mixer_mat, &hSpar->hMdEnc->spar_md, &hSpar->hMdEnc->spar_md_cfg, d_start_band, d_end_band, sba_order, dtx_vad, Wscale_d ); + ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, hSpar->hMdEnc->mixer_mat, &hSpar->hMdEnc->spar_md, &hSpar->hMdEnc->spar_md_cfg, + d_start_band, d_end_band, +#ifdef SBA_HOA_HBR_IMPROV + ( hSpar->hMdEnc->spar_hoa_md_flag ) ? 1 : sba_order, +#else + sba_order, +#endif + dtx_vad, Wscale_d ); } +#ifdef SBA_HOA_HBR_IMPROV + if ( hSpar->hMdEnc->spar_hoa_md_flag ) + { + ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, hMetaData, dtx_vad, nchan_inp, sba_order ); + } +#endif /*-----------------------------------------------------------------------------------------* * FB mixer diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index ce8a0e3bc176332fce4415a4ddee6ace2dc1de9b..2624389cc42606485bc63fb2ee3de587025cccb5 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -121,6 +121,10 @@ ivas_error ivas_spar_md_enc_open( num_channels = 2 * sba_order + 2; +#ifdef SBA_HOA_HBR_IMPROV + hMdEnc->spar_hoa_md_flag = ivas_sba_get_spar_hoa_md_flag( sba_order, hEncoderConfig->ivas_total_brate ); +#endif + if ( ( hMdEnc->spar_md.band_coeffs = (ivas_band_coeffs_t *) count_malloc( IVAS_MAX_NUM_BANDS * sizeof( ivas_band_coeffs_t ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for band_coeffs in SPAR MD" ); @@ -320,7 +324,13 @@ static ivas_error ivas_spar_md_enc_init( table_idx = ivas_get_spar_table_idx( hEncoderConfig->ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); hMdEnc->spar_md_cfg.gen_bs = 1; - ivas_spar_set_bitrate_config( &hMdEnc->spar_md_cfg, table_idx, SPAR_DIRAC_SPLIT_START_BAND ); + ivas_spar_set_bitrate_config( &hMdEnc->spar_md_cfg, table_idx, +#ifdef SBA_HOA_HBR_IMPROV + ( hMdEnc->spar_hoa_md_flag ) ? IVAS_MAX_NUM_BANDS : SPAR_DIRAC_SPLIT_START_BAND +#else + SPAR_DIRAC_SPLIT_START_BAND +#endif + ); /* get FB coefficients */ for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) @@ -570,7 +580,9 @@ ivas_error ivas_spar_md_enc_process( { float pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; - +#ifdef SBA_HOA_HBR_IMPROV + float pred_coeffs_re_local[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; +#endif int16_t i, b, qsi, ndm, ndec, num_ch, num_quant_strats; int16_t j, planarCP; #ifdef SBA_SPAR_HARM @@ -598,7 +610,12 @@ ivas_error ivas_spar_md_enc_process( bwidth = min( bwidth, hEncoderConfig->max_bwidth ); num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW ); - num_bands = min( num_bands, SPAR_DIRAC_SPLIT_START_BAND ); +#ifdef SBA_HOA_HBR_IMPROV + if ( hMdEnc->spar_hoa_md_flag == 0 ) +#endif + { + num_bands = min( num_bands, SPAR_DIRAC_SPLIT_START_BAND ); + } num_bands_full = num_bands; num_bands_bw = ivas_get_num_bands_from_bw_idx( bwidth ); @@ -671,6 +688,20 @@ ivas_error ivas_spar_md_enc_process( bands_bw = 1; } +#ifdef SBA_HOA_HBR_IMPROV + if ( hMdEnc->spar_hoa_md_flag ) + { + for ( b = SPAR_DIRAC_SPLIT_START_BAND; b < num_bands; b++ ) + { + for ( i = 0; i < FOA_CHANNELS - 1; i++ ) + { + pred_coeffs_re_local[i][b] = + hMdEnc->spar_md.band_coeffs[b].pred_re[i]; + } + } + } +#endif + #ifdef SBA_SPAR_HARM ivas_compute_spar_params( cov_real, dm_fv_re, 0, hMdEnc->mixer_mat, 0, nB, dtx_vad, num_ch, bands_bw, active_w, &hMdEnc->spar_md_cfg, &hMdEnc->spar_md, Wscale, 0 ); @@ -807,6 +838,24 @@ ivas_error ivas_spar_md_enc_process( } } +#ifdef SBA_HOA_HBR_IMPROV + if ( hMdEnc->spar_hoa_md_flag ) + { + for ( b = SPAR_DIRAC_SPLIT_START_BAND; b < num_bands; b++ ) + { + for ( i = 0; i < FOA_CHANNELS - 1; i++ ) + { + /* Use the prediction coeffs computed based on DirAC MD + to generate mixer matrix */ + pred_coeffs_re[i][b] = + pred_coeffs_re_local[i][b]; + hMdEnc->spar_md.band_coeffs[b].pred_quant_re[i] = 0; + hMdEnc->spar_md.band_coeffs_idx[b].pred_index_re[i] = 0; + } + } + } +#endif + ivas_create_fullr_dmx_mat( pred_coeffs_re, dm_fv_re, hMdEnc->mixer_mat, num_ch, 0, num_bands, active_w, &hMdEnc->spar_md_cfg ); for ( b = 0; b < num_bands; b++ ) @@ -1298,6 +1347,7 @@ static void ivas_get_huffman_coded_bs( const int16_t planarCP ) { int16_t i, j; + int16_t pred_coeff_dim, pred_offset; for ( i = 0; i < nB; i++ ) { @@ -1305,9 +1355,21 @@ static void ivas_get_huffman_coded_bs( int16_t ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[i]; int16_t ndec = hMdEnc->spar_md_cfg.num_decorr_per_band[i]; + pred_coeff_dim = ndm + ndec - 1; + pred_offset = 0; +#ifdef SBA_HOA_HBR_IMPROV + if ( hMdEnc->spar_hoa_md_flag ) + { + if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) + { + pred_offset = FOA_CHANNELS - 1; + } + } +#endif + if ( planarCP ) { - for ( j = 0; j < ndm + ndec - 1; j++ ) + for ( j = pred_offset; j < pred_coeff_dim; j++ ) { ivas_huffman_encode( &hMdEnc->huff_coeffs.pred_huff_re[qsi], hMdEnc->spar_md.band_coeffs_idx[i].pred_index_re[j], &code, &len ); push_next_indice( hMetaData, code, len ); @@ -1333,7 +1395,7 @@ static void ivas_get_huffman_coded_bs( } else { - for ( j = 0; j < ndm + ndec - 1; j++ ) + for ( j = pred_offset; j < pred_coeff_dim; j++ ) { ivas_huffman_encode( &hMdEnc->huff_coeffs.pred_huff_re[qsi], hMdEnc->spar_md.band_coeffs_idx[i].pred_index_re[j], &code, &len ); push_next_indice( hMetaData, code, len ); @@ -1386,6 +1448,15 @@ static void ivas_get_arith_coded_bs( ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; ndec = hMdEnc->spar_md_cfg.num_decorr_per_band[bands_bw * i]; pred_cell_dims[i].dim1 = ndm + ndec - 1; +#ifdef SBA_HOA_HBR_IMPROV + if ( hMdEnc->spar_hoa_md_flag ) + { + if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) + { + pred_cell_dims[i].dim1 -= ( FOA_CHANNELS - 1 ); + } + } +#endif pred_cell_dims[i].dim2 = 1; drct_cell_dims[i].dim1 = ndec; drct_cell_dims[i].dim2 = ndm - 1; @@ -1404,7 +1475,28 @@ static void ivas_get_arith_coded_bs( break; } } - +#ifdef SBA_HOA_HBR_IMPROV + if ( hMdEnc->spar_hoa_md_flag ) + { + int16_t j; + for ( i = 0; i < nB; i++ ) + { + if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) + { + for ( j = 0; j < pred_cell_dims[i].dim1; j++ ) + { + hMdEnc->spar_md.band_coeffs_idx[i].pred_index_re[j] = + hMdEnc->spar_md.band_coeffs_idx[i].pred_index_re[j + ( FOA_CHANNELS - 1 )]; + if ( any_diff == 1 ) + { + hMdEnc->spar_md_prior.band_coeffs_idx_mapped[i].pred_index_re[j] = + hMdEnc->spar_md_prior.band_coeffs_idx_mapped[i].pred_index_re[j + ( FOA_CHANNELS - 1 )]; + } + } + } + } + } +#endif ivas_copy_band_coeffs_idx_to_arr( hMdEnc->spar_md.band_coeffs_idx, nB, symbol_arr_re, pred_cell_dims, PRED_COEFF, planarCP ); if ( any_diff == 1 ) @@ -1415,6 +1507,29 @@ static void ivas_get_arith_coded_bs( ivas_arith_encode_cmplx_cell_array( &hMdEnc->arith_coeffs.pred_arith_re[qsi], &hMdEnc->arith_coeffs.pred_arith_re_diff[qsi], pDo_diff, nB, symbol_arr_re, symbol_arr_old_re, pred_cell_dims, hMetaData, any_diff ); + +#ifdef SBA_HOA_HBR_IMPROV + if ( hMdEnc->spar_hoa_md_flag ) + { + int16_t j; + for ( i = 0; i < nB; i++ ) + { + if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) + { + for ( j = pred_cell_dims[i].dim1 - 1; j >= 0; j-- ) + { + hMdEnc->spar_md.band_coeffs_idx[i].pred_index_re[j + ( FOA_CHANNELS - 1 )] = + hMdEnc->spar_md.band_coeffs_idx[i].pred_index_re[j]; + } + for ( j = 0; j < FOA_CHANNELS - 1; j++ ) + { + hMdEnc->spar_md.band_coeffs_idx[i].pred_index_re[j] = 0; + } + } + } + } +#endif + #ifdef SPAR_HOA_DBG /*fprintf(stderr, "\n\n band_indexes:\n"); for (int16_t j = 1; j < drct_cell_dims[0].dim1 * drct_cell_dims[0].dim2; j++) diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index a4e8e1142afde9eb8729a35d6a89767068b02652..24e9ebaf76f970921324e039b86c43d1b84441f0 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -657,7 +657,9 @@ typedef struct ivas_spar_md_enc_state_t ivas_arith_coeffs_t arith_coeffs; ivas_huff_coeffs_t huff_coeffs; int16_t table_idx; - +#ifdef SBA_HOA_HBR_IMPROV + int16_t spar_hoa_md_flag; +#endif } ivas_spar_md_enc_state_t; #ifndef SBA_SPAR_HARM