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 */