diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ef7291844c0db903946df08b6e2dda2a3908f444..3f643add3401f219bf8d6d11e8fbb67b1ee4f173 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -331,7 +331,7 @@ external-renderer-make-pytest: - make -j IVAS_rend - make -j unittests - make -j --directory scripts/td_object_renderer/object_renderer_standalone - - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py + - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py artifacts: name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" when: always @@ -353,7 +353,8 @@ external-renderer-cmake-asan-pytest: - python3 ci/disable_ram_counting.py - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py + - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py + artifacts: name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" when: always @@ -375,7 +376,8 @@ external-renderer-cmake-msan-pytest: - python3 ci/disable_ram_counting.py - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py + - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py + artifacts: name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" when: always @@ -397,7 +399,7 @@ external-renderer-cmake-msan-pytest: script: - cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true -DDEC_TO_REND_FLOAT_DUMP=true - cmake --build cmake-build -- -j - - python3 -m pytest -q --log-level ERROR -n 1 -rA --junit-xml=report-junit.xml tests/renderer/test_renderer_vs_decoder.py + - python3 -m pytest -q -n 1 -rA --junit-xml=report-junit.xml tests/renderer/test_renderer_vs_decoder.py artifacts: name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" when: always diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 7306216378b47fa704882c4e3a42459489f61cda..9d5e02c66fbe976b97e5558deffb6b10b196fe62 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1388,8 +1388,19 @@ typedef enum #define SFX_SPAT_BIN_MAX_FILTER_LENGTH 256 #define SPAT_BIN_MAX_INPUT_CHANNELS 1 /* Max number of input channels per source/object. Mono for now, but stereo objects may be considered. */ - +#ifdef FIX_ITD +#define MAX_ITD 50 +#define SFX_SPAT_BIN_SINC_M 5 +#define SFX_SPAT_BIN_NUM_SUBSAMPLES 64 +#define ITD_MEM_LEN (MAX_ITD + SFX_SPAT_BIN_SINC_M) +#define L_SUBFRAME5MS_48k (L_FRAME48k/4) +#define MAX_ANGULAR_STEP (15.0f) +#define MAX_ANGULAR_STEP_INV ( 1.0f / MAX_ANGULAR_STEP ) +#define MAX_INTERPOLATION_STEPS 12 +#define BINAURAL_TD_LATENCY_S 0.0f /* ITD fix removes TD renderer delay -- should be cleaned out */ +#else #define BINAURAL_TD_LATENCY_S 0.00675f /* Binaural TD renderer latency in second == 324 samples in between 333 and 315 */ +#endif /* ----- Enums - TD Renderer ----- */ diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 7b2ad0a798f30dda411c09418b901c6c1b9065d6..4dfc6c0dfd502fb85dcaa7a5ee1d59af738e6517 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -5004,7 +5004,13 @@ void GetFilterFromAngle( TDREND_HRFILT_FiltSet_t *HrFiltSet_p, /* i/o: HR filter set structure */ const float Elev, /* i : Elevation, degrees */ float Azim, /* i : Azimuth, degrees */ +#ifdef FIX_ITD + float *LeftFilter, /* o : Left HR filter */ + float *RightFilter, /* o : Right HR filter */ + int16_t *itd /* o : ITD value */ +#else SFX_SpatBin_Params_t *SfxSpatBinParams_p /* i/o: Currently used HR filter */ +#endif ); void HRTF_model_precalc( @@ -5029,12 +5035,22 @@ void TDREND_HRFILT_SetFiltSet( ivas_error TDREND_REND_RenderSourceHRFilt( TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ +#ifdef FIX_ITD + const float *hrf_left_delta, /* i: Left filter interpolation delta */ + const float *hrf_right_delta, /* i: Right filter interpolation delta */ + const int16_t intp_count, /* i: Interpolation count */ +#else #ifdef TDREND_HRTF_TABLE_METHODS BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ +#endif #endif float output_buf[][L_SPATIAL_SUBFR_48k], /* o : Output buffer */ +#ifdef FIX_ITD + const int16_t subframe_length /* i : Subframe length in use */ +#else const int16_t subframe_length, /* i : Subframe length in use */ const int32_t output_Fs /* i : Output sample rate */ +#endif ); /* ----- Object renderer - sources ----- */ @@ -5067,7 +5083,20 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ TDREND_SRC_REND_t *SrcRend_p, /* i/o: Source object */ TDREND_SRC_SPATIAL_t *SrcSpatial_p, /* i : Spatial aspects of source */ +#ifdef FIX_ITD + float *hrf_left_prev, /* o: Left filter */ + float *hrf_right_prev, /* o: Right filter */ + float *hrf_left_delta, /* o: Left filter interpolation delta */ + float *hrf_right_delta, /* o: Right filter interpolation delta */ + int16_t *intp_count, /* o: Interpolation count */ + int16_t *filterlength, /* o: Length of filters */ + int16_t *itd, /* o: ITD value */ + float *Gain, /* o: Gain value */ + TDREND_SRC_t *Src_p, + const int16_t subframe_idx /* i : Subframe index to 5 ms subframe */ +#else const int32_t output_Fs /* i : Output sample rate */ +#endif ); ivas_error TDREND_SRC_Alloc( @@ -5080,8 +5109,12 @@ void TDREND_SRC_Dealloc( void TDREND_SRC_Init( TDREND_SRC_t *Src_p, /* i/o: Source to initialize */ +#ifdef FIX_ITD + const TDREND_PosType_t PosType /* i : Position type specifier */ +#else const TDREND_PosType_t PosType, /* i : Position type specifier */ const int32_t output_Fs /* i : Output sampling rate */ +#endif ); /* ----- Object renderer - vec ----- */ @@ -5126,8 +5159,12 @@ int16_t TDREND_SPATIAL_EvalOrthonormOrient( ivas_error TDREND_MIX_AddSrc( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ int16_t *SrcInd, /* o : Source index */ +#ifdef FIX_ITD + const TDREND_PosType_t PosType /* i : Position type (absolute/relative) */ +#else const TDREND_PosType_t PosType, /* i : Position type (absolute/relative) */ const int32_t output_Fs /* i : Output sampling rate */ +#endif ); ivas_error TDREND_MIX_SetDistAttenModel( @@ -5158,7 +5195,7 @@ ivas_error TDREND_MIX_Init( ); /* ----- Object renderer - sfx ----- */ - +#ifndef FIX_ITD ivas_error TDREND_SFX_SpatBin_Initialize( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters handle */ const int32_t output_Fs /* i : Output sampling rate */ @@ -5180,8 +5217,29 @@ void TDREND_SFX_SpatBin_Execute_Main( int16_t *NoOfDeliveredOutputSamples_p, /* o : Number of output samples actually rendered */ const int32_t output_Fs /* i : Output sample rate */ ); +#endif - +#ifdef FIX_ITD +void TDREND_Apply_ITD( + float *input, /* i: Input SCE subframe to be time adjusted */ + float *out_left, /* o: Output left channels with ITD applied */ + float *out_right, /* o: Output right channels with ITD applied */ + int16_t *previtd, /*i/o: Previous ITD value */ + const int16_t itd, /* i: Current subframe ITD value */ + float *mem_itd, /*i/o: ITD buffer memory */ + const int16_t length /* i: Subframe length */ +); + +void TDREND_firfilt( + float *signal, /* i/o: Input signal / Filtered signal */ + float *filter, /* i/o: FIR filter */ + const float *filter_delta, /* i : FIR filter delta */ + const int16_t intp_count, /* i : interpolation count */ + float *mem, /* i/o: filter memory */ + const int16_t subframe_length, /* i : Length of signal */ + const int16_t filterlength /* i : Filter length */ +); +#endif /*----------------------------------------------------------------------------------* * Filter-bank (FB) Mixer *----------------------------------------------------------------------------------*/ diff --git a/lib_com/options.h b/lib_com/options.h old mode 100755 new mode 100644 index d62cb1880b1ed327b96d3f6f32b3afc6e2a12841..a4c706f0ee0d96b66a3406a10803a2e22b5cc28b --- a/lib_com/options.h +++ b/lib_com/options.h @@ -153,6 +153,7 @@ #define FIX_MCT_PLC_RECOVERY /* Issue 184: scale the old synthesis part correctly in the first good frame after lost frames in MCT modes - to be activated after previous switch is merged */ #define SBA_BR_SWITCHING /* Issue 114: Changes for sba bit rate switching*/ #define FIX_AGC_WINFUNC_MEMORY /* Issue 62: lower agc_com.winFunc memory consumption */ +#define FIX_ITD /* Contribution 16: TD renderer ITD improvement and code cleanup */ #define REMOVE_SID_HARM_LEFTOVERS /* Issue 192: remove leftovers from the SID bitrate harmonization */ #define FIX_MCT_UNINIT_MEM /* Issue 166: Reading of uninitialized memory in TCX range coder */ #define FIX_IGF_NOISE_REPETITION /* Issue 182: fix repetition of same noise in IGF */ diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 2393a41f2f5a831f0f03546264bf605e1a9cf536..7e867a7f19c695810a43a32308ff77e79fe4e94b 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1328,6 +1328,8 @@ typedef struct ivas_binaural_head_track_struct /*----------------------------------------------------------------------------------* * TD ISm Object Renderer structure *----------------------------------------------------------------------------------*/ + +#ifndef FIX_ITD // VE2AT: move to ivas_rom_rend.h ? typedef struct { @@ -1391,6 +1393,7 @@ typedef struct TDREND_LIST_Item_s struct TDREND_LIST_Item_s *Next_p; /* Pointer to the next item */ } TDREND_LIST_Item_t; +#endif typedef struct { @@ -1583,10 +1586,10 @@ typedef struct TDREND_SRC_REND_s float SrcGainMax_p[SPAT_BIN_MAX_INPUT_CHANNELS]; float DirGain_p[SPAT_BIN_MAX_INPUT_CHANNELS]; float DistGain_p[SPAT_BIN_MAX_INPUT_CHANNELS]; - +#ifndef FIX_ITD /* HR filtering parameters */ SFX_SpatBin_t *SfxSpatBin_p; - +#endif } TDREND_SRC_REND_t; @@ -1609,7 +1612,19 @@ typedef struct float *InputFrame_p; /* Input frame pointer */ TDREND_SRC_SPATIAL_t *SrcSpatial_p; TDREND_SRC_REND_t *SrcRend_p; - +#ifdef FIX_ITD + 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 count_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; +#endif } TDREND_SRC_t; /* Top level TD binaural renderer handle */ diff --git a/lib_rend/ivas_lib_rend_internal.h b/lib_rend/ivas_lib_rend_internal.h index 94a762c315814b5f06a6ba2c4917213d173e6f73..6a362c8c1c435adff745a447f700cdb92047c9f7 100644 --- a/lib_rend/ivas_lib_rend_internal.h +++ b/lib_rend/ivas_lib_rend_internal.h @@ -109,8 +109,10 @@ ivas_error ivas_rend_TDObjRenderFrame( const IVAS_REND_HeadRotData *headRotData, /* i : Input head positions */ const IVAS_REND_AudioObjectPosition *currentPos, /* i : Object position */ const int16_t output_frame, /* i : output frame length */ - const int32_t output_Fs, /* i : output sampling rate */ - float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ +#ifndef FIX_ITD + const int32_t output_Fs, /* i : output sampling rate */ +#endif + float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ ); ivas_error ivas_rend_TDObjRendOpen( diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 31bc3b5e0a9c705db9e97a5d03627888b362d5cf..1979abe230e67499416989b68fe0e8c4b51a1026 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -50,8 +50,11 @@ * Local function prototypes *---------------------------------------------------------------------*/ +#ifdef FIX_ITD +static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, float output[][L_FRAME48k], const int16_t subframe_length, const int16_t subframe_idx ); +#else static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, float output[][L_FRAME48k], const int16_t subframe_length, const int32_t output_Fs, const int16_t subframe_idx ); - +#endif static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd ); static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, @@ -134,7 +137,11 @@ ivas_error ivas_td_binaural_open( for ( nS = 0; nS < nchan_rend; nS++ ) { +#ifdef FIX_ITD + if ( ( error = TDREND_MIX_AddSrc( hBinRendererTd, &SrcInd[nS], PosType ) ) != IVAS_ERR_OK ) +#else if ( ( error = TDREND_MIX_AddSrc( hBinRendererTd, &SrcInd[nS], PosType, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -281,7 +288,11 @@ void ObjRenderIVASFrame( } /* Render subframe */ +#ifdef FIX_ITD + TDREND_GetMix( st_ivas->hBinRendererTd, output, subframe_length, subframe_idx ); +#else TDREND_GetMix( st_ivas->hBinRendererTd, output, subframe_length, st_ivas->hDecoderConfig->output_Fs, subframe_idx ); +#endif } if ( st_ivas->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ @@ -307,8 +318,10 @@ static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ float output[][L_FRAME48k], /* i/o: ISm object synth / rendered output in 0,1 */ const int16_t subframe_length, /* i/o: subframe length */ - const int32_t output_Fs, /* i : Output sampling rate */ - const int16_t subframe_idx /* i : Subframe index to 5 ms subframe */ +#ifndef FIX_ITD + const int32_t output_Fs, /* i : Output sampling rate */ +#endif + const int16_t subframe_idx /* i : Subframe index to 5 ms subframe */ ) { int16_t i; @@ -317,12 +330,24 @@ static ivas_error TDREND_GetMix( TDREND_SRC_REND_t *SrcRend_p; ivas_error error; float output_buf[2][L_SPATIAL_SUBFR_48k]; /* Temp buffer for left/right rendered signal */ +#ifdef FIX_ITD + float hrf_left_delta[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + float hrf_right_delta[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + int16_t intp_count; +#endif error = IVAS_ERR_OK; /* Clear the output buffer to accumulate rendered sources */ set_f( output_buf[0], 0.0f, subframe_length ); set_f( output_buf[1], 0.0f, subframe_length ); +#ifdef FIX_ITD + /* Clear interpolation buffers and counter */ + set_f( hrf_left_delta, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + set_f( hrf_right_delta, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + intp_count = 0; +#endif + /* Create the mix */ /* Loop through the source list and render each source */ for ( i = 0; i < hBinRendererTd->NumOfSrcs; i++ ) @@ -334,16 +359,25 @@ static ivas_error TDREND_GetMix( /* Update rendering params if needed */ if ( hBinRendererTd->Listener_p->PoseUpdated || SrcSpatial_p->Updated ) { +#ifdef FIX_ITD + TDREND_SRC_REND_UpdateFiltersFromSpatialParams( hBinRendererTd, SrcRend_p, SrcSpatial_p, Src_p->hrf_left_prev, + Src_p->hrf_right_prev, hrf_left_delta, hrf_right_delta, &intp_count, &Src_p->filterlength, &Src_p->itd, &Src_p->Gain, Src_p, subframe_idx ); +#else TDREND_SRC_REND_UpdateFiltersFromSpatialParams( hBinRendererTd, SrcRend_p, SrcSpatial_p, output_Fs ); +#endif } /* Render source if needed */ if ( ( SrcRend_p->InputAvailable == TRUE ) && ( SrcRend_p->PlayStatus == TDREND_PLAYSTATUS_PLAYING ) ) { +#ifdef FIX_ITD + error = TDREND_REND_RenderSourceHRFilt( Src_p, hrf_left_delta, hrf_right_delta, intp_count, output_buf, subframe_length ); +#else #ifdef TDREND_HRTF_TABLE_METHODS error = TDREND_REND_RenderSourceHRFilt( Src_p, hBinRendererTd, output_buf, subframe_length, output_Fs ); #else error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, subframe_length, output_Fs ); +#endif #endif } } @@ -580,7 +614,11 @@ ivas_error ivas_rend_TDObjRendOpen( for ( nS = 0; nS < nchan_rend; nS++ ) { +#ifdef FIX_ITD + if ( ( error = TDREND_MIX_AddSrc( hBinRendererTd, &SrcInd[nS], PosType ) ) != IVAS_ERR_OK ) +#else if ( ( error = TDREND_MIX_AddSrc( hBinRendererTd, &SrcInd[nS], PosType, outFs ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -665,8 +703,10 @@ ivas_error ivas_rend_TDObjRenderFrame( const IVAS_REND_HeadRotData *headRotData, /* i : Input head positions */ const IVAS_REND_AudioObjectPosition *currentPos, /* i : Object position */ const int16_t output_frame, /* i : output frame length */ - const int32_t output_Fs, /* i : output sampling rate */ - float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ +#ifndef FIX_ITD + const int32_t output_Fs, /* i : output sampling rate */ +#endif + float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ ) { int16_t subframe_length; @@ -737,7 +777,11 @@ ivas_error ivas_rend_TDObjRenderFrame( // } /* Render subframe */ +#ifdef FIX_ITD + TDREND_GetMix( pTDRend->hBinRendererTd, output, subframe_length, subframe_idx ); +#else TDREND_GetMix( pTDRend->hBinRendererTd, output, subframe_length, output_Fs, subframe_idx ); +#endif } /* TODO tmu : pass down renderer config struct */ diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index 016d5a60f989e3ed52bfff769025b4762fdd55a1..5269b580b0d74698d24127459f40265a4a6cbc5f 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -344,21 +344,38 @@ void TDREND_HRFILT_SetFiltSet( ivas_error TDREND_REND_RenderSourceHRFilt( TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ +#ifdef FIX_ITD + const float *hrf_left_delta, /* i: Left filter interpolation delta */ + const float *hrf_right_delta, /* i: Right filter interpolation delta */ + const int16_t intp_count, /* i: Interpolation count */ +#else #ifdef TDREND_HRTF_TABLE_METHODS BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ +#endif #endif float output_buf[][L_SPATIAL_SUBFR_48k], /* o : Output buffer */ - const int16_t subframe_length, /* i : Subframe length in use */ - - const int32_t output_Fs /* i : Output sample rate */ +#ifdef FIX_ITD + const int16_t subframe_length /* i : Subframe length in use */ +#else + const int16_t subframe_length, /* i : Subframe length in use */ + const int32_t output_Fs /* i : Output sample rate */ +#endif ) { +#ifndef FIX_ITD TDREND_SRC_REND_t *SrcRend_p; const float *InFrame_nIC_p; int16_t NoOfUsedInputSamples, NoOfDeliveredOutputSamples; +#endif float LeftOutputFrame[L_SPATIAL_SUBFR_48k]; float RightOutputFrame[L_SPATIAL_SUBFR_48k]; +#ifdef FIX_ITD + TDREND_Apply_ITD( Src_p->InputFrame_p, LeftOutputFrame, RightOutputFrame, &Src_p->previtd, Src_p->itd, Src_p->mem_itd, subframe_length ); + TDREND_firfilt( LeftOutputFrame, Src_p->hrf_left_prev, hrf_left_delta, intp_count, Src_p->mem_hrf_left, subframe_length, Src_p->filterlength ); + TDREND_firfilt( RightOutputFrame, Src_p->hrf_right_prev, hrf_right_delta, intp_count, Src_p->mem_hrf_right, subframe_length, Src_p->filterlength ); +#else + /* Input channel rendering loop */ InFrame_nIC_p = Src_p->InputFrame_p; SrcRend_p = Src_p->SrcRend_p; @@ -375,7 +392,7 @@ ivas_error TDREND_REND_RenderSourceHRFilt( SrcRend_p->SfxSpatBin_p->HrFilterInterpOn = 1; /* Turn on after first frame is rendered. */ } #endif - +#endif /* Copy to accumulative output frame */ v_add( LeftOutputFrame, output_buf[0], output_buf[0], subframe_length ); v_add( RightOutputFrame, output_buf[1], output_buf[1], subframe_length ); @@ -698,16 +715,28 @@ static void GetFilterFromAngle_M( #else void GetFilterFromAngle( #endif - TDREND_HRFILT_FiltSet_t *HrFiltSet_p, /* i/o: HR filter set structure */ - const float Elev, /* i : Elevation, degrees */ - float Azim, /* i : Azimuth, degrees */ + TDREND_HRFILT_FiltSet_t *HrFiltSet_p, /* i/o: HR filter set structure */ + const float Elev, /* i : Elevation, degrees */ + float Azim, /* i : Azimuth, degrees */ +#ifdef FIX_ITD + float *hrf_left, /* o : Left HR filter */ + float *hrf_right, /* o : Right HR filter */ + int16_t *itd /* o : ITD value */ +#else SFX_SpatBin_Params_t *SfxSpatBinParams_p /* i/o: Currently used HR filter */ +#endif ) { +#ifndef FIX_ITD int16_t count, ii; +#endif GenerateFilter( Elev, Azim, &HrFiltSet_p->ModelParams, &HrFiltSet_p->ModelEval ); +#ifdef FIX_ITD + mvr2r( HrFiltSet_p->ModelEval.hrfModL, hrf_left, HrFiltSet_p->ModelParams.K ); + mvr2r( HrFiltSet_p->ModelEval.hrfModR, hrf_right, HrFiltSet_p->ModelParams.K ); +#else /* Renderer requires filter in reversed order: */ count = 0; for ( ii = ( HrFiltSet_p->ModelParams.K - 1 ); ii >= 0; ii-- ) @@ -716,16 +745,24 @@ void GetFilterFromAngle( SfxSpatBinParams_p->RightFilter_p[ii] = HrFiltSet_p->ModelEval.hrfModR[count]; count++; } - +#endif /* 4. Evaluate the ITD */ if ( HrFiltSet_p->ModelParams.UseItdModel ) { GenerateITD( Elev, Azim, &HrFiltSet_p->ModelParamsITD, &HrFiltSet_p->ModelEval ); +#ifdef FIX_ITD + *itd = (int16_t) HrFiltSet_p->ModelEval.itdMod; +#else SfxSpatBinParams_p->Itd = HrFiltSet_p->ModelEval.itdMod; +#endif } else { +#ifdef FIX_ITD + *itd = 0; +#else SfxSpatBinParams_p->Itd = 0; /* No extracted ITD */ +#endif } return; diff --git a/lib_rend/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix.c index df190b91b1971ac3bbb9390374f04967fc3e503c..c8e75cfd0451e19cc236d8abad9533e0367d53e6 100644 --- a/lib_rend/ivas_objectRenderer_mix.c +++ b/lib_rend/ivas_objectRenderer_mix.c @@ -290,8 +290,12 @@ ivas_error TDREND_MIX_SetDistAttenModel( ivas_error TDREND_MIX_AddSrc( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ int16_t *SrcInd, /* o : Source index */ - const TDREND_PosType_t PosType, /* i : Position type (absolute/relative) */ - const int32_t output_Fs /* i : Output sampling rate */ +#ifdef FIX_ITD + const TDREND_PosType_t PosType /* i : Position type (absolute/relative) */ +#else + const TDREND_PosType_t PosType, /* i : Position type (absolute/relative) */ + const int32_t output_Fs /* i : Output sampling rate */ +#endif ) { TDREND_SRC_t *Src_p; @@ -323,7 +327,11 @@ ivas_error TDREND_MIX_AddSrc( return error; } +#ifdef FIX_ITD + TDREND_SRC_Init( Src_p, PosType ); +#else TDREND_SRC_Init( Src_p, PosType, output_Fs ); +#endif /* Special OpenAL initialization due to a common distance attenuation model */ if ( hBinRendererTd->DistAttenModel != 0 ) diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index 59c37eb6714b728e59137dd69c01fd40f56c9323..a5f3b58e7a9545696157a16efe98a6675a643163 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -43,15 +43,17 @@ * Local constants *---------------------------------------------------------------------*/ +#ifndef FIX_ITD /* Sinc constants */ #define SFX_SPAT_BIN_SINC_M 5 #define SFX_SPAT_BIN_NUM_SUBSAMPLES_BITS 6 #define SFX_SPAT_BIN_NUM_SUBSAMPLES ( 1 << SFX_SPAT_BIN_NUM_SUBSAMPLES_BITS ) +#endif /*---------------------------------------------------------------------* * Local function prototypes *---------------------------------------------------------------------*/ - +#ifndef FIX_ITD static void TDREND_SFX_SpatBin_SetParamsInitializeOn( SFX_SpatBin_t *SfxSpatBin_p, const SFX_SpatBin_Params_t *NewParam_p, const int32_t output_Fs ); static void TDREND_SFX_SpatBin_SetParamsInitializeOff( SFX_SpatBin_t *SfxSpatBin_p, const SFX_SpatBin_Params_t *NewParam_p, const int32_t output_Fs ); static void TDREND_SFX_SpatBin_SetParamsOn( SFX_SpatBin_t *SfxSpatBin_p, const SFX_SpatBin_Params_t *NewParam_p, const int32_t output_Fs ); @@ -71,8 +73,11 @@ static void TDREND_FirFilterRev( float *OutputFrame_p, float *FirFilterRev_p, co static void TDREND_FirFilterRevInterp( float *OutputFrame_p, float *FirFilterRev_p, const int16_t FirFilterLength, float *InputFrame_p, const int16_t NumOfSamples, float *FilterStored ); #endif static void TDREND_SFX_SpatBin_Clear( SFX_SpatBin_t *SfxSpatBin_p, const int32_t output_Fs ); +#else +static void sincResample( const float *input, float *output, const int16_t length_in, const int16_t length_out ); +#endif - +#ifndef FIX_ITD /*-------------------------------------------------------------------* * TDREND_SFX_SpatBin_Resampling() * @@ -1450,3 +1455,227 @@ static void TDREND_FirFilterRevInterp( return; } #endif +#endif + +#ifdef FIX_ITD +/*---------------------------------------------------------------------* + * TDREND_Apply_ITD() + * + * Apply ITD by delaying late channel + *---------------------------------------------------------------------*/ +void TDREND_Apply_ITD( + float *input, /* i: Input subframe to be time adjusted */ + float *out_left, /* o: Output left channel with ITD applied */ + float *out_right, /* o: Output right channel with ITD applied */ + int16_t *previtd, /*i/o: Previous ITD value */ + const int16_t itd, /* i: Current subframe ITD value */ + float *mem_itd, /*i/o: ITD buffer memory */ + const int16_t length /* i: Subframe length */ +) +{ + int16_t transition_len; + int16_t tlen1, tlen2, tlen3; + int16_t length_in1; + int16_t length_in2; + int16_t currShift; + int16_t prevShift; + float *pstart1; + float *pstart2; + float *pstart3; + float buffer[ITD_MEM_LEN + L_SUBFRAME5MS_48k]; + float *p_input; + float *out_buf_A, *out_buf_B; + + wmops_sub_start( "TDREND_Apply_ITD" ); + + /* Prepare resampling buffer */ + mvr2r( mem_itd, buffer, ITD_MEM_LEN ); /* Retrieve memory */ + p_input = buffer + ITD_MEM_LEN; /* pointer to the current subframe */ + mvr2r( input, p_input, length ); /* input current subframe */ + mvr2r( buffer + length, mem_itd, ITD_MEM_LEN ); /* update memory for next frame */ + + currShift = (int16_t) abs( itd ); + prevShift = (int16_t) abs( *previtd ); + tlen3 = max( 0, SFX_SPAT_BIN_SINC_M - currShift ); /* Make sure there is enough look-ahead for the sinc resampling */ + transition_len = length - tlen3; + + if ( ( ( *previtd ) * itd ) < 0 ) + { + /* ITD sign change - apply shift on both channels */ + tlen1 = (int16_t) ( ( (float) ( transition_len * prevShift ) / ( (float) ( prevShift + currShift ) ) ) + 0.5f ); + tlen2 = transition_len - tlen1; + pstart1 = p_input - prevShift; + length_in1 = tlen1 + prevShift; + pstart2 = pstart1 + length_in1; + length_in2 = tlen2 - currShift; + pstart3 = pstart2 + length_in2; + } + else + { + /* ITD sign stays the same, or one of them is zero */ + tlen1 = transition_len; + tlen2 = 0; + pstart1 = p_input - prevShift; + length_in1 = transition_len + prevShift - currShift; + pstart2 = pstart1 + length_in1; + length_in2 = 0; + pstart3 = pstart2 + length_in2 + currShift; + } + + if ( *previtd == 0 ) + { + if ( itd > 0 ) + { + out_buf_A = out_right; + out_buf_B = out_left; + } + else + { + out_buf_A = out_left; + out_buf_B = out_right; + } + } + else + { + if ( *previtd > 0 ) + { + out_buf_A = out_right; + out_buf_B = out_left; + } + else + { + out_buf_A = out_left; + out_buf_B = out_right; + } + } + + /* Output buffer A */ + sincResample( pstart1, out_buf_A, length_in1, tlen1 ); + mvr2r( pstart2, out_buf_A + tlen1, length - tlen1 ); + + /* Output buffer B */ + mvr2r( p_input, out_buf_B, tlen1 ); + sincResample( pstart2, out_buf_B + tlen1, length_in2, tlen2 ); + mvr2r( pstart3, out_buf_B + transition_len, tlen3 ); + + *previtd = itd; + wmops_sub_end(); + return; +} + +/*---------------------------------------------------------------------* + * sincResample() + * + * Resample signal (stretch/compress) to new ITD + * The sinc resampling reads SFX_SPAT_BIN_SINC_M (5) samples outside of + * the target frame. + *---------------------------------------------------------------------*/ +static void sincResample( + const float *input, /*i : Input signal */ + float *output, /*o : Output signal */ + const int16_t length_in, /*i : Input length */ + const int16_t length_out /*i : Output length */ +) +{ + int16_t snc0; + int16_t i, j; + int16_t t; + float t_frac; + float t_step; + float tmp; + const float *p_mid; + const float *p_forward; + const float *p_backward; + const float *p_sinc_forward; + const float *p_sinc_backward; + + /* Compute fractional time step */ + t_step = (float) ( length_in ) / (float) ( length_out ); + t_frac = 0; + + for ( i = 0; i < length_out; i++ ) + { + t = (int16_t) ( t_frac + EPSILON ); + + /* Calculate the sinc-index for the center value of the sinc */ + snc0 = (int16_t) ( ( t_frac - t + EPSILON ) * SFX_SPAT_BIN_NUM_SUBSAMPLES + 0.5f ); + + /* Run convolution forward and backward from mid point */ + p_mid = input + t; + p_forward = p_mid + 1; + p_backward = p_mid - 1; + p_sinc_forward = SincTable + SFX_SPAT_BIN_NUM_SUBSAMPLES - snc0; + p_sinc_backward = SincTable + SFX_SPAT_BIN_NUM_SUBSAMPLES + snc0; + + tmp = *p_mid * SincTable[snc0]; /* Middle point */ + for ( j = 0; j < SFX_SPAT_BIN_SINC_M - 1; j++ ) + { + tmp += ( *p_forward ) * ( *p_sinc_forward ) + ( *p_backward ) * ( *p_sinc_backward ); + p_sinc_forward += SFX_SPAT_BIN_NUM_SUBSAMPLES; + p_sinc_backward += SFX_SPAT_BIN_NUM_SUBSAMPLES; + p_forward++; + p_backward--; + } + tmp += ( *p_forward ) * ( *p_sinc_forward ); /* Integer index always rounded down --> 4 steps backward, 5 steps forward */ + + output[i] = tmp; + + /* Advance fractional time */ + t_frac += t_step; + } + + return; +} + +/*-------------------------------------------------------------------* + * TDREND_firfilt() + * + * FIR filtering function + * + --------------------------------------------------------------------*/ + +void TDREND_firfilt( + float *signal, /* i/o: Input signal / Filtered signal */ + float *filter, /* i/o: FIR filter */ + const float *filter_delta, /* i : FIR filter delta */ + const int16_t intp_count, /* i : interpolation count */ + float *mem, /* i/o: filter memory */ + const int16_t subframe_length, /* i : Length of signal */ + const int16_t filterlength /* i : Filter length */ +) +{ + float buffer[SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 + L_SUBFRAME5MS_48k]; + float *p_signal; + float *p_tmp; + float *p_filter; + float tmp; + int16_t i, j; + + /* Handle memory */ + p_signal = buffer + filterlength - 1; + mvr2r( mem, buffer, filterlength - 1 ); /* Insert memory */ + mvr2r( signal, buffer + filterlength - 1, subframe_length ); /* Insert current frame */ + mvr2r( signal + subframe_length - filterlength + 1, mem, filterlength - 1 ); /* Update memory for next frame */ + + /* Convolution */ + for ( i = 0; i < subframe_length; i++ ) + { + tmp = 0.0f; + p_tmp = p_signal + i; + p_filter = filter; + for ( j = 0; j < filterlength; j++ ) + { + tmp += ( *p_filter++ ) * ( *p_tmp-- ); + } + signal[i] = tmp; + + if ( i < intp_count ) + { + v_add( filter, filter_delta, filter, filterlength ); + } + } + + return; +} + +#endif diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index a9e88602ca45fd8462e828045321db5bd01dc1a6..fa645f1492f6d3800f3b76e856d0b4e63e67689c 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -50,9 +50,14 @@ static void TDREND_SRC_SPATIAL_SetDirAtten( TDREND_SRC_SPATIAL_t *SrcSpatial_p, static float TDREND_SRC_SPATIAL_GetDirGain( const TDREND_DirAtten_t *DirAtten_p, const float *Front_p, const float *RelPos_p ); static float TDREND_SRC_SPATIAL_GetDistGain( const TDREND_DistAtten_t *DistAtten_p, const float Dist ); static ivas_error TDREND_SRC_REND_Alloc( TDREND_SRC_REND_t **SrcRend_pp ); +#ifndef FIX_ITD static void TDREND_SRC_REND_Dealloc( TDREND_SRC_REND_t *SrcRend_p ); +#endif +#ifdef FIX_ITD +static void TDREND_SRC_REND_Init( TDREND_SRC_REND_t *SrcRend_p ); +#else static void TDREND_SRC_REND_Init( TDREND_SRC_REND_t *SrcRend_p, const int32_t output_Fs ); - +#endif /*-------------------------------------------------------------------* * TDREND_MIX_SRC_SetPos() @@ -192,20 +197,20 @@ static ivas_error TDREND_SRC_REND_Alloc( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "SrcRend_p allocation error\n" ) ); } - +#ifndef FIX_ITD /* Allocate the HR filtering structures */ SrcRend_p->SfxSpatBin_p = (SFX_SpatBin_t *) count_malloc( SPAT_BIN_MAX_INPUT_CHANNELS * sizeof( SFX_SpatBin_t ) ); if ( SrcRend_p->SfxSpatBin_p == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "SrcRend_p->SfxSpatBin_p allocation error\n" ) ); } - +#endif *SrcRend_pp = SrcRend_p; return IVAS_ERR_OK; } - +#ifndef FIX_ITD /*-------------------------------------------------------------------* * TDREND_SRC_REND_Dealloc() * @@ -255,7 +260,7 @@ static void TDREND_SRC_REND_Dealloc( return; } - +#endif /*-------------------------------------------------------------------* * TDREND_SRC_REND_Init() @@ -264,8 +269,12 @@ static void TDREND_SRC_REND_Dealloc( --------------------------------------------------------------------*/ static void TDREND_SRC_REND_Init( +#ifdef FIX_ITD + TDREND_SRC_REND_t *SrcRend_p /* i/o: Source object */ +#else TDREND_SRC_REND_t *SrcRend_p, /* i/o: Source object */ const int32_t output_Fs /* i : Output sampling rate */ +#endif ) { int16_t nC; @@ -293,11 +302,13 @@ static void TDREND_SRC_REND_Init( SrcRend_p->DistGain_p[nC] = 1.0f; } +#ifndef FIX_ITD /* Init the SfxSpatBin structs. One per channel. Default is effect turned off. */ for ( nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) { TDREND_SFX_SpatBin_Initialize( SrcRend_p->SfxSpatBin_p + nC, output_Fs ); } +#endif return; } @@ -313,23 +324,49 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ TDREND_SRC_REND_t *SrcRend_p, /* i/o: Source object */ TDREND_SRC_SPATIAL_t *SrcSpatial_p, /* i : Spatial aspects of source */ - const int32_t output_Fs /* i : Output sampling rate */ +#ifdef FIX_ITD + float *hrf_left_prev, /* o: Left filter */ + float *hrf_right_prev, /* o: Right filter */ + float *hrf_left_delta, /* o: Left filter interpolation delta */ + float *hrf_right_delta, /* o: Right filter interpolation delta */ + int16_t *intp_count, /* o: Interpolation count */ + int16_t *filterlength, /* o: Length of filters */ + int16_t *itd, /* o: ITD value */ + float *Gain, /* o: Gain value */ + TDREND_SRC_t *Src_p, /* i/o: Source pointer */ + const int16_t subframe_idx /* i : Subframe index to 5 ms subframe */ +#else + const int32_t output_Fs /* i : Output sampling rate */ +#endif ) { TDREND_MIX_Listener_t *Listener_p; TDREND_HRFILT_FiltSet_t *HrFiltSet_p; +#ifndef FIX_ITD SFX_SpatBin_t *SfxSpatBin_p; SFX_SpatBin_Params_t SfxSpatBinParams; - +#endif float ListRelPos[3], ListRelDist; +#ifndef FIX_ITD float Gain; +#endif float Azim, Elev; +#ifndef FIX_ITD int16_t mem_size; +#else + float hrf_left[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + float hrf_right[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + float azim_delta; + float elev_delta; +#endif /* Evaluate the HR filters from the source and listener positions and orientations */ Listener_p = hBinRendererTd->Listener_p; HrFiltSet_p = hBinRendererTd->HrFiltSet_p; +#ifdef FIX_ITD + *filterlength = HrFiltSet_p->FiltLength; +#else SfxSpatBinParams.LeftFilter_p = NULL; SfxSpatBinParams.RightFilter_p = NULL; @@ -342,6 +379,7 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( SfxSpatBinParams.FilterLength = HrFiltSet_p->FiltLength; SfxSpatBinParams.LeftFilter_p = (float *) count_malloc( mem_size ); SfxSpatBinParams.RightFilter_p = (float *) count_malloc( mem_size ); +#endif /* 1. Map source pos to the coordinate system of the listener */ switch ( SrcSpatial_p->PosType ) @@ -378,7 +416,11 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( Azim = -1.0f * _180_OVER_PI * (float) atan2f( ListRelPos[1], ListRelPos[0] ); } +#ifdef FIX_ITD + GetFilterFromAngle( HrFiltSet_p, Elev, Azim, hrf_left, hrf_right, itd ); +#else GetFilterFromAngle( HrFiltSet_p, Elev, Azim, &SfxSpatBinParams ); +#endif /* 6. Evaluate the directional and distance gains */ /* Directional gain */ @@ -407,6 +449,35 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( } /* Update total gains */ +#ifdef FIX_ITD + *Gain = ( *SrcRend_p->SrcGain_p ) * ( *SrcRend_p->DirGain_p ) * ( *SrcRend_p->DistGain_p ) * hBinRendererTd->Gain; + + /* Delta for interpolation, in case the angular step exceeds MAX_ANGULAR_STEP */ + elev_delta = Elev - Src_p->elev_prev; + azim_delta = Azim - Src_p->azim_prev; + Src_p->elev_prev = Elev; + Src_p->azim_prev = Azim; + + azim_delta = ( azim_delta > 180.0f ) ? ( azim_delta - 360 ) : ( ( azim_delta < -180.0f ) ? ( azim_delta + 360 ) : ( azim_delta ) ); /* map to -180:180 range */ + *intp_count = min( MAX_INTERPOLATION_STEPS, max( (int16_t) ( fabsf( azim_delta ) * MAX_ANGULAR_STEP_INV ), (int16_t) ( fabsf( elev_delta ) * MAX_ANGULAR_STEP_INV ) ) ); + + if ( ( *intp_count > 0 ) && subframe_idx == 0 ) + { + /* Set deltas for interpolation */ + v_sub( hrf_left, hrf_left_prev, hrf_left_delta, *filterlength ); + v_multc( hrf_left_delta, 1.0f / *intp_count, hrf_left_delta, *filterlength ); + v_sub( hrf_right, hrf_right_prev, hrf_right_delta, *filterlength ); + v_multc( hrf_right_delta, 1.0f / *intp_count, hrf_right_delta, *filterlength ); + } + else + { + /* No interpolation, just set the new filters and reset deltas */ + mvr2r( hrf_left, hrf_left_prev, *filterlength ); + mvr2r( hrf_right, hrf_right_prev, *filterlength ); + set_f( hrf_left_delta, 0.0f, *filterlength ); + set_f( hrf_right_delta, 0.0f, *filterlength ); + } +#else Gain = ( *SrcRend_p->SrcGain_p ) * ( *SrcRend_p->DirGain_p ) * ( *SrcRend_p->DistGain_p ) * hBinRendererTd->Gain; SfxSpatBinParams.LeftVolume = Gain; SfxSpatBinParams.RightVolume = Gain; @@ -426,6 +497,7 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( { count_free( SfxSpatBinParams.RightFilter_p ); } +#endif return; } @@ -700,7 +772,12 @@ void TDREND_SRC_Dealloc( TDREND_SRC_SPATIAL_Dealloc( Src_p->SrcSpatial_p ); /* Delloc the TDREND_SRC_REND__t variable */ +#ifdef FIX_ITD + count_free( Src_p->SrcRend_p ); + Src_p->SrcRend_p = NULL; +#else TDREND_SRC_REND_Dealloc( Src_p->SrcRend_p ); +#endif /* Free the Src_p variable */ count_free( Src_p ); @@ -717,9 +794,13 @@ void TDREND_SRC_Dealloc( --------------------------------------------------------------------*/ void TDREND_SRC_Init( - TDREND_SRC_t *Src_p, /* i/o: Source to initialize */ + TDREND_SRC_t *Src_p, /* i/o: Source to initialize */ +#ifdef FIX_ITD + const TDREND_PosType_t PosType /* i : Position type specifier */ +#else const TDREND_PosType_t PosType, /* i : Position type specifier */ const int32_t output_Fs /* i : Output sampling rate */ +#endif ) { /* Init the TDREND_SRC_Spatial_t variable */ @@ -729,7 +810,29 @@ void TDREND_SRC_Init( } /* Init the TDREND_SRC_REND_t variable */ +#ifdef FIX_ITD + TDREND_SRC_REND_Init( Src_p->SrcRend_p ); +#else TDREND_SRC_REND_Init( Src_p->SrcRend_p, output_Fs ); +#endif + +#ifdef FIX_ITD + /* Reset memory buffers */ + Src_p->itd = 0; + Src_p->previtd = 0; + Src_p->filterlength = -1; + 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; + +#endif return; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index caff4d52c02aa1924e311d883455297a98702921..d766334988c1a9533f86e70a1584e81e60e34c53 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1478,6 +1478,7 @@ static ivas_error updateMcPanGains( return IVAS_ERR_OK; } +#ifndef FIX_ITD #ifndef FIX_I81 /* Fixes initialization issues in TD renderer. Fix to be merged with branch. See issue: https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/-/issues/81 */ @@ -1497,6 +1498,7 @@ static void tmpFixBuggyTdBinRendInit( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRen } } #endif +#endif static ivas_error initMcBinauralRendering( input_mc *inputMc, @@ -1542,8 +1544,10 @@ static ivas_error initMcBinauralRendering( { return error; } +#ifndef FIX_ITD #ifndef FIX_I81 tmpFixBuggyTdBinRendInit( inputMc->tdRendWrapper.hBinRendererTd ); +#endif #endif } @@ -3662,7 +3666,9 @@ static ivas_error renderIsmToBinaural( ismInput->base.ctx.pHeadRotData, &ismInput->currentPos, outAudio.config.numSamplesPerChannel, +#ifndef FIX_ITD *ismInput->base.ctx.pOutSampleRate, +#endif tmpTDRendBuffer ) ) != IVAS_ERR_OK ) { return error; @@ -4002,7 +4008,9 @@ static ivas_error renderMcToBinaural( mcInput->base.ctx.pHeadRotData, NULL, mcInput->base.inputBuffer.config.numSamplesPerChannel, +#ifndef FIX_ITD *mcInput->base.ctx.pOutSampleRate, +#endif tmpRendBuffer ) ) != IVAS_ERR_OK ) { return error; diff --git a/scripts/td_object_renderer/object_renderer_standalone/Makefile b/scripts/td_object_renderer/object_renderer_standalone/Makefile index c8a43fc6f13cbe11cfc278f35a4eca67a2a562e8..42b762bcfe8f83aa3c5b0a375bcac961f08ed57b 100644 --- a/scripts/td_object_renderer/object_renderer_standalone/Makefile +++ b/scripts/td_object_renderer/object_renderer_standalone/Makefile @@ -77,10 +77,6 @@ CFLAGS += -fsanitize=undefined LDFLAGS += -fsanitize=undefined endif - -CFLAGS += -DTDREND_HRTF_TABLE_METHODS -LDFLAGS += -DTDREND_HRTF_TABLE_METHODS - ifeq "$(RELEASE)" "1" CFLAGS += -DRELEASE OPTIM ?= 2 diff --git a/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c b/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c index e34ca952f8383fbdfc29ae9f9ab68ccb703bb1c0..0b386dd4194d5f64110498726e8dbd98427622a9 100644 --- a/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c +++ b/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c @@ -115,7 +115,9 @@ int main( int argc, char *argv[] ) { int16_t nFrameLength; int16_t n, nS, nSamplesRead, i, j; +#ifndef FIX_ITD int16_t offset; +#endif float *MixFrame; float output[MAX_CICP_CHANNELS][L_FRAME48k]; @@ -390,7 +392,17 @@ int main( int argc, char *argv[] ) { output[nS][n] = input_buff[nChannels * n + nS]; } +#ifdef FIX_ITD + /* Pad to full frame length */ + for ( ; n < nFrameLength; n++ ) + { + output[nS][n] = 0; + } +#endif } +#ifdef FIX_ITD + currFrameLength = nFrameLength; +#endif if ( st_ivas->ivas_format == ISM_FORMAT ) { @@ -445,6 +457,8 @@ int main( int argc, char *argv[] ) /* Apply limiter */ ivas_limiter_dec( st_ivas->hLimiter, output, st_ivas->hDecoderConfig->nchan_out, nFrameLength, FALSE ); + +#ifndef FIX_ITD /* Trim first frame to compensate for delay */ if ( nFrameCount == 0 ) { @@ -454,14 +468,23 @@ int main( int argc, char *argv[] ) { offset = 0; } +#endif /* For Wav: Interleave, convert to int16_t */ +#ifdef FIX_ITD + for ( n = 0; n < currFrameLength; n++ ) +#else for ( n = 0; n < ( currFrameLength - offset ); n++ ) +#endif { for ( nS = 0; nS < NumLdspks; nS++ ) { #ifdef FIX_I214_CLIPPING_STANDALONE_REND +#ifdef FIX_ITD + tmp = output[nS][n] + 0.5f * sign( output[nS][n] ); +#else tmp = output[nS][n + offset] + 0.5f * sign( output[nS][n + offset] ); +#endif if ( tmp > MAX16B_FLT ) { tmp = MAX16B_FLT; @@ -473,12 +496,20 @@ int main( int argc, char *argv[] ) noClipping++; } MixFrameWav[n * NumLdspks + nS] = (int16_t) ( tmp ); +#else +#ifdef FIX_ITD + MixFrameWav[n *NumLdspks + nS] = (int16_t) ( output[nS][n] + 0.5f * sign( output[nS][n] ) ); #else MixFrameWav[n * NumLdspks + nS] = (int16_t) ( output[nS][n + offset] + 0.5f * sign( output[nS][n + offset] ) ); +#endif #endif } } +#ifdef FIX_ITD + fwrite( MixFrameWav, sizeof( int16_t ), ( currFrameLength ) * NumLdspks, f_output ); +#else fwrite( MixFrameWav, sizeof( int16_t ), ( currFrameLength - offset ) * NumLdspks, f_output ); +#endif nFrameCount++;