diff --git a/Workspace_msvc/Win32/Release/LC3plus.lib b/Workspace_msvc/Win32/Release/LC3plus.lib new file mode 100644 index 0000000000000000000000000000000000000000..a2bf35b7ca3dd448831a00d35ec7e63789b596f8 Binary files /dev/null and b/Workspace_msvc/Win32/Release/LC3plus.lib differ diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 85859e257cb0d7e5ebb4efb670a53c44e7cd6361..5389742f5427a08356cd33d78944625a4ccec6d3 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -110,6 +110,7 @@ + @@ -144,6 +145,7 @@ + diff --git a/Workspace_msvc/lib_util.vcxproj.filters b/Workspace_msvc/lib_util.vcxproj.filters index 07c8fdfe435e4f5835dd69ec4c25598d4e67e0f4..f1534dfdf89a384c00e5d050535ff1cd690205d4 100644 --- a/Workspace_msvc/lib_util.vcxproj.filters +++ b/Workspace_msvc/lib_util.vcxproj.filters @@ -97,6 +97,9 @@ util_c + + util_c + @@ -207,6 +210,9 @@ util_h + + util_h + diff --git a/apps/decoder.c b/apps/decoder.c index f6b55ba00f5851cf9aa35d911047ba98f45b2059..e909f973144251782180efe04152cd9723f1879c 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -45,6 +45,10 @@ #include "masa_file_writer.h" #include "render_config_reader.h" #include "rotation_file_reader.h" +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO +#include "socket_comm.h" +#include "ivas_error_utils.h" +#endif #include "aeid_file_reader.h" #include "split_render_file_read_write.h" #include "obj_edit_file_reader.h" @@ -106,6 +110,10 @@ typedef struct bool voipMode; bool enableHeadRotation; char *headrotTrajFileName; +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + bool enableHeadrotTrajSocket; + uint16_t socketPort; +#endif bool enableReferenceRotation; char *refrotTrajFileName; bool enableReferenceVectorTracking; @@ -178,9 +186,17 @@ typedef struct *------------------------------------------------------------------------------------------*/ static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg ); +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO +static ivas_error parseQuaternionData( char *rxBuffer, IVAS_QUATERNION *pQuaternion ); +#endif static void usage_dec( void ); +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO +static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, unsigned int hSocket, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtf, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, unsigned int hSocket, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_RENDER_CONFIG_DATA *renderConfig, IVAS_DEC_HANDLE *phIvasDec, int16_t *pcmBuf ); +#else static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtf, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_RENDER_CONFIG_DATA *renderConfig, IVAS_DEC_HANDLE *phIvasDec, int16_t *pcmBuf ); +#endif static ivas_error load_hrtf_from_file( IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, IVAS_DEC_HANDLE hIvasDec, const IVAS_AUDIO_CONFIG OutputConfig, const int32_t output_Fs ); #ifdef DEBUGGING static ivas_error printBitstreamInfoVoip( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HANDLE hIvasDec ); @@ -220,6 +236,9 @@ int main( IVAS_RENDER_FRAMESIZE asked_frame_size; IVAS_DEC_HRTF_BINARY_WRAPPER hHrtfBinary; ObjectEditFileReader *objectEditFileReader = NULL; +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + uint32_t hSocket = (uint32_t) NULL; +#endif IVAS_ROOM_ACOUSTICS_CONFIG_DATA **pAE = NULL; uint32_t aeCount = 0; IVAS_RENDER_CONFIG_DATA renderConfig = { 0 }; @@ -338,15 +357,38 @@ int main( /* sanity check */ if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + fprintf( stderr, "\nError: Head-rotation cannot be used in this output configuration.\n\n" ); +#else fprintf( stderr, "\nError: Head-rotation file file cannot be used in this output configuration.\n\n" ); +#endif goto cleanup; } +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + if ( arg.enableHeadrotTrajSocket ) + { + if ( ( error = SocketComm_start( &hSocket, arg.socketPort ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: Can't start socket communication \n\n" ); + goto cleanup; + } + } + else + { + if ( ( error = RotationFileReader_open( arg.headrotTrajFileName, &headRotReader ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: Can't open head-rotation file %s \n\n", arg.headrotTrajFileName ); + goto cleanup; + } + } +#else if ( ( error = RotationFileReader_open( arg.headrotTrajFileName, &headRotReader ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError: Can't open head-rotation file %s \n\n", arg.headrotTrajFileName ); goto cleanup; } +#endif } /*------------------------------------------------------------------------------------------* @@ -783,11 +825,19 @@ int main( if ( arg.voipMode ) { +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, hSocket, &splitRendBits, &renderConfig, &hIvasDec, pcmBuf ); +#else error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, &splitRendBits, &renderConfig, &hIvasDec, pcmBuf ); +#endif } else { +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + error = decodeG192( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, hSocket, &splitRendBits, hIvasDec, pcmBuf ); +#else error = decodeG192( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, &splitRendBits, hIvasDec, pcmBuf ); +#endif } if ( error == IVAS_ERR_OK || error == IVAS_ERR_END_OF_FILE ) @@ -865,6 +915,13 @@ cleanup: RenderConfigReader_close( &renderConfigReader ); ObjectEditFileReader_close( &objectEditFileReader ); +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + if ( arg.enableHeadrotTrajSocket ) + { + SocketComm_close( hSocket ); + } +#endif + if ( BS_Reader_Close( &hBsReader ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError while closing file: %s\nContinuing...\n\n", arg.inputBitstreamFilename ); @@ -1014,9 +1071,15 @@ static bool parseCmdlIVAS_dec( arg->enableHeadRotation = false; arg->headrotTrajFileName = NULL; +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + arg->enableHeadrotTrajSocket = false; + arg->socketPort = 0; +#endif arg->orientation_tracking = IVAS_HEAD_ORIENT_TRK_NONE; arg->enableReferenceRotation = false; +#ifndef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO arg->headrotTrajFileName = NULL; +#endif arg->enableReferenceVectorTracking = false; arg->referenceVectorTrajFileName = NULL; arg->enableExternalOrientation = false; @@ -1248,6 +1311,15 @@ static bool parseCmdlIVAS_dec( } else if ( strcmp( argv_to_upper, "-T" ) == 0 ) { +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + if ( arg->enableHeadRotation ) + { + fprintf( stderr, "Error: Head rotation file and socket communication cannot be used together!\n\n" ); + usage_dec(); + return false; + } +#endif + arg->enableHeadRotation = true; i++; @@ -1261,6 +1333,37 @@ static bool parseCmdlIVAS_dec( arg->headrotTrajFileName = argv[i]; i++; } +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + else if ( strcmp( argv_to_upper, "-SOCKET" ) == 0 ) + { + if ( arg->enableHeadRotation ) + { + fprintf( stderr, "Error: Head rotation file and socket communication cannot be used together!\n\n" ); + usage_dec(); + return false; + } + + arg->enableHeadRotation = true; + arg->enableHeadrotTrajSocket = true; + i++; + + if ( argc - i <= 4 || argv[i][0] == '-' ) + { + fprintf( stderr, "Error: Socket port not specified!\n\n" ); + usage_dec(); + return false; + } + + arg->socketPort = (int16_t) atoi( argv[i++] ); + + if ( arg->socketPort < SOCKET_PORT_MIN || arg->socketPort > SOCKET_PORT_MAX ) + { + fprintf( stderr, "Error: Only ports in the range of %d-%d can be used!\n\n", SOCKET_PORT_MIN, SOCKET_PORT_MAX ); + usage_dec(); + return false; + } + } +#endif else if ( strcmp( argv_to_upper, "-FR" ) == 0 ) { int32_t tmp; @@ -1738,6 +1841,43 @@ static bool parseCmdlIVAS_dec( return true; } +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO +/*-----------------------------------------------------------------------* + * parseQuaternionData() + * + * Parse Quaternion Data + *-----------------------------------------------------------------------*/ + +static ivas_error parseQuaternionData( + char *rxBuffer, /* i : data buffer */ + IVAS_QUATERNION *pQuaternion /* o : head-tracking data */ +) +{ + float w, x, y, z; + size_t charsConsumed; + const char *messageHeader = "IVAS buffer request"; + const int32_t read_values = sscanf( rxBuffer, "%*[^:]%n: %f, %f, %f, %f", &charsConsumed, &w, &x, &y, &z ); + + if ( read_values == 4 && charsConsumed == strlen( messageHeader ) && strncmp( rxBuffer, messageHeader, charsConsumed ) == 0 ) + { + { + /* Recieved values can be seen in console */ + printf( "[rotation: w=%+.2f, x=%+.2f, y=%+.2f, z=%+.2f]\n", w, x, y, z ); + + pQuaternion->w = w; + pQuaternion->x = x; + pQuaternion->y = y; + pQuaternion->z = z; + } + } + else + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Quaternion Parser: parsing error." ); + } + + return IVAS_ERR_OK; +} +#endif /*---------------------------------------------------------------------* * usage_dec() @@ -1799,6 +1939,10 @@ static void usage_dec( void ) fprintf( stdout, " default bitstream file format is G.192\n" ); fprintf( stdout, "-hrtf File : HRTF filter File used in BINAURAL output configuration\n" ); fprintf( stdout, "-T File : Head rotation specified by external trajectory File\n" ); +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + fprintf( stdout, "-socket port : Socket communication for pose input and audio output\n" ); + fprintf( stdout, " port = 49152-65535 (range of dynamic, private or ephemeral ports\n" ); +#endif fprintf( stdout, "-otr tracking_type : Head orientation tracking type: 'none', 'ref', 'avg', 'ref_vec' \n" ); fprintf( stdout, " or 'ref_vec_lev' (only for binaural rendering)\n" ); fprintf( stdout, "-rf File : Reference rotation specified by external trajectory File\n" ); @@ -2199,8 +2343,12 @@ static ivas_error decodeG192( RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, + Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + uint32_t hSocket, +#endif ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ) @@ -2269,6 +2417,9 @@ static ivas_error decodeG192( return error; } +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + char rxBuffer[SOCKET_BUFFER_SIZE]; +#endif IVAS_RENDER_CONFIG_DATA renderConfig; RenderConfigReader *renderConfigReader = NULL; @@ -2426,7 +2577,11 @@ static ivas_error decodeG192( { IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + if ( headRotReader == NULL && !arg.enableHeadrotTrajSocket ) +#else if ( headRotReader == NULL ) +#endif { for ( i = 0; i < num_subframes; i++ ) { @@ -2443,11 +2598,42 @@ static ivas_error decodeG192( { for ( i = 0; i < num_subframes; i++ ) { +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + if ( arg.enableHeadrotTrajSocket ) + { + if ( i % num_subframes != 0 ) + { + Quaternions[i] = Quaternions[0]; + continue; + } + + if ( ( error = SocketComm_recv( hSocket, rxBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while receiving head orientation\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( error = parseQuaternionData( rxBuffer, &Quaternions[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while parsing head orientation\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + else + { + if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; + } + } +#else if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) ); goto cleanup; } +#endif } } @@ -2548,6 +2734,22 @@ static ivas_error decodeG192( { if ( error == IVAS_ERR_END_OF_FILE ) { +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + /* Rewind the input bitstream at the end of file in case of socket communication */ + if ( arg.enableHeadrotTrajSocket ) + { + if ( ( error = BS_Reader_Rewind( hBsReader ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: unable to rewind input bitstream file: %s \n\n", arg.inputBitstreamFilename ); + goto cleanup; + } + if ( ( error = BS_Reader_ReadFrame_short( hBsReader, bit_stream, &num_bits, &bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); + goto cleanup; + } + } +#endif break; } fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); @@ -2727,6 +2929,16 @@ static ivas_error decodeG192( { if ( delayNumSamples < nOutSamples ) { +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + if ( arg.enableHeadrotTrajSocket ) + { + if ( ( error = SocketComm_send( hSocket, (char *) &pcmBuf[delayNumSamples * nOutChannels], ( nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) * ( sizeof( *pcmBuf ) / sizeof( char ) ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while sending audio buffer\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } +#endif if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nOutput audio file writer error\n" ); @@ -3136,6 +3348,9 @@ static ivas_error decodeVoIP( RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + uint32_t hSocket, +#endif ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_RENDER_CONFIG_DATA *renderConfig, IVAS_DEC_HANDLE *phIvasDec, @@ -3186,6 +3401,9 @@ static ivas_error decodeVoIP( int16_t vec_pos_update, vec_pos_len; int16_t nOutSamples = 0; +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + char rxBuffer[SOCKET_BUFFER_SIZE]; +#endif bool bitstreamReadDone = false; bool parametersAvailableForEditing = false; @@ -3388,7 +3606,11 @@ static ivas_error decodeVoIP( { IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + if ( headRotReader == NULL && !arg.enableHeadrotTrajSocket ) +#else if ( headRotReader == NULL ) +#endif { for ( i = 0; i < num_subframes; i++ ) { @@ -3405,12 +3627,44 @@ static ivas_error decodeVoIP( { for ( i = 0; i < num_subframes; i++ ) { +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + if ( arg.enableHeadrotTrajSocket ) + { + if ( i % num_subframes != 0 ) + { + Quaternions[i] = Quaternions[0]; + continue; + } + + if ( ( error = SocketComm_recv( hSocket, rxBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while receiving head orientation\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( error = parseQuaternionData( rxBuffer, &Quaternions[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while parsing head orientation\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + else + { + if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), + RotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; + } + } +#else if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) ); goto cleanup; } +#endif } } @@ -3701,6 +3955,16 @@ static ivas_error decodeVoIP( { if ( delayNumSamples < nOutSamples ) { +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + if ( arg.enableHeadrotTrajSocket ) + { + if ( ( error = SocketComm_send( hSocket, (char *) &pcmBuf[delayNumSamples * nOutChannels], ( nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) * ( sizeof( *pcmBuf ) / sizeof( char ) ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while sending audio buffer\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } +#endif if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nOutput audio file writer error\n" ); diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index 4a5249934ce8cd4167a9d3a39b410dc9c9bee7b2..ffeb6cc1dc73f4efa3e09aac34fdc0c29fc7eae1 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -136,6 +136,15 @@ typedef enum IVAS_ERR_SAMPLING_RATE_UNKNOWN, IVAS_ERR_EXTERNAL_ORIENTATION_INVALID_FORMAT, +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + /*----------------------------------------* + * socket errors (lib_util only) * + *----------------------------------------*/ + IVAS_ERR_SOCKET_RECEIVE_FAILED, + IVAS_ERR_SOCKET_SEND_FAILED, + IVAS_ERR_SOCKET_TIMEOUT, +#endif + /*----------------------------------------* * renderer (lib_rend only) * *----------------------------------------*/ diff --git a/lib_com/options.h b/lib_com/options.h old mode 100644 new mode 100755 index bb9519cb16727ec7af7c0d28364bc68af9f71e6e..0c70efa09a4c5b6f4c0d5c8c3d75313b40bd1ad4 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -160,6 +160,10 @@ /* only BE switches wrt wrt. TS 26.258 V3.0 */ /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ +#ifdef _MSC_VER +#define SOCKET_INTERFACE_FOR_POSE_AND_AUDIO /* Philips: issue #1019: Socket interface for head rotation - Windows only */ +#endif + #define TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR /* FhG: Temporary workaround for incorrect implementation of decoder flush with split rendering */ #define NONBE_1122_KEEP_EVS_MODE_UNCHANGED /* FhG: Disables fix for issue 1122 in EVS mode to keep BE tests green. This switch should be removed once the 1122 fix is added to EVS via a CR. */ #define FIX_2287_MCT_MDCT_STEREO_DATA_MALLOC_SIZE /* FhG: correct allocation size for STEREO_MDCT_DEC_DATA struct */ diff --git a/lib_util/bitstream_reader.c b/lib_util/bitstream_reader.c index c6fe784fbde9de4ec48281e50048066bc9909f19..54422588540c9d1f7ce3692c0128ac6d88e5f81e 100644 --- a/lib_util/bitstream_reader.c +++ b/lib_util/bitstream_reader.c @@ -261,7 +261,7 @@ cleanup: return error; } -#ifdef DEBUGGING +#if defined( SOCKET_INTERFACE_FOR_POSE_AND_AUDIO ) || defined( DEBUGGING ) ivas_error BS_Reader_Rewind( BS_READER_HANDLE hBsReader ) { if ( hBsReader == NULL ) diff --git a/lib_util/bitstream_reader.h b/lib_util/bitstream_reader.h index 8c88bd773ca3eed7d419ac74bf6560163af4fe72..9f8c2303e13f5c9c6d9d523625ef5b036c68f1bd 100644 --- a/lib_util/bitstream_reader.h +++ b/lib_util/bitstream_reader.h @@ -58,7 +58,7 @@ typedef struct BS_Reader *BS_READER_HANDLE; ivas_error BS_Reader_Open_filename( BS_READER_HANDLE *phBsReader, const char *filename, BS_READER_FORMAT format ); -#ifdef DEBUGGING +#if defined( SOCKET_INTERFACE_FOR_POSE_AND_AUDIO ) || defined( DEBUGGING ) ivas_error BS_Reader_Rewind( BS_READER_HANDLE hBsReader ); #endif diff --git a/lib_util/socket_comm.c b/lib_util/socket_comm.c new file mode 100644 index 0000000000000000000000000000000000000000..b8acd887ca5bd88463202e189b2ca3a23e11d612 --- /dev/null +++ b/lib_util/socket_comm.c @@ -0,0 +1,193 @@ +/****************************************************************************************************** \ + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "socket_comm.h" + +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO +/* Locally disable MAC and _MAC macros to avoid issues with MAC implementation for winsock2.h */ +#pragma push_macro( "MAC" ) +#undef MAC +#pragma push_macro( "_MAC" ) +#undef _MAC +#include +#include +#pragma pop_macro( "MAC" ) +#pragma pop_macro( "_MAC" ) + +/*-----------------------------------------------------------------------* + * SocketComm_start() + * + * Start hSocket communication and return a listening socket handle + *-----------------------------------------------------------------------*/ + +ivas_error SocketComm_start( + uint32_t *hSocket, /* o : socket handle */ + uint16_t port /* i : IP port */ +) +{ + WSADATA wsaData; + SOCKADDR_IN sockAddr; + SOCKET serverSocket; + SOCKET clientSocket; + + if ( WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) != 0 ) + { + fprintf( stderr, "Socket communication: WSAStartup() failed with error %ld\n\n", WSAGetLastError() ); + WSACleanup(); + return IVAS_ERR_INIT_ERROR; + } + + /* Create a socket for the server to listen for client connections */ + serverSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); + + if ( serverSocket == INVALID_SOCKET ) + { + fprintf( stderr, "Socket communication: socket() failed with error %ld\n\n", WSAGetLastError() ); + WSACleanup(); + return IVAS_ERR_INIT_ERROR; + } + + sockAddr.sin_family = AF_INET; + sockAddr.sin_port = htons( port ); + InetPton( sockAddr.sin_family, "127.0.0.1", &sockAddr.sin_addr.s_addr ); + + /* Setup the TCP listening socket */ + if ( bind( serverSocket, (SOCKADDR *) &sockAddr, sizeof( sockAddr ) ) == SOCKET_ERROR ) + { + fprintf( stderr, "Socket communication: bind() failed with error %ld\n\n", WSAGetLastError() ); + closesocket( serverSocket ); + WSACleanup(); + return IVAS_ERR_INIT_ERROR; + } + + /* Start listening */ + if ( listen( serverSocket, SOMAXCONN ) == SOCKET_ERROR ) + { + printf( "Socket communication: listen() failed with error: %ld\n\n", WSAGetLastError() ); + closesocket( serverSocket ); + WSACleanup(); + return IVAS_ERR_INIT_ERROR; + } + + /* Accept a client socket */ + clientSocket = accept( serverSocket, NULL, NULL ); + + if ( clientSocket == INVALID_SOCKET ) + { + printf( "Socket communication: accept() failed with error: %ld\n\n", WSAGetLastError() ); + closesocket( serverSocket ); + WSACleanup(); + return IVAS_ERR_INIT_ERROR; + } + + /* Close the server socket */ + closesocket( serverSocket ); + + *hSocket = clientSocket; + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------* + * SocketComm_recv() + * + * Receive data from a socket + *-----------------------------------------------------------------------*/ + +ivas_error SocketComm_recv( + uint32_t hSocket, /* i : socket handle */ + char *rxBuffer /* o : receive data buffer */ +) +{ + int32_t wsaError; + int32_t rxByteCount = recv( hSocket, rxBuffer, SOCKET_BUFFER_SIZE, 0 ); + + if ( rxByteCount <= 0 ) + { + wsaError = WSAGetLastError(); + if ( wsaError == 10060 ) + { + fprintf( stderr, "Socket communication: timeout\n\n" ); + return IVAS_ERR_SOCKET_TIMEOUT; + } + else + { + fprintf( stderr, "Socket communication: recv() failed with error: %ld\n\n", WSAGetLastError() ); + return IVAS_ERR_SOCKET_RECEIVE_FAILED; + } + } + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------* + * SocketComm_send() + * + * Send a buffer using a socket + *-----------------------------------------------------------------------*/ + +ivas_error SocketComm_send( + uint32_t hSocket, /* i : socket handle */ + const char *txBuffer, /* i : buffer to send */ + uint16_t size /* i : size of buffer */ +) +{ + if ( send( hSocket, txBuffer, size, 0 ) == SOCKET_ERROR ) + { + fprintf( stderr, "Socket communication: send() failed with error %ld\n\n", WSAGetLastError() ); + closesocket( hSocket ); + WSACleanup(); + return IVAS_ERR_SOCKET_SEND_FAILED; + } + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------* + * SocketComm_close() + * + * Close a scoket + *-----------------------------------------------------------------------*/ + +void SocketComm_close( + uint32_t hSocket /* i: socket handle */ +) +{ + if ( shutdown( hSocket, SD_SEND ) == SOCKET_ERROR ) + { + fprintf( stderr, "Socket communication: shutdown() failed with error: %ld\n\n", WSAGetLastError() ); + } + + closesocket( hSocket ); + WSACleanup(); +} +#endif diff --git a/lib_util/socket_comm.h b/lib_util/socket_comm.h new file mode 100644 index 0000000000000000000000000000000000000000..c224c2676a8479ac389302a82bfaed00db1ec47f --- /dev/null +++ b/lib_util/socket_comm.h @@ -0,0 +1,89 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef IVAS_SOCKET_COMM_H +#define IVAS_SOCKET_COMM_H + +#include "common_api_types.h" + +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + +#define SOCKET_BUFFER_SIZE ( 512 ) +#define SOCKET_PORT_MIN ( 49152 ) +#define SOCKET_PORT_MAX ( 65535 ) + +/*-----------------------------------------------------------------------* + * SocketComm_start() + * + * Start socket communication and return socket + *-----------------------------------------------------------------------*/ + +ivas_error SocketComm_start( + uint32_t *hSocket, /* o : socket handle */ + uint16_t port /* i : port */ +); + +/*-----------------------------------------------------------------------* + * SocketComm_recv() + * + * Receive request from socket + *-----------------------------------------------------------------------*/ + +ivas_error SocketComm_recv( + uint32_t hSocket, /* i : socket handle */ + char *rxBuffer /* o : data buffer */ +); + +/*-----------------------------------------------------------------------* + * SocketComm_send() + * + * Send via socket + *-----------------------------------------------------------------------*/ + +ivas_error SocketComm_send( + uint32_t hSocket, /* i : socket handle */ + const char *txBuffer, /* i : buffer to send */ + uint16_t size /* i : buffer size */ +); + +/*-----------------------------------------------------------------------* + * SocketComm_close() + * + * Close socket communication + *-----------------------------------------------------------------------*/ + +void SocketComm_close( + uint32_t hSocket /* i: socket handle */ +); + +#endif +#endif /* IVAS_SOCKET_COMM_H */