Commit c00ed89b authored by hsd's avatar hsd
Browse files

merged latest 109-harmonize-head-and-orientation-tracking

parents 2bf733f4 1d5f21f5
Loading
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ workflow:
    # see https://docs.gitlab.com/ee/ci/yaml/workflow.html#switch-between-branch-pipelines-and-merge-request-pipelines
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
      when: never
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event' # Runs for merge requests
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
    - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Pushes to main
    - if: $CI_PIPELINE_SOURCE == 'schedule' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Scheduled in main
    - if: $CI_PIPELINE_SOURCE == 'web' # for testing
@@ -130,7 +130,7 @@ stages:
.rules-merge-request:
  extends: .rules-basis
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" # only have MR pipelines for MRs to main
    - if: $CI_PIPELINE_SOURCE == 'push'
      when: never

+7 −9
Original line number Diff line number Diff line
@@ -112,45 +112,42 @@ project(stereo-evs)
set_property(GLOBAL PROPERTY USE_FOLDERS ON) # make Visual Studio projects look nicer
include(CTest)

include_directories(
  lib_com
  lib_debug
  lib_dec
  lib_enc
  lib_rend
  lib_util
)

file(GLOB libComSrcs "lib_com/*.c")
file(GLOB libComHeaders "lib_com/*.h")
add_library(lib_com ${libComSrcs} ${libComHeaders})
if(UNIX)
  target_link_libraries(lib_com m)
endif()
target_include_directories(lib_com PUBLIC lib_com PRIVATE lib_enc lib_dec lib_rend lib_debug)

file(GLOB libDebugSrcs "lib_debug/*.c")
file(GLOB libDebugHeaders "lib_debug/*.h")
add_library(lib_debug ${libDebugSrcs} ${libDebugHeaders})
target_link_libraries(lib_debug lib_com)
target_include_directories(lib_debug PUBLIC lib_debug PRIVATE lib_enc lib_dec lib_rend)

file(GLOB libEncSrcs "lib_enc/*.c")
file(GLOB libEncHeaders "lib_enc/*.h")
add_library(lib_enc ${libEncSrcs} ${libEncHeaders})
target_link_libraries(lib_enc lib_com lib_debug)
target_include_directories(lib_enc PUBLIC lib_enc PRIVATE lib_dec lib_rend)

file(GLOB libRendSrcs "lib_rend/*.c")
file(GLOB libRendHeaders "lib_rend/*.h")
add_library(lib_rend ${libRendSrcs} ${libRendHeaders})
target_link_libraries(lib_rend lib_dec lib_com lib_debug) # Todo refactor: This dependency on lib_dec should be removed.
target_include_directories(lib_rend PUBLIC lib_rend PRIVATE lib_enc)

file(GLOB libDecSrcs "lib_dec/*.c")
file(GLOB libDecHeaders "lib_dec/*.h")
add_library(lib_dec ${libDecSrcs} ${libDecHeaders})
target_link_libraries(lib_dec lib_com lib_rend lib_debug)
target_include_directories(lib_dec PUBLIC lib_dec lib_rend PRIVATE lib_enc)

file(GLOB libUtilSrcs "lib_util/*.c")
file(GLOB libUtilHeaders "lib_util/*.h")
add_library(lib_util ${libUtilSrcs} ${libUtilHeaders})
target_include_directories(lib_util PUBLIC lib_util PRIVATE lib_com lib_enc lib_dec lib_rend lib_debug)

add_executable(IVAS_cod apps/encoder.c)
target_link_libraries(IVAS_cod lib_enc lib_util)
@@ -166,6 +163,7 @@ endif()

add_executable(IVAS_rend apps/renderer.c)
target_link_libraries(IVAS_rend lib_rend lib_util)
target_include_directories(IVAS_rend PRIVATE lib_enc)

if(COPY_EXECUTABLES_FROM_BUILD_DIR)
  # Optionally copy executables to the same place where Make puts them (useful for tests that expect executables in specific places)
