From 7b73ca379e5fe232e1aba4dd81668249cb179595 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Mon, 21 Jul 2025 16:25:57 +0200 Subject: [PATCH 1/4] Port MR1531 under define CONF_DISTATT --- apps/decoder.c | 11 +- lib_com/basop_util.c | 4 + lib_com/common_api_types.h | 4 + lib_com/options.h | 1 + lib_dec/ivas_objectRenderer_internal_fx.c | 19 +- lib_dec/lib_dec_fx.c | 3 + lib_rend/ivas_objectRenderer_fx.c | 71 +++++++- lib_rend/ivas_objectRenderer_sources_fx.c | 93 ++++++++++ lib_rend/ivas_prot_rend_fx.h | 11 +- lib_rend/ivas_render_config_fx.c | 9 +- lib_util/render_config_reader.c | 201 +++++++++++++++++++++- lib_util/render_config_reader.h | 6 + 12 files changed, 422 insertions(+), 11 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 98673972e..2de216bee 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -478,7 +478,16 @@ int main( renderConfig.directivity_fx[i * 3 + 1] = (Word16) ( renderConfig.directivity[i * 3 + 1] * ( 1u << 6 ) ); renderConfig.directivity_fx[i * 3 + 2] = (Word16) ( renderConfig.directivity[i * 3 + 2] * ( ( 1u << 15 ) - 1 ) ); } - +#ifdef CONF_DISTATT + if ( ( error = RenderConfigReader_getDistanceAttenuation( renderConfigReader, renderConfig.distAtt ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to get Distance Attenuation \n\n" ); + goto cleanup; + } + renderConfig.distAtt_fx[0] = (Word32) ( renderConfig.distAtt[0] * ( 1u << 27 ) ); + renderConfig.distAtt_fx[1] = (Word32) ( renderConfig.distAtt[1] * ( 1u << 30 ) ); + renderConfig.distAtt_fx[2] = (Word32) ( renderConfig.distAtt[2] * ( 1u << 30 ) ); +#endif if ( ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 3d6324783..6ac8a7700 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -45,6 +45,10 @@ #include "basop_settings.h" #include "cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif + extern const Word32 SqrtTable[32]; // Q31 extern const Word16 SqrtDiffTable[32]; /* Q15 */ diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 33013360e..81c6137a5 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -347,6 +347,10 @@ typedef struct _IVAS_RENDER_CONFIG ISAR_SPLIT_REND_CONFIG_DATA split_rend_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} +#ifdef CONF_DISTATT + float distAtt[3]; + Word32 distAtt_fx[3]; /* {Q27, Q30, Q30} */ +#endif } IVAS_RENDER_CONFIG_DATA, *IVAS_RENDER_CONFIG_HANDLE; typedef struct diff --git a/lib_com/options.h b/lib_com/options.h index 32c53988a..894b2ae67 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -130,6 +130,7 @@ #define NONBE_FIX_991_PARAMBIN_BINARY_HRTF /* Nokia: issue #991: fix using of binary file HRTF in ParamBin (to activate when USE_NEW_HRTF_BINARY_FILE_FORMAT and FIX_777_COMBI_RENDER_CONFIG_FILE are on ) */ #define FIX_1741_REVERB_TIMES_Q_FORMAT /* Philips: reverberation times in Q26 format instead of Q31 */ +#define CONF_DISTATT /* Eri: Make distance attenuation configurable */ /* #################### End BASOP porting switches ############################ */ diff --git a/lib_dec/ivas_objectRenderer_internal_fx.c b/lib_dec/ivas_objectRenderer_internal_fx.c index 08bf0f437..e64e9d220 100644 --- a/lib_dec/ivas_objectRenderer_internal_fx.c +++ b/lib_dec/ivas_objectRenderer_internal_fx.c @@ -59,7 +59,11 @@ ivas_error ivas_td_binaural_open_fx( *num_src = st_ivas->nchan_ism; move16(); } +#ifdef CONF_DISTATT + return ivas_td_binaural_open_unwrap_fx( &st_ivas->hHrtfTD, st_ivas->hDecoderConfig->output_Fs, *num_src, st_ivas->ivas_format, st_ivas->transport_config, st_ivas->hRenderConfig->directivity_fx, st_ivas->hRenderConfig->distAtt_fx, st_ivas->hTransSetup, &st_ivas->hBinRendererTd, &st_ivas->binaural_latency_ns, SrcInd ); +#else return ivas_td_binaural_open_unwrap_fx( &st_ivas->hHrtfTD, st_ivas->hDecoderConfig->output_Fs, *num_src, st_ivas->ivas_format, st_ivas->transport_config, st_ivas->hRenderConfig->directivity_fx, st_ivas->hTransSetup, &st_ivas->hBinRendererTd, &st_ivas->binaural_latency_ns, SrcInd ); +#endif } @@ -328,7 +332,19 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( { continue; } - +#ifdef CONF_DISTATT + IF( ( error = ivas_td_binaural_open_unwrap_fx( &st_ivas->hHrtfTD, + st_ivas->hDecoderConfig->output_Fs, + st_ivas->nchan_transport, + st_ivas->ivas_format, + st_ivas->transport_config, + st_ivas->hRenderConfig->directivity_fx, + st_ivas->hRenderConfig->distAtt_fx, + st_ivas->hTransSetup, + &st_ivas->hTdRendHandles[i], + &st_ivas->binaural_latency_ns, + SrcInd ) ) != IVAS_ERR_OK ) +#else IF( ( error = ivas_td_binaural_open_unwrap_fx( &st_ivas->hHrtfTD, st_ivas->hDecoderConfig->output_Fs, st_ivas->nchan_transport, @@ -339,6 +355,7 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( &st_ivas->hTdRendHandles[i], &st_ivas->binaural_latency_ns, SrcInd ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 4c448efc7..01ca3c708 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -2734,6 +2734,9 @@ ivas_error IVAS_DEC_FeedRenderConfig( Copy32( renderConfig.roomAcoustics.pAcoustic_dsr_fx, hRenderConfig->roomAcoustics.pAcoustic_dsr_fx, CLDFB_NO_CHANNELS_MAX ); // Q30 Copy( renderConfig.directivity_fx, hRenderConfig->directivity_fx, 3 * MAX_NUM_OBJECTS ); +#ifdef CONF_DISTATT + Copy32( renderConfig.distAtt_fx, hRenderConfig->distAtt_fx, 3 ); +#endif hRenderConfig->split_rend_config = renderConfig.split_rend_config; diff --git a/lib_rend/ivas_objectRenderer_fx.c b/lib_rend/ivas_objectRenderer_fx.c index 9eea08c71..bfd856656 100644 --- a/lib_rend/ivas_objectRenderer_fx.c +++ b/lib_rend/ivas_objectRenderer_fx.c @@ -68,12 +68,15 @@ static void angles_to_vec_fx( *---------------------------------------------------------------------*/ ivas_error ivas_td_binaural_open_unwrap_fx( - TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HR filter model (from file or NULL) */ - const Word32 output_Fs, /* i : Output sampling rate */ - const Word16 nchan_transport, /* i : Number of channels */ - const IVAS_FORMAT ivas_format, /* i : IVAS format (ISM/MC) */ - const AUDIO_CONFIG transport_config, /* i : Transport configuration */ - const Word16 *directivity, /* i : Directivity pattern (used for ISM) */ + TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HR filter model (from file or NULL) */ + const Word32 output_Fs, /* i : Output sampling rate */ + const Word16 nchan_transport, /* i : Number of channels */ + const IVAS_FORMAT ivas_format, /* i : IVAS format (ISM/MC) */ + const AUDIO_CONFIG transport_config, /* i : Transport configuration */ + const Word16 *directivity, /* i : Directivity pattern (used for ISM) */ +#ifdef CONF_DISTATT + const Word32 *distAtt, /* i : Distance attenuation (used for ISM) */ +#endif const IVAS_OUTPUT_SETUP hTransSetup, /* i : Loudspeaker layout */ BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd, /* o : TD renderer handle */ Word32 *binaural_latency_ns, /* i : Binauralization delay */ @@ -86,6 +89,9 @@ ivas_error ivas_td_binaural_open_unwrap_fx( Word32 Pos_fx[3]; // Q25 Word32 Dir_fx[3]; // Q30 TDREND_DirAtten_t *DirAtten_p; +#ifdef CONF_DISTATT + TDREND_DistAtten_t DistAtten; +#endif Word16 nchan_rend; ivas_error error; @@ -202,6 +208,17 @@ ivas_error ivas_td_binaural_open_unwrap_fx( DirAtten_p->ConeOuterGain_fx = ONE_IN_Q30; move32(); +#ifdef CONF_DISTATT + DistAtten.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; // Q0 + move16(); + 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 ) ) { @@ -220,6 +237,12 @@ ivas_error ivas_td_binaural_open_unwrap_fx( { return error; } +#ifdef CONF_DISTATT + IF( NE_32( ( error = TDREND_MIX_SRC_SetDistAtten( pBinRendTd, nS, &DistAtten ) ), IVAS_ERR_OK ) ) + { + return error; + } +#endif } } test(); @@ -245,10 +268,36 @@ ivas_error ivas_td_binaural_open_unwrap_fx( move32(); move32(); move32(); +#ifdef CONF_DISTATT + if ( NULL == distAtt ) + { + DistAtten.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; // Q0 + move16(); + 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(); + } + else + { + DistAtten.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; // Q0 + DistAtten.MaxDist_fx = distAtt[0]; + DistAtten.RefDist_fx = distAtt[1]; + DistAtten.RollOffFactor_fx = distAtt[2]; + } +#endif IF( NE_32( ( error = TDREND_MIX_SRC_SetDirAtten_fx( pBinRendTd, nS, DirAtten_p ) ), IVAS_ERR_OK ) ) { return error; } +#ifdef CONF_DISTATT + IF( NE_32( ( error = TDREND_MIX_SRC_SetDistAtten( pBinRendTd, nS, &DistAtten ) ), IVAS_ERR_OK ) ) + { + return error; + } +#endif } } @@ -760,6 +809,9 @@ ivas_error ivas_td_binaural_open_ext_fx( IVAS_OUTPUT_SETUP hTransSetup; ivas_error error; +#ifdef CONF_DISTATT + Word32 *distAtt_fx = NULL; +#endif Word16 *directivity_fx = NULL; IF( NE_16( inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) @@ -801,8 +853,15 @@ ivas_error ivas_td_binaural_open_ext_fx( if ( NULL != hRendCfg ) { directivity_fx = hRendCfg->directivity_fx; +#ifdef CONF_DISTATT + distAtt_fx = hRendCfg->distAtt_fx; +#endif } +#ifdef CONF_DISTATT + return ivas_td_binaural_open_unwrap_fx( pTDRend->hHrtfTD, outFs, nchan_transport, ivas_format, transport_config, directivity_fx, distAtt_fx, hTransSetup, &pTDRend->hBinRendererTd, &pTDRend->binaural_latency_ns, SrcInd ); +#else return ivas_td_binaural_open_unwrap_fx( pTDRend->hHrtfTD, outFs, nchan_transport, ivas_format, transport_config, directivity_fx, hTransSetup, &pTDRend->hBinRendererTd, &pTDRend->binaural_latency_ns, SrcInd ); +#endif } /*---------------------------------------------------------------------* * ivas_td_binaural_renderer_ext() diff --git a/lib_rend/ivas_objectRenderer_sources_fx.c b/lib_rend/ivas_objectRenderer_sources_fx.c index cdb2d9847..b63aa7bf7 100644 --- a/lib_rend/ivas_objectRenderer_sources_fx.c +++ b/lib_rend/ivas_objectRenderer_sources_fx.c @@ -48,6 +48,9 @@ static void TDREND_SRC_SPATIAL_Init_fx( TDREND_SRC_SPATIAL_t *SrcSpatial_p, cons static Word16 TDREND_SRC_SPATIAL_GetDirGain_fx( const TDREND_DirAtten_t *DirAtten_p, const Word32 *Front_p_fx, const Word32 *RelPos_p, const Word16 RelPos_p_e ); static Word16 TDREND_SRC_SPATIAL_GetDistGain_fx( const TDREND_DistAtten_t *DistAtten_p, const Word32 Dist_fx, const Word16 Dist_e ); static void TDREND_SRC_SPATIAL_SetDirAtten_fx( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_DirAtten_t *DirAtten_p ); +#ifdef CONF_DISTATT +static void TDREND_SRC_SPATIAL_SetDistAtten( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_DistAtten_t *DistAtten_p ); +#endif static ivas_error TDREND_SRC_REND_Alloc( TDREND_SRC_REND_t **SrcRend_pp ); static void TDREND_SRC_SPATIAL_Dealloc( TDREND_SRC_SPATIAL_t *SrcSpatial_p ); @@ -154,6 +157,34 @@ ivas_error TDREND_MIX_SRC_SetDirAtten_fx( return IVAS_ERR_OK; } +#ifdef CONF_DISTATT +/*-------------------------------------------------------------------* + * TDREND_MIX_SRC_SetDistAtten() + * + * Set distance attenuation for the mixer. + --------------------------------------------------------------------*/ + +ivas_error TDREND_MIX_SRC_SetDistAtten( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word16 SrcInd, /* i : Source index */ + const TDREND_DistAtten_t *DistAtten_p /* i : Distance attenuation specifier */ +) +{ + TDREND_SRC_SPATIAL_t *SrcSpatial_p; + IF( GT_16( SrcInd, hBinRendererTd->MaxSrcInd ) ) + { + return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index\n" ) ); + } + ELSE + { + SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p; + TDREND_SRC_SPATIAL_SetDistAtten( SrcSpatial_p, DistAtten_p ); + } + + return IVAS_ERR_OK; +} +#endif + /*-------------------------------------------------------------------* * TDREND_MIX_SRC_SetPlayState() @@ -624,6 +655,32 @@ static void TDREND_SRC_SPATIAL_SetDirAtten_fx( return; } +#ifdef CONF_DISTATT +/*-------------------------------------------------------------------* + * TDREND_SRC_SPATIAL_SetDistAtten() + * + * Sets the distance attenuation. + --------------------------------------------------------------------*/ + +static void TDREND_SRC_SPATIAL_SetDistAtten( + TDREND_SRC_SPATIAL_t *SrcSpatial_p, + const TDREND_DistAtten_t *DistAtten_p ) +{ + /* Set distance attenuation */ + SrcSpatial_p->DistAttenEnabled = TRUE; + SrcSpatial_p->DistAtten.DistAttenModel = DistAtten_p->DistAttenModel; + SrcSpatial_p->DistAtten.MaxDist_fx = DistAtten_p->MaxDist_fx; + SrcSpatial_p->DistAtten.RefDist_fx = DistAtten_p->RefDist_fx; + SrcSpatial_p->DistAtten.RollOffFactor_fx = DistAtten_p->RollOffFactor_fx; + move16(); + move32(); + move32(); + move32(); + + return; +} +#endif + /*-------------------------------------------------------------------* * TDREND_SRC_SPATIAL_GetDirGain() * @@ -729,6 +786,10 @@ static Word16 TDREND_SRC_SPATIAL_GetDistGain_fx( Word16 DistGain_e; Word32 tmp32; Word16 flag; +#ifdef CONF_DISTATT + Word16 Dist_s; + Word16 tmp16; +#endif DistGain_fx = ONE_IN_Q14; // Q14 move16(); @@ -738,15 +799,29 @@ static Word16 TDREND_SRC_SPATIAL_GetDistGain_fx( move32(); Dist2_e = Dist_e; move16(); +#ifdef CONF_DISTATT + tmp32 = 0; + move32(); + tmp_e = 0; + move16(); +#endif SWITCH( DistAtten_p->DistAttenModel ) { case TDREND_DIST_ATTEN_MODEL_INV_DIST: +#ifdef CONF_DISTATT + /* DistGain = powf( DistAtten_p->RefDist / Dist2, DistAtten_p->RollOffFactor ); */ + 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) */ +#else tmp32 = BASOP_Util_Add_Mant32Exp( Dist2_fx, Dist2_e, L_negate( DistAtten_p->RefDist_fx ), 1, &tmp_e ); // exp: tmp_e tmp32 = Mpy_32_32( tmp32, DistAtten_p->RollOffFactor_fx ); // exp: 1 + tmp_e tmp32 = BASOP_Util_Add_Mant32Exp( DistAtten_p->RefDist_fx, 1, tmp32, add( 1, tmp_e ), &tmp_e ); // exp: tmp_e DistGain_fx = BASOP_Util_Divide3232_Scale( DistAtten_p->RefDist_fx, tmp32, &DistGain_e ); // exp: DistGain_e DistGain_e = add( DistGain_e, sub( 1, tmp_e ) ); +#endif BREAK; case TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED: @@ -766,16 +841,34 @@ static Word16 TDREND_SRC_SPATIAL_GetDistGain_fx( Dist2_e = 4; move16(); } +#ifdef CONF_DISTATT + /* DistGain = powf( DistAtten_p->RefDist / Dist2, DistAtten_p->RollOffFactor ); */ + 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) */ +#else tmp32 = BASOP_Util_Add_Mant32Exp( Dist2_fx, Dist2_e, L_negate( DistAtten_p->RefDist_fx ), 1, &tmp_e ); // exp: tmp_e tmp32 = Mpy_32_32( tmp32, DistAtten_p->RollOffFactor_fx ); // exp: 1 + tmp_e tmp32 = BASOP_Util_Add_Mant32Exp( DistAtten_p->RefDist_fx, 1, tmp32, add( 1, tmp_e ), &tmp_e ); // exp: tmp_e DistGain_fx = BASOP_Util_Divide3232_Scale( DistAtten_p->RefDist_fx, tmp32, &DistGain_e ); // exp: DistGain_e DistGain_e = add( DistGain_e, sub( 1, tmp_e ) ); +#endif BREAK; } +#ifdef CONF_DISTATT + tmp16 = extract_h( L_shr( tmp32, sub( 1, tmp_e ) ) ); // Reducing it to Q14: Go to Q30 and extract_h. right shift by 31-tmp_e-30 = 1-tmp_e + IF( GT_16( tmp16, ONE_IN_Q14 ) ) + { + tmp16 = ONE_IN_Q14; + } + + DistGain_fx = tmp16; +#else DistGain_fx = shr( DistGain_fx, sub( 1, DistGain_e ) ); // Reducing it to Q14 +#endif return DistGain_fx; } diff --git a/lib_rend/ivas_prot_rend_fx.h b/lib_rend/ivas_prot_rend_fx.h index 0e2033fd4..e7c8fcc42 100644 --- a/lib_rend/ivas_prot_rend_fx.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -669,6 +669,9 @@ ivas_error ivas_td_binaural_open_unwrap_fx( const IVAS_FORMAT ivas_format, /* i : IVAS format (ISM/MC) */ const AUDIO_CONFIG transport_config, /* i : Transport configuration */ const Word16 *directivity, /* i : Directivity pattern (used for ISM) */ +#ifdef CONF_DISTATT + const Word32 *distAtt, /* i : Distance attenuation (used for ISM) */ +#endif const IVAS_OUTPUT_SETUP hTransSetup, /* i : Loudspeaker layout */ BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd, /* o : TD renderer handle */ Word32 *binaural_latency_ns, /* i : Binauralization delay */ @@ -750,7 +753,13 @@ ivas_error TDREND_MIX_SRC_SetDirAtten_fx( const Word16 SrcInd, /* i : Source index */ const TDREND_DirAtten_t *DirAtten_p /* i : Directional attenuation specifier */ ); - +#ifdef CONF_DISTATT +ivas_error TDREND_MIX_SRC_SetDistAtten( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word16 SrcInd, /* i : Source index */ + const TDREND_DistAtten_t *DistAtten_p /* i : Distance attenuation specifier */ +); +#endif ivas_error TDREND_MIX_SRC_SetPlayState( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const Word16 SrcInd, /* i : Source index */ diff --git a/lib_rend/ivas_render_config_fx.c b/lib_rend/ivas_render_config_fx.c index fc5c26351..14e2c2a5d 100644 --- a/lib_rend/ivas_render_config_fx.c +++ b/lib_rend/ivas_render_config_fx.c @@ -136,7 +136,14 @@ 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 CONF_DISTATT + ( *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 = SPLIT_REND_768k; move32(); ( *hRenderConfig )->split_rend_config.dof = 3; diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index bd9e7a48e..25891ff6d 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -129,6 +129,9 @@ struct RenderConfigReader AcousticEnv *pAE; /* Acoustic environments */ uint32_t nDP; /* Number of directivity patterns */ DirectrivityPat *pDP; /* Directivity Pattern */ +#ifdef CONF_DISTATT + float distAtt[3]; /* [MaxDist Q30, RefDist Q30, Rolloff Q30] */ +#endif }; @@ -1005,6 +1008,77 @@ static ivas_error get_bin_outer_attenuation( return IVAS_ERR_OK; } +#ifdef CONF_DISTATT +/*-----------------------------------------------------------------------------------------* + * Function get_bin_max_dist () + * Gets a Maximum Distance value [1.0, 64.0] + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_max_dist( + RenderConfigReader *this, /* i/o : Render config reader handle */ + float *pResult /* o : Attenuation value */ +) +{ + ivas_error error; + uint32_t value; + + if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK ) + { + return error; + } + + *pResult = usdequant( (int16_t) value, 1.0f, 1.0f ); + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_ref_dist () + * Gets a Reference Distance value [0.1, 6.4] + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_ref_dist( + RenderConfigReader *this, /* i/o : Render config reader handle */ + float *pResult /* o : Attenuation value */ +) +{ + ivas_error error; + uint32_t value; + + if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK ) + { + return error; + } + + *pResult = usdequant( (int16_t) value, 0.1f, 0.1f ); + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_rolloff () + * Gets a Rollof Factor [0.0, 4.0] + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_rolloff( + RenderConfigReader *this, /* i/o : Render config reader handle */ + float *pResult /* o : Attenuation value */ +) +{ + ivas_error error; + uint32_t value; + + if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK ) + { + return error; + } + + *pResult = usdequant( (int16_t) value, 0.0f, 0.1f ); + + return IVAS_ERR_OK; +} + +#endif /*-----------------------------------------------------------------------------------------* * Function read_txt_vector() @@ -1132,7 +1206,9 @@ ivas_error RenderConfigReader_checkValues( pRoom_acoustics = &hRenderConfig->roomAcoustics; tab_value_err_count = 0; int16_t wall_idx; - +#ifdef CONF_DISTATT + int16_t i; +#endif /* Verify the number of frequency bands in the config input data */ if ( ( pRoom_acoustics->nBands > N_BANDS_MAX ) || ( pRoom_acoustics->nBands < N_BANDS_MIN ) ) @@ -1238,6 +1314,21 @@ ivas_error RenderConfigReader_checkValues( pRoom_acoustics->AbsCoeff_fx[wall_idx] = ER_MAX_ABS_COEFF_FX; } } +#ifdef CONF_DISTATT + /* Verify range of distance attenuation parameters: 0.1 <= distAtt[0] <= distAtt[1] */ + /* 0.0 <= distAtt[2] <= 10.0 */ + hRenderConfig->distAtt[0] = max( 0.1f, hRenderConfig->distAtt[0] ); + hRenderConfig->distAtt[1] = max( hRenderConfig->distAtt[0], hRenderConfig->distAtt[1] ); + hRenderConfig->distAtt[2] = max( 0.0f, min( 10.0f, hRenderConfig->distAtt[2] ) ); + + /* Verify range of directivity patterns */ + for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ ) + { + hRenderConfig->directivity[i * 3] = max( 0.0f, min( 360.0f, hRenderConfig->directivity[i * 3] ) ); + hRenderConfig->directivity[i * 3 + 1] = max( 0.0f, min( 360.0f, hRenderConfig->directivity[i * 3 + 1] ) ); + hRenderConfig->directivity[i * 3 + 2] = max( 0.0f, min( 1.0f, hRenderConfig->directivity[i * 3 + 2] ) ); + } +#endif } @@ -1279,6 +1370,9 @@ ivas_error RenderConfigReader_open( pSelf->pAE = NULL; pSelf->nDP = 0; pSelf->pDP = NULL; +#ifdef CONF_DISTATT + pSelf->distAtt[0] = -1; +#endif *ppRenderConfigReader = pSelf; return IVAS_ERR_OK; @@ -1798,6 +1892,36 @@ static ivas_error RenderConfigReader_readBinary( } } } +#ifdef CONF_DISTATT + /**********************************/ + /* Read the distance attenuation */ + /**********************************/ + + /* Has distance attenuation */ + if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( value == true ) + { + /* Read the Max Distance */ + if ( ( error = get_bin_max_dist( pRenderConfigReader, &pRenderConfigReader->distAtt[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + /* Read the Ref Distance */ + if ( ( error = get_bin_ref_dist( pRenderConfigReader, &pRenderConfigReader->distAtt[1] ) ) != IVAS_ERR_OK ) + { + return error; + } + /* Read the Rolloff Facto r*/ + if ( ( error = get_bin_rolloff( pRenderConfigReader, &pRenderConfigReader->distAtt[2] ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + /* Cleanup */ free( pRenderConfigReader->pBitstream ); @@ -2562,6 +2686,53 @@ ivas_error RenderConfigReader_read( free( pValue ); accDPIdx++; } +#ifdef CONF_DISTATT + else if ( strcmp( chapter, "DISTANCEATTENUATION" ) == 0 ) + { + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + + /* Set default values if parameters are only partially specified */ + pRenderConfigReader->distAtt[0] = 15.75f; + pRenderConfigReader->distAtt[1] = 1.0f; + pRenderConfigReader->distAtt[2] = 1.0f; + + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + + if ( strcmp( item, "MAXDIST" ) == 0 ) + { + /* Read the Maximum distance */ + if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[0] ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + if ( strcmp( item, "REFDIST" ) == 0 ) + { + /* Read the Reference distance */ + if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[1] ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + if ( strcmp( item, "ROLLOFFFACTOR" ) == 0 ) + { + /* Read the Rolloff Factor */ + if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[2] ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + } + + free( pValue ); + } +#endif else if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) { params_idx = 0; @@ -2788,6 +2959,34 @@ ivas_error RenderConfigReader_getDirectivity( return IVAS_ERR_OK; } +#ifdef CONF_DISTATT +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_getDistanceAttenuation() + * + * Gets Distance Attenuation + *------------------------------------------------------------------------------------------*/ + +ivas_error RenderConfigReader_getDistanceAttenuation( + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + float *distAtt /* o : Distance attenuation */ +) +{ + if ( pRenderConfigReader->distAtt[0] == -1 ) + { + distAtt[0] = 15.75f; + distAtt[1] = 1.0f; + distAtt[2] = 1.0f; + } + else + { + distAtt[0] = pRenderConfigReader->distAtt[0]; + distAtt[1] = pRenderConfigReader->distAtt[1]; + distAtt[2] = pRenderConfigReader->distAtt[2]; + } + + return IVAS_ERR_OK; +} +#endif /*------------------------------------------------------------------------------------------* * RenderConfigReader_close() diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 5edf73ded..561e05f31 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -62,6 +62,12 @@ ivas_error RenderConfigReader_getDirectivity( uint16_t *pId, /* i : Directivity pattern ID */ float *directivity /* o : Target directivity */ ); +#ifdef CONF_DISTATT +ivas_error RenderConfigReader_getDistanceAttenuation( + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + float *distAtt /* o : Distance attenuation */ +); +#endif /* Verifies configuration parameters */ ivas_error RenderConfigReader_checkValues( IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ -- GitLab From ddd5346b1a040ff1b6b4b858ae996b566c62f6e2 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Mon, 21 Jul 2025 16:38:59 +0200 Subject: [PATCH 2/4] Cleanup around CONF_DISTATT --- apps/decoder.c | 11 +++++++---- lib_util/render_config_reader.c | 30 ++++++++++++++++++++++++++++-- lib_util/render_config_reader.h | 8 ++++++-- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 2de216bee..1c6907187 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -467,26 +467,29 @@ int main( goto cleanup; } +#ifdef CONF_DISTATT + if ( ( error = RenderConfigReader_getDirectivity( renderConfigReader, arg.directivityPatternId, renderConfig.directivity_fx ) ) != IVAS_ERR_OK ) +#else if ( ( error = RenderConfigReader_getDirectivity( renderConfigReader, arg.directivityPatternId, renderConfig.directivity ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "Failed to get directivity patterns for one or more of IDs: %d %d %d %d\n\n", arg.directivityPatternId[0], arg.directivityPatternId[1], arg.directivityPatternId[2], arg.directivityPatternId[3] ); goto cleanup; } +#ifndef CONF_DISTATT FOR( Word16 i = 0; i < 4; i++ ) { renderConfig.directivity_fx[i * 3] = (Word16) ( renderConfig.directivity[i * 3] * ( 1u << 6 ) ); renderConfig.directivity_fx[i * 3 + 1] = (Word16) ( renderConfig.directivity[i * 3 + 1] * ( 1u << 6 ) ); renderConfig.directivity_fx[i * 3 + 2] = (Word16) ( renderConfig.directivity[i * 3 + 2] * ( ( 1u << 15 ) - 1 ) ); } +#endif #ifdef CONF_DISTATT - if ( ( error = RenderConfigReader_getDistanceAttenuation( renderConfigReader, renderConfig.distAtt ) ) != IVAS_ERR_OK ) + if ( ( error = RenderConfigReader_getDistanceAttenuation( renderConfigReader, renderConfig.distAtt_fx ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Failed to get Distance Attenuation \n\n" ); goto cleanup; } - renderConfig.distAtt_fx[0] = (Word32) ( renderConfig.distAtt[0] * ( 1u << 27 ) ); - renderConfig.distAtt_fx[1] = (Word32) ( renderConfig.distAtt[1] * ( 1u << 30 ) ); - renderConfig.distAtt_fx[2] = (Word32) ( renderConfig.distAtt[2] * ( 1u << 30 ) ); #endif if ( ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 25891ff6d..68d0a2ef9 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2893,12 +2893,19 @@ ivas_error RenderConfigReader_getAcousticEnvironment( ivas_error RenderConfigReader_getDirectivity( RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ uint16_t *id, /* i : Directivity pattern ID */ - float *directivity /* o : Target directivity */ +#ifdef CONF_DISTATT + Word16 *directivity_fx /* o : Target directivity */ +#else + float *directivity /* o : Target directivity */ +#endif ) { uint16_t n, m; uint16_t last_specified_id; bool idExists; +#ifdef CONF_DISTATT + float directivity[12]; +#endif if ( pRenderConfigReader == NULL ) { @@ -2956,6 +2963,17 @@ ivas_error RenderConfigReader_getDirectivity( } } } + +#ifdef CONF_DISTATT + /* Convert to Word16 */ + FOR( n = 0; n < 4; n++ ) + { + 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 ) ); + } +#endif + return IVAS_ERR_OK; } @@ -2968,9 +2986,12 @@ ivas_error RenderConfigReader_getDirectivity( ivas_error RenderConfigReader_getDistanceAttenuation( RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ - float *distAtt /* o : Distance attenuation */ + + Word32 *distAtt_fx /* o : Distance attenuation */ ) { + float distAtt[3]; + if ( pRenderConfigReader->distAtt[0] == -1 ) { distAtt[0] = 15.75f; @@ -2984,6 +3005,11 @@ ivas_error RenderConfigReader_getDistanceAttenuation( distAtt[2] = pRenderConfigReader->distAtt[2]; } + /* Convert to Word32 */ + distAtt_fx[0] = (Word32) ( distAtt[0] * ( 1u << 27 ) ); + distAtt_fx[1] = (Word32) ( distAtt[1] * ( 1u << 30 ) ); + distAtt_fx[2] = (Word32) ( distAtt[2] * ( 1u << 30 ) ); + return IVAS_ERR_OK; } #endif diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 561e05f31..ff6e30d83 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -60,12 +60,16 @@ ivas_error RenderConfigReader_getAcousticEnvironment( ivas_error RenderConfigReader_getDirectivity( RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ uint16_t *pId, /* i : Directivity pattern ID */ - float *directivity /* o : Target directivity */ +#ifdef CONF_DISTATT + Word16 *directivity_fx /* o : Target directivity */ +#else + float *directivity /* o : Target directivity */ +#endif ); #ifdef CONF_DISTATT ivas_error RenderConfigReader_getDistanceAttenuation( RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ - float *distAtt /* o : Distance attenuation */ + Word32 *distAtt_fx /* o : Distance attenuation */ ); #endif /* Verifies configuration parameters */ -- GitLab From c7869c0efb1a61701ebf0cf543544951533b6b64 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Mon, 21 Jul 2025 16:44:13 +0200 Subject: [PATCH 3/4] Cleanup around CONF_DISTATT, part2 --- lib_com/basop_util.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 6ac8a7700..3d6324783 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -45,10 +45,6 @@ #include "basop_settings.h" #include "cnst.h" -#ifdef DEBUGGING -#include "debug.h" -#endif - extern const Word32 SqrtTable[32]; // Q31 extern const Word16 SqrtDiffTable[32]; /* Q15 */ -- GitLab From 8db2e97867a9bb6fd5c4b1227622aec31d27d14a Mon Sep 17 00:00:00 2001 From: Charles Kinuthia Date: Tue, 5 Aug 2025 09:54:12 +0200 Subject: [PATCH 4/4] add define to DistGain_e variable --- lib_rend/ivas_objectRenderer_sources_fx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib_rend/ivas_objectRenderer_sources_fx.c b/lib_rend/ivas_objectRenderer_sources_fx.c index b63aa7bf7..bf8b3a30e 100644 --- a/lib_rend/ivas_objectRenderer_sources_fx.c +++ b/lib_rend/ivas_objectRenderer_sources_fx.c @@ -783,18 +783,21 @@ static Word16 TDREND_SRC_SPATIAL_GetDistGain_fx( Word32 Dist2_fx; Word16 Dist2_e; Word16 tmp_e; - Word16 DistGain_e; Word32 tmp32; Word16 flag; #ifdef CONF_DISTATT Word16 Dist_s; Word16 tmp16; +#else + Word16 DistGain_e; #endif DistGain_fx = ONE_IN_Q14; // Q14 move16(); +#ifndef CONF_DISTATT DistGain_e = 1; move16(); +#endif Dist2_fx = Dist_fx; move32(); Dist2_e = Dist_e; -- GitLab