Use the kissfft gem instead - warvox - Unnamed repository; edit this file 'desc… | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit eab48926160862f223dd8727063349e2eec79087 | |
parent d3e37a6ac19cf12e4a91e48885e6b2622c17c64f | |
Author: HD Moore <[email protected]> | |
Date: Wed, 10 Oct 2012 01:32:54 -0500 | |
Use the kissfft gem instead | |
Diffstat: | |
M Makefile | 12 +----------- | |
D src/ruby-kissfft/COPYING | 30 ------------------------------ | |
D src/ruby-kissfft/_kiss_fft_guts.h | 150 -----------------------------… | |
D src/ruby-kissfft/extconf.rb | 5 ----- | |
D src/ruby-kissfft/kiss_fft.c | 427 -----------------------------… | |
D src/ruby-kissfft/kiss_fft.h | 123 -----------------------------… | |
D src/ruby-kissfft/kiss_fftr.c | 159 -----------------------------… | |
D src/ruby-kissfft/kiss_fftr.h | 46 -----------------------------… | |
D src/ruby-kissfft/main.c | 155 -----------------------------… | |
D src/ruby-kissfft/sample.data | 0 | |
D src/ruby-kissfft/test_kissfft.rb | 47 -----------------------------… | |
M web/Gemfile | 1 + | |
M web/Gemfile.lock | 2 ++ | |
13 files changed, 4 insertions(+), 1153 deletions(-) | |
--- | |
diff --git a/Makefile b/Makefile | |
@@ -3,18 +3,11 @@ all: test | |
test: install | |
bin/verify_install.rb | |
-install: bundler dtmf2num ruby-kissfft | |
+install: bundler dtmf2num | |
cp -a src/dtmf2num/dtmf2num bin/ | |
-ruby-kissfft-install: ruby-kissfft | |
- cp -a src/ruby-kissfft/kissfft.so lib/ | |
- | |
dtmf2num: | |
make -C src/dtmf2num/ | |
- | |
-ruby-kissfft: | |
- ( cd src/ruby-kissfft/; ruby extconf.rb ) | |
- make -C src/ruby-kissfft/ && cp src/ruby-kissfft/kissfft.so lib/ | |
db: | |
@echo "Checking the database.." | |
@@ -31,7 +24,4 @@ bundler: | |
(cd web; bundle install) | |
clean: | |
- ( cd src/ruby-kissfft/; ruby extconf.rb ) | |
- make -C src/ruby-kissfft/ clean | |
make -C src/dtmf2num/ clean | |
- rm -f lib/kissfft.so | |
diff --git a/src/ruby-kissfft/COPYING b/src/ruby-kissfft/COPYING | |
@@ -1,30 +0,0 @@ | |
-Kiss FFT library | |
-================== | |
- | |
-Copyright (c) 2003-2006 Mark Borgerding | |
- | |
-All rights reserved. | |
- | |
-Redistribution and use in source and binary forms, with or without modificatio… | |
- | |
- * Redistributions of source code must retain the above copyright notice, t… | |
- * Redistributions in binary form must reproduce the above copyright notice… | |
- * Neither the author nor the names of any contributors may be used to endo… | |
- | |
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN… | |
- | |
- | |
-Ruby wrapper layer | |
-================== | |
- | |
-Copyright (C) 2009 H D Moore | |
- | |
-All rights reserved. | |
- | |
-Redistribution and use in source and binary forms, with or without modificatio… | |
- | |
- * Redistributions of source code must retain the above copyright notice, t… | |
- * Redistributions in binary form must reproduce the above copyright notice… | |
- * Neither the author nor the names of any contributors may be used to endo… | |
- | |
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN… | |
diff --git a/src/ruby-kissfft/_kiss_fft_guts.h b/src/ruby-kissfft/_kiss_fft_gut… | |
@@ -1,150 +0,0 @@ | |
-/* | |
-Copyright (c) 2003-2004, Mark Borgerding | |
- | |
-All rights reserved. | |
- | |
-Redistribution and use in source and binary forms, with or without modificatio… | |
- | |
- * Redistributions of source code must retain the above copyright notice, t… | |
- * Redistributions in binary form must reproduce the above copyright notice… | |
- * Neither the author nor the names of any contributors may be used to endo… | |
- | |
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN… | |
-*/ | |
- | |
-/* kiss_fft.h | |
- defines kiss_fft_scalar as either short or a float type | |
- and defines | |
- typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ | |
-#include "kiss_fft.h" | |
-#include <limits.h> | |
- | |
-#define MAXFACTORS 32 | |
-/* e.g. an fft of length 128 has 4 factors | |
- as far as kissfft is concerned | |
- 4*4*4*2 | |
- */ | |
- | |
-struct kiss_fft_state{ | |
- int nfft; | |
- int inverse; | |
- int factors[2*MAXFACTORS]; | |
- kiss_fft_cpx twiddles[1]; | |
-}; | |
- | |
-/* | |
- Explanation of macros dealing with complex math: | |
- | |
- C_MUL(m,a,b) : m = a*b | |
- C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise | |
- C_SUB( res, a,b) : res = a - b | |
- C_SUBFROM( res , a) : res -= a | |
- C_ADDTO( res , a) : res += a | |
- * */ | |
-#ifdef FIXED_POINT | |
-#if (FIXED_POINT==32) | |
-# define FRACBITS 31 | |
-# define SAMPPROD int64_t | |
-#define SAMP_MAX 2147483647 | |
-#else | |
-# define FRACBITS 15 | |
-# define SAMPPROD int32_t | |
-#define SAMP_MAX 32767 | |
-#endif | |
- | |
-#define SAMP_MIN -SAMP_MAX | |
- | |
-#if defined(CHECK_OVERFLOW) | |
-# define CHECK_OVERFLOW_OP(a,op,b) \ | |
- if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SA… | |
- fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op… | |
-#endif | |
- | |
- | |
-# define smul(a,b) ( (SAMPPROD)(a)*(b) ) | |
-# define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRAC… | |
- | |
-# define S_MUL(a,b) sround( smul(a,b) ) | |
- | |
-# define C_MUL(m,a,b) \ | |
- do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \ | |
- (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0) | |
- | |
-# define DIVSCALAR(x,k) \ | |
- (x) = sround( smul( x, SAMP_MAX/k ) ) | |
- | |
-# define C_FIXDIV(c,div) \ | |
- do { DIVSCALAR( (c).r , div); \ | |
- DIVSCALAR( (c).i , div); }while (0) | |
- | |
-# define C_MULBYSCALAR( c, s ) \ | |
- do{ (c).r = sround( smul( (c).r , s ) ) ;\ | |
- (c).i = sround( smul( (c).i , s ) ) ; }while(0) | |
- | |
-#else /* not FIXED_POINT*/ | |
- | |
-# define S_MUL(a,b) ( (a)*(b) ) | |
-#define C_MUL(m,a,b) \ | |
- do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ | |
- (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) | |
-# define C_FIXDIV(c,div) /* NOOP */ | |
-# define C_MULBYSCALAR( c, s ) \ | |
- do{ (c).r *= (s);\ | |
- (c).i *= (s); }while(0) | |
-#endif | |
- | |
-#ifndef CHECK_OVERFLOW_OP | |
-# define CHECK_OVERFLOW_OP(a,op,b) /* noop */ | |
-#endif | |
- | |
-#define C_ADD( res, a,b)\ | |
- do { \ | |
- CHECK_OVERFLOW_OP((a).r,+,(b).r)\ | |
- CHECK_OVERFLOW_OP((a).i,+,(b).i)\ | |
- (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ | |
- }while(0) | |
-#define C_SUB( res, a,b)\ | |
- do { \ | |
- CHECK_OVERFLOW_OP((a).r,-,(b).r)\ | |
- CHECK_OVERFLOW_OP((a).i,-,(b).i)\ | |
- (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ | |
- }while(0) | |
-#define C_ADDTO( res , a)\ | |
- do { \ | |
- CHECK_OVERFLOW_OP((res).r,+,(a).r)\ | |
- CHECK_OVERFLOW_OP((res).i,+,(a).i)\ | |
- (res).r += (a).r; (res).i += (a).i;\ | |
- }while(0) | |
- | |
-#define C_SUBFROM( res , a)\ | |
- do {\ | |
- CHECK_OVERFLOW_OP((res).r,-,(a).r)\ | |
- CHECK_OVERFLOW_OP((res).i,-,(a).i)\ | |
- (res).r -= (a).r; (res).i -= (a).i; \ | |
- }while(0) | |
- | |
- | |
-#ifdef FIXED_POINT | |
-# define KISS_FFT_COS(phase) floor(.5+SAMP_MAX * cos (phase)) | |
-# define KISS_FFT_SIN(phase) floor(.5+SAMP_MAX * sin (phase)) | |
-# define HALF_OF(x) ((x)>>1) | |
-#elif defined(USE_SIMD) | |
-# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) ) | |
-# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) ) | |
-# define HALF_OF(x) ((x)*_mm_set1_ps(.5)) | |
-#else | |
-# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) | |
-# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) | |
-# define HALF_OF(x) ((x)*.5) | |
-#endif | |
- | |
-#define kf_cexp(x,phase) \ | |
- do{ \ | |
- (x)->r = KISS_FFT_COS(phase);\ | |
- (x)->i = KISS_FFT_SIN(phase);\ | |
- }while(0) | |
- | |
- | |
-/* a debugging function */ | |
-#define pcpx(c)\ | |
- fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) ) | |
diff --git a/src/ruby-kissfft/extconf.rb b/src/ruby-kissfft/extconf.rb | |
@@ -1,5 +0,0 @@ | |
-require 'mkmf' | |
- | |
-if(have_library("m")) | |
- create_makefile("kissfft") | |
-end | |
diff --git a/src/ruby-kissfft/kiss_fft.c b/src/ruby-kissfft/kiss_fft.c | |
@@ -1,427 +0,0 @@ | |
-/* | |
-Copyright (c) 2003-2004, Mark Borgerding | |
- | |
-All rights reserved. | |
- | |
-Redistribution and use in source and binary forms, with or without modificatio… | |
- | |
- * Redistributions of source code must retain the above copyright notice, t… | |
- * Redistributions in binary form must reproduce the above copyright notice… | |
- * Neither the author nor the names of any contributors may be used to endo… | |
- | |
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN… | |
-*/ | |
- | |
- | |
-#include "_kiss_fft_guts.h" | |
-/* The guts header contains all the multiplication and addition macros that ar… | |
- fixed or floating point complex numbers. It also delares the kf_ internal fu… | |
- */ | |
- | |
-static kiss_fft_cpx *scratchbuf=NULL; | |
-static size_t nscratchbuf=0; | |
-static kiss_fft_cpx *tmpbuf=NULL; | |
-static size_t ntmpbuf=0; | |
- | |
-#define CHECKBUF(buf,nbuf,n) \ | |
- do { \ | |
- if ( nbuf < (size_t)(n) ) {\ | |
- free(buf); \ | |
- buf = (kiss_fft_cpx*)KISS_FFT_MALLOC(sizeof(kiss_fft_cpx)*(n)); \ | |
- nbuf = (size_t)(n); \ | |
- } \ | |
- }while(0) | |
- | |
- | |
-static void kf_bfly2( | |
- kiss_fft_cpx * Fout, | |
- const size_t fstride, | |
- const kiss_fft_cfg st, | |
- int m | |
- ) | |
-{ | |
- kiss_fft_cpx * Fout2; | |
- kiss_fft_cpx * tw1 = st->twiddles; | |
- kiss_fft_cpx t; | |
- Fout2 = Fout + m; | |
- do{ | |
- C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2); | |
- | |
- C_MUL (t, *Fout2 , *tw1); | |
- tw1 += fstride; | |
- C_SUB( *Fout2 , *Fout , t ); | |
- C_ADDTO( *Fout , t ); | |
- ++Fout2; | |
- ++Fout; | |
- }while (--m); | |
-} | |
- | |
-static void kf_bfly4( | |
- kiss_fft_cpx * Fout, | |
- const size_t fstride, | |
- const kiss_fft_cfg st, | |
- const size_t m | |
- ) | |
-{ | |
- kiss_fft_cpx *tw1,*tw2,*tw3; | |
- kiss_fft_cpx scratch[6]; | |
- size_t k=m; | |
- const size_t m2=2*m; | |
- const size_t m3=3*m; | |
- | |
- tw3 = tw2 = tw1 = st->twiddles; | |
- | |
- do { | |
- C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV… | |
- | |
- C_MUL(scratch[0],Fout[m] , *tw1 ); | |
- C_MUL(scratch[1],Fout[m2] , *tw2 ); | |
- C_MUL(scratch[2],Fout[m3] , *tw3 ); | |
- | |
- C_SUB( scratch[5] , *Fout, scratch[1] ); | |
- C_ADDTO(*Fout, scratch[1]); | |
- C_ADD( scratch[3] , scratch[0] , scratch[2] ); | |
- C_SUB( scratch[4] , scratch[0] , scratch[2] ); | |
- C_SUB( Fout[m2], *Fout, scratch[3] ); | |
- tw1 += fstride; | |
- tw2 += fstride*2; | |
- tw3 += fstride*3; | |
- C_ADDTO( *Fout , scratch[3] ); | |
- | |
- if(st->inverse) { | |
- Fout[m].r = scratch[5].r - scratch[4].i; | |
- Fout[m].i = scratch[5].i + scratch[4].r; | |
- Fout[m3].r = scratch[5].r + scratch[4].i; | |
- Fout[m3].i = scratch[5].i - scratch[4].r; | |
- }else{ | |
- Fout[m].r = scratch[5].r + scratch[4].i; | |
- Fout[m].i = scratch[5].i - scratch[4].r; | |
- Fout[m3].r = scratch[5].r - scratch[4].i; | |
- Fout[m3].i = scratch[5].i + scratch[4].r; | |
- } | |
- ++Fout; | |
- }while(--k); | |
-} | |
- | |
-static void kf_bfly3( | |
- kiss_fft_cpx * Fout, | |
- const size_t fstride, | |
- const kiss_fft_cfg st, | |
- size_t m | |
- ) | |
-{ | |
- size_t k=m; | |
- const size_t m2 = 2*m; | |
- kiss_fft_cpx *tw1,*tw2; | |
- kiss_fft_cpx scratch[5]; | |
- kiss_fft_cpx epi3; | |
- epi3 = st->twiddles[fstride*m]; | |
- | |
- tw1=tw2=st->twiddles; | |
- | |
- do{ | |
- C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); | |
- | |
- C_MUL(scratch[1],Fout[m] , *tw1); | |
- C_MUL(scratch[2],Fout[m2] , *tw2); | |
- | |
- C_ADD(scratch[3],scratch[1],scratch[2]); | |
- C_SUB(scratch[0],scratch[1],scratch[2]); | |
- tw1 += fstride; | |
- tw2 += fstride*2; | |
- | |
- Fout[m].r = Fout->r - HALF_OF(scratch[3].r); | |
- Fout[m].i = Fout->i - HALF_OF(scratch[3].i); | |
- | |
- C_MULBYSCALAR( scratch[0] , epi3.i ); | |
- | |
- C_ADDTO(*Fout,scratch[3]); | |
- | |
- Fout[m2].r = Fout[m].r + scratch[0].i; | |
- Fout[m2].i = Fout[m].i - scratch[0].r; | |
- | |
- Fout[m].r -= scratch[0].i; | |
- Fout[m].i += scratch[0].r; | |
- | |
- ++Fout; | |
- }while(--k); | |
-} | |
- | |
-static void kf_bfly5( | |
- kiss_fft_cpx * Fout, | |
- const size_t fstride, | |
- const kiss_fft_cfg st, | |
- int m | |
- ) | |
-{ | |
- kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; | |
- int u; | |
- kiss_fft_cpx scratch[13]; | |
- kiss_fft_cpx * twiddles = st->twiddles; | |
- kiss_fft_cpx *tw; | |
- kiss_fft_cpx ya,yb; | |
- ya = twiddles[fstride*m]; | |
- yb = twiddles[fstride*2*m]; | |
- | |
- Fout0=Fout; | |
- Fout1=Fout0+m; | |
- Fout2=Fout0+2*m; | |
- Fout3=Fout0+3*m; | |
- Fout4=Fout0+4*m; | |
- | |
- tw=st->twiddles; | |
- for ( u=0; u<m; ++u ) { | |
- C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDI… | |
- scratch[0] = *Fout0; | |
- | |
- C_MUL(scratch[1] ,*Fout1, tw[u*fstride]); | |
- C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]); | |
- C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]); | |
- C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]); | |
- | |
- C_ADD( scratch[7],scratch[1],scratch[4]); | |
- C_SUB( scratch[10],scratch[1],scratch[4]); | |
- C_ADD( scratch[8],scratch[2],scratch[3]); | |
- C_SUB( scratch[9],scratch[2],scratch[3]); | |
- | |
- Fout0->r += scratch[7].r + scratch[8].r; | |
- Fout0->i += scratch[7].i + scratch[8].i; | |
- | |
- scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch… | |
- scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch… | |
- | |
- scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); | |
- scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); | |
- | |
- C_SUB(*Fout1,scratch[5],scratch[6]); | |
- C_ADD(*Fout4,scratch[5],scratch[6]); | |
- | |
- scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratc… | |
- scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratc… | |
- scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); | |
- scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); | |
- | |
- C_ADD(*Fout2,scratch[11],scratch[12]); | |
- C_SUB(*Fout3,scratch[11],scratch[12]); | |
- | |
- ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; | |
- } | |
-} | |
- | |
-/* perform the butterfly for one stage of a mixed radix FFT */ | |
-static void kf_bfly_generic( | |
- kiss_fft_cpx * Fout, | |
- const size_t fstride, | |
- const kiss_fft_cfg st, | |
- int m, | |
- int p | |
- ) | |
-{ | |
- int u,k,q1,q; | |
- kiss_fft_cpx * twiddles = st->twiddles; | |
- kiss_fft_cpx t; | |
- int Norig = st->nfft; | |
- | |
- CHECKBUF(scratchbuf,nscratchbuf,p); | |
- | |
- for ( u=0; u<m; ++u ) { | |
- k=u; | |
- for ( q1=0 ; q1<p ; ++q1 ) { | |
- scratchbuf[q1] = Fout[ k ]; | |
- C_FIXDIV(scratchbuf[q1],p); | |
- k += m; | |
- } | |
- | |
- k=u; | |
- for ( q1=0 ; q1<p ; ++q1 ) { | |
- int twidx=0; | |
- Fout[ k ] = scratchbuf[0]; | |
- for (q=1;q<p;++q ) { | |
- twidx += fstride * k; | |
- if (twidx>=Norig) twidx-=Norig; | |
- C_MUL(t,scratchbuf[q] , twiddles[twidx] ); | |
- C_ADDTO( Fout[ k ] ,t); | |
- } | |
- k += m; | |
- } | |
- } | |
-} | |
- | |
-static | |
-void kf_work( | |
- kiss_fft_cpx * Fout, | |
- const kiss_fft_cpx * f, | |
- const size_t fstride, | |
- int in_stride, | |
- int * factors, | |
- const kiss_fft_cfg st | |
- ) | |
-{ | |
- kiss_fft_cpx * Fout_beg=Fout; | |
- const int p=*factors++; /* the radix */ | |
- const int m=*factors++; /* stage's fft length/p */ | |
- const kiss_fft_cpx * Fout_end = Fout + p*m; | |
- | |
-#ifdef _OPENMP | |
- // use openmp extensions at the | |
- // top-level (not recursive) | |
- if (fstride==1) { | |
- int k; | |
- | |
- // execute the p different work units in different threads | |
-# pragma omp parallel for | |
- for (k=0;k<p;++k) | |
- kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,fac… | |
- // all threads have joined by this point | |
- | |
- switch (p) { | |
- case 2: kf_bfly2(Fout,fstride,st,m); break; | |
- case 3: kf_bfly3(Fout,fstride,st,m); break; | |
- case 4: kf_bfly4(Fout,fstride,st,m); break; | |
- case 5: kf_bfly5(Fout,fstride,st,m); break; | |
- default: kf_bfly_generic(Fout,fstride,st,m,p); break; | |
- } | |
- return; | |
- } | |
-#endif | |
- | |
- if (m==1) { | |
- do{ | |
- *Fout = *f; | |
- f += fstride*in_stride; | |
- }while(++Fout != Fout_end ); | |
- }else{ | |
- do{ | |
- // recursive call: | |
- // DFT of size m*p performed by doing | |
- // p instances of smaller DFTs of size m, | |
- // each one takes a decimated version of the input | |
- kf_work( Fout , f, fstride*p, in_stride, factors,st); | |
- f += fstride*in_stride; | |
- }while( (Fout += m) != Fout_end ); | |
- } | |
- | |
- Fout=Fout_beg; | |
- | |
- // recombine the p smaller DFTs | |
- switch (p) { | |
- case 2: kf_bfly2(Fout,fstride,st,m); break; | |
- case 3: kf_bfly3(Fout,fstride,st,m); break; | |
- case 4: kf_bfly4(Fout,fstride,st,m); break; | |
- case 5: kf_bfly5(Fout,fstride,st,m); break; | |
- default: kf_bfly_generic(Fout,fstride,st,m,p); break; | |
- } | |
-} | |
- | |
-/* facbuf is populated by p1,m1,p2,m2, ... | |
- where | |
- p[i] * m[i] = m[i-1] | |
- m0 = n */ | |
-static | |
-void kf_factor(int n,int * facbuf) | |
-{ | |
- int p=4; | |
- double floor_sqrt; | |
- floor_sqrt = floor( sqrt((double)n) ); | |
- | |
- /*factor out powers of 4, powers of 2, then any remaining primes */ | |
- do { | |
- while (n % p) { | |
- switch (p) { | |
- case 4: p = 2; break; | |
- case 2: p = 3; break; | |
- default: p += 2; break; | |
- } | |
- if (p > floor_sqrt) | |
- p = n; /* no more factors, skip to end */ | |
- } | |
- n /= p; | |
- *facbuf++ = p; | |
- *facbuf++ = n; | |
- } while (n > 1); | |
-} | |
- | |
-/* | |
- * | |
- * User-callable function to allocate all necessary storage space for the fft. | |
- * | |
- * The return value is a contiguous block of memory, allocated with malloc. A… | |
- * It can be freed with free(), rather than a kiss_fft-specific function. | |
- * */ | |
-kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenme… | |
-{ | |
- kiss_fft_cfg st=NULL; | |
- size_t memneeded = sizeof(struct kiss_fft_state) | |
- + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/ | |
- | |
- if ( lenmem==NULL ) { | |
- st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded ); | |
- }else{ | |
- if (mem != NULL && *lenmem >= memneeded) | |
- st = (kiss_fft_cfg)mem; | |
- *lenmem = memneeded; | |
- } | |
- if (st) { | |
- int i; | |
- st->nfft=nfft; | |
- st->inverse = inverse_fft; | |
- | |
- for (i=0;i<nfft;++i) { | |
- const double pi=3.141592653589793238462643383279502884197169399375… | |
- double phase = -2*pi*i / nfft; | |
- if (st->inverse) | |
- phase *= -1; | |
- kf_cexp(st->twiddles+i, phase ); | |
- } | |
- | |
- kf_factor(nfft,st->factors); | |
- } | |
- return st; | |
-} | |
- | |
- | |
- | |
- | |
-void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fou… | |
-{ | |
- if (fin == fout) { | |
- CHECKBUF(tmpbuf,ntmpbuf,st->nfft); | |
- kf_work(tmpbuf,fin,1,in_stride, st->factors,st); | |
- memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft); | |
- }else{ | |
- kf_work( fout, fin, 1,in_stride, st->factors,st ); | |
- } | |
-} | |
- | |
-void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) | |
-{ | |
- kiss_fft_stride(cfg,fin,fout,1); | |
-} | |
- | |
- | |
-/* not really necessary to call, but if someone is doing in-place ffts, they m… | |
- buffers from CHECKBUF | |
- */ | |
-void kiss_fft_cleanup(void) | |
-{ | |
- free(scratchbuf); | |
- scratchbuf = NULL; | |
- nscratchbuf=0; | |
- free(tmpbuf); | |
- tmpbuf=NULL; | |
- ntmpbuf=0; | |
-} | |
- | |
-int kiss_fft_next_fast_size(int n) | |
-{ | |
- while(1) { | |
- int m=n; | |
- while ( (m%2) == 0 ) m/=2; | |
- while ( (m%3) == 0 ) m/=3; | |
- while ( (m%5) == 0 ) m/=5; | |
- if (m<=1) | |
- break; /* n is completely factorable by twos, threes, and fives */ | |
- n++; | |
- } | |
- return n; | |
-} | |
diff --git a/src/ruby-kissfft/kiss_fft.h b/src/ruby-kissfft/kiss_fft.h | |
@@ -1,123 +0,0 @@ | |
-#ifndef KISS_FFT_H | |
-#define KISS_FFT_H | |
- | |
-#include <stdlib.h> | |
-#include <stdio.h> | |
-#include <math.h> | |
-#include <string.h> | |
-#include <malloc.h> | |
- | |
-#ifdef __cplusplus | |
-extern "C" { | |
-#endif | |
- | |
-/* | |
- ATTENTION! | |
- If you would like a : | |
- -- a utility that will handle the caching of fft objects | |
- -- real-only (no imaginary time component ) FFT | |
- -- a multi-dimensional FFT | |
- -- a command-line utility to perform ffts | |
- -- a command-line utility to perform fast-convolution filtering | |
- | |
- Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c | |
- in the tools/ directory. | |
-*/ | |
- | |
-#ifdef USE_SIMD | |
-# include <xmmintrin.h> | |
-# define kiss_fft_scalar __m128 | |
-#define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes) | |
-#else | |
-#define KISS_FFT_MALLOC malloc | |
-#endif | |
- | |
- | |
-#ifdef FIXED_POINT | |
-#include <sys/types.h> | |
-# if (FIXED_POINT == 32) | |
-# define kiss_fft_scalar int32_t | |
-# else | |
-# define kiss_fft_scalar int16_t | |
-# endif | |
-#else | |
-# ifndef kiss_fft_scalar | |
-/* default is float */ | |
-# define kiss_fft_scalar float | |
-# endif | |
-#endif | |
- | |
-typedef struct { | |
- kiss_fft_scalar r; | |
- kiss_fft_scalar i; | |
-}kiss_fft_cpx; | |
- | |
-typedef struct kiss_fft_state* kiss_fft_cfg; | |
- | |
-/* | |
- * kiss_fft_alloc | |
- * | |
- * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. | |
- * | |
- * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL); | |
- * | |
- * The return value from fft_alloc is a cfg buffer used internally | |
- * by the fft routine or NULL. | |
- * | |
- * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using ma… | |
- * The returned value should be free()d when done to avoid memory leaks. | |
- * | |
- * The state can be placed in a user supplied buffer 'mem': | |
- * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, | |
- * then the function places the cfg in mem and the size used in *lenmem | |
- * and returns mem. | |
- * | |
- * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), | |
- * then the function returns NULL and places the minimum cfg | |
- * buffer size in *lenmem. | |
- * */ | |
- | |
-kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenme… | |
- | |
-/* | |
- * kiss_fft(cfg,in_out_buf) | |
- * | |
- * Perform an FFT on a complex input buffer. | |
- * for a forward FFT, | |
- * fin should be f[0] , f[1] , ... ,f[nfft-1] | |
- * fout will be F[0] , F[1] , ... ,F[nfft-1] | |
- * Note that each element is complex and can be accessed like | |
- f[k].r and f[k].i | |
- * */ | |
-void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); | |
- | |
-/* | |
- A more generic version of the above function. It reads its input from every N… | |
- * */ | |
-void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fo… | |
- | |
-/* If kiss_fft_alloc allocated a buffer, it is one contiguous | |
- buffer and can be simply free()d when no longer needed*/ | |
-#define kiss_fft_free free | |
- | |
-/* | |
- Cleans up some memory that gets managed internally. Not necessary to call, bu… | |
- your compiler output to call this before you exit. | |
-*/ | |
-void kiss_fft_cleanup(void); | |
- | |
- | |
-/* | |
- * Returns the smallest integer k, such that k>=n and k has only "fast" factor… | |
- */ | |
-int kiss_fft_next_fast_size(int n); | |
- | |
-/* for real ffts, we need an even size */ | |
-#define kiss_fftr_next_fast_size_real(n) \ | |
- (kiss_fft_next_fast_size( ((n)+1)>>1)<<1) | |
- | |
-#ifdef __cplusplus | |
-} | |
-#endif | |
- | |
-#endif | |
diff --git a/src/ruby-kissfft/kiss_fftr.c b/src/ruby-kissfft/kiss_fftr.c | |
@@ -1,159 +0,0 @@ | |
-/* | |
-Copyright (c) 2003-2004, Mark Borgerding | |
- | |
-All rights reserved. | |
- | |
-Redistribution and use in source and binary forms, with or without modificatio… | |
- | |
- * Redistributions of source code must retain the above copyright notice, t… | |
- * Redistributions in binary form must reproduce the above copyright notice… | |
- * Neither the author nor the names of any contributors may be used to endo… | |
- | |
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN… | |
-*/ | |
- | |
-#include "kiss_fftr.h" | |
-#include "_kiss_fft_guts.h" | |
- | |
-struct kiss_fftr_state{ | |
- kiss_fft_cfg substate; | |
- kiss_fft_cpx * tmpbuf; | |
- kiss_fft_cpx * super_twiddles; | |
-#ifdef USE_SIMD | |
- long pad; | |
-#endif | |
-}; | |
- | |
-kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * len… | |
-{ | |
- int i; | |
- kiss_fftr_cfg st = NULL; | |
- size_t subsize, memneeded; | |
- | |
- if (nfft & 1) { | |
- fprintf(stderr,"Real FFT optimization must be even.\n"); | |
- return NULL; | |
- } | |
- nfft >>= 1; | |
- | |
- kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize); | |
- memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx… | |
- | |
- if (lenmem == NULL) { | |
- st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded); | |
- } else { | |
- if (*lenmem >= memneeded) | |
- st = (kiss_fftr_cfg) mem; | |
- *lenmem = memneeded; | |
- } | |
- if (!st) | |
- return NULL; | |
- | |
- st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state stru… | |
- st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize); | |
- st->super_twiddles = st->tmpbuf + nfft; | |
- kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize); | |
- | |
- for (i = 0; i < nfft/2; ++i) { | |
- double phase = | |
- -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5); | |
- if (inverse_fft) | |
- phase *= -1; | |
- kf_cexp (st->super_twiddles+i,phase); | |
- } | |
- return st; | |
-} | |
- | |
-void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *… | |
-{ | |
- /* input buffer timedata is stored row-wise */ | |
- int k,ncfft; | |
- kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; | |
- | |
- if ( st->substate->inverse) { | |
- fprintf(stderr,"kiss fft usage error: improper alloc\n"); | |
- exit(1); | |
- } | |
- | |
- ncfft = st->substate->nfft; | |
- | |
- /*perform the parallel fft of two real signals packed in real,imag*/ | |
- kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf ); | |
- /* The real part of the DC element of the frequency spectrum in st->tmpbuf | |
- * contains the sum of the even-numbered elements of the input time sequen… | |
- * The imag part is the sum of the odd-numbered elements | |
- * | |
- * The sum of tdc.r and tdc.i is the sum of the input time sequence. | |
- * yielding DC of input time sequence | |
- * The difference of tdc.r - tdc.i is the sum of the input (dot product) [… | |
- * yielding Nyquist bin of input time sequence | |
- */ | |
- | |
- tdc.r = st->tmpbuf[0].r; | |
- tdc.i = st->tmpbuf[0].i; | |
- C_FIXDIV(tdc,2); | |
- CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); | |
- CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); | |
- freqdata[0].r = tdc.r + tdc.i; | |
- freqdata[ncfft].r = tdc.r - tdc.i; | |
-#ifdef USE_SIMD | |
- freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0); | |
-#else | |
- freqdata[ncfft].i = freqdata[0].i = 0; | |
-#endif | |
- | |
- for ( k=1;k <= ncfft/2 ; ++k ) { | |
- fpk = st->tmpbuf[k]; | |
- fpnk.r = st->tmpbuf[ncfft-k].r; | |
- fpnk.i = - st->tmpbuf[ncfft-k].i; | |
- C_FIXDIV(fpk,2); | |
- C_FIXDIV(fpnk,2); | |
- | |
- C_ADD( f1k, fpk , fpnk ); | |
- C_SUB( f2k, fpk , fpnk ); | |
- C_MUL( tw , f2k , st->super_twiddles[k-1]); | |
- | |
- freqdata[k].r = HALF_OF(f1k.r + tw.r); | |
- freqdata[k].i = HALF_OF(f1k.i + tw.i); | |
- freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r); | |
- freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i); | |
- } | |
-} | |
- | |
-void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar … | |
-{ | |
- /* input buffer timedata is stored row-wise */ | |
- int k, ncfft; | |
- | |
- if (st->substate->inverse == 0) { | |
- fprintf (stderr, "kiss fft usage error: improper alloc\n"); | |
- exit (1); | |
- } | |
- | |
- ncfft = st->substate->nfft; | |
- | |
- st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r; | |
- st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r; | |
- C_FIXDIV(st->tmpbuf[0],2); | |
- | |
- for (k = 1; k <= ncfft / 2; ++k) { | |
- kiss_fft_cpx fk, fnkc, fek, fok, tmp; | |
- fk = freqdata[k]; | |
- fnkc.r = freqdata[ncfft - k].r; | |
- fnkc.i = -freqdata[ncfft - k].i; | |
- C_FIXDIV( fk , 2 ); | |
- C_FIXDIV( fnkc , 2 ); | |
- | |
- C_ADD (fek, fk, fnkc); | |
- C_SUB (tmp, fk, fnkc); | |
- C_MUL (fok, tmp, st->super_twiddles[k-1]); | |
- C_ADD (st->tmpbuf[k], fek, fok); | |
- C_SUB (st->tmpbuf[ncfft - k], fek, fok); | |
-#ifdef USE_SIMD | |
- st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); | |
-#else | |
- st->tmpbuf[ncfft - k].i *= -1; | |
-#endif | |
- } | |
- kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); | |
-} | |
diff --git a/src/ruby-kissfft/kiss_fftr.h b/src/ruby-kissfft/kiss_fftr.h | |
@@ -1,46 +0,0 @@ | |
-#ifndef KISS_FTR_H | |
-#define KISS_FTR_H | |
- | |
-#include "kiss_fft.h" | |
-#ifdef __cplusplus | |
-extern "C" { | |
-#endif | |
- | |
- | |
-/* | |
- | |
- Real optimized version can save about 45% cpu time vs. complex fft of a real … | |
- | |
- | |
- | |
- */ | |
- | |
-typedef struct kiss_fftr_state *kiss_fftr_cfg; | |
- | |
- | |
-kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * le… | |
-/* | |
- nfft must be even | |
- | |
- If you don't care to allocate space, use mem = lenmem = NULL | |
-*/ | |
- | |
- | |
-void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx … | |
-/* | |
- input timedata has nfft scalar points | |
- output freqdata has nfft/2+1 complex points | |
-*/ | |
- | |
-void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar… | |
-/* | |
- input freqdata has nfft/2+1 complex points | |
- output timedata has nfft scalar points | |
-*/ | |
- | |
-#define kiss_fftr_free free | |
- | |
-#ifdef __cplusplus | |
-} | |
-#endif | |
-#endif | |
diff --git a/src/ruby-kissfft/main.c b/src/ruby-kissfft/main.c | |
@@ -1,155 +0,0 @@ | |
-/* | |
- ruby-kissfft: a simple ruby module embedding the Kiss FFT library | |
- Copyright (C) 2009-2010 Rapid7 LLC - H D Moore <hdm[at]metasploit.com> | |
- | |
- Derived from "psdpng.c" from the KissFFT tools directory | |
- Copyright (C) 2003-2006 Mark Borgerding | |
-*/ | |
- | |
-#include "ruby.h" | |
- | |
- | |
-#include <stdlib.h> | |
-#include <math.h> | |
-#include <stdio.h> | |
-#include <string.h> | |
-#include <unistd.h> | |
- | |
-#include "kiss_fft.h" | |
-#include "kiss_fftr.h" | |
- | |
-static VALUE rb_cKissFFT; | |
- | |
-#define KISS_VERSION "1.2.8-1.0" | |
- | |
- | |
-static VALUE | |
-rbkiss_s_version(VALUE class) | |
-{ | |
- return rb_str_new2(KISS_VERSION); | |
-} | |
- | |
-#define CHECKNULL(p) if ( (p)==NULL ) do { fprintf(stderr,"CHECKNULL failed @ … | |
- | |
-static VALUE | |
-rbkiss_s_fftr(VALUE class, VALUE r_nfft, VALUE r_rate, VALUE r_buckets, VALUE … | |
-{ | |
- kiss_fftr_cfg cfg=NULL; | |
- kiss_fft_scalar *tbuf; | |
- kiss_fft_cpx *fbuf; | |
- float *mag2buf; | |
- int i; | |
- int avgctr=0; | |
- int nrows=0; | |
- | |
- int nfft; | |
- int rate; | |
- int navg; | |
- int nfreqs; | |
- | |
- int inp_len; | |
- int inp_idx; | |
- | |
- // Result set | |
- VALUE res; | |
- VALUE tmp; | |
- VALUE set; | |
- res = rb_ary_new(); | |
- | |
- if(TYPE(r_nfft) != T_FIXNUM) { | |
- return Qnil; | |
- } | |
- nfft=NUM2INT(r_nfft); | |
- | |
- if(TYPE(r_rate) != T_FIXNUM) { | |
- return Qnil; | |
- } | |
- rate=NUM2INT(r_rate); | |
- | |
- if(TYPE(r_buckets) != T_FIXNUM) { | |
- return Qnil; | |
- } | |
- navg=NUM2INT(r_buckets); | |
- | |
- if(TYPE(r_data) != T_ARRAY) { | |
- return Qnil; | |
- } | |
- | |
- if(RARRAY_LEN(r_data) == 0) { | |
- return Qnil; | |
- } | |
- | |
- if(TYPE(RARRAY_PTR(r_data)[0]) != T_FIXNUM ) { | |
- return Qnil; | |
- } | |
- | |
- nfreqs=nfft/2+1; | |
- | |
- CHECKNULL( cfg=kiss_fftr_alloc(nfft,0,0,0) ); | |
- CHECKNULL( tbuf=(kiss_fft_scalar*)malloc(sizeof(kiss_fft_scalar)*(nfft… | |
- CHECKNULL( fbuf=(kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx)*(nfft + 2))… | |
- CHECKNULL( mag2buf=(float*)malloc(sizeof(float)*(nfft + 2) )); | |
- | |
- memset(mag2buf,0,sizeof(mag2buf)*nfreqs); | |
- | |
- inp_len = RARRAY_LEN(r_data); | |
- inp_idx = 0; | |
- | |
- while(inp_idx < inp_len) { | |
- | |
- // Fill tbuf with nfft samples | |
- for(i=0;i<nfft;i++) { | |
- if(inp_idx + i >= inp_len) { | |
- tbuf[i] = 0; | |
- } else { | |
- if(TYPE(RARRAY_PTR(r_data)[ inp_idx + i ]) != … | |
- tbuf[i] = 0; | |
- } else { | |
- tbuf[i] = NUM2INT( RARRAY_PTR(r_data)[… | |
- } | |
- } | |
- } | |
- | |
- | |
- /* do FFT */ | |
- kiss_fftr(cfg,tbuf,fbuf); | |
- | |
- for (i=0;i<nfreqs;++i) { | |
- mag2buf[i] += fbuf[i].r * fbuf[i].r + fbuf[i].i * fbuf… | |
- } | |
- | |
- if (++avgctr == navg) { | |
- float eps = 1; | |
- avgctr=0; | |
- ++nrows; | |
- | |
- // RESULTS | |
- set = rb_ary_new(); | |
- for (i=0;i<nfreqs;++i) { | |
- float pwr = 10 * log10( mag2buf[i] / navg + ep… | |
- tmp = rb_ary_new(); | |
- rb_ary_push(tmp, rb_float_new( (float)i * ( ( … | |
- rb_ary_push(tmp, rb_float_new( pwr)); | |
- rb_ary_push(set, tmp); | |
- } | |
- rb_ary_push(res, set); | |
- memset(mag2buf,0,sizeof(mag2buf[0])*nfreqs); | |
- } | |
- inp_idx += nfft; | |
- } | |
- | |
- free(cfg); | |
- free(tbuf); | |
- free(fbuf); | |
- free(mag2buf); | |
- return(res); | |
-} | |
- | |
-void | |
-Init_kissfft() | |
-{ | |
- // KissFFT | |
- rb_cKissFFT = rb_define_class("KissFFT", rb_cObject); | |
- rb_define_module_function(rb_cKissFFT, "version", rbkiss_s_version, 0); | |
- rb_define_module_function(rb_cKissFFT, "fftr", rbkiss_s_fftr, 4); | |
-} | |
diff --git a/src/ruby-kissfft/sample.data b/src/ruby-kissfft/sample.data | |
Binary files differ. | |
diff --git a/src/ruby-kissfft/test_kissfft.rb b/src/ruby-kissfft/test_kissfft.rb | |
@@ -1,47 +0,0 @@ | |
-#!/usr/bin/ruby | |
- | |
-base = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__ | |
-$:.unshift(File.join(File.dirname(base))) | |
- | |
-require 'test/unit' | |
-require 'kissfft' | |
-require 'pp' | |
- | |
-# | |
-# Simple unit test | |
-# | |
- | |
-class KissFFT::UnitTest < Test::Unit::TestCase | |
- def test_version | |
- assert_equal(String, KissFFT.version.class) | |
- puts "KissFFT version: #{KissFFT.version}" | |
- end | |
- def test_fftr | |
- data = File.read('sample.data').unpack('s*') | |
- | |
- min = 1 | |
- res = KissFFT.fftr(8192, 8000, 1, data) | |
- | |
- tones = {} | |
- res.each do |x| | |
- rank = x.sort{|a,b| a[1].to_i <=> b[1].to_i }.reverse | |
- rank[0..10].each do |t| | |
- f = t[0].round | |
- p = t[1].round | |
- next if f == 0 | |
- next if p < min | |
- tones[ f ] ||= [] | |
- tones[ f ] << t | |
- end | |
- end | |
- | |
- tones.keys.sort.each do |t| | |
- next if tones[t].length < 2 | |
- puts "#{t}hz" | |
- tones[t].each do |x| | |
- puts "\t#{x[0]}hz @ #{x[1]}" | |
- end | |
- end | |
- | |
- end | |
-end | |
diff --git a/web/Gemfile b/web/Gemfile | |
@@ -2,6 +2,7 @@ source 'http://rubygems.org' | |
gem 'rails', '3.2.8' | |
gem 'pg', '0.11' | |
+gem 'kissfft' | |
# Gems used only for assets and not required | |
# in production environments by default. | |
diff --git a/web/Gemfile.lock b/web/Gemfile.lock | |
@@ -48,6 +48,7 @@ GEM | |
railties (>= 3.1.0, < 5.0) | |
thor (~> 0.14) | |
json (1.7.5) | |
+ kissfft (0.0.1) | |
libv8 (3.3.10.4) | |
mail (2.4.4) | |
i18n (>= 0.4.0) | |
@@ -111,6 +112,7 @@ DEPENDENCIES | |
coffee-rails (~> 3.2.1) | |
dynamic_form | |
jquery-rails | |
+ kissfft | |
pg (= 0.11) | |
rails (= 3.2.8) | |
sass-rails (~> 3.2.3) |