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

📄 fft.c

📁 Fast Fourier Transform in C
💻 C
📖 第 1 页 / 共 2 页
字号:
/* file: fft.c		G. Moody	24 February 1988		   Last revised:	  10 June 2005-------------------------------------------------------------------------------fft: Fast Fourier transform of real dataCopyright (C) 1988-2005 George B. MoodyThis program is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the Free SoftwareFoundation; either version 2 of the License, or (at your option) any laterversion.This program is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR APARTICULAR PURPOSE.  See the GNU General Public License for more details.You should have received a copy of the GNU General Public License along withthis program; if not, write to the Free Software Foundation, Inc., 59 TemplePlace - Suite 330, Boston, MA 02111-1307, USA.You may contact the author by e-mail (george@mit.edu) or postal mail(MIT Room E25-505A, Cambridge, MA 02139 USA).  For updates to this software,please visit PhysioNet (http://www.physionet.org/)._______________________________________________________________________________   The default input to this program is a text file containing a uniformly sampledtime series, presented as a column of numbers.  The default standard output isthe magnitude of the discrete Fourier transform of the input series, normalizedby the length of the FFT.The functions `realft' and `four1' are based on those in Press, W.H., et al.,Numerical Recipes in C: the Art of Scientific Computing (Cambridge Univ. Press,1989;  2nd ed., 1992).*/#include <stdio.h>#include <math.h>#ifdef __STDC__#include <stdlib.h>#elseextern void exit();#endif#ifndef BSD# include <string.h>#else           /* for Berkeley UNIX only */# include <strings.h># define strchr index#endif#define	LEN	16384		/* maximum points in FFT */#ifdef i386#define strcasecmp strcmp#endif#define PI	M_PI	/* pi to machine precision, defined in math.h */#define TWOPI	(2.0*PI)void four1();void realft();double wsum;/* See Oppenheim & Schafer, Digital Signal Processing, p. 241 (1st ed.) */double win_bartlett(j, n)int j, n;{    double a = 2.0/(n-1), w;    if ((w = j*a) > 1.0) w = 2.0 - w;    wsum += w;    return (w);}/* See Oppenheim & Schafer, Digital Signal Processing, p. 242 (1st ed.) */double win_blackman(j, n)int j, n;{    double a = 2.0*PI/(n-1), w;    w = 0.42 - 0.5*cos(a*j) + 0.08*cos(2*a*j);    wsum += w;    return (w);}/* See Harris, F.J., "On the use of windows for harmonic analysis with the   discrete Fourier transform", Proc. IEEE, Jan. 1978 */double win_blackman_harris(j, n)int j, n;{    double a = 2.0*PI/(n-1), w;    w = 0.35875 - 0.48829*cos(a*j) + 0.14128*cos(2*a*j) - 0.01168*cos(3*a*j);    wsum += w;    return (w);}/* See Oppenheim & Schafer, Digital Signal Processing, p. 242 (1st ed.) */double win_hamming(j, n)int j, n;{    double a = 2.0*PI/(n-1), w;    w = 0.54 - 0.46*cos(a*j);    wsum += w;    return (w);}/* See Oppenheim & Schafer, Digital Signal Processing, p. 242 (1st ed.)   The second edition of Numerical Recipes calls this the "Hann" window. */double win_hanning(j, n)int j, n;{    double a = 2.0*PI/(n-1), w;    w = 0.5 - 0.5*cos(a*j);    wsum += w;    return (w);}/* See Press, Flannery, Teukolsky, & Vetterling, Numerical Recipes in C,   p. 442 (1st ed.) */double win_parzen(j, n)int j, n;{    double a = (n-1)/2.0, w;    if ((w = (j-a)/(a+1)) > 0.0) w = 1 - w;    else w = 1 + w;    wsum += w;    return (w);}/* See any of the above references. */double win_square(j, n)int j, n;{    wsum += 1.0;    return (1.0);}/* See Press, Flannery, Teukolsky, & Vetterling, Numerical Recipes in C,   p. 442 (1st ed.) or p. 554 (2nd ed.) */double win_welch(j, n)int j, n;{    double a = (n-1)/2.0, w;    w = (j-a)/(a+1);    w = 1 - w*w;    wsum += w;    return (w);}char *pname;double rsum;FILE *ifile;int m, n;int cflag;int decimation = 1;int iflag;int fflag;int len = LEN;int nflag;int Nflag;int nchunks;int pflag;int Pflag;int smooth = 1;int wflag;int zflag;static float *c;double freq, fstep, norm, rmean, (*window)();main(argc, argv)int argc;char *argv[];{    int i;    char *prog_name();    double atof();    void help();    pname = prog_name(argv[0]);    if (--argc < 1) {	help();	exit(1);    }    else if (strcmp(argv[argc], "-") == 0)	ifile = stdin;		/* read data from standard input */    else if ((ifile = fopen(argv[argc], "rt")) == NULL) {	fprintf(stderr, "%s: can't open %s\n", pname, argv[argc]);	exit(2);    }    for (i = 1; i < argc; i++) {	if (*argv[i] == '-') switch (*(argv[i]+1)) {	  case 'c':	/* print complex FFT (rectangular form) */	    cflag = 1;	    break;	  case 'f':	/* print frequencies */	    if (++i >= argc) {		fprintf(stderr, "%s: sampling frequency must follow -f\n",			pname);		exit(1);	    }	    freq = atof(argv[i]);	    fflag = 1;	    break;	  case 'h':	/* print help and exit */	    help();	    exit(0);	    break;	  case 'i':	/* calculate inverse FFT from `fft -c' format input */	    if (argc > 2) {		fprintf(stderr, "%s: no other option may be used with -i\n",			pname);		exit(1);	    }	    iflag = 1;	    break;	  case 'I':	/* calculate inverse FFT from `fft -p' format input */	    if (argc > 2) {		fprintf(stderr, "%s: no other option may be used with -I\n",			pname);		exit(1);	    }	    iflag = -1;	    break;	  case 'l':	/* perform up to n-point transforms */	    if (++i >= argc) {		fprintf(stderr, "%s: transform size must follow -l\n", pname);		exit(1);	    }	    len = atoi(argv[i]);	    break;	  case 'n':	/* process in overlapping n-point chunks, output avg */	    if (++i >= argc) {		fprintf(stderr, "%s: chunk size must follow -n\n", pname);		exit(1);	    }	    nflag = atoi(argv[i]);	    break;	  case 'N':	/* process in overlapping n-point chunks, output raw */	    if (++i >= argc) {		fprintf(stderr, "%s: chunk size must follow -N\n", pname);		exit(1);	    }	    Nflag = atoi(argv[i]);	    break;	  case 'p':	/* print phases (polar form) */	    pflag = 1;	    break;	  case 'P':	/* print power spectrum (squared magnitudes) */	    Pflag = 1;	    break;	  case 's':	/* smooth spectrum */	    if (++i >= argc || ((smooth=atoi(argv[i])) < 2) || smooth > 1024) {		fprintf(stderr, "%s: smoothing parameter must follow -s\n",			pname);		exit(1);	    }	    break;	  case 'S':	/* smooth and decimate spectrum */	    if (++i >= argc || ((smooth=atoi(argv[i])) < 2) || smooth > 1024) {		fprintf(stderr, "%s: smoothing parameter must follow -s\n",			pname);		exit(1);	    }	    decimation = smooth;	    break;	  case 'w':	/* apply windowing function to input */	    if (++i >= argc) {		fprintf(stderr, "%s: window type must follow -w\n",			pname);		exit(1);	    }	    if (strcasecmp(argv[i], "Bartlett") == 0)		window = win_bartlett;	    else if (strcasecmp(argv[i], "Blackman") == 0)		window = win_blackman;	    else if (strcasecmp(argv[i], "Blackman-Harris") == 0)		window = win_blackman_harris;	    else if (strcasecmp(argv[i], "Hamming") == 0)		window = win_hamming;	    /* Numerical Recipes 2nd ed. calls Hanning window "Hann window" */	    else if (strcasecmp(argv[i], "Hann") == 0)		window = win_hanning;	    else if (strcasecmp(argv[i], "Hanning") == 0)		window = win_hanning;	    else if (strcasecmp(argv[i], "Parzen") == 0)		window = win_parzen;	    else if (strcasecmp(argv[i], "Square") == 0 ||		     strcasecmp(argv[i], "Rectangular") == 0 ||		     strcasecmp(argv[i], "Dirichlet") == 0)		window = win_square;	    else if (strcasecmp(argv[i], "Welch") == 0)		window = win_welch;	    else {		fprintf(stderr, "%s: unrecognized window type %s\n",			pname, argv[i]);		exit(1);	    }	    wflag = 1;	    break;	  case 'z':	/* zero-mean the input */	    zflag = 1;	    break;	  case 'Z':	/* zero-mean and detrend the input */	    zflag = 2;	    break;	  default:	    fprintf(stderr, "%s: unrecognized option %s ignored\n",		    pname, argv[i]);	    break;	}    }    if (cflag) {	if (fflag) {	    fprintf(stderr, "%s: -c and -f are incompatible\n", pname);	    exit(1);	}	if (pflag) {	    fprintf(stderr, "%s: -c and -p are incompatible\n", pname);	    exit(1);	}	if (Pflag) {	    fprintf(stderr, "%s: -c and -P are incompatible\n", pname);	    exit(1);	}    }    if (nflag & pflag & Pflag) {	fprintf(stderr, "%s: -n, -p, and -P are incompatible\n", pname);	exit(1);    }    if (Nflag) {	if (nflag) {	    fprintf(stderr, "%s: -n and -N are incompatible\n", pname);	    exit(1);	}	else	    nflag = Nflag;    }    if (smooth > 1) {        if (cflag) {	    fprintf(stderr, "%s: -c and -s or -S are incompatible\n", pname);	    exit(1);	}        if (pflag) {	    fprintf(stderr, "%s: -p and -s or -S are incompatible\n", pname);	    exit(1);	}    }    /* Make sure that len is a power of two. */    if (len < 1) len = 1;    if (len < LEN) {	for (m = LEN; m >= len; m >>= 1)	    ;	m <<= 1;    }    else {	for (m = LEN; m < len; m <<= 1)	    ;    }    len = m;    if ((c = (float *)calloc(len, sizeof(float))) == NULL) {	fprintf(stderr, "%s: insufficient memory\n", pname);	exit(2);    }

⌨️ 快捷键说明

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