plotspec.c
来自「speech signal process tools」· C语言 代码 · 共 826 行 · 第 1/2 页
C
826 行
/* * 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) 1987-1990 Entropic Speech, Inc. * "Copyright (c) 1990-1996 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: Shankar Narayan * Checked by: * Revised by: * * Plot spectral data. *//*----------------------------------------------------------------------+| || plotspec -- plot spectral data in plotas input format || || Originally by Shankar Narayan, EPI. SDS version by Joe Buck. || SPS version by Rod Johnson. Modified by John Shore to remove || common.ndrec dependence. -d option by Ajaipal S. Virdy. || -D, -F and -l options by Rod Johnson. Converted from SPEC to || FEA_SPEC input by Rod Johnson. Modified by Derek Lin so that || atan2: domain error when 0 complex number is encountered. || || Module: plotspec.c || || This, the main module of plotspec, interprets the command line, || sets up and checks input, output, and temporary files, and reads || the data. Using a temporary file, it makes two passes over the || data--one to determine the maximum and minimum values and one to || draw the plot. It calls on plotscale to determine axis labels, || draw_box to draw and label the axes, plotdata to plot the data, || and printtime to write the date and time on the plot. || || Input to plotspec is an ESPS FEA_SPEC file. More than one record || may be plotted, superposed on one set of axes. Output, in the || ``Stanford'' Ascii format accepted by plotas and stou, is written || to the standard output. || |+----------------------------------------------------------------------*/static char *sccs_id = "@(#)plotspec.c 3.12 1/20/97 ESI/ERL";#include <stdio.h>#include <esps/esps.h>#include <esps/unix.h>#include <esps/constants.h>#include <esps/fea.h>#include <esps/feaspec.h>#define THISPROG "plotspec"#define SYNTAX \USAGE("plotspec [-d][-l][-r range][-t text]... [-x debug_level][-y range]\n [-D][-E][-F][-T device][-X range][-Y range] file.spec") /* -T option handled by command script, not C program. */#define TRYALLOC(type,num,var) { \ if (((var) = (type *) malloc((unsigned)(num)*sizeof(type)))==NULL) \ { Fprintf(stderr, "%s: can't allocate memory for %d points.\n", \ THISPROG, (int)(num)); \ exit(1); }}#define REQUIRE(test,text) {if (!(test)) {(void) fprintf(stderr, \"%s: %s - exiting\n", ProgName, text); exit(1);}}#define Printf (void) printf#define MAXTEXT 10#define kHz 1000.0/* external system functions */double pow(), log10(), atan2();/* external ESPS functions */void lrange_switch();void frange_switch();void plotscale();void plotexscale();char **genhd_codes();/* local ESPS functions */void erase();char *e_temp_name();/* external variables */extern int optind; /* Used in command-line parsing by getopt */extern char *optarg; /* Used in command-line parsing by getopt *//* global variable */char *ProgName = THISPROG;int debug_level = 0; /* MAIN PROGRAM */main(argc, argv) int argc; char **argv;{ int c; /* Command-line option letter */ struct feaspec *spec_rec; /* Input data record */ struct header *ih; /* Input ESPS file header */ struct header *temp_hd; /* Temporary ESPS file header */ FILE *specfile; /* Input file pointer */ FILE *tempfile; /* Temporary file pointer */ char *specname; /* Name of input file */ char *tempname = "plspXXXXXX"; /* Template for temp file name */ char *newname; /* Temp file name */ char *rrange = NULL; /* Range of records to plot (-r option) */ char *xrange = NULL; /* Range of frequencies (-X option) */ char *yrange = NULL; /* Spectral value range (-y & -Y options) */ int yflag = NO; /* -Y or -y option specified? */ int yexact = NO; /* -Y option specified? */ char *text[MAXTEXT]; /* Text lines below plot (-t option) */ int ntext = 0; /* Number of text lines below plot */ int sflag = NO; /* -s option specified? */ int dflag = NO; /* -d option specified? */ int lflag = NO; /* -l option specified? */ int Dflag = NO; /* -D option specified? */ int Fflag = NO; /* -F option specified? */ int Eflag = NO; /* -E option specified? */ double xmin, xmax; /* x-axis limits */ double xmin_def; /* default xmin */ double xmink, xmaxk; /* x-axis limits (kilohertz) */ double xstepk; /* x-axis tic spacing */ double ymin, ymax; /* y-axis limits */ double ystep; /* y-axis tic spacing */ short freq_format; /* How set of freqencies is defined. */ short spec_type; /* Is spectrum log power, complex, etc.? */ short contin; /* Continuous or discrete spectrum? */ long num_freqs; /* Number of points in spectrum record */ long start_plot; /* Index of first point in record to plot */ long end_plot; /* Index of last point in record to plot */ int num_plot; /* Number of points in record to plot */ float sf; /* Sampling frequency */ float *freqs; /* Frequencies of points in spectrum */ double freqmin; /* Frequency of first point in record */ double freqmax; /* Frequency of last point in record */ double datamin; /* Lowest data value in range to be plotted */ double datamax; /* Highest data value in range to be plotted */ float *dist_func; /* Cumulative distribution function */ float *dfreqs; /* Frequencies of points in distr. function */ double delta_h; /* Difference between successive frequencies */ double R0; /* Running total of power in spectrum */ double delta_R; /* Increment in R0 */ double rsv, isv; /* Real & imag. spectral values from record */ double tot_power; /* Total power in spectrum */ float zero_power = 0.0; /* Used when tot_power field not defined in input file. */ int xdp, ydp; /* Number of decimal places for scale marks */ long firstrec, lastrec; /* First and last records in specified range */ long nplots; /* Number of records in specified range */ long nrec; /* Number of records to actually plot */ int i, j, iy, k; /* Loop indices */ int clr = 0; /* Color *//* Process command-line options */ while ((c = getopt(argc, argv, "dlr:st:x:y:DEFX:Y:")) != EOF) switch (c) { case 'd': /* plot cumulative distribution function */ dflag++; break; case 'l': /* plot frequencies with log scale */ lflag++; break; case 'r': rrange = optarg; break; case 's': /* plot records on separate pages */ /* (not working) */ sflag++; break; case 't': if (ntext < MAXTEXT) text[ntext++] = optarg; else { Fprintf(stderr, "%s: Too many -t options\n", ProgName); exit(1); } break; case 'x': debug_level = atoi(optarg); break; case 'y': yrange = optarg; yflag = YES; break; case 'D': /* convert to dB */ Dflag++; break; case 'E': /* don't erase */ Eflag++; break; case 'F': /* plot phase */ Fflag++; break; case 'X': xrange = optarg; break; case 'Y': yrange = optarg; yflag = YES; yexact = YES; break; default: SYNTAX; break; }/* Process file name argument and open file */ if (optind >= argc) { Fprintf(stderr, "%s: no input file\n", ProgName); SYNTAX; exit(1); } else if (optind < argc - 1) { Fprintf(stderr, "%s: more than one input file\n", ProgName); SYNTAX; exit(1); } else specname = eopen(ProgName, argv[optind], "r", FT_FEA, FEA_SPEC, &ih, &specfile); temp_hd = copy_header(ih);/* Get generic header items./* Check for violations of certain limitations. */ REQUIRE(genhd_type("freq_format", (int *) NULL, ih) == CODED, "Header item \"freq_format\" wrong type or undefined.") freq_format = *get_genhd_s("freq_format", ih); switch (freq_format) { case SPFMT_SYM_EDGE: case SPFMT_SYM_CTR: case SPFMT_ASYM_EDGE: case SPFMT_ASYM_CTR: break; default: Fprintf(stderr, "%s: only freq formats %s supported so far.\n", "SYM_EDGE, SYM_CTR, ASYM_EDGE, ASYM_CTR", ProgName); exit(1); break; } REQUIRE(genhd_type("spec_type", (int *) NULL, ih) == CODED, "Header item \"spec_type\" wrong type or undefined.") spec_type = *get_genhd_s("spec_type", ih); REQUIRE(genhd_type("contin", (int *) NULL, ih) == CODED, "Header item \"contin\" wrong type or undefined.") contin = *get_genhd_s("contin", ih); if (!contin) { Fprintf(stderr, "%s: discrete distributions not yet supported.\n", ProgName); exit(1); } REQUIRE(genhd_type("num_freqs", (int *) NULL, ih) == LONG, "Header item \"num_freqs\" wrong type or undefined.") num_freqs = *get_genhd_l("num_freqs", ih); REQUIRE(genhd_type("sf", (int *) NULL, ih) == FLOAT, "Header item \"sf\" wrong type or undefined.") (sf = *get_genhd_f("sf", ih)) || (sf = 1.0); if (sflag) { Fprintf(stderr, "%s: -s option not implemented yet.\n", ProgName); exit(1); } if (dflag && Fflag) { Fprintf(stderr, "%s: -d and -F options incompatible.\n", ProgName); exit(1); } if (dflag && Dflag) { Fprintf(stderr, "%s: -d and -D options incompatible.\n", ProgName); exit(1); } if (Dflag && Fflag) { Fprintf(stderr, "%s: -D and -F options incompatible.\n", ProgName); exit(1); } if (Fflag && spec_type != SPTYP_CPLX) { Fprintf(stderr, "%s: -F option requires complex data.\n", ProgName); exit(1); }/* get range of records to try to plot */ firstrec = 1; lastrec = LONG_MAX; lrange_switch(rrange, &firstrec, &lastrec, 0); if (firstrec < 1) firstrec = 1; nplots = lastrec - firstrec + 1;/* Open temporary file */ if ((tempfile = fopen(newname = e_temp_name(tempname), "w+")) == NULL) { perror(ProgName); Fprintf(stderr, "%s: can't open temporary file.\n", ProgName); exit(1); } (void) unlink(newname); write_header(temp_hd, tempfile); spec_rec = allo_feaspec_rec(ih, FLOAT); if (spec_rec->tot_power == NULL) { spec_rec->tot_power = &zero_power; }/* allocate memory */ TRYALLOC(float, num_freqs, freqs) if (dflag) { TRYALLOC(float, num_freqs + 1, dist_func) TRYALLOC(float, num_freqs + 1, dfreqs) } switch (freq_format) { case SPFMT_SYM_CTR: delta_h = sf / (2 * num_freqs); if (dflag) { freqmin = dfreqs[0] = 0.0; freqmax = dfreqs[num_freqs] = 0.5 * sf; for (j = 1; j < num_freqs; j++) dfreqs[j] = j * delta_h; } else { freqmin = 0.5 * delta_h; freqmax = 0.5 * sf - freqmin; } for (j = 0; j < num_freqs; j++) freqs[j] = (j + 0.5) * delta_h; break; case SPFMT_SYM_EDGE: delta_h = sf / (2 * (num_freqs - 1)); if (dflag) { freqmin = dfreqs[0] = 0.0; freqmax = dfreqs[num_freqs] = 0.5 * sf; for (j = 1; j < num_freqs; j++) dfreqs[j] = (j - 0.5) * delta_h; } else { freqmin = 0.0; freqmax = 0.5 * sf; } for (j = 0; j < num_freqs; j++) freqs[j] = j * delta_h; break; case SPFMT_ASYM_CTR: delta_h = sf / num_freqs; if (dflag) { freqmin = dfreqs[0] = -0.5 * sf;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?