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

📄 fanaspec.c

📁 speech signal process tools
💻 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 + -