window.c
来自「speech signal process tools」· C语言 代码 · 共 500 行
C
500 行
/*----------------------------------------------------------------------+| || This material contains proprietary software of Entropic Speech, || Inc. Any reproduction, distribution, or publication without the || prior written permission of Entropic Speech, Inc. is strictly || prohibited. Any public distribution of copies of this work || authorized in writing by Entropic Speech, Inc. must bear the || notice || || "Copyright (c) 1988, 1990 Entropic Speech, Inc. All rights reserved."| |+-----------------------------------------------------------------------+| || Program: window.c || || This program windows the data in sampled-data records in a FEA || file. The output is contains copies of the input records with a || field containing the windowed data. || || John Shore, Entropic Speech, Inc. || based on power.c by Rodney Johnson || User-defined window added by David Burton |+----------------------------------------------------------------------*/#ifndef lint static char *sccs_id = "@(#)window.c 1.10 8/31/95 ESI";#endif#define VERSION "1.10"#define DATE "8/31/95"#include <stdio.h>#include <esps/esps.h>#include <esps/unix.h>#include <esps/fea.h>#include <esps/window.h>#define REQUIRE(test,text) {if (!(test)) {(void) fprintf(stderr, \"%s: %s - exiting\n", ProgName, text); exit(1);}}#define SYNTAX USAGE("window [-f sd_field [-f winsd_field]] [-l window_length]\n [-r range] [-x debug_level] [-w window_type] [-P params]\n input.fea output.fea") ;#define WT_PREFIX "WT_"void pr_farray();char *get_cmd_line();void lrange_switch();char *type_convert();char *atoarray();char *ProgName = "window";char *Version = VERSION;char *Date = DATE;int debug_level = 0; /* debug level, global for library*//*array of field names to copy over from input to output (these are for *copying over the segment labelling*/char *seg_fields[] = {"source_file", "segment_start", "segment_length", NULL};/* * MAIN PROGRAM */main(argc, argv) int argc; char **argv;{ extern int optind; /* for use of getopt() */ extern char *optarg; /* for use of getopt() */ int ch; /* command-line option letter */ int fflag = 0; /* -f option specified 0, 1, or 2 times? */ char *sd_name; /* field name for input sampled data */ int sd_type; /* data type of sampled-data field */ char *wsd_name; /* field name for windowed sampled-data */ char *window_type = NULL; /* name of type of window to apply to data */ char *pref_w_type; /* window type name with added prefix */ int win; /* window type code */ int wflag = 0; /* flag for window option*/ int rflag = NO; /* -r option specified? */ int lflag = NO; /* -l option specified? */ char *rrange; /* arguments of -r option */ long start_rec; /* starting record number */ long end_rec; /* ending record number */ long num_recs; /* number of records to read (0 means all up to end of file) */ long num_read; /* number of records actually read */ char *param_name = NULL; /* parameter file name */ char *iname; /* input file name */ FILE *ifile; /* input stream */ FILE *instrm = stdin; /* for ASCII data*/ struct header *ihd; /* input file header */ struct fea_data *irec; /* input record */ char *sd_ptr; /* pointer (untyped) to sampled-data field in input record */ long *frame_len; /* pointer to frame size in input header or record */ long size; /* size of input sampled-data field */ long win_len; /* size of window to apply */ float *data; /* input data as float */ char *oname; /* output file name */ FILE *ofile; /* output stream */ struct header *ohd; /* output file header */ struct fea_data *orec; /* output record */ float *wsd_ptr; /* pointer to windowed sampled data field in output record */ int i; /* loop index */ int seglenwarn = 0; /* warning flag for segment lengths less than window length*/ short tagged=0; /* flag to indicate input is tagged */ short seglab=0; /* to indicate segmenta labelled input */ short file_ind; /* index for location of source_file field */ extern char *window_types[]; /* standard window type names */ double *udefined; /*pointer for user defined window coeffs*//* * Parse command-line options. */ while ((ch = getopt(argc, argv, "f:r:x:P:l:w:")) != EOF) switch (ch) { case 'f': switch (fflag) { case 0: sd_name = optarg; fflag++; break; case 1: wsd_name = optarg; fflag++; break; default: Fprintf(stderr, "%s: -f option may be specified at most twice.\n", ProgName); exit(1); } break; case 'r': rflag = YES; rrange = optarg; break; case 'x': debug_level = atoi(optarg); break; case 'P': param_name = optarg; break; case 'l': win_len = atoi(optarg); lflag = YES; break; case 'w': window_type = optarg; wflag++; 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 } iname = eopen(ProgName, argv[optind++], "r", FT_FEA, NONE, &ihd, &ifile); oname = eopen(ProgName, argv[optind++], "w", NONE, NONE, &ohd, &ofile); if (debug_level) Fprintf(stderr, "Input file: %s\nOutput file: %s\n", iname, oname);/* * Get parameter values. */ if (ifile != stdin) (void) read_params(param_name, SC_CHECK_FILE, iname); else (void) read_params(param_name, SC_NOCOMMON, iname); if (fflag < 1) sd_name = (symtype("sd_field_name") != ST_UNDEF) ? getsym_s("sd_field_name") : "sd"; if (fflag < 2) wsd_name = (symtype("wind_field_name") != ST_UNDEF) ? getsym_s("wind_field_name") : "wind_sd"; if (debug_level) Fprintf(stderr, "sd_field_name: \"%s\". wind_field_name: \"%s\".\n", sd_name, wsd_name); sd_type = get_fea_type(sd_name, ihd); REQUIRE(sd_type != UNDEF, "sampled-data field not in input file"); REQUIRE(!is_field_complex(ihd, sd_name), "sorry, can't deal with complex data"); if (rflag) { start_rec = 1; end_rec = LONG_MAX; lrange_switch(rrange, &start_rec, &end_rec, 0); num_recs = (end_rec != LONG_MAX) ? end_rec - start_rec + 1 : 0; } else { start_rec = (symtype("start") != ST_UNDEF) ? getsym_i("start") : 1; num_recs = (symtype("nan") != ST_UNDEF) ? getsym_i("nan") : 0; end_rec = (num_recs != 0) ? start_rec - 1 + num_recs : LONG_MAX; } if (!lflag) win_len = (symtype("window_len") != ST_UNDEF) ? getsym_i("window_len") : 0; if (debug_level) Fprintf(stderr, "start_rec: %ld. end_rec: %ld. num_recs: %ld.\n", start_rec, end_rec, num_recs); if (debug_level) Fprintf(stderr, "window_len: %ld.\n", win_len); REQUIRE(start_rec >= 1, "can't start before beginning of file"); REQUIRE(end_rec >= start_rec, "empty range of records specified"); if (!wflag) window_type = (symtype("window_type") != ST_UNDEF) ? getsym_s("window_type") : "HAMMING"; pref_w_type = malloc((unsigned)(strlen(WT_PREFIX) + strlen(window_type) + 1)); REQUIRE(pref_w_type, "can't allocate space for window type name"); (void) strcpy(pref_w_type, WT_PREFIX); (void) strcat(pref_w_type, window_type); win = lin_search(window_types, pref_w_type); if(win == -1){ Fprintf(stderr, "window: Window type is not recognized.\n\t Assume type is name of ASCII file (or stdin) containing weight coefficients\n"); /* * open file with coefficients */ if (strcmp (window_type, "-") == 0) window_type = "<stdin>"; else TRYOPEN(argv[0], window_type, "r", instrm); if(strcmp(window_type, iname) == 0){ Fprintf(stderr, "window: input window coefficients and signal data cannot both come from standard input - exiting.\n"); exit(1); } udefined = (double *) atoarray(instrm, DOUBLE, &win_len, (double *)NULL); win = WT_ARB; } if (debug_level) Fprintf(stderr, "%s: window_type = %s, win = %d\n", ProgName, window_type, win); irec = allo_fea_rec(ihd); REQUIRE(irec != NULL, "can't allocate memory for input record"); sd_ptr = get_fea_ptr(irec, sd_name, ihd); REQUIRE(sd_ptr, "can't locate sampled-data field in input record"); size = get_fea_siz(sd_name, ihd, (short *) NULL, (long **) NULL); REQUIRE(size != -1, "bad sampled-data field definition in input file"); REQUIRE(win_len <= size, "window_len larger than sd field size"); if (ihd->hd.fea->segment_labeled) { frame_len = (long *) get_fea_ptr(irec, "segment_length", ihd); REQUIRE(frame_len, "no segment_length field in input file header"); if (debug_level) Fprintf(stderr, "Input file segment_labeled.\n"); file_ind = lin_search2(ihd->hd.fea->names,"source_file"); set_seg_lab(ohd, ihd->hd.fea->enums[file_ind]); seglab = 1; } else { frame_len = &size; if (debug_level) Fprintf(stderr, "Input file not segment_labeled. Frame length: %ld.\n", *frame_len); } /* 0 input for window_len (default) means size of sd field*/ if (win_len == 0) win_len = size;/* * Create and write output-file header */ ohd = new_header(FT_FEA); if (ihd->common.tag == YES) { ohd->common.tag = YES; ohd->variable.refer = ihd->variable.refer; tagged = 1; ohd->variable.refhd = ihd->variable.refhd; } (void) strcpy(ohd->common.prog, ProgName); (void) strcpy(ohd->common.vers, Version); (void) strcpy(ohd->common.progdate, Date); add_source_file(ohd, iname, ihd); add_comment(ohd, get_cmd_line(argc, argv)); *add_genhd_e( "window_type", (short *) NULL, 1, window_types, ohd) = win; REQUIRE( add_fea_fld(wsd_name, size, (short) 1, (long *) NULL, FLOAT, (char **) NULL, ohd) != -1, "can't create wind_field_name field in output file header" ); *add_genhd_l( "window_len", (long *) NULL, 1, ohd) = win_len; *add_genhd_l("nan", (long *) NULL, 1, ohd) = num_recs; *add_genhd_l("start", (long *) NULL, 1, ohd) = start_rec; (void) copy_genhd(ohd, ihd, "src_sf"); update_waves_gen(ihd, ohd, (float) start_rec, 1.0); if (debug_level) Fprintf(stderr, "Writing output header to file.\n"); write_header(ohd, ofile);/* * Allocate records and set up pointers */ orec = allo_fea_rec(ohd); REQUIRE(orec != NULL, "can't allocate memory for output record"); wsd_ptr = (float *) get_fea_ptr(orec, wsd_name, ohd); REQUIRE(wsd_ptr, "can't locate wind_samp_data field in output record"); data = calloc_f((unsigned) size); REQUIRE(data, "can't allocate space for array of data as floats"); for (i = 0; i < size; i++) wsd_ptr[i] = 0.0;/* * Main read-write loop */ num_read = start_rec - 1, fea_skiprec(ifile, num_read, ihd); for ( ; num_read < end_rec && get_fea_rec(irec, ihd, ifile) != EOF; num_read++ ) { if (debug_level > 2) Fprintf(stderr, "Record number %ld read.\n", num_read + 1); if (tagged) orec->tag = irec->tag; else if (seglab) copy_fea_rec(irec, ihd, orec, ohd, seg_fields, (short **) NULL); (void) type_convert(win_len, (char *) sd_ptr, sd_type, (char *) data, FLOAT, (void (*)())NULL); if (debug_level > 3) pr_farray("sampled data input", win_len, data); if (*frame_len < win_len) seglenwarn++; /* window it, with results going directly to output record*/ if(win != WT_ARB){ (void) window(win_len, data, wsd_ptr, win, (double *) NULL); (void)add_genhd_c("window_data_in", window_type, 1, ohd); } else (void)window(win_len, data, wsd_ptr, win, udefined); if (debug_level > 3) pr_farray("windowed sampled data", win_len, wsd_ptr); put_fea_rec(orec, ohd, ofile); } if (seglenwarn) Fprintf(stderr, "%s: WARNING - some segment_length values less than window size\n", ProgName); if (num_read < end_rec && num_recs != 0) Fprintf(stderr, "window: only %ld records read.\n", num_read - start_rec + 1);/* * Write common */ if (ofile != stdout) { REQUIRE(putsym_i("start", (int) start_rec) != -1, "can't write \"start\" to Common"); REQUIRE(putsym_i("nan", (int) num_recs) != -1, "can't write \"nan\" to Common"); REQUIRE(putsym_s("prog", ProgName) != -1, "can't write \"prog\" to Common"); REQUIRE(putsym_s("filename", iname) != -1, "can't write \"filename\" to Common"); } exit(0); /*NOTREACHED*/}/* * For debug printout of float arrays */void pr_farray(text, n, arr) char *text; long n; float *arr;{ int i; Fprintf(stderr, "%s: %s -- %d points:\n", ProgName, text, n); for (i = 0; i < n; i++) { Fprintf(stderr, "%f ", arr[i]); if (i%5 == 4 || i == n - 1) Fprintf(stderr, "\n"); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?