Commit d189a905 authored by Lauros Pajunen's avatar Lauros Pajunen
Browse files

Add external output to PI data

parent cad37be1
Loading
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -2950,7 +2950,7 @@ static ivas_error printBitstreamInfoVoip(
        case IVAS_DEC_INPUT_FORMAT_RTPDUMP:
        case IVAS_DEC_INPUT_FORMAT_RTPDUMP_HF:
#ifdef IVAS_RTPDUMP
            if ( ( error = IVAS_RTP_READER_Init( &ivasRtp, arg.inputBitstreamFilename, arg.piOutputFilename ) ) != IVAS_ERR_OK )
            if ( ( error = IVAS_RTP_READER_Init( &ivasRtp, arg.inputBitstreamFilename, arg.piOutputFilename, arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL, arg.outputWavFilename ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "error in IVAS_RTP_READER_Init(): %d\n", error );
                goto cleanup;
@@ -3178,7 +3178,7 @@ static ivas_error decodeVoIP(
        case IVAS_DEC_INPUT_FORMAT_RTPDUMP:
        case IVAS_DEC_INPUT_FORMAT_RTPDUMP_HF:
#ifdef IVAS_RTPDUMP
            if ( ( error = IVAS_RTP_READER_Init( &ivasRtp, arg.inputBitstreamFilename, arg.piOutputFilename ) ) != IVAS_ERR_OK )
            if ( ( error = IVAS_RTP_READER_Init( &ivasRtp, arg.inputBitstreamFilename, arg.piOutputFilename, arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL, arg.outputWavFilename ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "error in IVAS_RTP_READER_Init(): %d\n", error );
                goto cleanup;
@@ -3706,6 +3706,8 @@ static ivas_error decodeVoIP(
                        goto cleanup;
                    }
                }

                IVAS_RTP_WriteExtPiData( ivasRtp.f_piExtOut, ivasRtp.piData, ivasRtp.nReadPiData, numObj );
            }
        }

@@ -3806,6 +3808,8 @@ static ivas_error decodeVoIP(
                    goto cleanup;
                }
            }

            IVAS_RTP_WriteExtPiData( ivasRtp.f_piExtOut, ivasRtp.piData, ivasRtp.nReadPiData, numObj );
        }
    }

@@ -3859,6 +3863,8 @@ static ivas_error decodeVoIP(
        {
            fprintf( stdout, "\nOutput MASA metadata file:   %s\n", MasaFileWriter_getFilePath( masaWriter ) );
        }

        fprintf( stdout, "\nOutput PI data file:   %s\n", IVAS_RTP_GetExtPiFilePath( &ivasRtp ) );
    }

    /*------------------------------------------------------------------------------------------*
+282 −1
Original line number Diff line number Diff line
@@ -337,6 +337,258 @@ void IVAS_RTP_LogPiData(
    fprintf( f_piDataOut, "\n\t}" );
}

void IVAS_RTP_WriteExtPiData(
    FILE *f_piDataOut,       /* i/o : Output csv file handle to dump PI data for external output         */
    const PIDATA_TS *piData, /* i   : PI Data + Timestamp array containing all PI data in current packet */
    uint32_t nPiDataPresent, /* i   : Number of valid elements in the piData array                       */
    uint16_t numObj          /* i   : Number of objects                                                  */
)
{
    if ( f_piDataOut == NULL || piData == NULL || nPiDataPresent == 0 )
    {
        return;
    }

    int i = 0;

    while ( nPiDataPresent-- > 0 )
    {
        const PIDATA_TS *cur = piData++;

        /* The writing follows the pattern of: timestamp, PI DATA TYPE, PI DATA */

        fprintf( f_piDataOut, "%d,%s,", cur->timestamp, PiDataNames[cur->data.noPiData.piDataType] );
        switch ( cur->data.noPiData.piDataType )
        {
            case IVAS_PI_SCENE_ORIENTATION:
            {
                fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.scene.orientation.w, cur->data.scene.orientation.x, cur->data.scene.orientation.y, cur->data.scene.orientation.z );
            }
            break;
            case IVAS_PI_DEVICE_ORIENTATION_COMPENSATED:
            {
                fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.deviceCompensated.orientation.w, cur->data.deviceCompensated.orientation.x, cur->data.deviceCompensated.orientation.y, cur->data.deviceCompensated.orientation.z );
            }
            break;
            case IVAS_PI_DEVICE_ORIENTATION_UNCOMPENSATED:
            {
                fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.deviceUnCompensated.orientation.w, cur->data.deviceUnCompensated.orientation.x, cur->data.deviceUnCompensated.orientation.y, cur->data.deviceUnCompensated.orientation.z );
            }
            break;
