formsy.c

来自「speech signal process tools」· C语言 代码 · 共 681 行 · 第 1/2 页

C
681
字号
/* * 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-1993 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:  David Talkin * Checked by: * Revised by: * * Brief description:a crude, cascade, n-fromant, pitch-excited synthesizer * */static char *sccs_id = "@(#)formsy.c	1.3	5/19/98	ERL";/*formsy [-P param_file][-b bandwidths][-r frame_rate_scale][-a formant_scale][-v voic_prob][-l min_bandwidth][-n n_formants][-s synthesis_rate][-h n_high_pole_formants][-f f0_scale][-g ][-e excite_file ] f0file fbfile outfileWhere "f0" is a file containing F0, VUV, and amplitude data, and "fb" containsthe formant frequencies and bandwidths.  The program "formant" producesfiles of the required format.  These may be used as templates forhand-generated or modified parameter files.  The "syn" file contains thesynthesis output.  The options are: -bn.m   Instead of using the bandwidths from the "fb" file, bandwidths are	synthesized from formant frequencies by the formula		bandwidth = n + ( .m * frequency) [null]. -vn   The probability of voicing in the .f0 file is ignored and the value	of n is used throughout the synthesis instead (0 <= n <= 1) [null]. -ln   The bandwidths from the "fb" file are constrained to be >= n.  The	-b and -l options are mutually exclusive [null]. -nn   Only the first n formants in the "fb" file are used [null]. -sn   The synthesis frequency is set to nHz [10kHz]. -hn   n constant "higher-pole" formants are synthesized  [0]. -an   n is the factor by which formant frequencies are to be scaled [1.0] -fn   The fundamental frequency from the "f0" file is multiplied by n [1.0]. -rn   The frame rate of both the "f0" and "fb" files are multiplied by n [1.0]. -gn   n is a boolean (1 or 0) which determines whether amplitude correction	is applied after synthesis.  This tends to improve the quality	in the voiced regions and degrade quality in unvoiced regions [0]. -ef   f is the name of a signal file to use for excitation [null].  If f is	specified, the .f0 file must NOT be specified and the v, s, f, r and	g options are not available; the synthesis frequency will be that	of the excitation file.Formsy is a simple n-formant synthesizer designed to help assess thevalidity of formant and F0 estimates obtained from the program"formant."  "Formsy" is not a serious attempt at quality synthesis andshould be used accordingly.  In particular, the voiced and unvoicedexcitation functions can be substantially improved and the amplitudebalance between voiced and unvoiced segments is not quite correct.*/#include <math.h>#include <esps/esps.h>#include <esps/fea.h>#include <esps/feasd.h>#include <Objects.h>#define NUPDATE 1#define NFORM 10#define SFREQ		16000.0#define SYNTAX USAGE("formsy [-P param_file][-b bandwidths][-r frame_rate_scale][-a formant_scale][-v voice_prob][-l min_bandwidth][-n n_formants][-s synthesis_rate][-h n_high_pole_formants][-f f0_scale][-g][-e excite_file ][-x debug_level] f0file fbfile outfile")int debug_level = 0, w_verbose = 0, max_buff_bytes = 2000000;char	*ProgName = "formsy";char	*Version = "1.3";char	*Date = "5/19/98";double  drand48();void formsy();voidset_pvd(hdr)    struct header   *hdr;{    (void) strcpy(hdr->common.prog, ProgName);    (void) strcpy(hdr->common.vers, Version);    (void) strcpy(hdr->common.progdate, Date);}intmain(ac,av)     int ac;     char **av;{  int i, j, nsamples, fd, nform, in, nframes, fix_gain, nforce, high_pole,  f0skip, fbskip, seskip, c;  double limit, f0scale, rate, start, end;  double fs = SFREQ, fscale;  short *sig, **spp, *ep;	/* output buffer for the synthesized signal */  double **dpp, *ff[NFORM], *fb[NFORM], *f0, *pv, *rms, frint, bws, vforce;  char *cp;  extern int optind;  extern char *optarg;  Signal *fbs, *f0s, *so, *se, *get_any_signal();  char temp[200], *excit;  char *param_file = NULL, *str, *bdstr = "0.0";  int bflag=0, eflag=0, lflag=0, fflag=0, aflag=0, rflag=0, sflag=0,      vflag=0, gflag=0, hflag=0, nflag=0;    if(ac < 2)     SYNTAX;  excit = NULL;  f0s = NULL;  fix_gain = 0;  bws = 0.0;  limit = 0.0;  f0scale = 1.0;  vforce = -1.0;  nforce = -1;  rate = 1.0;  high_pole = 0;  fscale = 1.0;  while((c = getopt(ac,av,"P:b:e:l:f:a:r:s:v:h:n:x:g")) != EOF) {    switch(c) {    case 'P':      param_file = optarg;      break;    case 'b':      bws = atof(optarg);      bflag++;      break;    case 'e':      excit = optarg;      eflag++;      break;    case 'l':      limit = atof(optarg);      lflag++;      break;    case 'f':      f0scale = atof(optarg);      fflag++;      break;    case 'a':      fscale = atof(optarg);      aflag++;      break;    case 'r':      rate= atof(optarg);      rflag++;      break;    case 's':      fs = atof(optarg);      sflag++;      break;    case 'v':      vforce = atof(optarg);      vflag++;      break;    case 'g':      fix_gain = 1;      gflag++;      break;    case 'h':      high_pole = atoi(optarg);      hflag++;      break;    case 'n':      nforce = atoi(optarg);      nflag++;      break;    case 'x':      debug_level = atoi(optarg);      break;    default:      SYNTAX    }  }  (void) read_params(param_file, SC_NOCOMMON, (char *) NULL);  if(!bflag && symtype("bandwidth") != ST_UNDEF){    bdstr = getsym_s("bandwidth");    bws = atof(str);  }  if(!eflag && symtype("excite_file") != ST_UNDEF)    excit = getsym_s("excite_file");  if(!lflag && symtype("min_bandwidth") != ST_UNDEF)    limit = getsym_d("min_bandwidth");  if(!fflag && symtype("f0_scale") != ST_UNDEF)     f0scale = getsym_d("f0_scale");  if(!aflag && symtype("formant_scale") != ST_UNDEF)    fscale = getsym_d("formant_scale");  if(!rflag && symtype("frame_rate_scale") != ST_UNDEF)    rate = getsym_d("frame_rate_scale");  if(!sflag && symtype("synthesis_rate") != ST_UNDEF)    fs = getsym_d("synthesis_rate");  if(!vflag && symtype("voice_prob") != ST_UNDEF)    vforce = getsym_d("voice_prob");  if(!gflag && symtype("amp_correct") != ST_UNDEF){    str = getsym_s("amp_correct");    if( !strcmp(str, "YES") || !strcmp(str, "yes") || !strcmp(str, "Yes"))      fix_gain = 1;  }  if(!hflag && symtype("n_high_pole_formants") != ST_UNDEF)    high_pole = getsym_i("n_high_pole_formants");  if(!nflag && symtype("n_formants") != ST_UNDEF)    nforce = getsym_i("n_formants");  for(in=optind; in < ac; in++) {    cp = av[ac-1];    if((fd = open(cp,O_TRUNC|O_RDWR|O_CREAT,0664)) >= 0) {      if(debug_level & 1)	printf("File is open for output\n");      if(excit) {	i = 0;	if(!(se = get_any_signal(excit,0.0,-1.0,NULL))) {	  printf("Can't get excitation file %s\n",excit);	  exit(-1);	}      } else {	i = 1;	if(!(f0s = get_any_signal(av[in],0.0,-1.0,NULL))) {	  printf("Can't get F0 file (%s)\n",av[in]);	  exit(-1);	}      }      if((fbs = get_any_signal(av[in+i],0.0,-1.0,NULL))) {	if(debug_level & 1)	  printf("Got input signals %s and %s \n",av[in],av[in+i]);	/* Determine the time region common to both input signals.	   Arrange to synthesize based only on this common segment. */	start = BUF_START_TIME(fbs);	end = BUF_END_TIME(fbs);	if(f0s) {	  if(BUF_START_TIME(f0s) > start) {	    start = BUF_START_TIME(f0s);	    if(BUF_END_TIME(fbs) <= start) {	      printf("F0 and Fn files do not overlap in time\n");	      exit(-1);	    }	  } else	    if(start >= BUF_END_TIME(f0s)) {	      printf("F0 and Fn files do not overlap in time\n");	      exit(-1);	    }	  if(end > BUF_END_TIME(f0s))	    end = BUF_END_TIME(f0s);	}	if(excit) {	  if(BUF_END_TIME(se) < end) end = BUF_END_TIME(se);	  if(BUF_START_TIME(se) > start) start = BUF_START_TIME(se);	}	fbskip = (start - BUF_START_TIME(fbs)) * fbs->freq;	if(f0s)	  f0skip = (start - BUF_START_TIME(f0s)) * f0s->freq;	if(excit) {	  seskip = (start - BUF_START_TIME(se)) * se->freq;	  fs = se->freq;	  rate = 1.0;	  ep = *((short**)se->data) + seskip;	} else	  ep = NULL;	nframes = (end - start) * fbs->freq;	nsamples = nframes * ((int)(0.5 + fs/fbs->freq));	if((sig = (short*)malloc(sizeof(short)*nsamples))) {	  if(debug_level & 1)	    printf("Allocated memory (%d)\n",nsamples);	  nform = fbs->dim/2;	  for(i=0; i < nform; i++) {	    ff[i] = ((double**)fbs->data)[i] + fbskip;	    fb[i] = ((double**)fbs->data)[i+nform] + fbskip;	  }	  if(f0s) {	    dpp = (double**)f0s->data;	    f0 = dpp[0] + f0skip;	    pv = dpp[1] + f0skip;	    rms = dpp[2] + f0skip;	  }	  if(debug_level & 1)	    printf("Finished pointersetup\n");	  frint = 1.0/(rate * fbs->freq);	  if((nforce > 0) && (nforce < nform)) nform = nforce;	  if(debug_level & 1)	    printf("Entering formsy()\n");	  formsy(nframes,frint,nform,ff,fb,f0,pv,rms,sig,fs,bws,		 limit,fscale,f0scale,vforce, high_pole,ep);	  if(f0s && fix_gain) {	    double frate, wsize, *dp;	    int nrms;	    short *rmsd, *sig2, *get_rms(), *adjust_gain();	      	    frate = 1.0/frint;	    wsize = frint;	    dp = ((double**)f0s->data)[2];	    rmsd = get_rms(sig,nsamples,fs,&frate,&wsize,&nrms);	    sig2 = adjust_gain(sig,nsamples,fs,rmsd,nrms,frate,dp);	    free(sig);	    free(rmsd);	    sig = sig2;	  }	  spp = (short**)malloc(sizeof(short*));	  *spp = sig;	  if((so=new_signal(cp,fd,NULL,spp, nsamples,fs,1))) {	    Header *w_new_header();	    so->header = w_new_header(1);	    if(fbs->header->magic == ESPS_MAGIC) {	      struct header *sd_oh;	      char   *get_cmd_line (), *cmd_line;	      	      /* create output ESPS header*/	      cmd_line = get_cmd_line (ac, av);	      sd_oh = new_header (FT_FEA);	      add_source_file (sd_oh, fbs->name, fbs->header->esps_hdr);	      if(excit)		add_source_file (sd_oh, se->name, se->header->esps_hdr);	      else		add_source_file (sd_oh, f0s->name, f0s->header->esps_hdr);	      add_comment (sd_oh, cmd_line);	      sd_oh -> common.tag = NO;	      set_pvd(sd_oh);	      if((init_feasd_hd(sd_oh, SHORT, 1, &start, 0, fs)) !=0){		fprintf(stderr, "formsy: Couldn't allocate FEA_SD header - exiting.\n");		exit(1);	      }	      (void)add_genhd_d("record_freq", &fs, 1, sd_oh);	      	      if(strcmp(bdstr,"0.0"))

⌨️ 快捷键说明

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