Commit 7bd70129 authored by vaillancour's avatar vaillancour
Browse files

addition of lib_debug

parent 64894827
Loading
Loading
Loading
Loading

lib_debug/debug.c

0 → 100644
+845 −0
Original line number Diff line number Diff line
/******************************************************************************************************

   (C) 2022 Baseline Development Group with portions copyright Dolby International AB, Ericsson AB,
   Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
   Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies OY, Orange,
   Panasonic Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation. All Rights Reserved.

   This software is protected by copyright law and by international treaties.
   The Baseline Development Group consisting of Dolby International AB, Ericsson AB,
   Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
   Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies OY, Orange,
   Panasonic Corporation, Qualcomm Technologies, Inc., and VoiceAge Corporation retain full ownership
   rights in their respective contributions in the software. No license of any kind, including but not
   limited to patent license, of any foregoing parties is hereby granted by implication, estoppel or
   otherwise.

   This software is provided "AS IS", without any express or implied warranties. The software is in the
   development stage. It is intended exclusively for experts who have experience with such software and
   solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
   and/or fitness for a particular purpose are hereby disclaimed and excluded.

   Any dispute, controversy or claim arising under or in relation to providing this software shall be
   submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
   accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
   the United Nations Convention on Contracts on the International Sales of Goods.

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

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stdint.h>
#include "options.h"
//#include "prot.h"
#ifdef DEBUGGING
#include "debug.h"
#ifdef DEBUG_MODE_INFO
#ifdef DEBUG_MODE_INFO_TWEAK
#include <sys/stat.h>
#include <sys/types.h>
#endif
#endif
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#ifdef _WIN32
#include <direct.h>
#else
#endif
#include "wmops.h"


/*-------------------------------------------------------------------*
 * Global variables used for debugging but not under DEBUGGING flag
 *--------------------------------------------------------------------*/

#ifdef DEBUGGING
uint16_t g_nPrintedLines = 0;

int16_t g_verbose = 0; /* global variable for debugging */
#ifdef DEBUG_MODE_INFO
#ifdef DEBUG_MODE_INFO_TWEAK
char infoFolder[FILENAME_MAX];
#endif
#endif
#endif

FILE *DJB_delay = NULL; /* per-frame de-jitter buffer delay dump out file */

#ifdef DEBUGGING
int16_t debug_level = 0;
#endif

/*-------------------------------------------------------------------*
 * Read/write I/O tool
 *--------------------------------------------------------------------*/

#ifdef DEBUGGING
#define N_FILEPTR 500
#define N_DBGFLAG 100
#define N_DBGVAL  100
#define N_TYPES   6

static FILE *in_fileptr[N_FILEPTR];
static FILE *out_fileptr[N_FILEPTR];

static char *in_filename[N_FILEPTR];
static char *out_filename[N_FILEPTR];

static int16_t in_count = 0;
static int16_t out_count = 0;

static int16_t flag_count = 0;
static char *flag_name[N_DBGFLAG];
static int16_t val_count = 0;
static char *val_name[N_DBGVAL];
static char *val[N_DBGVAL];

static char *type_list[N_TYPES] = { "char", "short", "int", "long", "float", "double" };

static void setvalue(
    const char *value_name, /* i  : Value name         */
    const char *value       /* i  : Value as string    */
);

static int16_t make_dirs( const char *const pathname );

/*-------------------------------------------------------------------*
 * dbgwrite()
 *
 * Writes the buffer content to the specified file. If the file is not in the
 * debug file list, it is opened before write.
 *--------------------------------------------------------------------*/

