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

📄 downsample.c

📁 speech signal process tools
💻 C
字号:
/*	Copyright (c) 1987, 1988, 1989 AT&T	*//*	  All Rights Reserved	*//*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*//*	The copyright notice above does not evidence any	*//*	actual or intended publication of such source code.	*/#ifndef lint	static char *sccs_id = "@(#)downsample.c	1.4 1/26/93		ATT, ESI ";#endif/* downsample.c *//* a quick and dirty downsampler */#include <Objects.h>#define PI 3.1415927/* ----------------------------------------------------------------------- */Signal *downsample(s,freq2)     double freq2;     Signal *s;{  short	*bufin, **bufout;  static double	beta = 0.0, b[256];  double	ratio_t, maxi, maxc, ratio, beta_new, freq1;  static int	ncoeff = 127, ncoefft = 0, nbits = 15;  static short	ic[256];  int	insert, decimate, out_samps, smin, smax;  Signal *so;  register int i, j, k, l;  register short	*bufp;  char *cp, temp[200];  if(s) {    freq1 = s->freq;  cp = new_ext(s->name,"ds");  if((bufout = (short**)malloc(sizeof(short*))) &&     (so=new_signal(cp,SIG_UNKNOWN,dup_header(s->header),bufout,s->buff_size,		    s->freq,s->dim))) {    so->start_time = s->start_time + (((double)s->start_samp)/s->freq);    bufin = ((short**)s->data)[0];    ratio = freq2/freq1;    ratprx(ratio,&insert,&decimate,10);    ratio_t = ((double)insert)/((double)decimate);    if(ratio_t > .99) return(s);      freq2 = ratio_t * freq1;    beta_new = (.5 * freq2)/(insert * freq1);    if(beta != beta_new){      beta = beta_new;      if( !lc_lin_fir(beta,&ncoeff,b)) {	printf("\nProblems computing interpolation filter\n");	return(FALSE);      }      maxi = (1 << nbits) - 1;      j = (ncoeff/2) + 1;      for(ncoefft = 0, i=0; i < j; i++){	ic[i] = 0.5 + (maxi * b[i]);	if(ic[i]) ncoefft = i+1;      }    }				/*  endif new coefficients need to be computed */    if(dwnsamp(bufin,s->buff_size,bufout,&out_samps,insert,decimate,ncoefft,ic,	       &smin,&smax)){      double fmin = smin, fmax = smax;      so->buff_size = so->file_size = out_samps;      so->freq = freq2;      so->band = freq2/2.0;      so->version += 1;      head_printf(so->header,"version",&(so->version));      sprintf(temp,"downsample: ncoefft %d window Hanning signal %s",	      ncoefft, s->name);      head_printf(so->header,"operation",temp);      head_printf(so->header,"samples",&(so->buff_size));      head_printf(so->header,"frequency",&(so->freq));      head_printf(so->header,"bandwidth",&(so->band));      head_printf(so->header,"minimum",&fmin);      head_printf(so->header,"maximum",&fmax);      head_printf(so->header,"time",get_date());      return(so);    } else      printf("Problems in dwnsamp() in downsample()\n");  } else       printf("Can't create a new Signal in downsample()\n");  } else    printf("Null Signal passed to downsample()\n");    return(NULL);}  /* ******************************************************************** */get_abs_maximum(d,n)     register short *d;     register int n;{  register int i;  register short amax, t;  if((t = *d++) >= 0) amax = t;  else amax = -t;    for(i = n-1; i-- > 0; ) {    if((t = *d++) > amax) amax = t;    else {      if(-t > amax) amax = -t;    }  }  return((int)amax);}/* ******************************************************************** */dwnsamp(buf,in_samps,buf2,out_samps,insert,decimate,ncoef,ic,smin,smax)     short	*buf, **buf2;     int	in_samps, *out_samps, insert, decimate, ncoef, *smin, *smax;     short ic[];{  register short  *bufp, *bufp2;  short	*buft;  register int i, j, k, l, m;  int imax, imin;      if(!(*buf2 = buft = (short*)malloc(sizeof(short)*insert*in_samps))) {    perror("malloc() in dwnsamp()");    return(FALSE);  }      k = imax = get_abs_maximum(buf,in_samps);  if(insert > 1) k = (32767 * 32767)/k;	/*  prepare to scale data */  else k = (16384 * 32767)/k;  l = 16384;  m = 15;      /* Insert zero samples to boost the sampling frequency and scale the     signal to maintain maximum precision. */  for(i=0, bufp=buft, bufp2=buf; i < in_samps; i++) {    *bufp++ = ((k * (*bufp2++)) + l) >> m ;     for(j=1; j < insert; j++) *bufp++ = 0;  }      do_fir(buft,in_samps*insert,buft,ncoef,ic,0);      /*	Finally, decimate and return the downsampled signal. */  *out_samps = j = (in_samps * insert)/decimate;  k = decimate;  for(i=0, bufp=buft, imax = imin = *bufp; i < j; bufp += k,i++) {    *buft++ = *bufp;    if(imax < *bufp) imax = *bufp;    else      if(imin > *bufp) imin = *bufp;  }  *smin = imin;  *smax = imax;  *buf2 = (short*)realloc(*buf2,sizeof(short) * (*out_samps));  return(TRUE);}/*      ----------------------------------------------------------      */do_fir(buf,in_samps,bufo,ncoef,ic,invert)/* ic contains 1/2 the coefficients of a symmetric FIR filter with unity    passband gain.  This filter is convolved with the signal in buf.    The output is placed in buf2.  If invert != 0, the filter magnitude    response will be inverted. */short	*buf, *bufo, ic[];int	in_samps, ncoef, invert;{    register short  *buft, *bufp, *bufp2, stem;    short co[256], mem[256];    register int i, j, k, l, m, sum, integral;    int lim;        for(i=ncoef-1, bufp=ic+ncoef-1, bufp2=co, buft = co+((ncoef-1)*2),	integral = 0; i-- > 0; )      if(!invert) *buft-- = *bufp2++ = *bufp--;      else {	integral += (stem = *bufp--);	*buft-- = *bufp2++ = -stem;      }    if(!invert)  *buft-- = *bufp2++ = *bufp--; /* point of symmetry */    else {      integral *= 2;      integral += *bufp;      *buft-- = integral - *bufp;    }/*         for(i=(ncoef*2)-2; i >= 0; i--) printf("\n%4d%7d",i,co[i]);  */    for(i=ncoef-1, buft=mem; i-- > 0; ) *buft++ = 0;    for(i=ncoef; i-- > 0; ) *buft++ = *buf++;    l = 16384;    m = 15;    k = (ncoef << 1) -1;    for(i=in_samps-ncoef; i-- > 0; ) {      for(j=k, buft=mem, bufp=co, bufp2=mem+1, sum = 0; j-- > 0;	  *buft++ = *bufp2++ )	sum += (((*bufp++ * *buft) + l) >> m);      *--buft = *buf++;		/* new data to memory */      *bufo++ = sum;     }    for(i=ncoef; i-- > 0; ) {	/* pad data end with zeros */      for(j=k, buft=mem, bufp=co, bufp2=mem+1, sum = 0; j-- > 0;	  *buft++ = *bufp2++ )	sum += (((*bufp++ * *buft) + l) >> m);      *--buft = 0;      *bufo++ = sum;     }}/*      ----------------------------------------------------------      */lc_lin_fir(fc,nf,coef)/* create the coefficients for a symmetric FIR lowpass filter using the   window technique with a Hanning window. */register double	fc;double	coef[];int	*nf;{    register int	i, n, ieo;    register double	twopi, fn, c;    if(((*nf % 2) != 1) || (*nf > 127)) {	if(*nf <= 126) *nf = *nf + 1;	else *nf = 127;    }    n = (*nf + 1)/2;    /*  compute part of the ideal impulse response */    twopi = PI * 2.0;    coef[0] = 2.0 * fc;    c = PI;    fn = twopi * fc;    for(i=1;i < n; i++) coef[i] = sin(i * fn)/(c * i);    /* Now apply a Hanning window to the (infinite) impulse response. */    fn = twopi/((double)(*nf - 1));    for(i=0;i<n;i++) 	coef[i] *= (.5 + (.5 * cos(fn * ((double)i))));        return(TRUE);}/*      ----------------------------------------------------------      */ratprx(a,k,l,qlim)double	a;    int	*l, *k, qlim;{    double	aa, af, q, em, qq, pp, ps, e;    int	ai, ip, i;        aa = fabs(a);    ai = aa;/*    af = fmod(aa,1.0); */    i = aa;    af = aa - i;    q = 0;    em = 1.0;    while(++q <= qlim) {	ps = q * af;	ip = ps + 0.5;	e = fabs((ps - (double)ip)/q);	if(e < em) {	    em = e;	    pp = ip;	    qq = q;	}    };    *k = (ai * qq) + pp;    *k = (a > 0)? *k : -(*k);    *l = qq;    return(TRUE);    }

⌨️ 快捷键说明

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