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

📄 fft.c.txt

📁 This program produces a Frequency Domain display from the Time Domain * data input using the Fast
💻 TXT
字号:
/* 
 *  fft.c 
 * 
 *  Unix Version 2.4 by Steve Sampson, Public Domain, September 1988 
 * 
 *  This program produces a Frequency Domain display from the Time Domain 
 *  data input; using the Fast Fourier Transform. 
 * 
 *  The Real data is generated by the in-phase (I) channel, and the 
 *  Imaginary data is produced by the quadrature-phase (Q) channel of 
 *  a Doppler Radar receiver.  The middle filter is zero Hz.  Closing 
 *  targets are displayed to the right, and Opening targets to the left. 
 * 
 *  Note: With Imaginary data set to zero the output is a mirror image. 
 * 
 *  Usage:  fft samples input output 
 *      1. samples is a variable power of two. 
 *      2. Input is (samples * sizeof(double)) characters. 
 *      3. Output is (samples * sizeof(double)) characters. 
 *      4. Standard error is help or debugging messages. 
 * 
 *  See also: readme.doc, pulse.c, and sine.c. 
 */  
  
/* Includes */  
  
#include <STDIO.H>   
#include <MALLOC.H>   
#include <MATH.H>   
  
/* Defines */  
  
#define TWO_PI  (2.0 * 3.14159265358979324) /* alias 360 deg */   
#define Chunk   (Samples * sizeof(double))   
  
#define sine(x)     Sine[(x)]   
#define cosine(x)   Sine[((x) + (Samples >> 2)) % Samples]   
  
/* Globals, Forward declarations */  
  
static int  Samples, Power;  
static double   *Real, *Imag, Maxn, magnitude();  
static void scale(), fft(), max_amp(), display(), err_report();  
  
static int  permute();  
static double   *Sine;  
static void build_trig();  
  
static FILE *Fpi, *Fpo;  
  
  
/* The program */  
  
main(argc, argv)  
int argc;  
char    **argv;  
{  
    if (argc != 4)  
        err_report(0);  
  
    Samples = abs(atoi(*++argv));  
    Power = log10((double)Samples) / log10(2.0);  
  
    /* Allocate memory for the variable arrays */  
  
    if ((Real = (double *)malloc(Chunk)) == NULL)  
        err_report(1);  
  
    if ((Imag = (double *)malloc(Chunk)) == NULL)  
        err_report(2);  
  
    if ((Sine = (double *)malloc(Chunk)) == NULL)  
        err_report(3);  
  
    /* open the data files */  
  
    if ((Fpi = fopen(*++argv, "r")) == NULL)  
        err_report(4);  
  
    if ((Fpo = fopen(*++argv, "w")) == NULL)  
        err_report(5);  
  
    /* read in the data from the input file */  
  
    fread(Real, sizeof(double), Samples, Fpi);  
    fread(Imag, sizeof(double), Samples, Fpi);  
    fclose(Fpi);  
  
    build_trig();  
    scale();  
    fft();  
    display();  
  
    /* write the frequency domain data to the standard output */  
  
    fwrite(Real, sizeof(double), Samples, Fpo);  
    fwrite(Imag, sizeof(double), Samples, Fpo);  
    fclose(Fpo);  
  
    /* free up memory and let's get back to our favorite shell */  
  
    free((char *)Real);  
    free((char *)Imag);  
    free((char *)Sine);  
  
    exit(0);  
}  
  
  
static void err_report(n)  
int n;  
{  
    switch (n)  {  
    case 0:  
        fprintf(stderr, "Usage: fft samples in_file out_file\n");  
        fprintf(stderr, "Where samples is a power of two\n");  
        break;  
    case 1:  
        fprintf(stderr, "fft: Out of memory getting real space\n");  
        break;  
    case 2:  
        fprintf(stderr, "fft: Out of memory getting imag space\n");  
        free((char *)Real);  
        break;  
    case 3:  
        fprintf(stderr, "fft: Out of memory getting sine space\n");  
        free((char *)Real);  
        free((char *)Imag);  
        break;  
    case 4:  
        fprintf(stderr,"fft: Unable to open data input file\n");  
        free((char *)Real);  
        free((char *)Imag);  
        free((char *)Sine);  
        break;  
    case 5:  
        fprintf(stderr,"fft: Unable to open data output file\n");  
        fclose(Fpi);  
        free((char *)Real);  
        free((char *)Imag);  
        free((char *)Sine);  
        break;  
    }  
  
    exit(1);  
}  
  
  
static void scale()  
{  
    register int    loop;  
  
    for (loop = 0; loop < Samples; loop++)  {  
        Real[loop] /= Samples;  
        Imag[loop] /= Samples;  
    }  
}  
  
  
static void fft()  
{  
    register int    loop, loop1, loop2;  
    unsigned    i1;         /* going to right shift this */  
    int     i2, i3, i4, y;  
    double      a1, a2, b1, b2, z1, z2;  
  
    i1 = Samples >> 1;  
    i2 = 1;  
  
    /* perform the butterfly's */  
  
    for (loop = 0; loop < Power; loop++)  {  
        i3 = 0;  
        i4 = i1;  
  
        for (loop1 = 0; loop1 < i2; loop1++)  {  
            y = permute(i3 / (int)i1);  
            z1 =  cosine(y);  
            z2 = -sine(y);  
  
            for (loop2 = i3; loop2 < i4; loop2++)  {  
  
                a1 = Real[loop2];  
                a2 = Imag[loop2];  
  
                b1  = z1*Real[loop2+i1] - z2*Imag[loop2+i1];  
                b2  = z2*Real[loop2+i1] + z1*Imag[loop2+i1];  
  
                Real[loop2] = a1 + b1;  
                Imag[loop2] = a2 + b2;  
  
                Real[loop2+i1] = a1 - b1;  
                Imag[loop2+i1] = a2 - b2;  
            }  
  
            i3 += (i1 << 1);  
            i4 += (i1 << 1);  
        }  
  
        i1 >>= 1;  
        i2 <<= 1;  
    }  
}  
  
