diff --git a/lib_com/cnst.h b/lib_com/cnst.h index e2e19ab3da23658e6c176042078a6c20e6e8e9b8..221b77da7e73fb92f89c0baec67dbac1bbdfa641 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -156,11 +156,20 @@ #define MIN16B ( -32768 ) #define MAX16B_FLT 32767.0f #define MIN16B_FLT ( -32768.0f ) +#ifdef IVAS_FLOAT_FIXED +#define MIN16B_FLT_FX -32768 //Q0 +#define MIN16B_FLT_FX_IN_Q11 -67108864//Q11 +#define MIN16B_FLT_FX_IN_Q15 -1073741824//Q15 +#endif #define PCM16_TO_FLT_FAC 32768.0f #ifdef IVAS_FLOAT_FIXED -#define PCM16_TO_FLT_FAC_FX 32768 +#define PCM16_TO_FLT_FAC_FX 32768 //Q0 #endif // IVAS_FLOAT_FIXED #define MDFT_NORM_SCALING ( 1.0f / PCM16_TO_FLT_FAC ) +#ifdef IVAS_FLOAT_FIXED +#define MDFT_NORM_SCALING_FX 65536 //Q31 +#define LOG2_MDFT_NORM_SCALING_FX -503316448 //Q25 +#endif #define MAX_FRAME_COUNTER 200 #define MAX_BITS_PER_FRAME 10240 /* Bits per frame for max. bitrate 512kbps, == IVAS_MAX_BITS_PER_FRAME */ @@ -734,6 +743,9 @@ enum #define L_HP20_MEM 4 /* HP20 filter memory length */ #define CLDFB_NO_CHANNELS_MAX 60 /* CLDFB resampling - max number of CLDFB channels, == IVAS_CLDFB_NO_CHANNELS_MAX */ +#ifdef IVAS_FLOAT_FIXED +#define CLDFB_NO_CHANNELS_MAX_FX 30720 /*Q9*/ +#endif #define CLDFB_NO_COL_MAX 16 /* CLDFB resampling - max number of CLDFB col., == IVAS_CLDFB_NO_COL_MAX */ #define CLDFB_NO_COL_MAX_SWITCH 6 /* CLDFB resampling - max number of CLDFB col. for switching */ #define CLDFB_NO_COL_MAX_SWITCH_BFI 10 /* CLDFB resampling - max number of CLDFB col. for switching, BFI */ diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index f75e321a7e39304d366a9c558efcabf505e70567..c1d76ee787d882a0118803218ed93864036cfdd0 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -248,7 +248,9 @@ typedef struct _IVAS_RENDER_CONFIG { IVAS_ROOM_ACOUSTICS_CONFIG_DATA roomAcoustics; float directivity[IVAS_MAX_NUM_OBJECTS * 3]; - +#ifdef IVAS_FLOAT_FIXED + Word16 directivity_fx[IVAS_MAX_NUM_OBJECTS * 3]; // has the following q-factor pattern: {6, 6, 15, 6, 6, 15, 6, 6, 15, 6, 6, 15} +#endif } IVAS_RENDER_CONFIG_DATA, *IVAS_RENDER_CONFIG_HANDLE; #endif /* COMMON_API_TYPES_H */ diff --git a/lib_com/ivas_ism_com.c b/lib_com/ivas_ism_com.c index be778b44013ce0b7017dc187d6213bb730b94ac5..bf04a9b35dd33df7dd71859cd3e7471c877fb201 100644 --- a/lib_com/ivas_ism_com.c +++ b/lib_com/ivas_ism_com.c @@ -43,6 +43,7 @@ #include "ivas_prot_fx.h" #include "prot_fx1.h" +#define IVAS_FLOAT_FIXED_TO_BE_REMOVED /*-----------------------------------------------------------------------* * Local constants @@ -734,30 +735,51 @@ ivas_error ivas_ism_config_fx( * Reset ISM metadata parameters *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED void ivas_ism_reset_metadata( ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */ ) { -#ifdef IVAS_FLOAT_FIXED hIsmMeta->azimuth_fx = 0; + move32(); hIsmMeta->elevation_fx = 0; + move32(); hIsmMeta->yaw_fx = 0; + move32(); hIsmMeta->pitch_fx = 0; + move32(); hIsmMeta->radius_fx = 1 << 9; -#endif - // To be removed later ///////////////////// + move16(); +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED hIsmMeta->azimuth = 0.0f; hIsmMeta->elevation = 0.0f; hIsmMeta->yaw = 0.0f; hIsmMeta->pitch = 0.0f; hIsmMeta->radius = 1.0f; - //////////////////////////////////////////// +#endif hIsmMeta->ism_metadata_flag = 0; + move16(); hIsmMeta->non_diegetic_flag = 0; + move16(); return; } +#else +void ivas_ism_reset_metadata( + ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */ +) +{ + hIsmMeta->azimuth = 0.0f; + hIsmMeta->elevation = 0.0f; + hIsmMeta->yaw = 0.0f; + hIsmMeta->pitch = 0.0f; + hIsmMeta->radius = 1.0f; + hIsmMeta->ism_metadata_flag = 0; + hIsmMeta->non_diegetic_flag = 0; + return; +} +#endif /*-------------------------------------------------------------------* * ivas_ism_reset_metadata_API() @@ -1006,6 +1028,32 @@ ISM_MODE ivas_ism_mode_select( * Deallocate ISM metadata handles * ---------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_ism_metadata_close( + ISM_METADATA_HANDLE hIsmMetaData[], /* i/o: object metadata handles */ + const Word16 first_idx /* i : index of first handle to deallocate */ +) +{ + Word16 n; + + test(); + IF( hIsmMetaData == NULL || *hIsmMetaData == NULL ) + { + return; + } + + FOR( n = first_idx; n < MAX_NUM_OBJECTS; n++ ) + { + IF( hIsmMetaData[n] != NULL ) + { + free( hIsmMetaData[n] ); + hIsmMetaData[n] = NULL; + } + } + + return; +} +#else void ivas_ism_metadata_close( ISM_METADATA_HANDLE hIsmMetaData[], /* i/o: object metadata handles */ const int16_t first_idx /* i : index of first handle to deallocate */ @@ -1029,6 +1077,7 @@ void ivas_ism_metadata_close( return; } +#endif /*-------------------------------------------------------------------* diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 88bcea92986f2b4d54d08512fa4901e1ae72f1a8..f2acd512f7d91c6b94913d5fa6f608ae39bbec4c 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3554,12 +3554,22 @@ void ivas_mdct_core_tns_ns( const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ ); +#ifdef IVAS_FLOAT_FIXED +void ivas_mct_core_dec( + MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ + CPE_DEC_HANDLE hCPE[MCT_MAX_BLOCKS], /* i/o: CPE decoder structure */ + const Word16 nCPE, /* i : number of CPEs */ + Word32 *signal_out_fx[], + Word16 q_x[MCT_MAX_CHANNELS] +); +#else void ivas_mct_core_dec( MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ CPE_DEC_HANDLE hCPE[MCT_MAX_BLOCKS], /* i/o: CPE decoder structure */ const int16_t nCPE, /* i : number of CPEs */ float *signal_out[] /* o : synthesis @internal_FS */ ); +#endif void ivas_mct_dec_mct( MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ @@ -4819,16 +4829,46 @@ int16_t ivas_agc_enc_get_flag( const int16_t nchan_transport /* i : number of transport channels */ ); +#ifdef IVAS_FLOAT_FIXED +Word16 ivas_agc_enc_get_flag_fx( + const Word16 nchan_transport /* i : number of transport channels */ +); +#endif + ivas_error ivas_spar_agc_enc_open( ivas_agc_enc_state_t **hAgcEnc, /* i/o: AGC decoder handle */ const int32_t input_Fs, /* i : input sampling rate */ const int16_t nchan_inp /* i : number of input channels */ ); +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_spar_agc_enc_open_fx( + ivas_agc_enc_state_t **hAgcEnc, /* i/o: SPAR AGC encoder handle */ + const Word32 input_Fs, /* i : input sampling rate */ + const Word16 nchan_inp /* i : number of input channels */ +); +#endif + void ivas_spar_agc_enc_close( ivas_agc_enc_state_t **hAgcEnc /* i/o: AGC encoder handle */ ); +#ifdef IVAS_FLOAT_FIXED +void ivas_spar_agc_enc_close_fx( + ivas_agc_enc_state_t **hAgcEnc /* i/o: SPAR AGC encoder handle */ +); + +void ivas_agc_enc_process_fx( + ivas_agc_enc_state_t *hAgcEnc, /* i/o: AGC encoder handle */ + BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ + Word32 **ppPcm_in, /* i : input audio channels */ + Word32 **ppPcm_out, /* o : output audio channels */ + const Word16 n_channels, /* i : number of channels */ + const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ + Word16 *q_ppPcm +); +#endif + void ivas_agc_enc_process( ivas_agc_enc_state_t *hAgcEnc, /* i/o: AGC encoder handle */ BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ @@ -6642,8 +6682,7 @@ void ivas_omasa_modify_masa_energy_ratios( ivas_error ivas_td_binaural_open_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ Word16 * SrcInd, /*Temporarily used to store the updated value of SrcInd*/ - Word16 *num_src, - Word16 *directivity_fx + Word16 *num_src ); #endif // IVAS_FLOAT_FIXED diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index a5482a57ebd28a594fb127b6b538d3df515542ad..a592f0269f173739fa6cb49d31837f8b41f13ab0 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -147,6 +147,14 @@ ivas_error ivas_omasa_ism_metadata_dec_fx( const Word16 dirac_bs_md_write_idx, /* i : DirAC bitstream write index */ Word16 nb_bits_metadata[] /* o : number of ISM metadata bits */ ); +ivas_error ivas_omasa_dec_config_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + UWord16 *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ + Word16 Q_cldfbSynDec, /* i : Q factor for cldfb state */ + Word16 *num_src, + Word16 SrcInd[MAX_NUM_TDREND_CHANNELS], + Word16 *data /* o : output synthesis signal */ +); #endif void ivas_omasa_modify_masa_energy_ratios_fx( @@ -564,6 +572,20 @@ void ivas_jbm_dec_get_adapted_subframes_fx( Word16 *nb_subframes /* i/o: number of subframes in the frame */ ); +void ivas_jbm_dec_copy_tc_no_tsm_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle Q0 */ + Word32 *tc_fx[], /* i : transport channels Q11 */ + const Word16 output_frame /* i : output frame size Q0 */ +); + +void ivas_ism_param_dec_tc_gain_ajust_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const UWord16 nSamples, /* i : number of samples to be compensate */ + const UWord16 nFadeLength, /* i : length of the crossfade in samples */ + Word32 *transport_channels_f[], /* i : synthesized core-coder transport channels/DirAC output Q_tc*/ + Word16 *Q_tc /* i/o : Q of input tc buffer */ +); + #ifdef IVAS_FLOAT_FIXED /*! r: number of bits read */ Word16 read_GR0( diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index e6dcccddbf0baee42a89dc15485ac4cc9961ccf7..e68d016b1f869b91156518a86e84ba99a963990a 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -811,6 +811,7 @@ typedef struct ivas_fb_mixer_state_structure #ifdef IVAS_FLOAT_FIXED const Word16 *pFilterbank_cross_fade_fx; Word16 cldfb_cross_fade_fx[CLDFB_NO_COL_MAX]; + Word16 cldfb_cross_fade_q; #endif // IVAS_FLOAT_FIXED int16_t cldfb_cross_fade_start; int16_t cldfb_cross_fade_end; @@ -851,6 +852,7 @@ typedef struct ivas_param_ism_data_structure float last_cardioid_left[MAX_NUM_OBJECTS]; Word16 last_dmx_gain_fx; + Word16 last_dmx_gain_e; Word16 last_cardioid_left_fx[MAX_NUM_OBJECTS]; } PARAM_ISM_CONFIG_DATA, *PARAM_ISM_CONFIG_HANDLE; diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 6a490087a7ff950473bbf242abc030febd27e27f..2bd750daac266bc40d2c033747794b20b1d56435 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -1210,7 +1210,7 @@ ivas_error init_decoder_ivas_fx( } #ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED // To be removed when fixed version is available. - Init_post_filter_ivas(st_fx->hPFstat); + Init_post_filter_ivas(st_fx->hPFstat); st_fx->psf_lp_noise = 0.0f; #endif Init_post_filter(st_fx->hPFstat); diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index e56c6b714f88914379f01fa3528a0cdcd3d1e958..e67f7a0aa4f511dee7341c7c0f2f1d1faf37e127 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -668,6 +668,7 @@ ivas_error ivas_cpe_dec_fx( /* DFT Stereo residual decoding */ IF( GT_16( hCPE->hStereoDft->res_cod_band_max, 0 ) && !st_ivas->bfi ) { + #ifndef IVAS_FLOAT_FIXED_ stereo_dft_dec_res( hCPE, res_buf, output_flt[1] ); #else diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 2024ddf541a1bc1236a42fed3c0c9d0234547b03..7803d68d28c9fe26666d80812ad468abdeeddc7f 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -733,16 +733,26 @@ static ivas_error ivas_dirac_rend_config_fx( IF( ( EQ_16( flag_config, DIRAC_OPEN && hDirACRend->proto_signal_decorr_on ) ) || ( EQ_16( flag_config, DIRAC_RECONFIGURE ) && ( hDirACRend->proto_signal_decorr_on && !proto_signal_decorr_on_old ) ) ) { - /*WIP*/ +#ifdef IVAS_FLOAT_FIXED + FOR( int i = 0; i < st_ivas->hSpatParamRendCom->num_freq_bands; i++ ) + { + hDirACRend->frequency_axis_fx[i] = (Word16) hDirACRend->frequency_axis[i]; + } + IF( ( error = ivas_dirac_dec_decorr_open_fx( &( hDirACRend->h_freq_domain_decorr_ap_params ), &( hDirACRend->h_freq_domain_decorr_ap_state ), hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff, + hDirACRend->num_protos_diff, hDirACRend->synthesisConf, hDirACRend->frequency_axis_fx, nchan_transport > 2 ? 4 : nchan_transport, output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } +#else IF( ( error = ivas_dirac_dec_decorr_open( &( hDirACRend->h_freq_domain_decorr_ap_params ), &( hDirACRend->h_freq_domain_decorr_ap_state ), hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff, hDirACRend->num_protos_diff, hDirACRend->synthesisConf, hDirACRend->frequency_axis, nchan_transport > 2 ? 4 : nchan_transport, output_Fs ) ) != IVAS_ERR_OK ) { return error; } +#endif } ELSE IF( EQ_16( flag_config, DIRAC_RECONFIGURE ) && ( !hDirACRend->proto_signal_decorr_on && proto_signal_decorr_on_old ) ) { - /*WIP*/ ivas_dirac_dec_decorr_close( &hDirACRend->h_freq_domain_decorr_ap_params, &hDirACRend->h_freq_domain_decorr_ap_state ); } ELSE IF( EQ_16( flag_config, DIRAC_RECONFIGURE ) && hDirACRend->proto_signal_decorr_on && proto_signal_decorr_on_old ) @@ -750,14 +760,24 @@ static ivas_error ivas_dirac_rend_config_fx( IF( NE_16( nchan_transport, nchan_transport_old ) || NE_16( hDirACRend->num_outputs_diff, num_outputs_diff_old ) || EQ_16( flag_config_inp, DIRAC_RECONFIGURE_MODE ) ) { /* close and reopen the decorrelator */ - /*WIP*/ ivas_dirac_dec_decorr_close( &hDirACRend->h_freq_domain_decorr_ap_params, &hDirACRend->h_freq_domain_decorr_ap_state ); - /*WIP*/ +#ifdef IVAS_FLOAT_FIXED + FOR( int i = 0; i < st_ivas->hSpatParamRendCom->num_freq_bands; i++ ) + { + hDirACRend->frequency_axis_fx[i] = (Word16) hDirACRend->frequency_axis[i]; + } + IF( ( error = ivas_dirac_dec_decorr_open_fx( &( hDirACRend->h_freq_domain_decorr_ap_params ), &( hDirACRend->h_freq_domain_decorr_ap_state ), hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff, + hDirACRend->num_protos_diff, hDirACRend->synthesisConf, hDirACRend->frequency_axis_fx, nchan_transport > 2 ? 4 : nchan_transport, output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } +#else IF( ( error = ivas_dirac_dec_decorr_open( &( hDirACRend->h_freq_domain_decorr_ap_params ), &( hDirACRend->h_freq_domain_decorr_ap_state ), hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff, hDirACRend->num_protos_diff, hDirACRend->synthesisConf, hDirACRend->frequency_axis, nchan_transport > 2 ? 4 : nchan_transport, output_Fs ) ) != IVAS_ERR_OK ) { return error; } +#endif } } @@ -1752,16 +1772,23 @@ ivas_error ivas_dirac_dec_config( { frequency_axis[i] = (float) frequency_axis_fx[i]; } + + IF( ( error = ivas_dirac_dec_decorr_open_fx( &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, + DIRAC_SYNTHESIS_PSD_LS, frequency_axis_fx, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } #else ivas_dirac_dec_get_frequency_axis( frequency_axis, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSpatParamRendCom->num_freq_bands ); -#endif - /*WIP*/ - IF( ( error = ivas_dirac_dec_decorr_open( &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, - DIRAC_SYNTHESIS_PSD_LS, frequency_axis, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + + IF((error = ivas_dirac_dec_decorr_open(&(st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params), &(st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, + DIRAC_SYNTHESIS_PSD_LS, frequency_axis, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs)) != IVAS_ERR_OK) { return error; } +#endif + } } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index ef6569cde2ec124e7aad2e84b81512d66560b4a8..24d27f7b8d0aec137c653ad632f64a51bd6e8352 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -196,11 +196,136 @@ ivas_error ivas_dec_setup( } ELSE { - IF ( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#ifdef IVAS_FLOAT_FIXED + //////////////// Cleanup changes: float to fixed ////////////////// + Word16 SrcInd[MAX_NUM_TDREND_CHANNELS]; + Word16 num_src = 0; + Word16 i, Q_cldfbSynDec = 21; + + Word16 old_ism_mode = ivas_omasa_ism_mode_select(st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->nchan_ism); + Word16 new_ism_mode = ivas_omasa_ism_mode_select(st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_ism); + if (old_ism_mode != new_ism_mode && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC) + { + // Float to fix conversions for ivas_td_binaural_open_fx + if (st_ivas->ism_mode == ISM_MASA_MODE_DISC) + { + FOR(i = 0; i < 4; i++) + { + st_ivas->hRenderConfig->directivity_fx[i * 3] = (Word16)floatToFixed(st_ivas->hRenderConfig->directivity[i * 3], 6); + st_ivas->hRenderConfig->directivity_fx[i * 3 + 1] = (Word16)floatToFixed(st_ivas->hRenderConfig->directivity[i * 3 + 1], 6); + st_ivas->hRenderConfig->directivity_fx[i * 3 + 2] = (Word16)floatToFixed(st_ivas->hRenderConfig->directivity[i * 3 + 2], 15); + } + } + // Float to fix conversions for ivas_cldfb_dec_reconfig_fx + FOR(i = 0; i < 16; i++) + { + IF(st_ivas->cldfbAnaDec[i]) + floatToFixed_arrL(st_ivas->cldfbAnaDec[i]->cldfb_state, st_ivas->cldfbAnaDec[i]->cldfb_state_fx, 11, sub(st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels)); + } + IF(st_ivas->hSpar) + { + st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q = Q_factor_arr(st_ivas->hSpar->hFbMixer->cldfb_cross_fade, 16); + floatToFixed_arr(st_ivas->hSpar->hFbMixer->cldfb_cross_fade, st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q, 16); + } + IF(st_ivas->cldfbSynDec[0]) + { + Q_cldfbSynDec = s_min(Q_cldfbSynDec, Q_factor_arrL(st_ivas->cldfbSynDec[0]->cldfb_state, sub(st_ivas->cldfbSynDec[0]->p_filter_length, st_ivas->cldfbSynDec[0]->no_channels))); + floatToFixed_arrL(st_ivas->cldfbSynDec[0]->cldfb_state, st_ivas->cldfbSynDec[0]->cldfb_state_fx, Q_cldfbSynDec, sub(st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels)); + } + } + //////////////////////////////////////////////////////////////// + IF( ( error = ivas_omasa_dec_config_fx( st_ivas, nSamplesRendered, Q_cldfbSynDec, &num_src, SrcInd, data ) ) != IVAS_ERR_OK ) + { + return error; + } + + //////////////// Cleanup changes: float to fixed /////////////// + IF( NE_16( new_ism_mode, old_ism_mode ) && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC ) + { + // Cleanup changes for ivas_td_binaural_open: fixed to float + IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) + { + st_ivas->hBinRendererTd->Gain = 1.0f; /*1.0f Q15*/ + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Pos_fx, st_ivas->hBinRendererTd->Listener_p->Pos, 15, 3 ); + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Vel_fx, st_ivas->hBinRendererTd->Listener_p->Vel, 15, 3 ); + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Front_fx, st_ivas->hBinRendererTd->Listener_p->Front, 15, 3 ); + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Up_fx, st_ivas->hBinRendererTd->Listener_p->Up, 15, 3 ); + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Right_fx, st_ivas->hBinRendererTd->Listener_p->Right, 15, 3 ); + TDREND_DirAtten_t *DirAtten_p = st_ivas->hBinRendererTd->DirAtten_p; + DirAtten_p->ConeInnerAngle = fixedToFloat( DirAtten_p->ConeInnerAngle_fx, 6 ); + DirAtten_p->ConeOuterAngle = fixedToFloat( DirAtten_p->ConeOuterAngle_fx, 6 ); + DirAtten_p->ConeOuterGain = fixedToFloat( DirAtten_p->ConeOuterGain_fx, 15 ); + Word16 nchan_rend = num_src; + IF( EQ_16( st_ivas->ivas_format, MC_FORMAT ) && NE_16( st_ivas->transport_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) + { + nchan_rend--; /* Skip LFE channel -- added to the others */ + } + FOR( Word16 nS = 0; nS < nchan_rend; nS++ ) + { + TDREND_SRC_t *Src_p = st_ivas->hBinRendererTd->Sources[SrcInd[nS]]; + IF( Src_p->SrcSpatial_p != NULL ) + { + Src_p->SrcSpatial_p->DirAtten.ConeInnerAngle = 360.0f; + Src_p->SrcSpatial_p->DirAtten.ConeOuterAngle = 360.0f; + Src_p->SrcSpatial_p->DirAtten.ConeOuterGain = 1.0f; + Src_p->SrcSpatial_p->DistAtten.RefDist = 1.0f; + Src_p->SrcSpatial_p->DistAtten.MaxDist = 15.75f; /* Maximum radius (2^ISM_RADIUS_NBITS-1)*0.25 */ + Src_p->SrcSpatial_p->DistAtten.RollOffFactor = 1.0f; + FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) + { + fixedToFloat_arr( Src_p->SrcSpatial_p->Pos_p_fx + nC * 3, Src_p->SrcSpatial_p->Pos_p + nC * 3, 15, 3 ); + fixedToFloat_arr( Src_p->SrcSpatial_p->Front_p_fx + nC * 3, Src_p->SrcSpatial_p->Front_p + nC * 3, 15, 3 ); + } + } + FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) + { + Src_p->SrcRend_p->SrcGainMin_p[nC] = 0.0f; + Src_p->SrcRend_p->SrcGain_p[nC] = 1.0f; + Src_p->SrcRend_p->SrcGainMax_p[nC] = 1.0f; + } + FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) + { + Src_p->SrcRend_p->DirGain_p[nC] = 1.0f; + Src_p->SrcRend_p->DistGain_p[nC] = 1.0f; + } + set_f( Src_p->mem_itd, 0.0f, ITD_MEM_LEN ); + set_f( Src_p->mem_hrf_left, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); + set_f( Src_p->mem_hrf_right, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); + set_f( Src_p->hrf_left_prev, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + set_f( Src_p->hrf_right_prev, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + Src_p->hrf_left_prev[0] = 1; + Src_p->hrf_right_prev[0] = 1; + Src_p->azim_prev = 0.0f; + Src_p->elev_prev = 0.0f; + Src_p->Gain = 1.0f; + Src_p->prevGain = 1.0f; + TDREND_SRC_SPATIAL_t *SrcSpatial_p = st_ivas->hBinRendererTd->Sources[nS]->SrcSpatial_p; + fixedToFloat_arr( SrcSpatial_p->Pos_p_fx, SrcSpatial_p->Pos_p, 15, 3 ); + fixedToFloat_arr( SrcSpatial_p->Front_p_fx, SrcSpatial_p->Front_p, 15, 3 ); + SrcSpatial_p->DirAtten.ConeInnerAngle = fixedToFloat( SrcSpatial_p->DirAtten.ConeInnerAngle_fx, 6 ); + SrcSpatial_p->DirAtten.ConeOuterAngle = fixedToFloat( SrcSpatial_p->DirAtten.ConeOuterAngle_fx, 6 ); + SrcSpatial_p->DirAtten.ConeOuterGain = fixedToFloat( SrcSpatial_p->DirAtten.ConeOuterGain_fx, 15 ); + } + } + // Cleanup changes for ivas_cldfb_dec_reconfig_fx: fixed to float + FOR( i = 0; i < 16; i++ ) + { + IF( st_ivas->cldfbAnaDec[i] ) + fixedToFloat_arrL( st_ivas->cldfbAnaDec[i]->cldfb_state_fx, st_ivas->cldfbAnaDec[i]->cldfb_state, 11, sub( st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels ) ); + } + IF( st_ivas->cldfbSynDec[0] ) + { + fixedToFloat_arrL( st_ivas->cldfbSynDec[0]->cldfb_state_fx, st_ivas->cldfbSynDec[0]->cldfb_state, Q_cldfbSynDec, sub( st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels ) ); + } + } + //////////////////////////////////////////////////////////////// +#else + IF( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) { return error; } +#endif } } } @@ -218,10 +343,136 @@ ivas_error ivas_dec_setup( /* reconfigure in case a change of operation mode is detected */ IF ( ( GT_32(ivas_total_brate, IVAS_SID_5k2) && NE_32(ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate )) || EQ_16( st_ivas->ini_active_frame, 0 ) ) { - IF ( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#ifdef IVAS_FLOAT_FIXED + //////////////// Cleanup changes: float to fixed ////////////////// + Word16 SrcInd[MAX_NUM_TDREND_CHANNELS]; + Word16 num_src = 0; + Word16 i, Q_cldfbSynDec = 21; + + Word16 old_ism_mode = ivas_omasa_ism_mode_select( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->nchan_ism ); + Word16 new_ism_mode = ivas_omasa_ism_mode_select( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_ism ); + if ( old_ism_mode != new_ism_mode && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC ) + { + // Float to fix conversions for ivas_td_binaural_open_fx + if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + FOR( i = 0; i < 4; i++ ) + { + st_ivas->hRenderConfig->directivity_fx[i * 3] = (Word16) floatToFixed( st_ivas->hRenderConfig->directivity[i * 3], 6 ); + st_ivas->hRenderConfig->directivity_fx[i * 3 + 1] = (Word16) floatToFixed( st_ivas->hRenderConfig->directivity[i * 3 + 1], 6 ); + st_ivas->hRenderConfig->directivity_fx[i * 3 + 2] = (Word16) floatToFixed( st_ivas->hRenderConfig->directivity[i * 3 + 2], 15 ); + } + } + // Float to fix conversions for ivas_cldfb_dec_reconfig_fx + FOR( i = 0; i < 16; i++ ) + { + IF( st_ivas->cldfbAnaDec[i] ) + floatToFixed_arrL( st_ivas->cldfbAnaDec[i]->cldfb_state, st_ivas->cldfbAnaDec[i]->cldfb_state_fx, 11, sub( st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels ) ); + } + IF( st_ivas->hSpar ) + { + st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q = Q_factor_arr( st_ivas->hSpar->hFbMixer->cldfb_cross_fade, 16 ); + floatToFixed_arr( st_ivas->hSpar->hFbMixer->cldfb_cross_fade, st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q, 16 ); + } + IF( st_ivas->cldfbSynDec[0] ) + { + Q_cldfbSynDec = s_min( Q_cldfbSynDec, Q_factor_arrL( st_ivas->cldfbSynDec[0]->cldfb_state, sub( st_ivas->cldfbSynDec[0]->p_filter_length, st_ivas->cldfbSynDec[0]->no_channels ) ) ); + floatToFixed_arrL( st_ivas->cldfbSynDec[0]->cldfb_state, st_ivas->cldfbSynDec[0]->cldfb_state_fx, Q_cldfbSynDec, sub( st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels ) ); + } + } + //////////////////////////////////////////////////////////////// + + IF( ( error = ivas_omasa_dec_config_fx( st_ivas, nSamplesRendered, Q_cldfbSynDec, &num_src, SrcInd, data ) ) != IVAS_ERR_OK ) + { + return error; + } + + //////////////// Cleanup changes: float to fixed /////////////// + IF( NE_16( new_ism_mode, old_ism_mode ) && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC ) + { + // Cleanup changes for ivas_td_binaural_open: fixed to float + IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) + { + st_ivas->hBinRendererTd->Gain = 1.0f; /*1.0f Q15*/ + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Pos_fx, st_ivas->hBinRendererTd->Listener_p->Pos, 15, 3 ); + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Vel_fx, st_ivas->hBinRendererTd->Listener_p->Vel, 15, 3 ); + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Front_fx, st_ivas->hBinRendererTd->Listener_p->Front, 15, 3 ); + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Up_fx, st_ivas->hBinRendererTd->Listener_p->Up, 15, 3 ); + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Right_fx, st_ivas->hBinRendererTd->Listener_p->Right, 15, 3 ); + TDREND_DirAtten_t *DirAtten_p = st_ivas->hBinRendererTd->DirAtten_p; + DirAtten_p->ConeInnerAngle = fixedToFloat( DirAtten_p->ConeInnerAngle_fx, 6 ); + DirAtten_p->ConeOuterAngle = fixedToFloat( DirAtten_p->ConeOuterAngle_fx, 6 ); + DirAtten_p->ConeOuterGain = fixedToFloat( DirAtten_p->ConeOuterGain_fx, 15 ); + Word16 nchan_rend = num_src; + IF( EQ_16( st_ivas->ivas_format, MC_FORMAT ) && NE_16( st_ivas->transport_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) + { + nchan_rend--; /* Skip LFE channel -- added to the others */ + } + FOR( Word16 nS = 0; nS < nchan_rend; nS++ ) + { + TDREND_SRC_t *Src_p = st_ivas->hBinRendererTd->Sources[SrcInd[nS]]; + IF( Src_p->SrcSpatial_p != NULL ) + { + Src_p->SrcSpatial_p->DirAtten.ConeInnerAngle = 360.0f; + Src_p->SrcSpatial_p->DirAtten.ConeOuterAngle = 360.0f; + Src_p->SrcSpatial_p->DirAtten.ConeOuterGain = 1.0f; + Src_p->SrcSpatial_p->DistAtten.RefDist = 1.0f; + Src_p->SrcSpatial_p->DistAtten.MaxDist = 15.75f; /* Maximum radius (2^ISM_RADIUS_NBITS-1)*0.25 */ + Src_p->SrcSpatial_p->DistAtten.RollOffFactor = 1.0f; + FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) + { + fixedToFloat_arr( Src_p->SrcSpatial_p->Pos_p_fx + nC * 3, Src_p->SrcSpatial_p->Pos_p + nC * 3, 15, 3 ); + fixedToFloat_arr( Src_p->SrcSpatial_p->Front_p_fx + nC * 3, Src_p->SrcSpatial_p->Front_p + nC * 3, 15, 3 ); + } + } + FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) + { + Src_p->SrcRend_p->SrcGainMin_p[nC] = 0.0f; + Src_p->SrcRend_p->SrcGain_p[nC] = 1.0f; + Src_p->SrcRend_p->SrcGainMax_p[nC] = 1.0f; + } + FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) + { + Src_p->SrcRend_p->DirGain_p[nC] = 1.0f; + Src_p->SrcRend_p->DistGain_p[nC] = 1.0f; + } + set_f( Src_p->mem_itd, 0.0f, ITD_MEM_LEN ); + set_f( Src_p->mem_hrf_left, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); + set_f( Src_p->mem_hrf_right, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); + set_f( Src_p->hrf_left_prev, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + set_f( Src_p->hrf_right_prev, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + Src_p->hrf_left_prev[0] = 1; + Src_p->hrf_right_prev[0] = 1; + Src_p->azim_prev = 0.0f; + Src_p->elev_prev = 0.0f; + Src_p->Gain = 1.0f; + Src_p->prevGain = 1.0f; + TDREND_SRC_SPATIAL_t *SrcSpatial_p = st_ivas->hBinRendererTd->Sources[nS]->SrcSpatial_p; + fixedToFloat_arr( SrcSpatial_p->Pos_p_fx, SrcSpatial_p->Pos_p, 15, 3 ); + fixedToFloat_arr( SrcSpatial_p->Front_p_fx, SrcSpatial_p->Front_p, 15, 3 ); + SrcSpatial_p->DirAtten.ConeInnerAngle = fixedToFloat( SrcSpatial_p->DirAtten.ConeInnerAngle_fx, 6 ); + SrcSpatial_p->DirAtten.ConeOuterAngle = fixedToFloat( SrcSpatial_p->DirAtten.ConeOuterAngle_fx, 6 ); + SrcSpatial_p->DirAtten.ConeOuterGain = fixedToFloat( SrcSpatial_p->DirAtten.ConeOuterGain_fx, 15 ); + } + } + // Cleanup changes for ivas_cldfb_dec_reconfig_fx: fixed to float + FOR( i = 0; i < 16; i++ ) + { + IF( st_ivas->cldfbAnaDec[i] ) + fixedToFloat_arrL( st_ivas->cldfbAnaDec[i]->cldfb_state_fx, st_ivas->cldfbAnaDec[i]->cldfb_state, 11, sub( st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels ) ); + } + IF( st_ivas->cldfbSynDec[0] ) + { + fixedToFloat_arrL( st_ivas->cldfbSynDec[0]->cldfb_state_fx, st_ivas->cldfbSynDec[0]->cldfb_state, Q_cldfbSynDec, sub( st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels ) ); + } + } + //////////////////////////////////////////////////////////////// +#else + IF( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) { return error; } +#endif } } } diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index d9cc5e4e0ef6e91222b8a54fd986a8c2d32e8ec5..459e5cf587710647604fa8d2c9c5ffa995e713ae 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -205,17 +205,16 @@ static ivas_error ivas_ism_bitrate_switching_dec( { #ifdef IVAS_FLOAT_FIXED #if 1 /*Cleanup changes: float to fixed */ - Word16 directivity_fx[IVAS_MAX_NUM_OBJECTS * 3]; Word16 SrcInd[MAX_NUM_TDREND_CHANNELS]; Word16 num_src; FOR( Word16 i = 0; i < 4; i++ ) { - directivity_fx[i * 3] = (Word16)floatToFixed( st_ivas->hRenderConfig->directivity[i * 3], 6 ); - directivity_fx[i * 3 + 1] = (Word16)floatToFixed( st_ivas->hRenderConfig->directivity[i * 3 + 1], 6 ); - directivity_fx[i * 3 + 2] = (Word16)floatToFixed( st_ivas->hRenderConfig->directivity[i * 3 + 2], 15 ); + st_ivas->hRenderConfig->directivity_fx[i * 3] = (Word16)floatToFixed( st_ivas->hRenderConfig->directivity[i * 3], 6 ); + st_ivas->hRenderConfig->directivity_fx[i * 3 + 1] = (Word16)floatToFixed( st_ivas->hRenderConfig->directivity[i * 3 + 1], 6 ); + st_ivas->hRenderConfig->directivity_fx[i * 3 + 2] = (Word16)floatToFixed( st_ivas->hRenderConfig->directivity[i * 3 + 2], 15 ); } #endif - IF ( ( error = ivas_td_binaural_open_fx( st_ivas , SrcInd,&num_src, directivity_fx) ) != IVAS_ERR_OK ) + IF ( ( error = ivas_td_binaural_open_fx( st_ivas , SrcInd, &num_src ) ) != IVAS_ERR_OK ) { return error; } @@ -432,7 +431,7 @@ static ivas_error ivas_ism_bitrate_switching_dec( #ifdef IVAS_FLOAT_FIXED #if 1 /*Cleanup changes: float to fixed*/ - Word16 i, Q_weights, Q_cldfbSynDec = 21; + Word16 i, Q_cldfbSynDec = 21; FOR( i = 0; i < 16; i++ ) { IF( st_ivas->cldfbAnaDec[i] ) @@ -440,8 +439,8 @@ static ivas_error ivas_ism_bitrate_switching_dec( } IF ( st_ivas->hSpar ) { - Q_weights = Q_factor_arr( st_ivas->hSpar->hFbMixer->cldfb_cross_fade, 16 ); - floatToFixed_arr( st_ivas->hSpar->hFbMixer->cldfb_cross_fade, st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, Q_weights, 16 ); + st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q = Q_factor_arr( st_ivas->hSpar->hFbMixer->cldfb_cross_fade, CLDFB_NO_COL_MAX ); + floatToFixed_arr( st_ivas->hSpar->hFbMixer->cldfb_cross_fade, st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q, CLDFB_NO_COL_MAX ); } IF( st_ivas->cldfbSynDec[0] ) { diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index 16cbe46ee3ae312443bfd825c952a49903300053..f2da41369d676e27ec86dd76265b5b639986535c 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -45,6 +45,8 @@ #include "wmc_auto.h" #include "ivas_prot_fx.h" +#define IVAS_FLOAT_FIXED_TO_BE_REMOVED + /*-----------------------------------------------------------------------* * Local functions @@ -1143,7 +1145,7 @@ ivas_error ivas_ism_metadata_dec_fx( } } - IF ( ( error = ivas_ism_config( ism_total_brate, *nchan_transport, nchan_ism, hIsmMeta, ism_extmeta_bitstream, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata, masa_ism_flag ) ) != IVAS_ERR_OK ) + IF ( ( error = ivas_ism_config_fx( ism_total_brate, *nchan_transport, nchan_ism, hIsmMeta, ism_extmeta_bitstream, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata, masa_ism_flag ) ) != IVAS_ERR_OK ) { return error; } @@ -1222,42 +1224,104 @@ ivas_error ivas_ism_metadata_dec_fx( * Create, allocate, initialize and configure IVAS decoder ISM metadata handles *-------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED ivas_error ivas_ism_metadata_dec_create( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t n_ISms, /* i : number of objects */ - int32_t element_brate_tmp[] /* o : element bitrate per object */ + const Word16 n_ISms, /* i : number of objects */ + Word32 element_brate_tmp[] /* o : element bitrate per object */ ) { - int16_t ch; + Word16 ch; ivas_error error; /* allocate ISM metadata handles */ - for ( ch = 0; ch < MAX_NUM_OBJECTS; ch++ ) + FOR( ch = 0; ch < MAX_NUM_OBJECTS; ch++ ) { - if ( ( st_ivas->hIsmMetaData[ch] = (ISM_METADATA_HANDLE) malloc( sizeof( ISM_METADATA_FRAME ) ) ) == NULL ) + IF( ( st_ivas->hIsmMetaData[ch] = (ISM_METADATA_HANDLE) malloc( sizeof( ISM_METADATA_FRAME ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM MetaData\n" ) ); } st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0; + move16(); st_ivas->hIsmMetaData[ch]->position_angle.last_angle1_idx = 0; + move16(); st_ivas->hIsmMetaData[ch]->position_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); + move16(); st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle1_idx = 0; + move16(); st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); + move16(); st_ivas->hIsmMetaData[ch]->last_radius_idx = 8; /* Init to radius 1.0 */ + move16(); -#ifdef IVAS_FLOAT_FIXED st_ivas->hIsmMetaData[ch]->last_true_azimuth_fx = 0; + move32(); st_ivas->hIsmMetaData[ch]->last_true_elevation_fx = 0; + move32(); st_ivas->hIsmMetaData[ch]->last_azimuth_fx = 0; + move32(); st_ivas->hIsmMetaData[ch]->last_elevation_fx = 0; + move32(); +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED + st_ivas->hIsmMetaData[ch]->last_true_azimuth = 0; + st_ivas->hIsmMetaData[ch]->last_true_elevation = 0; + st_ivas->hIsmMetaData[ch]->last_azimuth = 0; + st_ivas->hIsmMetaData[ch]->last_elevation = 0; #endif - // To be removed later //////////////////////////////// + + st_ivas->hIsmMetaData[ch]->ism_imp = -1; + move16(); + st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0; + move16(); + st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0; + move16(); + + ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] ); + } + + IF( element_brate_tmp != NULL ) + { + IF( ( error = ivas_ism_config_fx( st_ivas->hDecoderConfig->ivas_total_brate, n_ISms, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + st_ivas->hISMDTX.ism_dtx_hangover_cnt = IVAS_ISM_DTX_HO_MAX; + move16(); + + return IVAS_ERR_OK; +} +#else +ivas_error ivas_ism_metadata_dec_create( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t n_ISms, /* i : number of objects */ + int32_t element_brate_tmp[] /* o : element bitrate per object */ +) +{ + int16_t ch; + ivas_error error; + + /* allocate ISM metadata handles */ + for ( ch = 0; ch < MAX_NUM_OBJECTS; ch++ ) + { + if ( ( st_ivas->hIsmMetaData[ch] = (ISM_METADATA_HANDLE) malloc( sizeof( ISM_METADATA_FRAME ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM MetaData\n" ) ); + } + + st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0; + st_ivas->hIsmMetaData[ch]->position_angle.last_angle1_idx = 0; + st_ivas->hIsmMetaData[ch]->position_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); + st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle1_idx = 0; + st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); + st_ivas->hIsmMetaData[ch]->last_radius_idx = 8; /* Init to radius 1.0 */ + st_ivas->hIsmMetaData[ch]->last_true_azimuth = 0; st_ivas->hIsmMetaData[ch]->last_true_elevation = 0; st_ivas->hIsmMetaData[ch]->last_azimuth = 0; st_ivas->hIsmMetaData[ch]->last_elevation = 0; - ////////////////////////////////////////////////////// st_ivas->hIsmMetaData[ch]->ism_imp = -1; st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0; @@ -1268,17 +1332,24 @@ ivas_error ivas_ism_metadata_dec_create( if ( element_brate_tmp != NULL ) { +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_ism_config_fx( st_ivas->hDecoderConfig->ivas_total_brate, n_ISms, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, n_ISms, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ) != IVAS_ERR_OK ) { return error; } +#endif } st_ivas->hISMDTX.ism_dtx_hangover_cnt = IVAS_ISM_DTX_HO_MAX; return IVAS_ERR_OK; } - +#endif /*------------------------------------------------------------------------- * decode_angle_indices() diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index d9f1a061d890f8ceae70f600c9cd39b032f54df6..b1cd70474cb7c6311372b34c787d1063a23ad30e 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -665,17 +665,17 @@ ivas_error ivas_param_ism_dec_open( } set_zero( hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc, n_slots_to_alloc * nchan_transport * hSpatParamRendCom->num_freq_bands ); #ifdef IVAS_FLOAT_FIXED - IF( ( hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx = (Word16 *) malloc( n_slots_to_alloc * nchan_transport * hSpatParamRendCom->num_freq_bands * sizeof( Word16 ) ) ) == NULL ) + IF( ( hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx = (Word32 *) malloc( n_slots_to_alloc * nchan_transport * hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM JBM Rendering handle\n" ) ); } - set16_fx( hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx, 0, n_slots_to_alloc * nchan_transport * hSpatParamRendCom->num_freq_bands ); + set32_fx( hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx, 0, n_slots_to_alloc * nchan_transport * hSpatParamRendCom->num_freq_bands ); - IF( ( hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx = (Word16 *) malloc( n_slots_to_alloc * nchan_transport * hSpatParamRendCom->num_freq_bands * sizeof( Word16 ) ) ) == NULL ) + IF( ( hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx = (Word32 *) malloc( n_slots_to_alloc * nchan_transport * hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM JBM Rendering handle\n" ) ); } - set16_fx( hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx, 0, n_slots_to_alloc * nchan_transport * hSpatParamRendCom->num_freq_bands ); + set32_fx( hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx, 0, n_slots_to_alloc * nchan_transport * hSpatParamRendCom->num_freq_bands ); #endif // IVAS_FLOAT_FIXED } @@ -1477,6 +1477,139 @@ void ivas_ism_param_dec_tc_gain_ajust( return; } +#ifdef IVAS_FLOAT_FIXED +void ivas_ism_param_dec_tc_gain_ajust_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const UWord16 nSamples, /* i : number of samples to be compensate */ + const UWord16 nFadeLength, /* i : length of the crossfade in samples */ + Word32 *transport_channels_f[], /* i : synthesized core-coder transport channels/DirAC output Q_tc*/ + Word16 *Q_tc /* i/o : Q of input tc buffer */ +) + +{ + Word16 i, tmp_e1, tmp_e2, tmp, tmp2, invFade; + Word32 L_tmp1, L_tmp2; + + Word16 gain_fx, last_gain_fx; + Word32 ene_tc_fx, ene_sum_fx; + + Word16 ene_tc_e, ene_sum_e; + + ene_tc_fx = 0; + move32(); + ene_tc_e = 0; + move16(); + ene_sum_fx = 0; + move32(); + ene_sum_e = 0; + move16(); + + + last_gain_fx = st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain_fx; + + Word32 ch0, ch1; + Word16 ch0_e, ch1_e; + ch0_e = 0; + move16(); + ch1_e = 0; + move16(); + + FOR( i = 0; i < nSamples; i++ ) + { + ch0_e = 0; + ch1_e = 0; + ch0 = transport_channels_f[0][i]; + ch1 = transport_channels_f[1][i]; + ch0 = BASOP_Util_Add_Mant32Exp( ch0, ch0_e, 0, 0, &ch0_e ); + ch1 = BASOP_Util_Add_Mant32Exp( ch1, ch1_e, 0, 0, &ch1_e ); + + + L_tmp1 = Mpy_32_32( ch0, ch0 ); /*L*L*/ + tmp_e1 = add( ch0_e, ch0_e ); + L_tmp2 = Mpy_32_32( ch1, ch1 ); /*R*R*/ + tmp_e2 = add( ch1_e, ch1_e ); + /*L*LL + R*R*/ + ene_tc_fx = BASOP_Util_Add_Mant32Exp( ene_tc_fx, ene_tc_e, L_tmp1, tmp_e1, &ene_tc_e ); + ene_tc_fx = BASOP_Util_Add_Mant32Exp( ene_tc_fx, ene_tc_e, L_tmp2, tmp_e2, &ene_tc_e ); + + + L_tmp1 = BASOP_Util_Add_Mant32Exp( ch0, ch0_e, ch1, ch1_e, &tmp_e1 ); /*L + R*/ + L_tmp1 = Mpy_32_32( L_tmp1, L_tmp1 ); /*(L + R)*(L + R)*/ + tmp_e1 = add( tmp_e1, tmp_e1 ); + + ene_sum_fx = BASOP_Util_Add_Mant32Exp( ene_sum_fx, ene_sum_e, L_tmp1, tmp_e1, &ene_sum_e ); + } + + IF( NE_32( ene_sum_fx, 0 ) ) + { + gain_fx = BASOP_Util_Divide3232_Scale( ene_tc_fx, ene_sum_fx, &tmp_e1 ); + } + ELSE + { + /*handling denominator equals to zero*/ + gain_fx = 1; + move16(); + tmp_e1 = -32767; + move16(); + } + tmp_e1 = add( tmp_e1, sub( ene_tc_e, ene_sum_e ) ); /* tmp_e1 + (ene_tc_e - ene_sum_e)*/ + gain_fx = Sqrt16( gain_fx, &tmp_e1 ); + + tmp_e2 = st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain_e; + + IF( GT_16( tmp_e2, tmp_e1 ) ) + { + gain_fx = shr( gain_fx, tmp_e2 - tmp_e1 ); + tmp_e1 = tmp_e2; + } + ELSE + { + last_gain_fx = shr( last_gain_fx, tmp_e1 - tmp_e2 ); + } + + IF( st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame > 1 ) + { + /* Smoothing */ + gain_fx = add( mult_r( 24574, gain_fx ), mult_r( 8192, last_gain_fx ) ); + /* 10ms ramp */ + /* slope between two consecutive gains, 480 samples length */ + invFade = div_s( 1, nFadeLength ); + tmp = 0; + FOR( i = 0; i < ( nFadeLength ); i++ ) + { + /* tmp2 = ( last_gain_fx + i * grad_fx )*/ + tmp2 = add( mult_r( sub( 32767, tmp ), last_gain_fx ), mult_r( tmp, gain_fx ) ); + + transport_channels_f[0][i] = Mpy_32_16_1( transport_channels_f[0][i], tmp2 ); + transport_channels_f[1][i] = Mpy_32_16_1( transport_channels_f[1][i], tmp2 ); + + tmp = add( tmp, invFade ); + } + FOR( ; i < nSamples; i++ ) + { + transport_channels_f[0][i] = Mpy_32_16_1( transport_channels_f[0][i], gain_fx ); + transport_channels_f[1][i] = Mpy_32_16_1( transport_channels_f[1][i], gain_fx ); + } + } + ELSE + { + FOR( i = 0; i < nSamples; i++ ) + { + transport_channels_f[0][i] = Mpy_32_16_1( transport_channels_f[0][i], gain_fx ); + transport_channels_f[1][i] = Mpy_32_16_1( transport_channels_f[1][i], gain_fx ); + } + } + + st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain_fx = gain_fx; + move16(); + st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain_e = tmp_e1; + move16(); + + *Q_tc = sub( *Q_tc, tmp_e1 ); + + return; +} +#endif /*-------------------------------------------------------------------------* * ivas_ism_param_dec_render_sf() diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index c2f56d36c37eb595f08511d106aa83c99ff5895e..1fc8abe2869e64fc5639dfcbef7ff76421d88b20 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -3038,7 +3038,151 @@ ivas_error ivas_jbm_dec_tc( else { /* directly copy to tc buffers */ +#ifdef IVAS_FLOAT_FIXED + /*note : the q of cldfb buffers (imag/real) are needed to be Q_p_output - 5 here 6 is taken for that*/ + /*------------------------flt 2 fix----------------------*/ + Word16 Q_tc = 11; + DECODER_TC_BUFFER_HANDLE hTcBuffer = st_ivas->hTcBuffer; + Word16 n_ch_full_copy_temp = s_min( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); + Word16 n_ch_cldfb_tmp = hTcBuffer->nchan_transport_jbm - hTcBuffer->nchan_buffer_full; + Word32 *p_output_temp[12]; + if ( st_ivas->hParamIsmDec != NULL ) + { + f2me_16( st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain, &st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain_fx, &st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain_e ); + } + + for ( int lp = 0; lp < n_ch_cldfb_tmp; lp++ ) + { + p_output_temp[lp] = (Word32 *) malloc( 960 * sizeof( Word32 ) ); + floatToFixed_arrL( p_output[lp], p_output_temp[lp], 11, 960 ); + } + // cldfb_state + + for ( int ch = 0; ch < n_ch_cldfb_tmp; ch++ ) + { + Word16 cldfb_size = st_ivas->cldfbAnaDec[ch]->cldfb_size; + for ( int lp = 0; lp < cldfb_size; lp++ ) + { + st_ivas->cldfbAnaDec[ch]->cldfb_state_fx[lp] = floatToFixed( st_ivas->cldfbAnaDec[ch]->cldfb_state[lp], Q_tc ); + } + } + // cldfb + Word32 *real_buf; + Word32 *imag_buf; + Word16 num_freq_bands; + + if ( st_ivas->ivas_format == ISM_FORMAT ) + { + if ( st_ivas->hSpatParamRendCom != NULL ) + { + num_freq_bands = st_ivas->hSpatParamRendCom->num_freq_bands; + } + for ( int lp = 0; lp < n_ch_cldfb_tmp; lp++ ) + { + Word16 length = 15 * num_freq_bands * n_ch_cldfb_tmp + num_freq_bands * ( n_ch_cldfb_tmp - 1 ) + st_ivas->cldfbAnaDec[lp]->no_channels; + for ( Word16 i = 0; i < length; i++ ) + { + st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[i] = + floatToFixed( st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc[i], 6 ); + st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[i] = + floatToFixed( st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc[i], 6 ); + } + } + } + else if ( st_ivas->ivas_format == MC_FORMAT ) + { + if ( st_ivas->hParamMC != NULL ) + { + num_freq_bands = st_ivas->hParamMC->num_freq_bands; + } + for ( int lp = 0; lp < n_ch_cldfb_tmp; lp++ ) + { + Word16 length = 15 * num_freq_bands * n_ch_cldfb_tmp + num_freq_bands * ( n_ch_cldfb_tmp - 1 ) + st_ivas->cldfbAnaDec[lp]->no_channels; + for ( Word16 lp2 = 0; lp2 < length; lp2++ ) + { + st_ivas->hParamMC->Cldfb_RealBuffer_tc_fx[lp2] = + floatToFixed( st_ivas->hParamMC->Cldfb_RealBuffer_tc[lp2], 6 ); + st_ivas->hParamMC->Cldfb_ImagBuffer_tc_fx[lp2] = + floatToFixed( st_ivas->hParamMC->Cldfb_ImagBuffer_tc[lp2], 6 ); + } + } + } + + /*------------------------flt 2 fix----------------------*/ + + ivas_jbm_dec_copy_tc_no_tsm_fx( st_ivas, p_output_temp, output_frame ); + + /*------------------------fix 2 flt----------------------*/ + // cldfb_state + for ( int ch = 0; ch < n_ch_cldfb_tmp; ch++ ) + { + Word16 cldfb_size = st_ivas->cldfbAnaDec[ch]->cldfb_size; + for ( int lp = 0; lp < cldfb_size; lp++ ) + { + st_ivas->cldfbAnaDec[ch]->cldfb_state[lp] = fixedToFloat( st_ivas->cldfbAnaDec[ch]->cldfb_state_fx[lp], Q_tc ); + } + } + if ( st_ivas->ivas_format == ISM_FORMAT ) + { + if ( st_ivas->hSpatParamRendCom != NULL ) + { + num_freq_bands = st_ivas->hSpatParamRendCom->num_freq_bands; + } + for ( int lp = 0; lp < n_ch_cldfb_tmp; lp++ ) + { + Word16 length = 15 * num_freq_bands * n_ch_cldfb_tmp + num_freq_bands * ( n_ch_cldfb_tmp - 1 ) + st_ivas->cldfbAnaDec[lp]->no_channels; + for ( Word16 lp2 = 0; lp2 < length; lp2++ ) + { + st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc[lp2] = + fixedToFloat( st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[lp2], 6 ); + st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc[lp2] = + fixedToFloat( st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[lp2], 6 ); + } + } + } + else if ( st_ivas->ivas_format == MC_FORMAT ) + { + if ( st_ivas->hParamMC != NULL ) + { + num_freq_bands = st_ivas->hParamMC->num_freq_bands; + } + for ( int lp = 0; lp < n_ch_cldfb_tmp; lp++ ) + { + Word16 length = 15 * num_freq_bands * n_ch_cldfb_tmp + num_freq_bands * ( n_ch_cldfb_tmp - 1 ) + st_ivas->cldfbAnaDec[lp]->no_channels; + for ( Word16 lp2 = 0; lp2 < length; lp2++ ) + { + st_ivas->hParamMC->Cldfb_RealBuffer_tc[lp2] = + fixedToFloat( st_ivas->hParamMC->Cldfb_RealBuffer_tc_fx[lp2], 6 ); + st_ivas->hParamMC->Cldfb_ImagBuffer_tc[lp2] = + fixedToFloat( st_ivas->hParamMC->Cldfb_ImagBuffer_tc_fx[lp2], 6 ); + } + } + } + + for ( int lp = 0; lp < n_ch_cldfb_tmp; lp++ ) + { + fixedToFloat_arrL( p_output_temp[lp], p_output[lp], 11, 960 ); + free( p_output_temp[lp] ); + } + + if ( st_ivas->hParamIsmDec != NULL ) + { + st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain = me2f_16( st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain_fx, st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain_e ); + } + + IF( st_ivas->hDecoderConfig->Opt_tsm ) + { + FOR( int lp = 0; lp < n_ch_full_copy_temp; lp++ ) + { + fixedToFloat_arrL( st_ivas->hTcBuffer->tc_fx[lp], st_ivas->hTcBuffer->tc[lp], Q_tc, hTcBuffer->n_samples_buffered ); + } + } + + /*------------------------fix 2 flt----------------------*/ + +#else ivas_jbm_dec_copy_tc_no_tsm( st_ivas, p_output, output_frame ); +#endif } /*----------------------------------------------------------------* @@ -6647,6 +6791,94 @@ void ivas_jbm_dec_copy_tc_no_tsm( } +#ifdef IVAS_FLOAT_FIXED +void ivas_jbm_dec_copy_tc_no_tsm_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle Q0 */ + Word32 *tc_fx[], /* i : transport channels Q11 */ + const Word16 output_frame /* i : output frame size Q0 */ +) +{ + Word16 Q_tc; + Word16 n_ch_full_copy; + Word16 n_ch_cldfb; + Word16 ch_idx; + DECODER_TC_BUFFER_HANDLE hTcBuffer; + + hTcBuffer = st_ivas->hTcBuffer; + hTcBuffer->n_samples_buffered = output_frame; + hTcBuffer->n_samples_available = hTcBuffer->n_samples_buffered; + n_ch_full_copy = s_min( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); + n_ch_cldfb = sub( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); + + Q_tc = 11; /*tc buffer is at Q11*/ + /* copy full tcs*/ + IF( st_ivas->hDecoderConfig->Opt_tsm ) + { + FOR( ch_idx = 0; ch_idx < n_ch_full_copy; ch_idx++ ) + { + Copy32( tc_fx[ch_idx], st_ivas->hTcBuffer->tc_fx[ch_idx], hTcBuffer->n_samples_buffered ); // keeping tc_fx in Q11 + } + } + ch_idx = 0; + move16(); + + /* CLDFB ana for ParamMC/ParamISM */ + IF( GT_16( n_ch_cldfb, 0 ) ) + { + Word32 *cldfb_real_buffer_fx; + Word32 *cldfb_imag_buffer_fx; + Word16 cldfb_real_e, cldfb_imag_e; + Word16 cldfb_ch, slot_idx, num_freq_bands; + + cldfb_real_buffer_fx = NULL; + cldfb_imag_buffer_fx = NULL; + num_freq_bands = 0; + move16(); + + IF( EQ_16( (Word16) st_ivas->ivas_format, (Word16) ISM_FORMAT ) ) + { + cldfb_real_buffer_fx = st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx; + cldfb_real_e = st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_e; + cldfb_imag_buffer_fx = st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx; + cldfb_imag_e = st_ivas->hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_e; + num_freq_bands = st_ivas->hSpatParamRendCom->num_freq_bands; + + ivas_ism_param_dec_tc_gain_ajust_fx( st_ivas, output_frame, output_frame / 2, tc_fx, &Q_tc ); + Scale_sig32( tc_fx[0], output_frame, 11 - Q_tc ); /*keepeing tc_fx at Q11*/ + Scale_sig32( tc_fx[1], output_frame, 11 - Q_tc ); /*keepeing tc_fx at Q11*/ + } + ELSE IF( EQ_16( (Word16) st_ivas->ivas_format, (Word16) MC_FORMAT ) ) + { + cldfb_real_buffer_fx = st_ivas->hParamMC->Cldfb_RealBuffer_tc_fx; + cldfb_real_e = st_ivas->hParamMC->Cldfb_RealBuffer_tc_e; + cldfb_imag_buffer_fx = st_ivas->hParamMC->Cldfb_ImagBuffer_tc_fx; + cldfb_imag_e = st_ivas->hParamMC->Cldfb_ImagBuffer_tc_e; + num_freq_bands = st_ivas->hParamMC->num_freq_bands; + } + /* CLDFB Analysis*/ + + FOR( cldfb_ch = 0; cldfb_ch < n_ch_cldfb; ( cldfb_ch++, ch_idx++ ) ) + { + FOR( slot_idx = 0; slot_idx < DEFAULT_JBM_CLDFB_TIMESLOTS; slot_idx++ ) + { + Q_tc = 11; + move16(); + cldfbAnalysis_ts_fx_fixed_q( &( tc_fx[ch_idx][num_freq_bands * slot_idx] ), + &cldfb_real_buffer_fx[slot_idx * num_freq_bands * n_ch_cldfb + cldfb_ch * num_freq_bands], + &cldfb_imag_buffer_fx[slot_idx * num_freq_bands * n_ch_cldfb + cldfb_ch * num_freq_bands], + num_freq_bands, st_ivas->cldfbAnaDec[cldfb_ch], &Q_tc ); + } + } + } + hTcBuffer->n_samples_rendered = 0; + move16(); + hTcBuffer->subframes_rendered = 0; + move16(); + + return; +} +#endif + /*--------------------------------------------------------------------------* * ivas_jbm_dec_metadata_open() * diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 88e018d421973d48e64558cb9639ede84b95d596..fcc175f72941ea1d64b288758fff0f342b565f50 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -394,18 +394,26 @@ ivas_error ivas_param_mc_dec_open( Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, hParamMC->num_freq_bands ); - for (int i = 0; i < hParamMC->num_freq_bands; i++) { + for ( int i = 0; i < hParamMC->num_freq_bands; i++ ) + { frequency_axis[i] = (float) frequency_axis_fx[i]; } + + IF( ( error = ivas_dirac_dec_decorr_open_fx( &( hParamMC->h_freq_domain_decorr_ap_params ), &( hParamMC->h_freq_domain_decorr_ap_state ), hParamMC->num_freq_bands, hParamMC->num_outputs_diff, hParamMC->diff_proto_info->num_protos_diff, + DIRAC_SYNTHESIS_COV_MC_LS, frequency_axis_fx, nchan_transport, output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } #else ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, hParamMC->num_freq_bands ); -#endif - - if ( ( error = ivas_dirac_dec_decorr_open( &( hParamMC->h_freq_domain_decorr_ap_params ), &( hParamMC->h_freq_domain_decorr_ap_state ), hParamMC->num_freq_bands, hParamMC->num_outputs_diff, hParamMC->diff_proto_info->num_protos_diff, - DIRAC_SYNTHESIS_COV_MC_LS, frequency_axis, nchan_transport, output_Fs ) ) != IVAS_ERR_OK ) + if ((error = ivas_dirac_dec_decorr_open(&(hParamMC->h_freq_domain_decorr_ap_params), &(hParamMC->h_freq_domain_decorr_ap_state), hParamMC->num_freq_bands, hParamMC->num_outputs_diff, hParamMC->diff_proto_info->num_protos_diff, + DIRAC_SYNTHESIS_COV_MC_LS, frequency_axis, nchan_transport, output_Fs)) != IVAS_ERR_OK) { return error; } +#endif + + hParamMC->h_output_synthesis_params.use_onset_filters = 0; hParamMC->max_band_decorr = hParamMC->h_freq_domain_decorr_ap_params->max_band_decorr; @@ -922,21 +930,27 @@ ivas_error ivas_param_mc_dec_reconfig( #ifdef IVAS_FLOAT_FIXED Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; - ivas_dirac_dec_get_frequency_axis_fx(frequency_axis_fx, output_Fs, hParamMC->num_freq_bands); + ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, hParamMC->num_freq_bands ); - for ( i = 0; i < hParamMC->num_freq_bands; i++) { - frequency_axis[i] = ( float ) frequency_axis_fx[i]; + FOR( i = 0; i < hParamMC->num_freq_bands; i++ ) + { + frequency_axis[i] = (float) frequency_axis_fx[i]; + } + + IF( ( error = ivas_dirac_dec_decorr_open_fx( &( hParamMC->h_freq_domain_decorr_ap_params ), &( hParamMC->h_freq_domain_decorr_ap_state ), hParamMC->num_freq_bands, hParamMC->num_outputs_diff, + hParamMC->diff_proto_info->num_protos_diff, DIRAC_SYNTHESIS_COV_MC_LS, frequency_axis_fx, nchan_transport, output_Fs ) ) != IVAS_ERR_OK ) + { + return error; } #else ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, hParamMC->num_freq_bands ); -#endif - if ( ( error = ivas_dirac_dec_decorr_open( &( hParamMC->h_freq_domain_decorr_ap_params ), &( hParamMC->h_freq_domain_decorr_ap_state ), hParamMC->num_freq_bands, hParamMC->num_outputs_diff, - hParamMC->diff_proto_info->num_protos_diff, DIRAC_SYNTHESIS_COV_MC_LS, frequency_axis, nchan_transport, output_Fs ) ) != IVAS_ERR_OK ) + if ((error = ivas_dirac_dec_decorr_open(&(hParamMC->h_freq_domain_decorr_ap_params), &(hParamMC->h_freq_domain_decorr_ap_state), hParamMC->num_freq_bands, hParamMC->num_outputs_diff, + hParamMC->diff_proto_info->num_protos_diff, DIRAC_SYNTHESIS_COV_MC_LS, frequency_axis, nchan_transport, output_Fs)) != IVAS_ERR_OK) { return error; } - +#endif hParamMC->h_output_synthesis_params.use_onset_filters = 0; hParamMC->max_band_decorr = hParamMC->h_freq_domain_decorr_ap_params->max_band_decorr; /* init decorrelation */ diff --git a/lib_dec/ivas_mct_core_dec.c b/lib_dec/ivas_mct_core_dec.c index 5a8b6c9227753fa00b1e64ae795279c515eb35e4..4a3147df6c5f0b4e689b8a5ba9de5eae6b9c5e12 100644 --- a/lib_dec/ivas_mct_core_dec.c +++ b/lib_dec/ivas_mct_core_dec.c @@ -163,7 +163,136 @@ void ivas_mct_side_bits( * * IVAS MCT core decoder *--------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_mct_core_dec( + MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ + CPE_DEC_HANDLE hCPE[MCT_MAX_BLOCKS], /* i/o: CPE decoder structure */ + const Word16 nCPE, /* i : number of CPEs */ + Word32 *signal_out_fx[], + Word16 q_x[MCT_MAX_CHANNELS] ) +{ + Word16 i, k, ch, cpe_id, nChannels; + Decoder_State *st, *sts[MCT_MAX_CHANNELS]; + Word16 bfi; + /* Framing */ + Word16 L_frame, L_frameTCX, nSubframes; + /* TCX */ + Word16 tcx_offset; + Word16 tcx_offsetFB; + Word16 left_rect; + Word16 L_spec; +#ifdef DEBUG_MCT + float nrg[MCT_MAX_CHANNELS]; +#endif + Word32 *x_fx[MCT_MAX_CHANNELS][NB_DIV]; + + push_wmops( "mct_decoding" ); + + /*--------------------------------------------------------------------------------* + * Initializations + *--------------------------------------------------------------------------------*/ + + nChannels = hMCT->nchan_out_woLFE; + + /*initializations */ + i = 0; + FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) + { + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + sts[i] = hCPE[cpe_id]->hCoreCoder[ch]; + i++; + } + } + + i = 0; + FOR( ch = 0; ch < nChannels; ch++ ) + { + IF( sts[ch]->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) + { + continue; + } + i++; + } + + bfi = sts[0]->bfi; + + FOR( ch = 0; ch < nChannels; ch++ ) + { + /* Initialization or re-configuration of Stereo TCX */ + sts[ch]->enablePlcWaveadjust = 0; + x_fx[ch][0] = signal_out_fx[ch]; + x_fx[ch][1] = signal_out_fx[ch] + ( L_FRAME48k / 2 ); + q_x[ch] = Q12; + } + + IF( sts[0]->igf ) + { + IF( !hMCT->currBlockDataCnt ) + { + FOR( ch = 0; ch < nChannels; ch++ ) + { + st = sts[ch]; + + IF( sts[ch]->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) /*indicates LFE */ + { + continue; + } + + IF( bfi && st->core == ACELP_CORE ) /*no igf processing needed*/ + { + continue; + } + nSubframes = ( st->core == TCX_10_CORE ) ? NB_DIV : 1; + + FOR( k = 0; k < nSubframes; k++ ) + { + L_spec = st->hTcxCfg->tcx_coded_lines / nSubframes; + + init_tcx_info_fx( st, st->L_frame / nSubframes, st->hTcxDec->L_frameTCX / nSubframes, k, bfi, &tcx_offset, &tcx_offsetFB, &L_frame, &L_frameTCX, &left_rect, &L_spec ); + + Word16 x_e, x_len; + /* mono or dual mono IGF decoding */ + x_e = 31 - q_x[ch]; + decoder_tcx_IGF_mono_fx( st, x_fx[ch][k], &x_e, &x_len, L_frame, left_rect, bfi, k ); + q_x[ch] = 31 - x_e; + for ( int i = 0; i < x_len; i++ ) + { + x_fx[ch][k][i] = L_shr( x_fx[ch][k][i], q_x[ch] - Q12 ); + } + q_x[ch] = Q12; + } + } + } + ELSE + { + mctStereoIGF_dec_fx( hMCT, sts, x_fx, bfi ); + } + } + IF( !bfi ) + { + /*--------------------------------------------------------------------------------* + * MCT processing + *--------------------------------------------------------------------------------*/ + + apply_MCT_dec_fx( hMCT, sts, x_fx, q_x ); + FOR( ch = 0; ch < nChannels; ch++ ) + { + for ( int i = 0; i < L_FRAME48k / 2; i++ ) + { + x_fx[ch][0][i] = L_shr( x_fx[ch][0][i], q_x[ch] - Q12 ); + x_fx[ch][1][i] = L_shr( x_fx[ch][1][i], q_x[ch] - Q12 ); + } + q_x[ch] = Q12; + } + } + + pop_wmops(); + + return; +} +#else void ivas_mct_core_dec( MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ CPE_DEC_HANDLE hCPE[MCT_MAX_BLOCKS], /* i/o: CPE decoder structure */ @@ -250,81 +379,15 @@ void ivas_mct_core_dec( { L_spec = st->hTcxCfg->tcx_coded_lines / nSubframes; -#ifdef IVAS_FLOAT_FIXED - init_tcx_info_fx( st, st->L_frame / nSubframes, st->hTcxDec->L_frameTCX / nSubframes, k, bfi, &tcx_offset, &tcx_offsetFB, &L_frame, &L_frameTCX, &left_rect, &L_spec ); - - // Float to fixed - Word32 x_fx[N_MAX]; - Word16 x_e; - Word16 x_len; - -#if 1 - // NOTE: The folloing code is to pre-calculate "stop", which is the length of x that will get - // updated inside the function decoder_tcx_IGF_mono_fx. Can remove this later. - Word16 stop; - Word16 tmp_igfGridIdx = IGF_GRID_LB_SHORT; - IF(NE_16(L_frame, shr(st->L_frame, 1)) && st->tcxonly) - { - tmp_igfGridIdx = (EQ_16(st->last_core, ACELP_CORE) || (left_rect && bfi)) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM; - } - stop = st->hIGFDec->igfData.igfInfo.grid[tmp_igfGridIdx].stopLine; - IF(st->igf) - { - f2me_buf(x[ch][k], x_fx, &x_e, stop); - } -#endif - - /* mono or dual mono IGF decoding */ - decoder_tcx_IGF_mono_fx( st, x_fx, &x_e, &x_len, L_frame, left_rect, bfi, k ); - - IF(st->igf) - { - // Fixed to float - me2f_buf(x_fx, x_e, x[ch][k], x_len); - me2f_buf(st->hIGFDec->virtualSpec, st->hIGFDec->virtualSpec_e, st->hIGFDec->virtualSpec_float, (N_MAX_TCX - IGF_START_MN)); - // 16bit to u8bit - FOR(Word16 l = 0; l < IGF_START_MX; l++) - { - st->hIGFDec->infoTCXNoise[l] = (uint8_t)st->hIGFDec->infoTCXNoise_evs[l]; - } - } -#else init_tcx_info( st, st->L_frame / nSubframes, st->hTcxDec->L_frameTCX / nSubframes, k, bfi, &tcx_offset, &tcx_offsetFB, &L_frame, &L_frameTCX, &left_rect, &L_spec ); /* mono or dual mono IGF decoding */ decoder_tcx_IGF_mono( st, x[ch][k], L_frame, left_rect, bfi, k ); -#endif } } } else { -#ifdef IVAS_FLOAT_FIXED - Word32 *x_fx[MCT_MAX_CHANNELS][NB_DIV]; - Word16 q_x[MCT_MAX_CHANNELS]; - - FOR( ch = 0; ch < nChannels; ch++ ) - { - x_fx[ch][0] = malloc( ( L_FRAME48k ) * sizeof( Word32 ) ); - x_fx[ch][1] = x_fx[ch][0] + L_FRAME48k / 2; - - floatToFixed_arrL( x[ch][0], x_fx[ch][0], Q12, L_FRAME48k / 2 ); - floatToFixed_arrL( x[ch][1], x_fx[ch][1], Q12, L_FRAME48k / 2 ); - q_x[ch] = Q12; - } - mctStereoIGF_dec_fx( hMCT, sts, x_fx, bfi ); - FOR( ch = 0; ch < nChannels; ch++ ) - { - fixedToFloat_arrL( x_fx[ch][0], x[ch][0], q_x[ch], L_FRAME48k / 2 ); - fixedToFloat_arrL( x_fx[ch][1], x[ch][1], q_x[ch], L_FRAME48k / 2 ); - } - - FOR( ch = 0; ch < nChannels; ch++ ) - { - free( x_fx[ch][0] ); - } -#else mctStereoIGF_dec( hMCT, sts, x, bfi ); -#endif } } @@ -333,40 +396,11 @@ void ivas_mct_core_dec( /*--------------------------------------------------------------------------------* * MCT processing *--------------------------------------------------------------------------------*/ - -#ifdef IVAS_FLOAT_FIXED - Word32 *x_fx[MCT_MAX_CHANNELS][NB_DIV]; - Word16 q_x[MCT_MAX_CHANNELS]; - - FOR( ch = 0; ch < nChannels; ch++ ) - { - x_fx[ch][0] = malloc( ( L_FRAME48k ) * sizeof( Word32 ) ); - x_fx[ch][1] = x_fx[ch][0] + L_FRAME48k / 2; - - floatToFixed_arrL( x[ch][0], x_fx[ch][0], Q12, L_FRAME48k / 2 ); - floatToFixed_arrL( x[ch][1], x_fx[ch][1], Q12, L_FRAME48k / 2 ); - - q_x[ch] = Q12; - } - - apply_MCT_dec_fx( hMCT, sts, x_fx, q_x ); - - FOR( ch = 0; ch < nChannels; ch++ ) - { - fixedToFloat_arrL( x_fx[ch][0], x[ch][0], q_x[ch], L_FRAME48k / 2 ); - fixedToFloat_arrL( x_fx[ch][1], x[ch][1], q_x[ch], L_FRAME48k / 2 ); - } - - FOR( ch = 0; ch < nChannels; ch++ ) - { - free( x_fx[ch][0] ); - } -#else apply_MCT_dec( hMCT, sts, x ); -#endif } pop_wmops(); return; } +#endif \ No newline at end of file diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 046640f03d2c03e940373d9ddec40b2b60bba0f8..13f327cd4d55da8d9938b04348f17f97e3372cec 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -324,7 +324,82 @@ ivas_error ivas_mct_dec( } /* MCT core decoder */ +#ifdef IVAS_FLOAT_FIXED +#if 1 + Word32 *signal_out_fx[MAX_TRANSPORT_CHANNELS]; + Decoder_State *st, *sts_tmp[MAX_TRANSPORT_CHANNELS]; + int i = 0; + for (cpe_id = 0; cpe_id < nCPE; cpe_id++) + { + for (int ch = 0; ch < CPE_CHANNELS; ch++) + { + sts_tmp[i] = st_ivas->hCPE[cpe_id]->hCoreCoder[ch]; + i++; + } + } + + i = 0; + for (int ch = 0; ch < hMCT->nchan_out_woLFE; ch++) + { + if (sts_tmp[ch]->mct_chan_mode == MCT_CHAN_MODE_IGNORE) + { + continue; + } + i++; + } + + for (int i = 0; i < hMCT->nchan_out_woLFE; ++i) + { + signal_out_fx[i] = malloc(L_FRAME48k * sizeof(Word32)); + floatToFixed_arrL(output[i], signal_out_fx[i], Q12, L_FRAME48k); + } + Word16 q_x[MAX_TRANSPORT_CHANNELS]; + set16_fx(q_x, Q12, MAX_TRANSPORT_CHANNELS); +#endif + + ivas_mct_core_dec(hMCT, st_ivas->hCPE, nCPE, signal_out_fx, q_x); + + for (int ch = 0; ch < hMCT->nchan_out_woLFE; ch++) + { + fixedToFloat_arrL(signal_out_fx[ch], output[ch], q_x[ch], L_FRAME48k); + free(signal_out_fx[ch]); + } + /*for (int ch = 0; ch < hMCT->nchan_out_woLFE; ch++) + { + dbgwrite_txt(output[ch] , L_FRAME48k, "Fixed_code_mct_core.txt", NULL); + for (int k = 0; k < L_FRAME48k; k++) + { + k = k; + } + }*/ +#if 1 + if (sts_tmp[0]->igf) + { + if (!hMCT->currBlockDataCnt) + { + for (int ch = 0; ch < hMCT->nchan_out_woLFE; ch++) + { + st = sts_tmp[ch]; + + IF(st->igf) + { + me2f_buf(st->hIGFDec->virtualSpec, st->hIGFDec->virtualSpec_e, st->hIGFDec->virtualSpec_float, (N_MAX_TCX - IGF_START_MN)); + FOR(Word16 l = 0; l < IGF_START_MX; l++) + { + st->hIGFDec->infoTCXNoise[l] = (uint8_t)st->hIGFDec->infoTCXNoise_evs[l]; + } + } + } + } + } +#endif +#else ivas_mct_core_dec( hMCT, st_ivas->hCPE, nCPE, output ); + /*for (int ch = 0; ch < hMCT->nchan_out_woLFE; ch++) + { + dbgwrite_txt(output[ch], L_FRAME48k, "Float_code_mct_core.txt", NULL); + }*/ +#endif /* for sba to stereo output disable any further processing for TCs > 2 as it is not needed*/ if ( st_ivas->sba_dirac_stereo_flag && st_ivas->ivas_format != SBA_ISM_FORMAT ) diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 25ca9808ce499bb1e92abd5e66c74d07284e0d2e..69116e3b70b43b044f77735fc5289d2150c071c1 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -55,8 +55,7 @@ ivas_error ivas_td_binaural_open_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ Word16 * SrcInd, /*Temporarily used to store the updated value of SrcInd*/ - Word16 *num_src, - Word16 *directivity_fx + Word16 *num_src ) { *num_src = st_ivas->nchan_transport; @@ -66,7 +65,7 @@ ivas_error ivas_td_binaural_open_fx( *num_src = st_ivas->nchan_ism; move16(); } - return ivas_td_binaural_open_unwrap_fx( &st_ivas->hHrtfTD, st_ivas->hDecoderConfig->output_Fs, *num_src, st_ivas->ivas_format, st_ivas->transport_config, directivity_fx, st_ivas->hTransSetup, &st_ivas->hBinRendererTd, &st_ivas->binaural_latency_ns, SrcInd ); + return ivas_td_binaural_open_unwrap_fx( &st_ivas->hHrtfTD, st_ivas->hDecoderConfig->output_Fs, *num_src, st_ivas->ivas_format, st_ivas->transport_config, st_ivas->hRenderConfig->directivity_fx, st_ivas->hTransSetup, &st_ivas->hBinRendererTd, &st_ivas->binaural_latency_ns, SrcInd ); } #endif // IVAS_FLOAT_FIXED diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 9ffdfdd7edc34d636f3ce5475bf80cb28efa9652..9b833d71a9d5f57e7ab4a8a0b57929e2c5c363d8 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -42,6 +42,7 @@ #include "ivas_prot_fx.h" #include "prot_fx2.h" +#define IVAS_FLOAT_FIXED_TO_BE_REMOVED /*------------------------------------------------------------------------- * Local constants @@ -288,6 +289,299 @@ void ivas_omasa_data_close( * * oMASA decoder configuration *--------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_omasa_dec_config_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + UWord16 *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ + Word16 Q_cldfbSynDec, /* i : Q factor for cldfb state */ + Word16 *num_src, + Word16 SrcInd[MAX_NUM_TDREND_CHANNELS], + Word16 *data /* o : output synthesis signal */ +) +{ + Word16 k, sce_id, nSCE_old, nchan_hp20_old, numCldfbAnalyses_old, numCldfbSyntheses_old, n_MD; + Word32 ivas_total_brate, ism_total_brate, cpe_brate; + Word32 brate_SCE, brate_CPE; + ISM_MODE ism_mode_old; + IVAS_FORMAT ivas_format_orig; + Word16 nchan_out_buff, nchan_out_buff_old; + ivas_error error; + RENDERER_TYPE old_renderer_type; + + /* initializations */ + ism_total_brate = 0; + move32(); + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + move32(); + + /* save previous frame parameters */ + ism_mode_old = ivas_omasa_ism_mode_select( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->nchan_ism ); + move16(); + st_ivas->ism_mode = ism_mode_old; + move16(); + + ivas_format_orig = st_ivas->ivas_format; + move16(); + st_ivas->ivas_format = st_ivas->last_ivas_format; + move16(); + ivas_init_dec_get_num_cldfb_instances_ivas_fx( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); + nchan_out_buff_old = ivas_get_nchan_buffers_dec_ivas_fx( st_ivas, -1, -1 ); + move16(); + + st_ivas->ivas_format = ivas_format_orig; + move16(); + + nSCE_old = st_ivas->nSCE; + move16(); + nchan_hp20_old = getNumChanSynthesis( st_ivas ); + move16(); + + /* set ism_mode of current frame */ + st_ivas->ism_mode = ivas_omasa_ism_mode_select( ivas_total_brate, st_ivas->nchan_ism ); + move16(); + + /*-----------------------------------------------------------------* + * Renderer selection + *-----------------------------------------------------------------*/ + + old_renderer_type = st_ivas->renderer_type; + + /* MASA reconfig. */ + cpe_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism ); + move32(); + test(); test(); test(); + IF ( st_ivas->ini_active_frame == 0 && NE_32(ivas_total_brate, FRAME_NO_DATA ) && LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) && EQ_16( st_ivas->nCPE, 1 ) ) + { + st_ivas->hCPE[0]->nchan_out = 1; + move16(); + } + ELSE IF( ( error = ivas_masa_dec_reconfigure_fx( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) ) + { + st_ivas->hCPE[0]->nchan_out = 1; + move16(); + } + ELSE + { + st_ivas->hCPE[0]->nchan_out = 2; + move16(); + } + + /* OMASA reconfig. */ + test(); + IF( st_ivas->hMasaIsmData == NULL && EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) + { + IF( ( error = ivas_omasa_data_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + ivas_set_omasa_TC( st_ivas->ism_mode, st_ivas->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE ); + + /* re-configure hp20 memories */ + IF( ( error = ivas_hp20_dec_reconfig_fx( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) + { + return error; + } +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED + /* Float code to be removed. */ + IF( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + + /* reconfigure core-coders for ISMs */ + k = 0; + move16(); + WHILE( LT_16(k, SIZE_IVAS_BRATE_TBL) && NE_32( ivas_total_brate, ivas_brate_tbl[k] ) ) + { + k = add(k, 1); + } + + FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) + { + ism_total_brate = L_add(ism_total_brate, sep_object_brate[k - 2][st_ivas->nSCE - 1]); + } + + brate_SCE = 0; + move32(); + IF( GT_16( st_ivas->nSCE, 0 )) + { + brate_SCE = sep_object_brate[k - 2][st_ivas->nSCE - 1]; + move32(); + } + brate_CPE = L_sub( ivas_total_brate, ism_total_brate ); + IF( ( error = ivas_corecoder_dec_reconfig( st_ivas, nSCE_old, 1, 2, 0, brate_SCE, brate_CPE ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF ( NE_16(ism_mode_old, st_ivas->ism_mode) ) + { + /* ISM MD reconfig. */ + n_MD = 0; + move16(); + + test(); + IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) ) + { + n_MD = 1; + move16(); + + IF( st_ivas->hIsmMetaData[0] == NULL ) + { + IF( ( error = ivas_ism_metadata_dec_create( st_ivas, 1, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) + { + n_MD = st_ivas->nchan_ism; + move16(); + + ivas_ism_metadata_close( st_ivas->hIsmMetaData, 0 ); + + IF( ( error = ivas_ism_metadata_dec_create( st_ivas, st_ivas->nchan_ism, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + ivas_ism_metadata_close( st_ivas->hIsmMetaData, n_MD ); + + st_ivas->hCPE[0]->element_brate = L_sub( ivas_total_brate, ism_total_brate); + + /*-----------------------------------------------------------------* + * Renderer selection + *-----------------------------------------------------------------*/ + + ivas_renderer_select( st_ivas ); + + /*-------------------------------------------------------------------* + * Reallocate rendering handles + *--------------------------------------------------------------------*/ + + IF( NE_16( old_renderer_type, st_ivas->renderer_type ) ) + { + IF( EQ_16( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) ) + { + IF( ( error = ivas_mono_dmx_renderer_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + ELSE + { + ivas_mono_dmx_renderer_close( &st_ivas->hMonoDmxRenderer ); + } + } + + /* objects renderer reconfig. */ + IF( st_ivas->hMasaIsmData != NULL ) + { + ivas_omasa_separate_object_renderer_close( st_ivas ); + } + + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) ) + { + IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) + { + /* Allocate TD renderer for the objects in DISC mode */ + IF ( ( error = ivas_td_binaural_open_fx( st_ivas, SrcInd, num_src ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */ + IF( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + ELSE + { + /* TD renderer handle */ + ivas_td_binaural_close_fx( &st_ivas->hBinRendererTd ); + + st_ivas->hHrtfTD = NULL; + + /* ISM renderer handle + ISM data handle */ + ivas_omasa_separate_object_renderer_close( st_ivas ); + } + } + + IF( st_ivas->renderer_type == RENDERER_DIRAC ) + { + IF( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */ + IF( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + ELSE + { + /* ISM renderer handle + ISM data handle */ + ivas_omasa_separate_object_renderer_close( st_ivas ); + } + } + + /*-----------------------------------------------------------------* + * TD Decorrelator + *-----------------------------------------------------------------*/ + + IF( st_ivas->hDiracDecBin != NULL ) + { + IF( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK ) + + { + return error; + } + } + + /*-----------------------------------------------------------------* + * CLDFB instances + *-----------------------------------------------------------------*/ + + IF ( ( error = ivas_cldfb_dec_reconfig_fx( st_ivas, 2, numCldfbAnalyses_old, numCldfbSyntheses_old, Q_cldfbSynDec ) ) != IVAS_ERR_OK ) + { + return error; + } + + /*-----------------------------------------------------------------* + * floating-point output audio buffers + *-----------------------------------------------------------------*/ + + nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); + IF( ( error = ivas_output_buff_dec_fx( st_ivas->p_output_fx, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) + { + return error; + } +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED + IF( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + } + + return IVAS_ERR_OK; +} +#endif ivas_error ivas_omasa_dec_config( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ @@ -331,20 +625,12 @@ ivas_error ivas_omasa_dec_config( old_renderer_type = st_ivas->renderer_type; /* MASA reconfig. */ -#ifdef IVAS_FLOAT_FIXED - cpe_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism ); -#else cpe_brate = calculate_cpe_brate_MASA_ISM( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism ); -#endif if ( st_ivas->ini_active_frame == 0 && ivas_total_brate != FRAME_NO_DATA && ( cpe_brate < MASA_STEREO_MIN_BITRATE ) && st_ivas->nCPE == 1 ) { st_ivas->hCPE[0]->nchan_out = 1; } -#ifdef IVAS_FLOAT_FIXED - else if ( ( error = ivas_masa_dec_reconfigure_fx( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#else else if ( ( error = ivas_masa_dec_reconfigure( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -370,12 +656,6 @@ ivas_error ivas_omasa_dec_config( ivas_set_omasa_TC( st_ivas->ism_mode, st_ivas->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE ); /* re-configure hp20 memories */ -#ifdef IVAS_FLOAT_FIXED - if ((error = ivas_hp20_dec_reconfig_fx(st_ivas, nchan_hp20_old)) != IVAS_ERR_OK) - { - return error; - } -#endif // IVAS_FLOAT_FIXED if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) { return error; @@ -467,7 +747,7 @@ ivas_error ivas_omasa_dec_config( if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { /* Allocate TD renderer for the objects in DISC mode */ - if ( ( error = ivas_td_binaural_open( st_ivas ) ) != IVAS_ERR_OK ) + if ((error = ivas_td_binaural_open(st_ivas)) != IVAS_ERR_OK) { return error; } @@ -482,6 +762,7 @@ ivas_error ivas_omasa_dec_config( { /* TD renderer handle */ ivas_td_binaural_close( &st_ivas->hBinRendererTd ); + st_ivas->hHrtfTD = NULL; /* ISM renderer handle + ISM data handle */ @@ -527,7 +808,6 @@ ivas_error ivas_omasa_dec_config( /*-----------------------------------------------------------------* * CLDFB instances *-----------------------------------------------------------------*/ - if ( ( error = ivas_cldfb_dec_reconfig( st_ivas, 2, numCldfbAnalyses_old, numCldfbSyntheses_old ) ) != IVAS_ERR_OK ) { return error; @@ -537,11 +817,12 @@ ivas_error ivas_omasa_dec_config( * floating-point output audio buffers *-----------------------------------------------------------------*/ - nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); - if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) - { - return error; - } + nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); + + if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) + { + return error; + } } diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index ce2aebb99172ba7f684ea0f71b36f231b1abdad5..7936d5bc5def69d2e3cbc84f1fa1a66915ee91e2 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -612,8 +612,10 @@ typedef struct param_ism_rendering #ifdef IVAS_FLOAT_FIXED Word16 *proto_matrix_fx; Word16 *interpolator_fx; - Word16 *Cldfb_RealBuffer_tc_fx; - Word16 *Cldfb_ImagBuffer_tc_fx; + Word32 *Cldfb_RealBuffer_tc_fx; + Word16 *Cldfb_RealBuffer_tc_e; + Word32 *Cldfb_ImagBuffer_tc_fx; + Word16 *Cldfb_ImagBuffer_tc_e; #endif // IVAS_FLOAT_FIXED float *proto_matrix; float *interpolator; @@ -1224,7 +1226,7 @@ typedef struct decoder_tc_buffer_structure float *tc[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc */ // VE2SB: TBV #ifdef IVAS_FLOAT_FIXED Word32 *tc_buffer_fx; /* the buffer itself */ - Word32 *tc_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc */ // VE2SB: TBV + Word32 *tc_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc Q11 for ivas */ // VE2SB: TBV #endif TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ int16_t nchan_transport_jbm; /* number of TCs after TC decoding */ diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc.c index 0bf9255844d77cb29c4b2bed00362ed2a221e547..9b059aefb979e51187da3c80c4987b9597b0d80f 100644 --- a/lib_enc/ivas_agc_enc.c +++ b/lib_enc/ivas_agc_enc.c @@ -38,13 +38,173 @@ #include #include #include "wmc_auto.h" - +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "ivas_prot_fx.h" +#include "basop_util.h" +#endif /*------------------------------------------------------------------------------------------* * Local constants *------------------------------------------------------------------------------------------*/ #define AGC_MIN_DELTA ( 4.656612873077393e-10f ) /*2^-31*/ +#ifdef IVAS_FLOAT_FIXED +#define AGC_MIN_DELTA_FX 1 //q31 +#define TWO_IN_Q29 1073741824 +#define ONE_MINUS_M_DELTA_PROD_FLT_FC 1073741824 //Q15 +#endif + +#ifdef IVAS_FLOAT_FIXED +static Word16 ceil_fx( Word16 inp, Word16 Q ); +static Word16 ceil_fx( Word16 inp, Word16 Q ) +{ + Word16 ret; + Word32 ret_32; + IF( GT_16( inp, 0 ) ) + { + IF( EQ_16( Q, 15 ) ) + { + ret = 1; + return ret; + } + ELSE + { + ret_32 = L_add( inp , sub( shl( 1, Q ), 1 ) ); //(inp+(pow(2,q)-1))/pow(2,q)// + ret_32 = L_shr(ret_32, Q ); + return (Word16)( ret_32 ); + } + } + ELSE + { + ret = negate( shr( abs_s( inp ), Q ) ); + } + + return ret; +} + +Word16 BASOP_Util_Cmp_Mant32Exp_sat /*!< o: flag: result of comparison */ +/* 0, if a == b */ +/* 1, if a > b */ +/* -1, if a < b */ +(Word32 a_m, /*!< i: Mantissa of 1st operand a */ + Word16 a_e, /*!< i: Exponent of 1st operand a */ + Word32 b_m, /*!< i: Mantissa of 2nd operand b */ + Word16 b_e) /*!< i: Exponent of 2nd operand b */ + +{ + Word32 diff_m; + Word16 diff_e, shift, result; + + + + /* + This function compares two input parameters, both represented by a 32-bit mantissa and a 16-bit exponent. + If both values are identical, 0 is returned. + If a is greater b, 1 is returned. + If a is less than b, -1 is returned. + */ + + /* Check, if both mantissa and exponents are identical, when normalized: return 0 */ + shift = norm_l(a_m); + if (shift) + a_m = L_shl(a_m, shift); + if (shift) + a_e = sub(a_e, shift); + + shift = norm_l(b_m); + if (shift) + b_m = L_shl(b_m, shift); + if (shift) + b_e = sub(b_e, shift); + + /* align exponent, if any mantissa is zero */ + if (!a_m) + { + a_e = b_e; + move16(); + } + if (!b_m) + { + b_e = a_e; + move16(); + } + + BASOP_SATURATE_WARNING_OFF_EVS + diff_m = L_sub_sat( a_m, b_m ); + BASOP_SATURATE_WARNING_ON_EVS + diff_e = sub( a_e, b_e ); + + test(); + IF( diff_m == 0 && diff_e == 0 ) + { + return 0; + } + + /* Check sign, exponent and mantissa to identify, whether a is greater b or not */ + result = sub( 0, 1 ); + + IF( a_m >= 0 ) + { + /* a is positive */ + if ( b_m < 0 ) + { + result = 1; + move16(); + } + + test(); + test(); + test(); + if ( ( b_m >= 0 ) && ( ( diff_e > 0 ) || ( diff_e == 0 && diff_m > 0 ) ) ) + { + result = 1; + move16(); + } + } + ELSE + { + /* a is negative */ + test(); + test(); + test(); + if ( ( b_m < 0 ) && ( ( diff_e < 0 ) || ( diff_e == 0 && diff_m > 0 ) ) ) + { + result = 1; + move16(); + } + } + return result; +} + +Word32 pow32_fx( Word16 inp, Word16 indx ) +{ + Word32 temp_1, temp_2; + IF( EQ_16( indx, 1 ) ) + { + return L_deposit_h(inp); + } + ELSE IF( EQ_16( indx, 0 ) ) + { + return ONE_IN_Q31; + } + ELSE + { + temp_1 = L_mult( inp, inp ); // Q31 + temp_2 = temp_1; + FOR( int i = 0; i < ( shr( indx, 1 ) ); i++ ) + { + temp_1 = Mpy_32_32( temp_1, temp_1 ); // Q31 + } + IF( s_and( indx, 1 ) ) + { + temp_1 = Mpy_32_32( temp_2, temp_1 ); // Q31 + } + } + return temp_1; +} +#endif /*-----------------------------------------------------------------------------------------* @@ -67,6 +227,21 @@ Word16 ivas_agc_enc_get_flag( return agc_flag; } +#ifdef IVAS_FLOAT_FIXED +Word16 ivas_agc_enc_get_flag_fx( + const Word16 nchan_transport /* i : number of transport channels */ +) +{ + Word16 agc_flag; + + /* AGC is enabled only if there is one transport channel. */ + agc_flag = (Word16) ( nchan_transport == 1 ); + + + return agc_flag; +} +#endif + /*-----------------------------------------------------------------------------------------* * Function ivas_agc_enc_init() @@ -115,6 +290,52 @@ static void ivas_agc_enc_init( return; } +#ifdef IVAS_FLOAT_FIXED +static void ivas_agc_enc_init_fx( + ivas_agc_enc_state_t *hAgcEnc, + const Word16 input_frame, + const Word16 nchan_inp, + const Word16 delay ) +{ + Word16 i; + ivas_agc_enc_chan_state_t *ptrG = hAgcEnc->gain_state; + ivas_agc_chan_data_t *ptr = hAgcEnc->gain_data; + + hAgcEnc->agc_com.in_delay = delay; + hAgcEnc->agc_com.num_coeff = FOA_CHANNELS; + + ivas_agc_calcGainParams_fx( &hAgcEnc->agc_com.absEmin, &hAgcEnc->agc_com.betaE, &hAgcEnc->agc_com.maxAttExp, hAgcEnc->agc_com.num_coeff ); + + ivas_agc_initWindowFunc_fx( hAgcEnc->agc_com.winFunc_fx, input_frame - hAgcEnc->agc_com.in_delay ); + + hAgcEnc->minDelta_fx = AGC_MIN_DELTA_FX; + hAgcEnc->smFact_fx = 214748368;//q31 + + for ( i = 0; i < nchan_inp; i++ ) + { + /* gain_state */ + ptrG->lastExp = 0; + ptrG->prevExp = 0; + ptrG->lastGain_fx = ONE_IN_Q31; + ptrG->q_lastGain_fx = Q31; + ptrG->lastMaxAbs_fx = 0; + ptrG->q_lastMaxAbs_fx = Q31; + ptrG->gainExpVal = 0; + ptrG->MaxAbsVal_del_fx = 0; + ptrG->q_MaxAbsVal_del_fx = Q31; + ptrG->MaxAbsValIdx_del = 0; + ptrG++; + + /* gain_data */ + ptr->absGainExp = hAgcEnc->agc_com.absEmin; + ptr->absGainExpCurr = hAgcEnc->agc_com.absEmin; + ptr++; + } + + return; +} +#endif + /*------------------------------------------------------------------------- * ivas_spar_agc_enc_open() @@ -161,6 +382,47 @@ ivas_error ivas_spar_agc_enc_open( return IVAS_ERR_OK; } +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_spar_agc_enc_open_fx( + ivas_agc_enc_state_t **hAgcEnc, /* i/o: SPAR AGC encoder handle */ + const Word32 input_Fs, /* i : input sampling rate */ + const Word16 nchan_inp /* i : number of input channels */ +) +{ + ivas_agc_enc_state_t *hAgc; + Word16 input_frame, delay; + + if ( ( hAgc = (ivas_agc_enc_state_t *) malloc( sizeof( ivas_agc_enc_state_t ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR AGC encoder" ); + } + + input_frame = (Word16) Mpy_32_16_1( input_Fs, INV_FRAME_PER_SEC_Q15 ); + delay = NS2SA_fx2( input_Fs, ( IVAS_ENC_DELAY_NS + IVAS_DEC_DELAY_NS ) ); + + if ( ( hAgc->agc_com.winFunc_fx = (Word16 *) malloc( sizeof( Word16 ) * ( input_frame - delay ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR AGC encoder" ); + } + + if ( ( hAgc->gain_state = (ivas_agc_enc_chan_state_t *) malloc( sizeof( ivas_agc_enc_chan_state_t ) * nchan_inp ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR AGC encoder" ); + } + + if ( ( hAgc->gain_data = (ivas_agc_chan_data_t *) malloc( sizeof( ivas_agc_chan_data_t ) * nchan_inp ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR AGC encoder" ); + } + + ivas_agc_enc_init_fx( hAgc, input_frame, nchan_inp, delay ); + + *hAgcEnc = hAgc; + + return IVAS_ERR_OK; +} +#endif + /*------------------------------------------------------------------------- * ivas_spar_agc_enc_close() @@ -196,6 +458,36 @@ void ivas_spar_agc_enc_close( return; } +#ifdef IVAS_FLOAT_FIXED +void ivas_spar_agc_enc_close_fx( + ivas_agc_enc_state_t **hAgcEnc /* i/o: SPAR AGC encoder handle */ +) +{ + ivas_agc_enc_state_t *hAgc; + + if ( hAgcEnc == NULL || *hAgcEnc == NULL ) + { + return; + } + + hAgc = *hAgcEnc; + + free( hAgc->agc_com.winFunc_fx ); + hAgc->agc_com.winFunc_fx = NULL; + + free( hAgc->gain_state ); + hAgc->gain_state = NULL; + + free( hAgc->gain_data ); + hAgc->gain_data = NULL; + + free( *hAgcEnc ); + *hAgcEnc = NULL; + + return; +} +#endif + /*-----------------------------------------------------------------------------------------* * Function ivas_agc_enc_process() @@ -434,3 +726,451 @@ void ivas_agc_enc_process( return; } +#ifdef IVAS_FLOAT_FIXED +void ivas_agc_enc_process_fx( + ivas_agc_enc_state_t *hAgcEnc, /* i/o: AGC encoder handle */ + BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ + Word32 **ppPcm_in, /* i : input audio channels */ + Word32 **ppPcm_out, /* o : output audio channels */ + const Word16 n_channels, /* i : number of channels */ + const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ + Word16 *q_ppPcm ) +{ + Word16 i, j, idx, input_frame, offset; + Word16 per_ch_bit[FOA_CHANNELS], AGC_flag; + Word16 extendedExpVal = FALSE; + Word16 isGainAdjusted; + Word32 gain; + Word16 q_predMaxAbsVal, q_MaxAbsVal; + ivas_agc_enc_state_t *pState = hAgcEnc; + + input_frame = (Word16) Mpy_32_16_1( hEncoderConfig->input_Fs, INV_FRAME_PER_SEC_Q15 ); + offset = input_frame - pState->agc_com.in_delay; + + AGC_flag = 0; + + FOR( i = 0; i < n_channels; i++ ) + { + Word16 q_pcm = q_ppPcm[i]; + Word32 sampleAbsVal; + Word16 isClipped = FALSE; + Word16 clippedIdx = 0; + Word16 MaxAbsValIdx = 0; + Word16 q_sampleAbsVal, gain_norm; + Word32 MaxAbsVal = pState->gain_state[i].MaxAbsVal_del_fx; + Word32 predMaxAbsVal = L_abs( ppPcm_in[i][offset] ); + q_predMaxAbsVal = q_ppPcm[i]; + q_MaxAbsVal = pState->gain_state[i].q_MaxAbsVal_del_fx; + + IF( LT_16( pState->gain_state[i].q_lastGain_fx, 31 ) ) + { + gain_norm = norm_l( L_abs( pState->gain_state[i].lastGain_fx ) ); + pState->gain_state[i].lastGain_fx = L_shl( pState->gain_state[i].lastGain_fx, gain_norm ); + pState->gain_state[i].q_lastGain_fx = pState->gain_state[i].q_lastGain_fx + gain_norm; + } + FOR( j = 0; j < input_frame; j++ ) + { + sampleAbsVal = L_abs( ppPcm_in[i][j] ); + q_sampleAbsVal = q_ppPcm[i]; + + IF( EQ_16( ( BASOP_Util_Cmp_Mant32Exp_sat( sampleAbsVal, 31 - q_sampleAbsVal, MaxAbsVal, 31 - q_MaxAbsVal ) ), 1 ) ) + { + MaxAbsVal = sampleAbsVal; + q_MaxAbsVal = q_sampleAbsVal; + MaxAbsValIdx = j; + } + + IF( GT_16( j, offset ) ) + { + IF( EQ_16( ( BASOP_Util_Cmp_Mant32Exp_sat( sampleAbsVal, 31 - q_sampleAbsVal, predMaxAbsVal, 31 - q_predMaxAbsVal ) ), 1 ) ) + { + predMaxAbsVal = sampleAbsVal; + q_predMaxAbsVal = q_sampleAbsVal; + } + } + + ppPcm_out[i][j] = Mpy_32_32( ppPcm_in[i][j], pState->gain_state[i].lastGain_fx ); + q_pcm = q_ppPcm[i] + ( pState->gain_state[i].q_lastGain_fx ) - 31; + IF( !isClipped ) + { + Word16 comp_flag_1 = 0; + comp_flag_1 = BASOP_Util_Cmp_Mant32Exp_sat( ppPcm_in[i][j], ( 31 - q_pcm ), ONE_MINUS_M_DELTA_PROD_FLT_FC, 16 ); + IF( EQ_16( comp_flag_1, 1 ) ) + { + comp_flag_1 = 1; + } + ELSE + { + comp_flag_1 = 0; + } + Word16 comp_flag_2 = BASOP_Util_Cmp_Mant32Exp_sat( MIN16B_FLT_FX_IN_Q15, 16, ppPcm_in[i][j], ( 31 - q_pcm ) ); + IF( EQ_16( comp_flag_2, 1 ) ) + { + comp_flag_2 = 1; + } + ELSE + { + comp_flag_2 = 0; + } + IF( ( comp_flag_1 ) || ( comp_flag_2 ) ) + { + clippedIdx = j; + isClipped = TRUE; + } + } + } + + pState->gain_state[i].MaxAbsVal_del_fx = predMaxAbsVal; + pState->gain_state[i].q_MaxAbsVal_del_fx = q_predMaxAbsVal; + + isGainAdjusted = FALSE; + IF( !isClipped ) + { + // CHECK THIS PART AGAIN MaxAbsVal < FLT_MIN + Word16 flag = 0; + IF( LE_32( MaxAbsVal, 0 ) ) + { + flag = 1; + } + IF( ( EQ_16( pState->gain_state[i].lastExp, 0 ) ) || ( flag ) ) + { + pState->gain_state[i].gainExpVal = 0; + pState->gain_state[i].prevExp = pState->gain_state[i].lastExp; + isGainAdjusted = TRUE; + } + ELSE + { + Word32 smoothedMaxAbsVal, maxGain; + Word16 q_smoothedMaxAbsVal, q_maxGain; + Word32 temp1, temp2; + Word16 Comp_flag, q_temp, e_result = 0; + temp1 = Mpy_32_32( pState->smFact_fx, MaxAbsVal ); // q_MaxAbsVal + temp2 = Mpy_32_32( ( L_sub( ONE_IN_Q31, pState->smFact_fx ) ), pState->gain_state[i].lastMaxAbs_fx ); // q_lastMaxAbs_fx + + smoothedMaxAbsVal = BASOP_Util_Add_Mant32Exp( temp1, ( 31 - q_MaxAbsVal ), temp2, ( 31 - pState->gain_state[i].q_lastMaxAbs_fx ), &e_result ); + q_smoothedMaxAbsVal = 31 - e_result; + + pState->gain_state[i].lastMaxAbs_fx = smoothedMaxAbsVal; + pState->gain_state[i].q_lastMaxAbs_fx = q_smoothedMaxAbsVal; + + Comp_flag = BASOP_Util_Cmp_Mant32Exp_sat( smoothedMaxAbsVal, 31 - q_smoothedMaxAbsVal, MaxAbsVal, 31 - q_MaxAbsVal ); + IF( EQ_16( Comp_flag, 1 ) ) + { + temp1 = smoothedMaxAbsVal; + q_temp = q_smoothedMaxAbsVal; + } + ELSE + { + temp1 = MaxAbsVal; + q_temp = q_MaxAbsVal; + } + temp1 = Mpy_32_32( temp1, TWO_IN_Q29 ); + q_temp = q_temp + 29 - 31; + maxGain = Mpy_32_32( temp1, pState->gain_state[i].lastGain_fx ); + q_maxGain = q_temp + ( pState->gain_state[i].q_lastGain_fx ) - 31; + + temp2 = ONE_MINUS_M_DELTA_PROD_FLT_FC; // Q15 + Comp_flag = BASOP_Util_Cmp_Mant32Exp_sat( temp2, 16, maxGain, 31 - q_maxGain ); + IF( EQ_16( Comp_flag, 1 ) ) + { + pState->gain_state[i].gainExpVal = -1; + } + ELSE + { + pState->gain_state[i].gainExpVal = 0; + } + } + } + ELSE + { + pState->gain_state[i].lastMaxAbs_fx = MaxAbsVal; + pState->gain_state[i].q_lastMaxAbs_fx = q_MaxAbsVal; + } + + IF( !isGainAdjusted ) + { + Word32 actualMaxAbsVal = 0; + Word16 currMaxAttExp, q_actualMaxAbsVal; + + currMaxAttExp = min( ( add( pState->gain_state[i].lastExp, pState->agc_com.absEmin ) ), pState->agc_com.maxAttExp ); + extendedExpVal = FALSE; + + IF( isClipped ) + { + Word16 isCompensated = FALSE; + Word32 temp1, temp2; + actualMaxAbsVal = Mpy_32_32( pState->gain_state[i].lastMaxAbs_fx, pState->gain_state[i].lastGain_fx ); // QlastGain_fx + q_actualMaxAbsVal = pState->gain_state[i].q_lastMaxAbs_fx + ( pState->gain_state[i].q_lastGain_fx ) - 31; + idx = min( offset - 1, MaxAbsValIdx ); + + q_actualMaxAbsVal = add( q_actualMaxAbsVal, norm_l( actualMaxAbsVal ) ); + temp1 = L_shl( actualMaxAbsVal, norm_l( actualMaxAbsVal ) ); + temp1 = BASOP_Util_Log2( temp1 ); // Q25 + temp1 = L_add( temp1, L_shl( ( Q31 - q_actualMaxAbsVal ), 25 ) ); // Q25 + temp1 = L_negate( L_add( temp1, LOG2_MDFT_NORM_SCALING_FX ) ); // Q25 + temp2 = BASOP_Util_Log2( L_deposit_h( pState->agc_com.winFunc_fx[idx] ) ); // Q25 + Word16 temp_16, div_e; + IF( EQ_32( temp2, 0 ) ) + { + temp_16 = 0; + } + ELSE + { + temp_16 = BASOP_Util_Divide3232_Scale( temp1, temp2, &div_e ); + IF( LT_16( div_e, 0 ) ) + { + temp_16 = shr( temp_16, abs( div_e ) ); + div_e = 0; + } + temp_16 = ceil_fx( temp_16, 15 - div_e ); + } + pState->gain_state[i].gainExpVal = temp_16; + + WHILE( !isCompensated ) + { + Word32 tmpSignal; + Word16 q_tmpSignal; + isCompensated = TRUE; + Word16 tmp_1, q_tmp_2 = 31, e_div; + Word32 tmp_2 = ONE_IN_Q31; + tmp_1 = pState->gain_state[i].gainExpVal; + FOR( idx = clippedIdx; idx <= MaxAbsValIdx; idx++ ) + { + IF( GE_16( idx, offset ) ) + { + idx = MaxAbsValIdx; + IF( LT_16( tmp_1, 0 ) ) + { + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], ( negate( tmp_1 ) ) ); + IF( LT_32( tmp_2, 0 ) ) + { + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); + tmp_2 = L_negate( tmp_2 ); + } + ELSE + { + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); + } + q_tmp_2 = Q31 - e_div; + } + ELSE + { + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], tmp_1 ); + q_tmp_2 = Q31; + } + } + ELSE + { + IF( LT_16( tmp_1, 0 ) ) + { + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[idx], ( negate( tmp_1 ) ) ); + IF( LT_32( tmp_2, 0 ) ) + { + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); + tmp_2 = L_negate( tmp_2 ); + } + ELSE + { + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); + } + q_tmp_2 = Q31 - e_div; + } + ELSE + { + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[idx], tmp_1 ); + q_tmp_2 = Q31; + } + } + + tmpSignal = Mpy_32_32( ppPcm_out[i][idx], tmp_2 ); + q_tmpSignal = q_pcm + (q_tmp_2) -31; + + Word16 comp_flag_1 = BASOP_Util_Cmp_Mant32Exp_sat( tmpSignal, 31 - q_tmpSignal, ONE_MINUS_M_DELTA_PROD_FLT_FC, 16 ); + IF( EQ_16( comp_flag_1, 1 ) ) + { + comp_flag_1 = 1; + } + ELSE + { + comp_flag_1 = 0; + } + + Word16 comp_flag_2 = BASOP_Util_Cmp_Mant32Exp_sat( MIN16B_FLT_FX_IN_Q15, 16, tmpSignal, 31 - q_tmpSignal ); + IF( EQ_16( comp_flag_2, 1 ) ) + { + comp_flag_2 = 1; + } + ELSE + { + comp_flag_2 = 0; + } + IF( ( comp_flag_1 ) || ( comp_flag_2 ) ) + { + isCompensated = FALSE; + break; + } + } + IF( !isCompensated ) + { + pState->gain_state[i].gainExpVal = add( pState->gain_state[i].gainExpVal, 1 ); + } + + IF( GT_16( pState->gain_state[i].gainExpVal, currMaxAttExp ) ) + { + pState->gain_state[i].gainExpVal = min( pState->gain_state[i].gainExpVal, currMaxAttExp ); + BREAK; + } + } + } + + Word16 q_pcm_tmp = q_pcm; + FOR( idx = 0; idx < input_frame; idx++ ) + { + Word16 tmp_1, q_tmp_2, e_div; + Word32 tmp_2; + tmp_1 = pState->gain_state[i].gainExpVal; + + IF( GT_16( offset, idx ) ) + { + IF( LT_16( tmp_1, 0 ) ) + { + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[idx], ( negate( tmp_1 ) ) ); + IF( LT_32( tmp_2, 0 ) ) + { + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); + tmp_2 = L_negate( tmp_2 ); + } + ELSE + { + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); + } + q_tmp_2 = Q31 - e_div; + } + ELSE + { + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[idx], tmp_1 ); + q_tmp_2 = Q31; + } + } + ELSE + { + IF( LT_16( tmp_1, 0 ) ) + { + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], ( negate( tmp_1 ) ) ); + IF( LT_32( tmp_2, 0 ) ) + { + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); + tmp_2 = L_negate( tmp_2 ); + } + ELSE + { + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); + } + q_tmp_2 = Q31 - e_div; + } + ELSE + { + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], tmp_1 ); + q_tmp_2 = Q31; + } + } + // gain = tmp_2; + ppPcm_out[i][idx] = Mpy_32_32( ppPcm_out[i][idx], tmp_2 ); // Q remains same + q_pcm = q_pcm_tmp + (q_tmp_2) -31; + } + + + Word16 tmp_1, q_tmp_2, e_div; + Word32 tmp_2; + tmp_1 = pState->gain_state[i].gainExpVal; + IF( LT_16( tmp_1, 0 ) ) + { + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], ( negate( tmp_1 ) ) ); + IF( LT_32( tmp_2, 0 ) ) + { + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); + tmp_2 = L_negate( tmp_2 ); + } + ELSE + { + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); + } + q_tmp_2 = Q31 - e_div; + } + ELSE + { + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], tmp_1 ); + q_tmp_2 = Q31; + } + pState->gain_state[i].lastGain_fx = Mpy_32_32( pState->gain_state[i].lastGain_fx, tmp_2 ); + pState->gain_state[i].q_lastGain_fx = pState->gain_state[i].q_lastGain_fx + (q_tmp_2) -31; + + /*safety check starts*/ + IF( EQ_16( pState->gain_state[i].gainExpVal, ( pState->agc_com.maxAttExp + 1 ) ) ) + { + extendedExpVal = TRUE; + } + /*safety check ends*/ + + pState->gain_state[i].prevExp = pState->gain_state[i].lastExp; + + pState->gain_state[i].lastExp -= pState->gain_state[i].gainExpVal; + IF( extendedExpVal ) + { + pState->gain_state[i].gainExpVal = -1; + } + } + + pState->gain_data[i].absGainExp = add( pState->gain_state[i].prevExp, pState->agc_com.absEmin ); + + IF( extendedExpVal ) + { + IF( LE_16( pState->gain_state[i].gainExpVal, 0 ) ) + { + pState->gain_state[i].gainExpVal = add( pState->agc_com.maxAttExp, 1 ); + } + } + pState->gain_data[i].absGainExpCurr = pState->gain_data[i].absGainExp - pState->gain_state[i].gainExpVal; + + if ( ( pState->gain_data[i].absGainExpCurr > pState->agc_com.absEmin ) || ( pState->gain_data[i].absGainExpCurr < 0 ) ) + { + assert( 0 ); + } + + IF( EQ_16( pState->gain_data[i].absGainExpCurr, pState->agc_com.absEmin ) ) + { + per_ch_bit[i] = 0; + } + ELSE + { + per_ch_bit[i] = 1; + AGC_flag = 1; + } + q_ppPcm[i] = q_pcm; + } + + push_next_indice( hMetaData, AGC_flag, 1 ); + /* encode AGC parameters */ + IF( EQ_16( AGC_flag, 1 ) ) + { + IF( GT_16( n_channels, 1 ) ) + { + FOR( i = 0; i < n_channels; i++ ) + { + push_next_indice( hMetaData, per_ch_bit[i], 1 ); + } + } + assert( AGC_BITS_PER_CH == ( pState->agc_com.betaE + 1 ) ); + + FOR( i = 0; i < n_channels; i++ ) + { + IF( EQ_16( per_ch_bit[i], 1 ) ) + { + push_next_indice( hMetaData, (Word16) pState->gain_data[i].absGainExpCurr, (Word16) pState->agc_com.betaE ); + } + } + } + + return; +} +#endif \ No newline at end of file diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index 9f5370d1702f95e7e4646ad35d6936f4016a56c6..e6d54ba796d4c1c9e6852bb51bfe65526d6ea709 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -35,6 +35,9 @@ #include "ivas_prot.h" #ifdef IVAS_FLOAT_FIXED #include "ivas_prot_fx.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "options.h" #endif #include "ivas_rom_com.h" #include "ivas_stat_com.h" @@ -50,7 +53,19 @@ *--------------------------------------------------------------------*/ 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[] ); +#ifdef IVAS_FLOAT_FIXED +static Word16 Q_factor_L_abs( float x ); +#endif +#ifdef IVAS_FLOAT_FIXED +Word16 Q_factor_L_abs( float x ) +{ + Word16 Q = 31; + if ( x >= 1 || x <= -1 ) + Q = norm_l( L_abs( (Word32) x ) ); + return Q; +} +#endif /*------------------------------------------------------------------------- * ivas_spar_enc_open() @@ -153,15 +168,26 @@ ivas_error ivas_spar_enc_open( hSpar->hMdEnc->table_idx = -1; /* AGC handle */ - hSpar->AGC_Enable = ivas_agc_enc_get_flag( nchan_transport ); +#ifdef IVAS_FLOAT_FIXED + hSpar->AGC_Enable = ivas_agc_enc_get_flag_fx( nchan_transport ); +#else + hSpar->AGC_Enable = ivas_agc_enc_get_flag(nchan_transport); +#endif hSpar->hAgcEnc = NULL; if ( hSpar->AGC_Enable ) { +#ifdef IVAS_FLOAT_FIXED + if ((error = ivas_spar_agc_enc_open_fx(&hSpar->hAgcEnc, input_Fs, nchan_inp)) != IVAS_ERR_OK) + { + return error; + } +#else if ( ( error = ivas_spar_agc_enc_open( &hSpar->hAgcEnc, input_Fs, nchan_inp ) ) != IVAS_ERR_OK ) { return error; } +#endif } /* PCA handle */ @@ -474,7 +500,11 @@ void ivas_spar_enc_close( ivas_FB_mixer_close( &( *hSpar )->hFbMixer, input_Fs, spar_reconfig_flag ); /* AGC */ +#ifdef IVAS_FLOAT_FIXED + ivas_spar_agc_enc_close_fx( &( *hSpar )->hAgcEnc ); +#else ivas_spar_agc_enc_close( &( *hSpar )->hAgcEnc ); +#endif /* PCA */ if ( ( *hSpar )->hPCA != NULL ) @@ -751,6 +781,13 @@ static ivas_error ivas_spar_enc_process( { float pcm_tmp[DIRAC_MAX_ANA_CHANS][L_FRAME48k * 2]; float *p_pcm_tmp[DIRAC_MAX_ANA_CHANS]; +#ifdef IVAS_FLOAT_FIXED + Word32 pcm_tmp_fx[DIRAC_MAX_ANA_CHANS][L_FRAME48k * 2]; + Word32 *p_pcm_tmp_fx[DIRAC_MAX_ANA_CHANS]; + Word16 q_pcm_tmp_fx[DIRAC_MAX_ANA_CHANS][L_FRAME48k * 2]; + Word16 *q_p_pcm_tmp_fx[DIRAC_MAX_ANA_CHANS]; + Word16 q_pcm_fx[DIRAC_MAX_ANA_CHANS]; +#endif int16_t i, j, input_frame, dtx_vad; int16_t transient_det[2]; int16_t hodirac_flag; @@ -1004,7 +1041,29 @@ static ivas_error ivas_spar_enc_process( { if ( hSpar->AGC_Enable != 0 ) { +#ifdef IVAS_FLOAT_FIXED + FOR( i = 0; i < hSpar->hFbMixer->fb_cfg->num_out_chans; i++ ) + { + p_pcm_tmp_fx[i] = &pcm_tmp_fx[i][0]; + q_pcm_fx[i] = Q_factor_arrL(&p_pcm_tmp[i][0], input_frame); + FOR( j = 0; j < input_frame; j++ ) + { + p_pcm_tmp_fx[i][j] = float_to_fix( p_pcm_tmp[i][j], q_pcm_fx[i]); + } + } + + ivas_agc_enc_process_fx(hSpar->hAgcEnc, hMetaData, p_pcm_tmp_fx, p_pcm_tmp_fx, hSpar->hFbMixer->fb_cfg->num_out_chans, hEncoderConfig, q_pcm_fx); + + FOR(i = 0; i < hSpar->hFbMixer->fb_cfg->num_out_chans; i++) + { + FOR( j = 0; j < input_frame; j++ ) + { + p_pcm_tmp[i][j] = fix_to_float( p_pcm_tmp_fx[i][j], q_pcm_fx[i]); + } + } +#else ivas_agc_enc_process( hSpar->hAgcEnc, hMetaData, p_pcm_tmp, p_pcm_tmp, hSpar->hFbMixer->fb_cfg->num_out_chans, hEncoderConfig ); +#endif } } diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 96dbacae10fbbd986db84947befebf53e66fe38c..789c5a27f1d31e0ea63d9965376bbac93e59844c 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -823,12 +823,24 @@ typedef struct ivas_agc_enc_chan_state_t int16_t gainExpVal; float MaxAbsVal_del; int16_t MaxAbsValIdx_del; +#ifdef IVAS_FLOAT_FIXED + Word32 lastGain_fx; + Word32 lastMaxAbs_fx; + Word32 MaxAbsVal_del_fx; + Word16 q_lastGain_fx; + Word16 q_lastMaxAbs_fx; + Word16 q_MaxAbsVal_del_fx; +#endif } ivas_agc_enc_chan_state_t; typedef struct ivas_agc_enc_state_t { ivas_agc_com_state_t agc_com; +#ifdef IVAS_FLOAT_FIXED + Word32 minDelta_fx; + Word32 smFact_fx; +#endif float minDelta; float smFact; ivas_agc_enc_chan_state_t *gain_state; diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 0854e6ab47c976b159662eb10e3d66ab761c2005..c0ce7af10b086d8f8a3fc6270f5a1286efa347c4 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -255,24 +255,40 @@ ivas_error ivas_dirac_dec_init_binaural_data( #ifdef IVAS_FLOAT_FIXED Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, nBins ); - FOR(Word16 i = 0; i < nBins; i++) { - frequency_axis[i] = (float)frequency_axis_fx[i]; + FOR( Word16 i = 0; i < nBins; i++ ) + { + frequency_axis[i] = (float) frequency_axis_fx[i]; + } + + IF( ( error = ivas_dirac_dec_decorr_open_fx( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), + &( hDiracDecBin->h_freq_domain_decorr_ap_state ), + nBins, + BINAURAL_CHANNELS, + BINAURAL_CHANNELS, + DIRAC_SYNTHESIS_PSD_LS, + frequency_axis_fx, + BINAURAL_CHANNELS, + output_Fs ) ) != IVAS_ERR_OK ) + { + return error; } #else ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, nBins ); -#endif - if ( ( error = ivas_dirac_dec_decorr_open( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), - &( hDiracDecBin->h_freq_domain_decorr_ap_state ), - nBins, - BINAURAL_CHANNELS, - BINAURAL_CHANNELS, - DIRAC_SYNTHESIS_PSD_LS, - frequency_axis, - BINAURAL_CHANNELS, - output_Fs ) ) != IVAS_ERR_OK ) + + if ((error = ivas_dirac_dec_decorr_open(&(hDiracDecBin->h_freq_domain_decorr_ap_params), + &(hDiracDecBin->h_freq_domain_decorr_ap_state), + nBins, + BINAURAL_CHANNELS, + BINAURAL_CHANNELS, + DIRAC_SYNTHESIS_PSD_LS, + frequency_axis, + BINAURAL_CHANNELS, + output_Fs)) != IVAS_ERR_OK) { return error; } +#endif + } #ifdef IVAS_FLOAT_FIXED diff --git a/lib_rend/ivas_dirac_decorr_dec.c b/lib_rend/ivas_dirac_decorr_dec.c index 3df8407b5949f9627b26f8a7028603ee0559d1a9..d070205aa4ed5dc5c7f5e7d2539b1b36d617344a 100644 --- a/lib_rend/ivas_dirac_decorr_dec.c +++ b/lib_rend/ivas_dirac_decorr_dec.c @@ -41,7 +41,8 @@ #include "ivas_cnst.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" - +#include "prot_fx1.h" +#include "prot_fx2.h" /*------------------------------------------------------------------------- * Local constants @@ -59,20 +60,17 @@ *------------------------------------------------------------------------*/ static void get_lattice_coeffs( const int16_t band_index, const int16_t channel_index, float *lattice_coeffs ); - +static void lattice2allpass( const int16_t filter_length, const float *lattice_coeffs, float *filter_coeffs_num_real, float *filter_coeffs_den_real ); #ifdef IVAS_FLOAT_FIXED static void get_lattice_coeffs_fx( const Word16 band_index, const Word16 channel_index, Word16 *lattice_coeffs ); +static void lattice2allpass_fx( const int16_t filter_length, const Word16 *lattice_coeffs_fx, Word16 *filter_coeffs_num_real_fx, Word16 *filter_coeffs_den_real_fx ); #endif -static void lattice2allpass( const int16_t filter_length, const float *lattice_coeffs, float *filter_coeffs_num_real, float *filter_coeffs_den_real ); - - /*------------------------------------------------------------------------- * ivas_dirac_dec_decorr_open() * * Allocate and initialize TD decorrelator decoder handle *------------------------------------------------------------------------*/ - ivas_error ivas_dirac_dec_decorr_open( DIRAC_DECORR_PARAMS **ph_freq_domain_decorr_ap_params, DIRAC_DECORR_STATE **ph_freq_domain_decorr_ap_state, @@ -97,17 +95,295 @@ ivas_error ivas_dirac_dec_decorr_open( DIRAC_DECORR_PARAMS *freq_domain_decorr_ap_params = NULL; DIRAC_DECORR_STATE *freq_domain_decorr_ap_state = NULL; + /*-----------------------------------------------------------------* + * prepare library opening + *-----------------------------------------------------------------*/ + + /* allocate structs */ + if ((freq_domain_decorr_ap_params = (DIRAC_DECORR_PARAMS *)malloc(sizeof(DIRAC_DECORR_PARAMS))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n")); + } + + if ((freq_domain_decorr_ap_state = (DIRAC_DECORR_STATE *)malloc(sizeof(DIRAC_DECORR_STATE))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n")); + } + + /*-----------------------------------------------------------------* + * check input parameters + *-----------------------------------------------------------------*/ + + assert((num_freq_bands > 0) && "Error: Number of frequency bands <= 0!"); + + + if (synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD) + { + num_outputs_diff -= nchan_transport; + } + + assert((num_outputs_diff >= 0) && (num_outputs_diff <= DIRAC_MAX_NUM_DECORR_FILTERS) && "Error: Number of channels <= 0 or > DIRAC_MAX_NUM_DECORR_FILTERS"); + + /*-----------------------------------------------------------------* + * set default parameters + *-----------------------------------------------------------------*/ + + if (synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD) + { + /*Decorrelation in SHD*/ + freq_domain_decorr_ap_params->add_back_onsets_on = 0; + if (nchan_transport > 2) + { + freq_domain_decorr_ap_params->max_frequency = 2000; + } + else + { + freq_domain_decorr_ap_params->max_frequency = (min(num_freq_bands, DIRAC_MAX_DECORR_CLDFB_BANDS_AMBI) * 24000) / CLDFB_NO_CHANNELS_MAX; + } + } + else if (synthesisConf == DIRAC_SYNTHESIS_COV_MC_LS) + { + /*Decorrelation in LS channels for MC*/ + freq_domain_decorr_ap_params->add_back_onsets_on = 1; + freq_domain_decorr_ap_params->max_frequency = (PARAM_MC_MAX_DECORR_CLDFB_BANDS * 24000) / CLDFB_NO_CHANNELS_MAX; + } + else + { + /*Decorrelation in LS channels*/ + freq_domain_decorr_ap_params->add_back_onsets_on = 1; + freq_domain_decorr_ap_params->max_frequency = (DIRAC_MAX_DECORR_CLDFB_BANDS * 24000) / CLDFB_NO_CHANNELS_MAX; + } + + freq_domain_decorr_ap_params->use_ducker = 1; + + assert((freq_domain_decorr_ap_params->max_frequency >= 0) && (freq_domain_decorr_ap_params->max_frequency <= output_Fs / 2) && "Error: max_frequency invalid!"); + + /* compute maximum band for decorrelation */ + assert(frequency_axis != NULL); + for (k = num_freq_bands - 1; k > 0; --k) + { + freq_domain_decorr_ap_params->max_band_decorr = k + 1; /* outside "if" to avoid uninitialized variable */ + + if (frequency_axis[k] < freq_domain_decorr_ap_params->max_frequency) + { + break; + } + } + + /*-----------------------------------------------------------------* + * open sub-modules + *-----------------------------------------------------------------*/ + + /* open onset detection module */ +#ifdef IVAS_FLOAT_FIXED + IF (synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD) + { + /*Onset detector up to Nyquist and not only up to max_band_decorr*/ + IF ((error = ivas_dirac_dec_onset_detection_open_fx(num_protos_diff, num_freq_bands, num_freq_bands, &freq_domain_decorr_ap_params->h_onset_detection_power_params, &freq_domain_decorr_ap_state->h_onset_detection_power_state)) != IVAS_ERR_OK) + { + return error; + } + } + ELSE + { + if ((error = ivas_dirac_dec_onset_detection_open_fx(num_protos_diff, num_freq_bands, freq_domain_decorr_ap_params->max_band_decorr, &freq_domain_decorr_ap_params->h_onset_detection_power_params, &freq_domain_decorr_ap_state->h_onset_detection_power_state)) != IVAS_ERR_OK) + { + return error; + } + } +#else + if (synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD) + { + /*Onset detector up to Nyquist and not only up to max_band_decorr*/ + if ((error = ivas_dirac_dec_onset_detection_open(num_protos_diff, num_freq_bands, num_freq_bands, &freq_domain_decorr_ap_params->h_onset_detection_power_params, &freq_domain_decorr_ap_state->h_onset_detection_power_state)) != IVAS_ERR_OK) + { + return error; + } + } + else + { + if ((error = ivas_dirac_dec_onset_detection_open(num_protos_diff, num_freq_bands, freq_domain_decorr_ap_params->max_band_decorr, &freq_domain_decorr_ap_params->h_onset_detection_power_params, &freq_domain_decorr_ap_state->h_onset_detection_power_state)) != IVAS_ERR_OK) + { + return error; + } + } +#endif + /*-----------------------------------------------------------------* + * prepare processing parameters + *-----------------------------------------------------------------*/ + + /* calculate decorrelation split bands */ + split_freq_ptr = &split_frequencies_bands[0]; + split_freq_ptr[0] = 0; + for (k = 1; k < DIRAC_DECORR_NUM_SPLIT_BANDS; k++) + { + split_freq_ptr[k] = (int16_t)((float)CLDFB_NO_CHANNELS_MAX * ap_split_frequencies[k] + 0.5f) - 1; + } + split_band_index_start = 0; + + split_frequencies_bands[k] = 0; + freq_domain_decorr_ap_params->num_split_frequency_bands = 0; + for (k = 1; k < DIRAC_DECORR_NUM_SPLIT_BANDS + 1; k++) + { + freq_domain_decorr_ap_params->num_split_frequency_bands++; + if (split_frequencies_bands[k] >= freq_domain_decorr_ap_params->max_band_decorr) + { + split_frequencies_bands[k] = freq_domain_decorr_ap_params->max_band_decorr; + break; + } + } + + if ((freq_domain_decorr_ap_params->split_frequency_bands = (int16_t *)malloc(sizeof(int16_t) * (freq_domain_decorr_ap_params->num_split_frequency_bands + 1))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n")); + } + mvs2s(&split_frequencies_bands[0], freq_domain_decorr_ap_params->split_frequency_bands, freq_domain_decorr_ap_params->num_split_frequency_bands + 1); + + /* calc buffer size and allocate arrays */ + freq_domain_decorr_ap_state->decorr_buffer = NULL; + freq_domain_decorr_ap_params->filter_coeff_num_real = NULL; + freq_domain_decorr_ap_params->filter_coeff_den_real = NULL; + freq_domain_decorr_ap_params->phase_coeff_real = NULL; + freq_domain_decorr_ap_params->phase_coeff_imag = NULL; + freq_domain_decorr_ap_state->direct_energy_smooth = NULL; + freq_domain_decorr_ap_state->reverb_energy_smooth = NULL; + freq_domain_decorr_ap_params->pre_delay = NULL; + freq_domain_decorr_ap_params->filter_length = NULL; + + if (num_outputs_diff > 0) + { + buffer_size_decorr = (ap_pre_delay[split_band_index_start] + ap_filter_length[split_band_index_start]); + if ((freq_domain_decorr_ap_state->decorr_buffer = (float *)malloc(sizeof(float) * 2 * buffer_size_decorr * num_outputs_diff * freq_domain_decorr_ap_params->max_band_decorr)) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n")); + } + set_f(freq_domain_decorr_ap_state->decorr_buffer, 0.0f, 2 * buffer_size_decorr * num_outputs_diff * freq_domain_decorr_ap_params->max_band_decorr); + + if ((freq_domain_decorr_ap_params->filter_coeff_num_real = (float *)malloc(sizeof(float) * (ap_filter_length[split_band_index_start] + 1) * freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff)) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n")); + } + + if ((freq_domain_decorr_ap_params->filter_coeff_den_real = (float *)malloc(sizeof(float) * (ap_filter_length[split_band_index_start] + 1) * freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff)) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n")); + } + + if ((freq_domain_decorr_ap_params->phase_coeff_real = (float *)malloc(sizeof(float) * freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff)) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n")); + } + + if ((freq_domain_decorr_ap_params->phase_coeff_imag = (float *)malloc(sizeof(float) * freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff)) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n")); + } + + if ((freq_domain_decorr_ap_state->direct_energy_smooth = (float *)malloc(sizeof(float) * freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff)) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n")); + } + + if ((freq_domain_decorr_ap_state->reverb_energy_smooth = (float *)malloc(sizeof(float) * freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff)) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n")); + } + + if ((freq_domain_decorr_ap_params->pre_delay = (int16_t *)malloc(sizeof(int16_t) * freq_domain_decorr_ap_params->num_split_frequency_bands)) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n")); + } + if ((freq_domain_decorr_ap_params->filter_length = (int16_t *)malloc(sizeof(int16_t) * freq_domain_decorr_ap_params->num_split_frequency_bands)) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n")); + } + + set_f(freq_domain_decorr_ap_state->direct_energy_smooth, 0.0f, freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff); + set_f(freq_domain_decorr_ap_state->reverb_energy_smooth, 0.0f, freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff); + + /* compute filter coefficients */ + for (k = 0; k < freq_domain_decorr_ap_params->num_split_frequency_bands; k++) + { + k_in = freq_domain_decorr_ap_params->split_frequency_bands[k]; + k_out = freq_domain_decorr_ap_params->split_frequency_bands[k + 1]; + num_bands = k_out - k_in; + band_table_idx = k + split_band_index_start; + freq_domain_decorr_ap_params->filter_length[k] = ap_filter_length[band_table_idx] + 1; + freq_domain_decorr_ap_params->pre_delay[k] = ap_pre_delay[band_table_idx]; + + for (l = 0; l < num_outputs_diff; l++) + { + for (m = 0; m < num_bands; m++) + { + n = k_in + m; + cur_lattice_delta_phi = ap_lattice_delta_phi[l * DIRAC_MAX_DECORR_FILTER_LEN + ap_filter_length[k] - 1] * n; + static int count = 0; + count++; + freq_domain_decorr_ap_params->phase_coeff_real[l * freq_domain_decorr_ap_params->max_band_decorr + n] = cosf(cur_lattice_delta_phi); + freq_domain_decorr_ap_params->phase_coeff_imag[l * freq_domain_decorr_ap_params->max_band_decorr + n] = -sinf(cur_lattice_delta_phi); + + /* calculate phase offset */ +#ifdef IVAS_FLOAT_FIXED + Word16 lattice_coeffs_fx[2 * DIRAC_MAX_DECORR_FILTER_LEN]; + get_lattice_coeffs_fx(band_table_idx, l, lattice_coeffs_fx); + FOR(Word16 i = 0; i < ap_filter_length[band_table_idx]; i++) { + lattice_coeffs[i] = (float)lattice_coeffs_fx[i] / (1 << 15); + } +#else + get_lattice_coeffs(band_table_idx, l, lattice_coeffs); +#endif + + + /* calcualte transfer function coefficients from the lattice coefficients */ + lattice2allpass(freq_domain_decorr_ap_params->filter_length[k], lattice_coeffs, &freq_domain_decorr_ap_params->filter_coeff_num_real[(k_in + m) * (freq_domain_decorr_ap_params->filter_length[0] * num_outputs_diff) + l * freq_domain_decorr_ap_params->filter_length[0]], &freq_domain_decorr_ap_params->filter_coeff_den_real[(k_in + m) * (freq_domain_decorr_ap_params->filter_length[0] * num_outputs_diff) + l * freq_domain_decorr_ap_params->filter_length[0]]); + } + } + } + } + + *ph_freq_domain_decorr_ap_params = freq_domain_decorr_ap_params; + *ph_freq_domain_decorr_ap_state = freq_domain_decorr_ap_state; + + return IVAS_ERR_OK; +} + +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_dirac_dec_decorr_open_fx( + DIRAC_DECORR_PARAMS **ph_freq_domain_decorr_ap_params, + DIRAC_DECORR_STATE **ph_freq_domain_decorr_ap_state, + const Word16 num_freq_bands, + Word16 num_outputs_diff, + const Word16 num_protos_diff, + const DIRAC_SYNTHESIS_CONFIG synthesisConf, + Word16 *frequency_axis, + const Word16 nchan_transport, /* i : number of transport channels*/ + const Word32 output_Fs /* i : output sampling rate */ +) +{ + int16_t k, l, m, n; + int16_t split_band_index_start; + int16_t k_in, k_out, num_bands, band_table_idx, buffer_size_decorr; + int16_t split_frequencies_bands[DIRAC_DECORR_NUM_SPLIT_BANDS + 1] = { 0, 0, 0, 23768 }; + int16_t *split_freq_ptr; + Word16 cur_lattice_delta_phi_fx, lattice_coeffs_fx[2 * DIRAC_MAX_DECORR_FILTER_LEN]; + + ivas_error error; + + /* pointers to structs for allocation */ + DIRAC_DECORR_PARAMS *freq_domain_decorr_ap_params = NULL; + DIRAC_DECORR_STATE *freq_domain_decorr_ap_state = NULL; + /*-----------------------------------------------------------------* * prepare library opening *-----------------------------------------------------------------*/ /* allocate structs */ - if ( ( freq_domain_decorr_ap_params = (DIRAC_DECORR_PARAMS *) malloc( sizeof( DIRAC_DECORR_PARAMS ) ) ) == NULL ) + IF( ( freq_domain_decorr_ap_params = (DIRAC_DECORR_PARAMS *) malloc( sizeof( DIRAC_DECORR_PARAMS ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); } - if ( ( freq_domain_decorr_ap_state = (DIRAC_DECORR_STATE *) malloc( sizeof( DIRAC_DECORR_STATE ) ) ) == NULL ) + IF( ( freq_domain_decorr_ap_state = (DIRAC_DECORR_STATE *) malloc( sizeof( DIRAC_DECORR_STATE ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); } @@ -119,9 +395,9 @@ ivas_error ivas_dirac_dec_decorr_open( assert( ( num_freq_bands > 0 ) && "Error: Number of frequency bands <= 0!" ); - if ( synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + IF( EQ_16( synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { - num_outputs_diff -= nchan_transport; + num_outputs_diff = sub( num_outputs_diff, nchan_transport ); } assert( ( num_outputs_diff >= 0 ) && ( num_outputs_diff <= DIRAC_MAX_NUM_DECORR_FILTERS ) && "Error: Number of channels <= 0 or > DIRAC_MAX_NUM_DECORR_FILTERS" ); @@ -130,26 +406,26 @@ ivas_error ivas_dirac_dec_decorr_open( * set default parameters *-----------------------------------------------------------------*/ - if ( synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + IF( EQ_16( synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { /*Decorrelation in SHD*/ freq_domain_decorr_ap_params->add_back_onsets_on = 0; - if ( nchan_transport > 2 ) + IF( GT_16( nchan_transport, 2 ) ) { freq_domain_decorr_ap_params->max_frequency = 2000; } - else + ELSE { freq_domain_decorr_ap_params->max_frequency = ( min( num_freq_bands, DIRAC_MAX_DECORR_CLDFB_BANDS_AMBI ) * 24000 ) / CLDFB_NO_CHANNELS_MAX; } } - else if ( synthesisConf == DIRAC_SYNTHESIS_COV_MC_LS ) + ELSE IF( EQ_16( synthesisConf, DIRAC_SYNTHESIS_COV_MC_LS ) ) { /*Decorrelation in LS channels for MC*/ freq_domain_decorr_ap_params->add_back_onsets_on = 1; freq_domain_decorr_ap_params->max_frequency = ( PARAM_MC_MAX_DECORR_CLDFB_BANDS * 24000 ) / CLDFB_NO_CHANNELS_MAX; } - else + ELSE { /*Decorrelation in LS channels*/ freq_domain_decorr_ap_params->add_back_onsets_on = 1; @@ -162,13 +438,13 @@ ivas_error ivas_dirac_dec_decorr_open( /* compute maximum band for decorrelation */ assert( frequency_axis != NULL ); - for ( k = num_freq_bands - 1; k > 0; --k ) + FOR( k = num_freq_bands - 1; k > 0; --k ) { - freq_domain_decorr_ap_params->max_band_decorr = k + 1; /* outside "if" to avoid uninitialized variable */ + freq_domain_decorr_ap_params->max_band_decorr = add( k, 1 ); /* outside "if" to avoid uninitialized variable */ - if ( frequency_axis[k] < freq_domain_decorr_ap_params->max_frequency ) + IF( frequency_axis[k] < freq_domain_decorr_ap_params->max_frequency ) { - break; + BREAK; } } @@ -177,17 +453,17 @@ ivas_error ivas_dirac_dec_decorr_open( *-----------------------------------------------------------------*/ /* open onset detection module */ - if ( synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + IF( synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { /*Onset detector up to Nyquist and not only up to max_band_decorr*/ - if ( ( error = ivas_dirac_dec_onset_detection_open( num_protos_diff, num_freq_bands, num_freq_bands, &freq_domain_decorr_ap_params->h_onset_detection_power_params, &freq_domain_decorr_ap_state->h_onset_detection_power_state ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_dirac_dec_onset_detection_open_fx( num_protos_diff, num_freq_bands, num_freq_bands, &freq_domain_decorr_ap_params->h_onset_detection_power_params, &freq_domain_decorr_ap_state->h_onset_detection_power_state ) ) != IVAS_ERR_OK ) { return error; } } - else + ELSE { - if ( ( error = ivas_dirac_dec_onset_detection_open( num_protos_diff, num_freq_bands, freq_domain_decorr_ap_params->max_band_decorr, &freq_domain_decorr_ap_params->h_onset_detection_power_params, &freq_domain_decorr_ap_state->h_onset_detection_power_state ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_dirac_dec_onset_detection_open_fx( num_protos_diff, num_freq_bands, freq_domain_decorr_ap_params->max_band_decorr, &freq_domain_decorr_ap_params->h_onset_detection_power_params, &freq_domain_decorr_ap_state->h_onset_detection_power_state ) ) != IVAS_ERR_OK ) { return error; } @@ -200,31 +476,43 @@ ivas_error ivas_dirac_dec_decorr_open( /* calculate decorrelation split bands */ split_freq_ptr = &split_frequencies_bands[0]; split_freq_ptr[0] = 0; - for ( k = 1; k < DIRAC_DECORR_NUM_SPLIT_BANDS; k++ ) + + Word16 temp = 0; + FOR( k = 1; k < DIRAC_DECORR_NUM_SPLIT_BANDS; k++ ) { - split_freq_ptr[k] = (int16_t) ( (float) CLDFB_NO_CHANNELS_MAX * ap_split_frequencies[k] + 0.5f ) - 1; + temp = mult( CLDFB_NO_CHANNELS_MAX_FX, ap_split_frequencies_fx[k] ); // Q8 + temp = add( temp, (Word16) floatToFixed( 0.5, Q8 ) ); + split_freq_ptr[k] = sub( temp, ONE_IN_Q8 ); } split_band_index_start = 0; split_frequencies_bands[k] = 0; freq_domain_decorr_ap_params->num_split_frequency_bands = 0; - for ( k = 1; k < DIRAC_DECORR_NUM_SPLIT_BANDS + 1; k++ ) + FOR( k = 1; k < DIRAC_DECORR_NUM_SPLIT_BANDS + 1; k++ ) { freq_domain_decorr_ap_params->num_split_frequency_bands++; - if ( split_frequencies_bands[k] >= freq_domain_decorr_ap_params->max_band_decorr ) + IF( GE_16( split_frequencies_bands[k], shl( freq_domain_decorr_ap_params->max_band_decorr, Q8 ) ) ) { - split_frequencies_bands[k] = freq_domain_decorr_ap_params->max_band_decorr; + split_frequencies_bands[k] = shl( freq_domain_decorr_ap_params->max_band_decorr, Q8 ); break; } } - if ( ( freq_domain_decorr_ap_params->split_frequency_bands = (int16_t *) malloc( sizeof( int16_t ) * ( freq_domain_decorr_ap_params->num_split_frequency_bands + 1 ) ) ) == NULL ) + /*make it Q0*/ + FOR( k = 1; k < DIRAC_DECORR_NUM_SPLIT_BANDS; k++ ) + { + split_frequencies_bands[k] = shr( split_frequencies_bands[k], Q8 ); + } + + IF( ( freq_domain_decorr_ap_params->split_frequency_bands = (Word16 *) malloc( sizeof( Word16 ) * ( add( freq_domain_decorr_ap_params->num_split_frequency_bands, 1 ) ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); } - mvs2s( &split_frequencies_bands[0], freq_domain_decorr_ap_params->split_frequency_bands, freq_domain_decorr_ap_params->num_split_frequency_bands + 1 ); + Copy( &split_frequencies_bands[0], freq_domain_decorr_ap_params->split_frequency_bands, add( freq_domain_decorr_ap_params->num_split_frequency_bands, 1 ) ); /* calc buffer size and allocate arrays */ +#if 1 + /*float code to be cleaned up*/ freq_domain_decorr_ap_state->decorr_buffer = NULL; freq_domain_decorr_ap_params->filter_coeff_num_real = NULL; freq_domain_decorr_ap_params->filter_coeff_den_real = NULL; @@ -234,10 +522,23 @@ ivas_error ivas_dirac_dec_decorr_open( freq_domain_decorr_ap_state->reverb_energy_smooth = NULL; freq_domain_decorr_ap_params->pre_delay = NULL; freq_domain_decorr_ap_params->filter_length = NULL; +#endif +#ifdef IVAS_FLOAT_FIXED + freq_domain_decorr_ap_state->decorr_buffer_fx = NULL; + freq_domain_decorr_ap_params->filter_coeff_num_real_fx = NULL; + freq_domain_decorr_ap_params->filter_coeff_den_real_fx = NULL; + freq_domain_decorr_ap_params->filter_coeff_num_real_fx = NULL; + freq_domain_decorr_ap_params->filter_coeff_den_real_fx = NULL; + freq_domain_decorr_ap_params->phase_coeff_real_fx = NULL; + freq_domain_decorr_ap_params->phase_coeff_imag_fx = NULL; + freq_domain_decorr_ap_state->direct_energy_smooth_fx = NULL; + freq_domain_decorr_ap_state->reverb_energy_smooth_fx = NULL; +#endif - if ( num_outputs_diff > 0 ) + IF ( num_outputs_diff > 0 ) { buffer_size_decorr = ( ap_pre_delay[split_band_index_start] + ap_filter_length[split_band_index_start] ); +#if 1 if ( ( freq_domain_decorr_ap_state->decorr_buffer = (float *) malloc( sizeof( float ) * 2 * buffer_size_decorr * num_outputs_diff * freq_domain_decorr_ap_params->max_band_decorr ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); @@ -274,51 +575,108 @@ ivas_error ivas_dirac_dec_decorr_open( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); } - if ( ( freq_domain_decorr_ap_params->pre_delay = (int16_t *) malloc( sizeof( int16_t ) * freq_domain_decorr_ap_params->num_split_frequency_bands ) ) == NULL ) + if ( ( freq_domain_decorr_ap_params->pre_delay = (Word16 *) malloc( sizeof( Word16 ) * freq_domain_decorr_ap_params->num_split_frequency_bands ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); } - if ( ( freq_domain_decorr_ap_params->filter_length = (int16_t *) malloc( sizeof( int16_t ) * freq_domain_decorr_ap_params->num_split_frequency_bands ) ) == NULL ) + if ( ( freq_domain_decorr_ap_params->filter_length = (Word16 *) malloc( sizeof( Word16 ) * freq_domain_decorr_ap_params->num_split_frequency_bands ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); } - set_f( freq_domain_decorr_ap_state->direct_energy_smooth, 0.0f, freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff ); set_f( freq_domain_decorr_ap_state->reverb_energy_smooth, 0.0f, freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff ); +#endif + IF( ( freq_domain_decorr_ap_state->decorr_buffer_fx = (Word16 *) malloc( sizeof( Word16 ) * 2 * buffer_size_decorr * num_outputs_diff * freq_domain_decorr_ap_params->max_band_decorr ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); + } + set16_fx( freq_domain_decorr_ap_state->decorr_buffer_fx, 0, 2 * buffer_size_decorr * num_outputs_diff * freq_domain_decorr_ap_params->max_band_decorr ); + + IF( ( freq_domain_decorr_ap_params->filter_coeff_num_real_fx = (Word16 *) malloc( sizeof( Word16 ) * ( ap_filter_length[split_band_index_start] + 1 ) * freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); + } + + IF( ( freq_domain_decorr_ap_params->filter_coeff_den_real_fx = (Word16 *) malloc( sizeof( Word16 ) * ( ap_filter_length[split_band_index_start] + 1 ) * freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); + } + + IF( ( freq_domain_decorr_ap_params->phase_coeff_real_fx = (Word16 *) malloc( sizeof( Word16 ) * freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); + } + + IF( ( freq_domain_decorr_ap_params->phase_coeff_imag_fx = (Word16 *) malloc( sizeof( Word16 ) * freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); + } + + IF( ( freq_domain_decorr_ap_state->direct_energy_smooth_fx = (Word16 *) malloc( sizeof( Word16 ) * freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); + } + + IF( ( freq_domain_decorr_ap_state->reverb_energy_smooth_fx = (Word16 *) malloc( sizeof( Word16 ) * freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); + } + set16_fx( freq_domain_decorr_ap_state->direct_energy_smooth_fx, 0, freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff ); + set16_fx( freq_domain_decorr_ap_state->reverb_energy_smooth_fx, 0, freq_domain_decorr_ap_params->max_band_decorr * num_outputs_diff ); /* compute filter coefficients */ - for ( k = 0; k < freq_domain_decorr_ap_params->num_split_frequency_bands; k++ ) + FOR ( k = 0; k < freq_domain_decorr_ap_params->num_split_frequency_bands; k++ ) { k_in = freq_domain_decorr_ap_params->split_frequency_bands[k]; k_out = freq_domain_decorr_ap_params->split_frequency_bands[k + 1]; - num_bands = k_out - k_in; - band_table_idx = k + split_band_index_start; - freq_domain_decorr_ap_params->filter_length[k] = ap_filter_length[band_table_idx] + 1; + num_bands = sub( k_out, k_in ); + band_table_idx = add( k, split_band_index_start ); + freq_domain_decorr_ap_params->filter_length[k] = add( ap_filter_length[band_table_idx], 1 ); freq_domain_decorr_ap_params->pre_delay[k] = ap_pre_delay[band_table_idx]; - for ( l = 0; l < num_outputs_diff; l++ ) + FOR ( l = 0; l < num_outputs_diff; l++ ) { - for ( m = 0; m < num_bands; m++ ) + FOR ( m = 0; m < num_bands; m++ ) { - n = k_in + m; - cur_lattice_delta_phi = ap_lattice_delta_phi[l * DIRAC_MAX_DECORR_FILTER_LEN + ap_filter_length[k] - 1] * n; - freq_domain_decorr_ap_params->phase_coeff_real[l * freq_domain_decorr_ap_params->max_band_decorr + n] = cosf( cur_lattice_delta_phi ); - freq_domain_decorr_ap_params->phase_coeff_imag[l * freq_domain_decorr_ap_params->max_band_decorr + n] = -sinf( cur_lattice_delta_phi ); + n = add(k_in , m); + Word32 cur_lattice_delta_phi_32_fx = L_mult( ap_lattice_delta_phi_fx[l * DIRAC_MAX_DECORR_FILTER_LEN + ap_filter_length[k] - 1], (Word16) floatToFixed( n, 10 ) ); + cur_lattice_delta_phi_fx = extract_h( cur_lattice_delta_phi_32_fx ); // Q10 - /* calculate phase offset */ -#ifdef IVAS_FLOAT_FIXED - Word16 lattice_coeffs_fx[2 * DIRAC_MAX_DECORR_FILTER_LEN]; - get_lattice_coeffs_fx(band_table_idx, l, lattice_coeffs_fx); - FOR (Word16 i = 0; i < ap_filter_length[band_table_idx]; i++) { - lattice_coeffs[i] = ( float ) lattice_coeffs_fx[i] / (1 << 15); + WHILE( GT_16( cur_lattice_delta_phi_fx, sub( ONE_IN_Q11, 1 ) ) ) + { + cur_lattice_delta_phi_fx = sub( cur_lattice_delta_phi_fx, 3217 ); } -#else - get_lattice_coeffs( band_table_idx, l, lattice_coeffs ); -#endif + WHILE( LT_16( cur_lattice_delta_phi_fx, negate( ONE_IN_Q11 ) ) ) + { + cur_lattice_delta_phi_fx = add( cur_lattice_delta_phi_fx, 3217 ); + } + + cur_lattice_delta_phi_fx = shl( cur_lattice_delta_phi_fx, 4 ); + Word16 temp_a = getCosWord16( cur_lattice_delta_phi_fx ); + Word16 temp_b = negate( getCosWord16( sub( 12868 /*PI/2 in Q13*/, cur_lattice_delta_phi_fx ) ) ); + + freq_domain_decorr_ap_params->phase_coeff_real_fx[l * freq_domain_decorr_ap_params->max_band_decorr + n] = temp_a; + freq_domain_decorr_ap_params->phase_coeff_imag_fx[l * freq_domain_decorr_ap_params->max_band_decorr + n] = temp_b; + /*To be cleaned up later*/ + freq_domain_decorr_ap_params->phase_coeff_real[l * freq_domain_decorr_ap_params->max_band_decorr + n] = fixedToFloat( freq_domain_decorr_ap_params->phase_coeff_real_fx[l * freq_domain_decorr_ap_params->max_band_decorr + n], Q14 ); + freq_domain_decorr_ap_params->phase_coeff_imag[l * freq_domain_decorr_ap_params->max_band_decorr + n] = fixedToFloat( freq_domain_decorr_ap_params->phase_coeff_imag_fx[l * freq_domain_decorr_ap_params->max_band_decorr + n], Q14 ); + + /* calculate phase offset */ + get_lattice_coeffs_fx( band_table_idx, l, lattice_coeffs_fx ); /* calcualte transfer function coefficients from the lattice coefficients */ - lattice2allpass( freq_domain_decorr_ap_params->filter_length[k], lattice_coeffs, &freq_domain_decorr_ap_params->filter_coeff_num_real[( k_in + m ) * ( freq_domain_decorr_ap_params->filter_length[0] * num_outputs_diff ) + l * freq_domain_decorr_ap_params->filter_length[0]], &freq_domain_decorr_ap_params->filter_coeff_den_real[( k_in + m ) * ( freq_domain_decorr_ap_params->filter_length[0] * num_outputs_diff ) + l * freq_domain_decorr_ap_params->filter_length[0]] ); + Word16 a = ( k_in + m ) * ( freq_domain_decorr_ap_params->filter_length[0] * num_outputs_diff ) + l * freq_domain_decorr_ap_params->filter_length[0]; + Word16 filter_length = freq_domain_decorr_ap_params->filter_length[k]; + + lattice2allpass_fx( freq_domain_decorr_ap_params->filter_length[k], lattice_coeffs_fx, &freq_domain_decorr_ap_params->filter_coeff_num_real_fx[a], &freq_domain_decorr_ap_params->filter_coeff_den_real_fx[a] ); + + /*To be cleaned up later*/ + FOR( Word16 i = 0; i < filter_length; i++ ) + { + freq_domain_decorr_ap_params->filter_coeff_num_real[a + i] = fixedToFloat( freq_domain_decorr_ap_params->filter_coeff_num_real_fx[a + i], Q12 ); + freq_domain_decorr_ap_params->filter_coeff_den_real[a + i] = fixedToFloat( freq_domain_decorr_ap_params->filter_coeff_den_real_fx[a + i], Q12 ); + } } } } @@ -329,8 +687,7 @@ ivas_error ivas_dirac_dec_decorr_open( return IVAS_ERR_OK; } - - +#endif /*------------------------------------------------------------------------- * ivas_dirac_dec_decorr_process() * @@ -658,6 +1015,19 @@ void ivas_dirac_dec_decorr_close( free(dirac_onset_detection_state->onset_detector_2); dirac_onset_detection_state->onset_detector_2 = NULL; } +#ifdef IVAS_FLOAT_FIXED + IF( dirac_onset_detection_state->onset_detector_1_fx != NULL ) + { + free( dirac_onset_detection_state->onset_detector_1_fx ); + dirac_onset_detection_state->onset_detector_1_fx = NULL; + } + + IF( dirac_onset_detection_state->onset_detector_2_fx != NULL ) + { + free( dirac_onset_detection_state->onset_detector_2_fx ); + dirac_onset_detection_state->onset_detector_2_fx = NULL; + } +#endif /*-----------------------------------------------------------------* * memory deallocation @@ -684,6 +1054,28 @@ void ivas_dirac_dec_decorr_close( (*ph_freq_domain_decorr_ap_state)->reverb_energy_smooth = NULL; } +#ifdef IVAS_FLOAT_FIXED + IF( ( *ph_freq_domain_decorr_ap_state )->decorr_buffer_fx != NULL ) + { + free( ( *ph_freq_domain_decorr_ap_state )->decorr_buffer_fx ); + ( *ph_freq_domain_decorr_ap_state )->decorr_buffer_fx = NULL; + } + + /* free ducker smoothed direct energy buffer */ + IF( ( *ph_freq_domain_decorr_ap_state )->direct_energy_smooth_fx != NULL ) + { + free( ( *ph_freq_domain_decorr_ap_state )->direct_energy_smooth_fx ); + ( *ph_freq_domain_decorr_ap_state )->direct_energy_smooth_fx = NULL; + } + + /* free ducker smoothed reverb energy buffer */ + IF( ( *ph_freq_domain_decorr_ap_state )->reverb_energy_smooth_fx != NULL ) + { + free( ( *ph_freq_domain_decorr_ap_state )->reverb_energy_smooth_fx ); + ( *ph_freq_domain_decorr_ap_state )->reverb_energy_smooth_fx = NULL; + } +#endif + /* free pre-delay param buffer */ if ((*ph_freq_domain_decorr_ap_params)->pre_delay != NULL) { @@ -733,6 +1125,33 @@ void ivas_dirac_dec_decorr_close( (*ph_freq_domain_decorr_ap_params)->split_frequency_bands = NULL; } +#ifdef IVAS_FLOAT_FIXED + IF( ( *ph_freq_domain_decorr_ap_params )->filter_coeff_num_real_fx != NULL ) + { + free( ( *ph_freq_domain_decorr_ap_params )->filter_coeff_num_real_fx ); + ( *ph_freq_domain_decorr_ap_params )->filter_coeff_num_real_fx = NULL; + } + + IF( ( *ph_freq_domain_decorr_ap_params )->filter_coeff_den_real_fx != NULL ) + { + free( ( *ph_freq_domain_decorr_ap_params )->filter_coeff_den_real_fx ); + ( *ph_freq_domain_decorr_ap_params )->filter_coeff_den_real_fx = NULL; + } + + /* free pre-delay param buffer */ + IF( ( *ph_freq_domain_decorr_ap_params )->phase_coeff_imag_fx != NULL ) + { + free( ( *ph_freq_domain_decorr_ap_params )->phase_coeff_imag_fx ); + ( *ph_freq_domain_decorr_ap_params )->phase_coeff_imag_fx = NULL; + } + + /* free pre-delay param buffer */ + IF( ( *ph_freq_domain_decorr_ap_params )->phase_coeff_real_fx != NULL ) + { + free( ( *ph_freq_domain_decorr_ap_params )->phase_coeff_real_fx ); + ( *ph_freq_domain_decorr_ap_params )->phase_coeff_real_fx = NULL; + } +#endif /* free pointers to state and parameter structs */ free(*ph_freq_domain_decorr_ap_params); *ph_freq_domain_decorr_ap_params = NULL; @@ -826,3 +1245,94 @@ static void lattice2allpass( return; } + +#ifdef IVAS_FLOAT_FIXED +static void lattice2allpass_fx( + const int16_t filter_length, + const Word16 *lattice_coeffs_fx, + Word16 *filter_coeffs_num_real_fx, + Word16 *filter_coeffs_den_real_fx) +{ + int16_t i, p; + +#ifdef IVAS_FLOAT_FIXED + Word16 alpha_real_fx[2][DIRAC_MAX_DECORR_FILTER_LEN + 1]; + Word16 *alpha_real_p_old_fx = &alpha_real_fx[0][0]; + Word16 *alpha_real_p_fx = &alpha_real_fx[1][0]; + Word16 *tmp_fx; +#else + float alpha_real[2][DIRAC_MAX_DECORR_FILTER_LEN + 1]; + float *alpha_real_p_old = &alpha_real[0][0]; + float *alpha_real_p = &alpha_real[1][0]; + float *tmp; +#endif + + for (i = 0; i < 2; i++) + { +#ifdef IVAS_FLOAT_FIXED + set16_fx(alpha_real_fx[i], 0, DIRAC_MAX_DECORR_FILTER_LEN + 1); +#else + set_f(alpha_real[i], 0.0f, DIRAC_MAX_DECORR_FILTER_LEN + 1); +#endif + } + +#ifdef IVAS_FLOAT_FIXED + alpha_real_p_fx[0] = ONE_IN_Q12; + alpha_real_p_old_fx[0] = ONE_IN_Q12; +#else + alpha_real_p[0] = 1.0f; + alpha_real_p_old[0] = 1.0f; +#endif + + /* recursion */ + +#ifdef IVAS_FLOAT_FIXED + Word16 lattice_alpha = 0; + FOR (p = 1; p < filter_length; p++) + { + alpha_real_p_fx[p] = shr(lattice_coeffs_fx[(p - 1)], 3);//Q12 + + FOR (i = 1; i < p; i++) + { + lattice_alpha = mult(lattice_coeffs_fx[(p - 1)] , alpha_real_p_old_fx[p - i]);//Q12 + alpha_real_p_fx[i] = add(alpha_real_p_old_fx[i] , lattice_alpha);//Q12 + } + /* switch pointers */ + tmp_fx = alpha_real_p_old_fx; + alpha_real_p_old_fx = alpha_real_p_fx; + alpha_real_p_fx = tmp_fx; + } +#else + for (p = 1; p < filter_length; p++) + { + alpha_real_p[p] = lattice_coeffs[(p - 1)]; + + for (i = 1; i < p; i++) + { + alpha_real_p[i] = alpha_real_p_old[i] + lattice_coeffs[(p - 1)] * alpha_real_p_old[p - i]; + } + /* switch pointers */ + tmp = alpha_real_p_old; + alpha_real_p_old = alpha_real_p; + alpha_real_p = tmp; + } +#endif + + +#ifdef IVAS_FLOAT_FIXED + FOR (i = 0; i < filter_length; i++) + { + filter_coeffs_den_real_fx[i] = alpha_real_p_old_fx[i]; + filter_coeffs_num_real_fx[i] = alpha_real_p_old_fx[filter_length - i - 1]; + }//Q12 +#else + for (i = 0; i < filter_length; i++) + { + filter_coeffs_den_real[i] = alpha_real_p_old[i]; + filter_coeffs_num_real[i] = alpha_real_p_old[filter_length - i - 1]; + } +#endif + + return; +} +#endif diff --git a/lib_rend/ivas_dirac_onsets_dec.c b/lib_rend/ivas_dirac_onsets_dec.c index 415407ceef1eaf6032288a898cae2a41e27729ca..f8a919a06d6786f728a907361de78b255f43e7d9 100644 --- a/lib_rend/ivas_dirac_onsets_dec.c +++ b/lib_rend/ivas_dirac_onsets_dec.c @@ -41,7 +41,8 @@ #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" - +#include "prot_fx1.h" +#include "prot_fx2.h" /*------------------------------------------------------------------------- * ivas_dirac_dec_onset_detection_open() @@ -60,6 +61,55 @@ ivas_error ivas_dirac_dec_onset_detection_open( DIRAC_ONSET_DETECTION_PARAMS *dirac_onset_detection_params = ph_dirac_onset_detection_params; DIRAC_ONSET_DETECTION_STATE *dirac_onset_detection_state = ph_dirac_onset_detection_state; + /* check / set input parameters */ + dirac_onset_detection_params->num_freq_bands = num_freq_bands; + assert(dirac_onset_detection_params->num_freq_bands > 0 && "Error: Number of frequency bands <= 0!"); + + dirac_onset_detection_params->max_band_decorr = max_band_decorr; + + /* memory allocation */ +#ifdef IVAS_FLOAT_FIXED + IF((dirac_onset_detection_state->onset_detector_1_fx = (Word16 *)malloc(sizeof(Word16) * num_protos_diff * dirac_onset_detection_params->max_band_decorr)) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for onset detection\n")); + } + IF((dirac_onset_detection_state->onset_detector_2_fx = (Word16 *)malloc(sizeof(Word16) * num_protos_diff * dirac_onset_detection_params->max_band_decorr)) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for onset detection\n")); + } + /* init to zero */ + set16_fx(dirac_onset_detection_state->onset_detector_1_fx, 0, num_protos_diff * dirac_onset_detection_params->max_band_decorr); + set16_fx(dirac_onset_detection_state->onset_detector_2_fx, 0, num_protos_diff * dirac_onset_detection_params->max_band_decorr); +#endif + /*to be cleand up*/ + IF((dirac_onset_detection_state->onset_detector_1 = (float *)malloc(sizeof(float) * num_protos_diff * dirac_onset_detection_params->max_band_decorr)) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for onset detection\n")); + } + IF((dirac_onset_detection_state->onset_detector_2 = (float *)malloc(sizeof(float) * num_protos_diff * dirac_onset_detection_params->max_band_decorr)) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for onset detection\n")); + } + + /* init to zero */ + set_zero(dirac_onset_detection_state->onset_detector_1, num_protos_diff * dirac_onset_detection_params->max_band_decorr); + set_zero(dirac_onset_detection_state->onset_detector_2, num_protos_diff * dirac_onset_detection_params->max_band_decorr); + + return IVAS_ERR_OK; +} + +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_dirac_dec_onset_detection_open_fx( + const Word16 num_protos_diff, + const Word16 num_freq_bands, + const Word16 max_band_decorr, + DIRAC_ONSET_DETECTION_PARAMS *ph_dirac_onset_detection_params, + DIRAC_ONSET_DETECTION_STATE *ph_dirac_onset_detection_state ) +{ + /* pointers to structs for allocation */ + DIRAC_ONSET_DETECTION_PARAMS *dirac_onset_detection_params = ph_dirac_onset_detection_params; + DIRAC_ONSET_DETECTION_STATE *dirac_onset_detection_state = ph_dirac_onset_detection_state; + /* check / set input parameters */ dirac_onset_detection_params->num_freq_bands = num_freq_bands; assert( dirac_onset_detection_params->num_freq_bands > 0 && "Error: Number of frequency bands <= 0!" ); @@ -67,11 +117,25 @@ ivas_error ivas_dirac_dec_onset_detection_open( dirac_onset_detection_params->max_band_decorr = max_band_decorr; /* memory allocation */ - if ( ( dirac_onset_detection_state->onset_detector_1 = (float *) malloc( sizeof( float ) * num_protos_diff * dirac_onset_detection_params->max_band_decorr ) ) == NULL ) +#ifdef IVAS_FLOAT_FIXED + IF( ( dirac_onset_detection_state->onset_detector_1_fx = (Word16 *) malloc( sizeof( Word16 ) * num_protos_diff * dirac_onset_detection_params->max_band_decorr ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for onset detection\n" ) ); } - if ( ( dirac_onset_detection_state->onset_detector_2 = (float *) malloc( sizeof( float ) * num_protos_diff * dirac_onset_detection_params->max_band_decorr ) ) == NULL ) + IF( ( dirac_onset_detection_state->onset_detector_2_fx = (Word16 *) malloc( sizeof( Word16 ) * num_protos_diff * dirac_onset_detection_params->max_band_decorr ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for onset detection\n" ) ); + } + /* init to zero */ + set16_fx(dirac_onset_detection_state->onset_detector_1_fx, 0, num_protos_diff * dirac_onset_detection_params->max_band_decorr); + set16_fx(dirac_onset_detection_state->onset_detector_2_fx, 0, num_protos_diff * dirac_onset_detection_params->max_band_decorr); +#endif + /*to be cleand up*/ + IF( ( dirac_onset_detection_state->onset_detector_1 = (float *) malloc( sizeof( float ) * num_protos_diff * dirac_onset_detection_params->max_band_decorr ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for onset detection\n" ) ); + } + IF( ( dirac_onset_detection_state->onset_detector_2 = (float *) malloc( sizeof( float ) * num_protos_diff * dirac_onset_detection_params->max_band_decorr ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for onset detection\n" ) ); } @@ -82,8 +146,7 @@ ivas_error ivas_dirac_dec_onset_detection_open( return IVAS_ERR_OK; } - - +#endif /*------------------------------------------------------------------------- * ivas_dirac_dec_onset_detection_process() * diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 42ab480885f83f08b764491aceaef1e77f4b8694..a66c4854376a945db234cdf118f3af45f03f6cce 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -530,6 +530,28 @@ ivas_error ivas_dirac_dec_onset_detection_open( DIRAC_ONSET_DETECTION_STATE *ph_dirac_onset_detection_state ); +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_dirac_dec_onset_detection_open_fx( + const Word16 num_protos_diff, + const Word16 num_freq_bands, + const Word16 max_band_decorr, + DIRAC_ONSET_DETECTION_PARAMS *ph_dirac_onset_detection_params, + DIRAC_ONSET_DETECTION_STATE *ph_dirac_onset_detection_state +); + +ivas_error ivas_dirac_dec_decorr_open_fx( + DIRAC_DECORR_PARAMS **ph_freq_domain_decorr_ap_params, + DIRAC_DECORR_STATE **ph_freq_domain_decorr_ap_state, + const Word16 num_freq_bands, + Word16 num_outputs_diff, + const Word16 num_protos_diff, + const DIRAC_SYNTHESIS_CONFIG synthesisConf, + Word16 *frequency_axis, + const Word16 nchan_transport, /* i : number of transport channels */ + const Word32 output_Fs /* i : output sampling rate */ +); +#endif + void ivas_dirac_dec_onset_detection_process( const float *input_power_f, float *onset_filter, diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend.c index dbcefb7a47f70c5d7969bb3e40889e60cdbb9dee..2c3c43cf411632427e8be089e5bddd3d3c37529c 100644 --- a/lib_rend/ivas_rom_rend.c +++ b/lib_rend/ivas_rom_rend.c @@ -92,6 +92,32 @@ const float ap_lattice_delta_phi[DIRAC_MAX_NUM_DECORR_FILTERS*DIRAC_MAX_DECORR_F 0.915365f, 1.394094f, 0.757041f, 0.350064f, 1.199679f, 1.319499f, 1.128405f, 0.632337f, 0.790673f, 0.461582f, 1.693343f, 1.537442f, 0.346527f, 0.433782f, 1.754552f, 0.550903f, 0.686724f, 0.764433f, 1.792750f, 1.489998f }; +#ifdef IVAS_FLOAT_FIXED +const Word16 ap_lattice_delta_phi_fx[DIRAC_MAX_NUM_DECORR_FILTERS*DIRAC_MAX_DECORR_FILTER_LEN] /*Q14*/ = +{ + 29532 , 15122 , 29715 , 20854 , 14040 , 6006 , 25088 , 21597 , 2029 , 14699 , 15707 , 20585 , 2944 , 10960 , 23598 , 25773 , 22880 , 19521 , 7277 , 27311 , 20872 , 28626 , 23074 , + 16430 , 25548 , 29213 , 24165 , 13323 , 23883 , 9642 , 22680 , 2564 , 9831 , 27224 , 8830 , 10575 , 9261 , 404 , 4329 , 1018 , 20240 , 13955 , 29822 , 1903 , 15927 , + 8007 , 29125 , 23792 , 13339 , 20851 , 20995 , 1669 , 14711 , 3273 , 1405 , 27633 , 15803 , 938 , 14914 , 27235 , 15651 , 13670 , 27402 , 21707 , 7283 , 28200 , 2513 , + 26251 , 2816 , 19166 , 8907 , 23095 , 28897 , 27636 , 19831 , 6598 , 16116 , 14139 , 19995 , 14583 , 518 , 7563 , 28173 , 22245 , 18223 , 19112 , 4032 , 22730 , 2908 , + 23696 , 13099 , 27316 , 28237 , 24673 , 4028 , 18938 , 13622 , 11095 , 9320 , 27068 , 324 , 19625 , 10413 , 8711 , 14388 , 787 , 1319 , 25670 , 11865 , 13986 , 28528 , + 11444 , 25453 , 2135 , 11278 , 21809 , 9826 , 18440 , 28915 , 17087 , 24356 , 26673 , 30657 , 1677 , 574 , 22990 , 24063 , 3119 , 9065 , 16896 , 20191 , 20574 , 24649 , + 11199 , 9846 , 28622 , 25055 , 23727 , 10598 , 1901 , 21026 , 5820 , 22620 , 30449 , 13415 , 3588 , 7804 , 6882 , 21155 , 9318 , 19236 , 10302 , 28724 , 23914 , 22191 , + 28767 , 7238 , 14029 , 27000 , 11245 , 22860 , 11468 , 3921 , 3925 , 15699 , 12268 , 8418 , 27301 , 23953 , 26199 , 14633 , 5601 , 22736 , 29628 , 11084 , 23347 , 5088 , + 13701 , 16566 , 27627 , 29875 , 16299 , 26797 , 11213 , 16663 , 23599 , 27765 , 9947 , 19617 , 14126 , 10919 , 17170 , 2615 , 707 , 20505 , 26521 , 3554 , 2494 , 7727 , + 12194 , 9450 , 26742 , 25508 , 30578 , 9308 , 25261 , 28291 , 4508 , 13352 , 14146 , 21841 , 2429 , 3242 , 17181 , 18974 , 27725 , 14488 , 4745 , 6236 , 28315 , 23482 , + 28664 , 25130 , 10972 , 6104 , 17242 , 18295 , 2971 , 18663 , 3648 , 9902 , 29684 , 28562 , 22426 , 30498 , 12319 , 2618 , 25666 , 7263 , 27321 , 17745 , 20368 , 11760 , + 11060 , 11313 , 11014 , 17380 , 6940 , 19636 , 7959 , 16285 , 7267 , 5926 , 25429 , 14149 , 24866 , 17398 , 11328 , 26916 , 28780 , 4560 , 12949 , 2823 , 6834 , 153 , + 12834 , 22435 , 17057 , 7653 , 16266 , 24988 , 14274 , 3996 , 25265 , 7359 , 13822 , 3142 , 26448 , 17010 , 23194 , 9029 , 6269 , 23103 , 1673 , 2249 , 10995 , 4176 , + 28804 , 17679 , 2116 , 23116 , 2466 , 9849 , 12464 , 15989 , 3658 , 11635 , 27477 , 16332 , 30308 , 25169 , 1458 , 15743 , 6368 , 6225 , 16420 , 20831 , 23112 , 4168 , + 25159 , 18575 , 21386 , 24028 , 4492 , 6548 , 22276 , 28939 , 22960 , 21478 , 4277 , 21542 , 25209 , 21594 , 20368 , 28663 , 27684 , 407 , 10400 , 16979 , 29952 , 27475 , + 387 , 14041 , 1253 , 26578 , 4169 , 23783 , 28195 , 12514 , 3064 , 934 , 9675 , 6149 , 26366 , 9957 , 432 , 7919 , 13499 , 12991 , 2680 , 12347 , 11973 , 2228 , + 16903 , 25463 , 19544 , 273 , 2061 , 16678 , 26080 , 9436 , 1850 , 4088 , 22931 , 872 , 23114 , 4123 , 17352 , 415 , 23313 , 16882 , 13906 , 5200 , 22535 , 18299 , + 27563 , 4580 , 5341 , 15363 , 28579 , 7336 , 16782 , 16409 , 30535 , 20944 , 14102 , 22058 , 27731 , 371 , 16935 , 8951 , 6485 , 24356 , 22627 , 21500 , 4030 , 26336 , + 29799 , 15800 , 24520 , 10977 , 25165 , 30177 , 16042 , 10060 , 30789 , 8397 , 19121 , 1339 , 29056 , 25160 , 12415 , 3611 , 25203 , 20991 , 4951 , 14580 , 13083 , 24188 , + 27295 , 14997 , 22841 , 12403 , 5735 , 19656 , 21619 , 18488 , 10360 , 12954 , 7563 , 27744 , 25189 , 5677 , 7107 , 28747 , 9026 , 11251 , 12524 , 29372 , 24412 +}; +#endif + const float ap_lattice_coeffs_1[DIRAC_DECORR_FILTER_LEN_1*DIRAC_MAX_NUM_DECORR_FILTERS] = { 0.795329f, 0.502700f, 0.204456f, 0.416566f, 0.459648f, 0.270454f, -0.201944f, 0.027997f, 0.067811f, -0.052627f, -0.038779f, -0.057387f, 0.020480f, 0.367697f, -0.593705f, @@ -195,6 +221,12 @@ const float ap_split_frequencies[DIRAC_DECORR_NUM_SPLIT_BANDS + 1] = 0.0f, 0.125f, 0.375f, 1.0f }; +#ifdef IVAS_FLOAT_FIXED +const Word16 ap_split_frequencies_fx[DIRAC_DECORR_NUM_SPLIT_BANDS + 1]/*Q14*/ = { + 0 , 2048, 6144, 16384 +}; +#endif + const int16_t sba_map_tc[11] = { 0, 1, 2, 3, 4, 8, 9, 15, 5, 6, 7 diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index 7f26e6cf7f2042e62bbd73b6d8a40900ae3dbafd..807fe1931ea3b36e73f6df3ab7ea6c6fb6d0ecc0 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -64,6 +64,10 @@ extern const float ap_lattice_coeffs_3[DIRAC_DECORR_FILTER_LEN_3 * DIRAC_MAX_NUM extern const float *const ap_lattice_coeffs[DIRAC_DECORR_NUM_SPLIT_BANDS]; extern const Word16 *const ap_lattice_coeffs_fx[DIRAC_DECORR_NUM_SPLIT_BANDS]; extern const float ap_split_frequencies[DIRAC_DECORR_NUM_SPLIT_BANDS + 1]; +#ifdef IVAS_FLOAT_FIXED +extern const Word16 ap_split_frequencies_fx[DIRAC_DECORR_NUM_SPLIT_BANDS + 1]; +extern const Word16 ap_lattice_delta_phi_fx[DIRAC_MAX_NUM_DECORR_FILTERS*DIRAC_MAX_DECORR_FILTER_LEN]; +#endif extern const int16_t sba_map_tc[11]; extern const int16_t sba_map_tc_512[11]; diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 09c3fa45baf039ed02346a9aea5211311f33405d..0edbd69a457b8891602537e93ebbeed91dfe4db9 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -145,6 +145,10 @@ typedef struct dirac_onset_detection_state_structure { float *onset_detector_1; float *onset_detector_2; +#ifdef IVAS_FLOAT_FIXED + Word16 *onset_detector_1_fx; + Word16 *onset_detector_2_fx; +#endif } DIRAC_ONSET_DETECTION_STATE; @@ -158,8 +162,16 @@ typedef struct dirac_decorr_params_structure int16_t *filter_length; float *filter_coeff_num_real; float *filter_coeff_den_real; + float *phase_coeff_real; float *phase_coeff_imag; +#ifdef IVAS_FLOAT_FIXED + Word16 *filter_coeff_num_real_fx; + Word16 *filter_coeff_den_real_fx; + + Word16 *phase_coeff_real_fx; + Word16 *phase_coeff_imag_fx; +#endif int16_t *split_frequency_bands; int16_t num_split_frequency_bands; @@ -175,6 +187,11 @@ typedef struct dirac_decorr_state_structure float *decorr_buffer; float *direct_energy_smooth; float *reverb_energy_smooth; +#ifdef IVAS_FLOAT_FIXED + Word16 *decorr_buffer_fx; + Word16 *direct_energy_smooth_fx; + Word16 *reverb_energy_smooth_fx; +#endif DIRAC_ONSET_DETECTION_STATE h_onset_detection_power_state; diff --git a/lib_rend/ivas_td_decorr.c b/lib_rend/ivas_td_decorr.c index 4a1f459104606ba4602e4b60f954834c75d04de8..079b2bd30bb3a9c53686366a120f02621c9ef60e 100644 --- a/lib_rend/ivas_td_decorr.c +++ b/lib_rend/ivas_td_decorr.c @@ -144,6 +144,7 @@ static void ivas_td_decorr_init( ivas_td_decorr_state_t *hTdDecorr, const Word16 * Allocate and initialize time domain decorrelator handle *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED ivas_error ivas_td_decorr_reconfig_dec( const IVAS_FORMAT ivas_format, /* i : IVAS format */ const Word32 ivas_total_brate, /* i : total IVAS bitrate */ @@ -189,11 +190,7 @@ ivas_error ivas_td_decorr_reconfig_dec( { IF( *hTdDecorr == NULL ) { -#ifdef IVAS_FLOAT_FIXED IF( ( error = ivas_td_decorr_dec_open_fx( hTdDecorr, output_Fs, 3, 1 ) ) != IVAS_ERR_OK ) -#else - IF( ( error = ivas_td_decorr_dec_open( hTdDecorr, output_Fs, 3, 1 ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -212,11 +209,91 @@ ivas_error ivas_td_decorr_reconfig_dec( { IF( *hTdDecorr == NULL ) { -#ifdef IVAS_FLOAT_FIXED IF( ( error = ivas_td_decorr_dec_open_fx( hTdDecorr, output_Fs, 3, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + } + ELSE + { + ivas_td_decorr_init( *hTdDecorr, 3, 0 ); + } + } + } + ELSE + { + ivas_td_decorr_dec_close( hTdDecorr ); + } + } + + return IVAS_ERR_OK; +} #else +ivas_error ivas_td_decorr_reconfig_dec( + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word32 ivas_total_brate, /* i : total IVAS bitrate */ + const Word16 nchan_transport, /* i : number of transport channels */ + const Word32 output_Fs, /* i : output sampling rate */ + ivas_td_decorr_state_t **hTdDecorr, /* i/o: TD decorrelator handle */ + UWord16 *useTdDecorr /* i/o: TD decorrelator flag */ +) +{ + UWord16 useTdDecorr_new; + ivas_error error; + + useTdDecorr_new = 0; + IF( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) + { + IF( nchan_transport == 1 ) + { + useTdDecorr_new = 1; + } + } + ELSE IF( ivas_format == MASA_FORMAT ) + { + IF( ( LT_32( ivas_total_brate, IVAS_48k ) && nchan_transport == 1 ) || LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) ) + { + useTdDecorr_new = 1; + } + } + ELSE IF( ivas_format == MC_FORMAT ) + { + IF( LT_32( ivas_total_brate, IVAS_48k ) && EQ_16( nchan_transport, 1 ) ) + { + useTdDecorr_new = 1; + } + } + + IF( *useTdDecorr != useTdDecorr_new ) + { + *useTdDecorr = useTdDecorr_new; + + IF( *useTdDecorr ) + { + IF( GE_32( ivas_total_brate, IVAS_13k2 ) && ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) ) + { + IF( *hTdDecorr == NULL ) + { + IF( ( error = ivas_td_decorr_dec_open( hTdDecorr, output_Fs, 3, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + IF( LT_32( ivas_total_brate, IVAS_24k4 ) ) + { + ( *hTdDecorr )->pTrans_det->duck_mult_fac = IVAS_TDET_DUCK_MULT_FAC_PARA_BIN_LOW_BR; + } + ELSE + { + ( *hTdDecorr )->pTrans_det->duck_mult_fac = IVAS_TDET_DUCK_MULT_FAC_PARA_BIN; + } + } + ELSE + { + IF( *hTdDecorr == NULL ) + { IF( ( error = ivas_td_decorr_dec_open( hTdDecorr, output_Fs, 3, 0 ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -235,6 +312,7 @@ ivas_error ivas_td_decorr_reconfig_dec( return IVAS_ERR_OK; } +#endif #ifdef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------------