+118 −13
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "options.h"
#include "lib_dec.h"
#include "cmdl_tools.h"
#include "audio_file_writer.h"
@@ -257,8 +256,21 @@ int main(

    if ( arg.hrtfReaderEnabled )
    {
#ifdef FIX_351_HRTF_COMMAND
        /* sanity check */
        if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM )
        {
            arg.hrtfReaderEnabled = false;
            fprintf( stderr, "\nError: HRTF binary file cannot be used in this output configuration.\n\n" );
            goto cleanup;
        }
#endif

        if ( ( error = hrtfFileReader_open( arg.hrtfFileName, &hrtfReader ) ) != IVAS_ERR_OK )
        {
#ifdef FIX_351_HRTF_COMMAND
            arg.hrtfReaderEnabled = false;
#endif
            fprintf( stderr, "\nError: Can't open HRTF binary file %s \n\n", arg.hrtfFileName );
            goto cleanup;
        }
@@ -270,6 +282,15 @@ int main(

    if ( arg.enableHeadRotation )
    {
#ifdef FIX_351_HRTF_COMMAND
        /* sanity check */
        if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM )
        {
            fprintf( stderr, "\nError: Head-rotation file file cannot be used in this output configuration.\n\n" );
            goto cleanup;
        }
#endif

        if ( ( error = HeadRotationFileReader_open( arg.headrotTrajFileName, &headRotReader ) ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "\nError: Can't open head-rotation file %s \n\n", arg.headrotTrajFileName );
@@ -323,6 +344,15 @@ int main(

    if ( arg.renderConfigEnabled )
    {
#ifdef FIX_351_HRTF_COMMAND
        /* sanity check */
        if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM )
        {
            fprintf( stderr, "\nError: Renderer configuration file cannot be used in this output configuration.\n\n" );
            goto cleanup;
        }
#endif

        if ( ( error = RenderConfigReader_open( arg.renderConfigFilename, &renderConfigReader ) ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "\nError: Can't open Renderer configuration file %s \n\n", arg.renderConfigFilename );
@@ -335,13 +365,21 @@ int main(
     *------------------------------------------------------------------------------------------*/

#ifdef REMOVE_FORCE_SUBFRAME_BIN
    if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation ) ) != IVAS_ERR_OK )
    if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.renderConfigEnabled ) ) != IVAS_ERR_OK )
#else
#ifdef DEBUGGING
#ifdef FIX_351_HRTF_COMMAND
    if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.renderConfigEnabled, arg.forceSubframeBinauralization ) ) != IVAS_ERR_OK )
#else
    if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.forceSubframeBinauralization ) ) != IVAS_ERR_OK )
#endif
#else
#ifdef FIX_351_HRTF_COMMAND
    if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.renderConfigEnabled ) ) != IVAS_ERR_OK )
#else
    if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation ) ) != IVAS_ERR_OK )
#endif
#endif
#endif
    {
        fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) );