int16_t dbgwrite(
    const void *const buffer, /* i  : Write buffer */
    const int16_t size,       /* i  : Element size */
    const int16_t count,      /* i  : Number of elements */
    const int16_t repeat,     /* i  : Number of times the elements are repeated */
#ifdef DEBUG_MODE_INFO_TWEAK
    const char *filename /* i  : Output file name */
#else
    const char *const filename
#endif
)
{
    int16_t index, i;
    void *tmp_buf;

#ifdef DEBUG_MODE_INFO
#ifdef DEBUG_MODE_INFO_TWEAK
    char filename_mod[FILENAME_MAX];
    int16_t textmode = 0;
    int16_t x = *(const int16_t *const) buffer; /* currently the textmode is only defined with "short" as input */
    memset( filename_mod, 0, FILENAME_MAX );
    tweakdbgfolder( filename, filename_mod, &textmode );
    if ( filename_mod[0] != 0 )
    {
        filename = filename_mod;
    }
#endif
#endif

    index = lookup( filename, (const char *const *) out_filename, out_count );

    if ( index == -1 )
    {
        if ( make_dirs( filename ) != 0 )
        {
            fprintf( stderr, "dbgwrite: Could not create directory structure for %s. Exiting..\n", filename );
            exit( -1 );
        }

        index = out_count;
        out_fileptr[index] = fopen( filename, "wb" );
        out_filename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) );
        strcpy( out_filename[index], filename );
        out_count++;
    }

    if ( out_fileptr[index] != NULL )
    {
        tmp_buf = calloc( count * repeat, size );
        if ( buffer != NULL )
        {
            for ( i = 0; i < repeat; i++ )
            {
                memcpy( (char *) tmp_buf + i * size * count, buffer, size * count );
            }
        }
#ifdef DEBUG_MODE_INFO
#ifdef DEBUG_MODE_INFO_TWEAK
        if ( 1 == textmode && 2 == size )
        { /* currently the textmode is only defined with "short" as input */
            fprintf( out_fileptr[index], "%d\n", x );
        }
        else
        {
#endif
#endif
            fwrite( tmp_buf, size * count * repeat, 1, out_fileptr[index] );
#ifdef DEBUG_MODE_INFO
#ifdef DEBUG_MODE_INFO_TWEAK
        }
#endif
#endif
        free( tmp_buf );
    }
    else
    {
        fprintf( stderr, "dbgwrite: Could not write to file: %s. Exiting..\n", filename );
        exit( -1 );
    }

    return 0;
}

/*-------------------------------------------------------------------*
 * dbgwrite_mat_repeat()
 *
 * Writes buffer a buffer containing a column-wise ordered matrix
 * to the specified file. If the file is not in the
 * debug file list, it is opened before write.
 *--------------------------------------------------------------------*/

void dbgwrite_mat_repeat( float *buffer,      /* i  : write buffer */
                          int16_t nRow,       /* i  : matrix size (rows) */
                          int16_t mCol,       /* i  : matrix size (columns) */
                          int16_t row_repeat, /* i  : number of times rows are repeated */
                          int16_t col_repeat, /* i  : number of times columns are repeated */
#ifdef DEBUG_MODE_INFO_TWEAK
                          const char *filename /* i  : Output file name */
#else
                          const char *const filename
#endif
)
{
    float *copy_buffer = calloc( nRow * row_repeat * mCol * col_repeat, sizeof( float ) );
    int16_t r, c, rr, cc;
    float *cp = &copy_buffer[0];
    float *colp;
    for ( c = 0; c < mCol; c++ )
    {
        for ( cc = 0; cc < col_repeat; cc++ )
        {
            colp = buffer + c * nRow;
            for ( r = 0; r < nRow; r++ )
            {
                for ( rr = 0; rr < row_repeat; rr++ )
                {
                    *( cp++ ) = *colp;
                }
                colp++;
            }
        }
    }

    dbgwrite( copy_buffer, sizeof( float ), nRow * row_repeat * mCol * col_repeat, 1, filename );
    free( copy_buffer );
}


/*-------------------------------------------------------------------*
 * dbgappend()
 *
 * Appends the buffer content to the specified file. If the file is not in the
 * debug file list, it is opened before first write.
 *--------------------------------------------------------------------*/

int16_t dbgappend(
    const void *const buffer, /* i  : Append buffer */
    const int16_t size,       /* i  : Element size */
    const int16_t count,      /* i  : Number of elements */
    const int16_t repeat,     /* i  : Number of times the elements are repeated */
#ifdef DEBUG_MODE_INFO_TWEAK
    const char *filename /* i  : Output file name */
#else
    const char *const filename
#endif
)
{
    int16_t index, i;

#ifdef DEBUG_MODE_INFO
#ifdef DEBUG_MODE_INFO_TWEAK
    char filename_mod[FILENAME_MAX];
    int16_t textmode = 0; /* textmode is only implemented in dbgwrite() currently */
    memset( filename_mod, 0, FILENAME_MAX );
    tweakdbgfolder( filename, filename_mod, &textmode );
    if ( filename_mod[0] != 0 )
    {
        filename = filename_mod;
    }
#endif
#endif
    index = lookup( filename, (const char *const *) out_filename, out_count );

    if ( index == -1 )
    {
        if ( make_dirs( filename ) != 0 )
        {
            fprintf( stderr, "dbgwrite: Could not create directory structure for %s. Exiting..\n", filename );
            exit( -1 );
        }

        index = out_count;
        out_fileptr[index] = fopen( filename, "ab" );
        out_filename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) );
        strcpy( out_filename[index], filename );
        out_count++;
    }

    if ( out_fileptr[index] != NULL )
    {
        for ( i = 0; i < repeat; i++ )
        {
            fwrite( buffer, size, count, out_fileptr[index] );
        }
    }
    else
    {
        fprintf( stderr, "dbgappend: Could not write to file: %s. Exiting..\n", filename );
        exit( -1 );
    }

    return 0;
}

