Commit c75ed52b authored by Jan Kiene's avatar Jan Kiene
Browse files

Merge branch 'main' into replace_cmp_custom

parents 5ae94ce6 ea0efc47
Loading
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -937,7 +937,8 @@ coverage-test-on-main-scheduled:
    - python3 -m pytest -q -n auto tests/renderer/test_renderer_be_comparison.py
    - bash ci/ivas_voip_be_test.sh coverage
    - lcov -c -d obj -o coverage.info
    - genhtml coverage.info -o coverage
    - commit_sha=$(git rev-parse HEAD)
    - genhtml coverage.info -o coverage -t "Coverage on main @ $commit_sha"
  artifacts:
    name: "main-coverage-sha-$CI_COMMIT_SHORT_SHA"
    when: always
+324 −0
Original line number Diff line number Diff line
@@ -132,6 +132,14 @@ typedef struct
    bool quietModeEnabled;
    bool sceneDescriptionInput;
    float inputGainGlobal; /* Linear gain (not in dB) */
#ifdef REND_CFG_LFE
    bool lfePanningEnabled;
    float lfeConfigGain; /* Linear gain (not in dB) */
    float lfeConfigAzimuth;
    float lfeConfigElevation;
    bool lfeCustomRoutingEnabled;
    char inLfePanningMatrixFile[RENDERER_MAX_CLI_ARG_LENGTH];
#endif
} CmdlnArgs;

typedef enum
@@ -146,7 +154,12 @@ typedef enum
    CmdLnOptionId_renderConfigFile,
    CmdLnOptionId_noDiegeticPan,
    CmdLnOptionId_orientationTracking,
#ifdef REND_CFG_LFE
    CmdlnOptionId_lfePosition,
    CmdlnOptionId_lfeMatrix,
#else
    CmdLnOptionId_customLfeRouting,
#endif
    CmdLnOptionId_noDelayCmp,
    CmdLnOptionId_quietModeEnabled,
    CmdLnOptionId_inputMetadata,
@@ -222,13 +235,26 @@ static const CmdLnParser_Option cliOptions[] = {
        .description = "Head orientation tracking type: 'ref' or 'avg' (only for BINAURAL and BINAURAL_ROOM) (todo: check implementation)",
    },
    {
#ifdef REND_CFG_LFE
        .id = CmdlnOptionId_lfePosition,
        .match = "lfe_position",
        .matchShort = "lp",
        .description = "Output LFE position. Comma-delimited triplet of [gain, azimuth, elevation] where gain is linear (like --gain, -g) and azimuth, elevation are in degrees.\nIf specified, overrides the default behavior which attempts to map input to output LFE channel(s)",
#else
        /* TODO(sgi): Replace with more configurable input, e.g. ask for a list of triplets: (gain, azimuth, elevation) to place LFE signal */
        /* rename to "lfeHandling" */
        .id = CmdLnOptionId_customLfeRouting,
        .match = "neverDropLfe",
        .matchShort = "ndl",
        .description = "[flag] If set, renderer tries to render LFE into other channels in an optimal way when rendering to configs w/o LFE",
#endif
    },
#ifdef REND_CFG_LFE
    { .id = CmdlnOptionId_lfeMatrix,
      .match = "lfe_matrix",
      .matchShort = "lm",
      .description = "LFE panning matrix. File (CSV table) containing a matrix of dimensions [ num_input_lfe x num_output_channels ] with elements specifying linear routing gain (like --gain, -g). \nIf specified, overrides the output LFE position option and the default behavior which attempts to map input to output LFE channel(s)" },
#endif
    {
        .id = CmdLnOptionId_noDelayCmp,
        .match = "no_delay_cmp",
@@ -334,6 +360,12 @@ static void parseMetadata(
    IsmPositionProvider *positionProvider,
    MasaFileReader **masaReaders );

#ifdef REND_CFG_LFE
static ivas_error parseLfePanMtxFile(
    const char *lfeRoutingMatrixFilePath,
    IVAS_REND_LfePanMtx *lfePanMtx );
#endif

static void convert_backslash( char *str );

static void remove_cr( char *str );
@@ -550,6 +582,9 @@ int main(
    convert_backslash( args.inputFilePath );
    convert_backslash( args.outputFilePath );
    convert_backslash( args.headRotationFilePath );
#ifdef REND_CFG_LFE
    convert_backslash( args.inLfePanningMatrixFile );
#endif

    if ( !isEmptyString( args.headRotationFilePath ) )
    {
@@ -656,6 +691,21 @@ int main(
        }
    }

#ifdef REND_CFG_LFE
    IVAS_REND_LfePanMtx lfePanMatrix;

    /* parse input LFE panning matrix */
    if ( args.lfeCustomRoutingEnabled && !isEmptyString( args.inLfePanningMatrixFile ) )
    {
        /* TODO tmu: how should we handle this on CLI for multiple MC inputs? */
        if ( ( error = parseLfePanMtxFile( args.inLfePanningMatrixFile, &lfePanMatrix ) ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
            exit( -1 );
        }
    }
#endif

    for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i )
    {
        if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.multiChannelBuses[i].audioConfig, &mcIds[i] ) ) != IVAS_ERR_OK )
