diff --git a/apps/decoder.c b/apps/decoder.c index bf830ae2d920c664f7f84e8c21fda09006c7095d..179ad3273e02f32a719aa64438decea2df40fe4b 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -488,18 +488,30 @@ 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_fx ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to get Distance Attenuation \n\n" ); + goto cleanup; + } +#endif if ( ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 33013360eb62747e4ffb9b3ced06e34862bb2caa..81c6137a5845222067b712fd3dc2565cc3604567 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 dcaa4dfca393b77e3b60bd4c9a0acdc9146189ba..e940ae943df4b16fd3b5bf2ac119f32d0891322b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -102,6 +102,7 @@ #define NONBE_FIX_SBA_SIGNALING_BITS_B /* FhG: issue 1061: option B: signal sba order additionally in OSBA */ #define NONBE_FIX_1028_1DB_TCX_LEVEL_DROP /* VA: Harmonize the logic setting LP weighting factor between TCX encoder and TCX decoder */ #define FIX_1053_REVERB_RECONFIGURATION /* Philips: issue 1053: fix for dynamic switching of acoustic environment */ +#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 08bf0f437ec7d1abf36ef64e9f968cbaf66c21ca..e64e9d2208082d85a1d7d1e44046ed94799d3eaf 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 98bbfd3d53091ffca8387c1b9c10efe06130ce8b..6252a5aac97912f02090cb3af5e875168b33bf5c 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -2827,6 +2827,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 9eea08c71c7ddcf882b37e82c27be0291f1be424..bfd8566566a6e7d04e58cd985560aa67b4baec72 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 cdb2d98472c9f750d7d0e189b1a1a1febf2cf4a8..bf8b3a30e7f553287f147ed86af51eaf3f2a9b7a 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() * @@ -726,27 +783,48 @@ 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; 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 +844,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 77960f73ef351689c859edd96173757575db243b..b95c152bb06c5ef2d8df7ff4d229d7188b2b844d 100644 --- a/lib_rend/ivas_prot_rend_fx.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -665,6 +665,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 */ @@ -746,7 +749,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 fc5c263510d659daf4507178a7402fc36b1a1e0d..14e2c2a5deed1f8cf764fe378902e8c9fd70194a 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 bef3dfdbefc1c9834d219f21371cc0252a4b99eb..ff2da6484b347b835227680ed60a0001b75d8a03 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; @@ -2728,12 +2899,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 ) { @@ -2791,9 +2969,56 @@ 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; } +#ifdef CONF_DISTATT +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_getDistanceAttenuation() + * + * Gets Distance Attenuation + *------------------------------------------------------------------------------------------*/ + +ivas_error RenderConfigReader_getDistanceAttenuation( + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + + Word32 *distAtt_fx /* o : Distance attenuation */ +) +{ + float distAtt[3]; + + 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]; + } + + /* 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 /*------------------------------------------------------------------------------------------* * RenderConfigReader_close() diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 5edf73ded33d2cc91653c86276a86a92bc496432..ff6e30d83c34b0dbe7ad1bdb0383c467d9aea51b 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -60,8 +60,18 @@ 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 */ + Word32 *distAtt_fx /* o : Distance attenuation */ ); +#endif /* Verifies configuration parameters */ ivas_error RenderConfigReader_checkValues( IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */