home *** CD-ROM | disk | FTP | other *** search
- # include <stdio.h>
- # include <stdlib.h>
- # include <math.h>
- # include "miscio.h"
-
-
- float Parzen(float n,float j)
- {
- float fret;
-
- fret = 1.0 - fabs((j - 0.5 * (n - 1.0)) / (0.5 * (n - 1.0)));
- return(fret);
- }
-
-
- float Hanning(float n,float j)
- {
- float fret;
-
- fret = 0.5 * (1.0 - cos(2.0 * M_PI * j / (n-1.0)));
- return(fret);
- }
-
- float Hamming(float n,float j)
- {
- float fret;
-
- fret = 0.54 - 0.46 * cos(2.0 * M_PI * j / (n-1.0));
- return(fret);
- }
-
- float ExactBlackman(float n,float j)
- {
- float fret;
-
- fret = 0.42 - 0.50 * cos(2.0 * M_PI * j /(n-1.0)) + 0.08 * cos(4.0 * M_PI * j / (n-1.0));
- return(fret);
- }
-
- float Welch(float n,float j)
- {
- float fret;
- fret = (j - 0.5 * (n - 1.0)) / (0.5 * (n + 1.0));
- fret = 1 - fret*fret;
- return(fret);
- }
-
- void WindowData(float *x,int numdat,int window)
- {
- int i;
- float multiplier;
-
- for ( i = 0; i <= numdat - 1; ++i ) {
- switch ( window ) {
- case 0:
- multiplier = 1.0;
- break;
- case 1:
- multiplier = Parzen(numdat,i);
- break;
- case 2:
- multiplier = Hanning(numdat,i);
- break;
- case 3:
- multiplier = Welch(numdat,i);
- break;
- case 4:
- multiplier = Hamming(numdat,i);
- break;
- case 5:
- multiplier = ExactBlackman(numdat,i);
- break;
- default:
- multiplier = 1.0;
- break;
- }
- x[i] = multiplier * x[i];
- }
- }
-
- void WindowFFTData(float *xdata, float *ydata, int numdat, int window)
- {
- WindowData(xdata,numdat, window);
- WindowData(xdata,numdat, window );
- }
-
-
- void FFT_swap(float *s1, float *s2)
- {
- float temp;
-
- temp = (*s1);
- (*s1) = (*s2);
- (*s2) = temp;
- }
-
- void fft(float *xreal, float *yimag, int numdat, int flag)
- {
- int maxpower, arg, q, cntr, pnt0, pnt1, i;
- int j, a, b, k, m;
- float sign, prodreal, prodimag, harm, x, y;
- float *cosary;
- float *sinary;
-
- cosary = (float *) calloc(numdat,sizeof(float));
- if (cosary == NULL)
- exit(1);
- sinary = (float *) calloc(numdat,sizeof(float));
- if (sinary == NULL)
- exit(1);
- j = 0;
- if ( flag != 0 ) {
- sign = 1.0;
- for ( i = 0; i <= numdat - 1; ++i ) {
- xreal[i] = xreal[i] / numdat;
- yimag[i] = yimag[i] / numdat;
- }
- }
- else {
- sign = -1.0;
- }
- for ( i = 0; i <= numdat - 2; ++i ) {
- if ( i < j ) {
- FFT_swap(&xreal[i],&xreal[j]);
- FFT_swap(&yimag[i],&yimag[j]);
- }
- k = numdat / 2;
- while ( k <= j ) {
- j = j - k;
- k = k / 2;
- }
- j = j + k;
- }
- maxpower = 0;
- i = numdat;
- while ( i != 1 ) {
- maxpower = maxpower + 1;
- i = i / 2;
- }
- harm = 2 * M_PI / numdat;
- for ( i = 0; i <= numdat - 1; ++i ) {
- sinary[i] = sign * sin(harm * i);
- cosary[i] = cos(harm * i);
- }
- a = 2;
- b = 1;
- for ( cntr = 1; cntr <= maxpower; ++cntr ) {
- pnt0 = numdat / a;
- pnt1 = 0;
- for ( k = 0; k <= b - 1; ++k ) {
- i = k;
- while ( i < numdat ) {
- arg = i + b;
- if ( k == 0 ) {
- prodreal = xreal[arg];
- prodimag = yimag[arg];
- }
- else {
- prodreal = xreal[arg] * cosary[pnt1] - yimag[arg] * sinary[pnt1];
- prodimag = xreal[arg] * sinary[pnt1] + yimag[arg] * cosary[pnt1];
- }
- xreal[arg] = xreal[i] - prodreal;
- yimag[arg] = yimag[i] - prodimag;
- xreal[i] = xreal[i] + prodreal;
- yimag[i] = yimag[i] + prodimag;
- i = i + a;
- }
- pnt1 = pnt1 + pnt0;
- }
- a = 2 * a;
- b = b * 2;
- }
- free(cosary);
- free(sinary);
- }
-
- void FFTCalc(float *xreal,float *yimag,int numdat)
- {
-
- fft(xreal,yimag,numdat,0);
- }
-
- void FFTInvCalc(float *xreal,float *yimag, int numdat)
- {
-
- fft(xreal,yimag,numdat,1);
- }
-
- float SquareAndSum(float a,float b)
- {
- float fret;
-
- fret = a*a+b*b;
- return(fret);
- }
-
- void PowerSpectrumCalc(float *xreal, float *yimag,int numdat,float delta)
- {
- float timespan;
- float normal;
- int i;
- float n;
- char c;
-
- n = numdat;
- normal = 1.0 / (n*n);
- fft(xreal,yimag,numdat,0);
- xreal[0] = SquareAndSum(xreal[0],yimag[0]) * normal;
-
- for ( i = 1; i <= (numdat / 2) - 1; ++i ) {
- xreal[i] = normal * (SquareAndSum(xreal[i],yimag[i]) +
- SquareAndSum(xreal[numdat - i],yimag[numdat - i]));
-
- }
- i = numdat / 2;
- xreal[i] = SquareAndSum(xreal[i],yimag[i]) * normal;
- timespan = (1.0*numdat) * delta;
- for ( i = 0; i <= (numdat/2); ++i ) {
- yimag[i] = (1.0*i) / timespan;
- }
- }
-
- void FFT2DCalc(float *xreal,float *yimag,
- int c,int r,int flag)
- {
- int a, b, i, j, jc;
- float *yVector;
- float *xVector;
-
- xVector = (float *) calloc(r,sizeof(float));
- if (xVector == NULL)
- exit(1);
- yVector = (float *) calloc(r,sizeof(float));
- if (yVector == NULL)
- exit(1);
- for ( j = 0; j <= r - 1; ++j ) {
- jc = j * c;
- for ( a = 0; a <= c - 1; ++a ) {
- xVector[a] = xreal[jc+a];
- yVector[a] = yimag[jc+a];
- }
- if ( flag == 0 )
- FFTCalc(xVector,yVector,c);
- else
- FFTInvCalc(xVector,yVector,c);
- for ( a = 0; a <= c - 1; ++a ) {
- xreal[jc+a] = xVector[a];
- yimag[jc+a] = yVector[a];
- }
- }
- for ( i = 0; i <= c - 1; ++i ) {
- for ( a = 0; a <= r - 1; ++a ) {
- xVector[a] = xreal[a*c+i];
- yVector[a] = yimag[a*c+i];
- }
- if ( flag == 0 )
- FFTCalc(xVector,yVector,r);
- else
- FFTInvCalc(xVector,yVector,r);
- for ( a = 0; a <= r - 1; ++a ) {
- xreal[a*c+i] = xVector[a];
- yimag[a*c+i] = yVector[a];
- }
- }
- free(xVector); free(yVector);
- }
-
- void FreqResponse(float *filtcoef, float *a, int n,int k )
- {
- int i,j,m,n2;
- float att,am,q;
-
- q = M_PI/k;
- am = (n+1)/2.0;
- m = (n+1) / 2;
- n2 = n / 2;
- for (j = 1; j <= k + 1; j++)
- {
- att = 0.0;
- if (am == m) att = filtcoef[m-1]/2.0;
- for (i = 1; i <= n2; i++)
- att = att + filtcoef[i-1] * cos(q*(am-i)*(j-1));
- a[j-1] = 2.0 * att;
- }
- }
-
- void FIRFreqSample(float *filtcoef,float fp,int n,
- int dc,int filtType, int win)
-
- {
- int np, i, j, m, m1, n2;
- float lowbin, highbin, xt, am, q;
- float *a;
-
- a = (float *) calloc(n,sizeof(float));
- if (a == NULL)
- exit(1);
- m = (n+1) / 2;
- am = (n+1)/2.0;
- m1 = n / 2 + 1;
- q = 2.0*M_PI/n;
- n2 = n / 2;
- if (dc == 1)
- np = floor(n * fp + 0.5);
- else
- np = floor(n * fp + 1.0);
-
- if (filtType == 1){
- lowbin = 0.0;
- highbin = 1.0;
- }
- else {
- lowbin = 1.0;
- highbin = 0.0;
- }
- for (j = 0; j <= np; j++)
- a[j] = lowbin;
-
- for (j = np+1; j <= m1; j++)
- a[j] = highbin;
-
- if (dc == 0) {
- for (j = 1; j <= m; j++){
- xt = a[1] / 2.0;
- for (i = 2; i <= m; i++)
- xt = xt + a[i]* cos(q * (am-j) * (i-1));
- filtcoef[j-1] = 2.0 * xt / n;
- filtcoef[n-j] = filtcoef[j-1];
- }
- }
- else{
- for (j = 1; j <= m; j++){
- xt = 0.0;
- for (i = 1; i <= n2; i++)
- xt = xt + a[i]* cos(q * (am-j) * (i-0.5));
- if (am != m) xt = xt + a[m]*cos(M_PI * (am-j))/2.0;
- filtcoef[j-1] = 2.0 * xt / n;
- filtcoef[n-j] = filtcoef[j-1];
- }
- }
- /* Modify filter by Hanning Window if win = 1 */
- if (win > 0 ) WindowData( filtcoef, n, win );
- free(a);
- }
-
-
- void Convolve(float *filtcoef,float *x,float *y, int filtLen,int aLen)
- {
- int n,m;
- float summ;
-
- for (n = 0; n <= aLen-1; n++){
- summ = 0.0;
- if (n >= filtLen-1) {
- for (m = 0; m <= filtLen-1; m++)
- summ = summ + filtcoef[m] * x[n-m];
- }
- y[n] = summ;
- }
- }
-