diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 68f818067ba0a6b30fca29b0c86db11f58f13c67..ccda2dc3f625b33237d0beeafe0a1cfe8d2bfcbf 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -163,9 +163,11 @@ typedef struct typedef struct { + float x, y, z; + #ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION - Word32 x_fx, y_fx, z_fx; /* qfact, qfact, qfact */ + Word32 x_fx, y_fx, z_fx; /* q_fact, q_fact, q_fact */ #else Word32 x_fx, y_fx, z_fx; #endif diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index bd52ea307a7a0e2f9671c5b4aeb19008e367ec10..03293b9fc57eeb2a9501f32c3dd79c79ad346fd3 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1939,7 +1939,7 @@ void TDREND_MIX_LIST_SetPos_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ #ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION const Word32 *Pos_p, /* i : Listener's position */ - const Word16 Pos_q /* i : Listener's position Q value */ + const Word16 Pos_q /* i : Listener's position Q */ #else const Word32 *Pos_p /* i : Listener's position */ #endif diff --git a/lib_com/options.h b/lib_com/options.h index 52de155d3597204da31db740d8045d4c13e03bbc..67e88ae43283c1c47338714591545b1f3507ba7c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -115,6 +115,7 @@ #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_2023_TDREND_DISTATT_PRECISION_BUGFIX /* Eri: Bug discovered in cleanup of basop issue 2023 */ #define USE_RTPDUMP /* FhG: RTPDUMP format (rtptools standard) instead of custom format */ #define FIX_FLOAT_1569_REND_RENDER_CONFIG_CHECKS /* Nokia: float issue 1569: fix render config checks in renderer */ #define FIX_BASOP_2526_SPAR_MASA_PARAM_MAP_Q_BUG /* Nokia: BASOP issue 2526: Fix wrong Q variable in SPAR to MASA param mapping */ diff --git a/lib_rend/ivas_objectRenderer_fx.c b/lib_rend/ivas_objectRenderer_fx.c index b9b92a56fff032230876290057d30c27ae7a0a1a..b904e2be03a1378f64b5be7986f677932c50e874 100644 --- a/lib_rend/ivas_objectRenderer_fx.c +++ b/lib_rend/ivas_objectRenderer_fx.c @@ -1023,7 +1023,11 @@ ivas_error ivas_td_binaural_renderer_ext_fx( IF( *hCombinedOrientationData != NULL && ( *hCombinedOrientationData )->listenerPos != NULL ) { #ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION_BUGFIX + ( *hCombinedOrientationData )->listenerPos[idx].q_fact = pos_q; +#else pos_q = ( *hCombinedOrientationData )->listenerPos[idx].q_fact; +#endif move16(); #else ( *hCombinedOrientationData )->listenerPos[idx].x_fx = L_shr( ( *hCombinedOrientationData )->listenerPos[idx].x_fx, sub( ( *hCombinedOrientationData )->listenerPos[idx].q_fact, pos_q ) ); diff --git a/lib_rend/ivas_objectRenderer_mix_fx.c b/lib_rend/ivas_objectRenderer_mix_fx.c index 2924da90809afc69e956f3760414f2a2ad457b85..4ead8081dd85a1fc85fb05bcf0f6774f91be0d88 100644 --- a/lib_rend/ivas_objectRenderer_mix_fx.c +++ b/lib_rend/ivas_objectRenderer_mix_fx.c @@ -56,9 +56,8 @@ static ivas_error DefaultBSplineModel_fx( TDREND_HRFILT_FiltSet_t *HrFiltSet_p, void TDREND_MIX_LIST_SetPos_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ #ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION - const Word32 *Pos_p, - /* i : Listener's position */ // Q Pos_fx->q_fact - const Word16 Pos_q /* i : Listener's position Q value */ + const Word32 *Pos_p, /* i : Listener's position */ + const Word16 Pos_q /* i : Listener's position Q */ #else const Word32 *Pos_p /* i : Listener's position */ // Q Pos_fx->q_fact #endif diff --git a/lib_rend/ivas_objectRenderer_sources_fx.c b/lib_rend/ivas_objectRenderer_sources_fx.c index 748ea0d0de24069c238e68805d6c30497e0d4785..9840278cb430c6e9c142ea7a240ae5cd52fadf5b 100644 --- a/lib_rend/ivas_objectRenderer_sources_fx.c +++ b/lib_rend/ivas_objectRenderer_sources_fx.c @@ -317,6 +317,9 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( Word32 ListRelPos[3]; Word32 ListRelDist; Word32 ListRelPosAbs[3]; /* Relative position, ignoring orientation of listener */ +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + Word16 ListRelPosAbs_e; +#endif Word32 Azim, Elev; Word32 hrf_left[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; Word32 hrf_right[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; @@ -326,7 +329,8 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( Word16 ListRelPos_e, ListRelDist_e; #ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION Word16 pos_q; - Word32 Src_p_aligned[3], Lis_p_aligned[3]; + Word32 Src_p_tmp[3]; + Word32 Listener_p_tmp[3]; #endif /* Evaluate the HR filters from the source and listener positions and orientations */ @@ -340,11 +344,12 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( /* Absolute position */ #ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION + /* Align to smallest common Q-factor */ pos_q = s_min( SrcSpatial_p->q_Pos_p, Listener_p->Pos_q ); - Copy_Scale_sig32( SrcSpatial_p->Pos_p_fx, Src_p_aligned, 3, sub( pos_q, SrcSpatial_p->q_Pos_p ) ); - Copy_Scale_sig32( Listener_p->Pos_fx, Lis_p_aligned, 3, sub( pos_q, Listener_p->Pos_q ) ); - TDREND_SPATIAL_VecMapToNewCoordSystem_fx( Src_p_aligned, Lis_p_aligned, Listener_p->Front_fx, Listener_p->Up_fx, Listener_p->Right_fx, ListRelPos, ListRelPosAbs ); - ListRelPos_e = sub( 62, add( pos_q, Q30 ) ); // Qq + Q30 - 31, exp = 62 - q - 30 + Copy_Scale_sig32( SrcSpatial_p->Pos_p_fx, Src_p_tmp, 3, sub( pos_q, SrcSpatial_p->q_Pos_p ) ); + Copy_Scale_sig32( Listener_p->Pos_fx, Listener_p_tmp, 3, sub( pos_q, Listener_p->Pos_q ) ); + TDREND_SPATIAL_VecMapToNewCoordSystem_fx( Src_p_tmp, Listener_p_tmp, Listener_p->Front_fx, Listener_p->Up_fx, Listener_p->Right_fx, ListRelPos, ListRelPosAbs ); + ListRelPos_e = sub( 32, pos_q ); // output q of above function is pos_q + Q30 - 31. so exp will be 62 - pos_q - 30 = 32 - pos_q #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. @@ -389,7 +394,8 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( 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, sub( 31, pos_q ) ); + ListRelPosAbs_e = sub( 31, pos_q ); + *SrcRend_p->DirGain_p_fx = TDREND_SRC_SPATIAL_GetDirGain_fx( &SrcSpatial_p->DirAtten, SrcSpatial_p->Front_p_fx, ListRelPosAbs, ListRelPosAbs_e ); #else *SrcRend_p->DirGain_p_fx = TDREND_SRC_SPATIAL_GetDirGain_fx( &SrcSpatial_p->DirAtten, SrcSpatial_p->Front_p_fx, ListRelPosAbs, 6 ); #endif @@ -655,7 +661,7 @@ static void TDREND_SRC_SPATIAL_Init_fx( 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(); + move16(); #else SrcSpatial_p->DistAtten.RefDist_fx = ONE_IN_Q30; // Q30 move32(); @@ -855,10 +861,17 @@ static Word16 TDREND_SRC_SPATIAL_GetDistGain_fx( { case TDREND_DIST_ATTEN_MODEL_INV_DIST: /* 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; case TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED: @@ -882,7 +895,7 @@ static Word16 TDREND_SRC_SPATIAL_GetDistGain_fx( #endif } #ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION - flag = BASOP_Util_Cmp_Mant32Exp( Dist2_fx, Dist2_e, DistAtten_p->MaxDist_fx, 6 ); + flag = BASOP_Util_Cmp_Mant32Exp( Dist2_fx, Dist2_e, DistAtten_p->MaxDist_fx, 6 /*Q25*/ ); #else flag = BASOP_Util_Cmp_Mant32Exp( Dist2_fx, Dist2_e, DistAtten_p->MaxDist_fx, 4 ); #endif diff --git a/lib_rend/ivas_objectRenderer_vec_fx.c b/lib_rend/ivas_objectRenderer_vec_fx.c index 6f01adcd633048918926426b66d36274a71b88cb..995e6b787f679f6622b0ae61637435239d64fccf 100644 --- a/lib_rend/ivas_objectRenderer_vec_fx.c +++ b/lib_rend/ivas_objectRenderer_vec_fx.c @@ -78,7 +78,11 @@ Word32 TDREND_SPATIAL_VecNorm_fx( Word32 tmp; Word16 tmp_e; #ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION - tmp = L_add( L_add( Mpy_32_32( L_shr( Vec_p[0], 1 ), Vec_p[0] ), Mpy_32_32( L_shr( Vec_p[1], 1 ), Vec_p[1] ) ), Mpy_32_32( L_shr( Vec_p[2], 1 ), Vec_p[2] ) ); + Word32 tmp_Vec[3]; + + /* Create 1-bit headroom */ + Copy_Scale_sig32( Vec_p, tmp_Vec, 3, -1 ); + tmp = L_add( L_add( Mpy_32_32( tmp_Vec[0], Vec_p[0] ), Mpy_32_32( tmp_Vec[1], Vec_p[1] ) ), Mpy_32_32( tmp_Vec[2], Vec_p[2] ) ); tmp_e = add( shl( in_exp, 1 ), 1 ); // 2 * in_exp + 1 #else tmp = L_add( L_add( Mpy_32_32( Vec_p[0], Vec_p[0] ), Mpy_32_32( Vec_p[1], Vec_p[1] ) ), Mpy_32_32( Vec_p[2], Vec_p[2] ) ); @@ -100,9 +104,12 @@ void TDREND_SPATIAL_VecNormalize_fx( Word32 scaler_fx; Word32 sqrd_sum; Word16 exp, shift; - #ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION - sqrd_sum = L_add( Mpy_32_32( L_shr( Vec_p_fx[0], 1 ), Vec_p_fx[0] ), L_add( Mpy_32_32( L_shr( Vec_p_fx[1], 1 ), Vec_p_fx[1] ), Mpy_32_32( L_shr( Vec_p_fx[2], 1 ), Vec_p_fx[2] ) ) ); + Word32 tmp_Vec[3]; + + /* Create 1-bit headroom */ + Copy_Scale_sig32( Vec_p_fx, tmp_Vec, 3, -1 ); + sqrd_sum = L_add( Mpy_32_32( tmp_Vec[0], Vec_p_fx[0] ), L_add( Mpy_32_32( tmp_Vec[1], Vec_p_fx[1] ), Mpy_32_32( tmp_Vec[2], Vec_p_fx[2] ) ) ); exp = add( shl( sub( 31, q ), 1 ), 1 ); #else sqrd_sum = L_add( Mpy_32_32( Vec_p_fx[0], Vec_p_fx[0] ), L_add( Mpy_32_32( Vec_p_fx[1], Vec_p_fx[1] ), Mpy_32_32( Vec_p_fx[2], Vec_p_fx[2] ) ) ); diff --git a/lib_util/float_to_fix_ops.c b/lib_util/float_to_fix_ops.c index 4e020fc9c5a37bb8cec730685276e8947e9b7bbf..5da59c51e75e3d9e93d32397229ba8061e0796fa 100644 --- a/lib_util/float_to_fix_ops.c +++ b/lib_util/float_to_fix_ops.c @@ -3,7 +3,9 @@ #include "float_to_fix_ops.h" #include #include - +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION +#include +#endif #define Q15 15 #define Q31 31 @@ -129,17 +131,22 @@ Word32 floatToFixed_32( } +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION Word16 float_to_fix_find_q( const float val ) { - Word16 bits; - float absVal; + uint32_t bits; + Word16 biased_exp; + + memcpy( &bits, &val, sizeof( bits ) ); /* Extract raw bits */ + biased_exp = ( bits >> 23 ) & 0xFF; /* Extract biased exponent from single-precision float (masking out bits 23-30) */ - absVal = fabsf( val ); - if ( absVal < 1e-10f ) + if ( biased_exp == 0 ) { return Q31; } - bits = (Word16) floorf( log2f( absVal ) ) + 1; - return (Word16) ( 31 - bits ); + + /* Subtract bias of 127 (from floating point format), add 1 and subtract result from 31 to get Q */ + return (Word16) ( 31 - ( biased_exp - 127 + 1 ) ); } +#endif diff --git a/lib_util/float_to_fix_ops.h b/lib_util/float_to_fix_ops.h index be23e5a164d6f07a4c1519ba9a5d267a49129a4a..8559a872b1dc77c6b039ee43ea9e1477d50b3f26 100644 --- a/lib_util/float_to_fix_ops.h +++ b/lib_util/float_to_fix_ops.h @@ -16,6 +16,8 @@ float fixedToFloat( const Word32 i, const Word16 Q ); float fix16_to_float( const Word16 number, const Word16 Q ); +#ifdef FIX_BASOP_2023_TDREND_DISTATT_PRECISION Word16 float_to_fix_find_q( const float val ); +#endif #endif /* FLOAT_TO_FIX_OPS_H */ diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 541aac3388616dca2e7455bfc53fee2b3abc8d11..c208d6ffe9931e552c8eb4f2ba3bfb8efb4701fb 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -3171,7 +3171,6 @@ ivas_error RenderConfigReader_getDistanceAttenuation( 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 ) ); diff --git a/lib_util/rotation_file_reader.c b/lib_util/rotation_file_reader.c index 5fa236a7fd2edaef7224015a88b4f630bf7608fa..1701f285bbcda3ffa152cdb643e7b9a62c14574d 100644 --- a/lib_util/rotation_file_reader.c +++ b/lib_util/rotation_file_reader.c @@ -160,16 +160,16 @@ 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 ); + posx = min( max( -IVAS_LISTENER_POSITION_MAX, posx ), IVAS_LISTENER_POSITION_MAX ); + posy = min( max( -IVAS_LISTENER_POSITION_MAX, posy ), IVAS_LISTENER_POSITION_MAX ); + posz = min( max( -IVAS_LISTENER_POSITION_MAX, posz ), IVAS_LISTENER_POSITION_MAX ); - maxAbsPos = max( max( fabsf( pPos->x ), fabsf( pPos->y ) ), fabsf( pPos->z ) ); + maxAbsPos = max( max( fabsf( posx ), fabsf( posy ) ), fabsf( posz ) ); pPos->q_fact = float_to_fix_find_q( maxAbsPos ); - pPos->x_fx = floatToFixed_32( pPos->x, pPos->q_fact ); - pPos->y_fx = floatToFixed_32( pPos->y, pPos->q_fact ); - pPos->z_fx = floatToFixed_32( pPos->z, pPos->q_fact ); + pPos->x_fx = floatToFixed_32( posx, pPos->q_fact ); + pPos->y_fx = floatToFixed_32( posy, pPos->q_fact ); + pPos->z_fx = floatToFixed_32( posz, pPos->q_fact ); #else pPos->x = posx; pPos->y = posy;