diff --git a/apps/decoder.c b/apps/decoder.c index 5cf6f77f74fc5329417a4c625fb023cc294e3b67..054a219063fd75252a41305e8803e344662371b1 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1649,7 +1649,11 @@ static void resetHeadRotation( pPos[i].x_fx = 0; pPos[i].y_fx = 0; pPos[i].z_fx = 0; +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + pPos[i].q_fact = 22; +#else pPos[i].q_fact = 25; +#endif } return; diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 5b158d957fbb062f99105191ca8d803ec09d0825..0a693d0451ab92c8a693b9f7f563b4b19d6c90c0 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -63,6 +63,10 @@ #define IVAS_ER_LIST_HEIGHT 1.6f #define IVAS_ER_LIST_HEIGHT_FX 6710886 /* 1.6f in Q.22 */ #define IVAS_DEFAULT_AEID 65535 +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION +#define IVAS_LISTENER_POSITION_MAX 327.67f +#define IVAS_LISTENER_POSITION_MAX_Q22 1374347592 /* 327.67 in Q22 */ +#endif /* JBM constants for adaptive-playout */ #define IVAS_TIME_SCALE_MIN 50 /* min. time-scaling [%] */ @@ -160,7 +164,11 @@ typedef struct typedef struct { float x, y, z; +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + Word32 x_fx, y_fx, z_fx; /* Q22, Q22, Q22 */ +#else Word32 x_fx, y_fx, z_fx; +#endif Word16 q_fact; } IVAS_VECTOR3; @@ -351,7 +359,11 @@ typedef struct _IVAS_RENDER_CONFIG float directivity[IVAS_MAX_NUM_OBJECTS * 3]; Word16 directivity_fx[IVAS_MAX_NUM_OBJECTS * 3]; // has the following q-factor pattern: {6, 6, 15, 6, 6, 15, 6, 6, 15, 6, 6, 15} float distAtt[3]; +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + Word32 distAtt_fx[3]; /* {Q25, Q28, Q28} */ +#else Word32 distAtt_fx[3]; /* {Q27, Q30, Q30} */ +#endif } IVAS_RENDER_CONFIG_DATA, *IVAS_RENDER_CONFIG_HANDLE; diff --git a/lib_com/options.h b/lib_com/options.h index 499a45afcaccdbf438b8eba5bbfc75c275211997..24be4ca8b9a48d433a042cec0e843179040f948b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -107,6 +107,7 @@ #define FIX_BASOP_2486_HQ_FINE_GAIN_ALIGNMENT /* Eri: Basop issue 2486: IVAS BASOP used calculations with truncation, EVS BASOP used rounding. This aligns the use of a table lookup. */ #define FIX_1540_EXPOSE_PT_IN_RTP_HEADER_API /* Expose Payload Type setting in RTP Header */ +#define FIX_BASOP_2023_TDREND_DISTATT_PRECISION /* Eri: Basop issue 2023: Distance attenuation scaling, adding clamping of distance att input and listener position */ #define FIX_BASOP_2511_PROTO_REF_POWER_FIX /* FhG: BASOP 2511; Fix reference power computation in protoSignalComputation_shd_fx() */ #define FIX_BASOP_2512_WRONG_SHIFT_IN_DIRAC_CONFIG /* Nokia: BASOP 2512: Fix wrong division by shift */ #define FIX_BASOP_2513_EXTRA_RETURN_REND_OPEN /* Nokia: BASOP issue 2513: Removes extra return block */ diff --git a/lib_dec/ivas_objectRenderer_internal_fx.c b/lib_dec/ivas_objectRenderer_internal_fx.c index 999fe3824c93ee34ad56e917605469209f9b4a26..814ba4254ff6373368d4ae5eea9c1513cf0282a7 100644 --- a/lib_dec/ivas_objectRenderer_internal_fx.c +++ b/lib_dec/ivas_objectRenderer_internal_fx.c @@ -264,7 +264,11 @@ ivas_error ivas_td_binaural_renderer_sf_fx( enableCombinedOrientation = st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx]; move16(); +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + /* Shifting x_fx, y_fx, z_fx to the same Q-factor as Listener_p->Pos_q (usually Q22) */ +#else /* Shifting x_fx, y_fx, z_fx to the same Q-factor as Listener_p->Pos_q (usually Q25) */ +#endif Word16 pos_q = st_ivas->hBinRendererTd->Listener_p->Pos_q; move16(); tmp_vector_fx->x_fx = L_shr( tmp_vector_fx->x_fx, sub( tmp_vector_fx->q_fact, pos_q ) ); diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index f79e5f233d10e15649773eeb55e946d2f5e28388..c49bf243355ab98557df651359d2a63a37f8af9e 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -44,6 +44,13 @@ #include #include "wmc_auto.h" +#ifndef min +#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) +#endif + +#ifndef max +#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) +#endif /*---------------------------------------------------------------------* * Local structs @@ -2102,9 +2109,15 @@ ivas_error IVAS_DEC_FeedHeadTrackData( return error; } +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + hHeadTrackData->Pos[subframe_idx].x_fx = max( min( IVAS_LISTENER_POSITION_MAX_Q22, Pos.x_fx ), -IVAS_LISTENER_POSITION_MAX_Q22 ); + hHeadTrackData->Pos[subframe_idx].y_fx = max( min( IVAS_LISTENER_POSITION_MAX_Q22, Pos.y_fx ), -IVAS_LISTENER_POSITION_MAX_Q22 ); + hHeadTrackData->Pos[subframe_idx].z_fx = max( min( IVAS_LISTENER_POSITION_MAX_Q22, Pos.z_fx ), -IVAS_LISTENER_POSITION_MAX_Q22 ); +#else hHeadTrackData->Pos[subframe_idx].x_fx = Pos.x_fx; hHeadTrackData->Pos[subframe_idx].y_fx = Pos.y_fx; hHeadTrackData->Pos[subframe_idx].z_fx = Pos.z_fx; +#endif hHeadTrackData->Pos[subframe_idx].q_fact = Pos.q_fact; move32(); move32(); diff --git a/lib_rend/ivas_objectRenderer_fx.c b/lib_rend/ivas_objectRenderer_fx.c index 8255fe0b7fc61ee358a54f56165ec7ef8e08d6b9..bfa5d30396b09886024bb8878181b4873e3f3064 100644 --- a/lib_rend/ivas_objectRenderer_fx.c +++ b/lib_rend/ivas_objectRenderer_fx.c @@ -82,7 +82,11 @@ ivas_error ivas_td_binaural_open_unwrap_fx( TDREND_PosType_t PosType; Word16 nS; const Word32 *ls_azimuth_fx, *ls_elevation_fx; +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + Word32 Pos_fx[3]; // Q22 +#else Word32 Pos_fx[3]; // Q25 +#endif Word32 Dir_fx[3]; // Q30 TDREND_DirAtten_t *DirAtten_p; TDREND_DistAtten_t DistAtten; @@ -185,6 +189,9 @@ ivas_error ivas_td_binaural_open_unwrap_fx( { /* Set source positions according to loudspeaker layout */ angles_to_vec_fx( ONE_IN_Q9, ls_azimuth_fx[nS], ls_elevation_fx[nS], Pos_fx ); +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + Scale_sig32( Pos_fx, 3, -3 ); /* Q25 -> Q22 */ +#endif Dir_fx[0] = ONE_IN_Q30; move32(); @@ -202,12 +209,21 @@ ivas_error ivas_td_binaural_open_unwrap_fx( DistAtten.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; // Q0 move16(); +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + DistAtten.MaxDist_fx = 528482304; /* Maximum radius (2^ISM_RADIUS_NBITS-1)*0.25 */ /*15.75 in Q25*/ + move32(); + DistAtten.RefDist_fx = ONE_IN_Q28; // Q28 + move32(); + DistAtten.RollOffFactor_fx = ONE_IN_Q28; // Q28 + move32(); +#else DistAtten.MaxDist_fx = 2113929216; /* Maximum radius (2^ISM_RADIUS_NBITS-1)*0.25 */ /*15.75 in Q27*/ move32(); DistAtten.RefDist_fx = ONE_IN_Q30; // Q30 move32(); DistAtten.RollOffFactor_fx = ONE_IN_Q30; // Q30 move32(); +#endif // TDREND_SRC_SPATIAL_t *SrcSpatial_p = pBinRendTd->Sources[nS]->SrcSpatial_p; IF( NE_32( ( error = TDREND_MIX_SRC_SetPos_fx( pBinRendTd, nS, Pos_fx ) ), IVAS_ERR_OK ) ) @@ -638,7 +654,11 @@ ivas_error TDREND_Update_object_positions_fx( ) { Word16 nS; +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + Word32 Pos_fx[3]; // Q22 +#else Word32 Pos_fx[3]; // Q25 +#endif Word32 Dir_fx[3]; // Q30 ivas_error error; @@ -651,7 +671,12 @@ ivas_error TDREND_Update_object_positions_fx( { /* Update the source positions */ /* Source position and direction */ +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + angles_to_vec_fx( hIsmMetaData[nS]->radius_fx /*Q9*/, hIsmMetaData[nS]->azimuth_fx, hIsmMetaData[nS]->elevation_fx, Pos_fx ); + Scale_sig32( Pos_fx, 3, -3 ); /* Q25 -> Q22 */ +#else angles_to_vec_fx( hIsmMetaData[nS]->radius_fx /*Q9*/, hIsmMetaData[nS]->azimuth_fx, hIsmMetaData[nS]->elevation_fx, Pos_fx ); +#endif angles_to_vec_fx( ONE_IN_Q14, hIsmMetaData[nS]->yaw_fx, hIsmMetaData[nS]->pitch_fx, Dir_fx ); // DirAtten_p->ConeInnerAngle_fx = DEG_360_IN_Q22; @@ -674,7 +699,11 @@ ivas_error TDREND_Update_object_positions_fx( { Pos_fx[0] = 0; /* Pos[1] = hIsmMetaData[nS]->azimuth / 90.f; */ +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + Pos_fx[1] = L_shl( Mpy_32_32_r( hIsmMetaData[nS]->azimuth_fx, 23860929 /* 1 / 90.f in Q31 */ ), 0 ); /* Q22 */ +#else Pos_fx[1] = L_shl( Mpy_32_32_r( hIsmMetaData[nS]->azimuth_fx, 23860929 /* 1 / 90.f in Q31 */ ), Q3 ); /* Q25 */ +#endif move32(); Pos_fx[2] = 0; move32(); @@ -983,7 +1012,11 @@ ivas_error ivas_td_binaural_renderer_ext_fx( { Word16 idx = subframe_idx; move16(); +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + Word16 pos_q = Q22; +#else Word16 pos_q = Q25; +#endif move16(); test(); diff --git a/lib_rend/ivas_objectRenderer_hrFilt_fx.c b/lib_rend/ivas_objectRenderer_hrFilt_fx.c index 7b2ebf908717859de29f68e4ee35eb1bfbe20b7b..88be20e0c9a43595b6799c043911a0039a4b5e56 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt_fx.c +++ b/lib_rend/ivas_objectRenderer_hrFilt_fx.c @@ -38,7 +38,7 @@ #include "ivas_rom_rend.h" #include "ivas_cnst.h" #include "wmc_auto.h" - +#include "debug.h" /*---------------------------------------------------------------------* * Local function prototypes diff --git a/lib_rend/ivas_objectRenderer_mix_fx.c b/lib_rend/ivas_objectRenderer_mix_fx.c index 598308fd4dd355706e29d1084f972522c898de9d..c895b196779c5c2fa592023a7fba9dfe77d32788 100644 --- a/lib_rend/ivas_objectRenderer_mix_fx.c +++ b/lib_rend/ivas_objectRenderer_mix_fx.c @@ -198,7 +198,11 @@ ivas_error TDREND_MIX_Init_fx( } /* Init virtual and rendering listeners for spatial mixers */ TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Pos_fx, 0, 0, 0 ); +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + hBinRendererTd->Listener_p->Pos_q = Q22; +#else hBinRendererTd->Listener_p->Pos_q = Q25; +#endif move16(); TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Vel_fx, 0, 0, 0 ); TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Front_fx, 0, 0, -ONE_IN_Q30 ); diff --git a/lib_rend/ivas_objectRenderer_sources_fx.c b/lib_rend/ivas_objectRenderer_sources_fx.c index ad4776fbcb57c09b8a4b679bd4b04cdffa96c0f7..4f0ccb8cfceb906e555e01152bc8f0ef6ddaaf42 100644 --- a/lib_rend/ivas_objectRenderer_sources_fx.c +++ b/lib_rend/ivas_objectRenderer_sources_fx.c @@ -61,7 +61,11 @@ static void TDREND_SRC_SPATIAL_Dealloc( TDREND_SRC_SPATIAL_t *SrcSpatial_p ); ivas_error TDREND_MIX_SRC_SetPos_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const Word16 SrcInd, /* i : Source index */ - const Word32 *Vec_p /* i : Position vector Q25 */ +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + const Word32 *Vec_p /* i : Position vector Q22 */ +#else + const Word32 *Vec_p /* i : Position vector Q25 */ +#endif ) { TDREND_SRC_SPATIAL_t *SrcSpatial_p; @@ -73,6 +77,15 @@ ivas_error TDREND_MIX_SRC_SetPos_fx( ELSE { SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p; +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + SrcSpatial_p->Pos_p_fx[0] = L_shr( SrcSpatial_p->Pos_p_fx[0], sub( SrcSpatial_p->q_Pos_p, Q22 ) ); // Q22 + move32(); + SrcSpatial_p->Pos_p_fx[1] = L_shr( SrcSpatial_p->Pos_p_fx[1], sub( SrcSpatial_p->q_Pos_p, Q22 ) ); // Q22 + move32(); + SrcSpatial_p->Pos_p_fx[2] = L_shr( SrcSpatial_p->Pos_p_fx[2], sub( SrcSpatial_p->q_Pos_p, Q22 ) ); // Q22 + move32(); + SrcSpatial_p->q_Pos_p = Q22; +#else SrcSpatial_p->Pos_p_fx[0] = L_shr( SrcSpatial_p->Pos_p_fx[0], sub( SrcSpatial_p->q_Pos_p, Q25 ) ); // Q25 move32(); SrcSpatial_p->Pos_p_fx[1] = L_shr( SrcSpatial_p->Pos_p_fx[1], sub( SrcSpatial_p->q_Pos_p, Q25 ) ); // Q25 @@ -80,12 +93,17 @@ ivas_error TDREND_MIX_SRC_SetPos_fx( SrcSpatial_p->Pos_p_fx[2] = L_shr( SrcSpatial_p->Pos_p_fx[2], sub( SrcSpatial_p->q_Pos_p, Q25 ) ); // Q25 move32(); SrcSpatial_p->q_Pos_p = Q25; +#endif move16(); test(); test(); IF( NE_32( SrcSpatial_p->Pos_p_fx[0], Vec_p[0] ) || NE_32( SrcSpatial_p->Pos_p_fx[1], Vec_p[1] ) || NE_32( SrcSpatial_p->Pos_p_fx[2], Vec_p[2] ) ) { +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + Copy32( Vec_p, SrcSpatial_p->Pos_p_fx, 3 ); // Q22 +#else Copy32( Vec_p, SrcSpatial_p->Pos_p_fx, 3 ); // Q25 +#endif SrcSpatial_p->Updated = TRUE; move16(); } @@ -324,6 +342,9 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( Word32 azim_delta; Word32 elev_delta; Word16 ListRelPos_e, ListRelDist_e; +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + Word32 Pos_p_q21[3], Lis_p_q21[3]; +#endif /* Evaluate the HR filters from the source and listener positions and orientations */ Listener_p = hBinRendererTd->Listener_p; @@ -335,8 +356,17 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( { /* Absolute position */ +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + /* Q22 -> Q21 for 1 bit headroom. Relative position has twice the range of the position */ + Copy_Scale_sig32( SrcSpatial_p->Pos_p_fx, Pos_p_q21, 3, -1 ); + Copy_Scale_sig32( Listener_p->Pos_fx, Lis_p_q21, 3, -1 ); + TDREND_SPATIAL_VecMapToNewCoordSystem_fx( Pos_p_q21, Lis_p_q21, Listener_p->Front_fx, Listener_p->Up_fx, Listener_p->Right_fx, ListRelPos, ListRelPosAbs ); + ListRelPos_e = 11; // Q21 + Q30 - 31 = Q20, exp = 31 - 20 = 11 +#else TDREND_SPATIAL_VecMapToNewCoordSystem_fx( SrcSpatial_p->Pos_p_fx, Listener_p->Pos_fx, Listener_p->Front_fx, Listener_p->Up_fx, Listener_p->Right_fx, ListRelPos, ListRelPosAbs ); ListRelPos_e = 7; // output q of above function is Q25 + Q30 - 31. so exp will be 62 - Q25 - Q30. +#endif + move16(); ListRelDist = TDREND_SPATIAL_VecNorm_fx( ListRelPos, ListRelPos_e, &ListRelDist_e ); @@ -375,7 +405,11 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( move16(); IF( SrcSpatial_p->DirAttenEnabled ) { +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + *SrcRend_p->DirGain_p_fx = TDREND_SRC_SPATIAL_GetDirGain_fx( &SrcSpatial_p->DirAtten, SrcSpatial_p->Front_p_fx, ListRelPosAbs, 9 /*exp: 31 - 22 = 9 */ ); +#else *SrcRend_p->DirGain_p_fx = TDREND_SRC_SPATIAL_GetDirGain_fx( &SrcSpatial_p->DirAtten, SrcSpatial_p->Front_p_fx, ListRelPosAbs, 6 ); +#endif } /* Distance gain */ @@ -458,6 +492,15 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( move32(); set32_fx( hrf_left, 0, *filterlength ); set32_fx( hrf_right, 0, *filterlength ); +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + hrf_left[0] = L_shr( L_add( SrcSpatial_p->Pos_p_fx[1], ONE_IN_Q22 ), 1 ); // Q22 + move32(); + hrf_right[0] = L_sub( ONE_IN_Q22, hrf_left[0] ); // Q22 + move32(); + hrf_left_e = 9; + move16(); + hrf_right_e = 9; +#else hrf_left[0] = L_shr( L_add( SrcSpatial_p->Pos_p_fx[1], ONE_IN_Q25 ), 1 ); // Q25 move32(); hrf_right[0] = L_sub( ONE_IN_Q25, hrf_left[0] ); // Q25 @@ -465,6 +508,7 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( hrf_left_e = 6; move16(); hrf_right_e = 6; +#endif move16(); *intp_count = MAX_INTERPOLATION_STEPS; // Q22 move16(); @@ -628,12 +672,21 @@ static void TDREND_SRC_SPATIAL_Init_fx( move16(); SrcSpatial_p->DistAtten.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; // Q0 move16(); +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + SrcSpatial_p->DistAtten.RefDist_fx = ONE_IN_Q28; // Q28 + move32(); + SrcSpatial_p->DistAtten.MaxDist_fx = 528482304; /* Maximum radius (2^ISM_RADIUS_NBITS-1)*0.25 */ /*15.75 in Q25*/ + move32(); + SrcSpatial_p->DistAtten.RollOffFactor_fx = ONE_IN_Q28; // Q28 + move32(); +#else SrcSpatial_p->DistAtten.RefDist_fx = ONE_IN_Q30; // Q30 move32(); SrcSpatial_p->DistAtten.MaxDist_fx = 2113929216; /* Maximum radius (2^ISM_RADIUS_NBITS-1)*0.25 */ /*15.75 in Q27*/ move32(); SrcSpatial_p->DistAtten.RollOffFactor_fx = ONE_IN_Q30; // Q30 move16(); +#endif return; } @@ -832,28 +885,56 @@ static Word16 TDREND_SRC_SPATIAL_GetDistGain_fx( BREAK; case TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED: +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + flag = BASOP_Util_Cmp_Mant32Exp( Dist2_fx, Dist2_e, DistAtten_p->RefDist_fx, 3 ); +#else flag = BASOP_Util_Cmp_Mant32Exp( Dist2_fx, Dist2_e, DistAtten_p->RefDist_fx, 1 ); +#endif IF( flag < 0 ) { +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + Dist2_fx = DistAtten_p->RefDist_fx; // Q28 + move32(); + Dist2_e = 3; + move16(); +#else Dist2_fx = DistAtten_p->RefDist_fx; // Q30 move32(); Dist2_e = 1; move16(); +#endif } +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + flag = BASOP_Util_Cmp_Mant32Exp( Dist2_fx, Dist2_e, DistAtten_p->MaxDist_fx, 6 ); +#else flag = BASOP_Util_Cmp_Mant32Exp( Dist2_fx, Dist2_e, DistAtten_p->MaxDist_fx, 4 ); +#endif IF( flag > 0 ) { +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + Dist2_fx = DistAtten_p->MaxDist_fx; // Q25 + move32(); + Dist2_e = 6; + move16(); +#else Dist2_fx = DistAtten_p->MaxDist_fx; // Q27 move32(); Dist2_e = 4; move16(); +#endif } /* DistGain = powf( DistAtten_p->RefDist / Dist2, DistAtten_p->RollOffFactor ); */ +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + tmp16 = BASOP_Util_Divide3232_Scale( DistAtten_p->RefDist_fx, Dist2_fx, &Dist_s ); /* tmp16 is Q(15 - Dist_s + Dist2_e - 3) */ + tmp32 = L_deposit_h( tmp16 ); /* tmp32 is Q(31 - Dist_s + Dist2_e - 3) */ + /* tmp32 exponent: 31 - (31 - Dist_s + Dist2_e - 3) = Dist_s - Dist2_e + 3, RollOffFactor_fx exponent: 31 - 28 = 3 */ + tmp32 = BASOP_Util_fPow( tmp32, add( sub( Dist_s, Dist2_e ), 3 ), DistAtten_p->RollOffFactor_fx, 3, &tmp_e ); /* Q(31 - tmp_e) */ +#else tmp16 = BASOP_Util_Divide3232_Scale( DistAtten_p->RefDist_fx, Dist2_fx, &Dist_s ); /* tmp16 is Q(15 - Dist_s + Dist2_e - 1) */ tmp32 = L_deposit_h( tmp16 ); /* tmp32 is Q(31 - Dist_s + Dist2_e - 1) */ /* tmp32 exponent: 31 - (31 - Dist_s + Dist2_e - 1) = Dist_s - Dist2_e + 1, RollOffFactor_fx exponent: 31 - 30 = 1 */ tmp32 = BASOP_Util_fPow( tmp32, add( sub( Dist_s, Dist2_e ), 1 ), DistAtten_p->RollOffFactor_fx, 1, &tmp_e ); /* Q(31 - tmp_e) */ - +#endif BREAK; } diff --git a/lib_rend/ivas_render_config_fx.c b/lib_rend/ivas_render_config_fx.c index 81f66bf60af8e61e1eac8098d2204cde18c0265f..87192a4f6d310a236122db947d0306a90b3a1c43 100644 --- a/lib_rend/ivas_render_config_fx.c +++ b/lib_rend/ivas_render_config_fx.c @@ -140,12 +140,21 @@ ivas_error ivas_render_config_init_from_rom_fx( ( *hRenderConfig )->directivity_fx[add( i_mult( i, 3 ), 2 )] = 32767 /*1.0f in Q15*/; /* Back attenuation */ move16(); } +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + ( *hRenderConfig )->distAtt_fx[0] = 528482304; /* Maximum radius (2^ISM_RADIUS_NBITS-1)*0.25 */ /*15.75 in Q25*/ /* Default max dist */ + move32(); + ( *hRenderConfig )->distAtt_fx[1] = ONE_IN_Q28; // Q28 /* Default ref dist */ + move32(); + ( *hRenderConfig )->distAtt_fx[2] = ONE_IN_Q28; // Q28 /* Default rolloff factor */ + move32(); +#else ( *hRenderConfig )->distAtt_fx[0] = 2113929216; /* Maximum radius (2^ISM_RADIUS_NBITS-1)*0.25 */ /*15.75 in Q27*/ /* Default max dist */ move32(); ( *hRenderConfig )->distAtt_fx[1] = ONE_IN_Q30; // Q30 /* Default ref dist */ move32(); ( *hRenderConfig )->distAtt_fx[2] = ONE_IN_Q30; // Q30 /* Default rolloff factor */ move32(); +#endif ( *hRenderConfig )->split_rend_config.splitRendBitRate = ISAR_MAX_SPLIT_REND_BITRATE; move32(); ( *hRenderConfig )->split_rend_config.dof = 3; diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index dc5db5e4fa92a98e80a6fb0a14271e2f9cef5490..f2d1e48752a602c791f578849e517b743aec9212 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -1178,9 +1178,15 @@ typedef struct ivas_hrtf_TDREND_HRFILT_FiltSet_struct typedef struct { TDREND_DistAttenModel_t DistAttenModel; +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + Word32 RefDist_fx; /* Q28 */ + Word32 MaxDist_fx; /* Q25 */ + Word32 RollOffFactor_fx; /* Q28 */ +#else Word32 RefDist_fx; /* Q30 */ Word32 MaxDist_fx; /* Q27 */ Word32 RollOffFactor_fx; /* Q30 */ +#endif } TDREND_DistAtten_t; @@ -1218,7 +1224,11 @@ typedef struct { Word16 Updated; TDREND_PosType_t PosType; +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + Word32 Pos_p_fx[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; // Q22 +#else Word32 Pos_p_fx[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; // Q25 +#endif Word16 q_Pos_p; Word32 Front_p_fx[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; // Q30 Word16 DirAttenEnabled; diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 318072fe8566da06ff6755c612e8f231b09868ed..4a313b6c26ba2370ee14847b532701e9bad1443a 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -80,6 +80,20 @@ #define IVAS_ER_LIST_ORIGIN_X_FX 0 #define IVAS_ER_LIST_ORIGIN_Y_FX 0 +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION +#define DIST_ATT_MAX_MAXDIST 63.0f +#define DIST_ATT_MAX_REFDIST 6.3f +#define DIST_ATT_MAX_ROLLOFF 4.0f + +#ifndef min +#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) +#endif + +#ifndef max +#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) +#endif +#endif + #ifndef TRUE #define TRUE 1 #endif @@ -143,7 +157,11 @@ struct RenderConfigReader AcousticEnv *pAE; /* Acoustic environments */ uint32_t nDP; /* Number of directivity patterns */ DirectrivityPat *pDP; /* Directivity Pattern */ - float distAtt[3]; /* [MaxDist Q30, RefDist Q30, Rolloff Q30] */ +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + float distAtt[3]; /* [MaxDist Q25, RefDist Q28, Rolloff Q28] */ +#else + float distAtt[3]; /* [MaxDist Q30, RefDist Q30, Rolloff Q30] */ +#endif }; @@ -3094,6 +3112,14 @@ ivas_error RenderConfigReader_getDirectivity( /* Convert to Word16 */ FOR( n = 0; n < 4; n++ ) { +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + /* Verify range of directivity patterns */ + /* Range needs to be checked before converting to fixed point -- different from float */ + directivity[n * 3] = max( 0.0f, min( 360.0f, directivity[n * 3] ) ); + directivity[n * 3 + 1] = max( 0.0f, min( 360.0f, directivity[n * 3 + 1] ) ); + directivity[n * 3 + 2] = max( 0.0f, min( 1.0f, directivity[n * 3 + 2] ) ); +#endif + directivity_fx[n * 3] = (Word16) ( directivity[n * 3] * ( 1u << 6 ) ); directivity_fx[n * 3 + 1] = (Word16) ( directivity[n * 3 + 1] * ( 1u << 6 ) ); directivity_fx[n * 3 + 2] = (Word16) ( directivity[n * 3 + 2] * ( ( 1u << 15 ) - 1 ) ); @@ -3131,9 +3157,23 @@ ivas_error RenderConfigReader_getDistanceAttenuation( } /* Convert to Word32 */ +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + /* Range needs to be checked before converting to fixed point -- different from float */ + /* Verify range of distance attenuation parameters: refDist: 0.0 <= distAtt[1] <= 6.3 */ + /* maxDist: distAtt[1] <= distAtt[0] <= 63.0 */ + /* rollOffFactor: 0 <= distAtt[2] <= 4.0 */ + distAtt[1] = min( max( 0, distAtt[1] ), DIST_ATT_MAX_REFDIST ); + distAtt[0] = min( max( distAtt[1], distAtt[0] ), DIST_ATT_MAX_MAXDIST ); + distAtt[2] = min( max( 0.0f, distAtt[2] ), DIST_ATT_MAX_ROLLOFF ); + + distAtt_fx[0] = (Word32) ( distAtt[0] * ( 1u << 25 ) ); + distAtt_fx[1] = (Word32) ( distAtt[1] * ( 1u << 28 ) ); + distAtt_fx[2] = (Word32) ( distAtt[2] * ( 1u << 28 ) ); +#else distAtt_fx[0] = (Word32) ( distAtt[0] * ( 1u << 27 ) ); distAtt_fx[1] = (Word32) ( distAtt[1] * ( 1u << 30 ) ); distAtt_fx[2] = (Word32) ( distAtt[2] * ( 1u << 30 ) ); +#endif return IVAS_ERR_OK; } diff --git a/lib_util/rotation_file_reader.c b/lib_util/rotation_file_reader.c index 5530371b090f41232163ea275c94296668c4c540..2652fde9172540a6c809531aa8530ca3765cb878 100644 --- a/lib_util/rotation_file_reader.c +++ b/lib_util/rotation_file_reader.c @@ -41,6 +41,17 @@ #define Q29 29 #define Q31 31 +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION +#ifndef min +#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) +#endif + +#ifndef max +#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) +#endif +#endif + + struct RotFileReader { FILE *trajFile; @@ -144,6 +155,15 @@ ivas_error HeadRotationFileReading( if ( pPos != NULL ) { +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + pPos->x = min( max( -IVAS_LISTENER_POSITION_MAX, posx ), IVAS_LISTENER_POSITION_MAX ); + pPos->y = min( max( -IVAS_LISTENER_POSITION_MAX, posy ), IVAS_LISTENER_POSITION_MAX ); + pPos->z = min( max( -IVAS_LISTENER_POSITION_MAX, posz ), IVAS_LISTENER_POSITION_MAX ); + pPos->x_fx = floatToFixed_32( pPos->x, Q22 ); + pPos->y_fx = floatToFixed_32( pPos->y, Q22 ); + pPos->z_fx = floatToFixed_32( pPos->z, Q22 ); + pPos->q_fact = Q22; +#else pPos->x = posx; pPos->y = posy; pPos->z = posz; @@ -151,6 +171,7 @@ ivas_error HeadRotationFileReading( pPos->y_fx = floatToFixed_32( posy, Q25 ); pPos->z_fx = floatToFixed_32( posz, Q25 ); pPos->q_fact = Q25; +#endif } return IVAS_ERR_OK;