diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index eb14bfdc43e5b2600794e9f19e6c8e236ae7e2e3..8b4d2b08ce6ab48a66c6607b74a5769fc3ee93d8 100755 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -40,6 +40,9 @@ #include "stat_enc.h" #include "stat_dec.h" #include "stat_com.h" +#ifdef FIX_197_CREND_INTERFACE +#include "ivas_stat_rend.h" +#endif #include "ivas_stat_enc.h" #include "ivas_stat_dec.h" #include "ivas_stat_com.h" @@ -5334,6 +5337,7 @@ int16_t ivas_get_num_bands_from_bw_idx( /*----------------------------------------------------------------------------------* * Crend renderer *----------------------------------------------------------------------------------*/ +#ifndef FIX_197_CREND_INTERFACE ivas_error ivas_crend_init_from_rom( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ @@ -5352,6 +5356,51 @@ ivas_error ivas_crend_process( float output[][L_FRAME48k] /* i/o: input/output audio channels */ ); +#else + +IVAS_REND_AudioConfigType getAudioConfigType( + const IVAS_REND_AudioConfig config ); + +ivas_error getAudioConfigNumChannels( + const IVAS_REND_AudioConfig config, + int16_t *numChannels ); + +IVAS_REND_AudioConfig getRendAudioConfigFromIvasAudioConfig( + AUDIO_CONFIG config ); + +ivas_error ivas_rend_openCrend( + CREND_WRAPPER_HANDLE *pCrend, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, + RENDER_CONFIG_DATA *hRendCfg, + int16_t Opt_Headrotation, + const int32_t output_Fs ); + +ivas_error ivas_rend_initCrend( + CREND_WRAPPER *pCrend, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, + RENDER_CONFIG_DATA *hRendCfg, + const int32_t output_Fs ); + +#ifdef FIX_197_CREND_INTERFACE +void ivas_rend_closeCrend( +#else +ivas_error ivas_rend_closeCrend( +#endif + CREND_WRAPPER_HANDLE *pCrend ); + +ivas_error ivas_rend_crendProcess( + const CREND_WRAPPER *pCrend, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, + DECODER_CONFIG_HANDLE hDecoderConfig, + HEAD_TRACK_DATA_HANDLE hHeadTrackData, + IVAS_OUTPUT_SETUP_HANDLE hIntSetup, + EFAP_HANDLE hEFAPdata, + float output[][L_FRAME48k], /* i/o: input/output audio channels */ + const int32_t output_Fs ); +#endif /*----------------------------------------------------------------------------------* * Renderer configuration diff --git a/lib_com/options.h b/lib_com/options.h index da82759607d84037fba7782ff1fc00b7695becb4..1db2103272620bd8afae7b8c17383d62e6d6098e 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -157,6 +157,7 @@ #define FIX_268 /* Issue 268: Add low cost dry-run of memory analysis */ #define LOW_RATE_TRANS_FIX /* Eri: Fix for critical item during transitions */ +#define FIX_197_CREND_INTERFACE /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ #endif diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index fa341b093fed719cb01ff64a666439d2b9ad308d..b52c92b239dadaaa3339db63e5dc4304434bf567 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -207,7 +207,22 @@ ivas_error ivas_dec( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { +#ifdef FIX_197_CREND_INTERFACE + if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, + IVAS_REND_AUDIO_CONFIG_7_1_4, + IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM, + NULL, + NULL, + NULL, + NULL, + output, + output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } +#else ivas_crend_process( st_ivas, output ); +#endif ivas_binaural_add_LFE( st_ivas, output_frame, output ); } #ifdef DEBUGGING @@ -389,7 +404,22 @@ ivas_error ivas_dec( /* Rendering */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { +#ifdef FIX_197_CREND_INTERFACE + if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, + getRendAudioConfigFromIvasAudioConfig( st_ivas->intern_config ), + getRendAudioConfigFromIvasAudioConfig( st_ivas->hOutSetup.output_config ), + st_ivas->hDecoderConfig, + st_ivas->hHeadTrackData, + &st_ivas->hIntSetup, + st_ivas->hEFAPdata, + output, + output_Fs ) != IVAS_ERR_OK ) ) + { + return error; + } +#else ivas_crend_process( st_ivas, output ); +#endif ivas_binaural_add_LFE( st_ivas, output_frame, output ); } else if ( st_ivas->renderer_type == RENDERER_MC ) diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 595b362223f31903bf14c7a38354c0a58ca600af..20fccb60d130b3b85d33b3c6049d0228081c14ab 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1145,9 +1145,17 @@ ivas_error ivas_init_decoder( if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) { +#ifdef FIX_197_CREND_INTERFACE + if ( ( st_ivas->hCrendWrapper = (CREND_WRAPPER_HANDLE) malloc( sizeof( CREND_WRAPPER ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Wrapper\n" ); + } + if ( ( st_ivas->hCrendWrapper->hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) +#else if ( ( st_ivas->hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) +#endif { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR Crend\n" ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend\n" ); } } } @@ -1167,10 +1175,33 @@ ivas_error ivas_init_decoder( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { +#ifdef FIX_197_CREND_INTERFACE + if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && st_ivas->ivas_format == MC_FORMAT && st_ivas->hDecoderConfig->Opt_Headrotation ) + { + if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), + st_ivas->hIntSetup.ls_azimuth, + st_ivas->hIntSetup.ls_elevation, + st_ivas->hIntSetup.nchan_out_woLFE, + EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) + { + return error; + } + } + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), + getRendAudioConfigFromIvasAudioConfig( st_ivas->intern_config ), + getRendAudioConfigFromIvasAudioConfig( st_ivas->hDecoderConfig->output_config ), + st_ivas->hRenderConfig, st_ivas->hDecoderConfig->Opt_Headrotation, + st_ivas->hDecoderConfig->output_Fs ) != IVAS_ERR_OK ) ) + { + return error; + } + st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns; +#else if ( ivas_crend_open( st_ivas ) != IVAS_ERR_OK ) { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "ivas_crend_open failed" ); } +#endif } if ( st_ivas->ivas_format == ISM_FORMAT && @@ -1474,8 +1505,12 @@ void ivas_initialize_handles_dec( st_ivas->hIsmRendererData = NULL; st_ivas->hBinRendererTd = NULL; st_ivas->hMonoDmxRenderer = NULL; +#ifdef FIX_197_CREND_INTERFACE + st_ivas->hCrendWrapper = NULL; +#else st_ivas->hCrend = NULL; st_ivas->hHrtf = NULL; +#endif st_ivas->hoa_dec_mtx = NULL; st_ivas->hHeadTrackData = NULL; @@ -1630,7 +1665,11 @@ void ivas_destroy_dec( ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); /* Crend handle */ +#ifdef FIX_197_CREND_INTERFACE + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); +#else ivas_crend_close( st_ivas ); +#endif /* LS config converter handle */ ivas_ls_setup_conversion_close( &st_ivas->hLsSetUpConversion ); diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 63cbbd91adecaad82d2d4e1f5d6ebe5232b3efc8..090a69257c0b89f5679d0a1fd865a53dba1b5714 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -1085,7 +1085,20 @@ static ivas_error ivas_ism_bitrate_switching( ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); /* Open Crend Binaural renderer */ +#ifdef FIX_197_CREND_INTERFACE + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), + getRendAudioConfigFromIvasAudioConfig( st_ivas->intern_config ), + getRendAudioConfigFromIvasAudioConfig( st_ivas->hOutSetup.output_config ), + st_ivas->hRenderConfig, + st_ivas->hDecoderConfig->Opt_Headrotation, + st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns; +#else ivas_crend_open( st_ivas ); +#endif } } @@ -1128,12 +1141,16 @@ static ivas_error ivas_ism_bitrate_switching( ivas_dirac_dec_init_binaural_data( st_ivas ); /* close the crend binaural renderer */ +#ifdef FIX_197_CREND_INTERFACE + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); +#else ivas_crend_close( st_ivas ); if ( st_ivas->hHrtf != NULL ) { st_ivas->hHrtf = NULL; } +#endif } } diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 14c8cc3be194bf0c92076f33776cb4b8f812014f..48381432a5a69a8f6bf74ea7b7173168621035de 100755 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -1034,9 +1034,17 @@ static ivas_error ivas_mc_dec_reconfig( ivas_binRenderer_close( &st_ivas->hBinRenderer ); } +#ifdef FIX_197_CREND_INTERFACE + if ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hCrend != NULL ) && ( st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV && st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV_ROOM && ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD || st_ivas->hRenderConfig->roomAcoustics.late_reverb_on == 0 ) ) ) +#else if ( st_ivas->hCrend != NULL && ( st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV && st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV_ROOM && ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD || st_ivas->hRenderConfig->roomAcoustics.late_reverb_on == 0 ) ) ) +#endif { +#ifdef FIX_197_CREND_INTERFACE + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); +#else ivas_crend_close( st_ivas ); +#endif } if ( st_ivas->hBinRendererTd != NULL && ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) ) @@ -1084,22 +1092,53 @@ static ivas_error ivas_mc_dec_reconfig( return error; } +#ifdef FIX_197_CREND_INTERFACE + if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) + { + if ( ( st_ivas->hCrendWrapper = (CREND_WRAPPER_HANDLE) malloc( sizeof( CREND_WRAPPER ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Wrapper\n" ); + } + if ( ( st_ivas->hCrendWrapper->hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend\n" ); + } + } +#else if ( st_ivas->hCrend == NULL && st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) { if ( ( st_ivas->hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR Crend\n" ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend\n" ); } } +#endif } - else if ( st_ivas->hCrend == NULL && ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) +#ifdef FIX_197_CREND_INTERFACE + else if ( st_ivas->hCrendWrapper == NULL && ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) { - if ( ivas_crend_open( st_ivas ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), + getRendAudioConfigFromIvasAudioConfig( st_ivas->intern_config ), + getRendAudioConfigFromIvasAudioConfig( st_ivas->hDecoderConfig->output_config ), + st_ivas->hRenderConfig, st_ivas->hDecoderConfig->Opt_Headrotation, + st_ivas->hDecoderConfig->output_Fs ) != IVAS_ERR_OK ) ) { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "ivas_crend_open failed" ); + return error; } + st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns; + } +#else + } + else if ( st_ivas->hCrend == NULL && ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) + { + if ( ivas_crend_open( st_ivas ) != IVAS_ERR_OK ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "ivas_crend_open failed" ); } } + +#endif + } /* mono/stereo */ else if ( output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) { diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 82123af232d73093a3465d084e7277b2023178f3..126ab559442aea9364843efcfac7d7abe8997c7d 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -169,7 +169,11 @@ ivas_error ivas_sba_dec_reinit( ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); /* Crend handle */ +#ifdef FIX_197_CREND_INTERFACE + ivas_rend_closeCrend( &st_ivas->hCrendWrapper ); +#else ivas_crend_close( st_ivas ); +#endif /* LS config converter handle */ ivas_ls_setup_conversion_close( &st_ivas->hLsSetUpConversion ); @@ -461,9 +465,17 @@ ivas_error ivas_sba_dec_reinit( if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) { +#ifdef FIX_197_CREND_INTERFACE + if ( ( st_ivas->hCrendWrapper = (CREND_WRAPPER_HANDLE) malloc( sizeof( CREND_WRAPPER ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CrendWrapper\n" ); + } + if ( ( st_ivas->hCrendWrapper->hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) +#else if ( ( st_ivas->hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) +#endif { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR Crend\n" ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend\n" ); } } } @@ -483,10 +495,23 @@ ivas_error ivas_sba_dec_reinit( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { +#ifdef FIX_197_CREND_INTERFACE + if ( ( error = ivas_rend_openCrend( &st_ivas->hCrendWrapper, + getRendAudioConfigFromIvasAudioConfig( st_ivas->intern_config ), + getRendAudioConfigFromIvasAudioConfig( st_ivas->hDecoderConfig->output_config ), + st_ivas->hRenderConfig, + t_ivas->hDecoderConfig->Opt_Headrotation, + st_ivas->hDecoderConfig->output_Fs ) != IVAS_ERR_OK ) ) + { + return error; + } + st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns; +#else if ( ivas_crend_open( st_ivas ) != IVAS_ERR_OK ) { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "ivas_crend_open failed" ); } +#endif } ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses, &numCldfbSyntheses ); diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index c09629466df4ff09b69680a6e7bf946610edb701..4fceaf79f6758aa9bf5808227718338b7e8dd55b 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -40,8 +40,11 @@ #include "ivas_cnst.h" #include "ivas_stat_com.h" #include "ivas_stat_rend.h" +#ifndef FIX_197_CREND_INTERFACE #include "common_api_types.h" // VE2AT: don't we want to avoid this include in the library? I admit that the rules hefre are not 100% clear to me but introducing it just for IVAS_QUATERNION is not necessry I think +#endif +#ifndef FIX_197_CREND_INTERFACE /*----------------------------------------------------------------------------------* * Output configuration for renderer (e.g. DirAC, MASA, Binaural Renderer...) @@ -66,7 +69,7 @@ typedef struct ivas_output_setup_structure } IVAS_OUTPUT_SETUP, *IVAS_OUTPUT_SETUP_HANDLE; - +#endif /*----------------------------------------------------------------------------------* * DFT Stereo decoder structure *----------------------------------------------------------------------------------*/ @@ -817,6 +820,7 @@ typedef struct ivas_spar_md_dec_state_t int16_t spar_hoa_md_flag; } ivas_spar_md_dec_state_t; +#ifndef FIX_197_CREND_INTERFACE /* AGC structure */ typedef struct ivas_agc_dec_chan_state_t @@ -856,6 +860,8 @@ typedef struct ivas_td_decorr_state_t } ivas_td_decorr_state_t; +#endif + /* PCA structure */ typedef struct { @@ -987,6 +993,7 @@ typedef struct mct_dec_data_structure } MCT_DEC_DATA, *MCT_DEC_HANDLE; +#ifndef FIX_197_CREND_INTERFACE /*----------------------------------------------------------------------------------* * EFAP structures @@ -1120,7 +1127,7 @@ typedef struct renderer_struct } ISM_RENDERER_DATA, *ISM_RENDERER_HANDLE; - +#endif /*----------------------------------------------------------------------------------* * MASA decoder structures *----------------------------------------------------------------------------------*/ @@ -1175,6 +1182,7 @@ typedef struct ivas_masa_decoder_struct } MASA_DECODER, *MASA_DECODER_HANDLE; +#ifndef FIX_197_CREND_INTERFACE /*----------------------------------------------------------------------------------* * Binaural Rendering structure @@ -1815,7 +1823,7 @@ typedef struct decoder_config_structure } DECODER_CONFIG, *DECODER_CONFIG_HANDLE; - +#endif /*----------------------------------------------------------------------------------* * * Main IVAS decoder structure @@ -1889,8 +1897,12 @@ typedef struct Decoder_Struct EFAP_HANDLE hEFAPdata; /* EFAP structure */ VBAP_HANDLE hVBAPdata; /* VBAP structure */ MONO_DOWNMIX_RENDERER_HANDLE hMonoDmxRenderer; /* Mono downmix structure */ +#ifdef FIX_197_CREND_INTERFACE + CREND_WRAPPER_HANDLE hCrendWrapper; +#else CREND_HANDLE hCrend; /* Convolution mixer renderer structure */ HRTFS_HANDLE hHrtf; /* HRTFs handle */ +#endif LSSETUP_CUSTOM_HANDLE hLsSetupCustom; /* Custom LS configuration handle */ float *hoa_dec_mtx; /* Pointer to decoder matrix for SBA */ HEAD_TRACK_DATA_HANDLE hHeadTrackData; /* Head tracking data structure */ diff --git a/lib_rend/ivas_binauralRenderer.c b/lib_rend/ivas_binauralRenderer.c index be2a8193c89ce53874298af1665c80dbffaf6b65..6503e8e1f796be5a89e47dc227d5e0ff1b37fc71 100644 --- a/lib_rend/ivas_binauralRenderer.c +++ b/lib_rend/ivas_binauralRenderer.c @@ -791,7 +791,11 @@ void ivas_binaural_add_LFE( if ( render_lfe ) { +#ifdef FIX_197_CREND_INTERFACE + gain = ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hHrtfCrend != NULL ) ) ? st_ivas->hCrendWrapper->hHrtfCrend->gain_lfe : GAIN_LFE; +#else gain = st_ivas->hHrtf != NULL ? st_ivas->hHrtf->gain_lfe : GAIN_LFE; +#endif for ( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ ) { v_multc( output_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain, output_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_frame ); diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 41c60261f753027314b29e2450d7299b39f2c5e1..d824e2b758c7094bcdc6889f735d152636f27a63 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -39,8 +39,13 @@ #include "ivas_stat_dec.h" #include #include "ivas_rom_binaural_crend_head.h" +#ifdef FIX_197_CREND_INTERFACE +#include "ivas_stat_rend.h" +#include "lib_rend.h" +#else #include "lib_rend.h" #include "ivas_lib_rend_internal.h" +#endif #ifdef DEBUGGING #include "debug.h" #endif @@ -148,6 +153,7 @@ static ivas_error ivas_hrtf_close( } +#ifndef FIX_197_CREND_INTERFACE /*------------------------------------------------------------------------- * ivas_crend_init_from_rom() * @@ -163,7 +169,12 @@ ivas_error ivas_crend_init_from_rom( AUDIO_CONFIG intern_config; HRTFS_HANDLE hHrtf; +#ifdef FIX_197_CREND_INTERFACE + hHrtf = st_ivas->hCrendWrapper->hHrtfCrend; +#else hHrtf = st_ivas->hHrtf; +#endif + output_Fs = st_ivas->hDecoderConfig->output_Fs; intern_config = st_ivas->intern_config; @@ -635,12 +646,17 @@ ivas_error ivas_crend_init_from_rom( return IVAS_ERROR( IVAS_ERR_INTERNAL, "Unsupported renderer type in Crend" ); } +#ifdef FIX_197_CREND_INTERFACE + st_ivas->hCrendWrapper->hHrtfCrend = hHrtf; +#else st_ivas->hHrtf = hHrtf; +#endif return IVAS_ERR_OK; } +#endif - +#ifndef FIX_197_CREND_INTERFACE /*------------------------------------------------------------------------- * ivas_crend_open() * @@ -803,7 +819,9 @@ ivas_error ivas_crend_open( return error; } +#endif +#ifndef FIX_197_CREND_INTERFACE /*------------------------------------------------------------------------- * ivas_crend_close() @@ -882,7 +900,9 @@ ivas_error ivas_crend_close( return IVAS_ERR_OK; } +#endif +#ifndef FIX_197_CREND_INTERFACE /*-----------------------------------------------------------------------------------------* * Function ivas_crend_convolver() @@ -1020,7 +1040,9 @@ static ivas_error ivas_crend_convolver( return IVAS_ERR_OK; } +#endif +#ifndef FIX_197_CREND_INTERFACE /*-----------------------------------------------------------------------------------------* * Function ivas_crend_process() @@ -1121,7 +1143,7 @@ ivas_error ivas_crend_process( return IVAS_ERR_OK; } - +#endif /*------------------------------------------------------------------------- * ivas_rend_openCrend() @@ -1130,10 +1152,17 @@ ivas_error ivas_crend_process( *------------------------------------------------------------------------*/ ivas_error ivas_rend_openCrend( +#ifdef FIX_197_CREND_INTERFACE + CREND_WRAPPER_HANDLE *pCrend, +#else CREND_WRAPPER *pCrend, +#endif const IVAS_REND_AudioConfig inConfig, const IVAS_REND_AudioConfig outConfig, RENDER_CONFIG_DATA *hRendCfg, +#ifdef FIX_197_CREND_INTERFACE + int16_t Opt_Headrotation, +#endif const int32_t output_Fs ) { /* TODO tmu : Based on ivas_crend_open() - could be harmonized / refactored */ @@ -1144,8 +1173,36 @@ ivas_error ivas_rend_openCrend( ivas_error error; error = IVAS_ERR_OK; + +#ifdef FIX_197_CREND_INTERFACE + if ( pCrend == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Wrapper\n" ); + } + + if ( *pCrend == NULL ) + { + if ( ( *pCrend = (CREND_WRAPPER_HANDLE) malloc( sizeof( CREND_WRAPPER ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Wrapper\n" ); + } + ( *pCrend )->binaural_latency_ns = 0; + ( *pCrend )->hCrend = NULL; + ( *pCrend )->hHrtfCrend = NULL; + } +#endif + subframe_length = (int16_t) ( output_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES; +#ifdef FIX_197_CREND_INTERFACE + if ( ( *pCrend )->hHrtfCrend == NULL ) + { + if ( ( error = ivas_rend_initCrend( *pCrend, inConfig, outConfig, hRendCfg, output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else if ( pCrend->hHrtfCrend == NULL ) { if ( ( error = ivas_rend_initCrend( pCrend, inConfig, outConfig, hRendCfg, output_Fs ) ) != IVAS_ERR_OK ) @@ -1153,6 +1210,7 @@ ivas_error ivas_rend_openCrend( return error; } } +#endif if ( ( hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) { @@ -1182,7 +1240,11 @@ ivas_error ivas_rend_openCrend( hCrend->m_fPitch = 0; hCrend->m_fRoll = 0; +#ifdef FIX_197_CREND_INTERFACE + hHrtf = ( *pCrend )->hHrtfCrend; +#else hHrtf = pCrend->hHrtfCrend; +#endif if ( hHrtf != NULL ) { @@ -1247,8 +1309,11 @@ ivas_error ivas_rend_openCrend( { hCrend->lfe_delay_line = NULL; } - +#ifdef FIX_197_CREND_INTERFACE + if ( Opt_Headrotation ) +#else if ( false ) /* TODO tmu : check renderer headrotation flag */ +#endif { if ( ( hCrend->hTrack = (ivas_orient_trk_state_t *) malloc( sizeof( ivas_orient_trk_state_t ) ) ) == NULL ) { @@ -1266,7 +1331,11 @@ ivas_error ivas_rend_openCrend( { if ( ( error = ivas_reverb_open( &( hCrend->hReverb ), getIvasAudioConfigFromRendAudioConfig( inConfig ), +#ifdef FIX_197_CREND_INTERFACE + ( *pCrend )->hHrtfCrend, +#else pCrend->hHrtfCrend, +#endif hRendCfg, output_Fs ) ) != IVAS_ERR_OK ) { @@ -1278,10 +1347,18 @@ ivas_error ivas_rend_openCrend( hCrend->hReverb = NULL; } +#ifdef FIX_197_CREND_INTERFACE + ( *pCrend )->binaural_latency_ns = (int32_t) ( ( *pCrend )->hHrtfCrend->latency_s * 1000000000.f ); +#else pCrend->binaural_latency_ns = (int32_t) ( pCrend->hHrtfCrend->latency_s * 1000000000.f ); +#endif } +#ifdef FIX_197_CREND_INTERFACE + ( *pCrend )->hCrend = hCrend; +#else pCrend->hCrend = hCrend; +#endif return IVAS_ERR_OK; } @@ -1327,10 +1404,17 @@ ivas_error ivas_rend_initCrend( /* set BRIR flag */ use_brir = false; +#ifdef FIX_197_CREND_INTERFACE + if ( ( ( hRendCfg != NULL ) && hRendCfg->roomAcoustics.use_brir ) || ( ( hRendCfg == NULL ) && ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) ) ) + { + use_brir = true; + } +#else if ( ( hRendCfg != NULL && hRendCfg->roomAcoustics.use_brir ) || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { use_brir = true; } +#endif if ( ( error = getAudioConfigNumChannels( inConfig, &nchan_in ) ) != IVAS_ERR_OK ) @@ -1678,11 +1762,91 @@ ivas_error ivas_rend_initCrend( * Deallocate Crend renderer handle *------------------------------------------------------------------------*/ +#ifdef FIX_197_CREND_INTERFACE +void ivas_rend_closeCrend( + CREND_WRAPPER_HANDLE *pCrend ) +#else ivas_error ivas_rend_closeCrend( CREND_WRAPPER *pCrend ) +#endif { int16_t i; +#ifdef FIX_197_CREND_INTERFACE + if ( pCrend == NULL ) + { + return; + } + + if ( *pCrend == NULL ) + { + return; + } + + if ( ( *pCrend )->hHrtfCrend != NULL ) + { + ivas_hrtf_close( &( *pCrend )->hHrtfCrend ); + } + + if ( ( *pCrend )->hCrend != NULL ) + { + + for ( i = 0; i < MAX_INTERN_CHANNELS; i++ ) + { + if ( ( *pCrend )->hCrend->freq_buffer_re[i] != NULL ) + { + free( ( *pCrend )->hCrend->freq_buffer_re[i] ); + ( *pCrend )->hCrend->freq_buffer_re[i] = NULL; + } + if ( ( *pCrend )->hCrend->freq_buffer_im[i] != NULL ) + { + free( ( *pCrend )->hCrend->freq_buffer_im[i] ); + ( *pCrend )->hCrend->freq_buffer_im[i] = NULL; + } + } + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + if ( ( *pCrend )->hCrend->prev_out_buffer[i] != NULL ) + { + free( ( *pCrend )->hCrend->prev_out_buffer[i] ); + ( *pCrend )->hCrend->prev_out_buffer[i] = NULL; + } + } + + if ( ( *pCrend )->hCrend->lfe_delay_line != NULL ) + { + free( ( *pCrend )->hCrend->lfe_delay_line ); + ( *pCrend )->hCrend->lfe_delay_line = NULL; + } + + if ( ( *pCrend )->hCrend->freq_buffer_re_diffuse != NULL ) + { + free( ( *pCrend )->hCrend->freq_buffer_re_diffuse ); + ( *pCrend )->hCrend->freq_buffer_re_diffuse = NULL; + } + + if ( ( *pCrend )->hCrend->freq_buffer_im_diffuse != NULL ) + { + free( ( *pCrend )->hCrend->freq_buffer_im_diffuse ); + ( *pCrend )->hCrend->freq_buffer_im_diffuse = NULL; + } + + if ( ( *pCrend )->hCrend->hTrack != NULL ) + { + free( ( *pCrend )->hCrend->hTrack ); + ( *pCrend )->hCrend->hTrack = NULL; + } + + ivas_reverb_close( &( *pCrend )->hCrend->hReverb ); + + free( ( *pCrend )->hCrend ); + ( *pCrend )->hCrend = NULL; + free( *pCrend ); + *pCrend = NULL; + } + return; +#else if ( pCrend->hHrtfCrend != NULL ) { ivas_hrtf_close( &pCrend->hHrtfCrend ); @@ -1743,10 +1907,167 @@ ivas_error ivas_rend_closeCrend( free( pCrend->hCrend ); pCrend->hCrend = NULL; } + return IVAS_ERR_OK; +#endif +} + +#ifdef FIX_197_CREND_INTERFACE + +/*-----------------------------------------------------------------------------------------* + * Function ivas_crend_convolver() + * + * Convolver block + *-----------------------------------------------------------------------------------------*/ + +static ivas_error ivas_rend_crendConvolver( + const CREND_WRAPPER *pCrend, + IVAS_REND_AudioConfig inConfig, + IVAS_REND_AudioConfig outConfig, + float pcm_in[][L_FRAME48k], + float pcm_out[][L_FRAME48k], + const int32_t output_Fs, + const int16_t i_ts ) +{ + int16_t i, j, k, m; + int16_t subframe_length, idx_in; + int16_t lfe_idx_in; + int16_t offset, offset_in, offset_diffuse; + int16_t nchan_in, nchan_out; + float *pIn; + float *pFreq_buf_re, *pFreq_buf_im; + float *pFreq_filt_re, *pFreq_filt_im; + float pOut[L_FRAME48k * 2]; + float tmp_out_re[L_FRAME48k], tmp_out_im[L_FRAME48k]; + + getAudioConfigNumChannels( inConfig, &nchan_in ); + getAudioConfigNumChannels( outConfig, &nchan_out ); + + subframe_length = (int16_t) ( output_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES; + + lfe_idx_in = -1; + if ( getAudioConfigType( inConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) + { + if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + lfe_idx_in = LFE_CHANNEL; + } + else + { + assert( 0 && "Custom LS not supported in CRend" ); + } + } + + offset = pCrend->hCrend->delay_line_rw_index * subframe_length; /* subframe_length * ( pCrend->hHrtfCrend->max_num_iterations - 1 ); */ + offset_diffuse = pCrend->hCrend->diffuse_delay_line_rw_index * subframe_length; /* subframe_length *( pCrend->hHrtfCrend->num_iterations_diffuse[0] - 1 ); */ + + if ( pCrend->hHrtfCrend->num_iterations_diffuse[0] > 0 ) + { + set_zero( &pCrend->hCrend->freq_buffer_re_diffuse[offset_diffuse], subframe_length ); + set_zero( &pCrend->hCrend->freq_buffer_im_diffuse[offset_diffuse], subframe_length ); + } + + i = 0; + for ( idx_in = 0; idx_in < nchan_in; idx_in++ ) + { + pIn = &pcm_in[idx_in][i_ts * subframe_length]; + if ( idx_in != lfe_idx_in ) + { + if ( pCrend->hHrtfCrend->num_iterations_diffuse[0] > 0 ) + { + pFreq_buf_re = &pCrend->hCrend->freq_buffer_re_diffuse[offset_diffuse]; + pFreq_buf_im = &pCrend->hCrend->freq_buffer_im_diffuse[offset_diffuse]; + pFreq_filt_re = &pCrend->hCrend->freq_buffer_re[i][offset]; + pFreq_filt_im = &pCrend->hCrend->freq_buffer_im[i][offset]; + + for ( k = 0; k < pCrend->hHrtfCrend->index_frequency_max_diffuse; k++ ) + { + pFreq_buf_re[k] += pFreq_filt_re[k] * pCrend->hHrtfCrend->inv_diffuse_weight[i]; + pFreq_buf_im[k] += pFreq_filt_im[k] * pCrend->hHrtfCrend->inv_diffuse_weight[i]; + } + } + + pFreq_buf_re = &pCrend->hCrend->freq_buffer_re[i][offset]; + pFreq_buf_im = &pCrend->hCrend->freq_buffer_im[i][offset]; + + ivas_mdft( pIn, pFreq_buf_re, pFreq_buf_im, subframe_length, subframe_length ); + i++; + } + } + + for ( j = 0; j < nchan_out; j++ ) + { + set_zero( tmp_out_re, subframe_length ); + set_zero( tmp_out_im, subframe_length ); + + i = 0; + for ( idx_in = 0; idx_in < nchan_in; idx_in++ ) + { + if ( idx_in != lfe_idx_in ) + { + offset = 0; + for ( m = 0; m < pCrend->hHrtfCrend->num_iterations[i][j]; m++ ) + { + offset_in = ( pCrend->hCrend->delay_line_rw_index + pCrend->hHrtfCrend->max_num_iterations - pCrend->hHrtfCrend->num_iterations[i][j] + m + 1 ); + offset_in = offset_in % ( pCrend->hHrtfCrend->max_num_iterations ); + offset_in = offset_in * subframe_length; + pFreq_buf_re = &pCrend->hCrend->freq_buffer_re[i][offset_in]; + pFreq_buf_im = &pCrend->hCrend->freq_buffer_im[i][offset_in]; + pFreq_filt_re = &pCrend->hHrtfCrend->pOut_to_bin_re[i][j][offset]; + pFreq_filt_im = &pCrend->hHrtfCrend->pOut_to_bin_im[i][j][offset]; + + for ( k = 0; k < pCrend->hHrtfCrend->pIndex_frequency_max[i][j][m]; k++ ) + { + tmp_out_re[k] += pFreq_buf_re[k] * pFreq_filt_re[k] - pFreq_buf_im[k] * pFreq_filt_im[k]; + tmp_out_im[k] += pFreq_buf_re[k] * pFreq_filt_im[k] + pFreq_buf_im[k] * pFreq_filt_re[k]; + } + offset = offset + k; + } + i++; + } + } + + offset = 0; + for ( m = 0; m < pCrend->hHrtfCrend->num_iterations_diffuse[j]; m++ ) + { + offset_diffuse = ( pCrend->hCrend->diffuse_delay_line_rw_index + m + 1 ); + offset_diffuse = offset_diffuse % pCrend->hHrtfCrend->num_iterations_diffuse[0]; + offset_diffuse = offset_diffuse * subframe_length; + pFreq_buf_re = &pCrend->hCrend->freq_buffer_re_diffuse[offset_diffuse]; + pFreq_buf_im = &pCrend->hCrend->freq_buffer_im_diffuse[offset_diffuse]; + pFreq_filt_re = &pCrend->hHrtfCrend->pOut_to_bin_diffuse_re[j][offset]; + pFreq_filt_im = &pCrend->hHrtfCrend->pOut_to_bin_diffuse_im[j][offset]; + + for ( k = 0; k < pCrend->hHrtfCrend->pIndex_frequency_max_diffuse[j][m]; k++ ) + { + tmp_out_re[k] += pFreq_buf_re[k] * pFreq_filt_re[k] - pFreq_buf_im[k] * pFreq_filt_im[k]; + tmp_out_im[k] += pFreq_buf_re[k] * pFreq_filt_im[k] + pFreq_buf_im[k] * pFreq_filt_re[k]; + } + offset = offset + k; + } + + ivas_imdft( tmp_out_re, tmp_out_im, pOut, subframe_length ); + + pFreq_buf_re = &pcm_out[j][i_ts * subframe_length]; + for ( k = 0; k < subframe_length; k++ ) + { + pFreq_buf_re[k] = pOut[k] + pCrend->hCrend->prev_out_buffer[j][k]; + pCrend->hCrend->prev_out_buffer[j][k] = pOut[k + subframe_length]; + } + } + + pCrend->hCrend->delay_line_rw_index++; + pCrend->hCrend->delay_line_rw_index = pCrend->hCrend->delay_line_rw_index % ( pCrend->hHrtfCrend->max_num_iterations ); + if ( pCrend->hHrtfCrend->num_iterations_diffuse[0] > 0 ) + { + pCrend->hCrend->diffuse_delay_line_rw_index++; + pCrend->hCrend->diffuse_delay_line_rw_index = pCrend->hCrend->diffuse_delay_line_rw_index % ( pCrend->hHrtfCrend->num_iterations_diffuse[0] ); + } return IVAS_ERR_OK; } +#endif + /*-----------------------------------------------------------------------------------------* * Function ivas_rend_crend_Process() * @@ -1757,10 +2078,20 @@ ivas_error ivas_rend_crendProcess( const CREND_WRAPPER *pCrend, const IVAS_REND_AudioConfig inConfig, const IVAS_REND_AudioConfig outConfig, +#ifdef FIX_197_CREND_INTERFACE + DECODER_CONFIG_HANDLE hDecoderConfig, + HEAD_TRACK_DATA_HANDLE hHeadTrackData, + IVAS_OUTPUT_SETUP_HANDLE hIntSetup, + EFAP_HANDLE hEFAPdata, +#endif float output[][L_FRAME48k], /* i/o: input/output audio channels */ const int32_t output_Fs ) { +#ifdef FIX_197_CREND_INTERFACE + int16_t i, subframe_idx, output_frame, subframe_len; +#else int16_t i, subframe_idx, output_frame; +#endif int16_t nchan_out; float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k]; AUDIO_CONFIG in_config; @@ -1773,9 +2104,49 @@ ivas_error ivas_rend_crendProcess( inConfigType = getAudioConfigType( inConfig ); getAudioConfigNumChannels( outConfig, &nchan_out ); output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); - +#ifdef FIX_197_CREND_INTERFACE + subframe_len = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; +#endif for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { +#ifdef FIX_197_CREND_INTERFACE + if ( hDecoderConfig && hDecoderConfig->Opt_Headrotation && hHeadTrackData && hHeadTrackData->num_quaternions >= 0 ) + { + /* Orientation tracking */ + if ( pCrend->hCrend->hTrack != NULL ) + { + if ( hDecoderConfig->orientation_tracking == IVAS_ORIENT_TRK_AVG ) + { + ivas_orient_trk_SetTrackingType( pCrend->hCrend->hTrack, OTR_TRACKING_AVG_ORIENT ); + } + else + { + ivas_orient_trk_SetTrackingType( pCrend->hCrend->hTrack, OTR_TRACKING_REF_ORIENT ); + } + + /* get current subframe quaternion and convert to euler angles */ + Quat2Euler( hHeadTrackData->Quaternions[subframe_idx], &( pCrend->hCrend->m_fYaw ), &( pCrend->hCrend->m_fPitch ), &( pCrend->hCrend->m_fRoll ) ); + ivas_orient_trk_SetAbsoluteOrientation( pCrend->hCrend->hTrack, pCrend->hCrend->m_fYaw, pCrend->hCrend->m_fPitch, pCrend->hCrend->m_fRoll ); + ivas_orient_trk_Process( pCrend->hCrend->hTrack ); + ivas_orient_trk_GetTrackedOrientation( pCrend->hCrend->hTrack, &( pCrend->hCrend->m_fYaw ), &( pCrend->hCrend->m_fPitch ), &( pCrend->hCrend->m_fRoll ) ); + } + + /* Rotation in SHD for: + MC with elevation (5_1_2 / 5_1_4 / 7_1_4) -> BINAURAL + SBA SPAR -> BINAURAL or BINAURAL_ROOM + */ + if ( in_config == AUDIO_CONFIG_FOA || in_config == AUDIO_CONFIG_HOA2 || in_config == AUDIO_CONFIG_HOA3 ) + { + rotateFrame_shd( hHeadTrackData, output, subframe_len, *hIntSetup, subframe_idx ); + } + /* Rotation in SD for MC -> BINAURAL_ROOM */ + else if ( ( hIntSetup != NULL ) && hIntSetup->is_loudspeaker_setup ) + { + rotateFrame_sd( hHeadTrackData, output, subframe_len, *hIntSetup, hEFAPdata, subframe_idx ); + } + } +#endif + if ( ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) || ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ) { if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, output, pcm_tmp, output_Fs, subframe_idx ) ) != IVAS_ERR_OK ) @@ -1808,6 +2179,8 @@ ivas_error ivas_rend_crendProcess( return IVAS_ERR_OK; } +#ifndef FIX_197_CREND_INTERFACE + /*-----------------------------------------------------------------------------------------* * Function ivas_crend_convolver() * @@ -1960,3 +2333,5 @@ ivas_error ivas_rend_crendConvolver( return IVAS_ERR_OK; } + +#endif diff --git a/lib_rend/ivas_lib_rend_internal.h b/lib_rend/ivas_lib_rend_internal.h index c779916703be646f4789e40497f4672422e0c9fd..3d784d9bb312c0d04c9a78f5c9eeeda3fc46c9c5 100644 --- a/lib_rend/ivas_lib_rend_internal.h +++ b/lib_rend/ivas_lib_rend_internal.h @@ -31,12 +31,17 @@ *******************************************************************************************************/ #include "ivas_error.h" +#ifdef FIX_197_CREND_INTERFACE +#include "ivas_stat_rend.h" +#else #include "lib_rend.h" +#endif #include "ivas_stat_dec.h" #ifndef IVAS_LIB_REND_INTERNALS_H #define IVAS_LIB_REND_INTERNALS_H +#ifndef FIX_197_CREND_INTERFACE typedef struct { int8_t headRotEnabled; @@ -100,6 +105,7 @@ ivas_error ivas_rend_crendConvolver( float pcm_out[][L_FRAME48k], const int32_t output_Fs, const int16_t i_ts ); +#endif ivas_error ivas_rend_TDObjRenderFrame( const TDREND_WRAPPER *pTDRend, /* i : TD Renderer wrapper structure */ diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 3aad7fe5a0e9fe28cfc8285d58970e6f1fdff797..10617d3c62968320d80df317e4ae31827860fc0d 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -245,7 +245,11 @@ void ObjRenderIVASFrame( if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on && ( st_ivas->ini_frame == 0 ) ) { +#ifdef FIX_197_CREND_INTERFACE + ivas_reverb_open( &st_ivas->hCrendWrapper->hCrend->hReverb, st_ivas->transport_config, NULL, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ); +#else ivas_reverb_open( &st_ivas->hCrend->hReverb, st_ivas->transport_config, NULL, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ); +#endif } } @@ -261,7 +265,11 @@ void ObjRenderIVASFrame( if ( ( st_ivas->hRenderConfig != NULL ) && ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) ) { +#ifdef FIX_197_CREND_INTERFACE + ivas_reverb_process( st_ivas->hCrendWrapper->hCrend->hReverb, st_ivas->transport_config, 0, output, reverb_signal, subframe_idx ); +#else ivas_reverb_process( st_ivas->hCrend->hReverb, st_ivas->transport_config, 0, output, reverb_signal, subframe_idx ); +#endif } /* Render subframe */ diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index a38b8d96c1f428dcb1d4d858639fdda1de8d74b8..b710202ce3062fd511fe240d1562b12c7d1e30f8 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -34,10 +34,965 @@ #define IVAS_STAT_REND_H #include +#ifdef FIX_197_CREND_INTERFACE +#include "cnst.h" #include "ivas_cnst.h" +#include "ivas_stat_com.h" +#include "common_api_types.h" // VE2AT: don't we want to avoid this include in the library? I admit that the rules hefre are not 100% clear to me but introducing it just for IVAS_QUATERNION is not necessry I think +#endif #define MAX_SPEAKERS 12 /* Max number of speakers (including LFE) in a channel-based config */ + +#ifdef FIX_197_CREND_INTERFACE + +#define RENDERER_HEAD_POSITIONS_PER_FRAME 4 // todo (Marc) -> renanr IVAS_RENDERER_HEAD_POSITIONS_PER_FRAME ? + +#ifdef REND_CFG_LFE +typedef float IVAS_REND_LfePanMtx[IVAS_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS]; +#endif +typedef struct +{ + int16_t numSamplesPerChannel; + int16_t numChannels; +} IVAS_REND_AudioBufferConfig; + +typedef struct +{ + IVAS_REND_AudioBufferConfig config; + float *data; +} IVAS_REND_AudioBuffer; + +typedef struct +{ + IVAS_REND_AudioBufferConfig config; + const float *data; +} IVAS_REND_ReadOnlyAudioBuffer; + +typedef struct +{ + float azimuth; + float elevation; +} IVAS_REND_AudioObjectPosition; + +typedef struct IVAS_REND *IVAS_REND_HANDLE; +typedef struct IVAS_REND const *IVAS_REND_CONST_HANDLE; + +typedef enum +{ + IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED = 0, + IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS, + IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED, + IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL, + IVAS_REND_AUDIO_CONFIG_TYPE_MASA, + IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN, +} IVAS_REND_AudioConfigType; + +/* TODO(sgi): Harmonize with AUDIO_CONFIG */ +/* + Note: numerical values carry specific information here. + + MSB LSB + -------------------------------------------------------------------------------- + ... unused (assumed all 0) ... | config type (1 byte) | config variant (1 byte) | + -------------------------------------------------------------------------------- + + Where "config type" is the general type from the following list: + - unknown + - channel-based + - ambisonics + - object-based + - binaural + - MASA + + Config variants are concrete configs of each type. + */ +typedef enum +{ + IVAS_REND_AUDIO_CONFIG_MONO = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 0, + IVAS_REND_AUDIO_CONFIG_STEREO = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 1, + IVAS_REND_AUDIO_CONFIG_5_1 = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 2, + IVAS_REND_AUDIO_CONFIG_7_1 = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 3, + IVAS_REND_AUDIO_CONFIG_5_1_2 = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 4, + IVAS_REND_AUDIO_CONFIG_5_1_4 = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 5, + IVAS_REND_AUDIO_CONFIG_7_1_4 = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 6, + IVAS_REND_AUDIO_CONFIG_LS_CUSTOM = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 255, + + IVAS_REND_AUDIO_CONFIG_FOA = IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS << 8 | 0, + IVAS_REND_AUDIO_CONFIG_HOA2 = IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS << 8 | 1, + IVAS_REND_AUDIO_CONFIG_HOA3 = IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS << 8 | 2, + + IVAS_REND_AUDIO_CONFIG_OBJECT = IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED << 8 | 0, + + IVAS_REND_AUDIO_CONFIG_BINAURAL = IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL << 8 | 0, + IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM = IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL << 8 | 1, + + IVAS_REND_AUDIO_CONFIG_MASA1 = IVAS_REND_AUDIO_CONFIG_TYPE_MASA << 8 | 0, + IVAS_REND_AUDIO_CONFIG_MASA2 = IVAS_REND_AUDIO_CONFIG_TYPE_MASA << 8 | 1, + + IVAS_REND_AUDIO_CONFIG_UNKNOWN = IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN << 8 | 0, +} IVAS_REND_AudioConfig; + +typedef uint16_t IVAS_REND_InputId; + +typedef struct +{ + int16_t numLfeChannels; + float lfeOutputGains[IVAS_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS]; +} IVAS_REND_LfeRouting; + +typedef struct +{ + int8_t headRotEnabled; + IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME]; + float crossfade[L_FRAME48k / RENDERER_HEAD_POSITIONS_PER_FRAME]; +} IVAS_REND_HeadRotData; + +/*----------------------------------------------------------------------------------* + * Binaural Rendering structure + *----------------------------------------------------------------------------------*/ +// VE2AT: move to ivas_rom_rend.h ? +/* Binaural reverberator structure */ +typedef struct ivas_binaural_reverb_struct +{ + float *loopBufReal[CLDFB_NO_CHANNELS_MAX]; + float *loopBufImag[CLDFB_NO_CHANNELS_MAX]; + float preDelayBufferReal[REVERB_PREDELAY_MAX + 1][CLDFB_NO_CHANNELS_MAX]; + float preDelayBufferImag[REVERB_PREDELAY_MAX + 1][CLDFB_NO_CHANNELS_MAX]; + float **tapPointersReal[CLDFB_NO_CHANNELS_MAX][BINAURAL_CHANNELS]; + float **tapPointersImag[CLDFB_NO_CHANNELS_MAX][BINAURAL_CHANNELS]; + + float binauralCoherenceCrossmixGains[CLDFB_NO_CHANNELS_MAX]; + float binauralCoherenceDirectGains[CLDFB_NO_CHANNELS_MAX]; + float reverbEqGains[CLDFB_NO_CHANNELS_MAX]; + float loopAttenuationFactor[CLDFB_NO_CHANNELS_MAX]; + + float *outputBufferReal[CLDFB_NO_CHANNELS_MAX][BINAURAL_CHANNELS]; + float *outputBufferImag[CLDFB_NO_CHANNELS_MAX][BINAURAL_CHANNELS]; + + int16_t numBins; + + int16_t useBinauralCoherence; + int16_t loopBufLength[CLDFB_NO_CHANNELS_MAX]; + int16_t loopBufLengthMax[CLDFB_NO_CHANNELS_MAX]; + int16_t preDelayBufferIndex; + int16_t preDelayBufferLength; + + int16_t taps[CLDFB_NO_CHANNELS_MAX][BINAURAL_CHANNELS]; + int16_t *tapPhaseShiftType[CLDFB_NO_CHANNELS_MAX][BINAURAL_CHANNELS]; + + int16_t blockSize; + uint32_t binRend_RandNext; + int16_t highestBinauralCoherenceBin; + + float dmxmtx[BINAURAL_CHANNELS][MAX_OUTPUT_CHANNELS]; + float foa_enc[MAX_OUTPUT_CHANNELS][FOA_CHANNELS]; + +} REVERB_STRUCT, *REVERB_STRUCT_HANDLE; + +/* AGC structure */ +typedef struct ivas_agc_dec_chan_state_t +{ + float lastGain; + int16_t gainExpVal; + +} ivas_agc_dec_chan_state_t; + +typedef struct ivas_agc_dec_state_t +{ + ivas_agc_com_state_t agc_com; + ivas_agc_dec_chan_state_t *gain_state; + ivas_agc_chan_data_t *gain_data; + +} ivas_agc_dec_state_t; + +/* TD decorr */ +typedef struct ivas_td_decorr_APD_filt_state_t +{ + int16_t order[IVAS_MAX_DECORR_APD_SECTIONS]; + int16_t idx[IVAS_MAX_DECORR_APD_SECTIONS]; + float coeffs[IVAS_MAX_DECORR_APD_SECTIONS]; + float *state[IVAS_MAX_DECORR_APD_SECTIONS]; + +} ivas_td_decorr_APD_filt_state_t; + +typedef struct ivas_td_decorr_state_t +{ + ivas_trans_det_state_t *pTrans_det; + float *look_ahead_buf; + ivas_td_decorr_APD_filt_state_t APD_filt_state[IVAS_MAX_DECORR_CHS]; + + int16_t num_apd_outputs; + int16_t num_apd_sections; + int16_t ducking_flag; + +} ivas_td_decorr_state_t; + +/* Parametric binaural data structure */ +typedef struct ivas_dirac_dec_binaural_data_structure +{ + float ChEnePrev[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + float ChCrossRePrev[CLDFB_NO_CHANNELS_MAX]; + float ChCrossImPrev[CLDFB_NO_CHANNELS_MAX]; + float ChEne[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + float ChCrossRe[CLDFB_NO_CHANNELS_MAX]; + float ChCrossIm[CLDFB_NO_CHANNELS_MAX]; + float ChEneOutPrev[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + float ChCrossReOutPrev[CLDFB_NO_CHANNELS_MAX]; + float ChCrossImOutPrev[CLDFB_NO_CHANNELS_MAX]; + float ChEneOut[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + float ChCrossReOut[CLDFB_NO_CHANNELS_MAX]; + float ChCrossImOut[CLDFB_NO_CHANNELS_MAX]; + float processMtxRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS + 1][CLDFB_NO_CHANNELS_MAX]; /* +1 refers to SeparateChannel */ + float processMtxIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS + 1][CLDFB_NO_CHANNELS_MAX]; + float processMtxDecRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + float processMtxDecIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + float diffuseFieldCoherence[CLDFB_NO_CHANNELS_MAX]; + float diffuseFieldCoherenceX[BINAURAL_COHERENCE_DIFFERENCE_BINS]; + float diffuseFieldCoherenceY[BINAURAL_COHERENCE_DIFFERENCE_BINS]; + float diffuseFieldCoherenceZ[BINAURAL_COHERENCE_DIFFERENCE_BINS]; + float earlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX]; + REVERB_STRUCT_HANDLE hReverb; + uint8_t renderStereoOutputInsteadOfBinaural; + float frameMeanDiffuseness[CLDFB_NO_CHANNELS_MAX]; + float processMtxRePrev[BINAURAL_CHANNELS][BINAURAL_CHANNELS + 1][CLDFB_NO_CHANNELS_MAX]; + float processMtxImPrev[BINAURAL_CHANNELS][BINAURAL_CHANNELS + 1][CLDFB_NO_CHANNELS_MAX]; + float processMtxDecRePrev[BINAURAL_CHANNELS][BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + float processMtxDecImPrev[BINAURAL_CHANNELS][BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + uint16_t useSubframeMode; /* 0 = process in 20 ms frames, 1 = process in 5 ms subframes */ + uint16_t useTdDecorr; + ivas_td_decorr_state_t *hTdDecorr; + +} DIRAC_DEC_BIN_DATA, *DIRAC_DEC_BIN_HANDLE; + +typedef struct ivas_binaural_rendering_conv_module_struct +{ + float ***filterTapsLeftReal; + float ***filterTapsLeftImag; + float ***filterTapsRightReal; + float ***filterTapsRightImag; + + float ***filterStatesLeftReal; + float ***filterStatesLeftImag; + + int16_t numTapsArray[BINAURAL_CONVBANDS]; + int16_t numTaps; + +} BINRENDERER_CONV_MODULE, *BINRENDERER_CONV_MODULE_HANDLE; + +/*----------------------------------------------------------------------------------* + * Output configuration for renderer (e.g. DirAC, MASA, Binaural Renderer...) + *----------------------------------------------------------------------------------*/ +typedef struct ivas_output_setup_structure +{ + AUDIO_CONFIG output_config; + int16_t nchan_out_woLFE; /* number of output audio channels without LFE */ + int16_t ambisonics_order; + int8_t is_loudspeaker_setup; + int8_t is_planar_setup; + int8_t is_binaural_setup; + + int16_t num_lfe; + int16_t index_lfe[1]; + const float *ls_azimuth; + const float *ls_elevation; + + uint8_t separateChannelEnabled; + int16_t separateChannelIndex; + +} IVAS_OUTPUT_SETUP, *IVAS_OUTPUT_SETUP_HANDLE; + +/*----------------------------------------------------------------------------------* + * EFAP structures + *----------------------------------------------------------------------------------*/ +// VE2AT: move to ivas_rom_rend.h ? +typedef struct EFAP_VERTEX +{ + float azi; /* azimuth of the loudspeaker */ + float ele; /* elevation of the loudspeaker */ + float pos[3]; /* [x y z] cartesian coordinate vector */ + int16_t idx; /* integer, that corresponds to the first index for the LS in the 1D output */ + int16_t isNaN; /* used to indicate if the vertex is a virtual speaker */ + EFAP_VTX_DMX_TYPE dmxType; /* virtual speaker downmix type */ + +} EFAP_VERTEX; + +typedef struct EFAP_VERTEX_DATA +{ + EFAP_VERTEX *vertexArray; /* Array of vertices */ + int16_t numVtx; /* Number of vertices */ + int16_t *vtxOrder; /* Array that indicates the order of the vertex ranked by increasing azimuth */ + +} EFAP_VERTEX_DATA; + +typedef struct EFAP_POLYSET +{ + int16_t chan[EFAP_MAX_CHAN_NUM]; /* An array indicating the loudspeaker index of the polygon vertices */ + int16_t isNaN[EFAP_MAX_CHAN_NUM]; /* Indicates if one of the vertices isNaN */ + int16_t numChan; /* An integer between 0 and EFAP_MAX_CHAN_NUM corresponding to the number of vertices of the polygon */ + float polyAzi[EFAP_MAX_CHAN_NUM]; /* An array (same length as "chan"), with the azimuth of the channels */ + float polyEle[EFAP_MAX_CHAN_NUM]; /* An array (same length as "chan"), with the elevation of the channels */ + +} EFAP_POLYSET; + +typedef struct EFAP_LS_TRIANGLE +{ + int16_t LS[3]; /* Array indicating the loudspeaker index of the triangle vertices */ + +} EFAP_LS_TRIANGLE; + +typedef struct EFAP_POLYSET_DATA +{ + EFAP_POLYSET polysetArray[EFAP_MAX_POLY_SET]; /* Array of polygons */ + int16_t numPoly; /* Number of polygons */ + EFAP_LS_TRIANGLE triArray[EFAP_MAX_POLY_SET]; /* Array of triangles */ + int16_t numTri; /* Number of triangles */ + +} EFAP_POLYSET_DATA; + +typedef struct EFAP +{ + int16_t numSpk; /* Number of loudspeakers */ + float *aziSpk; /* Loudspeaker azimuths */ + float *eleSpk; /* Loudspeaker elevations */ + EFAP_VERTEX_DATA vtxData; /* Vertex Data, contains all the data concerning the vertex */ + EFAP_POLYSET_DATA polyData; /* Polygon data */ + float **dmTranspose; /* Downmix Matrix used for redistributing the energy of ghosts LS and its transpose */ + float *bufferLong; /* tmp buffer that will be given as a parameter for computing the gain; this is a 1D array of length numVtx */ + float *bufferShort; /* tmp buffer that will be given as a parameter for computing the gain; this is the result of downMixMatrix*bufferLong, length is numSpk */ + int16_t numTot; /* Total number of real + ghost loudspeakers, used later for freeing memory */ + +} EFAP, *EFAP_HANDLE; + + +/*----------------------------------------------------------------------------------* + * VBAP structures + *----------------------------------------------------------------------------------*/ +// VE2AT: move to ivas_rom_rend.h ? +enum SpeakerNodeGroup +{ + SPEAKER_NODE_BOTTOM_HALF, + SPEAKER_NODE_HORIZONTAL, + SPEAKER_NODE_TOP_HALF, + SPEAKER_NODE_BACK, + SPEAKER_NODE_ALL +}; + +/* Defines a single virtual surface triplet of loudspeakers + * with a precalculated inverse matrix */ +typedef struct vbap_vs_triplet_structure +{ + uint8_t speaker_node[3]; + float inverse_matrix[3][3]; + +} VBAP_VS_TRIPLET; + +/* Defines a single speaker node */ +typedef struct vbap_speaker_node_structure +{ + float azi_deg; + float ele_deg; + float unit_vec[3]; + enum SpeakerNodeGroup group; + +} VBAP_SPEAKER_NODE; + +/* Storage structure for fast runtime triplet search */ +typedef struct triplet_search_structure +{ + VBAP_VS_TRIPLET *triplets; + int16_t num_triplets; + int16_t initial_search_indices[VBAP_NUM_SEARCH_SECTORS]; + +} VBAP_SEARCH_STRUCT; + +/* VBAP data structure. Contains the formed virtual surface arrangement * and supporting data. */ +typedef struct vbap_data_structure +{ + VBAP_SEARCH_STRUCT search_struct[2]; /* Default to max two groups in this implementation */ + int16_t num_search_structs; + int16_t num_speaker_nodes; + int16_t num_speaker_nodes_internal; + int16_t top_virtual_speaker_node_index; /* These indices can be negative */ + int16_t bottom_virtual_speaker_node_index; + int16_t back_virtual_speaker_node_index; + float *bottom_virtual_speaker_node_division_gains; + float *top_virtual_speaker_node_division_gains; + float *back_virtual_speaker_node_division_gains; + +} VBAP_DATA, *VBAP_HANDLE; + + +/*----------------------------------------------------------------------------------* + * renderer structures + *----------------------------------------------------------------------------------*/ +// VE2AT: move to ivas_rom_rend.h ? +typedef struct renderer_struct +{ + float prev_gains[MAX_CICP_CHANNELS - 1][MAX_OUTPUT_CHANNELS]; + float interpolator[L_FRAME48k]; + +} ISM_RENDERER_DATA, *ISM_RENDERER_HANDLE; + +/* Fastconv binaural data structure */ +typedef struct ivas_binaural_rendering_struct +{ + /* Common variables for all modules */ + IVAS_OUTPUT_SETUP_HANDLE hInputSetup; /* pointer to input spatial format for binaural renderer*/ + EFAP_HANDLE hEFAPdata; /* EFAP structure*/ + float *hoa_dec_mtx; /* pointer to HOA decoder mtx */ + int8_t rotInCldfb; /* Flag to enable rotation within bin Renderer in CLDFB*/ + int16_t max_band; /* band upto which rendering is performed */ + int16_t conv_band; /* band upto which convolution in cldfb domain is performed */ + int16_t timeSlots; /* number of time slots of binaural renderer */ + int16_t nInChannels; /* number input channels */ + int8_t render_lfe; /* Flag to render LFE in binaural rendering*/ + IVAS_FORMAT ivas_format; /* format; corresponds to st_ivas->ivas_format, unless the signal gets transormed to a different domain for rendering */ + + /* Convolution module structure */ + BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; + + /* Variables related to reverb module */ + float earlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX]; + REVERB_STRUCT_HANDLE hReverb; + +} BINAURAL_RENDERER, *BINAURAL_RENDERER_HANDLE; + + +/*----------------------------------------------------------------------------------* + * Head tracking data structure + *----------------------------------------------------------------------------------*/ +// VE2AT: move to ivas_rom_rend.h ? + +typedef struct ivas_binaural_head_track_struct +{ + int16_t num_quaternions; + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; + float Rmat[3][3]; + float Rmat_prev[3][3]; + + uint8_t lrSwitchedNext; + uint8_t lrSwitchedCurrent; + float lrSwitchInterpVal; + + int16_t shd_rot_max_order; + +} HEAD_TRACK_DATA, *HEAD_TRACK_DATA_HANDLE; + +/* Reverberator structures */ + + +typedef struct ivas_roomAcoustics_t +{ + int16_t override; + int16_t use_brir; + int16_t late_reverb_on; + int16_t nBands; /* Number of frequency bands for which reverb properties are provided, integer, range [2..256] */ + float pFc_input[CLDFB_NO_CHANNELS_MAX]; /* Center frequencies for which following values are provided: */ + float pAcoustic_rt60[CLDFB_NO_CHANNELS_MAX]; /* - The room's T60 per center frequency */ + float pAcoustic_dsr[CLDFB_NO_CHANNELS_MAX]; /* - The room's Diffuse to Source Ratio per center frequency */ + float acousticPreDelay; /* Time elapsed between input signal and late reverberation start, float, range [0.001..10] */ + float inputPreDelay; /* Offset in seconds from where DSR is computed in the RIR (0 = at source), float, range [0.001..10] */ + +} ivas_roomAcoustics_t; + +typedef struct ivas_render_config_t +{ +#ifdef DEBUGGING + ivas_renderTypeOverride renderer_type_override; +#endif + ivas_roomAcoustics_t roomAcoustics; + +} RENDER_CONFIG_DATA, *RENDER_CONFIG_HANDLE; + + +typedef struct ivas_rev_delay_line_t +{ + float *pBuffer; + uint16_t MaxDelay; + int16_t Delay; + uint16_t BufferPos; + float Gain; + +} ivas_rev_delay_line_t; + +typedef struct ivas_rev_iir_filter_t +{ + uint16_t MaxTaps; + uint16_t nr_taps; + uint16_t isFIR; + float Output; + float CoefA[IVAS_REV_MAX_IIR_FILTER_LENGTH]; + float CoefB[IVAS_REV_MAX_IIR_FILTER_LENGTH]; + float pBuffer[IVAS_REV_MAX_IIR_FILTER_LENGTH]; + +} ivas_rev_iir_filter_t; + + +typedef float rv_fftwf_type_complex[2]; /* complex type of fftwf library */ + +/* Convertion block for FFT filter: from time domain to frequency domain (with OLS) and back */ +typedef struct ivas_reverb_t2f_f2t_t +{ + int16_t fft_size; + int16_t log2_fft_size; + int16_t block_size; + int16_t hist_size; /* rv_fft_size - rv_block_size */ + float fft_history_L[RV_FILTER_MAX_HISTORY]; + float fft_history_R[RV_FILTER_MAX_HISTORY]; + +} ivas_reverb_t2f_f2t_t; + +/* FFT filter with its frequency response coefficients */ +typedef struct ivas_reverb_fft_filter_t +{ + int16_t fft_size; + float fft_spectrum[RV_FILTER_MAX_FFT_SIZE]; + +} ivas_reverb_fft_filter_t; + + +typedef struct ivas_reverb_state_t +{ + RENDER_CONFIG_DATA pConfig; + + /* input downmixer: */ + float dmx_gain; /* downmix gain */ + + /* predelay: */ + ivas_rev_delay_line_t predelay_line; + float *pPredelay_buffer; + + /* jot reverberator: */ + uint16_t nr_of_branches; /* number of feedback loops */ + ivas_rev_delay_line_t delay_line[IVAS_REV_MAX_NR_BRANCHES]; /* feedback loop delays */ + float *loop_delay_buffer[IVAS_REV_MAX_NR_BRANCHES]; /* feedback loop delay sample buffers */ + ivas_rev_iir_filter_t t60[IVAS_REV_MAX_NR_BRANCHES]; /* feedback loop filters */ + float gain_matrix[IVAS_REV_MAX_NR_BRANCHES][IVAS_REV_MAX_NR_BRANCHES]; /* feedback matrix */ + float mixer[BINAURAL_CHANNELS][IVAS_REV_MAX_NR_BRANCHES]; /* output mixer matrix */ + + /* binauralization filters: */ + int16_t do_corr_filter; + ivas_reverb_t2f_f2t_t fft_filter_ols; + ivas_reverb_fft_filter_t fft_filter_correl_0; + ivas_reverb_fft_filter_t fft_filter_correl_1; + ivas_reverb_fft_filter_t fft_filter_color_0; + ivas_reverb_fft_filter_t fft_filter_color_1; + uint16_t fft_size; /* fft processing size */ + uint16_t fft_subblock_size; /* fft block processing size */ + uint16_t num_fft_subblocks; /* number of fft subblocks */ + uint16_t full_block_size; /* full block processing size */ + +} REVERB_DATA, *REVERB_HANDLE; + + +typedef struct ivas_orient_trk_state_t +{ + OTR_TRACKING_T trackingType; + float centerAdaptationRate; + float offCenterAdaptationRate; + float adaptationAngle; + + float alpha; + + float absYaw; /* absolute orientation */ + float absPitch; + float absRoll; + + float absAvgYaw; /* average absolute orientation */ + float absAvgPitch; + float absAvgRoll; + + float refYaw; /* reference orientation */ + float refPitch; + float refRoll; + + float trkYaw; /* tracked orientation */ + float trkPitch; + float trkRoll; + +} ivas_orient_trk_state_t; + + +/*----------------------------------------------------------------------------------* + * TD ISm Object Renderer structure + *----------------------------------------------------------------------------------*/ + + +typedef struct +{ + int16_t modelROM; /* Flag that indicates that the model resides in ROM (controls init/dealloc). */ + int16_t UseItdModel; /* Controls whether ITD model is used. */ + int16_t SplineDegree; /* Degree of the spline functions */ + int16_t K; /* Length of filter */ + int16_t elevDim2; + int16_t elevDim3; + int16_t AlphaN; /* Number of rows in Alpha matrices */ + int16_t num_unique_azim_splines; + int16_t elevSegSamples; + + int16_t elevBsLen[HRTF_MODEL_BSPLINE_NUM_COEFFS]; + int16_t elevBsStart[HRTF_MODEL_BSPLINE_NUM_COEFFS]; + const int16_t *azimDim2; + const int16_t *azimDim3; + const int16_t *azim_start_idx; + const int16_t *azimSegSamples; + const int16_t *azimShapeIdx; + const int16_t *azimShapeSampFactor; + + const float *elevKSeq; /* Array, N x elevDim2 x elevDim3 */ + const float *AlphaL; /* Array, size AlphaN x K */ + const float *AlphaR; /* Array, size AlphaN x K */ + const float *elevBsShape; + float **azimKSeq; /* Array, length azimDim3+1 */ + const float **azimBsShape; + + int16_t azimDim3Max; + int16_t iSecFirst[HRTF_MODEL_N_SECTIONS]; /* Indices for start of sections */ + int16_t iSecLast[HRTF_MODEL_N_SECTIONS]; /* Indices for end of sections */ + const float *EL; /* Array, size (AlphaN*HRTF_MODEL_N_SECTIONS) */ + const float *ER; /* Array, size (AlphaN*HRTF_MODEL_N_SECTIONS) */ + + /* Pointers for allocation of dynamic memory */ + float *AlphaL_dyn; + float *AlphaR_dyn; + float *EL_dyn; + float *ER_dyn; + float *elevBsShape_dyn; + float *elevKSeq_dyn; + int16_t *azimDim2_dyn; + int16_t *azimDim3_dyn; + int16_t *azim_start_idx_dyn; + int16_t *azimSegSamples_dyn; + int16_t *azimShapeIdx_dyn; + int16_t *azimShapeSampFactor_dyn; + float **azimBsShape_dyn; + +} ModelParams_t; + +typedef struct +{ + int16_t N; /* Polynomial degree */ + + int16_t elevDim2; + int16_t elevDim3; + const float *elevKSeq; /* Array, length elevDim3-2 */ + int16_t azimDim2; + int16_t azimDim3; + const float *azimKSeq; /* Array, length azimDim3-2 */ + const float *W; /* Array, size (elevDim3*azimDim3) x K */ + + int16_t azimBsLen[HRTF_MODEL_BSPLINE_NUM_COEFFS]; + int16_t azimBsStart[HRTF_MODEL_BSPLINE_NUM_COEFFS]; + const float *azimBsShape; + int16_t azimSegSamples; + + int16_t elevBsLen[HRTF_MODEL_BSPLINE_NUM_COEFFS]; + int16_t elevBsStart[HRTF_MODEL_BSPLINE_NUM_COEFFS]; + const float *elevBsShape; + int16_t elevSegSamples; + float resamp_factor; + + /* Pointers for allocation of dynamic memory */ + float *elevKSeq_dyn; + float *azimKSeq_dyn; + float *W_dyn; + float *azimBsShape_dyn; + float *elevBsShape_dyn; + +} ModelParamsITD_t; + +typedef struct +{ + float val; + int16_t i; + +} ValueIndex_t; + +/* Shared memory for use when evaluating BSpline HR filter model*/ +typedef struct +{ + float BM[HRTF_MODEL_BSPLINE_NUM_COEFFS_SQ]; + ValueIndex_t BMEnergiesL[HRTF_MODEL_BSPLINE_NUM_COEFFS_SQ]; + ValueIndex_t BMEnergiesR[HRTF_MODEL_BSPLINE_NUM_COEFFS_SQ]; + int16_t UseIndsL[HRTF_MODEL_BSPLINE_NUM_COEFFS_SQ]; + int16_t UseIndsR[HRTF_MODEL_BSPLINE_NUM_COEFFS_SQ]; + float *hrfModL; + float *hrfModR; + float elevBfVec[HRTF_MODEL_BSPLINE_NUM_COEFFS]; + float azimBfVec[HRTF_MODEL_BSPLINE_NUM_COEFFS][HRTF_MODEL_BSPLINE_NUM_COEFFS]; + float BM_ITD[HRTF_MODEL_BSPLINE_NUM_COEFFS_SQ]; + float elevBfVecITD[HRTF_MODEL_BSPLINE_NUM_COEFFS]; + float azimBfVecITD[HRTF_MODEL_BSPLINE_NUM_COEFFS]; + float itdMod; + +} ModelEval_t; + +/* Mixer listener */ +typedef struct +{ + int16_t PoseUpdated; + float Pos[3]; + float Front[3]; + float Up[3]; + float Right[3]; + + int16_t VelUpdated; + float Vel[3]; + +} TDREND_MIX_Listener_t; + +/* HR filter */ +typedef struct TDREND_HRFILT_FiltSet_struct +{ + int32_t SampleRate; /* Sample rate of the HR filter */ + int16_t NumPos; + int16_t NumElev; + float Dist; + float *ItdSet_p; + int16_t FiltLength; + float *Azim_p; + float *Elev_p; + float *ItdSetNominal_p; + float *LeftFiltSet_p; + float *RightFiltSet_p; +#ifdef TDREND_HRTF_TABLE_METHODS + int16_t *AzimStartIdx_p; + int16_t *NumAzim_p; + float *ElevFull_p; + float ElevIncr; +#endif + ModelParams_t ModelParams; + ModelEval_t ModelEval; + ModelParamsITD_t ModelParamsITD; + TDREND_HRFILT_Method_t FilterMethod; /* HR filtering method */ + +} TDREND_HRFILT_FiltSet_t; + + +/* Distance attenuation */ +typedef struct +{ + TDREND_DistAttenModel_t DistAttenModel; + float RefDist; + float MaxDist; + float RollOffFactor; + +} TDREND_DistAtten_t; + +/* Directional attenuation */ +typedef struct +{ + float ConeInnerAngle; + float ConeOuterAngle; + float ConeOuterGain; + +} TDREND_DirAtten_t; + +/* Mixer spatial specification */ +typedef struct +{ + int16_t UseCommonDistAttenModel; /* Common distance attenuation model flag */ + TDREND_DistAttenModel_t DistAttenModel; /* Distance attenuation model */ + +} TDREND_MixSpatSpec_t; + + +typedef struct TDREND_SRC_REND_s +{ + int16_t InputAvailable; + TDREND_PlayStatus_t PlayStatus; + + /* Gains */ + int16_t SrcGainUpdated; + float SrcGain_p[SPAT_BIN_MAX_INPUT_CHANNELS]; + float SrcGainMin_p[SPAT_BIN_MAX_INPUT_CHANNELS]; + float SrcGainMax_p[SPAT_BIN_MAX_INPUT_CHANNELS]; + float DirGain_p[SPAT_BIN_MAX_INPUT_CHANNELS]; + float DistGain_p[SPAT_BIN_MAX_INPUT_CHANNELS]; +} TDREND_SRC_REND_t; + + +/* Source spatial parameters */ +typedef struct +{ + int16_t Updated; + TDREND_PosType_t PosType; + float Pos_p[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; + float Front_p[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; + int16_t DirAttenEnabled; + TDREND_DirAtten_t DirAtten; + int16_t DistAttenEnabled; + TDREND_DistAtten_t DistAtten; + +} TDREND_SRC_SPATIAL_t; + +typedef struct +{ + float *InputFrame_p; /* Input frame pointer */ + TDREND_SRC_SPATIAL_t *SrcSpatial_p; + TDREND_SRC_REND_t *SrcRend_p; + int16_t itd; + int16_t previtd; + int16_t filterlength; + float mem_itd[ITD_MEM_LEN]; + float hrf_left_prev[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; /* Todo: Should we allocate these buffers with malloc() instead of the maximum length? */ + float hrf_right_prev[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + float azim_prev; + float elev_prev; + float mem_hrf_left[SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1]; + float mem_hrf_right[SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1]; + float Gain; +} TDREND_SRC_t; + +/* Top level TD binaural renderer handle */ +typedef struct ivas_binaural_td_rendering_struct +{ + TDREND_MixSpatSpec_t *TdRend_MixSpatSpec_p; + TDREND_DirAtten_t *DirAtten_p; + int16_t NumOfSrcs; + int16_t MaxSrcInd; + + TDREND_SRC_t *Sources[MAX_NUM_TDREND_CHANNELS]; + + float Gain; /* Mixer gain */ + TDREND_MIX_Listener_t *Listener_p; /* The virtual listener */ + TDREND_HRFILT_FiltSet_t *HrFiltSet_p; /* HR filter set */ + + int16_t UseCommonDistAttenModel; /* Use common dist atten model (TRUE/FALSE) */ + int16_t DistAttenEnabled; /* (TRUE/FALSE) */ + TDREND_DistAttenModel_t DistAttenModel; /* Common distance attenuation model */ + +} BINAURAL_TD_OBJECT_RENDERER, *BINAURAL_TD_OBJECT_RENDERER_HANDLE; + +/*------------------------------------------------------------------------------------------* + * Crend structures + *------------------------------------------------------------------------------------------*/ +// VE2AT: move to ivas_rom_rend.h ? +typedef struct ivas_hrtfs_structure +{ + float *pOut_to_bin_re[MAX_INTERN_CHANNELS][BINAURAL_CHANNELS]; + float *pOut_to_bin_im[MAX_INTERN_CHANNELS][BINAURAL_CHANNELS]; + float *pOut_to_bin_diffuse_re[BINAURAL_CHANNELS]; + float *pOut_to_bin_diffuse_im[BINAURAL_CHANNELS]; + float latency_s; + uint16_t num_iterations[MAX_INTERN_CHANNELS][BINAURAL_CHANNELS]; + uint16_t num_iterations_diffuse[BINAURAL_CHANNELS]; + uint16_t *pIndex_frequency_max[MAX_INTERN_CHANNELS][BINAURAL_CHANNELS]; + uint16_t *pIndex_frequency_max_diffuse[BINAURAL_CHANNELS]; + uint16_t index_frequency_max_diffuse; + int16_t max_num_ir; + int16_t max_num_iterations; + float inv_diffuse_weight[MAX_INTERN_CHANNELS]; /* inverse diffuse weights array, access one inverse weight by pInvDiffuseWeight[channel] */ + float gain_lfe; + +} HRTFS_DATA, *HRTFS_HANDLE; + + +/* Main Crend structure */ +typedef struct ivas_crend_state_t +{ + float *freq_buffer_re[MAX_INTERN_CHANNELS]; + float *freq_buffer_im[MAX_INTERN_CHANNELS]; + float *freq_buffer_re_diffuse; + float *freq_buffer_im_diffuse; + float *prev_out_buffer[BINAURAL_CHANNELS]; + float *lfe_delay_line; + float m_fYaw; + float m_fPitch; + float m_fRoll; + ivas_orient_trk_state_t *hTrack; + REVERB_HANDLE hReverb; + int16_t delay_line_rw_index; + int16_t diffuse_delay_line_rw_index; + +} CREND_DATA, *CREND_HANDLE; + +/* Main Crend wrapper structure */ +typedef struct ivas_binaural_crend_wrapper_struct +{ + int32_t binaural_latency_ns; + CREND_HANDLE hCrend; + HRTFS_HANDLE hHrtfCrend; +} CREND_WRAPPER, *CREND_WRAPPER_HANDLE; + +/*----------------------------------------------------------------------------------* + * LFE decoder structure + *----------------------------------------------------------------------------------*/ + +typedef struct ivas_lfe_dec_data_structure +{ + ivas_filters_process_state_t filter_state; + LFE_WINDOW_HANDLE pWindow_state; + const uint16_t *cum_freq_models[IVAS_MAX_NUM_QUANT_STRATS][IVAS_MAX_NUM_DCT_COEF_GROUPS]; + int16_t lfe_dec_indices_coeffs_tbl[IVAS_MAX_NUM_QUANT_STRATS][IVAS_MAX_NUM_DCT_COEF_GROUPS]; + float lfe_block_delay_s; + int16_t lfe_prior_buf_len; + float *prior_out_buffer; + + float *prevsynth_buf; + float *lfe_delay_buf; + int16_t lfe_addl_delay; + int16_t bfi_count; + +} LFE_DEC_DATA, *LFE_DEC_HANDLE; + + +/*----------------------------------------------------------------------------------* + * Limiter structure + *----------------------------------------------------------------------------------*/ + +typedef struct +{ + int16_t max_num_channels; + int16_t num_channels; + float **channel_ptrs; + int32_t sampling_rate; + float gain; + float release_heuristic; + float attack_constant; + int16_t strong_saturation_count; +#ifdef DEBUGGING + int32_t cnt_frames_limited; /* counter of frames in which the limiter is applied */ +#endif + +} IVAS_LIMITER, *IVAS_LIMITER_HANDLE; + + +/*----------------------------------------------------------------------------------* + * Decoder configuration structure + *----------------------------------------------------------------------------------*/ + +typedef struct decoder_config_structure +{ + int32_t ivas_total_brate; /* IVAS total bitrate in bps */ + int32_t last_ivas_total_brate; /* last IVAS total bitrate in bps */ + int32_t output_Fs; /* output signal sampling frequency in Hz */ + int16_t nchan_out; /* number of output audio channels */ + AUDIO_CONFIG output_config; /* output audio configuration */ + int16_t Opt_LsCustom; /* indicates whether loudspeaker custom setup is used */ + int16_t Opt_HRTF_binary; /* indicates whether HRTF binary file is used */ + int16_t Opt_Headrotation; /* indicates whether head-rotation is used */ + int16_t orientation_tracking; /* indicates orientation tracking type */ + float no_diegetic_pan; + int16_t Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ + + /* temp. development parameters */ +#ifdef DEBUGGING + int16_t forceSubframeBinauralization; /* Flag for forcing Parametric binauralizer to subframe mode */ + int16_t force_rend; /* forced TD/CLDFB binaural renderer (for ISM and MC) */ +#endif + +} DECODER_CONFIG, *DECODER_CONFIG_HANDLE; + +typedef struct +{ + int32_t binaural_latency_ns; + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd; + TDREND_HRFILT_FiltSet_t *hHrtfTD; +} TDREND_WRAPPER, *TDREND_WRAPPER_HANDLE; +#endif + /*----------------------------------------------------------------------------------* * Loudspeaker Configuration Conversion structure *----------------------------------------------------------------------------------*/ diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index db50f8c16e9a0a976cb355a91ec2cd87ec2a8efa..237838499e880b4f0a53959f2fd783ba0e63607c 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -38,6 +38,9 @@ #include "ivas_rom_dec.h" #include "ivas_rom_rend.h" #include "ivas_lib_rend_internal.h" +#ifdef FIX_197_CREND_INTERFACE +#include "lib_rend.h" +#endif #include "prot.h" #include "wmc_auto.h" @@ -111,7 +114,11 @@ typedef struct IVAS_REND_AudioObjectPosition currentPos; IVAS_REND_AudioObjectPosition previousPos; TDREND_WRAPPER tdRendWrapper; +#ifdef FIX_197_CREND_INTERFACE + CREND_WRAPPER_HANDLE crendWrapper; +#else CREND_WRAPPER crendWrapper; +#endif rotation_matrix rot_mat_prev; } input_ism; @@ -138,7 +145,11 @@ typedef struct LSSETUP_CUSTOM_STRUCT customLsInput; EFAP_WRAPPER efapInWrapper; TDREND_WRAPPER tdRendWrapper; +#ifdef FIX_197_CREND_INTERFACE + CREND_WRAPPER_HANDLE crendWrapper; +#else CREND_WRAPPER crendWrapper; +#endif rotation_gains rot_gains_prev; #ifdef REND_CFG_LFE lfe_routing lfeRouting; @@ -151,7 +162,11 @@ typedef struct { input_base base; pan_matrix hoaDecMtx; +#ifdef FIX_197_CREND_INTERFACE + CREND_WRAPPER_HANDLE crendWrapper; +#else CREND_WRAPPER crendWrapper; +#endif rotation_gains rot_gains_prev; } input_sba; @@ -303,7 +318,11 @@ static int32_t limitRendererOutput( return numClipping; } +#ifdef FIX_197_CREND_INTERFACE +AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( +#else static AUDIO_CONFIG rendAudioConfigToIvasAudioConfig( // VE2AT: similar is defined again at line 397, why? +#endif IVAS_REND_AudioConfig rendConfig ) { switch ( rendConfig ) @@ -449,11 +468,46 @@ ivas_error getAudioConfigNumChannels( return IVAS_ERR_OK; } +#ifdef FIX_197_CREND_INTERFACE +IVAS_REND_AudioConfig getRendAudioConfigFromIvasAudioConfig( + AUDIO_CONFIG config ) +#else AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( IVAS_REND_AudioConfig config ) +#endif { switch ( config ) { +#ifdef FIX_197_CREND_INTERFACE + case AUDIO_CONFIG_MONO: + return IVAS_REND_AUDIO_CONFIG_MONO; + case AUDIO_CONFIG_STEREO: + return IVAS_REND_AUDIO_CONFIG_STEREO; + case AUDIO_CONFIG_BINAURAL: + return IVAS_REND_AUDIO_CONFIG_BINAURAL; + case AUDIO_CONFIG_BINAURAL_ROOM: + return IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM; + case AUDIO_CONFIG_5_1: + return IVAS_REND_AUDIO_CONFIG_5_1; + case AUDIO_CONFIG_7_1: + return IVAS_REND_AUDIO_CONFIG_7_1; + case AUDIO_CONFIG_5_1_2: + return IVAS_REND_AUDIO_CONFIG_5_1_2; + case AUDIO_CONFIG_5_1_4: + return IVAS_REND_AUDIO_CONFIG_5_1_4; + case AUDIO_CONFIG_7_1_4: + return IVAS_REND_AUDIO_CONFIG_7_1_4; + case AUDIO_CONFIG_FOA: + return IVAS_REND_AUDIO_CONFIG_FOA; + case AUDIO_CONFIG_HOA2: + return IVAS_REND_AUDIO_CONFIG_HOA2; + case AUDIO_CONFIG_HOA3: + return IVAS_REND_AUDIO_CONFIG_HOA3; + default: + break; + } + return IVAS_REND_AUDIO_CONFIG_UNKNOWN; +#else case IVAS_REND_AUDIO_CONFIG_MONO: return AUDIO_CONFIG_MONO; case IVAS_REND_AUDIO_CONFIG_STEREO: @@ -481,8 +535,8 @@ AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( default: break; } - return AUDIO_CONFIG_INVALID; +#endif } static ivas_error initLimiter( @@ -1000,7 +1054,11 @@ static ivas_error setRendInputActiveIsm( inputIsm->currentPos = defaultObjectPosition(); inputIsm->previousPos = defaultObjectPosition(); +#ifdef FIX_197_CREND_INTERFACE + inputIsm->crendWrapper = NULL; +#else inputIsm->crendWrapper = defaultCrendWrapper(); +#endif inputIsm->tdRendWrapper = defaultTdRendWrapper(); initRotMatrix( inputIsm->rot_mat_prev ); @@ -1015,6 +1073,9 @@ static ivas_error setRendInputActiveIsm( IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, +#ifdef FIX_197_CREND_INTERFACE + 0, +#endif *rendCtx.pOutSampleRate ); } if ( error != IVAS_ERR_OK ) @@ -1035,7 +1096,11 @@ static void clearInputIsm( initRendInputBase( &inputIsm->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx ); /* Free input's internal handles */ +#ifdef FIX_197_CREND_INTERFACE + if ( inputIsm->crendWrapper != NULL ) +#else if ( inputIsm->crendWrapper.hCrend != NULL ) +#endif { ivas_rend_closeCrend( &inputIsm->crendWrapper ); } @@ -1110,8 +1175,13 @@ static ivas_error initMcPanGainsWithConversionMapping( AUDIO_CONFIG ivasConfigIn, ivasConfigOut; int16_t i; +#ifdef FIX_197_CREND_INTERFACE + ivasConfigIn = getIvasAudioConfigFromRendAudioConfig( inputMc->base.inConfig ); + ivasConfigOut = getIvasAudioConfigFromRendAudioConfig( outConfig ); +#else ivasConfigIn = rendAudioConfigToIvasAudioConfig( inputMc->base.inConfig ); ivasConfigOut = rendAudioConfigToIvasAudioConfig( outConfig ); +#endif /* Find conversion mapping for current I/O config pair. * Stay with default panning matrix if conversion_matrix is NULL */ @@ -1669,7 +1739,11 @@ static ivas_error initMcBinauralRendering( ivas_td_binaural_close( &inputMc->tdRendWrapper.hBinRendererTd ); inputMc->tdRendWrapper.hHrtfTD = NULL; } +#ifdef FIX_197_CREND_INTERFACE + if ( inputMc->crendWrapper != NULL ) +#else if ( inputMc->crendWrapper.hCrend != NULL ) +#endif { ivas_rend_closeCrend( &inputMc->crendWrapper ); } @@ -1709,6 +1783,9 @@ static ivas_error initMcBinauralRendering( ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) ? IVAS_REND_AUDIO_CONFIG_7_1_4 : inConfig, outConfig, hRendCfg, +#ifdef FIX_197_CREND_INTERFACE + 0, +#endif outSampleRate ) ) != IVAS_ERR_OK ) { return error; @@ -1811,7 +1888,11 @@ static ivas_error setRendInputActiveMc( setZeroPanMatrix( inputMc->panGains ); inputMc->customLsInput = defaultCustomLs(); inputMc->tdRendWrapper = defaultTdRendWrapper(); +#ifdef FIX_197_CREND_INTERFACE + inputMc->crendWrapper = NULL; +#else inputMc->crendWrapper = defaultCrendWrapper(); +#endif initRotGains( inputMc->rot_gains_prev ); inputMc->lfeRouting = defaultLfeRouting( inConfig, inputMc->customLsInput, outConfig, *inputMc->base.ctx.pCustomLsOut ); @@ -1845,7 +1926,11 @@ static void clearInputMc( { efap_free_data( &inputMc->efapInWrapper.hEfap ); } +#ifdef FIX_197_CREND_INTERFACE + if ( inputMc->crendWrapper != NULL ) +#else if ( inputMc->crendWrapper.hCrend != NULL ) +#endif { ivas_rend_closeCrend( &inputMc->crendWrapper ); } @@ -1885,7 +1970,11 @@ static ivas_error initSbaPanGainsForMcOut( case IVAS_REND_AUDIO_CONFIG_MONO: hOutSetup.ls_azimuth = ls_azimuth_CICP1; hOutSetup.ls_elevation = ls_elevation_CICP1; +#ifdef FIX_197_CREND_INTERFACE + ivas_output_init( &hOutSetup, getIvasAudioConfigFromRendAudioConfig( outConfig ) ); +#else ivas_output_init( &hOutSetup, rendAudioConfigToIvasAudioConfig( outConfig ) ); +#endif break; case IVAS_REND_AUDIO_CONFIG_STEREO: case IVAS_REND_AUDIO_CONFIG_5_1: @@ -1893,7 +1982,11 @@ static ivas_error initSbaPanGainsForMcOut( case IVAS_REND_AUDIO_CONFIG_5_1_2: case IVAS_REND_AUDIO_CONFIG_5_1_4: case IVAS_REND_AUDIO_CONFIG_7_1_4: +#ifdef FIX_197_CREND_INTERFACE + ivas_output_init( &hOutSetup, getIvasAudioConfigFromRendAudioConfig( outConfig ) ); +#else ivas_output_init( &hOutSetup, rendAudioConfigToIvasAudioConfig( outConfig ) ); +#endif break; case IVAS_REND_AUDIO_CONFIG_LS_CUSTOM: ivas_ls_custom_setup( &hOutSetup, outSetupCustom ); @@ -1973,14 +2066,22 @@ static ivas_error updateSbaPanGains( switch ( outConfig ) { case IVAS_REND_AUDIO_CONFIG_BINAURAL: +#ifdef FIX_197_CREND_INTERFACE + error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, hRendCfg, 0, *rendCtx.pOutSampleRate ); +#else error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, hRendCfg, *rendCtx.pOutSampleRate ); +#endif break; case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: if ( ( error = initSbaPanGainsForMcOut( inputSba, IVAS_REND_AUDIO_CONFIG_7_1_4, NULL ) ) != IVAS_ERR_OK ) { return error; } +#ifdef FIX_197_CREND_INTERFACE + error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, 0, *rendCtx.pOutSampleRate ); +#else error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, *rendCtx.pOutSampleRate ); +#endif break; default: return IVAS_ERR_INVALID_OUTPUT_FORMAT; @@ -2015,7 +2116,11 @@ static ivas_error setRendInputActiveSba( initRendInputBase( &inputSba->base, inConfig, id, rendCtx ); setZeroPanMatrix( inputSba->hoaDecMtx ); +#ifdef FIX_197_CREND_INTERFACE + inputSba->crendWrapper = NULL; +#else inputSba->crendWrapper = defaultCrendWrapper(); +#endif initRotGains( inputSba->rot_gains_prev ); if ( ( error = updateSbaPanGains( inputSba, outConfig, hRendCfg ) ) != IVAS_ERR_OK ) @@ -2036,7 +2141,11 @@ static void clearInputSba( initRendInputBase( &inputSba->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx ); /* Free input's internal handles */ +#ifdef FIX_197_CREND_INTERFACE + if ( inputSba->crendWrapper != NULL ) +#else if ( inputSba->crendWrapper.hCrend != NULL ) +#endif { ivas_rend_closeCrend( &inputSba->crendWrapper ); } @@ -2054,7 +2163,11 @@ static ivas_error initMasaDummyDecForMcOut( input_masa *inputMasa, IVAS_REND_Aud DecoderDummy *decDummy; decDummy = inputMasa->decDummy; +#ifdef FIX_197_CREND_INTERFACE + output_config = getIvasAudioConfigFromRendAudioConfig( outConfig ); +#else output_config = rendAudioConfigToIvasAudioConfig( outConfig ); +#endif decDummy->hDecoderConfig->output_config = output_config; decDummy->hDecoderConfig->ivas_total_brate = IVAS_512k; /* Todo Nokia: This is preventing initialization of 2TC as 1TC, should be fixed properly in ivas_dirac_dec_config() */ @@ -2135,7 +2248,11 @@ static ivas_error initMasaDummyDecForSbaOut( input_masa *inputMasa, IVAS_REND_Au decDummy = inputMasa->decDummy; +#ifdef FIX_197_CREND_INTERFACE + output_config = getIvasAudioConfigFromRendAudioConfig( outConfig ); +#else output_config = rendAudioConfigToIvasAudioConfig( outConfig ); +#endif decDummy->hDecoderConfig->output_config = output_config; decDummy->hDecoderConfig->ivas_total_brate = IVAS_512k; /* Todo Nokia: This is preventing initialization of 2TC as 1TC, should be fixed properly in ivas_dirac_dec_config() */ @@ -2200,7 +2317,11 @@ static ivas_error initMasaDummyDecForBinauralOut( input_masa *inputMasa, IVAS_RE decDummy = inputMasa->decDummy; +#ifdef FIX_197_CREND_INTERFACE + output_config = getIvasAudioConfigFromRendAudioConfig( outConfig ); +#else output_config = rendAudioConfigToIvasAudioConfig( outConfig ); +#endif decDummy->hDecoderConfig->output_config = output_config; output_config = decDummy->hDecoderConfig->output_config; @@ -2303,7 +2424,12 @@ static DecoderDummy *initDecoderDummy( int32_t sampleRate, int16_t numTransChann decDummy->hBinRenderer = NULL; decDummy->hEFAPdata = NULL; +#ifdef FIX_197_CREND_INTERFACE + decDummy->hCrendWrapper = NULL; +#else decDummy->hHrtf = NULL; + decDummy->hCrend = NULL; +#endif decDummy->hHrtfTD = NULL; decDummy->hSpar = NULL; decDummy->hoa_dec_mtx = NULL; @@ -2311,7 +2437,11 @@ static DecoderDummy *initDecoderDummy( int32_t sampleRate, int16_t numTransChann decDummy->hMasa = NULL; decDummy->hDiracDecBin = NULL; decDummy->hQMetaData = NULL; +#ifdef FIX_197_CREND_INTERFACE + decDummy->hDecoderConfig->output_config = getIvasAudioConfigFromRendAudioConfig( outConfig ); +#else decDummy->hDecoderConfig->output_config = rendAudioConfigToIvasAudioConfig( outConfig ); +#endif decDummy->nchan_transport = numTransChannels; if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) @@ -2522,20 +2652,32 @@ ivas_error IVAS_REND_Open( for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { initRendInputBase( &hIvasRend->inputsIsm[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) ); +#ifdef FIX_197_CREND_INTERFACE + hIvasRend->inputsIsm[i].crendWrapper = NULL; +#else hIvasRend->inputsIsm[i].crendWrapper.hCrend = NULL; +#endif hIvasRend->inputsIsm[i].tdRendWrapper.hBinRendererTd = NULL; } for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { initRendInputBase( &hIvasRend->inputsMc[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) ); hIvasRend->inputsMc[i].efapInWrapper.hEfap = NULL; +#ifdef FIX_197_CREND_INTERFACE + hIvasRend->inputsMc[i].crendWrapper = NULL; +#else hIvasRend->inputsMc[i].crendWrapper.hCrend = NULL; +#endif hIvasRend->inputsMc[i].tdRendWrapper.hBinRendererTd = NULL; } for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) { initRendInputBase( &hIvasRend->inputsSba[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) ); +#ifdef FIX_197_CREND_INTERFACE + hIvasRend->inputsSba[i].crendWrapper = NULL; +#else hIvasRend->inputsSba[i].crendWrapper.hCrend = NULL; +#endif } for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { @@ -3251,8 +3393,13 @@ ivas_error IVAS_REND_GetDelay( { if ( hIvasRend->inputsIsm[i].base.inConfig != IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { +#ifdef FIX_197_CREND_INTERFACE + latency_ns = max( hIvasRend->inputsIsm[i].crendWrapper->binaural_latency_ns, + hIvasRend->inputsIsm[i].tdRendWrapper.binaural_latency_ns ); +#else latency_ns = max( hIvasRend->inputsIsm[i].crendWrapper.binaural_latency_ns, hIvasRend->inputsIsm[i].tdRendWrapper.binaural_latency_ns ); +#endif *nSamples = max( *nSamples, NS2SA( *timeScale, latency_ns ) ); } } @@ -3261,8 +3408,13 @@ ivas_error IVAS_REND_GetDelay( { if ( hIvasRend->inputsMc[i].base.inConfig != IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { +#ifdef FIX_197_CREND_INTERFACE + latency_ns = max( hIvasRend->inputsMc[i].crendWrapper->binaural_latency_ns, + hIvasRend->inputsMc[i].tdRendWrapper.binaural_latency_ns ); +#else latency_ns = max( hIvasRend->inputsMc[i].crendWrapper.binaural_latency_ns, hIvasRend->inputsMc[i].tdRendWrapper.binaural_latency_ns ); +#endif *nSamples = max( *nSamples, NS2SA( *timeScale, latency_ns ) ); } } @@ -3271,7 +3423,11 @@ ivas_error IVAS_REND_GetDelay( { if ( hIvasRend->inputsSba[i].base.inConfig != IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { +#ifdef FIX_197_CREND_INTERFACE + latency_ns = hIvasRend->inputsSba[i].crendWrapper->binaural_latency_ns; +#else latency_ns = hIvasRend->inputsSba[i].crendWrapper.binaural_latency_ns; +#endif *nSamples = max( *nSamples, NS2SA( *timeScale, latency_ns ) ); } } @@ -3424,6 +3580,24 @@ ivas_error IVAS_REND_InitConfig( IVAS_REND_HANDLE st, st->rendererConfigEnabled = 0; } +#ifdef FIX_197_CREND_INTERFACE + if ( rendererConfigEnabled ) + { + if ( ( error = ivas_render_config_open( &( st->hRendererConfig ) ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ivas_render_config_init_from_rom( &st->hRendererConfig, st->rendererConfigEnabled ) != IVAS_ERR_OK ) + { + return IVAS_ERR_INTERNAL_FATAL; + } + } + else + { + st->hRendererConfig = NULL; + } +#else if ( ( error = ivas_render_config_open( &( st->hRendererConfig ) ) ) != IVAS_ERR_OK ) { return error; @@ -3433,6 +3607,7 @@ ivas_error IVAS_REND_InitConfig( IVAS_REND_HANDLE st, { return IVAS_ERR_INTERNAL_FATAL; } +#endif return IVAS_ERR_OK; } @@ -3967,7 +4142,11 @@ static ivas_error renderIsmToBinauralRoom( copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); +#ifdef FIX_197_CREND_INTERFACE + ivas_rend_crendProcess( ismInput->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM, NULL, NULL, NULL, NULL, tmpCrendBuffer, *ismInput->base.ctx.pOutSampleRate ); +#else ivas_rend_crendProcess( &ismInput->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM, tmpCrendBuffer, *ismInput->base.ctx.pOutSampleRate ); +#endif accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); @@ -4269,7 +4448,11 @@ static ivas_error renderMcToBinaural( } /* call CREND */ +#ifdef FIX_197_CREND_INTERFACE + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, mcInput->base.inConfig, outConfig, tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -4321,7 +4504,11 @@ static ivas_error renderMcToBinauralRoom( } /* call CREND */ +#ifdef FIX_197_CREND_INTERFACE + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, mcInput->base.inConfig, outConfig, tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -4388,7 +4575,11 @@ static ivas_error renderMcCustomLsToBinauralRoom( copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); /* call CREND */ +#ifdef FIX_197_CREND_INTERFACE + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, NULL, NULL, tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -4616,7 +4807,11 @@ static ivas_error renderSbaToBinaural( } /* call CREND */ +#ifdef FIX_197_CREND_INTERFACE + if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( &sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -4676,7 +4871,11 @@ static ivas_error renderSbaToBinauralRoom( copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); /* call CREND */ +#ifdef FIX_197_CREND_INTERFACE + if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, NULL, NULL, tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( &sbaInput->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -5079,3 +5278,23 @@ int32_t IVAS_REND_GetCntFramesLimited( return hIvasRend->hLimiter->cnt_frames_limited; } #endif + +#ifdef FIX_197_CREND_INTERFACE +ivas_error ivas_rend_initEfap( + AUDIO_CONFIG outConfig, + EFAP_HANDLE *hEfap ) +{ + ivas_error err; + IVAS_REND_AudioConfig audioCfg; + EFAP_WRAPPER wrap; + LSSETUP_CUSTOM_STRUCT customLsOut; + wrap.hEfap = NULL; + wrap.pCustomLsSetup = NULL; + audioCfg = getRendAudioConfigFromIvasAudioConfig( outConfig ); + memset( &customLsOut, 0, sizeof( LSSETUP_CUSTOM_STRUCT ) ); + err = initEfap( &wrap, audioCfg, &customLsOut ); + *hEfap = wrap.hEfap; + + return err; +} +#endif diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 7ef4664ccf8e759b504ba94c4a232e3e9a05664a..c8531881540258577d0ccec924af5cf6f02aca6c 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -40,13 +40,17 @@ #include "options.h" #include "common_api_types.h" #include "ivas_error.h" - +#ifdef FIX_197_CREND_INTERFACE +#include "ivas_stat_rend.h" +#endif #define RENDERER_MAX_ISM_INPUTS 4 #define RENDERER_MAX_MC_INPUTS 1 #define RENDERER_MAX_SBA_INPUTS 1 #define RENDERER_MAX_MASA_INPUTS 1 +#ifndef FIX_197_CREND_INTERFACE + #define RENDERER_HEAD_POSITIONS_PER_FRAME 4 #ifdef REND_CFG_LFE @@ -145,6 +149,13 @@ typedef struct } IVAS_REND_LfeRouting; #endif +#else + +AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( + IVAS_REND_AudioConfig config ); + +#endif + /* clang-format off */ /*----------------------------------------------------------------------------------* * Function prototypes @@ -299,6 +310,12 @@ int32_t IVAS_REND_GetCntFramesLimited( ); #endif +#ifdef FIX_197_CREND_INTERFACE +ivas_error ivas_rend_initEfap( + AUDIO_CONFIG outConfig, + EFAP_HANDLE *hEfap + ); +#endif /* clang-format on */ #endif