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