📄 dspsgram.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: dspsgram.c || || This program computes spectrograms (FEA_SPEC files) from FEA_SD files|| by using the AT&T dsp board. || || Rodney Johnson, Entropic Speech, Inc. || based on ESPS module sgram.c and waves+ module spect.c || |+----------------------------------------------------------------------*/#ifndef lint static char *sccs_id = "@(#)dspsgram.c 1.7 6/21/91 ESI";#endif#define VERSION "1.7"#define DATE "6/21/91"#define PROGNAME "dspsgram"#include <Objects.h>#include <stdio.h>#include <esps/esps.h>#include <esps/unix.h>#include <esps/limits.h>#include <esps/fea.h>#include <esps/feasd.h>#include <esps/feaspec.h>#include <esps/window.h>#include <dsplock.h>#include <dsp32.h>#include <spectrogram.h>#define ALWAYS_LOAD 1#include <sys/ioctl.h>#include <dsp32c.h>#include <vme32c.h>#define PARAM_WAIT_CODE ((short int) 2)#define DATA_WAIT_CODE ((short int) 3)#define DSP_INIT_CODE ((short) 0)#define DSP_START_CODE ((short) 1)#define DSP_CHIP 0extern int dsp32c_sm, dsp32c_io, dsp32c[];extern char *DSP_SharedMemory, *DSP_io;char *spect_prog=NULL;#define EXIT(x) {if (locked) (void) DSP_UNLOCK; exit(x);}#define ERROR_EXIT(text) {(void) fprintf(stderr, "%s: %s - exiting\n", \ ProgName, text); EXIT(1)}#define SYNTAX \USAGE("dspsgram [-d data_window][-m method][-o fft_order][-r range] [-p range][-s range][-w window_len][-E pre_emphasis][-P param_file][-S step_size] input.sd output.fspec")#define WT_PREFIX "WT_"#define GET_NX (nx = nsamps / (step*sizeof(long)) * sizeof(long))#define ADJ_NFRM (nfrm = MIN(nx - x, nfrm)) /* must be even *//* * global variables */char *Version = VERSION;char *Date = DATE;char *ProgName = PROGNAME;int debug_level = 0; /* debug level */int dsp32_wait = 5;int dsp_type;int setup_dsp();char *dspmap();void pr_farray();char *sh_mem;char loaded[100] = "";/* * external functions */double pow();char *get_cmd_line();void lrange_switch(), frange_switch();char *eopen();/* * 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 *ih, *oh; /* input and output file headers */ char *iname, *oname; /* input and output file names */ struct feaspec *spec_rec; /* record for output spectral data */ char *re_spec_val; /* pointer to spectral data in record */ extern int optind; extern char *optarg; int ch; int dflag = NO; /* flag for data_window option */ int mflag = NO; /* flag for method option -m */ int p_mflag = NO; /* flag for method in parameter file */ 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 */ int oflag = NO; /* flag for fft_order option */ int order; /* order (exponent of 2) of fft */ int def_order; /* default order */ int pflag = 0; /* flag for range (pts.) option*/ char *prange = NULL; /* string for range specification (-p) */ int sflag = 0; /* flag for range (sec.) option */ char *srange = NULL; /* string for range specification (-s) */ int wflag = 0; /* flag for window_len option */ double window_len; /* length of window (ms) */ double def_window_len; /* default window length */ int Eflag = 0; /* flag for preemphasis option */ double preemph; /* preemphasis */ double def_preemph; /* default preemphasis */ int Sflag = 0; /* flag for step_size option */ double step_size; /* step size (ms) */ double def_step_size; /* default step size */ int size; /* size of generic header item */ short freq_format; short spec_type; long num_freqs; long frame_len; /* number of sampled data points */ long tr_length; /* number of points in transform */ double sf; /* sampling frequency */ int actsize; /* actual number points read */ short *data; /* array for sampled data */ long position; /* current position in SD file */ long step; /* step size for shifting frames */ long start; long end; long nan; int win; /* window type code */ extern char *window_types[]; /* standard window type names */ double file_start_time; double data_start_time; double data_end_time; long num_channels; int locked = NO; /* lock file set? */ int nfrm, nsamps, nx, ny, x, nk; int eof; int i, cnt; short *p, *q; /* pointers into data or shared memory */ static float fwind[1024]; struct mem_dpr { short nfft, win, step, ni; float pre, qc[5], qbw[5]; short fnx, fny, fni, fnh; float fh[100]; float window[512]; } dp; char **dpp; /* * process command line options */ while ((ch = getopt(argc, argv, "d:m:o:r:p:s:w:x:E:P:S:")) != EOF) switch (ch) { case 'd': dflag = YES; window_type = optarg; hd_method = "other"; break; case 'm': method = optarg; mflag = YES; break; case 'o': order = atoi(optarg); oflag = YES; hd_method = "other"; break; case 'r': case 'p': prange = optarg; pflag = YES; break; case 's': srange = optarg; sflag = YES; break; case 'w': wflag = YES; 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 = YES; hd_method = "other"; 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 for bad input data types */ if((num_channels = get_fea_siz("samples", ih,(short *) NULL, (long **) NULL)) != 1){ Fprintf(stderr, "%s: Multichannel data not supported yet - exiting.\n", ProgName); exit(1); } if(is_field_complex(ih, "samples") == YES) { Fprintf(stderr, "%s: Complex data not supported - exiting.\n", ProgName); exit(1); } if (ih->common.ndrec != -1) end = ih->common.ndrec; else { Fprintf(stderr,"dspsgram: input cannot be pipe.\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 = "HAMMING"; def_order = 9; def_window_len = 40.0; def_preemph = .94; def_step_size = 2.0; break; case 1: /* "wb" */ def_window_type = "HAMMING"; def_order = 7; def_window_len = 8.0; def_preemph = .94; def_step_size = 2.0; break; default: ERROR_EXIT("Unrecognized method given with -m option.") break; } /* if method was given in parameter file set the various values since they will not be overriden by other parameters*/ if (p_mflag) { 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) ERROR_EXIT("Can't handle order > 10.") 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.)) == -1.){ Fprintf(stderr,"%s: Invalid record frequency in input file - exiting.\n", ProgName); 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: start = getsym_i("start"); break; default: ERROR_EXIT("Parameter \"start\" not of integer type.") break; } switch (symtype("nan")) { case ST_UNDEF: nan = 0; break; case ST_INT: nan = getsym_i("nan"); break; default: ERROR_EXIT("Parameter \"nan\" not of integer type.") break; } end = (nan == 0) ? LONG_MAX : start + nan - 1; data_start_time = file_start_time + (start - 1) / sf; } if (start < 1) ERROR_EXIT("can't start before beginning of file"); if (debug_level) Fprintf(stderr, "start = %ld, nan = %ld, end = %ld, data_start_time = %g\n", start, nan, end, data_start_time); /* -w window_len */ if (!(wflag || p_mflag)) switch (symtype("window_len")) { case ST_UNDEF: window_len = def_window_len; break; case ST_FLOAT: window_len = getsym_d("window_len"); break; default: ERROR_EXIT("Parameter \"window_len\" not of float type.") break; } frame_len = LROUND(window_len * sf / 1000.0); if (debug_level) Fprintf(stderr, "window_len = %g, frame_len = %ld\n", window_len, frame_len); if (frame_len < 1) ERROR_EXIT("Window must be at least 1 sample wide.") if (frame_len > 1024) ERROR_EXIT("Window must not exceed 1024 samples.") while (frame_len > tr_length) tr_length *= 2; if (debug_level) Fprintf(stderr, "frame length %ld, transform length %ld\n", frame_len, tr_length); /* -E pre_emphasis */ if (!(Eflag || p_mflag)) switch (symtype("pre_emphasis")) { case ST_UNDEF: preemph = def_preemph; break; case ST_FLOAT: preemph = getsym_d("pre_emphasis"); break; default: ERROR_EXIT("Parameter \"pre_emphasis\" not of float type.") break; } if (debug_level)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -