slight restructuring, clean up

This commit is contained in:
Mark Borgerding 2003-08-09 14:22:30 +00:00
parent db556661ed
commit b95e3ea18a
6 changed files with 24 additions and 193 deletions

View File

@ -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 kiss_fft_s: kiss_fft.h kiss_fft.c
gcc -Wall -O3 -o kiss_fft_s -DFIXED_POINT -DFFT_UTIL kiss_fft.c -lm 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 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 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: clean:
rm -f kiss_fft_s kiss_fft_f kiss_fft_d *~ fftin.dat fftout.dat \ rm -f kiss_fft_s kiss_fft_f kiss_fft_d *~ fftin.dat fftout.dat $(SPEEDTESTFILE)
freqpeak testsig tones
test: all test: all
./test.oct ./test.oct
speedtest: /dev/shm/junk kiss_fft_f speedf: kiss_fft_f $(SPEEDTESTFILE)
time ./kiss_fft_f < /dev/shm/junk > /dev/null time ./kiss_fft_f < $(SPEEDTESTFILE) > /dev/null
/dev/shm/junk: $(SPEEDTESTFILE):
dd if=/dev/urandom bs=8192 count=1000 of=/dev/shm/junk dd if=/dev/zero bs=8192 count=$(SPEEDTESTNSAMPS) of=$(SPEEDTESTFILE)
tarball: clean tarball: clean
tar -czf kiss_fft.tar.gz . tar -czf kiss_fft.tar.gz .

25
README
View File

@ -12,10 +12,14 @@ USAGE:
void * cfg = kiss_fft_alloc( nfft ,inverse_fft ); void * cfg = kiss_fft_alloc( nfft ,inverse_fft );
while ... 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 ); kiss_fft( cfg , cx_buf_in_out );
... ... // transformed
free(cfg); 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 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 two functions you'll need to use. Code definitions are in kiss_fft.c, along
@ -53,8 +57,8 @@ last bit of performance.
PERFORMANCE: PERFORMANCE:
(on Athlon XP 2100+, with gcc 2.96, optimization O3, float data type) (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. Kiss performed 1000 1024-pt ffts in 110 ms of cpu time (132ms real time).
Just for comparison, it took md5sum 160 ms to process the same amount of data For comparison, it took md5sum 160ms cputime to process the same amount of data
DO NOT: DO NOT:
... use Kiss if you need the absolute fastest fft in the world ... 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. addressing is corrected as the last step in the transform. No scaling is done.
LICENSE: LICENSE:
BSD, see COPYING for details. BSD, see COPYING for details. Basically, "free to use, give credit where due, no guarantees"
TODO: TODO:
Make the fixed point scaling and bit shifts more easily configurable. *) Add sample code for parallel ffts (stereo) packed into re,im components of time sequence.
Document/revisit the input/output fft scaling *) Add simple windowing function, e.g. Hamming : w(i)=.54-.46*cos(2pi*i/(n-1))
See if the fixed point code can be optimized a little without adding complexity. *) 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: AUTHOR:
Mark Borgerding Mark Borgerding
mark@borgerding.net Mark@Borgerding.net

View File

@ -1,87 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>
#include <stdio.h>
#include <math.h>
#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<NFFT;++k) {
cbuf[k].r = sampsin[2*k];
cbuf[k].i = sampsin[2*k+1];
}
if (removedc) {
float dcr=0,dci=0;
for (k=0;k<NFFT;++k){
dcr += cbuf[k].r;
dci += cbuf[k].i;
}
dcr /= NFFT;
dci /= NFFT;
for (k=0;k<NFFT;++k) {
cbuf[k].r -= dcr;
cbuf[k].i -= dci;
}
}
// perform the fft on the L+R packed buffer
kiss_fft( st , cbuf );
// get the half-symmetric FFTs for the Left and Right Channels
for (k=0;k<NFFT/2;++k) {
int k2 = (NFFT-k)%NFFT;
kiss_fft_cpx r,l;
r.r = (cbuf[k].r + cbuf[k2].r) * 0.5;
r.i = (cbuf[k].i - cbuf[k2].i) * 0.5;
l.r = (cbuf[k].i + cbuf[k2].i) * 0.5;
l.i = (cbuf[k].r - cbuf[k2].r) * 0.5;
rmag2[k] += r.r * r.r + r.i * r.i;
lmag2[k] += l.r * l.r + l.i * l.i;
}
++nbufs;
}
free(st);
for (k=0;k<NFFT/2;++k) {
if (rmag2[peakr] < rmag2[k])
peakr = k;
if (lmag2[peakl] < lmag2[k])
peakl = k;
}
printf("%d buffers\n",nbufs);
printf("peak frequency R:%.3fdB @ %.1f Hz\n",10*log10(rmag2[peakr]) , peakr*fs/NFFT);
printf(" L:%.3fdB @ %.1f Hz\n",10*log10(lmag2[peakl]) , peakl*fs/NFFT);
return 0;
}

View File

@ -140,7 +140,6 @@ void undo_bit_rev( kiss_fft_cpx * f, const int * swap_indices,int nswap)
} }
#define OPT1
// the heart of the fft // the heart of the fft
static static
void fft_work(int N,kiss_fft_cpx *f,const kiss_fft_cpx * twid,int twid_step) void fft_work(int N,kiss_fft_cpx *f,const kiss_fft_cpx * twid,int twid_step)
@ -149,23 +148,10 @@ void fft_work(int N,kiss_fft_cpx *f,const kiss_fft_cpx * twid,int twid_step)
{ // declare automatic variables in here to reduce stack usage { // declare automatic variables in here to reduce stack usage
int n; int n;
kiss_fft_cpx csum,cdiff; kiss_fft_cpx csum,cdiff;
#ifdef OPT1
const kiss_fft_cpx * cur_twid = twid+twid_step;
kiss_fft_cpx *f1 = f;
kiss_fft_cpx *f2 = f+N;
C_SUB( cdiff, *f1 , *f2 );
C_ADD( csum, *f1 , *f2 );
*f1++ = csum;
*f2++ = cdiff;
for (n=1;n<N;++n)
#else
const kiss_fft_cpx * cur_twid = twid; const kiss_fft_cpx * cur_twid = twid;
kiss_fft_cpx *f1 = f; kiss_fft_cpx *f1 = f;
kiss_fft_cpx *f2 = f+N; kiss_fft_cpx *f2 = f+N;
for (n=0;n<N;++n) for (n=0;n<N;++n)
#endif
{ {
C_ADD( csum, *f1 , *f2 ); C_ADD( csum, *f1 , *f2 );
C_SUB( cdiff, *f1 , *f2 ); C_SUB( cdiff, *f1 , *f2 );

View File

@ -1,32 +0,0 @@
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
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;
}

35
tones.c
View File

@ -1,35 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>
#include <stdio.h>
#include <math.h>
#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;
}