| [658] | 1 | #include "fftserver.h" | 
|---|
|  | 2 | #include <iostream.h> | 
|---|
|  | 3 |  | 
|---|
|  | 4 | extern "C" { | 
|---|
|  | 5 | int rffti_(int *n, float *wsave);             //fftpack functions | 
|---|
|  | 6 | int rfftf_(int *n, float *r__, float *wsave); | 
|---|
|  | 7 | int rfftb_(int *n, float *r__, float *wsave); | 
|---|
|  | 8 | int dffti_(int *n, double *wsave); | 
|---|
|  | 9 | int dfftf_(int *n, double *r__, double *wsave); | 
|---|
|  | 10 | int dfftb_(int *n, double *r__, double *wsave); | 
|---|
|  | 11 | int cffti_(int *n, float *wsave); | 
|---|
|  | 12 | int cfftf_(int *n, float *c__, float *wsave); | 
|---|
|  | 13 | int cfftb_(int *n, float *c__, float *wsave); | 
|---|
|  | 14 | int cdffti_(int *n, double *wsave); | 
|---|
|  | 15 | int cdfftf_(int *n, double *c__, double *wsave); | 
|---|
|  | 16 | int cdfftb_(int *n, double *c__, double *wsave); | 
|---|
|  | 17 | } | 
|---|
|  | 18 |  | 
|---|
|  | 19 | FFTServer::FFTServer() | 
|---|
|  | 20 | { | 
|---|
|  | 21 | sz_rfft = 0;     //the working array and its size for the different | 
|---|
|  | 22 | ws_rfft = NULL;  //possible numerical types | 
|---|
|  | 23 | sz_cfft = 0; | 
|---|
|  | 24 | ws_cfft = NULL; | 
|---|
|  | 25 | sz_cdfft = 0; | 
|---|
|  | 26 | ws_cdfft = NULL; | 
|---|
|  | 27 | } | 
|---|
|  | 28 |  | 
|---|
|  | 29 | FFTServer::~FFTServer() | 
|---|
|  | 30 | { | 
|---|
|  | 31 | if (ws_rfft) delete[] ws_rfft; | 
|---|
|  | 32 | if (ws_cfft) delete[] ws_cfft; | 
|---|
|  | 33 | if (ws_cdfft) delete[] ws_cdfft; | 
|---|
|  | 34 | } | 
|---|
|  | 35 |  | 
|---|
|  | 36 | void FFTServer::checkint_rfft(int l) | 
|---|
|  | 37 | { | 
|---|
|  | 38 | if (sz_rfft == l) return;       //checkint functions check and reallocate | 
|---|
|  | 39 | //memory for the work arrays when performing | 
|---|
|  | 40 | if (ws_rfft) delete[] ws_rfft;  //a transform | 
|---|
|  | 41 | sz_rfft = l; | 
|---|
|  | 42 | ws_rfft = new float[2*l+15]; | 
|---|
|  | 43 | rffti_(&l, ws_rfft); | 
|---|
|  | 44 | } | 
|---|
|  | 45 |  | 
|---|
|  | 46 | void FFTServer::checkint_cfft(int l) | 
|---|
|  | 47 | { | 
|---|
|  | 48 | if (sz_cfft == l) return; | 
|---|
|  | 49 |  | 
|---|
|  | 50 | if (ws_cfft) delete[] ws_cfft; | 
|---|
|  | 51 | sz_cfft = l; | 
|---|
|  | 52 | ws_cfft = new float[4*l+15]; | 
|---|
|  | 53 | cffti_(&l, ws_cfft); | 
|---|
|  | 54 | } | 
|---|
|  | 55 |  | 
|---|
|  | 56 | void FFTServer::checkint_dfft(int l) | 
|---|
|  | 57 | { | 
|---|
|  | 58 | if (sz_dfft == l) return; | 
|---|
|  | 59 |  | 
|---|
|  | 60 | if (ws_dfft) delete[] ws_dfft; | 
|---|
|  | 61 | sz_dfft = l; | 
|---|
|  | 62 | ws_dfft = new double[2*l+15]; | 
|---|
|  | 63 | dffti_(&l, ws_dfft); | 
|---|
|  | 64 | } | 
|---|
|  | 65 |  | 
|---|
|  | 66 | void FFTServer::checkint_cdfft(int l) | 
|---|
|  | 67 | { | 
|---|
|  | 68 | if (sz_cdfft == l) return; | 
|---|
|  | 69 |  | 
|---|
|  | 70 | if (ws_cdfft) delete[] ws_cdfft; | 
|---|
|  | 71 | sz_cdfft = l; | 
|---|
|  | 72 | ws_cdfft = new double[4*l+15]; | 
|---|
|  | 73 | cdffti_(&l, ws_cdfft); | 
|---|
|  | 74 | } | 
|---|
|  | 75 |  | 
|---|
|  | 76 | /* In general forward transformations are resorted since fftpack functions | 
|---|
|  | 77 | return inverse transformations */ | 
|---|
|  | 78 |  | 
|---|
|  | 79 | void FFTServer::fftf(int l, float* inout) | 
|---|
|  | 80 | { | 
|---|
|  | 81 | checkint_rfft(l); | 
|---|
|  | 82 | rfftf_(&l, inout, ws_rfft); | 
|---|
|  | 83 | for (int k= 2;k<=(l+1)/2;k++) inout[2*k-2]=-inout[2*k-2]; | 
|---|
|  | 84 | } | 
|---|
|  | 85 |  | 
|---|
|  | 86 | void FFTServer::fftf(int l, double* inout) | 
|---|
|  | 87 | { | 
|---|
|  | 88 | checkint_dfft(l); | 
|---|
|  | 89 | dfftf_(&l, inout, ws_dfft); | 
|---|
|  | 90 | for (int k= 2;k<=(l+1)/2;k++) inout[2*k-2]=-inout[2*k-2]; | 
|---|
|  | 91 | } | 
|---|
|  | 92 |  | 
|---|
|  | 93 | void FFTServer::fftf(int l, complex<float>* inout) | 
|---|
|  | 94 | { | 
|---|
|  | 95 | checkint_cfft(l); | 
|---|
|  | 96 | float* foo = new float[2*l]; | 
|---|
|  | 97 | int i; | 
|---|
|  | 98 | for (i=0;i<l;i++){ | 
|---|
|  | 99 | foo[2*i]=inout[i].real(); | 
|---|
|  | 100 | foo[2*i+1]=inout[i].imag(); | 
|---|
|  | 101 | } | 
|---|
|  | 102 | cfftf_(&l, foo, ws_cfft); | 
|---|
|  | 103 | inout[0]=complex<float> (foo[0],foo[1]); | 
|---|
|  | 104 | for (i=1;i<l;i++) inout[l-i]= complex<float> (foo[2*i], foo[2*i+1]); | 
|---|
|  | 105 | delete[] foo; | 
|---|
|  | 106 | } | 
|---|
|  | 107 |  | 
|---|
|  | 108 | void FFTServer::fftf(int l, complex<double>* inout) | 
|---|
|  | 109 | { | 
|---|
|  | 110 | checkint_cdfft(l); | 
|---|
|  | 111 | double* foo=new double[2*l]; | 
|---|
|  | 112 | int i; | 
|---|
|  | 113 | for (i=0;i<l;i++){ | 
|---|
|  | 114 | foo[2*i]=inout[i].real(); | 
|---|
|  | 115 | foo[2*i+1]=inout[i].imag(); | 
|---|
|  | 116 | } | 
|---|
|  | 117 | cdfftf_(&l, foo, ws_cdfft); | 
|---|
|  | 118 | inout[0]=complex<double> (foo[0],foo[1]); | 
|---|
|  | 119 | for (i=1;i<l;i++) { | 
|---|
|  | 120 | inout[l-i]= complex<double> (foo[2*i],foo[2*i+1]); | 
|---|
|  | 121 | } | 
|---|
|  | 122 | delete[] foo; | 
|---|
|  | 123 | } | 
|---|
|  | 124 |  | 
|---|
|  | 125 | void FFTServer::fftb(int l, float* inout) | 
|---|
|  | 126 | { | 
|---|
|  | 127 | checkint_rfft(l); | 
|---|
|  | 128 | rfftf_(&l, inout, ws_rfft); | 
|---|
|  | 129 | } | 
|---|
|  | 130 |  | 
|---|
|  | 131 | void FFTServer::fftb(int l, double* inout) | 
|---|
|  | 132 | { | 
|---|
|  | 133 | checkint_dfft(l); | 
|---|
|  | 134 | dfftf_(&l, inout, ws_dfft); | 
|---|
|  | 135 | } | 
|---|
|  | 136 |  | 
|---|
|  | 137 | void FFTServer::fftb(int l, complex<float>* inout) | 
|---|
|  | 138 | { | 
|---|
|  | 139 | checkint_cfft(l); | 
|---|
|  | 140 | float* foo = new float[2*l]; | 
|---|
|  | 141 | int i; | 
|---|
|  | 142 | for (i=0;i<l;i++){ | 
|---|
|  | 143 | foo[2*i]=inout[i].real(); | 
|---|
|  | 144 | foo[2*i+1]=inout[i].imag(); | 
|---|
|  | 145 | } | 
|---|
|  | 146 | cfftf_(&l, foo, ws_cfft); | 
|---|
|  | 147 | for (i=0;i<l;i++) inout[i]=complex<float> (foo[2*i],foo[2*i+1]); | 
|---|
|  | 148 | delete[] foo; | 
|---|
|  | 149 | } | 
|---|
|  | 150 |  | 
|---|
|  | 151 | void FFTServer::fftb(int l, complex<double>* inout) | 
|---|
|  | 152 | { | 
|---|
|  | 153 | checkint_cdfft(l); | 
|---|
|  | 154 | double* foo = new double[2*l]; | 
|---|
|  | 155 | int i; | 
|---|
|  | 156 | for (i=0;i<l;i++){ | 
|---|
|  | 157 | foo[2*i]=inout[i].real(); | 
|---|
|  | 158 | foo[2*i+1]=inout[i].imag(); | 
|---|
|  | 159 | } | 
|---|
|  | 160 | cdfftf_(&l, foo, ws_cdfft); | 
|---|
|  | 161 | for (i=0;i<l;i++) inout[i]=complex<double> (foo[2*i],foo[2*i+1]); | 
|---|
|  | 162 | delete[] foo; | 
|---|
|  | 163 | } | 
|---|
|  | 164 |  | 
|---|
|  | 165 | void FFTServer::fftf(Vector& in, Vector& out) | 
|---|
|  | 166 | { | 
|---|
|  | 167 | int l = in.NElts(); | 
|---|
|  | 168 | /* ----- Si c'etait un Vector<float> on aurait ecrit comme ca | 
|---|
|  | 169 | Pour le moment Vector est double, on passe donc par un tableau | 
|---|
|  | 170 | intermediare | 
|---|
|  | 171 | // La transformee sur le tableau de flaot se fait en place, | 
|---|
|  | 172 | // on utilise donc out comme in-out | 
|---|
|  | 173 | out = in; | 
|---|
|  | 174 | fftf_float(l, out.Data() ); | 
|---|
|  | 175 | ------------------------------------------------------------- */ | 
|---|
|  | 176 | float * inout = new float[l]; | 
|---|
|  | 177 | int i; | 
|---|
|  | 178 | for(i=0; i<l; i++) inout[i] = in(i); | 
|---|
|  | 179 | fftf(l, inout); | 
|---|
|  | 180 | out.Realloc(l); | 
|---|
|  | 181 | for(i=0; i<l; i++) out(i) = inout[i]; | 
|---|
|  | 182 | } | 
|---|
|  | 183 |  | 
|---|
|  | 184 | void FFTServer::fftb(Vector& in, Vector& out) | 
|---|
|  | 185 | { | 
|---|
|  | 186 | int l = in.NElts(); | 
|---|
|  | 187 | /* ----- Si c'etait un Vector<float> on aurait ecrit comme ca | 
|---|
|  | 188 | Pour le moment Vector est double, on passe donc par un tableau | 
|---|
|  | 189 | intermediare | 
|---|
|  | 190 | // La transformee sur le tableau de flaot se fait en place, | 
|---|
|  | 191 | // on utilise donc out comme in-out | 
|---|
|  | 192 | out = in; | 
|---|
|  | 193 | fftf_float(l, out.Data() ); | 
|---|
|  | 194 | ------------------------------------------------------------- */ | 
|---|
|  | 195 | float * inout = new float[l]; | 
|---|
|  | 196 | int i; | 
|---|
|  | 197 | for(i=0; i<l; i++) inout[i] = in(i); | 
|---|
|  | 198 | fftb(l, inout); | 
|---|
|  | 199 | out.Realloc(l); | 
|---|
|  | 200 | for(i=0; i<l; i++) out(i) = inout[i]; | 
|---|
|  | 201 | } | 
|---|
|  | 202 |  | 
|---|