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

📄 rtfft.c

📁 FFT FUNCTION "C" SOURCE CODE
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************/
/*							         */
/*   copyright (c) quinn-curtis, 1992                            */
/*							         */
/*   filename:  fft.c                                         */
/*   revision:  3.0                                              */
/*   date:      2/04/92                                          */
/*							         */
/*   description: -fourier analysis 	*/
/*							         */
/*****************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "rtstdhdr.h"

#ifndef RECTANG
#define RECTANG 0
#define PARZEN  1
#define HANNING 2
#define WELCH   3
#define HAMMING 4
#define EXACTB  5
#endif


void rtfft2 (realtype *aa, realtype *bb, int n, int m, int ks);
void rtrfft2 (realtype *aa, realtype *bb, int n, int m, int ks);
void rtreorder (realtype *aa, realtype *bb, int n, int m, int ks, int reel);
void rttrans (realtype *aa, realtype *bb, int n, int eval);

realtype *rtgetmem(int n)
{      realtype *xt;
       xt = (realtype *) calloc(n,sizeof(realtype));
       return(xt);
}

int rtbadmem(void *p)
{
       if (p==NULL){
	    printf("out of memory\n");
	    return(1);
       }
       else
	    return(0);

}

realtype rtparzen (realtype n, realtype j)
{
	realtype fret;

	fret = (realtype) 1.0 - fabs((j - 0.5 * (n - 1.0)) / (0.5 * (n - 1.0)));
	return(fret);
}


realtype rthanning (realtype n, realtype j)
{
	realtype fret;

	fret =  (realtype) 0.5 * (1.0 - cos(2.0 * M_PI * j / (n-1.0)));
	return(fret);
}

realtype rthamming (realtype n, realtype j)
{
	realtype fret;

	fret =  (realtype) 0.54 - 0.46 * cos(2.0 * M_PI * j / (n-1.0));
	return(fret);
}

realtype rtexactblackman (realtype n, realtype j)
{
	realtype fret;

	fret =  (realtype) 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);
}

realtype rtwelch (realtype n, realtype j)
{
	realtype fret;
	fret =  (realtype) (j - 0.5 * (n - 1.0)) / (0.5 * (n + 1.0));
	fret = (realtype) 1.0 - fret*fret;
	return(fret);
}

void rtwindowdata (realtype *x, int numdat, int window)
{
   int i;
   realtype multiplier;

   for ( i = 0; i < numdat; i++ )
   {
	  switch ( window )
	  {
		 case RECTANG:
			multiplier = (realtype) 1.0;
			break;
		 case PARZEN:
			multiplier = rtparzen (numdat, i);
			break;
		 case HANNING:
			multiplier = rthanning (numdat, i);
			break;
		 case WELCH:
			multiplier = rtwelch (numdat, i);
			break;
		 case HAMMING:
			multiplier = rthamming (numdat, i);
			break;
		 case EXACTB:
			multiplier = rtexactblackman (numdat, i);
			break;
		 default:
			multiplier =  (realtype) 1.0;
			break;
	  }
	  x[i] = multiplier * x[i];
   }
}

void rtwindowfftdata (realtype *xdata, realtype *ydata, int numdat, int window)
{
	rtwindowdata (xdata, numdat, window);
	rtwindowdata (ydata, numdat, window );
}



/**************************************************************************/
/* complex fourier transform
/* number of points n must be a power of 2
/**************************************************************************/
void rtfft (realtype *xr, realtype *yi, int n, int inverse)
{
	int nn, j;
	int		 m;
	realtype pp, qq;

	m = -1;
	nn = n;

	/* determine power of 2 */
	while (nn > 0)
	{
		nn = nn >> 1;
		m++;
	}

	rtfft2 (xr, yi, n, m, n);
	rtreorder (xr, yi, n, m, n, 0);
	if (inverse)
	{
		pp = (realtype) 1.0 / n;
		qq = -pp;
		for (j = 0; j < n; j++)
		{
			xr [j] *= pp;
			yi [j] *= qq;
		}
	}
	else
	{
		for (j = 0; j < n; j++)
			yi [j] = -yi[j];
	}
}

/**************************************************************************/
/* 	real array is passed in x, cos and sin coefficients are returned in
/*  x and sinc
/**************************************************************************/
void rtrealfft ( realtype *x, realtype *sinc, int n, int inverse)
{
	int 	 nn, j;
	int		 m;
	realtype pp;

	m = -1;
	nn = n / 2;

	/* determine power of 2 */
	while (nn > 0)
	{
		nn = nn >> 1;
		m++;
	}
	nn = n / 2;

	if (inverse)
	{
		pp = (realtype) 0.5 / nn;
		rttrans (x, sinc, nn, 1);
		rtfft2 (x, sinc, nn, m, nn);
		for (j = 0; j < nn; j++)
		{
			x [j] *= pp;
			sinc [j] *= -pp;
		}
		rtreorder (x, sinc, nn, m, nn, 1);
		for (j = 0; j < nn; j++)		/* combine */
			x [j + nn] = sinc [j];
	}
	else
	{
		for (j = 0; j < nn; j++)		/* split array in 2 */
			sinc [j] = x [j + nn];

		rtreorder (x, sinc, nn, m, nn, 1);
		rtrfft2 (x, sinc, nn, m, 1);
		for (j = 0; j < nn; j++)
		{
			x [j] *= 0.5;
			sinc [j] *= 0.5;
		}
		rttrans (x, sinc, nn, 0);
		for (j = 0; j < nn; j++)
			sinc [j] = -sinc[j];

		for (j = 1; j < nn; j++)
		{
			x [j + nn] = x [nn - j];
			sinc [j + nn] = -sinc [nn - j];
		}
	}
}
/**************************************************************************/
/* fft for one variable of dimension n = 2^m
/**************************************************************************/
void rtfft2 (realtype *x, realtype *y, int n, int m, int ks)
{
	int  	   indx, k0, k1, k2, k3, span, j, k, kb, kn, mm, mk;
	realtype	rad, c1, c2, c3, s1, s2, s3, ck, sk, sq;
	realtype	x0, x1, x2, x3, y0, y1, y2, y3;
	int	*cc;

	cc = (int far *) calloc (m + 1, sizeof (int));

	sq = (realtype) 0.707106781187;
	sk = (realtype) 0.382683432366;
	ck = (realtype) 0.92387953251;

	cc[m] = ks;
	mm = (m / 2) * 2;
	kn = 0;
	for (k = m - 1; k >= 0; k--)
		cc[k] = cc[k+1] / 2;
	rad = (realtype) 6.28318530718 / (cc[0] * ks);
	mk = m - 5;

	do
	{
		kb = kn;
		kn = kn + ks;

		if (mm != m)
		{
			k2 = kn;
			k0 = cc[mm] + kb;
			do
			{
				k2--;
				k0--;
				x0 = x [k2];
				y0 = y [k2];
				x[k2] = x[k0] - x0;
				x[k0] = x[k0] + x0;
				y[k2] = y[k0] - y0;
				y[k0] = y[k0] + y0;
			}  while (k0 > kb);
		}

		c1 = (realtype) 1.0, s1 = (realtype) 0.0;
		indx = 0;
		k = mm - 2;
		j = 3;

		if (k >= 0)
			goto l2;
		else
			if (kn < n)
				continue;
			else
				break;

l1:	   	while (1)
		{
			if (cc[j] <= indx)
			{
				indx = indx - cc[j];
				j--;
				if (cc[j] <= indx)
				{
					indx = indx - cc[j];
					j--;
					k += 2;
				}
			}
			else
				break;
		}

		indx = cc[j] + indx;
		j = 3;

l2:		span = cc[k];
		if (indx != 0)
		{
			c2 = indx * span * rad;
			c1 = (realtype) cos (c2);
			s1 = (realtype) sin (c2);
l5:
			c2 = c1 * c1 - s1 * s1;
			s2 = (realtype) 2.0 * s1 * c1;
			c3 = c2 * c1 - s2 * s1;
			s3 = c2 * s1 + s2* c1;
		}
		for (k0 = kb + span - 1; k0 >= kb; k0--)
		{
			k1 = k0 + span;
			k2 = k1 + span;
			k3 = k2 + span;
			x0 = x[k0];
			y0 = y [k0];
			if (s1 == 0)
			{
				x1 = x[k1]; y1 = y [k1];
				x2 = x[k2]; y2 = y [k2];
				x3 = x[k3]; y3 = y [k3];
			}
			else
			{
				x1 = x[k1] * c1 - y [k1] * s1;
				y1 = x[k1] * s1 + y [k1] * c1;
				x2 = x[k2] * c2 - y [k2] * s2;
				y2 = x[k2] * s2 + y [k2] * c2;
				x3 = x[k3] * c3 - y [k3] * s3;
				y3 = x[k3] * s3 + y [k3] * c3;
			}
			x [k0] = x0 + x2 + x1 + x3; y[k0] = y0 + y2 + y1 + y3;
			x [k1] = x0 + x2 - x1 - x3; y[k1] = y0 + y2 - y1 - y3;
			x [k2] = x0 - x2 - y1 + y3; y[k2] = y0 - y2 + x1 - x3;
			x [k3] = x0 - x2 + y1 - y3; y[k3] = y0 - y2 - x1 + x3;
		}
		if (k > 0)
		{
			k = k - 2;
			goto l2;
		}
		kb = k3 + span;
		if (kb < kn)
		{
			if (j == 0)
			{
				k = 2;
				j = mk;
				goto l1;
			}
			j--;
			c2 = c1;
			if (j == 1)
			{
				c1 = c1 * ck + s1 * sk;
				s1 = s1 * ck - c2 * sk;
			}
			else
			{
				c1 = (c1 - s1) * sq;
				s1 = (s1 + c2) * sq;
			}
			goto	l5;
		}
	}
	while (kn < n);

	free (cc);
}
/**************************************************************************/