#ifdef RTP_S4_251135_CR26253_0016_REV1
            case IVAS_PI_PLAYBACK_DEVICE_ORIENTATION:
            {
                fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.playbackOrientation.orientation.w, cur->data.playbackOrientation.orientation.x, cur->data.playbackOrientation.orientation.y, cur->data.playbackOrientation.orientation.z );
            }
            break;
            case IVAS_PI_HEAD_ORIENTATION:
            {
                fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.headOrientation.orientation.w, cur->data.headOrientation.orientation.x, cur->data.headOrientation.orientation.y, cur->data.headOrientation.orientation.z );
            }
            break;
#endif
            case IVAS_PI_ACOUSTIC_ENVIRONMENT:
            {
                fprintf( f_piDataOut, "%d", cur->data.acousticEnv.aeid );
                if ( cur->data.acousticEnv.availLateReverb )
                {
                    fprintf( f_piDataOut, ",%f,%f,%f", cur->data.acousticEnv.rt60[0], cur->data.acousticEnv.rt60[1], cur->data.acousticEnv.rt60[2] );
                    fprintf( f_piDataOut, ",%f,%f,%f", cur->data.acousticEnv.dsr[0], cur->data.acousticEnv.dsr[1], cur->data.acousticEnv.dsr[2] );
                }
                if ( cur->data.acousticEnv.availEarlyReflections )
                {
                    fprintf( f_piDataOut, ",%f,%f,%f", cur->data.acousticEnv.roomDimensions.x, cur->data.acousticEnv.roomDimensions.y, cur->data.acousticEnv.roomDimensions.z );
                    fprintf( f_piDataOut, ",%f,%f,%f,%f,%f,%f", cur->data.acousticEnv.absorbCoeffs[0], cur->data.acousticEnv.absorbCoeffs[1], cur->data.acousticEnv.absorbCoeffs[2], cur->data.acousticEnv.absorbCoeffs[3], cur->data.acousticEnv.absorbCoeffs[4], cur->data.acousticEnv.absorbCoeffs[5] );
                }
            }
            break;
