Update of /cvsroot/pure-data/pd/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1688
Modified Files: Tag: devel_0_37 d_fft.c Log Message: fftw-interface changed from basic to guru
Index: d_fft.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/d_fft.c,v retrieving revision 1.1.1.1.16.1 retrieving revision 1.1.1.1.16.2 diff -C2 -d -r1.1.1.1.16.1 -r1.1.1.1.16.2 *** d_fft.c 2 Mar 2004 11:04:50 -0000 1.1.1.1.16.1 --- d_fft.c 5 Mar 2004 21:19:37 -0000 1.1.1.1.16.2 *************** *** 270,276 **** fftwf_plan plan; t_int bins; ! fftwf_complex * incomplex; ! fftwf_complex * outcomplex; ! } t_sigfftw;
--- 270,278 ---- fftwf_plan plan; t_int bins; ! fftwf_iodim dim; ! t_sample * inreal; ! t_sample * inimag; ! t_sample * outreal; ! t_sample * outimag; } t_sigfftw;
*************** *** 285,293 **** //get ready for the default blocksize x->bins=64; ! x->incomplex = fftwf_malloc(sizeof(fftw_complex) * x->bins); ! x->outcomplex = fftwf_malloc(sizeof(fftw_complex) * x->bins); ! x->plan = fftwf_plan_dft_1d(x->bins,x->incomplex,x->outcomplex, ! FFTW_FORWARD,FFTW_MEASURE); ! return (x); } --- 287,300 ---- //get ready for the default blocksize x->bins=64; ! x->inreal = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->inimag = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->outreal = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->outimag = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->dim.n=64; ! x->dim.is=1; ! x->dim.os=1; ! x->plan = fftwf_plan_guru_split_dft(1, &(x->dim), 0, NULL, x->inreal, ! x->inimag, x->outreal, x->outimag, ! FFTW_MEASURE); return (x); } *************** *** 303,310 **** //get ready for the default blocksize x->bins=64; ! x->incomplex = fftwf_malloc(sizeof(fftw_complex) * x->bins); ! x->outcomplex = fftwf_malloc(sizeof(fftw_complex) * x->bins); ! x->plan = fftwf_plan_dft_1d(x->bins,x->incomplex,x->outcomplex, ! FFTW_BACKWARD,FFTW_MEASURE); return (x); } --- 310,323 ---- //get ready for the default blocksize x->bins=64; ! x->inreal = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->inimag = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->outreal = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->outimag = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->dim.n=64; ! x->dim.is=1; ! x->dim.os=1; ! x->plan = fftwf_plan_guru_split_dft(1, &(x->dim), 0, NULL, x->inimag, ! x->inreal, x->outimag, x->outreal, ! FFTW_MEASURE); return (x); } *************** *** 312,325 **** static void sigfftw_free(t_sigfftw * x) { ! fftwf_free(x->incomplex); ! fftwf_free(x->outcomplex); fftwf_destroy_plan(x->plan); - }
static void sigifftw_free(t_sigfftw * x) { ! fftwf_free(x->incomplex); ! fftwf_free(x->outcomplex); fftwf_destroy_plan(x->plan); } --- 325,341 ---- static void sigfftw_free(t_sigfftw * x) { ! fftwf_free(x->inreal); ! fftwf_free(x->inimag); ! fftwf_free(x->outreal); ! fftwf_free(x->outimag); fftwf_destroy_plan(x->plan); }
static void sigifftw_free(t_sigfftw * x) { ! fftwf_free(x->inreal); ! fftwf_free(x->inimag); ! fftwf_free(x->outreal); ! fftwf_free(x->outimag); fftwf_destroy_plan(x->plan); } *************** *** 337,370 **** { x->bins=n; ! //re-allocate fft buffers ! fftwf_free(x->incomplex); ! x->incomplex = fftwf_malloc(sizeof(fftwf_complex) * x->bins); ! fftwf_free(x->outcomplex); ! x->outcomplex = fftwf_malloc(sizeof(fftwf_complex) * x->bins); ! //set plan, this might take a few seconds //but you don't have to do that on the fly... fftwf_destroy_plan(x->plan); ! x->plan = fftwf_plan_dft_1d(x->bins,x->incomplex,x->outcomplex, ! FFTW_FORWARD,FFTW_MEASURE); ! } ! ! t_int i=n; ! while(i!=0) ! { ! --i; ! x->incomplex[i][0]=*(in1+i); ! x->incomplex[i][1]=*(in2+i); } - fftwf_execute(x->plan);
! i=n; ! while(i!=0) ! { ! --i; ! *(out1+i)=x->outcomplex[i][0]; ! *(out2+i)=x->outcomplex[i][1]; ! }
return (w+7); --- 353,382 ---- { x->bins=n; ! x->dim.n=n; ! //re-allocate fft buffers ! fftwf_free(x->inreal); ! fftwf_free(x->inimag); ! fftwf_free(x->outreal); ! fftwf_free(x->outimag); ! x->inreal = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->inimag = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->outreal = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->outimag = fftwf_malloc(sizeof(t_sample) * x->bins); ! //set plan, this might take a few seconds //but you don't have to do that on the fly... fftwf_destroy_plan(x->plan); ! x->plan = fftwf_plan_guru_split_dft(1, &(x->dim), 0, NULL, x->inreal, ! x->inimag, x->outreal, x->outimag, ! FFTW_MEASURE); }
! //prepare, execute and output results ! memcpy(x->inreal,in1,(sizeof(t_sample) * x->bins)); ! memcpy(x->inimag,in2,(sizeof(t_sample) * x->bins)); ! fftwf_execute(x->plan); ! memcpy(out1,x->outreal,(sizeof(t_sample) * x->bins)); ! memcpy(out2,x->outimag,(sizeof(t_sample) * x->bins));
return (w+7); *************** *** 383,419 **** { x->bins=n; ! //re-allocate fft buffers ! fftwf_free(x->incomplex); ! x->incomplex = fftwf_malloc(sizeof(fftwf_complex) * x->bins); ! fftwf_free(x->outcomplex); ! x->outcomplex = fftwf_malloc(sizeof(fftwf_complex) * x->bins); ! //set plan, this might take a few seconds //but you don't have to do that on the fly... fftwf_destroy_plan(x->plan); ! x->plan = fftwf_plan_dft_1d(x->bins,x->incomplex,x->outcomplex, ! FFTW_BACKWARD,FFTW_MEASURE); ! } ! ! t_int i=n; ! while(i!=0) ! { ! --i; ! x->incomplex[i][0]=*(in1+i); ! x->incomplex[i][1]=*(in2+i); } - fftwf_execute(x->plan);
! i=n; ! while(i!=0) ! { ! --i; ! *(out1+i)=x->outcomplex[i][0]; ! *(out2+i)=x->outcomplex[i][1]; ! }
return (w+7); - }
--- 395,426 ---- { x->bins=n; ! x->dim.n=n; ! //re-allocate fft buffers ! fftwf_free(x->inreal); ! fftwf_free(x->inimag); ! fftwf_free(x->outreal); ! fftwf_free(x->outimag); ! x->inreal = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->inimag = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->outreal = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->outimag = fftwf_malloc(sizeof(t_sample) * x->bins); ! //set plan, this might take a few seconds //but you don't have to do that on the fly... fftwf_destroy_plan(x->plan); ! x->plan = fftwf_plan_guru_split_dft(1, &(x->dim), 0, NULL, x->inimag, ! x->inreal, x->outimag, x->outreal, ! FFTW_MEASURE); }
! //prepare, execute and output results ! memcpy(x->inreal,in1,(sizeof(t_sample) * x->bins)); ! memcpy(x->inimag,in2,(sizeof(t_sample) * x->bins)); ! fftwf_execute(x->plan); ! memcpy(out1,x->outreal,(sizeof(t_sample) * x->bins)); ! memcpy(out2,x->outimag,(sizeof(t_sample) * x->bins));
return (w+7); }
*************** *** 454,457 **** --- 461,465 ---- gensym("dsp"), 0); class_sethelpsymbol(sigifftw_class, gensym("fft~")); + }
*************** *** 463,475 **** typedef struct rfftw { ! t_object x_obj; //me ! ! fftwf_plan plan; //fftw plan ! t_int bins; //number of bins ! t_sample * infft; //array fftw is working on ! t_sample * outfft; //array fftw uses to output it's values ! float x_f;
} t_sigrfftw;
--- 471,483 ---- typedef struct rfftw { ! t_object x_obj; float x_f;
+ fftwf_plan plan; + t_int bins; + fftwf_iodim dim; + t_sample * infft; + t_sample * outreal; + t_sample * outimag; } t_sigrfftw;
*************** *** 485,493 **** x->bins=64; x->infft = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->outfft = fftwf_malloc(sizeof(t_sample) * x->bins); ! //it seems that the halfcomplex transformation is a bit faster ! x->plan = fftwf_plan_r2r_1d(x->bins,x->infft,x->outfft, ! FFTW_FORWARD,FFTW_MEASURE); ! return (x); } --- 493,504 ---- x->bins=64; x->infft = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->outreal = fftwf_malloc(sizeof(t_sample) * (x->bins)/2); ! x->outimag = fftwf_malloc(sizeof(t_sample) * (x->bins)/2); ! x->dim.n=64; ! x->dim.is=1; ! x->dim.os=1; ! x->plan = fftwf_plan_guru_split_dft_r2c(1, &(x->dim), 0, NULL, x->infft, ! x->outreal, x->outimag, ! FFTW_MEASURE); return (x); } *************** *** 497,504 **** { fftwf_free(x->infft); ! fftwf_free(x->outfft); fftwf_destroy_plan(x->plan); }
static t_int *sigrfftw_perform(t_int *w) { --- 508,526 ---- { fftwf_free(x->infft); ! fftwf_free(x->outreal); ! fftwf_free(x->outimag); fftwf_destroy_plan(x->plan); }
+ //we don't want to return the complex conjugated result of the fft + static void sigrfftw_invert(t_sample * s, t_int n) + { + while (n!=0) + { + --n; + s[n]=-s[n]; + } + } + static t_int *sigrfftw_perform(t_int *w) { *************** *** 512,539 **** { x->bins=n; //re-allocate fft buffers fftwf_free(x->infft); ! x->infft = fftwf_malloc(sizeof(float) * x->bins); ! fftwf_free(x->outfft); ! x->outfft = fftwf_malloc(sizeof(float) * x->bins); ! //set plan, this might take a few seconds //but you don't have to do that on the fly... fftwf_destroy_plan(x->plan); ! x->plan = fftwf_plan_r2r_1d(x->bins,x->infft,x->outfft, ! FFTW_FORWARD,FFTW_MEASURE); }
memcpy(x->infft,in1,n*sizeof(t_sample)); fftwf_execute(x->plan); ! memcpy(out1,x->outfft,n/2*(sizeof(t_sample))); ! ! t_int i = n/2; ! while (i) ! { ! out2[i] = -(x->outfft[n-i]); ! --i; ! } return (w+6); } --- 534,562 ---- { x->bins=n; + x->dim.n=n; //re-allocate fft buffers fftwf_free(x->infft); ! fftwf_free(x->outreal); ! fftwf_free(x->outimag); ! x->infft = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->outreal = fftwf_malloc(sizeof(t_sample) * (x->bins)/2); ! x->outimag = fftwf_malloc(sizeof(t_sample) * (x->bins)/2); ! //set plan, this might take a few seconds //but you don't have to do that on the fly... fftwf_destroy_plan(x->plan); ! x->plan = fftwf_plan_guru_split_dft_r2c(1, &(x->dim), 0, NULL, ! x->infft, x->outreal, ! x->outimag, FFTW_MEASURE); }
+ //prepare, execute and output results memcpy(x->infft,in1,n*sizeof(t_sample)); fftwf_execute(x->plan); ! memcpy(out1,x->outreal,n/2*(sizeof(t_sample))); ! sigrfftw_invert(x->outimag,n/2); ! memcpy(out2,x->outimag,n/2*(sizeof(t_sample))); ! return (w+6); } *************** *** 576,591 **** typedef struct rifftw { ! t_object x_obj; //me ! ! fftwf_iodim iodim;
! fftwf_plan plan; //fftw plan ! t_int bins; //number of bins ! t_sample * infft; t_sample * inimag; t_sample * outfft; - - float x_f; - } t_sigrifftw;
--- 599,611 ---- typedef struct rifftw { ! t_object x_obj; ! float x_f;
! fftwf_plan plan; ! t_int bins; ! fftwf_iodim dim; ! t_sample * inreal; t_sample * inimag; t_sample * outfft; } t_sigrifftw;
*************** *** 600,613 **** //get ready for the default blocksize x->bins=64; ! x->infft = fftwf_malloc(sizeof(t_sample) * (x->bins)); ! //x->inimag = fftwf_malloc(sizeof(t_sample) * (x->bins)/2); x->outfft = fftwf_malloc(sizeof(t_sample) * x->bins); ! ! // x->iodim->1; ! ! x->plan = fftwf_plan_r2r_1d(x->bins,x->infft,x->outfft, ! FFTW_BACKWARD,FFTW_MEASURE); ! ! return (x); } --- 620,632 ---- //get ready for the default blocksize x->bins=64; ! x->inreal = fftwf_malloc(sizeof(t_sample) * (x->bins)/2); ! x->inimag = fftwf_malloc(sizeof(t_sample) * (x->bins)/2); x->outfft = fftwf_malloc(sizeof(t_sample) * x->bins); ! x->dim.n=64; ! x->dim.is=1; ! x->dim.os=1; ! x->plan = fftwf_plan_guru_split_dft_c2r(1, &(x->dim), 0, NULL, x->inreal, ! x->inimag, x->outfft, ! FFTW_MEASURE); return (x); } *************** *** 616,620 **** static void sigrifftw_free(t_sigrifftw *x) { ! fftwf_free(x->infft); fftwf_free(x->inimag); fftwf_free(x->outfft); --- 635,639 ---- static void sigrifftw_free(t_sigrifftw *x) { ! fftwf_free(x->inreal); fftwf_free(x->inimag); fftwf_free(x->outfft); *************** *** 633,663 **** { x->bins=n; ! //re-allocate fft buffers ! fftwf_free(x->infft); ! x->infft = fftwf_malloc(sizeof(float) * (x->bins)); ! //fftwf_free(x->inimag); ! //x->inimag = fftwf_malloc(sizeof(float) * (x->bins)/2); fftwf_free(x->outfft); ! x->outfft = fftwf_malloc(sizeof(float) * x->bins); //set plan, this might take a few seconds //but you don't have to do that on the fly... fftwf_destroy_plan(x->plan); ! x->plan = fftwf_plan_r2r_1d(x->bins,x->infft,x->outfft, ! FFTW_BACKWARD,FFTW_MEASURE); ! ! //x->plan = fftwf_plan_guru_split_dft_c2r(1,iodim ,x->bins,x->infft,x->outfft,FFTW_BACKWARD,FFTW_MEASURE); ! } ! ! memcpy(x->infft,in1,n/2*sizeof(t_sample)); ! ! t_int i = n/2; ! while (i!=n) ! { ! x->infft[i]=-in2[n-i]; ! ++i; }
fftwf_execute(x->plan); memcpy(out1,x->outfft,n*(sizeof(t_sample))); --- 652,677 ---- { x->bins=n; ! x->dim.n=n; ! //re-allocate fft buffers ! fftwf_free(x->inreal); ! fftwf_free(x->inimag); fftwf_free(x->outfft); ! x->inreal = fftwf_malloc(sizeof(t_sample) * (x->bins)/2); ! x->inimag = fftwf_malloc(sizeof(t_sample) * (x->bins)/2); ! x->outfft = fftwf_malloc(sizeof(t_sample) * x->bins); //set plan, this might take a few seconds //but you don't have to do that on the fly... fftwf_destroy_plan(x->plan); ! x->plan = fftwf_plan_guru_split_dft_c2r(1, &(x->dim), 0, NULL, ! x->inreal, x->inimag, ! x->outfft, FFTW_MEASURE); }
+ //prepare, execute and output results + memcpy(x->inreal,in1,n/2*sizeof(t_sample)); + memcpy(x->inimag,in2,n/2*sizeof(t_sample)); + sigrfftw_invert(x->inimag,n/2); fftwf_execute(x->plan); memcpy(out1,x->outfft,n*(sizeof(t_sample))); *************** *** 681,685 **** else dsp_add(sigrifftw_perform,5,x,in1,in2,out1,n); - }
--- 695,698 ----