diff --git a/Makefile b/Makefile index de261c2..91acf21 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ +SPEEDTESTFILE=/dev/shm/kissfft_speedtest +SPEEDTESTNSAMPS=1000 -all: kiss_fft_s kiss_fft_f kiss_fft_d freqpeak tones testsig +all: kiss_fft_s kiss_fft_f kiss_fft_d kiss_fft_s: kiss_fft.h kiss_fft.c gcc -Wall -O3 -o kiss_fft_s -DFIXED_POINT -DFFT_UTIL kiss_fft.c -lm @@ -10,27 +12,17 @@ kiss_fft_f: kiss_fft.h kiss_fft.c kiss_fft_d: kiss_fft.h kiss_fft.c gcc -Wall -O3 -o kiss_fft_d -Dkiss_fft_scalar=double -DFFT_UTIL kiss_fft.c -lm -freqpeak: kiss_fft.h kiss_fft.c freqpeak.c - gcc -Wall -O3 -o freqpeak freqpeak.c kiss_fft.c -lm - -testsig: testsig.c - gcc -Wall -O3 -o testsig testsig.c -lm - -tones: tones.c - gcc -Wall -O3 -o tones tones.c -lm - clean: - rm -f kiss_fft_s kiss_fft_f kiss_fft_d *~ fftin.dat fftout.dat \ - freqpeak testsig tones + rm -f kiss_fft_s kiss_fft_f kiss_fft_d *~ fftin.dat fftout.dat $(SPEEDTESTFILE) test: all ./test.oct -speedtest: /dev/shm/junk kiss_fft_f - time ./kiss_fft_f < /dev/shm/junk > /dev/null +speedf: kiss_fft_f $(SPEEDTESTFILE) + time ./kiss_fft_f < $(SPEEDTESTFILE) > /dev/null -/dev/shm/junk: - dd if=/dev/urandom bs=8192 count=1000 of=/dev/shm/junk +$(SPEEDTESTFILE): + dd if=/dev/zero bs=8192 count=$(SPEEDTESTNSAMPS) of=$(SPEEDTESTFILE) tarball: clean tar -czf kiss_fft.tar.gz . diff --git a/README b/README index a7644a4..ef72078 100644 --- a/README +++ b/README @@ -12,10 +12,14 @@ USAGE: void * cfg = kiss_fft_alloc( nfft ,inverse_fft ); while ... - ... + ... // put kth sample in cx_buf_in_out[k].r and cx_buf_in_out[k].i kiss_fft( cfg , cx_buf_in_out ); - ... + ... // transformed free(cfg); + + Note: frequency-domain data is stored from dc to 2pi. + so cx_buf_in_out[0] is the dc bin of the FFT + and cx_buf_in_out[nfft/2] is the Nyquist bin Declarations are in "kiss_fft.h", along with a brief description of the two functions you'll need to use. Code definitions are in kiss_fft.c, along @@ -53,8 +57,8 @@ last bit of performance. PERFORMANCE: (on Athlon XP 2100+, with gcc 2.96, optimization O3, float data type) - Kiss performed 1000 1024-pt ffts in 136 ms. This translates to 7.5 Msamples/s. - Just for comparison, it took md5sum 160 ms to process the same amount of data + Kiss performed 1000 1024-pt ffts in 110 ms of cpu time (132ms real time). + For comparison, it took md5sum 160ms cputime to process the same amount of data DO NOT: ... use Kiss if you need the absolute fastest fft in the world @@ -67,13 +71,16 @@ UNDER THE HOOD: addressing is corrected as the last step in the transform. No scaling is done. LICENSE: - BSD, see COPYING for details. + BSD, see COPYING for details. Basically, "free to use, give credit where due, no guarantees" TODO: - Make the fixed point scaling and bit shifts more easily configurable. - Document/revisit the input/output fft scaling - See if the fixed point code can be optimized a little without adding complexity. + *) Add sample code for parallel ffts (stereo) packed into re,im components of time sequence. + *) Add simple windowing function, e.g. Hamming : w(i)=.54-.46*cos(2pi*i/(n-1)) + *) Could mixed-radix FFTs be made simple enough to stand by the KISS principle? + *) Make the fixed point scaling and bit shifts more easily configurable. + *) Document/revisit the input/output fft scaling + *) See if the fixed point code can be optimized a little without adding complexity. AUTHOR: Mark Borgerding - mark@borgerding.net + Mark@Borgerding.net diff --git a/freqpeak.c b/freqpeak.c deleted file mode 100644 index cd9e2ff..0000000 --- a/freqpeak.c +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "kiss_fft.h" - -#define NFFT 1024 -int main(int argc, char ** argv) -{ - int k; - void * st; - float fs=44100; - - short sampsin[2*NFFT]; - float lmag2[NFFT/2]; - float rmag2[NFFT/2]; - int peakr=0,peakl=0; - int removedc=1; - - kiss_fft_cpx cbuf[NFFT]; - int nbufs=0; - - st = kiss_fft_alloc(NFFT,0); - - memset( lmag2 , 0 , sizeof(lmag2) ); - memset( rmag2 , 0 , sizeof(rmag2) ); - - while ( fread( sampsin , sizeof(short) * 2*NFFT, 1 , stdin ) == 1 ) { - - //perform two ffts in parallel by packing the left&right channels into the real and imaginary - for (k=0;k -#include -#include - -int usage() -{ - fprintf(stderr,"usage:testsig nsamps\n"); - exit(1); - return 1; -} - -double randphase() -{ - return (double)rand()*2*3.14159/RAND_MAX; -} - -int main(int argc, char ** argv) -{ - float samps[2]; - int nsamps; - - if (argc != 2) - return usage(); - nsamps = atoi( argv[1] ); - - while (nsamps-- > 0) { - samps[0]=sin( randphase() ); - samps[1]=sin( randphase() ); - fwrite(samps,sizeof(samps),1,stdout); - } - return 0; -} diff --git a/tones.c b/tones.c deleted file mode 100644 index 43f9f89..0000000 --- a/tones.c +++ /dev/null @@ -1,35 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include "kiss_fft.h" - -#define PI 3.14159 - -int main(int argc, char ** argv) -{ - int k; - float fs=44100; - - float fr=1,fl=300; - - float th[2] = {0,0}; - float thinc[2] = {2*PI*fr/fs,2*PI*fl/fs }; - - while (1){ - for (k=0;k<2;++k){ - short s; - th[k] += thinc[k]; - if (th[k] > 2*PI){ - th[k] -= 2*PI; - } - s=(short)32767*cos( th[k] ); - fwrite(&s,sizeof(s),1,stdout); - } - } - - return 0; -}