/* 
 *  Display the frequency domain. 
 * 
 *  The filters are aranged so that DC is in the middle filter. 
 *  Thus -Doppler is on the left, +Doppler on the right. 
 */  
  
static void display()  
{  
    register int    loop, offset;  
    int     n, x;  
  
    max_amp();  
    n = Samples >> 1;  
  
    for (loop = n; loop < Samples; loop++)  {  
        x = (int)(magnitude(loop) * 59.0 / Maxn);  
        printf("%d\t|", loop - n);  
        offset = 0;  
        while (++offset <= x)  
            putchar('=');  
  
        putchar('\n');  
    }  
  
    for (loop = 0; loop < n; loop++)  {  
        x = (int)(magnitude(loop) * 59.0 / Maxn);  
        printf("%d\t|", loop + n);  
        offset = 0;  
        while (++offset <= x)  
            putchar('=');  
  
        putchar('\n');  
    }  
}  
  
/* 
 *  Find maximum amplitude 
 */  
  
static void max_amp()  
{  
    register int    loop;  
    double      mag;  
  
    Maxn = 0.0;  
    for (loop = 0; loop < Samples; loop++)  {  
        if ((mag = magnitude(loop)) > Maxn)  
            Maxn = mag;  
    }  
}  
  
/* 
 *  Calculate Power Magnitude 
 */  
  
static double magnitude(n)  
int n;  
{  
    n = permute(n);  
    return hypot(Real[n], Imag[n]);  
}  
  
/* 
 *  Bit reverse the number 
 * 
 *  Change 11100000b to 00000111b or vice-versa 
 */  
  
static int permute(index)  
int index;  
{  
    register int    loop;  
    unsigned    n1;  
    int     result;  
  
    n1 = Samples;  
    result = 0;  
  
    for (loop = 0; loop < Power; loop++)  {  
        n1 >>= 1;  
        if (index < n1)  
            continue;  
  
        /* Unix has a truncation problem with pow() */  
  
        result += (int)(pow(2.0, (double)loop) + .05);  
        index -= n1;  
    }  
  
    return result;  
}  
  
/* 
 *  Pre-compute the sine and cosine tables 
 */  
  
static void build_trig()  
{  
    register int    loop;  
    double      angle, increment;  
  
    angle = 0.0;  
    increment = TWO_PI / (double)Samples;  
  
    for (loop = 0; loop < Samples; loop++)  {  
        Sine[loop] = sin(angle);  
        angle += increment;  
    }  
}  
  
/* EOF */  

⌨️ 快捷键说明

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