@@ -518,9 +556,7 @@ int main(
        if ( ( error = create_SetOfHRTF_from_binary( hSetOfHRTF, hrtfReader, arg.output_Fs ) ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "\nError in loading HRTF binary file %s for CRend \n\n", arg.hrtfCRendFileName );
#ifndef FIX_FOR_TEST
            goto cleanup;
#endif
        }
        IVAS_DEC_HRTF_FASTCONV_HANDLE hHrtfFastConv;
        IVAS_DEC_GetHrtfFastConvHandle( hIvasDec, &hHrtfFastConv );
@@ -605,6 +641,7 @@ cleanup:
#ifdef DEBUG_SBA_AUDIO_DUMP
    IVAS_DEC_GetSbaDebugParams( hIvasDec, &numOutChannels, &numTransportChannels, &pca_ingest_channels );
#endif

    if ( arg.hrtfReaderEnabled )
    {
        IVAS_DEC_HRTF_HANDLE hHrtfTD;
@@ -1301,9 +1338,17 @@ static ivas_error initOnFirstGoodFrame(
    }
    else
    {
#ifdef BINAURALIZATION_DELAY_REPORT
        pFullDelayNumSamples[0] = 0;
#else
        *pFullDelayNumSamples = 0;
#endif
    }
#ifdef BINAURALIZATION_DELAY_REPORT
    *pRemainingDelayNumSamples = pFullDelayNumSamples[0];
#else
    *pRemainingDelayNumSamples = *pFullDelayNumSamples;
#endif

    if ( ( error = IVAS_DEC_GetNumOutputChannels( hIvasDec, pNumOutChannels ) ) != IVAS_ERR_OK )
    {
@@ -1460,7 +1505,11 @@ static ivas_error decodeG192(
    int16_t numInitialBadFrames = 0; /* Number of bad frames received until first good frame is decoded */
    int16_t nOutChannels = 0;
    int16_t delayNumSamples = -1;
#ifdef BINAURALIZATION_DELAY_REPORT
    int16_t delayNumSamples_orig[3]; /* stores: overall delay, dec+rend delay, and binauralization delay */
#else
    int16_t delayNumSamples_orig = 0;
#endif
    int16_t nOutSamples = 0;
    int32_t delayTimeScale = 0;
    ivas_error error = IVAS_ERR_UNKNOWN;
@@ -1483,6 +1532,10 @@ static ivas_error decodeG192(
        fprintf( stdout, "\n-- Start the decoder (quiet mode) --\n\n" );
    }

#ifdef BINAURALIZATION_DELAY_REPORT
    delayNumSamples_orig[0] = -1;
#endif

#ifdef WMOPS
    reset_stack();
    reset_wmops();
@@ -1620,7 +1673,11 @@ static ivas_error decodeG192(
                    arg,
                    numInitialBadFrames,
                    nOutSamples,
#ifdef BINAURALIZATION_DELAY_REPORT
                    delayNumSamples_orig,
#else
                    &delayNumSamples_orig,
#endif
                    &delayNumSamples,
                    &delayTimeScale,
                    &bsFormat,
@@ -1721,13 +1778,39 @@ static ivas_error decodeG192(
#endif
    }

    /*------------------------------------------------------------------------------------------*
     * Add zeros at the end to have equal length of synthesized signals
     *------------------------------------------------------------------------------------------*/

#ifdef BINAURALIZATION_DELAY_REPORT
    memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) );
    if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK )
#else
    memset( pcmBuf, 0, delayNumSamples_orig * nOutChannels * sizeof( int16_t ) );
    if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig * nOutChannels ) ) != IVAS_ERR_OK )
#endif
    {
        fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) );
        goto cleanup;
    }

    /*------------------------------------------------------------------------------------------*
     * Printouts after decoding has finished
     *------------------------------------------------------------------------------------------*/

    if ( !arg.quietModeEnabled )
    {
#ifdef BINAURALIZATION_DELAY_REPORT
        printf( "\n\nDecoder+renderer delay: %4.2f ms   (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[1] / (float) delayTimeScale, delayNumSamples_orig[1], delayTimeScale );

        if ( delayNumSamples_orig[2] > 0 )
        {
            printf( "HRIR/BRIR delay:        %4.2f ms   (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[2] / (float) delayTimeScale, delayNumSamples_orig[2], delayTimeScale );
            printf( "Total delay:            %4.2f ms   (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[0] / (float) delayTimeScale, delayNumSamples_orig[0], delayTimeScale );
        }
#else
        fprintf( stdout, "\nDecoder delay:          %-5u [samples]  - Timescale: %5u\n", delayNumSamples_orig, delayTimeScale );
#endif
    }

    /* Print output metadata file name(s) */
@@ -1747,14 +1830,6 @@ static ivas_error decodeG192(
        }
    }

    /* add zeros at the end to have equal length of synthesized signals */
    memset( pcmBuf, 0, delayNumSamples_orig * nOutChannels * sizeof( int16_t ) );
    if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig * nOutChannels ) ) != IVAS_ERR_OK )
    {
        fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) );
        goto cleanup;
    }

    /*------------------------------------------------------------------------------------------*
     * Close files and deallocate resources
     *------------------------------------------------------------------------------------------*/
