📄 lpcfloat.c
字号:
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; } durbin ( r, kp, &ap[1], lpc_ord, &er); *ap = 1.0; if(rms) *rms = en; if(normerr) *normerr = er; return(TRUE);}/* covariance LPC analysis; originally from Markel and Gray *//* (a translation from the fortran) */covar(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; y--; /* KLUGE to fortranify the array */ if((n+1) > nold) { if(x) free(x); x = NULL; if(!(x = (double*)malloc(sizeof(double)*(n+1)))) { printf("Allocation failure in covar()\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[1] = 1.0; y[2] = 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]; grc[minc] = -s/beta[minc]; for(ip=2; ip <= minc; ip++) { m2 = msub+ip-1; y[ip] += grc[minc]*b[m2]; } y[minc+1] = grc[minc]; s = grc[minc]*grc[minc]*beta[minc]; *alpha -= s; if(*alpha <= 0.0) { if(minc < *m) *m = minc; return; } }} /* 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; y--; /* KLUGE to fortranify the array */ if((n+1) > nold) { if(x) free(x); x = NULL; if(!(x = (double*)malloc(sizeof(double)*(n+1)))) { printf("Allocation failure in covar()\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[1] = 1.0; y[2] = 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]; grc[minc] = -s/beta[minc]; for(ip=2; ip <= minc; ip++) { m2 = msub+ip-1; y[ip] += grc[minc]*b[m2]; } y[minc+1] = 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; } }} /*-----------------------------------------------------------------------*/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)? 10.0 * log10(ssq) : -200.0; } return(TRUE); } else { return(FALSE); }}/*-----------------------------------------------------------------------*/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;#include "thetable.c" /* table of sines and cosines */ for ( np=1, i=1; i <= l; i++) np *= 2; if(tablesize < (np/2)) { printf("\nPrecomputed trig tables are not big enough in fft().\n"); return(FALSE); } k = (tablesize * 2)/np; for (lmx=np, lo=0; lo < l; lo++, k *= 2) { lix = lmx; lmx /= 2; lixnp = np - lix; for (i=0, lm=0; lm<lmx; lm++, i += k ) { c = cosine[i]; s = sine[i]; for ( li = lixnp+lm, j1 = lm, j2 = lm+lmx; j1<=li; j1+=lix, j2+=lix ) { t1 = x[j1] - x[j2]; t2 = y[j1] - y[j2]; x[j1] += x[j2]; y[j1] += y[j2]; x[j2] = (c * t1) + (s * t2); y[j2] = (c * t2) - (s * t1); } } } /* Now perform the bit reversal. */ j = 1; nv2 = np/2; for ( i=1; i < np; i++ ) { if ( j < i ) { jm = j-1; im = i-1; t1 = x[jm]; t2 = y[jm]; x[jm] = x[im]; y[jm] = y[im]; x[im] = t1; y[im] = t2; } k = nv2; while ( j > k ) { j -= k; k /= 2; } j += k; } return(TRUE);}#ifdef STANDALONEmain(ac, av) int ac; char **av;{ int i,j,k, nfft=9; FILE *fd, *fopen(); double x[4096], y[4096]; char line[500]; if((fd = fopen(av[1],"r"))) { i=0; while((i < 512) && fgets(line,500,fd)) { sscanf(line,"%lf",&x[i]); y[i++] = 0.0; } for( ; i < 512; i++) { x[i] = y[i] = 0.0; } fft(nfft,x,y); log_mag(x,y,x,257); for(i=0; i<257; i++) { printf("%4d %7.3lf\n",i,x[i]); } }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -