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

📄 pkmc_filt.c

📁 speech signal process tools
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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:  Derek Lin * Checked by: * Revised by: * * Brief description: Parks-McClellan FIR design * */static char *sccs_id = "@(#)pkmc_filt.c	1.7 7/30/97 ERL";#include <math.h>#include <string.h>#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <esps/esps.h>#include <esps/constants.h>#include <esps/fea.h>#include <esps/feafilt.h>#include <esps/feasd.h>#include <esps/strlist.h>#define SYNTAX USAGE ("pkmc_filt [-P param_file][-x debug_level] filt_file");#define ERROR_EXIT(text) {(void) fprintf(stderr, "%s: %s - exiting\n", \					 argv[0], text); exit(1);}/* local definitions*/#define MAX_ITER 25#define MAX_NBANDS 10#define SMALL 0.00000001#define OPPSIGN(A, B) ((A > 0 && B < 0) || (A < 0 && B > 0))struct diff{  double err;    /* value */  int idx;       /* position on the grid */};struct edges{  int idx1;  int idx2;};struct spec{  double edge[2];  double des;  double wt;};int debug_level = 0;#define MULTIBAND 0#define DIFFERENTIATOR 1#define HILBERT 2static char *jtype_code[] = {"MULTIBAND", "DIFFERENTIATOR", "HILBERT"};#define CASE1 1#define CASE2 2#define CASE3 3#define CASE4 4/* system functions */double pow(), fabs();void perror();/*ESPS functions*/int getopt();char *get_cmd_line();/* local function definitions*/void find_del_interpolate();void find_extrema();int check_extrema();void write_outsd();void get_coef();void remez_exchange();void setup();void find_impulse();char *Date="7/30/97";char *Version="1.7";char *Program="@(#)pkmc_filt.c	1.7";voidmain( argc, argv)     int argc;     char **argv;{  extern char *optarg;  extern optind;  FILE *fpout;  struct header *oh;  struct feafilt *frec;  char *param_file = NULL;  char *filt_file = NULL;  filtdesparams *fdp;  char *str, stri[3], *str_edge1, *str_edge2, *str_des, *str_wt;  char *stu = "band";  char *stl1 = "edge1";  char *stl2 = "edge2";  char *std = "des";  char *stw = "wt";  char *filt_type = NULL;  int c, i, j, err=0;  double *des, *cx, *wt;  int Ngrid, nbands;  float *hd_edges, *hd_des, *hd_wt;  struct edges *bands;  struct spec *firspecs;  int Ncoef, Ntaps, jtype, fcase;  double *A, fs, *coef, *h, *f, del, delay = 0;  float *ripple_db;/* * Check the command line options. */  while ((c = getopt (argc, argv, "P:x:")) != EOF)    {      switch (c)        {        case 'P':          param_file = optarg;          break;        case 'x':          debug_level = atoi(optarg);          break;        default:          SYNTAX          }    }/* * Get the output filter filename */  if (optind < argc)    {      filt_file = argv [optind];      if (strcmp (filt_file, "-") == 0)        {          filt_file = "<stdout>";          fpout = stdout;        }      else TRYOPEN("pkmc_filt", filt_file, "w", fpout);      if (debug_level)        Fprintf (stderr,"%s: Output file is %s\n", argv[0],filt_file);    }  else    {      Fprintf (stderr,"%s: No output file specified.\n", argv[0]);      SYNTAX        exit (1);    }/*  *Read parameter file and get design parameters  */    if (debug_level)    Fprintf (stderr,"%s: Reading parameter file %s\n", argv[0],param_file);    if (read_params (param_file, SC_NOCOMMON, (char *)NULL) != 0)    ERROR_EXIT("read_params could not read the params file.");  /* filt_type: MULTIBAND, DIFFERENTIATOR, HILBERT */  if (symtype("filt_type") != ST_UNDEF)    filt_type = getsym_s ("filt_type");  else ERROR_EXIT("Filt_type not specified in params file.");  if((jtype = lin_search(jtype_code, filt_type)) == -1 ){    Fprintf(stderr, "%s: Invalid filt_type (%s) specified - exiting.\n",	    argv[0], filt_type);    exit(1);  }  /* filter length parameter: even or odd number */  if (symtype("filt_length") != ST_UNDEF)    Ntaps = getsym_i ("filt_length");  else ERROR_EXIT("Filt_length not specified in params file.");  /* Ngrid parameter */  if (symtype("ngrid") != ST_UNDEF)    Ngrid = getsym_i ("ngrid");  else Ngrid = 2 * Ntaps;  /* sampling frequency parameter*/  if( symtype("samp_freq") != ST_UNDEF)    fs = getsym_d("samp_freq");  else ERROR_EXIT("Samp_freq not specified in params file.");    /* nbands parameter */  if( symtype("nbands") != ST_UNDEF)    nbands = getsym_i("nbands");  else ERROR_EXIT("Nbands not specified in params file.");   firspecs = (struct spec *) malloc( sizeof(struct spec) * nbands);  /* band edges parameters, must be < fs/2 */  str = (char *) malloc(sizeof(char)*20);  str_edge1 = (char *) malloc(sizeof(char)*20);  str_edge2 = (char *) malloc(sizeof(char)*20);  str_des = (char *) malloc(sizeof(char)*20);  str_wt = (char *) malloc(sizeof(char)*20);  for( i = 1 ;i<=nbands; i++){    str = (char *) strcpy( str, stu);    sprintf( stri, "%d", i);    str = (char *) strcat(str, stri);    str = (char *) strcat(str, "_");    /* find edges */    str_edge1 = (char *) strcpy (str_edge1, str);    str_edge1 = (char *) strcat(str_edge1, stl1);    str_edge2 = (char *) strcpy (str_edge2, str);    str_edge2 = (char *) strcat(str_edge2, stl2);    if( symtype(str_edge1) != ST_UNDEF)      firspecs[i-1].edge[0] = getsym_d(str_edge1);    else err = 1;    if( symtype(str_edge2) != ST_UNDEF)      firspecs[i-1].edge[1] = getsym_d(str_edge2);    else err = 1;    if(err){      Fprintf(stderr,"%s: missing band edges for band %d\n", argv[0], i);      exit(1);    }    if( firspecs[i-1].edge[1] > fs/2)      ERROR_EXIT("bandedge can not be greater than the Nyquist rate");    /* find desired value */    str_des = (char *) strcpy (str_des, str);    str_des = (char *) strcat (str_des, std);    if( symtype(str_des) != ST_UNDEF)      firspecs[i-1].des = getsym_d(str_des);    else{      Fprintf(stderr,"%s: missing desired value for band %d\n", argv[0], i);      exit(1);    }    str_wt = (char *) strcpy (str_wt, str);    str_wt = (char *) strcat (str_wt, stw);    if( symtype(str_wt) != ST_UNDEF)      firspecs[i-1].wt = getsym_d(str_wt);    else{      Fprintf(stderr,"%s: missing weight value for band %d\n", argv[0], i);      exit(1);    }  }  /* Check that upper limit of last band == (sampling rate)/2.     DB added to avoid numeric-error/core-dump that can occur.   */  if( firspecs[nbands-1].edge[1] != fs/2.) {      Fprintf(stderr, "Upper bandedge of last band (%.2f) != sampling frequency / 2 (%.2f).\n\tPlease correct parameters and try again.\n",		 firspecs[nbands-1].edge[1], fs/2);      exit(1);    }  /* set up output generic header items */  hd_edges = (float *) malloc(sizeof(float) * 2* nbands);  hd_des = (float *) malloc(sizeof(float) *nbands);  hd_wt = (float *) malloc(sizeof(float) *nbands);  for(i=0, j=0; i<nbands;i++, j+=2){     hd_edges[j] = firspecs[i].edge[0];    hd_edges[j+1] = firspecs[i].edge[1];    hd_des[i] = firspecs[i].des;    hd_wt[i] = firspecs[i].wt;  }  bands = (struct edges *) malloc( sizeof(struct edges) * nbands);  des = (double *) malloc(sizeof(double) * Ngrid);  wt = (double *) malloc(sizeof(double) * Ngrid);  cx = (double *) malloc(sizeof(double) * Ngrid);  A = (double *) malloc (sizeof(double)* Ngrid);  coef = (double *) malloc (sizeof(double)* Ntaps);  h = (double *) malloc( sizeof(double) * Ntaps);  f = (double *) malloc(sizeof(double) *Ngrid);  ripple_db = ( float *) malloc(sizeof(float) * nbands);  setup( f, cx, des, wt, &Ngrid, nbands, bands, Ntaps, &Ncoef, firspecs, jtype, &fcase, fs );  remez_exchange( Ncoef, Ngrid, cx, des, wt, nbands, bands, A, coef, &del);  for(i=0;i<nbands;i++) ripple_db[i] = 20*log10( firspecs[i].des + del/wt[i] );  if(debug_level > 0)    for(i=0;i<nbands;i++)       Fprintf(stderr,"%s: ripple in band %d is %f dB\n", argv[0],  	      i, ripple_db[i]);    if(debug_level == 15521) {    write_outsd(A,Ngrid,"pkmc_A");    write_outsd(des,Ngrid,"pkmc_des");  }  find_impulse(coef, Ncoef, h, fcase, Ntaps );  fdp = (filtdesparams *) calloc( 1, sizeof(filtdesparams));  fdp->define_pz = NO;  fdp->method = PARKS_MC;  fdp->nbands = nbands;  fdp->bandedges = hd_edges;  fdp->wts = hd_wt;  fdp->gains = hd_des;  fdp->g_size = Ngrid;  delay = (double) (Ntaps-1) / 2;  oh = new_header(FT_FEA);  (void) strcpy (oh->common.prog, argv[0]);  (void) strcpy (oh->common.vers, Version);  (void) strcpy (oh->common.progdate, Date);  oh->common.tag = NO;  add_comment(oh, get_cmd_line(argc, argv));  init_feafilt_hd( oh, (long)(Ntaps), 0L, fdp);  (void)add_genhd_f("band_edges", hd_edges, 2*nbands, oh);  (void)add_genhd_f("desired_value", hd_des, nbands, oh);  (void)add_genhd_f("desired_weight", hd_wt, nbands, oh);  (void)add_genhd_f("ripple_dB", ripple_db, nbands, oh);  (void)add_genhd_d("samp_freq", &fs, 1, oh);  (void)add_genhd_d("delay_samples", &delay, 1, oh);  (void) write_header ( oh, fpout );  frec = allo_feafilt_rec(oh);  *frec->num_size = Ntaps;  for(i=0;i<Ntaps;i++) frec->re_num_coeff[i] = h[i];  put_feafilt_rec( frec, oh, fpout);  /* clean up*/  free(firspecs);  free(str);  free(str_edge1);  free(str_wt);  free(str_edge2);  free(str_des);  free(hd_edges);  free(hd_des);  free(hd_wt);  free(bands);  free(des);  free(wt);  free(cx);  free(A);  free(coef);  free(h);  free(f);  free(ripple_db);  free(fdp);    exit(0);}voidfind_impulse(coef, Ncoef, h, fcase, Ntaps)  double *coef, *h;  int Ncoef, fcase, Ntaps;{  int i;  switch(fcase){  case CASE1:    if( Ncoef != (Ntaps - 1)/2 + 1)       Fprintf(stderr,"ERROR: number of coefficients mismatch.\n");    for(i=0; i< Ncoef-1; i++) h[i] = 0.5 * coef[Ncoef- 1 - i];    h[Ncoef-1] = coef[0];    for(i=Ncoef; i< Ntaps; i++) h[i] = h[Ntaps -i -1];    break;  case CASE2:    if( Ncoef != Ntaps / 2)      Fprintf(stderr,"ERROR: number of coefficients mismatch.\n");    if( Ncoef > 1){      h[0] = 0.25 * coef[Ncoef - 1];      for(i=1; i< Ncoef-1; i++) h[i] = 0.25* (coef[Ncoef-1-i] + coef[Ncoef-i]);      h[Ncoef - 1] = 0.5*(coef[0] + 0.5 * coef[1]);    }    else      h[0] = 0.5*coef[0];    for(i=Ncoef; i< Ntaps; i++) h[i] = h[Ntaps -i -1];    break;  case CASE3:    if( Ncoef != (Ntaps-1) / 2)      Fprintf(stderr,"ERROR: number of coefficients mismatch.\n");    if( Ncoef >= 3){      h[0] = .25 * coef[Ncoef -1];      h[1] =  0.25 * coef[Ncoef -1 ];      for(i=2; i< Ncoef-1; i++) h[i]= 0.25*(coef[Ncoef-i-1] - coef[Ncoef-i+1]);      h[Ncoef-1] = 0.5 *(coef[0] -0.5*coef[2]);    }    else if(Ncoef==2){      h[0] = 0.25 * coef[1];      h[1] = 0.5 * coef[0];    }    else if(Ncoef==1)      h[0] = 0.5 * coef[0];        h[Ncoef] = 0;    for(i=Ncoef+1; i< Ntaps; i++) h[i] = -h[Ntaps -i-1];    break;  case CASE4:    if( Ncoef != Ntaps/ 2)      Fprintf(stderr,"ERROR: number of coefficients mismatch.\n");    if( Ncoef > 1){      h[0] = 0.25 * coef[Ncoef-1];      for(i=1; i< Ncoef-1; i++) h[i]= 0.25*(coef[Ncoef-i-1]-coef[Ncoef-i]);      h[Ncoef-1] = 0.5 * (coef[0] - 0.5 * coef[1]);    }    else      h[0] = 0.5 * coef[0];    for(i=Ncoef; i<Ntaps; i++) h[i] = - h[Ntaps-i-1];    break;  }}voidsetup( w, cx, des, wt, Ngrid, nbands, bands, Ntaps, Ncoef, 	   firspecs, jtype, fcase, nfs )     double *w, *cx, *des, *wt;     int *Ngrid, nbands, *Ncoef, Ntaps;     struct edges *bands;     struct spec *firspecs;     int jtype, *fcase;     double nfs;        /* Nyquist rate, not sampling rate */{  double pi2, dfreq, minf, maxf, f, desired, weight;  int k,m,i,j,d;    pi2 = 2 * PI;  dfreq = 0.5 / (*Ngrid-1);  if( jtype == MULTIBAND ){    if( 2*(Ntaps/2) != Ntaps) {       *fcase = CASE1;      minf = 0;      maxf = 0.5;

⌨️ 快捷键说明

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