📄 synt.c
字号:
/*| 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."|| Written by: S. Shankar Narayan| Converted to SPS by: Rod Johnson (primarily) and John Shore|| Module: synt.c|| This is the main module of the SPS program synt, which performs | pitch synchronous synthesis from an ANA file. This module handles | the user-interface and the main processing loop. */#ifdef SCCSstatic char *sccs_id = "@(#)synt.c 1.8 1/22/87 EPI";#endif#include <stdio.h>#include <sps/sps.h>#include <sps/ana.h>#include <sps/sd.h>#define SYNTAX USAGE("synt [-d][-x level][-h hisfile][-P parfile][-p range][-s] ana_file sd_file ")#define VOICED 1#define UNVOICED 0#define SEED 1712583int debug_level = 0, whisper_flag = 0, int_flag = 0, window_flag = 0, extend_order_flag = 0, smooth_int_flag = 0, match_gain_flag = 0, smart_synt_flag = 1;char *strcpy ();struct ana_data *ana_rec;float int_rc[100], rc0[100], rc1[100], rc2[100], delta_rc[100];#define NPR 3float post_filt_num[NPR], post_filt_den[NPR], post_filt_state[NPR];float num[NPR], den[NPR], deemp_state[NPR];int ns, ds;double tmpd[NPR];int sflag = 0; /* write data out as SHORT instead of FLOAT */ /* this is global so that zeros() knows about it */FILE * hptr = NULL;main (argc, argv)int argc;char **argv;{ float outbfr[256], synstate[100], gain; float lattice_filt (), gauss (), sig_power, get_rmsval (); double sqrt (), dummy, rmsval, input; short par_interp (), par_pwr (), par_rc (), par_v_excit (), par_uv_excit (), par_method (); FILE * istrm = stdin, *ostrm = stdout; char *inp_file = "<stdin>"; struct header *ih, *oh; int start, nan, start_p, end_p; int order_vcd, order_unvcd, order_max, synt_filt_order = 0; int frmlen; int locn, blksze, oblksze, prev_seg_type, seg_type, i, c; short range_err = 0; char *param_file = "params"; char *p_switch = NULL; extern char *optarg; extern optind; extern char *Version, *Date;/* defined in version.c */ void zeros (), fcopy (), parm_err (); short shortbuf[256]; while ((c = getopt (argc, argv, "dP:p:x:h:s")) != EOF) { switch (c) { case 'h': if ((hptr = fopen (optarg, "w")) == NULL) CANTOPEN ("synt", optarg); break; case 'P': param_file = optarg; break; case 'd': smart_synt_flag--; break; case 'x': debug_level = atoi (optarg); break; case 'p': p_switch = optarg; break; case 's': sflag++; break; default: SYNTAX; } } if (optind < argc) { inp_file = argv[optind++]; if (strcmp (inp_file, "-") == 0) inp_file = "<stdin>"; else TRYOPEN ("synt", inp_file, "r", istrm); } if (optind < argc) { if (strcmp (argv[optind], "-") != 0) TRYOPEN ("synt", argv[optind], "w", ostrm); }/*read ANA file header*/ if ((ih = read_header (istrm)) == NULL) NOTSPS ("synt", inp_file); if (ih -> common.type != FT_ANA) { fprintf (stderr, "synt: input file not .ana\n"); exit (1); } frmlen = ih -> hd.ana -> frmlen; order_vcd = ih -> hd.ana -> order_vcd; order_unvcd = ih -> hd.ana -> order_unvcd; order_max = (order_unvcd > order_vcd) ? order_unvcd : order_vcd; if (ih -> hd.ana -> pre_emp) { struct zfunc *z = ih -> hd.ana -> pre_emp; if ((z -> nsiz > 3) || (z -> dsiz > 3)) { fprintf (stderr, "synt: pre-emphasis filter order > 3; exiting\n"); exit (1); } fcopy (num, z -> zeros, z -> nsiz); fcopy (den, z -> poles, z -> dsiz); } ana_rec = allo_ana_rec (ih);/*create output header*/ oh = new_header (FT_SD); if (sflag) set_sd_type (oh, SHORT); else set_sd_type (oh, FLOAT); add_source_file (oh, inp_file, ih); oh -> hd.sd -> nchan = 1; oh -> hd.sd -> max_value = 0; oh -> hd.sd -> scale = 0; oh -> hd.sd -> equip = NONE; oh -> hd.sd -> sf = oh -> hd.sd -> src_sf = ih -> hd.ana -> src_sf; oh -> variable.refer = ih -> variable.refer; oh -> hd.sd -> dcrem = 0; oh -> common.tag = NO; oh -> hd.sd -> sf = oh -> hd.sd -> src_sf = ih -> hd.ana -> src_sf; strcpy (oh -> common.prog, "synt");#ifdef SCCS strcpy (oh -> common.vers, Version); strcpy (oh -> common.progdate, Date);#else strcpy (oh -> common.vers, "0.1");#endif /* read SPS parameter file */ read_param (param_file); oh -> hd.sd -> synt_interp = par_interp ("synt_interp"); if (oh -> hd.sd -> synt_interp == PULSE) int_flag++; else if (oh -> hd.sd -> synt_interp == SAMPLE) smooth_int_flag++; oh -> hd.sd -> synt_pwr = par_pwr ("synt_pwr"); if (oh -> hd.sd -> synt_pwr == RAWPULSE) match_gain_flag++; oh -> hd.sd -> synt_rc = par_rc ("synt_rc"); if (oh -> hd.sd -> synt_rc == SINX) window_flag++; oh -> hd.sd -> v_excit_method = par_v_excit ("v_excit_method"); if (oh -> hd.sd -> v_excit_method == WHITE) whisper_flag++; oh -> hd.sd -> uv_excit_method = par_uv_excit ("uv_excit_method"); oh -> hd.sd -> synt_method = par_method ("synt_method"); oh -> hd.sd -> synt_order = getsym_i ("synt_order"); ns = getsym_da ("post_filter_num", tmpd, NPR); for (i = 0; i < NPR; i++) post_filt_num[i] = tmpd[i]; ds = getsym_da ("post_filter_den", tmpd, NPR); for (i = 0; i < NPR; i++) post_filt_den[i] = tmpd[i]; oh -> hd.sd -> prefilter = new_zfunc (ns, ds, post_filt_num, post_filt_den);/*parse range -- whole file unless -p option overrides*/ start = start_p = ih -> hd.ana -> start; nan = ih -> hd.ana -> nan; end_p = start + nan - 1; if (p_switch) { range_switch (p_switch, &start_p, &end_p, 1); if ((start_p < start) || (end_p > (start + nan - 1))) range_err++; start = start_p; nan = end_p - start_p + 1; } if (range_err > 0) { fprintf (stderr, "synt: specified range %d:%d not in input file\n", start_p, end_p); exit (1); } oh -> common.ndrec = nan; write_header (oh, ostrm); dummy = SEED; if (synt_filt_order < order_max || !window_flag) synt_filt_order = order_max; for (i = 0; i < synt_filt_order; synstate[i++] = 0.0); for (i = 0; i < NPR; i++) deemp_state[i] = post_filt_state[i] = 0.0; i = 0; do { if (!get_ana (&locn, &seg_type, &blksze, &sig_power, order_vcd, order_unvcd, synt_filt_order, ih, istrm)) { printf ("synt: EOF encountered before start reached\n"); exit (2); } i++; } while (start > locn || blksze == 0); if (debug_level) fprintf (stderr, "start: locn = %d\n", locn);/* Insert leading zeros if start < locn. If the difference is greater than one frame, complain and exit */ if (i == 1 && locn - start > frmlen) { fprintf (stderr, "synt: no analysis data near point %d; first locn = %d\n", start, locn); exit (1); } zeros (locn - start, oh, ostrm); prev_seg_type = VOICED; while (locn < (start + nan)) { if (whisper_flag) seg_type = UNVOICED; if (debug_level) fprintf (stderr, "locn = %d\tsize = %d\n", locn, blksze); if (prev_seg_type == UNVOICED && seg_type == VOICED) for (i = 0; i <= synt_filt_order; synstate[i++] = 0.0);/* obtain lpc filter gain */ gain = 1.0; for (i = 0; i < synt_filt_order; i++) gain *= (1.0 - int_rc[i] * int_rc[i]); if (seg_type == VOICED) { sig_power = blksze * sig_power; if (match_gain_flag) rmsval = get_rmsval (int_rc, delta_rc, synt_filt_order, sig_power, synstate, deemp_state, blksze, locn); else rmsval = sqrt ((double) sig_power * gain); input = rmsval; outbfr[0] = lattice_filt (int_rc, delta_rc, synt_filt_order, synstate, input); input = -rmsval / (blksze-1); for (i = 1; i < blksze; i++) outbfr[i] = lattice_filt (int_rc, delta_rc, synt_filt_order, synstate, input); } else { /* Unvoiced segment */ rmsval = sqrt ((double) sig_power * gain); for (i = 0; i < blksze; i++) { input = rmsval * gauss (dummy); outbfr[i] = lattice_filt (int_rc, delta_rc, synt_filt_order, synstate, input); } } /* De-emphasize output */ pre_emphasis (outbfr, blksze, den, num, deemp_state); /* Post-filtering */ pre_emphasis (outbfr, blksze, post_filt_num, post_filt_den, post_filt_state);/* if overflow ... fprintf (hptr, "\t\tOVF %d\tVAL %f\n", locn, outbfr[i]);*/ if (sflag) { for (i = 0; i < blksze; i++) shortbuf[i] = (short) outbfr[i]; put_sd_recs (shortbuf, blksze, oh, ostrm); } else put_sd_recf (outbfr, blksze, oh, ostrm);/* if write error ... { perror ("synt: write I/O error"); exit (1); }*/ prev_seg_type = seg_type; oblksze = blksze; if (!get_ana (&locn, &seg_type, &blksze, &sig_power, order_vcd, order_unvcd, synt_filt_order, ih, istrm)) {/* Don't beef if we're within one frame of the end */ if (start + nan - locn - oblksze > frmlen) { fprintf (stderr, "synt: EOF encountered in input file\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -