Commit 2df5ead6 authored by bayers's avatar bayers
Browse files

add binaural rotation capability to the VoIP/JBM decoding

parent c4a157ed
Loading
Loading
Loading
Loading
+180 −12
Original line number Diff line number Diff line
@@ -165,7 +165,14 @@ static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotF
                              IVAS_DEC_HANDLE hIvasDec,
                              int16_t *pcmBuf );

static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HANDLE hIvasDec );
static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader,
#ifdef NONBE_UNIFIED_DECODING_PATHS
                              RotFileReader *headRotReader,
                              RotFileReader *externalOrientationFileReader,
                              RotFileReader *refRotReader,
                              Vector3PairFileReader *referenceVectorReader,
#endif
                              IVAS_DEC_HANDLE hIvasDec );
#ifdef DEBUGGING
#ifdef VARIABLE_SPEED_DECODING
static ivas_error decodeVariableSpeed( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec );
@@ -791,7 +798,11 @@ int main(

    if ( arg.voipMode )
    {
        error = decodeVoIP( arg, hBsReader, hIvasDec );
        error = decodeVoIP( arg, hBsReader,
#ifdef NONBE_UNIFIED_DECODING_PATHS
                            headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader,
#endif
                            hIvasDec );
    }
    else
    {
@@ -2214,13 +2225,6 @@ static ivas_error decodeG192(
            }
        }

#ifdef NONBE_UNIFIED_DECODING_PATHS
        if ( arg.enableExternalOrientation )
        {
        }
#endif


        /* decode and get samples */
        nSamplesRendered = 0;
        nSamplesToRender = nOutSamples;
@@ -2828,6 +2832,12 @@ static ivas_error writeJbmTraceFileFrameWrapper( const void *data, void *writer
static ivas_error decodeVoIP(
    DecArguments arg,
    BS_READER_HANDLE hBsReader,
#ifdef NONBE_UNIFIED_DECODING_PATHS
    RotFileReader *headRotReader,
    RotFileReader *externalOrientationFileReader,
    RotFileReader *refRotReader,
    Vector3PairFileReader *referenceVectorReader,
#endif
    IVAS_DEC_HANDLE hIvasDec )
{
    bool decodingFailed = true; /* Assume failure until cleanup is reached without errors */
@@ -2871,8 +2881,36 @@ static ivas_error decodeVoIP(

    IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN;
    IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS];
#ifdef NONBE_UNIFIED_DECODING_PATHS
    IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };
    int16_t vec_pos_update, vec_pos_len, i;
#if defined( SPLIT_REND_WITH_HEAD_ROT )
    uint16_t nOutSamples = 0;
#else
    int16_t nOutSamples = 0;
#endif
#endif

    for ( int16_t i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i )
#ifdef NONBE_UNIFIED_DECODING_PATHS
    vec_pos_update = 0;
    if ( arg.enableHeadRotation && arg.enable5ms )
    {
        nOutSamples = (int16_t) ( arg.output_Fs / 1000 * HEADROTATION_FETCH_FRAMESIZE_MS );
        vec_pos_len = IVAS_MAX_PARAM_SPATIAL_SUBFRAMES;
    }
    else
    {
        nOutSamples = (int16_t) ( arg.output_Fs / 1000 * DEFAULT_FETCH_FRAMESIZE_MS );
        vec_pos_len = 1;
    }
#endif

    for (
#ifndef NONBE_UNIFIED_DECODING_PATHS
        int16_t
#endif
            i = 0;
        i < IVAS_MAX_NUM_OBJECTS; ++i )
    {
        ismWriters[i] = NULL;
    }
@@ -2977,6 +3015,7 @@ static ivas_error decodeVoIP(

    while ( 1 )
    {
#ifndef NONBE_UNIFIED_DECODING_PATHS
#if defined( SPLIT_REND_WITH_HEAD_ROT )
        uint16_t nOutSamples = 0;
#else
@@ -2987,6 +3026,129 @@ static ivas_error decodeVoIP(
#else
        nOutSamples = (int16_t) ( arg.output_Fs / 1000 * JBM_FRONTEND_FETCH_FRAMESIZE_MS );
#endif
#endif

#ifdef NONBE_UNIFIED_DECODING_PATHS
        /* reference vector */
        if ( arg.enableReferenceVectorTracking && vec_pos_update == 0 )
        {
            IVAS_VECTOR3 listenerPosition, referencePosition;
            if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPosition, &referencePosition ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "\nError %s while reading listener and reference positions from %s\n", IVAS_DEC_GetErrorMessage( error ), Vector3PairFileReader_getFilePath( referenceVectorReader ) );
                goto cleanup;
            }

            if ( ( error = IVAS_DEC_FeedRefVectorData( hIvasDec, listenerPosition, referencePosition ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "\nIVAS_DEC_FeedRefVectorData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
                goto cleanup;
            }
        }

        /* Reference rotation */
        if ( arg.enableReferenceRotation && vec_pos_update == 0 )
        {
            IVAS_QUATERNION quaternion;
            if ( ( error = HeadRotationFileReading( refRotReader, &quaternion, NULL ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "\nError %s while reading reference rotation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( refRotReader ) );
                goto cleanup;
            }

            if ( ( error = IVAS_DEC_FeedRefRotData( hIvasDec, quaternion ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "\nIVAS_DEC_FeedRefRotData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
                goto cleanup;
            }
        }
        int16_t enable5ms, num_subframes;
        IVAS_DEC_Get5msFlag( hIvasDec, &enable5ms );
        arg.enable5ms = enable5ms;
        num_subframes = ( arg.enable5ms ) ? 1 : IVAS_MAX_PARAM_SPATIAL_SUBFRAMES;

        /* Head-tracking input simulation */
        /* Head-tracking input simulation */
        if ( arg.enableHeadRotation )
        {
            IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES];

#ifdef SPLIT_REND_WITH_HEAD_ROT
            if ( headRotReader == NULL )
            {
                for ( i = 0; i < num_subframes; i++ )
                {
                    Quaternions[i].w = -3.0f;
                    Quaternions[i].x = 0.0f;
                    Quaternions[i].y = 0.0f;
                    Quaternions[i].z = 0.0f;
                    Pos[i].x = 0.0f;
                    Pos[i].y = 0.0f;
                    Pos[i].z = 0.0f;
                }
            }
            else
            {
#endif
                for ( i = 0; i < num_subframes; i++ )
                {
                    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;
                    }
                }
#ifdef SPLIT_REND_WITH_HEAD_ROT
            }
#endif

            for ( i = 0; i < num_subframes; i++ )
            {
                if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i
#ifdef SPLIT_REND_WITH_HEAD_ROT
                                                           ,
                                                           DEFAULT_AXIS
#endif
                                                           ) ) != IVAS_ERR_OK )
                {
                    fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
                    goto cleanup;
                }
            }
        }
        
        if ( arg.enableExternalOrientation )
        {
            IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES];
            int8_t enableHeadRotation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES];
            int8_t enableExternalOrientation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES];
            int8_t enableRotationInterpolation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES];
            int16_t numFramesToTargetOrientation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES];

            for ( i = 0; i < num_subframes; i++ )
            {

                if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &Quaternions[i], &enableHeadRotation[i], &enableExternalOrientation[i], &enableRotationInterpolation[i], &numFramesToTargetOrientation[i] ) ) != IVAS_ERR_OK )
                {
                    fprintf( stderr, "\nError %s while reading external orientation from %s\n", IVAS_DEC_GetErrorMessage( error ),
                             RotationFileReader_getFilePath( externalOrientationFileReader ) );
                    goto cleanup;
                }
            }
            for ( i = 0; i < num_subframes; i++ )
            {
                if ( ( error = IVAS_DEC_FeedExternalOrientationData( hIvasDec, Quaternions[i], enableHeadRotation[i], enableExternalOrientation[i], enableRotationInterpolation[i], numFramesToTargetOrientation[i], i ) ) != IVAS_ERR_OK )
                {
                    fprintf( stderr, "\nIVAS_DEC_FeedExternalOrientationData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
                    goto cleanup;
                }
            }
        }

#endif


        /* read all packets with a receive time smaller than the system time */
        while ( nextPacketRcvTime_ms <= systemTime_ms )
        {
@@ -3151,8 +3313,9 @@ static ivas_error decodeVoIP(
            /* Write ISM metadata to external file(s) */
            if ( decodedGoodFrame && arg.outputConfig == AUDIO_CONFIG_EXTERNAL )
            {
#ifndef NONBE_UNIFIED_DECODING_PATHS
                int16_t i;

#endif
                if ( bsFormat == IVAS_DEC_BS_OBJ || bsFormat == IVAS_DEC_BS_MASA_ISM )
                {
                    if ( ( error = IVAS_DEC_GetNumObjects( hIvasDec, &numObj ) ) != IVAS_ERR_OK )
@@ -3252,7 +3415,12 @@ cleanup:
    JbmTraceFileWriter_close( &jbmTraceWriter );
#endif
    MasaFileWriter_close( &masaWriter );
    for ( int16_t i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ )
    for (
#ifndef NONBE_UNIFIED_DECODING_PATHS
        int16_t
#endif
            i = 0;
        i < IVAS_MAX_NUM_OBJECTS; i++ )
    {
        IsmFileWriter_close( &ismWriters[i] );
    }