/* ruby-kissfft: a simple ruby module embedding the Kiss FFT library Copyright (C) 2009-2010 Rapid7, Inc - H D Moore Derived from "psdpng.c" from the KissFFT tools directory Copyright (C) 2003-2006 Mark Borgerding */ #include "ruby.h" #include #include #include #include #include #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 @ %s(%d): %s\n",__FILE__,__LINE__,#p );exit(1);} while(0) static VALUE rbkiss_s_fftr(VALUE class, VALUE r_nfft, VALUE r_rate, VALUE r_buckets, VALUE r_data) { 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 + 2) ) ); 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= inp_len) { tbuf[i] = 0; } else { if(TYPE(RARRAY_PTR(r_data)[ inp_idx + i ]) != T_FIXNUM) { tbuf[i] = 0; } else { tbuf[i] = NUM2INT( RARRAY_PTR(r_data)[ inp_idx + i ] ); } } } /* do FFT */ kiss_fftr(cfg,tbuf,fbuf); for (i=0;i