Commit 97140f25 authored by Archit Tamarapu's avatar Archit Tamarapu
Browse files

Merge branch 'extrend_osba_omasa_support' into 'main'

Add OSBA/OMASA support to IVAS_rend

See merge request !1908
parents e1e7eeb4 41010d0a
Loading
Loading
Loading
Loading
Loading
+76 −29
Original line number Diff line number Diff line
@@ -158,7 +158,7 @@ typedef struct
    int32_t sampleRate;
    InputConfig inConfig;
    OutputConfig outConfig;
    char inMetadataFilePaths[RENDERER_MAX_ISM_INPUTS][RENDERER_MAX_CLI_ARG_LENGTH];
    char inMetadataFilePaths[RENDERER_MAX_ISM_INPUTS + RENDERER_MAX_MASA_INPUTS][RENDERER_MAX_CLI_ARG_LENGTH];
    int16_t numInMetadataFiles;
    char outMetadataFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
    char headRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
@@ -238,7 +238,7 @@ static const CmdLnParser_Option cliOptions[] = {
        .id = CmdLnOptionId_inputMetadata,
        .match = "input_metadata",
        .matchShort = "im",
        .description = "Space-separated list of path to metadata files for ISM or MASA inputs or BINAURAL_SPLIT_PCM input mode",
        .description = "Space-separated list of path to metadata files for ISM or MASA inputs or BINAURAL_SPLIT_PCM input mode. For OMASA, ISM files must be specified first.",
    },
    {
        .id = CmdLnOptionId_outputFile,
@@ -397,6 +397,8 @@ static IVAS_AUDIO_CONFIG ambisonicsOrderToEnum( const int16_t order );

static void parseSceneDescriptionFile( char *path, char *audioFilePath, InputConfig *inConfig, IsmPositionProvider *positionProvider, MasaFileReader **masaReaders, LfeRoutingConfig **lfeRoutingConfigs );

static void parseCombinedFormatInput( InputConfig *inConfig, char **configString );

static ivas_error parseCustomLayoutFile( const char *filePath, IVAS_CUSTOM_LS_DATA *pLsSetupCustom );

static CmdlnArgs parseCmdlnArgs( const int argc, char **argv );
@@ -555,25 +557,7 @@ static void setupWithSingleFormatInput(
    strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 );

    /* Depending on input format, prepare metadata reading for ISM or MASA */
    if ( args.inConfig.numMasaBuses != 0 )
    {
        if ( args.inConfig.numMasaBuses != args.numInMetadataFiles )
        {
            fprintf( stderr, "Error: all MASA inputs must have a corresponding metadata file" );
            exit( -1 );
        }

        for ( int16_t i = 0; i < args.numInMetadataFiles; ++i )
        {
            masaReaders[i] = MasaFileReader_open( args.inMetadataFilePaths[i] );
            if ( masaReaders[i] == NULL )
            {
                fprintf( stderr, "Could not open MASA metadata file %s\n", args.inMetadataFilePaths[i] );
                exit( -1 );
            }
        }
    }
    else if ( args.inConfig.numAudioObjects != 0 )
    if ( args.inConfig.numAudioObjects != 0 )
    {
        positionProvider->numObjects = args.inConfig.numAudioObjects;
        for ( int16_t i = 0; i < positionProvider->numObjects; ++i )
@@ -596,6 +580,26 @@ static void setupWithSingleFormatInput(
            }
        }
    }
    if ( args.inConfig.numMasaBuses != 0 )
    {
        if ( args.inConfig.numMasaBuses != ( args.numInMetadataFiles - args.inConfig.numAudioObjects ) )
        {
            fprintf( stderr, "Error: all MASA inputs must have a corresponding metadata file" );
            exit( -1 );
        }

        int16_t reader_idx = 0;
        for ( int16_t i = args.inConfig.numAudioObjects; i < args.numInMetadataFiles; ++i )
        {
            reader_idx = i - args.inConfig.numAudioObjects;
            masaReaders[reader_idx] = MasaFileReader_open( args.inMetadataFilePaths[i] );
            if ( masaReaders[reader_idx] == NULL )
            {
                fprintf( stderr, "Could not open MASA metadata file %s\n", args.inMetadataFilePaths[i] );
                exit( -1 );
            }
        }
    }

    return;
}
@@ -2117,16 +2121,11 @@ static bool parseInConfig(
            inConfig->masaBuses[0].gain_dB = 0.0f;
            break;
        case IVAS_AUDIO_CONFIG_OBA:
            /* If input format is objects, parse the characters after "ISM" to get number of objects */
            /* If input format is objects, parse the characters after "ISM" to get
             * number of objects and check for combined formats. */
            {
                char *ptr = NULL;
                inConfig->numAudioObjects = (uint16_t) strtol( inFormatStr + 3, &ptr, 10 );
                if ( ptr == NULL || *ptr != '\0' )
                {
                    /* Failed to parse string as a number */
                    fprintf( stderr, "Cannot parse string \"%s\" as a valid input format", inFormatStr );
                    return false;
                }
                if ( inConfig->numAudioObjects > RENDERER_MAX_ISM_INPUTS )
                {
                    fprintf( stderr, "Too many objects at input. Max %d supported.", RENDERER_MAX_ISM_INPUTS );
@@ -2138,6 +2137,17 @@ static bool parseInConfig(
                    inConfig->audioObjects[i].inputChannelIndex = i;
                    inConfig->audioObjects[i].gain_dB = 0.0f;
                }
                if ( *ptr != '\0' )
                {
                    /* Try to parse combined format */
                    parseCombinedFormatInput( inConfig, &ptr );
                }
                if ( ptr == NULL || *ptr != '\0' )
                {
                    /* Failed to parse string as a number */
                    fprintf( stderr, "Cannot parse string \"%s\" as a valid input format", inFormatStr );
                    return false;
                }
            }
            break;
        case IVAS_AUDIO_CONFIG_INVALID:
@@ -2630,7 +2640,7 @@ static void parseOption(
            }
            break;
        case CmdLnOptionId_inputMetadata:
            assert( numOptionValues <= RENDERER_MAX_ISM_INPUTS );
            assert( numOptionValues <= RENDERER_MAX_ISM_INPUTS + RENDERER_MAX_MASA_INPUTS );
            for ( int16_t i = 0; i < numOptionValues; ++i )
            {
                strncpy( args->inMetadataFilePaths[i], optionValues[i], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
@@ -3458,6 +3468,41 @@ static void parseMasa(
    return;
}

static void parseCombinedFormatInput(
    InputConfig *inConfig,
    char **configString )
{
    IVAS_AUDIO_CONFIG audioConfig;
    audioConfig = parseAudioConfig( *configString );

    if ( audioConfig == IVAS_AUDIO_CONFIG_FOA || audioConfig == IVAS_AUDIO_CONFIG_HOA2 || audioConfig == IVAS_AUDIO_CONFIG_HOA3 )
    {
        /* OSBA */
        inConfig->numAmbisonicsBuses = 1;
        inConfig->ambisonicsBuses[0].audioConfig = audioConfig;
        inConfig->ambisonicsBuses[0].inputChannelIndex = inConfig->numAudioObjects;
        inConfig->ambisonicsBuses[0].gain_dB = -6.f;
        *configString += 4;

        /* Modify input gain for objects too */
        for ( int16_t i = 0; i < inConfig->numAudioObjects; ++i )
        {
            inConfig->audioObjects[i].gain_dB = -6.f;
        }
    }
    else if ( audioConfig == IVAS_AUDIO_CONFIG_MASA1 || audioConfig == IVAS_AUDIO_CONFIG_MASA2 )
    {
        /* OMASA */
        inConfig->numMasaBuses = 1;
        inConfig->masaBuses[0].audioConfig = audioConfig;
        inConfig->masaBuses[0].inputChannelIndex = inConfig->numAudioObjects;
        inConfig->masaBuses[0].gain_dB = 0.0f;
        *configString += 5;
    }

    return;
}

static ivas_error parseCustomLayoutFile(
    const char *filePath,
    IVAS_CUSTOM_LS_DATA *pLsSetupCustom )
@@ -3674,6 +3719,8 @@ static void printSupportedAudioConfigs( void )
        "HOA2",
        "HOA3",
        "ISMx (input only)",
        "ISMxSBAy (OSBA, input only)",
        "ISMxMASAy (OMASA, input only)",
        "MASAx",
        "BINAURAL (output only)",
        "BINAURAL_SPLIT_PCM",