featohtk.c

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

C
825
字号
/* * 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) 1998 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:  Rod Johnson * Checked by: * Revised by: * * Brief description: *   HTK input filter for ESPS FEA files. */static char *sccs_id = "@(#)featohtk.c	1.1\t3/17/98\tERL";/* INCLUDE FILES */#include <stdlib.h>#include <math.h>#include <esps/esps.h>#include <esps/fea.h>#include <esps/feasd.h>#include <esps/array.h>#include <esps/types.h>#include <esps/range_switch.h>#include <esps/strlist.h>/* LOCAL CONSTANTS */#define EC_SCCS_DATE	"3/17/98"#define EC_SCCS_VERSION	"1.1"#define MAX_INT		(0x7fffffff)	/* INT_MAX for EDR machines */#define MAX_SHORT	(0x7fff)	/* SHRT_MAX for EDR machines */#define SD_BUF_LEN	(1000)		/* length of FEA_SD intput buffer *//* LOCAL MACROS */#define ERROR(text) { \  (void) fprintf(stderr, "%s: %s - exiting\n", ProgName, (text)); \  exit(1);}#define REQUIRE(test, text) {if (!(test)) ERROR(text)}#define SYNTAX \USAGE("featohtk [-f field[range]] [-k parmKind] [-r range] [-x debug_level]\n\t[-E field[index]] [-L] [-O field[index]] [-P param_file] input output")/* LOCAL TYPEDEFS AND STRUCTURES *//* HTK DEFINITIONS AND DECLARATIONS */        /* These are taken from the HTK version 2.1.1 source files     * HTKLib/HParm.h and HTKLib/HParm.c.     * They may need to be revised when a later version is released.     * Simply including HParm.h (the "right thing to do") required     * including a cascade of further header files, extending to the     * Esignal header file esignal.h, which contains definitions that     * conflict with definitions in esps/esps.h.     * Likewise linking the HTK libraries and the ESPS libraries in one     * binary resulted in multiple definitions of numerous symbols     * (apparently in the license manager).     * All in all, too much complication to be worth doing.     */enum{    WAVEFORM,   LPC,        LPREFC,     LPCEPSTRA,    LPDELCEP,   IREFC,      MFCC,       FBANK,    MELSPEC,    USER,       DISCRETE,   ANON};static char	*pmkmap[] ={    "WAVEFORM", "LPC",      "LPREFC",   "LPCEPSTRA",    "LPDELCEP", "IREFC",    "MFCC",     "FBANK",    "MELSPEC",  "USER",     "DISCRETE", "ANON",    NULL /* NULL termination, not in HTK source, needed for lin_search2 */};typedef short	ParmKind;#define HASENERGY   (0100)#define HASZEROC  (020000)#define BASEMASK     (077)/* SYSTEM FUNCTIONS AND VARIABLES */extern int	getopt();extern int	optind;extern char	*optarg;/* ESPS FUNCTIONS AND VARIABLES */int		debug_level = 0;/* LOCAL FUNCTION DECLARATIONS *//* STATIC (LOCAL) GLOBAL VARIABLES */ static char	*ProgName = "featohtk";static char	*Version = EC_SCCS_VERSION;static char	*Date = EC_SCCS_DATE;static char	*no_yes[] = {"NO", "YES", NULL};/* MAIN PROGRAM */intmain(argc, argv)    int 	    argc;    char	    **argv;{    int	    	    ch;			/* command-line option letter */    char	    *fld = NULL;	/* basic param or sample field					 * name with range */    char	    *fld_name;		/* field name part of fld */    long	    *fld_range;		/* indices of subrange of fld */    long	    rng_len;		/* length of subrange of fld */    int		    contig;		/* is fld_range a single sequence					 * of consecutive integers without					 * gaps? */    int 	    fld_type;		/* data type of field named fld */    char	    *fld_data;		/* data from subrange of fld */    char	    *fldptr;		/* pointer to field data in rec */    long	    fld_length;		/* length of field named fld */    char	    *kind = NULL;	/* parameter kind string */    short	    parmKind;		/* parameter kind binary code */    int		    out_type;		/* output data type */    char	    *rrange = NULL;	/* range of records to process */    long	    start_rec;		/* number of first record to process */    long	    end_rec;		/* number of last record to process */    long	    num_recs;		/* number of records to process */    int		    nSamples;		/* num_recs as int */    char	    *Efld = NULL;	/* energy field name with index */    char	    *Efld_name;		/* field name part of Efld */    long	    *Efld_range;	/* pointer to index in Efld */    long	    Erng_len;		/* length of subrange in Efld */    int 	    Efld_type;		/* data type of E field (energy) */    char	    *Eptr = NULL;	/* pointer to E data in rec */    int 	    log_requested = NO;	/* compute log of energy? */    char	    *comp_log_param;	/* value of "compute_log" in ESPS					 * param file */    char	    *Ofld = NULL;	/* 0-th cepstral coeff field name */    char	    *Ofld_name;		/* field name part of Ofld */    long	    *Ofld_range;	/* pointer to index in Ofld */    long	    Orng_len;		/* length of subrange in Ofld */    int 	    Ofld_type;		/* data type of O field (0-th order					 * cepstral coefficient) */    char	    *Optr = NULL;	/* pointer to O data in rec */    char    	    *param_name = NULL;	/* parameter file name */    char	    *inname;		/* input file name */    FILE	    *infile;		/* input stream */    struct header   *hd;		/* input file header */    double	    record_freq;	/* input file record frequency (Hz) */    int		    sampPeriod;		/* sampling period (100 ns) */    double	    sampP_dbl;		/* sampPeriod as double */    long	    ndrec;		/* input header item: number of					 * data records */    int		    fea_sd;		/* is input file FEA_SD? */    struct fea_data *rec;		/* FEA input data record */    struct feasd    *sd_rec;		/* FEA_SD input data structure */    long	    chunk_len;		/* number of FEA_SD samples to try					 * to read at one time */    long	    act_len;		/* number of samples actually read */    int		    eof;		/* end of input file reached? */    char	    *outname;		/* output file name */    FILE	    *outfile;		/* output stream */    long	    samp_len;		/* number of items in output sample */    int		    typesize;		/* size of one output item */    short	    sampSize;		/* number of bytes in output sample */    int		    out_len;		/* number of items of output sample					 * actually written */    char	    *buf;		/* output data buffer */    float	    *Ebuf;		/* pointer to E data in buf */    float	    *Obuf;		/* pointer to O data in buf */    long	    num_read;		/* number of input records read					 * or skipped over */    long	    i, j;		/* loop and array indices */    /*     * PARSE COMMAND-LINE OPTIONS.     */    while ((ch = getopt(argc, argv, "f:k:r:x:E:LO:P:")) != EOF)	switch (ch)	{	case 'f':	    fld = optarg;	    break;	case 'k':	    kind = optarg;	    break;	case 'r':	    rrange = optarg;	    break;	case 'x':	    debug_level = atoi(optarg);	    break;	case 'E':	    Efld = optarg;	    break;	case 'L':	    log_requested = YES;	    break;	case 'O':	    Ofld = optarg;	    break;	case 'P':	    param_name = optarg;	    break;	default:	    SYNTAX;	    break;	}    /*     * PROCESS FILE NAMES AND OPEN FILES.     */    if (argc - optind > 2)    {	Fprintf(stderr,		"%s: too many file names specified.\n", ProgName);	SYNTAX;    }    if (argc - optind < 2)    {	Fprintf(stderr,		"%s: too few file names specified.\n", ProgName);	SYNTAX;    }    inname = eopen(ProgName,		   argv[optind++], "r", FT_FEA, NONE, &hd, &infile);    if (debug_level)	Fprintf(stderr, "%s: input file \"%s\"\n", ProgName, inname);    if (infile != stdin)	REQUIRE(strcmp(inname, argv[optind]),		"output file same as input");    outname = eopen(ProgName,		    argv[optind++], "w", NONE, NONE, NULL, &outfile);    if (debug_level)	Fprintf(stderr, "%s: output file: \"%s\"\n", ProgName, outname);    /*     * GET PARAMETER VALUES.     */    (void) read_params(param_name, SC_NOCOMMON, inname);    /* Parameter kind (-k) */    if (kind == NULL && symtype("parmKind") == ST_STRING)    {	kind = getsym_s("parmKind");    }    REQUIRE (kind != NULL,	     "can't determine parameter kind");    if (debug_level)	Fprintf(stderr, "%s: parameter kind \"%s\"\n", ProgName, kind);    parmKind = (short) lin_search2(pmkmap, kind);    if (debug_level)	Fprintf(stderr, "%s: parmKind code %x\n", ProgName, parmKind);    switch (parmKind)    {	/* Most cases FALL THROUGH. */    case WAVEFORM:    case IREFC:    case DISCRETE:	out_type = SHORT;	typesize = 2;	break;    case LPC:    case LPREFC:    case LPCEPSTRA:    case MFCC:    case FBANK:    case MELSPEC:    case USER:	out_type = FLOAT;	typesize = 4;	break;    case LPDELCEP:	ERROR("delta-parameter fields not supported");	break;    default:	ERROR("unsupported parmKind");	break;    }    if (debug_level)	Fprintf(stderr, "%s: out_type %d (%s), typesize %d\n",		ProgName, out_type, ((out_type == SHORT) ? "SHORT"				     : (out_type == FLOAT) ? "FLOAT"				     : "other"),		typesize);    /* Base parameter field (-f) */    if (fld == NULL && symtype("field") == ST_STRING)    {	fld = getsym_s("field");    }    REQUIRE (fld != NULL,	     "can't determine field name");    if (debug_level)	Fprintf(stderr, "%s: base parameter field \"%s\"\n",		ProgName, fld);    fld_range = fld_range_switch(fld, &fld_name, &rng_len, hd);    fld_type = get_fea_type(fld_name, hd);    fld_length = get_fea_siz(fld_name, hd, NULL, NULL);    if (debug_level)    {	Fprintf(stderr, "%s: field name \"%s\", range length %ld\n",		ProgName, fld_name, rng_len);	Fprintf(stderr, "%s: field type %d (%s), field length %ld\n",		ProgName, fld_type, type_codes[fld_type], fld_length);    }    REQUIRE(is_type_numeric(fld_type),	    "field undefined or non-numeric in input file header");    spsassert(fld_range != NULL,	      "fld_range_switch returned NULL");    if (debug_level >= 2)    {	Fprintf(stderr, "%s: field elements\n\t[", ProgName);	for (i = 0; i < rng_len; i++)	    Fprintf(stderr, "%ld%s", fld_range[i],		    (i == rng_len - 1) ? "]\n"		    : (i%10 == 9) ? ",\n\t "		    : ", ");    }    if (parmKind == WAVEFORM)	REQUIRE(rng_len == 1,		"range size must be 1 for WAVEFORM");    contig = YES;    for (i = 0; i < rng_len; i++)    {	j = fld_range[i];	REQUIRE(j >= 0 && j < fld_length,		"index out of range for field");	if (j != fld_range[0] + i)	    contig = NO;    }    if (debug_level)	Fprintf(stderr, "%s: range %s contiguous\n",		ProgName, (contig) ? "IS" : "is NOT");    /* Energy parameter field (-E) */    if (Efld == NULL && symtype("Efield") == ST_STRING)    {	Efld = getsym_s("Efield");    }    if (debug_level)	Fprintf(stderr, "%s: E field \"%s\"\n",		ProgName, (Efld == NULL) ? "<null>" : Efld);    if (Efld != NULL)    {	REQUIRE(out_type == FLOAT,		"energy term not supported with non-FLOAT output");	Efld_range = fld_range_switch(Efld, &Efld_name, &Erng_len, hd);	Efld_type = get_fea_type(Efld_name, hd);	if (debug_level)	{	    Fprintf(stderr, "%s: Efld name \"%s\", range len %ld\n",		    ProgName, Efld_name, Erng_len);	    Fprintf(stderr, "%s: Efld type %d (%s)\n",		    ProgName, Efld_type, type_codes[Efld_type]);	    Fprintf(stderr, "%s: Efld element %ld\n", ProgName, Efld_range[0]);	}	REQUIRE(is_type_numeric(Efld_type),		"Energy field undefined or non-numeric in input file header");	spsassert(Efld_range != NULL,		  "fld_range_switch returned NULL");	REQUIRE(Erng_len == 1,		"Energy field must have exactly one element");	REQUIRE(Efld_range[0] >= 0		&& Efld_range[0] < get_fea_siz(Efld_name, hd, NULL, NULL),		"index out of range for Energy field");	parmKind |= HASENERGY;	if (debug_level)	    Fprintf(stderr, "%s: now parmKind code is %x\n",

⌨️ 快捷键说明

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