esignal.c

来自「speech signal process tools」· C语言 代码 · 共 1,936 行 · 第 1/3 页

C
1,936
字号
/* * Copyright (c) 1995 Entropic Research Laboratory, Inc. * All rights reserved. * * Permission to use, copy, modify, and distribute this Esignal (TM) * I/O software and its documentation for any purpose and without fee * is hereby granted, provided that the above copyright notice and this * statement of permission appears in all copies of the software as * well as in supporting documentation.  Entropic Research Laboratory, * Inc. makes no representations about the suitability of this * software for any purpose.  It is provided "as is" without express * or implied warranty. * * Esignal (TM) is a Trademark of Entropic Research Laboratory, Inc. *//* * Example programs for Esignal public external file format. * Utility; field specifications and lists; general I/O. * * Author:  Rod Johnson */static char *sccs_id = "@(#)esignal.c	1.11 10/6/97 ERL";#include <esignal.h>/* *  LOCAL FUNCTION DECLARATIONS *//* Used by FieldListLength, FieldOrder, and TypeOrder. */static int	    FieldArrayLength(FieldSpec **fields);/* Used by FieldOrder */static FieldSpec    **SubFieldOrder(FieldList list, char *prefix);/* Used by ReadPreamble */static int	    GetLine(char *buf, int len, FILE *file);static int	    GetLong(long *val, int len, FILE *file);/* Used by GetFieldOrdering */static int  LongVal(void *src, int type, long *dest);/* * GLOBAL VARIABLES */static short	Types[] ={    NO_TYPE,    ARRAY,    DOUBLE,    FLOAT,    LONG,    ULONG,    SHORT,    USHORT,    SCHAR,    UCHAR,    BOOL,    DOUBLE_COMPLEX,    FLOAT_COMPLEX,    LONG_COMPLEX,    SHORT_COMPLEX,    SCHAR_COMPLEX,    CHAR,    WCHAR};int	DebugMsgLevel;void	(*DebugMsgFunc)(char *msg);char	EsignalArch[] = ARCH;   /* Architecture string in native-mode				 * preambles.  Defined in Makefile				 *//* * PUBLIC FUNCTION DEFINITIONS * *** Miscellaneous * *** Debug output * *** Types * *** Field specs and field lists * *** General input/output *//* * *** MISCELLANEOUS * - StrDup * - LongProd *//* * Replacement for non-ANSI function strdup. */char *StrDup(char *str){    char    *cpy;    if (str == NULL)	return NULL;    cpy = (char *) malloc(1 + strlen(str));    if (cpy == NULL)	return NULL;    return strcpy(cpy, str);}/* * Product of array of longs (e.g. array length from dimensions). */longLongProd(int     n,	 long    *arr){    int     i;    long    prod;    prod = 1;    for (i = 0; i < n; i++)	prod *= arr[i];    return prod;}/* * *** DEBUG OUTPUT * - DebugPrint */voidDebugPrint(char *msg){    fprintf(stderr, "%s\n", msg);}/* * *** TYPES * - ValidType * - TypeName * - TypeCode * - InternTypeSize * - ExternTypeSize *//* * Does type code denote either NO_TYPE or supported data * type? */intValidType(int type    /* numeric data-type code */ ){    switch (type)    {	/* All non-default cases fall through. */    case NO_TYPE:    case ARRAY:    case DOUBLE:    case FLOAT:    case LONG:    case ULONG:    case SHORT:    case USHORT:    case SCHAR:    case UCHAR:    case BOOL:    case DOUBLE_COMPLEX:    case FLOAT_COMPLEX:    case LONG_COMPLEX:    case SHORT_COMPLEX:    case SCHAR_COMPLEX:    case CHAR:    case WCHAR:	return TRUE;    default:	return FALSE;    }}/* * String containing name of data type. */char *TypeName(int type    /* numeric data-type code */ ){    switch (type)    {    case NO_TYPE:	return "NO_TYPE";    case ARRAY:	return "ARRAY";    case DOUBLE:	return "DOUBLE";    case FLOAT:	return "FLOAT";    case LONG:	return "LONG";    case ULONG:	return "ULONG";    case SHORT:	return "SHORT";    case USHORT:	return "USHORT";    case SCHAR:	return "SCHAR";    case UCHAR:	return "UCHAR";    case BOOL:	return "BOOL";    case DOUBLE_COMPLEX:	return "DOUBLE_COMPLEX";    case FLOAT_COMPLEX:	return "FLOAT_COMPLEX";    case LONG_COMPLEX:	return "LONG_COMPLEX";    case SHORT_COMPLEX:	return "SHORT_COMPLEX";    case SCHAR_COMPLEX:	return "SCHAR_COMPLEX";    case CHAR:	return "CHAR";    case WCHAR:	return "WCHAR";    default:    /* Invalid code. */	return NULL;    }}/* * Return data-type code for type with a given name. */intTypeCode(char *name){    int     num_types = sizeof(Types)/sizeof(Types[0]);    int     i;    char    *code;    if (name == NULL)	return 0;    for (i = 0; i < num_types; i++)    {	code = TypeName(Types[i]);	if (code != NULL && strcmp(code, name) == 0)	    return Types[i];    }    return 0;}/* * Number of bytes of memory to allocate for an item of a given type. */longInternTypeSize(int type		/* numeric data_type code */ ){    switch (type)    {    case ARRAY:	return sizeof(Array);    case DOUBLE:	return sizeof(double);    case FLOAT:	return sizeof(float);    case LONG:    case ULONG:	return sizeof(long);    case SHORT:    case USHORT:	return sizeof(short);    case SCHAR:	return sizeof(Schar);    case UCHAR:	return sizeof(Uchar);    case BOOL:	return sizeof(Bool);    case DOUBLE_COMPLEX:	return sizeof(DoubleComplex);    case FLOAT_COMPLEX:	return sizeof(FloatComplex);    case LONG_COMPLEX:	return sizeof(LongComplex);    case SHORT_COMPLEX:	return sizeof(ShortComplex);    case SCHAR_COMPLEX:	return sizeof(ScharComplex);    case CHAR:	return sizeof(char);    case WCHAR:	return sizeof(Wchar);    default:    /* Invalid code or NO_TYPE. */	return 0;    }}/* * Number of bytes of external storage occupied by an item of a given type * in a file with a given format. */longExternTypeSize(int type,	       int arch){    switch (arch)    {    case EDR1:	return EdrTypeSize(type, EDR1);	break;    case EDR2:	return EdrTypeSize(type, EDR2);	break;    case NATIVE:	return NativeTypeSize(type);	break;    case ASCII:	return -1;	break;    default:	return -1;	break;    }}/* * *** FIELD SPECS AND FIELD LISTS * - NewFieldSpec * - FreeFieldSpec * - FreeFieldList * - FreeAxisNames	(used only in esig_asc.c) * - FieldLength * - FieldListLength * - FindField * - GetField		(used only in FindField, higher-level API) * - FirstComponent	(used only in FindField, higher-level API) * - AddField * - AddSubfield * - FieldOrder * - TypeOrder * - GetFieldOrdering * - SetFieldOrdering *//* * Create a new FieldSpec structure. */FieldSpec *NewFieldSpec(int    type,	/* numeric code for data type */	     int    rank)	/* number of dimensions */{    FieldSpec	*field;		/* new FieldSpec structure */    /* Check for bad arguments. */    if (!ValidType(type) || rank < 0)	return NULL;    /* Allocate new struct. */    field = (FieldSpec *) malloc(sizeof(*field));    if (field == NULL)	return NULL;    /* Fill in default values for members. */    field->type = type;    field->rank = rank;    if (type == NO_TYPE || rank == 0)	field->dim = NULL;    else    {	/* Allocate dimension vector according to rank. */	field->dim = (long *) malloc(rank * sizeof(long));	if (field->dim == NULL)	{	    free(field);	    return NULL;	}    }    field->occurrence = REQUIRED;    field->name = NULL;    field->subfields = NULL;    field->units = NULL;    field->scale = 1.0;    field->offset = 0.0;    field->axis_names = NULL;    field->data = NULL;    field->present = TRUE;    field->fullname = NULL;    return field;}/* * Free storage for a field specification, not including the subfield * list. */voidFreeFieldSpec(FieldSpec *spec){    int     i;    if (spec == NULL)	return;    if (spec->name != NULL)	free(spec->name);    if (spec->dim != NULL)	free(spec->dim);    if (spec->units != NULL)	free(spec->units);    if (spec->axis_names != NULL)    {	for (i = 0; i < spec->rank; i++)	    if (spec->axis_names[i] != NULL)		free(spec->axis_names[i]);	free(spec->axis_names);    }    if (spec->data != NULL)	free(spec->data);    if (spec->fullname != NULL)	free(spec->fullname);    free(spec);}/* * Free storage for a field list, including all field specifications, * and (recursively) their subfield lists. */voidFreeFieldList(FieldList list){    int     i;    if (list == NULL)	return;    for (i = 0; list[i] != NULL; i++)    {	FreeFieldList(list[i]->subfields);	FreeFieldSpec(list[i]);    }    free(list);}/* * Free all non-NULL elements of a string array and the array itself. * Used within the Esignal I/O package, but outside this file (e.g. in * esig_asc.c); hence the declaration is non-static. * Not part of the public interface. */voidFreeAxisNames(char  **axis_names,	      int   rank){    int     i;    if (axis_names != NULL)    {	for (i = 0; i < rank; i++)	    if (axis_names[i] != NULL)		free(axis_names[i]);	free(axis_names);    }}/* * Number of array elements of a field.  Zero in case of error. */longFieldLength(FieldSpec *field){    if (field == NULL	|| field->rank != 0 && field->dim == NULL	|| field->type == NO_TYPE)    {	return 0;    }    return LongProd(field->rank, field->dim);}/* * Number of top-level fields on a field list. */intFieldListLength(FieldList list){    /* This depends on field lists being implemented as     * NULL-terminated arrays of pointers. */    return FieldArrayLength(list);}/* * Find field specification with given full name on given * field list (including tree of subfields). */FieldSpec *FindField(FieldList list,	/* field list */	  char      *name)	/* full name of field */{    char	*prefix;	/* first component of name */    char	*tail;		/* rest of name after prefix */    FieldSpec	*ancestor;	/* parent of named field spec				   (or parent of parent ...). */    FieldSpec	*field;		/* named field spec */    /* Check for bad or empty arguments. */    if (list == NULL || *list == NULL || name == NULL)	return NULL;    /* Parse name. */    tail = strchr(name, DOT);    /* Handle simple case immediately or complex case by       recursion. */    if (tail == NULL)		/* Just one component. */	return GetField(list, name);    else			/* Multi-component name. */    {	tail++;			/* Skip over dot. */	prefix = FirstComponent(name);	if (prefix == NULL)	    return NULL;	ancestor = GetField(list, prefix);	if (ancestor == NULL)	/* Search failed. */	    field = NULL;	else			/* Descend into subfields. */	    field = FindField(ancestor->subfields, tail);	free(prefix);	return field;    }}/* * Find field specification with given name at top level on given * field list.  Used in FindField. * Also used outside this file, in the higher-level API; * hence the declaration is non-static. * Not part of the public interface. */FieldSpec *GetField(FieldList  list,	/* field list */	 char	    *name)	/* component name */{    int	    i;			/* index into list */    if (list == NULL || name == NULL)	return NULL;    /* Search NULL-terminated list for field spec with matching name. */    for (i = 0;	 list[i] != NULL && strcmp(name, list[i]->name) != 0;	 i++)    { }    return list[i];}/* * Copy first component of field name: everything up to * first dot if any or whole string if none.  Used in FindField. * Also used outside this file, in the higher-level API; * hence the declaration is non-static. * Not part of the public interface. */char *FirstComponent(char *name){    char    *tail;		/* pointer to first dot */    long    len;		/* length of first component */    int	    terminator;		/* delimiting char: '.' or null */    char    *head;		/* copy of first component */    char    *p;			/* pointer into copy */    if (name == NULL)	return NULL;    /* Parse name. */    tail = strchr(name, DOT);    if (tail == NULL)		/* Just one component. */    {	len = strlen(name);	terminator = '\0';

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?