/*-------------------------------------------------------------------*
 * dbgread()
 *
 * Reads data from the specified file. If the file is not open, it will be
 * opened.
 *--------------------------------------------------------------------*/

int16_t dbgread(
    void *const buffer,  /* o  : Read buffer        */
    const int16_t size,  /* i  : Element size       */
    const int16_t count, /* i  : Number of elements */
#ifdef DEBUG_MODE_INFO_TWEAK
    const char *filename /* i  : Input file name */
#else
    const char *const filename
#endif
)
{
    int16_t index;

#ifdef DEBUG_MODE_INFO
#ifdef DEBUG_MODE_INFO_TWEAK
    char filename_mod[FILENAME_MAX];
    int16_t textmode = 0; /* textmode is only implemented in dbgwrite() currently */
    memset( filename_mod, 0, FILENAME_MAX );
    tweakdbgfolder( filename, filename_mod, &textmode );
    if ( filename_mod[0] != 0 )
    {
        filename = filename_mod;
    }
#endif
#endif

    index = lookup( filename, (const char *const *) in_filename, in_count );

    if ( index == -1 )
    {
        index = in_count;
        in_fileptr[index] = fopen( filename, "rb" );
        in_filename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) );
        strcpy( in_filename[index], filename );
        in_count++;
    }

    if ( in_fileptr[index] != NULL )
    {
        fread( buffer, size, count, in_fileptr[index] );
    }
    else
    {
        fprintf( stderr, "dbgread: Could not read from file: %s. Exiting..\n", filename );
        exit( -1 );
    }

    return 0;
}

/*-------------------------------------------------------------------*
 * dbgclose()
 *
 * Closes opened files and frees allocated memory
 *--------------------------------------------------------------------*/

void dbgclose()
{
    int16_t i;

    for ( i = 0; i < in_count; i++ )
    {
        fclose( in_fileptr[i] );
        free( in_filename[i] );
    }

    for ( i = 0; i < out_count; i++ )
    {
        fclose( out_fileptr[i] );
        free( out_filename[i] );
    }
#if 0
    for ( i = 0; i < snr_count; i++ )
    {
        free( snr_name[i] );
    }
#endif
    for ( i = 0; i < flag_count; i++ )
    {
        free( flag_name[i] );
    }

    for ( i = 0; i < val_count; i++ )
    {
        free( val_name[i] );
        free( val[i] );
    }

    return;
}


/*-------------------------------------------------------------------*
 * dbgflag()
 *
 * Checks if a debug flag is set. The flag is identified with a string.
 *--------------------------------------------------------------------*/

int16_t dbgflag(
    const char *flagname /* i  : Flag name */
)
{
    int16_t result;

    result = lookup( flagname, (const char *const *) flag_name, flag_count );

    return ( result != -1 );
}

/*-------------------------------------------------------------------*
 * setflag()
 *
 * Sets the flag with the specified string
 *--------------------------------------------------------------------*/

void setflag(
    const char *flagname /* i  : Flag name */
)
{
    int16_t result;

    result = lookup( flagname, (const char *const *) flag_name, flag_count );

    if ( result == -1 )
    {
        flag_name[flag_count] = malloc( sizeof( char ) * ( strlen( flagname ) + 1 ) );
        strcpy( flag_name[flag_count], flagname );
        flag_count++;
    }

    return;
}

/*----------------------------------------------------------------------------*
 * dbgargs()
 *
 * N.B. Should be run before existing command line interpretation
 *
 * Command line interpreter for debug arguments. Removes the debug
 * arguments after interpretation so that existing command line interpretation
 * may be run afterwards.
 *
 * Arguments:
 * -D flag_name      Sets the debug flag labelled flag_name.
 *                   The function dbgflag("flag_name") will return 1.
 *
 * -V val_name val   Sets the debug value labelled val_name to val.
 *                   dbgvalue("type","val_name",&value) will retrieve the value
 *
 *-----------------------------------------------------------------------------*/

