diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config.c index a81e7921954167f7d63e2ec3d70aa25ea8d88c51..9ae98584131c63d94fa0949f7a20dc2815bf2d1b 100644 --- a/lib_com/ivas_sba_config.c +++ b/lib_com/ivas_sba_config.c @@ -224,8 +224,12 @@ int16_t ivas_sba_get_nchan_metadata( { if ( ivas_total_brate >= IVAS_512k ) { +#ifndef COVARIANCE_MEMORY_OPT nb_channels = ( SBA_HOA2_ORDER + 1 ) * ( SBA_HOA2_ORDER + 1 ); nb_channels += 2; +#else + nb_channels = IVAS_SPAR_MAX_CH; +#endif nb_channels = min( nb_channels, ( sba_order + 1 ) * ( sba_order + 1 ) ); } else diff --git a/lib_com/options.h b/lib_com/options.h old mode 100755 new mode 100644 index 570d275dd2ddee8379a79dce5766310287b38792..9a0f6f306766d61203d04cb9a5366f130fbbd7c2 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -181,6 +181,7 @@ #define FIX_583_CLANG_TRANS_DET /* FhG: Issue 583: clang left shift on ramp_up_flag in transient detector */ #define FIX_280_PLANAR_CP /* Dlb : fix issue 28 : remove planarCP=1 related code*/ #define CODE_CLEAN_UP_DIRAC /* Dlb : code clean up*/ +#define COVARIANCE_MEMORY_OPT /* Dlb : Issue 231: define SPAR covariance buffers in stack instead of inter-frame heap */ #define NONBE_FIX_589_JBM_TC_OFFSETS /* FhG: issue 589: wrong offset into the TC buffers is used in some rendering paths in the JBM main rendering function */ #define FIX_MEM_REALLOC_IND_LIST /* VA: issue 601: failure of the automatic memory re-allocation mechanism when ind_list[] buffer is depleted in MASA mode with 2 TC*/ #define FIX_581_CLANG_OFFSET_TO_NULL /* FhG: issue 581: fix CLANG error about applying an offset to a NULL pointer */ diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index 6d7e58829e2ff4c962a6581da346a6915c6b32e1..a4ee09adc19fa5a25767a3c0a18081ed31500aaf 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -598,6 +598,7 @@ ivas_error ivas_spar_md_dec_init( { set_zero( hMdDec->smooth_buf[i], 2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1 ); } + for ( i = 0; i < IVAS_SPAR_MAX_CH; i++ ) { for ( j = 0; j < IVAS_SPAR_MAX_CH; j++ ) diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index 5f382c4719882668e0f9892202e80d1b2c07d9a1..7233234f4948b8f0cac4bb002e08cea8f0afbb5c 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -369,6 +369,137 @@ ivas_error ivas_spar_enc( } +#ifdef COVARIANCE_MEMORY_OPT +/*-------------------------------------------------------------------* + * ivas_spar_cov_md_process() + * + * Process call for SPAR covariance and MD encoder + *-------------------------------------------------------------------*/ + +static ivas_error ivas_spar_cov_md_process( + const ENCODER_CONFIG_HANDLE hEncoderConfig, + SPAR_ENC_HANDLE hSpar, + const IVAS_QMETADATA_HANDLE hQMetaData, + BSTR_ENC_HANDLE hMetaData, + const int16_t nchan_inp, + const int16_t sba_order, + float *ppIn_FR_real[IVAS_SPAR_MAX_CH], + float *ppIn_FR_imag[IVAS_SPAR_MAX_CH], + const int16_t transient_det[2], + const int16_t dtx_vad ) +{ + int16_t i, j, i_ts, b, table_idx; + int16_t active_w_vlbr; + /* note: the actual dimensions of matrixes correspond to num_channels = ivas_sba_get_nchan_metadata( sba_order, ivas_total_brate ); */ + float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + float cov_real_buf[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; + float cov_dtx_real_buf[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; + ivas_error error; + + error = IVAS_ERR_OK; + + active_w_vlbr = ( hEncoderConfig->ivas_total_brate < IVAS_24k4 ) ? 1 : 0; + + /*-----------------------------------------------------------------------------------------* + * Set SPAR bitrates + *-----------------------------------------------------------------------------------------*/ + + table_idx = ivas_get_spar_table_idx( hEncoderConfig->ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); + + if ( hSpar->hMdEnc->table_idx != table_idx ) + { + hSpar->hMdEnc->table_idx = table_idx; + if ( hEncoderConfig->ivas_total_brate != hEncoderConfig->last_ivas_total_brate && !hSpar->spar_reconfig_flag ) + { + if ( ( error = ivas_spar_md_enc_init( hSpar->hMdEnc, hEncoderConfig, sba_order ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + ivas_spar_set_bitrate_config( &hSpar->hMdEnc->spar_md_cfg, table_idx, ( hSpar->hMdEnc->spar_hoa_md_flag ) ? IVAS_MAX_NUM_BANDS : SPAR_DIRAC_SPLIT_START_BAND, hSpar->hMdEnc->spar_hoa_dirac2spar_md_flag, 1, hEncoderConfig->Opt_PCA_ON, hSpar->AGC_Enable ); + } + } + + /*-----------------------------------------------------------------------------------------* + * Covariance process + *-----------------------------------------------------------------------------------------*/ + + for ( i = 0; i < nchan_inp; i++ ) + { + for ( j = 0; j < nchan_inp; j++ ) + { + cov_real[i][j] = cov_real_buf[i][j]; + cov_dtx_real[i][j] = cov_dtx_real_buf[i][j]; + } + } + + ivas_enc_cov_handler_process( hSpar->hCovEnc, ppIn_FR_real, ppIn_FR_imag, cov_real, cov_dtx_real, hSpar->hFbMixer->pFb, 0, hSpar->hFbMixer->pFb->filterbank_num_bands, nchan_inp, dtx_vad, transient_det, hSpar->hMdEnc->HOA_md_ind ); + + /*-----------------------------------------------------------------------------------------* + * MetaData encoder + *-----------------------------------------------------------------------------------------*/ + + if ( hSpar->hMdEnc->spar_hoa_md_flag == 0 ) + { + ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, hMetaData, dtx_vad, nchan_inp, sba_order, hSpar->hFbMixer->prior_mixer ); + } + + if ( hSpar->hMdEnc->spar_hoa_dirac2spar_md_flag ) + { + float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + float diffuseness[IVAS_MAX_NUM_BANDS]; + float Wscale_d[IVAS_MAX_NUM_BANDS]; + int16_t d_start_band, d_end_band; + int16_t dirac_band_idx; + + d_start_band = hSpar->enc_param_start_band; + d_end_band = IVAS_MAX_NUM_BANDS; + + for ( b = d_start_band; b < d_end_band; b++ ) + { + dirac_band_idx = hSpar->dirac_to_spar_md_bands[b] - d_start_band; + for ( i_ts = 0; i_ts < hQMetaData->q_direction->cfg.nblocks; i_ts++ ) + { + azi_dirac[b][i_ts] = hQMetaData->q_direction->band_data[dirac_band_idx].azimuth[i_ts]; + ele_dirac[b][i_ts] = hQMetaData->q_direction->band_data[dirac_band_idx].elevation[i_ts]; + } + diffuseness[b] = 1.0f - hQMetaData->q_direction->band_data[dirac_band_idx].energy_ratio[0]; + } + + if ( d_start_band >= 6 && dtx_vad == 1 ) + { + mvr2r( hSpar->hMdEnc->spar_md.band_coeffs[d_start_band - 1].P_quant_re, hSpar->hMdEnc->spar_md.band_coeffs[d_start_band - 1].P_re, IVAS_SPAR_MAX_CH - 1 ); + } + + for ( b = d_start_band; b < d_end_band; b++ ) + { + Wscale_d[b] = 1.0f; + for ( i = 1; i < nchan_inp; i++ ) + { + Wscale_d[b] += cov_real[i][i][b] / max( EPSILON, cov_real[0][0][b] ); + } + Wscale_d[b] = Wscale_d[b] / ( 1.0f + (float) sba_order ); /*DirAC normalized signal variance sums to 1 + order*/ + Wscale_d[b] = sqrtf( Wscale_d[b] ); + 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, ( hSpar->hMdEnc->spar_hoa_md_flag ) ? 1 : sba_order, dtx_vad, Wscale_d, hQMetaData->useLowerRes, active_w_vlbr ); + } + + 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, hSpar->hFbMixer->prior_mixer ); + } + + return error; +} +#endif + + /*-----------------------------------------------------------------------------------------* * Function ivas_spar_enc_process() * @@ -385,14 +516,20 @@ static ivas_error ivas_spar_enc_process( { float pcm_tmp[DIRAC_MAX_ANA_CHANS][L_FRAME48k * 2]; float *p_pcm_tmp[DIRAC_MAX_ANA_CHANS]; +#ifdef COVARIANCE_MEMORY_OPT + int16_t i, j, input_frame, dtx_vad; +#else int16_t i, j, b, i_ts, input_frame, dtx_vad; +#endif int16_t transient_det[2]; int16_t hodirac_flag; int32_t ivas_total_brate, input_Fs; + int16_t nchan_inp, sba_order, nchan_transport; +#ifndef COVARIANCE_MEMORY_OPT float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - int16_t nchan_inp, nchan_transport, sba_order; int16_t table_idx; +#endif int16_t in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH]; ivas_error error; const int16_t *order; @@ -426,9 +563,10 @@ static ivas_error ivas_spar_enc_process( sba_order = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); nchan_inp = ivas_sba_get_nchan_metadata( sba_order, hEncoderConfig->ivas_total_brate ); assert( nchan_inp <= hEncoderConfig->nchan_inp ); - +#ifndef COVARIANCE_MEMORY_OPT int16_t active_w_vlbr; active_w_vlbr = ( hEncoderConfig->ivas_total_brate < IVAS_24k4 ) ? 1 : 0; +#endif nchan_fb_in = hSpar->hFbMixer->fb_cfg->nchan_fb_in; nchan_transport = st_ivas->nchan_transport; @@ -515,6 +653,17 @@ static ivas_error ivas_spar_enc_process( ivas_dirac_enc( st_ivas->hDirAC, hQMetaData, hMetaData, data_f, ppIn_FR_real, ppIn_FR_imag, input_frame, dtx_vad, hEncoderConfig->ivas_format, hodirac_flag ); + +#ifdef COVARIANCE_MEMORY_OPT + /*-----------------------------------------------------------------------------------------* + * Covariance and MD processing + *-----------------------------------------------------------------------------------------*/ + + if ( ( error = ivas_spar_cov_md_process( hEncoderConfig, st_ivas->hSpar, st_ivas->hQMetaData, hMetaData, nchan_inp, sba_order, ppIn_FR_real, ppIn_FR_imag, transient_det, dtx_vad ) ) != IVAS_ERR_OK ) + { + return error; + } +#else /*-----------------------------------------------------------------------------------------* * Set SPAR bitrates *-----------------------------------------------------------------------------------------*/ @@ -610,6 +759,7 @@ static ivas_error ivas_spar_enc_process( { ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, hMetaData, dtx_vad, nchan_inp, sba_order, hSpar->hFbMixer->prior_mixer ); } +#endif #ifdef DEBUG_LBR_SBA /* Dumping SPAR Coefficients */ diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index 097628daffc294b643ff308365a8ad121e69bd11..757f772b13a3a4bf4cc956ea90fdfb598f86ea51 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -154,6 +154,7 @@ ivas_error ivas_spar_md_enc_open( } } +#ifndef COVARIANCE_MEMORY_OPT if ( ( hMdEnc->cov_real = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR cov real matrix" ); @@ -191,7 +192,7 @@ ivas_error ivas_spar_md_enc_open( } } } - +#endif if ( ( hMdEnc->mixer_mat_local = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); @@ -261,6 +262,7 @@ void ivas_spar_md_enc_close( free( hMdEnc->mixer_mat ); } +#ifndef COVARIANCE_MEMORY_OPT if ( hMdEnc->cov_real != NULL ) { for ( i = 0; i < num_channels; i++ ) @@ -286,7 +288,7 @@ void ivas_spar_md_enc_close( } free( hMdEnc->cov_dtx_real ); } - +#endif if ( hMdEnc->mixer_mat_local != NULL ) { for ( i = 0; i < num_channels; i++ ) @@ -378,6 +380,7 @@ ivas_error ivas_spar_md_enc_init( } } +#ifndef COVARIANCE_MEMORY_OPT for ( i = 0; i < num_channels; i++ ) { for ( j = 0; j < num_channels; j++ ) @@ -389,7 +392,7 @@ ivas_error ivas_spar_md_enc_init( } } } - +#endif ivas_clear_band_coeffs( hMdEnc->spar_md.band_coeffs, IVAS_MAX_NUM_BANDS ); ivas_clear_band_coeff_idx( hMdEnc->spar_md.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); ivas_clear_band_coeff_idx( hMdEnc->spar_md_prior.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 6a5964e86c0885892b62bfac3d21b724e4549b77..12e0bd7d3056120811daf8a04ce6a30cf6e3a417 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -662,8 +662,10 @@ typedef struct ivas_spar_md_enc_state_t int16_t num_decorr; float ***mixer_mat; +#ifndef COVARIANCE_MEMORY_OPT float ***cov_real; float ***cov_dtx_real; +#endif float ***mixer_mat_local; ivas_spar_md_com_cfg spar_md_cfg; ivas_arith_coeffs_t arith_coeffs;