📄 ana.c
字号:
/*---------------------------------------------------------------------------+| ANA - Speech Analysis Program (Pitch synchronous and asynchronous) || Written by S. Shankar Narayan, EPI, CA 95014. || Modified to meet SPS requirements by David Burton- 4/23/86 || Usage: ana [-d] [-x level] [-p parfile] sd pitch [out] || -x specifies a level for debug messages. || -p specifies an alternate parameter file. || sd specifies the input sampled data file. || pitch specifies the input pitch file. || out specifies the output analysis file. || -d specifies that ana be performed with no voicing correction logic || || This material contains proprietary software of Entropic Processing, Inc. || Any reproduction, distribution, or publication without the the prior || written permission of Entropic Processing, Inc. is strictly prohibited. || Any public distribution of copies of this work authorized in writing by || Entropic Processing, Inc. must bear the notice || || "Copyright 1986 Entropic Processing, Inc." |----------------------------------------------------------------------------*/#ifdef SCCSstatic char *sccs_id = "@(#)ana.c 1.11 9/29/86 EPI";#endif#define SYNTAX USAGE ("ana [-d] [-p param] [-x level] sdfile pitchfile [out]");#include <stdio.h>#include <sps/sps.h>#include <sps/pitch.h>#include <sps/ana.h>#define voiced 1#define unvoiced 0#define UU 0#define UV 1#define VU 2 /* 10 binary */#define VV 3 /* 11 binary */#define BUFSIZE 1024float data_mem[BUFSIZE];char *vuchr[] ={ "UU", "UV", "VU", "VV"};#define lntpbuf 10#define Fprintf (void)fprintf#define MAX(a,b) (a > b) ? a : b/* returns greater of a, b */void parm_err ();static int tail_ptr, head_ptr, pulse_count, plocn[lntpbuf], period[lntpbuf], to_be_analyzed[lntpbuf];static float pitch_pos, pitch_period, dc_val_rem = 0, dc_pts_rem = 0;static int istan;static short uvced_frmlen, vced_frmlen, p_offset;static n_ana_rec = 0;float remove_dc ();short flag_interp (), get_anal_mthd (), get_window (), process_frame ();static char *inp_file = NULL;static char *pitch_file = "<stdin>";static char *anafile = "<stdout>";FILE * labptr = stdin;FILE * anaptr, *outptr = stdout;FILE * hptr = NULL;int debug_level = 0;/* Temporary file name template. We write all the analysis data there first, then write out the header followed by the data. */char *tmp_name = "/tmp/anaXXXXXX";static int john_flag = 0, smartana_flag = 1, vuv_state;static float prev_lpcfilter[100], lpc_filt_state[100];float fowrd_filter ();static int order, matsiz, window, win_type, dcrem, sinc_flg = 0, sampfreq, psynch;static int unv_order = 0, v_order = 0;#define NPR 3float num[NPR], den[NPR], pstate[NPR];static char method = ' ';static FILE * ifd;char *strcpy ();static struct header *ih, *oh, *ph, *tmphd;int maxpulses, maxraw, maxlpc;main (argc, argv)int argc;char **argv;{ struct pitch *p; struct ana_data *record; double tmpd[NPR]; int nan, pos_nan, nsamples, smpnum, blksze, ns, ds; int windowlnt, previous_seg_type, present_seg_type, i, k, c, error = no; char *param_file = "params"; extern optind; extern char *optarg; char datatype = 'w'; while ((c = getopt (argc, argv, "djp:x:h:")) != EOF) { switch (c) { case 'd': smartana_flag = 0; break; case 'j': john_flag++; break; case 'p': param_file = optarg; break; case 'x': debug_level = atoi (optarg); break; default: SYNTAX; } }/* ---------- open input and output files ---------- */ if (optind > argc - 2) SYNTAX; if (optind == (argc-3)) inp_file = argv[optind++]; read_params(param_file, SC_CHECK_FILE, inp_file); if (inp_file == NULL) { if(symtype("filename") == ST_UNDEF) { fprintf(stderr,"ana: no input SD file\n"); exit(1); } inp_file = getsym_s("filename"); fprintf(stderr,"ana: input file %s from Common File.\n",inp_file); } if (strcmp (inp_file, "-") == 0) inp_file = "<stdin>"; else TRYOPEN ("ana", inp_file, "r", ifd); if ((ih = read_header (ifd)) == NULL) NOTSPS ("ana", inp_file); if (ih -> common.type != FT_SD) { fprintf (stderr, "ana: %s is not SPS sampled data\n", inp_file); exit (3); } pitch_file = argv[optind++]; if (strcmp (pitch_file, "-") == 0) { if (ifd == stdin) { fprintf ("ana: can't use stdin for both streams\n"); exit (2); } else pitch_file = "<stdin>"; } else TRYOPEN ("ana", pitch_file, "r", labptr); if ((ph = read_header (labptr)) == NULL) NOTSPS ("ana", pitch_file); if (ph -> common.type != FT_PIT) { fprintf (stderr, "ana: %s is not pitch data\n", pitch_file); exit (3); } anafile = argv[optind]; if (strcmp (anafile, "-") == 0) anafile = "-"; else TRYOPEN ("ana", anafile, "w", outptr);/* Open temporary file */ if ((anaptr = fopen (mktemp (tmp_name), "w+")) == NULL) { perror ("ana: can't open temporary file"); exit (1); } if ((abs (ih -> hd.sd -> sf - ph -> hd.pit -> src_sf)) > 0) { fprintf (stderr, "ana: sample frequencies of sources disagree\n"); exit (4); } sampfreq = ih -> hd.sd -> sf;/* ---------- get initialization parameters ---------- *//* At this point separate unvoiced and voiced model orders are not used */ unv_order = getsym_i ("order_unvcd"); v_order = getsym_i ("order_vcd"); if (unv_order != v_order) Fprintf (stderr, "Seperate specification of voiced and unvoiced orders is not supported yet; the order used for both voiced and unvoiced frames is %d\n", MAX (unv_order, v_order)); matsiz = getsym_i ("matsiz");/* The MAX function is used to make sure enough space is allocated */ order = unv_order = v_order = MAX (unv_order, v_order); if (matsiz == 0) matsiz = order + 1; p_offset = getsym_i ("p_offset"); istan = getsym_i ("start"); if (ph -> hd.pit -> start > istan) istan = ph -> hd.pit -> start; if (istan < p_offset + NPR - 1) { istan = p_offset + NPR - 1; fprintf (stderr, "ana: analysis starts at %d\n", istan); } nan = getsym_i ("nan"); pos_nan = ph -> hd.pit -> start + ph -> hd.pit -> nan - istan; if (nan == 0) nan = pos_nan; if (nan > pos_nan) nan = pos_nan; fprintf(stderr,"ana: start: %d, nan: %d\n",istan,nan); if (ifd != stdin) { putsym_i("start",istan); putsym_i("nan",nan); putsym_s("filename",inp_file); putsym_s("prog","ana"); } ns = getsym_da ("pre_num", tmpd, NPR); for (i = 0; i < NPR; i++) num[i] = tmpd[i]; ds = getsym_da ("pre_den", tmpd, NPR); for (i = 0; i < NPR; i++) den[i] = tmpd[i]; uvced_frmlen = getsym_i ("uvced_frmlen"); vced_frmlen = getsym_i ("vced_frmlen"); window = get_window ("win_type"); window = 0; maxpulses = getsym_i ("maxpulses"); maxraw = getsym_i ("maxraw"); maxlpc = getsym_i ("maxlpc"); dcrem = flag_interp ("dcrem"); sinc_flg = flag_interp ("sinc_flg"); symerr_exit ();/* ---------- make output header ---------- *//* need to fill in ndrec and dcrem later */ if ((oh = new_header (FT_ANA)) == NULL) { Fprintf (stderr, "ANA output file is not a valid SPS file type\n"); exit (1); }/* CHANGE: remove next exec statement and add next two lines oh -> hd.ana -> uvced_frmlen = uvced_frmlen; oh -> hd.ana -> vced_frmlen = vced_frmlen;*/ oh -> hd.ana -> frmlen = vced_frmlen; oh -> hd.ana -> src_sf = ih -> hd.sd -> sf; oh -> hd.ana -> maxpulses = maxpulses; oh -> hd.ana -> maxraw = maxraw; oh -> hd.ana -> maxlpc = maxlpc; oh -> hd.ana -> order_vcd = v_order; oh -> hd.ana -> order_unvcd = unv_order; oh -> hd.ana -> win_type = window; oh -> hd.ana -> pre_emp = new_zfunc (ns, ds, num, den); oh -> hd.ana -> start = istan; oh -> hd.ana -> nan = nan; strcpy (oh -> common.prog, "ana");#ifdef SCCS strcpy (oh -> common.vers, "1.5");#else strcpy (oh -> common.vers, "0.1");#endif oh -> hd.ana -> psynch = flag_interp ("psynch"); psynch = flag_interp ("psynch"); oh -> hd.ana -> a_method = get_anal_mthd ("a_method");/*translate a_method integer into character for analyze program */ if (oh -> hd.ana -> a_method == AUTO_SAM) method = 'a'; if (oh -> hd.ana -> a_method == BURG_SAM) method = 'b'; if (oh -> hd.ana -> a_method == COV_SAM) method = 'c'; if (oh -> hd.ana -> a_method == MBURG_SAM) method = 'm'; if (oh -> hd.ana -> a_method == STRCOV_SAM) method = 's'; if (oh -> hd.ana -> a_method == VBURG_SAM) method = 'v'; oh -> hd.ana -> sinc_flg = sinc_flg; oh -> hd.ana -> p_offset = p_offset; oh -> hd.ana -> matsiz = matsiz; add_source_file (oh, inp_file, ih); add_source_file (oh, pitch_file, ph);/*make temporary file header and write it out*/ if ((tmphd = copy_header (oh)) == NULL) { Fprintf (stderr, "Temporary file is not a valid SPS file type\n"); exit (1); } write_header (tmphd, anaptr);/* ---------- skip initial data ---------- */ /* first determine type of data *//* to be changed in next SPS update - this will be eliminated and SD functions will be used */ if (ih -> common.ndouble) datatype = 'd'; if (ih -> common.nfloat) datatype = 'f'; if (ih -> common.nlong) datatype = 'l'; if (ih -> common.nshort) datatype = 'w'; if (ih -> common.nchar) datatype = 'b';/* skip initial data, if any */ if (istan > p_offset + NPR - 1) skiprec (ifd, (long) istan - p_offset - NPR + 1, size_rec (ih)); /* Minor initialization *//*Allocate memory for data records*/ p = allo_pitch_rec (); record = allo_ana_rec (oh); for (i = 0; i < lntpbuf; to_be_analyzed[i++] = no); previous_seg_type = unvoiced; windowlnt = 0; head_ptr = tail_ptr = 0; nsamples = nan + istan; smpnum = istan;/*main loop*/ while (smpnum < nsamples) { blksze = vced_frmlen; if (psynch == no) error = process_frame (smpnum, blksze, record, datatype, maxpulses, maxraw, maxlpc); else { get_pitch_info (labptr, smpnum, &blksze, &present_seg_type, p); if (debug_level) fprintf (stderr, "smpnum = %d, blksze = %d, %svoiced\n", smpnum, blksze, present_seg_type ? "" : "un");/* Given the starting location, the get_pitch_info routine returns the pitch period, if speech data is voiced, and an appropriate block size ("uvced_frmlen" and different during unvoice to voice transition ). Whether or not data is voiced is indicated by variable pre_seg_type.*/ vuv_state = previous_seg_type * 2 + present_seg_type; if (debug_level) fprintf (stderr, "State: %s\n", vuchr[vuv_state]); switch (vuv_state) { case UU: /* Prev and Present segments unvoiced */ if (debug_level) Fprintf ("main: UU\n"); error = process_frame (smpnum, blksze, record, datatype, maxpulses, maxraw, maxlpc); break; case VU: /* Voice to Unvoice transition */ if (maxpulses > 1) { /* First finish processing of remaining V data */ k = plocn[tail_ptr]; windowlnt = smpnum - k; pulse_count = head_ptr - tail_ptr; if (pulse_count < 0) pulse_count += lntpbuf; if (debug_level) Fprintf ("main: VU: pknt is %d\n", pulse_count); error = process_frame (k, windowlnt, record, datatype, maxpulses, maxraw, maxlpc); head_ptr = 0; pulse_count = 0; tail_ptr = 0; windowlnt = 0; } /* Now process the first unvoiced frame */ if (debug_level) Fprintf ("main: VU: pknt is \n", pulse_count); error = process_frame (smpnum, blksze, record, datatype, maxpulses, maxraw, maxlpc); break; case UV: /* Unvoice to Voice transition */ case VV: /* Voiced segment */ plocn[head_ptr] = smpnum; period[head_ptr] = blksze; to_be_analyzed[head_ptr] = yes; if (maxpulses == 1) { pulse_count = 1; head_ptr = 1; error = process_frame (smpnum, blksze, record, datatype, maxpulses, maxraw, maxlpc); head_ptr = 0; pulse_count = 0; break; }/*"tail_ptr" points to the first pulse that will be used to make a frame of appropriatesize, when V/U transition is encountered. Remember, some pulses are used more thanonce in spectrum analysis at the time of V/U transition.*/ while (smpnum + blksze - plocn[tail_ptr] - period[tail_ptr] / 2 > vced_frmlen) tail_ptr = (tail_ptr + 1) % lntpbuf; if (debug_level) { Fprintf (stderr, "VV: wlnt = %d, blksze = %d, frmlen = %d\n", windowlnt, blksze, vced_frmlen); } if ((windowlnt + blksze / 2) > vced_frmlen) { error = process_frame (smpnum - windowlnt, windowlnt, record, datatype, maxpulses, maxraw, maxlpc); windowlnt = 0; pulse_count = 0; } head_ptr = (head_ptr + 1) % lntpbuf; windowlnt += blksze; pulse_count++; } } if (error)/* problem in process_frame - maxpulses, maxraw, or maxlpc exceeded */ break; previous_seg_type = present_seg_type; smpnum += blksze; }/* Fill in missing fields, write out header, data */ oh -> common.ndrec = n_ana_rec; if (dcrem && dc_pts_rem > 0) oh -> hd.ana -> dcrem = dc_val_rem / dc_pts_rem; write_header (oh, outptr); rewind (anaptr); tmphd = read_header (anaptr); for (i = 0; i < n_ana_rec; i++) { get_ana_rec (record, tmphd, anaptr); put_ana_rec (record, oh, outptr); } fclose (anaptr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -