esig_asc.c

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

C
3,198
字号
/* * 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. * elib (R) is a Registered Trademark of Entropic Research Laboratory, * Inc. *//* * Example programs for Esignal public external file format. * Ascii I/O. * * Author:  Rod Johnson */static char *sccs_id = "@(#)esig_asc.c	1.11 11/21/95 ERL";#include <esignal.h>#include <ctype.h>/* * LOCAL CONSTANTS */#define MAX_FLD_DEPTH	200#define STR_ALLOC_SIZE	100#define Q(X)        QUOTE(X)#define QUOTE(X)    #X#define DBL_W       23#define DBL_FMT     "%.16g"#define DBL_WFMT    "%#" Q(DBL_W) ".16g"#define FLT_W       14#define FLT_FMT     "%.8g"#define FLT_WFMT    "%#" Q(FLT_W) ".8g"#define LNG_W       11#define LNG_FMT     "%ld"#define LNG_WFMT    "%" Q(LNG_W) "ld"#define ULN_W       11#define ULN_FMT     "%lu"#define ULN_WFMT    "%" Q(ULN_W) "lu"#define SHR_W       6#define SHR_FMT     "%d"#define SHR_WFMT    "%" Q(SHR_W) "d"#define USH_W       5#define USH_FMT     "%u"#define USH_WFMT    "%" Q(USH_W) "u"#define SCH_W       4#define SCH_FMT     "%d"#define SCH_WFMT    "%" Q(SCH_W) "d"#define UCH_W       3#define UCH_FMT     "%u"#define UCH_WFMT    "%" Q(UCH_W) "u"#define DBLCX_W     DBL_W#define DBLCX_FMT   DBL_FMT " " DBL_FMT#define DBLCX_WFMT  "(" DBL_WFMT ", " DBL_WFMT ")"#define FLTCX_W     FLT_W#define FLTCX_FMT   FLT_FMT " " FLT_FMT#define FLTCX_WFMT  "(" FLT_WFMT ", " FLT_WFMT ")"#define LNGCX_W     LNG_W#define LNGCX_FMT   LNG_FMT " " LNG_FMT#define LNGCX_WFMT  "(" LNG_WFMT ", " LNG_WFMT ")"#define SHRCX_W     SHR_W#define SHRCX_FMT   SHR_FMT " " SHR_FMT#define SHRCX_WFMT  "(" SHR_WFMT ", " SHR_WFMT ")"#define SCHCX_W     SCH_W#define SCHCX_FMT   SCH_FMT " " SCH_FMT#define SCHCX_WFMT  "(" SCH_WFMT ", " SCH_WFMT ")"#define CHR_W       2#define WCH_W       6/* *  LOCAL FUNCTION DECLARATIONS *//* Functions for input */static int  ReadAsciiData(FieldSpec *field, FILE *file);static int  ReadAsciiArray(Array *array, FILE *file);static int  ReadAsciiFieldSpec(FieldSpec **field, int depth,			       char **names, FILE *file);static int  ReadAsciiFieldStruct(FieldSpec **field,			       char *name, FILE *file);static int  ReadAsciiName(int depth, char **names, FILE *file);static int  ReadAsciiType(short *type, FILE *file);static int  ReadAsciiDims(short *rank, long**dim, FILE *file);static int  ReadAsciiMisc(int rank, char **units,			  double *scale, double *offset,			  char ***axis_names, FILE *file);static int  ReadAsciiString(char **string, FILE *file);static int  ReadAsciiDouble(double *x, FILE *file);static int  ReadAsciiAxisNames(char ***axis_names,			       int rank, FILE *file);static int  ReadAsciiOccurrence(short *occurrence, FILE *file);static int  AsciiRead(void *data, int type, long length, FILE *file);static int  ReadAsciiEscape(unsigned long *val, FILE *file);static int  ReadAsciiNewline(FILE *file);static int  SkipSpace(int ch, FILE *file);static int  SkipComment(FILE *file);static int  GetNonSpace(FILE *file);static int  ReadSpace(FILE *file);static int  ReadOptSpace(FILE *file);static int  AddChar(int ch, char **str, long *alloc_len, long *len);/* Functions for output */static int  WriteAsciiData(FieldSpec *field,			   FILE *file, Annot *annotate);static int  AsciiWriteSub(void *data, int type, long length,			  FILE *file, int rank, long *dim, Annot *annotate);static int  AsciiWrite(void *data, int type,		       long length, FILE *file, Annot *annotate);static int  WriteAsciiArray(Array *array, FILE *file, Annot *annotate);static int  WriteAsciiFieldSpec(FieldSpec *field,				int depth, FILE *file, Annot *annotate);static int  WriteAsciiString(char *data, FILE *file);static int  AsciiWriteChar(char *data, long length, FILE *file);static int  AsciiWriteWchar(Wchar *data, long length, FILE *file);static long ApproxWidth(int type);/* * PUBLIC FUNCTION DEFINITIONS * - ReadAsciiFieldList * - ReadAsciiRecord * - ReadAsciiSamples * - WriteAsciiFieldList * - WriteAsciiRecord * - WriteAsciiSamples *//* * Read field list in Ascii format from file.  Return TRUE on success, * FALSE on failure. */intReadAsciiFieldList(FieldList	*listp,		   FILE		*file){    static char	*names[MAX_FLD_DEPTH]; /* field name components */    FieldList	list;    int		name_len;	/* number of name components */    FieldSpec	*spec;    if (file == NULL)    {	DebugMsg(1, "ReadAsciiFieldList: NULL file");	return FALSE;    }    list = NULL;    name_len = ReadAsciiName(0, names, file);    while (name_len == 1)    {	name_len = ReadAsciiFieldSpec(&spec, 1, names, file);	if (spec == NULL || !AddField(&list, spec))	{	    if (list != NULL)		 FreeFieldList(list);	    DebugMsg(2, ((spec == NULL)			 ? "ReadAsciiFieldList: couldn't read field spec."			 : ("ReadAsciiFieldList: "			    "couldn't add field spec to list.")));	    return FALSE;	}    }    if (listp != NULL)	*listp = list;    if (name_len != 0)    {	DebugMsg(1, "ReadAsciiFieldList: bad name length.");	return FALSE;    }    return TRUE;}/* * Read one record in Ascii format from file into the "data" members of * the field specs on a NULL-terminated linear array of REQUIRED and * OPTIONAL fields, like those produced by TypeOrder and FieldOrder. * Return TRUE on success, FALSE on failure. */intReadAsciiRecord(FieldSpec **fields,		FILE      *file){    int     ch;    long    i;    if (file == NULL || fields == NULL)    {	DebugMsg(1, "ReadAsciiRecord: NULL argument.");	return FALSE;    }    for (i = 0 ; fields[i] != NULL; i++)    {	if (fields[i]->occurrence == OPTIONAL)	{	    if (!ReadOptSpace(file))	    {		DebugMsg(2, "ReadAsciiRecord: EOF encountered.");		return FALSE;	    }	    ch = getc(file);	    if (ch == '*')	    {		fields[i]->present = FALSE;	    }	    else	    {		fields[i]->present = TRUE;		ungetc(ch, file);		if (!ReadAsciiData(fields[i], file))		{		    DebugMsg(2, ("ReadAsciiRecord: "				 "couldn't read data for OPTIONAL field."));		    return FALSE;		}	    }	}	else		/* REQUIRED field */	{	    if (!ReadAsciiData(fields[i], file))	    {		DebugMsg(1, ("ReadAsciiRecord: "			     "couldn't read data for REQUIRED field."));		return FALSE;	    }	}	if (!ReadSpace(file))	{	    DebugMsg(1, ("ReadAsciiRecord: "			 "couldn't skip space at end of field."));	    return FALSE;	}    }    return TRUE;}/* * Read nrec one-field records in Ascii format from file into the array * indicated by data.  The field is specified by fields, * a NULL-terminated linear array like those produced by TypeOrder * and FieldOrder and containing exactly one REQUIRED field. * Return the number of complete records read. */longReadAsciiSamples(void	    *data,		 long	    nrec,		 FieldSpec  **fields,		 FILE	    *file){    int		type;    long	length;    FieldSpec	*field;    if (data == NULL)    {	DebugMsg(1, "ReadAsciiSamples: NULL data pointer.");	return 0;    }    if (nrec < 0)    {	DebugMsg(1, ("ReadAsciiSamples: "		     "negative number or records specified."));	return 0;    }    if (fields == NULL || (field = fields[0]) == NULL || fields[1] != NULL	|| field->occurrence != REQUIRED)    {	DebugMsg(1, "ReadAsciiSamples: bad \"fields\" array.");	return 0;    }    if (file == NULL)    {	DebugMsg(1, "ReadAsciiSamples: NULL file pointer.");	return 0;    }    type = field->type;    if (type == NO_TYPE)	return 0;    length = FieldLength(field);    if (nrec*length == 0)	return nrec;    return AsciiRead(data, type, nrec*length, file) / length;}/* * Write field list to file in Ascii format. * If annotate != NULL, add annotations in "[]" for readability. * Return TRUE on success, FALSE on failure. */intWriteAsciiFieldList(FieldList list,		    FILE      *file,		    Annot     *annotate){    int     i;			/* loop index */    if (file == NULL || list == NULL)    {	DebugMsg(1, "WriteAsciiFieldList: NULL argument.");	return FALSE;    }    for (i = 0; list[i] != NULL; i++)	if (!WriteAsciiFieldSpec(list[i], 1, file, annotate))	{	    DebugMsg(1, "WriteAsciiFieldList: Failed writing field spec.");	    return FALSE;	}    return TRUE;		/* Success. */}/* * Write to file one record in Ascii format, consisting of the contents * of the "data" members of the field specs on a NULL-terminated linear * array of REQUIRED and OPTIONAL fields, like those produced by * TypeOrder and FieldOrder. * If annotate != NULL, add annotations in "[]" for readability. * Return TRUE on success, FALSE on failure. */intWriteAsciiRecord(FieldSpec **fields,	/* linear array of fields */		 FILE      *file,	/* output file */		 Annot     *annotate)	/* supply annotations? */{    long	i;    FieldSpec	*field;    /* Check arguments. */    if (file == NULL || fields == NULL)    {	DebugMsg(1, "WriteAsciiRecord: NULL argument.");	return FALSE;    }    /* Write record number if annotating. */    if (annotate != NULL)    {	fprintf(file, "[Record %ld]\n", annotate->recnum);	annotate->recnum++;	annotate->indent = 4;    }    /* Traverse NULL-terminated list of fields. */    for (i = 0; (field = fields[i]) != NULL; i++)    {	if (annotate != NULL)	/* Write field name if annotating. */	{	    fprintf(file, "  [%s]", field->fullname);	}	if (field->occurrence == OPTIONAL && !field->present)	    fprintf(file, (annotate != NULL) ? " *\n" : "*\n");	else	{	    if (annotate != NULL && field->rank == 0)		fprintf(file, "  ");	    if (WriteAsciiData(field, file, annotate))		fprintf(file, "\n");	    else	    {		DebugMsg(1, "WriteAsciiRecord: Failed writing field.");		return FALSE;	    }	}    }    return TRUE;		/* Success. */}/* * Write nrec one-field records in Ascii format to file from the * array indicated by data.  The field is specified by fields, a * NULL-terminated linear array like those produced by TypeOrder * and FieldOrder and containing exactly one REQUIRED field. * Return the number of complete records written. */longWriteAsciiSamples(void	    *data,		  long	    nrec,		  FieldSpec **fields,		  FILE	    *file,		  Annot	    *annotate){    int		type;    long	length;    long	rtn;    FieldSpec	*field;    int		i, rank;    long	j, step, stride, recnum;    if (data == NULL)    {	DebugMsg(1, "WriteAsciiSamples: NULL data pointer.");	return 0;    }    if (nrec < 0)    {	DebugMsg(1, ("WriteAsciiSamples: "		     "negative number of records specified."));	return 0;    }    if (fields == NULL || (field = fields[0]) == NULL || fields[1] != NULL	|| field->occurrence != REQUIRED)    {	DebugMsg(1, "WriteAsciiSamples: bad \"fields\" array.");	return 0;    }    if (file == NULL)    {	DebugMsg(1, "WriteAsciiSamples: NULL file pointer.");	return 0;    }    type = field->type;    if (type == NO_TYPE)	return 0;    length = FieldLength(field);    if (nrec*length == 0)	return nrec;    if (annotate == NULL)    {	rtn = AsciiWrite(data, type, nrec*length, file, annotate) / length;    }    else    {	rank = field->rank;	recnum = annotate->recnum;	annotate->recnum += nrec;	if (length == 1)	{	    if (type == ARRAY)		step = 1;	    else	    {		step = (annotate->width - annotate->indent - 3*rank + 1)		    / ApproxWidth(type);		if (step < 1)		    step = 1;	    }	    stride = step*InternTypeSize(type);	    for (j = 0; nrec > 0; j += step, nrec -= step)	    {		if (j > 0)		{		    fprintf(file, "\n");		    data = (char *) data + stride;		}		annotate->indent =		    fprintf(file, "[%ld]", j + recnum)			+ 3*rank + 2;		for (i = 0; i < rank; i++)		    fprintf(file, "[0]");		fprintf(file, "  ");		AsciiWrite(data, type,			   (nrec < step) ? nrec : step, file, annotate);	    }	}	else	{	    stride = length*InternTypeSize(type);	    for (j = 0; j < nrec; j++)	    {		if (j > 0)		    fprintf(file, "\n");		annotate->indent =		    fprintf(file, "[%ld]", j + recnum);		AsciiWriteSub(j*stride + (char *) data, type, length,			      file, rank, field->dim, annotate);	    }	}	annotate->indent = 0;    }    fprintf(file, "\n");    return rtn;}/* * LOCAL FUNCTION DEFINITIONS *//* * *** FUNCTIONS FOR INPUT *//* * Read Ascii data from file into the "data" member of field. * The number of elements and the data type are obtained from field. * If field->data is NULL, allocate space before reading the data. * Return TRUE on success, FALSE on failure. */static intReadAsciiData(FieldSpec *field, FILE *file){    size_t  size;    long    length;    if (file == NULL || field == NULL)    {	DebugMsg(1, "ReadAsciiData: NULL arguments.");	return FALSE;    }    if (field->type == NO_TYPE)    {	DebugMsg(1, "ReadAsciiData: type NO_TYPE.");	return FALSE;    }    size = InternTypeSize(field->type);    length = FieldLength(field);    if (length == 0)	return TRUE;    if (field->data == NULL)    {	field->data = malloc(length * size);	if (field->data == NULL)	{	    DebugMsg(1, "ReadAsciiData: allocation failure.");	    return FALSE;	}    }    return (AsciiRead(field->data, field->type, length, file) == length);}/* * Read from file the Ascii representation of an item of type ARRAY, * not including the surrounding parentheses.  Store the type, rank, * dimensions, and data in the members of the array structure, * allocating the necessary space for dimensions and data. * Return TRUE for success, FALSE for failure. */static intReadAsciiArray(Array	*array,	       FILE	*file){    short   type;    short   rank;    long    *dim;    void    *data;    size_t  size;    long    length;    int     ch;    if (!ReadAsciiType(&type, file))    {	DebugMsg(1, "ReadAsciiArray: couldn't read type.");	return FALSE;    }    if (type == NO_TYPE)    {	DebugMsg(1, "ReadAsciiArray: type NO_TYPE.");	return FALSE;

⌨️ 快捷键说明

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