auto.c

来自「speech signal process tools」· C语言 代码 · 共 487 行

C
487
字号
/* * 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) 1990-1991  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:  Burton, Johnson, Shore * Checked by: * Revised by: * * Brief description: * */static char *sccs_id = "@(#)auto.c	1.11	8/31/95	ERL";char *Version = "1.11";char *Date = "8/31/95";/* * System Includes*/#include <stdio.h>#include <math.h>/* * ESPS INCLUDES*/#include <esps/esps.h>#include <esps/sd.h>#include <esps/anafea.h>#include <esps/fea.h>#include <esps/unix.h>#include <esps/window.h>/* * Defines */#define ERROR_EXIT(text) {(void) fprintf(stderr, "%s: %s - exiting\n", \		ProgName, text); exit(1);}#define SYNTAX \USAGE("auto [-l frame_len] [-o order] [-{pr} range] [-w window_type]\n [-x debug_level] [-P param] [-S step_size] [-B] sd.file fea_ana.file")#define BUFSIZE 8192#define STRCOV_CONV 1e-5#define STRCOV_ITER 20/* * global variables */char	*ProgName = "auto";int	debug_level = 0;		/* debug level */void	get_range();/* * ESPS Functions */    int get_auto();    char *get_cmd_line();    void lrange_switch();    void put_sd_recf();    extern int            optind;    extern char            *optarg;/* * 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,	    *tmp = NULL;	/*tmp file stream*/    struct header  		/* input and output file headers */            *ih, *oh;    char    *iname, 		/* input and output file names */	    *oname;	        struct anafea	    *fea_ana_rec;	/* record for fea_ana data */    short   window_type = WT_RECT;  /* type of data window*/    char    *w_type = "RECT";	/*window type description*/    char    *window_func;	/*variable to use in lin_search*/    int     order = 10;		/* order of auto */    char    *prange = NULL;	/* string for range specification (-p) */    int     o_flag = 0;		/* flag for order option */    int	    p_flag = 0;		/* flag for range option */    int     w_flag = 0;		/* flag for data window option*/    int     B_flag = 0;		/* flag for strcov option */    long    first, i, j;    long    frame_len = -1;	/* number of sampled data points per frame*/    long    step_size = 0;	/* number of points between frames*/    int	    actsize;		/* actual number points read */    long    nframes = 1;	/*number fixed length frames to process*/    float   tot_power;		/* total power */    float   *x, *xwindow;	/* array for data and windowed data*/    double  *y;			/* array for autocorrelation of data*/    long    position;		/* current position in FEA_SD file */    int     c;			/*option argument*/    long    num_of_points = 0;	/*total points in input file*/    int     npts = 0;		/* # pts returned by get_sd_recf*/    long    nan;		/*total points analyzed*/    static float	    tmpdata[BUFSIZE];	/*temporary data storage*/    int     first_time = YES;	/* flag for get_sd_orec*/    char    *power = "unwindowed";  /*power computation option*/    /*     * process command line options     */    while ((c = getopt(argc, argv, "w:P:o:p:r:x:l:S:B")) != EOF)        switch (c) {	case 'P':	    param_file = optarg;	    break;        case 'o':            order = atoi(optarg);	    o_flag++;	    break;	case 'x':	    debug_level = atoi(optarg);	    break;        case 'p':	case 'r':            prange = optarg;	    p_flag++;            break;	case 'l':	    frame_len = atoi(optarg);	    break;	case 'S':	    step_size = atoi(optarg);	    break;	case 'w':	    w_flag++;	    w_type = optarg;	    break;	case 'B':	    B_flag++;	    break;        default:             SYNTAX;            break;        }    /*     * process file arguments     */    if (optind < argc)	iname = argv[optind++];    else {	Fprintf(stderr, "auto: no input sampled_data file specified.\n");	SYNTAX;    }    if (optind < argc)	oname = argv[optind++];    else {	Fprintf(stderr, "%s: no output FEA_ANA file specified.\n", ProgName);	SYNTAX;    }    if (optind < argc)    {	Fprintf(stderr, "%s: too many file names.\n", ProgName);	SYNTAX;    }    iname = eopen(ProgName, iname, "r", FT_FEA, FEA_SD, &ih, &ifile);    oname = eopen(ProgName, oname, "w", NONE, NONE, &oh, &ofile);    if (debug_level)    {	Fprintf(stderr, "Input file is %s\n", iname);	Fprintf(stderr, "Output file is %s\n", oname);    }    /*     * is file single-channel and real?     */    if (get_fea_siz("samples", ih, (short *) NULL, (long **) NULL) != 1)	ERROR_EXIT("Multichannel data not supported yet");    if (is_field_complex(ih, "samples"))	ERROR_EXIT("Complex data not supported yet");        /*     * determine frame_length, power option, and range     */    (void) read_params(param_file, SC_CHECK_FILE, iname);    if (!o_flag)	if (symtype("order") != ST_UNDEF)	    order = getsym_i("order");    if(symtype("power") != ST_UNDEF)	power = getsym_s("power");    if (!w_flag)	if (symtype("window") != ST_UNDEF)	    w_type = getsym_s("window");    if (!B_flag)       if (symtype("strcov_auto") != ST_UNDEF)	if (!strcmp(getsym_s("strcov_auto"), "yes"))	  B_flag = 1;    /*     * Add prefix to window type and find numeric value     */    window_func = malloc((unsigned)(strlen(w_type) + 4));    (void)strcpy(window_func, "WT_");    (void)strcat(window_func, w_type);    if((window_type = lin_search(window_types, window_func)) == -1){	ERROR_EXIT("ERROR: Invalid window function specified");    }   /*    * Get number of points in the file    */    num_of_points = 0;    if(ih->common.ndrec == -1){/*input is pipe - count the points*/	tmp = tmpfile();	while((npts = get_sd_recf(tmpdata, (int)BUFSIZE, ih, ifile)) != 0) {	    put_sd_recf(tmpdata, npts, ih, tmp);	    num_of_points += npts;	}	rewind(tmp);	ifile = tmp;	/*reassign input file stream to tmp*/    }    else	num_of_points = ih->common.ndrec;    get_range	(&first, &frame_len, &nframes, prange, 	p_flag, num_of_points, &nan, &step_size);    symerr_exit();  /*exit if any of the parameters were missing*/    if(debug_level > 1){	Fprintf(stderr,           "\nauto: first point = %ld, frame length = %ld, step size = %ld\n",		    first, frame_len, step_size);	Fprintf(stderr,    "\nauto: # of frames = %ld, total points analyzed = %ld\n", nframes, nan);	Fprintf(stderr, "\nauto: number of points in input file = %ld\n",		num_of_points);    }/* * Check for inconsistencies */    if (first < 1)	ERROR_EXIT("can't have negative starting point");    if (frame_len == 0)	ERROR_EXIT("range must specify more than one point");    if (debug_level) Fprintf(stderr,    "\nauto: frame length %ld, order %ld, NO. frames %ld, step size = %ld\n", 	    frame_len, order, nframes, step_size);    if (order > frame_len) 	ERROR_EXIT("order greater than frame length");/* * create, fill in, and write FEA_ANA file header */    oh = new_header(FT_FEA);    if(init_anafea_hd(oh, (long)0, (long)order, (long)1, (long)1, (long)1, (short)0, (short)0) != 0)	ERROR_EXIT("Error filling FEA_ANA header");    add_source_file(oh, iname, ih);    oh->common.tag = YES;    (void) strcpy(oh->common.prog, ProgName);    (void) strcpy(oh->common.vers, Version);    (void) strcpy(oh->common.progdate, Date);    oh->variable.refer = iname;    add_comment(oh, get_cmd_line(argc, argv));    *(long *) get_genhd("start", oh) = first;    *(long *) get_genhd("nan", oh) = nan;    *(long *) get_genhd("frmlen", oh) = frame_len;    *(float *)get_genhd("src_sf", oh) = get_genhd_val("record_freq", ih, 0.0);    *(short *)get_genhd("spec_rep", oh) = AUTO;    /* add generic header item for data window, power option and step_size*/    /* this illustrates both "styles" of using add_genhd*/    *add_genhd_l("step_size", (long *) NULL, 1, oh) = step_size;    (void) add_genhd_e("data_window", &window_type, 1, window_types, oh);    (void) add_genhd_c("power", power, 0, oh);    if (B_flag)       (void) add_genhd_c("strcov_auto", "yes", 0, oh);    else       (void) add_genhd_c("strcov_auto", "no", 0, oh);          (void)update_waves_gen(ih, oh, (float)(first + (frame_len+1)/2), 		(float)step_size);    write_header(oh, ofile);/* * Allocate memory for data and autocorrelations */    x = (float *) calloc((unsigned) frame_len, sizeof(float));    spsassert(x != NULL, "Couldn't allocate enough memory for input data");    xwindow = (float *) calloc((unsigned) frame_len, sizeof(float));    spsassert(xwindow != NULL, 		    "Couldn't allocate enough memory for windowed data");    y = (double *) calloc((unsigned) order+1, sizeof(double));    spsassert(y != NULL, "Couldn't allocate space for autocorrelations"); /*  * allocate anafea record and move to starting position  */    fea_ana_rec = allo_anafea_rec(oh);     if (first > 1) fea_skiprec(ifile, first - 1, ih);    position = first;    /*     * main loop     */    for (i = 0; i < nframes; i++) {	/*	 * get sampled data and window it	 */    	actsize = get_sd_orecf(x, (int)frame_len, (int)step_size, 				first_time, ih, ifile);	first_time = NO;	if (actsize != frame_len) break;	/* window data */	if((window(frame_len, x, xwindow, window_type, (double *)NULL)) != 0)	    ERROR_EXIT("Invalid window function specified");	if (debug_level) 	    Fprintf(stderr, "auto: got %d points to analyze\n", actsize);	if (debug_level > 2) {	    Fprintf(stderr, 	    "auto: sampled data input to get_auto for frame %d:\n", i+1);	    for (j = 0; j < frame_len; j++) 		Fprintf(stderr, "%f\n", xwindow[j]);	}	/*	 * compute autocorrelations and power	 */	    /* first compute autocorrelations of windowed data */	if (B_flag) 	  strcov_auto(xwindow, actsize, y, order, order +1, (int) 0, 		      'f', STRCOV_CONV, STRCOV_ITER); 	else	  (void)get_auto(xwindow, actsize, y, order);	for(j=0; j<order; j++)	  fea_ana_rec->spec_param[j] = (float)y[j+1];	/* compute power of input or windowed data */	if(strcmp(power, "unwindowed") == 0)	  (void)get_auto(x, actsize, y, 0);	else if(strcmp(power, "windowed") != 0)	  ERROR_EXIT("Invalid power computation window option");	tot_power = (float)y[0]/actsize;	/*	 * fill in and write out fea_ana record	 */	*fea_ana_rec->frame_type = NONE;	*fea_ana_rec->raw_power = tot_power;	*fea_ana_rec->frame_len = (long)actsize;        *fea_ana_rec->tag = (long)position;        position += step_size;	put_anafea_rec(fea_ana_rec, oh, ofile);    }/* * put info in ESPS common */    if (strcmp(oname, "<stdout>") != 0) {	(void) putsym_s("filename", iname);	(void) putsym_s("prog", ProgName);	(void) putsym_i("start", (int) first);	(void) putsym_i("nan", (int) nan);	(void) putsym_i("step_size", (int)step_size);	(void) putsym_i("frmlen", (int)frame_len);    }        exit(0);    return (0);}voidget_range(srec, fsize, nfrm, rng, rflag, total_pts, nan, step)long *srec;			/* starting record */long *fsize;			/* frame size */long *nfrm;			/* number of frames */char *rng;			/* range string from range option */int rflag;			/* flag for whether range option used */long total_pts;			/* length of input file*/long *nan;			/* total number of points to process*/long *step;			/* number of points between frames*/{    long last, lnan;    *srec = 1;    last = total_pts;    if (rflag) {	lrange_switch (rng, srec, &last, 1);		if(last == 0)	    last = total_pts;    }    else {	if(symtype("start") != ST_UNDEF) 	    *srec = getsym_i("start");	if(symtype("nan") != ST_UNDEF) {	    lnan = getsym_i("nan");	    if (lnan == 0)		last = total_pts;	    else		last = *srec + lnan - 1;	}	    }    *nan = last - *srec + 1;    if (debug_level) 	Fprintf(stderr, "auto: range is %ld to %ld\n", *srec, last);/* * Get Frame size info*/    if (*fsize == -1) /*-l option not used -- get from param file*/	if(symtype("frame_len") != ST_UNDEF) 	    *fsize = getsym_i("frame_len");/* * if no frame_len set or if set to 0, use whole range as frame_len*/    if (*fsize == 0 || *fsize == -1) { 	*nfrm = 1;	*fsize = *nan;		*step = *fsize;    }    else { /*frame_len was set explicitly*/ 	/*	 * Get step size info	*/	    if(*step == 0){	        if(symtype("step_size") != ST_UNDEF)		    *step = getsym_i("step_size");	    }    	    if(*step == 0)		*step = *fsize;	    if (*fsize > *nan) {		Fprintf(stderr,     "auto: Frame size is greater than total number of points - exiting\n");	    exit(1);	    }	    else {		*nfrm =  ((*nan - *fsize) / *step) + 1;		*nan = (*nfrm - 1)* *step + *fsize;	    }    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?