diff --git a/kiss_fft.c b/kiss_fft.c index 4272e65..f9d0ce4 100644 --- a/kiss_fft.c +++ b/kiss_fft.c @@ -59,6 +59,8 @@ typedef struct { # define C_FIXDIV(c,div) /* NOOP */ #endif +#define C_ADD( res, a,b)\ + do { (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; }while(0) #define C_SUB( res, a,b)\ do { (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; }while(0) #define C_ADDTO( res , a)\ @@ -162,6 +164,59 @@ void bfly4( }while(--m); } +void bfly3( + kiss_fft_cpx * Fout, + int fstride, + const kiss_fft_state * st, + int m + ) +{ + kiss_fft_cpx *Fout0,*Fout1,*Fout2; + kiss_fft_cpx *tw1,*tw2; + kiss_fft_cpx * scratch = st->scratch; + kiss_fft_cpx * twiddles = st->twiddles; + kiss_fft_cpx epi3; + epi3 = twiddles[fstride*m]; + + Fout0=Fout; + Fout1=Fout0+m; + Fout2=Fout0+2*m; + tw1=tw2=twiddles; + + do{ + + C_FIXDIV(*Fout,3); C_FIXDIV(*Fout1,3); C_FIXDIV(*Fout2,3); + + scratch[0] = *Fout0; + + C_MUL(scratch[1],*Fout1 , *tw1); + C_MUL(scratch[2],*Fout2 , *tw2); + tw1 += fstride; + tw2 += fstride*2; + + C_ADD(scratch[4],scratch[1],scratch[2]); + C_ADD(*Fout0,scratch[0],scratch[4]); + + scratch[4].r /= -2; + scratch[4].i /= -2; + + C_SUB(scratch[5],scratch[1],scratch[2]); + scratch[5].r *= epi3.i; + scratch[5].i *= epi3.i; + + scratch[3].r = scratch[4].r - scratch[5].i ; + scratch[3].i = scratch[4].i + scratch[5].r ; + + C_ADD( *Fout1, scratch[0] , scratch[3] ); + + scratch[3].r = scratch[4].r + scratch[5].i; + scratch[3].i = scratch[4].i - scratch[5].r; + C_ADD( *Fout2, scratch[0] , scratch[3] ); + + ++Fout0;++Fout1;++Fout2; + }while(--m); +} + /* perform the butterfly for one stage of a mixed radix FFT */ void bfly_generic( kiss_fft_cpx * Fout, @@ -221,8 +276,11 @@ void fft_work( } switch (p) { - case 4: bfly4(Fout,fstride,st,m); break; case 2: bfly2(Fout,fstride,st,m); break; +#if 1 + case 3: bfly3(Fout,fstride,st,m); break; +#endif + case 4: bfly4(Fout,fstride,st,m); break; default: bfly_generic(Fout,fstride,st,m,p); break; } } diff --git a/test/Makefile b/test/Makefile index 15bd87a..b07d4ea 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,11 +1,10 @@ ifeq "$(NFFT)" "" - NFFT=1024 + NFFT=1024 endif - ifeq "$(NUMFFTS)" "" - NUMFFTS=10000 + NUMFFTS=10000 endif UTILSRC=../kiss_fft.c fftutil.c @@ -13,7 +12,7 @@ UTILSRC=../kiss_fft.c fftutil.c CFLAGS=-Wall -O3 -lm -I.. -ansi -pedantic ifeq "$(DATATYPE)" "" - DATATYPE=float + DATATYPE=float endif UTIL=fftutil_$(DATATYPE) @@ -21,9 +20,9 @@ UTIL=fftutil_$(DATATYPE) all: $(UTIL) ifeq "$(DATATYPE)" "short" - TYPEFLAGS=-DFIXED_POINT -Dkiss_fft_scalar=short + TYPEFLAGS=-DFIXED_POINT -Dkiss_fft_scalar=short else - TYPEFLAGS=-Dkiss_fft_scalar=$(DATATYPE) + TYPEFLAGS=-Dkiss_fft_scalar=$(DATATYPE) endif $(UTIL): $(UTILSRC) @@ -47,7 +46,7 @@ time: all $(RANDDAT) POW2=256 512 1024 2048 POW3=243 729 2187 mtime: all - @for n in $(POW2) $(POW3) ;do \ + @for n in $(POW3) ;do \ export NFFT=$$n;make time; \ done @@ -56,7 +55,7 @@ snr: all @echo @echo "### testing SNR for $(NFFT) point FFTs" @echo "#### $(DATATYPE)" - @echo "testkiss($(NFFT),'$(DATATYPE)',1,1/$(NFFT));" | octave -q + @echo "testkiss( $(NFFT) , '$(DATATYPE)' );" | octave -q test: snr time diff --git a/test/testkiss.m b/test/testkiss.m index fc86c17..ba04eff 100755 --- a/test/testkiss.m +++ b/test/testkiss.m @@ -1,11 +1,11 @@ -function snr= testkiss( nfft , prec ,scale_t2f ,scale_f2t ) -if nargin<1, nfft=1024 -endif -if nargin<2, prec='float' -endif -if nargin<3, scale_t2f=1 -endif -if nargin<4, scale_f2t=1 +function snr= testkiss( nfft , prec ) + +if strcmp( prec ,'short') + scale_t2f=nfft; + scale_f2t=nfft; +else + scale_t2f=1; + scale_f2t=1/nfft; endif kfft= sprintf('./fftutil_%s',prec); diff --git a/tools/Makefile b/tools/Makefile index 15bd87a..b07d4ea 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,11 +1,10 @@ ifeq "$(NFFT)" "" - NFFT=1024 + NFFT=1024 endif - ifeq "$(NUMFFTS)" "" - NUMFFTS=10000 + NUMFFTS=10000 endif UTILSRC=../kiss_fft.c fftutil.c @@ -13,7 +12,7 @@ UTILSRC=../kiss_fft.c fftutil.c CFLAGS=-Wall -O3 -lm -I.. -ansi -pedantic ifeq "$(DATATYPE)" "" - DATATYPE=float + DATATYPE=float endif UTIL=fftutil_$(DATATYPE) @@ -21,9 +20,9 @@ UTIL=fftutil_$(DATATYPE) all: $(UTIL) ifeq "$(DATATYPE)" "short" - TYPEFLAGS=-DFIXED_POINT -Dkiss_fft_scalar=short + TYPEFLAGS=-DFIXED_POINT -Dkiss_fft_scalar=short else - TYPEFLAGS=-Dkiss_fft_scalar=$(DATATYPE) + TYPEFLAGS=-Dkiss_fft_scalar=$(DATATYPE) endif $(UTIL): $(UTILSRC) @@ -47,7 +46,7 @@ time: all $(RANDDAT) POW2=256 512 1024 2048 POW3=243 729 2187 mtime: all - @for n in $(POW2) $(POW3) ;do \ + @for n in $(POW3) ;do \ export NFFT=$$n;make time; \ done @@ -56,7 +55,7 @@ snr: all @echo @echo "### testing SNR for $(NFFT) point FFTs" @echo "#### $(DATATYPE)" - @echo "testkiss($(NFFT),'$(DATATYPE)',1,1/$(NFFT));" | octave -q + @echo "testkiss( $(NFFT) , '$(DATATYPE)' );" | octave -q test: snr time