@@ -1924,7 +1999,11 @@ static ivas_error decodeVoIP(
#endif
    JbmOffsetFileWriter *jbmOffsetWriter = NULL;

#ifdef BINAURALIZATION_DELAY_REPORT
    int16_t delayNumSamples_orig[3]; /* stores: overall delay, dec+rend delay, and binauralization delay */
#else
    int16_t delayNumSamples_orig = -1;
#endif
    int16_t delayNumSamples = -1;
    int32_t delayTimeScale = -1;

@@ -1938,11 +2017,15 @@ static ivas_error decodeVoIP(

    IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN;
    IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS];

    for ( int16_t i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i )
    {
        ismWriters[i] = NULL;
    }

#ifdef BINAURALIZATION_DELAY_REPORT
    delayNumSamples_orig[0] = -1;
#endif

    rtpdumpDepacker.rtpdump = NULL;
    switch ( arg.inputFormat )
@@ -2139,7 +2222,11 @@ static ivas_error decodeVoIP(
                    arg,
                    numInitialBadFrames,
                    nOutSamples,
#ifdef BINAURALIZATION_DELAY_REPORT
                    delayNumSamples_orig,
#else
                    &delayNumSamples_orig,
#endif
                    &delayNumSamples,
                    &delayTimeScale,
                    &bsFormat,
@@ -2192,9 +2279,17 @@ static ivas_error decodeVoIP(
#endif
    }

    /* add zeros at the end to have equal length of synthesized signals */
    /*------------------------------------------------------------------------------------------*
     * Add zeros at the end to have equal length of synthesized signals
     *------------------------------------------------------------------------------------------*/

#ifdef BINAURALIZATION_DELAY_REPORT
    memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) );
    if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK )
#else
    memset( pcmBuf, 0, delayNumSamples_orig * nOutChannels * sizeof( int16_t ) );
    if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig * nOutChannels ) ) != IVAS_ERR_OK )
#endif
    {
        fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) );
        goto cleanup;
