00001 #include "qtsFFT.h"
00002 #include <cassert>
00003 #include <math.h>
00004
00005
00006
00007 qtsFFT::qtsFFT(long n) : _ftt_Real(n)
00008 {
00009 fftReal = new double[n];
00010 fftFreq = new double[n];
00011
00012 length = n;
00013 }
00014 qtsFFT::~qtsFFT()
00015 {
00016 delete [] fftReal;
00017 delete [] fftFreq;
00018 }
00019
00020 PlotLine * qtsFFT::do_FFTqts(PlotLine *r)
00021 {
00022
00023 PlotLine * result = new PlotLine;
00024
00025 int i = 0;
00026
00027 for (i = 0; i < length; i++)
00028 {
00029 fftReal[i] = r->getData(i);
00030 }
00031
00032 _ftt_Real.do_fft(fftFreq, fftReal);
00033
00034 for (i = 0; i < length; i++)
00035 {
00036 result->append(fftFreq[i]);
00037 }
00038
00039 return result;
00040 }
00041
00042 PlotLine *qtsFFT::do_iFFTqts(PlotLine *f)
00043 {
00044 PlotLine * result = new PlotLine;
00045
00046 int i = 0;
00047
00048 for (i = 0; i < length; i++)
00049 {
00050 fftFreq[i] = f->getData(i);
00051 }
00052
00053 _ftt_Real.do_ifft(fftFreq, fftReal);
00054 _ftt_Real.rescale(fftReal);
00055
00056 for (i = 0; i < length; i++)
00057 {
00058 result->append(fftReal[i]);
00059 }
00060
00061 return result;
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 qtsFFT::FFTReal::FFTReal (const long length)
00078 : _length (length)
00079 , _nbr_bits (int (floor (log (length) / log (2) + 0.5)))
00080 , _bit_rev_lut (int (floor (log (length) / log (2) + 0.5)))
00081 , _trigo_lut (int (floor (log (length) / log (2) + 0.5)))
00082 , _sqrt2_2 (flt_t (sqrt (2) * 0.5))
00083 {
00084 assert ((1L << _nbr_bits) == length);
00085
00086 _buffer_ptr = 0;
00087 if (_nbr_bits > 2)
00088 {
00089 _buffer_ptr = new flt_t [_length];
00090 }
00091 }
00092
00093 qtsFFT::FFTReal::~FFTReal (void)
00094 {
00095 delete [] _buffer_ptr;
00096 _buffer_ptr = 0;
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 void qtsFFT::FFTReal::do_fft (flt_t f [], const flt_t x []) const
00113 {
00114
00115
00116
00117
00118
00119
00120
00121 if (_nbr_bits > 2)
00122 {
00123 flt_t * sf;
00124 flt_t * df;
00125
00126 if (_nbr_bits & 1)
00127 {
00128 df = _buffer_ptr;
00129 sf = f;
00130 }
00131 else
00132 {
00133 df = f;
00134 sf = _buffer_ptr;
00135 }
00136
00137
00138 {
00139 int pass;
00140 long nbr_coef;
00141 long h_nbr_coef;
00142 long d_nbr_coef;
00143 long coef_index;
00144
00145
00146 {
00147 const long * const bit_rev_lut_ptr = _bit_rev_lut.get_ptr ();
00148 coef_index = 0;
00149 do
00150 {
00151 const long rev_index_0 = bit_rev_lut_ptr [coef_index];
00152 const long rev_index_1 = bit_rev_lut_ptr [coef_index + 1];
00153 const long rev_index_2 = bit_rev_lut_ptr [coef_index + 2];
00154 const long rev_index_3 = bit_rev_lut_ptr [coef_index + 3];
00155
00156 flt_t * const df2 = df + coef_index;
00157 df2 [1] = x [rev_index_0] - x [rev_index_1];
00158 df2 [3] = x [rev_index_2] - x [rev_index_3];
00159
00160 const flt_t sf_0 = x [rev_index_0] + x [rev_index_1];
00161 const flt_t sf_2 = x [rev_index_2] + x [rev_index_3];
00162
00163 df2 [0] = sf_0 + sf_2;
00164 df2 [2] = sf_0 - sf_2;
00165
00166 coef_index += 4;
00167 }
00168 while (coef_index < _length);
00169 }
00170
00171
00172 {
00173 coef_index = 0;
00174 const flt_t sqrt2_2 = _sqrt2_2;
00175 do
00176 {
00177 flt_t v;
00178
00179 sf [coef_index] = df [coef_index] + df [coef_index + 4];
00180 sf [coef_index + 4] = df [coef_index] - df [coef_index + 4];
00181 sf [coef_index + 2] = df [coef_index + 2];
00182 sf [coef_index + 6] = df [coef_index + 6];
00183
00184 v = (df [coef_index + 5] - df [coef_index + 7]) * sqrt2_2;
00185 sf [coef_index + 1] = df [coef_index + 1] + v;
00186 sf [coef_index + 3] = df [coef_index + 1] - v;
00187
00188 v = (df [coef_index + 5] + df [coef_index + 7]) * sqrt2_2;
00189 sf [coef_index + 5] = v + df [coef_index + 3];
00190 sf [coef_index + 7] = v - df [coef_index + 3];
00191
00192 coef_index += 8;
00193 }
00194 while (coef_index < _length);
00195 }
00196
00197
00198 for (pass = 3; pass < _nbr_bits; ++pass)
00199 {
00200 coef_index = 0;
00201 nbr_coef = 1 << pass;
00202 h_nbr_coef = nbr_coef >> 1;
00203 d_nbr_coef = nbr_coef << 1;
00204 const flt_t * const cos_ptr = _trigo_lut.get_ptr (pass);
00205 do
00206 {
00207 long i;
00208 const flt_t * const sf1r = sf + coef_index;
00209 const flt_t * const sf2r = sf1r + nbr_coef;
00210 flt_t * const dfr = df + coef_index;
00211 flt_t * const dfi = dfr + nbr_coef;
00212
00213
00214 dfr [0] = sf1r [0] + sf2r [0];
00215 dfi [0] = sf1r [0] - sf2r [0];
00216 dfr [h_nbr_coef] = sf1r [h_nbr_coef];
00217 dfi [h_nbr_coef] = sf2r [h_nbr_coef];
00218
00219
00220 const flt_t * const sf1i = sf1r + h_nbr_coef;
00221 const flt_t * const sf2i = sf1i + nbr_coef;
00222 for (i = 1; i < h_nbr_coef; ++ i)
00223 {
00224 const flt_t c = cos_ptr [i];
00225 const flt_t s = cos_ptr [h_nbr_coef - i];
00226 flt_t v;
00227
00228 v = sf2r [i] * c - sf2i [i] * s;
00229 dfr [i] = sf1r [i] + v;
00230 dfi [-i] = sf1r [i] - v;
00231
00232 v = sf2r [i] * s + sf2i [i] * c;
00233 dfi [i] = v + sf1i [i];
00234 dfi [nbr_coef - i] = v - sf1i [i];
00235 }
00236
00237 coef_index += d_nbr_coef;
00238 }
00239 while (coef_index < _length);
00240
00241
00242 {
00243 flt_t * const temp_ptr = df;
00244 df = sf;
00245 sf = temp_ptr;
00246 }
00247 }
00248 }
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258 else if (_nbr_bits == 2)
00259 {
00260 f [1] = x [0] - x [2];
00261 f [3] = x [1] - x [3];
00262
00263 const flt_t b_0 = x [0] + x [2];
00264 const flt_t b_2 = x [1] + x [3];
00265
00266 f [0] = b_0 + b_2;
00267 f [2] = b_0 - b_2;
00268 }
00269
00270
00271 else if (_nbr_bits == 1)
00272 {
00273 f [0] = x [0] + x [1];
00274 f [1] = x [0] - x [1];
00275 }
00276
00277
00278 else
00279 {
00280 f [0] = x [0];
00281 }
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 void qtsFFT::FFTReal::do_ifft (const flt_t f [], flt_t x []) const
00302 {
00303
00304
00305
00306
00307
00308
00309
00310 if (_nbr_bits > 2)
00311 {
00312 flt_t * sf = const_cast <flt_t *> (f);
00313 flt_t * df;
00314 flt_t * df_temp;
00315
00316 if (_nbr_bits & 1)
00317 {
00318 df = _buffer_ptr;
00319 df_temp = x;
00320 }
00321 else
00322 {
00323 df = x;
00324 df_temp = _buffer_ptr;
00325 }
00326
00327
00328 {
00329 int pass;
00330 long nbr_coef;
00331 long h_nbr_coef;
00332 long d_nbr_coef;
00333 long coef_index;
00334
00335
00336 for (pass = _nbr_bits - 1; pass >= 3; --pass)
00337 {
00338 coef_index = 0;
00339 nbr_coef = 1 << pass;
00340 h_nbr_coef = nbr_coef >> 1;
00341 d_nbr_coef = nbr_coef << 1;
00342 const flt_t *const cos_ptr = _trigo_lut.get_ptr (pass);
00343 do
00344 {
00345 long i;
00346 const flt_t * const sfr = sf + coef_index;
00347 const flt_t * const sfi = sfr + nbr_coef;
00348 flt_t * const df1r = df + coef_index;
00349 flt_t * const df2r = df1r + nbr_coef;
00350
00351
00352 df1r [0] = sfr [0] + sfi [0];
00353 df2r [0] = sfr [0] - sfi [0];
00354 df1r [h_nbr_coef] = sfr [h_nbr_coef] * 2;
00355 df2r [h_nbr_coef] = sfi [h_nbr_coef] * 2;
00356
00357
00358 flt_t * const df1i = df1r + h_nbr_coef;
00359 flt_t * const df2i = df1i + nbr_coef;
00360 for (i = 1; i < h_nbr_coef; ++ i)
00361 {
00362 df1r [i] = sfr [i] + sfi [-i];
00363 df1i [i] = sfi [i] - sfi [nbr_coef - i];
00364
00365 const flt_t c = cos_ptr [i];
00366 const flt_t s = cos_ptr [h_nbr_coef - i];
00367 const flt_t vr = sfr [i] - sfi [-i];
00368 const flt_t vi = sfi [i] + sfi [nbr_coef - i];
00369
00370 df2r [i] = vr * c + vi * s;
00371 df2i [i] = vi * c - vr * s;
00372 }
00373
00374 coef_index += d_nbr_coef;
00375 }
00376 while (coef_index < _length);
00377
00378
00379 if (pass < _nbr_bits - 1)
00380 {
00381 flt_t * const temp_ptr = df;
00382 df = sf;
00383 sf = temp_ptr;
00384 }
00385 else
00386 {
00387 sf = df;
00388 df = df_temp;
00389 }
00390 }
00391
00392
00393 {
00394 const flt_t sqrt2_2 = _sqrt2_2;
00395 coef_index = 0;
00396 do
00397 {
00398 df [coef_index] = sf [coef_index] + sf [coef_index + 4];
00399 df [coef_index + 4] = sf [coef_index] - sf [coef_index + 4];
00400 df [coef_index + 2] = sf [coef_index + 2] * 2;
00401 df [coef_index + 6] = sf [coef_index + 6] * 2;
00402
00403 df [coef_index + 1] = sf [coef_index + 1] + sf [coef_index + 3];
00404 df [coef_index + 3] = sf [coef_index + 5] - sf [coef_index + 7];
00405
00406 const flt_t vr = sf [coef_index + 1] - sf [coef_index + 3];
00407 const flt_t vi = sf [coef_index + 5] + sf [coef_index + 7];
00408
00409 df [coef_index + 5] = (vr + vi) * sqrt2_2;
00410 df [coef_index + 7] = (vi - vr) * sqrt2_2;
00411
00412 coef_index += 8;
00413 }
00414 while (coef_index < _length);
00415 }
00416
00417
00418 {
00419 coef_index = 0;
00420 const long * bit_rev_lut_ptr = _bit_rev_lut.get_ptr ();
00421 const flt_t * sf2 = df;
00422 do
00423 {
00424 {
00425 const flt_t b_0 = sf2 [0] + sf2 [2];
00426 const flt_t b_2 = sf2 [0] - sf2 [2];
00427 const flt_t b_1 = sf2 [1] * 2;
00428 const flt_t b_3 = sf2 [3] * 2;
00429
00430 x [bit_rev_lut_ptr [0]] = b_0 + b_1;
00431 x [bit_rev_lut_ptr [1]] = b_0 - b_1;
00432 x [bit_rev_lut_ptr [2]] = b_2 + b_3;
00433 x [bit_rev_lut_ptr [3]] = b_2 - b_3;
00434 }
00435 {
00436 const flt_t b_0 = sf2 [4] + sf2 [6];
00437 const flt_t b_2 = sf2 [4] - sf2 [6];
00438 const flt_t b_1 = sf2 [5] * 2;
00439 const flt_t b_3 = sf2 [7] * 2;
00440
00441 x [bit_rev_lut_ptr [4]] = b_0 + b_1;
00442 x [bit_rev_lut_ptr [5]] = b_0 - b_1;
00443 x [bit_rev_lut_ptr [6]] = b_2 + b_3;
00444 x [bit_rev_lut_ptr [7]] = b_2 - b_3;
00445 }
00446
00447 sf2 += 8;
00448 coef_index += 8;
00449 bit_rev_lut_ptr += 8;
00450 }
00451 while (coef_index < _length);
00452 }
00453 }
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463 else if (_nbr_bits == 2)
00464 {
00465 const flt_t b_0 = f [0] + f [2];
00466 const flt_t b_2 = f [0] - f [2];
00467
00468 x [0] = b_0 + f [1] * 2;
00469 x [2] = b_0 - f [1] * 2;
00470 x [1] = b_2 + f [3] * 2;
00471 x [3] = b_2 - f [3] * 2;
00472 }
00473
00474
00475 else if (_nbr_bits == 1)
00476 {
00477 x [0] = f [0] + f [1];
00478 x [1] = f [0] - f [1];
00479 }
00480
00481
00482 else
00483 {
00484 x [0] = f [0];
00485 }
00486 }
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 void qtsFFT::FFTReal::rescale (flt_t x []) const
00500 {
00501 const flt_t mul = flt_t (1.0 / _length);
00502 long i = _length - 1;
00503
00504 do
00505 {
00506 x [i] *= mul;
00507 --i;
00508 }
00509 while (i >= 0);
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 qtsFFT::FFTReal::BitReversedLUT::BitReversedLUT (const int nbr_bits)
00523 {
00524 long length;
00525 long cnt;
00526 long br_index;
00527 long bit;
00528
00529 length = 1L << nbr_bits;
00530 _ptr = new long [length];
00531
00532 br_index = 0;
00533 _ptr [0] = 0;
00534 for (cnt = 1; cnt < length; ++cnt)
00535 {
00536
00537 bit = length >> 1;
00538 while (((br_index ^= bit) & bit) == 0)
00539 {
00540 bit >>= 1;
00541 }
00542
00543 _ptr [cnt] = br_index;
00544 }
00545 }
00546
00547
00548 qtsFFT::FFTReal::BitReversedLUT::~BitReversedLUT (void)
00549 {
00550 delete [] _ptr;
00551 _ptr = 0;
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 qtsFFT::FFTReal::TrigoLUT::TrigoLUT (const int nbr_bits)
00566 {
00567 long total_len;
00568
00569 _ptr = 0;
00570 if (nbr_bits > 3)
00571 {
00572 total_len = (1L << (nbr_bits - 1)) - 4;
00573 _ptr = new flt_t [total_len];
00574
00575 const double PI = atan (1) * 4;
00576 for (int level = 3; level < nbr_bits; ++level)
00577 {
00578 const long level_len = 1L << (level - 1);
00579 flt_t * const level_ptr = const_cast<flt_t *> (get_ptr (level));
00580 const double mul = PI / (level_len << 1);
00581
00582 for (long i = 0; i < level_len; ++ i)
00583 {
00584 level_ptr [i] = (flt_t) cos (i * mul);
00585 }
00586 }
00587 }
00588 }
00589
00590 qtsFFT::FFTReal::TrigoLUT::~TrigoLUT (void)
00591 {
00592 delete [] _ptr;
00593 _ptr = 0;
00594 }
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616