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

📄 pkmc_filt.c

📁 speech signal process tools
💻 C
📖 第 1 页 / 共 2 页
字号:
      *Ncoef = (Ntaps -1)/2 + 1;        /* THIS IS L ONLY!!!*/    }    else {       *fcase = CASE2;      minf = 0;      maxf = 0.5-dfreq;      *Ncoef = Ntaps / 2;     }  }  else{    if( 2*(Ntaps/2) != Ntaps) {       minf = dfreq;      maxf = 0.5-dfreq;      *Ncoef = (Ntaps -1)/2;       *fcase = CASE3;    }    else {       minf = dfreq;      maxf = 0.5;      *Ncoef = Ntaps / 2;       *fcase = CASE4;    }  }/* use JTYPE determine des, wt: JTYPE=HILBERT, keep const, JTYPE=DIFFERENTIATOR, desired=1/f*/  /* convert frequency point to 0 to 0.5 */  k = 0;  m = 0;  for(i=0; i<nbands; i++){    firspecs[i].edge[0] = MAX(minf, firspecs[i].edge[0]/ nfs);    firspecs[i].edge[1] = MIN(maxf, firspecs[i].edge[1]/ nfs);    d = (firspecs[i].edge[1] - firspecs[i].edge[0]) / dfreq;    bands[i].idx1 = m;    bands[i].idx2 = bands[i].idx1 + d;    m = bands[i].idx2 + 1;    for( j=0; j <= d; j++){      f = MAX(minf, firspecs[i].edge[0]) + dfreq * j;      w[k] = f*nfs;      if( jtype != DIFFERENTIATOR ){	desired = firspecs[i].des;	weight = firspecs[i].wt;      }      else{	desired = firspecs[i].des * f;	if( f!=0) weight = firspecs[i].wt / f;	else weight = firspecs[i].wt;      }      cx[k] = cos( pi2 * f);      if(*fcase == CASE1){	des[k] = desired;	wt[k] = weight;      }      if(*fcase == CASE2){	des[k] = desired / cos(PI*f);	wt[k] = weight * cos(PI*f);      }      if(*fcase == CASE3){	des[k] = desired / sin(pi2*f);	wt[k] = weight * sin(pi2*f);      }      if(*fcase == CASE4){	des[k] = desired/ sin(PI*f);	wt[k] = weight * sin(PI*f);      }      k++;    }  }  *Ngrid = k;}  voidremez_exchange( Ncoef, Ngrid, cx, des, wt, Nbands, bands, A, coef, final_db)int Ncoef;   /* L+1 in 7.110 */int Ngrid;   /* number of points on frequency */     double *cx;  /* the cos'ed frequecy grid point on appx. bands */double *des, *wt;   /* desired, weights ordinate on cx abscissa */int Nbands;struct edges *bands;double *A, *coef, *final_db;{  int do_again = 1, iter = MAX_ITER;  int Nexm;  int CNexm;  struct diff *exm, *Cexm;  int dgrid, i, j, k, m,  bdN;  double del, olddel=0;  double *d, *C;  Nexm = Ncoef+1;  exm = (struct diff *) malloc (sizeof(struct diff)* Nexm);  Cexm = (struct diff *) malloc (sizeof(struct diff)* Ngrid);  d = (double *) malloc( sizeof(double) * Nexm );  C = (double *) malloc( sizeof(double) * Nexm-1 );  /* initial guess, place extremas uniformly on the bands */  for(i=0, k=0; i<Nbands-1; i++){    if(0==(bdN = (int) Nexm *  (bands[i].idx2 - bands[i].idx1+1)/Ngrid)){      Fprintf(stderr,"ERROR: transition band too narrow - exiting\n");      exit(1);    }    dgrid = (int) (bands[i].idx2 - bands[i].idx1 ) / bdN;    for( m = 0, j=bands[i].idx1; j<= bands[i].idx2 && m< bdN; j += dgrid, m++ )      {exm[k].idx = j; k++;}  }  bdN = Nexm - k;  dgrid = (int) (bands[Nbands-1].idx2 - bands[Nbands-1].idx1 ) / bdN;  for( m=0, j=bands[Nbands-1].idx1; j<= bands[Nbands-1].idx2 && m<bdN; m++,j += dgrid ) {exm[k].idx = j; k++;}  if(debug_level>=10){    Fprintf(stderr,"initial guess on extremas\n");    for(i=0; i<Nexm; i++) Fprintf(stderr,"extrema on %d\n", exm[i].idx);  }  while( do_again && iter-- > 0 ){        if(debug_level>=10) Fprintf(stderr,"Iteration %d\n", MAX_ITER - iter);    (void) find_del_interpolate(exm, Nexm, des, wt, cx, Ngrid, A, &del, d, C);    if(debug_level >=10)      Fprintf(stderr,"   delta = %g\n", del);    if(fabs(del) < olddel){      Fprintf(stderr,"ERROR: remez_exchange: delta value non-increasing, numerical problem - exiting\n");      exit(1);    }    olddel = fabs(del);    (void) find_extrema(A, des, wt, Ngrid, del, Cexm, &CNexm);    if(debug_level >=10){      Fprintf(stderr,"   found %d extremas\n", CNexm);      for(i=0; i<CNexm; i++) Fprintf(stderr,"   found extrema on %d val %g\n",				     Cexm[i].idx, Cexm[i].err);    }    do_again = check_extrema( CNexm, Cexm, &Nexm, exm, del);    if(debug_level >=10){      Fprintf(stderr,"   found %d extremas\n", CNexm);      Fprintf(stderr,"   decide %d extremas\n", Nexm);      for(i=0; i<Nexm; i++) Fprintf(stderr,"   use extrema on %d val %g\n",				    exm[i].idx, exm[i].err);      Fprintf(stderr,"\n");    }  }  if( iter == 0 ) {    Fprintf(stderr,"remez_exchange: Unable to find a solution after %d iterations.-- exiting\n", MAX_ITER);    exit(1);  }  get_coef(cx, Ncoef, coef, exm, d,C);  *final_db = fabs(del);  /* clean up */  free(exm);  free(Cexm);  free(d);  free(C);}voidget_coef(cx,  Ncoef, coef, exm, d, C)     double  *coef, *cx, *d, *C;     int Ncoef;     struct diff *exm;{  double sum = 0;  int i, k, j, sign = 0, M;  double x;  double num, den;  double *Ai, pi2, D;  pi2 = 2* PI;  Ai = (double *) malloc(sizeof(double) * Ncoef);  M = 2 * Ncoef - 1;  for(i = 0; i< Ncoef; i++){    num =0;    den = 0;    x = cos(pi2 * i / M);    for( k=0; k<Ncoef; k++){      if( fabs(cx[exm[k].idx] - x) <= SMALL){	num = C[k];	den = 1.0;	sign = (sign > 0) ? -1: 1;	break;      }      else{	D = d[k] / ( x - cx[exm[k].idx]);	num += D * C[k];	den += D;	sign = (sign > 0) ? -1: 1;      }    }    Ai[i] = num/den;    /* frequency sampling */  }  if(debug_level == 15521) write_outsd(Ai, Ncoef, "pkmc_Ai");/* freq response in Ai is   A(w) = sum a[n]*cos[wn], n->[0, N-1]    N terms       --> Ncoef   A(w) also = sum b(n) * exp(jwn) , n->[0, M-1] M terms;       M = 2N-1       b(0) = a(0)       b(n) = a(n)/2 for n->(0,N)       b(n) = b(M-n) for n->[N, M)   if Q(k) = Q(2*PI k/M), the dft of b(0).... b(M-1)  Q(k) = Q(M-k).   inv dft gives       b(n) = 1/M * sum Q(k)*exp(j2PI kn/M) ,   k->[0, M-1]            = (Q(0)/M) + (2/M) * sum Q(k) *cos(2 PI kn/M), k->[1, N-1]   -->   a(0) = 1/M (P(0) + 2 sum Q(k)), k->[1, N-1]   a(n) = (2/M) [Q(0) + 2*sum Q(k) *cos(2 PI kn/M)], k->[1, N-1] for       all n ->(0, N)*//*  Ncoef ---> terms used in sum a(n) * cos(wn) */  sum = 0;  for(i=1; i< Ncoef; i++) sum += Ai[i];  coef[0] = (Ai[0] + 2 * sum ) / M;  for(i=1; i< Ncoef; i++){    sum = 0;    for(j = 1; j< Ncoef; j++)  sum += Ai[j] * cos(pi2* i * j / M);    coef[i] = 2 * ( Ai[0] + 2*sum) / M;  }  /*clean up*/  free(Ai);      }void find_del_interpolate(exm, Nexm, des, wt, cx, Ngrid, A, delta, d, C)     double *des, *wt, *A, *cx;     struct diff *exm;     int Ngrid, Nexm;     double *delta;     double *d, *C;{  int i, k, j, st, order, sign;  double num=0, den=0, b=1, D;  order = Nexm - 1;  st = Nexm / 10 + 1;  sign = 1;  for( k=0; k< Nexm; k++){    b = 1.0;    for( j =0; j< st; j++){      for(i=j; i<Nexm; i+=st){	if( i!=k ) b =  2 * b * (cx[exm[k].idx] - cx[exm[i].idx]);      }    }    if( fabs(b) == 0){      Fprintf(stderr,"ERROR: lagrange coef b[%d] not distinct\n", k);      exit(1);    }    b = 1/b;    d[k] = b * (cx[exm[k].idx] - cx[exm[Nexm-1].idx]);    num += b * des[exm[k].idx];    den += (sign > 0) ? (b / wt[exm[k].idx]): (-b / wt[exm[k].idx]);    sign = (sign > 0) ? -1: 1;  }  *delta = num / den;  for( sign = 1, i = 0; i<order; i++){    if(sign > 0)      C[i] = des[exm[i].idx] - (*delta / wt[exm[i].idx]);    else      C[i] = des[exm[i].idx] + (*delta / wt[exm[i].idx]);    sign = (sign>0) ? -1:1;  }  for( j=0; j<Ngrid; j++){    num = 0;    den = 0;    for( k=0; k<order; k++){      if( exm[k].idx == j){	num = C[k];	den = 1.0;	break;      }      else{	D = d[k] / (cx[j] - cx[exm[k].idx]);	num += D * C[k];	den += D;      }    }    A[j] = num / den;  }  if(debug_level >= 1000)     for(i=0; i<Ngrid; i++)       Fprintf(stderr,"err[%d] %g A[%d] %g\n", i, wt[i]*(des[i]-A[i]), i, A[i]);}void find_extrema(A, des, wt, Ngrid, del, exm, Nexm)     double *A, *des, *wt, del;     int Ngrid,  *Nexm;     struct diff *exm;{  int i, j, k;  double *err, *ferr;  del = fabs(del);  err = (double *) malloc(sizeof(double ) *Ngrid);  ferr = (double *) malloc(sizeof(double ) *Ngrid);  for( i=0; i<Ngrid; i++){       /* each i <-> x[i], the freq */    err[i] = wt[i] * (des[i] - A[i]);    ferr[i] = fabs(err[i]);  }    /* first endpoint */  j = 0;  if( ferr[0] >= del-SMALL )    if( (err[0] > 0 && err[1] > 0 && err[0] > err[1]) ||       ( err[0] < 0 && err[1] < 0 && err[0] < err[1]) ||       OPPSIGN(err[0], err[1]) ){      exm[j].idx = 0;      exm[j].err = err[0];      j++;    }  for( k=1; k< Ngrid-1; k++){    if( ((err[k] > err[k+1] && err[k] > err[k-1]) ||    /* local max */	 (err[k] < err[k-1] && err[k] < err[k+1]) ) &&  /* local min */       ferr[k] >= del -SMALL ){                         /* |E| >= delta */      if( j == 0 ){	exm[j].idx = k;	exm[j].err = err[k];	j++;      }      else if( OPPSIGN(exm[j-1].err, err[k])){         /* possible alter.*/	exm[j].idx = k;	exm[j].err = err[k];	j++;      }    }  }  /* last endpoint */  k = Ngrid - 1;  if(   ferr[k] >= del - SMALL &&        OPPSIGN(exm[j-1].err , err[k])){      exm[j].idx = k;      exm[j].err = err[ k];      j++;    }  *Nexm = j;  /*clean up */  free(err);  free(ferr);}int check_extrema(Nexm, exm, NexmN, exmN, del)     double del;     int *NexmN, Nexm;     struct diff *exm, *exmN;        /* exm: new found */                                     /* exmN: largest extremas of new found 					was the old extremas */{  int st, en, i, j, redo=0;  del = fabs(del);  if( Nexm > *NexmN ){                 /* retain the largest */    i = Nexm;        st = 0;    en = Nexm - 1;    while( i-- > *NexmN ){                 /* rid extra end points */      if( fabs(exm[st].err) >= fabs(exm[en].err) )	en--;      if( fabs(exm[st].err) < fabs(exm[en].err) )	st++;    }    for( i = st, j=0; i<= en; i++, j++){      exmN[j].idx = exm[i].idx;      exmN[j].err = exm[i].err;    }    redo = 1;  }  if ( *NexmN == Nexm ){    redo = 0;    for(i=0; i < Nexm; i++){      if( exmN[i].idx != exm[i].idx || fabs(exm[i].err) >= del + SMALL){	for(j = 0; j<Nexm; j++){	  exmN[j].idx = exm[j].idx;	  exmN[j].err = exm[j].err;	}	redo = 1;	break;      }    }  }  if( *NexmN > Nexm ){    Fprintf(stderr,	    "ERROR: check_extrema: only found %d extremas, should be %d\n\n - numerical problem - exiting\n", Nexm, *NexmN);    exit(1);  }  return( redo);}voidwrite_outsd(pt, nsamp, fname )     double *pt;     int nsamp;     char *fname;{  struct header *ohd;  FILE *osdfile;  char *oname = NULL;  struct feasd *osd_rec;  double *data;  double start_time = 0;  int i;  oname = eopen("remez", fname, "w", NONE, NONE, &ohd, &osdfile);  ohd = new_header(FT_FEA);  (void) strcpy (ohd->common.prog, "remez");  (void) strcpy (ohd->common.vers, Version);  (void) strcpy (ohd->common.progdate, Date);  ohd->common.tag = NO;  init_feasd_hd(ohd, DOUBLE, 1 , &start_time  ,NO, 1.0);  (void) write_header ( ohd, osdfile );  osd_rec = allo_feasd_recs(ohd, DOUBLE, nsamp, (char*) NULL, NO);  data = (double *) osd_rec->data;  for(i=0;i<nsamp;i++) data[i] = pt[i];  put_feasd_recs( osd_rec, 0L, nsamp, ohd, osdfile );}

⌨️ 快捷键说明

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