void rtrfft2 ( realtype *x, realtype *y, int n, int m, int ks)
{
	int  		k0, k1, k2, k3, k4, span, j, indx, k, kb, nt, kn, mk;
	realtype	rad, c1, c2, c3, s1, s2, s3, ck, sk, sq;
	realtype	x0, x1, x2, x3, y0, y1, y2, y3, re, im;
	int	*cc;

	cc =  (int far *)calloc (m + 1, sizeof (int));

	sq = (realtype) 0.707106781187;
	sk = (realtype) 0.382683432366;
	ck = (realtype) 0.92387953251;

	cc[0] = ks;
	kn = 0;
	k4 = 4 * ks;
	mk = m - 4;

	for (k = 1; k <= m; k++)
	{
		ks = ks + ks;
		cc[k] = ks;
	}
	rad = (realtype) 3.14159265359 / (cc[0] * ks);

	do
	{
		kb = kn + 4;
		kn = kn + ks;
		if (m != 1)
		{
			k = indx = 0;
			j = mk;
			nt = 3;
			c1 = (realtype) 1.0, s1 = (realtype) 0.0;

			do
			{
			   span = cc[k];
				if (indx != 0)
				{
					c2 = indx * span * rad;
					c1 = (realtype) cos (c2);
					s1 = (realtype) sin (c2);
l1:
					c2 = c1 * c1 - s1 * s1;
					s2 = (realtype) 2.0 * s1 * c1;
					c3 = c2 * c1 - s2 * s1;
					s3 = c2 * s1 + s2 * c1;
				}
				else
					s1 = 0;
				k3 = kb - span;
				do
				{
		           k2 = k3 - span;
					k1 = k2 - span;
					k0 = k1 - span;
		
					x0 = x[k0]; y0 = y [k0];
					x1 = x[k1]; y1 = y [k1];
					x2 = x[k2]; y2 = y [k2];
					x3 = x[k3]; y3 = y [k3];

					x [k0] = x0 + x2 + x1 + x3; y[k0] = y0 + y2 + y1 + y3;
					if (s1 == 0)
					{
						x [k1] = x0 - x1 - y2 + y3;
						y[k1] = y0 - y1 + x2 - x3;
						x [k2] = x0 + x1 - x2 - x3;
			y[k2] = y0 + y1 - y2 - y3;
						x [k3] = x0 - x1 + y2 - y3;
                        y[k3] = y0 - y1 - x2 + x3;
					}
					else
					{
						re = x0 - x1 - y2 + y3;
						im = y0 - y1 + x2 - x3;
						x [k1] = re * c1 - im * s1;
                        y[k1] = re * s1 + im * c1;
						re = x0 + x1 - x2 - x3;
						im = y0 + y1 - y2 - y3;
						x [k2] = re * c2 - im * s2;
						y[k2] = re * s2 + im * c2;
						re = x0 - x1 + y2 - y3;
						im = y0 - y1 - x2 + x3;
						x [k3] = re * c3 - im * s3;
                        y[k3] = re * s3 + im * c3;
					}
					k3++;
		      		}
				while (k3 < kb);

				nt--;
				if (nt >= 0)

⌨️ 快捷键说明

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