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 bead7110f33c5f14f0318980c52e315d490a5d9b..218ad45528998fcd33f1e70b82449d3c815c50c8 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -110,6 +110,7 @@ + @@ -139,6 +140,7 @@ + diff --git a/apps/decoder.c b/apps/decoder.c index 41089d057e230d20fb65f02c48a9db930b5ac612..9e6b2cfd49f479a3c10259461f3b6b6c0e2bcfcf 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -44,6 +44,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" @@ -100,6 +104,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; @@ -169,13 +177,28 @@ 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 *hHrtf, 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 ); +#else static ivas_error decodeG192( 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_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +#endif #ifdef FIX_1119_SPLIT_RENDERING_VOIP +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO +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_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +#else 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_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +#endif +#else +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO +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, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); #else 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, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); #endif +#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 ); @@ -214,6 +237,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 #ifdef DEBUGGING int32_t noClipping; int32_t cnt_frames_limited; @@ -326,15 +352,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 } /*------------------------------------------------------------------------------------------* @@ -757,14 +806,26 @@ int main( if ( arg.voipMode ) { #ifdef FIX_1119_SPLIT_RENDERING_VOIP +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, hSocket, &splitRendBits, hIvasDec, pcmBuf ); +#else error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, &splitRendBits, hIvasDec, pcmBuf ); +#endif +#else +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, hSocket, hIvasDec, pcmBuf ); #else error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, hIvasDec, pcmBuf ); +#endif #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 ) @@ -830,6 +891,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 ); @@ -980,9 +1048,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; @@ -1198,6 +1272,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++; @@ -1211,6 +1294,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; @@ -1640,6 +1754,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() @@ -1695,6 +1846,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" ); @@ -2065,8 +2220,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 ) @@ -2137,6 +2296,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; @@ -2294,7 +2456,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++ ) { @@ -2311,11 +2477,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 } } @@ -2416,6 +2613,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 ); @@ -2599,6 +2812,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" ); @@ -3021,6 +3244,9 @@ static ivas_error decodeVoIP( RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, +#ifdef SOCKET_INTERFACE_FOR_POSE_AND_AUDIO + uint32_t hSocket, +#endif #ifdef FIX_1119_SPLIT_RENDERING_VOIP ISAR_SPLIT_REND_BITS_DATA *splitRendBits, #endif @@ -3070,6 +3296,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; @@ -3262,7 +3491,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++ ) { @@ -3279,12 +3512,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 } } @@ -3534,6 +3799,16 @@ static ivas_error decodeVoIP( #endif 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 563b10e39112c34c9c5093d1d50bde1242ca558a..4ed52cc05f1a7c848a51627d6135f7226470f76c 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 index 8b761e69b28eb127ce5471ef638b7ef56c56b668..67a091d9884f4397703eab3ac975e0b9041329c9 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -162,6 +162,10 @@ /* only BE switches wrt selection floating point code */ /*#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 FIX_1119_SPLIT_RENDERING_VOIP /* FhG: Add split rendering support to decoder in VoIP mode */ #define TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR /* FhG: Temporary workaround for incorrect implementation of decoder flush with split rendering */ #define FIX_1377_HANDLE_ERROR_CODE /* Eri: Add missing error code handling from IVAS_REND_SetObjectIDs */ 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 */