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

📄 rtfft.c

📁 FFT FUNCTION "C" SOURCE CODE
💻 C
📖 第 1 页 / 共 2 页
字号:
				{
					c2 = c1;
					if (nt == 1)
					{
						c1 = c1 * ck + s1 * sk;
						s1 = s1 * ck - c2 * sk;
					}
					else
					{
						c1 = (c1 - s1) * sq;
						s1 = (s1 + c2) * sq;
					}
					kb = kb + k4;
					if (kb <= kn)
						goto l1;
					else
						break;
				}
				if (nt == -1)
				{
					k = 2;
					continue;
				}
				if (cc[j] <= indx)
				{
					indx = indx - cc[j];
					j--;
					if (cc[j] <= indx)
					{
						indx = indx - cc[j];
						j--;
						k = k + 2;
					}
					else
					{
						indx = cc[j] + indx;
						j = mk;
					}
				}
				else
				{
					indx = cc[j] + indx;
					j = mk;
				}
				if (j < mk)
					continue;
				k = 0;
				nt = 3;
				kb = kb + k4;
				if (kb > kn)
					break;
			}
			while (1);
		}
		k = (m / 2) * 2;
		if (k != m)
		{
			k2 = kn;
			k0 = j = kn - cc[k];

			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 (k2 > j);
		}
	}
	while (kn < n);
	free (cc);
}

/**************************************************************************/
void rtreorder ( realtype *x, realtype *y, int n, int m, int ks, int reel)
{
	int	i, j, indx, k, kk, kb, k2, ku, lim, p;
	realtype  temp;

	int	*cc, *lst;

	cc =  (int far *)calloc (m + 1, sizeof (int));
	lst =  (int far *)calloc (m + 1, sizeof (int));
	
	cc [m] = ks;
	for (k = m; k > 0; k--)
		cc [k-1] = cc [k] / 2;
	p = j = m - 1;
	i = kb = 0;
	if (reel)
	{
		ku = n - 2;
		for (k = 0; k <= ku; k += 2)
		{
			temp = x [k + 1];
			x [k + 1] = y [k];
			y [k] = temp;
		}
	}
	else
		m--;
	lim = (m + 2) / 2;
	if (p > 0)
	do
	{
		ku = k2 = cc [j] + kb;
		indx = cc [m - j];
		kk = kb + indx;

		do
		{
			 k = kk + indx;
   	   		 do
			 {
		         temp = x [kk];
				  x [kk] = x [k2];
				  x [k2] = temp;
        		  temp = y [kk];
				  y [kk] = y [k2];
				  y [k2] = temp;
				  kk++;
				  k2++;
			 }
			 while (kk < k);

			 kk = kk + indx;
			 k2 = k2 + indx;
		}
		while (kk < ku);

		if (j > lim)
		{
			j--, i++;
			lst [i] = j;
			continue;
		}
		kb = k2;
		if (i > 0)
		{
			j = lst [i];
			i--;
			continue;
		}
		if (kb < n)
			j = p;
		else
			break;
    }
	while (1);

	free (cc);
	free (lst);
}

/**************************************************************************/

void rttrans (realtype *x, realtype *y, int n, int eval)
{
	int		  k, nk, nn;
	realtype  x1, ab, ba, y1, re, im, ck, sk, dc, ds, r;

	nn = n / 2;
	r = (realtype) 3.14159265359 / n;
	ds = (realtype) sin (r);
	r = (realtype) 2.0 * sin (0.5 * r);
	r = - r * r;
	dc = (realtype) -0.5 * r;
	ck = (realtype) 1.0;
	sk = (realtype) 0.0;

	if (!eval)
	{
		x[n] = x[0]; y [n] = y [0];
	}
	for (k = 0; k <= nn; k++)
	{
		nk = n - k;
		x1 = x[k] + x[nk];
		ab = x[k] - x[nk];
		ba = y[k] + y[nk];
		y1 = y[k] - y[nk];

		re = ck * ba + sk * ab;
		im = sk * ba - ck * ab;
		y [nk] = im - y1;
		y [k] = im + y1;
		x [nk] = x1 - re;
		x [k] = x1 + re;
		dc = r * ck + dc;
		ck = ck + dc;
		ds = r * sk + ds;
		sk = sk + ds;
	}
}