#ifdef RTP_S4_251135_CR26253_0016_REV1
            case IVAS_PI_LISTENER_POSITION:
            {
                fprintf( f_piDataOut, "%f,%f,%f", cur->data.listnerPosition.position.x, cur->data.listnerPosition.position.y, cur->data.listnerPosition.position.z );
            }
            break;
            case IVAS_PI_AUDIO_DESCRIPTION:
            {
                uint32_t nEntries = cur->data.audioDesc.nValidEntries;
                const IVAS_AUDIO_ID *audioId = cur->data.audioDesc.audioId;

                while ( nEntries-- > 0 )
                {
                    fprintf( f_piDataOut, "%d,%d,%d,%d,%d", audioId->speech, audioId->music, audioId->ambiance, audioId->editable, audioId->binaural );
                    audioId++;
                }
            }
            break;
            case IVAS_PI_DIEGETIC_TYPE:
            {
                const bool *isDiegetic = cur->data.digeticIndicator.isDiegetic;
                fprintf( f_piDataOut, "%d,%d,%d,%d,%d", isDiegetic[0], isDiegetic[1], isDiegetic[2], isDiegetic[3], isDiegetic[4] );
            }
            break;
            case IVAS_PI_AUDIO_FOCUS_INDICATION:
            {
                if ( cur->data.focusIndication.availDirection )
                {
                    fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.focusIndication.direction.w, cur->data.focusIndication.direction.x, cur->data.focusIndication.direction.y, cur->data.focusIndication.direction.z );
                    if ( cur->data.focusIndication.availLevel )
                    {
                        fprintf( f_piDataOut, "," );
                    }
                }
                if ( cur->data.focusIndication.availLevel )
                {
                    fprintf( f_piDataOut, "%d", cur->data.focusIndication.flvl );
                }
            }
            break;
            case IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION:
            {
                const IVAS_PIDATA_DYNAMIC_SUPPRESSION *das = &cur->data.dynSuppression;
                fprintf( f_piDataOut, "%d,%d,%d,%d", das->speech, das->music, das->ambiance, das->sli );
            }
            break;
            case IVAS_PI_RESERVED13:
            case IVAS_PI_AUDIO_FOCUS_REQUEST:
            {

                if ( cur->data.focusRequest.availDirection )
                {
                    fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.focusRequest.direction.w, cur->data.focusRequest.direction.x, cur->data.focusRequest.direction.y, cur->data.focusRequest.direction.z );
                    if ( cur->data.focusRequest.availLevel )
                    {
                        fprintf( f_piDataOut, "," );
                    }
                }
                if ( cur->data.focusRequest.availLevel )
                {
                    fprintf( f_piDataOut, "%d", cur->data.focusRequest.flvl );
                }
            }
            break;
            case IVAS_PI_RESERVED15:
            case IVAS_PI_RESERVED27:
            case IVAS_PI_RESERVED28:
            case IVAS_PI_RESERVED29:
            case IVAS_PI_RESERVED30:
            case IVAS_PI_ISM_NUM:
            {
                fprintf( f_piDataOut, "%d", cur->data.ismNum.numObjects );
            }
            break;
            case IVAS_PI_ISM_ID:
            {
                for ( i = 0; i < numObj; ++i )
                {
                    if ( i != 0 )
                    {
                        fprintf( f_piDataOut, "," );
                    }
                    fprintf( f_piDataOut, "%d", cur->data.ismId.id[i] );
                }
            }
            break;
            case IVAS_PI_ISM_GAIN:
            {
                for ( i = 0; i < numObj; ++i )
                {
                    if ( i != 0 )
                    {
                        fprintf( f_piDataOut, "," );
                    }
                    fprintf( f_piDataOut, "%d", cur->data.ismGain.dB[i] );
                }
            }
            break;
            case IVAS_PI_ISM_ORIENTATION:
            {
                for ( i = 0; i < numObj; ++i )
                {
                    if ( i != 0 )
                    {
                        fprintf( f_piDataOut, "," );
                    }
                    fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.ismOrientation.orientation[i].w, cur->data.ismOrientation.orientation[i].x, cur->data.ismOrientation.orientation[i].y, cur->data.ismOrientation.orientation[i].z );
                }
            }
            break;
            case IVAS_PI_ISM_POSITION:
            {
                for ( i = 0; i < numObj; ++i )
                {
                    if ( i != 0 )
                    {
                        fprintf( f_piDataOut, "," );
                    }
                    fprintf( f_piDataOut, "%f,%f,%f", cur->data.ismPosition.position[i].x, cur->data.ismPosition.position[i].y, cur->data.ismPosition.position[i].z );
                }
            }
            break;
            case IVAS_PI_ISM_DISTANCE_ATTENUATION:
            {
                for ( i = 0; i < numObj; ++i )
                {
                    if ( i != 0 )
                    {
                        fprintf( f_piDataOut, "," );
                    }
                    fprintf( f_piDataOut, "%f,%f,%f", cur->data.ismAttenuation.distAtten[i].ref_dist, cur->data.ismAttenuation.distAtten[i].max_dist, cur->data.ismAttenuation.distAtten[i].roll );
                }
            }
            break;
            case IVAS_PI_ISM_DIRECTIVITY:
            {
                for ( i = 0; i < numObj; ++i )
                {
                    if ( i != 0 )
                    {
                        fprintf( f_piDataOut, "," );
                    }
                    fprintf( f_piDataOut, "%d,%d,%f", cur->data.ismDirectivity.directivity[i].innerConeAngle, cur->data.ismDirectivity.directivity[i].outerConeAngle, cur->data.ismDirectivity.directivity[i].outerAttenuationdB );
                }
            }
            break;
            case IVAS_PI_PI_LATENCY:
            {
                fprintf( f_piDataOut, "%d", cur->data.piLatency.latency );
            }
            break;
            case IVAS_PI_R_ISM_ID:
            {
                fprintf( f_piDataOut, "%d", cur->data.ismEditId.id );
            }
            break;
            case IVAS_PI_R_ISM_GAIN:
            {
                fprintf( f_piDataOut, "%d", cur->data.ismEditGain.piDataType );
            }
            break;
            case IVAS_PI_R_ISM_ORIENTATION:
            {
                fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.ismEditOrientation.orientation.w, cur->data.ismEditOrientation.orientation.x, cur->data.ismEditOrientation.orientation.y, cur->data.ismEditOrientation.orientation.z );
            }
            break;
            case IVAS_PI_R_ISM_POSITION:
            {
                    fprintf( f_piDataOut, "%f,%f,%f", cur->data.ismEditPosition.position.x, cur->data.ismEditPosition.position.y, cur->data.ismEditPosition.position.z );
            }
            break;
            case IVAS_PI_R_ISM_DIRECTION:
            {
                fprintf( f_piDataOut, "%f,%f", cur->data.ismEditDirection.azimuth, cur->data.ismEditDirection.elevation );
            }
            break;
#endif /* RTP_S4_251135_CR26253_0016_REV1 */
        }
        fprintf( f_piDataOut, "\n" );
    }
}

