18 #if defined (ffft_FFTReal_CURRENT_CODEHEADER)
19 #error Recursive inclusion of FFTReal code header.
21 #define ffft_FFTReal_CURRENT_CODEHEADER
23 #if ! defined (ffft_FFTReal_CODEHEADER_INCLUDED)
24 #define ffft_FFTReal_CODEHEADER_INCLUDED
40 static inline bool FFTReal_is_pow2 (
long x)
44 return ((x & -x) == x);
49 static inline int FFTReal_get_next_pow2 (
long x)
54 while ((x & ~0xFFFFL) != 0)
59 while ((x & ~0xFL) != 0)
92 , _nbr_bits (FFTReal_get_next_pow2 (length))
98 assert (FFTReal_is_pow2 (length));
99 assert (_nbr_bits <= MAX_BIT_DEPTH);
146 assert (f != use_buffer ());
148 assert (x != use_buffer ());
154 compute_fft_general (f, x);
158 else if (_nbr_bits == 2)
160 f [1] = x [0] - x [2];
161 f [3] = x [1] - x [3];
171 else if (_nbr_bits == 1)
173 f [0] = x [0] + x [1];
174 f [1] = x [0] - x [1];
207 assert (f != use_buffer ());
209 assert (x != use_buffer ());
215 compute_ifft_general (f, x);
219 else if (_nbr_bits == 2)
224 x [0] = b_0 + f [1] * 2;
225 x [2] = b_0 - f [1] * 2;
226 x [1] = b_2 + f [3] * 2;
227 x [3] = b_2 - f [3] * 2;
231 else if (_nbr_bits == 1)
233 x [0] = f [0] + f [1];
234 x [1] = f [0] - f [1];
265 long i = _length - 1;
276 assert ((_length & 3) == 0);
279 long i = _length - 4;
312 return (&_buffer [0]);
328 const long length = 1L << _nbr_bits;
329 _br_lut.resize (length);
333 for (
long cnt = 1; cnt < length; ++cnt)
336 long bit = length >> 1;
337 while (((br_index ^= bit) & bit) == 0)
342 _br_lut [cnt] = br_index;
349 void FFTReal <DT>::init_trigo_lut ()
355 const long total_len = (1L << (_nbr_bits - 1)) - 4;
356 _trigo_lut.resize (total_len);
358 for (
int level = 3; level < _nbr_bits; ++level)
360 const long level_len = 1L << (level - 1);
361 DataType *
const level_ptr =
362 &_trigo_lut [get_trigo_level_index (level)];
363 const double mul =
PI / (level_len << 1);
365 for (
long i = 0;
i < level_len; ++
i)
367 level_ptr [
i] = static_cast <DataType> (cos (
i * mul));
376 void FFTReal <DT>::init_trigo_osc ()
378 const int nbr_osc = _nbr_bits - TRIGO_BD_LIMIT;
381 _trigo_osc.resize (nbr_osc);
383 for (
int osc_cnt = 0; osc_cnt < nbr_osc; ++osc_cnt)
385 OscType & osc = _trigo_osc [osc_cnt];
387 const long len = 1L << (TRIGO_BD_LIMIT + osc_cnt);
388 const double mul = (0.5 *
PI) / len;
397 const long * FFTReal <DT>::get_br_ptr ()
const
399 return (&_br_lut [0]);
405 const typename FFTReal <DT>::DataType * FFTReal <DT>::get_trigo_ptr (
int level)
const
409 return (&_trigo_lut [get_trigo_level_index (level)]);
415 long FFTReal <DT>::get_trigo_level_index (
int level)
const
419 return ((1L << (level - 1)) - 4);
426 void FFTReal <DT>::compute_fft_general (DataType f [],
const DataType x [])
const
429 assert (f != use_buffer ());
431 assert (x != use_buffer ());
437 if ((_nbr_bits & 1) != 0)
448 compute_direct_pass_1_2 (df, x);
449 compute_direct_pass_3 (sf, df);
451 for (
int pass = 3; pass < _nbr_bits; ++ pass)
453 compute_direct_pass_n (df, sf, pass);
455 DataType *
const temp_ptr = df;
464 void FFTReal <DT>::compute_direct_pass_1_2 (DataType df [],
const DataType x [])
const
470 const long *
const bit_rev_lut_ptr = get_br_ptr ();
474 const long rev_index_0 = bit_rev_lut_ptr [coef_index];
475 const long rev_index_1 = bit_rev_lut_ptr [coef_index + 1];
476 const long rev_index_2 = bit_rev_lut_ptr [coef_index + 2];
477 const long rev_index_3 = bit_rev_lut_ptr [coef_index + 3];
479 DataType *
const df2 = df + coef_index;
480 df2 [1] = x [rev_index_0] - x [rev_index_1];
481 df2 [3] = x [rev_index_2] - x [rev_index_3];
483 const DataType sf_0 = x [rev_index_0] + x [rev_index_1];
484 const DataType sf_2 = x [rev_index_2] + x [rev_index_3];
486 df2 [0] = sf_0 + sf_2;
487 df2 [2] = sf_0 - sf_2;
491 while (coef_index < _length);
497 void FFTReal <DT>::compute_direct_pass_3 (DataType df [],
const DataType sf [])
const
503 const DataType sqrt2_2 = DataType (
SQRT2 * 0.5);
509 df [coef_index] = sf [coef_index] + sf [coef_index + 4];
510 df [coef_index + 4] = sf [coef_index] - sf [coef_index + 4];
511 df [coef_index + 2] = sf [coef_index + 2];
512 df [coef_index + 6] = sf [coef_index + 6];
514 v = (sf [coef_index + 5] - sf [coef_index + 7]) * sqrt2_2;
515 df [coef_index + 1] = sf [coef_index + 1] + v;
516 df [coef_index + 3] = sf [coef_index + 1] - v;
518 v = (sf [coef_index + 5] + sf [coef_index + 7]) * sqrt2_2;
519 df [coef_index + 5] = v + sf [coef_index + 3];
520 df [coef_index + 7] = v - sf [coef_index + 3];
524 while (coef_index < _length);
530 void FFTReal <DT>::compute_direct_pass_n (DataType df [],
const DataType sf [],
int pass)
const
536 assert (pass < _nbr_bits);
538 if (pass <= TRIGO_BD_LIMIT)
540 compute_direct_pass_n_lut (df, sf, pass);
544 compute_direct_pass_n_osc (df, sf, pass);
551 void FFTReal <DT>::compute_direct_pass_n_lut (DataType df [],
const DataType sf [],
int pass)
const
557 assert (pass < _nbr_bits);
559 const long nbr_coef = 1 << pass;
560 const long h_nbr_coef = nbr_coef >> 1;
561 const long d_nbr_coef = nbr_coef << 1;
563 const DataType *
const cos_ptr = get_trigo_ptr (pass);
566 const DataType *
const sf1r = sf + coef_index;
567 const DataType *
const sf2r = sf1r + nbr_coef;
568 DataType *
const dfr = df + coef_index;
569 DataType *
const dfi = dfr + nbr_coef;
572 dfr [0] = sf1r [0] + sf2r [0];
573 dfi [0] = sf1r [0] - sf2r [0];
574 dfr [h_nbr_coef] = sf1r [h_nbr_coef];
575 dfi [h_nbr_coef] = sf2r [h_nbr_coef];
578 const DataType *
const sf1i = sf1r + h_nbr_coef;
579 const DataType *
const sf2i = sf1i + nbr_coef;
580 for (
long i = 1;
i < h_nbr_coef; ++
i)
582 const DataType c = cos_ptr [
i];
583 const DataType
s = cos_ptr [h_nbr_coef -
i];
586 v = sf2r [
i] * c - sf2i [
i] *
s;
587 dfr [
i] = sf1r [
i] + v;
588 dfi [-
i] = sf1r [
i] - v;
590 v = sf2r [
i] * s + sf2i [
i] * c;
591 dfi [
i] = v + sf1i [
i];
592 dfi [nbr_coef -
i] = v - sf1i [
i];
595 coef_index += d_nbr_coef;
597 while (coef_index < _length);
603 void FFTReal <DT>::compute_direct_pass_n_osc (DataType df [],
const DataType sf [],
int pass)
const
608 assert (pass > TRIGO_BD_LIMIT);
609 assert (pass < _nbr_bits);
611 const long nbr_coef = 1 << pass;
612 const long h_nbr_coef = nbr_coef >> 1;
613 const long d_nbr_coef = nbr_coef << 1;
615 OscType & osc = _trigo_osc [pass - (TRIGO_BD_LIMIT + 1)];
618 const DataType *
const sf1r = sf + coef_index;
619 const DataType *
const sf2r = sf1r + nbr_coef;
620 DataType *
const dfr = df + coef_index;
621 DataType *
const dfi = dfr + nbr_coef;
623 osc.clear_buffers ();
626 dfr [0] = sf1r [0] + sf2r [0];
627 dfi [0] = sf1r [0] - sf2r [0];
628 dfr [h_nbr_coef] = sf1r [h_nbr_coef];
629 dfi [h_nbr_coef] = sf2r [h_nbr_coef];
632 const DataType *
const sf1i = sf1r + h_nbr_coef;
633 const DataType *
const sf2i = sf1i + nbr_coef;
634 for (
long i = 1;
i < h_nbr_coef; ++
i)
637 const DataType c = osc.get_cos ();
638 const DataType
s = osc.get_sin ();
641 v = sf2r [
i] * c - sf2i [
i] *
s;
642 dfr [
i] = sf1r [
i] + v;
643 dfi [-
i] = sf1r [
i] - v;
645 v = sf2r [
i] * s + sf2i [
i] * c;
646 dfi [
i] = v + sf1i [
i];
647 dfi [nbr_coef -
i] = v - sf1i [
i];
650 coef_index += d_nbr_coef;
652 while (coef_index < _length);
659 void FFTReal <DT>::compute_ifft_general (
const DataType f [], DataType x [])
const
662 assert (f != use_buffer ());
664 assert (x != use_buffer ());
667 DataType * sf = const_cast <DataType *> (f);
679 df_temp = use_buffer ();
682 for (
int pass = _nbr_bits - 1; pass >= 3; -- pass)
684 compute_inverse_pass_n (df, sf, pass);
686 if (pass < _nbr_bits - 1)
688 DataType *
const temp_ptr = df;
699 compute_inverse_pass_3 (df, sf);
700 compute_inverse_pass_1_2 (x, df);
706 void FFTReal <DT>::compute_inverse_pass_n (DataType df [],
const DataType sf [],
int pass)
const
712 assert (pass < _nbr_bits);
714 if (pass <= TRIGO_BD_LIMIT)
716 compute_inverse_pass_n_lut (df, sf, pass);
720 compute_inverse_pass_n_osc (df, sf, pass);
727 void FFTReal <DT>::compute_inverse_pass_n_lut (DataType df [],
const DataType sf [],
int pass)
const
733 assert (pass < _nbr_bits);
735 const long nbr_coef = 1 << pass;
736 const long h_nbr_coef = nbr_coef >> 1;
737 const long d_nbr_coef = nbr_coef << 1;
739 const DataType *
const cos_ptr = get_trigo_ptr (pass);
742 const DataType *
const sfr = sf + coef_index;
743 const DataType *
const sfi = sfr + nbr_coef;
744 DataType *
const df1r = df + coef_index;
745 DataType *
const df2r = df1r + nbr_coef;
748 df1r [0] = sfr [0] + sfi [0];
749 df2r [0] = sfr [0] - sfi [0];
750 df1r [h_nbr_coef] = sfr [h_nbr_coef] * 2;
751 df2r [h_nbr_coef] = sfi [h_nbr_coef] * 2;
754 DataType *
const df1i = df1r + h_nbr_coef;
755 DataType *
const df2i = df1i + nbr_coef;
756 for (
long i = 1;
i < h_nbr_coef; ++
i)
758 df1r [
i] = sfr [
i] + sfi [-
i];
759 df1i [
i] = sfi [
i] - sfi [nbr_coef -
i];
761 const DataType c = cos_ptr [
i];
762 const DataType
s = cos_ptr [h_nbr_coef -
i];
763 const DataType vr = sfr [
i] - sfi [-
i];
764 const DataType vi = sfi [
i] + sfi [nbr_coef -
i];
766 df2r [
i] = vr * c + vi *
s;
767 df2i [
i] = vi * c - vr *
s;
770 coef_index += d_nbr_coef;
772 while (coef_index < _length);
778 void FFTReal <DT>::compute_inverse_pass_n_osc (DataType df [],
const DataType sf [],
int pass)
const
783 assert (pass > TRIGO_BD_LIMIT);
784 assert (pass < _nbr_bits);
786 const long nbr_coef = 1 << pass;
787 const long h_nbr_coef = nbr_coef >> 1;
788 const long d_nbr_coef = nbr_coef << 1;
790 OscType & osc = _trigo_osc [pass - (TRIGO_BD_LIMIT + 1)];
793 const DataType *
const sfr = sf + coef_index;
794 const DataType *
const sfi = sfr + nbr_coef;
795 DataType *
const df1r = df + coef_index;
796 DataType *
const df2r = df1r + nbr_coef;
798 osc.clear_buffers ();
801 df1r [0] = sfr [0] + sfi [0];
802 df2r [0] = sfr [0] - sfi [0];
803 df1r [h_nbr_coef] = sfr [h_nbr_coef] * 2;
804 df2r [h_nbr_coef] = sfi [h_nbr_coef] * 2;
807 DataType *
const df1i = df1r + h_nbr_coef;
808 DataType *
const df2i = df1i + nbr_coef;
809 for (
long i = 1;
i < h_nbr_coef; ++
i)
811 df1r [
i] = sfr [
i] + sfi [-
i];
812 df1i [
i] = sfi [
i] - sfi [nbr_coef -
i];
815 const DataType c = osc.get_cos ();
816 const DataType
s = osc.get_sin ();
817 const DataType vr = sfr [
i] - sfi [-
i];
818 const DataType vi = sfi [
i] + sfi [nbr_coef -
i];
820 df2r [
i] = vr * c + vi *
s;
821 df2i [
i] = vi * c - vr *
s;
824 coef_index += d_nbr_coef;
826 while (coef_index < _length);
832 void FFTReal <DT>::compute_inverse_pass_3 (DataType df [],
const DataType sf [])
const
838 const DataType sqrt2_2 = DataType (
SQRT2 * 0.5);
842 df [coef_index] = sf [coef_index] + sf [coef_index + 4];
843 df [coef_index + 4] = sf [coef_index] - sf [coef_index + 4];
844 df [coef_index + 2] = sf [coef_index + 2] * 2;
845 df [coef_index + 6] = sf [coef_index + 6] * 2;
847 df [coef_index + 1] = sf [coef_index + 1] + sf [coef_index + 3];
848 df [coef_index + 3] = sf [coef_index + 5] - sf [coef_index + 7];
850 const DataType vr = sf [coef_index + 1] - sf [coef_index + 3];
851 const DataType vi = sf [coef_index + 5] + sf [coef_index + 7];
853 df [coef_index + 5] = (vr + vi) * sqrt2_2;
854 df [coef_index + 7] = (vi - vr) * sqrt2_2;
858 while (coef_index < _length);
864 void FFTReal <DT>::compute_inverse_pass_1_2 (DataType x [],
const DataType sf [])
const
870 const long * bit_rev_lut_ptr = get_br_ptr ();
871 const DataType * sf2 = sf;
876 const DataType b_0 = sf2 [0] + sf2 [2];
877 const DataType b_2 = sf2 [0] - sf2 [2];
878 const DataType b_1 = sf2 [1] * 2;
879 const DataType b_3 = sf2 [3] * 2;
881 x [bit_rev_lut_ptr [0]] = b_0 + b_1;
882 x [bit_rev_lut_ptr [1]] = b_0 - b_1;
883 x [bit_rev_lut_ptr [2]] = b_2 + b_3;
884 x [bit_rev_lut_ptr [3]] = b_2 - b_3;
887 const DataType b_0 = sf2 [4] + sf2 [6];
888 const DataType b_2 = sf2 [4] - sf2 [6];
889 const DataType b_1 = sf2 [5] * 2;
890 const DataType b_3 = sf2 [7] * 2;
892 x [bit_rev_lut_ptr [4]] = b_0 + b_1;
893 x [bit_rev_lut_ptr [5]] = b_0 - b_1;
894 x [bit_rev_lut_ptr [6]] = b_2 + b_3;
895 x [bit_rev_lut_ptr [7]] = b_2 - b_3;
900 bit_rev_lut_ptr += 8;
902 while (coef_index < _length);
911 #endif // ffft_FFTReal_CODEHEADER_INCLUDED
913 #undef ffft_FFTReal_CURRENT_CODEHEADER