Commit 8a2014c1 authored by malenovsky's avatar malenovsky
Browse files

Merge branch '1057-support-mode-enforcement-force-in-basop-framework' into 'main'

Resolve "Support mode enforcement (-force) in BASOP framework"

Closes #1057

See merge request !825
parents 47e354cc 9aa7a999
Loading
Loading
Loading
Loading
Loading
+251 −5
Original line number Diff line number Diff line
@@ -30,8 +30,13 @@

*******************************************************************************************************/

#include "lib_enc.h"
#include <string.h>
#include "options.h"
#ifdef DEBUGGING
#include "debug.h"
#endif
#include "stl.h"
#include "lib_enc.h"
#include "cmdl_tools.h"
#include "audio_file_reader.h"
#include "bitstream_writer.h"
@@ -39,9 +44,6 @@
#include "jbm_file_reader.h"
#include "masa_file_reader.h"
#include "wmc_auto.h"
#include "options.h"
#include "stl.h"


#define WMC_TOOL_SKIP

@@ -62,6 +64,10 @@ typedef union _EncInputFormatConfig
    /* MONO details */
    bool stereoToMonoDownmix;

#ifdef DEBUGGING
    /* STEREO details */
    IVAS_ENC_STEREO_MODE stereoMode;
#endif

    /* ISM details */
    struct EncIsmConfig
@@ -126,6 +132,10 @@ typedef struct
    const char *ca_config_file;
    bool mimeOutput;
    IVAS_ENC_COMPLEXITY_LEVEL complexityLevel;
#ifdef DEBUGGING
    IVAS_ENC_FORCED_MODE forcedMode;
    const char *forcedModeFile;
#endif
    bool pca;
    bool ism_extended_metadata;

@@ -141,6 +151,10 @@ static bool parseCmdlIVAS_enc( int16_t argc, char *argv[], EncArguments *arg );
static void usage_enc( void );
static bool readBandwidth( FILE *file, IVAS_ENC_BANDWIDTH *bandwidth, int32_t *bandwidthFrameCounter );
static bool readBitrate( FILE *file, int32_t *bitrate );
#ifdef DEBUGGING
static ivas_error readForcedMode( FILE *file, IVAS_ENC_FORCED_MODE *forcedMode, int32_t *forceFrameCounter );
static IVAS_ENC_FORCED_MODE parseForcedMode( char *forcedModeChar );
#endif


