From 315a71fbea459db6ff1ff938cc1f87a419c15c9f Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 24 Jan 2023 16:06:21 +0100 Subject: [PATCH 1/5] Added radius and orientation encoding to metadata under define TD5 --- Workspace_msvc/Workspace_msvc.sln | 10 - apps/decoder.c | 19 ++ apps/renderer.c | 5 + lib_com/common_api_types.h | 8 + lib_com/ivas_cnst.h | 11 + lib_com/ivas_ism_config.c | 6 + lib_com/ivas_prot.h | 15 + lib_com/ivas_rom_com.h | 4 +- lib_com/ivas_stat_com.h | 27 +- lib_com/options.h | 1 + lib_dec/ivas_ism_metadata_dec.c | 320 ++++++++++++++++- lib_dec/ivas_stat_dec.h | 6 + lib_dec/lib_dec.c | 24 +- lib_dec/lib_dec.h | 5 + lib_enc/ivas_ism_metadata_enc.c | 456 ++++++++++++++++++++++++- lib_enc/lib_enc.c | 6 +- lib_rend/ivas_lib_rend_internal.h | 3 + lib_rend/ivas_objectRenderer.c | 97 +++++- lib_rend/ivas_objectRenderer_hrFilt.c | 11 + lib_rend/ivas_objectRenderer_sfx.c | 11 +- lib_rend/ivas_objectRenderer_sources.c | 18 +- lib_rend/ivas_objectRenderer_vec.c | 24 +- lib_rend/ivas_render_config.c | 7 + lib_rend/ivas_stat_rend.h | 10 +- lib_util/head_rotation_file_reader.c | 25 +- lib_util/head_rotation_file_reader.h | 9 +- lib_util/ism_file_reader.c | 25 +- lib_util/ism_file_writer.c | 19 +- lib_util/render_config_reader.c | 9 + 29 files changed, 1144 insertions(+), 47 deletions(-) diff --git a/Workspace_msvc/Workspace_msvc.sln b/Workspace_msvc/Workspace_msvc.sln index 32f41bb6dd..169de8644d 100644 --- a/Workspace_msvc/Workspace_msvc.sln +++ b/Workspace_msvc/Workspace_msvc.sln @@ -25,8 +25,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ..\.clang-format = ..\.clang-format EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ivas_crend_unit_test", "..\scripts\ivas_pytests\tests\unit_tests\crend\ivas_crend_unit_test.vcxproj", "{32354377-ACA7-40F9-9A0E-87FC956F0B78}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -118,14 +116,6 @@ Global {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Unittests|Win32.ActiveCfg = Unittests|Win32 {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Unittests|Win32.Build.0 = Unittests|Win32 {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Unittests|x64.ActiveCfg = Release|Win32 - {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Debug|Win32.ActiveCfg = Debug|Win32 - {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Debug|x64.ActiveCfg = Debug|Win32 - {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Release|Win32.ActiveCfg = Release|Win32 - {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Release|x64.ActiveCfg = Release|Win32 - {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Unittests|Win32.ActiveCfg = Release|Win32 - {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Unittests|Win32.Build.0 = Release|Win32 - {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Unittests|x64.ActiveCfg = Release|Win32 - {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Unittests|x64.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/apps/decoder.c b/apps/decoder.c index 88f7322691..7288e40d06 100755 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -378,9 +378,17 @@ int main( IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ +#ifdef TD5 + if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL ) +#else if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM ) +#endif { +#ifdef TD5 + fprintf( stderr, "\nExternal Renderer Config is supported only for BINAURAL and BINAURAL_ROOM. Exiting. \n\n" ); +#else fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n\n" ); +#endif goto cleanup; } @@ -1262,6 +1270,9 @@ static ivas_error decodeG192( ivas_error error = IVAS_ERR_UNKNOWN; uint16_t numObj = 0; IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN; +#ifdef TD5 + float Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES][3]; +#endif IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) @@ -1332,13 +1343,21 @@ static ivas_error decodeG192( { IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef TD5 + if ( ( error = HeadRotationFileReading( headRotReader, Quaternions, Pos ) ) != IVAS_ERR_OK ) +#else if ( ( error = HeadRotationFileReading( headRotReader, Quaternions, frame ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), HeadRotationFileReader_getFilePath( headRotReader ) ); goto cleanup; } +#ifdef TD5 + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions, Pos ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; diff --git a/apps/renderer.c b/apps/renderer.c index 8446b4ad99..ed7bb74616 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -892,7 +892,12 @@ int main( if ( headRotReader != NULL ) { IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME]; +#ifdef TD5 + float Pos[RENDERER_HEAD_POSITIONS_PER_FRAME][3]; + HeadRotationFileReading( headRotReader, quatBuffer, Pos ); +#else HeadRotationFileReading( headRotReader, quatBuffer, frame ); +#endif IVAS_REND_SetHeadRotation( hIvasRend, quatBuffer ); } else diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index b6d4a21c5d..7486bc271a 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -75,6 +75,11 @@ typedef struct _IVAS_ISM_METADATA float radius; float spread; float gainFactor; +#ifdef TD5 + /* Add azimuth/elevation for orientation here */ + float azimuth_orientation; /* azimuth orientation value */ + float elevation_orientation; /* elevation orientation value */ +#endif } IVAS_ISM_METADATA; typedef struct @@ -116,6 +121,9 @@ typedef struct _IVAS_RENDER_CONFIG IVAS_RENDER_TYPE_OVERRIDE renderer_type_override; #endif IVAS_ROOM_ACOUSTICS_CONFIG_DATA room_acoustics; +#ifdef TD5 + float directivity[3]; +#endif } IVAS_RENDER_CONFIG_DATA, *IVAS_RENDER_CONFIG_HANDLE; typedef struct _IVAS_LS_CUSTOM_LAYOUT diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index ceeb78b282..e869abdcab 100755 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -321,6 +321,12 @@ typedef enum #define ISM_Q_STEP 2.5f #define ISM_Q_STEP_BORDER 5.0f +#ifdef TD5 +#define ISM_RADIUS_NBITS 6 +#define ISM_RADIUS_MIN 0.0f +#define ISM_RADIUS_DELTA 0.25f /* Max radius = (2^ISM_RADIUS_NBITS-1)*0.25 = 15.75 */ +#endif // To do TD5 + /* Parametric ISM */ #define MAX_PARAM_ISM_NBANDS 11 #define MAX_PARAM_ISM_NBANDS_WB 9 @@ -355,7 +361,12 @@ enum IND_ISM_AZIMUTH = TAG_ISM_LOOP_START, IND_ISM_ELEVATION_DIFF_FLAG = TAG_ISM_LOOP_START, IND_ISM_ELEVATION = TAG_ISM_LOOP_START, +#ifdef TD5 + IND_ISM_RADIUS_DIFF_FLAG = TAG_ISM_LOOP_START, + IND_ISM_RADIUS = TAG_ISM_LOOP_START, +#endif // TD5 TAG_ISM_LOOP_END = TAG_ISM_LOOP_START + 100, /* IVAS_fmToDo: to be reviewed once the final metadata are defined */ + /* --------- end of loop for objects ----------- */ ISM_MAX_NUM_INDICES diff --git a/lib_com/ivas_ism_config.c b/lib_com/ivas_ism_config.c index a666c5594e..591b826f7a 100644 --- a/lib_com/ivas_ism_config.c +++ b/lib_com/ivas_ism_config.c @@ -329,6 +329,11 @@ void ivas_ism_reset_metadata( { hIsmMeta->azimuth = 0.0f; hIsmMeta->elevation = 0.0f; +#ifdef TD5 + hIsmMeta->azimuth_orientation = 0.0f; + hIsmMeta->elevation_orientation = 0.0f; + hIsmMeta->radius = 0.0f; +#endif // TD5 return; } @@ -459,6 +464,7 @@ void ivas_param_ism_config( hParamIsm->last_az_sgn[i] = 1; hParamIsm->last_el_diff[i] = 0; hParamIsm->last_el_sgn[i] = 1; + // To do TD5 ?? } return; diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 8b4d2b08ce..b9090dcb46 100755 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -828,6 +828,12 @@ ivas_error set_ism_metadata( ISM_METADATA_HANDLE hIsmMeta, /* i/o: ISM metadata handle */ float azimuth, /* i : azimuth */ float elevation /* i : elevation */ +#ifdef TD5 + , + float radius_meta, /* i : radius */ + float azimuth_orientation, /* i : azimuth_orientation */ + float elevation_orientation /* i : elevation_orientation */ +#endif /* TD5 */ ); ivas_error create_ism_metadata_enc( @@ -5192,6 +5198,10 @@ void TDREND_SPATIAL_VecMapToNewCoordSystem( const float *UpVec_p, /* i : Up vector */ const float *RightVec_p, /* i : Right vector */ float *MappedVec_p /* o : Transformed vector */ +#ifdef TD5 + , + float *LisRelPosAbs /* o : Transformed vector without orientation */ +#endif // TD5 ); /*! r: Flag if the orientation has been updated */ @@ -5257,7 +5267,12 @@ void TDREND_firfilt( const int16_t intp_count, /* i : interpolation count */ float *mem, /* i/o: filter memory */ const int16_t subframe_length, /* i : Length of signal */ +#ifdef TD5 + const int16_t filterlength, /* i : Filter length */ + const float Gain /* i : Gain */ +#else const int16_t filterlength /* i : Filter length */ +#endif ); /*----------------------------------------------------------------------------------* * Filter-bank (FB) Mixer diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index 2b3755087c..0b8ba95028 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -318,7 +318,9 @@ extern const float McMASA_LFEGain_vectors[64]; extern const float ism_azimuth_borders[4]; extern const float ism_elevation_borders[4]; - +#ifdef TD5 +extern const float ism_radius_borders[4]; +#endif // TD5 /*----------------------------------------------------------------------------------* * Param ISM ROM tables *----------------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 79d29ea575..0629153f8e 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -43,7 +43,20 @@ /*----------------------------------------------------------------------------------* * Declaration of ISm common (encoder & decoder) structure *----------------------------------------------------------------------------------*/ - +#ifdef TD5 +typedef struct +{ + int16_t last_azimuth_idx; /* last frame index of coded azimuth */ + int16_t azimuth_diff_cnt; /* FEC counter of consecutive differentially azimuth coded frames */ + int16_t last_elevation_idx; /* last frame index of coded elevation */ + int16_t elevation_diff_cnt; /* FEC counter of consecutive differentially elevation coded frames */ +} ISM_METADATA_ANGLE, *ISM_METADATA_ANGLE_HANDLE; +typedef struct +{ + int16_t last_radius_idx; /* last frame index of coded radius */ + int16_t radius_diff_cnt; /* FEC counter of consecutive differentially radius coded frames */ +} ISM_METADATA_RADIUS, *ISM_METADATA_RADIUS_HANDLE; +#endif /* ISM metadata handle (storage for one frame of read ISM metadata) */ typedef struct { @@ -52,12 +65,18 @@ typedef struct float azimuth; /* azimuth value read from the input metadata file */ float elevation; /* azimuth value read from the input metadata file */ - +#ifdef TD5 + float radius; + float azimuth_orientation; /* azimuth orientation value read from the input metadata file */ + float elevation_orientation; /* elevation orientation value read from the input metadata file */ + ISM_METADATA_ANGLE angle[2]; + ISM_METADATA_RADIUS radius_handle; /* radius value read from the input metadata file */ +#else int16_t last_azimuth_idx; /* last frame index of coded azimuth */ int16_t azimuth_diff_cnt; /* FEC counter of consecutive differentially azimuth coded frames */ int16_t last_elevation_idx; /* last frame index of coded elevation */ int16_t elevation_diff_cnt; /* FEC counter of consecutive differentially elevation coded frames */ - +#endif } ISM_METADATA_FRAME, *ISM_METADATA_HANDLE; @@ -145,7 +164,7 @@ typedef struct ivas_param_ism_data_structure int16_t flag_noisy_speech; int16_t noisy_speech_buffer[PARAM_ISM_HYS_BUF_SIZE]; - + // To do TD5 ?? Radius, orientation } PARAM_ISM_CONFIG_DATA, *PARAM_ISM_CONFIG_HANDLE; diff --git a/lib_com/options.h b/lib_com/options.h index 1db2103272..32d84b05c7 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -158,6 +158,7 @@ #define LOW_RATE_TRANS_FIX /* Eri: Fix for critical item during transitions */ #define FIX_197_CREND_INTERFACE +#define TD5 /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ #endif diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index 7a5731a286..e9cda9ec35 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -42,6 +42,14 @@ #endif #include "wmc_auto.h" +/* Local Functions */ +#ifdef TD5 +/*-----------------------------------------------------------------------* + * Local functions + *-----------------------------------------------------------------------*/ +static void decode_angle_indices( DEC_CORE_HANDLE st0, ISM_METADATA_ANGLE_HANDLE angle, int16_t *flag_abs_azimuth ); +int16_t decode_radius( DEC_CORE_HANDLE st0, ISM_METADATA_RADIUS_HANDLE radius_handle, int16_t *flag_abs_radius ); +#endif /*-------------------------------------------------------------------------* * ivas_ism_metadata_dec() @@ -60,11 +68,24 @@ ivas_error ivas_ism_metadata_dec( const PARAM_ISM_CONFIG_HANDLE hParamIsm /* i : Param ISM Config Handle */ ) { +#ifdef TD5 + int16_t ch, nb_bits_start = 0, last_bit_pos; + int16_t idx_radius; +#else int16_t ch, nb_bits_start = 0, last_bit_pos, sgn, diff; +#endif int32_t element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS]; DEC_CORE_HANDLE st0; +#ifdef TD5 + int16_t decode_orientation_radius_flag; + int16_t flag_abs_radius; + int16_t flag_abs_orientation; + int16_t idx_azimuth, flag_abs_azimuth; + int16_t idx_elevation; +#else int16_t idx_azimuth, nbits_diff_azimuth, flag_abs_azimuth; int16_t idx_elevation, nbits_diff_elevation; +#endif int16_t next_bit_pos_orig; uint16_t i, bstr_meta[MAX_BITS_METADATA], *bstr_orig; ISM_METADATA_HANDLE hIsmMetaData; @@ -105,7 +126,16 @@ ivas_error ivas_ism_metadata_dec( st0 = hSCE[0]->hCoreCoder[0]; ism_metadata_flag_global = 0; nchan_transport_prev = *nchan_transport; - +#ifdef TD5 + if ( ism_total_brate < IVAS_64k ) + { + decode_orientation_radius_flag = 0; + } + else + { + decode_orientation_radius_flag = 1; + } +#endif last_bit_pos = (int16_t) ( ( ism_total_brate / FRAMES_PER_SEC ) - 1 ); bstr_orig = st0->bit_stream; next_bit_pos_orig = st0->next_bit_pos; @@ -208,9 +238,47 @@ ivas_error ivas_ism_metadata_dec( } flag_abs_azimuth = 0; - +#ifdef TD5 + flag_abs_orientation = 0; + flag_abs_radius = 0; +#endif if ( hIsmMeta[ch]->ism_metadata_flag ) { + +#ifdef TD5 + decode_angle_indices( st0, &( hIsmMetaData->angle[0] ), &flag_abs_azimuth ); + idx_azimuth = hIsmMetaData->angle[0].last_azimuth_idx; + idx_elevation = hIsmMetaData->angle[0].last_elevation_idx; + + /* Azimuth/Elevation dequantization */ + if ( ism_mode == ISM_MODE_PARAM ) + { + hParamIsm->azi_index[ch] = idx_azimuth; + hParamIsm->ele_index[ch] = idx_elevation; + } + else /* ISM_MODE_DISC */ + { + hIsmMetaData->azimuth = ism_dequant_meta( idx_azimuth, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ); + hIsmMetaData->elevation = ism_dequant_meta( idx_elevation, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ); + + if ( decode_orientation_radius_flag ) + { + decode_angle_indices( st0, &( hIsmMetaData->angle[1] ), &flag_abs_orientation ); + idx_azimuth = hIsmMetaData->angle[1].last_azimuth_idx; + idx_elevation = hIsmMetaData->angle[1].last_elevation_idx; + + hIsmMetaData->azimuth_orientation = ism_dequant_meta( idx_azimuth, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ); + hIsmMetaData->elevation_orientation = ism_dequant_meta( idx_elevation, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ); + + idx_radius = decode_radius( st0, &( hIsmMetaData->radius_handle ), &flag_abs_radius ); + hIsmMetaData->radius = usdequant( idx_radius, ISM_RADIUS_MIN, ISM_RADIUS_DELTA ); + } + else + { + hIsmMetaData->radius = 1.0f; + } + } +#else /*----------------------------------------------------------------* * Azimuth decoding and dequantization *----------------------------------------------------------------*/ @@ -254,8 +322,11 @@ ivas_error ivas_ism_metadata_dec( nbits_diff_azimuth++; } } - +#ifdef TD5 + idx_azimuth = hIsmMetaData->angle[0].last_azimuth_idx + sgn * diff; +#else idx_azimuth = hIsmMetaData->last_azimuth_idx + sgn * diff; +#endif } /* azimuth is on a circle - check for diff coding for -180° -> 180° and vice versa changes */ @@ -277,7 +348,11 @@ ivas_error ivas_ism_metadata_dec( /* sanity check in case of FER or BER */ if ( idx_azimuth < 0 || idx_azimuth > ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) { +#ifdef TD5 + idx_azimuth = hIsmMetaData->angle[0].last_azimuth_idx; +#else idx_azimuth = hIsmMetaData->last_azimuth_idx; +#endif } /* Azimuth dequantization */ @@ -333,13 +408,21 @@ ivas_error ivas_ism_metadata_dec( } } +#ifdef TD5 + idx_elevation = hIsmMetaData->angle[0].last_elevation_idx + sgn * diff; +#else idx_elevation = hIsmMetaData->last_elevation_idx + sgn * diff; +#endif } /* sanity check in case of FER or BER */ if ( idx_elevation < 0 || idx_elevation > ( 1 << ISM_ELEVATION_NBITS ) - 1 ) { +#ifdef TD5 + idx_elevation = hIsmMetaData->angle[0].last_elevation_idx; +#else idx_elevation = hIsmMetaData->last_elevation_idx; +#endif } /* Elevation dequantization */ @@ -357,17 +440,21 @@ ivas_error ivas_ism_metadata_dec( *----------------------------------------------------------------*/ /* updates */ +#ifdef TD5 + hIsmMetaData->angle[0].last_azimuth_idx = idx_azimuth; + hIsmMetaData->angle[0].last_elevation_idx = idx_elevation; +#else hIsmMetaData->last_azimuth_idx = idx_azimuth; hIsmMetaData->last_elevation_idx = idx_elevation; +#endif +#endif } - /* save number of metadata bits read */ if ( ism_mode == ISM_MODE_DISC ) { nb_bits_metadata[ch] = st0->next_bit_pos - nb_bits_start; } } - if ( ism_mode == ISM_MODE_PARAM ) { hParamIsm->flag_noisy_speech = get_next_indice( st0, 1 ); @@ -443,8 +530,13 @@ ivas_error ivas_ism_metadata_dec( hParamIsm->ele_index[ch] = hParamIsm->ele_index[ch] + hParamIsm->last_el_sgn[ch] * hParamIsm->last_el_diff[ch]; /*hParamIsm->ele_index[ch] = hParamIsm->ele_index[ch] % hParamIsm->ele_alpha;*/ hParamIsm->ele_index[ch] = hParamIsm->ele_index[ch]; +#ifdef TD5 + hIsmMeta[ch]->angle[0].last_azimuth_idx = hParamIsm->azi_index[ch]; + hIsmMeta[ch]->angle[0].last_elevation_idx = hParamIsm->ele_index[ch]; +#else hIsmMeta[ch]->last_azimuth_idx = hParamIsm->azi_index[ch]; hIsmMeta[ch]->last_elevation_idx = hParamIsm->ele_index[ch]; +#endif } } } @@ -456,7 +548,6 @@ ivas_error ivas_ism_metadata_dec( if ( !bfi ) { ivas_ism_config( ism_total_brate, *nchan_transport, num_obj, hIsmMeta, localVAD, ism_imp, element_brate, total_brate, nb_bits_metadata ); - for ( ch = 0; ch < *nchan_transport; ch++ ) { hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag; @@ -528,8 +619,14 @@ ivas_error create_ism_metadata_dec( } st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0; +#ifdef TD5 + st_ivas->hIsmMetaData[ch]->angle[0].last_azimuth_idx = 0; + st_ivas->hIsmMetaData[ch]->angle[0].last_elevation_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); + st_ivas->hIsmMetaData[ch]->angle[1].last_elevation_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); +#else st_ivas->hIsmMetaData[ch]->last_azimuth_idx = 0; st_ivas->hIsmMetaData[ch]->last_elevation_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); +#endif ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] ); } @@ -538,3 +635,214 @@ ivas_error create_ism_metadata_dec( return IVAS_ERR_OK; } + +#ifdef TD5 +static void decode_angle_indices( + DEC_CORE_HANDLE st0, /* i/o: bitstream handle */ + ISM_METADATA_ANGLE_HANDLE angle, /* i/o: angle handle */ + int16_t *flag_abs_azimuth /* o : Azimuth encoding mode */ +) +{ + /*----------------------------------------------------------------* + * Azimuth decoding and dequantization + *----------------------------------------------------------------*/ + int16_t idx_azimuth, nbits_diff_azimuth, diff, sgn; + int16_t idx_elevation, nbits_diff_elevation; + + /* Decode azimuth index */ + if ( get_next_indice( st0, 1 ) == 1 ) /* azimuth_abs_flag */ + { + idx_azimuth = get_next_indice( st0, ISM_AZIMUTH_NBITS ); + *flag_abs_azimuth = 1; + } + else + { + diff = 0; + sgn = 1; + + if ( get_next_indice( st0, 1 ) == 0 ) + { + nbits_diff_azimuth = 1; + } + else + { + nbits_diff_azimuth = 1; + + if ( get_next_indice( st0, 1 ) == 1 ) /* negative sign */ + { + sgn = -1; + } + + nbits_diff_azimuth++; + + /* read until the stop bit */ + while ( ( nbits_diff_azimuth < ISM_AZIMUTH_NBITS - 1 ) && ( get_next_indice( st0, 1 ) == 1 ) ) + { + diff++; + nbits_diff_azimuth++; + } + + if ( nbits_diff_azimuth < ISM_AZIMUTH_NBITS - 1 ) + { + /* count stop bit */ + nbits_diff_azimuth++; + } + } + // idx_azimuth = hIsmMetaData->angle[0].last_azimuth_idx + sgn * diff; + idx_azimuth = angle->last_azimuth_idx + sgn * diff; + } + + /* azimuth is on a circle - check for diff coding for -180° -> 180° and vice versa changes */ + if ( idx_azimuth > ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) + { + idx_azimuth -= ( 1 << ISM_AZIMUTH_NBITS ) - 1; /* +180° -> -180° */ + } + else if ( idx_azimuth < 0 ) + { + idx_azimuth += ( 1 << ISM_AZIMUTH_NBITS ) - 1; /* -180° -> +180° */ + } + + /* +180° == -180° */ + if ( idx_azimuth == ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) + { + idx_azimuth = 0; + } + + /* sanity check in case of FER or BER */ + if ( idx_azimuth < 0 || idx_azimuth > ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) + { + // idx_azimuth = hIsmMetaData->angle[0].last_azimuth_idx; + idx_azimuth = angle->last_azimuth_idx; + } + + /*----------------------------------------------------------------* + * Elevation decoding and dequantization + *----------------------------------------------------------------*/ + + /* Decode elevation index */ + if ( *flag_abs_azimuth == 0 && get_next_indice( st0, 1 ) == 1 ) /* elevation_abs_flag */ + { + idx_elevation = get_next_indice( st0, ISM_ELEVATION_NBITS ); + } + else + { + diff = 0; + sgn = 1; + + if ( get_next_indice( st0, 1 ) == 0 ) + { + nbits_diff_elevation = 1; + } + else + { + nbits_diff_elevation = 1; + + if ( get_next_indice( st0, 1 ) == 1 ) /* negative sign */ + { + sgn = -1; + } + + nbits_diff_elevation++; + + /* read until the stop bit */ + while ( ( nbits_diff_elevation < ISM_ELEVATION_NBITS ) && ( get_next_indice( st0, 1 ) == 1 ) ) + { + diff++; + nbits_diff_elevation++; + } + + if ( nbits_diff_elevation < ISM_ELEVATION_NBITS ) + { + /* count stop bit */ + nbits_diff_elevation++; + } + } + + idx_elevation = angle->last_elevation_idx + sgn * diff; + } + + /* sanity check in case of FER or BER */ + if ( idx_elevation < 0 || idx_elevation > ( 1 << ISM_ELEVATION_NBITS ) - 1 ) + { + // idx_elevation = hIsmMetaData->angle[0].last_elevation_idx; + idx_elevation = angle->last_elevation_idx; + } + /*----------------------------------------------------------------* + * Final updates + *----------------------------------------------------------------*/ + + /* updates */ + angle->last_azimuth_idx = idx_azimuth; + angle->last_elevation_idx = idx_elevation; + return; +} + +int16_t decode_radius( + DEC_CORE_HANDLE st0, /* i/o: bitstream handle */ + ISM_METADATA_RADIUS_HANDLE radius_handle, /* i/o: radius handle */ + int16_t *flag_abs_radius /* o : Radius encoding mode */ +) +{ + /*----------------------------------------------------------------* + * Radius decoding and dequantization + *----------------------------------------------------------------*/ + int16_t idx_radius, nbits_diff_radius, diff, sgn; + + + /* Decode radius index */ + if ( get_next_indice( st0, 1 ) == 1 ) /* elevation_abs_flag */ + { + *flag_abs_radius = 1; + idx_radius = get_next_indice( st0, ISM_RADIUS_NBITS ); + } + else + { + diff = 0; + sgn = 1; + + if ( get_next_indice( st0, 1 ) == 0 ) + { + nbits_diff_radius = 1; + } + else + { + nbits_diff_radius = 1; + + if ( get_next_indice( st0, 1 ) == 1 ) /* negative sign */ + { + sgn = -1; + } + + nbits_diff_radius++; + + /* read until the stop bit */ + while ( ( nbits_diff_radius < ISM_RADIUS_NBITS ) && ( get_next_indice( st0, 1 ) == 1 ) ) + { + diff++; + nbits_diff_radius++; + } + + if ( nbits_diff_radius < ISM_RADIUS_NBITS ) + { + /* count stop bit */ + nbits_diff_radius++; + } + } + idx_radius = radius_handle->last_radius_idx + sgn * diff; + } + + /* sanity check in case of FER or BER */ + if ( idx_radius < 0 || idx_radius > ( 1 << ISM_RADIUS_NBITS ) - 1 ) + { + idx_radius = radius_handle->last_radius_idx; + } + + /*----------------------------------------------------------------* + * Final updates + *----------------------------------------------------------------*/ + + /* updates */ + radius_handle->last_radius_idx = idx_radius; + return idx_radius; +} +#endif diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 4fceaf79f6..2a0fdc1d61 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1312,6 +1312,9 @@ typedef struct ivas_binaural_head_track_struct { int16_t num_quaternions; IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef TD5 + float Pos[MAX_PARAM_SPATIAL_SUBFRAMES][3]; +#endif float Rmat[3][3]; float Rmat_prev[3][3]; @@ -1622,6 +1625,9 @@ typedef struct ivas_render_config_t ivas_renderTypeOverride renderer_type_override; #endif ivas_roomAcoustics_t roomAcoustics; +#ifdef TD5 + float directivity[3]; // Todo: Replace with constant +#endif } RENDER_CONFIG_DATA, *RENDER_CONFIG_HANDLE; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 13a5d96953..727aded955 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -844,7 +844,13 @@ ivas_error IVAS_DEC_GetObjectMetadata( { metadata->azimuth = hIsmMeta->azimuth; metadata->elevation = hIsmMeta->elevation; +#ifdef TD5 + metadata->radius = hIsmMeta->radius; + metadata->azimuth_orientation = hIsmMeta->azimuth_orientation; + metadata->elevation_orientation = hIsmMeta->elevation_orientation; +#else metadata->radius = 0.f; +#endif // TD5 metadata->spread = 0.f; metadata->gainFactor = 1.f; } @@ -886,8 +892,13 @@ ivas_error IVAS_DEC_GetMasaMetadata( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_FeedHeadTrackData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifdef TD5 + IVAS_QUATERNION *orientation, /* i : listener orientation */ + float Pos[4][3] /* i : listener position */ +#else IVAS_QUATERNION *orientation /* i : head-tracking data */ +#endif ) { HEAD_TRACK_DATA_HANDLE hHeadTrackData; @@ -912,6 +923,11 @@ ivas_error IVAS_DEC_FeedHeadTrackData( hHeadTrackData->Quaternions[i].x = orientation[i].x; hHeadTrackData->Quaternions[i].y = orientation[i].y; hHeadTrackData->Quaternions[i].z = orientation[i].z; +#ifdef TD5 + hHeadTrackData->Pos[i][0] = Pos[i][0]; + hHeadTrackData->Pos[i][1] = Pos[i][1]; + hHeadTrackData->Pos[i][2] = Pos[i][2]; +#endif } hIvasDec->st_ivas->hHeadTrackData->num_quaternions = 0; @@ -1039,6 +1055,9 @@ ivas_error IVAS_DEC_GetRenderConfig( mvr2r( hRCin->roomAcoustics.pFc_input, hRCout->room_acoustics.pFc_input, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->roomAcoustics.pAcoustic_rt60, hRCout->room_acoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->room_acoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); +#ifdef TD5 + mvr2r( hRCin->directivity, hRCout->directivity, 3 ); +#endif return IVAS_ERR_OK; } @@ -1083,6 +1102,9 @@ ivas_error IVAS_DEC_FeedRenderConfig( mvr2r( renderConfig.room_acoustics.pFc_input, hRenderConfig->roomAcoustics.pFc_input, CLDFB_NO_CHANNELS_MAX ); mvr2r( renderConfig.room_acoustics.pAcoustic_rt60, hRenderConfig->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); mvr2r( renderConfig.room_acoustics.pAcoustic_dsr, hRenderConfig->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); +#ifdef TD5 + mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 ); +#endif return IVAS_ERR_OK; } diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 1af44bb43f..4999e93eb8 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -177,7 +177,12 @@ ivas_error IVAS_DEC_GetMasaMetadata( /*! r: error code */ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifdef TD5 + IVAS_QUATERNION *orientation, /* i : listener orientation */ + float Pos[4][3] /* i : listener position */ +#else IVAS_QUATERNION *orientation /* i : head-tracking data */ +#endif ); /*! r: error code */ diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index efec918914..3e6a6cbe43 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -53,11 +53,22 @@ #define ISM_MAX_AZIMUTH_DIFF_IDX ( ISM_AZIMUTH_NBITS - 1 /*zero*/ - 1 /*sign*/ ) #define ISM_MAX_ELEVATION_DIFF_IDX ( ISM_ELEVATION_NBITS - 1 /*zero*/ - 1 /*sign*/ ) +#ifdef TD5 +#define ISM_MAX_RADIUS_DIFF_IDX ( ISM_RADIUS_NBITS - 1 /*zero*/ - 1 /*sign*/ ) +#endif // TD5 #define ISM_FEC_MAX 10 #define INTER_OBJECT_PARAM_CHECK ( ( ISM_FEC_MAX / 2 ) - 2 ) /* note: constant must be less than (ISM_FEC_MAX / number of coded parameters) */ +#ifdef TD5 +/*-----------------------------------------------------------------------* + * Local functions + *-----------------------------------------------------------------------*/ +static void encode_angle_indices( BSTR_ENC_HANDLE hBstr, ISM_METADATA_ANGLE_HANDLE angle, const int16_t last_ism_metadata_flag, const int16_t ini_frame, const int16_t idx_azimuth_abs, const int16_t idx_elevation_abs, int16_t *flag_abs_azimuth, int16_t *flag_abs_elevation ); +static void encode_radius( BSTR_ENC_HANDLE hBstr, ISM_METADATA_RADIUS_HANDLE radius_handle, const int16_t last_ism_metadata_flag, const int16_t idx_radius_abs, int16_t *flag_abs_radius ); + +#endif /*-------------------------------------------------------------------------* * set_ism_metadata() @@ -69,7 +80,14 @@ ivas_error set_ism_metadata( ISM_METADATA_HANDLE hIsmMeta, float azimuth, - float elevation ) + float elevation +#ifdef TD5 + , + float radius_meta, + float azimuth_orientation, + float elevation_orientation +#endif /* TD5 */ +) { if ( hIsmMeta == NULL ) { @@ -81,7 +99,12 @@ ivas_error set_ism_metadata( /* save read metadata parameters to the internal codec structure */ hIsmMeta->azimuth = azimuth; hIsmMeta->elevation = elevation; - + /* TD5 azimuth_orientation, elevation_orientation*/ +#ifdef TD5 + hIsmMeta->radius = radius_meta; + hIsmMeta->azimuth_orientation = azimuth_orientation; + hIsmMeta->elevation_orientation = elevation_orientation; +#endif /* TD5 */ return IVAS_ERR_OK; } @@ -157,8 +180,16 @@ ivas_error ivas_ism_metadata_enc( ) { int16_t i, ch, nb_bits_start = 0, diff; +#ifdef TD5 + int16_t idx_azimuth_abs = 0, flag_abs_azimuth[MAX_NUM_OBJECTS]; + int16_t idx_elevation_abs = 0, flag_abs_elevation[MAX_NUM_OBJECTS]; + int16_t flag_abs_azimuth_orientation[MAX_NUM_OBJECTS]; + int16_t idx_radius_abs = 0, flag_abs_radius[MAX_NUM_OBJECTS]; + int16_t encode_orientation_radius_flag; +#else int16_t idx_azimuth, idx_azimuth_abs = 0, flag_abs_azimuth[MAX_NUM_OBJECTS], nbits_diff_azimuth; int16_t idx_elevation, idx_elevation_abs = 0, flag_abs_elevation[MAX_NUM_OBJECTS], nbits_diff_elevation; +#endif float valQ; ISM_METADATA_HANDLE hIsmMetaData; int32_t element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS]; @@ -197,6 +228,19 @@ ivas_error ivas_ism_metadata_enc( set_s( nb_bits_metadata, 0, nchan_transport ); set_s( flag_abs_azimuth, 0, num_obj ); set_s( flag_abs_elevation, 0, num_obj ); +#ifdef TD5 + if ( ism_total_brate < IVAS_64k ) + { + encode_orientation_radius_flag = 0; + } + else + { + encode_orientation_radius_flag = 1; + } + set_s( flag_abs_azimuth_orientation, 0, num_obj ); + set_s( flag_abs_radius, 0, num_obj ); +#endif + /*----------------------------------------------------------------* * Set Metadata presence / importance flag @@ -215,8 +259,18 @@ ivas_error ivas_ism_metadata_enc( if ( hIsmMeta[ch]->ism_metadata_flag == 0 ) { /* send metadata even in inactive segments when noise is audible and metadata are changing */ +#ifdef TD5 + diff = (int16_t) fabsf( hIsmMeta[ch]->azimuth - ism_dequant_meta( hIsmMeta[ch]->angle[0].last_azimuth_idx, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ) ); + diff = max( diff, (int16_t) fabsf( hIsmMeta[ch]->elevation - ism_dequant_meta( hIsmMeta[ch]->angle[0].last_elevation_idx, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ) ) ); + if ( encode_orientation_radius_flag ) + { + diff = max( diff, (int16_t) fabsf( hIsmMeta[ch]->azimuth_orientation - ism_dequant_meta( hIsmMeta[ch]->angle[1].last_azimuth_idx, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ) ) ); + diff = max( diff, (int16_t) fabsf( hIsmMeta[ch]->elevation_orientation - ism_dequant_meta( hIsmMeta[ch]->angle[1].last_elevation_idx, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ) ) ); + } +#else diff = (int16_t) fabsf( hIsmMeta[ch]->azimuth - ism_dequant_meta( hIsmMeta[ch]->last_azimuth_idx, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ) ); diff = max( diff, (int16_t) fabsf( hIsmMeta[ch]->elevation - ism_dequant_meta( hIsmMeta[ch]->last_elevation_idx, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ) ) ); +#endif if ( hSCE[ch]->hCoreCoder[0]->lp_noise > 15 && diff >= 10 ) { @@ -317,6 +371,39 @@ ivas_error ivas_ism_metadata_enc( if ( hIsmMeta[ch]->ism_metadata_flag ) { + +#ifdef TD5 + /*----------------------------------------------------------------* + * Obtain quantizer indices for azimuth and elevation + *----------------------------------------------------------------*/ + if ( ism_mode == ISM_MODE_DISC ) + { + idx_azimuth_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ); + idx_elevation_abs = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ); + } + else /* ISM_MODE_PARAM */ + { + idx_azimuth_abs = hParamIsm->azi_index[ch]; + idx_elevation_abs = hParamIsm->ele_index[ch]; + } + + encode_angle_indices( hBstr, &( hIsmMetaData->angle[0] ), hIsmMetaData->last_ism_metadata_flag, hSCE[0]->hCoreCoder[0]->ini_frame, idx_azimuth_abs, idx_elevation_abs, &flag_abs_azimuth[ch], &flag_abs_elevation[ch] ); + + /* Encode orientation and radius, if above certain bit rate etc, discrete ISM */ + if ( ism_mode == ISM_MODE_DISC && encode_orientation_radius_flag ) + { + idx_azimuth_abs = ism_quant_meta( hIsmMetaData->azimuth_orientation, &valQ, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ); + idx_elevation_abs = ism_quant_meta( hIsmMetaData->elevation_orientation, &valQ, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ); + idx_radius_abs = usquant( hIsmMetaData->radius, &valQ, ISM_RADIUS_MIN, ISM_RADIUS_DELTA, 1 << ISM_RADIUS_NBITS ); + encode_angle_indices( hBstr, &( hIsmMetaData->angle[1] ), hIsmMetaData->last_ism_metadata_flag, hSCE[0]->hCoreCoder[0]->ini_frame, idx_azimuth_abs, idx_elevation_abs, &flag_abs_azimuth_orientation[ch], &flag_abs_elevation[ch] ); + encode_radius( hBstr, &( hIsmMetaData->radius_handle ), hIsmMetaData->last_ism_metadata_flag, idx_radius_abs, &flag_abs_radius[ch] ); + } + /* save number of metadata bits written */ + if ( ism_mode == ISM_MODE_DISC ) + { + nb_bits_metadata[ch] = hBstr->nb_bits_tot - nb_bits_start; + } +#else /*----------------------------------------------------------------* * Azimuth quantization and encoding *----------------------------------------------------------------*/ @@ -561,6 +648,7 @@ ivas_error ivas_ism_metadata_enc( { nb_bits_metadata[ch] = hBstr->nb_bits_tot - nb_bits_start; } +#endif } } @@ -621,12 +709,20 @@ ivas_error ivas_ism_metadata_enc( if ( abs_next % ISM_NUM_PARAM == 0 ) { +#ifdef TD5 + hIsmMeta[ch]->angle[0].azimuth_diff_cnt = abs_num - 1; +#else hIsmMeta[ch]->azimuth_diff_cnt = abs_num - 1; +#endif } if ( abs_next % ISM_NUM_PARAM == 1 ) { +#ifdef TD5 + hIsmMeta[ch]->angle[0].elevation_diff_cnt = abs_num - 1; +#else hIsmMeta[ch]->elevation_diff_cnt = abs_num - 1; +#endif /*hIsmMeta[ch]->elevation_diff_cnt = min( hIsmMeta[ch]->elevation_diff_cnt, ISM_FEC_MAX );*/ } @@ -757,10 +853,24 @@ ivas_error create_ism_metadata_enc( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISm MetaData\n" ) ); } +#ifdef TD5 + st_ivas->hIsmMetaData[ch]->angle[0].last_azimuth_idx = 0; + st_ivas->hIsmMetaData[ch]->angle[0].azimuth_diff_cnt = ISM_FEC_MAX; + st_ivas->hIsmMetaData[ch]->angle[0].last_elevation_idx = 0; + st_ivas->hIsmMetaData[ch]->angle[0].elevation_diff_cnt = ISM_FEC_MAX - 1; + st_ivas->hIsmMetaData[ch]->radius_handle.last_radius_idx = 0; + st_ivas->hIsmMetaData[ch]->radius_handle.radius_diff_cnt = ISM_FEC_MAX - 2; + // To do TD5 --- + st_ivas->hIsmMetaData[ch]->angle[1].last_azimuth_idx = 0; + st_ivas->hIsmMetaData[ch]->angle[1].azimuth_diff_cnt = ISM_FEC_MAX - 2; + st_ivas->hIsmMetaData[ch]->angle[1].last_elevation_idx = 0; + st_ivas->hIsmMetaData[ch]->angle[1].elevation_diff_cnt = ISM_FEC_MAX - 2; +#else st_ivas->hIsmMetaData[ch]->last_azimuth_idx = 0; st_ivas->hIsmMetaData[ch]->azimuth_diff_cnt = ISM_FEC_MAX; st_ivas->hIsmMetaData[ch]->last_elevation_idx = 0; st_ivas->hIsmMetaData[ch]->elevation_diff_cnt = ISM_FEC_MAX - 1; +#endif st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0; ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] ); @@ -770,3 +880,345 @@ ivas_error create_ism_metadata_enc( return IVAS_ERR_OK; } + +#ifdef TD5 +static void encode_radius( + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + ISM_METADATA_RADIUS_HANDLE radius_handle, /* i/o: radius handle */ + const int16_t last_ism_metadata_flag, /* last frame ism_metadata_flag */ + const int16_t idx_radius_abs, /* i : Azimuth index */ + int16_t *flag_abs_radius /* o : Radius encoding mode */ +) +{ + int16_t idx_radius, nbits_diff_radius, diff; + + + /*----------------------------------------------------------------* + * Radius index encoding + *----------------------------------------------------------------*/ + idx_radius = idx_radius_abs; + + nbits_diff_radius = 0; + + *flag_abs_radius = 0; /* differential coding by default */ + + if ( radius_handle->radius_diff_cnt == ISM_FEC_MAX /* make differential encoding in ISM_FEC_MAX consecutive frames at maximum (in order to control the decoding in FEC) */ + || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */ + ) + { + *flag_abs_radius = 1; + } + + diff = idx_radius_abs - radius_handle->last_radius_idx; + + /* try differential coding */ + if ( *flag_abs_radius == 0 ) + { + if ( diff == 0 ) + { + idx_radius = 0; + nbits_diff_radius = 1; + } + else if ( ABSVAL( diff ) <= ISM_MAX_RADIUS_DIFF_IDX ) + { + idx_radius = 1 << 1; + nbits_diff_radius = 1; + + if ( diff < 0 ) + { + idx_radius += 1; /* negative sign */ + diff *= -1; + } + else + { + idx_radius += 0; /* positive sign */ + } + + idx_radius = idx_radius << diff; + nbits_diff_radius++; + + /* unary coding of "diff */ + idx_radius += ( ( 1 << diff ) - 1 ); + nbits_diff_radius += diff; + + if ( nbits_diff_radius < ISM_RADIUS_NBITS ) + { + /* add stop bit */ + idx_radius = idx_radius << 1; + nbits_diff_radius++; + } + } + else + { + *flag_abs_radius = 1; + } + } + + /* update counter */ + if ( *flag_abs_radius == 0 ) + { + radius_handle->radius_diff_cnt++; + radius_handle->radius_diff_cnt = min( radius_handle->radius_diff_cnt, ISM_FEC_MAX ); + } + else + { + radius_handle->radius_diff_cnt = 0; + } + + /* Write radius */ + push_indice( hBstr, IND_ISM_RADIUS_DIFF_FLAG, *flag_abs_radius, 1 ); + + if ( *flag_abs_radius ) + { + push_indice( hBstr, IND_ISM_RADIUS, idx_radius, ISM_RADIUS_NBITS ); + } + else + { + push_indice( hBstr, IND_ISM_RADIUS, idx_radius, nbits_diff_radius ); + } + + /*----------------------------------------------------------------* + * Updates + *----------------------------------------------------------------*/ + radius_handle->last_radius_idx = idx_radius_abs; + return; +} + +static void encode_angle_indices( + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + ISM_METADATA_ANGLE_HANDLE angle, /* i/o: angle handle */ + const int16_t last_ism_metadata_flag, /* last frame ism_metadata_flag */ + const int16_t ini_frame, /* i : initialization frames counter */ + const int16_t idx_azimuth_abs, /* i : Azimuth index */ + const int16_t idx_elevation_abs, /* i : Elevation index */ + int16_t *flag_abs_azimuth, /* o : Azimuth encoding mode */ + int16_t *flag_abs_elevation /* o : Elevation encoding mode */ +) +{ + int16_t idx_azimuth, nbits_diff_azimuth, diff; + int16_t idx_elevation, nbits_diff_elevation; + + + /*----------------------------------------------------------------* + * Azimuth index encoding + *----------------------------------------------------------------*/ + + idx_azimuth = idx_azimuth_abs; + + nbits_diff_azimuth = 0; + + *flag_abs_azimuth = 0; /* differential coding by default */ + if ( angle->azimuth_diff_cnt == ISM_FEC_MAX /* make differential encoding in ISM_FEC_MAX consecutive frames at maximum (in order to control the decoding in FEC) */ + || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */ + ) + { + *flag_abs_azimuth = 1; + } + + /* try differential coding */ + if ( *flag_abs_azimuth == 0 ) + { + diff = idx_azimuth_abs - angle->last_azimuth_idx; + + /* azimuth is on a circle - check for diff coding for -180° -> 180° and vice versa changes */ + if ( abs( diff ) > ( ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) - ISM_MAX_AZIMUTH_DIFF_IDX ) + { + if ( diff > 0 ) + { + diff -= ( 1 << ISM_AZIMUTH_NBITS ) - 1; + } + else + { + diff += ( 1 << ISM_AZIMUTH_NBITS ) - 1; + } + } + + if ( diff == 0 ) + { + idx_azimuth = 0; + nbits_diff_azimuth = 1; + } + else if ( ABSVAL( diff ) < ISM_MAX_AZIMUTH_DIFF_IDX ) /* when diff bits >= abs bits, prefer abs */ + { + idx_azimuth = 1 << 1; + nbits_diff_azimuth = 1; + + if ( diff < 0 ) + { + idx_azimuth += 1; /* negative sign */ + diff *= -1; + } + else + { + idx_azimuth += 0; /* positive sign */ + } + + idx_azimuth = idx_azimuth << diff; + nbits_diff_azimuth++; + + /* unary coding of "diff */ + idx_azimuth += ( ( 1 << diff ) - 1 ); + nbits_diff_azimuth += diff; + + if ( nbits_diff_azimuth < ISM_AZIMUTH_NBITS - 1 ) + { + /* add stop bit - only for codewords shorter than ISM_AZIMUTH_NBITS */ + idx_azimuth = idx_azimuth << 1; + nbits_diff_azimuth++; + } + } + else + { + *flag_abs_azimuth = 1; + } + } + + /* update counter */ + if ( *flag_abs_azimuth == 0 ) + { + angle->azimuth_diff_cnt++; + angle->elevation_diff_cnt = min( angle->elevation_diff_cnt, ISM_FEC_MAX ); + } + else + { + angle->azimuth_diff_cnt = 0; + } + + /* Write azimuth */ + push_indice( hBstr, IND_ISM_AZIMUTH_DIFF_FLAG, *flag_abs_azimuth, 1 ); + + if ( *flag_abs_azimuth ) + { + push_indice( hBstr, IND_ISM_AZIMUTH, idx_azimuth, ISM_AZIMUTH_NBITS ); + } + else + { + push_indice( hBstr, IND_ISM_AZIMUTH, idx_azimuth, nbits_diff_azimuth ); + } + + /*----------------------------------------------------------------* + * Elevation index encoding + *----------------------------------------------------------------*/ + idx_elevation = idx_elevation_abs; + + nbits_diff_elevation = 0; + + *flag_abs_elevation = 0; /* differential coding by default */ + if ( angle->elevation_diff_cnt == ISM_FEC_MAX /* make differential encoding in ISM_FEC_MAX consecutive frames at maximum (in order to control the decoding in FEC) */ + || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */ + ) + { + *flag_abs_elevation = 1; + } + + /* note: elevation is coded starting from the second frame only (it is meaningless in the init_frame) */ + if ( ini_frame == 0 ) + { + *flag_abs_elevation = 1; + angle->last_elevation_idx = idx_elevation_abs; + } + + diff = idx_elevation_abs - angle->last_elevation_idx; + + /* avoid absolute coding of elevation if absolute coding was already used for azimuth */ + if ( *flag_abs_azimuth == 1 ) + { + int16_t diff_orig = diff; + + *flag_abs_elevation = 0; + + + if ( diff >= 0 ) + { + diff = min( diff, ISM_MAX_ELEVATION_DIFF_IDX ); + } + else + { + diff = -1 * min( -diff, ISM_MAX_ELEVATION_DIFF_IDX ); + } + + if ( last_ism_metadata_flag == 0 || abs( diff_orig - diff ) > ISM_MAX_ELEVATION_DIFF_IDX ) + { + angle->elevation_diff_cnt = ISM_FEC_MAX - 1; + } + } + + /* try differential coding */ + if ( *flag_abs_elevation == 0 ) + { + if ( diff == 0 ) + { + idx_elevation = 0; + nbits_diff_elevation = 1; + } + else if ( ABSVAL( diff ) <= ISM_MAX_ELEVATION_DIFF_IDX ) + { + idx_elevation = 1 << 1; + nbits_diff_elevation = 1; + + if ( diff < 0 ) + { + idx_elevation += 1; /* negative sign */ + diff *= -1; + } + else + { + idx_elevation += 0; /* positive sign */ + } + + idx_elevation = idx_elevation << diff; + nbits_diff_elevation++; + + /* unary coding of "diff */ + idx_elevation += ( ( 1 << diff ) - 1 ); + nbits_diff_elevation += diff; + + if ( nbits_diff_elevation < ISM_ELEVATION_NBITS ) + { + /* add stop bit */ + idx_elevation = idx_elevation << 1; + nbits_diff_elevation++; + } + } + else + { + *flag_abs_elevation = 1; + } + } + + /* update counter */ + if ( *flag_abs_elevation == 0 ) + { + angle->elevation_diff_cnt++; + angle->elevation_diff_cnt = min( angle->elevation_diff_cnt, ISM_FEC_MAX ); + } + else + { + angle->elevation_diff_cnt = 0; + } + + /* Write elevation */ + if ( *flag_abs_azimuth == 0 ) /* do not write "flag_abs_elevation" if "flag_abs_azimuth == 1" */ + { + push_indice( hBstr, IND_ISM_ELEVATION_DIFF_FLAG, *flag_abs_elevation, 1 ); + } + + if ( *flag_abs_elevation ) + { + push_indice( hBstr, IND_ISM_ELEVATION, idx_elevation, ISM_ELEVATION_NBITS ); + } + else + { + push_indice( hBstr, IND_ISM_ELEVATION, idx_elevation, nbits_diff_elevation ); + } + + /*----------------------------------------------------------------* + * Updates + *----------------------------------------------------------------*/ + + angle->last_azimuth_idx = idx_azimuth_abs; + angle->last_elevation_idx = idx_elevation_abs; + + return; +} +#endif diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 4cd70f61fc..f1ed1a9431 100755 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -425,8 +425,12 @@ ivas_error IVAS_ENC_FeedObjectMetadata( { return IVAS_ERR_INDEX_OUT_OF_BOUNDS; } - + /* TD5 azimuth_orientation, elevation_orientation*/ +#ifdef TD5 + error = set_ism_metadata( hIvasEnc->st_ivas->hIsmMetaData[ismIndex], metadata.azimuth, metadata.elevation, metadata.radius, metadata.azimuth_orientation, metadata.elevation_orientation ); +#else error = set_ism_metadata( hIvasEnc->st_ivas->hIsmMetaData[ismIndex], metadata.azimuth, metadata.elevation ); +#endif /*TD5 */ if ( error != IVAS_ERR_OK ) { return error; diff --git a/lib_rend/ivas_lib_rend_internal.h b/lib_rend/ivas_lib_rend_internal.h index 3d784d9bb3..b7e34271de 100644 --- a/lib_rend/ivas_lib_rend_internal.h +++ b/lib_rend/ivas_lib_rend_internal.h @@ -46,6 +46,9 @@ typedef struct { int8_t headRotEnabled; IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME]; +#ifdef TD5 + float Pos[RENDERER_HEAD_POSITIONS_PER_FRAME][3]; +#endif float crossfade[L_FRAME48k / RENDERER_HEAD_POSITIONS_PER_FRAME]; } IVAS_REND_HeadRotData; diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 10617d3c62..56605794ec 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -53,13 +53,21 @@ static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRe static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, const int16_t headRotEnabled, +#ifdef TD5 + const IVAS_QUATERNION *headPosition, + const float *Pos ); +#else const IVAS_QUATERNION *headPosition ); +#endif static void TDREND_Update_object_positions( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, const int16_t numSources, const int16_t lfe_idx, const IVAS_FORMAT in_format, const ISM_METADATA_HANDLE *hIsmMetaData, float output[][L_FRAME48k] ); +#ifdef TD5 +static void angles_to_vec( const float radius, const float azimuth, const float elevation, float *vec ); +#endif /*---------------------------------------------------------------------* * ivas_td_binaural_open() @@ -168,9 +176,13 @@ ivas_error ivas_td_binaural_open( for ( nS = 0; nS < nchan_rend; nS++ ) { /* Set source positions according to loudspeaker layout */ +#ifdef TD5 + angles_to_vec( 1.0f, ls_azimuth[nS], ls_elevation[nS], Pos ); +#else Pos[0] = cosf( ls_elevation[nS] * PI_OVER_180 ) * cosf( ls_azimuth[nS] * PI_OVER_180 ); Pos[1] = cosf( ls_elevation[nS] * PI_OVER_180 ) * sinf( ls_azimuth[nS] * PI_OVER_180 ); Pos[2] = sinf( ls_elevation[nS] * PI_OVER_180 ); +#endif Dir[0] = 1.0f; Dir[1] = 0.0f; Dir[2] = 0.0f; @@ -186,6 +198,20 @@ ivas_error ivas_td_binaural_open( TDREND_MIX_SRC_SetDirAtten( hBinRendererTd, nS, DirAtten_p ); } } +#ifdef TD5 + if ( st_ivas->ivas_format == ISM_FORMAT ) + { + DirAtten_p = hBinRendererTd->DirAtten_p; + DirAtten_p->ConeInnerAngle = st_ivas->hRenderConfig->directivity[0]; + DirAtten_p->ConeOuterAngle = st_ivas->hRenderConfig->directivity[1]; + DirAtten_p->ConeOuterGain = st_ivas->hRenderConfig->directivity[2]; + + for ( nS = 0; nS < nchan_rend; nS++ ) + { + TDREND_MIX_SRC_SetDirAtten( hBinRendererTd, nS, DirAtten_p ); + } + } +#endif st_ivas->hBinRendererTd = hBinRendererTd; @@ -261,7 +287,12 @@ void ObjRenderIVASFrame( /* Update the listener's location/orientation */ TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, st_ivas->hDecoderConfig->Opt_Headrotation, +#ifdef TD5 + ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternions[subframe_idx] : NULL, + ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->Pos[subframe_idx] : NULL ); +#else ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternions[subframe_idx] : NULL ); +#endif if ( ( st_ivas->hRenderConfig != NULL ) && ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) ) { @@ -416,17 +447,24 @@ static void TDREND_Update_object_positions( /* Update the source positions */ /* Source position and direction */ +#ifdef TD5 + angles_to_vec( hIsmMetaData[nS]->radius, hIsmMetaData[nS]->azimuth, hIsmMetaData[nS]->elevation, Pos ); + angles_to_vec( 1.0f, hIsmMetaData[nS]->azimuth_orientation, hIsmMetaData[nS]->elevation_orientation, Dir ); +#else Pos[0] = cosf( hIsmMetaData[nS]->elevation * PI_OVER_180 ) * cosf( hIsmMetaData[nS]->azimuth * PI_OVER_180 ); Pos[1] = cosf( hIsmMetaData[nS]->elevation * PI_OVER_180 ) * sinf( hIsmMetaData[nS]->azimuth * PI_OVER_180 ); Pos[2] = sinf( hIsmMetaData[nS]->elevation * PI_OVER_180 ); Dir[0] = 1.0f; Dir[1] = 0.0f; Dir[2] = 0.0f; +#endif +#ifndef TD5 /* Source directivity info */ DirAtten_p->ConeInnerAngle = 360.0f; DirAtten_p->ConeOuterAngle = 360.0f; DirAtten_p->ConeOuterGain = 1.0f; +#endif TDREND_MIX_SRC_SetPos( hBinRendererTd, nS, Pos ); TDREND_MIX_SRC_SetDirAtten( hBinRendererTd, nS, DirAtten_p ); @@ -448,19 +486,30 @@ static void TDREND_Update_object_positions( static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle */ const int16_t headRotEnabled, /* i : Headrotation flag */ - const IVAS_QUATERNION *headPosition /* i : Head Position */ +#ifdef TD5 + const IVAS_QUATERNION *headPosition, /* i : Listener orientation */ + const float *Pos /* i : Listener position */ +#else + const IVAS_QUATERNION *headPosition /* i : Head Position */ +#endif ) { +#ifdef TD5 + float Pos_p[3]; +#else float Pos[3]; +#endif float FrontVec[3]; float UpVec[3]; float Rmat[3][3]; /* Update the listener's location/orientation */ +#ifndef TD5 /* Listener at the origin */ Pos[0] = 0.0f; Pos[1] = 0.0f; Pos[2] = 0.0f; +#endif if ( headRotEnabled ) { @@ -474,6 +523,12 @@ static void TDREND_Update_listener_orientation( UpVec[0] = Rmat[2][0]; UpVec[1] = Rmat[2][1]; UpVec[2] = Rmat[2][2]; +#ifdef TD5 + /* Input position */ + Pos_p[0] = Pos[0]; + Pos_p[1] = Pos[1]; + Pos_p[2] = Pos[2]; +#endif } else { @@ -485,10 +540,20 @@ static void TDREND_Update_listener_orientation( UpVec[0] = 0.0f; UpVec[1] = 0.0f; UpVec[2] = 1.0f; +#ifdef TD5 + /* Listener at the origin */ + Pos_p[0] = 0.0f; + Pos_p[1] = 0.0f; + Pos_p[2] = 0.0f; +#endif } /* Set the listener position and orientation:*/ +#ifdef TD5 + TDREND_MIX_LIST_SetPos( hBinRendererTd, Pos_p ); +#else TDREND_MIX_LIST_SetPos( hBinRendererTd, Pos ); +#endif TDREND_MIX_LIST_SetOrient( hBinRendererTd, FrontVec, UpVec ); return; @@ -609,9 +674,13 @@ ivas_error ivas_rend_TDObjRendOpen( for ( nS = 0; nS < nchan_rend; nS++ ) { /* Set source positions according to loudspeaker layout */ +#ifdef TD5 + angles_to_vec( 1.0f, ls_azimuth[nS], ls_elevation[nS], Pos ); +#else Pos[0] = cosf( ls_elevation[nS] * PI_OVER_180 ) * cosf( ls_azimuth[nS] * PI_OVER_180 ); Pos[1] = cosf( ls_elevation[nS] * PI_OVER_180 ) * sinf( ls_azimuth[nS] * PI_OVER_180 ); Pos[2] = sinf( ls_elevation[nS] * PI_OVER_180 ); +#endif Dir[0] = 1.0f; Dir[1] = 0.0f; Dir[2] = 0.0f; @@ -712,7 +781,11 @@ ivas_error ivas_rend_TDObjRenderFrame( for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { /* Update the listener's location/orientation */ +#ifdef TD5 + TDREND_Update_listener_orientation( pTDRend->hBinRendererTd, headRotData->headRotEnabled, ( headRotData != NULL ) ? &headRotData->headPositions[subframe_idx] : NULL, ( headRotData != NULL ) ? headRotData->Pos[subframe_idx] : NULL ); +#else TDREND_Update_listener_orientation( pTDRend->hBinRendererTd, headRotData->headRotEnabled, ( headRotData != NULL ) ? &headRotData->headPositions[subframe_idx] : NULL ); +#endif /* TODO tmu : pass down renderer config struct */ // if ( ( hRenderConfig != NULL ) && ( hRenderConfig->roomAcoustics.late_reverb_on ) ) @@ -739,3 +812,25 @@ ivas_error ivas_rend_TDObjRenderFrame( return IVAS_ERR_OK; } + +#ifdef TD5 +/*---------------------------------------------------------------------* + * angles_to_vec() + * + * Convert azimuth and elevation angles to position/orientation vector + *---------------------------------------------------------------------*/ + +static void angles_to_vec( + const float radius, /* i : radius */ + const float azimuth, /* i : Azimuth angle */ + const float elevation, /* i : Elevation angle */ + float *vec /* o : Pos/Dir vector */ +) +{ + vec[0] = radius * cosf( elevation * PI_OVER_180 ) * cosf( azimuth * PI_OVER_180 ); + vec[1] = radius * cosf( elevation * PI_OVER_180 ) * sinf( azimuth * PI_OVER_180 ); + vec[2] = radius * sinf( elevation * PI_OVER_180 ); + + return; +} +#endif diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index f71ae77a13..b9083b6d8a 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -353,10 +353,21 @@ ivas_error TDREND_REND_RenderSourceHRFilt( { float LeftOutputFrame[L_SPATIAL_SUBFR_48k]; float RightOutputFrame[L_SPATIAL_SUBFR_48k]; +#ifdef TD5 + float Gain; + + Gain = ( *Src_p->SrcRend_p->DirGain_p ) * ( *Src_p->SrcRend_p->DistGain_p ); +#endif TDREND_Apply_ITD( Src_p->InputFrame_p, LeftOutputFrame, RightOutputFrame, &Src_p->previtd, Src_p->itd, Src_p->mem_itd, subframe_length ); +#ifdef TD5 + TDREND_firfilt( LeftOutputFrame, Src_p->hrf_left_prev, hrf_left_delta, intp_count, Src_p->mem_hrf_left, subframe_length, Src_p->filterlength, Gain ); + TDREND_firfilt( RightOutputFrame, Src_p->hrf_right_prev, hrf_right_delta, intp_count, Src_p->mem_hrf_right, subframe_length, Src_p->filterlength, Gain ); +#else TDREND_firfilt( LeftOutputFrame, Src_p->hrf_left_prev, hrf_left_delta, intp_count, Src_p->mem_hrf_left, subframe_length, Src_p->filterlength ); TDREND_firfilt( RightOutputFrame, Src_p->hrf_right_prev, hrf_right_delta, intp_count, Src_p->mem_hrf_right, subframe_length, Src_p->filterlength ); +#endif + /* Copy to accumulative output frame */ v_add( LeftOutputFrame, output_buf[0], output_buf[0], subframe_length ); v_add( RightOutputFrame, output_buf[1], output_buf[1], subframe_length ); diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index 11b9893800..a17fc0b7ef 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -233,7 +233,12 @@ void TDREND_firfilt( const int16_t intp_count, /* i : interpolation count */ float *mem, /* i/o: filter memory */ const int16_t subframe_length, /* i : Length of signal */ - const int16_t filterlength /* i : Filter length */ +#ifdef TD5 + const int16_t filterlength, /* i : Filter length */ + const float Gain /* i : Gain */ +#else + const int16_t filterlength /* i : Filter length */ +#endif ) { float buffer[SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 + L_SUBFRAME5MS_48k]; @@ -259,7 +264,11 @@ void TDREND_firfilt( { tmp += ( *p_filter++ ) * ( *p_tmp-- ); } +#ifdef TD5 + signal[i] = tmp * Gain; +#else signal[i] = tmp; +#endif if ( i < intp_count ) { diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index 1c29e58bc3..d592536c15 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -261,6 +261,9 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( TDREND_MIX_Listener_t *Listener_p; TDREND_HRFILT_FiltSet_t *HrFiltSet_p; float ListRelPos[3], ListRelDist; +#ifdef TD5 + float ListRelPosAbs[3]; /* Relative position, ignoring orientation of listener */ +#endif float Azim, Elev; float hrf_left[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; float hrf_right[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; @@ -282,19 +285,26 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( break; case TDREND_POSTYPE_ABSOLUTE: /* Absolute position */ +#ifdef TD5 + TDREND_SPATIAL_VecMapToNewCoordSystem( SrcSpatial_p->Pos_p, Listener_p->Pos, Listener_p->Front, Listener_p->Up, Listener_p->Right, ListRelPos, ListRelPosAbs ); +#else TDREND_SPATIAL_VecMapToNewCoordSystem( SrcSpatial_p->Pos_p, Listener_p->Pos, Listener_p->Front, Listener_p->Up, Listener_p->Right, ListRelPos ); +#endif break; default: /* Illegal position type */ #ifdef DEBUGGING printf( "Warning! TDREND_SRC_REND_UpdateFiltersFromSpatialParams: Invalid position type. Assuming absolute position!\n" ); #endif /* Assume absolute position */ +#ifdef TD5 + TDREND_SPATIAL_VecMapToNewCoordSystem( SrcSpatial_p->Pos_p, Listener_p->Pos, Listener_p->Front, Listener_p->Up, Listener_p->Right, ListRelPos, ListRelPosAbs ); +#else TDREND_SPATIAL_VecMapToNewCoordSystem( SrcSpatial_p->Pos_p, Listener_p->Pos, Listener_p->Front, Listener_p->Up, Listener_p->Right, ListRelPos ); +#endif // TD5 break; } ListRelDist = TDREND_SPATIAL_VecNorm( ListRelPos ); - /* 2. Evaluate the Elevation and Azimuth angles */ if ( ( ListRelPos[0] == 0 ) && ( ListRelPos[1] == 0 ) && ( ListRelPos[2] == 0 ) ) { @@ -315,7 +325,11 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( *SrcRend_p->DirGain_p = 1.0f; if ( SrcSpatial_p->DirAttenEnabled ) { - *SrcRend_p->DirGain_p = TDREND_SRC_SPATIAL_GetDirGain( &SrcSpatial_p->DirAtten, SrcSpatial_p->Front_p, ListRelPos ); +#ifdef TD5 + *SrcRend_p->DirGain_p = TDREND_SRC_SPATIAL_GetDirGain(&SrcSpatial_p->DirAtten, SrcSpatial_p->Front_p, ListRelPosAbs); +#else + *SrcRend_p->DirGain_p = TDREND_SRC_SPATIAL_GetDirGain(&SrcSpatial_p->DirAtten, SrcSpatial_p->Front_p, ListRelPos); +#endif // TD5 } /* Distance gain */ diff --git a/lib_rend/ivas_objectRenderer_vec.c b/lib_rend/ivas_objectRenderer_vec.c index 17f5f229d1..e266107181 100644 --- a/lib_rend/ivas_objectRenderer_vec.c +++ b/lib_rend/ivas_objectRenderer_vec.c @@ -111,19 +111,29 @@ void TDREND_SPATIAL_VecMapToNewCoordSystem( const float *UpVec_p, /* i : Up vector */ const float *RightVec_p, /* i : Right vector */ float *MappedVec_p /* o : Transformed vector */ +#ifdef TD5 + , + float *LisRelPosAbs /* o : Transformed vector without orientation */ +#endif // TD5 ) { +#ifdef TD5 + v_sub(Vec_p, TranslVec_p, LisRelPosAbs, 3); + /* Evalute the relative Vec in the coordinates of the Orientation vectors, */ +/* which form an orthonormal basis */ + MappedVec_p[0] = dotp(LisRelPosAbs, DirVec_p, 3); + MappedVec_p[1] = dotp(LisRelPosAbs, RightVec_p, 3); + MappedVec_p[2] = dotp(LisRelPosAbs, UpVec_p, 3); +#else float RelVec[3]; - /* Evaluate Vec relative to the new origin given by TranslVec */ v_sub( Vec_p, TranslVec_p, RelVec, 3 ); - /* Evalute the relative Vec in the coordinates of the Orientation vectors, */ - /* which form an orthonormal basis */ - MappedVec_p[0] = dotp( RelVec, DirVec_p, 3 ); - MappedVec_p[1] = dotp( RelVec, RightVec_p, 3 ); - MappedVec_p[2] = dotp( RelVec, UpVec_p, 3 ); - +/* which form an orthonormal basis */ + MappedVec_p[0] = dotp(RelVec, DirVec_p, 3); + MappedVec_p[1] = dotp(RelVec, RightVec_p, 3); + MappedVec_p[2] = dotp(RelVec, UpVec_p, 3); +#endif // TD5 return; } diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index 0e9e089b93..6d72372e01 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -104,6 +104,7 @@ ivas_error ivas_render_config_init_from_rom( const int16_t room_flag_on /* i : room effect on/off flag */ ) { + if ( hRenderConfig == NULL || *hRenderConfig == NULL ) { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "Unexpected null pointer while attempting to fill renderer configuration from ROM" ); @@ -126,5 +127,11 @@ ivas_error ivas_render_config_init_from_rom( mvr2r( ivas_reverb_default_RT60, ( *hRenderConfig )->roomAcoustics.pAcoustic_rt60, IVAS_REVERB_DEFAULT_N_BANDS ); mvr2r( ivas_reverb_default_DSR, ( *hRenderConfig )->roomAcoustics.pAcoustic_dsr, IVAS_REVERB_DEFAULT_N_BANDS ); +#ifdef TD5 + ( *hRenderConfig )->directivity[0] = 360.0f; /* Front cone */ + ( *hRenderConfig )->directivity[1] = 360.0f; /* Back cone */ + ( *hRenderConfig )->directivity[2] = 1.0f; /* Back attenuation */ +#endif + return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index b710202ce3..9d0140065d 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -145,6 +145,9 @@ typedef struct { int8_t headRotEnabled; IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME]; +#ifdef TD5 + float Pos[RENDERER_HEAD_POSITIONS_PER_FRAME][3]; +#endif float crossfade[L_FRAME48k / RENDERER_HEAD_POSITIONS_PER_FRAME]; } IVAS_REND_HeadRotData; @@ -468,6 +471,9 @@ typedef struct ivas_binaural_head_track_struct { int16_t num_quaternions; IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef TD5 + float Pos[MAX_PARAM_SPATIAL_SUBFRAMES][3]; +#endif float Rmat[3][3]; float Rmat_prev[3][3]; @@ -502,7 +508,9 @@ typedef struct ivas_render_config_t ivas_renderTypeOverride renderer_type_override; #endif ivas_roomAcoustics_t roomAcoustics; - +#ifdef TD5 + float directivity[3]; // Todo: Replace with constant +#endif } RENDER_CONFIG_DATA, *RENDER_CONFIG_HANDLE; diff --git a/lib_util/head_rotation_file_reader.c b/lib_util/head_rotation_file_reader.c index cd1dd7bcf3..0823ce5f15 100644 --- a/lib_util/head_rotation_file_reader.c +++ b/lib_util/head_rotation_file_reader.c @@ -94,22 +94,38 @@ ivas_error HeadRotationFileReader_open( ivas_error HeadRotationFileReading( HeadRotFileReader *headRotReader, /* i/o: HeadRotFileReader handle */ - IVAS_QUATERNION *Quaternions, /* o : head-tracking data */ - const int32_t frame_dec /* i : decoded frame number */ +#ifdef TD5 + IVAS_QUATERNION *Quaternions, /* o : listener orientation */ + float Pos[4][3] /* o : listener position */ +#else + IVAS_QUATERNION *Quaternions, /* o : head-tracking data */ + const int32_t frame_dec /* i : decoded frame number */ +#endif ) { uint16_t i; float w, x, y, z; +#ifdef TD5 + float posx, posy, posz; +#endif for ( i = 0; i < IVAS_MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { +#ifdef TD5 + if ( 7 != fscanf( headRotReader->trajFile, "%f,%f,%f,%f,%f,%f,%f", &w, &x, &y, &z, &posx, &posy, &posz ) ) +#else if ( 4 != fscanf( headRotReader->trajFile, "%f,%f,%f,%f", &w, &x, &y, &z ) ) +#endif { if ( feof( headRotReader->trajFile ) ) { rewind( headRotReader->trajFile ); headRotReader->fileRewind = true; +#ifdef TD5 + return HeadRotationFileReading( headRotReader, Quaternions, Pos ); +#else return HeadRotationFileReading( headRotReader, Quaternions, frame_dec ); +#endif } return IVAS_ERR_FAILED_FILE_PARSE; } @@ -121,6 +137,11 @@ ivas_error HeadRotationFileReading( Quaternions[i].x = x; Quaternions[i].y = y; Quaternions[i].z = z; +#ifdef TD5 + Pos[i][0] = posx; + Pos[i][1] = posy; + Pos[i][2] = posz; +#endif } return IVAS_ERR_OK; diff --git a/lib_util/head_rotation_file_reader.h b/lib_util/head_rotation_file_reader.h index 6664908b00..4c6a2212dc 100644 --- a/lib_util/head_rotation_file_reader.h +++ b/lib_util/head_rotation_file_reader.h @@ -60,8 +60,13 @@ ivas_error HeadRotationFileReader_open( ivas_error HeadRotationFileReading( HeadRotFileReader *headRotReader, /* i/o: HeadRotFileReader handle */ - IVAS_QUATERNION *Quaternions, /* o : head-tracking data */ - const int32_t frame_dec /* i : decoded frame number */ +#ifdef TD5 + IVAS_QUATERNION *Quaternions, /* o : listener orientation */ + float Pos[4][3] /* o : listener position */ +#else + IVAS_QUATERNION *Quaternions, /* o : head-tracking data */ + const int32_t frame_dec /* i : decoded frame number */ +#endif ); /*-----------------------------------------------------------------------* diff --git a/lib_util/ism_file_reader.c b/lib_util/ism_file_reader.c index b511b30499..7ffa227739 100644 --- a/lib_util/ism_file_reader.c +++ b/lib_util/ism_file_reader.c @@ -37,8 +37,12 @@ #include -#define META_LINE_LENGTH 200 /* max number of characters at one line of metadata input/output file */ -#define NUM_ISM_METADATA_PER_LINE 5 /* Number of ISM metadata per line in a metadata file */ +#define META_LINE_LENGTH 200 /* max number of characters at one line of metadata input/output file */ +#ifdef TD5 +#define NUM_ISM_METADATA_PER_LINE 7 /* Number of ISM metadata per line in a metadata file */ +#else +#define NUM_ISM_METADATA_PER_LINE 5 /* Number of ISM metadata per line in a metadata file */ +#endif struct IsmFileReader @@ -146,6 +150,11 @@ ivas_error IsmFileReader_readNextFrame( ismMetadata->radius = meta_prm[2]; ismMetadata->spread = meta_prm[3]; ismMetadata->gainFactor = meta_prm[4]; +#ifdef TD5 + /* Add azimuth/elevation for orientation here */ + ismMetadata->azimuth_orientation = meta_prm[5]; + ismMetadata->elevation_orientation = meta_prm[6]; +#endif /* verify whether the read metadata values are in an expected range */ if ( ismMetadata->azimuth > 180 || ismMetadata->azimuth < -180 ) @@ -172,6 +181,18 @@ ivas_error IsmFileReader_readNextFrame( { return IVAS_ERR_ISM_INVALID_METADATA_VALUE; } +#ifdef TD5 + /* TO DO TD5 Verify azimuth/elevation_orientation */ + if ( ismMetadata->azimuth_orientation > 180 || ismMetadata->azimuth_orientation < -180 ) + { + return IVAS_ERR_ISM_INVALID_METADATA_VALUE; + } + + if ( ismMetadata->elevation_orientation > 90 || ismMetadata->elevation_orientation < -90 ) + { + return IVAS_ERR_ISM_INVALID_METADATA_VALUE; + } +#endif // TD5 return IVAS_ERR_OK; } diff --git a/lib_util/ism_file_writer.c b/lib_util/ism_file_writer.c index e0a910d5db..b203bdf63c 100644 --- a/lib_util/ism_file_writer.c +++ b/lib_util/ism_file_writer.c @@ -36,8 +36,12 @@ #include -#define META_LINE_LENGTH 200 /* max number of characters at one line of metadata input/output file */ -#define NUM_ISM_METADATA_PER_LINE 5 /* Number of ISM metadata per line in a metadata file */ +#define META_LINE_LENGTH 200 /* max number of characters at one line of metadata input/output file */ +#ifdef TD5 +#define NUM_ISM_METADATA_PER_LINE 7 /* Number of ISM metadata per line in a metadata file */ +#else +#define NUM_ISM_METADATA_PER_LINE 5 /* Number of ISM metadata per line in a metadata file */ +#endif struct IsmFileWriter @@ -121,9 +125,16 @@ ivas_error IsmFileWriter_writeFrame( /* IVAS_fmToDo: work in progress; currently position_azimuth, position_elevation, position_radius, spread, gain_factor */ #ifdef FIX_293_EXT_RENDERER_CLI - snprintf( char_buff, sizeof( char_buff ), "%+07.2f,%+06.2f,%05.2f,%06.2f,%04.2f\n", ismMetadata.azimuth, ismMetadata.elevation, ismMetadata.radius, ismMetadata.spread, ismMetadata.gainFactor ); +#ifdef TD5 + snprintf( char_buff, sizeof( char_buff ), "%+07.2f,%+06.2f,%05.2f,%06.2f,%04.2f,%+07.2f,%+06.2f\n", ismMetadata.azimuth, ismMetadata.elevation, ismMetadata.radius, ismMetadata.spread, ismMetadata.gainFactor, ismMetadata.azimuth_orientation, ismMetadata.elevation_orientation ); #else - sprintf( char_buff, "%+07.2f,%+06.2f,%05.2f,%06.2f,%04.2f\n", ismMetadata.azimuth, ismMetadata.elevation, ismMetadata.radius, ismMetadata.spread, ismMetadata.gainFactor ); + snprintf( char_buff, sizeof( char_buff ), "%+07.2f,%+06.2f,%05.2f,%06.2f,%04.2f\n", ismMetadata.azimuth, ismMetadata.elevation, ismMetadata.radius, ismMetadata.spread, ismMetadata.gainFactor ); +#endif +#ifdef TD5 + sprintf( char_buff, "%+07.2f,%+06.2f,%05.2f,%06.2f,%04.2f,%+07.2f,%+06.2f\n", ismMetadata.azimuth, ismMetadata.elevation, ismMetadata.radius, ismMetadata.spread, ismMetadata.gainFactor, ismMetadata.azimuth_orientation, ismMetadata.elevation_orientation ); +#else + sprintf( char_buff, "%+07.2f,%+06.2f,%05.2f,%06.2f,%04.2f\n", ismMetadata.azimuth, ismMetadata.elevation, ismMetadata.radius, ismMetadata.spread, ismMetadata.gainFactor ); +#endif #endif if ( file ) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 27eed3bf14..5209dd58b1 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -523,6 +523,15 @@ ivas_error RenderConfigReader_read( errorHandler( pValue, ERROR_VALUE_INVALID ); } } +#ifdef TD5 + else if ( strcmp( item, "DIRECTIVITY" ) == 0 ) + { + if ( read_vector( pValue, 3, hRenderConfig->directivity ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } +#endif #ifdef DEBUGGING else { -- GitLab From e8a2a3cb416b30e932707eb8682a36edd459e94d Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Wed, 15 Mar 2023 08:34:06 +0100 Subject: [PATCH 2/5] Correct bug from merge with TUNE_360_OBJECT_WITH_NOISE --- lib_enc/ivas_ism_metadata_enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index ee43fee5fe..07b3b2d718 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -262,7 +262,7 @@ ivas_error ivas_ism_metadata_enc( #ifdef TD5 #ifdef TUNE_360_OBJECT_WITH_NOISE /* In case of low level noise for low bitrate inactive frames, do not sent metadata */ - if ( localVAD[ch] == 0 && !( hSCE[ch]->hCoreCoder[0]->tcxonly ) && ( hSCE[ch]->hCoreCoder[0]->lp_noise <= 15 ) ) + if ( localVAD[ch] == 0 && !( hSCE[ch]->hCoreCoder[0]->tcxonly ) && ( hSCE[ch]->hCoreCoder[0]->lp_noise <= 10 ) ) { hIsmMeta[ch]->ism_metadata_flag = 0; } -- GitLab From 84348e6b498619aa81079157fb07062f0faeb940 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Wed, 15 Mar 2023 18:05:42 +0100 Subject: [PATCH 3/5] Added support of extended metadata and headtracking in external renderer --- apps/decoder.c | 2 +- apps/renderer.c | 73 +++++++++++++++++++++++++++- lib_com/common_api_types.h | 5 ++ lib_dec/lib_dec.c | 8 +-- lib_dec/lib_dec.h | 2 +- lib_rend/ivas_objectRenderer.c | 5 ++ lib_rend/lib_rend.c | 13 ++++- lib_rend/lib_rend.h | 5 ++ lib_util/head_rotation_file_reader.c | 8 +-- lib_util/head_rotation_file_reader.h | 2 +- 10 files changed, 109 insertions(+), 14 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 4d2d659d4e..875e3304a1 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1384,7 +1384,7 @@ static ivas_error decodeG192( uint16_t numObj = 0; IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN; #ifdef TD5 - float Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES][3] = { 0 }; /* Initialization needed for gcc */ + IVAS_POSITION Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; #endif IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; diff --git a/apps/renderer.c b/apps/renderer.c index 72696b556d..a90e47083f 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -517,6 +517,9 @@ int main( int32_t delayTimeScale = 0; int16_t i, numChannels; ivas_error error = IVAS_ERR_OK; +#ifdef TD5 + IVAS_POSITION Pos[RENDERER_HEAD_POSITIONS_PER_FRAME]; +#endif #ifdef WMOPS reset_wmops(); @@ -645,19 +648,31 @@ int main( } /* === Configure === */ +#ifdef TD5 + if ( ( error = IVAS_REND_InitConfig( hIvasRend, ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) || ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL ) ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_REND_InitConfig( hIvasRend, strlen( args.renderConfigFilePath ) != 0 ) ) != IVAS_ERR_OK ) { exit( -1 ); } +#endif if ( args.renderConfigFilePath[0] != '\0' ) { IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ +#ifdef TD5 + if ( ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) && ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL ) ) +#else if ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) +#endif { +#ifdef TD5 + fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL or BINAURAL_ROOM is used as output. Exiting. \n" ); +#else fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n" ); +#endif exit( -1 ); } @@ -889,16 +904,20 @@ int main( { IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME]; #ifdef TD5 - float Pos[RENDERER_HEAD_POSITIONS_PER_FRAME][3]; HeadRotationFileReading( headRotReader, quatBuffer, Pos ); + IVAS_REND_SetHeadRotation( hIvasRend, quatBuffer, Pos ); #else HeadRotationFileReading( headRotReader, quatBuffer, frame ); -#endif IVAS_REND_SetHeadRotation( hIvasRend, quatBuffer ); +#endif } else { +#ifdef TD5 + IVAS_REND_SetHeadRotation( hIvasRend, NULL, NULL ); +#else IVAS_REND_SetHeadRotation( hIvasRend, NULL ); +#endif } for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) @@ -1720,6 +1739,11 @@ void getMetadataFromFileReader( objectMetadataBuffer->positions[objIdx].azimuth = ismMetadata.azimuth; objectMetadataBuffer->positions[objIdx].elevation = ismMetadata.elevation; +#ifdef TD5 + objectMetadataBuffer->positions[objIdx].radius = ismMetadata.radius; + objectMetadataBuffer->positions[objIdx].yaw = ismMetadata.yaw; + objectMetadataBuffer->positions[objIdx].pitch = ismMetadata.pitch; +#endif return; } @@ -1774,6 +1798,11 @@ static void IsmPositionProvider_getNextFrame( { objectMetadataBuffer->positions[objIdx].azimuth = 0.0f; objectMetadataBuffer->positions[objIdx].elevation = 0.0f; +#ifdef TD5 + objectMetadataBuffer->positions[objIdx].radius = 1.0f; + objectMetadataBuffer->positions[objIdx].yaw = 0.0f; + objectMetadataBuffer->positions[objIdx].pitch = 0.0f; +#endif } /* Wrap azimuth to lie within (-180, 180] range */ @@ -1788,6 +1817,20 @@ static void IsmPositionProvider_getNextFrame( /* Clamp elevation to lie within [-90, 90] range (can't be wrapped easily) */ objectMetadataBuffer->positions[objIdx].elevation = min( max( objectMetadataBuffer->positions[objIdx].elevation, -90 ), 90 ); +#ifdef TD5 + /* Wrap yaw to lie within (-180, 180] range */ + while ( objectMetadataBuffer->positions[objIdx].yaw < 0.0f ) + { + objectMetadataBuffer->positions[objIdx].yaw += 360.0f; + } + while ( objectMetadataBuffer->positions[objIdx].yaw >= 360.0f ) + { + objectMetadataBuffer->positions[objIdx].yaw -= 360.0f; + } + + /* Clamp pitch to lie within [-90, 90] range (can't be wrapped easily) */ + objectMetadataBuffer->positions[objIdx].pitch = min( max( objectMetadataBuffer->positions[objIdx].pitch, -90 ), 90 ); +#endif } ++positionProvider->frameCounter; @@ -2049,6 +2092,32 @@ static void parseObjectPosition( exit( -1 ); } +#ifdef TD5 + readNextMetadataChunk( line, "," ); + position->radius = strtof( line, &endptr ); + + if ( *endptr != '\0' ) + { + fprintf( stderr, "Error reading metadata\n" ); + exit( -1 ); + } + + readNextMetadataChunk( line, "\n" ); + position->yaw = strtof( line, &endptr ); + if ( *endptr != '\0' ) + { + fprintf( stderr, "Error reading metadata\n" ); + exit( -1 ); + } + + readNextMetadataChunk( line, "\n" ); + position->pitch = strtof( line, &endptr ); + if ( *endptr != '\0' ) + { + fprintf( stderr, "Error reading metadata\n" ); + exit( -1 ); + } +#endif return; } diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index b2820f792c..dc1df1b5f0 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -123,6 +123,11 @@ typedef struct { float azimuth; float elevation; +#ifdef TD5 + float radius; + float yaw; + float pitch; +#endif } IVAS_REND_AudioObjectPosition; typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index b4f03c8cc6..7dbcc7e5c6 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -915,7 +915,7 @@ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ #ifdef TD5 IVAS_QUATERNION *orientation, /* i : head-tracking data, listener orientation */ - float Pos[4][3] /* i : listener position */ + IVAS_POSITION *Pos /* i : listener position */ #else IVAS_QUATERNION *orientation /* i : head-tracking data, listener orientation */ #endif @@ -944,9 +944,9 @@ ivas_error IVAS_DEC_FeedHeadTrackData( hHeadTrackData->Quaternions[i].y = orientation[i].y; hHeadTrackData->Quaternions[i].z = orientation[i].z; #ifdef TD5 - hHeadTrackData->Pos[i].x = Pos[i][0]; - hHeadTrackData->Pos[i].y = Pos[i][1]; - hHeadTrackData->Pos[i].z = Pos[i][2]; + hHeadTrackData->Pos[i].x = Pos[i].x; + hHeadTrackData->Pos[i].y = Pos[i].y; + hHeadTrackData->Pos[i].z = Pos[i].z; #endif } diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index c1cfad3580..570d3f1f09 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -187,7 +187,7 @@ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ #ifdef TD5 IVAS_QUATERNION *orientation, /* i : head-tracking data */ - float Pos[4][3] /* i : listener position */ + IVAS_POSITION *Pos /* i : listener position */ #else IVAS_QUATERNION *orientation /* i : head-tracking data */ #endif diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 7666059421..099d9aae38 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -744,6 +744,11 @@ ivas_error ivas_td_binaural_renderer_ext( hIsmMetaData[0] = &hIsmMetaDataFrame; hIsmMetaData[0]->azimuth = currentPos->azimuth; hIsmMetaData[0]->elevation = currentPos->elevation; +#ifdef TD5 + hIsmMetaData[0]->yaw = currentPos->yaw; + hIsmMetaData[0]->pitch = currentPos->pitch; + hIsmMetaData[0]->radius = currentPos->radius; +#endif } #ifndef FIX_330_ENABLE_TD_RENDERER_REVERB_REND diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 1056f45e5a..21cab52a73 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -3988,6 +3988,9 @@ int16_t IVAS_REND_FeedRenderConfig( } hRenderConfig = hIvasRend->hRendererConfig; +#ifdef TD5 + mvr2r(renderConfig.directivity, hRenderConfig->directivity, 3); +#endif #ifdef DEBUGGING hRenderConfig->renderer_type_override = RENDER_TYPE_OVERRIDE_NONE; if ( renderConfig.renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_FASTCONV ) @@ -4020,8 +4023,13 @@ int16_t IVAS_REND_FeedRenderConfig( *-------------------------------------------------------------------*/ ivas_error IVAS_REND_SetHeadRotation( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ +#ifdef TD5 + const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME], /* i : head orientations for next rendering call */ + const IVAS_POSITION Pos[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : listener positions for next rendering call */ +#else const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : head positions for next rendering call */ +#endif ) { int16_t i; @@ -4051,6 +4059,9 @@ ivas_error IVAS_REND_SetHeadRotation( for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { hIvasRend->headRotData.headPositions[i] = headRot[i]; +#ifdef TD5 + hIvasRend->headRotData.Pos[i] = Pos[i]; +#endif } } diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 6db5fd91dc..579dda711f 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -244,7 +244,12 @@ int16_t IVAS_REND_FeedRenderConfig( ivas_error IVAS_REND_SetHeadRotation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ +#ifdef TD5 + const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME], /* i : head orientations for next rendering call */ + const IVAS_POSITION Pos[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : listener positions for next rendering call */ +#else const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : head positions for next rendering call */ +#endif ); ivas_error IVAS_REND_GetSamples( diff --git a/lib_util/head_rotation_file_reader.c b/lib_util/head_rotation_file_reader.c index 2ef75e3488..d3a1018644 100644 --- a/lib_util/head_rotation_file_reader.c +++ b/lib_util/head_rotation_file_reader.c @@ -95,7 +95,7 @@ ivas_error HeadRotationFileReading( HeadRotFileReader *headRotReader, /* i/o: HeadRotFileReader handle */ IVAS_QUATERNION *Quaternions, /* o : head-tracking data, listener orientation */ #ifdef TD5 - float Pos[4][3] /* o : listener position */ + IVAS_POSITION *Pos /* o : listener position */ #else const int32_t frame_dec /* i : decoded frame number */ #endif @@ -141,9 +141,9 @@ ivas_error HeadRotationFileReading( Quaternions[i].y = y; Quaternions[i].z = z; #ifdef TD5 - Pos[i][0] = posx; - Pos[i][1] = posy; - Pos[i][2] = posz; + Pos[i].x = posx; + Pos[i].y = posy; + Pos[i].z = posz; #endif } diff --git a/lib_util/head_rotation_file_reader.h b/lib_util/head_rotation_file_reader.h index 20e503f11d..6fa05caef1 100644 --- a/lib_util/head_rotation_file_reader.h +++ b/lib_util/head_rotation_file_reader.h @@ -61,7 +61,7 @@ ivas_error HeadRotationFileReading( HeadRotFileReader *headRotReader, /* i/o: HeadRotFileReader handle */ IVAS_QUATERNION *Quaternions, /* o : head-tracking data */ #ifdef TD5 - float Pos[4][3] /* o : listener position */ + IVAS_POSITION *Pos /* o : listener position */ #else const int32_t frame_dec /* i : decoded frame number */ #endif -- GitLab From d458cf3b6c6b688b662cab09369ede1b730fc20f Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Wed, 15 Mar 2023 19:14:35 +0100 Subject: [PATCH 4/5] Clang format --- apps/decoder.c | 2 +- apps/renderer.c | 48 +++++++++++++------------- lib_dec/ivas_objectRenderer_internal.c | 3 +- lib_enc/ivas_ism_metadata_enc.c | 8 ++--- lib_rend/ivas_objectRenderer.c | 6 ++-- lib_rend/lib_rend.c | 6 ++-- 6 files changed, 36 insertions(+), 37 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 875e3304a1..e808721f14 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1384,7 +1384,7 @@ static ivas_error decodeG192( uint16_t numObj = 0; IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN; #ifdef TD5 - IVAS_POSITION Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_POSITION Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; #endif IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; diff --git a/apps/renderer.c b/apps/renderer.c index a90e47083f..00875cc4e3 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -657,43 +657,43 @@ int main( } #endif - if ( args.renderConfigFilePath[0] != '\0' ) - { - IVAS_RENDER_CONFIG_DATA renderConfig; + if ( args.renderConfigFilePath[0] != '\0' ) + { + IVAS_RENDER_CONFIG_DATA renderConfig; - /* sanity check */ + /* sanity check */ #ifdef TD5 - if ( ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) && ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL ) ) + if ( ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) && ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL ) ) #else if ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) #endif - { + { #ifdef TD5 - fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL or BINAURAL_ROOM is used as output. Exiting. \n" ); + fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL or BINAURAL_ROOM is used as output. Exiting. \n" ); #else fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n" ); #endif - exit( -1 ); - } + exit( -1 ); + } - if ( ( error = IVAS_REND_GetRenderConfig( hIvasRend, &renderConfig ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed\n" ); - exit( -1 ); - } + if ( ( error = IVAS_REND_GetRenderConfig( hIvasRend, &renderConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed\n" ); + exit( -1 ); + } - if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Failed to read renderer configuration from file %s\n", args.renderConfigFilePath ); - exit( -1 ); - } + if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to read renderer configuration from file %s\n", args.renderConfigFilePath ); + exit( -1 ); + } - if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" ); - exit( -1 ); + if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" ); + exit( -1 ); + } } - } /* Set up output custom layout configuration */ if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index c43efeece8..57ffe7e549 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -95,8 +95,7 @@ ivas_error ivas_td_binaural_renderer( #ifdef TD5 st_ivas->hIsmMetaData, st_ivas->hDecoderConfig->Opt_Headrotation, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->Quaternions : NULL, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->Pos : NULL, output, output_frame ); -#else +#else st_ivas->hIsmMetaData, st_ivas->hDecoderConfig->Opt_Headrotation, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->Quaternions : NULL, output, output_frame ); #endif - } diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index 07b3b2d718..3472de0c5a 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -84,10 +84,10 @@ ivas_error ivas_set_ism_metadata( ISM_METADATA_HANDLE hIsmMeta, /* o : ISM metadata handle */ const float azimuth, /* i : azimuth value */ #ifdef TD5 - const float elevation, /* i : elevation */ - float radius_meta, /* i : radius */ - float yaw, /* i : yaw */ - float pitch /* i : pitch */ + const float elevation, /* i : elevation */ + float radius_meta, /* i : radius */ + float yaw, /* i : yaw */ + float pitch /* i : pitch */ #else const float elevation /* i : elevation value */ #endif diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 099d9aae38..90ef392088 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -761,12 +761,12 @@ ivas_error ivas_td_binaural_renderer_ext( #endif #ifdef FIX_330_ENABLE_TD_RENDERER_REVERB_REND if ( ( error = ivas_td_binaural_renderer_unwrap( reverb, transport_config, pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, headRotData->headRotEnabled, - ( headRotData != NULL ) ? headRotData->headPositions : NULL, + ( headRotData != NULL ) ? headRotData->headPositions : NULL, #ifdef TD5 ( headRotData != NULL ) ? headRotData->Pos : NULL, output, output_frame ) ) != IVAS_ERR_OK ) #else output, output_frame ) ) != IVAS_ERR_OK ) -#endif +#endif { return error; } @@ -777,7 +777,7 @@ ivas_error ivas_td_binaural_renderer_ext( ( headRotData != NULL ) ? headRotData->Pos : NULL, output, output_frame ) ) != IVAS_ERR_OK ) #else output, output_frame ) ) != IVAS_ERR_OK ) -#endif +#endif { return error; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 21cab52a73..426993c094 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1123,7 +1123,7 @@ static ivas_error setRendInputActiveIsm( if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif +#endif { return error; } @@ -3989,7 +3989,7 @@ int16_t IVAS_REND_FeedRenderConfig( hRenderConfig = hIvasRend->hRendererConfig; #ifdef TD5 - mvr2r(renderConfig.directivity, hRenderConfig->directivity, 3); + mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 ); #endif #ifdef DEBUGGING hRenderConfig->renderer_type_override = RENDER_TYPE_OVERRIDE_NONE; @@ -4023,7 +4023,7 @@ int16_t IVAS_REND_FeedRenderConfig( *-------------------------------------------------------------------*/ ivas_error IVAS_REND_SetHeadRotation( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ #ifdef TD5 const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME], /* i : head orientations for next rendering call */ const IVAS_POSITION Pos[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : listener positions for next rendering call */ -- GitLab From 87fac8a6383de78778d1a4a09a98feb7e478eeb9 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Thu, 16 Mar 2023 17:01:13 +0100 Subject: [PATCH 5/5] Fixes for flexible reading of metadata in META format for external renderer --- apps/renderer.c | 38 +++++++++++++++++--------------------- lib_rend/lib_rend.c | 5 +++++ 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index 00875cc4e3..3fcf5a0eeb 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -2065,36 +2065,31 @@ static void parseObjectPosition( uint16_t *positionDuration ) { char *endptr; +#ifdef TD5 + int16_t read_values; + float meta_prm[7] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; readNextMetadataChunk( line, "," ); *positionDuration = (uint16_t) strtol( line, &endptr, 10 ); + readNextMetadataChunk( line, "\n" ); - if ( *endptr != '\0' ) - { - fprintf( stderr, "Error reading metadata\n" ); - exit( -1 ); - } - - readNextMetadataChunk( line, "," ); - position->azimuth = strtof( line, &endptr ); + read_values = (int16_t) sscanf( line, "%f,%f,%f,%f,%f,%f,%f", &meta_prm[0], &meta_prm[1], &meta_prm[2], &meta_prm[3], &meta_prm[4], &meta_prm[5], &meta_prm[6] ); - if ( *endptr != '\0' ) + if ( read_values < 2 ) { fprintf( stderr, "Error reading metadata\n" ); exit( -1 ); } - readNextMetadataChunk( line, "\n" ); - position->elevation = strtof( line, &endptr ); - if ( *endptr != '\0' ) - { - fprintf( stderr, "Error reading metadata\n" ); - exit( -1 ); - } + position->azimuth = meta_prm[0]; + position->elevation = meta_prm[1]; + position->radius = meta_prm[2]; + position->yaw = meta_prm[5]; + position->pitch = meta_prm[6]; +#else -#ifdef TD5 readNextMetadataChunk( line, "," ); - position->radius = strtof( line, &endptr ); + *positionDuration = (uint16_t) strtol( line, &endptr, 10 ); if ( *endptr != '\0' ) { @@ -2102,8 +2097,9 @@ static void parseObjectPosition( exit( -1 ); } - readNextMetadataChunk( line, "\n" ); - position->yaw = strtof( line, &endptr ); + readNextMetadataChunk( line, "," ); + position->azimuth = strtof( line, &endptr ); + if ( *endptr != '\0' ) { fprintf( stderr, "Error reading metadata\n" ); @@ -2111,7 +2107,7 @@ static void parseObjectPosition( } readNextMetadataChunk( line, "\n" ); - position->pitch = strtof( line, &endptr ); + position->elevation = strtof( line, &endptr ); if ( *endptr != '\0' ) { fprintf( stderr, "Error reading metadata\n" ); diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 09be168ecb..d45c2f5f78 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1005,6 +1005,11 @@ static IVAS_REND_AudioObjectPosition defaultObjectPosition( pos.azimuth = 0.0f; pos.elevation = 0.0f; +#ifdef TD5 + pos.radius = 1.0f; + pos.yaw = 0.0f; + pos.pitch = 0.0f; +#endif return pos; } -- GitLab