@@ -679,7 +729,34 @@ int main(
            }
        }

#ifdef REND_CFG_LFE
        /* set panning matrix for input LFE */
        if ( args.lfeCustomRoutingEnabled )
        {
            if ( args.lfePanningEnabled )
            {
                fprintf( stdout, "Warning LFE position specified as well as panning matrix! Ignoring position and using gains from panning matrix\n" );
                args.lfePanningEnabled = false;
            }

            if ( ( error = IVAS_REND_SetInputLfeMtx( hIvasRend, mcIds[i], (const IVAS_REND_LfePanMtx *) &lfePanMatrix ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
                exit( -1 );
            }
        }
        /* set panning gains for input LFE */
        else if ( args.lfePanningEnabled )
        {
            if ( ( error = IVAS_REND_SetInputLfePos( hIvasRend, mcIds[i], args.lfeConfigGain, args.lfeConfigAzimuth, args.lfeConfigElevation ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
                exit( -1 );
            }
        }
#else
        /* TODO(sgi): Test custom LFE routing here */
#endif
    }

    for ( i = 0; i < args.inConfig.numAudioObjects; ++i )
@@ -1041,6 +1118,22 @@ static IVAS_REND_AudioConfig ambisonicsOrderToEnum(
    return IVAS_REND_AUDIO_CONFIG_UNKNOWN;
}

#ifdef FIX_293_EXT_RENDERER_CLI
static const CmdLnParser_Option *findOptionById(
    const int32_t id )
{
    for ( int32_t i = 0; i < numCliOptions; ++i )
    {
        if ( cliOptions[i].id == id )
        {
            return &cliOptions[i];
        }
    }

    return NULL;
}
#endif

static bool parseInConfig(
    const char *inFormatStr,
    InputConfig *inConfig,
@@ -1128,8 +1221,13 @@ static bool parseInConfig(

                if ( error == IVAS_ERR_FAILED_FILE_OPEN )
                {
#ifdef FIX_293_EXT_RENDERER_CLI
                    /* Failed to open with given string - most likely wasn't a file path */
                    const CmdLnParser_Option *listOption = findOptionById( CmdLnOptionId_listFormats );
                    fprintf( stderr, "Unsupported input format: %s. To list valid formats, use option --%s.\n", inFormatStr, listOption->match );
#else
                    fprintf( stderr, "Unsupported input format: %s\n", inFormatStr );
#endif
                    return false;
                }
                if ( error != IVAS_ERR_OK )
@@ -1144,10 +1242,20 @@ static bool parseInConfig(
            }
            break;
        default:
#ifdef FIX_293_EXT_RENDERER_CLI
        {
            /* Default case covers formats that are defined in the IVAS_REND_AudioConfig enum,
             * but cannot be used at input, e.g. BINAURAL */
            const CmdLnParser_Option *listOption = findOptionById( CmdLnOptionId_listFormats );
            fprintf( stderr, "Unsupported input format: %s. To list valid formats, use option --%s.\n", inFormatStr, listOption->match );
            return false;
        }
#else
            /* Default case covers formats that are defined in the IVAS_REND_AudioConfig enum,
             * but cannot be used at input, e.g. BINAURAL */
            fprintf( stderr, "Unsupported input format: %s\n", inFormatStr );
            return false;
#endif
    }

    return true;
@@ -1175,12 +1283,18 @@ static bool parseOutConfig(
    return true;
}

#ifdef REND_CFG_LFE
static bool parseDiegeticPan(
#else
static int8_t parseDiegeticPan(
#endif
    char *value,
    float *noDiegeticPan )
{
#ifndef REND_CFG_LFE
    int8_t success;
    success = 1;
#endif
    to_upper( value );

    if ( ( strcmp( value, "CENTER" ) == 0 ) || ( strchr( value, 'C' ) != NULL ) )
@@ -1202,18 +1316,32 @@ static int8_t parseDiegeticPan(
        if ( *noDiegeticPan > 1.0f || *noDiegeticPan < -1.0f )
        {
            fprintf( stderr, "Error: Incorrect value for panning option argument specified!\n\n" );
#ifdef REND_CFG_LFE
            return false;
#else
            success = 0;
#endif
        }
    }
#ifdef REND_CFG_LFE
    return false;
#else
    return success ? 0 : -1;
#endif
}

#ifdef REND_CFG_LFE
static bool parseOrientationTracking(
#else
static int8_t parseOrientationTracking(
#endif
    char *value,
    int8_t *tracking_type )
{
#ifndef REND_CFG_LFE
    int8_t success;
    success = 1;
#endif

    to_upper( value );

@@ -1228,10 +1356,18 @@ static int8_t parseOrientationTracking(
    else
    {
        fprintf( stderr, "Error: Invalid orientation tracking type %s \n\n", value );
#ifdef REND_CFG_LFE
        return false;
#else
        success = 0;
#endif
    }

#ifdef REND_CFG_LFE
    return true;
#else
    return success ? 0 : -1;
#endif
}

static IVAS_REND_AudioConfig parseAudioConfig(
@@ -1285,8 +1421,21 @@ static IVAS_REND_AudioConfig parseAudioConfig(
    }
    if ( strncmp( charBuf, "ISM", 3 ) == 0 )
    {
#ifdef FIX_293_EXT_RENDERER_CLI
        /* Accept input config as ISM only if the 4th character is a number from 1 to 4.
         * Otherwise, do nothing. Unknown audio config will be returned. */
        switch ( charBuf[3] )
        {
            case '1':
            case '2':
            case '3':
            case '4':
                return IVAS_REND_AUDIO_CONFIG_OBJECT;
        }
#else
        return IVAS_REND_AUDIO_CONFIG_OBJECT;
#endif
    }
    if ( strncmp( charBuf, "MASA", 4 ) == 0 )
    {
        switch ( charBuf[4] )
@@ -1313,6 +1462,55 @@ static IVAS_REND_AudioConfig parseAudioConfig(
    return IVAS_REND_AUDIO_CONFIG_UNKNOWN;
}

#ifdef REND_CFG_LFE
static bool parseLfePositionConfig(
    const char *value,
    float *lfeGain,
    float *lfeAzimuth,
    float *lfeElevation )
{
    uint8_t nvalues;
    const char *tok;
    float values[3];
    char config_string[RENDERER_MAX_METADATA_LINE_LENGTH];

    strncpy( config_string, value, RENDERER_MAX_METADATA_LINE_LENGTH );
    nvalues = 0;

    for ( tok = strtok( config_string, "," ); tok && *tok; tok = strtok( NULL, ",\n" ) )
    {
        while ( *tok == ' ' )
        {
            tok++;
        }

        if ( *tok == '\0' )
        {
            continue;
        }
        values[nvalues] = (float) atof( tok );
        nvalues++;

        /* ignore any additionally specified values */
        if ( nvalues == 3 )
        {
            break;
        }
    }

    if ( nvalues != 3 )
    {
        return false;
    }

    *lfeGain = values[0];
    *lfeAzimuth = values[1];
    *lfeElevation = values[2];
    return true;
}
#endif

#ifndef FIX_293_EXT_RENDERER_CLI
static const CmdLnParser_Option *findOptionById(
    const int32_t id )
{
@@ -1326,6 +1524,7 @@ static const CmdLnParser_Option *findOptionById(

    return NULL;
}
#endif

static bool checkRequiredArgs(
    CmdlnArgs args )
@@ -1410,6 +1609,15 @@ static CmdlnArgs defaultArgs(
    args.sceneDescriptionInput = false;
    args.inputGainGlobal = 1.0f;

#ifdef REND_CFG_LFE
    args.lfePanningEnabled = false;
    args.lfeConfigGain = 1.0f;
    args.lfeConfigAzimuth = 0;
    args.lfeConfigElevation = 0;

    args.lfeCustomRoutingEnabled = false;
    clearString( args.inLfePanningMatrixFile );
#endif
    return args;
}

@@ -1480,7 +1688,11 @@ static void parseOption(
            break;
        case CmdLnOptionId_noDiegeticPan:
            assert( numOptionValues == 1 );
#ifdef REND_CFG_LFE
            if ( !parseDiegeticPan( optionValues[0], &args->noDiegeticPan ) )
#else
            if ( parseDiegeticPan( optionValues[0], &args->noDiegeticPan ) != 0 )
#endif
            {
                fprintf( stderr, "Unknown option for diegetic panning: %s\n", optionValues[0] );
                exit( -1 );
@@ -1488,15 +1700,38 @@ static void parseOption(
            break;
        case CmdLnOptionId_orientationTracking:
            assert( numOptionValues == 1 );
#ifdef REND_CFG_LFE
            if ( !parseOrientationTracking( optionValues[0], &args->orientationTracking ) )
#else
            if ( parseOrientationTracking( optionValues[0], &args->orientationTracking ) != 0 )
#endif
            {
                fprintf( stderr, "Unknown option for orientation tracking: %s\n", optionValues[0] );
                exit( -1 );
            }
            break;
#ifdef REND_CFG_LFE
        case CmdlnOptionId_lfePosition:
            assert( numOptionValues == 1 );
            if ( !parseLfePositionConfig( optionValues[0], &args->lfeConfigGain, &args->lfeConfigAzimuth, &args->lfeConfigElevation ) )
            {
                fprintf( stderr, "Unknown or invalid option for LFE position: %s\n", optionValues[0] );
                exit( -1 );
            }
            args->lfePanningEnabled = true;
            break;
#else
        case CmdLnOptionId_customLfeRouting:
            assert( 0 && "Not yet implemented in CLI" );
#endif
            break;
#ifdef REND_CFG_LFE
        case CmdlnOptionId_lfeMatrix:
            assert( numOptionValues == 1 );
            strncpy( args->inLfePanningMatrixFile, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
            args->lfeCustomRoutingEnabled = true;
            break;
#endif
        case CmdLnOptionId_noDelayCmp:
            assert( numOptionValues == 0 );
            args->delayCompensationEnabled = false;
@@ -1619,6 +1854,24 @@ void IsmPositionProvider_getNextFrame(

    for ( objIdx = 0; objIdx < positionProvider->numObjects; ++objIdx )
    {
#ifdef FIX_293_EXT_RENDERER_CLI
        /* If ISM metadata reader is open, read from metadata file */
        if ( positionProvider->ismReaders[objIdx] != NULL )
        {
            getMetadataFromFileReader( positionProvider->ismReaders[objIdx], objectMetadataBuffer, objIdx );
        }
        /* Otherwise, if positions were provided in a scene description file, use them */
        else if ( positionProvider->positions[objIdx] != NULL )
        {
            readFromShorthandMetadata( positionProvider, objectMetadataBuffer, objIdx );
        }
        /* Otherwise fall back to default position */
        else
        {
            objectMetadataBuffer->positions[objIdx].azimuth = 0.0f;
            objectMetadataBuffer->positions[objIdx].elevation = 0.0f;
        }
#else
        if ( positionProvider->ismReaders[objIdx] != NULL )
        {
            getMetadataFromFileReader( positionProvider->ismReaders[objIdx], objectMetadataBuffer, objIdx );
@@ -1627,6 +1880,7 @@ void IsmPositionProvider_getNextFrame(
        {
            readFromShorthandMetadata( positionProvider, objectMetadataBuffer, objIdx );
        }
#endif

        /* Wrap azimuth to lie within (-180, 180] range */
        while ( objectMetadataBuffer->positions[objIdx].azimuth < 0.0f )
@@ -2014,7 +2268,11 @@ static void parseMasa(
    if ( strncmp( line, "MASA", 4 ) != 0 )
    {
        char numTcs = *line;
#ifdef FIX_293_EXT_RENDERER_CLI
        snprintf( line, 6 /* write at most 6 characters: MASAx + null termination */, "MASA%c", numTcs );
#else
        sprintf( line, "MASA%c", numTcs );
#endif
    }

    inConfig->masaBuses[idx].audioConfig = parseAudioConfig( line );
@@ -2256,6 +2514,72 @@ static void printSupportedAudioConfigs()
    return;
}

#ifdef REND_CFG_LFE
static ivas_error parseLfePanMtxFile(
    const char *lfeRoutingMatrixFilePath,
    IVAS_REND_LfePanMtx *lfePanMtx )
{
    int16_t lfe_in, ch_out;
    const char *tok;
    char line[200]; /* > (10 chars * IVAS_MAX_OUTPUT_CHANNELS) i.e. "-999,     " */
    FILE *mtxFile;

    if ( strlen( lfeRoutingMatrixFilePath ) < 1 )
    {
        return IVAS_ERR_FAILED_FILE_OPEN;
    }

    mtxFile = fopen( lfeRoutingMatrixFilePath, "r" );

    if ( !mtxFile )
    {
        return IVAS_ERR_FAILED_FILE_OPEN;
    }

    /* set default panning matrix to all zeros
       any subsequent issue in file reading will gracefully exit the function */
    for ( lfe_in = 0; lfe_in < IVAS_MAX_INPUT_LFE_CHANNELS; lfe_in++ )
    {
        set_zero( ( *lfePanMtx )[lfe_in], IVAS_MAX_OUTPUT_CHANNELS );
    }

    for ( lfe_in = 0, ch_out = 0; lfe_in < IVAS_MAX_INPUT_LFE_CHANNELS; lfe_in++ )
    {
        /* if EOF or a blank line is encountered, simply return */
        if ( ( fgets( line, 200, mtxFile ) == NULL ) && ( strcmp( line, "\n" ) == 0 ) && ( strcmp( line, "\r\n" ) == 0 ) )
        {
            fclose( mtxFile );
            return IVAS_ERR_OK;
        }

        for ( tok = strtok( line, "," ); tok && *tok; tok = strtok( NULL, ",\n" ) )
        {
            while ( *tok == ' ' )
            {
                tok++;
            }

            if ( *tok == '\0' )
            {
                continue;
            }
            if ( ch_out > IVAS_MAX_OUTPUT_CHANNELS )
            {
                break;
            }
            else
            {
                ( *lfePanMtx )[lfe_in][ch_out] = (float) atof( tok );
                ch_out++;
            }
        }
    }

    fclose( mtxFile );
    return IVAS_ERR_OK;
}
#endif

// VE2AT: possibly move these functions to cmdln_parser.c ?
static void convert_backslash(
    char *str )
+15 −3
Original line number Diff line number Diff line
@@ -57,8 +57,20 @@ cfg=./scripts/config/ci_linux.json
dly_profile=./scripts/dly_error_profiles/dly_error_profile_10.dat

if [ $BUILD -eq 1 ];then
	# Enable memory macros to find unbalanced memory allocations/deallocations
	# Does not implement full memory analysis
	make clean
	
    # Replace free -> free_, malloc -> malloc_, calloc -> calloc_
	./scripts/prepare_mem_dryrun.py

	# Enable WMOPS and disable DEBUGGING
	sed -i.bak -e "s/\/\*\s*\(#define\s*WMOPS\)\s*\*\//\1/g" lib_com/options.h
	sed -i.bak -e "s/\/\/\s*\(#define\s*WMOPS\)/\1/g"        lib_com/options.h
#	sed -i.bak -e "s/\s*\(#define\s*DEBUGGING\)/\/\*\1*\//g" lib_com/options.h

	make all -j

fi

./scripts/runIvasCodec.py -p $cfg -U 1 $WORKERS | tee smoke_test_output.txt
+3 −0
Original line number Diff line number Diff line
@@ -148,10 +148,13 @@
#define FIX_I59_DELAY_ROUNDING                          /* Issue 59: rounding in sample domain instead of nanosec for IVAS_ENC_GetDelay() and IVAS_DEC_GetDelay() */
#define FIX_FIX_I59                                     /* Issue 59:  small fix concerning LFE delay rounding */
#define FIX_245_RANGE_CODER_VOIP_MSAN                   /* Issue 245: fix use-of-uninitialized-value in range coder in VoIP mode */
#define REND_CFG_LFE                                    /* Issue 110: Configurable LFE handling for external renderer */
#define FIX_235                                         /* Issue 235: Deallocation of HR filter memory separately for lib_rend (ROM) and lib_util (from file) */
#define ENV_STAB_FIX                                    /* Contribution 23: HQ envelope stability memory fix */
#define STABILIZE_GIPD                                  /* FhG: Contribution 22: gIPD stabilization */
#define FIX_292_VBAP_CALLOC_REMOVAL                     /* Nokia: Fixes issue 292 by removing the remnant callocs */
#define FIX_293_EXT_RENDERER_CLI                        /* FhG: Fix bugs in external renderer CLI */
#define FIX_268                                         /* Issue 268: Add low cost dry-run of memory analysis */

/* ################## End DEVELOPMENT switches ######################### */
/* clang-format on */
+3 −0
Original line number Diff line number Diff line
@@ -45,6 +45,9 @@
#include "debug.h"
#endif
#include "jbm_jb4_inputbuffer.h"
#ifdef FIX_268
#include "wmc_auto.h"
#endif

#define WMC_TOOL_SKIP

Loading