/*------------------------------------------------------------------------------------------*
@@ -168,6 +182,9 @@ int main(
    MasaFileReader *masaReader = NULL;
    IsmFileReader *ismReaders[IVAS_MAX_NUM_OBJECTS] = { NULL, NULL, NULL, NULL };
    int16_t *pcmBuf = NULL;
#ifdef DEBUGGING
    FILE *f_forcedModeProfile = NULL;
#endif

#ifdef WMOPS
    reset_wmops();
@@ -357,7 +374,11 @@ int main(
            }
            break;
        case IVAS_ENC_INPUT_STEREO:
#ifdef DEBUGGING
            if ( ( error = IVAS_ENC_ConfigureForStereo( hIvasEnc, arg.inputFs, totalBitrate, arg.max_bwidth_user, bandwidth, arg.dtxConfig, arg.is_binaural, arg.inputFormatConfig.stereoMode ) ) != IVAS_ERR_OK )
#else
            if ( ( error = IVAS_ENC_ConfigureForStereo( hIvasEnc, arg.inputFs, totalBitrate, arg.max_bwidth_user, bandwidth, arg.dtxConfig, arg.is_binaural ) ) != IVAS_ERR_OK )
#endif
            {
                fprintf( stderr, "\nIVAS_ENC_ConfigureForStereo failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) );
                goto cleanup;
@@ -505,6 +526,20 @@ int main(
        }
    }

#ifdef DEBUGGING
    IVAS_ENC_FORCED_MODE forcedMode = arg.forcedMode;
    int32_t force_profile_cnt = 0;

    if ( arg.forcedModeFile )
    {
        if ( ( f_forcedModeProfile = fopen( arg.forcedModeFile, "rb" ) ) == NULL )
        {
            fprintf( stderr, "\nError: Incorrect mode specification or the profile file could not be opened: %s\n\n", arg.forcedModeFile );
            usage_enc();
            goto cleanup;
        }
    }
#endif

    /*------------------------------------------------------------------------------------------*
     * Allocate input data buffer
@@ -639,6 +674,27 @@ int main(
            }
        }

#ifdef DEBUGGING
        if ( f_forcedModeProfile )
        {
            if ( ( error = readForcedMode( f_forcedModeProfile, &forcedMode, &force_profile_cnt ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "\nError reading from file: %s\n%s\n", arg.forcedModeFile, IVAS_ENC_GetErrorMessage( error ) );
                goto cleanup;
            }
        }

        /* Force mode not set when configuring, set in first frame even if not reading from file */
        if ( f_forcedModeProfile || frame == 0 )
        {
            if ( ( error = IVAS_ENC_SetForcedMode( hIvasEnc, forcedMode ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "\nIVAS_ENC_SetForcedMode failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) );
                goto cleanup;
            }
        }
#endif

        /* Read ISM input metadata */
        for ( i = 0; i < numIsmInputs; ++i )
        {
@@ -799,7 +855,10 @@ static void initArgStruct( EncArguments *arg )
    arg->mimeOutput = false;
    arg->ism_extended_metadata = false;
    arg->complexityLevel = IVAS_ENC_COMPLEXITY_LEVEL_THREE;

#ifdef DEBUGGING
    arg->forcedMode = IVAS_ENC_FORCE_UNFORCED;
    arg->forcedModeFile = NULL;
#endif
    arg->pca = false;

    return;
@@ -928,6 +987,29 @@ static bool parseCmdlIVAS_enc(
                return false;
            }
        }
#ifdef DEBUGGING
        /*-----------------------------------------------------------------*
         * Force specific mode
         *-----------------------------------------------------------------*/

        else if ( strcmp( argv_to_upper, "-FORCE" ) == 0 )
        {
            strncpy( stmp, argv[i + 1], sizeof( stmp ) );

            arg->forcedMode = parseForcedMode( stmp );

            if ( arg->forcedMode == IVAS_ENC_FORCE_UNDEFINED )
            {
                arg->forcedModeFile = argv[i + 1];
                fprintf( stdout, "Force switching file:   %s\n", argv[i + 1] );
            }
            else
            {
                fprintf( stdout, "Forcing codec to:       %s\n", argv[i + 1] );
            }

            i += 2;
        }
#ifdef DEBUG_MODE_INFO
#ifdef DEBUG_MODE_INFO_TWEAK
        /*-----------------------------------------------------------------*
@@ -941,6 +1023,7 @@ static bool parseCmdlIVAS_enc(
        }
#endif /* #ifdef DEBUG_MODE_INFO_TWEAK */
#endif /* #ifdef DEBUG_MODE_INFO */
#endif /* #ifdef DEBUGGING */

        /*-----------------------------------------------------------------*
         * deactivate delay compensation
@@ -1044,6 +1127,78 @@ static bool parseCmdlIVAS_enc(
        {
            i++;
            arg->inputFormat = IVAS_ENC_INPUT_STEREO;

#ifdef DEBUGGING
            if ( ( i < argc - 4 ) && argv[i][0] != 45 ) /* note: 45 corresponds to "-" */
            {
                if ( sscanf( argv[i], "%d", &tmp ) > 0 )
                {
                    if ( tmp == 1 )
                    {
                        arg->inputFormatConfig.stereoMode = IVAS_ENC_STEREO_MODE_DFT;
                        i++;
                    }
                    else if ( tmp == 2 )
                    {
                        arg->inputFormatConfig.stereoMode = IVAS_ENC_STEREO_MODE_TD;
                        i++;
                    }
                    else if ( tmp == 3 )
                    {
                        arg->inputFormatConfig.stereoMode = IVAS_ENC_STEREO_MODE_MDCT_DECISION;
#ifdef DEBUG_FORCE_MDCT_STEREO_MODE
                        i++;

                        /* force mdct stereo mode for debugging purposes */
                        if ( i < argc - 4 )
                        {
                            if ( sscanf( argv[i], "%d", &tmp ) > 0 )
                            {
                                if ( tmp == 0 )
                                {
                                    /* keep "DECISION" */
                                    arg->inputFormatConfig.stereoMode = IVAS_ENC_STEREO_MODE_MDCT_DECISION;
                                    i++;
                                }
                                else if ( tmp == 1 )
                                {
                                    arg->inputFormatConfig.stereoMode = IVAS_ENC_STEREO_MODE_MDCT_FORCE_LR;
                                    i++;
                                }
                                else if ( tmp == 2 )
                                {
                                    arg->inputFormatConfig.stereoMode = IVAS_ENC_STEREO_MODE_MDCT_FORCE_MS;
                                    i++;
                                }
                                else
                                {
                                    fprintf( stderr, "Error: Incorrect mdct stereo coding method (%d) specified\n\n", tmp );
                                    usage_enc();
                                    return false;
                                }
                            }
                        }
#endif
                    }
                    else
                    {
                        fprintf( stderr, "Error: Incorrect stereo mode (%d) specified\n\n", tmp );
                        usage_enc();
                        return false;
                    }
                }
                else
                {
                    fprintf( stderr, "Error: Stereo mode not specified.\n\n" ); /* in the debugging stage */
                    usage_enc();
                    return false;
                }
            }
            else
            {
                arg->inputFormatConfig.stereoMode = IVAS_ENC_STEREO_MODE_UNIFIED;
            }
#endif /* DEBUGGING */
        }
        else if ( strcmp( argv_to_upper, "-BINAURAL" ) == 0 )
        {
@@ -1640,6 +1795,10 @@ static void usage_enc( void )
    fprintf( stdout, "-pca                : activate PCA in SBA format FOA at 256 kbps \n" );
    fprintf( stdout, "-level level        : Complexity level, level = (1, 2, 3), will be defined after characterisation. \n" );
    fprintf( stdout, "                      Currently, all values default to level 3 (full functionality).\n" );
#ifdef DEBUGGING
    fprintf( stdout, "-force T            : Force specific mode, T = (speech, music, ACELP, GSC, TCX, HQ),\n" );
    fprintf( stdout, "                      alternatively, T can be a text file where each line contains \"nb_frames T\"\n" );
#endif
#ifdef DEBUG_MODE_INFO
#ifdef DEBUG_MODE_INFO_TWEAK
    fprintf( stdout, "-info <folder>      : specify subfolder name for debug output\n" );
@@ -1738,4 +1897,91 @@ static bool readBitrate(
}


#ifdef DEBUGGING
/*---------------------------------------------------------------------*
 * parseForcedMode()
 *
 *
 *---------------------------------------------------------------------*/

static IVAS_ENC_FORCED_MODE parseForcedMode(
    char *forcedModeChar )
{
    to_upper( forcedModeChar );

    if ( ( strcmp( forcedModeChar, "SPEECH" ) == 0 ) || ( strcmp( forcedModeChar, "'SPEECH'" ) == 0 ) ||
         ( strcmp( forcedModeChar, "0" ) == 0 ) )
    {
        return IVAS_ENC_FORCE_SPEECH;
    }
    if ( ( strcmp( forcedModeChar, "MUSIC" ) == 0 ) || ( strcmp( forcedModeChar, "'MUSIC'" ) == 0 ) || ( strcmp( forcedModeChar, "AUDIO" ) == 0 ) || ( strcmp( forcedModeChar, "'AUDIO'" ) == 0 ) || ( strcmp( forcedModeChar, "1" ) == 0 ) )
    {
        return IVAS_ENC_FORCE_MUSIC;
    }
    if ( ( strcmp( forcedModeChar, "ACELP" ) == 0 ) || ( strcmp( forcedModeChar, "'ACELP'" ) == 0 ) )
    {
        return IVAS_ENC_FORCE_ACELP;
    }
    if ( ( strcmp( forcedModeChar, "GSC" ) == 0 ) || ( strcmp( forcedModeChar, "'GSC'" ) == 0 ) )
    {
        return IVAS_ENC_FORCE_GSC;
    }
    if ( ( strcmp( forcedModeChar, "TCX" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX'" ) == 0 ) )
    {
        return IVAS_ENC_FORCE_TCX;
    }
    if ( ( strcmp( forcedModeChar, "HQ" ) == 0 ) || ( strcmp( forcedModeChar, "'HQ'" ) == 0 ) )
    {
        return IVAS_ENC_FORCE_HQ;
    }

    return IVAS_ENC_FORCE_UNDEFINED;
}


/*---------------------------------------------------------------------*
 * readForcedMode()
 *
 *
 *---------------------------------------------------------------------*/

static ivas_error readForcedMode(
    FILE *file,
    IVAS_ENC_FORCED_MODE *forcedMode,
    int32_t *forceFrameCounter )
{
    int16_t res;
    char stmp[8];

    if ( *forceFrameCounter == 0 )
    {
        /* read next force and number of frames from the profile file */
        while ( ( res = (int16_t) fscanf( file, "%d %7s", forceFrameCounter, stmp ) ) != 2 && feof( file ) )
        {
            rewind( file );
        }

        *forcedMode = parseForcedMode( stmp );

        if ( *forcedMode == IVAS_ENC_FORCE_UNDEFINED )
        {
            fprintf( stderr, "Error: incorect mode specification or the force profile file could not be opened: %s\n\n", stmp );
            return IVAS_ERR_WRONG_PARAMS;
        }

        if ( res != 2 && !feof( file ) )
        {
            fprintf( stderr, "Error: incorrect format of the force profile file (please ensure that it does not contain any empty lines)\n\n" );
            return IVAS_ERR_WRONG_PARAMS;
        }
    }

    /* current profile still active, only decrease the counter */
    ( *forceFrameCounter )--;

    return IVAS_ERR_OK;
}
#endif


#undef WMC_TOOL_SKIP
+11 −0
Original line number Diff line number Diff line
@@ -193,6 +193,17 @@
#define DEC_IVAS                        2               /* Index for IVAS decoder */
#define OUTPUT_Q 11

#ifdef DEBUGGING
#define FORCE_SPEECH                    100             /* debugging - force speech on the command line */
#define FORCE_MUSIC                     101             /* debugging - force music on the command line */
#define FORCE_ACELP                     102             /* debugging - force ACELP core on the command line */
#define FORCE_GSC                       103             /* debugging - force GSC core on the command line */
#define FORCE_TCX                       104             /* debugging - force TCX core on the command line */
#define FORCE_HQ                        105             /* debugging - force HQ core on the command line */
#define FORCE_TD_RENDERER               201
#define FORCE_CLDFB_RENDERER            202
#endif

enum{
    NB  = 0,                                            /* Indicator of 4 kHz bandwidth */
    WB  = 1,                                            /* Indicator of 8 kHz bandwidth */
+4 −0
Original line number Diff line number Diff line
@@ -882,6 +882,10 @@ enum fea_names

/* MDCT stereo modes */
#define SMDCT_MS_DECISION                       0
#ifdef DEBUG_FORCE_MDCT_STEREO_MODE
#define SMDCT_FORCE_LR                          1
#define SMDCT_FORCE_MS                          2
#endif

#define MAX_SFB                                 70                          /* Maximum number of stereo frequency bands = 64 + 6 for TCX after ACELP */

+7 −0
Original line number Diff line number Diff line
@@ -89,6 +89,9 @@ typedef enum
    IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED,
    IVAS_ERR_TSM_NOT_ENABLED,
    IVAS_ERR_FETCH_SIZE_NO_MULTIPLE_OF_5MS,
#ifdef DEBUGGING
    IVAS_ERR_INVALID_FORCE_MODE,
#endif

    /*----------------------------------------*
     *            input data errors           *
@@ -210,6 +213,10 @@ static inline const char *ivas_error_to_string( ivas_error error_code )
            return "Unexpected NULL pointer";
        case IVAS_ERR_METADATA_NOT_EXPECTED:
            return "Metadata input not expected for current configuration";
#ifdef DEBUGGING
        case IVAS_ERR_INVALID_FORCE_MODE:
            return "Invalid force mode";
#endif
        case IVAS_ERR_NOT_IMPLEMENTED:
            return "Not implemented";
        case IVAS_ERR_ISM_FILE_READER_INVALID_METADATA_FORMAT:
+4 −3
Original line number Diff line number Diff line
@@ -47,9 +47,10 @@

/*#define DEBUGGING*/                             /* Allows debugging message to be printed out during runtime */
#ifdef DEBUGGING
#define DEBUG_MODE_INFO /* define to output most important parameters to the subdirectory "res/" */
#define DEBUG_MODE_INFO_TWEAK /* enable command line switch to specify subdirectory for debug info output inside "./res/" */
/*#define DBG_WAV_WRITER*/ /* enable dbgwrite_wav() function for generating ".wav" files */
#define DEBUG_MODE_INFO                       /* Define to output most important parameters to the subdirectory "res/" */
#define DEBUG_MODE_INFO_TWEAK                 /* Enable command line switch to specify subdirectory for debug info output inside "./res/" */
#define DEBUG_FORCE_MDCT_STEREO_MODE      /* Force stereo mode decision for MDCT stereo: -stereo 3 1 forces L/R coding and -stereo 3 2 forces full M/S coding */
/*#define DBG_WAV_WRITER*/                    /* Enable dbgwrite_wav() function for generating ".wav" files */
#endif

#define SUPPORT_JBM_TRACEFILE                   /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */
Loading