/*! r: No. debug arguments */
int16_t dbgargs(
    int32_t *argc, /* i/o: No. input arguments / No. arguments without dbg arguments */
    char *argv[]   /* i/o: Input arguments / Input arguments without dbg arguments   */
)
{
    int16_t i, j, dbgargs;

    i = 0;
    dbgargs = 0;
    while ( i < *argc )
    {
        if ( strcmp( argv[i], "-D" ) == 0 )
        {
            j = i;
            dbgargs++;
            i++;
            setflag( argv[i] );
            for ( ; j < *argc - 2; j++ )
            {
                argv[j] = argv[j + 2];
            }
            *argc -= 2;
            i -= 2;
        }

        if ( strcmp( argv[i], "-V" ) == 0 )
        {
            j = i;
            dbgargs++;
            i++;
            setvalue( argv[i], argv[i + 1] );
            for ( ; j < *argc - 3; j++ )
            {
                argv[j] = argv[j + 3];
            }
            *argc -= 3;
            i -= 3;
        }
        i++;
    }

    return dbgargs;
}

/*-------------------------------------------------------------------*
 * dbgvalue()
 *
 * Lookup a debug value
 *
 * Allowed typestr values:
 * "char","short","int","long","float","double"
 *
 * If the value is not set, the output value is not assigned
 *
 *-------------------------------------------------------------------*/

/*! r: Returns 1 if value is assigned, otherwise 0 */
int16_t dbgvalue(
    const char *typestr,    /* i  : Type as string:"int","char",...              */
    const char *value_name, /* i  : Value tag name given on command line         */
    ...                     /* o  : Output variable, type: pointer to "typestr"  */
)
{
    int16_t index;
    char *value;
    int16_t assigned;
    char *c;
    int16_t *sh;
    int *i;
    int32_t *l;
    float *f;
    double *d;
    va_list ap;
    va_start( ap, value_name );

    index = lookup( value_name, (const char *const *) val_name, val_count );

    if ( index != -1 )
    {
        value = val[index];
        index = lookup( typestr, (const char *const *) type_list, N_TYPES );
        switch ( index )
        {
            case 0:
                c = va_arg( ap, char * );
                sscanf( value, "%c", c );
                break;
            case 1:
                sh = va_arg( ap, int16_t * );
                sscanf( value, "%hi", sh );
                break;
            case 2:
                i = va_arg( ap, int * );
                sscanf( value, "%i", i );
                break;
            case 3:
                l = va_arg( ap, int32_t * );
                sscanf( value, "%i", l );
                break;
            case 4:
                f = va_arg( ap, float * );
                sscanf( value, "%f", f );
                break;
            case 5:
                d = va_arg( ap, double * );
                sscanf( value, "%lf", d );
                break;
            default:
                fprintf( stderr, "dbgvalue::Unsupported type string %s. Exiting...\n", typestr );
                exit( -1 );
        }
        assigned = 1;
    }
    else
    {
        assigned = 0;
    }

    va_end( ap );

    return assigned;
}

/*-------------------------------------------------------------------*
 * lookup()
 *
 * Returns the index of the given string, or -1 if not found
 *--------------------------------------------------------------------*/

/*! r: Index of string, -1 if not found */
int16_t lookup(
    const char *const str,         /* i  : String to lookup */
    const char *const *const list, /* i  : List of strings */
    const int16_t n_elem           /* i  : Number of elements */
)
{
    int16_t i, result;

    result = -1;
    i = 0;
    while ( i < n_elem && result == -1 )
    {
        if ( strcmp( str, list[i] ) == 0 )
        {
            result = i;
        }
        i++;
    }

    return result;
}

/*-------------------------------------------------------------------*
 * setvalue()
 *
 * Sets the debug name value pair
 *--------------------------------------------------------------------*/

static void setvalue(
    const char *value_name, /* i  : Value name         */
    const char *value )     /* i  : Value as string    */

{
    int16_t result;

    result = lookup( value_name, (const char *const *) val_name, val_count );

    if ( result == -1 )
    {
        val_name[val_count] = malloc( sizeof( char ) * ( strlen( value_name ) + 1 ) );
        strcpy( val_name[val_count], value_name );
        val[val_count] = malloc( sizeof( char ) * ( strlen( value ) + 1 ) );
        strcpy( val[val_count], value );
        val_count++;
        fprintf( stdout, "\nDebug value set: %s = %s\n", value_name, value );
    }
    else
    {
        fprintf( stdout, "\n*** Value %s already set: %s\n", value_name, val[result] );
    }

    return;
}

#ifdef DEBUG_MODE_INFO
#ifdef DEBUG_MODE_INFO_TWEAK
/*-------------------------------------------------------------------*
 * tweakdbgfolder()
 *
 * in: filename
 * out: filename_mod
 *
 * returns modified path to debug files for reading and writing functions.
 * creates <subfolder> in "./res" if given on command line
 * with switch -info <subfolder>.
 *
 *--------------------------------------------------------------------*/

