Commit 9c9a6f07 authored by Vladimir Malenovsky's avatar Vladimir Malenovsky
Browse files

Merge branch 'sagnowski-cmdln-parser-improvements' into...

Merge branch 'sagnowski-cmdln-parser-improvements' into '1224-float-split-rendering-command-line-issues'

Command line parser improvements

See merge request !2454
parents 7cdaa419 8cf192bc
Loading
Loading
Loading
Loading
Loading
+17 −45
Original line number Diff line number Diff line
@@ -58,7 +58,6 @@
 *------------------------------------------------------------------------------------------*/

#define POST_REND_MAX_CLI_ARG_LENGTH ( FILENAME_MAX )
#define POST_REND_NUM_MANDATORY_CMD_LINE_PARAMS 3

#define ISAR_MAX16B_FLT 32767.0f
#define ISAR_MIN16B_FLT ( -32768.0f )
@@ -139,42 +138,52 @@ static const CmdLnParser_Option cliOptions[] = {
        .id = CmdLnOptionId_inputFile,
        .match = "input_file",
        .matchShort = "i",
        .placeholder = "<path>",
        .description = "Path to the input file (WAV or raw PCM with BINAURAL_SPLIT_PCM input format, coded ISAR file with BINAURAL_SPLIT_CODED)",
        .isMandatory = true,
    },
    {
        .id = CmdLnOptionId_inputFormat,
        .match = "input_format",
        .matchShort = "if",
        .placeholder = "<format>",
        .description = "Audio format of input file (e.g. BINAURAL_SPLIT_CODED, BINAURAL_SPLIT_PCM, ... Use -l for a list)",
        .isMandatory = true,
    },
    {
        .id = CmdLnOptionId_outputFile,
        .match = "output_file",
        .matchShort = "o",
        .placeholder = "<path>",
        .description = "Path to the output file",
        .isMandatory = true,
    },
    {
        .id = CmdLnOptionId_inputMetadata,
        .match = "input_metadata",
        .matchShort = "im",
        .placeholder = "<path>",
        .description = "Path to the input metadata file for BINAURAL_SPLIT_PCM input mode",
    },
    {
        .id = CmdLnOptionId_sampleRate,
        .match = "sample_rate",
        .matchShort = "fs",
        .placeholder = "<fs>",
        .description = "Input sampling rate in kHz (16, 32, 48) - required only with raw PCM inputs",
    },
    {
        .id = CmdLnOptionId_trajFile,
        .match = "trajectory_file",
        .matchShort = "T",
        .placeholder = "<path>",
        .description = "Head rotation trajectory file for simulation of head tracking",
    },
    {
        .id = CmdLnOptionId_SplitRendBFIFile,
        .match = "post_rend_bfi_file",
        .matchShort = "prbfi",
        .placeholder = "<path>",
        .description = "Split rendering BFI (Bad Frame Indicator) file",
    },
    {
@@ -187,6 +196,7 @@ static const CmdLnParser_Option cliOptions[] = {
        .id = CmdLnOptionId_complexityLevel,
        .match = "complexity_level",
        .matchShort = "level",
        .placeholder = "<level>",
        .description = "Complexity level, level = (1, 2, 3), will be defined after characterisation.",
    },
    {
@@ -205,12 +215,14 @@ static const CmdLnParser_Option cliOptions[] = {
        .id = CmdLnOptionId_framing,
        .match = "framing",
        .matchShort = "fr",
        .description = "Set audio rendering frame size",
        .placeholder = "<size>",
        .description = "Set audio rendering frame size in ms (5, 10, 20)",
    },
    {
        .id = CmdLnOptionId_srParamsFile,
        .match = "sr_params",
        .matchShort = "s",
        .placeholder = "<path>",
        .description = "Path to the split rendering init params file",
    },
    {
@@ -394,41 +406,6 @@ static IVAS_AUDIO_CONFIG parseAudioConfig(
}


static bool checkRequiredArgs(
    CmdlnArgs args )
{
    const CmdLnParser_Option *tmpOption;

    /* Check required arguments */
    bool missingRequiredArg = false;
    if ( isEmptyString( args.inputFilePath ) )
    {
        tmpOption = findOptionById( CmdLnOptionId_inputFile );
        fprintf( stderr, "Missing mandatory parameter: --%s/-%s\n", tmpOption->match, tmpOption->matchShort );
        missingRequiredArg = true;
    }

    if ( args.inConfig.numBinBuses == 0 )
    {
        tmpOption = findOptionById( CmdLnOptionId_inputFormat );
        fprintf( stderr, "Missing mandatory parameter: --%s/-%s\n", tmpOption->match, tmpOption->matchShort );
        missingRequiredArg = true;
    }

    if ( isEmptyString( args.outputFilePath ) )
    {
        tmpOption = findOptionById( CmdLnOptionId_outputFile );
        fprintf( stderr, "Missing mandatory parameter: --%s/-%s\n", tmpOption->match, tmpOption->matchShort );
        missingRequiredArg = true;
    }

    if ( missingRequiredArg )
    {
        CmdLnParser_printUsage( args.executableName, cliOptions, numCliOptions, POST_REND_NUM_MANDATORY_CMD_LINE_PARAMS );
    }

    return !missingRequiredArg;
}


static CmdlnArgs defaultArgs(
@@ -643,7 +620,7 @@ static int16_t parseOption(
            strncpy( args->srParamsFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 );
            break;
        case CmdLnOptionId_help:
            CmdLnParser_printUsage( args->executableName, cliOptions, numCliOptions, POST_REND_NUM_MANDATORY_CMD_LINE_PARAMS );
            CmdLnParser_printUsage( args->executableName, cliOptions, numCliOptions );
            exit( 0 );
        default:
            fprintf( stderr, "Error: Incorrect or invalid command-line usage!\n" );
@@ -661,12 +638,7 @@ static CmdlnArgs parseCmdlnArgs(
{
    CmdlnArgs args = defaultArgs( argv[0] );

    if ( CmdLnParser_parseArgs( argc, argv, cliOptions, numCliOptions, &args, parseOption, POST_REND_NUM_MANDATORY_CMD_LINE_PARAMS ) != 0 )
    {
        exit( -1 ); /* Error printout handled by failing function */
    }

    if ( !checkRequiredArgs( args ) )
    if ( CmdLnParser_parseArgs( argc, argv, cliOptions, numCliOptions, &args, parseOption ) != 0 )
    {
        exit( -1 ); /* Error printout handled by failing function */
    }
+35 −59
Original line number Diff line number Diff line
@@ -68,7 +68,6 @@
#define RENDERER_MAX_CLI_ARG_LENGTH       ( FILENAME_MAX )
#define RENDERER_MAX_METADATA_LENGTH      8192
#define RENDERER_MAX_METADATA_LINE_LENGTH 1024
#define RENDERER_NUM_MANDATORY_CMD_LINE_PARAMS 1000

#define IVAS_MAX16B_FLT 32767.0f
#define IVAS_MIN16B_FLT ( -32768.0f )
@@ -235,96 +234,116 @@ static const CmdLnParser_Option cliOptions[] = {
        .id = CmdLnOptionId_inputFile,
        .match = "input_file",
        .matchShort = "i",
        .placeholder = "<path>",
        .description = "Path to the input file (WAV, raw PCM or scene description file)",
        .isMandatory = true,
    },
    {
        .id = CmdLnOptionId_inputFormat,
        .match = "input_format",
        .matchShort = "if",
        .placeholder = "<format>",
        .description = "Audio format of input file (e.g. 5_1 or HOA3 or META,\nuse -l for a list)",
        .isMandatory = true,
    },
    {
        .id = CmdLnOptionId_inputMetadata,
        .match = "input_metadata",
        .matchShort = "im",
        .placeholder = "<path1> [<path2>...]",
        .description = "Space-separated list of path to metadata files for ISM/MASA/OMASA/\nOSBA/BINAURAL_SPLIT_PCM inputs. \nFor OMASA, ISM files must be specified first.",
    },
    {
        .id = CmdLnOptionId_outputFile,
        .match = "output_file",
        .matchShort = "o",
        .placeholder = "<path>",
        .description = "Path to the output file",
        .isMandatory = true,
    },
    {
        .id = CmdLnOptionId_outputFormat,
        .match = "output_format",
        .matchShort = "of",
        .placeholder = "<format>",
        .description = "Output format to render.\nAlternatively, can be a custom loudspeaker layout file",
        .isMandatory = true,
    },
    {
        .id = CmdLnOptionId_sampleRate,
        .match = "sample_rate",
        .matchShort = "fs",
        .placeholder = "<fs>",
        .description = "Input sampling rate in kHz (16, 32, 48) - required only with raw\nPCM inputs",
    },
    {
        .id = CmdLnOptionId_trajFile,
        .match = "trajectory_file",
        .matchShort = "T",
        .placeholder = "<path>",
        .description = "Head rotation trajectory file for simulation of head tracking\n(only for binaural outputs)",
    },
    {
        .id = CmdLnOptionId_outputMetadata,
        .match = "output_metadata",
        .matchShort = "om",
        .placeholder = "<path>",
        .description = "coded metadata file for BINAURAL_SPLIT_PCM output mode",
    },
    {
        .id = CmdLnOptionId_SplitRendBFIFile,
        .match = "post_rend_bfi_file",
        .matchShort = "prbfi",
        .placeholder = "<path>",
        .description = "Split rendering option: bfi file",
    },
    {
        .id = CmdLnOptionId_refRotFile,
        .match = "reference_rotation_file",
        .matchShort = "rf",
        .placeholder = "<path>",
        .description = "Reference rotation trajectory file for simulation of head tracking\n(only for binaural outputs)",
    },
    {
        .id = CmdLnOptionId_customHrtfFile,
        .match = "custom_hrtf",
        .matchShort = "hrtf",
        .placeholder = "<path>",
        .description = "Custom HRTF file for binaural rendering\n(only for binaural outputs)",
    },
    {
        .id = CmdLnOptionId_renderConfigFile,
        .match = "render_config_parameters",
        .matchShort = "render_config",
        .placeholder = "<path>",
        .description = "Binaural renderer configuration parameters in file\n(only for binaural outputs)",
    },
    {
        .id = CmdLnOptionId_nonDiegeticPan,
        .match = "non_diegetic_panning",
        .matchShort = "non_diegetic_pan",
        .placeholder = "<value>",
        .description = "Panning mono non diegetic sound to stereo -90<= pan <= 90\nleft or l or 90->left, right or r or -90->right,\ncenter or c or 0 ->middle",
    },
    {
        .id = CmdLnOptionId_orientationTracking,
        .match = "tracking_type",
        .matchShort = "otr",
        .placeholder = "<type>",
        .description = "Head orientation tracking type: 'none', 'ref', 'avg' or `ref_vec`\nor `ref_vec_lev` (only for binaural outputs)",
    },
    {
        .id = CmdlnOptionId_lfePosition,
        .match = "lfe_position",
        .matchShort = "lp",
        .placeholder = "<gain>,<azi>,<ele>",
        .description = "Output LFE position. Comma-delimited triplet of [gain, azimuth,\nelevation] where gain is linear (like --gain, -g) and azimuth,\nelevation are in degrees. If specified, overrides the default\nbehavior which attempts to map input to output LFE channel(s)",
    },
    {
        .id = CmdlnOptionId_lfeMatrix,
        .match = "lfe_matrix",
        .matchShort = "lm",
        .placeholder = "<path>",
        .description = "LFE panning matrix. File (CSV table) containing a matrix of\ndimensions [ num_input_lfe x num_output_channels ] with elements\nspecifying linear routing gain (like --gain, -g). If specified,\noverrides the output LFE position option and the default\nbehavior which attempts to map input to output LFE channel(s)",
    },
    {
@@ -337,6 +356,7 @@ static const CmdLnParser_Option cliOptions[] = {
        .id = CmdLnOptionId_complexityLevel,
        .match = "complexity_level",
        .matchShort = "level",
        .placeholder = "<level>",
        .description = "Complexity level, level = (1, 2, 3), will be defined after\ncharacterisation.",
    },
    {
@@ -349,6 +369,7 @@ static const CmdLnParser_Option cliOptions[] = {
        .id = CmdLnOptionId_inputGain,
        .match = "gain",
        .matchShort = "g",
        .placeholder = "<gain>",
        .description = "Input gain (linear, not in dB) to be applied to input audio file",
    },
    {
@@ -361,43 +382,50 @@ static const CmdLnParser_Option cliOptions[] = {
        .id = CmdLnOptionId_referenceVectorFile,
        .match = "reference_vector_file",
        .matchShort = "rvf",
        .placeholder = "<path>",
        .description = "Reference vector trajectory file for simulation of head tracking\n(only for binaural outputs)",
    },
    {
        .id = CmdLnOptionId_exteriorOrientationFile,
        .match = "exterior_orientation_file",
        .matchShort = "exof",
        .placeholder = "<path>",
        .description = "External orientation trajectory file for simulation of external\norientations",
    },
    {
        .id = CmdLnOptionId_framing,
        .match = "framing",
        .matchShort = "fr",
        .description = "Set Render audio framing.",
        .placeholder = "<duration>",
        .description = "Set render audio framing in ms",
    },
    {
        .id = CmdLnOptionId_syncMdDelay,
        .match = "sync_md_delay",
        .matchShort = "smd",
        .placeholder = "<duration>",
        .description = "Metadata Synchronization Delay in ms, Default is 0. Quantized by\n5ms subframes for TDRenderer (13ms -> 10ms -> 2subframes)",
    },
    {
        .id = CmdLnOptionId_directivityPatternId,
        .match = "ism_directivity_pattern_id",
        .matchShort = "dpid",
        .placeholder = "<id1> [<id2>...]",
        .description = "Directivity pattern ID(s) = [ID1, ID2, ID3, ID4]. Space-separated\nlist of up to 4 numbers (unsigned integers) can be specified for\nBINAURAL and BINAURAL_ROOM_REVERB output.\nID1, ID2, ID3, ID4 specify the directivity pattern IDs used for\nISMs 1,2,3 and 4 respectively. \nThis option needs to be accompanied by a render_config file,\notherwise a default directivity pattern is used.",
    },
    {
        .id = CmdLnOptionId_acousticEnvironmentId,
        .match = "acoustic_environment_id",
        .matchShort = "aeid",
        .placeholder = "<id|path>",
        .description = "Acoustic environment ID (number > 0) alternatively, it can be\na text file where each line contains \"ID duration\" for\nBINAURAL_ROOM_REVERB output.",
    },
    {
        .id = CmdLnOptionId_roomSize,
        .match = "room_size",
        .matchShort = "rsz",
        .description = "Selects default reverb based on a room size (S - small | M - medium | L - large)",
        .placeholder = "<size>",
        .description = "Selects default reverb based on a room size (S - small |\nM - medium | L - large)",
    }
};

@@ -2596,53 +2624,6 @@ static bool parseReverbRoomSize(
    return true;
}


static bool checkRequiredArgs(
    CmdlnArgs args )
{
    const CmdLnParser_Option *tmpOption;

    /* Check required arguments */
    bool missingRequiredArg = false;
    if ( isEmptyString( args.inputFilePath ) )
    {
        tmpOption = findOptionById( CmdLnOptionId_inputFile );
        fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort );
        missingRequiredArg = true;
    }

    const bool singleInputSpecified = args.inConfig.numAudioObjects != 0 ||
                                      args.inConfig.numAmbisonicsBuses != 0 ||
                                      args.inConfig.numMultiChannelBuses != 0 ||
                                      args.inConfig.numMasaBuses != 0;

    if ( !args.sceneDescriptionInput && !singleInputSpecified )
    {
        /* Neither scene description input nor single-type input was specified on command line */
        tmpOption = findOptionById( CmdLnOptionId_inputFormat );
        fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort );
        missingRequiredArg = true;
    }
    if ( isEmptyString( args.outputFilePath ) )
    {
        tmpOption = findOptionById( CmdLnOptionId_outputFile );
        fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort );
        missingRequiredArg = true;
    }
    if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_INVALID )
    {
        tmpOption = findOptionById( CmdLnOptionId_outputFormat );
        fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort );
        missingRequiredArg = true;
    }
    if ( missingRequiredArg )
    {
        CmdLnParser_printUsage( args.executableName, cliOptions, numCliOptions, 100 );
    }

    return !missingRequiredArg;
}

static CmdlnArgs defaultArgs(
    const char *executableName )
{
@@ -2921,12 +2902,7 @@ static CmdlnArgs parseCmdlnArgs(
{
    CmdlnArgs args = defaultArgs( argv[0] );

    if ( CmdLnParser_parseArgs( argc, argv, cliOptions, numCliOptions, &args, parseOption, RENDERER_NUM_MANDATORY_CMD_LINE_PARAMS ) != 0 )
    {
        exit( -1 ); /* Error printout handled by failing function */
    }

    if ( !checkRequiredArgs( args ) )
    if ( CmdLnParser_parseArgs( argc, argv, cliOptions, numCliOptions, &args, parseOption ) != 0 )
    {
        exit( -1 ); /* Error printout handled by failing function */
    }
+25 −0
Original line number Diff line number Diff line
@@ -225,3 +225,28 @@ bool isEmptyString(
{
    return str[0] == '\0';
}


/*---------------------------------------------------------------------*
 * strLength()
 *
 * Get the length of a string up to a maximum length.
 *
 * Equivalent to strnlen, which is not part of the C standard and only provided by POSIX.
 *
 *---------------------------------------------------------------------*/

int32_t strLength(
    const char *str,
    int32_t maxlen )
{
    int32_t len;

    len = 0;
    while ( len < maxlen && str[len] != '\0' )
    {
        len++;
    }

    return len;
}
+2 −0
Original line number Diff line number Diff line
@@ -50,4 +50,6 @@ void clearString( char *str );

bool isEmptyString( const char *str );

int32_t strLength( const char *str, int32_t maxlen );

#endif /* CMDL_TOOLS_H */
+242 −114

File changed.

Preview size limit exceeded, changes collapsed.

Loading