From 7f79519ea51789d952dbc8ec6c841095da072462 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Thu, 10 Nov 2022 14:50:41 +0100 Subject: [PATCH 01/13] Added TD renderer ITD update and cleanup under define FIX_ITD --- lib_com/ivas_cnst.h | 10 +- lib_com/ivas_prot.h | 47 +++++- lib_com/options.h | 2 +- lib_dec/ivas_stat_dec.h | 19 ++- lib_rend/ivas_lib_rend_internal.h | 2 + lib_rend/ivas_objectRenderer.c | 34 +++- lib_rend/ivas_objectRenderer_hrFilt.c | 54 +++++- lib_rend/ivas_objectRenderer_mix.c | 8 + lib_rend/ivas_objectRenderer_sfx.c | 223 ++++++++++++++++++++++++- lib_rend/ivas_objectRenderer_sources.c | 73 +++++++- lib_rend/lib_rend.c | 8 + 11 files changed, 456 insertions(+), 24 deletions(-) diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 0074be76d2..8d2206eefa 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1390,8 +1390,16 @@ 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 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 eac8ec005a..48d9bcb650 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -4992,7 +4992,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_p, /* o : Left HR filter */ + float *RightFilter_p, /* 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( @@ -5021,8 +5027,12 @@ ivas_error TDREND_REND_RenderSourceHRFilt( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ #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 ----- */ @@ -5055,7 +5065,15 @@ 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 *LeftFilter_p, /* o: Left filter */ + float *RightFilter_p, /* o: Right filter */ + int16_t *filterlength, /* o: Length of filters */ + int16_t *itd, /* o: ITD value */ + float *Gain /* o: Gain value */ +#else const int32_t output_Fs /* i : Output sample rate */ +#endif ); ivas_error TDREND_SRC_Alloc( @@ -5068,8 +5086,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 ----- */ @@ -5114,8 +5136,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( @@ -5146,7 +5172,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 */ @@ -5168,8 +5194,27 @@ 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 */ + const float *filter, /* i/o: FIR filter */ + 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 index 7e32d95326..5802a57198 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -151,7 +151,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 /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 50369fab6d..1177a80443 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1324,6 +1324,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 { @@ -1387,6 +1389,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 { @@ -1579,10 +1582,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; @@ -1605,7 +1608,17 @@ 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 hr_filt_left[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; /* Todo: Should we allocate these buffers with count_malloc instead of the maximum length? */ + float hr_filt_right[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + float mem_hr_filt_left[SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1]; + float mem_hr_filt_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 94a762c315..f3a9ca6d87 100644 --- a/lib_rend/ivas_lib_rend_internal.h +++ b/lib_rend/ivas_lib_rend_internal.h @@ -109,7 +109,9 @@ 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 */ +#ifndef FIX_ITD const int32_t output_Fs, /* i : output sampling rate */ +#endif float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ ); diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 31bc3b5e0a..475bc1d5d1 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,7 +318,9 @@ 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 */ +#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 */ ) { @@ -334,7 +347,12 @@ 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->hr_filt_left, + Src_p->hr_filt_right, &Src_p->filterlength, &Src_p->itd, &Src_p->Gain ); +#else TDREND_SRC_REND_UpdateFiltersFromSpatialParams( hBinRendererTd, SrcRend_p, SrcSpatial_p, output_Fs ); +#endif } /* Render source if needed */ @@ -342,8 +360,12 @@ static ivas_error TDREND_GetMix( { #ifdef TDREND_HRTF_TABLE_METHODS error = TDREND_REND_RenderSourceHRFilt( Src_p, hBinRendererTd, output_buf, subframe_length, output_Fs ); +#else +#ifdef FIX_ITD + error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, subframe_length ); #else error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, subframe_length, output_Fs ); +#endif #endif } } @@ -580,7 +602,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,7 +691,9 @@ 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 */ +#ifndef FIX_ITD const int32_t output_Fs, /* i : output sampling rate */ +#endif float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ ) { @@ -737,7 +765,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 016d5a60f9..aed06e1d60 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -348,17 +348,35 @@ ivas_error TDREND_REND_RenderSourceHRFilt( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ #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 ); +#ifdef FIX_ITD_DBG + dbgwrite( LeftOutputFrame, sizeof( float ), subframe_length, 1, "LeftOutputFrame.float" ); + dbgwrite( RightOutputFrame, sizeof( float ), subframe_length, 1, "RightOutputFrame.float" ); +#endif +#ifdef FIX_ITD_DBG + dbgwrite( Src_p->hr_filt_left, sizeof( float ), Src_p->filterlength, 1, "hr_filt_left.float" ); +#endif + TDREND_firfilt( LeftOutputFrame, Src_p->hr_filt_left, Src_p->mem_hr_filt_left, subframe_length, Src_p->filterlength ); + TDREND_firfilt( RightOutputFrame, Src_p->hr_filt_right, Src_p->mem_hr_filt_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 +393,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 +716,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 *LeftFilter_p, /* o : Left HR filter */ + float *RightFilter_p, /* 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, LeftFilter_p, HrFiltSet_p->ModelParams.K ); + mvr2r( HrFiltSet_p->ModelEval.hrfModR, RightFilter_p, 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 +746,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 df190b91b1..81992775bb 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 */ +#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 59c37eb671..cc7d9e45dd 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,217 @@ 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 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; + pstart2 = p_input + tlen1; + length_in1 = tlen1 + prevShift; + length_in2 = tlen2 - currShift; + } + else + { + /* ITD sign stays the same, or one of them is zero */ + tlen1 = transition_len; + tlen2 = 0; + pstart1 = p_input - prevShift; + pstart2 = p_input + tlen1 - currShift; + length_in1 = transition_len + prevShift - currShift; + length_in2 = 0; + } + + 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( input, out_buf_B, tlen1 ); + sincResample( pstart2, out_buf_B + tlen1, length_in2, tlen2 ); + mvr2r( pstart2 + tlen2 + currShift, 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 */ + const float *filter, /* i/o: FIR filter */ + 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; + const 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; + } + + return; +} + +#endif \ No newline at end of file diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index a9e88602ca..6fbcdcda13 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,39 @@ 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 *LeftFilter_p, /* o: Left filter */ + float *RightFilter_p, /* o: Right filter */ + int16_t *filterlength, /* o: Length of filters */ + int16_t *itd, /* o: ITD value */ + float *Gain /* o: Gain value */ +#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; +#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 +369,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 +406,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, LeftFilter_p, RightFilter_p, itd ); +#else GetFilterFromAngle( HrFiltSet_p, Elev, Azim, &SfxSpatBinParams ); +#endif /* 6. Evaluate the directional and distance gains */ /* Directional gain */ @@ -407,6 +439,9 @@ 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; +#else Gain = ( *SrcRend_p->SrcGain_p ) * ( *SrcRend_p->DirGain_p ) * ( *SrcRend_p->DistGain_p ) * hBinRendererTd->Gain; SfxSpatBinParams.LeftVolume = Gain; SfxSpatBinParams.RightVolume = Gain; @@ -426,6 +461,7 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( { count_free( SfxSpatBinParams.RightFilter_p ); } +#endif return; } @@ -700,7 +736,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 ); @@ -718,8 +759,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 ) { /* Init the TDREND_SRC_Spatial_t variable */ @@ -729,7 +774,21 @@ 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_hr_filt_left, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); + set_f( Src_p->mem_hr_filt_right, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); +#endif return; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index ef38d00c19..59b8739c97 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1459,6 +1459,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 */ @@ -1478,6 +1479,7 @@ static void tmpFixBuggyTdBinRendInit( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRen } } #endif +#endif static ivas_error initMcBinauralRendering( input_mc *inputMc, @@ -1523,8 +1525,10 @@ static ivas_error initMcBinauralRendering( { return error; } +#ifndef FIX_ITD #ifndef FIX_I81 tmpFixBuggyTdBinRendInit( inputMc->tdRendWrapper.hBinRendererTd ); +#endif #endif } @@ -3133,7 +3137,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; @@ -3473,7 +3479,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; -- GitLab From bb480125a3ebb0b54d5fdf843d440adcb401bba1 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Thu, 10 Nov 2022 22:20:35 +0100 Subject: [PATCH 02/13] Minor debug code cleanup and comment in options.h --- lib_com/options.h | 2 +- lib_rend/ivas_objectRenderer_hrFilt.c | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 5802a57198..6e56c9853b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -151,7 +151,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 +#define FIX_ITD /* Contribution 16: TD renderer ITD improvement and code cleanup */ /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index aed06e1d60..785bf6ed95 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -366,13 +366,6 @@ ivas_error TDREND_REND_RenderSourceHRFilt( #ifdef FIX_ITD TDREND_Apply_ITD( Src_p->InputFrame_p, LeftOutputFrame, RightOutputFrame, &Src_p->previtd, Src_p->itd, Src_p->mem_itd, subframe_length ); -#ifdef FIX_ITD_DBG - dbgwrite( LeftOutputFrame, sizeof( float ), subframe_length, 1, "LeftOutputFrame.float" ); - dbgwrite( RightOutputFrame, sizeof( float ), subframe_length, 1, "RightOutputFrame.float" ); -#endif -#ifdef FIX_ITD_DBG - dbgwrite( Src_p->hr_filt_left, sizeof( float ), Src_p->filterlength, 1, "hr_filt_left.float" ); -#endif TDREND_firfilt( LeftOutputFrame, Src_p->hr_filt_left, Src_p->mem_hr_filt_left, subframe_length, Src_p->filterlength ); TDREND_firfilt( RightOutputFrame, Src_p->hr_filt_right, Src_p->mem_hr_filt_right, subframe_length, Src_p->filterlength ); #else -- GitLab From 79372ffa88728a354fbe3477ee1c13efa1228acc Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 15 Nov 2022 09:21:12 +0100 Subject: [PATCH 03/13] Disabled TDREND_HRTF_TABLE_METHODS in standalone renderer, not working anymore --- .../td_object_renderer/object_renderer_standalone/Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/scripts/td_object_renderer/object_renderer_standalone/Makefile b/scripts/td_object_renderer/object_renderer_standalone/Makefile index c8a43fc6f1..42b762bcfe 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 -- GitLab From 6b622cc408265ac8d30c4de6c714cc0b65fe0632 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 15 Nov 2022 17:04:05 +0100 Subject: [PATCH 04/13] Cleanup and fix for asan error --- lib_rend/ivas_lib_rend_internal.h | 4 ++-- lib_rend/ivas_objectRenderer.c | 10 +++++----- lib_rend/ivas_objectRenderer_hrFilt.c | 6 +++--- lib_rend/ivas_objectRenderer_mix.c | 6 +++--- lib_rend/ivas_objectRenderer_sfx.c | 13 ++++++++----- lib_rend/ivas_objectRenderer_sources.c | 8 ++++---- 6 files changed, 25 insertions(+), 22 deletions(-) diff --git a/lib_rend/ivas_lib_rend_internal.h b/lib_rend/ivas_lib_rend_internal.h index f3a9ca6d87..6a362c8c1c 100644 --- a/lib_rend/ivas_lib_rend_internal.h +++ b/lib_rend/ivas_lib_rend_internal.h @@ -110,9 +110,9 @@ ivas_error ivas_rend_TDObjRenderFrame( const IVAS_REND_AudioObjectPosition *currentPos, /* i : Object position */ const int16_t output_frame, /* i : output frame length */ #ifndef FIX_ITD - const int32_t output_Fs, /* i : output sampling rate */ + const int32_t output_Fs, /* i : output sampling rate */ #endif - float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ + 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 475bc1d5d1..6d5c49ad61 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -319,9 +319,9 @@ static ivas_error TDREND_GetMix( float output[][L_FRAME48k], /* i/o: ISm object synth / rendered output in 0,1 */ const int16_t subframe_length, /* i/o: subframe length */ #ifndef FIX_ITD - const int32_t output_Fs, /* i : Output sampling rate */ + const int32_t output_Fs, /* i : Output sampling rate */ #endif - const int16_t subframe_idx /* i : Subframe index to 5 ms subframe */ + const int16_t subframe_idx /* i : Subframe index to 5 ms subframe */ ) { int16_t i; @@ -348,7 +348,7 @@ static ivas_error TDREND_GetMix( if ( hBinRendererTd->Listener_p->PoseUpdated || SrcSpatial_p->Updated ) { #ifdef FIX_ITD - TDREND_SRC_REND_UpdateFiltersFromSpatialParams( hBinRendererTd, SrcRend_p, SrcSpatial_p, Src_p->hr_filt_left, + TDREND_SRC_REND_UpdateFiltersFromSpatialParams( hBinRendererTd, SrcRend_p, SrcSpatial_p, Src_p->hr_filt_left, Src_p->hr_filt_right, &Src_p->filterlength, &Src_p->itd, &Src_p->Gain ); #else TDREND_SRC_REND_UpdateFiltersFromSpatialParams( hBinRendererTd, SrcRend_p, SrcSpatial_p, output_Fs ); @@ -692,9 +692,9 @@ ivas_error ivas_rend_TDObjRenderFrame( const IVAS_REND_AudioObjectPosition *currentPos, /* i : Object position */ const int16_t output_frame, /* i : output frame length */ #ifndef FIX_ITD - const int32_t output_Fs, /* i : output sampling rate */ + const int32_t output_Fs, /* i : output sampling rate */ #endif - float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ + float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ ) { int16_t subframe_length; diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index 785bf6ed95..93c7eb96cc 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -349,10 +349,10 @@ ivas_error TDREND_REND_RenderSourceHRFilt( #endif float output_buf[][L_SPATIAL_SUBFR_48k], /* o : Output buffer */ #ifdef FIX_ITD - const int16_t subframe_length /* i : Subframe length in use */ + 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 */ + const int16_t subframe_length, /* i : Subframe length in use */ + const int32_t output_Fs /* i : Output sample rate */ #endif ) { diff --git a/lib_rend/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix.c index 81992775bb..c8e75cfd04 100644 --- a/lib_rend/ivas_objectRenderer_mix.c +++ b/lib_rend/ivas_objectRenderer_mix.c @@ -291,10 +291,10 @@ 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) */ + 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 */ + const TDREND_PosType_t PosType, /* i : Position type (absolute/relative) */ + const int32_t output_Fs /* i : Output sampling rate */ #endif ) { diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index cc7d9e45dd..1da7c671cc 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -1481,6 +1481,7 @@ void TDREND_Apply_ITD( 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; @@ -1504,9 +1505,10 @@ void TDREND_Apply_ITD( tlen1 = (int16_t) ( ( (float) ( transition_len * prevShift ) / ( (float) ( prevShift + currShift ) ) ) + 0.5f ); tlen2 = transition_len - tlen1; pstart1 = p_input - prevShift; - pstart2 = p_input + tlen1; length_in1 = tlen1 + prevShift; + pstart2 = pstart1 + length_in1; length_in2 = tlen2 - currShift; + pstart3 = pstart2 + length_in2; } else { @@ -1514,9 +1516,10 @@ void TDREND_Apply_ITD( tlen1 = transition_len; tlen2 = 0; pstart1 = p_input - prevShift; - pstart2 = p_input + tlen1 - currShift; length_in1 = transition_len + prevShift - currShift; + pstart2 = pstart1 + length_in1; length_in2 = 0; + pstart3 = pstart2 + length_in2; } if ( *previtd == 0 ) @@ -1551,9 +1554,9 @@ void TDREND_Apply_ITD( mvr2r( pstart2, out_buf_A + tlen1, length - tlen1 ); /* Output buffer B */ - mvr2r( input, out_buf_B, tlen1 ); + mvr2r( p_input, out_buf_B, tlen1 ); sincResample( pstart2, out_buf_B + tlen1, length_in2, tlen2 ); - mvr2r( pstart2 + tlen2 + currShift, out_buf_B + transition_len, tlen3 ); + mvr2r( pstart3, out_buf_B + transition_len, tlen3 ); *previtd = itd; wmops_sub_end(); @@ -1668,4 +1671,4 @@ void TDREND_firfilt( return; } -#endif \ No newline at end of file +#endif diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index 6fbcdcda13..5b3ab93bfb 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -270,7 +270,7 @@ 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 */ + 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 */ @@ -331,7 +331,7 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( int16_t *itd, /* o: ITD value */ float *Gain /* o: Gain value */ #else - const int32_t output_Fs /* i : Output sampling rate */ + const int32_t output_Fs /* i : Output sampling rate */ #endif ) { @@ -758,9 +758,9 @@ 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 */ + 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 */ -- GitLab From 5d069af806fe9173fa49ac2e449af8b9af4890d1 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 15 Nov 2022 17:22:17 +0100 Subject: [PATCH 05/13] clang format applied --- lib_rend/ivas_objectRenderer_sfx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index 1da7c671cc..51306a9927 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -1524,7 +1524,7 @@ void TDREND_Apply_ITD( if ( *previtd == 0 ) { - if (itd > 0) + if ( itd > 0 ) { out_buf_A = out_right; out_buf_B = out_left; @@ -1532,7 +1532,7 @@ void TDREND_Apply_ITD( else { out_buf_A = out_left; - out_buf_B = out_right; + out_buf_B = out_right; } } else -- GitLab From 0a1d696201cb53853425da5cd95dcfa5cccfd424 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 15 Nov 2022 17:53:12 +0100 Subject: [PATCH 06/13] Fix in regexp for renderer non-be tag --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 67e815cded..e2db5e0e49 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -420,7 +420,7 @@ external-renderer-pytest-on-merge-request: - *print-common-info # some helper variables - "|| true" to prevent failures from grep not finding anything - - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[rend(erer)*[ -]*non[ -]*be\]") || true + - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[rend\(erer\)*[ -]*non[ -]*be\]") || true # TODO: needs splitting the test between reference and cut generation #- ref_using_main=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[ref[ -]*using[ -]*main\]") || true -- GitLab From 5d44874747988f0653699692d242ab42a18eaf01 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 15 Nov 2022 18:24:39 +0100 Subject: [PATCH 07/13] Trying fixes for external-renderer msan and asan --- .gitlab-ci.yml | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e2db5e0e49..1b35bf5cd7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -349,10 +349,23 @@ external-renderer-cmake-asan-pytest: needs: ["build-codec-linux-cmake"] stage: test script: + + - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[rend\(erer\)*[ -]*non[ -]*be\]") || true + - 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 + + # run test + - exit_code=0 + - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py || exit_code=$? + - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true + + - *merge-request-comparison-check + + allow_failure: + exit_codes: + - 123 artifacts: name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" when: always @@ -371,10 +384,23 @@ external-renderer-cmake-msan-pytest: needs: ["build-codec-linux-cmake"] stage: test script: + + - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[rend\(erer\)*[ -]*non[ -]*be\]") || true + - 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 + + # run test + - exit_code=0 + - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py || exit_code=$? + - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true + + - *merge-request-comparison-check + + allow_failure: + exit_codes: + - 123 artifacts: name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" when: always -- GitLab From d40479813d68f3ea5a7f5868ff25dae39bb4300d Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 15 Nov 2022 19:14:01 +0100 Subject: [PATCH 08/13] Fixes for external-renderer-make-pytest --- .gitlab-ci.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1b35bf5cd7..08902ecbe1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -327,10 +327,24 @@ external-renderer-make-pytest: needs: ["build-codec-linux-make"] stage: test script: + + - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[rend\(erer\)*[ -]*non[ -]*be\]") || true + - 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 + + # run test + - exit_code=0 + - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py || exit_code=$? + - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true + + - *merge-request-comparison-check + + allow_failure: + exit_codes: + - 123 + artifacts: name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" when: always -- GitLab From 7f9f24a4ac74b65abd647b28d30d9c19ef3f70a1 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Wed, 16 Nov 2022 09:56:24 +0100 Subject: [PATCH 09/13] Small fix in buffer --- lib_rend/ivas_objectRenderer_sfx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index 51306a9927..1b936f1672 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -1519,7 +1519,7 @@ void TDREND_Apply_ITD( length_in1 = transition_len + prevShift - currShift; pstart2 = pstart1 + length_in1; length_in2 = 0; - pstart3 = pstart2 + length_in2; + pstart3 = pstart2 + length_in2 + currShift; } if ( *previtd == 0 ) -- GitLab From 0e1e6e9636f7dc095cd637ae4785c48c072a8870 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Wed, 16 Nov 2022 13:36:53 +0100 Subject: [PATCH 10/13] Correct delay compensation in standalone renderer with FIX_ITD --- .../renderer_standalone.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) 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 b2963093a2..0cc698e7b0 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]; @@ -433,6 +435,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 ) { @@ -442,16 +446,29 @@ 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_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 } } +#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++; -- GitLab From fc0dbc7fc475a6c21db36de7157e52225fd04004 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 16 Nov 2022 13:44:00 +0100 Subject: [PATCH 11/13] [tests] remove restriction on logging level for renderer pytests --- .gitlab-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 08902ecbe1..a1aae1146b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -336,7 +336,7 @@ external-renderer-make-pytest: # run test - exit_code=0 - - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py || exit_code=$? + - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py || exit_code=$? - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true - *merge-request-comparison-check @@ -372,7 +372,7 @@ external-renderer-cmake-asan-pytest: # run test - exit_code=0 - - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py || exit_code=$? + - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py || exit_code=$? - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true - *merge-request-comparison-check @@ -407,7 +407,7 @@ external-renderer-cmake-msan-pytest: # run test - exit_code=0 - - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py || exit_code=$? + - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py || exit_code=$? - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true - *merge-request-comparison-check @@ -436,7 +436,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 @@ -482,7 +482,7 @@ external-renderer-pytest-on-merge-request: # run test - exit_code=0 - - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer_be_comparison.py || exit_code=$? + - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer_be_comparison.py || exit_code=$? - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true - *merge-request-comparison-check -- GitLab From 136b721f5001109b7d6d007e8713a262d58ed17b Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Wed, 16 Nov 2022 13:45:20 +0100 Subject: [PATCH 12/13] Revert updates to .gitlab-ci.yml where the intended comparison is within the same revision --- .gitlab-ci.yml | 46 +++------------------------------------------- 1 file changed, 3 insertions(+), 43 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 08902ecbe1..e2db5e0e49 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -327,24 +327,10 @@ external-renderer-make-pytest: needs: ["build-codec-linux-make"] stage: test script: - - - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[rend\(erer\)*[ -]*non[ -]*be\]") || true - - make -j IVAS_rend - make -j unittests - make -j --directory scripts/td_object_renderer/object_renderer_standalone - - # run test - - exit_code=0 - - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py || exit_code=$? - - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true - - - *merge-request-comparison-check - - allow_failure: - exit_codes: - - 123 - + - python3 -m pytest -q --log-level ERROR -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 @@ -363,23 +349,10 @@ external-renderer-cmake-asan-pytest: needs: ["build-codec-linux-cmake"] stage: test script: - - - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[rend\(erer\)*[ -]*non[ -]*be\]") || true - - 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 - - # run test - - exit_code=0 - - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py || exit_code=$? - - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true - - - *merge-request-comparison-check - - allow_failure: - exit_codes: - - 123 + - python3 -m pytest -q --log-level ERROR -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 @@ -398,23 +371,10 @@ external-renderer-cmake-msan-pytest: needs: ["build-codec-linux-cmake"] stage: test script: - - - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[rend\(erer\)*[ -]*non[ -]*be\]") || true - - 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 - - # run test - - exit_code=0 - - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py || exit_code=$? - - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true - - - *merge-request-comparison-check - - allow_failure: - exit_codes: - - 123 + - python3 -m pytest -q --log-level ERROR -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 -- GitLab From 1e65bda449a8a6d9f0dc04ce73840bc5aba5610e Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Thu, 24 Nov 2022 11:32:40 +0100 Subject: [PATCH 13/13] Added interpolation for large changes in position metadata --- lib_com/ivas_cnst.h | 3 + lib_com/ivas_prot.h | 25 ++++++-- lib_dec/ivas_stat_dec.h | 10 ++-- lib_rend/ivas_objectRenderer.c | 22 +++++-- lib_rend/ivas_objectRenderer_hrFilt.c | 24 +++++--- lib_rend/ivas_objectRenderer_sfx.c | 11 +++- lib_rend/ivas_objectRenderer_sources.c | 60 ++++++++++++++++--- .../renderer_standalone.c | 10 ++++ 8 files changed, 131 insertions(+), 34 deletions(-) diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 8d2206eefa..be10cd76a8 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1396,6 +1396,9 @@ typedef enum #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 */ diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index db1cd535c6..c19bde40d0 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -5002,8 +5002,8 @@ void GetFilterFromAngle( const float Elev, /* i : Elevation, degrees */ float Azim, /* i : Azimuth, degrees */ #ifdef FIX_ITD - float *LeftFilter_p, /* o : Left HR filter */ - float *RightFilter_p, /* o : Right HR filter */ + 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 */ @@ -5032,8 +5032,14 @@ 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 @@ -5075,11 +5081,16 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( 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 *LeftFilter_p, /* o: Left filter */ - float *RightFilter_p, /* o: Right filter */ + 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 */ + 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 @@ -5218,7 +5229,9 @@ void TDREND_Apply_ITD( void TDREND_firfilt( float *signal, /* i/o: Input signal / Filtered signal */ - const float *filter, /* i/o: FIR filter */ + 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 */ diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 4fdfa9a064..7e867a7f19 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1617,10 +1617,12 @@ typedef struct int16_t previtd; int16_t filterlength; float mem_itd[ITD_MEM_LEN]; - float hr_filt_left[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; /* Todo: Should we allocate these buffers with count_malloc instead of the maximum length? */ - float hr_filt_right[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; - float mem_hr_filt_left[SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1]; - float mem_hr_filt_right[SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1]; + 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; diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 6d5c49ad61..1979abe230 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -330,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++ ) @@ -348,8 +360,8 @@ static ivas_error TDREND_GetMix( if ( hBinRendererTd->Listener_p->PoseUpdated || SrcSpatial_p->Updated ) { #ifdef FIX_ITD - TDREND_SRC_REND_UpdateFiltersFromSpatialParams( hBinRendererTd, SrcRend_p, SrcSpatial_p, Src_p->hr_filt_left, - Src_p->hr_filt_right, &Src_p->filterlength, &Src_p->itd, &Src_p->Gain ); + 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 @@ -358,11 +370,11 @@ static ivas_error TDREND_GetMix( /* 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 -#ifdef FIX_ITD - error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, subframe_length ); #else error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, subframe_length, output_Fs ); #endif diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index 93c7eb96cc..5269b580b0 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -344,15 +344,21 @@ 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 */ + const int16_t subframe_length, /* i : Subframe length in use */ + const int32_t output_Fs /* i : Output sample rate */ #endif ) { @@ -366,8 +372,8 @@ ivas_error TDREND_REND_RenderSourceHRFilt( #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->hr_filt_left, Src_p->mem_hr_filt_left, subframe_length, Src_p->filterlength ); - TDREND_firfilt( RightOutputFrame, Src_p->hr_filt_right, Src_p->mem_hr_filt_right, subframe_length, Src_p->filterlength ); + 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 */ @@ -713,9 +719,9 @@ void GetFilterFromAngle( const float Elev, /* i : Elevation, degrees */ float Azim, /* i : Azimuth, degrees */ #ifdef FIX_ITD - float *LeftFilter_p, /* o : Left HR filter */ - float *RightFilter_p, /* o : Right HR filter */ - int16_t *itd /* o : ITD value */ + 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 @@ -728,8 +734,8 @@ void GetFilterFromAngle( GenerateFilter( Elev, Azim, &HrFiltSet_p->ModelParams, &HrFiltSet_p->ModelEval ); #ifdef FIX_ITD - mvr2r( HrFiltSet_p->ModelEval.hrfModL, LeftFilter_p, HrFiltSet_p->ModelParams.K ); - mvr2r( HrFiltSet_p->ModelEval.hrfModR, RightFilter_p, HrFiltSet_p->ModelParams.K ); + 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; diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index 1b936f1672..a5f3b58e7a 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -1636,7 +1636,9 @@ static void sincResample( void TDREND_firfilt( float *signal, /* i/o: Input signal / Filtered signal */ - const float *filter, /* i/o: FIR filter */ + 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 */ @@ -1645,7 +1647,7 @@ void TDREND_firfilt( float buffer[SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 + L_SUBFRAME5MS_48k]; float *p_signal; float *p_tmp; - const float *p_filter; + float *p_filter; float tmp; int16_t i, j; @@ -1666,6 +1668,11 @@ void TDREND_firfilt( tmp += ( *p_filter++ ) * ( *p_tmp-- ); } signal[i] = tmp; + + if ( i < intp_count ) + { + v_add( filter, filter_delta, filter, filterlength ); + } } return; diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index 5b3ab93bfb..fa645f1492 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -325,11 +325,16 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( 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 *LeftFilter_p, /* o: Left filter */ - float *RightFilter_p, /* o: Right filter */ - int16_t *filterlength, /* o: Length of filters */ - int16_t *itd, /* o: ITD value */ - float *Gain /* o: Gain value */ + 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 @@ -348,6 +353,11 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( 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 */ @@ -407,7 +417,7 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( } #ifdef FIX_ITD - GetFilterFromAngle( HrFiltSet_p, Elev, Azim, LeftFilter_p, RightFilter_p, itd ); + GetFilterFromAngle( HrFiltSet_p, Elev, Azim, hrf_left, hrf_right, itd ); #else GetFilterFromAngle( HrFiltSet_p, Elev, Azim, &SfxSpatBinParams ); #endif @@ -441,6 +451,32 @@ 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; @@ -786,8 +822,16 @@ void TDREND_SRC_Init( Src_p->previtd = 0; Src_p->filterlength = -1; set_f( Src_p->mem_itd, 0.0f, ITD_MEM_LEN ); - set_f( Src_p->mem_hr_filt_left, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); - set_f( Src_p->mem_hr_filt_right, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); + 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/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 5b2ec832d8..0b386dd419 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 @@ -392,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 ) { -- GitLab