@@ -2206,7 +2301,17 @@ static ivas_error decodeVoIP(

    if ( !arg.quietModeEnabled )
    {
#ifdef BINAURALIZATION_DELAY_REPORT
        printf( "\n\nDecoder+renderer delay: %4.2f ms   (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[1] / (float) delayTimeScale, delayNumSamples_orig[1], delayTimeScale );

        if ( delayNumSamples_orig[2] > 0 )
        {
            printf( "HRIR/BRIR delay:        %4.2f ms   (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[2] / (float) delayTimeScale, delayNumSamples_orig[2], delayTimeScale );
            printf( "Total delay:            %4.2f ms   (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[0] / (float) delayTimeScale, delayNumSamples_orig[0], delayTimeScale );
        }
#else
        printf( "\nDecoder delay:       %5u [samples]  - Timescale: %5u\n", delayNumSamples_orig, delayTimeScale );
#endif
    }

    /*------------------------------------------------------------------------------------------*
+63 −1
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "options.h"
#include "lib_enc.h"
#include "cmdl_tools.h"
#include "audio_file_reader.h"
@@ -214,6 +213,7 @@ int main(
        goto cleanup;
    }

#ifndef FIX_94_VERIFY_WAV_NUM_CHANNELS
    /*------------------------------------------------------------------------------------------*
     * Open input audio file
     *------------------------------------------------------------------------------------------*/
@@ -229,6 +229,7 @@ int main(
        fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", arg.inputFs, inFileSampleRate, arg.inputWavFilename );
        goto cleanup;
    }
#endif

    /*------------------------------------------------------------------------------------------*
     * Open output bitstream file
@@ -451,6 +452,67 @@ int main(
        goto cleanup;
    }

#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS
    /*------------------------------------------------------------------------------------------*
     * Open input audio file
     *------------------------------------------------------------------------------------------*/

    if ( AudioFileReader_open( &audioReader, arg.inputWavFilename ) != IVAS_ERR_OK )
    {
        fprintf( stderr, "\nCan't open %s\n\n", arg.inputWavFilename );
        goto cleanup;
    }

    /* Validate input sampling rate */
    int32_t inFileSampleRate = 0;
    error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate );
    switch ( error )
    {
        case IVAS_ERR_OK:
            if ( inFileSampleRate != arg.inputFs )
            {
                fprintf( stderr, "\nSampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n\n", arg.inputFs, inFileSampleRate, arg.inputWavFilename );
                goto cleanup;
            }
            break;
        case IVAS_ERR_SAMPLING_RATE_UNKNOWN:
            /* IVAS_ERR_SAMPLING_RATE_UNKNOWN will be returned for raw PCM files.
             * Nothing to check here */
            break;
        default:
            fprintf( stderr, "\nError: %s\n", ivas_error_to_string( error ) );
            goto cleanup;
    }


    /* Validate number of channels */
    int16_t encInNumChannels = 0;
    if ( ( error = IVAS_ENC_GetNumInChannels( hIvasEnc, &encInNumChannels ) ) != IVAS_ERR_OK )
    {
        fprintf( stderr, "\nError: %s\n", ivas_error_to_string( error ) );
        goto cleanup;
    }
    int16_t inFileNumChannels = 0;
    error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels );
    switch ( error )
    {
        case IVAS_ERR_OK:
            if ( inFileNumChannels != encInNumChannels )
            {
                fprintf( stderr, "\nNumber of input audio channels mismatch: %d accepted by encoder, but %d found in file %s\n\n", encInNumChannels, inFileNumChannels, arg.inputWavFilename );
                goto cleanup;
            }
            break;
        case IVAS_ERR_NUM_CHANNELS_UNKNOWN:
            /* IVAS_ERR_NUM_CHANNELS_UNKNOWN will be returned for raw PCM files.
             * Nothing to check here */
            break;
        default:
            fprintf( stderr, "\nError: %s\n", ivas_error_to_string( error ) );
            goto cleanup;
    }
#endif

    /*------------------------------------------------------------------------------------------*
     * Open input metadata files
     *------------------------------------------------------------------------------------------*/
+83 −11
Original line number Diff line number Diff line
@@ -30,26 +30,23 @@

*******************************************************************************************************/

#include "lib_rend.h"
#include <assert.h>
#include <ctype.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "options.h"
#include "audio_file_reader.h"
#include "audio_file_writer.h"
#include "cmdl_tools.h"
#include "cmdln_parser.h"
#include "common_api_types.h"
#include "head_rotation_file_reader.h"
#ifdef OTR_REFERENCE_VECTOR_TRACKING
#include "vector3_pair_file_reader.h"
#endif /* OTR_REFERENCE_VECTOR_TRACKING */
#include "hrtf_file_reader.h"
#include "ism_file_reader.h"
#include "lib_rend.h"
#include "ls_custom_file_reader.h"
#include "masa_file_reader.h"
#include "prot.h"
@@ -655,6 +652,51 @@ int main(
        setupWithSingleFormatInput( args, audioFilePath, positionProvider, masaReaders );
    }

#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS
    if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK )
    {
        fprintf( stderr, "Error opening file: %s\n", audioFilePath );
        exit( -1 );
    }

    int32_t inFileSampleRate = 0;
    error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate );
    switch ( error )
    {
        case IVAS_ERR_OK:
            /* If sampling rate not given on command line, use the one from wav file */
            if ( args.sampleRate == 0 )
            {
                args.sampleRate = inFileSampleRate;
            }
            /* else if sampling rate given on command line, compare with wav file */
            else if ( inFileSampleRate != args.sampleRate )
            {
                fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", args.sampleRate, inFileSampleRate, args.inputFilePath );
                exit( -1 );
            }
            break;
        case IVAS_ERR_SAMPLING_RATE_UNKNOWN: /* Returned when input is raw PCM */
            if ( args.sampleRate == 0 )
            {
                fprintf( stderr, "Sampling rate must be specified on command line when using raw PCM input\n" );
                exit( -1 );
            }
            args.sampleRate = inFileSampleRate;
            break;
        default:
            fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
            exit( -1 );
    }

    int16_t inFileNumChannels = 0;
    error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels );
    if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN )
    {
        fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
        exit( -1 );
    }
