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 + -
显示快捷键?