📄 fanaspec.c
字号:
/* * This material contains proprietary software of Entropic Speech, Inc. * Any reproduction, distribution, or publication without the prior * written permission of Entropic Speech, Inc. is strictly prohibited. * Any public distribution of copies of this work authorized in writing by * Entropic Speech, Inc. must bear the notice * * "Copyright (c) 1986, 1987 Entropic Speech, Inc.; All rights reserved" * * Program: fanaspec.c * * History: pre-SDS version by Shankar Narayana * SDS version by Joe Buck * SPS version by Rod Johnson * converted to use FEA_ANA files and to avoid ndrec by John Shore * * Checked by: * * This is anaspec, which makes a spectral records from FEA_ANA files * * This is the main module of anaspec; it interprets the command * line, sets up and checks input and output files, reads the * input data, calls on rctoc and getarspec to compute the * output values, and writes the output. * * Input to anaspec is an SPS fEA_ANA analysis file. Output is an SPS * spectral-record file (SPEC). *//*these will be replaced after sps headers modified*/#define SPSHIBITL (1L << (8 * (int)sizeof(long)) - 1)#define SPSMAXLONG (~SPSHIBITL)#define FM_VARIABLE 4 /*remove when fixed in SPEC files*/#ifdef SCCS static char *sccs_id = "@(#)fanaspec.c 1.1 6/11/87 ESI";#endif#include <esps/esps.h>#include <stdio.h>#include <esps/fea.h>#include <esps/anafea.h>#include <esps/spec.h>#include "getarspec.h"#define SYNTAX USAGE ("fanaspec [-x debug_level][-f range] [-o order] [-n num_freqs] ana_file spec_file")#define THISPROG "fanaspec"#define MAXORDER 999#define MIN(a, b) ((a < b) ? a : b) /*returns lower of a, b*/#define MAX(a, b) ((a > b) ? a : b) /*returns greater of a, b*/char head_errtxt[100];char *strcat(), *strcpy();char *malloc();void perror(), exit(); /* should be in <esps.h> */char *get_cmd_line();char *eopen();struct zfunc *get_genzfunc();double avg_raw_pwr();int debug_level = 0;voidmain(argc, argv) int argc; char **argv;{ struct header *ih, *oh; FILE *istrm = stdin, *ostrm = stdout; struct anafea *ana_rec; struct spec_data *spec_rec; float lpcfilter[MAXORDER + 1]; float gain, raw_pwr; int i, sampfreq, c; int maxorder, order, order_vcd, order_unvcd; int oflag = 0; long srec, erec, nrec; int num_freqs = 513, max_num_freqs = 1 + DFTMAX/2; short frmlen; extern optind; extern char *optarg; extern char *Version, *Date; /* defined in version.c */ char *range = NULL; char *inpfile = "<stdin>"; char *cmd_line; int first = 1; cmd_line = get_cmd_line(argc, argv); /*store copy of command line*/ while ((c = getopt(argc, argv, "x:f:n:o:")) != EOF) switch (c) { case 'x': debug_level = atoi(optarg); break; case 'f': range = optarg; break; case 'n': num_freqs = atoi(optarg); break; case 'o': maxorder = atoi(optarg); oflag++; break; default: SYNTAX; break; } if (optind < argc) inpfile = eopen(THISPROG, argv[optind++], "r", FT_FEA, FEA_ANA, &ih, &istrm); else { Fprintf(stderr, "%s: no input FEA_ANA file specified.\n", THISPROG); SYNTAX; } if (optind < argc) (void) eopen(THISPROG, argv[optind++], "w", FT_SPEC, NONE, &oh, &ostrm); else { Fprintf(stderr, "%s: no output file specified.\n", THISPROG); SYNTAX; } if (!pwr_of_two(num_freqs - 1)) { fprintf(stderr, "%s: number of frequencies %d ", THISPROG, num_freqs); fprintf(stderr, "is not 1 plus a power of 2.\n"); exit(1); } if (num_freqs > max_num_freqs) { fprintf(stderr, "%s: number of frequencies %d ", THISPROG, num_freqs); fprintf(stderr, "exceeds %d.\n", max_num_freqs); exit(1); } if (*(short *)get_genhd("spec_rep", ih) != RC) { (void) fprintf(stderr, "%s: input must have RC spec_rep; exiting\n", THISPROG); exit(1); } order_vcd = *(long *)get_genhd("order_vcd", ih); order_unvcd = *(long *)get_genhd("order_unvcd", ih); if (oflag) { if (maxorder > MAX(order_vcd, order_unvcd)) { (void) fprintf(stderr, "THISPROG: order %d too big\n", maxorder); exit(1); } } else /*no input order*/ maxorder = MAX(order_vcd, order_unvcd); sampfreq = *(float *)get_genhd("src_sf", ih); frmlen = *(short *) get_genhd("frmlen",ih);/* Make output header */ oh = new_header(FT_SPEC); add_source_file(oh, inpfile, ih); if (add_comment(oh, cmd_line) == 0) Fprintf(stderr, "THISPROG: WARNING- not enough space for command line in comment\n"); oh->common.tag = YES; strcpy(oh->common.prog, THISPROG); strcpy(oh->common.vers, Version); strcpy(oh->common.progdate, Date);/* Get subrange */ srec = 1; erec = nrec = SPSMAXLONG; lrange_switch(range, &srec, &erec, 0L); nrec = erec - srec + 1; oh->variable.refer = ih->variable.refer; oh->hd.spec->frmlen = frmlen; oh->hd.spec->order_vcd = order_vcd; oh->hd.spec->order_unvcd = order_unvcd; oh->hd.spec->sf = sampfreq; if (get_genhd("dcrem", ih) != NULL) oh->hd.spec->dcrem = *(float *) get_genhd("dcrem", ih); if (get_genhd("win_type", ih) != NULL) oh->hd.spec->win_type = *(short *) get_genhd("win_type", ih); oh->hd.spec->voicing = YES; oh->hd.spec->freq_format = SYM_EDGE; oh->hd.spec->spec_type = ST_DB; oh->hd.spec->contin = YES; oh->hd.spec->num_freqs = num_freqs; oh->hd.spec->pre_emp = get_genzfunc("pre_emp", ih); oh->hd.spec->frame_meth = FM_VARIABLE;/* Header is done, except for start and nan -- these may be filled in when the first record is read; here we give them values indicating they don't apply*/ oh->hd.spec->start = oh->hd.spec->nan = -1;/* Allocate records */ ana_rec = allo_anafea_rec(ih); spec_rec = allo_spec_rec(oh);/* Position at first record, then fire away */ if (srec > 1) skiprec(istrm, srec - 1, size_rec(ih)); while (nrec-- && (get_anafea_rec(ana_rec, ih, istrm) != EOF)) { /* if the file is tagged, we can use the first record to tell us the starting point; if there's only one record being processed, we also know the number of points */ if (first) { first = 0; if (ih->common.tag == YES) { oh->hd.spec->start = *ana_rec->tag; if (nrec == 0) oh->hd.spec->nan = *ana_rec->frame_len; } /*now we go ahead and write the header, before any records are output*/ write_header(oh, ostrm); } if (ih->common.tag == YES) spec_rec->tag = *ana_rec->tag; if (*ana_rec->frame_type == VOICED) { order = MIN(maxorder, order_vcd); spec_rec->voiced = YES; } else /*all no-VOICED frame types are treated as unvoiced*/ { order = MIN(maxorder, order_unvcd); spec_rec->voiced = NO; } spec_rec->frame_len = *ana_rec->frame_len; /* invalid if ana */ /* prog used overlapping or noncontiguous frames */ raw_pwr = avg_raw_pwr(ana_rec, ih); rctoc(ana_rec->spec_param - 1, order, lpcfilter, &gain); /* rctoc rc indices start at 1 */ if (debug_level) { fprintf(stderr, "Reflection coefficients:\n"); for (i = 1; i <= order; i++) fprintf(stderr, "%d\t%f\n", i, ana_rec->spec_param[i-1]); fprintf(stderr, "Gain = %f\n", gain); fprintf(stderr, "Raw_power = %f\n", raw_pwr); fprintf(stderr, "Locn = %d\n", *ana_rec->tag); } get_arspect(lpcfilter, order, raw_pwr*gain, sampfreq, spec_rec->re_spec_val, num_freqs); put_spec_rec(spec_rec, oh, ostrm); (void) fflush(ostrm); } exit(0);}pwr_of_two(n) /* Test whether n is an integer power of 2. */ int n;{ int p; for (p = 1; p < n; p *= 2) {} return p == n;}doubleavg_raw_pwr(ana_rec, h) /*Average raw power in analysis record */ struct anafea *ana_rec; struct header *h;{ if (ana_rec->p_pulse_len[0] == 0 /* unvoiced */ || ana_rec->raw_power[1] < 0) /* only one pwr for frame */ return ana_rec->raw_power[0]; else /* voiced, one pwr per pulse */ { int i; double len, sum_len = 0, sum_energy = 0; for ( i = 0; i < *(long *)get_genhd("maxpulses", h) && ana_rec->p_pulse_len[i] != 0; i++ ) { sum_len += len = ana_rec->p_pulse_len[i]; sum_energy += len * ana_rec->raw_power[i]; } return sum_energy/sum_len; }}rctoc(rc,order,c,pgain)float rc[],c[],*pgain;int order;{ float tmp, ctmp[1000], gain = 1.0; int i, j; for (i = 1; i <= order; i++) { tmp = rc[i]; gain = gain * (1.0 - tmp * tmp); /* printf("rc(%d) = %f, gain = %f\n",i,tmp,gain); */ if (i != 1) { for (j = 1; j < i; j++) ctmp[j] = c[j] - tmp * c[i - j]; } ctmp[i] = tmp; for (j = 1; j <= i; j++) c[j] = ctmp[j]; } *pgain = gain;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -