feasupport.c

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

C
1,513
字号
/* * This material contains unpublished, proprietary software of  * Entropic Research Laboratory, Inc. Any reproduction, distribution,  * or publication of this work must be authorized in writing by Entropic  * Research Laboratory, Inc., and must bear the notice:  * *    "Copyright (c) 1987-1990  Entropic Speech, Inc.  *    "Copyright (c) 1990-1996  Entropic Research Laboratory, Inc.  *                   All rights reserved" * * The copyright notice above does not evidence any actual or intended  * publication of this source code.      * * Written by:  Alan Parker, Entropic Speech, Inc. * Checked by: * Revised by: * * FEA file support routines */static char *sccs_id = "@(#)feasupport.c	1.33	5/1/98	ESI/ERL";#include <stdio.h>#include <esps/esps.h>#include <ctype.h>#include <esps/fea.h>#ifndef DEC_ALPHA#include <esps/unix.h>#endif#include <math.h>#include <esps/esignal_fea.h>#include <esps/pc_wav.h>char   *savestring ();int     lin_search2 (), idx_ok ();char   *get_sphere_hdr();static char *myrealloc();  /* my version of realloc */static void fatal();static int legal_name();static void decode_data();/* add a new field to a feature file*/intadd_fea_fld (name, size, rank, dimen, type, coded, hd)char   *name;long    size,       *dimen;short   rank;short   type;char  **coded;struct header  *hd;{    struct fea_header  *fea;    long    prod;    int     i, k;/* check the arguments */    spsassert(name != NULL, "add_fea_fld: name is NULL");    spsassert(size > 0, "add_fea_fld: size is zero or less");    spsassert(rank >= 0, "add_fea_fld: rank is negative");    if (rank == 0)	spsassert(size == 1, "add_fea_fld: size given for scalar is not 1");    if (rank >= 2)    {	spsassert(dimen != NULL, "add_fea_fld: rank >= 2, but dimen is NULL");	prod = 1;	for (i = 0; i < rank; i++)	    prod *= dimen[i];	spsassert(size == prod,		  "add_fea_fld: dimensions inconsistent with size");    }    spsassert(hd != NULL, "add_fea_fld: hd is NULL");    spsassert(hd->common.type == FT_FEA, "add_fea_fld: file not FEA");    if (!legal_name(name)) {	Fprintf(stderr,"add_fea_fld: %s not a valid field name.\n",name);	Fprintf(stderr,"add_fea_fld: exiting program.\n");	exit (1);    }	    fea = hd -> hd.fea;    if (fea->names && lin_search2 (fea -> names, name) != -1) {	Fprintf (stderr, "add_fea_fld: name %s already defined\n", name);	return (-1);    }/* increment the counter and reallocate the arrays*/    fea -> field_count++;    fea -> names = (char **) myrealloc ((char *) fea -> names,	    sizeof (char *) * (fea -> field_count + 1));    spsassert (fea -> names, "add_fea_fld: realloc failed");    fea -> names[fea -> field_count] = NULL;    fea -> sizes = (long *) myrealloc ((char *) fea -> sizes,	    fea -> field_count * sizeof (long));    spsassert (fea -> sizes, "add_fea_fld: realloc failed");    fea -> starts = (long *) myrealloc ((char *) fea -> starts,	    fea -> field_count * sizeof (long));    spsassert (fea -> starts, "add_fea_fld: realloc failed");    fea -> ranks = (short *) myrealloc ((char *) fea -> ranks,	    fea -> field_count * sizeof (short));    spsassert (fea -> ranks, "add_fea_fld: realloc failed");    fea -> dimens = (long **) myrealloc ((char *) fea -> dimens,	    fea -> field_count * sizeof (long *));    spsassert (fea -> dimens, "add_fea_fld: realloc failed");    fea -> types = (short *) myrealloc ((char *) fea -> types,	    fea -> field_count * sizeof (short));    spsassert (fea -> types, "add_fea_fld: realloc failed");    fea -> enums = (char ***) myrealloc ((char *) fea -> enums,	    sizeof (char **) * fea -> field_count);    spsassert (fea -> enums, "add_fea_fld: realloc failed");    fea -> srcfields = (char ***) myrealloc ((char *) fea -> srcfields,	    sizeof (char **) * fea -> field_count);    fea -> srcfields[fea -> field_count-1] = NULL;    spsassert (fea -> srcfields, "add_fea_fld: realloc failed");    fea -> derived = (short *) myrealloc ((char *) fea -> derived,	    fea -> field_count * sizeof (short));    fea -> derived[fea -> field_count-1] = NULL;    spsassert (fea -> derived, "add_fea_fld: realloc failed");/* save all the new values*/    k = fea -> field_count - 1;    fea -> names[k] = savestring (name);    spsassert (fea -> names[k], "add_fea_fld: savestring failed");    fea -> sizes[k] = size;    fea -> ranks[k] = rank;    fea -> types[k] = type;    fea -> derived[k] = 0;    if (type == CODED)	fea -> enums[k] = coded;    if (rank == 0)    {	fea->dimens[k] = NULL;    }    else if (rank == 1)    {	fea->dimens[k] = (long *) malloc(sizeof(long));	fea->dimens[k][0] = size;    }    else	fea->dimens[k] = dimen;/* fill in the starts array.  This information is redundant, but   worth computing here*/    switch (fea -> types[k]) {	case DOUBLE: 	    hd -> common.ndouble += fea -> sizes[k];	    fea -> starts[k] = fea -> ndouble;	    fea -> ndouble += fea -> sizes[k];	    break;	case FLOAT: 	    hd -> common.nfloat += fea -> sizes[k];	    fea -> starts[k] = fea -> nfloat;	    fea -> nfloat += fea -> sizes[k];	    break;	case LONG: 	    hd -> common.nlong += fea -> sizes[k];	    fea -> starts[k] = fea -> nlong;	    fea -> nlong += fea -> sizes[k];	    break;	case SHORT: 	case CODED: 	    hd -> common.nshort += fea -> sizes[k];	    fea -> starts[k] = fea -> nshort;	    fea -> nshort += fea -> sizes[k];	    break;	case CHAR: 	case BYTE:	    hd -> common.nchar += fea -> sizes[k];	    fea -> starts[k] = fea -> nbyte;	    fea -> nbyte += fea -> sizes[k];	    break;	case DOUBLE_CPLX:	    hd -> common.ndouble += fea->sizes[k]*2;		    fea -> starts[k] = fea -> ndcplx;		    fea -> ndcplx += fea -> sizes[k];	    break;	case FLOAT_CPLX:	    hd -> common.nfloat += fea->sizes[k]*2;		    fea -> starts[k] = fea -> nfcplx;		    fea -> nfcplx += fea -> sizes[k];	    break;	case LONG_CPLX:	    hd -> common.nlong += fea->sizes[k]*2;		    fea -> starts[k] = fea -> nlcplx;		    fea -> nlcplx += fea -> sizes[k];	    break;	case SHORT_CPLX:	    hd -> common.nshort += fea->sizes[k]*2;		    fea -> starts[k] = fea -> nscplx;		    fea -> nscplx += fea -> sizes[k];	    break;	case BYTE_CPLX:	    hd -> common.nchar += fea->sizes[k]*2;		    fea -> starts[k] = fea -> nbcplx;		    fea -> nbcplx += fea -> sizes[k];	    break;	default: 	    Fprintf (stderr, "add_fea_fld: bad type found for %s\n", 		fea -> names[k]);	    exit (1);    }    return 0;}/* allocate a feature file record;  this must be done after all   add_fea_fld calls and before a write header  for a new file, and   after a read header for an existing file.  In other words, the   header must be complete.*/struct fea_data *allo_fea_rec (hd)struct header  *hd;{    struct fea_data *p = (struct fea_data  *) calloc (1, sizeof *p);    struct fea_header *fea;    spsassert (p, "allo_fea_rec: calloc failed");    spsassert (hd,"allo_fae_rec: hd is NULL");    spsassert (hd->common.type == FT_FEA, "allo_fea_rec: file not FEA");    fea = hd->hd.fea;/* allocate storage*/    if (fea->ndouble) {    p->d_data = (double *)calloc((unsigned)fea->ndouble, sizeof (double));    spsassert(p->d_data, "allo_fea_rec: calloc failed!");    }    if (fea->nfloat) {    p->f_data = (float *)calloc((unsigned) fea->nfloat, sizeof (float));    spsassert(p->f_data, "allo_fea_rec: calloc failed!");    }    if (fea->nlong) {    p->l_data = (long *)calloc((unsigned) fea->nlong, sizeof (long));    spsassert(p->l_data, "allo_fea_rec: calloc failed!");    }    if (fea->nshort) {    p->s_data = (short *)calloc((unsigned) fea->nshort, sizeof (short));    spsassert(p->s_data, "allo_fea_rec: calloc failed!");    }    if (fea->nbyte) {    p->b_data = calloc((unsigned) fea->nbyte, sizeof (char));    spsassert(p->b_data, "allo_fea_rec: calloc failed!");    }    if (fea->ndcplx) {    p->dc_data = (double_cplx *)calloc((unsigned)fea->ndcplx, 	sizeof (double_cplx));    spsassert(p->dc_data, "allo_fea_rec: calloc failed!");    }    if (fea->nfcplx) {    p->fc_data = (float_cplx *)calloc((unsigned)fea->nfcplx, 	sizeof (float_cplx));    spsassert(p->fc_data, "allo_fea_rec: calloc failed!");    }    if (fea->nlcplx) {    p->lc_data = (long_cplx *)calloc((unsigned)fea->nlcplx, 	sizeof (long_cplx));    spsassert(p->lc_data, "allo_fea_rec: calloc failed!");    }    if (fea->nscplx) {    p->sc_data = (short_cplx *)calloc((unsigned)fea->nscplx, 	sizeof (short_cplx));    spsassert(p->sc_data, "allo_fea_rec: calloc failed!");    }    if (fea->nbcplx) {    p->bc_data = (byte_cplx *)calloc((unsigned)fea->nbcplx, 	sizeof (byte_cplx));    spsassert(p->bc_data, "allo_fea_rec: calloc failed!");    }/* return*/    return p;}/* del_fea_fld deletes a feature file field (before a write header   is done ofcourse)*/intdel_fea_fld(name, hd)char 	*name;struct header *hd;{     struct fea_header *fea = hd -> hd.fea;     long  size;     short type, type_i;     int   i, k;	     spsassert(name, "del_fea_fld: name is NULL");     spsassert(hd, "del_fea_fld: hd is NULL");     if ((k = lin_search2(fea->names, name)) == -1)          return -1;     type = fea->types[k];     size = fea->sizes[k];     /* adjust sizes of data storage areas */     switch (type) {	case DOUBLE: 	    hd->common.ndouble -= size;	    fea->ndouble -= size;	    break;	case FLOAT: 	    hd->common.nfloat -= size;	    fea->nfloat -= size;	    break;	case LONG: 	    hd->common.nlong -= size;	    fea->nlong -= size;	    break;	case SHORT: 	case CODED: 	    /* normalize type for comparison with type_i in loop below */	    type = SHORT;	    hd->common.nshort -= size;	    fea->nshort -= size;	    break;	case CHAR: 	case BYTE:	    /* normalize type for comparison with type_i in loop below */	    type = BYTE;	    hd->common.nchar -= size;	    fea->nbyte -= size;	    break;	case DOUBLE_CPLX:	    hd->common.ndouble -= size*2;		    fea->ndcplx -= size;	    break;	case FLOAT_CPLX:	    hd->common.nfloat -= size*2;		    fea->nfcplx -= size;	    break;	case LONG_CPLX:	    hd->common.nlong -= size*2;		    fea->nlcplx -= size;	    break;	case SHORT_CPLX:	    hd->common.nshort -= size*2;		    fea->nscplx -= size;	    break;	case BYTE_CPLX:	    hd->common.nchar -= size*2;		    fea->nbcplx -= size;	    break;	default: 	    Fprintf(stderr, "del_fea_fld: bad type found for %s\n", name);	    return -1;     }     for(i=k+1; i < fea->field_count; i++) {	fea->names[i-1] = fea->names[i];	fea->sizes[i-1] = fea->sizes[i];	/* Cf. reassignment of type in switch above.	 * This defines type_i so that (type_i == type) just when	 * fea->types[i] and fea->types[k] share storage areas.	 */	switch (type_i = fea->types[i])	{	case CODED:	    type_i = SHORT;	    break;	case CHAR:	    type_i = BYTE;	    break;	default:	    break;	}	fea->starts[i-1] =	    (type_i == type) ? fea->starts[i] - size : fea->starts[i];	fea->ranks[i-1] = fea->ranks[i];	fea->dimens[i-1] = fea->dimens[i];	fea->types[i-1] = fea->types[i];	fea->enums[i-1] = fea->enums[i];	fea->srcfields[i-1] = fea->srcfields[i];	fea->derived[i-1] = fea->derived[i];     }          fea->field_count--;     fea->names[fea->field_count] = NULL;     return 0;}     char   *get_fea_ptr (rec, name, hd)struct fea_data *rec;char   *name;struct header  *hd;{    struct fea_header  *fea = hd -> hd.fea;    char   *ptr;    int     k;    spsassert (rec, "get_fea_ptr: rec is NULL");    spsassert (hd, "get_fea_ptr: hd is NULL");    spsassert (hd->common.type == FT_FEA, "get_fea_ptr: file not FEA");    if (name == NULL || fea->names == NULL)	return NULL;    if ((k = lin_search2 (fea -> names, name)) == -1)	return NULL;    switch (fea -> types[k]) {	case DOUBLE: 	    ptr = (char *) & rec -> d_data[fea -> starts[k]];	    break;	case FLOAT: 	    ptr = (char *) & rec -> f_data[fea -> starts[k]];	    break;	case LONG: 	    ptr = (char *) & rec -> l_data[fea -> starts[k]];	    break;	case SHORT: 	case CODED: 	    ptr = (char *) & rec -> s_data[fea -> starts[k]];	    break;	case CHAR: 	case BYTE:	    ptr = &rec -> b_data[fea -> starts[k]];	    break;	case DOUBLE_CPLX:	    ptr = (char *) & rec -> dc_data[fea -> starts[k]];	    break;	case FLOAT_CPLX:	    ptr = (char *) & rec -> fc_data[fea -> starts[k]];	    break;	case LONG_CPLX:	    ptr = (char *) & rec -> lc_data[fea -> starts[k]];	    break;	case SHORT_CPLX:	    ptr = (char *) & rec -> sc_data[fea -> starts[k]];	    break;	case BYTE_CPLX:	    ptr = (char *) & rec -> bc_data[fea -> starts[k]];	    break;	default:	    spsassert(0,"failure in get_fea_ptr");    }    return ptr;}/* put_fea_rec write a feature file record to a file*/voidput_fea_rec (rec, hd, file)struct fea_data *rec;struct header  *hd;FILE *file;{    struct fea_header *fea = hd -> hd.fea;    spsassert(hd != NULL, "put_fea_rec: hd is NULL");    spsassert(hd->common.type == FT_FEA, "put_fea_rec: file not FEA");    spsassert(rec != NULL, "put_fea_rec: rec is NULL");    spsassert(file != NULL, "put_fea_rec: file is NULL");    if (hd -> common.tag)	if (!miio_put_long(&rec->tag, 1, hd->common.edr, file))  	    fatal("put_fea_rec: i/o error");#ifndef NOPAD    if (fea -> field_order) {	char *ptr;	int i;	for (i=0; i < fea->field_count; i++) {		switch (fea->types[i]) {		 case DOUBLE:			ptr = (char *)&rec->d_data[fea->starts[i]];			if(!miio_put_double(ptr,(int)fea->sizes[i],				hd->common.edr,file)) 				fatal("put_fea_rec: i/o error");

⌨️ 快捷键说明

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