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

📄 lpcfloat.c

📁 speech signal process tools
💻 C
📖 第 1 页 / 共 3 页
字号:
		s -= a[j] * r[i-j];	}	k[i] = ( s - r[i+1] )/e;	a[i] = k[i];	for ( j=0; j<=i; j++){		b[j] = a[j];	}	for ( j=0; j<i; j++){		a[j] += k[i] * b[i-j-1];	}	e *= ( 1. - (k[i] * k[i]) );    }    *ex = e;}a_to_aca ( a, b, c, p )double *a, *b, *c;register int p;/*  Compute the autocorrelations of the p LP coefficients in a.  *  (a[0] is assumed to be = 1 and not explicitely accessed.) *  The magnitude of a is returned in c. *  2* the other autocorrelation coefficients are returned in b. */{    double		s;    register short	i, j, pm;	for ( s=1., i = 0; i < p; i++ ){		s += (a[i] * a[i]);	}	*c = s;	pm = p-1;	for ( i = 0; i < p; i++){		s = a[i];		for ( j = 0; j < (pm-i); j++){			s += (a[j] * a[j+i+1]);		}		b[i] = 2. * s;	}}double itakura ( p, b, c, r, gain )register double *b, *c, *r, *gain;register int p;/* Compute the Itakura LPC distance between the model represented * by the signal autocorrelation (r) and its residual (gain) and * the model represented by an LPC autocorrelation (c, b). * Both models are of order p. * r is assumed normalized and r[0]=1 is not explicitely accessed. * Values returned by the function are >= 1. */ {     double s;     register int i;     for( s= *c, i=0; i< p; i++){	s += r[i] * b[i];    }    return (s/ *gain);}lpc(lpc_ord,lpc_stabl,wsize,data,lpca,ar,lpck,normerr,rms,preemp,type)     int lpc_ord, wsize, type;     double lpc_stabl, *lpca, *ar, *lpck, *normerr, *rms, preemp;     short *data;{  static double *dwind=NULL;  static int nwind=0;  double rho[MAXORDER+1], k[MAXORDER], a[MAXORDER+1],*r,*kp,*ap,en,er;  double wfact = 1.0;  if((wsize <= 0) || (!data) || (lpc_ord > MAXORDER)) return(FALSE);    if(nwind != wsize) {    if(dwind) dwind = (double*)realloc(dwind,wsize*sizeof(double));    else dwind = (double*)malloc(wsize*sizeof(double));    if(!dwind) {      printf("Can't allocate scratch memory in lpc()\n");      return(FALSE);    }    nwind = wsize;  }    w_window(data, dwind, wsize, preemp, type);  if(!(r = ar)) r = rho;  if(!(kp = lpck)) kp = k;  if(!(ap = lpca)) ap = a;  autoc( wsize, dwind, lpc_ord, r, &en );  if(lpc_stabl > 1.0) { /* add a little to the diagonal for stability */    int i;    double ffact;    ffact =1.0/(1.0 + exp((-lpc_stabl/20.0) * log(10.0)));    for(i=1; i <= lpc_ord; i++) rho[i] = ffact * r[i];    *rho = *r;    r = rho;    if(ar)      for(i=0;i<=lpc_ord; i++) ar[i] = r[i]; /* copy out for possible use later */  }  durbin ( r, kp, &ap[1], lpc_ord, &er);/* After talkin with David T., I decided to take the following correctionout -- if people window, the resulting output (spectrum and power) shouldcorrespond to the windowed data, and we shouldn't try to back-correctto un-windowed data. *//*  switch(type) {		/* rms correction for window *//*   case 0:    wfact = 1.0;		/* rectangular *//*    break;  case 1:    wfact = .630397;		/* Hamming *//*    break;  case 2:    wfact = .443149;		/* (.5 - .5*cos)^4 *//*    break;  case 3:    wfact = .612372;		/* Hanning *//*    break;  }*/  *ap = 1.0;  if(rms) *rms = en/wfact;  if(normerr) *normerr = er;  return(TRUE);}/* convert reflection (PARCOR) coefficients to areas */dreflar(c,a,n) double *c,*a; int n;{/*	refl to area			*/	register double *pa,*pa1,*pc,*pcl;	pa = a + 1;	pa1 = a;	*a = 1.;	for(pc=c,pcl=c+ n;pc<pcl;pc++)	*pa++ = *pa1++ * (1+*pc)/(1-*pc);	}/* covariance LPC analysis; originally from Markel and Gray *//* (a translation from the fortran) */w_covar(xx,m,n,istrt,y,alpha,r0,preemp,w_type)     double *y, *alpha, *r0, preemp;     short *xx;     int *m,n,istrt;     int w_type;{  static double *x=NULL;  static int nold = 0, ofile = -1;  static mold = 0;  static double *b = NULL, *beta = NULL, *grc = NULL, *cc = NULL, gam,s; int ibeg, ibeg1, ibeg2, ibegm2, ibegmp, np0, ibegm1, msq, np, np1, mf, jp, ip,     mp, i, j, minc, n1, n2, n3, npb, msub, mm1, isub, m2;  int mnew = 0;  if((n+1) > nold) {    if(x) free(x);    x = NULL;    if(!(x = (double*)calloc((n+1), sizeof(double)))) {      printf("Allocation failure in w_covar()\n");      return(FALSE);    }    nold = n+1;  }  if(*m > mold) {    if(b) free(b); if(beta) free(beta); if (grc) free(grc); if (cc) free(cc);    b = beta = grc = cc = NULL;    mnew = *m;        if(!((b = (double*)malloc(sizeof(double)*((mnew+1)*(mnew+1)/2))) &&        (beta = (double*)malloc(sizeof(double)*(mnew+3)))  &&       (grc = (double*)malloc(sizeof(double)*(mnew+3)))  &&       (cc = (double*)malloc(sizeof(double)*(mnew+3)))))   {      printf("Allocation failure in w_covar()\n");      return(FALSE);    }    mold = mnew;  }  w_window(xx, x, n, preemp, w_type);   ibeg = istrt - 1; ibeg1 = ibeg + 1; mp = *m + 1; ibegm1 = ibeg - 1; ibeg2 = ibeg + 2; ibegmp = ibeg + mp; i = *m; msq = ( i + i*i)/2; for (i=1; i <= msq; i++) b[i] = 0.0; *alpha = 0.0; cc[1] = 0.0; cc[2] = 0.0; for(np=mp; np <= n; np++) {   np1 = np + ibegm1;   np0 = np + ibeg;   *alpha += x[np0] * x[np0];   cc[1] += x[np0] * x[np1];   cc[2] += x[np1] * x[np1]; } *r0 = *alpha; b[1] = 1.0; beta[1] = cc[2]; grc[1] = -cc[1]/cc[2]; y[0] = 1.0; y[1] = grc[1]; *alpha += grc[1]*cc[1]; if( *m <= 1) return(FALSE);		/* need to correct indices?? */ mf = *m; for( minc = 2; minc <= mf; minc++) {   for(j=1; j <= minc; j++) {     jp = minc + 2 - j;     n1 = ibeg1 + mp - jp;     n2 = ibeg1 + n - minc;     n3 = ibeg2 + n - jp;     cc[jp] = cc[jp - 1] + x[ibegmp-minc]*x[n1] - x[n2]*x[n3];   }   cc[1] = 0.0;   for(np = mp; np <= n; np++) {     npb = np + ibeg;     cc[1] += x[npb-minc]*x[npb];   }   msub = (minc*minc - minc)/2;   mm1 = minc - 1;   b[msub+minc] = 1.0;   for(ip=1; ip <= mm1; ip++) {     isub = (ip*ip - ip)/2;     if(beta[ip] <= 0.0) {       *m = minc-1;       return(TRUE);     }     gam = 0.0;     for(j=1; j <= ip; j++)       gam += cc[j+1]*b[isub+j];     gam /= beta[ip];     for(jp=1; jp <= ip; jp++)       b[msub+jp] -= gam*b[isub+jp];   }   beta[minc] = 0.0;   for(j=1; j <= minc; j++)     beta[minc] += cc[j+1]*b[msub+j];   if(beta[minc] <= 0.0) {     *m = minc-1;     return(TRUE);   }   s = 0.0;   for(ip=1; ip <= minc; ip++)     s += cc[ip]*y[ip-1];   grc[minc] = -s/beta[minc];   for(ip=1; ip < minc; ip++) {     m2 = msub+ip;     y[ip] += grc[minc]*b[m2];   }   y[minc] = grc[minc];   s = grc[minc]*grc[minc]*beta[minc];   *alpha -= s;   if(*alpha <= 0.0) {     if(minc < *m) *m = minc;     return(TRUE);   } }}/* Same as above, but returns alpha as a function of order. */covar2(xx,m,n,istrt,y,alpha,r0,preemp)     double *y, *alpha, *r0, preemp;     short *xx;     int *m,n,istrt;{  static double *x=NULL;  static int nold = 0;  double b[513],beta[33],grc[33],cc[33],gam,s;  int ibeg, ibeg1, ibeg2,ibegm2, ibegmp, np0, ibegm1, msq, np, np1, mf, jp, ip,     mp, i, j, minc, n1, n2, n3, npb, msub, mm1, isub, m2;  if((n+1) > nold) {    if(x) free(x);    x = NULL;    if(!(x = (double*)malloc(sizeof(double)*(n+1)))) {      printf("Allocation failure in covar2()\n");      return(FALSE);    }    nold = n+1;  } for(i=1; i <= n; i++) x[i] = (double)xx[i] - preemp * xx[i-1]; ibeg = istrt - 1; ibeg1 = ibeg + 1; mp = *m + 1; ibegm1 = ibeg - 1; ibeg2 = ibeg + 2; ibegmp = ibeg + mp; i = *m; msq = ( i + i*i)/2; for (i=1; i <= msq; i++) b[i] = 0.0; *alpha = 0.0; cc[1] = 0.0; cc[2] = 0.0; for(np=mp; np <= n; np++) {   np1 = np + ibegm1;   np0 = np + ibeg;   *alpha += x[np0] * x[np0];   cc[1] += x[np0] * x[np1];   cc[2] += x[np1] * x[np1]; } *r0 = *alpha; b[1] = 1.0; beta[1] = cc[2]; grc[1] = -cc[1]/cc[2]; y[0] = 1.0; y[1] = grc[1]; *alpha += grc[1]*cc[1]; if( *m <= 1) return;		/* need to correct indices?? */ mf = *m; for( minc = 2; minc <= mf; minc++) {   for(j=1; j <= minc; j++) {     jp = minc + 2 - j;     n1 = ibeg1 + mp - jp;     n2 = ibeg1 + n - minc;     n3 = ibeg2 + n - jp;     cc[jp] = cc[jp - 1] + x[ibegmp-minc]*x[n1] - x[n2]*x[n3];   }   cc[1] = 0.0;   for(np = mp; np <= n; np++) {     npb = np + ibeg;     cc[1] += x[npb-minc]*x[npb];   }   msub = (minc*minc - minc)/2;   mm1 = minc - 1;   b[msub+minc] = 1.0;   for(ip=1; ip <= mm1; ip++) {     isub = (ip*ip - ip)/2;     if(beta[ip] <= 0.0) {       *m = minc-1;       return;     }     gam = 0.0;     for(j=1; j <= ip; j++)       gam += cc[j+1]*b[isub+j];     gam /= beta[ip];     for(jp=1; jp <= ip; jp++)       b[msub+jp] -= gam*b[isub+jp];   }   beta[minc] = 0.0;   for(j=1; j <= minc; j++)     beta[minc] += cc[j+1]*b[msub+j];   if(beta[minc] <= 0.0) {     *m = minc-1;     return;   }   s = 0.0;   for(ip=1; ip <= minc; ip++)     s += cc[ip]*y[ip-1];   grc[minc] = -s/beta[minc];   for(ip=1; ip < minc; ip++) {     m2 = msub+ip;     y[ip] += grc[minc]*b[m2];   }   y[minc] = grc[minc];   s = grc[minc]*grc[minc]*beta[minc];   alpha[minc-1] = alpha[minc-2] - s;   if(alpha[minc-1] <= 0.0) {     if(minc < *m) *m = minc;     return;   } }}   	 /*      ----------------------------------------------------------      *//* Find the roots of the LPC denominator polynomial and convert the z-plane	zeros to equivalent resonant frequencies and bandwidths.	*//* The complex poles are then ordered by frequency.  */formant(lpc_order,s_freq,lpca,n_form,freq,band,init)int	lpc_order, /* order of the LP model */	*n_form,   /* number of COMPLEX roots of the LPC polynomial */	init; 	   /* preset to true if no root candidates are available */double	s_freq,    /* the sampling frequency of the speech waveform data */	*lpca, 	   /* linear predictor coefficients */	*freq,     /* returned array of candidate formant frequencies */	*band;     /* returned array of candidate formant bandwidths */{  double  x, flo, pi2t, theta;  static double  rr[MAXORDER], ri[MAXORDER];  int	i,ii,iscomp1,iscomp2,fc,swit;  if(init){ /* set up starting points for the root search near unit circle */    x = M_PI/(lpc_order + 1);    for(i=0;i<=lpc_order;i++){      flo = lpc_order - i;      rr[i] = 2.0 * cos((flo + 0.5) * x);      ri[i] = 2.0 * sin((flo + 0.5) * x);    }  }  if(! lbpoly(lpca,lpc_order,rr,ri)){ /* find the roots of the LPC polynomial */    *n_form = 0;		/* was there a problem in the root finder? */    return(FALSE);  }  pi2t = M_PI * 2.0 /s_freq;  /* convert the z-plane locations to frequencies and bandwidths */  for(fc=0, ii=0; ii < lpc_order; ii++){    if((rr[ii] != 0.0)||(ri[ii] != 0.0)){      theta = atan2(ri[ii],rr[ii]);      freq[fc] = fabs(theta / pi2t);      if((band[fc] = 0.5 * s_freq *	  log(((rr[ii] * rr[ii]) + (ri[ii] * ri[ii])))/M_PI) < 0.0)	band[fc] = -band[fc];      fc++;			/* Count the number of real and complex poles. */      if((rr[ii] == rr[ii+1])&&(ri[ii] == -ri[ii+1]) /* complex pole? */	 && (ri[ii] != 0.0)) ii++; /* if so, don't duplicate */    }  }  /* Now order the complex poles by frequency.  Always place the (uninteresting)     real poles at the end of the arrays. 	*/  theta = s_freq/2.0;		/* temporarily hold the folding frequency. */  for(i=0; i < fc -1; i++){	/* order the poles by frequency (bubble) */    for(ii=0; ii < fc -1 -i; ii++){      /* Force the real poles to the end of the list. */      iscomp1 = (freq[ii] > 1.0) && (freq[ii] < theta);      iscomp2 = (freq[ii+1] > 1.0) && (freq[ii+1] < theta);      swit = (freq[ii] > freq[ii+1]) && iscomp2 ;      if(swit || (iscomp2 && ! iscomp1)){	flo = band[ii+1];	band[ii+1] = band[ii];	band[ii] = flo;	flo = freq[ii+1];	freq[ii+1] = freq[ii];	freq[ii] = flo;      }    }  }  /* Now count the complex poles as formant candidates. */  for(i=0, theta = theta - 1.0, ii=0 ; i < fc; i++)    if( (freq[i] > 1.0) && (freq[i] < theta) ) ii++;  *n_form = ii;  return(TRUE);}/*-----------------------------------------------------------------------*/log_mag(x,y,z,n)			/* z <- (10 * log10(x^2 + y^2))  for n elements */double	*x, *y, *z;int	n;{register double	*xp, *yp, *zp, t1, t2, ssq;    if(x && y && z && n) {        for(xp=x+n, yp=y+n, zp=z+n; zp > z;) {	    t1 = *--xp;	    t2 = *--yp;	    ssq = (t1*t1)+(t2*t2);	    *--zp = (ssq > 0.0)? 10.0 * log10(ssq) : -200.0;	}	return(TRUE);    } else {	return(FALSE);    }}/*-----------------------------------------------------------------------*/flog_mag(x,y,z,n)			/* z <- (10 * log10(x^2 + y^2))  for n elements */float	*x, *y, *z;int	n;{register float	*xp, *yp, *zp, t1, t2, ssq;    if(x && y && z && n) {        for(xp=x+n, yp=y+n, zp=z+n; zp > z;) {	    t1 = *--xp;	    t2 = *--yp;	    ssq = (t1*t1)+(t2*t2);	    *--zp = (ssq > 0.0)? 10.0 * log10((double)ssq) : -200.0;	}	return(TRUE);    } else {	return(FALSE);    }}#ifdef USE_OLD_FFT#include	"thetable.c"	/*  table of sines and cosines *//*-----------------------------------------------------------------------*/fft ( l, x, y )int l;double *x, *y;/* Compute the discrete Fourier transform of the 2**l complex sequence * in x (real) and y (imaginary).  The DFT is computed in place and the * Fourier coefficients are returned in x and y. */{register double	c, s,  t1, t2;register int	j1, j2, li, lix, i;int	np, lmx, lo, lixnp, lm, j, nv2, k, im, jm;

⌨️ 快捷键说明

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