#else
    int32_t inFileSampleRate = 0;
    if ( AudioFileReader_open( &audioReader, audioFilePath, &inFileSampleRate ) != IVAS_ERR_OK )
    {
@@ -675,6 +717,7 @@ int main(
    {
        args.sampleRate = inFileSampleRate;
    }
#endif
    const int16_t frameSize_smpls = (int16_t) ( 20 * args.sampleRate / 1000 );

    IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS] = { 0 };
@@ -691,6 +734,7 @@ int main(
    /* === Configure === */
    if ( ( error = IVAS_REND_InitConfig( hIvasRend, strlen( args.renderConfigFilePath ) != 0 ) ) != IVAS_ERR_OK )
    {
        fprintf( stderr, "Error in Renderer Config Init\n" );
        exit( -1 );
    }

@@ -849,8 +893,12 @@ int main(

    const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds, masaIds );

#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS
    if ( inFileNumChannels != 0 /* inFileNumChannels is 0 with raw PCM input */ && totalNumInChannels != inFileNumChannels )
#else
    if ( AudioFileReader_getNumChannels( audioReader ) != 0 /* If input file is raw PCM, audio reader has no info about number of channels */
         && totalNumInChannels != AudioFileReader_getNumChannels( audioReader ) )
#endif
    {
        fprintf( stderr, "Number of channels in input file does not match selected configuration\n" );
        exit( -1 );
@@ -898,7 +946,7 @@ int main(

    if ( !args.quietModeEnabled )
    {
        fprintf( stdout, "\n------ Running the renderer ------\n\n" );
        fprintf( stdout, "\n------ Running the rondoror ------\n\n" );
        fprintf( stdout, "Frames processed:       " );
    }
    else
@@ -938,16 +986,28 @@ int main(
#ifdef FIX_I109_ORIENTATION_TRACKING
            for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ )
            {
                HeadRotationFileReading( headRotReader, &quatBuffer[i] );
                if ( HeadRotationFileReading( headRotReader, &quatBuffer[i] ) != IVAS_ERR_OK )
                {
                    fprintf( stderr, "Error in Head Rotation File Reading.\r\n" );
                    exit( -1 );
                }
            }
#else
            HeadRotationFileReading( headRotReader, quatBuffer, frame );
#endif
            IVAS_REND_SetHeadRotation( hIvasRend, quatBuffer );
            if ( IVAS_REND_SetHeadRotation( hIvasRend, quatBuffer ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "Error setting Head Rotation\n" );
                exit( -1 );
            }
        }
        else
        {
            IVAS_REND_SetHeadRotation( hIvasRend, NULL );
            if ( ( IVAS_REND_SetHeadRotation( hIvasRend, NULL ) != IVAS_ERR_OK ) && ( IVAS_REND_SetHeadRotation( hIvasRend, NULL ) != IVAS_ERR_INVALID_OUTPUT_FORMAT ) )
            {
                fprintf( stderr, "Error setting Head Rotation\n" );
                exit( -1 );
            }
        }

#ifdef FIX_I109_ORIENTATION_TRACKING
@@ -971,8 +1031,16 @@ int main(
        if ( referenceRotReader != NULL )
        {
            IVAS_QUATERNION quaternion;
            HeadRotationFileReading( referenceRotReader, &quaternion );
            IVAS_REND_SetReferenceRotation( hIvasRend, quaternion );
            if ( HeadRotationFileReading( referenceRotReader, &quaternion ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "Error in Head Rotation File Reading.\r\n" );
                exit( -1 );
            }
            if ( IVAS_REND_SetReferenceRotation( hIvasRend, quaternion ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "Error setting Reference Rotation.\r\n" );
                exit( -1 );
            }
        }
#endif

@@ -1053,7 +1121,11 @@ int main(
            }
        }

        IVAS_REND_GetSamples( hIvasRend, outBuffer );
        if ( IVAS_REND_GetSamples( hIvasRend, outBuffer ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "Error in getting samples\n" );
            exit( -1 );
        }

        int16_t num_out_channels;
        num_out_channels = outBuffer.config.numChannels;
Loading