/**************************************************************************/

void rtfftcalc(realtype *xreal, realtype *yimag, int numdat)
{

   rtfft(xreal, yimag, numdat, 0);
}

void rtfftinvcalc(realtype *xreal, realtype *yimag, int numdat)
{

   rtfft(xreal, yimag, numdat, 1);
}

realtype rtsquareandsum (realtype a, realtype b)
{
   realtype fret;

   fret = a * a + b * b;
   return(fret);
}

void rtpowerspectrumcalc(realtype *xreal, realtype *yimag,
	int numdat, realtype delta)
{
	realtype timespan, normal, n;
	int i;

	n = numdat;
	normal =  (realtype) 1.0 / (n * n);
	rtfft (xreal, yimag, numdat, 0);
	xreal[0] = rtsquareandsum (xreal[0], yimag[0]) * normal;

	for (i = 1; i <= (numdat / 2) - 1; i++)
	{
		xreal[i] = normal * (rtsquareandsum(xreal[i], yimag[i]) +
		rtsquareandsum (xreal[numdat - i], yimag[numdat - i]));
	}
	i = numdat / 2;
	xreal[i] = rtsquareandsum(xreal[i], yimag[i]) * normal;
	timespan = (realtype) ((1.0*numdat) * delta);
	for (i = 0; i <= (numdat/2); i++)
	{
		yimag[i] = (realtype) (1.0*i) / timespan;
	}
}

/*--------------------------------------------------------------*/
/* Calculates the FFT magnitude associated with a given harmonic index. */
realtype rtfftmagnitude(realtype *xr, realtype *yi, int n, int i)
{
	realtype result, nr, rr, ii;

	nr = (realtype) n;
	if (i > n/2)
		result = (realtype) 0;
	else
	if (i == 0)
		result = sqrt(xr[0] * xr[0] + yi[0] * yi[0]) / nr;
	else
	{
		rr = fabs(xr[i]) + fabs(xr[n-i]);
		ii = fabs(yi[i]) + fabs(yi[n-i]);
		result =  sqrt(rr * rr + ii * ii) / nr;
	}
	return( result);
}

/*--------------------------------------------------------------*/
/* Calculates the FFT phase associated with a given harmonic index. */
realtype rtfftphase (realtype *xr, realtype *yi, int i)
{
	realtype result;

	result = atan2 (yi[i], xr[i]);
	return (result);
}

/*--------------------------------------------------------------*/
/* Calculates the FFT frequence associated with a given harmonic index
and sampling frequency. */
realtype rtfftfrequency (int n, realtype samplefreq, int i)
{
	realtype result;

	if (i <= n/2)
		result = samplefreq * (realtype)i/ (realtype)n;
	else
	{
		i = n - i;
		result = -samplefreq * (realtype)i/ (realtype)n;
	}
	return(result);
}



/* single pass of 2d fft done in row column order */
void rtfft2drccalc(matstruct *xreal,   /* input and output of real part of 2D array of data */
		 matstruct *yimag,   /* input and output of imaginary part of 2d data */
		 int c, int r,       /* number of columns, number of rows */
		 int flag)           /* 0 = forward fft, 1 = inverse fft */
{ int n,a,j;
  realtype *yvector, *xvector;
  if (r>=c) n=r; else n = c;
  xvector = rtgetmem(n); if (rtbadmem(xvector)) exit(0);
  yvector = rtgetmem(n); if (rtbadmem(yvector)) exit(0);
  for (j = 0; j <  r; j++)
  {
    for (a = 0; a < c; a++)
    {
      xvector[a] =rdmat(xreal,j,a);
      yvector[a] =rdmat(yimag,j,a);
    }
    if (flag == 0)
      rtfftcalc(xvector, yvector, c);
    else
      rtfftinvcalc(xvector, yvector, c);
    for (a = 0; a < c; a++)
    {
      wrmat(xreal,j,a,xvector[a]);
      wrmat(yimag,j,a,yvector[a]);
    }
  }
  free(xvector);
  free(yvector);
}

