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