const char *IVAS_RTP_GetExtPiFilePath( IVAS_RTP *rtp )
{
    return rtp->piExtFilename;
}

void IVAS_RTP_Term(
    IVAS_RTP *rtp /* i/o : IVAS RTP File reader/writer handle */
)
@@ -378,6 +630,12 @@ void IVAS_RTP_Term(
            rtp->f_piDataOut = NULL;
        }

        if ( rtp->f_piExtOut != NULL )
        {
            fclose( rtp->f_piExtOut );
            rtp->f_piExtOut = NULL;
        }

        if ( rtp->hRtpFile != NULL )
        {
            IvasRtpFile_Close( &rtp->hRtpFile );
@@ -423,7 +681,9 @@ ivas_error IVAS_RTP_WRITER_Init(
ivas_error IVAS_RTP_READER_Init(
    IVAS_RTP *rtp,                      /* i/o : IVAS RTP File reader handle  */
    const char *inputBitstreamFilename, /* i   : Input rtpdump filename       */
    const char *piOutputFilename        /* i   : Output PI data json filename */
    const char *piOutputFilename,       /* i   : Output PI data json filename */
    bool isExtOutput,                   /* i   : External output mode         */
    const char *outputWavFilename       /* i   : name of the output audio file */
)
{
    ivas_error error = IVAS_ERR_OK;
@@ -453,6 +713,27 @@ ivas_error IVAS_RTP_READER_Init(
            }
            fprintf( rtp->f_piDataOut, "{\n" );
        }

        if ( isExtOutput )
        {
            char ext_pi[12];

            /* sizeof( ext_pi ) accounts for terminating NULL, don't subtract extra 1 */
            const int32_t maxNameLenWithoutExt = FILENAME_MAX - (int32_t) sizeof( ext_pi );
            strncpy( rtp->piExtFilename, outputWavFilename , maxNameLenWithoutExt );
            snprintf( ext_pi, sizeof( ext_pi ), ".pidata.csv" );

            /* strlen( metadata_filename[0] ) doesn't account for terminating NULL, subtract extra 1 */
            const int32_t maxNumCharactersToAppend = FILENAME_MAX - (int32_t) strlen( rtp->piExtFilename ) - 1;
            strncat( rtp->piExtFilename, ext_pi, maxNumCharactersToAppend );

            rtp->f_piExtOut = fopen( rtp->piExtFilename, "w" );
            if ( rtp->f_piExtOut == NULL )
            {
                fprintf( stderr, "could not open: %s\n", rtp->piExtFilename );
                return IVAS_ERR_FAILED_FILE_OPEN;
            }
        }
    }

    return error;
+5 −2
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@ typedef struct

    IVAS_RTP_FILE_HANDLE hRtpFile;
    FILE *f_piDataOut;
    FILE *f_piExtOut;
    char piExtFilename[FILENAME_MAX];
    IVAS_RTP_CODEC codecId;
    uint32_t nWrittenPiData;
    uint32_t nReadPiData;
@@ -69,11 +71,12 @@ typedef struct
} IVAS_RTP;

ivas_error IVAS_RTP_WRITER_Init( IVAS_RTP *rtp, const char *outputBitstreamFilename, uint32_t numFramesPerPacket );
ivas_error IVAS_RTP_READER_Init( IVAS_RTP *rtp, const char *inputBitstreamFilename, const char *piOutputFilename );
ivas_error IVAS_RTP_READER_Init( IVAS_RTP *rtp, const char *inputBitstreamFilename, const char *piOutputFilename, bool isExtOutput, const char *outputWavFilename );
void IVAS_RTP_Term( IVAS_RTP *rtp );
ivas_error IVAS_RTP_WriteNextFrame( IVAS_RTP *rtp, uint8_t *au, int16_t auSizeBits, bool isMono, bool forcePacket );
ivas_error IVAS_RTP_ReadNextFrame( IVAS_RTP *rtp, uint8_t *au, int16_t *auSizeBits, uint32_t *rtpTimeStamp, uint16_t *rtpSequenceNumber, uint32_t *nextPacketRcvTime_ms, bool *qBit );
void IVAS_RTP_LogPiData( FILE *f_piDataOut, const PIDATA_TS *piData, uint32_t nPiDataPresent );

void IVAS_RTP_WriteExtPiData( FILE *f_piDataOut, const PIDATA_TS *piData, uint32_t nPiDataPresent, uint16_t numObj );
const char *IVAS_RTP_GetExtPiFilePath( IVAS_RTP *rtp );

#endif /* IVAS_RTP_FILE_H */