/* single pass of 2d fft done in column row order */
void rtfft2dcrcalc(matstruct *xreal,   /* input and output of real part of 2d array of data */
		   matstruct *yimag,   /* input and output of imaginary part of 2d data */
		 int c, int r,       /* number of columns, number of rows */
		 int flag)           /* 0 = forward fft, 1 = inverse fft */
{ int n,a,i;
  realtype *yvector, *xvector;

  if (r>=c) n=r; else n = c;
  xvector = rtgetmem(n); if (rtbadmem(xvector)) exit(0);
  yvector = rtgetmem(n); if (rtbadmem(yvector)) exit(0);
  for (i = 0; i < c; i++)
  {
    for (a = 0; a < r; a++)
    {
      xvector[a]=rdmat(xreal,a,i);
      yvector[a]=rdmat(yimag,a,i);
    }
    if (flag == 0)
      rtfftcalc(xvector, yvector, r);
    else
      rtfftinvcalc(xvector, yvector, r);
    for (a = 0; a < r; a++)
    {
      wrmat(xreal,a,i,xvector[a]);
      wrmat(yimag,a,i,yvector[a]);
    }
  }
  free(xvector);
  free(yvector);
}


void rtfft2dcalc (matstruct *xreal, matstruct *yimag,
			   int c, int r, int flag)
{
  if (flag)
  {
    rtfft2dcrcalc (xreal,yimag,c,r,flag);
    rtfft2drccalc (xreal,yimag,c,r,flag);
  }
  else
  {
    rtfft2drccalc (xreal,yimag,c,r,flag);
    rtfft2dcrcalc (xreal,yimag,c,r,flag);
  }
}

void rtfreqresponse (realtype *filtcoef, realtype *a, int n,int k )
{
	int i, j, m, n2;
	realtype att, am, q;

	q = (realtype) M_PI/k;
	am = (realtype) ((n+1)/2.0);
	m = (n+1) / 2;
	n2 = n / 2;
	for (j = 1; j <= k; j++)
	{
		att =  (realtype) 0.0;
		if (am == m)  att = filtcoef[m-1]/2.0;
		for (i = 1; i <= n2; i++)
			att = (realtype) (att + filtcoef[i-1] * cos(q*(am-i)*(j-1)));
		a[j-1] = (realtype) 2.0 * att;
	}
}

void rtfreqsamplefir (realtype *filtcoef, realtype fp, int n,
		int dc, int filttype, int win)
{
	int np, i, j, m, m1, n2;
	realtype lowbin, highbin, xt, am, q, *a;

	a = rtgetmem(n);  if (rtbadmem(a)) exit(0);

	m = (n+1) / 2;
	am = (realtype) ((n+1)/2.0);
	m1 = n / 2 + 1;
	q = (realtype) (2.0*M_PI/n);
	n2 = n / 2;
	if (dc == 1)
		np = (int) floor(n * fp + 0.5);
	else
		np = (int) floor(n * fp + 1.0);

	if (filttype == 1)
	{
		lowbin = (realtype) 0.0;
		highbin = (realtype) 1.0;
	}
	else
	{
		lowbin = (realtype) 1.0;
		highbin = (realtype) 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] = (realtype) (2.0 * xt / n);
			filtcoef[n-j] = filtcoef[j-1];
		}
	}
	else
	{
		for (j = 1; j <= m; j++)
		{
			xt = (realtype) 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] = (realtype) (2.0 * xt / n);
			filtcoef[n-j] = filtcoef[j-1];
		}
	}

	if (win > 0 ) rtwindowdata (filtcoef, n, win);
	free(a);
}


void rtconvolve (realtype *filtcoef, realtype *x, realtype *y,
	int filtlen, int alen)
{
	int n, m;
	realtype summ;

	for (n = 0; n <= (alen+filtlen-2); n++)
	{
		summ = (realtype) 0.0;
		for (m = 0; m <= filtlen-1; m++)
		{
			if ((n-m >= 0) && (n-m) <= (alen-1))
			{
				summ = summ + filtcoef[m] * x[n-m];
			}
		}
		y[n] = summ;
	}
}

⌨️ 快捷键说明

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