⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sgram.c

📁 speech signal process tools
💻 C
📖 第 1 页 / 共 2 页
字号:
	    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) {  /* In case of precision problems in start_time specs... */         start = 1;	 if (debug_level){	   Fprintf(stderr,"Can't start before beginning of file.\n");	   Fprintf(stderr, "Resetting starting sample to 1.\n");	 }    }    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;	}    window_size = frame_len = LROUND(window_len * sf / 1000.0);    if((win == WT_SINC) || (win == WT_SINC_C4))      frame_len = tr_length;    if (debug_level)	Fprintf(stderr, "window_len = %g, frame_len = %ld\n",		window_len, frame_len);    /* -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)	Fprintf(stderr, "preemph = %g\n", preemph);    if (!(Tflag))	switch (symtype("desired_frames"))	{	case ST_UNDEF:	    break;	case ST_INT:	    des_frames = getsym_i("desired_frames");	    if (des_frames > 0)	      Tflag++;	    break;	default:	    ERROR_EXIT("Parameter \"desired_frames\" not of int type.")	    break;	}    /* -S step_size */    if (!(Sflag || p_mflag || Tflag))	switch (symtype("step_size"))	{	case ST_UNDEF:	    step_size = def_step_size;	    break;	case ST_FLOAT:	    step_size = getsym_d("step_size");	    break;	default:	    ERROR_EXIT("Parameter \"step_size\" not of float type.")	    break;	}    step = LROUND(step_size * sf / 1000.0);    /* If -T (TI) option is used, the number of frames (number of ffts)      * is forced.  This facilitates looking at a narrow region with      * higher resolution.   Here we compute a step size that gives      * the (approximate) right number of frames     */    if (Tflag) {		if (nan == 0) {	  Fprintf(stderr, 	      "%s: can't use -T without specifying a range start\n", ProgName);	  Fprintf(stderr,"\tand stop with -r or -p\n");	  exit(1);	}	if (Sflag && (debug_level || !zflag))	  Fprintf(stderr, "%s: WARNING -S option overriden by -T\n", ProgName);	/* computed fixed step size */	step = LROUND((nan - frame_len)/((float) (des_frames - 1)));	if (step <= 0) 	  step = 1;      }    /* compute (adjust, in case of -T)  number of frames to fill        specified segment */        if (nan == 0)       nan = end - start + 1;    if (nan < frame_len)       nframes = 1;    else {      nframes = 1 + (nan - frame_len) / step;       /* we add one more frame unless the last one ends exactly at the 	 end point */      if (nan > (frame_len + (nframes - 1)*step)) {	nframes++;	if (debug_level) 	  Fprintf(stderr, 	     "%s: WARNING - last frame will exceed range by %ld points\n", 	      ProgName, frame_len + (nframes - 1)*step - nan);      }    }    if (debug_level) Fprintf(stderr,	"start = %ld, nan = %ld, frame size = %ld, step = %ld, nframes = %ld\n",	start, nan, frame_len, step, nframes);    /*     * Allocate buffers     */    alloc_len = MAX(frame_len, tr_length);    x = (float *) calloc(alloc_len + 1, sizeof(float));    px = (float *) calloc(alloc_len, sizeof(float));	    wx = (float *) calloc(alloc_len, sizeof(float));	    y = (float *) calloc(alloc_len, sizeof(float));    spsassert(x && y && wx, "sgram: couldn't allocate enough memory");    if (frame_len < 1)	ERROR_EXIT("window must be at least 1 sample wide");    if (debug_level) Fprintf(stderr, 	"frame length %ld, transform length %ld, no. frames %ld\n", 	    frame_len, tr_length, nframes);    /*     * only read as many points as length of transform     */    if (tr_length < frame_len && debug_level) {	Fprintf(stderr, 	    "%s: WARNING - transform length %ld less than frame length %ld\n",	    ProgName, tr_length, frame_len);	Fprintf(stderr,"\t\t(framing determined by step size)\n");    }	    if (tr_length > frame_len && debug_level) {	Fprintf(stderr, 	    "%s: WARNING - transform length %ld greater than frame length %ld\n",	    ProgName, tr_length, frame_len);	Fprintf(stderr,	    "\t %ld zeros padded for each frame\n", tr_length-frame_len);    }    /*     * create, fill in, and write output file header     */    oh = new_header(FT_FEA);    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));    freq_format = SPFMT_SYM_EDGE;    spec_type = SPTYP_DB;    num_freqs = tr_length/2 + 1;    spsassert(	!init_feaspec_hd(oh, YES, freq_format, spec_type,	    YES, num_freqs, SPFRM_FIXED, (float *) NULL, sf, frame_len,	    BYTE),	"Error filling FEA_SPEC header" )    *add_genhd_l("start", (long *) NULL, 1, oh) = start;    *add_genhd_l("nan", (long *) NULL, 1, oh) = nan;    (void) add_genhd_c("sgram_method", hd_method, strlen(hd_method), oh);    *add_genhd_l("fft_order", (long *) NULL, 1, oh) = order;    *add_genhd_l("fft_length", (long *) NULL, 1, oh) = tr_length;    *add_genhd_l("step", (long *) NULL, 1, oh) = step;    *add_genhd_e("window_type", (short *) NULL, 1, window_types, oh) = win;    *add_genhd_d("pre_emphasis", (double *) NULL, 1, oh) = preemph;    if (Tflag)       *add_genhd_l("desired_frames", (long *) NULL, 1, oh) = des_frames;    (void)update_waves_gen(ih, oh, (float) (start + frame_len/2), (float)step);    write_header(oh, ofile);    /*     * set scale factor to turn into continuous spectral density     */    scale = 10 * log10(2.0/(tr_length * sf));    /*     * allocate spectral record and move to starting position     */    spec_rec = allo_feaspec_rec(oh, FLOAT);    fea_skiprec(ifile, start - 1, ih);    /*     * main loop     */    position = start;    for (i = 0; i < nframes && more; i++) {	if (debug_level > 1)	    Fprintf(stderr, "frame %d\n", i + 1);	/*	 * get sampled data and preemphasize	 */	if (i == 0)	{	    x[0] = 0.0;	    actsize = get_sd_orecf(x + 1, (int) frame_len, (int) step, 				   YES, ih, ifile);	}	else	{	    actsize = - 1 + get_sd_orecf(x, (int) frame_len + 1, (int) step, 					 NO, ih, ifile);	}	{	  register float *ip, *op, old, new, pre = preemph;	  for (j = frame_len, ip = x, old = *ip++, op = px; j--; ) {	    *op++ = (new = *ip++) - (old*pre);	    old = new;	  }	}	if ((actsize < frame_len) && debug_level) 	  Fprintf(stderr, 	       "%s: WARNING - got fewer points than frame_len in frame %d\n",	       ProgName, i + 1);	if (actsize == 0) break;	if (debug_level > 1)	    Fprintf(stderr, "got %d points\n", actsize);	if (debug_level > 2)	{	    pr_farray("frame from get_sd_orec", frame_len + 1, x);	    pr_farray("preemphasized frame", frame_len, px);	}	more = (actsize == frame_len);    		/*	 * Window data.	 */	(void) gp_window(window_size, px, wx, win, (double *) NULL, &frame_len);	if (tr_length > actsize) {	    if (debug_level > 1) Fprintf(stderr, "padding zeros to frame\n");	    for (j = actsize; j < tr_length; j++) 		wx[j] = 0.0;	}	if (debug_level > 2) pr_farray("windowed frame, input to fft", 	    MAX(frame_len, tr_length), wx);	/*	 * compute total power	 */	tot_power = 0.0;	{	  register float ssq, *fp;	  register int cnt;	  data_length = (tr_length < actsize ? tr_length : actsize);	  for (cnt = data_length, ssq = 0.0, fp = wx; cnt-- ; fp++)	    ssq += *fp * *fp;	  tot_power = ssq / data_length;	}	if (debug_level > 1)	    Fprintf(stderr, "total power = %g\n", tot_power);	/*	 * compute fft	 */	{	  register float *wp = y, zero = 0.0;	  register int cnt = tr_length;	  do { *wp++ = zero; } while ( --cnt);	}	get_rfft(wx, y, order);	if (debug_level > 2) {	    Fprintf(stderr, "real, imag, and power from get_fft:\n");	    for (j = 0; j < tr_length; j++) 		Fprintf(stderr, "%f\t%f\t%g\n", wx[j], y[j], 		    wx[j]*wx[j] + y[j]*y[j]);	}	/*	 * fill in and write out spectral record	 */	zeros = 0;	{	  register float *op, *rp, *ip, zero = 0.0, rfpow, scl = scale, ten = 10.0;	  register int cnt;	  for (cnt = num_freqs, rp = wx, ip = y, op = spec_rec->re_spec_val;	       cnt-- ; rp++, ip++)	    {	      rfpow =  (*ip * *ip) + (*rp * *rp);	      if (rfpow > zero)		*op++ = scl + ten * log10(rfpow);	      else		{		  *op++ = scl - ten * log10(FLT_MAX);		  zeros++;		}	    }	}	if (zeros && !zflag)	    Fprintf(stderr,		    "%s: WARNING - zero power at %d points in frame %ld.\n",		    ProgName, zeros, i+1);	if (debug_level > 2) {	    Fprintf(stderr, "real, imag components in spec_rec:\n");	    for (j = 0; j < num_freqs; j++) 		Fprintf(stderr, "%f\t%f\t\n", 		    spec_rec->re_spec_val[j], spec_rec->im_spec_val[j]);	}	*spec_rec->tot_power = tot_power;	*spec_rec->tag = position;	position += step;	(void) put_feaspec_rec(spec_rec, oh, ofile);    }/* * put info in ESPS common */    if (strcmp(oname, "<stdout>") != 0 && strcmp(iname, "<stdin>") != 0) {	(void) putsym_s("filename", iname);	(void) putsym_s("prog", ProgName);	(void) putsym_i("start", (int) start);	(void) putsym_i("nan", (int) nan);    }        exit(0);    /*NOTREACHED*/}/* * For debug printout of float arrays */void pr_farray(text, n, arr)    char    *text;    long    n;    float  *arr;{    int	    i;    Fprintf(stderr, "%s: %s -- %d points:\n", ProgName, text, n);    for (i = 0; i < n; i++)    {	Fprintf(stderr, "%f ", arr[i]);	if (i%5 == 4 || i == n - 1) Fprintf(stderr,  "\n");    }}

⌨️ 快捷键说明

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