📄 sgram.c
字号:
/* * 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) 1990 Entropic Speech, Inc. All rights reserved." * * Program: sgram.c (FEA_SPEC version) * * This program computes spectrograms from FEA_SD files to FEA_SPEC files. * * Rodney Johnson, Entropic Speech, Inc. * based on fft.c */#ifndef lint static char *sccs_id = "@(#)sgram.c 1.20 8/31/95 ESI"; #endifchar *Version = "1.20";char *Date = "8/31/95";#include <stdio.h>#include <esps/esps.h>#include <esps/unix.h>#include <esps/limits.h>#include <esps/feasd.h>#include <esps/feaspec.h>#include <esps/fea.h>#include <esps/window.h>#define ERROR_EXIT(text) {(void) fprintf(stderr, "%s: %s - exiting\n", \ ProgName, text); exit(1);}#define SYNTAX \USAGE("sgram [-d data_window][-m method][-o fft_order][-{pr} range][-s range]\n\t[-w window_len][-E pre_emphasis][-P param_file][-S step_size] \n\t [-T desired_frames] [-z] input.sd output.fspec")#define WT_PREFIX "WT_"/* * global variables */char *ProgName = "sgram";int debug_level = 0; /* debug level */void pr_farray();/* * external functions */double log10(), pow(), ceil(), sqrt();char *get_cmd_line();void lrange_switch(), frange_switch();char *eopen();void get_rfft();/* * main program */main(argc, argv) int argc; char **argv;{ char *param_file = NULL; /* parameter file name */ FILE *ifile = stdin, /* input and output file streams */ *ofile = stdout; struct header /* input and output file headers */ *ih, *oh; char *iname, /* input and output file names */ *oname; struct feaspec /* record for spectral data */ *spec_rec; extern int optind; extern char *optarg; int ch; short zflag = 1; /* flag for -z (silent) option */ short dflag = 0; /* flag for data_window option */ short mflag = 0; /* flag for method option -m */ short p_mflag = 0; /* flag for method in parameter file */ short Tflag = 0; /* flag for -T option */ long des_frames = 0; /* number of required frames */ char *window_type; /* name of type of window to apply to data */ char *pref_w_type; /* window type name with added prefix */ char *def_window_type; /* default name of window type */ char *method = "wb"; /* method name */ char *hd_method = "wb"; /* method name for generic item */ static char *methods[] = {"nb", "wb", NULL}; /* valid method names */ short oflag = 0; /* flag for fft_order option */ long order; /* order (exponent of 2) of fft */ long def_order; /* default order */ short pflag = 0; /* flag for range (pts.) option*/ char *prange = NULL; /* string for range specification (-p) */ short sflag = 0; /* flag for range (sec.) option */ char *srange = NULL; /* string for range specification (-s) */ short wflag = 0; /* flag for window_len option */ long window_size; /* number of samples in effective window */ double window_len; /* length of window (ms) */ double def_window_len; /* default window length */ short Eflag = 0; /* flag for preemphasis option */ double preemph; /* preemphasis */ double def_preemph; /* default preemphasis */ short Sflag = 0; /* flag for step_size option */ double step_size; /* step size (ms) */ double def_step_size; /* default step size */ long i, j; long size; /* size of generic header item */ short freq_format; short spec_type; long num_freqs; long frame_len; /* number of sampled data points in frame */ long tr_length; /* number of points in transform */ unsigned alloc_len; double sf; /* sampling frequency */ long actsize; /* actual number points read */ long data_length; /* actual number points transformed */ long nframes; /* number fixed length frames to process*/ float fpow; /* power at one frequency */ float tot_power; /* total power */ float *x, *px; /* arrays for data and preemphasized data */ float *wx, *y; /* arrays for windowed data and fft */ float scale; /* scaling constant */ short more = 1; /* flag to indicate more sampled data*/ long position; /* current position in SD file */ long step; /* step size for shifting frames */ long start; long end; long nan; short win; /* window type code */ extern char *window_types[]; /* standard window type names */ double file_start_time; double data_start_time; double data_end_time; int zeros = 0; /* count frequencies with zero power */ long num_channels; /* holds number of input data channels*/ /* * process command line options */ while ((ch = getopt(argc, argv, "d:m:o:p:r:s:w:x:E:P:S:T:z")) != EOF) switch (ch) { case 'z': zflag = 1; break; case 'd': dflag++; window_type = optarg; hd_method = "other"; break; case 'm': method = optarg; mflag++; break; case 'o': order = atoi(optarg); oflag++; hd_method = "other"; break; case 'p': case 'r': prange = optarg; pflag++; break; case 's': srange = optarg; sflag++; break; case 'w': wflag++; window_len = atof(optarg); hd_method = "other"; break; case 'x': debug_level = atoi(optarg); break; case 'E': preemph = atof(optarg); Eflag = YES; hd_method = "other"; break; case 'P': param_file = optarg; break; case 'S': step_size = atof(optarg); Sflag++; hd_method = "other"; break; case 'T': des_frames = atoi(optarg); Tflag++; break; default: SYNTAX ; break; } if (mflag && (strcmp(hd_method, "other") != 0)) hd_method = method; /* * process file arguments */ if (optind < argc) iname = eopen(ProgName, argv[optind++], "r", FT_FEA, FEA_SD, &ih, &ifile); else { Fprintf(stderr, "%s: no input sampled data file specified.\n", ProgName); SYNTAX ; } if (debug_level) Fprintf(stderr, "Input file is %s\n", iname); if (optind < argc) oname = eopen(ProgName, argv[optind++], "w", NONE, NONE, &oh, &ofile); else { Fprintf(stderr, "%s: no output FEA_SPEC file specified.\n", ProgName); SYNTAX ; } if (debug_level) Fprintf(stderr, "Output file is %s\n", oname); /* * Check input file for multichannel and complex data */ if((num_channels = get_fea_siz("samples", ih,(short *) NULL, (long **) NULL)) != 1){ Fprintf(stderr, "sgram: Multichannel data not supported yet - exiting\n"); exit(1); } if(is_field_complex(ih, "samples") == YES){ Fprintf(stderr, "sgram: Complex input data not supported yet - exiting.\n"); exit(1); } /* * process parameters */ if (strcmp(iname, "<stdin>") != 0) (void) read_params(param_file, SC_CHECK_FILE, iname); else (void) read_params(param_file, SC_NOCOMMON, iname); /* -m method */ if (!mflag) { if (symtype("method") != ST_UNDEF) { method = getsym_s("method"); if (strcmp(method, "other") == 0) { /* if parameter file says 'other', defaults are for 'wb' but other params may override*/ hd_method = "other"; method = "wb"; } else { /* if param file has specific method (nb or wb), go with that and do not allow parameter overrides*/ hd_method = method; p_mflag++; } } } switch (lin_search2(methods, method)) { case 0: /* "nb" */ def_window_type = "HANNING"; def_order = 9; def_window_len = 40.0; def_preemph = .94; def_step_size = 2.0; break; case 1: /* "wb" */ def_window_type = "HANNING"; def_order = 8; def_window_len = 8.0; def_preemph = .94; def_step_size = 2.0; break; default: ERROR_EXIT("Unrecognized method given with -m option.") break; } /* Based on the method, set the various parameters unless they * have command line overrides */ if (!dflag) window_type = def_window_type; if (!oflag) order = def_order; if (!wflag) window_len = def_window_len; if (!Eflag) preemph = def_preemph; if (!Sflag) step_size = def_step_size; /* -d data_window */ if (!(dflag || p_mflag)) switch (symtype("data_window")) { case ST_UNDEF: window_type = def_window_type; break; case ST_STRING: window_type = getsym_s("data_window"); break; default: ERROR_EXIT("Parameter \"data_window\" not of string type.") break; } pref_w_type = malloc((unsigned)(strlen(WT_PREFIX) + strlen(window_type) + 1)); spsassert(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); spsassert(win > -1, "window type not recognized"); if (debug_level) Fprintf(stderr, "window_type = %s, win = %d\n", window_type, win); /* -o order */ if (!(oflag || p_mflag)) switch (symtype("fft_order")) { case ST_UNDEF: order = def_order; break; case ST_INT: order = getsym_i("fft_order"); break; default: ERROR_EXIT("Parameter \"fft_order\" not of integer type.") break; } if ((order > 10) && !zflag) Fprintf(stderr, "%s: WARNING - HEY!!!, order = %ld makes for a huge spectrogram\n", ProgName, order); tr_length = ROUND(pow(2.0, (double) order)); if (debug_level) Fprintf(stderr, "fft_order = %d, tr_length = %ld\n", order, tr_length); /* -p range & -s range */ switch (genhd_type("start_time", &size, ih)) { case HD_UNDEF: file_start_time = 0.0; break; case DOUBLE: file_start_time = *get_genhd_d("start_time", ih); break; default: ERROR_EXIT("Header item \"start_time\" not of double type.") break; } if((sf = get_genhd_val("record_freq", ih, (double) -1)) <= 0){ Fprintf(stderr, "sgram: Record_freq (sf) is not a positive value - exiting.\n"); exit(1); } if (debug_level) Fprintf(stderr, "file_start_time = %g, sf = %g\n", file_start_time, sf); if (pflag && sflag) ERROR_EXIT("Conflicting options specified: -p and -s.") else if (pflag) { start = 1; end = LONG_MAX; lrange_switch(prange, &start, &end, 0); nan = (end == LONG_MAX) ? 0 : end - start + 1; data_start_time = file_start_time + (start - 1) / sf; } else if (sflag) { data_start_time = file_start_time; data_end_time = FLT_MAX; frange_switch(srange, &data_start_time, &data_end_time); start = 1 + LROUND((data_start_time - file_start_time) * sf); if (data_end_time == FLT_MAX) { end = LONG_MAX; nan = 0; } else { end = LROUND((data_end_time - file_start_time) * sf); nan = end - start + 1; } } else { switch (symtype("start")) { case ST_UNDEF: start = 1; break; case ST_INT:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -