Commit 0b29b188 authored by sagnowski's avatar sagnowski
Browse files

CmdLnParser: add placeholders for option values in usage printout

parent d2fe0529
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ 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,
    },
@@ -145,6 +146,7 @@ static const CmdLnParser_Option cliOptions[] = {
        .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,
    },
@@ -152,6 +154,7 @@ static const CmdLnParser_Option cliOptions[] = {
        .id = CmdLnOptionId_outputFile,
        .match = "output_file",
        .matchShort = "o",
        .placeholder = "<path>",
        .description = "Path to the output file",
        .isMandatory = true,
    },
@@ -159,24 +162,28 @@ static const CmdLnParser_Option cliOptions[] = {
        .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",
    },
    {
@@ -189,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.",
    },
    {
@@ -207,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",
    },
    {
+27 −2
Original line number Diff line number Diff line
@@ -234,6 +234,7 @@ 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,
    },
@@ -241,6 +242,7 @@ static const CmdLnParser_Option cliOptions[] = {
        .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,
    },
@@ -248,12 +250,14 @@ static const CmdLnParser_Option cliOptions[] = {
        .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,
    },
@@ -261,6 +265,7 @@ static const CmdLnParser_Option cliOptions[] = {
        .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,
    },
@@ -268,66 +273,77 @@ static const CmdLnParser_Option cliOptions[] = {
        .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)",
    },
    {
@@ -340,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.",
    },
    {
@@ -352,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",
    },
    {
@@ -364,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)",
    }
};

+39 −21
Original line number Diff line number Diff line
@@ -304,15 +304,24 @@ static const char *getBasename(
    return path;
}

static int32_t totalOptionNameLength(
static int32_t totalNumOptChars(
    const OptionProps opt )
{
    return (int32_t) ( strlen( opt.match ) + strlen( opt.matchShort ) );
    int32_t len = (int32_t) strlen( opt.match ) + strlen( opt.matchShort );

    if ( opt.placeholder != NULL )
    {
        len += (int32_t) strlen( opt.placeholder ); 
    }

    return len;
}

static void printWhitespace(
    const int32_t n )
{
    assert( n >= 0 );

    for ( int32_t i = 0; i < n; ++i )
    {
        fprintf( stderr, " " );
@@ -352,12 +361,11 @@ static void printOptions(
    const OptionProps *optionProps,
    const int32_t numOptions,
    const bool mandatory,
    const int32_t maxOptNameLength
    const int32_t maxNumOptChars
    )
{
    const int32_t preDescriptionWhitespace = 4;
    const int32_t leftColumnAdditionalChars = 7;
    int32_t optNameLength;
    const int32_t descriptionColumnIdx = maxNumOptChars + 11 /* Additional chars we will print in the options column */;
    int32_t numOptChars;

    for ( int32_t i = 0; i < numOptions; ++i )
    {
@@ -368,13 +376,23 @@ static void printOptions(
            continue;
        }

        optNameLength = totalOptionNameLength( optionProps[i] );
        numOptChars = totalNumOptChars( optionProps[i] );

        if ( opt.placeholder != NULL )
        {
            fprintf( stderr, "  --%s, -%s %s", opt.match, opt.matchShort, opt.placeholder );
            numOptChars += 8;
        }
        else
        {
            fprintf( stderr, "  --%s, -%s", opt.match, opt.matchShort );
            numOptChars += 7;
        }

        printWhitespace( maxOptNameLength - optNameLength + preDescriptionWhitespace - 2 );
        /* Done printing options column, fill with whitespace until description column */
        printWhitespace( descriptionColumnIdx - numOptChars - 2 /* account for ": " below */ );
        fprintf( stderr, ": " );
        printOptDescriptionAligned( opt.description, maxOptNameLength + leftColumnAdditionalChars + preDescriptionWhitespace );
        printOptDescriptionAligned( opt.description, descriptionColumnIdx );
    }
}

@@ -383,21 +401,20 @@ static void printUsage(
    const OptionProps *optionProps,
    const int32_t numOptions )
{
    int32_t optNameLength;
    bool hasMandatoryOptions = false;

    fprintf( stderr, "\n" );
    fprintf( stderr, "Usage: %s [options]\n", getBasename( argv0 ) );
    fprintf( stderr, "\n" );

    int32_t maxOptNameLength = 0;
    int32_t numOptChars;
    int32_t maxNumOptChars = 0;
    bool hasMandatoryOptions = false;
    for ( int32_t i = 0; i < numOptions; ++i )
    {
        /* Find option with longest name, used for pretty formatting */
        optNameLength = totalOptionNameLength( optionProps[i] );
        if ( maxOptNameLength < optNameLength )
        /* Find option with most characters when printed, used for pretty formatting */
        numOptChars = totalNumOptChars( optionProps[i] );
        if ( maxNumOptChars < numOptChars )
        {
            maxOptNameLength = optNameLength;
            maxNumOptChars = numOptChars;
        }

        /* Check if mandatory parameters should be printed separately */
@@ -410,11 +427,12 @@ static void printUsage(
    if ( hasMandatoryOptions )
    {
        fprintf( stderr, "Mandatory parameters:\n---------------------\n" );
        printOptions( optionProps, numOptions, true, maxOptNameLength );
        printOptions( optionProps, numOptions, true, maxNumOptChars );
        fprintf( stderr, "\n" );
    }

    fprintf( stderr, "\nOptions:\n--------\n" );
    printOptions( optionProps, numOptions, false, maxOptNameLength );
    fprintf( stderr, "Options:\n--------\n" );
    printOptions( optionProps, numOptions, false, maxNumOptChars );

    return;
}
+6 −5
Original line number Diff line number Diff line
@@ -38,11 +38,12 @@

typedef struct
{
    int32_t id;
    const char *match;
    const char *matchShort;
    const char *description;
    bool isMandatory;
    int32_t id;              /* Unique ID for the option */
    const char *match;       /* String to match, e.g. "input" here will match "--input" on CLI */
    const char *matchShort;  /* Short version of the string to match, e.g. "i" here will match "-i" on CLI */
    const char *placeholder; /* If not NULL, this will follow the match string in the usage printout, e.g. "<file>" here will print "--input <file>" on CLI */
    const char *description; /* Description of the option for the usage printout. May contain '\n' for line breaks. */
    bool isMandatory;        /* Parsing will fail if an option with `isMandatory == true` is not given */
} CmdLnParser_Option;

/* Function for parsing option values into an output struct, to be implemented by the user */