diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj
index 4ec7948021793313475e6f86c8e5084b7364fed0..cfac84f4fddc2f1ba47ddab0e2cafc914cca199f 100644
--- a/Workspace_msvc/lib_util.vcxproj
+++ b/Workspace_msvc/lib_util.vcxproj
@@ -110,6 +110,7 @@
+
@@ -138,6 +139,7 @@
+
diff --git a/apps/decoder.c b/apps/decoder.c
index b317b9a53996d400d03cf16f914414074910db63..19cbae8b6d91d72f6bf27331328493d92d4fdfb2 100644
--- a/apps/decoder.c
+++ b/apps/decoder.c
@@ -44,6 +44,11 @@
#include "render_config_reader.h"
#include "rotation_file_reader.h"
#include "aeid_file_reader.h"
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+#include "quaternion_file_writer.h"
+#endif
+#endif
#include "split_render_file_read_write.h"
#ifdef VARIABLE_SPEED_DECODING
#include "tsm_scale_file_reader.h"
@@ -115,6 +120,16 @@ typedef struct
bool voipMode;
bool enableHeadRotation;
char *headrotTrajFileName;
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ bool mainOrientationWriterEnabled;
+ char *mainOrientationFilename;
+ bool trackedRotationWriterEnabled;
+ char *trackedRotationFilename;
+ bool combinedOrientationWriterEnabled;
+ char *combinedOrientationFilename;
+#endif
+#endif
bool enableReferenceRotation;
char *refrotTrajFileName;
bool enableReferenceVectorTracking;
@@ -168,8 +183,18 @@ typedef struct
static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg );
static void usage_dec( void );
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, QuaternionFileWriter *mainOrientWriter, QuaternionFileWriter *trackRotWriter, QuaternionFileWriter *combOrientWriter, Vector3PairFileReader *referenceVectorReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf );
+static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, QuaternionFileWriter *mainOrientWriter, QuaternionFileWriter *trackRotWriter, QuaternionFileWriter *combOrientWriter, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec );
+#else
static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf );
static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec );
+#endif
+#else
+static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf );
+static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec );
+#endif
#ifdef DEBUGGING
static ivas_error printBitstreamInfoVoip( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HANDLE hIvasDec );
@@ -201,6 +226,13 @@ int main(
RotFileReader *headRotReader = NULL;
RotFileReader *externalOrientationFileReader = NULL;
RotFileReader *refRotReader = NULL;
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ QuaternionFileWriter *mainOrientWriter = NULL;
+ QuaternionFileWriter *trackRotWriter = NULL;
+ QuaternionFileWriter *combOrientWriter = NULL;
+#endif
+#endif
Vector3PairFileReader *referenceVectorReader = NULL;
RenderConfigReader *renderConfigReader = NULL;
int16_t *pcmBuf = NULL;
@@ -328,6 +360,49 @@ int main(
}
}
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ /*------------------------------------------------------------------------------------------*
+ * Open main orientation output file for writing
+ *------------------------------------------------------------------------------------------*/
+
+ if ( arg.mainOrientationWriterEnabled )
+ {
+ if ( ( error = QuaternionFileWriter_open( arg.mainOrientationFilename, &mainOrientWriter ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nError: Can't open main orientation output file %s \n\n", arg.mainOrientationFilename );
+ goto cleanup;
+ }
+ }
+
+ /*------------------------------------------------------------------------------------------*
+ * Open tracked rotation output file for writing
+ *------------------------------------------------------------------------------------------*/
+
+ if ( arg.trackedRotationWriterEnabled )
+ {
+ if ( ( error = QuaternionFileWriter_open( arg.trackedRotationFilename, &trackRotWriter ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nError: Can't open tracked rotation output file %s \n\n", arg.trackedRotationFilename );
+ goto cleanup;
+ }
+ }
+
+ /*------------------------------------------------------------------------------------------*
+ * Open combined orientation output file for writing
+ *------------------------------------------------------------------------------------------*/
+
+ if ( arg.combinedOrientationWriterEnabled )
+ {
+ if ( ( error = QuaternionFileWriter_open( arg.combinedOrientationFilename, &combOrientWriter ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nError: Can't open combined orientation output file %s \n\n", arg.combinedOrientationFilename );
+ goto cleanup;
+ }
+ }
+#endif
+#endif
+
/*------------------------------------------------------------------------------------------*
* Open reference rotation file
*------------------------------------------------------------------------------------------*/
@@ -846,11 +921,27 @@ int main(
if ( arg.voipMode )
{
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ error = decodeVoIP( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, mainOrientWriter, trackRotWriter, combOrientWriter, referenceVectorReader, hIvasDec );
+#else
+ error = decodeVoIP( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec );
+#endif
+#else
error = decodeVoIP( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec );
+#endif
}
else
{
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, mainOrientWriter, trackRotWriter, combOrientWriter, referenceVectorReader, &splitRendBits, hIvasDec, pcmBuf );
+#else
error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, &splitRendBits, hIvasDec, pcmBuf );
+#endif
+#else
+ error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, &splitRendBits, hIvasDec, pcmBuf );
+#endif
}
if ( error == IVAS_ERR_OK || error == IVAS_ERR_END_OF_FILE )
@@ -918,6 +1009,13 @@ cleanup:
RotationFileReader_close( &headRotReader );
RotationFileReader_close( &externalOrientationFileReader );
RotationFileReader_close( &refRotReader );
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ QuaternionFileWriter_close( &mainOrientWriter );
+ QuaternionFileWriter_close( &trackRotWriter );
+ QuaternionFileWriter_close( &combOrientWriter );
+#endif
+#endif
Vector3PairFileReader_close( &referenceVectorReader );
RenderConfigReader_close( &renderConfigReader );
@@ -1067,6 +1165,16 @@ static bool parseCmdlIVAS_dec(
arg->enableHeadRotation = false;
arg->headrotTrajFileName = NULL;
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ arg->mainOrientationWriterEnabled = false;
+ arg->mainOrientationFilename = NULL;
+ arg->trackedRotationWriterEnabled = false;
+ arg->trackedRotationFilename = NULL;
+ arg->combinedOrientationWriterEnabled = false;
+ arg->combinedOrientationFilename = NULL;
+#endif
+#endif
arg->orientation_tracking = ORIENT_TRK_NONE;
arg->enableReferenceRotation = false;
arg->headrotTrajFileName = NULL;
@@ -1300,6 +1408,55 @@ static bool parseCmdlIVAS_dec(
arg->headrotTrajFileName = argv[i];
i++;
}
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ else if ( strcmp( argv_to_upper, "-MOOF" ) == 0 )
+ {
+ arg->mainOrientationWriterEnabled = true;
+ i++;
+
+ if ( argc - i <= 4 || argv[i][0] == '-' )
+ {
+ fprintf( stderr, "Error: Main orientation output file name not specified!\n\n" );
+ usage_dec();
+ return false;
+ }
+
+ arg->mainOrientationFilename = argv[i];
+ i++;
+ }
+ else if ( strcmp( argv_to_upper, "-TROF" ) == 0 )
+ {
+ arg->trackedRotationWriterEnabled = true;
+ i++;
+
+ if ( argc - i <= 4 || argv[i][0] == '-' )
+ {
+ fprintf( stderr, "Error: Tracked rotation output file name not specified!\n\n" );
+ usage_dec();
+ return false;
+ }
+
+ arg->trackedRotationFilename = argv[i];
+ i++;
+ }
+ else if ( strcmp( argv_to_upper, "-COOF" ) == 0 )
+ {
+ arg->combinedOrientationWriterEnabled = true;
+ i++;
+
+ if ( argc - i <= 4 || argv[i][0] == '-' )
+ {
+ fprintf( stderr, "Error: Combined orientation output file name not specified!\n\n" );
+ usage_dec();
+ return false;
+ }
+
+ arg->combinedOrientationFilename = argv[i];
+ i++;
+ }
+#endif
+#endif
else if ( strcmp( argv_to_upper, "-FR" ) == 0 )
{
int32_t tmp;
@@ -1756,6 +1913,13 @@ 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 FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ fprintf( stdout, "-moof File : Main orientation data output File\n" );
+ fprintf( stdout, "-trof File : Tracked rotation data output File\n" );
+ fprintf( stdout, "-coof File : Combined orientation data output File\n" );
+#endif
+#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" );
@@ -2105,6 +2269,13 @@ static ivas_error decodeG192(
RotFileReader *headRotReader,
RotFileReader *externalOrientationFileReader,
RotFileReader *refRotReader,
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ QuaternionFileWriter *mainOrientWriter,
+ QuaternionFileWriter *trackRotWriter,
+ QuaternionFileWriter *combOrientWriter,
+#endif
+#endif
Vector3PairFileReader *referenceVectorReader,
ISAR_SPLIT_REND_BITS_DATA *splitRendBits,
IVAS_DEC_HANDLE hIvasDec,
@@ -2351,6 +2522,48 @@ static ivas_error decodeG192(
goto cleanup;
}
}
+
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ if ( arg.mainOrientationWriterEnabled )
+ {
+ IVAS_QUATERNION orientation;
+
+ if ( ( error = IVAS_DEC_GetMainOrientation( hIvasDec, &orientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nIVAS_DEC_GetMainOrientation failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ else
+ {
+ if ( ( error = QuaternionFileWriter_writeFrame( mainOrientWriter, orientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nQuaternionFileWriter_writeFrame failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ }
+ }
+
+ if ( arg.trackedRotationWriterEnabled )
+ {
+ IVAS_QUATERNION rotation;
+
+ if ( ( error = IVAS_DEC_GetTrackedRotation( hIvasDec, &rotation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nIVAS_DEC_GetTrackedRotation failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ else
+ {
+ if ( ( error = QuaternionFileWriter_writeFrame( trackRotWriter, rotation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nQuaternionFileWriter_writeFrame failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ }
+ }
+#endif
+#endif
}
if ( arg.enableExternalOrientation )
@@ -2379,6 +2592,29 @@ static ivas_error decodeG192(
}
}
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ if ( arg.combinedOrientationWriterEnabled && ( arg.enableHeadRotation || arg.enableExternalOrientation ) )
+ {
+ IVAS_QUATERNION orientation;
+
+ if ( ( error = IVAS_DEC_GetCombinedOrientation( hIvasDec, &orientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nIVAS_DEC_GetCombinedOrientation failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ else
+ {
+ if ( ( error = QuaternionFileWriter_writeFrame( combOrientWriter, orientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nQuaternionFileWriter_writeFrame failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ }
+ }
+#endif
+#endif
+
/* decode and get samples */
nSamplesRendered = 0;
nSamplesToRender = nOutSamples;
@@ -2760,7 +2996,72 @@ static ivas_error decodeG192(
fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
goto cleanup;
}
+
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ if ( arg.mainOrientationWriterEnabled )
+ {
+ IVAS_QUATERNION orientation;
+
+ if ( ( error = IVAS_DEC_GetMainOrientation( hIvasDec, &orientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nIVAS_DEC_GetMainOrientation failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ else
+ {
+ if ( ( error = QuaternionFileWriter_writeFrame( mainOrientWriter, orientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nQuaternionFileWriter_writeFrame failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ }
+ }
+
+ if ( arg.trackedRotationWriterEnabled )
+ {
+ IVAS_QUATERNION rotation;
+
+ if ( ( error = IVAS_DEC_GetTrackedRotation( hIvasDec, &rotation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nIVAS_DEC_GetTrackedRotation failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ else
+ {
+ if ( ( error = QuaternionFileWriter_writeFrame( trackRotWriter, rotation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nQuaternionFileWriter_writeFrame failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ }
+ }
+#endif
+#endif
+ }
+
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ if ( arg.combinedOrientationWriterEnabled && ( arg.enableHeadRotation || arg.enableExternalOrientation ) )
+ {
+ IVAS_QUATERNION orientation;
+
+ if ( ( error = IVAS_DEC_GetCombinedOrientation( hIvasDec, &orientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nIVAS_DEC_GetCombinedOrientation failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ else
+ {
+ if ( ( error = QuaternionFileWriter_writeFrame( combOrientWriter, orientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nQuaternionFileWriter_writeFrame failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ }
}
+#endif
+#endif
/* decode and get samples */
if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK )
@@ -3042,6 +3343,13 @@ static ivas_error decodeVoIP(
RotFileReader *headRotReader,
RotFileReader *externalOrientationFileReader,
RotFileReader *refRotReader,
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ QuaternionFileWriter *mainOrientWriter,
+ QuaternionFileWriter *trackRotWriter,
+ QuaternionFileWriter *combOrientWriter,
+#endif
+#endif
Vector3PairFileReader *referenceVectorReader,
IVAS_DEC_HANDLE hIvasDec )
{
@@ -3294,6 +3602,48 @@ static ivas_error decodeVoIP(
goto cleanup;
}
}
+
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ if ( arg.mainOrientationWriterEnabled )
+ {
+ IVAS_QUATERNION orientation;
+
+ if ( ( error = IVAS_DEC_GetMainOrientation( hIvasDec, &orientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nIVAS_DEC_GetMainOrientation failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ else
+ {
+ if ( ( error = QuaternionFileWriter_writeFrame( mainOrientWriter, orientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nQuaternionFileWriter_writeFrame failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ }
+ }
+
+ if ( arg.trackedRotationWriterEnabled )
+ {
+ IVAS_QUATERNION rotation;
+
+ if ( ( error = IVAS_DEC_GetTrackedRotation( hIvasDec, &rotation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nIVAS_DEC_GetTrackedRotation failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ else
+ {
+ if ( ( error = QuaternionFileWriter_writeFrame( trackRotWriter, rotation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nQuaternionFileWriter_writeFrame failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ }
+ }
+#endif
+#endif
}
if ( arg.enableExternalOrientation )
@@ -3324,6 +3674,29 @@ static ivas_error decodeVoIP(
}
}
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ if ( arg.combinedOrientationWriterEnabled && ( arg.enableHeadRotation || arg.enableExternalOrientation ) )
+ {
+ IVAS_QUATERNION orientation;
+
+ if ( ( error = IVAS_DEC_GetCombinedOrientation( hIvasDec, &orientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nIVAS_DEC_GetCombinedOrientation failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ else
+ {
+ if ( ( error = QuaternionFileWriter_writeFrame( combOrientWriter, orientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nQuaternionFileWriter_writeFrame failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ }
+ }
+#endif
+#endif
+
/* read all packets with a receive time smaller than the system time */
while ( nextPacketRcvTime_ms <= systemTime_ms )
{
diff --git a/apps/renderer.c b/apps/renderer.c
index 52d6e81d099feb163957605d62f60a40c1b728df..1f9f962071fd172093f849e2f237bfd77b5e719a 100644
--- a/apps/renderer.c
+++ b/apps/renderer.c
@@ -45,6 +45,11 @@
#include "masa_file_writer.h"
#include "render_config_reader.h"
#include "rotation_file_reader.h"
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+#include "quaternion_file_writer.h"
+#endif
+#endif
#include "aeid_file_reader.h"
#include "split_render_file_read_write.h"
#include "split_rend_bfi_file_reader.h"
@@ -168,6 +173,13 @@ typedef struct
char externalOrientationFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
char customHrtfFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
char renderConfigFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ char mainOrientationOutputFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
+ char trackedOrientationOutputFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
+ char combinedOrientationOutputFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
+#endif
+#endif
int8_t orientation_tracking;
int16_t Opt_Headrotation;
int16_t Opt_ExternalOrientation;
@@ -215,6 +227,13 @@ typedef enum
CmdLnOptionId_SplitRendBFIFile,
CmdLnOptionId_referenceVectorFile,
CmdLnOptionId_exteriorOrientationFile,
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ CmdLnOptionId_mainOrientationOutputFile,
+ CmdLnOptionId_trackedRotationOutputFile,
+ CmdLnOptionId_combinedOrientationOutputFile,
+#endif
+#endif
CmdLnOptionId_framing,
CmdLnOptionId_syncMdDelay,
CmdLnOptionId_directivityPatternId,
@@ -360,6 +379,28 @@ static const CmdLnParser_Option cliOptions[] = {
.matchShort = "exof",
.description = "External orientation trajectory file for simulation of external orientations",
},
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ {
+ .id = CmdLnOptionId_mainOrientationOutputFile,
+ .match = "main_orientation_output_file",
+ .matchShort = "moof",
+ .description = "Main orientation data output File",
+ },
+ {
+ .id = CmdLnOptionId_trackedRotationOutputFile,
+ .match = "tracked_rotation_output_file",
+ .matchShort = "trof",
+ .description = "Tracked rotation data output File",
+ },
+ {
+ .id = CmdLnOptionId_combinedOrientationOutputFile,
+ .match = "combined_orientation_output_file",
+ .matchShort = "coof",
+ .description = "Combined orientation data output File",
+ },
+#endif
+#endif
{
.id = CmdLnOptionId_framing,
.match = "framing",
@@ -659,6 +700,13 @@ int main(
RotFileReader *headRotReader = NULL;
RotFileReader *externalOrientationFileReader = NULL;
RotFileReader *referenceRotReader = NULL;
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ QuaternionFileWriter *mainOrientationFileWriter = NULL;
+ QuaternionFileWriter *trackedRotationFileWriter = NULL;
+ QuaternionFileWriter *combinedOrientationFileWriter = NULL;
+#endif
+#endif
IVAS_CLDFB_FILTER_BANK_HANDLE cldfbAna[IVAS_MAX_INPUT_CHANNELS];
IVAS_CLDFB_FILTER_BANK_HANDLE cldfbSyn[IVAS_MAX_INPUT_CHANNELS];
int16_t cldfb_in_flag, CLDFBframeSize_smpls;
@@ -757,6 +805,13 @@ int main(
convert_backslash( args.referenceRotationFilePath );
convert_backslash( args.inLfePanningMatrixFile );
convert_backslash( args.externalOrientationFilePath );
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ convert_backslash( args.mainOrientationOutputFilePath );
+ convert_backslash( args.trackedOrientationOutputFilePath );
+ convert_backslash( args.combinedOrientationOutputFilePath );
+#endif
+#endif
if ( !isEmptyString( args.headRotationFilePath ) )
{
@@ -799,6 +854,36 @@ int main(
}
}
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ if ( !isEmptyString( args.mainOrientationOutputFilePath ) )
+ {
+ if ( QuaternionFileWriter_open( args.mainOrientationOutputFilePath, &mainOrientationFileWriter ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error opening file: %s\n", args.mainOrientationOutputFilePath );
+ exit( -1 );
+ }
+ }
+
+ if ( !isEmptyString( args.trackedOrientationOutputFilePath ) )
+ {
+ if ( QuaternionFileWriter_open( args.trackedOrientationOutputFilePath, &trackedRotationFileWriter ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error opening file: %s\n", args.trackedOrientationOutputFilePath );
+ exit( -1 );
+ }
+ }
+
+ if ( !isEmptyString( args.combinedOrientationOutputFilePath ) )
+ {
+ if ( QuaternionFileWriter_open( args.combinedOrientationOutputFilePath, &combinedOrientationFileWriter ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error opening file: %s\n", args.combinedOrientationOutputFilePath );
+ exit( -1 );
+ }
+ }
+#endif
+#endif
if ( !isEmptyString( args.renderConfigFilePath ) )
{
@@ -1574,6 +1659,67 @@ int main(
}
}
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ if ( mainOrientationFileWriter != NULL && headRotReader != NULL )
+ {
+ for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ IVAS_QUATERNION mainOrientation;
+
+ if ( ( error = IVAS_REND_GetMainOrientation( hIvasRend, &mainOrientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error while getting main orientation: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ if ( ( error = QuaternionFileWriter_writeFrame( mainOrientationFileWriter, mainOrientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error while writing main orientation data: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ }
+ }
+
+ if ( trackedRotationFileWriter != NULL && headRotReader != NULL )
+ {
+ for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ IVAS_QUATERNION trackedRotation;
+
+ if ( ( error = IVAS_REND_GetTrackedRotation( hIvasRend, &trackedRotation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error while getting main orientation: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ if ( ( error = QuaternionFileWriter_writeFrame( trackedRotationFileWriter, trackedRotation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error while writing main orientation data: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ }
+ }
+
+ if ( combinedOrientationFileWriter != NULL && ( headRotReader != NULL || externalOrientationFileReader != NULL ) )
+ {
+ for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ IVAS_QUATERNION combinedOrientation;
+
+ if ( ( error = IVAS_REND_GetCombinedOrientation( hIvasRend, &combinedOrientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error while getting main orientation: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ if ( ( error = QuaternionFileWriter_writeFrame( combinedOrientationFileWriter, combinedOrientation ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error while writing main orientation data: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ }
+ }
+#endif
+#endif
+
/* Combine external orientations and head rotation */
if ( ( error = IVAS_REND_CombineHeadAndExternalOrientation( hIvasRend ) ) != IVAS_ERR_OK )
@@ -1947,9 +2093,17 @@ cleanup:
MasaFileWriter_close( &masaWriter );
AudioFileReader_close( &audioReader );
AudioFileWriter_close( &audioWriter );
+
RotationFileReader_close( &headRotReader );
RotationFileReader_close( &externalOrientationFileReader );
RotationFileReader_close( &referenceRotReader );
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ QuaternionFileWriter_close( &mainOrientationFileWriter );
+ QuaternionFileWriter_close( &trackedRotationFileWriter );
+ QuaternionFileWriter_close( &combinedOrientationFileWriter );
+#endif
+#endif
Vector3PairFileReader_close( &referenceVectorReader );
destroy_td_hrtf( hHrtfTD );
@@ -2512,6 +2666,15 @@ static CmdlnArgs defaultArgs(
clearString( args.renderConfigFilePath );
clearString( args.externalOrientationFilePath );
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ clearString( args.mainOrientationOutputFilePath );
+ clearString( args.trackedOrientationOutputFilePath );
+ clearString( args.combinedOrientationOutputFilePath );
+#endif
+#endif
+
+
args.Opt_Headrotation = 0;
args.Opt_ExternalOrientation = 0;
args.orientation_tracking = IVAS_HEAD_ORIENT_TRK_NONE;
@@ -2627,6 +2790,22 @@ static void parseOption(
args->Opt_ExternalOrientation = 1;
strncpy( args->externalOrientationFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
break;
+#ifdef FIX_1100_OUTPUT_ORIENT
+#ifdef DEBUGGING
+ case CmdLnOptionId_mainOrientationOutputFile:
+ assert( numOptionValues == 1 );
+ strncpy( args->mainOrientationOutputFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
+ break;
+ case CmdLnOptionId_trackedRotationOutputFile:
+ assert( numOptionValues == 1 );
+ strncpy( args->trackedOrientationOutputFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
+ break;
+ case CmdLnOptionId_combinedOrientationOutputFile:
+ assert( numOptionValues == 1 );
+ strncpy( args->combinedOrientationOutputFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
+ break;
+#endif
+#endif
case CmdLnOptionId_customHrtfFile:
assert( numOptionValues == 1 );
strncpy( args->customHrtfFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
diff --git a/lib_com/options.h b/lib_com/options.h
index 367583eb90832fda74f176fdbb7859591948dbc0..590c6fc54df9fe6694c83cb0ee476eb0d4aa2ab2 100644
--- a/lib_com/options.h
+++ b/lib_com/options.h
@@ -172,6 +172,7 @@
#define FIX_1158_FASTCONV_REVERB_HRTF /* Philips: issue 1158: Rendering with FastConv to BINAURAL_ROOM_REVERB uses BRIR convolution instead of HRTF */
#define FIX_VOIP_FUNCTIONS /* VA: fix data type mismatch in IVAS_DEC_VoIP_SetScale() + add sanity checks to API functions */
+#define FIX_1100_OUTPUT_ORIENT /* Philips: issue 1100: Output for main/tracked/combined orientation for the decoder application */
/* #################### End BE switches ################################## */
/* #################### Start NON-BE switches ############################ */
diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c
index 900b879cb61323200c26964cdaa804e90063c42f..db613bdf25b5ebe24d90bf17703ae6c961f4af81 100644
--- a/lib_dec/lib_dec.c
+++ b/lib_dec/lib_dec.c
@@ -3065,6 +3065,92 @@ static void bsCompactToSerial(
}
+#ifdef FIX_1100_OUTPUT_ORIENT
+/*-------------------------------------------------------------------*
+ * IVAS_DEC_GetMainOrientation()
+ *
+ * Get main orientation
+ *-------------------------------------------------------------------*/
+
+ivas_error IVAS_DEC_GetMainOrientation(
+ IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */
+ IVAS_QUATERNION *pOrientation /* o : Quaternion pointer for main orientation */
+)
+{
+ ivas_error error;
+
+ if ( hIvasDec == NULL || pOrientation == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ if ( ( error = ivas_orient_trk_GetMainOrientation( hIvasDec->st_ivas->hHeadTrackData->OrientationTracker, pOrientation ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------*
+ * IVAS_DEC_GetTrackedRotation()
+ *
+ * Get tracked rotation
+ *-------------------------------------------------------------------*/
+
+ivas_error IVAS_DEC_GetTrackedRotation(
+ IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */
+ IVAS_QUATERNION *pRotation /* o : Quaternion pointer processed rotation */
+)
+{
+ ivas_error error;
+
+ if ( hIvasDec == NULL || pRotation == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ if ( ( error = ivas_orient_trk_GetTrackedRotation( hIvasDec->st_ivas->hHeadTrackData->OrientationTracker, pRotation ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+
+/*---------------------------------------------------------------------*
+ * IVAS_DEC_GetCombinedOrientation()
+ *
+ * Get combined orientation
+ *---------------------------------------------------------------------*/
+
+ivas_error IVAS_DEC_GetCombinedOrientation(
+ IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */
+ IVAS_QUATERNION *pOrientation /* o: Quaternion pointer processed orientation */
+)
+{
+ int16_t i;
+
+ if ( hIvasDec == NULL || pOrientation == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL )
+ {
+ for ( i = 0; i < hIvasDec->st_ivas->hCombinedOrientationData->num_subframes; ++i )
+ {
+ pOrientation[i] = hIvasDec->st_ivas->hCombinedOrientationData->Quaternions[i];
+ }
+ }
+
+ return IVAS_ERR_OK;
+}
+#endif
+
+
/*---------------------------------------------------------------------*
* IVAS_DEC_VoIP_FeedFrame( )
*
diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h
index 50476c964bda0a25f0e19907be177b64ad6a0533..40e2070d7dade1161ae41eb2d1e88ef2a1e7b2ed 100644
--- a/lib_dec/lib_dec.h
+++ b/lib_dec/lib_dec.h
@@ -487,6 +487,26 @@ ivas_error IVAS_DEC_GetPcmFrameSize(
int32_t *pcmFrameSize /* o : total size of the PCM output frame. This takes into account the number of output channels */
);
+#ifdef FIX_1100_OUTPUT_ORIENT
+/*! r: error code */
+ivas_error IVAS_DEC_GetMainOrientation(
+ IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */
+ IVAS_QUATERNION *pOrientation /* o : Quaternion pointer for main orientation */
+);
+
+/*! r: error code */
+ivas_error IVAS_DEC_GetTrackedRotation(
+ IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */
+ IVAS_QUATERNION *pRotation /* o : Quaternion pointer processed rotation */
+);
+
+/*! r: error code */
+ivas_error IVAS_DEC_GetCombinedOrientation(
+ IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */
+ IVAS_QUATERNION *pOrientation /* o : Quaternion pointer processed orientation */
+);
+#endif
+
/*! r: true if decoder has no data in VoIP jitter buffer */
bool IVAS_DEC_VoIP_IsEmpty(
IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c
index e3538025eca02a194e18b07ae216d5e7a91da5c9..887ec76f14a779e3719012297ad75ea51b0011b1 100644
--- a/lib_rend/lib_rend.c
+++ b/lib_rend/lib_rend.c
@@ -4598,7 +4598,9 @@ ivas_error IVAS_REND_SetReferenceRotation(
*
*
*-------------------------------------------------------------------*/
+#ifndef FIX_1100_OUTPUT_ORIENT
// ToDo: not used
+#endif
ivas_error IVAS_REND_GetMainOrientation(
IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
IVAS_QUATERNION *pOrientation /* i/o: Quaternion pointer for main orientation */
@@ -4625,7 +4627,9 @@ ivas_error IVAS_REND_GetMainOrientation(
*
*
*-------------------------------------------------------------------*/
+#ifndef FIX_1100_OUTPUT_ORIENT
// ToDo: not used
+#endif
ivas_error IVAS_REND_GetTrackedRotation(
IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
IVAS_QUATERNION *pRotation /* i/o: Quaternion pointer processed rotation */
@@ -4733,7 +4737,9 @@ ivas_error IVAS_REND_CombineHeadAndExternalOrientation(
*
*
*---------------------------------------------------------------------*/
+#ifndef FIX_1100_OUTPUT_ORIENT
// ToDo: not used
+#endif
ivas_error IVAS_REND_GetCombinedOrientation(
IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
IVAS_QUATERNION *pOrientation /* i/o: Quaternion pointer processed orientation */
diff --git a/lib_util/quaternion_file_writer.c b/lib_util/quaternion_file_writer.c
new file mode 100644
index 0000000000000000000000000000000000000000..f7d72db12e1e61b7def9d8cc1a9b4e3a412cb363
--- /dev/null
+++ b/lib_util/quaternion_file_writer.c
@@ -0,0 +1,156 @@
+/******************************************************************************************************
+
+ (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 "quaternion_file_writer.h"
+#ifdef FIX_1100_OUTPUT_ORIENT
+#include
+#include
+
+
+#define META_LINE_LENGTH 200 /* max number of characters at one line of metadata input/output file */
+
+
+struct QuaternionFileWriter
+{
+ FILE *file;
+ char *file_path;
+};
+
+/*---------------------------------------------------------------------*
+ * QuaternionFileWriter_open()
+ *
+ * Allocates memory for an QuaternionFileReader and opens the file at given path for writing.
+ *---------------------------------------------------------------------*/
+
+/*! r: error code */
+ivas_error QuaternionFileWriter_open(
+ const char *filePath, /* i : path to output file */
+ QuaternionFileWriter **quatWriter /* o : pointer to QuaternionFileWriter handle */
+)
+{
+ QuaternionFileWriter *self;
+ FILE *file;
+
+ if ( strlen( filePath ) < 1 )
+ {
+ return IVAS_ERR_FAILED_FILE_OPEN;
+ }
+
+ file = fopen( filePath, "w" );
+
+ if ( !file )
+ {
+ return IVAS_ERR_FAILED_FILE_OPEN;
+ }
+
+ self = calloc( sizeof( QuaternionFileWriter ), 1 );
+ self->file = file;
+ self->file_path = calloc( sizeof( char ), strlen( filePath ) + 1 );
+ strcpy( self->file_path, filePath );
+
+ *quatWriter = self;
+
+ return IVAS_ERR_OK;
+}
+
+/*---------------------------------------------------------------------*
+ * QuaternionFileWriter_writeFrame()
+ *
+ * Writes quaternion data into a previously opened file
+ *---------------------------------------------------------------------*/
+
+/*! r: error code */
+ivas_error QuaternionFileWriter_writeFrame(
+ QuaternionFileWriter *quatWriter, /* o : QuaternionFileWriter handle */
+ const IVAS_QUATERNION quatData /* i : Quaternion data */
+)
+{
+ FILE *file;
+
+ if ( quatWriter->file == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ file = quatWriter->file;
+
+ if ( fprintf( file, "%f,%f,%f,%f\n", quatData.w, quatData.x, quatData.y, quatData.z ) <= 0 )
+ {
+ return IVAS_ERR_FAILED_FILE_WRITE;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+
+/*---------------------------------------------------------------------*
+ * QuaternionFileWriter_close()
+ *
+ * De-allocates all underlying memory of an QuaternionFileWriter.
+ *---------------------------------------------------------------------*/
+
+void QuaternionFileWriter_close(
+ QuaternionFileWriter **quatWriter /* i/o: pointer to QuaternionFileWriter handle */
+)
+{
+ if ( quatWriter == NULL || *quatWriter == NULL )
+ {
+ return;
+ }
+
+ fclose( ( *quatWriter )->file );
+ free( ( *quatWriter )->file_path );
+ free( *quatWriter );
+ *quatWriter = NULL;
+
+ return;
+}
+
+
+/*---------------------------------------------------------------------*
+ * IsmFileWriter_getFilePath()
+ *
+ *---------------------------------------------------------------------*/
+
+/*! r: path to the currently opened file or NULL if `ismWriter` is NULL */
+const char *QuaternionFileWriter_getFilePath(
+ QuaternionFileWriter *quatWriter /* i : QuaternionFileWriter handle */
+)
+{
+ if ( quatWriter == NULL )
+ {
+ return NULL;
+ }
+
+ return quatWriter->file_path;
+}
+#endif
diff --git a/lib_util/quaternion_file_writer.h b/lib_util/quaternion_file_writer.h
new file mode 100644
index 0000000000000000000000000000000000000000..b2f1383ec5c22d0bac0cb06582b7ca3e45456643
--- /dev/null
+++ b/lib_util/quaternion_file_writer.h
@@ -0,0 +1,69 @@
+/******************************************************************************************************
+
+ (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_QUATERNION_WRITER_H
+#define IVAS_QUATERNION_WRITER_H
+
+#include "common_api_types.h"
+
+#ifdef FIX_1100_OUTPUT_ORIENT
+
+typedef struct QuaternionFileWriter QuaternionFileWriter;
+
+/* clang-format off */
+
+/*! r: error code */
+ivas_error QuaternionFileWriter_open(
+ const char *filePath, /* i : path to output file */
+ QuaternionFileWriter **quatWriter /* o : pointer to QuaternionFileWriter handle */
+);
+
+/*! r: error code */
+ivas_error QuaternionFileWriter_writeFrame(
+ QuaternionFileWriter *quatWriter, /* o : QuaternionFileWriter handle */
+ const IVAS_QUATERNION quatData /* i : Quaternion data */
+);
+
+void QuaternionFileWriter_close(
+ QuaternionFileWriter **quatWriter /* i/o: pointer to QuaternionFileWriter handle */
+);
+
+/*! r: path to the currently opened file or NULL if `ismWriter` is NULL */
+const char *QuaternionFileWriter_getFilePath(
+ QuaternionFileWriter *quatWriter /* i : QuaternionFileWriter handle */
+);
+
+/* clang-format on */
+
+#endif
+
+#endif /* IVAS_QUATERNION_WRITER_H */
diff --git a/readme.txt b/readme.txt
index e6fbd729ead207359e6e304a12d7ea5f9ff29388..88074516526721b7763b0d27291bf10f9ea8343d 100644
--- a/readme.txt
+++ b/readme.txt
@@ -289,7 +289,7 @@ Options:
Format files, the magic word in the mime file is used to determine
which of the two supported formats is in use.
default bitstream file format is G.192
--fr L : render frame size in ms L=(5,10,20), default is 20
+-fr L : render frame size in ms L=(5,10,20), default is 20
-hrtf File : HRTF filter File used in BINAURAL rendering
-T File : Head rotation specified by external trajectory File
-otr tracking_type : Head orientation tracking type: 'none', 'ref', 'avg', 'ref_vec'