Category : C Source Code
Archive   : FASTFFT.ZIP
Filename : FFT.C

 
Output of file : FFT.C contained in archive : FASTFFT.ZIP

/*************************************************************
** FAST FFT BY TABLE LOOKUP **
** This program will allow you to create a very fast FFT **
** It will create an assembly lookup table (assembly source)**
** and will also let you create sample wave forms to test **
** how well the FFT selects a given freq. **
** **
** This program will create a file FFTDAT in default DIR.**
** **
** Copyright (c) 1988 Chuck Hoelzen, Riverton WY 82501 **
** bbs 1200/2400,8,N,1 (307) 856-0174 **
** All rights reserved, Public domain software. **
**************************************************************

written using DeSmet C */

#include "bstdio.h"
#include "math.h"
/***********************************************
The 8 freq below are for a DTMF (telephone) decoder.
You may change thise to anything you like*/
int freq[8]={697,770,852,941,1209,1336,1477,1633};

int sample[512];
float wave[512][8][2],level;
int wavei[512][8][2];
int samples,i,fr,frq;
FILE *f1;
char disk;
float fft[8][2];

main()
{
printf("**************************************************************\n");
printf("** FAST FFT BY TABLE LOOKUP **\n");
printf("** This program will allow you to create a very fast FFT **\n");
printf("** It will create an assembly lookup table (assembly source)**\n");
printf("** and will also let you create sample wave forms to test **\n");
printf("** how well the FFT selects a given freq. **\n");
printf("** **\n");
printf("** This program will create a file FFTDAT in default DIR.**\n");
printf("** **\n");
printf("** Copyright (c) 1988 Chuck Hoelzen, Riverton WY 82501 **\n");
printf("** bbs 1200/2400,8,N,1 (307) 856-0174 **\n");
printf("** All rights reserved, Public domain software. **\n");
printf("**************************************************************\n");
printf("\n\nHow many samples? (1 to 512 try 32 or 64 first)");
scanf("%d",&samples);
printf("At what frequency?");
scanf("%d%",&frq);
printf("save to disk? (Y)");
disk=getyn('Y');
printf("\nin integer format for assembler (Y)?");
char int_format=getyn('Y');

if(disk=='Y') f1=fopen("fftdat","w");
fprintf(f1,";**************************************************\n");
fprintf(f1,";** DTMF 2 of 8 decoder lookup table **\n");
fprintf(f1,";** created by program written and **\n");
fprintf(f1,";** (c) by Chuck Hoelzen, Riverton WY **\n");
fprintf(f1,";**************************************************\n");
fprintf(f1,";FFT componants for %d samples at %dHz\n",samples,frq);
fprintf(f1,";simply multiply the input wave form by the REAL and\n");
fprintf(f1,"; sum to each of the 8 freq.,\n");
fprintf(f1,"; mult the IMAG and subtract from the sum of each of the 8 freq.\n");
fprintf(f1,"; for exact FFT=2*sqrt((REAL_sum/127)^2+(IMAG_sum/127)^2)\n");
fprintf(f1,"; to calculate the phase=ATN(REAL_sum/IMAG_sum)\n");
fprintf(f1,";for fast freq search FFTs=abs(REAL)+abs(IMAG)\n;\n");
fprintf(f1,"; real imag sample freq\n");
for(fr=0;fr<8;fr++)
{
float g;
int w1,w2;
g=2*3.14159*freq[fr]/frq;
for(i=0;i {
wave[i][fr][0]=cos(g*i)/samples;
wave[i][fr][1]=sin(g*i)/samples;
wavei[i][fr][0]=(float) wave[i][fr][0]*samples*127;
wavei[i][fr][1]=(float) wave[i][fr][1]*samples*127;
if(disk=='Y')
if(int_format=='Y')
fprintf(f1," DB %4d,%4d ;%03d, %04d \n",
wavei[i][fr][0],wavei[i][fr][1],i,freq[fr]);
else
fprintf(f1,"%d, %d, %9.3f, %9.3f\n",
i,freq[fr],wave[i][fr][0],wave[i][fr][1]);
else
printf("sample %d freq %d real %f imag %f\n",
i,freq[fr],wave[i][fr][0],wave[i][fr][1]);
}
}

if(disk=='Y') fclose(f1);
float amp,fin,w;
printf("\n\nNow lets test the system with a created input wave form.\n");
printf("To create the wave simply tell me what freq in Hz and it's\n");
printf("amplitude (0 to 1, over 1 will clip to +127 or -127).\n");
do
{
for(i=0;i sample[i]=0;
level=0.;
do
{
printf("\nInput wave freq? (-1 if none)");
scanf("%f",&fin);
if(fin>0.)
{
printf("\nInput wave amplitude? (0 to 1 is best)");
scanf("%f",&);
w=2*3.14159*fin/frq;
for(i=0;i {
sample[i]+=amp*sin(w*i)*127;
if(abs(sample[i])>127)
{
printf("clipping %5.2f%% ",abs(sample[i])/127);
sample[i]=sample[i]/abs(sample[i])*127;
}
printf("%4d %9.3f\n",sample[i],amp*sin(w*i));
}
}
}while(fin>0.);

/* now calculate the FFT from the sample data. This could be done on the
fly (summing one sample at a time)*/
float imag,real;
long reali,imagi,strip;
printf("\nFrequency products\n");
printf("FREQ REAL REAL_I IMAG IMAG_I\n");
for(fr=0;fr<8;fr++)
{
real=0.;
reali=0;
imag=0.;
imagi=0;
for(i=0;i {
real+=sample[i]*wave[i][fr][0];
imag-=sample[i]*wave[i][fr][1];
reali+=sample[i]*wavei[i][fr][0];
imagi-=sample[i]*wavei[i][fr][1];
}
printf("%d %9.2f %8ld %9.2f %8ld\n",freq[fr],real,reali,imag,imagi);
fft[fr][0]=2*sqrt(imag*imag+real*real)/127;
if(imagi<0) imagi*=-1;
if(reali<0) reali*=-1;
fft[fr][1]=imagi+reali;
level+=fft[fr][0];
}
level/=8;
char tag;
printf("\n FREQ APROX FFT RATIO FFT/AVERAGE SIGNAL\n");
for(fr=0;fr<8;fr++)
{
tag=' ';
if(fft[fr][0]>2*level) tag='*';
printf("FFT for %4d: %c %9.0f %9.3f %9.3f\n",freq[fr],tag,fft[fr][1],fft[fr][0],fft[fr][0]/level);
}
printf("\naverage %9.3f\nCreate another input wave (Y)?",level);
}while(getyn('Y')=='Y');
}
/* get 'Y' or 'N' or [return]*/
int getyn(def) char def;
{
int c;
do
{
c=getchar();
if(c=='\015') return(def);
c=toupper(c);
}while(c!='Y' && c!='N');
return(c);
}


  3 Responses to “Category : C Source Code
Archive   : FASTFFT.ZIP
Filename : FFT.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/