int16_t tweakdbgfolder( const char *filename, char *filename_mod, int16_t *textmode )
{
    int16_t i, j;
    char *p_infoFolder = infoFolder;
    char *p_filename_mod = filename_mod;
    int16_t n_prefix = 0;
    char *suffix;

    /* if debug folder name given on command line, write debug info to sub folder */
    if ( infoFolder[0] != 0 )
    {
        if ( filename[0] == '.' )
        {
            n_prefix = 5;
        }
        else if ( filename[0] == 'r' )
        {
            n_prefix = 3;
        }
        else
        {
            fprintf( stderr, "tweakdbgfolder: Unexpected debug folder. Exiting..\n" );
            exit( -1 );
        }
        for ( i = 0; i <= n_prefix; i++ )
        {
            p_filename_mod[i] = filename[i];
        }
        j = i;
        while ( *p_infoFolder != 0 )
        {
            p_filename_mod[i] = *p_infoFolder;
            i++;
            p_infoFolder++;
        }
        p_filename_mod[i] = '/';
        i++;

        while ( filename[j] != 0 )
        {
            p_filename_mod[i] = filename[j];
            i++;
            j++;
        }
        /* detect textmode, only working with given debug folder name, otherwise no counter available for length of filename */
        suffix = &p_filename_mod[i - 4];
        if ( strncmp( suffix, ".txt", 4 ) == 0 )
        {
            *textmode = 1;
        }
        else
        {
            *textmode = 0;
        }
    }


    return 0;
}
#endif
#endif


#ifdef DEBUG_MODE_INFO
/*-------------------------------------------------------------------*
   * fname()
   *
   * returns file name (string) that identifies - parameter/signal to be outputted
                                                - channel ID (0 or 1)
                                                - element ID (0, 1, etc.)
   *--------------------------------------------------------------------*/

char debug_dir[6] = "res/";

char tmp_fname[FILENAME_MAX];

char *fname(
    char *dir,
    char *file,
    const int16_t n,
    const int16_t id,
    const int16_t enc_dec )
{
    char idd[5] = ".idX";
    idd[3] = (char) ( id + '0' );

    strcpy( tmp_fname, dir );
    strcat( tmp_fname, file );

    if ( enc_dec == DEC )
        strcat( tmp_fname, ".dec" );
    if ( id > 0 )
        strcat( tmp_fname, idd );
    if ( n > 0 )
        strcat( tmp_fname, ".ch2" );

    return tmp_fname;
}
#endif


/*-------------------------------------------------------------------*
 * make_dirs()
 *
 * extract path(s) form the pathname and create them if not existing
 *--------------------------------------------------------------------*/

int16_t make_dirs( const char *const pathname )
{
    const char *p;
    char *temp;
    char sep = 0;
#ifdef _WIN32
    struct _stat s = { 0 };
#else
    struct stat s = { 0 };
#endif
    /* find path separator */
    if ( strchr( pathname, '\\' ) != NULL )
    {
        sep = '\\';
    }
    else if ( strchr( pathname, '/' ) != NULL )
    {
        sep = '/';
    }

    if ( sep != 0 )
    {
        temp = calloc( 1, strlen( pathname ) + 1 );
        p = pathname;
        while ( ( p = strchr( p, sep ) ) != NULL )
        {
            /* skip consecutive separators and '.', '..' symbols */
            if ( p != pathname && ( *( p - 1 ) == sep || *( p - 1 ) == '.' ) )
            {
                p++;
                continue;
            }

            /* put the path up to this point into a temp dir */
            memcpy( temp, pathname, p - pathname );
            temp[p - pathname] = '\0';
            p++;

            /* check if path exists and create it with mkdir() if not */
#ifdef _WIN32
            if ( _stat( temp, &s ) == -1 )
            {
                if ( _mkdir( temp ) != 0 )
                {
                    if ( errno != 0 )
                    {
                        return 1;
                    }
                }
            }
#else
            if ( stat( temp, &s ) == -1 )
            {
                if ( mkdir( temp, 0755 ) != 0 )
                {
                    if ( errno != 0 )
                    {
                        return 1;
                    }
                }
            }
#endif
        }

        free( temp );
    }

    return 0;
}

#endif /* DEBUGGING */

lib_debug/debug.h

0 → 100644
+251 −0

File added.

Preview size limit exceeded, changes collapsed.

lib_debug/mem_count.c

0 → 100644
+906 −0

File added.

Preview size limit exceeded, changes collapsed.

lib_debug/mem_count.h

0 → 100644
+104 −0

File added.

Preview size limit exceeded, changes collapsed.

lib_debug/wmops.c

0 → 100644
+499 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading