From f3531bee7c841be043f44a0e05ac3312a7bd5056 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 14 Jul 2022 09:44:56 +0200 Subject: [PATCH 1/4] rename in-function parameters to match their input function names --- lib_com/ivas_prot.h | 6 +++--- lib_enc/ivas_core_pre_proc_front.c | 16 ++++++++-------- lib_enc/ivas_sce_enc.c | 4 +--- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index ac4cd3fce1..a26a7e2f8f 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -182,9 +182,9 @@ ivas_error pre_proc_front_ivas( const int16_t localVAD_HE_SAD_LR[CPE_CHANNELS], /* i : HE-SAD flag without hangover, LR channels */ float band_energies_LR[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN */ const int16_t flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz */ - const int16_t spar_front_vad_flag, /* i : front-VAD flag to overwrite VAD decision */ - const int16_t spar_force_front_vad, /* i : flag to force VAD decision */ - const int16_t spar_front_vad_dtx_flag /* i : front-VAD DTX flag to overwrite VAD decision*/ + const int16_t front_vad_flag, /* i : front-VAD flag to overwrite VAD decision */ + const int16_t force_front_vad, /* i : flag to force VAD decision */ + const int16_t front_vad_dtx_flag /* i : front-VAD DTX flag to overwrite VAD decision*/ ); ivas_error pre_proc_ivas( diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index c0dc1b7276..ea2694a888 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -98,9 +98,9 @@ ivas_error pre_proc_front_ivas( const int16_t localVAD_HE_SAD_LR[CPE_CHANNELS], /* i : HE-SAD flag without hangover, LR channels */ float band_energies_LR[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN */ const int16_t flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz */ - const int16_t spar_front_vad_flag, /* i : front-VAD flag to overwrite VAD decision */ - const int16_t spar_force_front_vad, /* i : flag to force VAD decision */ - const int16_t spar_front_vad_dtx_flag /* i : front-VAD DTX flag to overwrite VAD decision*/ + const int16_t front_vad_flag, /* i : front-VAD flag to overwrite VAD decision */ + const int16_t force_front_vad, /* i : flag to force VAD decision */ + const int16_t front_vad_dtx_flag /* i : front-VAD DTX flag to overwrite VAD decision*/ ) { float *inp_12k8, *new_inp_12k8; /* pointers to current frame and new data */ @@ -442,11 +442,11 @@ ivas_error pre_proc_front_ivas( } #endif - if ( spar_force_front_vad == 1 || spar_front_vad_flag == 1 ) + if ( force_front_vad == 1 || front_vad_flag == 1 ) { /* overwrite VAD decision with front-VAD decision if external VAD is set to 1*/ - st->vad_flag = spar_front_vad_flag; - st->localVAD = spar_front_vad_flag; + st->vad_flag = front_vad_flag; + st->localVAD = front_vad_flag; } if ( ( hCPE != NULL && !( lr_vad_enabled && st->idchan == 0 ) ) || hSCE != NULL ) @@ -466,10 +466,10 @@ ivas_error pre_proc_front_ivas( *vad_hover_flag = *vad_flag_dtx && !( LR_localVAD || st->localVAD ); } - if ( spar_force_front_vad == 1 || spar_front_vad_dtx_flag == 1 ) + if ( force_front_vad == 1 || front_vad_dtx_flag == 1 ) { /* overwrite VAD decision with front-VAD decision if external VAD is set to 1*/ - *vad_flag_dtx = spar_front_vad_dtx_flag; + *vad_flag_dtx = front_vad_dtx_flag; } /*----------------------------------------------------------------* diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index c6bf72e4a7..28ad7350ee 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -183,10 +183,8 @@ ivas_error ivas_sce_enc( error = pre_proc_front_ivas( hSCE, NULL, hSCE->element_brate, nb_bits_metadata, input_frame, 0, old_inp_12k8[0], old_inp_16k[0], &Etot[0], &ener[0], &relE[0], A[0], Aw[0], epsP[0], lsp_new[0], lsp_mid[0], &vad_hover_flag[0], &attack_flag[0], realBuffer[0], imagBuffer[0], old_wsp[0], pitch_fr[0], voicing_fr[0], &loc_harm[0], &cor_map_sum[0], &vad_flag_dtx[0], enerBuffer[0], - fft_buff[0], A[0], lsp_new[0], currFlatness[0], 0, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, NULL, - flag_16k_smc, + fft_buff[0], A[0], lsp_new[0], currFlatness[0], 0, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, NULL, flag_16k_smc, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->force_front_vad : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_dtx_flag : 0 ); - if ( error != IVAS_ERR_OK ) { return error; -- GitLab From 5e52d728b6ae0bd9b378fd55cb2e9ff7feb2452e Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 14 Jul 2022 09:55:55 +0200 Subject: [PATCH 2/4] move initialization of parameter 'dtx_sce_sba' to ivas_init_encoder() --- lib_enc/ivas_init_enc.c | 12 ++++++++---- lib_enc/ivas_sce_enc.c | 5 ----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index 0e67b75cb5..c78bce4b85 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -430,11 +430,10 @@ ivas_error ivas_init_encoder( return error; } } + + if ( ( error = ivas_dirac_enc_open( st_ivas ) ) != IVAS_ERR_OK ) { - if ( ( error = ivas_dirac_enc_open( st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } } else @@ -459,6 +458,11 @@ ivas_error ivas_init_encoder( st_ivas->hSCE[sce_id]->hMetaData->ind_list = ind_list_metadata[sce_id]; reset_indices_enc( st_ivas->hSCE[sce_id]->hMetaData, MAX_BITS_METADATA ); + + if ( st_ivas->sba_mode == SBA_MODE_SPAR && st_ivas->hEncoderConfig->Opt_DTX_ON ) + { + st_ivas->hSCE[sce_id]->hCoreCoder[0]->dtx_sce_sba = 1; + } } for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index 28ad7350ee..388e7b4875 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -175,11 +175,6 @@ ivas_error ivas_sce_enc( * Front Pre-processing *----------------------------------------------------------------*/ - if ( st_ivas->sba_mode == SBA_MODE_SPAR && st_ivas->hEncoderConfig->Opt_DTX_ON ) - { - st->dtx_sce_sba = 1; - } - error = pre_proc_front_ivas( hSCE, NULL, hSCE->element_brate, nb_bits_metadata, input_frame, 0, old_inp_12k8[0], old_inp_16k[0], &Etot[0], &ener[0], &relE[0], A[0], Aw[0], epsP[0], lsp_new[0], lsp_mid[0], &vad_hover_flag[0], &attack_flag[0], realBuffer[0], imagBuffer[0], old_wsp[0], pitch_fr[0], voicing_fr[0], &loc_harm[0], &cor_map_sum[0], &vad_flag_dtx[0], enerBuffer[0], -- GitLab From 82dd05d911e9a277685299aea7792a2bf45091b4 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 14 Jul 2022 10:11:52 +0200 Subject: [PATCH 3/4] rename/remove SPAR source files containing *foa* in the name --- Workspace_msvc/lib_com.vcxproj | 1 - Workspace_msvc/lib_com.vcxproj.filters | 3 - Workspace_msvc/lib_dec.vcxproj | 3 +- Workspace_msvc/lib_dec.vcxproj.filters | 9 +- Workspace_msvc/lib_enc.vcxproj | 3 +- Workspace_msvc/lib_enc.vcxproj.filters | 5 +- lib_com/ivas_prot.h | 38 +- lib_com/ivas_spar_com.c | 180 +++ lib_com/ivas_spar_foa_br_dist.c | 224 ---- lib_dec/ivas_spar_decoder.c | 968 ++++++++++++++++ lib_dec/ivas_spar_foa_dec.c | 1012 ----------------- ...s_spar_foa_md_dec.c => ivas_spar_md_dec.c} | 0 lib_enc/ivas_spar_encoder.c | 622 ++++++++++ lib_enc/ivas_spar_foa_enc.c | 661 ----------- ...s_spar_foa_md_enc.c => ivas_spar_md_enc.c} | 0 15 files changed, 1788 insertions(+), 1941 deletions(-) delete mode 100644 lib_com/ivas_spar_foa_br_dist.c delete mode 100644 lib_dec/ivas_spar_foa_dec.c rename lib_dec/{ivas_spar_foa_md_dec.c => ivas_spar_md_dec.c} (100%) delete mode 100644 lib_enc/ivas_spar_foa_enc.c rename lib_enc/{ivas_spar_foa_md_enc.c => ivas_spar_md_enc.c} (100%) diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index a8063b8498..144ceed2da 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -261,7 +261,6 @@ - diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index c33a360403..f9d7920ca2 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -445,9 +445,6 @@ common_ivas_c - - common_ivas_c - common_ivas_c diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 94abc50aeb..3bde19ca47 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -327,8 +327,7 @@ - - + diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index 13ac1ed646..155b8dfc45 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -527,9 +527,6 @@ dec_ivas_c - - dec_ivas_c - dec_ivas_c @@ -539,9 +536,6 @@ dec_ivas_c - - dec_ivas_c - dec_ivas_c @@ -584,6 +578,9 @@ dec_ivas_c + + dec_ivas_c + diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 7eb81ef8e2..0e21d3f4a3 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -215,8 +215,7 @@ - - + diff --git a/Workspace_msvc/lib_enc.vcxproj.filters b/Workspace_msvc/lib_enc.vcxproj.filters index 5874c4a627..471a5f9a64 100644 --- a/Workspace_msvc/lib_enc.vcxproj.filters +++ b/Workspace_msvc/lib_enc.vcxproj.filters @@ -575,13 +575,10 @@ enc_ivas_c - - enc_ivas_c - enc_ivas_c - + enc_ivas_c diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index a26a7e2f8f..c75eb39f17 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3827,15 +3827,6 @@ void ivas_tda( const float *pIn, float *pOut, const int16_t length ); void ivas_imdct( const float *pIn, float *pOut, const int16_t length ); void ivas_itda( const float *re, float *pOut, const int16_t length ); -/* FOA module */ -ivas_error ivas_spar_enc_process( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ - BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ - const int16_t front_vad_flag, /* i : front-VAD decision */ - float ppPcm_in[][L_FRAME48k] /* i/o: input/transport audio channels */ -); - void ivas_spar_get_cldfb_gains( SPAR_DEC_HANDLE hSpar, HANDLE_CLDFB_FILTER_BANK cldfbAnaDec0, @@ -3858,16 +3849,16 @@ void ivas_spar_dec_upmixer( /* FOA MD module */ ivas_error ivas_spar_md_enc_open( - ivas_spar_md_enc_state_t **hMdEnc, /* i/o: SPAR MD encoder handle */ + ivas_spar_md_enc_state_t **hMdEnc, /* i/o: SPAR MD encoder handle */ const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ ); void ivas_spar_md_enc_close( - ivas_spar_md_enc_state_t **hMdEnc /* i/o: SPAR MD encoder handle */ + ivas_spar_md_enc_state_t **hMdEnc /* i/o: SPAR MD encoder handle */ ); ivas_error ivas_spar_md_enc_process( - ivas_spar_md_enc_state_t *hMdEnc, /* i/o: SPAR MD encoder handle */ + ivas_spar_md_enc_state_t *hMdEnc, /* i/o: SPAR MD encoder handle */ const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ ivas_spar_md_enc_in_buf_t *pIn_buf, BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ @@ -3931,22 +3922,17 @@ void ivas_get_spar_md_from_dirac( ); ivas_error ivas_spar_md_dec_open( - ivas_spar_md_dec_state_t **hMdDec_out, /* i/o: SPAR MD decoder handle */ + ivas_spar_md_dec_state_t **hMdDec_out, /* i/o: SPAR MD decoder handle */ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ const int16_t num_channels /* i : number of internal channels */ ); void ivas_spar_md_dec_close( - ivas_spar_md_dec_state_t **hMdDec /* i/o: SPAR MD decoder handle */ -); - -void ivas_spar_dec_MD( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - Decoder_State *st0 /* i/o: decoder state structure - for bitstream handling*/ + ivas_spar_md_dec_state_t **hMdDec /* i/o: SPAR MD decoder handle */ ); void ivas_spar_get_parameters( - SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */ + SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ const int16_t ts, /* i : time slot index */ const int16_t num_ch_out, /* i : number of channels out */ @@ -3956,7 +3942,7 @@ void ivas_spar_get_parameters( ); ivas_error ivas_spar_md_dec_init( - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ + ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ const int16_t num_channels /* i : number of internal channels */ ); @@ -3970,27 +3956,27 @@ void ivas_spar_md_dec_process( void ivas_spar_to_dirac( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ + ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ const int16_t dtx_vad, /* i : DTX frame flag */ const int16_t num_bands_out /* i : number of output bands */ ); void ivas_spar_update_md_hist( - ivas_spar_md_dec_state_t *hMdDec /* i/o: SPAR MD decoder handle */ + ivas_spar_md_dec_state_t *hMdDec /* i/o: SPAR MD decoder handle */ ); void ivas_spar_smooth_md_dtx( - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ + ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ const int16_t num_bands_out /* i : number of output bands */ ); void ivas_spar_setup_md_smoothing( - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ + ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ const int16_t num_bands_out /* i : number of output bands */ ); void ivas_spar_dec_gen_umx_mat( - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ + ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ 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 */ diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index 93dd07bdd1..baf63f6e35 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -2088,3 +2088,183 @@ int16_t ivas_get_bits_to_encode( return bits_req; } + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_set_bitrate_config() + * + * Set SPAR bitrate config + *-----------------------------------------------------------------------------------------*/ + +void ivas_spar_set_bitrate_config( + ivas_spar_md_com_cfg *pSpar_md_cfg, /* i/o: SPAR MD config. handle */ + const int16_t table_idx, /* i : config. table index */ + const int16_t num_bands /* i : number of bands */ +) +{ + int32_t ivas_total_brate; + int16_t i, total_bits, max_bits, code, length; + int16_t sba_order; + int16_t md_coding_bits_header; + pSpar_md_cfg->nchan_transport = ivas_spar_br_table_consts[table_idx].nchan_transport; + + for ( i = 0; i < pSpar_md_cfg->nchan_transport; i++ ) + { + pSpar_md_cfg->max_freq_per_chan[i] = ivas_spar_br_table_consts[table_idx].fpcs; + } + + pSpar_md_cfg->active_w = ivas_spar_br_table_consts[table_idx].active_w; + pSpar_md_cfg->agc_bits_ch_idx = ivas_spar_br_table_consts[table_idx].agc_bits_ch_idx; + ivas_spar_get_uniform_quant_strat( pSpar_md_cfg, table_idx ); + + if ( pSpar_md_cfg->quant_strat->C.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->C.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->PR.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->PR.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->P_c.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->P_c.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->P_r.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->P_r.q_levels[1] == 0 ) + { + pSpar_md_cfg->gen_bs = 0; + } + else + { + if ( 0 != pSpar_md_cfg->gen_bs ) + { + pSpar_md_cfg->quant_strat_bits = ivas_get_bits_to_encode( MAX_QUANT_STRATS ); + } + } + + /* BLOCK: getEntropyCoderModels */ + + pSpar_md_cfg->remix_unmix_order = ivas_spar_br_table_consts[table_idx].dmx_str; + + /* bits per block*/ + total_bits = 0; + max_bits = 0; + + ivas_total_brate = ivas_spar_br_table_consts[table_idx].ivas_total_brate; + sba_order = ivas_spar_br_table_consts[table_idx].sba_order; + ivas_get_spar_table_idx( ivas_total_brate, sba_order, ivas_spar_br_table_consts[table_idx].bwidth, &code, &length ); + + for ( i = 0; i < pSpar_md_cfg->nchan_transport; i++ ) + { + total_bits += ( int16_t )( ivas_spar_br_table_consts[table_idx].evs_brs[i][0] / FRAMES_PER_SEC ); + max_bits += ( int16_t )( ivas_spar_br_table_consts[table_idx].evs_brs[i][1] / FRAMES_PER_SEC ); + } + if ( ivas_total_brate >= IVAS_256k ) + { + pSpar_md_cfg->tgt_bits_per_blk = ( int16_t )( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - SBA_PLANAR_BITS - SBA_ORDER_BITS - length - total_bits; + + pSpar_md_cfg->max_bits_per_blk = ( int16_t )( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - SBA_PLANAR_BITS - SBA_ORDER_BITS - length - max_bits; + + // TODO : do this for lower bitrates as well once order/planar bits are added + md_coding_bits_header = SPAR_NUM_CODING_STRAT_BITS + pSpar_md_cfg->quant_strat_bits; + pSpar_md_cfg->tgt_bits_per_blk -= md_coding_bits_header; + pSpar_md_cfg->max_bits_per_blk -= md_coding_bits_header; + + pSpar_md_cfg->tgt_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->tgt_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS ); + pSpar_md_cfg->max_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->max_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS ); + + pSpar_md_cfg->tgt_bits_per_blk += md_coding_bits_header; + pSpar_md_cfg->max_bits_per_blk += md_coding_bits_header; + } + else + { + pSpar_md_cfg->tgt_bits_per_blk = ( int16_t )( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - length - total_bits; + + pSpar_md_cfg->max_bits_per_blk = ( int16_t )( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - length - max_bits; + + pSpar_md_cfg->tgt_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->tgt_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS ); + pSpar_md_cfg->max_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->max_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS ); + } + + return; +} + +#ifdef FIX_I1_113 +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_bitrate_dist() + * + * Set SPAR bitrate distribution + *-----------------------------------------------------------------------------------------*/ + +// this function is not currently used but it is kept for future use +void ivas_spar_bitrate_dist( + int32_t core_brates_act[], /* o : bitrates per core-coder */ + const int16_t nAvailBits, /* i : number of available bits */ + const int32_t ivas_total_brate, /* i : IVAS total bitrate */ + const int16_t sba_order, /* i : Ambisonic (SBA) order */ + const int16_t bwidth /* i : audio bandwidth */ +) +{ + int16_t i, nchan_transport, table_idx, bitlen; + int16_t core_bits_act[FOA_CHANNELS], core_range_bits[FOA_CHANNELS]; + int16_t sum_core_act_bits, residual_bits, overflow_bits; + + table_idx = ivas_get_spar_table_idx( ivas_total_brate, sba_order, bwidth, &bitlen, NULL ); + + nchan_transport = ivas_spar_br_table_consts[table_idx].nchan_transport; + + sum_core_act_bits = 0; + for ( i = 0; i < nchan_transport; i++ ) + { + core_bits_act[i] = ( int16_t )( ivas_spar_br_table_consts[table_idx].evs_brs[i][0] / FRAMES_PER_SEC ); + + sum_core_act_bits += core_bits_act[i]; + } + + residual_bits = nAvailBits - sum_core_act_bits; + + /* First compute core-coder bits as per bitrate distribution table and MD bitrate*/ + if ( residual_bits > 0 ) + { + for ( i = 0; i < nchan_transport; i++ ) + { + core_range_bits[i] = ( int16_t )( ( ivas_spar_br_table_consts[table_idx].evs_brs[i][2] - ivas_spar_br_table_consts[table_idx].evs_brs[i][0] ) / FRAMES_PER_SEC ); + core_bits_act[i] += min( residual_bits, core_range_bits[i] ); + residual_bits -= core_range_bits[i]; + + if ( residual_bits <= 0 ) + { + break; + } + } + } + else + { + for ( i = 0; i < nchan_transport; i++ ) + { + core_range_bits[i] = ( int16_t )( ( ivas_spar_br_table_consts[table_idx].evs_brs[i][0] - ivas_spar_br_table_consts[table_idx].evs_brs[i][1] ) / FRAMES_PER_SEC ); + } + + overflow_bits = -residual_bits; + + for ( i = 0; i < nchan_transport; i++ ) + { + core_bits_act[nchan_transport - 1 - i] -= min( overflow_bits, core_range_bits[nchan_transport - 1 - i] ); + overflow_bits -= core_range_bits[nchan_transport - 1 - i]; + + if ( overflow_bits <= 0 ) + { + break; + } + } + + if ( overflow_bits > 0 ) + { + int16_t overflow_bits_ch; + overflow_bits_ch = overflow_bits / nchan_transport; + + for ( i = 0; i < nchan_transport; i++ ) + { + core_bits_act[i] -= overflow_bits_ch; + overflow_bits -= overflow_bits_ch; + } + + core_bits_act[nchan_transport - 1] -= max( 0, overflow_bits ); + } + } + + for ( i = 0; i < nchan_transport; i++ ) + { + core_brates_act[i] = core_bits_act[i] * FRAMES_PER_SEC; + } + + return; +} +#endif diff --git a/lib_com/ivas_spar_foa_br_dist.c b/lib_com/ivas_spar_foa_br_dist.c deleted file mode 100644 index 5bbb771848..0000000000 --- a/lib_com/ivas_spar_foa_br_dist.c +++ /dev/null @@ -1,224 +0,0 @@ -/****************************************************************************************************** - - (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include "math.h" -#include "options.h" -#ifdef DEBUGGING -#include "debug.h" -#endif -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_rom_com.h" -#include "ivas_stat_com.h" -#include -#include "wmops.h" - - -/*-----------------------------------------------------------------------------------------* - * Function ivas_spar_set_bitrate_config() - * - * Set SPAR bitrate config - *-----------------------------------------------------------------------------------------*/ - -void ivas_spar_set_bitrate_config( - ivas_spar_md_com_cfg *pSpar_md_cfg, /* i/o: SPAR MD config. handle */ - const int16_t table_idx, /* i : config. table index */ - const int16_t num_bands /* i : number of bands */ -) -{ - int32_t ivas_total_brate; - int16_t i, total_bits, max_bits, code, length; - int16_t sba_order; - int16_t md_coding_bits_header; - pSpar_md_cfg->nchan_transport = ivas_spar_br_table_consts[table_idx].nchan_transport; - - for ( i = 0; i < pSpar_md_cfg->nchan_transport; i++ ) - { - pSpar_md_cfg->max_freq_per_chan[i] = ivas_spar_br_table_consts[table_idx].fpcs; - } - - pSpar_md_cfg->active_w = ivas_spar_br_table_consts[table_idx].active_w; - pSpar_md_cfg->agc_bits_ch_idx = ivas_spar_br_table_consts[table_idx].agc_bits_ch_idx; - ivas_spar_get_uniform_quant_strat( pSpar_md_cfg, table_idx ); - - if ( pSpar_md_cfg->quant_strat->C.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->C.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->PR.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->PR.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->P_c.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->P_c.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->P_r.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->P_r.q_levels[1] == 0 ) - { - pSpar_md_cfg->gen_bs = 0; - } - else - { - if ( 0 != pSpar_md_cfg->gen_bs ) - { - pSpar_md_cfg->quant_strat_bits = ivas_get_bits_to_encode( MAX_QUANT_STRATS ); - } - } - - /* BLOCK: getEntropyCoderModels */ - - pSpar_md_cfg->remix_unmix_order = ivas_spar_br_table_consts[table_idx].dmx_str; - - /* bits per block*/ - total_bits = 0; - max_bits = 0; - - ivas_total_brate = ivas_spar_br_table_consts[table_idx].ivas_total_brate; - sba_order = ivas_spar_br_table_consts[table_idx].sba_order; - ivas_get_spar_table_idx( ivas_total_brate, sba_order, ivas_spar_br_table_consts[table_idx].bwidth, &code, &length ); - - for ( i = 0; i < pSpar_md_cfg->nchan_transport; i++ ) - { - total_bits += (int16_t) ( ivas_spar_br_table_consts[table_idx].evs_brs[i][0] / FRAMES_PER_SEC ); - max_bits += (int16_t) ( ivas_spar_br_table_consts[table_idx].evs_brs[i][1] / FRAMES_PER_SEC ); - } - if ( ivas_total_brate >= IVAS_256k ) - { - pSpar_md_cfg->tgt_bits_per_blk = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - SBA_PLANAR_BITS - SBA_ORDER_BITS - length - total_bits; - - pSpar_md_cfg->max_bits_per_blk = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - SBA_PLANAR_BITS - SBA_ORDER_BITS - length - max_bits; - - // TODO : do this for lower bitrates as well once order/planar bits are added - md_coding_bits_header = SPAR_NUM_CODING_STRAT_BITS + pSpar_md_cfg->quant_strat_bits; - pSpar_md_cfg->tgt_bits_per_blk -= md_coding_bits_header; - pSpar_md_cfg->max_bits_per_blk -= md_coding_bits_header; - - pSpar_md_cfg->tgt_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->tgt_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS ); - pSpar_md_cfg->max_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->max_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS ); - - pSpar_md_cfg->tgt_bits_per_blk += md_coding_bits_header; - pSpar_md_cfg->max_bits_per_blk += md_coding_bits_header; - } - else - { - pSpar_md_cfg->tgt_bits_per_blk = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - length - total_bits; - - pSpar_md_cfg->max_bits_per_blk = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - length - max_bits; - - pSpar_md_cfg->tgt_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->tgt_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS ); - pSpar_md_cfg->max_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->max_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS ); - } - - return; -} - -#ifdef FIX_I1_113 -/*-----------------------------------------------------------------------------------------* - * Function ivas_spar_bitrate_dist() - * - * Set SPAR bitrate distribution - *-----------------------------------------------------------------------------------------*/ - -// this function is not currently used but it is kept for future use -void ivas_spar_bitrate_dist( - int32_t core_brates_act[], /* o : bitrates per core-coder */ - const int16_t nAvailBits, /* i : number of available bits */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t sba_order, /* i : Ambisonic (SBA) order */ - const int16_t bwidth /* i : audio bandwidth */ -) -{ - int16_t i, nchan_transport, table_idx, bitlen; - int16_t core_bits_act[FOA_CHANNELS], core_range_bits[FOA_CHANNELS]; - int16_t sum_core_act_bits, residual_bits, overflow_bits; - - table_idx = ivas_get_spar_table_idx( ivas_total_brate, sba_order, bwidth, &bitlen, NULL ); - - nchan_transport = ivas_spar_br_table_consts[table_idx].nchan_transport; - - sum_core_act_bits = 0; - for ( i = 0; i < nchan_transport; i++ ) - { - core_bits_act[i] = (int16_t) ( ivas_spar_br_table_consts[table_idx].evs_brs[i][0] / FRAMES_PER_SEC ); - - sum_core_act_bits += core_bits_act[i]; - } - - residual_bits = nAvailBits - sum_core_act_bits; - - /* First compute core-coder bits as per bitrate distribution table and MD bitrate*/ - if ( residual_bits > 0 ) - { - for ( i = 0; i < nchan_transport; i++ ) - { - core_range_bits[i] = (int16_t) ( ( ivas_spar_br_table_consts[table_idx].evs_brs[i][2] - ivas_spar_br_table_consts[table_idx].evs_brs[i][0] ) / FRAMES_PER_SEC ); - core_bits_act[i] += min( residual_bits, core_range_bits[i] ); - residual_bits -= core_range_bits[i]; - - if ( residual_bits <= 0 ) - { - break; - } - } - } - else - { - for ( i = 0; i < nchan_transport; i++ ) - { - core_range_bits[i] = (int16_t) ( ( ivas_spar_br_table_consts[table_idx].evs_brs[i][0] - ivas_spar_br_table_consts[table_idx].evs_brs[i][1] ) / FRAMES_PER_SEC ); - } - - overflow_bits = -residual_bits; - - for ( i = 0; i < nchan_transport; i++ ) - { - core_bits_act[nchan_transport - 1 - i] -= min( overflow_bits, core_range_bits[nchan_transport - 1 - i] ); - overflow_bits -= core_range_bits[nchan_transport - 1 - i]; - - if ( overflow_bits <= 0 ) - { - break; - } - } - - if ( overflow_bits > 0 ) - { - int16_t overflow_bits_ch; - overflow_bits_ch = overflow_bits / nchan_transport; - - for ( i = 0; i < nchan_transport; i++ ) - { - core_bits_act[i] -= overflow_bits_ch; - overflow_bits -= overflow_bits_ch; - } - - core_bits_act[nchan_transport - 1] -= max( 0, overflow_bits ); - } - } - - for ( i = 0; i < nchan_transport; i++ ) - { - core_brates_act[i] = core_bits_act[i] * FRAMES_PER_SEC; - } - - return; -} -#endif diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 87ff95a81a..4991177e55 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -45,6 +45,16 @@ #include #include "wmops.h" +#ifdef DEBUG_SPAR_FOA +extern FILE *fFb_pcm; +#endif + +/*-------------------------------------------------------------------* + * Local function prototypes + *--------------------------------------------------------------------*/ + +static void ivas_spar_dec_MD( Decoder_Struct *st_ivas, Decoder_State *st0 ); + /*------------------------------------------------------------------------- * ivas_spar_dec_open() @@ -259,3 +269,961 @@ ivas_error ivas_spar_dec( return error; } + + +/*---------------------------------------------------------------------* + * Function ivas_get_spar_table_idx_from_coded_idx() + * + * Get SPAR table index + *---------------------------------------------------------------------*/ + +static int16_t ivas_get_spar_table_idx_from_coded_idx( + const int32_t ivas_total_brate, /* i : IVAS total bitrate */ + const int16_t sba_order, /* i : Ambisonic (SBA) order */ + Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ + int16_t *bitlen /* o : number of bits */ +) +{ + int16_t table_idx, ind1[IVAS_SPAR_BR_TABLE_LEN]; + int16_t i, j, ind2; + + j = 0; + for ( i = 0; i < IVAS_SPAR_BR_TABLE_LEN; i++ ) + { + ind1[j] = 0; + if ( ( ivas_spar_br_table_consts[i].ivas_total_brate == ivas_total_brate ) && + ( ivas_spar_br_table_consts[i].sba_order == sba_order ) ) + { + ind1[j++] = i; + } + } + + assert( j > 0 ); + + *bitlen = ivas_get_bits_to_encode( j - 1 ); + + ind2 = get_next_indice( st0, *bitlen ); + + table_idx = ind1[ind2]; + + return table_idx; +} + + +/*---------------------------------------------------------------------* + * Function ivas_parse_spar_header() + * + * Get SPAR table index + *---------------------------------------------------------------------*/ + +static int16_t ivas_parse_spar_header( + const int32_t ivas_total_brate, /* i : IVAS total bitrate */ + const int16_t sba_order, /* i : Ambisonic (SBA) order */ + Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ + int16_t *table_idx ) +{ + int16_t bitlen, bwidth; + + *table_idx = ivas_get_spar_table_idx_from_coded_idx( ivas_total_brate, sba_order, st0, &bitlen ); + + bwidth = ivas_spar_br_table_consts[( *table_idx )].bwidth; + + return bwidth; +} + + +static float get_random_number( + int16_t *seed ) +{ + float x = (float) own_random( seed ) / 32768.0f; + + return x; +} + + +static float matrix_det( + const float a00, + const float a01, + const float a10, + const float a11 ) +{ + return a00 * a11 - a01 * a10; +} + + +static void matrix_inverse( + float in[3][3], + float out[3][3], + const int16_t size ) +{ + float det, fac; + float eps = 1e-16f; + + if ( size == 1 ) + { + out[0][0] = 1.0f / max( in[0][0], eps ); + + return; + } + else if ( size == 2 ) + { + det = matrix_det( in[0][1], in[0][1], in[1][0], in[1][1] ); + fac = 1.0f / max( det, eps ); + + out[0][0] = in[1][1] * fac; + out[1][0] = in[1][0] * ( -fac ); + + out[0][1] = in[0][1] * ( -fac ); + out[1][1] = in[0][0] * fac; + + return; + } + + det = in[0][0] * matrix_det( in[1][1], in[1][2], in[2][1], in[2][2] ) - in[1][0] * matrix_det( in[0][1], in[0][2], in[2][1], in[2][2] ) + in[2][0] * matrix_det( in[0][1], in[0][2], in[1][1], in[1][2] ); + fac = 1.0f / max( det, eps ); + + out[0][0] = matrix_det( in[1][1], in[1][2], in[2][1], in[2][2] ) * fac; + out[1][0] = matrix_det( in[1][0], in[1][2], in[2][0], in[2][2] ) * ( -fac ); + out[2][0] = matrix_det( in[1][0], in[1][1], in[2][0], in[2][1] ) * fac; + + out[0][1] = matrix_det( in[0][1], in[0][2], in[2][1], in[2][2] ) * ( -fac ); + out[1][1] = matrix_det( in[0][0], in[0][2], in[2][0], in[2][2] ) * fac; + out[2][1] = matrix_det( in[0][0], in[0][1], in[2][0], in[2][1] ) * ( -fac ); + + out[0][2] = matrix_det( in[0][1], in[0][2], in[1][1], in[1][2] ) * fac; + out[1][2] = matrix_det( in[0][0], in[0][2], in[1][0], in[1][2] ) * ( -fac ); + out[2][2] = matrix_det( in[0][0], in[0][1], in[1][0], in[1][1] ) * fac; + + return; +} + + +/*---------------------------------------------------------------------* + * Function ivas_spar_get_cldfb_gains() + * + * + *---------------------------------------------------------------------*/ + +void ivas_spar_get_cldfb_gains( + SPAR_DEC_HANDLE hSpar, + HANDLE_CLDFB_FILTER_BANK cldfbAnaDec0, + HANDLE_CLDFB_FILTER_BANK cldfbSynDec0, + const DECODER_CONFIG_HANDLE hDecoderConfig ) +{ + float output_Fs = (float) hDecoderConfig->output_Fs; + int16_t pt_len, stride, num_cldfb_bands, decfb_delay; + int16_t encfb_delay, cf_start, cf_end, cf_len; + float *weights; + int16_t ts, cf_cldfb_start, cf_cldfb_end; + float cf_start_s, cf_len_s; + int16_t sample, num_cf_slots, num_samples; + float T[3 * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX - CLDFB_NO_CHANNELS_MAX][3]; + float Tt_T[3][3]; + float Tt_T_inv[3][3]; + float Tt_tgt[3]; + float ts_inout[CLDFB_NO_CHANNELS_MAX]; + float ts_re[CLDFB_NO_CHANNELS_MAX]; + float ts_im[CLDFB_NO_CHANNELS_MAX]; + float *pp_ts_im[1], *pp_ts_re[1]; + float tgt[( 3 - 1 ) * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX]; + int16_t seed, split_band, slot_row, slot_col, slot, tmp_idx; + + pt_len = cldfbAnaDec0->p_filter_length; + num_cldfb_bands = cldfbAnaDec0->no_channels; + + stride = NS2SA( output_Fs, DELAY_CLDFB_NS ); + encfb_delay = NS2SA( output_Fs, IVAS_FB_ENC_DELAY_NS ); + decfb_delay = NS2SA( output_Fs, IVAS_FB_DEC_DELAY_NS ); + + cf_start = (int16_t) hSpar->hFbMixer->cross_fade_start_offset - encfb_delay + decfb_delay; /* time domain after CLDFB synthesis*/ + cf_end = (int16_t) hSpar->hFbMixer->cross_fade_end_offset - encfb_delay + decfb_delay; + cf_len = cf_end - cf_start; + weights = hSpar->hFbMixer->cldfb_cross_fade; + + cf_cldfb_start = (int16_t) ceil( ( cf_start - decfb_delay / 2 ) / (float) stride - 0.5f ); + cf_cldfb_end = ( int16_t )( ( cf_start - decfb_delay / 2 + cf_len ) / (float) stride - 0.5f ); + + num_cf_slots = cf_cldfb_end - cf_cldfb_start + 1; + num_samples = num_cf_slots * stride + pt_len - stride; + seed = RANDOM_INITSEED; + split_band = SPAR_DIRAC_SPLIT_START_BAND; + pp_ts_im[0] = ts_im; + pp_ts_re[0] = ts_re; + set_f( tgt, 0, ( 3 - 1 ) * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX ); + + cf_start_s = ( cf_start - decfb_delay / 2 ) / output_Fs; + cf_len_s = hSpar->hFbMixer->cross_fade_end_offset / output_Fs - hSpar->hFbMixer->cross_fade_start_offset / output_Fs; + + for ( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) + { + weights[ts] = ( ( ( ts + 0.5f ) * stride / output_Fs ) - cf_start_s ) / cf_len_s; + weights[ts] = max( min( weights[ts], 1.0f ), 0.0f ); + } + hSpar->hFbMixer->cldfb_cross_fade_start = cf_cldfb_start; + hSpar->hFbMixer->cldfb_cross_fade_end = cf_cldfb_end; + hSpar->hFbMixer->cldfb_latency = decfb_delay; + + if ( num_cf_slots > 3 || pt_len > 10 * CLDFB_NO_CHANNELS_MAX || stride > CLDFB_NO_CHANNELS_MAX || split_band == IVAS_MAX_NUM_BANDS ) + { + return; + } + + /* optimization*/ + /* compute time-domain cross-fade for considered time slots*/ + tmp_idx = cf_start - cf_cldfb_start * stride; + for ( sample = 0; sample < cf_len; sample++ ) + { + /* increasing window function */ + tgt[tmp_idx++] = hSpar->hFbMixer->pFilterbank_cross_fade[sample]; + } + + for ( ; tmp_idx < num_samples; tmp_idx++ ) + { + /* fill up with ones*/ + tgt[tmp_idx] = 1.0f; + } + + for ( sample = 0; sample < num_samples; sample++ ) + { + /* initialize trasnform matrix with zeros*/ + T[sample][0] = T[sample][1] = T[sample][2] = 0.0f; + } + + for ( sample = 0; sample < pt_len - stride; sample++ ) + { + /* fill internal CLDFB analysis time buffer with data*/ + float x = get_random_number( &seed ); + + cldfbAnaDec0->cldfb_state[sample] = x; + } + + for ( slot = 0; slot < num_cf_slots; slot++ ) + { + for ( sample = 0; sample < stride; sample++ ) + { + float x = get_random_number( &seed ); + ts_inout[sample] = x; + } + + cldfbAnalysis_ts( ts_inout, ts_re, ts_im, num_cldfb_bands, cldfbAnaDec0 ); + cldfb_reset_memory( cldfbSynDec0 ); + cldfbSynthesis( pp_ts_re, pp_ts_im, ts_inout, num_cldfb_bands, cldfbSynDec0 ); + + for ( sample = 0; sample < stride; sample++ ) + { + T[slot * stride + sample][slot] = ts_inout[sample]; + } + + tmp_idx = pt_len - 1; + for ( sample = stride; sample < pt_len; sample++ ) + { + T[slot * stride + sample][slot] = cldfbSynDec0->cldfb_state[tmp_idx--]; + } + } + + /* target is synthesis output times the cross-fade window*/ + for ( sample = 0; sample < num_samples; sample++ ) + { + tgt[sample] *= ( T[sample][0] + T[sample][1] + T[sample][2] ); + } + + /* compute matrices */ + for ( slot_row = 0; slot_row < num_cf_slots; slot_row++ ) + { + for ( slot_col = slot_row; slot_col < num_cf_slots; slot_col++ ) + { + Tt_T[slot_row][slot_col] = 0.0f; + for ( sample = 0; sample < num_samples; sample++ ) + { + Tt_T[slot_row][slot_col] += T[sample][slot_row] * T[sample][slot_col]; + } + } + } + + Tt_T[1][0] = Tt_T[0][1]; + Tt_T[2][0] = Tt_T[0][2]; + Tt_T[2][1] = Tt_T[1][2]; + + for ( slot_row = 0; slot_row < num_cf_slots; slot_row++ ) + { + Tt_tgt[slot_row] = 0.0f; + for ( sample = 0; sample < num_samples; sample++ ) + { + Tt_tgt[slot_row] += T[sample][slot_row] * tgt[sample]; + } + } + + matrix_inverse( Tt_T, Tt_T_inv, num_cf_slots ); + + /* compute the optimal coefficients */ + for ( slot_row = 0; slot_row < num_cf_slots; slot_row++ ) + { + float tmp = 0.0f; + for ( slot_col = 0; slot_col < num_cf_slots; slot_col++ ) + { + tmp += Tt_T_inv[slot_row][slot_col] * Tt_tgt[slot_col]; + } + weights[cf_cldfb_start + slot_row] = max( min( tmp, 1.0f ), 0.0f ); + } + + cldfb_reset_memory( cldfbSynDec0 ); + cldfb_reset_memory( cldfbAnaDec0 ); + + return; +} + + +/*---------------------------------------------------------------------* + * Function ivas_is_res_channel() + * + * determines if an FOA input channel is transmitted as residual channel. + *---------------------------------------------------------------------*/ + +/* !r: 1 if prediction residual channel */ +int16_t ivas_is_res_channel( + const int16_t ch, /* i : ch index in WYZX ordering */ + const int16_t nchan_transport /* i : number of transport channels (1-4) */ +) +{ + const int16_t rc_map[FOA_CHANNELS][FOA_CHANNELS] = { + { 0, 0, 0, 0 }, + { 0, 1, 0, 0 }, + { 0, 1, 0, 1 }, + { 0, 1, 1, 1 } + }; + + if ( ch >= FOA_CHANNELS ) + { + /* never transmitted */ + return 0; + } + assert( nchan_transport <= FOA_CHANNELS ); + + return ( rc_map[nchan_transport - 1][ch] ); +} + + +/*-------------------------------------------------------------------* + * ivas_spar_dec_MD() + * + * IVAS SPAR MD decoder + *-------------------------------------------------------------------*/ + +static void ivas_spar_dec_MD( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + Decoder_State *st0 /* i/o: decoder state structure - for bitstream handling*/ +) +{ + int16_t num_channels, table_idx, num_bands_out, bfi, sba_order; + int32_t ivas_total_brate; + DECODER_CONFIG_HANDLE hDecoderConfig = st_ivas->hDecoderConfig; + SPAR_DEC_HANDLE pState = st_ivas->hSpar; + + wmops_sub_start( "ivas_spar_dec_MD" ); + + /*---------------------------------------------------------------------* + * Initialization + *---------------------------------------------------------------------*/ + + sba_order = min( st_ivas->sba_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_bands_out = pState->hFbMixer->pFb->filterbank_num_bands; + + if ( ivas_total_brate > FRAME_NO_DATA && !bfi ) + { + if ( ivas_total_brate > IVAS_SID_5k ) + { + ivas_parse_spar_header( hDecoderConfig->ivas_total_brate, sba_order, st0, &table_idx ); + + pState->hMdDec->spar_md.num_bands = min( SPAR_DIRAC_SPLIT_START_BAND, IVAS_MAX_NUM_BANDS ); + + if ( pState->hMdDec->table_idx != table_idx ) + { + pState->hMdDec->table_idx = table_idx; + pState->hTdDecorr->ducking_flag = ivas_spar_br_table_consts[table_idx].td_ducking; + + ivas_spar_md_dec_init( pState->hMdDec, hDecoderConfig, num_channels ); + } + } + + /*---------------------------------------------------------------------* + * Decode MD + *---------------------------------------------------------------------*/ + + ivas_spar_md_dec_process( st_ivas, st0, num_bands_out, sba_order ); + + /*---------------------------------------------------------------------* + * read PCA bits + *---------------------------------------------------------------------*/ + +#ifdef SBA_CLEANING + if ( pState->hPCA != NULL ) +#else + if ( hDecoderConfig->ivas_total_brate == PCA_BRATE && sba_order == 1 ) +#endif + { + ivas_pca_read_bits( st0, pState->hPCA ); + } +#ifndef SBA_CLEANING + else + { + pState->hPCA->pca_bypass = PCA_MODE_INACTIVE; + } +#endif + + /*---------------------------------------------------------------------* + * Read AGC bits + *---------------------------------------------------------------------*/ + + if ( ivas_total_brate > IVAS_SID_5k && !bfi && pState->hMdDec->dtx_vad ) + { + pState->AGC_flag = get_next_indice( st0, 1 ); + + ivas_agc_read_bits( pState->hAgcDec, st0, pState->hMdDec->spar_md_cfg.nchan_transport, pState->AGC_flag ); + } + + /*---------------------------------------------------------------------* + * MD smoothing + *---------------------------------------------------------------------*/ + + if ( st0->m_old_frame_type == ZERO_FRAME && ivas_total_brate == IVAS_SID_5k && st0->prev_bfi == 0 && pState->hMdDec->spar_md_cfg.nchan_transport == 1 ) + { + ivas_spar_setup_md_smoothing( pState->hMdDec, num_bands_out ); + } + else + { + ivas_spar_update_md_hist( pState->hMdDec ); + } + } + else + { + if ( !bfi ) + { + ivas_spar_smooth_md_dtx( pState->hMdDec, num_bands_out ); + } + + set_s( pState->hMdDec->valid_bands, 0, IVAS_MAX_NUM_BANDS ); + } + + wmops_sub_end(); + return; +} + + +/*-------------------------------------------------------------------* + * ivas_spar_get_cldfb_slot_gain() + * + * + *-------------------------------------------------------------------*/ + +static float ivas_spar_get_cldfb_slot_gain( + SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */ + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ + const int16_t time_slot_idx, + int16_t *time_slot_idx0, + int16_t *time_slot_idx1, + float *weight_lowfreq ) +{ + SPAR_DEC_HANDLE pState = hSpar; + float weight; + float output_Fs, encfb_delay, decfb_delay; + float xfade_start_ns; + int16_t xfade_delay_subframes; + int16_t i_hist; + int16_t split_band; + + *weight_lowfreq = pState->hFbMixer->cldfb_cross_fade[time_slot_idx]; + + output_Fs = (float) hDecoderConfig->output_Fs; + encfb_delay = IVAS_FB_ENC_DELAY_NS; + decfb_delay = IVAS_FB_DEC_DELAY_NS; + xfade_start_ns = pState->hFbMixer->cross_fade_start_offset / output_Fs * 1000000000.f - encfb_delay + decfb_delay * 0.5f; + xfade_delay_subframes = ( int16_t )( xfade_start_ns / ( FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ) ); + + i_hist = 4 - xfade_delay_subframes; + split_band = SPAR_DIRAC_SPLIT_START_BAND; + + if ( split_band < IVAS_MAX_NUM_BANDS ) + { + if ( hSpar->i_subframe > 3 ) + { + weight = (float) ( time_slot_idx % MAX_PARAM_SPATIAL_SUBFRAMES ) / (float) MAX_PARAM_SPATIAL_SUBFRAMES; + } + else + { + weight = 0.0f; + } + *time_slot_idx0 = i_hist; + *time_slot_idx1 = i_hist + 1; + } + else + { + /* determine cross-fade gain for current frame Parameters*/ + *time_slot_idx0 = pState->hFbMixer->cldfb_cross_fade_start; + *time_slot_idx1 = pState->hFbMixer->cldfb_cross_fade_end; + weight = *weight_lowfreq; + } + + return weight; +} + + +/*-------------------------------------------------------------------* + * ivas_spar_get_parameters() + * + * + *-------------------------------------------------------------------*/ + +void ivas_spar_get_parameters( + SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */ + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ + const int16_t ts, + const int16_t num_ch_out, + const int16_t num_ch_in, + const int16_t num_spar_bands, + float par_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS] ) +{ + int16_t spar_band, out_ch, in_ch; + float weight, weight_20ms; + int16_t ts0, ts1, split_band; + + weight = ivas_spar_get_cldfb_slot_gain( hSpar, hDecoderConfig, ts, &ts0, &ts1, &weight_20ms ); + + split_band = SPAR_DIRAC_SPLIT_START_BAND; + for ( spar_band = 0; spar_band < num_spar_bands; spar_band++ ) + { + for ( out_ch = 0; out_ch < num_ch_out; out_ch++ ) + { + for ( in_ch = 0; in_ch < num_ch_in; in_ch++ ) + { + if ( split_band < IVAS_MAX_NUM_BANDS + /* 20ms cross-fade for Transport channels in all frequency bands */ + && ( 0 == ivas_is_res_channel( out_ch, hSpar->hMdDec->spar_md_cfg.nchan_transport ) ) /* sub-frame processing for missing channels in all frequency bands*/ + ) + { + if ( hSpar->i_subframe > 3 ) + { + par_mat[out_ch][in_ch][spar_band] = ( 1.0f - weight ) * hSpar->hMdDec->mixer_mat_prev[ts0][out_ch][in_ch][spar_band] + + weight * hSpar->hMdDec->mixer_mat_prev[ts1][out_ch][in_ch][spar_band]; + } + else + { + par_mat[out_ch][in_ch][spar_band] = hSpar->hMdDec->mixer_mat[out_ch][in_ch][spar_band]; + } + } + else + { + /* 20ms Transport channel reconstruction with matching encoder/decoder processing */ + int16_t prev_idx = SPAR_DIRAC_SPLIT_START_BAND < IVAS_MAX_NUM_BANDS ? 1 : 0; /* if SPAR_DIRAC_SPLIT_START_BAND == IVAS_MAX_NUM_BANDS, then the sub-frame mixer_mat delay line is not active */ + par_mat[out_ch][in_ch][spar_band] = ( 1.0f - weight_20ms ) * hSpar->hMdDec->mixer_mat_prev[prev_idx][out_ch][in_ch][spar_band] + weight_20ms * hSpar->hMdDec->mixer_mat[out_ch][in_ch][spar_band]; + } + } + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * ivas_spar_get_skip_mat() + * + * + *-------------------------------------------------------------------*/ + +static void ivas_spar_get_skip_mat( + SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */ + 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 spar_band, out_ch, in_ch; + int16_t i_ts, skip_flag; + + for ( out_ch = 0; out_ch < num_ch_out; out_ch++ ) + { + for ( in_ch = 0; in_ch < num_ch_in; in_ch++ ) + { + skip_mat[out_ch][in_ch] = 1; + skip_flag = 1; + + 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 || 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; + } + } + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * ivas_spar_foa_dec_upmixer() + * + * IVAS SPAR upmixer + *-------------------------------------------------------------------*/ + +void ivas_spar_dec_upmixer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + float output[][L_FRAME48k], /* i/o: input/output audio channels */ + const int16_t nchan_internal, /* i : number of internal channels */ + const int16_t output_frame /* i : output frame length */ +) +{ + int16_t cldfb_band, num_cldfb_bands, numch_in, numch_out; + float *cldfb_in_ts_re[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX]; + float *cldfb_in_ts_im[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX]; + int16_t i, b, ts, out_ch, in_ch; + int16_t num_spar_bands, spar_band, nchan_transport; + int16_t num_in_ingest, num_bands_out, split_band; + float Pcm_tmp[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + int16_t numch_out_dirac; + float *pPcm_tmp[MAX_OUTPUT_CHANNELS]; + float mixer_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; + int16_t b_skip_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + DECODER_CONFIG_HANDLE hDecoderConfig; + SPAR_DEC_HANDLE pState, hSpar; + + wmops_sub_start( "ivas_spar_dec_upmixer" ); + + hSpar = st_ivas->hSpar; + pState = hSpar; + hDecoderConfig = st_ivas->hDecoderConfig; + num_bands_out = pState->hFbMixer->pFb->filterbank_num_bands; + nchan_transport = pState->hMdDec->spar_md_cfg.nchan_transport; + + num_cldfb_bands = hSpar->hFbMixer->pFb->fb_bin_to_band.num_cldfb_bands; + numch_in = hSpar->hFbMixer->fb_cfg->num_in_chans; + numch_out = hSpar->hFbMixer->fb_cfg->num_out_chans; + +#ifdef DEBUG_SPAR_FOA + if ( fFb_pcm != NULL ) + { + for ( i = 0; i < output_frame; i++ ) + { + for ( int16_t j = 0; j < nchan_transport; j++ ) + { + fscanf( fFb_pcm, "%f\n", &output[j][i] ); + } + } + } +#endif + + /* by-pass EVS */ +#ifdef DEBUG_SPAR_BYPASS_EVS_CODEC + /*write the core coder output to a file for debugging*/ + { + float tmp; + int16_t pcm, j; + for ( j = 0; j < output_frame; j++ ) + { + for ( i = 0; i < nchan_transport; i++ ) + { + tmp = roundf( output[i][j] * PCM16_TO_FLT_FAC ); + pcm = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B : (short) tmp; + dbgwrite( &pcm, sizeof( int16_t ), 1, 1, "dmx_dec.raw" ); + } + } + } + + /*overwrite the core coder output with core input for debugging*/ + { + static FILE *fid_enc = 0; + int16_t smp; + + if ( !fid_enc ) + { + fid_enc = fopen( "evs_input_float.raw", "rb" ); + } + for ( smp = 0; smp < L_FRAME48k; smp++ ) + { + for ( in_ch = 0; in_ch < nchan_transport; in_ch++ ) + { + fread( &output[in_ch][smp], sizeof( float ), 1, fid_enc ); + } + } + } +#endif + + /*---------------------------------------------------------------------* + * AGC + *---------------------------------------------------------------------*/ + + ivas_agc_dec_process( pState->hAgcDec, output, output, nchan_transport, output_frame ); + + /*---------------------------------------------------------------------* + * TD Decorr and pcm ingest + *---------------------------------------------------------------------*/ + + if ( pState->hMdDec->td_decorr_flag ) + { + num_in_ingest = nchan_internal; + } + else + { + num_in_ingest = nchan_transport; + } + + for ( i = 0; i < nchan_internal; i++ ) + { + pPcm_tmp[i] = Pcm_tmp[i]; + } + + /*---------------------------------------------------------------------* + * PCA decoder + *---------------------------------------------------------------------*/ + +#ifdef SBA_CLEANING + if ( pState->hPCA != NULL ) +#endif + { + ivas_pca_dec( pState->hPCA, output_frame, num_in_ingest, hDecoderConfig->ivas_total_brate, hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, output ); + } + + /*---------------------------------------------------------------------* + * TD decorrelation + *---------------------------------------------------------------------*/ + + if ( pState->hMdDec->td_decorr_flag ) + { + ivas_td_decorr_process( pState->hTdDecorr, output, pPcm_tmp, output_frame ); + + for ( i = 0; i < nchan_internal - nchan_transport; i++ ) + { + mvr2r( pPcm_tmp[pState->hTdDecorr->num_apd_outputs - 1 - i], output[nchan_internal - 1 - i], output_frame ); + } + + pState->hFbMixer->fb_cfg->num_in_chans = num_in_ingest; + } + else + { + pState->hFbMixer->fb_cfg->num_in_chans = num_in_ingest; + } + + /*---------------------------------------------------------------------* + * Prepare CLDFB buffers + *---------------------------------------------------------------------*/ + + /* set-up pointers */ + if ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_FOA ) + { + /* at this point, output channels are used as intermediate procesing buffers */ + for ( in_ch = 0; in_ch < MAX_OUTPUT_CHANNELS; in_ch++ ) + { + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + { + cldfb_in_ts_re[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands]; + cldfb_in_ts_im[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands + 4 * num_cldfb_bands]; + } + } + } + else + { + for ( in_ch = 0; in_ch < numch_in; in_ch++ ) + { + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + { + cldfb_in_ts_re[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands]; + cldfb_in_ts_im[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands + 4 * num_cldfb_bands]; + } + } + } + + /*---------------------------------------------------------------------* + * Gen umx mat + *---------------------------------------------------------------------*/ + + ivas_spar_dec_gen_umx_mat( pState->hMdDec, nchan_transport, num_bands_out, st_ivas->bfi ); + + + /*---------------------------------------------------------------------* + * CLDFB Processing and Synthesis + *---------------------------------------------------------------------*/ + + num_spar_bands = hSpar->hFbMixer->pFb->filterbank_num_bands; + + /* 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*/ + + numch_out_dirac = st_ivas->hDecoderConfig->nchan_out; + + for ( int16_t i_sf = 0; i_sf < MAX_PARAM_SPATIAL_SUBFRAMES; i_sf++ ) + { + /* CLDFB analysis of incoming frame */ + for ( in_ch = 0; in_ch < numch_in; in_ch++ ) + { + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + { + cldfbAnalysis_ts( + &output[in_ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands], + cldfb_in_ts_re[in_ch][ts], + cldfb_in_ts_im[in_ch][ts], + num_cldfb_bands, + st_ivas->cldfbAnaDec[in_ch] ); + } + } + + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + { + /* determine SPAR parameters for this time slots */ + ivas_spar_get_parameters( hSpar, st_ivas->hDecoderConfig, ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES, numch_out, numch_in, num_spar_bands, mixer_mat ); + + for ( cldfb_band = 0; cldfb_band < num_cldfb_bands; cldfb_band++ ) + { + float out_re[IVAS_SPAR_MAX_CH]; + float out_im[IVAS_SPAR_MAX_CH]; + float cldfb_par; + ivas_fb_bin_to_band_data_t *bin2band = &pState->hFbMixer->pFb->fb_bin_to_band; + + for ( out_ch = 0; out_ch < numch_out; out_ch++ ) + { + out_re[out_ch] = 0.0f; + out_im[out_ch] = 0.0f; + + for ( in_ch = 0; in_ch < numch_in; in_ch++ ) + { + if ( b_skip_mat[out_ch][in_ch] ) + { + continue; + } + else 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; + } + } + + /*update CLDFB data with the parameter-modified data*/ + for ( out_ch = 0; out_ch < numch_out; out_ch++ ) + { + cldfb_in_ts_re[out_ch][ts][cldfb_band] = out_re[out_ch]; + cldfb_in_ts_im[out_ch][ts][cldfb_band] = out_im[out_ch]; + } + } + } + + if ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_FOA ) + { +#ifdef SBA_CLEANING + ivas_dirac_dec( st_ivas, output, nchan_internal, cldfb_in_ts_re, cldfb_in_ts_im, i_sf ); +#else + nchan_transport = ivas_sba_get_nchan_metadata( st_ivas->sba_order ); // VE: == nchan_internal that is already set correctly + + ivas_dirac_dec( st_ivas, output, nchan_transport, cldfb_in_ts_re, cldfb_in_ts_im, i_sf ); +#endif + } + + if ( st_ivas->hDirAC != NULL ) + { + int16_t outchannels, idx_in, idx_lfe, ch; + idx_in = 0; + idx_lfe = 0; + + outchannels = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; + for ( ch = 0; ch < outchannels; ch++ ) + { + if ( ( st_ivas->hOutSetup.num_lfe > 0 ) && ( st_ivas->hOutSetup.index_lfe[idx_lfe] == ch ) ) + { + set_zero( &( output[ch][i_sf * MAX_PARAM_SPATIAL_SUBFRAMES * num_cldfb_bands] ), MAX_PARAM_SPATIAL_SUBFRAMES * num_cldfb_bands ); + + if ( idx_lfe < ( st_ivas->hDirAC->hOutSetup.num_lfe - 1 ) ) + { + idx_lfe++; + } + } + else + { + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_FOA || + !( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM ) ) + { + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + { + cldfbSynthesis( + &cldfb_in_ts_re[idx_in][ts], + &cldfb_in_ts_im[idx_in][ts], + &output[ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands], + num_cldfb_bands, + st_ivas->cldfbSynDec[idx_in] ); + } + } + idx_in++; + } + } + } + else + { + /* CLDFB to time synthesis (overwrite mixer output) */ + for ( out_ch = 0; out_ch < numch_out_dirac; out_ch++ ) + { + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + { + cldfbSynthesis( + &cldfb_in_ts_re[out_ch][ts], + &cldfb_in_ts_im[out_ch][ts], + &output[out_ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands], + num_cldfb_bands, + st_ivas->cldfbSynDec[out_ch] + + ); + } + } + } + + split_band = SPAR_DIRAC_SPLIT_START_BAND; + if ( split_band < IVAS_MAX_NUM_BANDS ) + { + pState->i_subframe++; + pState->i_subframe = min( pState->i_subframe, MAX_PARAM_SPATIAL_SUBFRAMES ); + mvr2r( pState->hMdDec->mixer_mat_prev[1][0][0], pState->hMdDec->mixer_mat_prev[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( pState->hMdDec->mixer_mat_prev[2][0][0], pState->hMdDec->mixer_mat_prev[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( pState->hMdDec->mixer_mat_prev[3][0][0], pState->hMdDec->mixer_mat_prev[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( pState->hMdDec->mixer_mat_prev[4][0][0], pState->hMdDec->mixer_mat_prev[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + + for ( out_ch = 0; out_ch < numch_out; out_ch++ ) + { + for ( in_ch = 0; in_ch < numch_in; in_ch++ ) + { + for ( b = 0; b < num_spar_bands; b++ ) + { + pState->hMdDec->mixer_mat_prev[4][out_ch][in_ch][b] = pState->hMdDec->mixer_mat[out_ch][in_ch][b + i_sf * IVAS_MAX_NUM_BANDS]; + } + } + } + } + } + + wmops_sub_end(); + + return; +} diff --git a/lib_dec/ivas_spar_foa_dec.c b/lib_dec/ivas_spar_foa_dec.c deleted file mode 100644 index cbc685bb76..0000000000 --- a/lib_dec/ivas_spar_foa_dec.c +++ /dev/null @@ -1,1012 +0,0 @@ -/****************************************************************************************************** - - (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include "options.h" -#ifdef DEBUGGING -#include "debug.h" -#endif -#include "math.h" -#include "ivas_prot.h" -#include "prot.h" -#include "ivas_rom_com.h" -#include -#include "wmops.h" - - -#ifdef DEBUG_SPAR_FOA -extern FILE *fFb_pcm; -#endif - -/*----------------------------------------------------------------------* - * Local constants - *----------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------* - * Function ivas_get_spar_table_idx_from_coded_idx() - * - * Get SPAR table index - *---------------------------------------------------------------------*/ - -static int16_t ivas_get_spar_table_idx_from_coded_idx( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t sba_order, /* i : Ambisonic (SBA) order */ - Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ - int16_t *bitlen /* o : number of bits */ -) -{ - int16_t table_idx, ind1[IVAS_SPAR_BR_TABLE_LEN]; - int16_t i, j, ind2; - - j = 0; - for ( i = 0; i < IVAS_SPAR_BR_TABLE_LEN; i++ ) - { - ind1[j] = 0; - if ( ( ivas_spar_br_table_consts[i].ivas_total_brate == ivas_total_brate ) && - ( ivas_spar_br_table_consts[i].sba_order == sba_order ) ) - { - ind1[j++] = i; - } - } - - assert( j > 0 ); - - *bitlen = ivas_get_bits_to_encode( j - 1 ); - - ind2 = get_next_indice( st0, *bitlen ); - - table_idx = ind1[ind2]; - - return table_idx; -} - - -/*---------------------------------------------------------------------* - * Function ivas_parse_spar_header() - * - * Get SPAR table index - *---------------------------------------------------------------------*/ - -static int16_t ivas_parse_spar_header( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t sba_order, /* i : Ambisonic (SBA) order */ - Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ - int16_t *table_idx ) -{ - int16_t bitlen, bwidth; - - *table_idx = ivas_get_spar_table_idx_from_coded_idx( ivas_total_brate, sba_order, st0, &bitlen ); - - bwidth = ivas_spar_br_table_consts[( *table_idx )].bwidth; - - return bwidth; -} - - -static float get_random_number( - int16_t *seed ) -{ - float x = (float) own_random( seed ) / 32768.0f; - - return x; -} - - -static float matrix_det( - const float a00, - const float a01, - const float a10, - const float a11 ) -{ - return a00 * a11 - a01 * a10; -} - - -static void matrix_inverse( - float in[3][3], - float out[3][3], - const int16_t size ) -{ - float det, fac; - float eps = 1e-16f; - - if ( size == 1 ) - { - out[0][0] = 1.0f / max( in[0][0], eps ); - - return; - } - else if ( size == 2 ) - { - det = matrix_det( in[0][1], in[0][1], in[1][0], in[1][1] ); - fac = 1.0f / max( det, eps ); - - out[0][0] = in[1][1] * fac; - out[1][0] = in[1][0] * ( -fac ); - - out[0][1] = in[0][1] * ( -fac ); - out[1][1] = in[0][0] * fac; - - return; - } - - det = in[0][0] * matrix_det( in[1][1], in[1][2], in[2][1], in[2][2] ) - in[1][0] * matrix_det( in[0][1], in[0][2], in[2][1], in[2][2] ) + in[2][0] * matrix_det( in[0][1], in[0][2], in[1][1], in[1][2] ); - fac = 1.0f / max( det, eps ); - - out[0][0] = matrix_det( in[1][1], in[1][2], in[2][1], in[2][2] ) * fac; - out[1][0] = matrix_det( in[1][0], in[1][2], in[2][0], in[2][2] ) * ( -fac ); - out[2][0] = matrix_det( in[1][0], in[1][1], in[2][0], in[2][1] ) * fac; - - out[0][1] = matrix_det( in[0][1], in[0][2], in[2][1], in[2][2] ) * ( -fac ); - out[1][1] = matrix_det( in[0][0], in[0][2], in[2][0], in[2][2] ) * fac; - out[2][1] = matrix_det( in[0][0], in[0][1], in[2][0], in[2][1] ) * ( -fac ); - - out[0][2] = matrix_det( in[0][1], in[0][2], in[1][1], in[1][2] ) * fac; - out[1][2] = matrix_det( in[0][0], in[0][2], in[1][0], in[1][2] ) * ( -fac ); - out[2][2] = matrix_det( in[0][0], in[0][1], in[1][0], in[1][1] ) * fac; - - return; -} - - -/*---------------------------------------------------------------------* - * Function ivas_spar_get_cldfb_gains() - * - * - *---------------------------------------------------------------------*/ - -void ivas_spar_get_cldfb_gains( - SPAR_DEC_HANDLE hSpar, - HANDLE_CLDFB_FILTER_BANK cldfbAnaDec0, - HANDLE_CLDFB_FILTER_BANK cldfbSynDec0, - const DECODER_CONFIG_HANDLE hDecoderConfig ) -{ - float output_Fs = (float) hDecoderConfig->output_Fs; - int16_t pt_len, stride, num_cldfb_bands, decfb_delay; - int16_t encfb_delay, cf_start, cf_end, cf_len; - float *weights; - int16_t ts, cf_cldfb_start, cf_cldfb_end; - float cf_start_s, cf_len_s; - int16_t sample, num_cf_slots, num_samples; - float T[3 * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX - CLDFB_NO_CHANNELS_MAX][3]; - float Tt_T[3][3]; - float Tt_T_inv[3][3]; - float Tt_tgt[3]; - float ts_inout[CLDFB_NO_CHANNELS_MAX]; - float ts_re[CLDFB_NO_CHANNELS_MAX]; - float ts_im[CLDFB_NO_CHANNELS_MAX]; - float *pp_ts_im[1], *pp_ts_re[1]; - float tgt[( 3 - 1 ) * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX]; - int16_t seed, split_band, slot_row, slot_col, slot, tmp_idx; - - pt_len = cldfbAnaDec0->p_filter_length; - num_cldfb_bands = cldfbAnaDec0->no_channels; - - stride = NS2SA( output_Fs, DELAY_CLDFB_NS ); - encfb_delay = NS2SA( output_Fs, IVAS_FB_ENC_DELAY_NS ); - decfb_delay = NS2SA( output_Fs, IVAS_FB_DEC_DELAY_NS ); - - cf_start = (int16_t) hSpar->hFbMixer->cross_fade_start_offset - encfb_delay + decfb_delay; /* time domain after CLDFB synthesis*/ - cf_end = (int16_t) hSpar->hFbMixer->cross_fade_end_offset - encfb_delay + decfb_delay; - cf_len = cf_end - cf_start; - weights = hSpar->hFbMixer->cldfb_cross_fade; - - cf_cldfb_start = (int16_t) ceil( ( cf_start - decfb_delay / 2 ) / (float) stride - 0.5f ); - cf_cldfb_end = (int16_t) ( ( cf_start - decfb_delay / 2 + cf_len ) / (float) stride - 0.5f ); - - num_cf_slots = cf_cldfb_end - cf_cldfb_start + 1; - num_samples = num_cf_slots * stride + pt_len - stride; - seed = RANDOM_INITSEED; - split_band = SPAR_DIRAC_SPLIT_START_BAND; - pp_ts_im[0] = ts_im; - pp_ts_re[0] = ts_re; - set_f( tgt, 0, ( 3 - 1 ) * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX ); - - cf_start_s = ( cf_start - decfb_delay / 2 ) / output_Fs; - cf_len_s = hSpar->hFbMixer->cross_fade_end_offset / output_Fs - hSpar->hFbMixer->cross_fade_start_offset / output_Fs; - - for ( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) - { - weights[ts] = ( ( ( ts + 0.5f ) * stride / output_Fs ) - cf_start_s ) / cf_len_s; - weights[ts] = max( min( weights[ts], 1.0f ), 0.0f ); - } - hSpar->hFbMixer->cldfb_cross_fade_start = cf_cldfb_start; - hSpar->hFbMixer->cldfb_cross_fade_end = cf_cldfb_end; - hSpar->hFbMixer->cldfb_latency = decfb_delay; - - if ( num_cf_slots > 3 || pt_len > 10 * CLDFB_NO_CHANNELS_MAX || stride > CLDFB_NO_CHANNELS_MAX || split_band == IVAS_MAX_NUM_BANDS ) - { - return; - } - - /* optimization*/ - /* compute time-domain cross-fade for considered time slots*/ - tmp_idx = cf_start - cf_cldfb_start * stride; - for ( sample = 0; sample < cf_len; sample++ ) - { - /* increasing window function */ - tgt[tmp_idx++] = hSpar->hFbMixer->pFilterbank_cross_fade[sample]; - } - - for ( ; tmp_idx < num_samples; tmp_idx++ ) - { - /* fill up with ones*/ - tgt[tmp_idx] = 1.0f; - } - - for ( sample = 0; sample < num_samples; sample++ ) - { - /* initialize trasnform matrix with zeros*/ - T[sample][0] = T[sample][1] = T[sample][2] = 0.0f; - } - - for ( sample = 0; sample < pt_len - stride; sample++ ) - { - /* fill internal CLDFB analysis time buffer with data*/ - float x = get_random_number( &seed ); - - cldfbAnaDec0->cldfb_state[sample] = x; - } - - for ( slot = 0; slot < num_cf_slots; slot++ ) - { - for ( sample = 0; sample < stride; sample++ ) - { - float x = get_random_number( &seed ); - ts_inout[sample] = x; - } - - cldfbAnalysis_ts( ts_inout, ts_re, ts_im, num_cldfb_bands, cldfbAnaDec0 ); - cldfb_reset_memory( cldfbSynDec0 ); - cldfbSynthesis( pp_ts_re, pp_ts_im, ts_inout, num_cldfb_bands, cldfbSynDec0 ); - - for ( sample = 0; sample < stride; sample++ ) - { - T[slot * stride + sample][slot] = ts_inout[sample]; - } - - tmp_idx = pt_len - 1; - for ( sample = stride; sample < pt_len; sample++ ) - { - T[slot * stride + sample][slot] = cldfbSynDec0->cldfb_state[tmp_idx--]; - } - } - - /* target is synthesis output times the cross-fade window*/ - for ( sample = 0; sample < num_samples; sample++ ) - { - tgt[sample] *= ( T[sample][0] + T[sample][1] + T[sample][2] ); - } - - /* compute matrices */ - for ( slot_row = 0; slot_row < num_cf_slots; slot_row++ ) - { - for ( slot_col = slot_row; slot_col < num_cf_slots; slot_col++ ) - { - Tt_T[slot_row][slot_col] = 0.0f; - for ( sample = 0; sample < num_samples; sample++ ) - { - Tt_T[slot_row][slot_col] += T[sample][slot_row] * T[sample][slot_col]; - } - } - } - - Tt_T[1][0] = Tt_T[0][1]; - Tt_T[2][0] = Tt_T[0][2]; - Tt_T[2][1] = Tt_T[1][2]; - - for ( slot_row = 0; slot_row < num_cf_slots; slot_row++ ) - { - Tt_tgt[slot_row] = 0.0f; - for ( sample = 0; sample < num_samples; sample++ ) - { - Tt_tgt[slot_row] += T[sample][slot_row] * tgt[sample]; - } - } - - matrix_inverse( Tt_T, Tt_T_inv, num_cf_slots ); - - /* compute the optimal coefficients */ - for ( slot_row = 0; slot_row < num_cf_slots; slot_row++ ) - { - float tmp = 0.0f; - for ( slot_col = 0; slot_col < num_cf_slots; slot_col++ ) - { - tmp += Tt_T_inv[slot_row][slot_col] * Tt_tgt[slot_col]; - } - weights[cf_cldfb_start + slot_row] = max( min( tmp, 1.0f ), 0.0f ); - } - - cldfb_reset_memory( cldfbSynDec0 ); - cldfb_reset_memory( cldfbAnaDec0 ); - - return; -} - - -/*---------------------------------------------------------------------* - * Function ivas_is_res_channel() - * - * determines if an FOA input channel is transmitted as residual channel. - *---------------------------------------------------------------------*/ - -/* !r: 1 if prediction residual channel */ -int16_t ivas_is_res_channel( - const int16_t ch, /* i : ch index in WYZX ordering */ - const int16_t nchan_transport /* i : number of transport channels (1-4) */ -) -{ - const int16_t rc_map[FOA_CHANNELS][FOA_CHANNELS] = { - { 0, 0, 0, 0 }, - { 0, 1, 0, 0 }, - { 0, 1, 0, 1 }, - { 0, 1, 1, 1 } - }; - - if ( ch >= FOA_CHANNELS ) - { - /* never transmitted */ - return 0; - } - assert( nchan_transport <= FOA_CHANNELS ); - - return ( rc_map[nchan_transport - 1][ch] ); -} - - -/*-------------------------------------------------------------------* - * ivas_spar_dec_MD() - * - * IVAS SPAR MD decoder - *-------------------------------------------------------------------*/ - -void ivas_spar_dec_MD( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - Decoder_State *st0 /* i/o: decoder state structure - for bitstream handling*/ -) -{ - int16_t num_channels, table_idx, num_bands_out, bfi, sba_order; - int32_t ivas_total_brate; - DECODER_CONFIG_HANDLE hDecoderConfig = st_ivas->hDecoderConfig; - SPAR_DEC_HANDLE pState = st_ivas->hSpar; - - wmops_sub_start( "ivas_spar_dec_MD" ); - - /*---------------------------------------------------------------------* - * Initialization - *---------------------------------------------------------------------*/ - - sba_order = min( st_ivas->sba_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_bands_out = pState->hFbMixer->pFb->filterbank_num_bands; - - if ( ivas_total_brate > FRAME_NO_DATA && !bfi ) - { - if ( ivas_total_brate > IVAS_SID_5k ) - { - ivas_parse_spar_header( hDecoderConfig->ivas_total_brate, sba_order, st0, &table_idx ); - - pState->hMdDec->spar_md.num_bands = min( SPAR_DIRAC_SPLIT_START_BAND, IVAS_MAX_NUM_BANDS ); - - if ( pState->hMdDec->table_idx != table_idx ) - { - pState->hMdDec->table_idx = table_idx; - pState->hTdDecorr->ducking_flag = ivas_spar_br_table_consts[table_idx].td_ducking; - - ivas_spar_md_dec_init( pState->hMdDec, hDecoderConfig, num_channels ); - } - } - - /*---------------------------------------------------------------------* - * Decode MD - *---------------------------------------------------------------------*/ - - ivas_spar_md_dec_process( st_ivas, st0, num_bands_out, sba_order ); - - /*---------------------------------------------------------------------* - * read PCA bits - *---------------------------------------------------------------------*/ - -#ifdef SBA_CLEANING - if ( pState->hPCA != NULL ) -#else - if ( hDecoderConfig->ivas_total_brate == PCA_BRATE && sba_order == 1 ) -#endif - { - ivas_pca_read_bits( st0, pState->hPCA ); - } -#ifndef SBA_CLEANING - else - { - pState->hPCA->pca_bypass = PCA_MODE_INACTIVE; - } -#endif - - /*---------------------------------------------------------------------* - * Read AGC bits - *---------------------------------------------------------------------*/ - - if ( ivas_total_brate > IVAS_SID_5k && !bfi && pState->hMdDec->dtx_vad ) - { - pState->AGC_flag = get_next_indice( st0, 1 ); - - ivas_agc_read_bits( pState->hAgcDec, st0, pState->hMdDec->spar_md_cfg.nchan_transport, pState->AGC_flag ); - } - - /*---------------------------------------------------------------------* - * MD smoothing - *---------------------------------------------------------------------*/ - - if ( st0->m_old_frame_type == ZERO_FRAME && ivas_total_brate == IVAS_SID_5k && st0->prev_bfi == 0 && pState->hMdDec->spar_md_cfg.nchan_transport == 1 ) - { - ivas_spar_setup_md_smoothing( pState->hMdDec, num_bands_out ); - } - else - { - ivas_spar_update_md_hist( pState->hMdDec ); - } - } - else - { - if ( !bfi ) - { - ivas_spar_smooth_md_dtx( pState->hMdDec, num_bands_out ); - } - - set_s( pState->hMdDec->valid_bands, 0, IVAS_MAX_NUM_BANDS ); - } - - wmops_sub_end(); - return; -} - - -/*-------------------------------------------------------------------* - * ivas_spar_get_cldfb_slot_gain() - * - * - *-------------------------------------------------------------------*/ - -static float ivas_spar_get_cldfb_slot_gain( - SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */ - const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ - const int16_t time_slot_idx, - int16_t *time_slot_idx0, - int16_t *time_slot_idx1, - float *weight_lowfreq ) -{ - SPAR_DEC_HANDLE pState = hSpar; - float weight; - float output_Fs, encfb_delay, decfb_delay; - float xfade_start_ns; - int16_t xfade_delay_subframes; - int16_t i_hist; - int16_t split_band; - - *weight_lowfreq = pState->hFbMixer->cldfb_cross_fade[time_slot_idx]; - - output_Fs = (float) hDecoderConfig->output_Fs; - encfb_delay = IVAS_FB_ENC_DELAY_NS; - decfb_delay = IVAS_FB_DEC_DELAY_NS; - xfade_start_ns = pState->hFbMixer->cross_fade_start_offset / output_Fs * 1000000000.f - encfb_delay + decfb_delay * 0.5f; - xfade_delay_subframes = (int16_t) ( xfade_start_ns / ( FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ) ); - - i_hist = 4 - xfade_delay_subframes; - split_band = SPAR_DIRAC_SPLIT_START_BAND; - - if ( split_band < IVAS_MAX_NUM_BANDS ) - { - if ( hSpar->i_subframe > 3 ) - { - weight = (float) ( time_slot_idx % MAX_PARAM_SPATIAL_SUBFRAMES ) / (float) MAX_PARAM_SPATIAL_SUBFRAMES; - } - else - { - weight = 0.0f; - } - *time_slot_idx0 = i_hist; - *time_slot_idx1 = i_hist + 1; - } - else - { - /* determine cross-fade gain for current frame Parameters*/ - *time_slot_idx0 = pState->hFbMixer->cldfb_cross_fade_start; - *time_slot_idx1 = pState->hFbMixer->cldfb_cross_fade_end; - weight = *weight_lowfreq; - } - - return weight; -} - - -/*-------------------------------------------------------------------* - * ivas_spar_get_parameters() - * - * - *-------------------------------------------------------------------*/ - -void ivas_spar_get_parameters( - SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */ - const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ - const int16_t ts, - const int16_t num_ch_out, - const int16_t num_ch_in, - const int16_t num_spar_bands, - float par_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS] ) -{ - int16_t spar_band, out_ch, in_ch; - float weight, weight_20ms; - int16_t ts0, ts1, split_band; - - weight = ivas_spar_get_cldfb_slot_gain( hSpar, hDecoderConfig, ts, &ts0, &ts1, &weight_20ms ); - - split_band = SPAR_DIRAC_SPLIT_START_BAND; - for ( spar_band = 0; spar_band < num_spar_bands; spar_band++ ) - { - for ( out_ch = 0; out_ch < num_ch_out; out_ch++ ) - { - for ( in_ch = 0; in_ch < num_ch_in; in_ch++ ) - { - if ( split_band < IVAS_MAX_NUM_BANDS - /* 20ms cross-fade for Transport channels in all frequency bands */ - && ( 0 == ivas_is_res_channel( out_ch, hSpar->hMdDec->spar_md_cfg.nchan_transport ) ) /* sub-frame processing for missing channels in all frequency bands*/ - ) - { - if ( hSpar->i_subframe > 3 ) - { - par_mat[out_ch][in_ch][spar_band] = ( 1.0f - weight ) * hSpar->hMdDec->mixer_mat_prev[ts0][out_ch][in_ch][spar_band] + - weight * hSpar->hMdDec->mixer_mat_prev[ts1][out_ch][in_ch][spar_band]; - } - else - { - par_mat[out_ch][in_ch][spar_band] = hSpar->hMdDec->mixer_mat[out_ch][in_ch][spar_band]; - } - } - else - { - /* 20ms Transport channel reconstruction with matching encoder/decoder processing */ - int16_t prev_idx = SPAR_DIRAC_SPLIT_START_BAND < IVAS_MAX_NUM_BANDS ? 1 : 0; /* if SPAR_DIRAC_SPLIT_START_BAND == IVAS_MAX_NUM_BANDS, then the sub-frame mixer_mat delay line is not active */ - par_mat[out_ch][in_ch][spar_band] = ( 1.0f - weight_20ms ) * hSpar->hMdDec->mixer_mat_prev[prev_idx][out_ch][in_ch][spar_band] + weight_20ms * hSpar->hMdDec->mixer_mat[out_ch][in_ch][spar_band]; - } - } - } - } - - return; -} - - -/*-------------------------------------------------------------------* - * ivas_spar_get_skip_mat() - * - * - *-------------------------------------------------------------------*/ - -static void ivas_spar_get_skip_mat( - SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */ - 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 spar_band, out_ch, in_ch; - int16_t i_ts, skip_flag; - - for ( out_ch = 0; out_ch < num_ch_out; out_ch++ ) - { - for ( in_ch = 0; in_ch < num_ch_in; in_ch++ ) - { - skip_mat[out_ch][in_ch] = 1; - skip_flag = 1; - - 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 || 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; - } - } - } - } - - return; -} - - -/*-------------------------------------------------------------------* - * ivas_spar_foa_dec_upmixer() - * - * IVAS SPAR upmixer - *-------------------------------------------------------------------*/ - -void ivas_spar_dec_upmixer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float output[][L_FRAME48k], /* i/o: input/output audio channels */ - const int16_t nchan_internal, /* i : number of internal channels */ - const int16_t output_frame /* i : output frame length */ -) -{ - int16_t cldfb_band, num_cldfb_bands, numch_in, numch_out; - float *cldfb_in_ts_re[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX]; - float *cldfb_in_ts_im[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX]; - int16_t i, b, ts, out_ch, in_ch; - int16_t num_spar_bands, spar_band, nchan_transport; - int16_t num_in_ingest, num_bands_out, split_band; - float Pcm_tmp[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - int16_t numch_out_dirac; - float *pPcm_tmp[MAX_OUTPUT_CHANNELS]; - float mixer_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; - int16_t b_skip_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - DECODER_CONFIG_HANDLE hDecoderConfig; - SPAR_DEC_HANDLE pState, hSpar; - - wmops_sub_start( "ivas_spar_dec_upmixer" ); - - hSpar = st_ivas->hSpar; - pState = hSpar; - hDecoderConfig = st_ivas->hDecoderConfig; - num_bands_out = pState->hFbMixer->pFb->filterbank_num_bands; - nchan_transport = pState->hMdDec->spar_md_cfg.nchan_transport; - - num_cldfb_bands = hSpar->hFbMixer->pFb->fb_bin_to_band.num_cldfb_bands; - numch_in = hSpar->hFbMixer->fb_cfg->num_in_chans; - numch_out = hSpar->hFbMixer->fb_cfg->num_out_chans; - -#ifdef DEBUG_SPAR_FOA - if ( fFb_pcm != NULL ) - { - for ( i = 0; i < output_frame; i++ ) - { - for ( int16_t j = 0; j < nchan_transport; j++ ) - { - fscanf( fFb_pcm, "%f\n", &output[j][i] ); - } - } - } -#endif - - /* by-pass EVS */ -#ifdef DEBUG_SPAR_BYPASS_EVS_CODEC - /*write the core coder output to a file for debugging*/ - { - float tmp; - int16_t pcm, j; - for ( j = 0; j < output_frame; j++ ) - { - for ( i = 0; i < nchan_transport; i++ ) - { - tmp = roundf( output[i][j] * PCM16_TO_FLT_FAC ); - pcm = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B - : (short) tmp; - dbgwrite( &pcm, sizeof( int16_t ), 1, 1, "dmx_dec.raw" ); - } - } - } - - /*overwrite the core coder output with core input for debugging*/ - { - static FILE *fid_enc = 0; - int16_t smp; - - if ( !fid_enc ) - { - fid_enc = fopen( "evs_input_float.raw", "rb" ); - } - for ( smp = 0; smp < L_FRAME48k; smp++ ) - { - for ( in_ch = 0; in_ch < nchan_transport; in_ch++ ) - { - fread( &output[in_ch][smp], sizeof( float ), 1, fid_enc ); - } - } - } -#endif - - /*---------------------------------------------------------------------* - * AGC - *---------------------------------------------------------------------*/ - - ivas_agc_dec_process( pState->hAgcDec, output, output, nchan_transport, output_frame ); - - /*---------------------------------------------------------------------* - * TD Decorr and pcm ingest - *---------------------------------------------------------------------*/ - - if ( pState->hMdDec->td_decorr_flag ) - { - num_in_ingest = nchan_internal; - } - else - { - num_in_ingest = nchan_transport; - } - - for ( i = 0; i < nchan_internal; i++ ) - { - pPcm_tmp[i] = Pcm_tmp[i]; - } - - /*---------------------------------------------------------------------* - * PCA decoder - *---------------------------------------------------------------------*/ - -#ifdef SBA_CLEANING - if ( pState->hPCA != NULL ) -#endif - { - ivas_pca_dec( pState->hPCA, output_frame, num_in_ingest, hDecoderConfig->ivas_total_brate, hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, output ); - } - - /*---------------------------------------------------------------------* - * TD decorrelation - *---------------------------------------------------------------------*/ - - if ( pState->hMdDec->td_decorr_flag ) - { - ivas_td_decorr_process( pState->hTdDecorr, output, pPcm_tmp, output_frame ); - - for ( i = 0; i < nchan_internal - nchan_transport; i++ ) - { - mvr2r( pPcm_tmp[pState->hTdDecorr->num_apd_outputs - 1 - i], output[nchan_internal - 1 - i], output_frame ); - } - - pState->hFbMixer->fb_cfg->num_in_chans = num_in_ingest; - } - else - { - pState->hFbMixer->fb_cfg->num_in_chans = num_in_ingest; - } - - /*---------------------------------------------------------------------* - * Prepare CLDFB buffers - *---------------------------------------------------------------------*/ - - /* set-up pointers */ - if ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_FOA ) - { - /* at this point, output channels are used as intermediate procesing buffers */ - for ( in_ch = 0; in_ch < MAX_OUTPUT_CHANNELS; in_ch++ ) - { - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) - { - cldfb_in_ts_re[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands]; - cldfb_in_ts_im[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands + 4 * num_cldfb_bands]; - } - } - } - else - { - for ( in_ch = 0; in_ch < numch_in; in_ch++ ) - { - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) - { - cldfb_in_ts_re[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands]; - cldfb_in_ts_im[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands + 4 * num_cldfb_bands]; - } - } - } - - - /*---------------------------------------------------------------------* - * Gen umx mat - *---------------------------------------------------------------------*/ - - ivas_spar_dec_gen_umx_mat( pState->hMdDec, nchan_transport, num_bands_out, st_ivas->bfi ); - - - /*---------------------------------------------------------------------* - * CLDFB Processing and Synthesis - *---------------------------------------------------------------------*/ - - num_spar_bands = hSpar->hFbMixer->pFb->filterbank_num_bands; - - /* 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*/ - - numch_out_dirac = st_ivas->hDecoderConfig->nchan_out; - - for ( int16_t i_sf = 0; i_sf < MAX_PARAM_SPATIAL_SUBFRAMES; i_sf++ ) - { - /* CLDFB analysis of incoming frame */ - for ( in_ch = 0; in_ch < numch_in; in_ch++ ) - { - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) - { - cldfbAnalysis_ts( - &output[in_ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands], - cldfb_in_ts_re[in_ch][ts], - cldfb_in_ts_im[in_ch][ts], - num_cldfb_bands, - st_ivas->cldfbAnaDec[in_ch] ); - } - } - - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) - { - /* determine SPAR parameters for this time slots */ - ivas_spar_get_parameters( hSpar, st_ivas->hDecoderConfig, ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES, numch_out, numch_in, num_spar_bands, mixer_mat ); - - for ( cldfb_band = 0; cldfb_band < num_cldfb_bands; cldfb_band++ ) - { - float out_re[IVAS_SPAR_MAX_CH]; - float out_im[IVAS_SPAR_MAX_CH]; - float cldfb_par; - ivas_fb_bin_to_band_data_t *bin2band = &pState->hFbMixer->pFb->fb_bin_to_band; - - for ( out_ch = 0; out_ch < numch_out; out_ch++ ) - { - out_re[out_ch] = 0.0f; - out_im[out_ch] = 0.0f; - - for ( in_ch = 0; in_ch < numch_in; in_ch++ ) - { - if ( b_skip_mat[out_ch][in_ch] ) - { - continue; - } - else 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; - } - } - - /*update CLDFB data with the parameter-modified data*/ - for ( out_ch = 0; out_ch < numch_out; out_ch++ ) - { - cldfb_in_ts_re[out_ch][ts][cldfb_band] = out_re[out_ch]; - cldfb_in_ts_im[out_ch][ts][cldfb_band] = out_im[out_ch]; - } - } - } - - if ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_FOA ) - { -#ifdef SBA_CLEANING - ivas_dirac_dec( st_ivas, output, nchan_internal, cldfb_in_ts_re, cldfb_in_ts_im, i_sf ); -#else - nchan_transport = ivas_sba_get_nchan_metadata( st_ivas->sba_order ); // VE: == nchan_internal that is already set correctly - - ivas_dirac_dec( st_ivas, output, nchan_transport, cldfb_in_ts_re, cldfb_in_ts_im, i_sf ); -#endif - } - - if ( st_ivas->hDirAC != NULL ) - { - int16_t outchannels, idx_in, idx_lfe, ch; - idx_in = 0; - idx_lfe = 0; - - outchannels = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; - for ( ch = 0; ch < outchannels; ch++ ) - { - if ( ( st_ivas->hOutSetup.num_lfe > 0 ) && ( st_ivas->hOutSetup.index_lfe[idx_lfe] == ch ) ) - { - set_zero( &( output[ch][i_sf * MAX_PARAM_SPATIAL_SUBFRAMES * num_cldfb_bands] ), MAX_PARAM_SPATIAL_SUBFRAMES * num_cldfb_bands ); - - if ( idx_lfe < ( st_ivas->hDirAC->hOutSetup.num_lfe - 1 ) ) - { - idx_lfe++; - } - } - else - { - if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_FOA || - !( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM ) ) - { - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) - { - cldfbSynthesis( - &cldfb_in_ts_re[idx_in][ts], - &cldfb_in_ts_im[idx_in][ts], - &output[ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands], - num_cldfb_bands, - st_ivas->cldfbSynDec[idx_in] ); - } - } - idx_in++; - } - } - } - else - { - /* CLDFB to time synthesis (overwrite mixer output) */ - for ( out_ch = 0; out_ch < numch_out_dirac; out_ch++ ) - { - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) - { - cldfbSynthesis( - &cldfb_in_ts_re[out_ch][ts], - &cldfb_in_ts_im[out_ch][ts], - &output[out_ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands], - num_cldfb_bands, - st_ivas->cldfbSynDec[out_ch] - - ); - } - } - } - - split_band = SPAR_DIRAC_SPLIT_START_BAND; - if ( split_band < IVAS_MAX_NUM_BANDS ) - { - pState->i_subframe++; - pState->i_subframe = min( pState->i_subframe, MAX_PARAM_SPATIAL_SUBFRAMES ); - mvr2r( pState->hMdDec->mixer_mat_prev[1][0][0], pState->hMdDec->mixer_mat_prev[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); - mvr2r( pState->hMdDec->mixer_mat_prev[2][0][0], pState->hMdDec->mixer_mat_prev[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); - mvr2r( pState->hMdDec->mixer_mat_prev[3][0][0], pState->hMdDec->mixer_mat_prev[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); - mvr2r( pState->hMdDec->mixer_mat_prev[4][0][0], pState->hMdDec->mixer_mat_prev[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); - - for ( out_ch = 0; out_ch < numch_out; out_ch++ ) - { - for ( in_ch = 0; in_ch < numch_in; in_ch++ ) - { - for ( b = 0; b < num_spar_bands; b++ ) - { - pState->hMdDec->mixer_mat_prev[4][out_ch][in_ch][b] = pState->hMdDec->mixer_mat[out_ch][in_ch][b + i_sf * IVAS_MAX_NUM_BANDS]; - } - } - } - } - } - - wmops_sub_end(); - - return; -} diff --git a/lib_dec/ivas_spar_foa_md_dec.c b/lib_dec/ivas_spar_md_dec.c similarity index 100% rename from lib_dec/ivas_spar_foa_md_dec.c rename to lib_dec/ivas_spar_md_dec.c diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index 8254f306b7..a836cc05b3 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -39,10 +39,18 @@ #include "ivas_rom_com.h" #include "ivas_stat_com.h" #include "prot.h" +#include "math.h" #include #include "wmops.h" +/*-------------------------------------------------------------------* + * Local function prototypes + *--------------------------------------------------------------------*/ + +static ivas_error ivas_spar_enc_process( Encoder_Struct *st_ivas, const ENCODER_CONFIG_HANDLE hEncoderConfig, BSTR_ENC_HANDLE hMetaData, const int16_t front_vad_flag, float data_f[][L_FRAME48k] ); + + /*------------------------------------------------------------------------- * ivas_spar_enc_open() * @@ -317,3 +325,617 @@ ivas_error ivas_spar_enc( return error; } + +#ifdef DEBUG_SPAR_FOA +extern FILE *fEvs_enc_in; +extern FILE *fFb_out[4]; +#endif + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_enc_get_windowed_fr() + * + * Get windowed FRs + *-----------------------------------------------------------------------------------------*/ + +static void ivas_spar_enc_get_windowed_fr( + IVAS_FB_MIXER_HANDLE hFbMixer, + float *pIn_blocks[IVAS_SPAR_MAX_CH], + ivas_enc_cov_handler_in_buf_t *pCov_in_buf, + const int16_t input_frame, + const int16_t nchan_inp, + const int16_t num_past_samples ) +{ + int16_t i, j, rev_offset; + + for ( i = 0; i < nchan_inp; i++ ) + { + const int16_t stride = hFbMixer->pFb->fb_bin_to_band.short_stride; + float tmp_buf[MDFT_FB_BANDS_240 * 2]; + int16_t win_len = (int16_t) hFbMixer->ana_window_offset; + float *mdft_in_ptr = tmp_buf + stride - win_len; + float tmp_in_block[L_FRAME48k + MDFT_FB_BANDS_240]; + float *data_ptr = tmp_in_block; + float *fr_re_ptr = pCov_in_buf->ppIn_FR_real[i]; + float *fr_im_ptr = pCov_in_buf->ppIn_FR_imag[i]; + + set_f( tmp_buf, 0, MDFT_FB_BANDS_240 * 2 ); + + /* copy input data, because pIn_blocks and fr_re_ptr + fr_im_ptr use the same memory */ + mvr2r( &pIn_blocks[i][input_frame - num_past_samples], tmp_in_block, input_frame + win_len ); + + for ( int16_t blk = 0; blk < input_frame / stride; blk++ ) + { + + for ( j = 0; j < win_len; j++ ) + { + mdft_in_ptr[j] = data_ptr[j] * hFbMixer->pAna_window[j]; + } + + for ( j = win_len; j < stride; j++ ) + { + mdft_in_ptr[j] = data_ptr[j]; + } + + rev_offset = win_len - 1; + for ( j = stride; j < stride + win_len; j++ ) + { + mdft_in_ptr[j] = data_ptr[j] * hFbMixer->pAna_window[rev_offset--]; + } + + ivas_mdft( tmp_buf, fr_re_ptr, fr_im_ptr, stride << 1, stride ); + + data_ptr += stride; + fr_re_ptr += stride; + fr_im_ptr += stride; + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_enc_process() + * + * Process call for SPAR encoder + *-----------------------------------------------------------------------------------------*/ + +static ivas_error ivas_spar_enc_process( + Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ + const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ + BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ + const int16_t front_vad_flag, /* i : front-VAD decision */ + float data_f[][L_FRAME48k] /* i/o: input/transport audio channels */ +) +{ + float pcm_tmp[IVAS_SPAR_MAX_CH][L_FRAME48k * 2]; + float *p_pcm_tmp[IVAS_SPAR_MAX_CH]; + int16_t i, j, k, b, i_ts, input_frame, num_bands_bw; + int16_t dtx_vad, dtx_cov_flag, dtx_silence_mode; + int32_t ivas_total_brate, input_Fs; + ivas_enc_cov_handler_in_buf_t cov_in_buf; + float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + ivas_spar_md_enc_in_buf_t md_in_buf; + int16_t nchan_inp, nchan_transport, bwidth, sba_order; + int16_t table_idx; + int16_t in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH]; + ivas_error error; + const int16_t *order; + SPAR_ENC_HANDLE pState = 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]; + float w_del_buf[IVAS_FB_1MS_48K_SAMP]; + float dir[3], avg_dir[3]; + float energySum, vecLen; + + wmops_sub_start( "ivas_spar_enc_process" ); + + /*-----------------------------------------------------------------------------------------* + * Initialization + *-----------------------------------------------------------------------------------------*/ + + error = IVAS_ERR_OK; + + input_Fs = hEncoderConfig->input_Fs; + ivas_total_brate = hEncoderConfig->ivas_total_brate; + num_del_samples = pState->hFbMixer->fb_cfg->fb_latency; + + input_frame = ( int16_t )( input_Fs / FRAMES_PER_SEC ); + sba_order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); + nchan_inp = ivas_sba_get_nchan_metadata( sba_order ); + assert( nchan_inp <= hEncoderConfig->nchan_inp ); + + for ( i = FOA_CHANNELS + 1; i < nchan_inp; i++ ) + { + mvr2r( data_f[HOA_keep_ind[i]], data_f[i], input_frame ); + } + + table_idx = ivas_get_spar_table_idx( ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); + + /*-----------------------------------------------------------------------------------------* + * Transient detector + *-----------------------------------------------------------------------------------------*/ + + cov_in_buf.transient_det = ivas_transient_det_process( pState->hTranDet, data_f[0], input_frame ); + + /* store previous input samples for W in local buffer */ + assert( num_del_samples <= IVAS_FB_1MS_48K_SAMP ); + mvr2r( &pState->hFbMixer->ppFilterbank_prior_input[0][pState->hFbMixer->fb_cfg->prior_input_length - num_del_samples], w_del_buf, num_del_samples ); + + /*-----------------------------------------------------------------------------------------* + * FB mixer ingest + *-----------------------------------------------------------------------------------------*/ + + for ( i = 0; i < nchan_inp; i++ ) + { + 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( pState->hFbMixer, data_f, p_pcm_tmp, input_frame ); + + /* prepare Parameter MDFT analysis */ + for ( i = 0; i < nchan_inp; i++ ) + { + cov_in_buf.ppIn_FR_real[i] = p_pcm_tmp[i]; + cov_in_buf.ppIn_FR_imag[i] = p_pcm_tmp[i] + input_frame; + } + + for ( i = 0; i < nchan_inp; i++ ) + { + p_pcm_tmp[i] = &data_f[i][0]; + ppIn_FR_real[i] = cov_in_buf.ppIn_FR_real[i]; + ppIn_FR_imag[i] = cov_in_buf.ppIn_FR_imag[i]; + } + + l_ts = input_frame / MAX_PARAM_SPATIAL_SUBFRAMES; + + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + { + ivas_fb_mixer_get_windowed_fr( pState->hFbMixer, p_pcm_tmp, ppIn_FR_real, ppIn_FR_imag, l_ts, l_ts ); + ivas_fb_mixer_update_prior_input( pState->hFbMixer, p_pcm_tmp, l_ts ); + + for ( i = 0; i < nchan_inp; i++ ) + { + p_pcm_tmp[i] += l_ts; + ppIn_FR_real[i] += l_ts; + ppIn_FR_imag[i] += l_ts; + } + } + + /* turn pointers back to the local buffer, needed for the following processing */ + for ( i = 0; i < nchan_inp; i++ ) + { + p_pcm_tmp[i] = pcm_tmp[i]; + } + + cov_in_buf.num_ch = nchan_inp; + + dtx_vad = ( hEncoderConfig->Opt_DTX_ON == 1 ) ? front_vad_flag : 1; + + /*-----------------------------------------------------------------------------------------* + * DirAC encoding + *-----------------------------------------------------------------------------------------*/ + + ivas_dirac_param_est_enc( st_ivas->hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes, + data_f, cov_in_buf.ppIn_FR_real, cov_in_buf.ppIn_FR_imag, input_frame ); + + if ( hQMetaData->q_direction->cfg.nbands > 0 ) + { + orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands; + + if ( dtx_vad == 1 ) + { + /* WB 4TC mode bit : disable for now*/ + push_next_indice( hMetaData, 0, 1 ); + ivas_qmetadata_enc_encode( hMetaData, hQMetaData ); + } + else + { + hQMetaData->q_direction[0].cfg.nbands = DIRAC_DTX_BANDS; + + /* compute directions */ + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + set_zero( dir, 3 ); + set_zero( avg_dir, 3 ); + energySum = 0.0f; + + /*combine all dirac bands except the last one, handle last band separately, last band covers BW above WB*/ + for ( j = 0; j < orig_dirac_bands - 1; j++ ) + { + ivas_qmetadata_azimuth_elevation_to_direction_vector( hQMetaData->q_direction[0].band_data[j].azimuth[i], hQMetaData->q_direction[0].band_data[j].elevation[i], &dir[0] ); + vecLen = hQMetaData->q_direction[0].band_data[j].energy_ratio[i] * st_ivas->hDirAC->buffer_energy[i * orig_dirac_bands + j]; + + avg_dir[0] += dir[0] * vecLen; + avg_dir[1] += dir[1] * vecLen; + avg_dir[2] += dir[2] * vecLen; + + energySum += st_ivas->hDirAC->buffer_energy[i * orig_dirac_bands + j]; + } + + ivas_qmetadata_direction_vector_to_azimuth_elevation( &avg_dir[0], &hQMetaData->q_direction[0].band_data[0].azimuth[i], &hQMetaData->q_direction[0].band_data[0].elevation[i] ); + hQMetaData->q_direction[0].band_data[0].energy_ratio[i] = sqrtf( dotp( avg_dir, avg_dir, 3 ) ) / ( energySum + EPSILON ); + + hQMetaData->q_direction[0].band_data[1].azimuth[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i]; + hQMetaData->q_direction[0].band_data[1].elevation[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation[i]; + hQMetaData->q_direction[0].band_data[1].energy_ratio[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio[i]; + } + + /* 1 bit to indicate mode MD coding : temp solution*/ + push_next_indice( hMetaData, 1, 1 ); + + /* encode SID parameters */ + ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, SBA_FORMAT, st_ivas->sba_mode ); + } + + for ( b = hQMetaData->q_direction->cfg.start_band; b < hQMetaData->q_direction->cfg.nbands; b++ ) + { + for ( i_ts = 0; i_ts < ( ( dtx_vad == 1 ) ? hQMetaData->q_direction[0].cfg.nblocks : 1 ); i_ts++ ) + { + hQMetaData->q_direction->band_data[b].azimuth[i_ts] = hQMetaData->q_direction->band_data[b].q_azimuth[i_ts]; + hQMetaData->q_direction->band_data[b].elevation[i_ts] = hQMetaData->q_direction->band_data[b].q_elevation[i_ts]; + hQMetaData->q_direction[0].band_data[b].energy_ratio[0] = 1.0f - diffuseness_reconstructions[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]]; + } + } + + if ( dtx_vad == 0 ) + { + + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i] = hQMetaData->q_direction[0].band_data[1].azimuth[0]; + hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation[i] = hQMetaData->q_direction[0].band_data[1].elevation[0]; + hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio[0]; + } + + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + for ( j = orig_dirac_bands - 2; j >= 0; j-- ) + { + hQMetaData->q_direction[0].band_data[j].azimuth[i] = hQMetaData->q_direction[0].band_data[0].azimuth[0]; + hQMetaData->q_direction[0].band_data[j].elevation[i] = hQMetaData->q_direction[0].band_data[0].elevation[0]; + hQMetaData->q_direction[0].band_data[j].energy_ratio[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio[0]; + } + } + + hQMetaData->q_direction->cfg.nbands = orig_dirac_bands; + } + } + + + /*-----------------------------------------------------------------------------------------* + * Pre-proc flags + *-----------------------------------------------------------------------------------------*/ + + /* use just VAD function to get VAD flags */ + dtx_vad = ( hEncoderConfig->Opt_DTX_ON == 1 ) ? front_vad_flag : 1; + dtx_cov_flag = ( dtx_vad == 1 ) ? 0 : 1; + dtx_silence_mode = 0; + bwidth = ivas_get_bw_idx_from_sample_rate( input_Fs ); + bwidth = min( bwidth, hEncoderConfig->max_bwidth ); + + /*-----------------------------------------------------------------------------------------* + * Covariance process + *-----------------------------------------------------------------------------------------*/ + + cov_in_buf.num_ch = nchan_inp; + + for ( i = 0; i < nchan_inp; i++ ) + { + for ( j = 0; j < nchan_inp; j++ ) + { + cov_real[i][j] = pState->hMdEnc->cov_real[i][j]; + cov_dtx_real[i][j] = pState->hMdEnc->cov_dtx_real[i][j]; + } + } + + cov_in_buf.dtx_cov_flag = dtx_cov_flag; + ivas_enc_cov_handler_process( pState->hCovEnc, &cov_in_buf, cov_real, cov_dtx_real, pState->hFbMixer->pFb, 0, pState->hFbMixer->pFb->filterbank_num_bands ); + + if ( pState->hMdEnc->table_idx != table_idx ) + { + pState->hMdEnc->table_idx = table_idx; + ivas_spar_set_bitrate_config( &pState->hMdEnc->spar_md_cfg, table_idx, SPAR_DIRAC_SPLIT_START_BAND ); + } + + nchan_transport = pState->hMdEnc->spar_md_cfg.nchan_transport; + + /*-----------------------------------------------------------------------------------------* + * MetaData encoder + *-----------------------------------------------------------------------------------------*/ + + num_bands_bw = ivas_get_num_bands_from_bw_idx( bwidth ); + + if ( dtx_vad == 0 ) + { + for ( i = 0; i < nchan_inp; i++ ) + { + for ( j = 0; j < nchan_inp; j++ ) + { + md_in_buf.cov_real[i][j] = cov_dtx_real[i][j]; + for ( k = num_bands_bw; k < IVAS_MAX_NUM_BANDS; k++ ) + { + md_in_buf.cov_real[i][j][k] = 0; + } + } + } + } + else + { + for ( i = 0; i < nchan_inp; i++ ) + { + for ( j = 0; j < nchan_inp; j++ ) + { + md_in_buf.cov_real[i][j] = cov_real[i][j]; + for ( k = num_bands_bw; k < IVAS_MAX_NUM_BANDS; k++ ) + { + md_in_buf.cov_real[i][j][k] = 0; + } + } + } + } + + md_in_buf.num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW ); + md_in_buf.num_bands = min( md_in_buf.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); + + md_in_buf.dtx_vad = dtx_vad; + + ivas_spar_md_enc_process( pState->hMdEnc, hEncoderConfig, &md_in_buf, hMetaData, dtx_silence_mode ); + + if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + { + float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + float diffuseness[IVAS_MAX_NUM_BANDS]; + float Wscale_d[IVAS_MAX_NUM_BANDS]; + int16_t d_start_band, d_end_band; + int16_t dirac_band_idx; + + d_start_band = st_ivas->hSpar->enc_param_start_band; + d_end_band = IVAS_MAX_NUM_BANDS; + + for ( b = d_start_band; b < d_end_band; b++ ) + { + dirac_band_idx = st_ivas->hSpar->dirac_to_spar_md_bands[b] - d_start_band; + for ( i_ts = 0; i_ts < hQMetaData->q_direction->cfg.nblocks; i_ts++ ) + { + azi_dirac[b][i_ts] = hQMetaData->q_direction->band_data[dirac_band_idx].azimuth[i_ts]; + ele_dirac[b][i_ts] = hQMetaData->q_direction->band_data[dirac_band_idx].elevation[i_ts]; + } + diffuseness[b] = 1.0f - hQMetaData->q_direction->band_data[dirac_band_idx].energy_ratio[0]; + } + + if ( ( d_start_band >= 6 ) && ( dtx_vad == 1 ) ) + { + for ( i = 0; i < IVAS_SPAR_MAX_CH - 1; i++ ) + { + pState->hMdEnc->spar_md.band_coeffs[d_start_band - 1].P_re[i] = + pState->hMdEnc->spar_md.band_coeffs[d_start_band - 1].P_quant_re[i]; + } + } + + for ( b = d_start_band; b < d_end_band; b++ ) + { + Wscale_d[b] = 1.0f; + for ( i = 1; i < nchan_inp; i++ ) + { + Wscale_d[b] += md_in_buf.cov_real[i][i][b] / max( EPSILON, md_in_buf.cov_real[0][0][b] ); + } + Wscale_d[b] = Wscale_d[b] / ( 1.0f + (float) sba_order ); /*DirAC normalized signal variance sums to 1 + order*/ + Wscale_d[b] = sqrtf( Wscale_d[b] ); + Wscale_d[b] = min( 2.0f, max( Wscale_d[b], 1.0f ) ); + } + + ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, pState->hMdEnc->mixer_mat, &pState->hMdEnc->spar_md, &pState->hMdEnc->spar_md_cfg, + d_start_band, d_end_band, sba_order, dtx_vad, Wscale_d ); + } + + + /*-----------------------------------------------------------------------------------------* + * FB mixer + *-----------------------------------------------------------------------------------------*/ + + ivas_fb_mixer_get_in_out_mapping( pState->hFbMixer->fb_cfg, nchan_transport, ENC, remix_order_set[pState->hMdEnc->spar_md_cfg.remix_unmix_order], in_out_mixer_map ); + +#ifdef DEBUG_SPAR_FOA + { + static FILE *f_mat = 0; + + if ( f_mat == 0 ) + f_mat = fopen( "mixer_mat_enc", "w" ); + + for ( i = 0; i < pState->hFbMixer->fb_cfg->num_out_chans; i++ ) + { + for ( j = 0; j < pState->hFbMixer->fb_cfg->num_in_chans; j++ ) + { + for ( k = 0; k < pState->hFbMixer->pFb->filterbank_num_bands; k++ ) + { + fprintf( f_mat, "%f\n", pState->hMdEnc->mixer_mat[i][j][k] ); + + if ( ( in_out_mixer_map[i][j] == 0 ) && ( fabs( pState->hMdEnc->mixer_mat[i][j][k] ) > 1e-20 ) ) + { + assert( 0 && "Non zero value in unexpected mixer map!!!" ); + } + } + } + } + } +#endif +#ifdef DEBUG_SPAR_DIRAC_WRITE_OUT_PRED_PARS + { + static FILE *fid = 0; + int16_t band = 9; + if ( !fid ) + { + fid = fopen( "pred_coeffs_enc.txt", "wt" ); + } + fprintf( fid, "%.6f\n", pState->hMdEnc->mixer_mat[1][0][band] ); + } +#endif + + ivas_fb_mixer_process( pState->hFbMixer, pState->hMdEnc->mixer_mat, p_pcm_tmp, input_frame, in_out_mixer_map ); + + /* move delayed W into output buffer unless activeW operation*/ + if ( pState->hFbMixer->fb_cfg->active_w_mixing == 0 ) + { + mvr2r( w_del_buf, p_pcm_tmp[0], num_del_samples ); + mvr2r( data_f[0], p_pcm_tmp[0] + num_del_samples, input_frame - num_del_samples ); + } + + /*-----------------------------------------------------------------------------------------* + * PCA encoder + *-----------------------------------------------------------------------------------------*/ + + if ( pState->hPCA != NULL ) + { + ivas_pca_enc( hEncoderConfig, pState->hPCA, hMetaData, p_pcm_tmp, input_frame, FOA_CHANNELS ); + } + else + { + if ( ivas_total_brate == PCA_BRATE && sba_order == 1 ) + { + /* write PCA bypass bit */ + push_next_indice( hMetaData, PCA_MODE_INACTIVE, 1 ); + } + } + + +#ifdef SPAR_HOA_DBG + /*FILE *fp = fopen("int_enc_dmx.raw", "ab"); + for (int16_t t = 0; t < 960; t++) + { + for (int16_t c = 0; c < pState->hFbMixer->filterbank_num_out_chans; c++) + { + for ( k = 0; k < 2; k++ ) + { + fb_mixer_in_buf.ppMixer[i][j][k] = pState->hMdEnc->mixer_mat[i][j]; + } + } + } + fclose( fp );*/ +#endif + /*-----------------------------------------------------------------------------------------* + * AGC + *-----------------------------------------------------------------------------------------*/ + + if ( dtx_vad == 1 ) + { + if ( hEncoderConfig->Opt_AGC_ON > 0 ) + { + ivas_agc_enc_process( pState->hAgcEnc, hMetaData, p_pcm_tmp, p_pcm_tmp, pState->hFbMixer->fb_cfg->num_out_chans, hEncoderConfig ); + } + else + { + push_next_indice( hMetaData, 0, 1 ); + } + } + +#ifdef DEBUG_SPAR_BYPASS_EVS_CODEC + { + static FILE *fid_enc = 0; + static float delay_buf[576 * 4] = { 0 }; + int16_t smp, ch, buf_idx, framelen = input_frame, delay = 576; + if ( !fid_enc ) + { + fid_enc = fopen( "evs_input_float.raw", "wb" ); + } + + /* write out buffer */ + for ( smp = 0; smp < delay * nchan_transport; smp++ ) + { + fwrite( &delay_buf[smp], sizeof( float ), 1, fid_enc ); + } + + for ( smp = 0; smp < framelen - delay; smp++ ) + { + for ( ch = 0; ch < nchan_transport; ch++ ) + { + fwrite( &p_pcm_tmp[ch][smp], sizeof( float ), 1, fid_enc ); + } + } + + /* update delay buffer*/ + buf_idx = 0; + for ( ; smp < framelen; smp++ ) + { + for ( ch = 0; ch < nchan_transport; ch++ ) + { + delay_buf[buf_idx++] = p_pcm_tmp[ch][smp]; + } + } + } +#endif + +#ifdef DEBUG_SPAR_FOA + float tmp; + int16_t pcm; + + for ( j = 0; j < input_frame; j++ ) + { + for ( i = 0; i < nchan_transport; i++ ) + { + tmp = roundf( p_pcm_tmp[i][j] * PCM16_TO_FLT_FAC ); + pcm = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B : (short) tmp; + dbgwrite( &pcm, sizeof( int16_t ), 1, 1, "dmx.raw" ); + } + } + + /* Plug evs i/p from Matlab */ + if ( fEvs_enc_in != NULL ) + { + /*printf("evs enc in file found\n");*/ + float tmp_in = 0; + int16_t diff[FOA_CHANNELS][L_FRAME48k], tmp16; + int16_t max_diff = 0; + int16_t abs_tol = 8; + + for ( i = 0; i < input_frame; i++ ) + { + for ( j = 0; j < nchan_transport; j++ ) + { + tmp = p_pcm_tmp[j][i]; + tmp = roundf( tmp * PCM16_TO_FLT_FAC ); + tmp16 = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B : (int16_t) tmp; + fscanf( fEvs_enc_in, "%f\n", &tmp_in ); + p_pcm_tmp[j][i] = tmp_in; + + tmp = roundf( tmp_in * PCM16_TO_FLT_FAC ); + pcm = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B : (int16_t) tmp; + diff[j][i] = (int16_t) abs( tmp16 - pcm ); + max_diff = max( max_diff, diff[j][i] ); + } + } + + if ( max_diff > abs_tol ) + { + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR FOA ENC fb mixer out mismatch, max diff = %d", max_diff ); + } + } +#endif + + /*-----------------------------------------------------------------------------------------* + * Re-order the dmx back to ACN/SN3D format + *-----------------------------------------------------------------------------------------*/ + + order = remix_order_set[pState->hMdEnc->spar_md_cfg.remix_unmix_order]; + + for ( i = 0; i < input_frame; i++ ) + { + for ( j = 0; j < nchan_transport; j++ ) + { + data_f[order[j]][i] = p_pcm_tmp[j][i] * PCM16_TO_FLT_FAC; + } + for ( ; j < IVAS_SPAR_MAX_DMX_CHS; j++ ) + { + data_f[order[j]][i] = 0; + } + } + + wmops_sub_end(); + + return error; +} diff --git a/lib_enc/ivas_spar_foa_enc.c b/lib_enc/ivas_spar_foa_enc.c deleted file mode 100644 index 913ed599bb..0000000000 --- a/lib_enc/ivas_spar_foa_enc.c +++ /dev/null @@ -1,661 +0,0 @@ -/****************************************************************************************************** - - (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include "options.h" -#ifdef DEBUGGING -#include "debug.h" -#endif -#include "ivas_prot.h" -#include "prot.h" -#include "ivas_rom_com.h" -#include "ivas_stat_com.h" -#include "math.h" -#include -#include "wmops.h" - -#ifdef DEBUG_SPAR_FOA -extern FILE *fEvs_enc_in; -extern FILE *fFb_out[4]; -#endif - - -/*-----------------------------------------------------------------------------------------* - * Function ivas_spar_enc_get_windowed_fr() - * - * Get windowed FRs - *-----------------------------------------------------------------------------------------*/ - -static void ivas_spar_enc_get_windowed_fr( - IVAS_FB_MIXER_HANDLE hFbMixer, - float *pIn_blocks[IVAS_SPAR_MAX_CH], - ivas_enc_cov_handler_in_buf_t *pCov_in_buf, - const int16_t input_frame, - const int16_t nchan_inp, - const int16_t num_past_samples ) -{ - int16_t i, j, rev_offset; - - for ( i = 0; i < nchan_inp; i++ ) - { - const int16_t stride = hFbMixer->pFb->fb_bin_to_band.short_stride; - float tmp_buf[MDFT_FB_BANDS_240 * 2]; - int16_t win_len = (int16_t) hFbMixer->ana_window_offset; - float *mdft_in_ptr = tmp_buf + stride - win_len; - float tmp_in_block[L_FRAME48k + MDFT_FB_BANDS_240]; - float *data_ptr = tmp_in_block; - float *fr_re_ptr = pCov_in_buf->ppIn_FR_real[i]; - float *fr_im_ptr = pCov_in_buf->ppIn_FR_imag[i]; - - set_f( tmp_buf, 0, MDFT_FB_BANDS_240 * 2 ); - - /* copy input data, because pIn_blocks and fr_re_ptr + fr_im_ptr use the same memory */ - mvr2r( &pIn_blocks[i][input_frame - num_past_samples], tmp_in_block, input_frame + win_len ); - - for ( int16_t blk = 0; blk < input_frame / stride; blk++ ) - { - - for ( j = 0; j < win_len; j++ ) - { - mdft_in_ptr[j] = data_ptr[j] * hFbMixer->pAna_window[j]; - } - - for ( j = win_len; j < stride; j++ ) - { - mdft_in_ptr[j] = data_ptr[j]; - } - - rev_offset = win_len - 1; - for ( j = stride; j < stride + win_len; j++ ) - { - mdft_in_ptr[j] = data_ptr[j] * hFbMixer->pAna_window[rev_offset--]; - } - - ivas_mdft( tmp_buf, fr_re_ptr, fr_im_ptr, stride << 1, stride ); - - data_ptr += stride; - fr_re_ptr += stride; - fr_im_ptr += stride; - } - } - - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function ivas_spar_enc_process() - * - * Process call for SPAR encoder - *-----------------------------------------------------------------------------------------*/ - -ivas_error ivas_spar_enc_process( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ - BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ - const int16_t front_vad_flag, /* i : front-VAD decision */ - float data_f[][L_FRAME48k] /* i/o: input/transport audio channels */ -) -{ - float pcm_tmp[IVAS_SPAR_MAX_CH][L_FRAME48k * 2]; - float *p_pcm_tmp[IVAS_SPAR_MAX_CH]; - int16_t i, j, k, b, i_ts, input_frame, num_bands_bw; - int16_t dtx_vad, dtx_cov_flag, dtx_silence_mode; - int32_t ivas_total_brate, input_Fs; - ivas_enc_cov_handler_in_buf_t cov_in_buf; - float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - ivas_spar_md_enc_in_buf_t md_in_buf; - int16_t nchan_inp, nchan_transport, bwidth, sba_order; - int16_t table_idx; - int16_t in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH]; - ivas_error error; - const int16_t *order; - SPAR_ENC_HANDLE pState = 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]; - float w_del_buf[IVAS_FB_1MS_48K_SAMP]; - float dir[3], avg_dir[3]; - float energySum, vecLen; - - wmops_sub_start( "ivas_spar_enc_process" ); - - /*-----------------------------------------------------------------------------------------* - * Initialization - *-----------------------------------------------------------------------------------------*/ - - error = IVAS_ERR_OK; - - input_Fs = hEncoderConfig->input_Fs; - ivas_total_brate = hEncoderConfig->ivas_total_brate; - num_del_samples = pState->hFbMixer->fb_cfg->fb_latency; - - input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC ); - sba_order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); - nchan_inp = ivas_sba_get_nchan_metadata( sba_order ); - assert( nchan_inp <= hEncoderConfig->nchan_inp ); - - for ( i = FOA_CHANNELS + 1; i < nchan_inp; i++ ) - { - mvr2r( data_f[HOA_keep_ind[i]], data_f[i], input_frame ); - } - - table_idx = ivas_get_spar_table_idx( ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); - - /*-----------------------------------------------------------------------------------------* - * Transient detector - *-----------------------------------------------------------------------------------------*/ - - cov_in_buf.transient_det = ivas_transient_det_process( pState->hTranDet, data_f[0], input_frame ); - - /* store previous input samples for W in local buffer */ - assert( num_del_samples <= IVAS_FB_1MS_48K_SAMP ); - mvr2r( &pState->hFbMixer->ppFilterbank_prior_input[0][pState->hFbMixer->fb_cfg->prior_input_length - num_del_samples], w_del_buf, num_del_samples ); - - /*-----------------------------------------------------------------------------------------* - * FB mixer ingest - *-----------------------------------------------------------------------------------------*/ - - for ( i = 0; i < nchan_inp; i++ ) - { - 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( pState->hFbMixer, data_f, p_pcm_tmp, input_frame ); - - /* prepare Parameter MDFT analysis */ - for ( i = 0; i < nchan_inp; i++ ) - { - cov_in_buf.ppIn_FR_real[i] = p_pcm_tmp[i]; - cov_in_buf.ppIn_FR_imag[i] = p_pcm_tmp[i] + input_frame; - } - - for ( i = 0; i < nchan_inp; i++ ) - { - p_pcm_tmp[i] = &data_f[i][0]; - ppIn_FR_real[i] = cov_in_buf.ppIn_FR_real[i]; - ppIn_FR_imag[i] = cov_in_buf.ppIn_FR_imag[i]; - } - - l_ts = input_frame / MAX_PARAM_SPATIAL_SUBFRAMES; - - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) - { - ivas_fb_mixer_get_windowed_fr( pState->hFbMixer, p_pcm_tmp, ppIn_FR_real, ppIn_FR_imag, l_ts, l_ts ); - ivas_fb_mixer_update_prior_input( pState->hFbMixer, p_pcm_tmp, l_ts ); - - for ( i = 0; i < nchan_inp; i++ ) - { - p_pcm_tmp[i] += l_ts; - ppIn_FR_real[i] += l_ts; - ppIn_FR_imag[i] += l_ts; - } - } - - /* turn pointers back to the local buffer, needed for the following processing */ - for ( i = 0; i < nchan_inp; i++ ) - { - p_pcm_tmp[i] = pcm_tmp[i]; - } - - cov_in_buf.num_ch = nchan_inp; - - dtx_vad = ( hEncoderConfig->Opt_DTX_ON == 1 ) ? front_vad_flag : 1; - - /*-----------------------------------------------------------------------------------------* - * DirAC encoding - *-----------------------------------------------------------------------------------------*/ - - ivas_dirac_param_est_enc( st_ivas->hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes, - data_f, cov_in_buf.ppIn_FR_real, cov_in_buf.ppIn_FR_imag, input_frame ); - - if ( hQMetaData->q_direction->cfg.nbands > 0 ) - { - orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands; - - if ( dtx_vad == 1 ) - { - /* WB 4TC mode bit : disable for now*/ - push_next_indice( hMetaData, 0, 1 ); - ivas_qmetadata_enc_encode( hMetaData, hQMetaData ); - } - else - { - hQMetaData->q_direction[0].cfg.nbands = DIRAC_DTX_BANDS; - - /* compute directions */ - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - set_zero( dir, 3 ); - set_zero( avg_dir, 3 ); - energySum = 0.0f; - - /*combine all dirac bands except the last one, handle last band separately, last band covers BW above WB*/ - for ( j = 0; j < orig_dirac_bands - 1; j++ ) - { - ivas_qmetadata_azimuth_elevation_to_direction_vector( hQMetaData->q_direction[0].band_data[j].azimuth[i], hQMetaData->q_direction[0].band_data[j].elevation[i], &dir[0] ); - vecLen = hQMetaData->q_direction[0].band_data[j].energy_ratio[i] * st_ivas->hDirAC->buffer_energy[i * orig_dirac_bands + j]; - - avg_dir[0] += dir[0] * vecLen; - avg_dir[1] += dir[1] * vecLen; - avg_dir[2] += dir[2] * vecLen; - - energySum += st_ivas->hDirAC->buffer_energy[i * orig_dirac_bands + j]; - } - - ivas_qmetadata_direction_vector_to_azimuth_elevation( &avg_dir[0], &hQMetaData->q_direction[0].band_data[0].azimuth[i], &hQMetaData->q_direction[0].band_data[0].elevation[i] ); - hQMetaData->q_direction[0].band_data[0].energy_ratio[i] = sqrtf( dotp( avg_dir, avg_dir, 3 ) ) / ( energySum + EPSILON ); - - hQMetaData->q_direction[0].band_data[1].azimuth[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i]; - hQMetaData->q_direction[0].band_data[1].elevation[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation[i]; - hQMetaData->q_direction[0].band_data[1].energy_ratio[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio[i]; - } - - /* 1 bit to indicate mode MD coding : temp solution*/ - push_next_indice( hMetaData, 1, 1 ); - - /* encode SID parameters */ - ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, SBA_FORMAT, st_ivas->sba_mode ); - } - - for ( b = hQMetaData->q_direction->cfg.start_band; b < hQMetaData->q_direction->cfg.nbands; b++ ) - { - for ( i_ts = 0; i_ts < ( ( dtx_vad == 1 ) ? hQMetaData->q_direction[0].cfg.nblocks : 1 ); i_ts++ ) - { - hQMetaData->q_direction->band_data[b].azimuth[i_ts] = hQMetaData->q_direction->band_data[b].q_azimuth[i_ts]; - hQMetaData->q_direction->band_data[b].elevation[i_ts] = hQMetaData->q_direction->band_data[b].q_elevation[i_ts]; - hQMetaData->q_direction[0].band_data[b].energy_ratio[0] = 1.0f - diffuseness_reconstructions[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]]; - } - } - - if ( dtx_vad == 0 ) - { - - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i] = hQMetaData->q_direction[0].band_data[1].azimuth[0]; - hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation[i] = hQMetaData->q_direction[0].band_data[1].elevation[0]; - hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio[0]; - } - - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - for ( j = orig_dirac_bands - 2; j >= 0; j-- ) - { - hQMetaData->q_direction[0].band_data[j].azimuth[i] = hQMetaData->q_direction[0].band_data[0].azimuth[0]; - hQMetaData->q_direction[0].band_data[j].elevation[i] = hQMetaData->q_direction[0].band_data[0].elevation[0]; - hQMetaData->q_direction[0].band_data[j].energy_ratio[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio[0]; - } - } - - hQMetaData->q_direction->cfg.nbands = orig_dirac_bands; - } - } - - - /*-----------------------------------------------------------------------------------------* - * Pre-proc flags - *-----------------------------------------------------------------------------------------*/ - - /* use just VAD function to get VAD flags */ - dtx_vad = ( hEncoderConfig->Opt_DTX_ON == 1 ) ? front_vad_flag : 1; - dtx_cov_flag = ( dtx_vad == 1 ) ? 0 : 1; - dtx_silence_mode = 0; - bwidth = ivas_get_bw_idx_from_sample_rate( input_Fs ); - bwidth = min( bwidth, hEncoderConfig->max_bwidth ); - - /*-----------------------------------------------------------------------------------------* - * Covariance process - *-----------------------------------------------------------------------------------------*/ - - cov_in_buf.num_ch = nchan_inp; - - for ( i = 0; i < nchan_inp; i++ ) - { - for ( j = 0; j < nchan_inp; j++ ) - { - cov_real[i][j] = pState->hMdEnc->cov_real[i][j]; - cov_dtx_real[i][j] = pState->hMdEnc->cov_dtx_real[i][j]; - } - } - - cov_in_buf.dtx_cov_flag = dtx_cov_flag; - ivas_enc_cov_handler_process( pState->hCovEnc, &cov_in_buf, cov_real, cov_dtx_real, pState->hFbMixer->pFb, 0, pState->hFbMixer->pFb->filterbank_num_bands ); - - if ( pState->hMdEnc->table_idx != table_idx ) - { - pState->hMdEnc->table_idx = table_idx; - ivas_spar_set_bitrate_config( &pState->hMdEnc->spar_md_cfg, table_idx, SPAR_DIRAC_SPLIT_START_BAND ); - } - - nchan_transport = pState->hMdEnc->spar_md_cfg.nchan_transport; - - /*-----------------------------------------------------------------------------------------* - * MetaData encoder - *-----------------------------------------------------------------------------------------*/ - - num_bands_bw = ivas_get_num_bands_from_bw_idx( bwidth ); - - if ( dtx_vad == 0 ) - { - for ( i = 0; i < nchan_inp; i++ ) - { - for ( j = 0; j < nchan_inp; j++ ) - { - md_in_buf.cov_real[i][j] = cov_dtx_real[i][j]; - for ( k = num_bands_bw; k < IVAS_MAX_NUM_BANDS; k++ ) - { - md_in_buf.cov_real[i][j][k] = 0; - } - } - } - } - else - { - for ( i = 0; i < nchan_inp; i++ ) - { - for ( j = 0; j < nchan_inp; j++ ) - { - md_in_buf.cov_real[i][j] = cov_real[i][j]; - for ( k = num_bands_bw; k < IVAS_MAX_NUM_BANDS; k++ ) - { - md_in_buf.cov_real[i][j][k] = 0; - } - } - } - } - - md_in_buf.num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW ); - md_in_buf.num_bands = min( md_in_buf.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); - - md_in_buf.dtx_vad = dtx_vad; - - ivas_spar_md_enc_process( pState->hMdEnc, hEncoderConfig, &md_in_buf, hMetaData, dtx_silence_mode ); - - if ( st_ivas->sba_mode == SBA_MODE_SPAR ) - { - float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; - float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; - float diffuseness[IVAS_MAX_NUM_BANDS]; - float Wscale_d[IVAS_MAX_NUM_BANDS]; - int16_t d_start_band, d_end_band; - int16_t dirac_band_idx; - - d_start_band = st_ivas->hSpar->enc_param_start_band; - d_end_band = IVAS_MAX_NUM_BANDS; - - for ( b = d_start_band; b < d_end_band; b++ ) - { - dirac_band_idx = st_ivas->hSpar->dirac_to_spar_md_bands[b] - d_start_band; - for ( i_ts = 0; i_ts < hQMetaData->q_direction->cfg.nblocks; i_ts++ ) - { - azi_dirac[b][i_ts] = hQMetaData->q_direction->band_data[dirac_band_idx].azimuth[i_ts]; - ele_dirac[b][i_ts] = hQMetaData->q_direction->band_data[dirac_band_idx].elevation[i_ts]; - } - diffuseness[b] = 1.0f - hQMetaData->q_direction->band_data[dirac_band_idx].energy_ratio[0]; - } - - if ( ( d_start_band >= 6 ) && ( dtx_vad == 1 ) ) - { - for ( i = 0; i < IVAS_SPAR_MAX_CH - 1; i++ ) - { - pState->hMdEnc->spar_md.band_coeffs[d_start_band - 1].P_re[i] = - pState->hMdEnc->spar_md.band_coeffs[d_start_band - 1].P_quant_re[i]; - } - } - - for ( b = d_start_band; b < d_end_band; b++ ) - { - Wscale_d[b] = 1.0f; - for ( i = 1; i < nchan_inp; i++ ) - { - Wscale_d[b] += md_in_buf.cov_real[i][i][b] / max( EPSILON, md_in_buf.cov_real[0][0][b] ); - } - Wscale_d[b] = Wscale_d[b] / ( 1.0f + (float) sba_order ); /*DirAC normalized signal variance sums to 1 + order*/ - Wscale_d[b] = sqrtf( Wscale_d[b] ); - Wscale_d[b] = min( 2.0f, max( Wscale_d[b], 1.0f ) ); - } - - ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, pState->hMdEnc->mixer_mat, &pState->hMdEnc->spar_md, &pState->hMdEnc->spar_md_cfg, - d_start_band, d_end_band, sba_order, dtx_vad, Wscale_d ); - } - - - /*-----------------------------------------------------------------------------------------* - * FB mixer - *-----------------------------------------------------------------------------------------*/ - - ivas_fb_mixer_get_in_out_mapping( pState->hFbMixer->fb_cfg, nchan_transport, ENC, remix_order_set[pState->hMdEnc->spar_md_cfg.remix_unmix_order], in_out_mixer_map ); - -#ifdef DEBUG_SPAR_FOA - { - static FILE *f_mat = 0; - - if ( f_mat == 0 ) - f_mat = fopen( "mixer_mat_enc", "w" ); - - for ( i = 0; i < pState->hFbMixer->fb_cfg->num_out_chans; i++ ) - { - for ( j = 0; j < pState->hFbMixer->fb_cfg->num_in_chans; j++ ) - { - for ( k = 0; k < pState->hFbMixer->pFb->filterbank_num_bands; k++ ) - { - fprintf( f_mat, "%f\n", pState->hMdEnc->mixer_mat[i][j][k] ); - - if ( ( in_out_mixer_map[i][j] == 0 ) && ( fabs( pState->hMdEnc->mixer_mat[i][j][k] ) > 1e-20 ) ) - { - assert( 0 && "Non zero value in unexpected mixer map!!!" ); - } - } - } - } - } -#endif -#ifdef DEBUG_SPAR_DIRAC_WRITE_OUT_PRED_PARS - { - static FILE *fid = 0; - int16_t band = 9; - if ( !fid ) - { - fid = fopen( "pred_coeffs_enc.txt", "wt" ); - } - fprintf( fid, "%.6f\n", pState->hMdEnc->mixer_mat[1][0][band] ); - } -#endif - - ivas_fb_mixer_process( pState->hFbMixer, pState->hMdEnc->mixer_mat, p_pcm_tmp, input_frame, in_out_mixer_map ); - - /* move delayed W into output buffer unless activeW operation*/ - if ( pState->hFbMixer->fb_cfg->active_w_mixing == 0 ) - { - mvr2r( w_del_buf, p_pcm_tmp[0], num_del_samples ); - mvr2r( data_f[0], p_pcm_tmp[0] + num_del_samples, input_frame - num_del_samples ); - } - - /*-----------------------------------------------------------------------------------------* - * PCA encoder - *-----------------------------------------------------------------------------------------*/ - - if ( pState->hPCA != NULL ) - { - ivas_pca_enc( hEncoderConfig, pState->hPCA, hMetaData, p_pcm_tmp, input_frame, FOA_CHANNELS ); - } - else - { - if ( ivas_total_brate == PCA_BRATE && sba_order == 1 ) - { - /* write PCA bypass bit */ - push_next_indice( hMetaData, PCA_MODE_INACTIVE, 1 ); - } - } - - -#ifdef SPAR_HOA_DBG - /*FILE *fp = fopen("int_enc_dmx.raw", "ab"); - for (int16_t t = 0; t < 960; t++) - { - for (int16_t c = 0; c < pState->hFbMixer->filterbank_num_out_chans; c++) - { - for ( k = 0; k < 2; k++ ) - { - fb_mixer_in_buf.ppMixer[i][j][k] = pState->hMdEnc->mixer_mat[i][j]; - } - } - } - fclose( fp );*/ -#endif - /*-----------------------------------------------------------------------------------------* - * AGC - *-----------------------------------------------------------------------------------------*/ - - if ( dtx_vad == 1 ) - { - if ( hEncoderConfig->Opt_AGC_ON > 0 ) - { - ivas_agc_enc_process( pState->hAgcEnc, hMetaData, p_pcm_tmp, p_pcm_tmp, pState->hFbMixer->fb_cfg->num_out_chans, hEncoderConfig ); - } - else - { - push_next_indice( hMetaData, 0, 1 ); - } - } - -#ifdef DEBUG_SPAR_BYPASS_EVS_CODEC - { - static FILE *fid_enc = 0; - static float delay_buf[576 * 4] = { 0 }; - int16_t smp, ch, buf_idx, framelen = input_frame, delay = 576; - if ( !fid_enc ) - { - fid_enc = fopen( "evs_input_float.raw", "wb" ); - } - - /* write out buffer */ - for ( smp = 0; smp < delay * nchan_transport; smp++ ) - { - fwrite( &delay_buf[smp], sizeof( float ), 1, fid_enc ); - } - - for ( smp = 0; smp < framelen - delay; smp++ ) - { - for ( ch = 0; ch < nchan_transport; ch++ ) - { - fwrite( &p_pcm_tmp[ch][smp], sizeof( float ), 1, fid_enc ); - } - } - - /* update delay buffer*/ - buf_idx = 0; - for ( ; smp < framelen; smp++ ) - { - for ( ch = 0; ch < nchan_transport; ch++ ) - { - delay_buf[buf_idx++] = p_pcm_tmp[ch][smp]; - } - } - } -#endif - -#ifdef DEBUG_SPAR_FOA - float tmp; - int16_t pcm; - - for ( j = 0; j < input_frame; j++ ) - { - for ( i = 0; i < nchan_transport; i++ ) - { - tmp = roundf( p_pcm_tmp[i][j] * PCM16_TO_FLT_FAC ); - pcm = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B - : (short) tmp; - dbgwrite( &pcm, sizeof( int16_t ), 1, 1, "dmx.raw" ); - } - } - - /* Plug evs i/p from Matlab */ - if ( fEvs_enc_in != NULL ) - { - /*printf("evs enc in file found\n");*/ - float tmp_in = 0; - int16_t diff[FOA_CHANNELS][L_FRAME48k], tmp16; - int16_t max_diff = 0; - int16_t abs_tol = 8; - - for ( i = 0; i < input_frame; i++ ) - { - for ( j = 0; j < nchan_transport; j++ ) - { - tmp = p_pcm_tmp[j][i]; - tmp = roundf( tmp * PCM16_TO_FLT_FAC ); - tmp16 = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B - : (int16_t) tmp; - fscanf( fEvs_enc_in, "%f\n", &tmp_in ); - p_pcm_tmp[j][i] = tmp_in; - - tmp = roundf( tmp_in * PCM16_TO_FLT_FAC ); - pcm = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B - : (int16_t) tmp; - diff[j][i] = (int16_t) abs( tmp16 - pcm ); - max_diff = max( max_diff, diff[j][i] ); - } - } - - if ( max_diff > abs_tol ) - { - IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR FOA ENC fb mixer out mismatch, max diff = %d", max_diff ); - } - } -#endif - - /*-----------------------------------------------------------------------------------------* - * Re-order the dmx back to ACN/SN3D format - *-----------------------------------------------------------------------------------------*/ - - order = remix_order_set[pState->hMdEnc->spar_md_cfg.remix_unmix_order]; - - for ( i = 0; i < input_frame; i++ ) - { - for ( j = 0; j < nchan_transport; j++ ) - { - data_f[order[j]][i] = p_pcm_tmp[j][i] * PCM16_TO_FLT_FAC; - } - for ( ; j < IVAS_SPAR_MAX_DMX_CHS; j++ ) - { - data_f[order[j]][i] = 0; - } - } - - wmops_sub_end(); - - return error; -} diff --git a/lib_enc/ivas_spar_foa_md_enc.c b/lib_enc/ivas_spar_md_enc.c similarity index 100% rename from lib_enc/ivas_spar_foa_md_enc.c rename to lib_enc/ivas_spar_md_enc.c -- GitLab From 8b1b9403af3e75349ca395de06a95050400757c1 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 14 Jul 2022 10:17:53 +0200 Subject: [PATCH 4/4] remove *FOA* from comments where not relevant --- lib_com/ivas_prot.h | 16 ++++++++-------- lib_dec/ivas_spar_decoder.c | 6 +++--- lib_dec/ivas_spar_md_dec.c | 2 +- lib_dec/ivas_stat_dec.h | 4 ++-- lib_enc/ivas_agc_enc.c | 2 +- lib_enc/ivas_entropy_coder.c | 2 +- lib_enc/ivas_spar_encoder.c | 2 +- lib_enc/ivas_spar_md_enc.c | 2 +- lib_enc/ivas_stat_enc.h | 11 ++--------- 9 files changed, 20 insertions(+), 27 deletions(-) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index c75eb39f17..4bb7546b24 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3847,7 +3847,7 @@ void ivas_spar_dec_upmixer( const int16_t output_frame /* i : output frame length */ ); -/* FOA MD module */ +/* MD module */ ivas_error ivas_spar_md_enc_open( ivas_spar_md_enc_state_t **hMdEnc, /* i/o: SPAR MD encoder handle */ const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ @@ -3932,13 +3932,13 @@ void ivas_spar_md_dec_close( ); void ivas_spar_get_parameters( - SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */ - const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ - const int16_t ts, /* i : time slot index */ - const int16_t num_ch_out, /* i : number of channels out */ - const int16_t num_ch_in, /* i : number of channels in */ - const int16_t num_spar_bands, /* i : number of SPAR bands */ - float par_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS] /* o : mixing matrix */ + SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */ + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ + const int16_t ts, /* i : time slot index */ + const int16_t num_ch_out, /* i : number of channels out */ + const int16_t num_ch_in, /* i : number of channels in */ + const int16_t num_spar_bands, /* i : number of SPAR bands */ + float par_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS] /* o : mixing matrix */ ); ivas_error ivas_spar_md_dec_init( diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 4991177e55..95a2d7d61e 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -719,7 +719,7 @@ static void ivas_spar_dec_MD( *-------------------------------------------------------------------*/ static float ivas_spar_get_cldfb_slot_gain( - SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */ + SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ const int16_t time_slot_idx, int16_t *time_slot_idx0, @@ -777,7 +777,7 @@ static float ivas_spar_get_cldfb_slot_gain( *-------------------------------------------------------------------*/ void ivas_spar_get_parameters( - SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */ + SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ const int16_t ts, const int16_t num_ch_out, @@ -834,7 +834,7 @@ void ivas_spar_get_parameters( *-------------------------------------------------------------------*/ static void ivas_spar_get_skip_mat( - SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */ + SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */ const int16_t num_ch_out, const int16_t num_ch_in, const int16_t num_spar_bands, diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index 56fdf91bcf..291bbc5619 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -603,7 +603,7 @@ static ivas_error ivas_spar_set_dec_config( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_foa_md_dec_process() * - * SPAR FOA Meta Data decoder process + * SPAR Meta Data decoder process *-----------------------------------------------------------------------------------------*/ void ivas_spar_md_dec_process( diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index e09632c1f5..b9218ecaaa 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -780,7 +780,7 @@ typedef struct ivas_param_mc_dec_data_structure * SPAR decoder structures *------------------------------------------------------------------------------------------*/ -/* SPAR FOA MD structure */ +/* SPAR MD structure */ typedef struct ivas_spar_dec_matrices_t { float ***C_re; @@ -865,7 +865,6 @@ typedef struct } PCA_DEC_STATE; -/* SPAR FOA structures */ /* main SPAR decoder structure */ typedef struct ivas_spar_dec_lib_t { @@ -879,6 +878,7 @@ typedef struct ivas_spar_dec_lib_t int16_t enc_param_start_band; int32_t core_nominal_brate; /* Nominal bitrate for core coding */ int32_t i_subframe; + } SPAR_DEC_DATA, *SPAR_DEC_HANDLE; diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc.c index d001f8f484..45326ce8a7 100644 --- a/lib_enc/ivas_agc_enc.c +++ b/lib_enc/ivas_agc_enc.c @@ -475,7 +475,7 @@ void ivas_agc_enc_process( if ( ivas_agc_writeBits( agcOut, pIn_buf, pState ) ) { /* TODO: return error once error codes are harmonized */ - IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR FOA ENC AGC Failed to open agcOut\n " ); + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR ENC AGC Failed to open agcOut\n " ); } #endif diff --git a/lib_enc/ivas_entropy_coder.c b/lib_enc/ivas_entropy_coder.c index 3dfe74fef2..d43d1e4f6c 100644 --- a/lib_enc/ivas_entropy_coder.c +++ b/lib_enc/ivas_entropy_coder.c @@ -132,7 +132,7 @@ static ivas_error ivas_get_dyn_freq_model( if ( fabs( curr_bps_min - ref_min_bps ) > MREF_BPS_TOL ) { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR FOA model selection min BPS mismatch: %f, ref: %f, diff: %f \n", curr_bps_min, ref_min_bps, curr_bps_min - ref_min_bps ); + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR model selection min BPS mismatch: %f, ref: %f, diff: %f \n", curr_bps_min, ref_min_bps, curr_bps_min - ref_min_bps ); } else { diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index a836cc05b3..2647d96df3 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -912,7 +912,7 @@ static ivas_error ivas_spar_enc_process( if ( max_diff > abs_tol ) { - IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR FOA ENC fb mixer out mismatch, max diff = %d", max_diff ); + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR ENC fb mixer out mismatch, max diff = %d", max_diff ); } } #endif diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index f99c21c1df..e2e0796aa4 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -417,7 +417,7 @@ static ivas_error ivas_spar_md_enc_init( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_set_enc_config() * - * Set configuration for SPAR FOA md gen + * Set configuration for SPAR MD gen *-----------------------------------------------------------------------------------------*/ static ivas_error ivas_spar_set_enc_config( diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index b542859db0..331e1a75e7 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -593,7 +593,7 @@ typedef struct ivas_dirac_enc_data_structure * SPAR encoder structures *----------------------------------------------------------------------------------*/ -/* SPAR AGC structures */ +/* AGC structures */ typedef struct ivas_agc_enc_chan_state_t { int16_t lastExp; @@ -616,7 +616,7 @@ typedef struct ivas_agc_enc_state_t } ivas_agc_enc_state_t; -/* SPAR covariance structures */ +/* covariance structures */ typedef struct ivas_enc_cov_handler_state_t { ivas_cov_smooth_state_t *pCov_state; @@ -655,7 +655,6 @@ typedef struct ivas_spar_md_enc_state_t } ivas_spar_md_enc_state_t; - typedef struct ivas_spar_md_enc_in_buf_t { float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; @@ -664,7 +663,6 @@ typedef struct ivas_spar_md_enc_in_buf_t } ivas_spar_md_enc_in_buf_t; - /* PCA structure */ typedef struct { @@ -678,10 +676,6 @@ typedef struct } PCA_ENC_STATE; - -/* SPAR FOA structures */ - - /* SPAR main structure */ typedef struct ivas_spar_enc_lib_t { @@ -710,7 +704,6 @@ typedef struct ivas_spar_enc_lib_t typedef struct ivas_param_mc_enc_data_structure { - IVAS_FB_MIXER_HANDLE hFbMixer; int16_t transient_detector_delay; const float *dmx_factors; -- GitLab