esig_edr.c

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

C
2,690
字号
/* * 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. * EDR1 and EDR2 portable binary I/O. * * Author:  Rod Johnson */static char *sccs_id = "@(#)esig_edr.c	1.7 11/21/95 ERL";#include <esignal.h>/* * LOCAL CONSTANTS *//* *  LOCAL FUNCTION DECLARATIONS *//* Functions for input */static int	    ReadEdrData(FieldSpec *field,				FILE *file, int longlong);static FieldSpec    *ReadEdrFieldSpec(FILE *file, int longlong);static int	    ReadEdrString(char **string,				  FILE *file, int longlong);static int	    EdrRead(void *data, int type,			    long length, FILE *file, int longlong);static int	    ReadEdrArray(Array *array,				 FILE *file, int longlong);static int	    EdrReadArray(Array *data,				 long length, FILE *file, int longlong);static int	    EdrReadDouble(double *data,				  long length, FILE *file);static int	    EdrReadFloat(float *data,				 long length, FILE *file);static int	    EdrReadLong(long *data,				long length, FILE *file, int longlong);static int	    EdrReadUlong(Ulong *data,				 long length, FILE *file, int longlong);static int	    EdrReadShort(short *data,				 long length, FILE *file);static int	    EdrReadUshort(Ushort *data,				  long length, FILE *file);static int	    EdrReadSchar(Schar *data,				 long length, FILE *file);static int	    EdrReadUchar(Uchar *data,				 long length, FILE *file);static int	    EdrReadBool(Bool *data,				long length, FILE *file);static int	    EdrReadDoubleComplex(DoubleComplex *data,					 long length, FILE *file);static int	    EdrReadFloatComplex(FloatComplex *data,					long length, FILE *file);static int	    EdrReadLongComplex(LongComplex *data, long length,				       FILE *file, int longlong);static int	    EdrReadShortComplex(ShortComplex *data,					long length, FILE *file);static int	    EdrReadScharComplex(ScharComplex *data,					long length, FILE *file);static int	    EdrReadChar(char *data,				long length, FILE *file);static int	    EdrReadWchar(Wchar *data,				 long length, FILE *file);/* Functions for output */static int	    WriteEdrData(FieldSpec *field,				 FILE *file, int longlong);static int	    WriteEdrFieldSpec(FieldSpec *field,				      FILE *file, int longlong);static int	    WriteEdrString(char *string,				   FILE *file, int longlong);static int	    EdrWrite(void *data, int type,			     long length, FILE *file, int longlong);static int	    WriteEdrArray(Array *array,				  FILE *file, int longlong);static int	    EdrWriteArray(Array *data, long length,				  FILE *file, int longlong);static int	    EdrWriteDouble(double *data,				   long length, FILE *file);static int	    EdrWriteFloat(float *data, long length, FILE *file);static int	    EdrWriteLong(long *data,				 long length, FILE *file, int longlong);static int	    EdrWriteUlong(Ulong *data,				  long length, FILE *file, int longlong);static int	    EdrWriteShort(short *data, long length, FILE *file);static int	    EdrWriteUshort(Ushort *data, long length, FILE *file);static int	    EdrWriteSchar(Schar *data, long length, FILE *file);static int	    EdrWriteUchar(Uchar *data, long length, FILE *file);static int	    EdrWriteBool(Bool *data, long length, FILE *file);static int	    EdrWriteDoubleComplex(DoubleComplex *data,					  long length, FILE *file);static int	    EdrWriteFloatComplex(FloatComplex *data,					 long length, FILE *file);static int	    EdrWriteLongComplex(LongComplex *data, long length,					FILE *file, int longlong);static int	    EdrWriteShortComplex(ShortComplex *data,					 long length, FILE *file);static int	    EdrWriteScharComplex(ScharComplex *data,					 long length, FILE *file);static int	    EdrWriteChar(char *data,				 long length, FILE *file);static int	    EdrWriteWchar(Wchar *data,				  long length, FILE *file);/* * PUBLIC FUNCTION DEFINITIONS * - EdrTypeSize * - EdrRecordSize * - ReadEdrFieldList * - ReadEdrRecord * - ReadEdrSamples * - WriteEdrFieldList * - WriteEdrRecord * - WriteEdrSamples *//* * Size in bytes of EDR1 or EDR2 external representation of data type. */longEdrTypeSize(int type,		/* numeric data-type code */	    int longlong){    switch (type)    {    case ARRAY:	return -1;    case DOUBLE:	return 8;    case FLOAT:	return 4;    case LONG:    case ULONG:	switch (longlong)	{	case EDR1:  return 4;	case EDR2:  return 8;	default:    return 0;	}    case SHORT:    case USHORT:	return 2;    case SCHAR:    case UCHAR:	return 1;    case BOOL:	return 1;    case DOUBLE_COMPLEX:	return 16;    case FLOAT_COMPLEX:	return 8;    case LONG_COMPLEX:	switch (longlong)	{	case EDR1:  return 8;	case EDR2:  return 16;	default:    return 0;	}    case SHORT_COMPLEX:	return 4;    case SCHAR_COMPLEX:	return 2;    case CHAR:	return 1;    case WCHAR:	return 2;    default:	{	    DebugMsg(1, "EdrTypeSize: Invalid code or NO_TYPE.");	    return 0;	}    }}/* * Return the size, in bytes, of one record in EDR1 or EDR2 format, * according to the field specs on a field list. * Return 0 on NULL input; -1 is a code for variable-length records. */longEdrRecordSize(FieldList list,	      int	longlong){    long	size;		/* total array size in bytes */    FieldSpec	**fld_order;    long	i;    long	fld_size;    fld_order = FieldOrder(list);    if (fld_order == NULL)	return 0;    size = 0;    for (i = 0 ; fld_order[i] != NULL; i++)    {	if (fld_order[i]->occurrence == OPTIONAL)	{	    size = -1;	    break;	}	fld_size =	    FieldLength(fld_order[i])		* EdrTypeSize(fld_order[i]->type, longlong);	if (fld_size < 0)	{	    size = -1;	    break;	}	else	    size += fld_size;    }    free(fld_order);    return size;}/* * Read field list in EDR1 or EDR2 format from file.  Return TRUE on * success, FALSE on failure. */intReadEdrFieldList(FieldList  *listp,  /* output variable */		 FILE	    *file,   /* input file */		 int	    longlong){    FieldList	list;    long	num_fields;    long	i;    FieldSpec	*spec;    if (EdrReadLong(&num_fields, 1, file, longlong) != 1)    {	DebugMsg(1, "ReadEdrFieldList: Couldn't get number of fields.");	return FALSE;    }    list = NULL;    for (i = 0; i < num_fields; i++)    {	spec = ReadEdrFieldSpec(file, longlong);	if (spec == NULL || !AddField(&list, spec))	{	    if (list != NULL)		FreeFieldList(list);	    DebugMsg(2, ((spec == NULL)			 ? "ReadEdrFieldList: couldn't read field spec."			 : ("ReadEdrFieldList: "			    "couldn't add field spec to list.")));	    return FALSE;	}    }    *listp = list;    return TRUE;}/* * Read one record from file in EDR1 or EDR2 format, depending on the * value of longlong.  Read the record 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. */intReadEdrRecord(FieldSpec	**fields,	      FILE      *file,	      int	longlong){    long    i;    long    nopt;    Uchar   flags;    if (file == NULL || fields == NULL)    {	DebugMsg(1, "ReadEdrRecord: NULL argument.");	return FALSE;    }    /*! If FieldOrder & TypeOrder returned a linear array of OPTIONAL     * fields as well as the array of REQUIRED & OPTIONAL, we could     * avoid scanning all of "fields" checking for OPTIONAL entries     * for every record read. */    nopt = 0;    for (i = 0 ; fields[i] != NULL; i++)    {	if (fields[i]->occurrence == OPTIONAL)	{	    if (nopt % 8 == 0)	    {		if (EdrReadUchar(&flags, 1, file) != 1)		{		    DebugMsg(1, ("ReadEdrRecord: can't read "				 "\"presence\" flag for OPTIONAL field."));		    return FALSE;		}	    }	    else		flags <<= 1;	    fields[i]->present = ((flags & 0x80) != 0);	    nopt++;	}    }    for (i = 0 ; fields[i] != NULL; i++)	if (fields[i]->occurrence == REQUIRED || fields[i]->present)	{	    if (!ReadEdrData(fields[i], file, longlong))	    {		DebugMsg(2, "ReadEdrRecord: couldn't read field data.");		return FALSE;	    }	}    return TRUE;}/* * Read nrec one-field records from file in EDR1 or EDR2 format, * depending on the value of longlong.  Read the records 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. */longReadEdrSamples(void	    *data,	       long	    nrec,	       FieldSpec    **fields,	       FILE	    *file,	       int	    longlong){    int	    type;    long    length;    if (data == NULL)    {	DebugMsg(1, "ReadEdrSamples: NULL data pointer.");	return 0;    }    if (nrec < 0)    {	DebugMsg(1, ("ReadEdrSamples: "		     "negative number of records specified."));	return 0;    }    if (fields == NULL || fields[0] == NULL || fields[1] != NULL	|| fields[0]->occurrence != REQUIRED)    {	DebugMsg(1, "ReadEdrSamples: bad \"fields\" array.");	return 0;    }    if (file == NULL)    {	DebugMsg(1, "ReadEdrSamples: NULL file pointer.");	return 0;    }    type = fields[0]->type;    if (type == NO_TYPE)	return 0;    length = FieldLength(fields[0]);    if (nrec*length == 0)	return nrec;    return EdrRead(data, type, nrec*length, file, longlong) / length;}/* * Write field list to file in EDR1 or EDR2 format. * Return TRUE on success, FALSE on failure. */intWriteEdrFieldList(FieldList list,   /* field list */		  FILE      *file,  /* output file */		  int	    longlong){    long    num_fields;		/* number of fields */    long    i;			/* loop index */    if (file == NULL)    {	DebugMsg(1, "WriteEdrFieldList: NULL file pointer.");	return FALSE;    }    num_fields = FieldListLength(list);    if (EdrWriteLong(&num_fields, 1, file, longlong) != 1)    {	DebugMsg(1, "WriteEdrFieldList: couldn't write number of fields.");	return FALSE;    }    for (i = 0; i < num_fields; i++)	if (!WriteEdrFieldSpec(list[i], file, longlong))	{	    DebugMsg(2, "WriteEdrFieldList: couldn't write field spec.");	    return FALSE;	}    return TRUE;		/* Success. */}/* * Write to file one record in EDR1 or EDR2 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. * Return TRUE on success, FALSE on failure. */intWriteEdrRecord(FieldSpec    **fields,	       FILE         *file,	       int	    longlong){    long    i;    long    nopt;    Uchar   flags;    if (file == NULL || fields == NULL)    {	DebugMsg(1, "WriteEdrRecord: NULL argument.");	return FALSE;    }    /*! If FieldOrder & TypeOrder returned a linear array of OPTIONAL     * fields as well as the array of REQUIRED & OPTIONAL, we could     * avoid scanning all of "fields" checking for OPTIONAL entries     * for every record written. */    nopt = 0;    flags = 0;    for (i = 0; fields[i] != NULL; i++)    {	if (fields[i]->occurrence == OPTIONAL)	{	    flags |= fields[i]->present;	    nopt++;	    if (nopt % 8 == 0)	    {		if (EdrWriteUchar(&flags, 1, file) != 1)		{		    DebugMsg(2, ("WriteEdrRecord: couldn't write "				 "\"presence\" flag for OPTIONAL field."));		    return FALSE;		}		flags = 0;	    }	    else		flags <<= 1;	}    }    if (nopt % 8 != 0)    {	flags <<= (7 - nopt % 8);	if (EdrWriteUchar(&flags, 1, file) != 1)	{	    DebugMsg(1, ("WriteEdrRecord: couldn't write "			 "\"presence\" flags for OPTIONAL fields."));	    return FALSE;	}    }    for (i = 0; fields[i] != NULL; i++)    {	if (fields[i]->occurrence == REQUIRED || fields[i]->present)	{	    if (!WriteEdrData(fields[i], file, longlong))	    {		DebugMsg(2, "WriteEdrRecord: couldn't write field data.");		return FALSE;	    }	}    }    return TRUE;}/* * Write nrec one-field records to file in EDR1 or EDR2 format, * depending on the value of longlong.  The values are obtained * 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. */longWriteEdrSamples(void	    *data,		long	    nrec,		FieldSpec   **fields,		FILE	    *file,		int	    longlong){    int		type;    long	length;    if (data == NULL)    {	DebugMsg(1, "WriteEdrSamples: NULL data pointer.");	return 0;    }    if (nrec < 0)    {	DebugMsg(1, ("WriteEdrSamples: "		     "negative number of records specified."));	return 0;    }    if (fields == NULL || fields[0] == NULL || fields[1] != NULL	|| fields[0]->occurrence != REQUIRED)    {	DebugMsg(1, "WriteEdrSamples: bad \"fields\" array.");	return 0;    }    if (file == NULL)    {	DebugMsg(1, "WriteEdrSamples: NULL file pointer.");	return 0;    }    type = fields[0]->type;    if (type == NO_TYPE)	return 0;    length = FieldLength(fields[0]);    if (nrec*length == 0)	return nrec;    return EdrWrite(data, type, nrec*length, file, longlong) /length;}/* * LOCAL FUNCTION DEFINITIONS *//* * *** FUNCTIONS FOR INPUT *//* * Read "data" member of field from file in EDR format; * allocate if NULL.  Return TRUE on success, FALSE on failure. */static intReadEdrData(FieldSpec *field,	    FILE *file,	    int longlong){    long  size;		/* size of element (bytes) */    long    length;		/* number of elements */    if (file  == NULL || field == NULL || field->type == NO_TYPE)    {	DebugMsg(1, "ReadEdrData: NULL argument or type NO_TYPE.");	return FALSE;    }    size = InternTypeSize(field->type);    length = FieldLength(field);    if (field->data == NULL && length != 0)    {	field->data = malloc(length * size);	if (field->data == NULL)	{	    DebugMsg(1, "ReadEdrData: allocation failure.");	    return FALSE;	}    }    return (EdrRead(field->data, field->type, length, file, longlong)	    == length);}/* * Read field specification in EDR format from file and return * pointer to it; return NULL on failure. */static FieldSpec *ReadEdrFieldSpec(FILE	*file,		 int	longlong){    char	*name;		/* field name */    short	type;		/* data type code */    short	rank;		/* number of dimensions */    int		i;		/* loop index */    FieldSpec	*field;		/* field spec being read */    long	num_ax_names;	/* number of axis names */    /* Read name, type, rank. */    if (!ReadEdrString(&name, file, longlong))	return NULL;		/* Failure getting field name. */    if (EdrReadShort(&type, 1, file)  != 1)	return NULL;		/* Couldn't get type. */    if (EdrReadShort(&rank, 1, file) != 1)	return NULL;		/* Couldn't get rank. */    /* Allocate structure. */    field = NewFieldSpec(type, rank);    if (field == NULL)	return NULL;		/* Couldn't create field spec. */    field->name = name;    /* Read dimensions. */    if (rank != 0 && field->dim == NULL)

⌨️ 快捷键说明

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