diff --git a/ci/smoke_test.sh b/ci/smoke_test.sh index 852b74fe47d23c5a7a60503370781f5dbb2ae46d..d3206fce1a42943d5e01ff796c66ca02d2a455df 100755 --- a/ci/smoke_test.sh +++ b/ci/smoke_test.sh @@ -63,7 +63,7 @@ if [ $BUILD -eq 1 ];then make clean # Replace free -> free_, malloc -> malloc_, calloc -> calloc_ - ./scripts/prepare_mem_dryrun.py + python3 ./scripts/prepare_mem_dryrun.py # Enable WMOPS and disable DEBUGGING sed -i.bak -e "s/\/\*\s*\(#define\s*WMOPS\)\s*\*\//\1/g" lib_com/options.h diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h old mode 100644 new mode 100755 index f3b07ba2a2d53cc51bcf4a87cb7459c3b8807b3f..01b11b21e4ce86baa3918453de4ccd4a8637b413 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -174,6 +174,10 @@ typedef enum #define BINAURAL_CHANNELS 2 /* number of channels for binaural output configuration */ #define CPE_CHANNELS 2 /* number of CPE (stereo) channels */ #define FOA_CHANNELS 4 /* number of FOA channels */ +#ifdef HODIRAC +#define HOA2_CHANNELS 9 +#endif + #define MAX_NUM_OBJECTS 4 /* max. number of audio objects */ #define MAX_SCE MAX_NUM_OBJECTS /* max. number of SCEs */ @@ -905,7 +909,11 @@ typedef enum * DirAC Constants *----------------------------------------------------------------------------------*/ +#ifdef HODIRAC +#define DIRAC_MAX_ANA_CHANS 11 /* Maximum number of channels for DirAC analysis */ +#else #define DIRAC_MAX_ANA_CHANS FOA_CHANNELS /* Maximum number of channels for DirAC analysis */ +#endif #define DIRAC_NUM_DIMS 3 /* number of directions to estimate (X,Y,Z) */ #define DIRAC_MAX_NBANDS 12 /* Maximum number of frequency bands for the DirAC Side Parameter decoding */ @@ -919,6 +927,11 @@ typedef enum #define DIRAC_NO_FB_BANDS_MAX MDFT_FB_BANDS_240 #define DELAY_DIRAC_ENC_CMP_NS_PARAM_ISM ( IVAS_ENC_DELAY_NS + IVAS_DEC_DELAY_NS ) /* == 12 ms */ +#ifdef HODIRAC +#define DIRAC_HO_NUMSECTORS 2 +#define NUM_ANA_SECTORS 2 +#endif + /* DirAC renderer setup */ typedef enum @@ -977,7 +990,17 @@ typedef enum #define SPAR_CONFIG_BW FB +#ifndef SPAR_TUNING #define IVAS_SPAR_MAX_CH (FOA_CHANNELS + 2 * ( IVAS_MAX_SBA_ORDER - 1 )) /* FOA + planar HOA */ +#else +#define IVAS_SPAR_MAX_CH ((( IVAS_MAX_SBA_ORDER ) * ( IVAS_MAX_SBA_ORDER )) + 2) /* HOA2 + pHOA3*/ +#define IVAS_HBR_MAX_DECOR_CHS (2) +#endif + +#ifdef HODIRAC +#define IVAS_SPAR_MAX_FB_IN_CHAN 11 +#endif + #define IVAS_SPAR_P_LOWERTRI ((IVAS_SPAR_MAX_CH - 1) * (IVAS_SPAR_MAX_CH - 2)) >> 1 #define IVAS_SPAR_MAX_C_COEFF (IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS) * ( IVAS_SPAR_MAX_DMX_CHS - 1) @@ -1186,7 +1209,11 @@ enum #define MASA_ANGLE_TOLERANCE 0.5f #define MASA_LIMIT_NO_BANDS_SUR_COH 8 #define MINIMUM_BIT_BUDGET_NORMAL_META 100 +#ifdef HODIRAC +#define DIFF_DFRATIO_2BIT_LIMIT_IDX_HODIRAC 4 +#endif #define DIFF_DFRATIO_2BIT_LIMIT_IDX 3 + #define DIFF_DFRATIO_1BIT_LIMIT_IDX 6 #define DIFF_EC_HUFF_BAND_LIMIT 8 #define DIFF_EC_HUFF_GR0_LIMIT 8 diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index e4bea78e7933298a895c5542ba684e20d0861301..d17732b66c8c5fbcae9829e3b961be0a50708424 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -71,8 +71,10 @@ ivas_error ivas_dirac_config( int16_t spar_dirac_split_band; IVAS_FB_MIXER_HANDLE hFbMdft; SBA_MODE sba_mode; + int16_t *dirac_to_spar_md_bands; + error = IVAS_ERR_OK; if ( enc_dec == ENC ) @@ -128,7 +130,14 @@ ivas_error ivas_dirac_config( if ( sba_mode == SBA_MODE_SPAR ) { hConfig->nbands = IVAS_MAX_NUM_BANDS; + spar_dirac_split_band = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); +#ifdef HODIRAC + if ( sba_order > 1 && ivas_total_brate > IVAS_256k ) + { + spar_dirac_split_band = 0; + } +#endif } else { @@ -164,6 +173,16 @@ ivas_error ivas_dirac_config( { hConfig->enc_param_start_band = spar_dirac_split_band; } +#ifdef HODIRAC + if ( sba_order > 1 && ivas_total_brate > IVAS_256k ) + { + hConfig->dec_param_estim = FALSE; + hConfig->enc_param_start_band = 0; + + set_c( (int8_t *) hQMetaData->twoDirBands, (int8_t) 1, hQMetaData->q_direction[0].cfg.nbands ); + hQMetaData->numTwoDirBands = (uint8_t) hQMetaData->q_direction[0].cfg.nbands; + } +#endif } else { @@ -176,7 +195,9 @@ ivas_error ivas_dirac_config( if ( sba_mode == SBA_MODE_SPAR ) { - ivas_dirac_config_bands( band_grouping, IVAS_MAX_NUM_BANDS, (int16_t) ( Fs * INV_CLDFB_BANDWIDTH + 0.5f ), + ivas_dirac_config_bands( band_grouping, + IVAS_MAX_NUM_BANDS, + (int16_t) ( Fs * INV_CLDFB_BANDWIDTH + 0.5f ), dirac_to_spar_md_bands, hQMetaData->useLowerBandRes, hConfig->enc_param_start_band, hFbMdft ); } else @@ -354,12 +375,44 @@ ivas_error ivas_dirac_sba_config( else { hQMetaData->useLowerBandRes = 0; - nbands_coded = nbands - 1; /* always combine the last two bands */ +#ifdef HODIRAC + if ( !( sba_order > 1 && sba_total_brate > IVAS_256k ) ) +#endif + { + nbands_coded = nbands - 1; /* always combine the last two bands */ + } } - if ( ( error = ivas_qmetadata_allocate_memory( hQMetaData, nbands_coded, 1, 0 ) ) != IVAS_ERR_OK ) { - return error; + int16_t no_dirs = 1; +#ifdef HODIRAC + if ( sba_order > 1 && sba_total_brate > IVAS_256k ) + { + no_dirs = 2; + } +#endif + + if ( ( error = ivas_qmetadata_allocate_memory( hQMetaData, nbands_coded, no_dirs, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } +#ifdef HODIRAC_FIX_BR_SWITCHING_DTX + if ( sba_order > 1 && sba_total_brate > IVAS_256k ) + { + int16_t dir, j; + for ( dir = 0; dir < hQMetaData->no_directions; dir++ ) + { + for ( j = 0; j < nbands_coded; j++ ) + { + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + hQMetaData->q_direction[dir].band_data[j].energy_ratio_index[i] = 0; + hQMetaData->q_direction[dir].band_data[j].energy_ratio_index_mod[i] = 0; + } + } + } + } +#endif } if ( sba_total_brate <= IVAS_13k2 ) @@ -452,11 +505,19 @@ ivas_error ivas_dirac_sba_config( } if ( sba_total_brate >= IVAS_96k ) { - if ( ( error = ivas_qmetadata_allocate_memory( hQMetaData, 6, 1, 0 ) ) != IVAS_ERR_OK ) { - return error; + int16_t no_dirs = 1; +#ifdef HODIRAC + if ( sba_order > 1 && sba_total_brate > IVAS_256k ) + { + no_dirs = 2; + } +#endif + if ( ( error = ivas_qmetadata_allocate_memory( hQMetaData, 6, no_dirs, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } } - nbands_wb = 4; } else @@ -484,7 +545,16 @@ ivas_error ivas_dirac_sba_config( for ( i = 0; i < hQMetaData->no_directions; i++ ) { hQMetaData->q_direction[i].cfg.search_effort = 1; - hQMetaData->q_direction[i].cfg.start_band = nbands_wb; +#ifdef HODIRAC + if ( sba_order > 1 && sba_total_brate > IVAS_256k ) + { + hQMetaData->q_direction[i].cfg.start_band = 0; + } + else +#endif + { + hQMetaData->q_direction[i].cfg.start_band = nbands_wb; + } } *element_mode = IVAS_CPE_MDCT; @@ -787,6 +857,220 @@ void deindex_spherical_component( return; } +#ifdef HODIRAC +void calculate_hodirac_sector_parameters( + float RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i: signal vector (L+1)^2 x N_bins, real part */ + float ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i: signal vector, imaginary part*/ + const int16_t N_bins, /* i: number of bins */ + const float beta, /* i: forgetting factor for average filtering */ + const int16_t *band_grouping, /* i: indices of band groups */ + const int16_t N_bands, /* i: number of bands (groups) */ + const int16_t enc_param_start_band, /* i: first band to process */ + float *azi, /* o: array of sector azimuth angles, flat */ + float *ele, /* o: array of sector elevation angles, flat */ + float *diff, /* o: array of sector diffuseness values, flat*/ + float *ene /* o: array of sector energy values, flat*/ +) +{ + int16_t i_sec, i_bin, i_band; + + float p_real, p_imag, normI, energy, tmp_diff; + + float sec_I_vec_x[NUM_ANA_SECTORS]; + float sec_I_vec_y[NUM_ANA_SECTORS]; + float sec_I_vec_z[NUM_ANA_SECTORS]; + + static int16_t firstrun_sector_params = 1; + + static float sec_I_vec_smth_x[NUM_ANA_SECTORS][IVAS_MAX_NUM_BANDS]; + static float sec_I_vec_smth_y[NUM_ANA_SECTORS][IVAS_MAX_NUM_BANDS]; + static float sec_I_vec_smth_z[NUM_ANA_SECTORS][IVAS_MAX_NUM_BANDS]; + + static float energy_smth[NUM_ANA_SECTORS][IVAS_MAX_NUM_BANDS]; + static float azi_prev[NUM_ANA_SECTORS * IVAS_MAX_NUM_BANDS]; + static float ele_prev[NUM_ANA_SECTORS * IVAS_MAX_NUM_BANDS]; + +#ifdef DEBUGGING + assert( N_bins <= DIRAC_NO_FB_BANDS_MAX ); +#endif + + for ( i_sec = 0; i_sec < NUM_ANA_SECTORS; i_sec++ ) + { + + float *p_sec_I_vec_x = &sec_I_vec_x[i_sec]; + float *p_sec_I_vec_y = &sec_I_vec_y[i_sec]; + float *p_sec_I_vec_z = &sec_I_vec_z[i_sec]; + + const float *p_c_weights = c_weights; + + float *p_ImagBuffer_0 = ImagBuffer[0]; + float *p_ImagBuffer_1 = ImagBuffer[1]; + float *p_ImagBuffer_2 = ImagBuffer[2]; + float *p_ImagBuffer_3 = ImagBuffer[3]; + float *p_ImagBuffer_4 = ImagBuffer[4]; + float *p_ImagBuffer_5 = ImagBuffer[5]; + float *p_ImagBuffer_6 = ImagBuffer[6]; + float *p_ImagBuffer_8 = ImagBuffer[8]; + + float *p_RealBuffer_0 = RealBuffer[0]; + float *p_RealBuffer_1 = RealBuffer[1]; + float *p_RealBuffer_2 = RealBuffer[2]; + float *p_RealBuffer_3 = RealBuffer[3]; + float *p_RealBuffer_4 = RealBuffer[4]; + float *p_RealBuffer_5 = RealBuffer[5]; + float *p_RealBuffer_6 = RealBuffer[6]; + float *p_RealBuffer_8 = RealBuffer[8]; + + for ( i_band = enc_param_start_band; i_band < N_bands; i_band++ ) + { + float *p_azi = &azi[i_sec * N_bands + i_band]; + float *p_ele = &ele[i_sec * N_bands + i_band]; + float *p_ene = &ene[i_sec * N_bands + i_band]; + + float *p_diff = &diff[i_sec * N_bands + i_band]; + float *p_azi_prev = &azi_prev[i_sec * N_bands + i_band]; + float *p_ele_prev = &ele_prev[i_sec * N_bands + i_band]; + + float *p_energy_smth = &energy_smth[i_sec][i_band]; + float *p_sec_I_vec_smth_x = &sec_I_vec_smth_x[i_sec][i_band]; + float *p_sec_I_vec_smth_y = &sec_I_vec_smth_y[i_sec][i_band]; + float *p_sec_I_vec_smth_z = &sec_I_vec_smth_z[i_sec][i_band]; + + *p_sec_I_vec_x = 0.f; + *p_sec_I_vec_y = 0.f; + *p_sec_I_vec_z = 0.f; + energy = 0.f; + + if ( i_sec == 0 ) + { + for ( i_bin = band_grouping[i_band]; i_bin < band_grouping[i_band + 1]; i_bin++ ) + { + float w = *( p_c_weights++ ); + float sec_w_imag, sec_x_imag, sec_y_imag, sec_z_imag; + float sec_w_real, sec_x_real, sec_y_real, sec_z_real; + + sec_w_imag = 1.772454f * *( p_ImagBuffer_0 ) + 1.772454f * *( p_ImagBuffer_1 ); + sec_x_imag = 1.772454f * *( p_ImagBuffer_3++ ) + 1.023326f * *( p_ImagBuffer_4++ ); + sec_y_imag = 0.590818f * *( p_ImagBuffer_0++ ) + 1.772454f * *( p_ImagBuffer_1++ ) - 0.590817f * *( p_ImagBuffer_6++ ) - 1.023326f * *( p_ImagBuffer_8++ ); + sec_z_imag = 1.772454f * *( p_ImagBuffer_2++ ) + 1.023326f * *( p_ImagBuffer_5++ ); + + sec_w_real = 1.772454f * *( p_RealBuffer_0 ) + 1.772454f * *( p_RealBuffer_1 ); + sec_x_real = 1.772454f * *( p_RealBuffer_3++ ) + 1.023326f * *( p_RealBuffer_4++ ); + sec_y_real = 0.590818f * *( p_RealBuffer_0++ ) + 1.772454f * *( p_RealBuffer_1++ ) - 0.590817f * *( p_RealBuffer_6++ ) - 1.023326f * *( p_RealBuffer_8++ ); + sec_z_real = 1.772454f * *( p_RealBuffer_2++ ) + 1.023326f * *( p_RealBuffer_5++ ); + + p_real = sec_w_real * w; + p_imag = sec_w_imag * w; + + *p_sec_I_vec_x += p_real * sec_x_real + p_imag * sec_x_imag; + *p_sec_I_vec_y += p_real * sec_y_real + p_imag * sec_y_imag; + *p_sec_I_vec_z += p_real * sec_z_real + p_imag * sec_z_imag; + + energy += 0.5f * ( p_real * p_real + p_imag * p_imag + sec_x_real * sec_x_real + sec_x_imag * sec_x_imag + + sec_y_real * sec_y_real + sec_y_imag * sec_y_imag + + sec_z_real * sec_z_real + sec_z_imag * sec_z_imag ); + } + } + else + { + for ( i_bin = band_grouping[i_band]; i_bin < band_grouping[i_band + 1]; i_bin++ ) + { + float w = *( p_c_weights++ ); + float sec_w_imag, sec_x_imag, sec_y_imag, sec_z_imag; + float sec_w_real, sec_x_real, sec_y_real, sec_z_real; + + sec_w_imag = 1.772454f * *(p_ImagBuffer_0) -1.772454f * *( p_ImagBuffer_1 ); + sec_x_imag = 1.772454f * *( p_ImagBuffer_3++ ) - 1.023326f * *( p_ImagBuffer_4++ ); + sec_y_imag = -0.590818f * *( p_ImagBuffer_0++ ) + 1.772454f * *( p_ImagBuffer_1++ ) + 0.590817f * *( p_ImagBuffer_6++ ) + 1.023326f * *( p_ImagBuffer_8++ ); + sec_z_imag = 1.772454f * *( p_ImagBuffer_2++ ) - 1.023326f * *( p_ImagBuffer_5++ ); + + sec_w_real = 1.772454f * *(p_RealBuffer_0) -1.772454f * *( p_RealBuffer_1 ); + sec_x_real = 1.772454f * *( p_RealBuffer_3++ ) - 1.023326f * *( p_RealBuffer_4++ ); + sec_y_real = -0.590818f * *( p_RealBuffer_0++ ) + 1.772454f * *( p_RealBuffer_1++ ) + 0.590817f * *( p_RealBuffer_6++ ) + 1.023326f * *( p_RealBuffer_8++ ); + sec_z_real = 1.772454f * *( p_RealBuffer_2++ ) - 1.023326f * *( p_RealBuffer_5++ ); + + p_real = sec_w_real * w; + p_imag = sec_w_imag * w; + + *p_sec_I_vec_x += p_real * sec_x_real + p_imag * sec_x_imag; + *p_sec_I_vec_y += p_real * sec_y_real + p_imag * sec_y_imag; + *p_sec_I_vec_z += p_real * sec_z_real + p_imag * sec_z_imag; + + energy += 0.5f * ( p_real * p_real + p_imag * p_imag + sec_x_real * sec_x_real + sec_x_imag * sec_x_imag + + sec_y_real * sec_y_real + sec_y_imag * sec_y_imag + + sec_z_real * sec_z_real + sec_z_imag * sec_z_imag ); + } + } + + if ( firstrun_sector_params ) + { + *p_sec_I_vec_smth_x = *p_sec_I_vec_x; + *p_sec_I_vec_smth_y = *p_sec_I_vec_y; + *p_sec_I_vec_smth_z = *p_sec_I_vec_z; + *p_energy_smth = energy; + } + else + { + float w = ( 1.0f - beta ); + *p_sec_I_vec_smth_x = w * *p_sec_I_vec_x + beta * *p_sec_I_vec_smth_x; + *p_sec_I_vec_smth_y = w * *p_sec_I_vec_y + beta * *p_sec_I_vec_smth_y; + *p_sec_I_vec_smth_z = w * *p_sec_I_vec_z + beta * *p_sec_I_vec_smth_z; + *p_energy_smth = w * energy + beta * *p_energy_smth; + } + + if ( energy < EPSILON ) + { + *p_azi = 0.f; + *p_ele = 0.f; + *p_ene = 0.f; + *p_diff = 1.f; + } + else + { + normI = sqrtf( *p_sec_I_vec_smth_x * *p_sec_I_vec_smth_x + + *p_sec_I_vec_smth_y * *p_sec_I_vec_smth_y + + *p_sec_I_vec_smth_z * *p_sec_I_vec_smth_z ); + *p_azi = atan2f( *p_sec_I_vec_smth_y, *p_sec_I_vec_smth_x ) * _180_OVER_PI; + *p_ele = asinf( *p_sec_I_vec_smth_z / ( normI + EPSILON ) ) * _180_OVER_PI; + *p_ene = *p_energy_smth; + *p_diff = 1.f - normI / ( *p_energy_smth + EPSILON ); + } + + tmp_diff = *p_diff; + + if ( tmp_diff < 0.0f ) + { + *p_diff = 0.f; + } + if ( tmp_diff > 0.5f ) + { + if ( firstrun_sector_params ) + { + *p_azi = 0.f; + *p_ele = 0.f; + } + else + { + *p_azi = 2.f * ( 1.f - tmp_diff ) * *p_azi + ( 2.f * tmp_diff - 1.f ) * *p_azi_prev; + *p_ele = 2.f * ( 1.f - tmp_diff ) * *p_ele + ( 2.f * tmp_diff - 1.f ) * *p_ele_prev; + } + } + else + { + *p_azi_prev = *p_azi; + *p_ele_prev = *p_ele; + } +#ifdef HODIRAC_CHECK_VALUE_RANGE + assert( *p_azi >= -180.f && *p_azi <= 180.f ); + assert( *p_ele >= -90.f && *p_ele <= 90.f ); +#endif + } // i_band + } // i_sec + + firstrun_sector_params = 0; +} +#endif + /*-----------------------------------------------------------------------* * Local functions diff --git a/lib_com/ivas_fb_mixer.c b/lib_com/ivas_fb_mixer.c index 511f6ed558cba165c2ff8bf555c45039ad6448b1..3f54709bfff0ffafa5551aed85cbf27900f4c1d2 100644 --- a/lib_com/ivas_fb_mixer.c +++ b/lib_com/ivas_fb_mixer.c @@ -106,6 +106,10 @@ ivas_error ivas_fb_set_cfg( const int16_t num_out_chans, /* i : number of FB output channels*/ const int16_t active_w_mixing, /* i : active_w_mixing flag */ const int32_t sampling_rate /* i : sampling rate */ +#ifdef HODIRAC + , + const int16_t nchan_fb_in /* i: number of dirac analysis channels */ +#endif ) { IVAS_FB_CFG *pFb_cfg; @@ -117,6 +121,9 @@ ivas_error ivas_fb_set_cfg( pFb_cfg->num_in_chans = num_in_chans; pFb_cfg->num_out_chans = num_out_chans; +#ifdef HODIRAC + pFb_cfg->nchan_fb_in = nchan_fb_in; +#endif pFb_cfg->pcm_offset = 0; /* note: in SPAR decoder, this parameter is overwritten later */ pFb_cfg->active_w_mixing = active_w_mixing; @@ -219,7 +226,11 @@ ivas_error ivas_FB_mixer_open( } else if ( fb_cfg->active_w_mixing ) { +#ifdef HODIRAC + num_chs_alloc = max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in ); +#else num_chs_alloc = fb_cfg->num_in_chans; +#endif } else { @@ -259,7 +270,11 @@ ivas_error ivas_FB_mixer_open( } else { +#ifdef HODIRAC + num_chs_alloc = max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in ); +#else num_chs_alloc = fb_cfg->num_in_chans; +#endif } for ( i = 0; i < num_chs_alloc; i++ ) @@ -274,8 +289,11 @@ ivas_error ivas_FB_mixer_open( if ( ( fb_cfg->active_w_mixing != -1 ) && ( fb_cfg->num_out_chans > 0 ) ) { float *pTemp_mem; - +#ifdef HODIRAC + if ( ( pTemp_mem = (float *) malloc( sizeof( float ) * fb_cfg->num_out_chans * max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in ) * IVAS_MAX_NUM_BANDS ) ) == NULL ) +#else if ( ( pTemp_mem = (float *) malloc( sizeof( float ) * fb_cfg->num_out_chans * fb_cfg->num_in_chans * IVAS_MAX_NUM_BANDS ) ) == NULL ) +#endif { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer" ); } @@ -386,7 +404,11 @@ void ivas_FB_mixer_close( } else if ( fb_cfg->active_w_mixing ) { +#ifdef HODIRAC + num_chs_alloc = max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in ); +#else num_chs_alloc = fb_cfg->num_in_chans; +#endif } else { @@ -419,8 +441,14 @@ void ivas_FB_mixer_close( } else { +#ifdef HODIRAC + num_chs_alloc = max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in ); +#else num_chs_alloc = fb_cfg->num_in_chans; +#endif } + + for ( i = 0; i < num_chs_alloc; i++ ) { free( hFbMixer->ppFilterbank_prior_input[i] ); @@ -498,6 +526,10 @@ void ivas_fb_mixer_pcm_ingest( float pcm_in[][L_FRAME48k], /* i : input audio channels */ float **ppOut_pcm, /* o : output audio channels */ const int16_t frame_len /* i : frame length */ +#ifdef SPAR_TUNING + , + const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] +#endif ) { int16_t i; @@ -520,7 +552,15 @@ void ivas_fb_mixer_pcm_ingest( for ( i = 0; i < fb_cfg->num_in_chans; i++ ) { mvr2r( &hFbMixer->ppFilterbank_prior_input[i][fb_cfg->prior_input_length - frame_len], ppOut_pcm[i], frame_len ); +#ifdef HODIRAC +#ifdef SPAR_TUNING + mvr2r( pcm_in[HOA_md_ind[i]], &ppOut_pcm[i][frame_len], frame_len ); +#else + mvr2r( pcm_in[HOA_keep_ind_spar[i]], &ppOut_pcm[i][frame_len], frame_len ); +#endif +#else mvr2r( pcm_in[i], &ppOut_pcm[i][frame_len], frame_len ); +#endif } for ( i = 0; i < num_chs_ingest; i++ ) @@ -542,11 +582,21 @@ void ivas_fb_mixer_update_prior_input( IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ float *pcm_in[], /* i : input audio channels */ const int16_t length /* i : length of time slot */ +#ifdef HODIRAC + , + const int16_t nchan_fb_in +#endif ) { int16_t i; - for ( i = 0; i < hFbMixer->fb_cfg->num_in_chans; i++ ) + for ( i = 0; i < +#ifdef HODIRAC + nchan_fb_in; +#else + hFbMixer->fb_cfg->num_in_chans; +#endif + i++ ) { mvr2r( &hFbMixer->ppFilterbank_prior_input[i][length], hFbMixer->ppFilterbank_prior_input[i], hFbMixer->fb_cfg->prior_input_length - length ); mvr2r( pcm_in[i], &hFbMixer->ppFilterbank_prior_input[i][hFbMixer->fb_cfg->prior_input_length - length], length ); @@ -569,6 +619,10 @@ void ivas_fb_mixer_get_windowed_fr( float *frame_f_imag[], /* o : imag freq domain values */ const int16_t length, /* i : number of new samples in time slot */ const int16_t mdft_len /* i : MDFT frame length */ +#ifdef HODIRAC + , + int16_t nchan_fb_in +#endif ) { int16_t ch_idx, j, offset, rev_offset; @@ -583,7 +637,14 @@ void ivas_fb_mixer_get_windowed_fr( rev_offset = (int16_t) ( 2 * mdft_len - hFbMixer->ana_window_offset ); set_zero( fr_in_block, offset ); - for ( ch_idx = 0; ch_idx < hFbMixer->fb_cfg->num_in_chans; ch_idx++ ) + for ( ch_idx = 0; ch_idx < +#ifdef HODIRAC + nchan_fb_in +#else + hFbMixer->fb_cfg->num_in_chans +#endif + ; + ch_idx++ ) { mvr2r( &hFbMixer->ppFilterbank_prior_input[ch_idx][offset + hFbMixer->fb_cfg->windowed_fr_offset], &fr_in_block[offset], n_old_samples - offset ); mvr2r( pcm_in[ch_idx], &fr_in_block[n_old_samples], n_new_samples ); @@ -708,6 +769,7 @@ void ivas_fb_mixer_process( { int16_t start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i]; int16_t num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i]; + float mixer_const = hFbMixer->prior_mixer[ch][j][i]; pFilterbank_bin_to_band_re = pFb->fb_consts.ppFilterbank_FRs[0][i]; diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 22a4bd74cb2315a507997c3524b4f090669730b7..0355c00470244e4c5a33db19f2158a277d0051f0 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -2942,6 +2942,10 @@ void mdct_read_IGF_bits( ivas_error ivas_qmetadata_enc_encode( BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */ IVAS_QMETADATA *hQMetaData /* i/o: q_metadata handle */ +#ifdef HODIRAC + , + int16_t hodirac /* i: flag to indicate sector processing */ +#endif ); #ifdef HR_METADATA @@ -3014,6 +3018,10 @@ int16_t ivas_qmetadata_dec_decode( IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ uint16_t *bitstream, /* i : bitstream */ int16_t *index /* i/o: bitstream position */ +#ifdef HODIRAC + , + int16_t hodirac /* i: flag to indicate sector processing */ +#endif ); @@ -3035,6 +3043,9 @@ void ivas_qmetadata_to_dirac( MASA_DECODER_HANDLE hMasa, /* i : MASA decoder structure */ const int32_t ivas_total_brate, /* i : IVAS total bitrate */ const SBA_MODE sba_mode, /* i : SBA mode */ +#ifdef HODIRAC + const int16_t sba_analysis_order, /* i sba order*/ +#endif int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ ); @@ -3234,7 +3245,12 @@ void ivas_dirac_param_est_enc( float **pp_fr_real, float **pp_fr_imag, const int16_t input_frame, - const SBA_MODE sba_mode + const SBA_MODE sba_mode +#ifdef HODIRAC + , + const int16_t hodirac, + const int16_t nchan_fb_in +#endif ); @@ -3300,14 +3316,31 @@ int16_t ivas_sba_get_nchan( /*! r: number of ambisonics metadata channels */ int16_t ivas_sba_get_nchan_metadata( const int16_t sba_order /* i : Ambisonic (SBA) order */ +#ifdef SPAR_TUNING + , + const int32_t ivas_total_brate +#endif ); +#ifdef SPAR_TUNING +void ivas_sba_get_spar_hoa_ch_ind( + const int16_t num_md_chs, /* i : number of MD channels */ + const int32_t ivas_total_brate, /* i : IVAS total bitrate */ + int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] ); + +/*! r: flag indicating to code SPAR HOA MD for all bands */ +void 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, + int16_t *spar_hoa_dirac2spar_md_flag ); +#else /*! r: flag indicating to code SPAR HOA MD for all bands */ 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 */ @@ -3434,6 +3467,9 @@ void ivas_dirac_dec_read_BS( IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q metadata */ int16_t *nb_bits, /* o : number of bits read */ const SBA_MODE sba_mode, /* i : SBA mode */ +#ifdef HODIRAC + const int16_t sba_analysis_order, /* i sba order*/ +#endif int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ ); @@ -3548,11 +3584,19 @@ ivas_error ivas_dirac_dec_output_synthesis_open( const RENDERER_TYPE renderer_type, /* i : renderer type */ const int16_t nchan_transport, /* i : number of transport channels */ const int32_t output_Fs /* i : output sampling rate */ +#ifdef HODIRAC + , + const int16_t hodirac /* i : flag to indicate HO-DirAC mode*/ +#endif ); void ivas_dirac_dec_output_synthesis_init( DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ const int16_t nchan_out_woLFE /* i : number of output audio channels without LFE */ +#ifdef HODIRAC + , + const int16_t hodirac /* flag to indicate HO-DirAC mode */ +#endif ); void ivas_dirac_dec_output_synthesis_close( @@ -3566,7 +3610,13 @@ void ivas_dirac_dec_output_synthesis_process_slot( const float *p_Rmat, /* i : rotation matrix */ const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ - const int16_t nchan_transport /* i : number of transport channels */ + const int16_t nchan_transport, /* i : number of transport channels */ +#ifndef HODIRAC + const int16_t index_slot +#endif +#ifdef HODIRAC + const int16_t hodirac +#endif ); void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( @@ -3575,6 +3625,10 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ const int16_t nchan_transport, /* i : number of transport channels */ const float *onset_filter +#ifdef HODIRAC + , + const int16_t hodirac /* i: flag for sector-based processing */ +#endif ); void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( @@ -3622,6 +3676,10 @@ void ivas_dirac_dec_compute_directional_responses( const float *surCohRatio, const int16_t shd_rot_max_order, /* i : split-order rotation method */ const float *p_Rmat /* i : rotation matrix */ +#ifdef HODIRAC + , + const int16_t hodirac /* i : flag for sector based dirac processing */ +#endif ); void ivas_dirac_dec_get_frequency_axis( @@ -3629,6 +3687,22 @@ void ivas_dirac_dec_get_frequency_axis( const int32_t output_Fs, /* i : sampling frequency */ const int16_t num_freq_bands ); /* i : number of frequency bands */ +#ifdef HODIRAC +void calculate_hodirac_sector_parameters( + float RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i: signal vector (L+1)^2 x N_bins, real part */ + float ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i: signal vector, imaginary part*/ + const int16_t N_bins, /* i: number of bins */ + const float beta, /* i: forgetting factor for average filtering */ + const int16_t *band_grouping, /* i: indices of band groups */ + const int16_t N_bands, /* i: number of bands (groups) */ + const int16_t enc_param_start_band, /* i: first band to process */ + float *azi, /* o: array of sector azimuth angles, flat */ + float *ele, /* o: array of sector elevation angles, flat */ + float *diff, /* o: array of sector diffuseness values, flat*/ + float *ene /* o: array of sector energy values, flat*/ +); +#endif + void ivas_param_mc_metadata_open( const MC_LS_SETUP mc_ls_setup, /* i : MC ls setup */ const int16_t lfe_index, /* i : channel index of LFE */ @@ -4210,6 +4284,12 @@ void ivas_get_spar_md_from_dirac( const int16_t active_w_vlbr ); +#ifdef SPAR_TUNING +int16_t ivas_get_spar_dec_md_num_subframes( + const int16_t sba_order, /* i : Ambisonic (SBA) order */ + const int32_t ivas_total_brate ); +#endif + 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 */ @@ -4262,11 +4342,19 @@ void ivas_spar_update_md_hist( void ivas_spar_smooth_md_dtx( ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ const int16_t num_bands_out /* i : number of output bands */ + #ifdef SPAR_TUNING + , + const int16_t num_md_sub_frames /* i : number of metadata subframes */ +#endif ); void ivas_spar_setup_md_smoothing( ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ const int16_t num_bands_out /* i : number of output bands */ +#ifdef SPAR_TUNING + , + const int16_t num_md_sub_frames /* i : number of metadata subframes */ +#endif ); void ivas_spar_dec_gen_umx_mat( @@ -4274,6 +4362,10 @@ void ivas_spar_dec_gen_umx_mat( const int16_t nchan_transport, /* i : number of transport channels */ const int16_t num_bands_out, /* i : number of output bands */ const int16_t bfi /* i : bad frame indicator */ +#ifdef SPAR_TUNING + , + const int16_t num_md_sub_frames +#endif ); /* Covariance module */ @@ -4303,6 +4395,10 @@ void ivas_enc_cov_handler_process( const int16_t nchan_inp, const int16_t dtx_vad, const int16_t transient_det[2] +#ifdef SPAR_TUNING + , + const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] +#endif ); ivas_error ivas_spar_covar_smooth_enc_open( @@ -4664,6 +4760,10 @@ void masa_compensate_two_dir_energy_ratio_index( const int16_t ratio_index_2, /* i : Input ratio for direction 2 */ int16_t *ratio_index_mod1, /* o : Output modified ratio for direction 1 */ int16_t *ratio_index_mod2 /* o : Output modified ratio for direction 2 */ +#ifdef HODIRAC + , + int16_t hodirac /* i: flag to indicate sector processing */ +#endif ); void ivas_set_qmetadata_maxbit_req( @@ -4671,6 +4771,13 @@ void ivas_set_qmetadata_maxbit_req( const IVAS_FORMAT ivas_format /* i : IVAS format */ ); +#ifdef HODIRAC +/*! r: Bits to be used for quantizing distribution ratio of direct-to-total ratios */ +int16_t ivas_get_df_ratio_bits_hodirac( + int16_t index_diff /* i : Index of quantized diffuse-to-total ratio */ +); +#endif + /*! r: Bits to be used for quantizing distribution ratio of direct-to-total ratios */ int16_t ivas_get_df_ratio_bits( int16_t index_diff /* i : Index of quantized diffuse-to-total ratio */ @@ -4978,6 +5085,10 @@ void computeReferencePower_enc( const int16_t enc_param_start_band, /* i : first band to process */ const int16_t num_freq_bands, /* i : Number of frequency bands */ const SBA_MODE sba_mode /* i : SBA mode */ +#ifdef HODIRAC + , + int16_t nchan_ana /* i : no of analysis channels */ +#endif ); ivas_error ivas_mono_dmx_renderer_open( @@ -5102,6 +5213,10 @@ ivas_error ivas_fb_set_cfg( const int16_t num_out_chans, /* i : number of FB output channels */ const int16_t active_w_mixing, /* i : active_w_mixing flag */ const int32_t sampling_Fs /* i : sampling rate */ +#ifdef HODIRAC + , + const int16_t nachan_dirac_ana /* i: number of dirac analysis channels */ +#endif ); ivas_error ivas_FB_mixer_open( @@ -5122,6 +5237,10 @@ void ivas_fb_mixer_pcm_ingest( float pcm_in[][L_FRAME48k], /* i : input audio channels */ float **ppOut_pcm, /* o : output audio channels */ const int16_t frame_length /* i : frame length */ +#ifdef SPAR_TUNING + , + const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] +#endif ); void ivas_dirac_enc_spar_delay_synchro( @@ -5134,6 +5253,10 @@ void ivas_fb_mixer_update_prior_input( IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ float *pcm_in[], /* i : input audio channels */ const int16_t length /* i : length of time slot */ +#ifdef HODIRAC + , + const int16_t nchan_fb_in +#endif ); void ivas_fb_mixer_get_windowed_fr( @@ -5143,6 +5266,10 @@ void ivas_fb_mixer_get_windowed_fr( float *frame_f_imag[], /* o : imag freq domain values */ const int16_t length, /* i : number of new samples in time slot */ const int16_t mdft_len /* i : MDFT frame length */ +#ifdef HODIRAC + , + int16_t nchan_fb_in +#endif ); void ivas_fb_mixer_process( diff --git a/lib_com/ivas_qmetadata_com.c b/lib_com/ivas_qmetadata_com.c index 0f2491bad3545e1dcfe9a785d208aa1f702f3eb1..4bd135ec981ad288f319f6543c1718bfa54d5c16 100644 --- a/lib_com/ivas_qmetadata_com.c +++ b/lib_com/ivas_qmetadata_com.c @@ -508,24 +508,41 @@ void masa_compensate_two_dir_energy_ratio_index( const int16_t ratio_index_2, /* i : Input ratio for direction 2 */ int16_t *ratio_index_mod1, /* o : Output modified ratio for direction 1 */ int16_t *ratio_index_mod2 /* o : Output modified ratio for direction 2 */ +#ifdef HODIRAC + , + int16_t hodirac /* i: flag to indicate sector processing */ +#endif ) { - float ratio1, ratio2, ratioSum; + float ratio1, ratio2; +#ifndef HODIRAC + float ratioSum; +#endif ratio1 = 1.0f - diffuseness_reconstructions[ratio_index_1]; ratio2 = 1.0f - diffuseness_reconstructions[ratio_index_2]; - ratioSum = ratio1 + ratio2; - if ( ratio1 >= ratio2 ) - { - ratio2 = ratio2 / ratio1 * ratioSum; - ratio1 = ratioSum; - } - else +#ifdef HODIRAC + if ( !hodirac ) +#endif { - ratio1 = ratio1 / ratio2 * ratioSum; - ratio2 = ratioSum; +#ifdef HODIRAC + float ratioSum; +#endif + + ratioSum = ratio1 + ratio2; + if ( ratio1 >= ratio2 ) + { + ratio2 = ratio2 / ratio1 * ratioSum; + ratio1 = ratioSum; + } + else + { + ratio1 = ratio1 / ratio2 * ratioSum; + ratio2 = ratioSum; + } } + *ratio_index_mod1 = masa_sq( 1.0f - ratio1, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); *ratio_index_mod2 = masa_sq( 1.0f - ratio2, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); @@ -609,6 +626,30 @@ void ivas_qmetadata_direction_vector_to_azimuth_elevation( return; } +#ifdef HODIRAC +/*! r: bits to be used for quantizing ratio of ratios */ +int16_t ivas_get_df_ratio_bits_hodirac( + int16_t index_diff /* i : index of quantized diffuse-to-total ratio */ +) +{ + int16_t dfRatio_bits; + + if ( index_diff >= DIFF_DFRATIO_1BIT_LIMIT_IDX ) + { + dfRatio_bits = 1; + } + else if ( index_diff >= DIFF_DFRATIO_2BIT_LIMIT_IDX_HODIRAC ) + { + dfRatio_bits = 2; + } + else + { + dfRatio_bits = 3; + } + + return dfRatio_bits; +} +#endif /*--------------------------------------------------------------- * ivas_get_df_ratio_bits() diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index d9fc25c089d2b099b02d38565858ea7368a9ae0f..72e46cbda37d0465d6ed5a445ad8c4351336b857 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -877,7 +877,9 @@ const int16_t DirAC_block_grouping_5ms_MDFT[MAX_PARAM_SPATIAL_SUBFRAMES + 1] = 0, 1, 2, 3, 4 }; - +#ifdef HODIRAC +const float c_weights[DIRAC_NO_FB_BANDS_MAX] = { 9.962447e-02f, 9.627997e-01f, 9.926667e-01f, 9.981028e-01f, 9.996648e-01f, 1.000000e+00f, 9.997692e-01f, 9.992002e-01f, 9.983890e-01f, 9.973818e-01f, 9.962037e-01f, 9.948692e-01f, 9.933876e-01f, 9.917654e-01f, 9.900073e-01f, 9.881169e-01f, 9.860975e-01f, 9.839516e-01f, 9.816818e-01f, 9.792906e-01f, 9.767801e-01f, 9.741527e-01f, 9.714106e-01f, 9.685560e-01f, 9.655913e-01f, 9.625187e-01f, 9.593406e-01f, 9.560594e-01f, 9.526774e-01f, 9.491970e-01f, 9.456208e-01f, 9.419512e-01f, 9.381908e-01f, 9.343420e-01f, 9.304075e-01f, 9.263898e-01f, 9.222915e-01f, 9.181152e-01f, 9.138636e-01f, 9.095392e-01f, 9.051447e-01f, 9.006827e-01f, 8.961559e-01f, 8.915668e-01f, 8.869181e-01f, 8.822123e-01f, 8.774521e-01f, 8.726400e-01f, 8.677785e-01f, 8.628702e-01f, 8.579176e-01f, 8.529231e-01f, 8.478893e-01f, 8.428184e-01f, 8.377130e-01f, 8.325753e-01f, 8.274077e-01f, 8.222124e-01f, 8.169917e-01f, 8.117478e-01f, 8.064829e-01f, 8.011990e-01f, 7.958982e-01f, 7.905827e-01f, 7.852543e-01f, 7.799150e-01f, 7.745667e-01f, 7.692112e-01f, 7.638505e-01f, 7.584861e-01f, 7.531199e-01f, 7.477535e-01f, 7.423885e-01f, 7.370265e-01f, 7.316691e-01f, 7.263176e-01f, 7.209736e-01f, 7.156384e-01f, 7.103134e-01f, 7.049999e-01f, 6.996990e-01f, 6.944121e-01f, 6.891403e-01f, 6.838847e-01f, 6.786464e-01f, 6.734265e-01f, 6.682258e-01f, 6.630455e-01f, 6.578863e-01f, 6.527492e-01f, 6.476350e-01f, 6.425445e-01f, 6.374784e-01f, 6.324376e-01f, 6.274226e-01f, 6.224341e-01f, 6.174729e-01f, 6.125393e-01f, 6.076341e-01f, 6.027577e-01f, 5.979106e-01f, 5.930932e-01f, 5.883061e-01f, 5.835497e-01f, 5.788242e-01f, 5.741301e-01f, 5.694676e-01f, 5.648372e-01f, 5.602390e-01f, 5.556734e-01f, 5.511404e-01f, 5.466405e-01f, 5.421737e-01f, 5.377402e-01f, 5.333402e-01f, 5.289738e-01f, 5.246411e-01f, 5.203422e-01f, 5.160771e-01f, 5.118460e-01f, 5.076489e-01f, 5.034858e-01f, 4.993567e-01f, 4.952616e-01f, 4.912005e-01f, 4.871734e-01f, 4.831802e-01f, 4.792209e-01f, 4.752955e-01f, 4.714037e-01f, 4.675457e-01f, 4.637212e-01f, 4.599302e-01f, 4.561725e-01f, 4.524481e-01f, 4.487567e-01f, 4.450983e-01f, 4.414728e-01f, 4.378799e-01f, 4.343195e-01f, 4.307915e-01f, 4.272956e-01f, 4.238318e-01f, 4.203997e-01f, 4.169993e-01f, 4.136303e-01f, 4.102926e-01f, 4.069859e-01f, 4.037101e-01f, 4.004649e-01f, 3.972501e-01f, 3.940655e-01f, 3.909109e-01f, 3.877861e-01f, 3.846909e-01f, 3.816250e-01f, 3.785882e-01f, 3.755803e-01f, 3.726010e-01f, 3.696501e-01f, 3.667275e-01f, 3.638328e-01f, 3.609658e-01f, 3.581263e-01f, 3.553141e-01f, 3.525289e-01f, 3.497705e-01f, 3.470387e-01f, 3.443331e-01f, 3.416537e-01f, 3.390001e-01f, 3.363720e-01f, 3.337694e-01f, 3.311919e-01f, 3.286393e-01f, 3.261114e-01f, 3.236079e-01f, 3.211286e-01f, 3.186733e-01f, 3.162418e-01f, 3.138337e-01f, 3.114490e-01f, 3.090872e-01f, 3.067484e-01f, 3.044321e-01f, 3.021382e-01f, 2.998664e-01f, 2.976166e-01f, 2.953885e-01f, 2.931819e-01f, 2.909966e-01f, 2.888323e-01f, 2.866889e-01f, 2.845661e-01f, 2.824637e-01f, 2.803816e-01f, 2.783194e-01f, 2.762770e-01f, 2.742543e-01f, 2.722509e-01f, 2.702667e-01f, 2.683014e-01f, 2.663550e-01f, 2.644271e-01f, 2.625177e-01f, 2.606264e-01f, 2.587531e-01f, 2.568977e-01f, 2.550599e-01f, 2.532395e-01f, 2.514364e-01f, 2.496503e-01f, 2.478811e-01f, 2.461287e-01f, 2.443928e-01f, 2.426732e-01f, 2.409698e-01f, 2.392824e-01f, 2.376109e-01f, 2.359550e-01f, 2.343146e-01f, 2.326895e-01f, 2.310797e-01f, 2.294848e-01f, 2.279047e-01f, 2.263394e-01f, 2.247886e-01f, 2.232521e-01f, 2.217299e-01f, 2.202217e-01f, 2.187274e-01f, 2.172469e-01f, 2.157800e-01f, 2.143266e-01f, 2.128865e-01f, 2.114596e-01f, 2.100457e-01f, 2.086447e-01f, 2.072564e-01f, 2.058808e-01f }; +#endif /*----------------------------------------------------------------------* * SPAR ROM tables @@ -942,11 +944,19 @@ const ivas_spar_br_table_t ivas_spar_br_table_consts[IVAS_SPAR_BR_TABLE_LEN] = { 512000, 0, SBA_FOA_ORDER, FB, 24000, 4, WYXZ, 0, 0,{ { 128000, 128000, 128000 },{ 128000, 128000, 128000 },{ 128000, 128000, 128000 }, {118450, 118450, 128000 } }, // not yet optimized { { 31, 1, 1, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, +#ifdef SPAR_TUNING + { 512000, 0, SBA_HOA2_ORDER, FB, 24000, 4, WYXZ, 0, 0,{ { 124000, 124000, 128000 },{ 124000, 124000, 128000 },{ 125200, 118450, 128000 },{ 76300, 73000, 128000 } }, // not yet optimized + { { 31, 11, 11, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, + + { 512000, 0, SBA_HOA3_ORDER, FB, 24000, 4, WYXZ, 0, 0,{ { 118000, 118000, 128000 },{ 118000, 118000, 128000 },{ 117200, 109250, 128000 },{ 72300, 69000, 128000 } }, // not yet optimized + { { 31, 11, 11, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, +#else { 512000, 0, SBA_HOA2_ORDER, FB, 24000, 4, WYXZ, 0, 0,{ { 128000, 128000, 128000 },{ 128000, 128000, 128000 },{ 128000, 128000, 128000 },{ 97700, 93300, 128000 } }, // not yet optimized { { 31, 11, 11, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, { 512000, 0, SBA_HOA3_ORDER, FB, 24000, 4, WYXZ, 0, 0,{ { 128000, 128000, 128000 },{ 128000, 128000, 128000 },{ 127200, 122550, 128000 },{ 76300, 73550, 128000 } }, // not yet optimized { { 31, 11, 11, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, +#endif }; const ivas_freq_models_t ivas_arith_pred_r_consts[TOTAL_PRED_QUANT_STRATS_ARITH] = @@ -1463,11 +1473,31 @@ const int16_t dtx_pr_real_q_levels[3][3] = { { 9,9,9 },{ 9,7,9 },{ 9,5,7 } }; const int16_t pr_pr_idx_pairs[3][3][2] = { { { 0, 0 },{ 0, 0 },{ 0, 0 } },{ { 0, 0 },{ 0, 0 },{ 0, 0 } },{ { 0, 0 },{ 1, 3 },{ 0, 0 } } }; const int16_t pr_pd_idx_pairs[3][3][2] = { { { 1, 1 },{ 2, 2 },{ 3, 3 } },{ { 1, 1 },{ 3, 2 },{ 2, 0 } },{ { 2, 1 },{ 0, 0 },{ 0, 0 } } }; +#ifdef HODIRAC +const int16_t remix_order_set[1][DIRAC_MAX_ANA_CHANS] = { /* WYZX --> WYXZ... */ + { 0, 1, 3, 2, 4, 5, 6, 7, 8, 9, 10 } +}; +#else const int16_t remix_order_set[1][IVAS_SPAR_MAX_CH] = { /* WYZX --> WYXZ... */ { 0, 1, 3, 2, 4, 5, 6, 7} }; +#endif +#ifdef SPAR_TUNING +const int16_t keep_planar[IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS] = { 1, 1, 1, 1, 1, 1 }; +#else const int16_t keep_planar[IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS] = { 1, 1, 1, 1 }; +#endif +#ifdef HODIRAC +const int16_t HOA_keep_ind[IVAS_SPAR_MAX_FB_IN_CHAN] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15}; +#ifdef SPAR_TUNING +const int16_t HOA_keep_ind_spar[IVAS_SPAR_MAX_CH] = {0, 1, 2, 3, 4, 8, 9, 10, 10, 10, 10}; +const int16_t HOA_keep_ind_spar512[IVAS_SPAR_MAX_CH] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; +#else +const int16_t HOA_keep_ind_spar[IVAS_SPAR_MAX_CH] = {0, 1, 2, 3, 4, 8, 9, 10}; +#endif +#else const int16_t HOA_keep_ind[IVAS_SPAR_MAX_CH] = {0, 1, 2, 3, 4, 8, 9, 15}; +#endif /*----------------------------------------------------------------------* diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index ccfc3f9000282f65fcbc7ea088f4fecf00cfaafb..dbd09e4537ccf90df29310593ba234786fa2c9d4 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -161,6 +161,23 @@ extern const int16_t DirAC_band_grouping_5[5 + 1]; extern const int16_t DirAC_block_grouping[MAX_PARAM_SPATIAL_SUBFRAMES + 1]; extern const int16_t DirAC_block_grouping_5ms_MDFT[MAX_PARAM_SPATIAL_SUBFRAMES + 1]; +#ifdef HODIRAC +extern const float c_weights[DIRAC_NO_FB_BANDS_MAX]; +#endif + +#ifdef HODIRAC +extern const float w_nm[NUM_ANA_SECTORS][9]; +extern const float x_nm[NUM_ANA_SECTORS][9]; +extern const float y_nm[NUM_ANA_SECTORS][9]; +extern const float z_nm[NUM_ANA_SECTORS][9]; +#else +#define NUM_ANA_SECTORS 1 +extern const float w_nm[NUM_ANA_SECTORS][9]; +extern const float x_nm[NUM_ANA_SECTORS][9]; +extern const float y_nm[NUM_ANA_SECTORS][9]; +extern const float z_nm[NUM_ANA_SECTORS][9]; +#endif + /*------------------------------------------------------------------------------------------* * SPAR ROM tables *------------------------------------------------------------------------------------------*/ @@ -172,9 +189,19 @@ extern const ivas_huff_models_t ivas_huff_pred_r_consts[TOTAL_PRED_QUANT_STRATS_ extern const ivas_huff_models_t ivas_huff_drct_r_consts[TOTAL_DRCT_QUANT_STRATS]; extern const ivas_huff_models_t ivas_huff_decd_r_consts[TOTAL_DECD_QUANT_STRATS]; extern const ivas_spar_br_table_t ivas_spar_br_table_consts[IVAS_SPAR_BR_TABLE_LEN]; +#ifdef HODIRAC +extern const int16_t remix_order_set[1][DIRAC_MAX_ANA_CHANS]; +#else extern const int16_t remix_order_set[1][IVAS_SPAR_MAX_CH]; +#endif extern const int16_t keep_planar[IVAS_SPAR_MAX_CH - FOA_CHANNELS]; +#ifdef HODIRAC +extern const int16_t HOA_keep_ind[IVAS_SPAR_MAX_FB_IN_CHAN]; +extern const int16_t HOA_keep_ind_spar[IVAS_SPAR_MAX_CH]; +extern const int16_t HOA_keep_ind_spar512[IVAS_SPAR_MAX_CH]; +#else extern const int16_t HOA_keep_ind[IVAS_SPAR_MAX_CH]; +#endif extern const float dtx_pd_real_min_max[2]; extern const int16_t dtx_pd_real_q_levels[3][3]; diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config.c index d307e3e9acc765144cbeff170123ac5f2802ad64..f5e0c53e3a6b5414a0dca415caf2c9f3b6726c63 100644 --- a/lib_com/ivas_sba_config.c +++ b/lib_com/ivas_sba_config.c @@ -222,6 +222,10 @@ int16_t ivas_sba_get_nchan( /*! r: number of ambisonics metadata channels */ int16_t ivas_sba_get_nchan_metadata( const int16_t sba_order /* i : Ambisonic (SBA) order */ +#ifdef SPAR_TUNING + , + const int32_t ivas_total_brate +#endif ) { int16_t nb_channels; @@ -232,8 +236,19 @@ int16_t ivas_sba_get_nchan_metadata( } else { - /* FOA + planar HOA */ - nb_channels = FOA_CHANNELS + 2 * ( sba_order - 1 ); +#ifdef SPAR_TUNING + if ( ivas_total_brate >= IVAS_512k ) + { + nb_channels = ( SBA_HOA2_ORDER + 1 ) * ( SBA_HOA2_ORDER + 1 ); + nb_channels += 2; + nb_channels = min( nb_channels, ( sba_order + 1 ) * ( sba_order + 1 ) ); + } + else +#endif + { + /* FOA + planar HOA */ + nb_channels = FOA_CHANNELS + 2 * ( sba_order - 1 ); + } } return ( nb_channels ); @@ -246,6 +261,58 @@ int16_t ivas_sba_get_nchan_metadata( *-------------------------------------------------------------------*/ /*! r: flag indicating to code SPAR HOA MD for all bands */ +#ifdef SPAR_TUNING +void ivas_sba_get_spar_hoa_ch_ind( + const int16_t num_md_chs, /* i : number of MD channels */ + const int32_t ivas_total_brate, /* i : IVAS total bitrate */ + int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] ) +{ + int16_t ch; + const int16_t *hoa_ind; + + if ( ivas_total_brate >= IVAS_512k ) + { + hoa_ind = HOA_keep_ind_spar512; + } + else + { + hoa_ind = HOA_keep_ind_spar; + } + for ( ch = 0; ch < num_md_chs; ch++ ) + { + HOA_md_ind[ch] = hoa_ind[ch]; + } + + return; +} + +void 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, + int16_t *spar_hoa_dirac2spar_md_flag ) +{ + if ( sba_order > 1 && ivas_total_brate >= IVAS_256k ) + { + *spar_hoa_md_flag = 1; + } + else + { + *spar_hoa_md_flag = 0; + } + + if ( sba_order > 1 && ivas_total_brate >= IVAS_512k ) + { + *spar_hoa_dirac2spar_md_flag = 0; + } + else + { + *spar_hoa_dirac2spar_md_flag = 1; + } + + return; +} +#else 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 */ @@ -264,6 +331,8 @@ int16_t ivas_sba_get_spar_hoa_md_flag( 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 6688edc0415b0bcd0b037cf848e446e567a63584..7ca2d417159fb59b38284516609240168f887111 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -1679,14 +1679,27 @@ void ivas_get_spar_md_from_dirac( float **ppMixer_mat[IVAS_MAX_FB_MIXER_OUT_CH]; float *pMixer_mat[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH]; float en_ratio_fac, diff_norm_order1, diff_norm_order2, diff_norm_order3; + int16_t ndm, foa_ch, hoa2_ch; float P_dir_fact[IVAS_SPAR_MAX_CH - 1]; const int16_t *remix_order; remix_order = remix_order_set[hSpar_md_cfg->remix_unmix_order]; - num_ch = ivas_sba_get_nchan_metadata( order ); - hoa2_ch = ivas_sba_get_nchan_metadata( SBA_HOA2_ORDER ); + num_ch = ivas_sba_get_nchan_metadata( order +#ifdef SPAR_TUNING + , + IVAS_256k /*dummy value as order is always 1 in this function*/ +#endif + ); + + hoa2_ch = ivas_sba_get_nchan_metadata( SBA_HOA2_ORDER +#ifdef SPAR_TUNING + , + IVAS_256k /*dummy value as order is always 1 in this function*/ +#endif + ); + foa_ch = FOA_CHANNELS; diff_norm_order1 = 3.0f; diff_norm_order2 = 5.0f; @@ -1756,6 +1769,7 @@ void ivas_get_spar_md_from_dirac( /*SPAR from DirAC*/ set_f( response_avg, 0.0f, MAX_OUTPUT_CHANNELS ); + 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 ); @@ -1830,64 +1844,69 @@ void ivas_get_spar_md_from_dirac( { response_avg[i] = response_avg[HOA_keep_ind[i]]; } + en_ratio_fac = ( 1.0f - diffuseness[band] ); - for ( i = 0; i < num_ch; i++ ) { - for ( j = 0; j < num_ch; j++ ) + for ( i = 0; i < num_ch; i++ ) { - if ( i == j ) + for ( j = 0; j < num_ch; j++ ) { - if ( i == 0 ) + if ( i == j ) { - cov_real_dirac[i][i][band] = 1.0f; - } - else - { - cov_real_dirac[i][j][band] = en_ratio_fac * response_avg[i] * response_avg[j]; - if ( hSpar_md_cfg->nchan_transport <= 2 ) + if ( i == 0 ) + { + cov_real_dirac[i][i][band] = 1.0f; + } + else { - cov_real_dirac[i][j][band] *= en_ratio_fac; - if ( ( i >= ndm ) && ( dtx_vad == 1 ) ) + cov_real_dirac[i][j][band] = en_ratio_fac * response_avg[i] * response_avg[j]; + + if ( hSpar_md_cfg->nchan_transport <= 2 ) { - cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) * P_dir_fact[i - ndm]; + + cov_real_dirac[i][j][band] *= en_ratio_fac; + if ( ( i >= ndm ) && ( dtx_vad == 1 ) ) + { + cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) * P_dir_fact[i - ndm]; + } + else + { + if ( i < foa_ch ) + { + cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order1; + } + else if ( i < hoa2_ch ) + { + cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order2; + } + else + { + cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order3; + } + } } else { if ( i < foa_ch ) { - cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order1; + cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order1; } else if ( i < hoa2_ch ) { - cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order2; + cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order2; } else { - cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order3; + cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order3; } } } - else - { - if ( i < foa_ch ) - { - cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order1; - } - else if ( i < hoa2_ch ) - { - cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order2; - } - else - { - cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order3; - } - } } - } - else - { - cov_real_dirac[i][j][band] = en_ratio_fac * response_avg[i] * response_avg[j]; + else + { + cov_real_dirac[i][j][band] = en_ratio_fac * response_avg[i] * response_avg[j]; + } } } } @@ -1901,7 +1920,7 @@ void ivas_get_spar_md_from_dirac( } } -#ifdef DEBUG_SPAR_WRITE_OUT_COV +#ifdef DEBUG_SBA_MD_DUMP { static FILE *fid = 0; int16_t k = 0; diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 305a18951a2338d8d8d282cc81a5a88e4089ea39..965bd1f56ba1e963c792cc207080d4e4d953fde7 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -717,6 +717,9 @@ typedef struct ivas_fb_mixer_cfg_t int16_t fb_latency; int16_t num_in_chans; int16_t num_out_chans; +#ifdef HODIRAC + int16_t nchan_fb_in; +#endif int16_t pcm_offset; int16_t fade_len; /* this sets the stride length; no delay is introduced */ int16_t prior_input_length; diff --git a/lib_com/options.h b/lib_com/options.h index a8c5bdd0ef9d2605bc8d5b3ca62d172c8b434d6f..b6dba1a36810632aa62c6c7a060e339ee2fd0111 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -112,7 +112,7 @@ /*#define TDREND_HRTF_TABLE_METHODS*/ /* Enable HRTF lookup from tables, for testing & evaluation. Supply file in table format to use. Note that a suitable HR filter lookup method should be written if the filters sample point grids are not in the formats. */ /*#define TDREND_STANDALONE*/ /* Used when renderer is built in standalone form, without IVAS encoding/decoding (see scripts/object_renderer_standalone). This is just here to ensure this is cleaned out by prepare_instrumentation.sh */ -/*#define DEBUG_SBA*/ /* debug DIRAC/SPAR in-out */ +/*#define DEBUG_SBA*/ /* debug DIRAC/SPAR in-out */ #ifdef DEBUG_SBA /*#define DEBUG_LBR_SBA*/ /* debug low bitrate SBA (SPAR+DirAC) */ /*#define DEBUG_SBA_AUDIO_DUMP*/ /* SBA intermediate audio wav file dumping */ @@ -162,6 +162,7 @@ #define FIX_416_ISM_BR_SWITCHING /* FhG: add missing CLDFB reconfig to ISM BR switching */ #define FIX_SP2A /* VA: Issue 412: Adjust threshold for the S_p2a feature in the tonal detector */ + #define FIX_413_SBA_DTX /* Dlb: Fix for issue 413, SBA DTX CNG in 2TC mode*/ #define FIX_417_TD_DECORR_BRATE_SW /* VA: Issue 417: fix incorrect use of TD decorrelator in bitrate switching */ #define FIX_368_SBA_MODE /* Dlb: Fix for issue 368 */ @@ -180,6 +181,7 @@ #define FIX_355_REFACTOR_PARAMBIN_TO_5MS /* Nokia: Fixes issue 355 by refactoring parametric binauralizer code to 5 ms mode */ #define FIX_411_EVS_BE_TESTS_ON_WINDOWS_FAILING /* Eri: Fix incorrect use of stack variable used for channel aware config file */ #define COMBINED_FORMAT_SIGNALING /* VA: Introduce a signaling bit for combined format coding */ + #define FIX_386_CORECODER_RECONFIG_2 /* VA: Issue 386: Resolve remaining ToDo comments in CoreCoder reconfig. */ #define FIX_440_PARAM_ISM_DIR_NOISE /* FhG: Issue 440: Fix directional background noise becoming diffuse in ParamISM */ @@ -188,6 +190,24 @@ #define FIX_447_PARAMBIN_MASA_REGU_FAC /* Nokia: Issue 447: Fix issue by adjusting regularization factor minimum value. */ #define FIX_441_SBA_PARAMBIN_GAINS /* Nokia: Fix issue 441 by changing gains in SBA path of parametric binauralizer */ + +#define HODIRAC /* FhG: Sector-based HO-DirAC method for SBA at high bitrates */ + +#ifdef HODIRAC +#define SPAR_TUNING /* Dlb: tune SPAR for better quality */ +#define HODIRAC_FIX_BR_SWITCHING_DTX +#endif + +/*#define HODIRAC_DEBUG*/ + +#ifdef HODIRAC_DEBUG +//#define HODIRAC_CHECK_VALUE_RANGE +//#define HODIRAC_WRITE_PARAMS +//#define HODIRAC_READ_PARAMS +#endif + /* ################## End DEVELOPMENT switches ######################### */ + /* clang-format on */ + #endif diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index 68ce3c75fe84401cf24d6317dcf014474c332d9e..fd1638b849b08473db0c3a65351975cfedf60295 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -259,7 +259,11 @@ ivas_error ivas_dec( if ( st_ivas->ivas_format == SBA_FORMAT ) { - ivas_dirac_dec_read_BS( ivas_total_brate, st, st_ivas->hDirAC, st_ivas->hQMetaData, &nb_bits_metadata[0], st_ivas->sba_mode, 0 ); + ivas_dirac_dec_read_BS( ivas_total_brate, st, st_ivas->hDirAC, st_ivas->hQMetaData, &nb_bits_metadata[0], st_ivas->sba_mode, +#ifdef HODIRAC + st_ivas->sba_analysis_order > 1 && ivas_total_brate > IVAS_256k, +#endif + 0 ); } else { @@ -274,7 +278,17 @@ ivas_error ivas_dec( if ( st_ivas->hQMetaData != NULL ) { st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; - ivas_dirac_dec_read_BS( ivas_total_brate, st, st_ivas->hDirAC, st_ivas->hQMetaData, &nb_bits_metadata[0], st_ivas->sba_mode, st_ivas->hSpar->dirac_to_spar_md_bands ); + ivas_dirac_dec_read_BS( + ivas_total_brate, + st, + st_ivas->hDirAC, + st_ivas->hQMetaData, + &nb_bits_metadata[0], + st_ivas->sba_mode, +#ifdef HODIRAC + st_ivas->sba_analysis_order > 1 && ivas_total_brate > IVAS_256k, +#endif + st_ivas->hSpar->dirac_to_spar_md_bands ); } if ( ( error = ivas_spar_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) @@ -340,7 +354,12 @@ ivas_error ivas_dec( ivas_pca_dec( st_ivas->hSpar->hPCA, output_frame, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, output ); } - ivas_spar_dec_gen_umx_mat( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi ); + ivas_spar_dec_gen_umx_mat( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi +#ifdef SPAR_TUNING + , + ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, st_ivas->hDecoderConfig->ivas_total_brate ) +#endif + ); } ivas_sba_dirac_stereo_dec( st_ivas, output, output_frame, st_ivas->ivas_format == MC_FORMAT ); diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index b02b1144c343b7cbc93d73632ac63bc1fd600e6e..73c8dcf12e8fe3ebe947ee07845fcd8e8ab9db53 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -51,7 +51,12 @@ * Local function prototypes *-----------------------------------------------------------------------*/ -static ivas_error ivas_dirac_alloc_mem( DIRAC_DEC_HANDLE hDirAC, const RENDERER_TYPE renderer_type, DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem ); +static ivas_error ivas_dirac_alloc_mem( DIRAC_DEC_HANDLE hDirAC, const RENDERER_TYPE renderer_type, DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem +#ifdef HODIRAC + , + int16_t hodirac +#endif +); static void ivas_dirac_free_mem( DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem ); @@ -65,7 +70,12 @@ static void protoSignalComputation1( float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRA static void protoSignalComputation2( float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float *proto_frame_f, float *proto_direct_buffer_f, float *reference_power, float *proto_power_smooth, const int16_t isloudspeaker, const int16_t slot_index, const int16_t num_freq_bands, MASA_STEREO_TYPE_DETECT *stereo_type_detect ); -static void protoSignalComputation4( float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float *proto_frame_f, float *proto_direct_buffer_f, float *reference_power, float *proto_power_smooth, const int16_t slot_index, const int16_t num_outputs_diff, const int16_t num_freq_bands, const float *mtx_hoa_decoder, const int16_t nchan_transport ); +static void protoSignalComputation4( float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float *proto_frame_f, float *proto_direct_buffer_f, float *reference_power, float *proto_power_smooth, const int16_t slot_index, const int16_t num_outputs_diff, const int16_t num_freq_bands, const float *mtx_hoa_decoder, const int16_t nchan_transport +#ifdef SPAR_TUNING + , + const int16_t *sba_map_tc_ind +#endif +); static void ivas_dirac_dec_compute_diffuse_proto( DIRAC_DEC_HANDLE hDirAC, const int16_t slot_idx ); @@ -172,7 +182,12 @@ ivas_error ivas_dirac_dec_config( nchan_transport_orig = st_ivas->nchan_transport; if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) { - st_ivas->nchan_transport = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); + st_ivas->nchan_transport = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order +#ifdef SPAR_TUNING + , + st_ivas->hDecoderConfig->ivas_total_brate +#endif + ); } nchan_transport = st_ivas->nchan_transport; @@ -255,12 +270,62 @@ ivas_error ivas_dirac_dec_config( assert( hDirAC->nb_subframes <= MAX_PARAM_SPATIAL_SUBFRAMES ); } +#ifdef HODIRAC + if ( st_ivas->ivas_format == SBA_FORMAT && flag_config == DIRAC_RECONFIGURE && ( ( ivas_total_brate > IVAS_256k && st_ivas->hDecoderConfig->last_ivas_total_brate <= IVAS_256k ) || ( ivas_total_brate <= IVAS_256k && st_ivas->hDecoderConfig->last_ivas_total_brate > IVAS_256k ) ) ) + { + if ( st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k && hDirAC->azimuth2 == NULL ) + { + hDirAC->azimuth2 = (int16_t **) malloc( hDirAC->dirac_md_buffer_length * sizeof( int16_t * ) ); + hDirAC->elevation2 = (int16_t **) malloc( hDirAC->dirac_md_buffer_length * sizeof( int16_t * ) ); + hDirAC->energy_ratio2 = (float **) malloc( hDirAC->dirac_md_buffer_length * sizeof( float * ) ); + hDirAC->spreadCoherence2 = (float **) malloc( hDirAC->dirac_md_buffer_length * sizeof( float * ) ); + for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ ) + { + hDirAC->azimuth2[i] = (int16_t *) malloc( hDirAC->num_freq_bands * sizeof( int16_t ) ); + set_s( hDirAC->azimuth2[i], 0, hDirAC->num_freq_bands ); + hDirAC->elevation2[i] = (int16_t *) malloc( hDirAC->num_freq_bands * sizeof( int16_t ) ); + set_s( hDirAC->elevation2[i], 0, hDirAC->num_freq_bands ); + hDirAC->energy_ratio2[i] = (float *) malloc( hDirAC->num_freq_bands * sizeof( float ) ); + set_f( hDirAC->energy_ratio2[i], 0.0f, hDirAC->num_freq_bands ); + hDirAC->spreadCoherence2[i] = (float *) malloc( hDirAC->num_freq_bands * sizeof( float ) ); + set_f( hDirAC->spreadCoherence2[i], 0.0f, hDirAC->num_freq_bands ); + } + } + else if ( st_ivas->hDecoderConfig->ivas_total_brate <= IVAS_256k && hDirAC->azimuth2 != NULL ) + { + for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ ) + { + free( hDirAC->azimuth2[i] ); + free( hDirAC->elevation2[i] ); + free( hDirAC->energy_ratio2[i] ); + free( hDirAC->spreadCoherence2[i] ); + } + + free( hDirAC->azimuth2 ); + free( hDirAC->elevation2 ); + free( hDirAC->energy_ratio2 ); + free( hDirAC->spreadCoherence2 ); + + hDirAC->azimuth2 = NULL; + hDirAC->elevation2 = NULL; + hDirAC->energy_ratio2 = NULL; + hDirAC->spreadCoherence2 = NULL; + } + } +#endif + /* band config needed only for SPAR with FOA output */ - if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_FOA && st_ivas->sba_mode == SBA_MODE_SPAR ) + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_FOA && st_ivas->sba_mode == SBA_MODE_SPAR +#ifdef HODIRAC + /*DLB : why is this needed ?*/ + && ivas_total_brate < IVAS_256k +#endif + ) { return IVAS_ERR_OK; } + if ( nchan_transport_orig > 2 && hDirAC->hOutSetup.is_loudspeaker_setup && st_ivas->renderer_type == RENDERER_DIRAC ) { hDirAC->synthesisConf = DIRAC_SYNTHESIS_PSD_LS; @@ -412,6 +477,17 @@ ivas_error ivas_dirac_dec_config( } set_s( hDirAC->proto_index_diff, 0, hDirAC->num_outputs_diff ); +#ifdef SPAR_TUNING + hDirAC->sba_map_tc = sba_map_tc; + if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR ) + { + if ( st_ivas->sba_order > SBA_FOA_ORDER && ivas_total_brate >= IVAS_512k ) + { + hDirAC->sba_map_tc = sba_map_tc_512; + } + } +#endif + if ( nchan_transport == 1 ) { hDirAC->num_protos_ambi = 1; @@ -517,10 +593,17 @@ ivas_error ivas_dirac_dec_config( for ( k = 0; k < min( hDirAC->num_outputs_dir, hDirAC->num_protos_dir ); k++ ) { +#ifdef SPAR_TUNING + if ( hDirAC->sba_map_tc[k] < hDirAC->num_outputs_dir ) + { + hDirAC->proto_index_dir[hDirAC->sba_map_tc[k]] = k; + } +#else if ( sba_map_tc[k] < hDirAC->num_outputs_dir ) { hDirAC->proto_index_dir[sba_map_tc[k]] = k; } +#endif } } } @@ -696,7 +779,12 @@ ivas_error ivas_dirac_dec_config( /* output synthesis */ if ( flag_config == DIRAC_OPEN ) { - if ( ( ivas_dirac_dec_output_synthesis_open( hDirAC, st_ivas->renderer_type, nchan_transport, output_Fs ) ) != IVAS_ERR_OK ) + if ( ( ivas_dirac_dec_output_synthesis_open( hDirAC, st_ivas->renderer_type, nchan_transport, output_Fs +#ifdef HODIRAC + , + st_ivas->sba_analysis_order > 1 && ivas_total_brate > IVAS_256k +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -706,7 +794,12 @@ ivas_error ivas_dirac_dec_config( { ivas_dirac_dec_output_synthesis_close( hDirAC ); - if ( ( ivas_dirac_dec_output_synthesis_open( hDirAC, st_ivas->renderer_type, nchan_transport, output_Fs ) ) != IVAS_ERR_OK ) + if ( ( ivas_dirac_dec_output_synthesis_open( hDirAC, st_ivas->renderer_type, nchan_transport, output_Fs +#ifdef HODIRAC + , + st_ivas->sba_analysis_order > 1 && ivas_total_brate > IVAS_256k +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -800,14 +893,24 @@ ivas_error ivas_dirac_dec_config( } /* output synthesis */ - ivas_dirac_dec_output_synthesis_init( hDirAC, nchan_out_woLFE ); + ivas_dirac_dec_output_synthesis_init( hDirAC, nchan_out_woLFE +#ifdef HODIRAC + , + st_ivas->sba_analysis_order > 1 && ivas_total_brate > IVAS_256k +#endif + ); /* Allocate stack memory */ if ( flag_config != DIRAC_OPEN ) { ivas_dirac_free_mem( &( hDirAC->stack_mem ) ); } - if ( ( error = ivas_dirac_alloc_mem( hDirAC, st_ivas->renderer_type, &( hDirAC->stack_mem ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_dirac_alloc_mem( hDirAC, st_ivas->renderer_type, &( hDirAC->stack_mem ) +#ifdef HODIRAC + , + st_ivas->sba_analysis_order > 1 && ivas_total_brate > IVAS_256k +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -924,7 +1027,11 @@ ivas_error ivas_dirac_dec_config( set_f( hDirAC->surroundingCoherence[i], 0.0f, hDirAC->num_freq_bands ); } - if ( st_ivas->ivas_format == MASA_FORMAT ) + if ( st_ivas->ivas_format == MASA_FORMAT +#ifdef HODIRAC + || ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k ) +#endif + ) { if ( ( hDirAC->azimuth2 = (int16_t **) malloc( hDirAC->dirac_md_buffer_length * sizeof( int16_t * ) ) ) == NULL ) { @@ -1393,9 +1500,18 @@ void ivas_dirac_dec_close( static ivas_error ivas_dirac_alloc_mem( DIRAC_DEC_HANDLE hDirAC, const RENDERER_TYPE renderer_type, - DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem ) + DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem +#ifdef HODIRAC + , + int16_t hodirac +#endif +) { int16_t num_freq_bands, num_freq_bands_diff, size; +#ifdef HODIRAC + int16_t size_ho; + int16_t size_pf; +#endif int16_t num_outputs_dir, num_outputs_diff; int16_t num_protos_dir; @@ -1408,6 +1524,18 @@ static ivas_error ivas_dirac_alloc_mem( num_outputs_diff = hDirAC->num_outputs_diff; size = num_freq_bands * num_outputs_dir; +#ifdef HODIRAC + if ( hodirac ) + { + size_ho = size * DIRAC_HO_NUMSECTORS; + size_pf = num_freq_bands * DIRAC_HO_NUMSECTORS; + } + else + { + size_ho = size; + size_pf = num_freq_bands; + } +#endif /* PSD related buffers */ hDirAC_mem->cy_auto_dir_smooth = NULL; @@ -1454,7 +1582,11 @@ static ivas_error ivas_dirac_alloc_mem( hDirAC->h_output_synthesis_psd_state.direct_responses_square = hDirAC_mem->direct_responses_square; /* Target and smoothed nrg factors/gains */ +#ifdef HODIRAC + if ( ( hDirAC_mem->cy_cross_dir_smooth = (float *) malloc( sizeof( float ) * size_ho ) ) == NULL ) +#else if ( ( hDirAC_mem->cy_cross_dir_smooth = (float *) malloc( sizeof( float ) * size ) ) == NULL ) +#endif { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } @@ -1480,11 +1612,17 @@ static ivas_error ivas_dirac_alloc_mem( hDirAC->h_output_synthesis_psd_state.cy_auto_diff_smooth = hDirAC_mem->cy_auto_diff_smooth; /*Responses (gains/factors)*/ +#ifdef HODIRAC + if ( ( hDirAC_mem->direct_responses = (float *) malloc( sizeof( float ) * size_ho ) ) == NULL ) +#else if ( ( hDirAC_mem->direct_responses = (float *) malloc( sizeof( float ) * size ) ) == NULL ) +#endif { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } set_zero( hDirAC_mem->direct_responses, size ); + + hDirAC->h_output_synthesis_psd_state.direct_responses = hDirAC_mem->direct_responses; /* Prototypes */ @@ -1521,18 +1659,27 @@ static ivas_error ivas_dirac_alloc_mem( /* Gains/power factors*/ hDirAC_mem->direct_power_factor = NULL; hDirAC_mem->diffuse_power_factor = NULL; + if ( renderer_type != RENDERER_BINAURAL_PARAMETRIC && renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && renderer_type != RENDERER_STEREO_PARAMETRIC ) { +#ifdef HODIRAC + if ( ( hDirAC_mem->direct_power_factor = (float *) malloc( sizeof( float ) * size_pf ) ) == NULL ) +#else if ( ( hDirAC_mem->direct_power_factor = (float *) malloc( sizeof( float ) * num_freq_bands ) ) == NULL ) +#endif { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } - +#ifdef HODIRAC + if ( ( hDirAC_mem->diffuse_power_factor = (float *) malloc( sizeof( float ) * size_pf ) ) == NULL ) +#else if ( ( hDirAC_mem->diffuse_power_factor = (float *) malloc( sizeof( float ) * num_freq_bands ) ) == NULL ) +#endif { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } } + hDirAC->h_output_synthesis_psd_state.direct_power_factor = hDirAC_mem->direct_power_factor; hDirAC->h_output_synthesis_psd_state.diffuse_power_factor = hDirAC_mem->diffuse_power_factor; @@ -1655,7 +1802,10 @@ void ivas_dirac_dec_read_BS( IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata */ int16_t *nb_bits, /* o : number of bits read */ const SBA_MODE sba_mode, /* i : SBA mode */ - int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ +#ifdef HODIRAC + const int16_t hodirac, /* i : HO-Dirac flag */ +#endif + int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ ) { int16_t i, j, b, dir, orig_dirac_bands; @@ -1750,7 +1900,12 @@ void ivas_dirac_dec_read_BS( hQMetaData->q_direction[0].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES; } - *nb_bits += ivas_qmetadata_dec_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ) ); + *nb_bits += ivas_qmetadata_dec_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ) +#ifdef HODIRAC + , + hodirac +#endif + ); } #ifdef DEBUGGING @@ -1817,7 +1972,13 @@ void ivas_dirac_dec_read_BS( if ( hDirAC != NULL ) { - ivas_qmetadata_to_dirac( hQMetaData, hDirAC, NULL, ivas_total_brate, sba_mode, dirac_to_spar_md_bands ); + ivas_qmetadata_to_dirac( hQMetaData, hDirAC, NULL, ivas_total_brate, sba_mode +#ifdef HODIRAC + , + hodirac +#endif + , + dirac_to_spar_md_bands ); } return; @@ -1836,7 +1997,10 @@ void ivas_qmetadata_to_dirac( MASA_DECODER_HANDLE hMasa, /* i : MASA decoder structure */ const int32_t ivas_total_brate, /* i : IVAS total bitrate */ const SBA_MODE sba_mode, /* i : SBA mode */ - int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ +#ifdef HODIRAC + const int16_t hodirac, /* i : HO-DirAC flag*/ +#endif + int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ ) { int16_t block, band; @@ -1849,9 +2013,21 @@ void ivas_qmetadata_to_dirac( int16_t *band_mapping; int16_t *band_grouping; int16_t start_band; - int16_t nbands; - int16_t nblocks; + int16_t nbands = 0; + int16_t nblocks = 0; int16_t qBand_idx; +#ifdef HODIRAC + int16_t idx_sec = 0; + int16_t no_secs = 1; +#endif + +#ifdef HODIRAC_READ_PARAMS + static FILE *f_secparams = 0; + if ( f_secparams == 0 ) + { + f_secparams = fopen( "sector_params.txt", "r" ); + } +#endif q_direction = &( hQMetaData->q_direction[0] ); hDirAC->numSimultaneousDirections = hQMetaData->no_directions; @@ -1941,6 +2117,9 @@ void ivas_qmetadata_to_dirac( int16_t num_slots_in_subfr; int16_t tmp_write_idx_param_band; int16_t tmp_write_idx_band; +#ifdef HODIRAC + float diffuseness_sec = 0.f; +#endif num_slots_in_subfr = hDirAC->hConfig->dec_param_estim ? CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES : 1; /* ungroup */ @@ -1959,7 +2138,9 @@ void ivas_qmetadata_to_dirac( } else { +#ifndef HODIRAC assert( ( hQMetaData->no_directions == 1 ) && "Only 1 direction supported in SBA mode!" ); +#endif start_band = hDirAC->hConfig->enc_param_start_band; if ( sba_mode == SBA_MODE_SPAR ) @@ -1982,6 +2163,38 @@ void ivas_qmetadata_to_dirac( } } +#ifdef HODIRAC_READ_PARAMS + /* popular sector parameters from file */ + int16_t idx_f; + int idx_f_f, idx_sec_f; + float azi_secs[4][4][DIRAC_MAX_NBANDS], ele_secs[4][4][DIRAC_MAX_NBANDS], ene_secs[4][4][DIRAC_MAX_NBANDS], diff_secs[4][4][DIRAC_MAX_NBANDS], diff[4][DIRAC_MAX_NBANDS]; + assert( hDirAC->nb_subframes <= 4 ); + for ( block = 0; block < hDirAC->nb_subframes; block++ ) + { + int16_t block_qmetadata; + + block_qmetadata = min( block, nblocks - 1 ); + block_qmetadata = max( block_qmetadata, 0 ); + + assert( block_qmetadata == block ); // does this ever happen? + for ( idx_f = 0; idx_f < nbands; idx_f++ ) + { + for ( idx_sec = 0; idx_sec < 4; idx_sec++ ) + { + if ( 7 != fscanf( f_secparams, "%i %i %f %f %f %f %f\n", &idx_f_f, &idx_sec_f, &azi_secs[block_qmetadata][idx_sec][idx_f], &ele_secs[block_qmetadata][idx_sec][idx_f], &ene_secs[block_qmetadata][idx_sec][idx_f], &diff_secs[block_qmetadata][idx_sec][idx_f], &diff[block_qmetadata][idx_f] ) ) + { + printf( "ERROR reading parameters!\n" ); + exit( -1 ); + } + if ( azi_secs[block_qmetadata][idx_sec][idx_f] < 0.f ) + { + azi_secs[block_qmetadata][idx_sec][idx_f] += 360.f; + } + } + } + } +#endif + /* Low-Bands with no spatial data transmitted, analysis at decoder side */ for ( band = 0; band < start_band; band++ ) { @@ -1998,111 +2211,176 @@ void ivas_qmetadata_to_dirac( } /* Bands with spatial data transmitted */ - - for ( band = start_band; band < nbands; band++ ) +#ifdef HODIRAC + if ( hodirac ) { - band_start = band_grouping[band]; - band_end = band_grouping[band + 1]; - tmp_write_idx_param_band = hDirAC->dirac_bs_md_write_idx; - - if ( sba_mode == SBA_MODE_SPAR ) - { - qBand_idx = dirac_to_spar_md_bands[band] - start_band; - } - else - { - qBand_idx = band; - } - diffuseness = 1.0f - q_direction->band_data[qBand_idx].energy_ratio[0]; -#ifdef DEBUG_MODE_DIRAC - dbgwrite( &diffuseness, sizeof( float ), 1, 1, "./res/dirac_dec_diffuseness.dat" ); + no_secs = DIRAC_HO_NUMSECTORS; + } + for ( idx_sec = 0; idx_sec < no_secs; idx_sec++ ) #endif - diff_idx = q_direction->band_data[qBand_idx].energy_ratio_index[0]; - - for ( block = 0; block < hDirAC->nb_subframes; block++ ) + { + for ( band = start_band; band < nbands; band++ ) { - int16_t block_qmetadata; + band_start = band_grouping[band]; + band_end = band_grouping[band + 1]; + tmp_write_idx_param_band = hDirAC->dirac_bs_md_write_idx; - ts_start = hDirAC->block_grouping[block]; - ts_end = hDirAC->block_grouping[block + 1]; - - block_qmetadata = min( block, nblocks - 1 ); - block_qmetadata = max( block_qmetadata, 0 ); - - if ( q_direction->band_data[qBand_idx].azimuth[block_qmetadata] < 0.f ) + if ( sba_mode == SBA_MODE_SPAR ) { - q_direction->band_data[qBand_idx].azimuth[block_qmetadata] += 360.f; + qBand_idx = dirac_to_spar_md_bands[band] - start_band; } - azimuth = q_direction->band_data[qBand_idx].azimuth[block_qmetadata]; - elevation = q_direction->band_data[qBand_idx].elevation[block_qmetadata]; + else + { + qBand_idx = band; + } + diffuseness = 1.0f - q_direction->band_data[qBand_idx].energy_ratio[0]; +#ifdef DEBUG_MODE_DIRAC + dbgwrite( &diffuseness, sizeof( float ), 1, 1, "./res/dirac_dec_diffuseness.dat" ); +#endif + diff_idx = q_direction->band_data[qBand_idx].energy_ratio_index[0]; - for ( b = band_start; b < band_end; b++ ) + for ( block = 0; block < hDirAC->nb_subframes; block++ ) { - tmp_write_idx_band = tmp_write_idx_param_band; - azi = (int16_t) ( azimuth + rand_triangular_signed( seed_ptr ) * dirac_dithering_azi_scale[diff_idx] + 0.5f ); - ele = (int16_t) ( elevation + rand_triangular_signed( seed_ptr ) * dirac_dithering_ele_scale[diff_idx] + 0.5f ); - /* limit the elevation to [-90, 90] */ - ele = min( 90, ele ); - ele = max( -90, ele ); + int16_t block_qmetadata; + + ts_start = hDirAC->block_grouping[block]; + ts_end = hDirAC->block_grouping[block + 1]; - if ( ivas_total_brate > IVAS_SID_5k2 && q_direction->coherence_band_data != NULL ) + block_qmetadata = min( block, nblocks - 1 ); + block_qmetadata = max( block_qmetadata, 0 ); + +#ifdef HODIRAC + if ( q_direction[idx_sec].band_data[qBand_idx].azimuth[block_qmetadata] < 0.f ) { - hDirAC->spreadCoherence[tmp_write_idx_band][b] = q_direction->coherence_band_data[qBand_idx].spread_coherence[block] / 255.0f; + q_direction[idx_sec].band_data[qBand_idx].azimuth[block_qmetadata] += 360.f; } - else +#else + if ( q_direction->band_data[qBand_idx].azimuth[block_qmetadata] < 0.f ) { - hDirAC->spreadCoherence[tmp_write_idx_band][b] = 0.0f; + q_direction->band_data[qBand_idx].azimuth[block_qmetadata] += 360.f; } +#endif + - if ( ivas_total_brate > IVAS_SID_5k2 && q_direction->coherence_band_data != NULL ) +#ifdef HODIRAC + if ( hMasa == NULL && hodirac ) { - hDirAC->surroundingCoherence[tmp_write_idx_band][b] = hQMetaData->surcoh_band_data[qBand_idx].surround_coherence[0] / 255.0f; + azimuth = q_direction[idx_sec].band_data[qBand_idx].azimuth[block_qmetadata]; + elevation = q_direction[idx_sec].band_data[qBand_idx].elevation[block_qmetadata]; + diffuseness = 1.f - q_direction[0].band_data[qBand_idx].energy_ratio[block_qmetadata]; + diffuseness_sec = q_direction[1].band_data[qBand_idx].energy_ratio[block_qmetadata]; + assert( diffuseness_sec < 1.0001f && diffuseness_sec > -0.0001f ); } else +#endif { - hDirAC->surroundingCoherence[tmp_write_idx_band][b] = 0.0f; + azimuth = q_direction->band_data[qBand_idx].azimuth[block_qmetadata]; + elevation = q_direction->band_data[qBand_idx].elevation[block_qmetadata]; } - hDirAC->energy_ratio1[tmp_write_idx_band][b] = q_direction->band_data[qBand_idx].energy_ratio[0]; +#ifdef HODIRAC_READ_PARAMS + int16_t tmp_i; + tmp_i = 0; + ( idx_sec == 0 ) ? ( tmp_i = 1 ) : ( ( idx_sec == 1 ) ? ( tmp_i = 2 ) : ( tmp_i = -99 ) ); + assert( tmp_i < 3 ); + azimuth = azi_secs[block_qmetadata][tmp_i][qBand_idx]; + elevation = ele_secs[block_qmetadata][tmp_i][qBand_idx]; + diffuseness = diff[block_qmetadata][qBand_idx]; - if ( hDirAC->hConfig->dec_param_estim == FALSE ) + if ( azimuth < 0.f ) { - hDirAC->elevation[tmp_write_idx_band][b] = ele; - hDirAC->azimuth[tmp_write_idx_band][b] = azi; - hDirAC->diffuseness_vector[tmp_write_idx_band][b] = diffuseness; + azimuth += 360.f; } - else + diffuseness_sec = 1.f - ( diff_secs[block_qmetadata][1][qBand_idx] / ( diff_secs[block_qmetadata][1][qBand_idx] + diff_secs[block_qmetadata][2][qBand_idx] + EPSILON ) ); +#endif + + for ( b = band_start; b < band_end; b++ ) { - for ( ts = ts_start; ts < ts_end; ts++ ) + tmp_write_idx_band = tmp_write_idx_param_band; + +#ifdef HODIRAC + if ( hodirac ) { - hDirAC->elevation[tmp_write_idx_band][b] = ele; - hDirAC->azimuth[tmp_write_idx_band][b] = azi; - hDirAC->diffuseness_vector[tmp_write_idx_band][b] = diffuseness; - tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hDirAC->dirac_md_buffer_length; + azi = (int16_t) ( azimuth + 0.5f ); + ele = (int16_t) ( elevation + 0.5f ); + } + else +#endif + { + azi = (int16_t) ( azimuth + rand_triangular_signed( seed_ptr ) * dirac_dithering_azi_scale[diff_idx] + 0.5f ); + ele = (int16_t) ( elevation + rand_triangular_signed( seed_ptr ) * dirac_dithering_ele_scale[diff_idx] + 0.5f ); + /* limit the elevation to [-90, 90] */ + ele = min( 90, ele ); + ele = max( -90, ele ); } - } - } /* for ( band = ...) */ - tmp_write_idx_param_band = ( tmp_write_idx_param_band + num_slots_in_subfr ) % hDirAC->dirac_md_buffer_length; - } /* for ( block =...) */ - } -#ifdef DEBUG_MODE_DIRAC - { - for ( block = 0; block < hDirAC->nb_subframes; block++ ) - { - int16_t block_qmetadata; + if ( ivas_total_brate > IVAS_SID_5k2 && q_direction->coherence_band_data != NULL ) + { + hDirAC->spreadCoherence[tmp_write_idx_band][b] = q_direction->coherence_band_data[qBand_idx].spread_coherence[block] / 255.0f; + } + else + { + hDirAC->spreadCoherence[tmp_write_idx_band][b] = 0.0f; + } - block_qmetadata = min( block, nblocks - 1 ); - block_qmetadata = max( block_qmetadata, 0 ); - for ( band = start_band; band < nbands; band++ ) - { - dbgwrite( &q_direction->band_data[band].azimuth[block_qmetadata], sizeof( float ), 1, 1, "./res/dirac_dec_azi.dat" ); - dbgwrite( &q_direction->band_data[band].elevation[block_qmetadata], sizeof( float ), 1, 1, "./res/dirac_dec_ele.dat" ); - } - } - } + if ( ivas_total_brate > IVAS_SID_5k2 && q_direction->coherence_band_data != NULL ) + { + hDirAC->surroundingCoherence[tmp_write_idx_band][b] = hQMetaData->surcoh_band_data[qBand_idx].surround_coherence[0] / 255.0f; + } + else + { + hDirAC->surroundingCoherence[tmp_write_idx_band][b] = 0.0f; + } + + hDirAC->energy_ratio1[tmp_write_idx_band][b] = q_direction->band_data[qBand_idx].energy_ratio[0]; + + if ( hDirAC->hConfig->dec_param_estim == FALSE ) + { + + hDirAC->diffuseness_vector[tmp_write_idx_band][b] = diffuseness; + +#ifdef HODIRAC + if ( hodirac ) + { + if ( idx_sec == 0 ) + { + hDirAC->elevation[tmp_write_idx_band][b] = ele; + hDirAC->azimuth[tmp_write_idx_band][b] = azi; + hDirAC->energy_ratio1[tmp_write_idx_band][b] = 0.f; // not in use + } + else + { + assert( idx_sec == 1 ); + hDirAC->elevation2[tmp_write_idx_band][b] = ele; + hDirAC->azimuth2[tmp_write_idx_band][b] = azi; + hDirAC->energy_ratio2[tmp_write_idx_band][b] = 1.f - diffuseness_sec; + } + } + else #endif + { + hDirAC->elevation[tmp_write_idx_band][b] = ele; + hDirAC->azimuth[tmp_write_idx_band][b] = azi; + } + } + else + { + for ( ts = ts_start; ts < ts_end; ts++ ) + { + hDirAC->elevation[tmp_write_idx_band][b] = ele; + hDirAC->azimuth[tmp_write_idx_band][b] = azi; + hDirAC->diffuseness_vector[tmp_write_idx_band][b] = diffuseness; + tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hDirAC->dirac_md_buffer_length; + } + } + } + + tmp_write_idx_param_band = ( tmp_write_idx_param_band + num_slots_in_subfr ) % hDirAC->dirac_md_buffer_length; + + } /* for ( block =...) */ + } /* for ( band = ...) */ + } /* for ( idx_sec = ...)*/ /* Bands not transmitted -> zeroed*/ for ( b = band_grouping[band]; b < hDirAC->num_freq_bands; b++ ) @@ -2138,6 +2416,38 @@ void ivas_qmetadata_to_dirac( } } +#ifdef HODIRAC_WRITE_PARAMS + if ( hMasa == NULL && sba_analysis_order > 1 && ivas_total_brate > IVAS_256k ) + { + static FILE *f_params = 0; + int16_t tmp_write_idx_band = 0; + + if ( f_params == 0 ) + f_params = fopen( "param_dec", "w" ); + + tmp_write_idx_band = hDirAC->dirac_bs_md_write_idx; + for ( block = 0; block < hDirAC->nb_subframes; block++ ) + { + int16_t block_qmetadata; + + block_qmetadata = min( block, nblocks - 1 ); + block_qmetadata = max( block_qmetadata, 0 ); + + for ( band = 0; band < hDirAC->num_freq_bands; band++ ) + { + fprintf( f_params, "%d ", hDirAC->azimuth[tmp_write_idx_band][band] ); + fprintf( f_params, "%d ", hDirAC->elevation[tmp_write_idx_band][band] ); + fprintf( f_params, "%f ", hDirAC->diffuseness_vector[tmp_write_idx_band][band] ); + + fprintf( f_params, "%d ", hDirAC->azimuth2[tmp_write_idx_band][band] ); + fprintf( f_params, "%d ", hDirAC->elevation2[tmp_write_idx_band][band] ); + fprintf( f_params, "%f\n", 1.0f - hDirAC->energy_ratio2[tmp_write_idx_band][band] ); + } + tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hDirAC->dirac_md_buffer_length; + } + } +#endif + /* update buffer write index */ if ( hDirAC->hConfig->dec_param_estim == FALSE ) { @@ -2329,7 +2639,12 @@ void ivas_dirac_dec( st_ivas->hMasa, surCohRatio, st_ivas->hHeadTrackData->shd_rot_max_order, - p_Rmat ); + p_Rmat +#ifdef HODIRAC + , + st_ivas->sba_analysis_order > 1 && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k +#endif + ); } else { @@ -2338,7 +2653,12 @@ void ivas_dirac_dec( st_ivas->hMasa, surCohRatio, 0, - 0 ); + 0 +#ifdef HODIRAC + , + st_ivas->sba_analysis_order > 1 && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k +#endif + ); } } @@ -2359,11 +2679,19 @@ void ivas_dirac_dec( /* CLDFB Analysis*/ for ( ch = 0; ch < nchan_transport; ch++ ) { +#ifdef SPAR_TUNING + cldfbAnalysis_ts( &( output_f[hDirAC->sba_map_tc[ch]][hDirAC->num_freq_bands * index_slot] ), + Cldfb_RealBuffer[ch][0], + Cldfb_ImagBuffer[ch][0], + hDirAC->num_freq_bands, + st_ivas->cldfbAnaDec[ch] ); +#else cldfbAnalysis_ts( &( output_f[sba_map_tc[ch]][hDirAC->num_freq_bands * index_slot] ), Cldfb_RealBuffer[ch][0], Cldfb_ImagBuffer[ch][0], hDirAC->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); +#endif } } @@ -2431,6 +2759,9 @@ void ivas_dirac_dec( { switch ( nchan_transport ) { +#ifdef HODIRAC + case 11: +#endif case 8: case 6: case 4: @@ -2442,7 +2773,12 @@ void ivas_dirac_dec( slot_idx, hDirAC->num_outputs_diff, hDirAC->num_freq_bands, hDirAC->hoa_decoder, - nchan_transport ); + nchan_transport +#ifdef SPAR_TUNING + , + hDirAC->sba_map_tc +#endif + ); break; case 2: protoSignalComputation2( Cldfb_RealBuffer, Cldfb_ImagBuffer, @@ -2633,7 +2969,16 @@ void ivas_dirac_dec( p_Rmat, st_ivas->hVBAPdata, hDirAC->hOutSetup, - nchan_transport ); + nchan_transport, +#ifndef HODIRAC + index_slot +#endif +#ifdef HODIRAC + st_ivas->sba_analysis_order > 1 && + st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k +#endif + + ); } else { @@ -2643,7 +2988,15 @@ void ivas_dirac_dec( 0, st_ivas->hVBAPdata, hDirAC->hOutSetup, - nchan_transport ); + nchan_transport, +#ifndef HODIRAC + index_slot +#endif +#ifdef HODIRAC + st_ivas->sba_analysis_order > 1 && + st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k +#endif + ); } if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) @@ -2668,7 +3021,12 @@ void ivas_dirac_dec( Cldfb_ImagBuffer, hDirAC, nchan_transport, - p_onset_filter ); + p_onset_filter +#ifdef HODIRAC + , + st_ivas->sba_analysis_order > 1 && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k +#endif + ); } else { @@ -3544,7 +3902,12 @@ static void protoSignalComputation4( const int16_t num_outputs_diff, const int16_t num_freq_bands, const float *mtx_hoa_decoder, - const int16_t nchan_transport ) + const int16_t nchan_transport +#ifdef SPAR_TUNING + , + const int16_t *sba_map_tc_ind +#endif +) { int16_t k, l; int16_t n; @@ -3570,8 +3933,13 @@ static void protoSignalComputation4( proto_frame_f[2 * l * num_freq_bands + 2 * k + 1] = 0.f; for ( n = 0; n < nchan_transport; n++ ) { +#ifdef SPAR_TUNING + proto_frame_f[2 * l * num_freq_bands + 2 * k] += RealBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc_ind[n]]; + proto_frame_f[2 * l * num_freq_bands + 2 * k + 1] += ImagBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc_ind[n]]; +#else proto_frame_f[2 * l * num_freq_bands + 2 * k] += RealBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc[n]]; proto_frame_f[2 * l * num_freq_bands + 2 * k + 1] += ImagBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc[n]]; +#endif } } } diff --git a/lib_dec/ivas_dirac_output_synthesis_dec.c b/lib_dec/ivas_dirac_output_synthesis_dec.c old mode 100644 new mode 100755 index 362b63c04b3bba68812fa8b1209dd0f7672d774d..fc76524abb1397b21d641051892c8c44aa2104d5 --- a/lib_dec/ivas_dirac_output_synthesis_dec.c +++ b/lib_dec/ivas_dirac_output_synthesis_dec.c @@ -91,9 +91,16 @@ ivas_error ivas_dirac_dec_output_synthesis_open( RENDERER_TYPE renderer_type, /* i : renderer type */ const int16_t nchan_transport, /* i : number of transport channels*/ const int32_t output_Fs /* i : output sampling rate */ +#ifdef HODIRAC + , + const int16_t hodirac /* i : flag to indicate HO-DirAC mode*/ +#endif ) { int16_t idx, ch_idx; +#ifdef HODIRAC + int16_t size; +#endif float tmp; uint16_t num_diffuse_responses; float temp_alpha_synthesis[CLDFB_NO_CHANNELS_MAX]; @@ -167,10 +174,25 @@ ivas_error ivas_dirac_dec_output_synthesis_open( } /* target PSD buffers */ +#ifdef HODIRAC + if ( hodirac ) + { + size = hDirAC->num_freq_bands * hDirAC->num_outputs_dir * DIRAC_HO_NUMSECTORS; + } + else + { + size = hDirAC->num_freq_bands * hDirAC->num_outputs_dir; + } + if ( ( dirac_output_synthesis_state->cy_cross_dir_smooth_prev = (float *) malloc( size * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) ); + } +#else if ( ( dirac_output_synthesis_state->cy_cross_dir_smooth_prev = (float *) malloc( hDirAC->num_freq_bands * hDirAC->num_outputs_dir * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) ); } +#endif if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { @@ -204,10 +226,17 @@ ivas_error ivas_dirac_dec_output_synthesis_open( } /* direct and diffuse gain buffers */ +#ifdef HODIRAC + if ( ( dirac_output_synthesis_state->gains_dir_prev = (float *) malloc( size * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) ); + } +#else if ( ( dirac_output_synthesis_state->gains_dir_prev = (float *) malloc( hDirAC->num_freq_bands * hDirAC->num_outputs_dir * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) ); } +#endif if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { @@ -346,8 +375,16 @@ ivas_error ivas_dirac_dec_output_synthesis_open( void ivas_dirac_dec_output_synthesis_init( DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ const int16_t nchan_out_woLFE /* i : number of output audio channels without LFE */ +#ifdef HODIRAC + , + const int16_t hodirac /* flag to indicate HO-DirAC mode */ +#endif ) { +#ifdef HODIRAC + int16_t size; +#endif + DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params; DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state; @@ -364,7 +401,19 @@ void ivas_dirac_dec_output_synthesis_init( set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev, hDirAC->num_freq_bands * hDirAC->num_outputs_dir ); } +#ifdef HODIRAC + if ( hodirac ) + { + size = hDirAC->num_freq_bands * hDirAC->num_outputs_dir * DIRAC_HO_NUMSECTORS; + } + else + { + size = hDirAC->num_freq_bands * hDirAC->num_outputs_dir; + } + set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev, size ); +#else set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev, hDirAC->num_freq_bands * hDirAC->num_outputs_dir ); +#endif if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, h_dirac_output_synthesis_params->max_band_decorr * hDirAC->num_outputs_diff ); @@ -382,8 +431,11 @@ void ivas_dirac_dec_output_synthesis_init( { set_zero( h_dirac_output_synthesis_state->proto_power_smooth_prev, hDirAC->num_freq_bands * hDirAC->num_protos_dir ); } - +#ifdef HODIRAC + set_zero( h_dirac_output_synthesis_state->gains_dir_prev, size ); +#else set_zero( h_dirac_output_synthesis_state->gains_dir_prev, hDirAC->num_freq_bands * hDirAC->num_outputs_dir ); +#endif if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { @@ -517,7 +569,13 @@ void ivas_dirac_dec_output_synthesis_process_slot( const float *p_Rmat, /* i : rotation matrix */ const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ - const int16_t nchan_transport /* i : number of transport channels*/ + const int16_t nchan_transport, /* i : number of transport channels*/ +#ifndef HODIRAC + const int16_t index_slot +#endif +#ifdef HODIRAC + const int16_t hodirac +#endif ) { int16_t num_freq_bands, num_channels_dir; @@ -550,7 +608,51 @@ void ivas_dirac_dec_output_synthesis_process_slot( num_channels_dir = hOutSetup.nchan_out_woLFE; } - if ( hDirAC->hConfig->dec_param_estim == TRUE ) +#ifdef HODIRAC + if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD && hodirac ) + { + ivas_dirac_dec_compute_directional_responses( hDirAC, + hVBAPdata, + NULL, + NULL, + 2, + p_Rmat, + hodirac ); + } + if ( hDirAC->hConfig->dec_param_estim == FALSE && hodirac ) + { + if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + { + v_multc( hDirAC->energy_ratio1[hDirAC->dirac_read_idx], -1.f, aux_buf, num_freq_bands ); + v_addc( aux_buf, 1.f, aux_buf, num_freq_bands ); + mvr2r( hDirAC->energy_ratio1[hDirAC->dirac_read_idx], + h_dirac_output_synthesis_state->direct_power_factor, + num_freq_bands ); + mvr2r( aux_buf, + h_dirac_output_synthesis_state->diffuse_power_factor, + num_freq_bands ); + + v_multc( hDirAC->energy_ratio2[hDirAC->dirac_read_idx], -1.f, aux_buf, num_freq_bands ); + v_addc( aux_buf, 1.f, aux_buf, num_freq_bands ); + mvr2r( hDirAC->energy_ratio2[hDirAC->dirac_read_idx], + &h_dirac_output_synthesis_state->direct_power_factor[hDirAC->num_freq_bands], + num_freq_bands ); + mvr2r( aux_buf, + &h_dirac_output_synthesis_state->diffuse_power_factor[hDirAC->num_freq_bands], + num_freq_bands ); + } + else + { + ivas_dirac_dec_compute_gain_factors( num_freq_bands, + hDirAC->diffuseness_vector[hDirAC->dirac_read_idx], + h_dirac_output_synthesis_params->max_band_decorr, + h_dirac_output_synthesis_state->direct_power_factor, + h_dirac_output_synthesis_state->diffuse_power_factor ); + } + } + else // ( hDirAC->hConfig->dec_param_estim == TRUE ) +#endif + if ( hDirAC->hConfig->dec_param_estim == TRUE ) { /* compute direct responses */ ivas_dirac_dec_compute_directional_responses( hDirAC, @@ -558,7 +660,12 @@ void ivas_dirac_dec_output_synthesis_process_slot( NULL, NULL, 2, - p_Rmat ); + p_Rmat +#ifdef HODIRAC + , + 0 +#endif + ); if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { @@ -695,7 +802,12 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ const int16_t nchan_transport, /* i : number of transport channels */ - const float *onset_filter ) + const float *onset_filter +#ifdef HODIRAC + , + const int16_t hodirac /* i: flag for sector-based processing */ +#endif +) { int16_t buf_idx, ch_idx, i, l; int16_t num_freq_bands, num_freq_bands_diff; @@ -715,6 +827,12 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( int16_t nchan_transport_foa; int16_t ch_idx_diff; +#ifdef HODIRAC + float aux_buf[CLDFB_NO_CHANNELS_MAX]; + float ratio[DIRAC_HO_NUMSECTORS * CLDFB_NO_CHANNELS_MAX]; + const float *diffuseness; +#endif + /* collect some often used parameters */ h_dirac_output_synthesis_params = hDirAC->h_output_synthesis_psd_params; h_dirac_output_synthesis_state = hDirAC->h_output_synthesis_psd_state; @@ -727,11 +845,71 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( num_channels_diff = hDirAC->num_outputs_diff; nchan_transport_foa = min( 4, nchan_transport ); +#ifdef HODIRAC + diffuseness = hDirAC->diffuseness_vector[hDirAC->dirac_read_idx]; +#endif + /*-----------------------------------------------------------------* * comput target Gains *-----------------------------------------------------------------*/ - if ( hDirAC->hConfig->dec_param_estim == FALSE ) +#ifdef HODIRAC + if ( hodirac ) + { + assert( hDirAC->hConfig->dec_param_estim == FALSE ); + /*Direct gain*/ + for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ ) + { + v_multc( diffuseness, + 1.f, + &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands], + num_freq_bands ); + v_multc( &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands], + h_dirac_output_synthesis_params.diffuse_compensation_factor - 1.f, + &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands], + num_freq_bands ); + + for ( l = 0; l < num_freq_bands; l++ ) + { + h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + l] = sqrtf( 1.f + h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + l] ); + } + } + + /*Directional gain*/ + for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ ) + { + for ( l = 0; l < num_freq_bands; l++ ) + { + aux_buf[l] = 1.f - diffuseness[l]; + ratio[l] = 1.f - h_dirac_output_synthesis_state.direct_power_factor[hDirAC->num_freq_bands + l]; + ratio[l + num_freq_bands] = 1.f - ratio[l]; + } + + v_mult( aux_buf, ratio, ratio, num_freq_bands ); + v_mult( aux_buf, &ratio[num_freq_bands], &ratio[num_freq_bands], num_freq_bands ); + + v_mult( ratio, + &h_dirac_output_synthesis_state.direct_responses[ch_idx * num_freq_bands], + &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands], + num_freq_bands ); + v_mult( &ratio[num_freq_bands], + &h_dirac_output_synthesis_state.direct_responses[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir], + &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir], + num_freq_bands ); + } + + /*Diffuse gain*/ + for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ ) + { + v_multc( h_dirac_output_synthesis_state.diffuse_power_factor, + hDirAC->diffuse_response_function[ch_idx], + &h_dirac_output_synthesis_state.cy_auto_diff_smooth[ch_idx * num_freq_bands_diff], + num_freq_bands_diff ); + } + } + else +#endif + if ( hDirAC->hConfig->dec_param_estim == FALSE ) { /*Direct gain*/ for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ ) @@ -777,17 +955,37 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth; p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev; - /*Direct gains*/ - for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ ) +/*Direct gains*/ +#ifdef HODIRAC + if ( hodirac ) { - for ( l = 0; l < num_freq_bands; l++ ) + for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ ) { - g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f ); - g2 = ( 1.f - g1 ) * *( p_gains_dir ); - g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) ); - g2 = max( g2, 0.85f ); - g2 = min( g2, 1.15f ); - *( p_gains_dir++ ) = g2; + for ( l = 0; l < num_freq_bands; l++ ) + { + g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f ); + g2 = ( 1.f - g1 ) * *( p_gains_dir ); + g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) ); + g2 = max( g2, 0.99f ); + g2 = min( g2, 2.0f ); + *( p_gains_dir++ ) = g2; + } + } + } + else +#endif + { + for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ ) + { + for ( l = 0; l < num_freq_bands; l++ ) + { + g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f ); + g2 = ( 1.f - g1 ) * *( p_gains_dir ); + g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) ); + g2 = max( g2, 0.85f ); + g2 = min( g2, 1.15f ); + *( p_gains_dir++ ) = g2; + } } } @@ -804,6 +1002,39 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( *( p_gains_dir++ ) = g2; } } +#ifdef HODIRAC + if ( hodirac ) + { + // wkr: additional gains for second sector, hard coded to two sectors + p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth + num_freq_bands * num_channels_dir; + p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev + num_freq_bands * num_channels_dir; + + /*Direct gains*/ + for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ ) + { + for ( l = 0; l < num_freq_bands; l++ ) + { + p_cy_cross_dir_smooth++; + p_gains_dir++; + } + } + + /*Directional gains*/ + for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ ) + { + for ( l = 0; l < num_freq_bands; l++ ) + { + g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f ); + g2 = ( 1.f - g1 ) * *( p_gains_dir ); + g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) ); + g2 = max( g2, -DIRAC_GAIN_LIMIT ); + g2 = min( g2, DIRAC_GAIN_LIMIT ); + *( p_gains_dir++ ) = g2; + } + } + } +#endif + /*Diffuse gains*/ p_cy_auto_diff_smooth = h_dirac_output_synthesis_state.cy_auto_diff_smooth + nchan_transport_foa * num_freq_bands_diff; @@ -847,26 +1078,76 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( /*Directional stream*/ for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ ) { - p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f + - buf_idx * 2 * num_freq_bands * num_protos_dir + - proto_direct_index[ch_idx] * 2 * num_freq_bands; - if ( proto_direct_index[ch_idx] == 0 ) +#ifdef HODIRAC + if ( hodirac ) { - for ( l = 0; l < num_freq_bands; l++ ) + if ( proto_direct_index[ch_idx] == 0 ) { - g = g1 * ( *( p_gains_dir++ ) ) + g2 * ( *( p_gains_dir_prev++ ) ); - output_real[l * num_channels_dir + ch_idx] = g * ( *( p_proto++ ) ); - output_imag[l * num_channels_dir + ch_idx] = g * ( *( p_proto++ ) ); + float *p_proto2; + float gs1, gs2; + p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f + + buf_idx * 2 * num_freq_bands * num_protos_dir + + proto_direct_index[0] * 2 * num_freq_bands; + p_proto2 = h_dirac_output_synthesis_state.proto_direct_buffer_f + + buf_idx * 2 * num_freq_bands * num_protos_dir + + proto_direct_index[1] * 2 * num_freq_bands; + for ( l = 0; l < num_freq_bands; l++ ) + { + gs1 = g1 * ( *( p_gains_dir ) ) + g2 * ( *( p_gains_dir_prev ) ); + gs2 = g1 * ( *( p_gains_dir + num_freq_bands * num_channels_dir ) ) + g2 * ( *( p_gains_dir_prev + num_freq_bands * num_channels_dir ) ); + p_gains_dir++; + p_gains_dir_prev++; + + output_real[l * num_channels_dir + ch_idx] = 0.5f * gs1 * ( 1.772454e+00f * ( *p_proto ) + 1.023327e+00f * ( *p_proto2 ) ) + // s1 + 0.5f * gs2 * ( 1.772454e+00f * ( *p_proto ) - 1.023327e+00f * ( *p_proto2 ) ); // s2 + p_proto++; + p_proto2++; + output_imag[l * num_channels_dir + ch_idx] = 0.5f * gs1 * ( 1.772454e+00f * ( *p_proto ) + 1.023327e+00f * ( *p_proto2 ) ) + + 0.5f * gs2 * ( 1.772454e+00f * ( *p_proto ) - 1.023327e+00f * ( *p_proto2 ) ); + p_proto++; + p_proto2++; + } + } + else + { + p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f + + buf_idx * 2 * num_freq_bands * num_protos_dir + + proto_direct_index[ch_idx] * 2 * num_freq_bands; + for ( l = 0; l < num_freq_bands; l++ ) + { + p_gains_dir++; + p_gains_dir_prev++; + + + output_real[l * num_channels_dir + ch_idx] = *( p_proto++ ); + output_imag[l * num_channels_dir + ch_idx] = *( p_proto++ ); + } } } else +#endif { - for ( l = 0; l < num_freq_bands; l++ ) + p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f + + buf_idx * 2 * num_freq_bands * num_protos_dir + + proto_direct_index[ch_idx] * 2 * num_freq_bands; + if ( proto_direct_index[ch_idx] == 0 ) { - p_gains_dir++; - p_gains_dir_prev++; - output_real[l * num_channels_dir + ch_idx] = *( p_proto++ ); - output_imag[l * num_channels_dir + ch_idx] = *( p_proto++ ); + for ( l = 0; l < num_freq_bands; l++ ) + { + g = g1 * ( *( p_gains_dir++ ) ) + g2 * ( *( p_gains_dir_prev++ ) ); + output_real[l * num_channels_dir + ch_idx] = g * ( *( p_proto++ ) ); + output_imag[l * num_channels_dir + ch_idx] = g * ( *( p_proto++ ) ); + } + } + else + { + for ( l = 0; l < num_freq_bands; l++ ) + { + p_gains_dir++; + p_gains_dir_prev++; + output_real[l * num_channels_dir + ch_idx] = *( p_proto++ ); + output_imag[l * num_channels_dir + ch_idx] = *( p_proto++ ); + } } } } @@ -884,8 +1165,13 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( for ( l = 0; l < num_freq_bands_diff; l++ ) { g = g1 * ( *( p_gains_diff++ ) ) + g2 * ( *( p_gains_diff_prev++ ) ); +#ifdef SPAR_TUNING + output_real[l * num_channels_dir + hDirAC->sba_map_tc[ch_idx]] += g * ( *( p_proto++ ) ); /* maps ch_idx 5 to 8 */ + output_imag[l * num_channels_dir + hDirAC->sba_map_tc[ch_idx]] += g * ( *( p_proto++ ) ); +#else output_real[l * num_channels_dir + sba_map_tc[ch_idx]] += g * ( *( p_proto++ ) ); /* maps ch_idx 5 to 8 */ output_imag[l * num_channels_dir + sba_map_tc[ch_idx]] += g * ( *( p_proto++ ) ); +#endif } } else @@ -944,16 +1230,37 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( } } - /*-----------------------------------------------------------------* - * update buffers - *-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------* + * update buffers + *-----------------------------------------------------------------*/ + +/* store estimates for next synthesis block */ +#ifdef HODIRAC + if ( hodirac ) + { + mvr2r( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev, h_dirac_output_synthesis_state.gains_dir_prev, num_freq_bands * num_channels_dir * DIRAC_HO_NUMSECTORS ); + } + else +#endif + { + mvr2r( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev, h_dirac_output_synthesis_state.gains_dir_prev, num_freq_bands * num_channels_dir ); + } - /* store estimates for next synthesis block */ - mvr2r( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev, h_dirac_output_synthesis_state.gains_dir_prev, num_freq_bands * num_channels_dir ); mvr2r( h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev, h_dirac_output_synthesis_state.gains_diff_prev, num_freq_bands_diff * num_channels_diff ); - /* reset values */ - set_zero( h_dirac_output_synthesis_state.cy_cross_dir_smooth, num_freq_bands * num_channels_dir ); +/* reset values */ +#ifdef HODIRAC + if ( hodirac ) + { + set_zero( h_dirac_output_synthesis_state.cy_cross_dir_smooth, num_freq_bands * num_channels_dir * DIRAC_HO_NUMSECTORS ); + } + else +#endif + { + set_zero( h_dirac_output_synthesis_state.cy_cross_dir_smooth, num_freq_bands * num_channels_dir ); + } + + set_zero( h_dirac_output_synthesis_state.cy_auto_diff_smooth, num_freq_bands_diff * num_channels_diff ); return; @@ -1486,6 +1793,10 @@ void ivas_dirac_dec_compute_directional_responses( const float *surCohRatio, const int16_t shd_rot_max_order, /* i : split-order rotation method */ const float *p_Rmat /* i : rotation matrix */ +#ifdef HODIRAC + , + const int16_t hodirac /* i : flag for sector based dirac processing */ +#endif ) { int16_t k, l; @@ -1554,6 +1865,35 @@ void ivas_dirac_dec_compute_directional_responses( /* HOA3 PANNING */ if ( hDirAC->panningConf == DIRAC_PANNING_HOA3 ) { +#ifdef HODIRAC + set_f( direct_response_hoa, 1.0f, MAX_OUTPUT_CHANNELS ); + set_f( direct_response_dir2, 1.0f, MAX_OUTPUT_CHANNELS ); + if ( p_Rmat != 0 ) + { + ivas_dirac_dec_get_response_split_order( azimuth[k], elevation[k], direct_response_hoa, shd_rot_max_order, p_Rmat ); + if ( hodirac ) + { + ivas_dirac_dec_get_response_split_order( azimuth2[k], elevation2[k], direct_response_dir2, shd_rot_max_order, p_Rmat ); + } + } + else + { + ivas_dirac_dec_get_response( azimuth[k], elevation[k], direct_response_hoa, hDirAC->hOutSetup.ambisonics_order ); + if ( hodirac ) + { + ivas_dirac_dec_get_response( azimuth2[k], elevation2[k], direct_response_dir2, hDirAC->hOutSetup.ambisonics_order ); + } + } + + if ( hMasa == NULL && hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + { + mvr2r_inc( direct_response_hoa, 1, &hDirAC->h_output_synthesis_psd_state.direct_responses[k], hDirAC->num_freq_bands, num_channels_dir ); + if ( hodirac ) + { + mvr2r_inc( direct_response_dir2, 1, &hDirAC->h_output_synthesis_psd_state.direct_responses[k + hDirAC->num_freq_bands * num_channels_dir], hDirAC->num_freq_bands, num_channels_dir ); + } + } +#else set_f( direct_response_hoa, 1.0f, MAX_OUTPUT_CHANNELS ); if ( p_Rmat != 0 ) { @@ -1568,6 +1908,7 @@ void ivas_dirac_dec_compute_directional_responses( { mvr2r_inc( direct_response_hoa, 1, &hDirAC->h_output_synthesis_psd_state.direct_responses[k], hDirAC->num_freq_bands, num_channels_dir ); } +#endif else if ( ( ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) && ( hMasa != NULL ) ) || hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD || hDirAC->synthesisConf == DIRAC_SYNTHESIS_MONO ) { diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index a58220a9b7247078ac39cdba10924f39e77646df..b317d81cd169c7c18b46720e3a202cc307ef6b24 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -917,7 +917,21 @@ ivas_error ivas_init_decoder( } } - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_dirac_sba_config( + st_ivas->hQMetaData, + &st_ivas->nchan_transport, + &st_ivas->nSCE, + &st_ivas->nCPE, + &st_ivas->element_mode_init, + ivas_total_brate, + st_ivas->sba_analysis_order, + st_ivas->sba_mode, +#ifdef HODIRAC + st_ivas->sba_analysis_order > 1 && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) +#else + IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -940,6 +954,15 @@ ivas_error ivas_init_decoder( int16_t band_grouping[IVAS_MAX_NUM_BANDS + 1]; st_ivas->hSpar->enc_param_start_band = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); +#ifdef HODIRAC + if ( st_ivas->sba_analysis_order > 1 && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k ) + { + st_ivas->hSpar->enc_param_start_band = 0; + + set_c( (int8_t *) st_ivas->hQMetaData->twoDirBands, (int8_t) 1, st_ivas->hQMetaData->q_direction[0].cfg.nbands ); + st_ivas->hQMetaData->numTwoDirBands = (uint8_t) st_ivas->hQMetaData->q_direction[0].cfg.nbands; + } +#endif ivas_dirac_config_bands( band_grouping, IVAS_MAX_NUM_BANDS, (int16_t) ( st_ivas->hDecoderConfig->output_Fs * INV_CLDFB_BANDWIDTH + 0.5f ), st_ivas->hSpar->dirac_to_spar_md_bands, st_ivas->hQMetaData->useLowerBandRes, st_ivas->hSpar->enc_param_start_band, 0 ); diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index eead75925747f4c74be20decceb7fe52c3047f9e..2dde4a2bdc67e4794b56b99e77cd90fa8555bfec 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -206,9 +206,13 @@ ivas_error ivas_masa_decode( } else { - #endif - *nb_bits_read += ivas_qmetadata_dec_decode( hQMetaData, st->bit_stream, &st->next_bit_pos ); + *nb_bits_read += ivas_qmetadata_dec_decode( hQMetaData, st->bit_stream, &st->next_bit_pos +#ifdef HODIRAC + , + 0 +#endif + ); #ifdef HR_METADATA } #endif @@ -293,7 +297,14 @@ ivas_error ivas_masa_decode( } if ( st_ivas->hDirAC != NULL ) { - ivas_qmetadata_to_dirac( hQMetaData, st_ivas->hDirAC, hMasa, ivas_total_brate, SBA_MODE_NONE, 0 ); + ivas_qmetadata_to_dirac( hQMetaData, st_ivas->hDirAC, hMasa, ivas_total_brate, + SBA_MODE_NONE +#ifdef HODIRAC + , + 0 +#endif + , + 0 ); } st->next_bit_pos = next_bit_pos_orig; diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index ff73e6aa49d76ad1ebc592efb99a47e3b0afaf15..42e7c8506825c37c0fff7239790a3562fb68bf30 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config.c @@ -152,7 +152,12 @@ void ivas_renderer_select( if ( st_ivas->hDecoderConfig->Opt_Headrotation ) { - nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); + nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order +#ifdef SPAR_TUNING + , + st_ivas->hDecoderConfig->ivas_total_brate +#endif + ); if ( nchan_internal == 2 ) { st_ivas->hHeadTrackData->shd_rot_max_order = 1; diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index 47eb7917c0d17ea7ea1dd4333310a4a23ab8ddf7..3774c06799e017a6eec0b32e61abefbe6717bdbd 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -165,6 +165,10 @@ int16_t ivas_qmetadata_dec_decode( IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: hQMetaData handle */ uint16_t *bitstream, /* i : bitstream */ int16_t *index /* i/o: bitstream position */ +#ifdef HODIRAC + , + int16_t hodirac /* i: flag to indicate sector processing */ +#endif ) { int16_t d, b, m; @@ -254,20 +258,43 @@ int16_t ivas_qmetadata_dec_decode( bits_diff_sum += ivas_qmetadata_entropy_decode_diffuseness( bitstream, index, &( hQMetaData->q_direction[0] ), &diffuseness_index_max_ec_frame_pre[0] ); - if ( hQMetaData->no_directions == 2 ) +#ifdef HODIRAC + if ( hodirac ) { - /* Calculate bits for dfRatio */ - dir2band = 0; - for ( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) + if ( hQMetaData->no_directions == 2 ) { - if ( hQMetaData->twoDirBands[b] == 1 ) + /* Calculate bits for dfRatio */ + dir2band = 0; + for ( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) { - dfRatio_bits[dir2band] = ivas_get_df_ratio_bits( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] ); - dir2band++; + if ( hQMetaData->twoDirBands[b] == 1 ) + { + dfRatio_bits[dir2band] = ivas_get_df_ratio_bits_hodirac( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] ); + dir2band++; + } } + + bits_diff_sum += ivas_qmetadata_entropy_decode_df_ratio( bitstream, index, &( hQMetaData->q_direction[1] ), dfRatio_bits ); } + } + else +#endif + { + if ( hQMetaData->no_directions == 2 ) + { + /* Calculate bits for dfRatio */ + dir2band = 0; + for ( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) + { + if ( hQMetaData->twoDirBands[b] == 1 ) + { + dfRatio_bits[dir2band] = ivas_get_df_ratio_bits( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] ); + dir2band++; + } + } - bits_diff_sum += ivas_qmetadata_entropy_decode_df_ratio( bitstream, index, &( hQMetaData->q_direction[1] ), dfRatio_bits ); + bits_diff_sum += ivas_qmetadata_entropy_decode_df_ratio( bitstream, index, &( hQMetaData->q_direction[1] ), dfRatio_bits ); + } } /* Calculate direct-to-total energy ratios for both directions from diffuse-to-total ratio and distribution factor of direct-to-total ratios */ @@ -283,14 +310,37 @@ int16_t ivas_qmetadata_dec_decode( diffRatio = diffuseness_reconstructions[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]]; dfRatio_qsteps = 1 << dfRatio_bits[dir2band]; - dfRatio = usdequant( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], 0.5f, 0.5f / ( dfRatio_qsteps - 1 ) ); +#ifdef HODIRAC + /* already encoded as total and ratios in HODIRAC*/ + if ( hodirac ) + { + dfRatio = usdequant( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], 0.0f, 1.f / ( dfRatio_qsteps - 1 ) ); + dir1ratio = 1.f - diffRatio; + dir2ratio = dfRatio; + } + else +#endif + { + dfRatio = usdequant( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], 0.5f, 0.5f / ( dfRatio_qsteps - 1 ) ); + + dir1ratio = dfRatio * ( 1.0f - diffRatio ); + dir2ratio = ( 1.0f - diffRatio ) - dir1ratio; + } - dir1ratio = dfRatio * ( 1.0f - diffRatio ); - dir2ratio = ( 1.0f - diffRatio ) - dir1ratio; /* Requantize the 1 - dirRatio separately for each direction to obtain inverted dirRatio index. These are used in further decoding. */ hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] = masa_sq( 1.0f - dir1ratio, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); - hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0] = masa_sq( 1.0f - dir2ratio, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); +#ifdef HODIRAC + if ( hodirac ) + { + float tmp; + hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0] = usquant( dir2ratio, &tmp, 0.0f, 1.f / ( DIRAC_DIFFUSE_LEVELS - 1 ), DIRAC_DIFFUSE_LEVELS ); + } + else +#endif + { + hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0] = masa_sq( 1.0f - dir2ratio, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); + } for ( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ ) { @@ -346,7 +396,12 @@ int16_t ivas_qmetadata_dec_decode( index_dirRatio1Inv = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; index_dirRatio2Inv = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0]; - masa_compensate_two_dir_energy_ratio_index( index_dirRatio1Inv, index_dirRatio2Inv, &index_dirRatio1Inv_mod, &index_dirRatio2Inv_mod ); + masa_compensate_two_dir_energy_ratio_index( index_dirRatio1Inv, index_dirRatio2Inv, &index_dirRatio1Inv_mod, &index_dirRatio2Inv_mod +#ifdef HODIRAC + , + hodirac +#endif + ); for ( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ ) { @@ -736,16 +791,21 @@ int16_t ivas_qmetadata_dec_decode( } /* Scale energy ratios that sum to over one */ - for ( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) +#ifdef HODIRAC + if ( !hodirac ) +#endif { - float ratioSum; + for ( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) + { + float ratioSum; - ratioSum = hQMetaData->q_direction[0].band_data[b].energy_ratio[0] + hQMetaData->q_direction[1].band_data[b].energy_ratio[0]; + ratioSum = hQMetaData->q_direction[0].band_data[b].energy_ratio[0] + hQMetaData->q_direction[1].band_data[b].energy_ratio[0]; - if ( ratioSum > 1.0f ) - { - set_f( hQMetaData->q_direction[0].band_data[b].energy_ratio, hQMetaData->q_direction[0].band_data[b].energy_ratio[0] / ratioSum, nblocks ); - set_f( hQMetaData->q_direction[1].band_data[b].energy_ratio, hQMetaData->q_direction[1].band_data[b].energy_ratio[0] / ratioSum, nblocks ); + if ( ratioSum > 1.0f ) + { + set_f( hQMetaData->q_direction[0].band_data[b].energy_ratio, hQMetaData->q_direction[0].band_data[b].energy_ratio[0] / ratioSum, nblocks ); + set_f( hQMetaData->q_direction[1].band_data[b].energy_ratio, hQMetaData->q_direction[1].band_data[b].energy_ratio[0] / ratioSum, nblocks ); + } } } } diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index 66a2bc56639d6ca0a27c77bbc83050c4dfabc9d1..9daef50fa1bbec8394c00c10d1fbc4b25d6deb49 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -524,10 +524,21 @@ const float ap_split_frequencies[DIRAC_DECORR_NUM_SPLIT_BANDS + 1] = 0.0f, 0.125f, 0.375f, 1.0f }; +#ifdef SPAR_TUNING +const int16_t sba_map_tc[11] = +{ + 0, 1, 2, 3, 4, 8, 9, 15, 5, 6, 7 +}; +const int16_t sba_map_tc_512[11] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15 +}; +#else const int16_t sba_map_tc[8] = { 0, 1, 2, 3, 4, 8, 9, 15 }; +#endif /*----------------------------------------------------------------------------------* diff --git a/lib_dec/ivas_rom_dec.h b/lib_dec/ivas_rom_dec.h index 95612634b03e2dd582e1c1f8bce209bb120c9732..c3e21278c062af2de64db6be8ff260090bd8029b 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -115,8 +115,12 @@ extern const float ap_lattice_coeffs_3[DIRAC_DECORR_FILTER_LEN_3 * DIRAC_MAX_NUM extern const float *const ap_lattice_coeffs[DIRAC_DECORR_NUM_SPLIT_BANDS]; extern const float ap_split_frequencies[DIRAC_DECORR_NUM_SPLIT_BANDS + 1]; +#ifdef SPAR_TUNING +extern const int16_t sba_map_tc[11]; +extern const int16_t sba_map_tc_512[11]; +#else extern const int16_t sba_map_tc[8]; - +#endif /*----------------------------------------------------------------------------------* * FASTCONV and PARAMETRIC binaural renderer ROM tables diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c old mode 100644 new mode 100755 index ec47273c64dab60414b5bbc9028af72b87581a10..0b5cce1ca5e4f6ae2b981a3d11e5877618e52137 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -109,6 +109,10 @@ ivas_error ivas_sba_dec_reconfigure( int16_t numCldfbAnalyses_old, numCldfbSyntheses_old; int16_t sba_dirac_stereo_flag_old; int32_t ivas_total_brate; +#ifdef HODIRAC + int32_t last_ivas_total_brate; +#endif + RENDERER_TYPE old_renderer_type; DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; @@ -116,6 +120,11 @@ ivas_error ivas_sba_dec_reconfigure( hDecoderConfig = st_ivas->hDecoderConfig; ivas_total_brate = hDecoderConfig->ivas_total_brate; +#ifdef HODIRAC + last_ivas_total_brate = st_ivas->last_active_ivas_total_brate; +#endif + + /*-----------------------------------------------------------------* * Set SBA high-level parameters * Save old SBA high-level parameters @@ -146,7 +155,11 @@ ivas_error ivas_sba_dec_reconfigure( hSpar->hPCA = NULL; } - if ( nchan_transport_old != ivas_get_sba_num_TCs( ivas_total_brate, sba_order_internal ) ) + if ( nchan_transport_old != ivas_get_sba_num_TCs( ivas_total_brate, sba_order_internal ) +#ifdef HODIRAC + || ( last_ivas_total_brate >= IVAS_512k && ivas_total_brate < IVAS_512k ) || ( last_ivas_total_brate < IVAS_512k && ivas_total_brate >= IVAS_512k ) +#endif + ) { ivas_spar_dec_close( &( st_ivas->hSpar ), hDecoderConfig->output_Fs, 1 ); @@ -232,7 +245,12 @@ ivas_error ivas_sba_dec_reconfigure( { ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); } - if ( ( ( st_ivas->renderer_type != RENDERER_DISABLE ) && ( st_ivas->renderer_type != RENDERER_SBA_LINEAR_DEC ) ) || ( ( hDecoderConfig->output_config != AUDIO_CONFIG_FOA ) && ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_STEREO ) && ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_MONO ) ) ) + + if ( ( ( st_ivas->renderer_type != RENDERER_DISABLE ) && ( st_ivas->renderer_type != RENDERER_SBA_LINEAR_DEC ) ) || ( ( hDecoderConfig->output_config != AUDIO_CONFIG_FOA ) && ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_STEREO ) && ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_MONO ) ) +#ifdef HODIRAC + || ( last_ivas_total_brate > IVAS_256k && ivas_total_brate <= IVAS_256k ) || ( last_ivas_total_brate <= IVAS_256k && ivas_total_brate > IVAS_256k ) +#endif + ) { DIRAC_CONFIG_FLAG flag_config; @@ -247,7 +265,22 @@ ivas_error ivas_sba_dec_reconfigure( return error; } } - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_dirac_sba_config( + st_ivas->hQMetaData, + &st_ivas->nchan_transport, + &st_ivas->nSCE, + &st_ivas->nCPE, + &st_ivas->element_mode_init, + ivas_total_brate, + st_ivas->sba_analysis_order, + st_ivas->sba_mode, +#ifdef HODIRAC + ( st_ivas->sba_analysis_order > 1 && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) +#else + IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND +#endif + + ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal.c index a80986b39e7a41caf4b8a0844ac63951e90517a0..6947efa8682f16566b894bc93f7c37db98ad38b0 100644 --- a/lib_dec/ivas_sba_rendering_internal.c +++ b/lib_dec/ivas_sba_rendering_internal.c @@ -353,7 +353,12 @@ void ivas_sba_upmixer_renderer( push_wmops( "ivas_sba_upmixer_renderer" ); - nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); + nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order +#ifdef SPAR_TUNING + , + st_ivas->hDecoderConfig->ivas_total_brate +#endif + ); if ( st_ivas->nchan_transport >= 3 ) { @@ -581,7 +586,12 @@ void ivas_sba_mix_matrix_determiner( /* Mixing matrix determiner */ num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; - ivas_spar_dec_gen_umx_mat( hSpar->hMdDec, nchan_transport, num_bands_out, bfi ); + ivas_spar_dec_gen_umx_mat( hSpar->hMdDec, nchan_transport, num_bands_out, bfi +#ifdef SPAR_TUNING + , + MAX_PARAM_SPATIAL_SUBFRAMES +#endif + ); return; } diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index f0588ae30311554f1ff41efb8ceebba678bb02b1..6f917a6f412b442c6582a1bc95145b6ec5316177 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -72,10 +72,19 @@ ivas_error ivas_spar_dec_open( IVAS_FB_CFG *fb_cfg; int16_t i, j, b, active_w_mixing; int32_t output_Fs; +#ifdef SPAR_TUNING + int16_t num_decor_chs; +#endif error = IVAS_ERR_OK; sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); - num_channels_internal = ivas_sba_get_nchan_metadata( sba_order_internal ); + num_channels_internal = ivas_sba_get_nchan_metadata( sba_order_internal +#ifdef SPAR_TUNING + , + st_ivas->hDecoderConfig->ivas_total_brate +#endif + ); + hSpar = st_ivas->hSpar; if ( !spar_reconfig_flag ) @@ -88,12 +97,30 @@ ivas_error ivas_spar_dec_open( } output_Fs = st_ivas->hDecoderConfig->output_Fs; +#ifdef SPAR_TUNING + if ( num_channels_internal > ( SBA_HOA2_ORDER + 1 ) * ( SBA_HOA2_ORDER + 1 ) ) + { + num_decor_chs = IVAS_HBR_MAX_DECOR_CHS; + } + else + { + num_decor_chs = num_channels_internal - 1; + } +#endif +#ifdef SPAR_TUNING + /* TD decorr. */ + if ( ( error = ivas_td_decorr_dec_open( &hSpar->hTdDecorr, output_Fs, num_decor_chs + 1, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } +#else /* TD decorr. */ if ( ( error = ivas_td_decorr_dec_open( &hSpar->hTdDecorr, output_Fs, num_channels_internal, 1 ) ) != IVAS_ERR_OK ) { return error; } +#endif /* MD handle */ if ( ( error = ivas_spar_md_dec_open( &hSpar->hMdDec, st_ivas->hDecoderConfig, num_channels_internal, sba_order_internal, st_ivas->sid_format ) ) != IVAS_ERR_OK ) @@ -105,7 +132,12 @@ ivas_error ivas_spar_dec_open( /* set FB config. */ active_w_mixing = -1; - if ( ( error = ivas_fb_set_cfg( &fb_cfg, SBA_FORMAT, SBA_MODE_SPAR, num_channels_internal, num_channels_internal, active_w_mixing, output_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_fb_set_cfg( &fb_cfg, SBA_FORMAT, SBA_MODE_SPAR, num_channels_internal, num_channels_internal, active_w_mixing, output_Fs +#ifdef HODIRAC + , + 0 +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -636,6 +668,9 @@ static void ivas_spar_dec_MD( { int16_t num_channels, table_idx, num_bands_out, bfi, sba_order; int32_t ivas_total_brate; +#ifdef SPAR_TUNING + int16_t num_md_sub_frames; +#endif DECODER_CONFIG_HANDLE hDecoderConfig = st_ivas->hDecoderConfig; SPAR_DEC_HANDLE hSpar = st_ivas->hSpar; @@ -648,7 +683,17 @@ static void ivas_spar_dec_MD( sba_order = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); bfi = st_ivas->bfi; ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; - num_channels = ivas_sba_get_nchan_metadata( sba_order ); + num_channels = ivas_sba_get_nchan_metadata( sba_order +#ifdef SPAR_TUNING + , + ivas_total_brate +#endif + ); + +#ifdef SPAR_TUNING + num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( sba_order, st_ivas->hDecoderConfig->ivas_total_brate ); +#endif + num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; if ( ivas_total_brate > FRAME_NO_DATA && !bfi ) @@ -707,7 +752,13 @@ static void ivas_spar_dec_MD( if ( st0->m_old_frame_type == ZERO_FRAME && ivas_total_brate == IVAS_SID_5k2 && st0->prev_bfi == 0 && hSpar->hMdDec->spar_md_cfg.nchan_transport == 1 ) { - ivas_spar_setup_md_smoothing( hSpar->hMdDec, num_bands_out ); + ivas_spar_setup_md_smoothing( hSpar->hMdDec, num_bands_out + +#ifdef SPAR_TUNING + , + num_md_sub_frames +#endif + ); } else { @@ -718,7 +769,12 @@ static void ivas_spar_dec_MD( { if ( !bfi ) { - ivas_spar_smooth_md_dtx( hSpar->hMdDec, num_bands_out ); + ivas_spar_smooth_md_dtx( hSpar->hMdDec, num_bands_out +#ifdef SPAR_TUNING + , + num_md_sub_frames +#endif + ); } set_s( hSpar->hMdDec->valid_bands, 0, IVAS_MAX_NUM_BANDS ); @@ -857,7 +913,12 @@ static void ivas_spar_get_skip_mat( const int16_t num_ch_out, const int16_t num_ch_in, const int16_t num_spar_bands, - int16_t skip_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH] ) + int16_t skip_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH] +#ifdef SPAR_TUNING + , + const int16_t num_md_sub_frames +#endif +) { int16_t spar_band, out_ch, in_ch; int16_t i_ts, skip_flag; @@ -868,6 +929,45 @@ static void ivas_spar_get_skip_mat( { skip_mat[out_ch][in_ch] = 1; skip_flag = 1; +#ifdef SPAR_TUNING + for ( i_ts = 0; i_ts < MAX_PARAM_SPATIAL_SUBFRAMES; i_ts++ ) + { + for ( spar_band = 0; spar_band < num_spar_bands; spar_band++ ) + { + if ( hSpar->hMdDec->mixer_mat_prev[1 + i_ts][out_ch][in_ch][spar_band] != 0.0f ) + { + skip_flag = 0; + break; + } + } + + if ( skip_flag == 0 ) + { + skip_mat[out_ch][in_ch] = 0; + break; + } + } + if ( skip_mat[out_ch][in_ch] == 1 ) + { + for ( i_ts = 0; i_ts < num_md_sub_frames; i_ts++ ) + { + for ( spar_band = 0; spar_band < num_spar_bands; spar_band++ ) + { + if ( hSpar->hMdDec->mixer_mat[out_ch][in_ch][spar_band + i_ts * MAX_PARAM_SPATIAL_SUBFRAMES] != 0.0f ) + { + skip_flag = 0; + break; + } + } + + if ( skip_flag == 0 ) + { + skip_mat[out_ch][in_ch] = 0; + break; + } + } + } +#else for ( i_ts = 0; i_ts < MAX_PARAM_SPATIAL_SUBFRAMES; i_ts++ ) { @@ -886,6 +986,7 @@ static void ivas_spar_get_skip_mat( break; } } +#endif } } @@ -998,6 +1099,9 @@ void ivas_spar_dec_upmixer( int16_t b_skip_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; DECODER_CONFIG_HANDLE hDecoderConfig; SPAR_DEC_HANDLE hSpar; +#ifdef SPAR_TUNING + int16_t num_md_sub_frames, md_sf_idx; +#endif push_wmops( "ivas_spar_dec_upmixer" ); @@ -1010,6 +1114,10 @@ void ivas_spar_dec_upmixer( numch_in = hSpar->hFbMixer->fb_cfg->num_in_chans; numch_out = hSpar->hFbMixer->fb_cfg->num_out_chans; +#ifdef SPAR_TUNING + num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, hDecoderConfig->ivas_total_brate ); +#endif + #ifdef DEBUG_SPAR_BYPASS_EVS_CODEC /* by-pass core-coder */ /*write the core coder output to a file for debugging*/ @@ -1099,12 +1207,33 @@ void ivas_spar_dec_upmixer( if ( hSpar->hMdDec->td_decorr_flag ) { - ivas_td_decorr_process( hSpar->hTdDecorr, output, pPcm_tmp, output_frame ); + ivas_td_decorr_process( hSpar->hTdDecorr, output, pPcm_tmp, output_frame ); +#ifdef SPAR_TUNING + if ( hSpar->hTdDecorr->num_apd_outputs >= ( nchan_internal - nchan_transport ) ) + { + for ( i = 0; i < nchan_internal - nchan_transport; i++ ) + { + mvr2r( pPcm_tmp[hSpar->hTdDecorr->num_apd_outputs - 1 - i], output[nchan_internal - 1 - i], output_frame ); + } + } + else + { + for ( i = 0; i < nchan_internal - nchan_transport; i++ ) + { + set_zero( output[nchan_internal - 1 - i], output_frame ); + } + for ( i = 0; i < hSpar->hTdDecorr->num_apd_outputs; i++ ) + { + mvr2r( pPcm_tmp[hSpar->hTdDecorr->num_apd_outputs - 1 - i], output[nchan_internal - 1 - i], output_frame ); + } + } +#else for ( i = 0; i < nchan_internal - nchan_transport; i++ ) { mvr2r( pPcm_tmp[hSpar->hTdDecorr->num_apd_outputs - 1 - i], output[nchan_internal - 1 - i], output_frame ); } +#endif } hSpar->hFbMixer->fb_cfg->num_in_chans = num_in_ingest; @@ -1143,7 +1272,12 @@ void ivas_spar_dec_upmixer( * Gen umx mat *---------------------------------------------------------------------*/ - ivas_spar_dec_gen_umx_mat( hSpar->hMdDec, nchan_transport, num_bands_out, st_ivas->bfi ); + ivas_spar_dec_gen_umx_mat( hSpar->hMdDec, nchan_transport, num_bands_out, st_ivas->bfi +#ifdef SPAR_TUNING + , + num_md_sub_frames +#endif + ); /*---------------------------------------------------------------------* @@ -1154,7 +1288,12 @@ void ivas_spar_dec_upmixer( /* apply parameters */ /* determine if we can skip certain data */ - ivas_spar_get_skip_mat( hSpar, numch_out, numch_in, num_spar_bands, b_skip_mat ); /* this can be precomputed based on bitrate and format*/ + ivas_spar_get_skip_mat( hSpar, numch_out, numch_in, num_spar_bands, b_skip_mat +#ifdef SPAR_TUNING + , + num_md_sub_frames +#endif + ); /* this can be precomputed based on bitrate and format*/ numch_out_dirac = hDecoderConfig->nchan_out; @@ -1216,6 +1355,30 @@ void ivas_spar_dec_upmixer( for ( in_ch = 0; in_ch < numch_in; in_ch++ ) { +#ifdef SPAR_TUNING + if ( b_skip_mat[out_ch][in_ch] == 0 ) + { + if ( cldfb_band < CLDFB_PAR_WEIGHT_START_BAND ) /* tuning parameter, depends on how much SPAR Filters overlap for the CLDFB bands */ + { + spar_band = bin2band->p_cldfb_map_to_spar_band[cldfb_band]; + cldfb_par = mixer_mat[out_ch][in_ch][spar_band]; + } + else + { + cldfb_par = 0.0f; + for ( spar_band = bin2band->p_spar_start_bands[cldfb_band]; spar_band < num_spar_bands; spar_band++ ) + { + /* accumulate contributions from all SPAR bands */ + cldfb_par += mixer_mat[out_ch][in_ch][spar_band] * bin2band->pp_cldfb_weights_per_spar_band[cldfb_band][spar_band]; + } + } + + out_re[out_ch] += cldfb_in_ts_re[in_ch][ts][cldfb_band] * cldfb_par; + out_im[out_ch] += cldfb_in_ts_im[in_ch][ts][cldfb_band] * cldfb_par; + } + } +#else + if ( b_skip_mat[out_ch][in_ch] ) { continue; @@ -1238,6 +1401,7 @@ void ivas_spar_dec_upmixer( out_re[out_ch] += cldfb_in_ts_re[in_ch][ts][cldfb_band] * cldfb_par; out_im[out_ch] += cldfb_in_ts_im[in_ch][ts][cldfb_band] * cldfb_par; } +#endif } /*update CLDFB data with the parameter-modified data*/ @@ -1316,6 +1480,9 @@ void ivas_spar_dec_upmixer( /* Dump audio signal after cldfbSynthesis */ ivas_spar_dump_signal_wav( output_frame, NULL, output, hSpar->numOutChannels, spar_foa_dec_wav[3], "cldfbSynthesis()" ); #endif +#ifdef SPAR_TUNING + md_sf_idx = ( num_md_sub_frames == MAX_PARAM_SPATIAL_SUBFRAMES ) ? i_sf : 0; +#endif split_band = SPAR_DIRAC_SPLIT_START_BAND; if ( split_band < IVAS_MAX_NUM_BANDS ) @@ -1333,7 +1500,11 @@ void ivas_spar_dec_upmixer( { for ( b = 0; b < num_spar_bands; b++ ) { +#ifdef SPAR_TUNING + hSpar->hMdDec->mixer_mat_prev[4][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat[out_ch][in_ch][b + md_sf_idx * IVAS_MAX_NUM_BANDS]; +#else hSpar->hMdDec->mixer_mat_prev[4][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat[out_ch][in_ch][b + i_sf * IVAS_MAX_NUM_BANDS]; +#endif } } } diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index 1552734434d0da8cd218315ed3c92fb59ddd855e..9475c2f0264fa701d256a343438dbf5aad4bdef0 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -63,7 +63,13 @@ static const int16_t ivas_spar_dec_plc_spatial_target[IVAS_SPAR_MAX_CH] = { 1, 0 * Static functions declaration *------------------------------------------------------------------------------------------*/ -static void ivas_get_spar_matrices( ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands_out, const int16_t n_ts, const int16_t bw, const int16_t dtx_vad, const int16_t nB, const int16_t sba_order, const int16_t active_w_vlbr ); +static void ivas_get_spar_matrices( ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands_out, const int16_t n_ts, const int16_t bw, const int16_t dtx_vad, const int16_t nB, +#ifdef SPAR_TUNING + const int16_t numch_out, +#else + const int16_t sba_order, +#endif + const int16_t active_w_vlbr ); static void ivas_decode_arith_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, const uint16_t qsi, const int16_t nB, const int16_t bands_bw, int16_t *pDo_diff, const int16_t freq_diff, const int16_t planarCP, const int16_t strat, const int32_t ivas_total_brate ); @@ -75,9 +81,24 @@ static void ivas_get_band_idx_from_differential( ivas_spar_md_t *pSpar_md, const static void ivas_mat_col_rearrange( float in_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], const int16_t order[IVAS_SPAR_MAX_CH], const int16_t i_ts, float ***mixer_mat, const int16_t bands, const int16_t num_ch ); -static void ivas_spar_dec_compute_ramp_down_post_matrix( ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands, const int16_t bfi ); +static void ivas_spar_dec_compute_ramp_down_post_matrix( ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands, const int16_t bfi +#ifdef SPAR_TUNING + , + const int16_t num_md_sub_frames +#endif +); -static void ivas_spar_md_fill_invalid_bands( ivas_spar_dec_matrices_t *pSpar_coeffs, ivas_spar_dec_matrices_t *pSpar_coeffs_prev, const int16_t *valid_bands, int16_t *base_band_age, const int16_t num_bands, const int16_t sba_order ); +static void ivas_spar_md_fill_invalid_bands( ivas_spar_dec_matrices_t *pSpar_coeffs, ivas_spar_dec_matrices_t *pSpar_coeffs_prev, const int16_t *valid_bands, int16_t *base_band_age, const int16_t num_bands, +#ifdef SPAR_TUNING + const int16_t numch_out +#else + const int16_t sba_order +#endif +#ifdef SPAR_TUNING + , + const int16_t num_md_sub_frames +#endif +); static ivas_error ivas_spar_set_dec_config( ivas_spar_md_dec_state_t *hMdDec, const int16_t nchan_transport, float *pFC ); @@ -97,11 +118,23 @@ static void ivas_spar_dec_parse_md_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder static ivas_error ivas_spar_md_dec_matrix_open( ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ const int16_t num_channels /* i : number of internal channels */ +#ifdef SPAR_TUNING + , + const int16_t num_md_sub_frames +#endif ) { int16_t i, j; +#ifndef SPAR_TUNING + int16_t num_md_sub_frames; + num_md_sub_frames = MAX_PARAM_SPATIAL_SUBFRAMES; +#endif +#ifdef SPAR_TUNING + if ( ( hMdDec->spar_md.band_coeffs = (ivas_band_coeffs_t *) malloc( IVAS_MAX_NUM_BANDS * num_md_sub_frames * sizeof( ivas_band_coeffs_t ) ) ) == NULL ) +#else if ( ( hMdDec->spar_md.band_coeffs = (ivas_band_coeffs_t *) malloc( IVAS_MAX_NUM_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( ivas_band_coeffs_t ) ) ) == NULL ) +#endif { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for band_coeffs in SPAR MD" ); } @@ -117,7 +150,11 @@ static ivas_error ivas_spar_md_dec_matrix_open( } for ( j = 0; j < num_channels; j++ ) { +#ifdef SPAR_TUNING + if ( ( hMdDec->mixer_mat[i][j] = (float *) malloc( num_md_sub_frames * IVAS_MAX_NUM_BANDS * sizeof( float ) ) ) == NULL ) +#else if ( ( hMdDec->mixer_mat[i][j] = (float *) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * IVAS_MAX_NUM_BANDS * sizeof( float ) ) ) == NULL ) +#endif { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); } @@ -136,7 +173,11 @@ static ivas_error ivas_spar_md_dec_matrix_open( } for ( j = 0; j < num_channels; j++ ) { +#ifdef SPAR_TUNING + if ( ( hMdDec->spar_coeffs.C_re[i][j] = (float *) malloc( num_md_sub_frames * IVAS_MAX_NUM_BANDS * sizeof( float ) ) ) == NULL ) +#else if ( ( hMdDec->spar_coeffs.C_re[i][j] = (float *) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * IVAS_MAX_NUM_BANDS * sizeof( float ) ) ) == NULL ) +#endif { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); } @@ -155,7 +196,11 @@ static ivas_error ivas_spar_md_dec_matrix_open( } for ( j = 0; j < num_channels; j++ ) { +#ifdef SPAR_TUNING + if ( ( hMdDec->spar_coeffs.P_re[i][j] = (float *) malloc( num_md_sub_frames * IVAS_MAX_NUM_BANDS * sizeof( float ) ) ) == NULL ) +#else if ( ( hMdDec->spar_coeffs.P_re[i][j] = (float *) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * IVAS_MAX_NUM_BANDS * sizeof( float ) ) ) == NULL ) +#endif { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); } @@ -241,6 +286,23 @@ static ivas_error ivas_spar_md_dec_matrix_open( return IVAS_ERR_OK; } +#ifdef SPAR_TUNING +int16_t ivas_get_spar_dec_md_num_subframes( + const int16_t sba_order, /* i : Ambisonic (SBA) order */ + const int32_t ivas_total_brate ) +{ + int16_t num_subframes; + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + if ( sba_order > SBA_FOA_ORDER ) + { + if ( ivas_total_brate >= IVAS_512k ) + { + num_subframes = 1; + } + } + return ( num_subframes ); +} +#endif /*------------------------------------------------------------------------- * ivas_spar_md_dec_open() @@ -258,6 +320,9 @@ ivas_error ivas_spar_md_dec_open( { ivas_spar_md_dec_state_t *hMdDec; ivas_error error; +#ifdef SPAR_TUNING + int16_t num_md_sub_frames; +#endif error = IVAS_ERR_OK; @@ -266,7 +331,15 @@ ivas_error ivas_spar_md_dec_open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD decoder" ); } - if ( ( error = ivas_spar_md_dec_matrix_open( hMdDec, num_channels ) ) != IVAS_ERR_OK ) +#ifdef SPAR_TUNING + num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( sba_order, hDecoderConfig->ivas_total_brate ); +#endif + if ( ( error = ivas_spar_md_dec_matrix_open( hMdDec, num_channels +#ifdef SPAR_TUNING + , + num_md_sub_frames +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -443,7 +516,16 @@ ivas_error ivas_spar_md_dec_init( int16_t nchan_transport; float pFC[IVAS_MAX_NUM_BANDS], PR_minmax[2]; +#ifdef SPAR_TUNING + ivas_sba_get_spar_hoa_md_flag( sba_order, hDecoderConfig->ivas_total_brate, &hMdDec->spar_hoa_md_flag, &hMdDec->spar_hoa_dirac2spar_md_flag ); +#else hMdDec->spar_hoa_md_flag = ivas_sba_get_spar_hoa_md_flag( sba_order, hDecoderConfig->ivas_total_brate ); +#endif + +#ifdef SPAR_TUNING + ivas_sba_get_spar_hoa_ch_ind( num_channels, hDecoderConfig->ivas_total_brate, hMdDec->HOA_md_ind ); +#endif + hMdDec->spar_md.num_bands = ( hMdDec->spar_hoa_md_flag ) ? IVAS_MAX_NUM_BANDS : min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); ivas_spar_set_bitrate_config( &hMdDec->spar_md_cfg, hMdDec->table_idx, hMdDec->spar_md.num_bands ); @@ -577,7 +659,12 @@ static ivas_error ivas_spar_set_dec_config( hMdDec->spar_md_cfg.max_freq_per_chan[i] = ivas_spar_br_table_consts[hMdDec->table_idx].fpcs; } - nchan = ivas_sba_get_nchan_metadata( ivas_spar_br_table_consts[hMdDec->table_idx].sba_order ); + nchan = ivas_sba_get_nchan_metadata( ivas_spar_br_table_consts[hMdDec->table_idx].sba_order +#ifdef SPAR_TUNING + , + ivas_spar_br_table_consts[hMdDec->table_idx].ivas_total_brate +#endif + ); switch ( nchan ) { @@ -637,10 +724,26 @@ void ivas_spar_md_dec_process( { int16_t j, k, b, bw, dtx_vad, nB, i_ts; ivas_spar_md_dec_state_t *hMdDec; +#ifdef SPAR_TUNING + int16_t num_md_chs; +#endif + int16_t num_md_sub_frames; hMdDec = st_ivas->hSpar->hMdDec; + int16_t active_w_vlbr; active_w_vlbr = ( st_ivas->hDecoderConfig->ivas_total_brate < IVAS_24k4 ) ? 1 : 0; + +#ifdef SPAR_TUNING + num_md_chs = ivas_sba_get_nchan_metadata( sba_order, st_ivas->hDecoderConfig->ivas_total_brate ); +#endif +#ifdef SPAR_TUNING + num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( sba_order, st_ivas->hDecoderConfig->ivas_total_brate ); +#else + num_md_sub_frames = MAX_PARAM_SPATIAL_SUBFRAMES; +#endif + + ivas_spar_dec_parse_md_bs( hMdDec, st0, &nB, &bw, &dtx_vad, st_ivas->hDecoderConfig->ivas_total_brate, ivas_spar_br_table_consts[hMdDec->table_idx].usePlanarCoeff, st_ivas->hQMetaData->sba_inactive_mode ); @@ -649,7 +752,12 @@ void ivas_spar_md_dec_process( char f_name[100]; int16_t num_bands = nB; int16_t num_subframes = 1, num_block_groups = 1, num_elements = 1, byte_size = sizeof( float ); - int16_t num_ch = ivas_sba_get_nchan_metadata( sba_order ); + int16_t num_ch = ivas_sba_get_nchan_metadata( sba_order +#ifdef SPAR_TUNING + , + st_ivas->hDecoderConfig->ivas_total_brate +#endif + ); for ( b = 0; b < num_bands; b++ ) { sprintf( f_name, "spar_band_pred_coeffs_dec.bin" ); @@ -782,8 +890,12 @@ void ivas_spar_md_dec_process( }*/ #endif /* SPAR to DirAC conversion */ - ivas_spar_to_dirac( st_ivas, hMdDec, dtx_vad, num_bands_out, - bw ); +#ifdef SPAR_TUNING + if ( hMdDec->spar_hoa_dirac2spar_md_flag == 1 ) +#endif + { + ivas_spar_to_dirac( st_ivas, hMdDec, dtx_vad, num_bands_out, bw ); + } /* set correct number of bands*/ nB = IVAS_MAX_NUM_BANDS; @@ -915,7 +1027,11 @@ void ivas_spar_md_dec_process( }*/ #endif /* expand DirAC MD to all time slots */ +#ifdef SPAR_TUNING + for ( i_ts = 1; i_ts < num_md_sub_frames; i_ts++ ) +#else for ( i_ts = 1; i_ts < MAX_PARAM_SPATIAL_SUBFRAMES; i_ts++ ) +#endif { for ( b = 0; b < hMdDec->spar_md.num_bands; b++ ) { @@ -939,8 +1055,19 @@ void ivas_spar_md_dec_process( } } - ivas_get_spar_matrices( hMdDec, num_bands_out, MAX_PARAM_SPATIAL_SUBFRAMES, bw, dtx_vad, nB, sba_order, - active_w_vlbr ); +#ifdef SPAR_TUNING + ivas_get_spar_matrices( hMdDec, num_bands_out, num_md_sub_frames, bw, dtx_vad, nB, +#else + ivas_get_spar_matrices( hMdDec, num_bands_out, MAX_PARAM_SPATIAL_SUBFRAMES, bw, dtx_vad, nB, +#endif +#ifdef SPAR_TUNING + num_md_chs, +#else + sba_order, +#endif + active_w_vlbr + + ); #ifdef DEBUG_SPAR_DIRAC_WRITE_OUT_PRED_PARS { @@ -962,7 +1089,17 @@ void ivas_spar_md_dec_process( hMdDec->valid_bands[b] = 1; } - ivas_spar_md_fill_invalid_bands( &hMdDec->spar_coeffs, &hMdDec->spar_coeffs_prev, &hMdDec->valid_bands[0], &hMdDec->base_band_age[0], num_bands_out, sba_order ); + ivas_spar_md_fill_invalid_bands( &hMdDec->spar_coeffs, &hMdDec->spar_coeffs_prev, &hMdDec->valid_bands[0], &hMdDec->base_band_age[0], num_bands_out, +#ifdef SPAR_TUNING + num_md_chs +#else + sba_order +#endif +#ifdef SPAR_TUNING + , + num_md_sub_frames +#endif + ); hMdDec->dtx_md_smoothing_cntr = 1; @@ -982,6 +1119,10 @@ void ivas_spar_md_dec_process( void ivas_spar_smooth_md_dtx( ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ const int16_t num_bands_out /* i : number of output bands */ +#ifdef SPAR_TUNING + , + const int16_t num_md_sub_frames /* i : number of metadata subframes */ +#endif ) { int16_t j, k, b, dmx_ch; @@ -1017,7 +1158,11 @@ void ivas_spar_smooth_md_dtx( } /* expand MD to all time slots */ +#ifdef SPAR_TUNING + for ( int16_t i_ts = 1; i_ts < num_md_sub_frames; i_ts++ ) +#else for ( int16_t i_ts = 1; i_ts < MAX_PARAM_SPATIAL_SUBFRAMES; i_ts++ ) +#endif { for ( b = 0; b < num_bands_out; b++ ) { @@ -1057,6 +1202,10 @@ void ivas_spar_smooth_md_dtx( void ivas_spar_setup_md_smoothing( ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ const int16_t num_bands_out /* i : number of output bands */ +#ifdef SPAR_TUNING + , + const int16_t num_md_sub_frames /* i : number of metadata subframes */ +#endif ) { /* copy the coeffs */ @@ -1108,7 +1257,12 @@ void ivas_spar_setup_md_smoothing( } } - ivas_spar_smooth_md_dtx( hMdDec, num_bands_out ); + ivas_spar_smooth_md_dtx( hMdDec, num_bands_out +#ifdef SPAR_TUNING + , + num_md_sub_frames +#endif + ); return; } @@ -1188,15 +1342,25 @@ static void ivas_get_spar_matrices( const int16_t bw, const int16_t dtx_vad, const int16_t nB, +#ifdef SPAR_TUNING + const int16_t numch_out, +#else const int16_t sba_order, +#endif const int16_t active_w_vlbr ) { +#ifndef SPAR_TUNING int16_t numch_out, num_bands, dmx_ch, split_band; +#else + int16_t num_bands, dmx_ch, split_band; +#endif int16_t i, j, k, m, b, i_ts, active_w; const int16_t *order; float active_w_dm_fac, re; +#ifndef SPAR_TUNING numch_out = ivas_sba_get_nchan_metadata( sba_order ); +#endif num_bands = num_bands_out; order = remix_order_set[hMdDec->spar_md_cfg.remix_unmix_order]; @@ -1575,13 +1739,21 @@ void ivas_spar_dec_gen_umx_mat( const int16_t nchan_transport, /* i : number of transport channels */ const int16_t num_bands_out, /* i : number of output bands */ const int16_t bfi /* i : bad frame indicator */ +#ifdef SPAR_TUNING + , + const int16_t num_md_sub_frames +#endif ) { int16_t i, j, b, i_ts, num_out_ch; num_out_ch = hMdDec->spar_md_cfg.num_umx_chs; +#ifdef SPAR_TUNING + for ( i_ts = 0; i_ts < num_md_sub_frames; i_ts++ ) +#else for ( i_ts = 0; i_ts < MAX_PARAM_SPATIAL_SUBFRAMES; i_ts++ ) +#endif { if ( hMdDec->td_decorr_flag == 1 ) { @@ -1642,7 +1814,12 @@ void ivas_spar_dec_gen_umx_mat( #endif } - ivas_spar_dec_compute_ramp_down_post_matrix( hMdDec, num_bands_out, bfi ); + ivas_spar_dec_compute_ramp_down_post_matrix( hMdDec, num_bands_out, bfi +#ifdef SPAR_TUNING + , + num_md_sub_frames +#endif + ); return; } @@ -1992,7 +2169,8 @@ static void ivas_decode_arith_bs( const int16_t strat, const int32_t ivas_total_brate ) { - int16_t i, j, ndm, ndec; + int16_t i, ndm, ndec; + int16_t j; ivas_cell_dim_t pred_cell_dims[IVAS_MAX_NUM_BANDS]; ivas_cell_dim_t drct_cell_dims[IVAS_MAX_NUM_BANDS]; ivas_cell_dim_t decd_cell_dims[IVAS_MAX_NUM_BANDS]; @@ -2019,7 +2197,11 @@ static void ivas_decode_arith_bs( else { pred_cell_dims[i].dim1 = ndm + ndec - 1; - if ( hMdDec->spar_hoa_md_flag ) + if ( hMdDec->spar_hoa_md_flag +#ifdef SPAR_TUNING + && hMdDec->spar_hoa_dirac2spar_md_flag +#endif + ) { if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) { @@ -2048,7 +2230,11 @@ static void ivas_decode_arith_bs( if ( any_diff == 1 ) { +#ifdef SPAR_TUNING + if ( hMdDec->spar_hoa_md_flag && hMdDec->spar_hoa_dirac2spar_md_flag ) +#else if ( hMdDec->spar_hoa_md_flag ) +#endif { for ( i = 0; i < nB; i++ ) { @@ -2070,7 +2256,11 @@ 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 SPAR_TUNING + if ( hMdDec->spar_hoa_md_flag && hMdDec->spar_hoa_dirac2spar_md_flag ) +#else if ( hMdDec->spar_hoa_md_flag ) +#endif { for ( i = 0; i < nB; i++ ) { @@ -2335,7 +2525,11 @@ static void ivas_decode_huffman_bs( drct_dim = ndec * ( ndm - 1 ); decd_dim = ndec; pred_offset = 0; +#ifdef SPAR_TUNING + if ( hMdDec->spar_hoa_md_flag && hMdDec->spar_hoa_dirac2spar_md_flag ) +#else if ( hMdDec->spar_hoa_md_flag ) +#endif { if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) { @@ -2349,7 +2543,11 @@ static void ivas_decode_huffman_bs( &hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j] ); } +#ifdef SPAR_TUNING + if ( hMdDec->spar_hoa_md_flag && hMdDec->spar_hoa_dirac2spar_md_flag ) +#else if ( hMdDec->spar_hoa_md_flag ) +#endif { if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) { @@ -2402,16 +2600,26 @@ static void ivas_spar_md_fill_invalid_bands( const int16_t *valid_bands, int16_t *base_band_age, const int16_t num_bands, - const int16_t sba_order /* i : SBA order */ +#ifdef SPAR_TUNING + const int16_t num_channels +#else + const int16_t sba_order +#endif +#ifdef SPAR_TUNING + , + const int16_t num_md_sub_frames +#endif ) { int16_t i, j, b, all_valid; int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], idx = -1; int16_t last_valid_band_idx[IVAS_MAX_NUM_BANDS]; float w = 0; +#ifndef SPAR_TUNING int16_t num_channels; num_channels = ivas_sba_get_nchan_metadata( sba_order ); +#endif set_s( valid_band_idx, 0, IVAS_MAX_NUM_BANDS ); set_s( last_valid_band_idx, 0, IVAS_MAX_NUM_BANDS ); @@ -2498,7 +2706,11 @@ static void ivas_spar_md_fill_invalid_bands( { for ( j = 0; j < num_channels; j++ ) { +#ifdef SPAR_TUNING + for ( i_ts = 1; i_ts < num_md_sub_frames; i_ts++ ) +#else for ( i_ts = 1; i_ts < MAX_PARAM_SPATIAL_SUBFRAMES; i_ts++ ) +#endif { pSpar_coeffs->C_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = pSpar_coeffs->C_re[i][j][b]; pSpar_coeffs->P_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = pSpar_coeffs->P_re[i][j][b]; @@ -2522,7 +2734,12 @@ static void ivas_spar_md_fill_invalid_bands( static void ivas_spar_dec_compute_ramp_down_post_matrix( ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands_out, - const int16_t bfi ) + const int16_t bfi +#ifdef SPAR_TUNING + , + const int16_t num_md_sub_frames +#endif +) { int16_t num_in_ch, num_out_ch, i, j, b; @@ -2561,7 +2778,11 @@ static void ivas_spar_dec_compute_ramp_down_post_matrix( } /* apply the post matrix */ +#ifdef SPAR_TUNING + for ( int16_t i_ts = 0; i_ts < num_md_sub_frames; i_ts++ ) +#else for ( int16_t i_ts = 0; i_ts < MAX_PARAM_SPATIAL_SUBFRAMES; i_ts++ ) +#endif { for ( i = 0; i < num_out_ch; i++ ) { @@ -2825,6 +3046,7 @@ void ivas_spar_to_dirac( int16_t pred_idx; int16_t *dirac_to_spar_md_bands; int16_t enc_param_start_band; + int16_t active_w_vlbr; sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); start_band = 0; @@ -2833,9 +3055,13 @@ void ivas_spar_to_dirac( hDirAC = st_ivas->hDirAC; dirac_to_spar_md_bands = st_ivas->hSpar->dirac_to_spar_md_bands; enc_param_start_band = st_ivas->hSpar->enc_param_start_band / bw; - int16_t active_w_vlbr; active_w_vlbr = ( st_ivas->hDecoderConfig->ivas_total_brate < IVAS_24k4 ) ? 1 : 0; - if ( hDirAC != NULL ) + + if ( hDirAC != NULL +#ifdef HODIRAC + && ( st_ivas->sba_analysis_order <= 1 || st_ivas->hDecoderConfig->ivas_total_brate <= IVAS_256k ) +#endif + ) { band_grouping = hDirAC->band_grouping; #ifdef ENABLE_DITHER diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index ad453cd5bdf92aed36d256cbe7482f39cf1a0d27..4174b2772b639f23dd900de43dde42543cae9127 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -710,6 +710,9 @@ typedef struct ivas_dirac_dec_data_structure PARAM_ISM_RENDERING_HANDLE hParamIsmRendering; IVAS_FB_MIXER_HANDLE hFbMdft; int16_t dirac_to_spar_md_bands[DIRAC_MAX_NBANDS]; +#ifdef SPAR_TUNING + const int16_t *sba_map_tc; +#endif } DIRAC_DEC_DATA, *DIRAC_DEC_HANDLE; @@ -806,6 +809,12 @@ typedef struct ivas_spar_md_dec_state_t int16_t table_idx; int16_t dtx_vad; int16_t spar_hoa_md_flag; + +#ifdef SPAR_TUNING + int16_t spar_hoa_dirac2spar_md_flag; + int16_t HOA_md_ind[IVAS_SPAR_MAX_CH]; +#endif + float smooth_buf[IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS][2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1]; float smooth_fac[IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; float mixer_mat_prev2[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index 45ce09bb151e929cce83036f28bfff8d0ca21dad..6c094a4491e968999498e907cbe78146cdfd6d2c 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -99,7 +99,19 @@ ivas_error ivas_dirac_enc_open( } else { - if ( ( error = ivas_fb_set_cfg( &fb_cfg, SBA_FORMAT, SBA_MODE_DIRAC, DIRAC_MAX_ANA_CHANS, 0, 0, input_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_fb_set_cfg( &fb_cfg, SBA_FORMAT, SBA_MODE_DIRAC, +#ifdef HODIRAC + FOA_CHANNELS +#else + DIRAC_MAX_ANA_CHANS +#endif + , + 0, 0, input_Fs +#ifdef HODIRAC + , + FOA_CHANNELS +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -364,7 +376,13 @@ 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, SBA_MODE_DIRAC ); + ivas_dirac_param_est_enc( hDirAC, &( hQMetaData->q_direction[0] ), hQMetaData->useLowerRes, data_f, NULL, NULL, input_frame, SBA_MODE_DIRAC +#ifdef HODIRAC + , + 0, + FOA_CHANNELS +#endif + ); /* encode parameters */ if ( sba_planar || hQMetaData->useLowerRes ) @@ -376,7 +394,12 @@ void ivas_dirac_enc( } } - ivas_qmetadata_enc_encode( hMetaData, hQMetaData ); + ivas_qmetadata_enc_encode( hMetaData, hQMetaData +#ifdef HODIRAC + , + 0 +#endif + ); *nb_bits_metadata = hMetaData->nb_bits_tot; @@ -540,6 +563,10 @@ void computeReferencePower_enc( const int16_t enc_param_start_band, /* i : first band to process */ const int16_t num_freq_bands, /* i : Number of frequency bands */ const SBA_MODE sba_mode /* i : SBA mode */ +#ifdef HODIRAC + , + int16_t nchan_ana /* i : no of analysis channels */ +#endif ) { int16_t brange[2]; @@ -559,7 +586,11 @@ void computeReferencePower_enc( 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]; +#ifdef HODIRAC + for ( ch_idx = 1; ch_idx < nchan_ana; ch_idx++ ) +#else for ( ch_idx = 1; ch_idx < DIRAC_MAX_ANA_CHANS; ch_idx++ ) +#endif { /* abs()^2 */ for ( j = brange[0]; j < brange[1]; j++ ) @@ -596,7 +627,13 @@ void ivas_dirac_param_est_enc( float **pp_fr_real, float **pp_fr_imag, const int16_t input_frame, - const SBA_MODE sba_mode ) + const SBA_MODE sba_mode +#ifdef HODIRAC + , + const int16_t hodirac, + const int16_t nchan_fb_in +#endif +) { int16_t i, d, ts, index, l_ts, num_freq_bands; int16_t band_m_idx, block_m_idx; @@ -617,8 +654,30 @@ void ivas_dirac_param_est_enc( float reference_power[CLDFB_NO_COL_MAX][DIRAC_NO_FB_BANDS_MAX]; +#ifdef HODIRAC + float azi_secs[2 * DIRAC_MAX_ANA_CHANS * DIRAC_MAX_NBANDS] = { 0 }; + float ele_secs[2 * DIRAC_MAX_ANA_CHANS * DIRAC_MAX_NBANDS] = { 0 }; + float diff_secs[2 * DIRAC_MAX_ANA_CHANS * DIRAC_MAX_NBANDS] = { 0 }; + float ene_secs[2 * DIRAC_MAX_ANA_CHANS * DIRAC_MAX_NBANDS] = { 0 }; +#endif + +#ifdef HODIRAC_WRITE_PARAMS + static FILE *f_secparams = 0; +#endif + push_wmops( "dirac_enc_param_est" ); +#ifdef HODIRAC + num_freq_bands = hDirAC->hConfig->nbands; +#endif + +#ifdef HODIRAC_WRITE_PARAMS + if ( f_secparams == 0 ) + { + f_secparams = fopen( "sector_params.txt", "w" ); + } +#endif + /* Initialization */ l_ts = input_frame / MAX_PARAM_SPATIAL_SUBFRAMES; if ( useLowerRes ) @@ -640,7 +699,11 @@ void ivas_dirac_param_est_enc( } /* Copy current frame to memory for delay compensation */ +#ifdef HODIRAC + for ( i = 0; i < nchan_fb_in; i++ ) +#else for ( i = 0; i < DIRAC_MAX_ANA_CHANS; i++ ) +#endif { pcm_in[i] = &data_f[i][0]; p_Cldfb_RealBuffer[i] = &Cldfb_RealBuffer[i][0]; @@ -665,10 +728,24 @@ void ivas_dirac_param_est_enc( { if ( hDirAC->hFbMixer ) { - ivas_fb_mixer_get_windowed_fr( hDirAC->hFbMixer, pcm_in, p_Cldfb_RealBuffer, p_Cldfb_ImagBuffer, l_ts, l_ts ); - ivas_fb_mixer_update_prior_input( hDirAC->hFbMixer, pcm_in, l_ts ); + ivas_fb_mixer_get_windowed_fr( hDirAC->hFbMixer, pcm_in, p_Cldfb_RealBuffer, p_Cldfb_ImagBuffer, l_ts, l_ts +#ifdef HODIRAC + , + hDirAC->hFbMixer->fb_cfg->num_in_chans +#endif + ); + ivas_fb_mixer_update_prior_input( hDirAC->hFbMixer, pcm_in, l_ts +#ifdef HODIRAC + , + hDirAC->hFbMixer->fb_cfg->num_in_chans +#endif + ); +#ifdef HODIRAC + for ( i = 0; i < nchan_fb_in; i++ ) +#else for ( i = 0; i < DIRAC_MAX_ANA_CHANS; i++ ) +#endif { pcm_in[i] += l_ts; } @@ -679,14 +756,19 @@ void ivas_dirac_param_est_enc( assert( pp_fr_real ); assert( pp_fr_imag ); #endif +#ifdef HODIRAC + for ( i = 0; i < nchan_fb_in; i++ ) +#else for ( i = 0; i < DIRAC_MAX_ANA_CHANS; i++ ) +#endif { mvr2r( &pp_fr_real[i][block_m_idx * l_ts], Cldfb_RealBuffer[i], l_ts ); mvr2r( &pp_fr_imag[i][block_m_idx * l_ts], Cldfb_ImagBuffer[i], l_ts ); } } - +#ifndef HODIRAC num_freq_bands = hDirAC->hConfig->nbands; +#endif computeReferencePower_enc( hDirAC->band_grouping, @@ -695,7 +777,16 @@ void ivas_dirac_param_est_enc( reference_power[ts], hDirAC->hConfig->enc_param_start_band, num_freq_bands, - sba_mode ); +#ifdef HODIRAC + hodirac ? SBA_MODE_DIRAC : sba_mode +#else + sba_mode +#endif +#ifdef HODIRAC + , + FOA_CHANNELS +#endif + ); computeIntensityVector_enc( hDirAC, @@ -705,15 +796,20 @@ void ivas_dirac_param_est_enc( num_freq_bands, intensity_real ); - computeDirectionVectors( - intensity_real[0], - intensity_real[1], - intensity_real[2], - hDirAC->hConfig->enc_param_start_band, - num_freq_bands, - direction_vector[0], - direction_vector[1], - direction_vector[2] ); +#ifdef HODIRAC + if ( !hodirac ) +#endif + { + computeDirectionVectors( + intensity_real[0], + intensity_real[1], + intensity_real[2], + hDirAC->hConfig->enc_param_start_band, + num_freq_bands, + direction_vector[0], + direction_vector[1], + direction_vector[2] ); + } /* fill buffers of length "averaging_length" time slots for intensity and energy */ hDirAC->index_buffer_intensity = ( hDirAC->index_buffer_intensity % hDirAC->no_col_avg_diff ) + 1; /* averaging_length = 32 */ @@ -726,51 +822,135 @@ void ivas_dirac_param_est_enc( mvr2r( reference_power[ts], &( hDirAC->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands ); computeDiffuseness_mdft( hDirAC->buffer_intensity_real, hDirAC->buffer_energy, num_freq_bands, hDirAC->no_col_avg_diff, diffuseness_vector ); - - for ( band_m_idx = 0; band_m_idx < hDirAC->hConfig->nbands; band_m_idx++ ) +#ifdef HODIRAC + if ( hodirac ) { - norm_tmp = reference_power[ts][band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] ); - hDirAC->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx]; - hDirAC->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx]; - hDirAC->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx]; - renormalization_factor[band_m_idx] += norm_tmp; + calculate_hodirac_sector_parameters( + Cldfb_RealBuffer, + Cldfb_ImagBuffer, + l_ts, + 0.20f, + hDirAC->band_grouping, + hDirAC->hConfig->nbands, + hDirAC->hConfig->enc_param_start_band, + azi_secs, ele_secs, diff_secs, ene_secs ); + +#ifdef HODIRAC_WRITE_PARAMS + for ( i = 0; i < num_freq_bands; i++ ) + { + for ( uint16_t j = 0; j < 4; j++ ) + { + fprintf( f_secparams, "%d %d %f %f %f %f %f\n", i, j, + azi_secs[j * num_freq_bands + i], + ele_secs[j * num_freq_bands + i], + ene_secs[j * num_freq_bands + i], + diff_secs[j * num_freq_bands + i], + diffuseness_vector[i] ); + } + } - hDirAC->diffuseness_m[band_m_idx] += reference_power[ts][band_m_idx] * diffuseness_vector[band_m_idx]; - renormalization_factor_diff[band_m_idx] += reference_power[ts][band_m_idx]; +#endif // HODIRAC_WRITE_PARAMS } - } +#endif // HODIRAC - for ( band_m_idx = 0; band_m_idx < hDirAC->hConfig->nbands; band_m_idx++ ) - { - renormalization_factor[band_m_idx] = EPSILON; - for ( d = 0; d < DIRAC_NUM_DIMS; d++ ) +#ifdef HODIRAC + if ( hodirac ) { - renormalization_factor[band_m_idx] += ( hDirAC->direction_vector_m[d][block_m_idx][band_m_idx] * hDirAC->direction_vector_m[d][block_m_idx][band_m_idx] ); - } - renormalization_factor[band_m_idx] = sqrtf( renormalization_factor[band_m_idx] ); - - if ( renormalization_factor[band_m_idx] > EPSILON ) - { - hDirAC->direction_vector_m[0][block_m_idx][band_m_idx] /= renormalization_factor[band_m_idx]; - hDirAC->direction_vector_m[1][block_m_idx][band_m_idx] /= renormalization_factor[band_m_idx]; - hDirAC->direction_vector_m[2][block_m_idx][band_m_idx] /= renormalization_factor[band_m_idx]; + for ( band_m_idx = 0; band_m_idx < hDirAC->hConfig->nbands; band_m_idx++ ) + { + hDirAC->diffuseness_m[band_m_idx] += reference_power[ts][band_m_idx] * diffuseness_vector[band_m_idx]; + renormalization_factor_diff[band_m_idx] += reference_power[ts][band_m_idx]; + } } else +#endif { - hDirAC->direction_vector_m[0][block_m_idx][band_m_idx] = 1; - hDirAC->direction_vector_m[1][block_m_idx][band_m_idx] = 0; - hDirAC->direction_vector_m[2][block_m_idx][band_m_idx] = 0; + for ( band_m_idx = 0; band_m_idx < hDirAC->hConfig->nbands; band_m_idx++ ) + { + norm_tmp = reference_power[ts][band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] ); + + hDirAC->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx]; + hDirAC->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx]; + hDirAC->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx]; + renormalization_factor[band_m_idx] += norm_tmp; + + hDirAC->diffuseness_m[band_m_idx] += reference_power[ts][band_m_idx] * diffuseness_vector[band_m_idx]; + renormalization_factor_diff[band_m_idx] += reference_power[ts][band_m_idx]; + } } + } + +#ifdef HODIRAC + if ( !hodirac ) +#endif + + { - /* save the elevation and azimuth values to be used later by the ivas_dirac_QuantizeParameters function */ - for ( d = 0; d < DIRAC_NUM_DIMS; d++ ) + for ( band_m_idx = 0; band_m_idx < hDirAC->hConfig->nbands; band_m_idx++ ) { - dir_v[d] = hDirAC->direction_vector_m[d][block_m_idx][band_m_idx]; - } + renormalization_factor[band_m_idx] = EPSILON; + for ( d = 0; d < DIRAC_NUM_DIMS; d++ ) + { + renormalization_factor[band_m_idx] += ( hDirAC->direction_vector_m[d][block_m_idx][band_m_idx] * hDirAC->direction_vector_m[d][block_m_idx][band_m_idx] ); + } + renormalization_factor[band_m_idx] = sqrtf( renormalization_factor[band_m_idx] ); + + if ( renormalization_factor[band_m_idx] > EPSILON ) + { + hDirAC->direction_vector_m[0][block_m_idx][band_m_idx] /= renormalization_factor[band_m_idx]; + hDirAC->direction_vector_m[1][block_m_idx][band_m_idx] /= renormalization_factor[band_m_idx]; + hDirAC->direction_vector_m[2][block_m_idx][band_m_idx] /= renormalization_factor[band_m_idx]; + } + else + { + hDirAC->direction_vector_m[0][block_m_idx][band_m_idx] = 1; + hDirAC->direction_vector_m[1][block_m_idx][band_m_idx] = 0; + hDirAC->direction_vector_m[2][block_m_idx][band_m_idx] = 0; + } + + /* save the elevation and azimuth values to be used later by the ivas_dirac_QuantizeParameters function */ + for ( d = 0; d < DIRAC_NUM_DIMS; d++ ) + { + dir_v[d] = hDirAC->direction_vector_m[d][block_m_idx][band_m_idx]; + } - ivas_qmetadata_direction_vector_to_azimuth_elevation( dir_v, &q_direction->band_data[band_m_idx].azimuth[block_m_idx], &q_direction->band_data[band_m_idx].elevation[block_m_idx] ); + ivas_qmetadata_direction_vector_to_azimuth_elevation( + dir_v, + &q_direction->band_data[band_m_idx].azimuth[block_m_idx], + &q_direction->band_data[band_m_idx].elevation[block_m_idx] ); + } + } + /* Sectors */ +#ifdef HODIRAC + if ( hodirac ) + { + for ( band_m_idx = 0; band_m_idx < hDirAC->hConfig->nbands; band_m_idx++ ) + { + q_direction->band_data[band_m_idx].azimuth[block_m_idx] = azi_secs[band_m_idx]; + q_direction->band_data[band_m_idx].elevation[block_m_idx] = ele_secs[band_m_idx]; + // q_direction->band_data[band_m_idx].energy_ratio[block_m_idx] = 1.f - diffuseness_vector[band_m_idx]; // set later + + q_direction[1].band_data[band_m_idx].azimuth[block_m_idx] = azi_secs[num_freq_bands + band_m_idx]; + q_direction[1].band_data[band_m_idx].elevation[block_m_idx] = ele_secs[num_freq_bands + band_m_idx]; + q_direction[1].band_data[band_m_idx].energy_ratio[block_m_idx] = ( 1.f - diff_secs[band_m_idx] ) / ( ( 1.f - diff_secs[band_m_idx] ) + ( 1.f - diff_secs[num_freq_bands + band_m_idx] ) + EPSILON ); +#ifdef HODIRAC_WRITE_PARAMS + { + static FILE *f_a = 0; + if ( f_a == 0 ) + f_a = fopen( "param_enc", "w" ); + fprintf( f_a, "%f %f %f %f %f %f\n", + q_direction->band_data[band_m_idx].azimuth[block_m_idx], + q_direction->band_data[band_m_idx].elevation[block_m_idx], + diffuseness_vector[band_m_idx], + q_direction[1].band_data[band_m_idx].azimuth[block_m_idx], + q_direction[1].band_data[band_m_idx].elevation[block_m_idx], + q_direction[1].band_data[band_m_idx].energy_ratio[block_m_idx] ); + } +#endif + } } +#endif } /* Diffuseness */ diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc.c index bc374f88e59c4cedddc78ceb8cf25ccbf98283d8..fa293221d4457b95925cef5ae49f2e3bd8826efd 100644 --- a/lib_enc/ivas_enc.c +++ b/lib_enc/ivas_enc.c @@ -132,9 +132,17 @@ ivas_error ivas_enc( /* bypass EVS coding in float precision, emulating EVS encoder/decoder delay */ for ( i = 0; i < n; i++ ) { - if ( ( ivas_format == SBA_FORMAT ) && ( st_ivas->sba_mode == SBA_MODE_SPAR ) ) + if ( ( ivas_format == SBA_FORMAT ) && ( st_ivas->sba_mode == SBA_MODE_SPAR ) +#ifdef HODIRAC + && !( st_ivas->sba_analysis_order > 1 ) +#endif + ) { +#ifdef SPAR_TUNING + hp20( data_f[HOA_keep_ind[st_ivas->hSpar->hMdEnc->HOA_md_ind[i]]], input_frame, st_ivas->mem_hp20_in[i], input_Fs ); +#else hp20( data_f[HOA_keep_ind[i]], input_frame, st_ivas->mem_hp20_in[i], input_Fs ); +#endif } else if ( !( ivas_format == MC_FORMAT && i == LFE_CHANNEL ) ) /*TODO: is the HPF needed for LFE channel? */ { diff --git a/lib_enc/ivas_enc_cov_handler.c b/lib_enc/ivas_enc_cov_handler.c index 9524fb656fcdf1bcc789b49113b82bd67dd3f45a..e7a4f2d76f15161b4733bb06acf715048e11f252 100644 --- a/lib_enc/ivas_enc_cov_handler.c +++ b/lib_enc/ivas_enc_cov_handler.c @@ -34,6 +34,9 @@ #include "options.h" #include "prot.h" #include "ivas_prot.h" +#ifdef HODIRAC +#include "ivas_rom_com.h" +#endif #ifdef DEBUGGING #include "debug.h" #endif @@ -53,7 +56,12 @@ * Local functions declarations *------------------------------------------------------------------------------------------*/ -static void ivas_band_cov( float **ppIn_FR_real, float **ppIn_FR_imag, const int16_t num_chans, const int16_t num_bins, int16_t stride, float **pFb_bin_to_band, const int16_t *pFb_start_bin_per_band, const int16_t *pFb_active_bins_per_band, const int16_t start_band, const int16_t end_band, float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH] ); +static void ivas_band_cov( float **ppIn_FR_real, float **ppIn_FR_imag, const int16_t num_chans, const int16_t num_bins, int16_t stride, float **pFb_bin_to_band, const int16_t *pFb_start_bin_per_band, const int16_t *pFb_active_bins_per_band, const int16_t start_band, const int16_t end_band, float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH] +#ifdef SPAR_TUNING + , + const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] +#endif +); /*------------------------------------------------------------------------- * ivas_spar_covar_enc_open() @@ -154,7 +162,12 @@ void ivas_enc_cov_handler_process( const int16_t end_band, const int16_t num_ch, const int16_t dtx_vad, - const int16_t transient_det[2] ) + const int16_t transient_det[2] +#ifdef SPAR_TUNING + , + const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] +#endif +) { int16_t i, j; int16_t dtx_cov_flag; @@ -167,7 +180,12 @@ void ivas_enc_cov_handler_process( pFb->fb_bin_to_band.p_short_stride_start_bin_per_band, pFb->fb_bin_to_band.p_short_stride_num_bins_per_band, start_band, end_band, - cov_real ); + cov_real +#ifdef SPAR_TUNING + , + HOA_md_ind +#endif + ); #ifdef DEBUG_SPAR_WRITE_OUT_COV { @@ -259,7 +277,12 @@ static void ivas_band_cov( const int16_t *pFb_active_bins_per_band, const int16_t start_band, const int16_t end_band, - float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH] ) + float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH] +#ifdef SPAR_TUNING + , + const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] +#endif +) { int16_t i, j, k; float pV_re[L_FRAME48k]; @@ -269,9 +292,24 @@ static void ivas_band_cov( { for ( j = i; j < num_chans; j++ ) { + +#ifdef HODIRAC +#ifdef SPAR_TUNING + int16_t i1 = HOA_md_ind[i]; + int16_t j1 = HOA_md_ind[j]; +#else + int16_t i1 = HOA_keep_ind_spar[i]; + int16_t j1 = HOA_keep_ind_spar[j]; +#endif +#endif + for ( k = 0; k < num_bins; k++ ) { +#ifdef HODIRAC + pV_re[k] = ppIn_FR_real[i1][k] * ppIn_FR_real[j1][k] + ppIn_FR_imag[i1][k] * ppIn_FR_imag[j1][k]; +#else pV_re[k] = ppIn_FR_real[i][k] * ppIn_FR_real[j][k] + ppIn_FR_imag[i][k] * ppIn_FR_imag[j][k]; +#endif } for ( k = start_band; k < end_band; k++ ) diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index d617727be4bd4a5cddbd3b100b3ebd7441b2aa42..83a733fe480b976346090496e36141106f17235e 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -195,7 +195,15 @@ int16_t getNumChanAnalysis( n = st_ivas->nSCE + CPE_CHANNELS * st_ivas->nCPE; if ( st_ivas->hEncoderConfig->ivas_format == SBA_FORMAT ) { +#ifdef HODIRAC + n = ( st_ivas->sba_analysis_order + 1 ) * ( st_ivas->sba_analysis_order + 1 ); +#else +#ifdef SPAR_TUNING + n = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->ivas_total_brate ); +#else n = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); +#endif +#endif } else if ( st_ivas->hEncoderConfig->ivas_format == MC_FORMAT && ( st_ivas->mc_mode == MC_MODE_PARAMMC || st_ivas->mc_mode == MC_MODE_MCMASA ) ) { diff --git a/lib_enc/ivas_ism_param_enc.c b/lib_enc/ivas_ism_param_enc.c index 6534d215a5a8ea09fe7d5d533287c88bf3072f9d..db7ab98b10ea552895204aece8dff4bc424e739d 100644 --- a/lib_enc/ivas_ism_param_enc.c +++ b/lib_enc/ivas_ism_param_enc.c @@ -305,7 +305,12 @@ ivas_error ivas_param_ism_enc_open( /* set FB config. */ - if ( ( error = ivas_fb_set_cfg( &fb_cfg, ISM_FORMAT, SBA_MODE_NONE, st_ivas->hEncoderConfig->nchan_inp, 0, 0, input_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_fb_set_cfg( &fb_cfg, ISM_FORMAT, SBA_MODE_NONE, st_ivas->hEncoderConfig->nchan_inp, 0, 0, input_Fs +#ifdef HODIRAC + , + 0 +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -415,9 +420,19 @@ void ivas_param_ism_enc( for ( ts = 0; ts < num_time_slots; ts++ ) { - ivas_fb_mixer_get_windowed_fr( hDirAC->hFbMixer, pcm_in, p_fb_RealBuffer, p_fb_ImagBuffer, l_ts, l_ts ); + ivas_fb_mixer_get_windowed_fr( hDirAC->hFbMixer, pcm_in, p_fb_RealBuffer, p_fb_ImagBuffer, l_ts, l_ts +#ifdef HODIRAC + , + hDirAC->hFbMixer->fb_cfg->num_in_chans +#endif + ); - ivas_fb_mixer_update_prior_input( hDirAC->hFbMixer, pcm_in, l_ts ); + ivas_fb_mixer_update_prior_input( hDirAC->hFbMixer, pcm_in, l_ts +#ifdef HODIRAC + , + hDirAC->hFbMixer->fb_cfg->num_in_chans +#endif + ); for ( i = 0; i < nchan_ism; i++ ) { diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index 5b5363efb3eda26af319e9559d085bfcc877d7b5..8938a415ffc78f67051b53df1343d1373540b4a5 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -340,11 +340,17 @@ ivas_error ivas_masa_encode( else { #endif - ivas_qmetadata_enc_encode( hMetaData, hQMetaData ); + ivas_qmetadata_enc_encode( hMetaData, hQMetaData +#ifdef HODIRAC + , + 0 +#endif + ); #ifdef HR_METADATA } #endif + *nb_bits_metadata = hMetaData->nb_bits_tot; if ( ivas_format == MASA_FORMAT && Opt_DTX_ON ) diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c index 14eca6afee59ee3596c7c08a743aeb8eade52846..f32a5b60d3deaf136a848945b794141c46601116 100644 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc.c @@ -140,7 +140,12 @@ ivas_error ivas_param_mc_enc_open( hParamMC->dmx_factors = ivas_param_mc_conf[config_index].dmx_fac; /* set FB config. */ - if ( ( error = ivas_fb_set_cfg( &fb_cfg, MC_FORMAT, SBA_MODE_DIRAC, nchan_inp, 0, 0, input_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_fb_set_cfg( &fb_cfg, MC_FORMAT, SBA_MODE_DIRAC, nchan_inp, 0, 0, input_Fs +#ifdef HODIRAC + , + 0 +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -681,7 +686,12 @@ static void ivas_param_mc_param_est_enc( for ( ts = 0; ts < start_ts; ts++ ) { - ivas_fb_mixer_update_prior_input( hParamMC->hFbMixer, pcm_in, l_ts ); + ivas_fb_mixer_update_prior_input( hParamMC->hFbMixer, pcm_in, l_ts +#ifdef HODIRAC + , + hParamMC->hFbMixer->fb_cfg->num_in_chans +#endif + ); for ( i = 0; i < nchan_input; i++ ) { pcm_in[i] += l_ts; @@ -691,11 +701,22 @@ static void ivas_param_mc_param_est_enc( for ( ts = start_ts; ts < num_time_slots; ts++ ) { #ifdef PARAMMC_SHORT_ENC_MDFT - ivas_fb_mixer_get_windowed_fr( hParamMC->hFbMixer, pcm_in, p_slot_frame_f_real, p_slot_frame_f_imag, l_ts, l_ts ); + ivas_fb_mixer_get_windowed_fr( hParamMC->hFbMixer, pcm_in, p_slot_frame_f_real, p_slot_frame_f_imag, l_ts, l_ts +#ifdef HODIRAC + , + hParamMC->hFbMixer->fb_cfg->num_in_chans +#endif + ); #else ivas_fb_mixer_get_windowed_fr( hParamMC->hFbMixer, pcm_in, p_slot_frame_f_real, p_slot_frame_f_imag, l_ts, 2 * l_ts ); #endif - ivas_fb_mixer_update_prior_input( hParamMC->hFbMixer, pcm_in, l_ts ); + ivas_fb_mixer_update_prior_input( hParamMC->hFbMixer, pcm_in, l_ts +#ifdef HODIRAC + , + hParamMC->hFbMixer->fb_cfg->num_in_chans +#endif + ); + for ( i = 0; i < nchan_input; i++ ) { pcm_in[i] += l_ts; diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc.c index 8151b33c668ff1a2d382d1747b179bb81c147416..ba378ab1d68b673a3ffde43e29e168c2444ce7d8 100644 --- a/lib_enc/ivas_mcmasa_enc.c +++ b/lib_enc/ivas_mcmasa_enc.c @@ -188,7 +188,12 @@ ivas_error ivas_mcmasa_enc_open( } /* set FB config. */ - if ( ( error = ivas_fb_set_cfg( &fb_cfg, MASA_FORMAT, SBA_MODE_NONE, numAnalysisChannels, 0, 0, input_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_fb_set_cfg( &fb_cfg, MASA_FORMAT, SBA_MODE_NONE, numAnalysisChannels, 0, 0, input_Fs +#ifdef HODIRAC + , + 0 +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -219,7 +224,12 @@ ivas_error ivas_mcmasa_enc_open( else { /* Allocate and initialize FB mixer handle for LFE channel */ - if ( ( error = ivas_fb_set_cfg( &fb_cfgLfe, MASA_FORMAT, SBA_MODE_NONE, 1, 0, 0, input_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_fb_set_cfg( &fb_cfgLfe, MASA_FORMAT, SBA_MODE_NONE, 1, 0, 0, input_Fs +#ifdef HODIRAC + , + 0 +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -745,10 +755,17 @@ void ivas_mcmasa_param_est_enc( float Chnl_ImagBuffer[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX]; float *p_Chnl_RealBuffer[MCMASA_MAX_ANA_CHANS]; float *p_Chnl_ImagBuffer[MCMASA_MAX_ANA_CHANS]; +#ifdef HODIRAC + float Foa_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; + float Foa_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; + float FoaEven_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; + float FoaEven_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; +#else float Foa_RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX]; float Foa_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX]; float FoaEven_RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX]; float FoaEven_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX]; +#endif float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; float intensity_even_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; float direction_vector[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; @@ -831,8 +848,18 @@ void ivas_mcmasa_param_est_enc( for ( ts = mrange[0]; ts < mrange[1]; ts++ ) { - ivas_fb_mixer_get_windowed_fr( hMcMasa->hFbMixer, pcm_in, p_Chnl_RealBuffer, p_Chnl_ImagBuffer, l_ts, l_ts ); - ivas_fb_mixer_update_prior_input( hMcMasa->hFbMixer, pcm_in, l_ts ); + ivas_fb_mixer_get_windowed_fr( hMcMasa->hFbMixer, pcm_in, p_Chnl_RealBuffer, p_Chnl_ImagBuffer, l_ts, l_ts +#ifdef HODIRAC + , + hMcMasa->hFbMixer->fb_cfg->num_in_chans +#endif + ); + ivas_fb_mixer_update_prior_input( hMcMasa->hFbMixer, pcm_in, l_ts +#ifdef HODIRAC + , + hMcMasa->hFbMixer->fb_cfg->num_in_chans +#endif + ); for ( i = 0; i < numAnalysisChannels; i++ ) { pcm_in[i] += l_ts; @@ -973,7 +1000,12 @@ void ivas_mcmasa_param_est_enc( reference_power[ts], 0, num_freq_bands, - SBA_MODE_NONE ); + SBA_MODE_NONE +#ifdef HODIRAC + , + FOA_CHANNELS +#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 */ @@ -1702,8 +1734,18 @@ static void computeLfeEnergy( for ( ts = mrange[0]; ts < mrange[1]; ts++ ) { - ivas_fb_mixer_get_windowed_fr( hMcMasa->hFbMixerLfe, pcm_in, p_Chnl_RealBuffer, p_Chnl_ImagBuffer, l_ts, l_ts ); - ivas_fb_mixer_update_prior_input( hMcMasa->hFbMixerLfe, pcm_in, l_ts ); + ivas_fb_mixer_get_windowed_fr( hMcMasa->hFbMixerLfe, pcm_in, p_Chnl_RealBuffer, p_Chnl_ImagBuffer, l_ts, l_ts +#ifdef HODIRAC + , + hMcMasa->hFbMixerLfe->fb_cfg->num_in_chans +#endif + ); + ivas_fb_mixer_update_prior_input( hMcMasa->hFbMixerLfe, pcm_in, l_ts +#ifdef HODIRAC + , + hMcMasa->hFbMixerLfe->fb_cfg->num_in_chans +#endif + ); pcm_in[0] += l_ts; /* Compute low frequency energy for LFE, for other channels it is computed in ivas_chnl_param_est_enc() */ diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index 3a947584e9f869707194d55857b7d1d2d3de40a0..273703b3176a498af9b0eb7f6b51213f314f1cfd 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -52,7 +52,12 @@ static float direction_distance( float elevation[DIRAC_MAX_NBANDS][MAX_PARAM_SPA #endif -static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *needed_bits, int16_t *nbits_diff, int16_t *dfRatioBits ); +static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *needed_bits, int16_t *nbits_diff, int16_t *dfRatioBits +#ifdef HODIRAC + , + int16_t hodirac /* i: flag to indicate sector processing */ +#endif +); static int16_t ivas_qmetadata_entropy_encode_diffuseness( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, uint16_t *diffuseness_index_max_ec_frame ); @@ -176,6 +181,10 @@ static int16_t ivas_qmetadata_quantize_coherence_hr_512( ivas_error ivas_qmetadata_enc_encode( BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */ IVAS_QMETADATA *hQMetaData /* i/o: metadata handle */ +#ifdef HODIRAC + , + int16_t hodirac /* i: flag to indicate sector processing */ +#endif ) { int16_t i, bit_pos_start, bit_pos_start_coh; @@ -260,7 +269,12 @@ ivas_error ivas_qmetadata_enc_encode( assert( ndirections == 2 ); #endif /* Reorder 2dir bands for more efficient encoding. */ - ivas_qmetadata_reorder_2dir_bands( hQMetaData ); +#ifdef HODIRAC + if ( !hodirac ) +#endif + { + ivas_qmetadata_reorder_2dir_bands( hQMetaData ); + } d = 0; for ( i = hQMetaData->q_direction[1].cfg.start_band; i < hQMetaData->q_direction[1].cfg.nbands; i++ ) { @@ -294,7 +308,12 @@ ivas_error ivas_qmetadata_enc_encode( } /*Quantization of the Diffuseness */ - ivas_qmetadata_quantize_diffuseness_nrg_ratios( hQMetaData, bits_dir_raw_pre, bits_diff, dfRatio_bits ); + ivas_qmetadata_quantize_diffuseness_nrg_ratios( hQMetaData, bits_dir_raw_pre, bits_diff, dfRatio_bits +#ifdef HODIRAC + , + hodirac +#endif + ); bits_diff_sum = 0; bits_diff[0] = ivas_qmetadata_entropy_encode_diffuseness( hMetaData, &( hQMetaData->q_direction[0] ), &diffuseness_index_max_ec_frame_pre[0] ); @@ -1423,7 +1442,12 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr( * fact that with 2dir data, it is harder to achieve separate high direct-to-total ratio values * which are assumed by the direction quantization system. In practice, this improves direction * accuracy when it is perceptual meaningful. */ - masa_compensate_two_dir_energy_ratio_index( index_dirRatio1Inv, index_dirRatio2Inv, &index_dirRatio1Inv_mod, &index_dirRatio2Inv_mod ); + masa_compensate_two_dir_energy_ratio_index( index_dirRatio1Inv, index_dirRatio2Inv, &index_dirRatio1Inv_mod, &index_dirRatio2Inv_mod +#ifdef HODIRAC + , + 0 +#endif + ); for ( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ ) { @@ -1652,7 +1676,12 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *needed_bits, int16_t *nbits_diff, - int16_t *dfRatioBits ) + int16_t *dfRatioBits +#ifdef HODIRAC + , + int16_t hodirac /* i: flag to indicate sector processing */ +#endif +) { int16_t j, k, dir2band; int16_t index_dirRatio1Inv, index_dirRatio2Inv, index_dirRatio1Inv_mod, index_dirRatio2Inv_mod; @@ -1668,32 +1697,66 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( { if ( hQMetaData->no_directions == 2 && hQMetaData->twoDirBands[j] == 1 ) { - float dirRatio1, dirRatio2, diffRatio, sumRatio, dfRatio, dfRatioQ, diffRatioQ, dirRatio1Q, dirRatio2Q; + float diffRatio, dfRatio, dfRatioQ, diffRatioQ, dirRatio1Q, dirRatio2Q; + float dirRatio1, dirRatio2, sumRatio; int16_t dfRatio_index, dfRatio_qsteps, dfRatio_bits; /* With 2dir metadata, we quantize and transmit diffuse-to-total ratio (diffRatio) and * distribution factor of direct-to-total ratios (dFRatio). This is more efficient and * accurate than simple separate quantization of each direct-to-total ratio or their * separate inverses. */ - dirRatio1 = hQMetaData->q_direction[0].band_data[j].energy_ratio[0]; - dirRatio2 = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio[0]; - sumRatio = dirRatio1 + dirRatio2; - diffRatio = 1.0f - sumRatio; - dfRatio = sumRatio < EPSILON ? 0.5f : dirRatio1 / sumRatio; +#ifdef HODIRAC + if ( hodirac ) + { + /* already encoded as total and ratios in HODIRAC*/ + diffRatio = 1.f - hQMetaData->q_direction[0].band_data[j].energy_ratio[0]; + dfRatio = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio[0]; + } + else +#endif + { + dirRatio1 = hQMetaData->q_direction[0].band_data[j].energy_ratio[0]; + dirRatio2 = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio[0]; + sumRatio = dirRatio1 + dirRatio2; + diffRatio = 1.0f - sumRatio; + dfRatio = sumRatio < EPSILON ? 0.5f : dirRatio1 / sumRatio; + } + index_diff = masa_sq( diffRatio, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); diffRatioQ = diffuseness_reconstructions[index_diff]; - dfRatio_bits = ivas_get_df_ratio_bits( index_diff ); +#ifdef HODIRAC + if ( hodirac ) + { + dfRatio_bits = ivas_get_df_ratio_bits_hodirac( index_diff ); + } + else +#endif + { + dfRatio_bits = ivas_get_df_ratio_bits( index_diff ); + } dfRatioBits[dir2band] = dfRatio_bits; dfRatio_qsteps = ( 1 << dfRatio_bits ); - dfRatio_index = usquant( dfRatio, &dfRatioQ, 0.5f, 0.5f / ( dfRatio_qsteps - 1 ), dfRatio_qsteps ); +#ifdef HODIRAC + if ( hodirac ) + { + dfRatio_index = usquant( dfRatio, &dfRatioQ, 0.0f, 1.f / ( dfRatio_qsteps - 1 ), dfRatio_qsteps ); + dirRatio1Q = 1.f - diffRatioQ; + dirRatio2Q = dfRatioQ; + } + else +#endif + { + dfRatio_index = usquant( dfRatio, &dfRatioQ, 0.5f, 0.5f / ( dfRatio_qsteps - 1 ), dfRatio_qsteps ); + + /* Direction quantization requires also separately quantized direct-to-total ratios. Thus, we calculate them. */ + dirRatio1Q = dfRatioQ * ( 1.0f - diffRatioQ ); + dirRatio2Q = ( 1.0f - diffRatioQ ) - dirRatio1Q; + } - /* Direction quantization requires also separately quantized direct-to-total ratios. Thus, we calculate them. */ - dirRatio1Q = dfRatioQ * ( 1.0f - diffRatioQ ); - dirRatio2Q = ( 1.0f - diffRatioQ ) - dirRatio1Q; index_dirRatio1Inv = masa_sq( 1.0f - dirRatio1Q, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); @@ -1706,8 +1769,18 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( hQMetaData->q_direction[0].band_data[j].energy_ratio[k] = dirRatio1Q; } nbits_diff[0] += MASA_BITS_ER; +#ifdef HODIRAC + if ( hodirac ) + { + float tmp; + index_dirRatio2Inv = usquant( dirRatio2Q, &tmp, 0.0f, 1.f / ( DIRAC_DIFFUSE_LEVELS - 1 ), DIRAC_DIFFUSE_LEVELS ); + } + else +#endif + { + index_dirRatio2Inv = masa_sq( 1.0f - dirRatio2Q, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); + } - index_dirRatio2Inv = masa_sq( 1.0f - dirRatio2Q, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); for ( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ ) { hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[k] = dfRatio_index; @@ -1719,7 +1792,12 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( * fact that with 2dir data, it is harder to achieve separate high direct-to-total ratio values * which are assumed by the direction quantization system. In practice, this improves direction * accuracy when it is perceptual meaningful. */ - masa_compensate_two_dir_energy_ratio_index( index_dirRatio1Inv, index_dirRatio2Inv, &index_dirRatio1Inv_mod, &index_dirRatio2Inv_mod ); + masa_compensate_two_dir_energy_ratio_index( index_dirRatio1Inv, index_dirRatio2Inv, &index_dirRatio1Inv_mod, &index_dirRatio2Inv_mod +#ifdef HODIRAC + , + hodirac +#endif + ); for ( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ ) { @@ -5778,14 +5856,23 @@ static void ivas_qmetadata_reorder_2dir_bands( hQMetaData->q_direction[0].band_data[band].distance[sf] = hQMetaData->q_direction[1].band_data[band].distance[sf]; hQMetaData->q_direction[1].band_data[band].distance[sf] = uint8_tmp; - uint8_tmp = hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf]; - hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf]; - hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf] = uint8_tmp; +#ifdef HODIRAC + if ( hQMetaData->coherence_flag ) +#endif + { + uint8_tmp = hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf]; + hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf]; + hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf] = uint8_tmp; + } + } +#ifdef HODIRAC + if ( hQMetaData->coherence_flag ) +#endif + { + flt_tmp = hQMetaData->q_direction[0].band_data[band].energy_ratio[0]; + hQMetaData->q_direction[0].band_data[band].energy_ratio[0] = hQMetaData->q_direction[1].band_data[band].energy_ratio[0]; + hQMetaData->q_direction[1].band_data[band].energy_ratio[0] = flt_tmp; } - - flt_tmp = hQMetaData->q_direction[0].band_data[band].energy_ratio[0]; - hQMetaData->q_direction[0].band_data[band].energy_ratio[0] = hQMetaData->q_direction[1].band_data[band].energy_ratio[0]; - hQMetaData->q_direction[1].band_data[band].energy_ratio[0] = flt_tmp; } } } @@ -5917,6 +6004,16 @@ static void transform_azimuth_dir2( { hQMetaData->q_direction[1].band_data[i].azimuth[b] += 360; } +#ifdef HODIRAC + if ( hQMetaData->q_direction[1].band_data[i].azimuth[b] >= 180 ) + { + hQMetaData->q_direction[1].band_data[i].azimuth[b] -= 360; + } + if ( hQMetaData->q_direction[1].band_data[i].azimuth[b] < -180 ) + { + hQMetaData->q_direction[1].band_data[i].azimuth[b] += 360; + } +#endif #ifdef DEBUGGING assert( hQMetaData->q_direction[1].band_data[i].azimuth[b] < 180 && hQMetaData->q_direction[1].band_data[i].azimuth[b] >= -180 ); #endif diff --git a/lib_enc/ivas_sba_enc.c b/lib_enc/ivas_sba_enc.c index d9fb1fef8347bb3e63131e06481d48c927b1a050..35d22fe461cda1a059825ee4e0bf7ee4629fb15c 100644 --- a/lib_enc/ivas_sba_enc.c +++ b/lib_enc/ivas_sba_enc.c @@ -134,8 +134,13 @@ ivas_error ivas_sba_enc_reconfigure( int16_t i, n_old; float **old_mem_hp20_in; +#ifdef HODIRAC + n_old = ( analysis_order_old + 1 ) * ( analysis_order_old + 1 ); + n = ( st_ivas->sba_analysis_order + 1 ) * ( st_ivas->sba_analysis_order + 1 ); +#else n_old = ivas_sba_get_nchan_metadata( analysis_order_old ); n = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); +#endif if ( n > n_old ) { @@ -216,7 +221,11 @@ ivas_error ivas_sba_enc_reconfigure( { hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; } - if ( nchan_transport_old != st_ivas->nchan_transport ) + if ( nchan_transport_old != st_ivas->nchan_transport +#ifdef HODIRAC + || ( ivas_total_brate < IVAS_512k && hEncoderConfig->last_ivas_total_brate >= IVAS_512k ) || ( ivas_total_brate >= IVAS_512k && hEncoderConfig->last_ivas_total_brate < IVAS_512k ) +#endif + ) { /* FB mixer handle */ if ( hDirAC->hFbMixer != NULL ) diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index b13bb4f20d0fd7aeb0d07d562bc1c3de74e2d3ed..5ca91f334f68c4d8ef420dc039514061bbae4fdc 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -66,6 +66,9 @@ ivas_error ivas_spar_enc_open( ENCODER_CONFIG_HANDLE hEncoderConfig; IVAS_FB_CFG *fb_cfg; int16_t nchan_inp, nchan_transport, sba_order_internal; +#ifdef HODIRAC + int16_t nchan_fb_in; +#endif int16_t table_idx, active_w_mixing; int32_t input_Fs, ivas_total_brate; ivas_error error; @@ -85,10 +88,34 @@ ivas_error ivas_spar_enc_open( input_Fs = hEncoderConfig->input_Fs; sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); - nchan_inp = ivas_sba_get_nchan_metadata( sba_order_internal ); + nchan_inp = ivas_sba_get_nchan_metadata( sba_order_internal +#ifdef SPAR_TUNING + , + hEncoderConfig->ivas_total_brate +#endif + ); assert( nchan_inp <= hEncoderConfig->nchan_inp ); ivas_total_brate = hEncoderConfig->ivas_total_brate; +#ifdef HODIRAC + nchan_fb_in = 0; + if ( st_ivas->sba_analysis_order == 1 ) + { + nchan_fb_in = FOA_CHANNELS; + } + else if ( st_ivas->sba_analysis_order == 2 ) + { + nchan_fb_in = 9; + } + else if ( st_ivas->sba_analysis_order == 3 ) + { + nchan_fb_in = 11; + } + else + { + assert( 0 && "sba_order must be 1,2, or 3!" ); + } +#endif nchan_transport = ivas_get_sba_num_TCs( hEncoderConfig->ivas_total_brate, sba_order_internal ); // bw = ivas_get_bw_idx_from_sample_rate(pCfg->input_Fs); @@ -103,7 +130,12 @@ ivas_error ivas_spar_enc_open( /* set FB config. */ active_w_mixing = ivas_spar_br_table_consts[table_idx].active_w; - ivas_fb_set_cfg( &fb_cfg, SBA_FORMAT, SBA_MODE_SPAR, nchan_inp, nchan_transport, active_w_mixing, input_Fs ); + ivas_fb_set_cfg( &fb_cfg, SBA_FORMAT, SBA_MODE_SPAR, nchan_inp, nchan_transport, active_w_mixing, input_Fs +#ifdef HODIRAC + , + nchan_fb_in +#endif + ); fb_cfg->remix_order = remix_order_set[hSpar->hMdEnc->spar_md_cfg.remix_unmix_order]; /* FB mixer handle */ @@ -389,10 +421,17 @@ static ivas_error ivas_spar_enc_process( float data_f[][L_FRAME48k] /* i/o: input/transport audio channels */ ) { +#ifdef HODIRAC + float pcm_tmp[DIRAC_MAX_ANA_CHANS][L_FRAME48k * 2]; + float *p_pcm_tmp[DIRAC_MAX_ANA_CHANS]; +#else float pcm_tmp[IVAS_SPAR_MAX_CH][L_FRAME48k * 2]; float *p_pcm_tmp[IVAS_SPAR_MAX_CH]; +#endif + int16_t i, j, b, i_ts, input_frame, dtx_vad; int16_t transient_det[2]; + int32_t ivas_total_brate, input_Fs; float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; @@ -404,6 +443,7 @@ static ivas_error ivas_spar_enc_process( SPAR_ENC_HANDLE hSpar = st_ivas->hSpar; IVAS_QMETADATA_HANDLE hQMetaData = st_ivas->hQMetaData; int16_t ts, l_ts, orig_dirac_bands, num_del_samples; + float *ppIn_FR_real[IVAS_SPAR_MAX_CH], *ppIn_FR_imag[IVAS_SPAR_MAX_CH]; #ifdef SBA_TD_RESIDUAL float wyzx_del_buf[FOA_CHANNELS][IVAS_FB_1MS_48K_SAMP]; @@ -412,6 +452,9 @@ static ivas_error ivas_spar_enc_process( #endif float dir[3], avg_dir[3]; float energySum, vecLen; +#ifdef HODIRAC + int16_t nchan_fb_in; +#endif push_wmops( "ivas_spar_enc_process" ); @@ -427,15 +470,32 @@ static ivas_error ivas_spar_enc_process( input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC ); sba_order = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); - nchan_inp = ivas_sba_get_nchan_metadata( sba_order ); + nchan_inp = ivas_sba_get_nchan_metadata( sba_order +#ifdef SPAR_TUNING + , + hEncoderConfig->ivas_total_brate +#endif + ); assert( nchan_inp <= hEncoderConfig->nchan_inp ); + int16_t active_w_vlbr; active_w_vlbr = ( hEncoderConfig->ivas_total_brate < IVAS_24k4 ) ? 1 : 0; + +#ifdef HODIRAC + nchan_fb_in = hSpar->hFbMixer->fb_cfg->nchan_fb_in; + nchan_transport = st_ivas->nchan_transport; +#endif + +#ifdef HODIRAC + for ( i = FOA_CHANNELS + 1; i < nchan_fb_in; i++ ) +#else for ( i = FOA_CHANNELS + 1; i < nchan_inp; i++ ) +#endif { mvr2r( data_f[HOA_keep_ind[i]], data_f[i], input_frame ); } + /*-----------------------------------------------------------------------------------------* * Transient detector *-----------------------------------------------------------------------------------------*/ @@ -469,16 +529,29 @@ static ivas_error ivas_spar_enc_process( * FB mixer ingest *-----------------------------------------------------------------------------------------*/ +#ifdef HODIRAC + for ( i = 0; i < nchan_fb_in; i++ ) +#else for ( i = 0; i < nchan_inp; i++ ) +#endif { p_pcm_tmp[i] = pcm_tmp[i]; } /* run Filter Bank overlapping MDFT analysis first, then we can use the temporary buffer for Parameter MDFT analysis*/ - ivas_fb_mixer_pcm_ingest( hSpar->hFbMixer, data_f, p_pcm_tmp, input_frame ); + ivas_fb_mixer_pcm_ingest( hSpar->hFbMixer, data_f, p_pcm_tmp, input_frame +#ifdef SPAR_TUNING + , + hSpar->hMdEnc->HOA_md_ind +#endif + ); /* prepare Parameter MDFT analysis */ +#ifdef HODIRAC + for ( i = 0; i < nchan_fb_in; i++ ) +#else for ( i = 0; i < nchan_inp; i++ ) +#endif { ppIn_FR_real[i] = p_pcm_tmp[i]; ppIn_FR_imag[i] = p_pcm_tmp[i] + input_frame; @@ -489,10 +562,24 @@ static ivas_error ivas_spar_enc_process( for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) { - ivas_fb_mixer_get_windowed_fr( hSpar->hFbMixer, p_pcm_tmp, ppIn_FR_real, ppIn_FR_imag, l_ts, l_ts ); - ivas_fb_mixer_update_prior_input( hSpar->hFbMixer, p_pcm_tmp, l_ts ); + ivas_fb_mixer_get_windowed_fr( hSpar->hFbMixer, p_pcm_tmp, ppIn_FR_real, ppIn_FR_imag, l_ts, l_ts +#ifdef HODIRAC + , + nchan_fb_in +#endif + ); + ivas_fb_mixer_update_prior_input( hSpar->hFbMixer, p_pcm_tmp, l_ts +#ifdef HODIRAC + , + nchan_fb_in +#endif + ); +#ifdef HODIRAC + for ( i = 0; i < nchan_fb_in; i++ ) +#else for ( i = 0; i < nchan_inp; i++ ) +#endif { p_pcm_tmp[i] += l_ts; ppIn_FR_real[i] += l_ts; @@ -501,7 +588,11 @@ static ivas_error ivas_spar_enc_process( } /* turn pointers back to the local buffer, needed for the following processing */ +#ifdef HODIRAC + for ( i = 0; i < nchan_fb_in; i++ ) +#else for ( i = 0; i < nchan_inp; i++ ) +#endif { ppIn_FR_real[i] = pcm_tmp[i]; ppIn_FR_imag[i] = pcm_tmp[i] + input_frame; @@ -513,8 +604,14 @@ static ivas_error ivas_spar_enc_process( /*-----------------------------------------------------------------------------------------* * DirAC encoding *-----------------------------------------------------------------------------------------*/ - - ivas_dirac_param_est_enc( st_ivas->hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes, data_f, ppIn_FR_real, ppIn_FR_imag, input_frame, st_ivas->sba_mode ); + /*tyagiri: TODO: HODIRAC should be disabled for 256 kbps and outputs should be BE w.r.t baseline*/ + ivas_dirac_param_est_enc( st_ivas->hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes, data_f, ppIn_FR_real, ppIn_FR_imag, input_frame, st_ivas->sba_mode +#ifdef HODIRAC + , + st_ivas->sba_analysis_order > 1 && ivas_total_brate > IVAS_256k, + st_ivas->sba_analysis_order > 1 && ivas_total_brate > IVAS_256k ? HOA2_CHANNELS : FOA_CHANNELS +#endif + ); if ( hQMetaData->q_direction->cfg.nbands > 0 ) { @@ -524,14 +621,26 @@ static ivas_error ivas_spar_enc_process( { /* WB 4TC mode bit : disable for now*/ push_next_indice( hMetaData, 0, 1 ); - ivas_qmetadata_enc_encode( hMetaData, hQMetaData ); + + ivas_qmetadata_enc_encode( hMetaData, hQMetaData +#ifdef HODIRAC + , + st_ivas->sba_analysis_order > 1 && ivas_total_brate > IVAS_256k +#endif + ); } else { + hQMetaData->q_direction[0].cfg.nbands = DIRAC_DTX_BANDS; /* compute directions */ + +#ifdef HODIRAC + for ( i = 0; i < hQMetaData->q_direction[0].cfg.nblocks; i++ ) +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) +#endif { set_zero( dir, 3 ); set_zero( avg_dir, 3 ); @@ -631,7 +740,23 @@ static ivas_error ivas_spar_enc_process( } } - 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 ); + 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 +#ifdef SPAR_TUNING + , + hSpar->hMdEnc->HOA_md_ind +#endif + ); nchan_transport = st_ivas->nchan_transport; /*-----------------------------------------------------------------------------------------* @@ -643,7 +768,9 @@ 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 ); } - +#ifdef SPAR_TUNING + if ( hSpar->hMdEnc->spar_hoa_dirac2spar_md_flag ) +#endif { float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; @@ -660,8 +787,8 @@ static ivas_error ivas_spar_enc_process( 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]; + azi_dirac[b][i_ts] = hQMetaData->q_direction[0].band_data[dirac_band_idx].azimuth[i_ts]; + ele_dirac[b][i_ts] = hQMetaData->q_direction[0].band_data[dirac_band_idx].elevation[i_ts]; } diffuseness[b] = 1.0f - hQMetaData->q_direction->band_data[dirac_band_idx].energy_ratio[0]; } diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index cdfd6050ba872863a211f53c84c258bf1fcbc118..d27f149b6de2d35bb33e1ce65990ea845b16553e 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -119,7 +119,12 @@ ivas_error ivas_spar_md_enc_open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD encoder" ); } - num_channels = ivas_sba_get_nchan_metadata( sba_order ); + num_channels = ivas_sba_get_nchan_metadata( sba_order +#ifdef SPAR_TUNING + , + hEncoderConfig->ivas_total_brate +#endif + ); if ( ( hMdEnc->spar_md.band_coeffs = (ivas_band_coeffs_t *) malloc( IVAS_MAX_NUM_BANDS * sizeof( ivas_band_coeffs_t ) ) ) == NULL ) { @@ -314,9 +319,20 @@ ivas_error ivas_spar_md_enc_init( float PR_minmax[2]; int16_t num_channels, i, j, k; +#ifdef SPAR_TUNING + ivas_sba_get_spar_hoa_md_flag( sba_order, hEncoderConfig->ivas_total_brate, &hMdEnc->spar_hoa_md_flag, &hMdEnc->spar_hoa_dirac2spar_md_flag ); +#else hMdEnc->spar_hoa_md_flag = ivas_sba_get_spar_hoa_md_flag( sba_order, hEncoderConfig->ivas_total_brate ); - num_channels = ivas_sba_get_nchan_metadata( sba_order ); - +#endif + num_channels = ivas_sba_get_nchan_metadata( sba_order +#ifdef SPAR_TUNING + , + hEncoderConfig->ivas_total_brate +#endif + ); +#ifdef SPAR_TUNING + ivas_sba_get_spar_hoa_ch_ind( num_channels, hEncoderConfig->ivas_total_brate, hMdEnc->HOA_md_ind ); +#endif table_idx = ivas_get_spar_table_idx( hEncoderConfig->ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); ivas_spar_set_bitrate_config( &hMdEnc->spar_md_cfg, table_idx, ( hMdEnc->spar_hoa_md_flag ) ? IVAS_MAX_NUM_BANDS : SPAR_DIRAC_SPLIT_START_BAND ); @@ -550,9 +566,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]; + int16_t i, j, b, qsi, ndm, ndec, num_ch, num_quant_strats; + int16_t planarCP; float pred_coeffs_re_local[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; - int16_t i, b, qsi, ndm, ndec, num_ch, num_quant_strats; - int16_t j, planarCP; int16_t k, bwidth, num_bands, num_bands_full, num_bands_bw; int16_t active_w, nchan_transport, dmx_switch, strat; int16_t nB, bands_bw, packed_ok = 0; @@ -564,7 +580,12 @@ ivas_error ivas_spar_md_enc_process( float Wscale[IVAS_MAX_NUM_BANDS]; num_quant_strats = hMdEnc->spar_md_cfg.num_quant_strats; - num_ch = ivas_sba_get_nchan_metadata( sba_order ); + num_ch = ivas_sba_get_nchan_metadata( sba_order +#ifdef SPAR_TUNING + , + hEncoderConfig->ivas_total_brate +#endif + ); active_w = hMdEnc->spar_md_cfg.active_w; nchan_transport = hMdEnc->spar_md_cfg.nchan_transport; @@ -636,8 +657,11 @@ ivas_error ivas_spar_md_enc_process( nB = num_bands; bands_bw = 1; } - +#ifdef SPAR_TUNING + if ( hMdEnc->spar_hoa_md_flag && hMdEnc->spar_hoa_dirac2spar_md_flag ) +#else if ( hMdEnc->spar_hoa_md_flag ) +#endif { for ( b = SPAR_DIRAC_SPLIT_START_BAND; b < num_bands; b++ ) { @@ -814,7 +838,11 @@ ivas_error ivas_spar_md_enc_process( } } +#ifdef SPAR_TUNING + if ( hMdEnc->spar_hoa_md_flag && hMdEnc->spar_hoa_dirac2spar_md_flag ) +#else if ( hMdEnc->spar_hoa_md_flag ) +#endif { for ( b = SPAR_DIRAC_SPLIT_START_BAND; b < num_bands; b++ ) { @@ -1403,7 +1431,11 @@ static void ivas_get_huffman_coded_bs( pred_coeff_dim = ndm + ndec - 1; pred_offset = 0; +#ifdef SPAR_TUNING + if ( hMdEnc->spar_hoa_md_flag && hMdEnc->spar_hoa_dirac2spar_md_flag ) +#else if ( hMdEnc->spar_hoa_md_flag ) +#endif { if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) { @@ -1480,7 +1512,8 @@ static void ivas_get_arith_coded_bs( const int16_t strat, const int32_t ivas_total_brate ) { - int16_t i, j, any_diff; + int16_t i, any_diff; + int16_t j; ivas_cell_dim_t pred_cell_dims[IVAS_MAX_NUM_BANDS]; ivas_cell_dim_t drct_cell_dims[IVAS_MAX_NUM_BANDS]; ivas_cell_dim_t decd_cell_dims[IVAS_MAX_NUM_BANDS]; @@ -1493,6 +1526,7 @@ static void ivas_get_arith_coded_bs( int16_t ndm, ndec; 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]; + if ( ( ivas_total_brate < IVAS_24k4 ) && ( strat > 3 ) && ( ( ( i % 2 == 1 ) && ( strat % 2 == 0 ) ) || ( ( i % 2 == 0 ) && ( strat % 2 == 1 ) ) ) ) { pred_cell_dims[i].dim1 = 0; @@ -1507,7 +1541,11 @@ static void ivas_get_arith_coded_bs( else { pred_cell_dims[i].dim1 = ndm + ndec - 1; - if ( hMdEnc->spar_hoa_md_flag ) + if ( hMdEnc->spar_hoa_md_flag +#ifdef SPAR_TUNING + && hMdEnc->spar_hoa_dirac2spar_md_flag +#endif + ) { if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) { @@ -1533,7 +1571,11 @@ static void ivas_get_arith_coded_bs( break; } } +#ifdef SPAR_TUNING + if ( hMdEnc->spar_hoa_md_flag && hMdEnc->spar_hoa_dirac2spar_md_flag ) +#else if ( hMdEnc->spar_hoa_md_flag ) +#endif { for ( i = 0; i < nB; i++ ) { @@ -1563,7 +1605,11 @@ 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 SPAR_TUNING + if ( hMdEnc->spar_hoa_md_flag && hMdEnc->spar_hoa_dirac2spar_md_flag ) +#else if ( hMdEnc->spar_hoa_md_flag ) +#endif { for ( i = 0; i < nB; i++ ) { diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 9dfafbbc04fba7a832c29c042af618d7703dc179..5eced57880563a0edad11a10d9fa31a13d17fc69 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -656,6 +656,10 @@ typedef struct ivas_spar_md_enc_state_t ivas_huff_coeffs_t huff_coeffs; int16_t table_idx; int16_t spar_hoa_md_flag; +#ifdef SPAR_TUNING + int16_t spar_hoa_dirac2spar_md_flag; + int16_t HOA_md_ind[IVAS_SPAR_MAX_CH]; +#endif } ivas_spar_md_enc_state_t; /* PCA structure */ @@ -806,8 +810,13 @@ typedef struct ivas_mcmasa_enc_data_structure float **buffer_intensity_real_vert; float *buffer_energy; +#ifdef HODIRAC + float chnlToFoaMtx[FOA_CHANNELS][MCMASA_MAX_ANA_CHANS]; + float chnlToFoaEvenMtx[FOA_CHANNELS][MCMASA_MAX_ANA_CHANS]; +#else float chnlToFoaMtx[DIRAC_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; float chnlToFoaEvenMtx[DIRAC_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; +#endif float ls_azimuth[MCMASA_MAX_ANA_CHANS]; int16_t leftNearest[MCMASA_MAX_ANA_CHANS]; int16_t rightNearest[MCMASA_MAX_ANA_CHANS]; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 7744a6582b1e019890f23f5c7417d340e7ed0876..731b284b0e95d4c702c044d1a018bfcad4129ed0 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2195,6 +2195,10 @@ static ivas_error initMasaDummyDecForMcOut( output_config = getIvasAudioConfigFromRendAudioConfig( outConfig ); decDummy->hDecoderConfig->output_config = output_config; +#ifdef HODIRAC + decDummy->sba_analysis_order = 1; +#endif + decDummy->hDecoderConfig->ivas_total_brate = IVAS_512k; /* Todo Nokia: This is preventing initialization of 2TC as 1TC, should be fixed properly in ivas_dirac_dec_config() */ decDummy->sba_mode = SBA_MODE_NONE; /* Todo Nokia: This is done to prevent ivas_dirac_dec_config() to not use uninitialized value. It could be considered if this should not be even accessed when not in SBA. */ decDummy->mc_mode = MC_MODE_NONE; /* Todo Nokia: This should be also refactored in such way that it is not checked if not in MC mode */ @@ -2282,6 +2286,10 @@ static ivas_error initMasaDummyDecForSbaOut( decDummy->sba_mode = SBA_MODE_NONE; /* Todo Nokia: This is done to prevent ivas_dirac_dec_config() to not use uninitialized value. It could be considered if this should not be even accessed when not in SBA. */ decDummy->mc_mode = MC_MODE_NONE; /* Todo Nokia: This should be also refactored in such way that it is not checked if not in MC mode */ +#ifdef HODIRAC + decDummy->sba_analysis_order = 1; +#endif + ivas_output_init( &( decDummy->hOutSetup ), output_config ); ivas_output_init( &( decDummy->hIntSetup ), output_config ); decDummy->renderer_type = RENDERER_DIRAC; @@ -2348,6 +2356,10 @@ static ivas_error initMasaDummyDecForBinauralOut( output_config = decDummy->hDecoderConfig->output_config; +#ifdef HODIRAC + decDummy->sba_analysis_order = 1; +#endif + decDummy->hDecoderConfig->ivas_total_brate = IVAS_512k; /* Todo Nokia: This is preventing initialization of 2TC as 1TC, should be fixed properly in ivas_dirac_dec_config() */ decDummy->sba_mode = SBA_MODE_NONE; /* Todo Nokia: This is done to prevent ivas_dirac_dec_config() to not use uninitialized value. It could be considered if this should not be even accessed when not in SBA. */ decDummy->mc_mode = MC_MODE_NONE; /* Todo Nokia: This should be also refactored in such way that it is not checked if not in MC mode */