15 #pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion"
18 #if ! defined (ffft_FFTReal_HEADER_INCLUDED)
19 #define ffft_FFTReal_HEADER_INCLUDED
21 #if defined (_MSC_VER)
23 #pragma warning (4 : 4250)
47 #if ! defined (ffft_def_HEADER_INCLUDED)
48 #define ffft_def_HEADER_INCLUDED
50 #if defined (_MSC_VER)
52 #pragma warning (4 : 4250)
65 const double PI = 3.1415926535897932384626433832795;
67 const double SQRT2 = 1.41421356237309514547462185873883;
69 #if defined (_MSC_VER)
71 #define ffft_FORCEINLINE __forceinline
75 #define ffft_FORCEINLINE inline
108 #if ! defined (ffft_DynArray_HEADER_INCLUDED)
109 #define ffft_DynArray_HEADER_INCLUDED
111 #if defined (_MSC_VER)
113 #pragma warning (4 : 4250)
141 inline long size ()
const;
142 inline void resize (
long size);
144 inline const DataType &
145 operator [] (
long pos)
const;
147 operator [] (
long pos);
161 DataType * _data_ptr;
172 bool operator == (
const DynArray &other);
173 bool operator != (
const DynArray &other);
200 #if defined (ffft_DynArray_CURRENT_CODEHEADER)
201 #error Recursive inclusion of DynArray code header.
203 #define ffft_DynArray_CURRENT_CODEHEADER
205 #if ! defined (ffft_DynArray_CODEHEADER_INCLUDED)
206 #define ffft_DynArray_CODEHEADER_INCLUDED
226 DynArray <T>::DynArray ()
236 DynArray <T>::DynArray (
long size)
243 _data_ptr =
new DataType [size];
251 DynArray <T>::~DynArray ()
261 long DynArray <T>::size ()
const
269 void DynArray <T>::resize (
long size)
274 DataType * old_data_ptr = _data_ptr;
275 DataType * tmp_data_ptr =
new DataType [size];
277 _data_ptr = tmp_data_ptr;
280 delete [] old_data_ptr;
287 const typename DynArray <T>::DataType & DynArray <T>::operator [] (
long pos)
const
292 return (_data_ptr [pos]);
298 typename DynArray <T>::DataType & DynArray <T>::operator [] (
long pos)
303 return (_data_ptr [pos]);
322 #undef ffft_DynArray_CURRENT_CODEHEADER
354 #if ! defined (ffft_OscSinCos_HEADER_INCLUDED)
355 #define ffft_OscSinCos_HEADER_INCLUDED
357 #if defined (_MSC_VER)
359 #pragma warning (4 : 4250)
387 ffft_FORCEINLINE
void
388 set_step (
double angle_rad);
390 ffft_FORCEINLINE DataType
392 ffft_FORCEINLINE DataType
394 ffft_FORCEINLINE
void
396 ffft_FORCEINLINE
void
424 bool operator == (
const OscSinCos &other);
425 bool operator != (
const OscSinCos &other);
452 #if defined (ffft_OscSinCos_CURRENT_CODEHEADER)
453 #error Recursive inclusion of OscSinCos code header.
455 #define ffft_OscSinCos_CURRENT_CODEHEADER
457 #if ! defined (ffft_OscSinCos_CODEHEADER_INCLUDED)
458 #define ffft_OscSinCos_CODEHEADER_INCLUDED
480 OscSinCos <T>::OscSinCos ()
492 void OscSinCos <T>::set_step (
double angle_rad)
496 _step_cos =
static_cast <DataType
> (cos (angle_rad));
497 _step_sin =
static_cast <DataType
> (sin (angle_rad));
503 typename OscSinCos <T>::DataType OscSinCos <T>::get_cos ()
const
511 typename OscSinCos <T>::DataType OscSinCos <T>::get_sin ()
const
519 void OscSinCos <T>::step ()
521 const DataType old_cos = _pos_cos;
522 const DataType old_sin = _pos_sin;
524 _pos_cos = old_cos * _step_cos - old_sin * _step_sin;
525 _pos_sin = old_cos * _step_sin + old_sin * _step_cos;
531 void OscSinCos <T>::clear_buffers ()
533 _pos_cos =
static_cast <DataType
> (1);
534 _pos_sin =
static_cast <DataType
> (0);
553 #undef ffft_OscSinCos_CURRENT_CODEHEADER
584 enum { MAX_BIT_DEPTH = 30 };
588 explicit FFTReal (
long length);
591 long get_length ()
const;
592 void do_fft (DataType f [],
const DataType x [])
const;
593 void do_ifft (
const DataType f [], DataType x [])
const;
594 void rescale (DataType x [])
const;
595 DataType * use_buffer ()
const;
610 enum { TRIGO_BD_LIMIT = 12 };
615 void init_trigo_lut ();
616 void init_trigo_osc ();
618 ffft_FORCEINLINE
const long *
620 ffft_FORCEINLINE
const DataType *
621 get_trigo_ptr (
int level)
const;
622 ffft_FORCEINLINE
long
623 get_trigo_level_index (
int level)
const;
625 inline void compute_fft_general (DataType f [],
const DataType x [])
const;
626 inline void compute_direct_pass_1_2 (DataType df [],
const DataType x [])
const;
627 inline void compute_direct_pass_3 (DataType df [],
const DataType sf [])
const;
628 inline void compute_direct_pass_n (DataType df [],
const DataType sf [],
int pass)
const;
629 inline void compute_direct_pass_n_lut (DataType df [],
const DataType sf [],
int pass)
const;
630 inline void compute_direct_pass_n_osc (DataType df [],
const DataType sf [],
int pass)
const;
632 inline void compute_ifft_general (
const DataType f [], DataType x [])
const;
633 inline void compute_inverse_pass_n (DataType df [],
const DataType sf [],
int pass)
const;
634 inline void compute_inverse_pass_n_osc (DataType df [],
const DataType sf [],
int pass)
const;
635 inline void compute_inverse_pass_n_lut (DataType df [],
const DataType sf [],
int pass)
const;
636 inline void compute_inverse_pass_3 (DataType df [],
const DataType sf [])
const;
637 inline void compute_inverse_pass_1_2 (DataType x [],
const DataType sf [])
const;
659 bool operator == (
const FFTReal &other);
660 bool operator != (
const FFTReal &other);
687 #if defined (ffft_FFTReal_CURRENT_CODEHEADER)
688 #error Recursive inclusion of FFTReal code header.
690 #define ffft_FFTReal_CURRENT_CODEHEADER
692 #if ! defined (ffft_FFTReal_CODEHEADER_INCLUDED)
693 #define ffft_FFTReal_CODEHEADER_INCLUDED
709 static inline bool FFTReal_is_pow2 (
long x)
713 return ((x & -x) == x);
718 static inline int FFTReal_get_next_pow2 (
long x)
723 while ((x & ~0xFFFFL) != 0)
728 while ((x & ~0xFL) != 0)
759 FFTReal <DT>::FFTReal (
long length)
761 , _nbr_bits (FFTReal_get_next_pow2 (length))
767 assert (FFTReal_is_pow2 (length));
768 assert (_nbr_bits <= MAX_BIT_DEPTH);
788 long FFTReal <DT>::get_length ()
const
812 void FFTReal <DT>::do_fft (DataType f [],
const DataType x [])
const
815 assert (f != use_buffer ());
817 assert (x != use_buffer ());
823 compute_fft_general (f, x);
827 else if (_nbr_bits == 2)
829 f [1] = x [0] - x [2];
830 f [3] = x [1] - x [3];
832 const DataType b_0 = x [0] + x [2];
833 const DataType b_2 = x [1] + x [3];
840 else if (_nbr_bits == 1)
842 f [0] = x [0] + x [1];
843 f [1] = x [0] - x [1];
873 void FFTReal <DT>::do_ifft (
const DataType f [], DataType x [])
const
876 assert (f != use_buffer ());
878 assert (x != use_buffer ());
884 compute_ifft_general (f, x);
888 else if (_nbr_bits == 2)
890 const DataType b_0 = f [0] + f [2];
891 const DataType b_2 = f [0] - f [2];
893 x [0] = b_0 + f [1] * 2;
894 x [2] = b_0 - f [1] * 2;
895 x [1] = b_2 + f [3] * 2;
896 x [3] = b_2 - f [3] * 2;
900 else if (_nbr_bits == 1)
902 x [0] = f [0] + f [1];
903 x [1] = f [0] - f [1];
928 void FFTReal <DT>::rescale (DataType x [])
const
930 const DataType mul = DataType (1.0 / _length);
934 long i = _length - 1;
945 assert ((_length & 3) == 0);
948 long i = _length - 4;
979 typename FFTReal <DT>::DataType * FFTReal <DT>::use_buffer ()
const
981 return (&_buffer [0]);
995 void FFTReal <DT>::init_br_lut ()
997 const long length = 1L << _nbr_bits;
998 _br_lut.resize (length);
1002 for (
long cnt = 1; cnt < length; ++cnt)
1005 long bit = length >> 1;
1006 while (((br_index ^= bit) & bit) == 0)
1011 _br_lut [cnt] = br_index;
1018 void FFTReal <DT>::init_trigo_lut ()
1020 using namespace std;
1024 const long total_len = (1L << (_nbr_bits - 1)) - 4;
1025 _trigo_lut.resize (total_len);
1027 for (
int level = 3; level < _nbr_bits; ++level)
1029 const long level_len = 1L << (level - 1);
1030 DataType *
const level_ptr =
1031 &_trigo_lut [get_trigo_level_index (level)];
1032 const double mul = PI / (level_len << 1);
1034 for (
long i = 0; i < level_len; ++ i)
1036 level_ptr [i] =
static_cast <DataType
> (cos (i * mul));
1045 void FFTReal <DT>::init_trigo_osc ()
1047 const int nbr_osc = _nbr_bits - TRIGO_BD_LIMIT;
1050 _trigo_osc.resize (nbr_osc);
1052 for (
int osc_cnt = 0; osc_cnt < nbr_osc; ++osc_cnt)
1054 OscType & osc = _trigo_osc [osc_cnt];
1056 const long len = 1L << (TRIGO_BD_LIMIT + osc_cnt);
1057 const double mul = (0.5 * PI) / len;
1066 const long * FFTReal <DT>::get_br_ptr ()
const
1068 return (&_br_lut [0]);
1074 const typename FFTReal <DT>::DataType * FFTReal <DT>::get_trigo_ptr (
int level)
const
1076 assert (level >= 3);
1078 return (&_trigo_lut [get_trigo_level_index (level)]);
1084 long FFTReal <DT>::get_trigo_level_index (
int level)
const
1086 assert (level >= 3);
1088 return ((1L << (level - 1)) - 4);
1095 void FFTReal <DT>::compute_fft_general (DataType f [],
const DataType x [])
const
1098 assert (f != use_buffer ());
1100 assert (x != use_buffer ());
1106 if ((_nbr_bits & 1) != 0)
1117 compute_direct_pass_1_2 (df, x);
1118 compute_direct_pass_3 (sf, df);
1120 for (
int pass = 3; pass < _nbr_bits; ++ pass)
1122 compute_direct_pass_n (df, sf, pass);
1124 DataType *
const temp_ptr = df;
1133 void FFTReal <DT>::compute_direct_pass_1_2 (DataType df [],
const DataType x [])
const
1139 const long *
const bit_rev_lut_ptr = get_br_ptr ();
1140 long coef_index = 0;
1143 const long rev_index_0 = bit_rev_lut_ptr [coef_index];
1144 const long rev_index_1 = bit_rev_lut_ptr [coef_index + 1];
1145 const long rev_index_2 = bit_rev_lut_ptr [coef_index + 2];
1146 const long rev_index_3 = bit_rev_lut_ptr [coef_index + 3];
1148 DataType *
const df2 = df + coef_index;
1149 df2 [1] = x [rev_index_0] - x [rev_index_1];
1150 df2 [3] = x [rev_index_2] - x [rev_index_3];
1152 const DataType sf_0 = x [rev_index_0] + x [rev_index_1];
1153 const DataType sf_2 = x [rev_index_2] + x [rev_index_3];
1155 df2 [0] = sf_0 + sf_2;
1156 df2 [2] = sf_0 - sf_2;
1160 while (coef_index < _length);
1166 void FFTReal <DT>::compute_direct_pass_3 (DataType df [],
const DataType sf [])
const
1172 const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
1173 long coef_index = 0;
1178 df [coef_index] = sf [coef_index] + sf [coef_index + 4];
1179 df [coef_index + 4] = sf [coef_index] - sf [coef_index + 4];
1180 df [coef_index + 2] = sf [coef_index + 2];
1181 df [coef_index + 6] = sf [coef_index + 6];
1183 v = (sf [coef_index + 5] - sf [coef_index + 7]) * sqrt2_2;
1184 df [coef_index + 1] = sf [coef_index + 1] + v;
1185 df [coef_index + 3] = sf [coef_index + 1] - v;
1187 v = (sf [coef_index + 5] + sf [coef_index + 7]) * sqrt2_2;
1188 df [coef_index + 5] = v + sf [coef_index + 3];
1189 df [coef_index + 7] = v - sf [coef_index + 3];
1193 while (coef_index < _length);
1199 void FFTReal <DT>::compute_direct_pass_n (DataType df [],
const DataType sf [],
int pass)
const
1205 assert (pass < _nbr_bits);
1207 if (pass <= TRIGO_BD_LIMIT)
1209 compute_direct_pass_n_lut (df, sf, pass);
1213 compute_direct_pass_n_osc (df, sf, pass);
1220 void FFTReal <DT>::compute_direct_pass_n_lut (DataType df [],
const DataType sf [],
int pass)
const
1226 assert (pass < _nbr_bits);
1228 const long nbr_coef = 1 << pass;
1229 const long h_nbr_coef = nbr_coef >> 1;
1230 const long d_nbr_coef = nbr_coef << 1;
1231 long coef_index = 0;
1232 const DataType *
const cos_ptr = get_trigo_ptr (pass);
1235 const DataType *
const sf1r = sf + coef_index;
1236 const DataType *
const sf2r = sf1r + nbr_coef;
1237 DataType *
const dfr = df + coef_index;
1238 DataType *
const dfi = dfr + nbr_coef;
1241 dfr [0] = sf1r [0] + sf2r [0];
1242 dfi [0] = sf1r [0] - sf2r [0];
1243 dfr [h_nbr_coef] = sf1r [h_nbr_coef];
1244 dfi [h_nbr_coef] = sf2r [h_nbr_coef];
1247 const DataType *
const sf1i = sf1r + h_nbr_coef;
1248 const DataType *
const sf2i = sf1i + nbr_coef;
1249 for (
long i = 1; i < h_nbr_coef; ++ i)
1251 const DataType c = cos_ptr [i];
1252 const DataType s = cos_ptr [h_nbr_coef - i];
1255 v = sf2r [i] * c - sf2i [i] * s;
1256 dfr [i] = sf1r [i] + v;
1257 dfi [-i] = sf1r [i] - v;
1259 v = sf2r [i] * s + sf2i [i] * c;
1260 dfi [i] = v + sf1i [i];
1261 dfi [nbr_coef - i] = v - sf1i [i];
1264 coef_index += d_nbr_coef;
1266 while (coef_index < _length);
1272 void FFTReal <DT>::compute_direct_pass_n_osc (DataType df [],
const DataType sf [],
int pass)
const
1277 assert (pass > TRIGO_BD_LIMIT);
1278 assert (pass < _nbr_bits);
1280 const long nbr_coef = 1 << pass;
1281 const long h_nbr_coef = nbr_coef >> 1;
1282 const long d_nbr_coef = nbr_coef << 1;
1283 long coef_index = 0;
1284 OscType & osc = _trigo_osc [pass - (TRIGO_BD_LIMIT + 1)];
1287 const DataType *
const sf1r = sf + coef_index;
1288 const DataType *
const sf2r = sf1r + nbr_coef;
1289 DataType *
const dfr = df + coef_index;
1290 DataType *
const dfi = dfr + nbr_coef;
1292 osc.clear_buffers ();
1295 dfr [0] = sf1r [0] + sf2r [0];
1296 dfi [0] = sf1r [0] - sf2r [0];
1297 dfr [h_nbr_coef] = sf1r [h_nbr_coef];
1298 dfi [h_nbr_coef] = sf2r [h_nbr_coef];
1301 const DataType *
const sf1i = sf1r + h_nbr_coef;
1302 const DataType *
const sf2i = sf1i + nbr_coef;
1303 for (
long i = 1; i < h_nbr_coef; ++ i)
1306 const DataType c = osc.get_cos ();
1307 const DataType s = osc.get_sin ();
1310 v = sf2r [i] * c - sf2i [i] * s;
1311 dfr [i] = sf1r [i] + v;
1312 dfi [-i] = sf1r [i] - v;
1314 v = sf2r [i] * s + sf2i [i] * c;
1315 dfi [i] = v + sf1i [i];
1316 dfi [nbr_coef - i] = v - sf1i [i];
1319 coef_index += d_nbr_coef;
1321 while (coef_index < _length);
1328 void FFTReal <DT>::compute_ifft_general (
const DataType f [], DataType x [])
const
1331 assert (f != use_buffer ());
1333 assert (x != use_buffer ());
1336 DataType * sf =
const_cast <DataType *
> (f);
1348 df_temp = use_buffer ();
1351 for (
int pass = _nbr_bits - 1; pass >= 3; -- pass)
1353 compute_inverse_pass_n (df, sf, pass);
1355 if (pass < _nbr_bits - 1)
1357 DataType *
const temp_ptr = df;
1368 compute_inverse_pass_3 (df, sf);
1369 compute_inverse_pass_1_2 (x, df);
1375 void FFTReal <DT>::compute_inverse_pass_n (DataType df [],
const DataType sf [],
int pass)
const
1381 assert (pass < _nbr_bits);
1383 if (pass <= TRIGO_BD_LIMIT)
1385 compute_inverse_pass_n_lut (df, sf, pass);
1389 compute_inverse_pass_n_osc (df, sf, pass);
1396 void FFTReal <DT>::compute_inverse_pass_n_lut (DataType df [],
const DataType sf [],
int pass)
const
1402 assert (pass < _nbr_bits);
1404 const long nbr_coef = 1 << pass;
1405 const long h_nbr_coef = nbr_coef >> 1;
1406 const long d_nbr_coef = nbr_coef << 1;
1407 long coef_index = 0;
1408 const DataType *
const cos_ptr = get_trigo_ptr (pass);
1411 const DataType *
const sfr = sf + coef_index;
1412 const DataType *
const sfi = sfr + nbr_coef;
1413 DataType *
const df1r = df + coef_index;
1414 DataType *
const df2r = df1r + nbr_coef;
1417 df1r [0] = sfr [0] + sfi [0];
1418 df2r [0] = sfr [0] - sfi [0];
1419 df1r [h_nbr_coef] = sfr [h_nbr_coef] * 2;
1420 df2r [h_nbr_coef] = sfi [h_nbr_coef] * 2;
1423 DataType *
const df1i = df1r + h_nbr_coef;
1424 DataType *
const df2i = df1i + nbr_coef;
1425 for (
long i = 1; i < h_nbr_coef; ++ i)
1427 df1r [i] = sfr [i] + sfi [-i];
1428 df1i [i] = sfi [i] - sfi [nbr_coef - i];
1430 const DataType c = cos_ptr [i];
1431 const DataType s = cos_ptr [h_nbr_coef - i];
1432 const DataType vr = sfr [i] - sfi [-i];
1433 const DataType vi = sfi [i] + sfi [nbr_coef - i];
1435 df2r [i] = vr * c + vi * s;
1436 df2i [i] = vi * c - vr * s;
1439 coef_index += d_nbr_coef;
1441 while (coef_index < _length);
1447 void FFTReal <DT>::compute_inverse_pass_n_osc (DataType df [],
const DataType sf [],
int pass)
const
1452 assert (pass > TRIGO_BD_LIMIT);
1453 assert (pass < _nbr_bits);
1455 const long nbr_coef = 1 << pass;
1456 const long h_nbr_coef = nbr_coef >> 1;
1457 const long d_nbr_coef = nbr_coef << 1;
1458 long coef_index = 0;
1459 OscType & osc = _trigo_osc [pass - (TRIGO_BD_LIMIT + 1)];
1462 const DataType *
const sfr = sf + coef_index;
1463 const DataType *
const sfi = sfr + nbr_coef;
1464 DataType *
const df1r = df + coef_index;
1465 DataType *
const df2r = df1r + nbr_coef;
1467 osc.clear_buffers ();
1470 df1r [0] = sfr [0] + sfi [0];
1471 df2r [0] = sfr [0] - sfi [0];
1472 df1r [h_nbr_coef] = sfr [h_nbr_coef] * 2;
1473 df2r [h_nbr_coef] = sfi [h_nbr_coef] * 2;
1476 DataType *
const df1i = df1r + h_nbr_coef;
1477 DataType *
const df2i = df1i + nbr_coef;
1478 for (
long i = 1; i < h_nbr_coef; ++ i)
1480 df1r [i] = sfr [i] + sfi [-i];
1481 df1i [i] = sfi [i] - sfi [nbr_coef - i];
1484 const DataType c = osc.get_cos ();
1485 const DataType s = osc.get_sin ();
1486 const DataType vr = sfr [i] - sfi [-i];
1487 const DataType vi = sfi [i] + sfi [nbr_coef - i];
1489 df2r [i] = vr * c + vi * s;
1490 df2i [i] = vi * c - vr * s;
1493 coef_index += d_nbr_coef;
1495 while (coef_index < _length);
1501 void FFTReal <DT>::compute_inverse_pass_3 (DataType df [],
const DataType sf [])
const
1507 const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
1508 long coef_index = 0;
1511 df [coef_index] = sf [coef_index] + sf [coef_index + 4];
1512 df [coef_index + 4] = sf [coef_index] - sf [coef_index + 4];
1513 df [coef_index + 2] = sf [coef_index + 2] * 2;
1514 df [coef_index + 6] = sf [coef_index + 6] * 2;
1516 df [coef_index + 1] = sf [coef_index + 1] + sf [coef_index + 3];
1517 df [coef_index + 3] = sf [coef_index + 5] - sf [coef_index + 7];
1519 const DataType vr = sf [coef_index + 1] - sf [coef_index + 3];
1520 const DataType vi = sf [coef_index + 5] + sf [coef_index + 7];
1522 df [coef_index + 5] = (vr + vi) * sqrt2_2;
1523 df [coef_index + 7] = (vi - vr) * sqrt2_2;
1527 while (coef_index < _length);
1533 void FFTReal <DT>::compute_inverse_pass_1_2 (DataType x [],
const DataType sf [])
const
1539 const long * bit_rev_lut_ptr = get_br_ptr ();
1540 const DataType * sf2 = sf;
1541 long coef_index = 0;
1545 const DataType b_0 = sf2 [0] + sf2 [2];
1546 const DataType b_2 = sf2 [0] - sf2 [2];
1547 const DataType b_1 = sf2 [1] * 2;
1548 const DataType b_3 = sf2 [3] * 2;
1550 x [bit_rev_lut_ptr [0]] = b_0 + b_1;
1551 x [bit_rev_lut_ptr [1]] = b_0 - b_1;
1552 x [bit_rev_lut_ptr [2]] = b_2 + b_3;
1553 x [bit_rev_lut_ptr [3]] = b_2 - b_3;
1556 const DataType b_0 = sf2 [4] + sf2 [6];
1557 const DataType b_2 = sf2 [4] - sf2 [6];
1558 const DataType b_1 = sf2 [5] * 2;
1559 const DataType b_3 = sf2 [7] * 2;
1561 x [bit_rev_lut_ptr [4]] = b_0 + b_1;
1562 x [bit_rev_lut_ptr [5]] = b_0 - b_1;
1563 x [bit_rev_lut_ptr [6]] = b_2 + b_3;
1564 x [bit_rev_lut_ptr [7]] = b_2 - b_3;
1569 bit_rev_lut_ptr += 8;
1571 while (coef_index < _length);
1582 #undef ffft_FFTReal_CURRENT_CODEHEADER
1614 #if ! defined (ffft_FFTRealFixLen_HEADER_INCLUDED)
1615 #define ffft_FFTRealFixLen_HEADER_INCLUDED
1617 #if defined (_MSC_VER)
1619 #pragma warning (4 : 4250)
1643 #if ! defined (ffft_Array_HEADER_INCLUDED)
1644 #define ffft_Array_HEADER_INCLUDED
1646 #if defined (_MSC_VER)
1648 #pragma warning (4 : 4250)
1662 template <
class T,
long LEN>
1674 inline const DataType &
1675 operator [] (
long pos)
const;
1677 operator [] (
long pos);
1694 DataType _data_arr [LEN];
1704 bool operator == (
const Array &other);
1705 bool operator != (
const Array &other);
1732 #if defined (ffft_Array_CURRENT_CODEHEADER)
1733 #error Recursive inclusion of Array code header.
1735 #define ffft_Array_CURRENT_CODEHEADER
1737 #if ! defined (ffft_Array_CODEHEADER_INCLUDED)
1738 #define ffft_Array_CODEHEADER_INCLUDED
1757 template <
class T,
long LEN>
1758 Array <T, LEN>::Array ()
1765 template <
class T,
long LEN>
1766 const typename Array <T, LEN>::DataType & Array <T, LEN>::operator [] (
long pos)
const
1771 return (_data_arr [pos]);
1776 template <
class T,
long LEN>
1777 typename Array <T, LEN>::DataType & Array <T, LEN>::operator [] (
long pos)
1782 return (_data_arr [pos]);
1787 template <
class T,
long LEN>
1788 long Array <T, LEN>::size ()
1809 #undef ffft_Array_CURRENT_CODEHEADER
1841 #if ! defined (ffft_DynArray_HEADER_INCLUDED)
1842 #define ffft_DynArray_HEADER_INCLUDED
1844 #if defined (_MSC_VER)
1846 #pragma warning (4 : 4250)
1871 explicit DynArray (
long size);
1874 inline long size ()
const;
1875 inline void resize (
long size);
1877 inline const DataType &
1878 operator [] (
long pos)
const;
1880 operator [] (
long pos);
1894 DataType * _data_ptr;
1903 DynArray (
const DynArray &other);
1904 DynArray & operator = (
const DynArray &other);
1905 bool operator == (
const DynArray &other);
1906 bool operator != (
const DynArray &other);
1933 #if defined (ffft_DynArray_CURRENT_CODEHEADER)
1934 #error Recursive inclusion of DynArray code header.
1936 #define ffft_DynArray_CURRENT_CODEHEADER
1938 #if ! defined (ffft_DynArray_CODEHEADER_INCLUDED)
1939 #define ffft_DynArray_CODEHEADER_INCLUDED
1959 DynArray <T>::DynArray ()
1969 DynArray <T>::DynArray (
long size)
1976 _data_ptr =
new DataType [size];
1984 DynArray <T>::~DynArray ()
1986 delete [] _data_ptr;
1994 long DynArray <T>::size ()
const
2002 void DynArray <T>::resize (
long size)
2007 DataType * old_data_ptr = _data_ptr;
2008 DataType * tmp_data_ptr =
new DataType [size];
2010 _data_ptr = tmp_data_ptr;
2013 delete [] old_data_ptr;
2020 const typename DynArray <T>::DataType & DynArray <T>::operator [] (
long pos)
const
2023 assert (pos < _len);
2025 return (_data_ptr [pos]);
2031 typename DynArray <T>::DataType & DynArray <T>::operator [] (
long pos)
2034 assert (pos < _len);
2036 return (_data_ptr [pos]);
2055 #undef ffft_DynArray_CURRENT_CODEHEADER
2087 #if ! defined (ffft_FFTRealFixLenParam_HEADER_INCLUDED)
2088 #define ffft_FFTRealFixLenParam_HEADER_INCLUDED
2090 #if defined (_MSC_VER)
2092 #pragma warning (4 : 4250)
2114 enum { TRIGO_BD_LIMIT = 12 };
2116 typedef float DataType;
2178 #if ! defined (ffft_OscSinCos_HEADER_INCLUDED)
2179 #define ffft_OscSinCos_HEADER_INCLUDED
2181 #if defined (_MSC_VER)
2183 #pragma warning (4 : 4250)
2211 ffft_FORCEINLINE
void
2212 set_step (
double angle_rad);
2214 ffft_FORCEINLINE DataType
2216 ffft_FORCEINLINE DataType
2218 ffft_FORCEINLINE
void
2220 ffft_FORCEINLINE
void
2246 OscSinCos (
const OscSinCos &other);
2247 OscSinCos & operator = (
const OscSinCos &other);
2248 bool operator == (
const OscSinCos &other);
2249 bool operator != (
const OscSinCos &other);
2276 #if defined (ffft_OscSinCos_CURRENT_CODEHEADER)
2277 #error Recursive inclusion of OscSinCos code header.
2279 #define ffft_OscSinCos_CURRENT_CODEHEADER
2281 #if ! defined (ffft_OscSinCos_CODEHEADER_INCLUDED)
2282 #define ffft_OscSinCos_CODEHEADER_INCLUDED
2304 OscSinCos <T>::OscSinCos ()
2316 void OscSinCos <T>::set_step (
double angle_rad)
2318 using namespace std;
2320 _step_cos =
static_cast <DataType
> (cos (angle_rad));
2321 _step_sin =
static_cast <DataType
> (sin (angle_rad));
2327 typename OscSinCos <T>::DataType OscSinCos <T>::get_cos ()
const
2335 typename OscSinCos <T>::DataType OscSinCos <T>::get_sin ()
const
2343 void OscSinCos <T>::step ()
2345 const DataType old_cos = _pos_cos;
2346 const DataType old_sin = _pos_sin;
2348 _pos_cos = old_cos * _step_cos - old_sin * _step_sin;
2349 _pos_sin = old_cos * _step_sin + old_sin * _step_cos;
2355 void OscSinCos <T>::clear_buffers ()
2357 _pos_cos =
static_cast <DataType
> (1);
2358 _pos_sin =
static_cast <DataType
> (0);
2377 #undef ffft_OscSinCos_CURRENT_CODEHEADER
2403 typedef int CompileTimeCheck1 [(LL2 >= 0) ? 1 : -1];
2404 typedef int CompileTimeCheck2 [(LL2 <= 30) ? 1 : -1];
2410 typedef FFTRealFixLenParam::DataType DataType;
2413 enum { FFT_LEN_L2 = LL2 };
2414 enum { FFT_LEN = 1 << FFT_LEN_L2 };
2418 inline long get_length ()
const;
2419 void do_fft (DataType f [],
const DataType x []);
2420 void do_ifft (
const DataType f [], DataType x []);
2421 void rescale (DataType x [])
const;
2435 enum { TRIGO_BD_LIMIT = FFTRealFixLenParam::TRIGO_BD_LIMIT };
2437 enum { BR_ARR_SIZE_L2 = ((FFT_LEN_L2 - 3) < 0) ? 0 : (FFT_LEN_L2 - 2) };
2438 enum { BR_ARR_SIZE = 1 << BR_ARR_SIZE_L2 };
2440 enum { TRIGO_BD = ((FFT_LEN_L2 - TRIGO_BD_LIMIT) < 0)
2442 : (
int)TRIGO_BD_LIMIT };
2443 enum { TRIGO_TABLE_ARR_SIZE_L2 = (LL2 < 4) ? 0 : (TRIGO_BD - 2) };
2444 enum { TRIGO_TABLE_ARR_SIZE = 1 << TRIGO_TABLE_ARR_SIZE_L2 };
2446 enum { NBR_TRIGO_OSC = FFT_LEN_L2 - TRIGO_BD };
2447 enum { TRIGO_OSC_ARR_SIZE = (NBR_TRIGO_OSC > 0) ? NBR_TRIGO_OSC : 1 };
2449 void build_br_lut ();
2450 void build_trigo_lut ();
2451 void build_trigo_osc ();
2498 #if defined (ffft_FFTRealFixLen_CURRENT_CODEHEADER)
2499 #error Recursive inclusion of FFTRealFixLen code header.
2501 #define ffft_FFTRealFixLen_CURRENT_CODEHEADER
2503 #if ! defined (ffft_FFTRealFixLen_CODEHEADER_INCLUDED)
2504 #define ffft_FFTRealFixLen_CODEHEADER_INCLUDED
2528 #if ! defined (ffft_FFTRealPassDirect_HEADER_INCLUDED)
2529 #define ffft_FFTRealPassDirect_HEADER_INCLUDED
2531 #if defined (_MSC_VER)
2533 #pragma warning (4 : 4250)
2559 typedef FFTRealFixLenParam::DataType DataType;
2562 ffft_FORCEINLINE
static void
2563 process (
long len, DataType dest_ptr [], DataType src_ptr [],
const DataType x_ptr [],
const DataType cos_ptr [],
long cos_len,
const long br_ptr [],
OscType osc_list []);
2615 #if defined (ffft_FFTRealPassDirect_CURRENT_CODEHEADER)
2616 #error Recursive inclusion of FFTRealPassDirect code header.
2618 #define ffft_FFTRealPassDirect_CURRENT_CODEHEADER
2620 #if ! defined (ffft_FFTRealPassDirect_CODEHEADER_INCLUDED)
2621 #define ffft_FFTRealPassDirect_CODEHEADER_INCLUDED
2644 #if ! defined (ffft_FFTRealUseTrigo_HEADER_INCLUDED)
2645 #define ffft_FFTRealUseTrigo_HEADER_INCLUDED
2647 #if defined (_MSC_VER)
2649 #pragma warning (4 : 4250)
2675 typedef FFTRealFixLenParam::DataType DataType;
2678 ffft_FORCEINLINE
static void
2680 ffft_FORCEINLINE
static void
2681 iterate (
OscType &osc, DataType &c, DataType &s,
const DataType cos_ptr [],
long index_c,
long index_s);
2734 #if defined (ffft_FFTRealUseTrigo_CURRENT_CODEHEADER)
2735 #error Recursive inclusion of FFTRealUseTrigo code header.
2737 #define ffft_FFTRealUseTrigo_CURRENT_CODEHEADER
2739 #if ! defined (ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED)
2740 #define ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED
2760 void FFTRealUseTrigo <ALGO>::prepare (OscType &osc)
2762 osc.clear_buffers ();
2766 inline void FFTRealUseTrigo <0>::prepare (OscType &osc)
2774 void FFTRealUseTrigo <ALGO>::iterate (OscType &osc, DataType &c, DataType &s,
const DataType cos_ptr [],
long index_c,
long index_s)
2782 inline void FFTRealUseTrigo <0>::iterate (OscType &osc, DataType &c, DataType &s,
const DataType cos_ptr [],
long index_c,
long index_s)
2784 c = cos_ptr [index_c];
2785 s = cos_ptr [index_s];
2804 #undef ffft_FFTRealUseTrigo_CURRENT_CODEHEADER
2832 inline void FFTRealPassDirect <1>::process (
long len, DataType dest_ptr [], DataType src_ptr [],
const DataType x_ptr [],
const DataType cos_ptr [],
long cos_len,
const long br_ptr [], OscType osc_list [])
2835 const long qlen = len >> 2;
2837 long coef_index = 0;
2841 const long ri_0 = br_ptr [coef_index >> 2];
2842 const long ri_1 = ri_0 + 2 * qlen;
2843 const long ri_2 = ri_0 + 1 * qlen;
2844 const long ri_3 = ri_0 + 3 * qlen;
2846 DataType *
const df2 = dest_ptr + coef_index;
2847 df2 [1] = x_ptr [ri_0] - x_ptr [ri_1];
2848 df2 [3] = x_ptr [ri_2] - x_ptr [ri_3];
2850 const DataType sf_0 = x_ptr [ri_0] + x_ptr [ri_1];
2851 const DataType sf_2 = x_ptr [ri_2] + x_ptr [ri_3];
2853 df2 [0] = sf_0 + sf_2;
2854 df2 [2] = sf_0 - sf_2;
2858 while (coef_index < len);
2862 inline void FFTRealPassDirect <2>::process (
long len, DataType dest_ptr [], DataType src_ptr [],
const DataType x_ptr [],
const DataType cos_ptr [],
long cos_len,
const long br_ptr [], OscType osc_list [])
2865 FFTRealPassDirect <1>::process (
2877 const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
2879 long coef_index = 0;
2882 dest_ptr [coef_index ] = src_ptr [coef_index] + src_ptr [coef_index + 4];
2883 dest_ptr [coef_index + 4] = src_ptr [coef_index] - src_ptr [coef_index + 4];
2884 dest_ptr [coef_index + 2] = src_ptr [coef_index + 2];
2885 dest_ptr [coef_index + 6] = src_ptr [coef_index + 6];
2889 v = (src_ptr [coef_index + 5] - src_ptr [coef_index + 7]) * sqrt2_2;
2890 dest_ptr [coef_index + 1] = src_ptr [coef_index + 1] + v;
2891 dest_ptr [coef_index + 3] = src_ptr [coef_index + 1] - v;
2893 v = (src_ptr [coef_index + 5] + src_ptr [coef_index + 7]) * sqrt2_2;
2894 dest_ptr [coef_index + 5] = v + src_ptr [coef_index + 3];
2895 dest_ptr [coef_index + 7] = v - src_ptr [coef_index + 3];
2899 while (coef_index < len);
2903 void FFTRealPassDirect <PASS>::process (
long len, DataType dest_ptr [], DataType src_ptr [],
const DataType x_ptr [],
const DataType cos_ptr [],
long cos_len,
const long br_ptr [], OscType osc_list [])
2906 FFTRealPassDirect <PASS - 1>::process (
2917 const long dist = 1L << (PASS - 1);
2918 const long c1_r = 0;
2919 const long c1_i = dist;
2920 const long c2_r = dist * 2;
2921 const long c2_i = dist * 3;
2922 const long cend = dist * 4;
2923 const long table_step = cos_len >> (PASS - 1);
2925 enum { TRIGO_OSC = PASS - FFTRealFixLenParam::TRIGO_BD_LIMIT };
2926 enum { TRIGO_DIRECT = (TRIGO_OSC >= 0) ? 1 : 0 };
2928 long coef_index = 0;
2931 const DataType *
const sf = src_ptr + coef_index;
2932 DataType *
const df = dest_ptr + coef_index;
2935 df [c1_r] = sf [c1_r] + sf [c2_r];
2936 df [c2_r] = sf [c1_r] - sf [c2_r];
2937 df [c1_i] = sf [c1_i];
2938 df [c2_i] = sf [c2_i];
2940 FFTRealUseTrigo <TRIGO_DIRECT>::prepare (osc_list [TRIGO_OSC]);
2943 for (
long i = 1; i < dist; ++ i)
2947 FFTRealUseTrigo <TRIGO_DIRECT>::iterate (
2948 osc_list [TRIGO_OSC],
2953 (dist - i) * table_step
2956 const DataType sf_r_i = sf [c1_r + i];
2957 const DataType sf_i_i = sf [c1_i + i];
2959 const DataType v1 = sf [c2_r + i] * c - sf [c2_i + i] * s;
2960 df [c1_r + i] = sf_r_i + v1;
2961 df [c2_r - i] = sf_r_i - v1;
2963 const DataType v2 = sf [c2_r + i] * s + sf [c2_i + i] * c;
2964 df [c2_r + i] = v2 + sf_i_i;
2965 df [cend - i] = v2 - sf_i_i;
2970 while (coef_index < len);
2989 #undef ffft_FFTRealPassDirect_CURRENT_CODEHEADER
3021 #if ! defined (ffft_FFTRealPassInverse_HEADER_INCLUDED)
3022 #define ffft_FFTRealPassInverse_HEADER_INCLUDED
3024 #if defined (_MSC_VER)
3026 #pragma warning (4 : 4250)
3053 typedef FFTRealFixLenParam::DataType DataType;
3056 ffft_FORCEINLINE
static void
3057 process (
long len, DataType dest_ptr [], DataType src_ptr [],
const DataType f_ptr [],
const DataType cos_ptr [],
long cos_len,
const long br_ptr [],
OscType osc_list []);
3058 ffft_FORCEINLINE
static void
3059 process_rec (
long len, DataType dest_ptr [], DataType src_ptr [],
const DataType cos_ptr [],
long cos_len,
const long br_ptr [],
OscType osc_list []);
3060 ffft_FORCEINLINE
static void
3061 process_internal (
long len, DataType dest_ptr [],
const DataType src_ptr [],
const DataType cos_ptr [],
long cos_len,
const long br_ptr [],
OscType osc_list []);
3113 #if defined (ffft_FFTRealPassInverse_CURRENT_CODEHEADER)
3114 #error Recursive inclusion of FFTRealPassInverse code header.
3116 #define ffft_FFTRealPassInverse_CURRENT_CODEHEADER
3118 #if ! defined (ffft_FFTRealPassInverse_CODEHEADER_INCLUDED)
3119 #define ffft_FFTRealPassInverse_CODEHEADER_INCLUDED
3142 #if ! defined (ffft_FFTRealUseTrigo_HEADER_INCLUDED)
3143 #define ffft_FFTRealUseTrigo_HEADER_INCLUDED
3145 #if defined (_MSC_VER)
3147 #pragma warning (4 : 4250)
3166 class FFTRealUseTrigo
3173 typedef FFTRealFixLenParam::DataType DataType;
3174 typedef OscSinCos <DataType> OscType;
3176 ffft_FORCEINLINE
static void
3177 prepare (OscType &osc);
3178 ffft_FORCEINLINE
static void
3179 iterate (OscType &osc, DataType &c, DataType &s,
const DataType cos_ptr [],
long index_c,
long index_s);
3200 ~FFTRealUseTrigo ();
3201 FFTRealUseTrigo (
const FFTRealUseTrigo &other);
3203 operator = (
const FFTRealUseTrigo &other);
3204 bool operator == (
const FFTRealUseTrigo &other);
3205 bool operator != (
const FFTRealUseTrigo &other);
3232 #if defined (ffft_FFTRealUseTrigo_CURRENT_CODEHEADER)
3233 #error Recursive inclusion of FFTRealUseTrigo code header.
3235 #define ffft_FFTRealUseTrigo_CURRENT_CODEHEADER
3237 #if ! defined (ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED)
3238 #define ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED
3258 void FFTRealUseTrigo <ALGO>::prepare (OscType &osc)
3260 osc.clear_buffers ();
3264 inline void FFTRealUseTrigo <0>::prepare (OscType &osc)
3272 void FFTRealUseTrigo <ALGO>::iterate (OscType &osc, DataType &c, DataType &s,
const DataType cos_ptr [],
long index_c,
long index_s)
3280 inline void FFTRealUseTrigo <0>::iterate (OscType &osc, DataType &c, DataType &s,
const DataType cos_ptr [],
long index_c,
long index_s)
3282 c = cos_ptr [index_c];
3283 s = cos_ptr [index_s];
3302 #undef ffft_FFTRealUseTrigo_CURRENT_CODEHEADER
3330 void FFTRealPassInverse <PASS>::process (
long len, DataType dest_ptr [], DataType src_ptr [],
const DataType f_ptr [],
const DataType cos_ptr [],
long cos_len,
const long br_ptr [], OscType osc_list [])
3341 FFTRealPassInverse <PASS - 1>::process_rec (
3355 void FFTRealPassInverse <PASS>::process_rec (
long len, DataType dest_ptr [], DataType src_ptr [],
const DataType cos_ptr [],
long cos_len,
const long br_ptr [], OscType osc_list [])
3366 FFTRealPassInverse <PASS - 1>::process_rec (
3378 inline void FFTRealPassInverse <0>::process_rec (
long len, DataType dest_ptr [], DataType src_ptr [],
const DataType cos_ptr [],
long cos_len,
const long br_ptr [], OscType osc_list [])
3386 void FFTRealPassInverse <PASS>::process_internal (
long len, DataType dest_ptr [],
const DataType src_ptr [],
const DataType cos_ptr [],
long cos_len,
const long br_ptr [], OscType osc_list [])
3388 const long dist = 1L << (PASS - 1);
3389 const long c1_r = 0;
3390 const long c1_i = dist;
3391 const long c2_r = dist * 2;
3392 const long c2_i = dist * 3;
3393 const long cend = dist * 4;
3394 const long table_step = cos_len >> (PASS - 1);
3396 enum { TRIGO_OSC = PASS - FFTRealFixLenParam::TRIGO_BD_LIMIT };
3397 enum { TRIGO_DIRECT = (TRIGO_OSC >= 0) ? 1 : 0 };
3399 long coef_index = 0;
3402 const DataType *
const sf = src_ptr + coef_index;
3403 DataType *
const df = dest_ptr + coef_index;
3406 df [c1_r] = sf [c1_r] + sf [c2_r];
3407 df [c2_r] = sf [c1_r] - sf [c2_r];
3408 df [c1_i] = sf [c1_i] * 2;
3409 df [c2_i] = sf [c2_i] * 2;
3411 FFTRealUseTrigo <TRIGO_DIRECT>::prepare (osc_list [TRIGO_OSC]);
3414 for (
long i = 1; i < dist; ++ i)
3416 df [c1_r + i] = sf [c1_r + i] + sf [c2_r - i];
3417 df [c1_i + i] = sf [c2_r + i] - sf [cend - i];
3421 FFTRealUseTrigo <TRIGO_DIRECT>::iterate (
3422 osc_list [TRIGO_OSC],
3427 (dist - i) * table_step
3430 const DataType vr = sf [c1_r + i] - sf [c2_r - i];
3431 const DataType vi = sf [c2_r + i] + sf [cend - i];
3433 df [c2_r + i] = vr * c + vi * s;
3434 df [c2_i + i] = vi * c - vr * s;
3439 while (coef_index < len);
3443 inline void FFTRealPassInverse <2>::process_internal (
long len, DataType dest_ptr [],
const DataType src_ptr [],
const DataType cos_ptr [],
long cos_len,
const long br_ptr [], OscType osc_list [])
3446 const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
3448 long coef_index = 0;
3451 dest_ptr [coef_index ] = src_ptr [coef_index] + src_ptr [coef_index + 4];
3452 dest_ptr [coef_index + 4] = src_ptr [coef_index] - src_ptr [coef_index + 4];
3453 dest_ptr [coef_index + 2] = src_ptr [coef_index + 2] * 2;
3454 dest_ptr [coef_index + 6] = src_ptr [coef_index + 6] * 2;
3456 dest_ptr [coef_index + 1] = src_ptr [coef_index + 1] + src_ptr [coef_index + 3];
3457 dest_ptr [coef_index + 3] = src_ptr [coef_index + 5] - src_ptr [coef_index + 7];
3459 const DataType vr = src_ptr [coef_index + 1] - src_ptr [coef_index + 3];
3460 const DataType vi = src_ptr [coef_index + 5] + src_ptr [coef_index + 7];
3462 dest_ptr [coef_index + 5] = (vr + vi) * sqrt2_2;
3463 dest_ptr [coef_index + 7] = (vi - vr) * sqrt2_2;
3467 while (coef_index < len);
3471 inline void FFTRealPassInverse <1>::process_internal (
long len, DataType dest_ptr [],
const DataType src_ptr [],
const DataType cos_ptr [],
long cos_len,
const long br_ptr [], OscType osc_list [])
3474 const long qlen = len >> 2;
3476 long coef_index = 0;
3479 const long ri_0 = br_ptr [coef_index >> 2];
3481 const DataType b_0 = src_ptr [coef_index ] + src_ptr [coef_index + 2];
3482 const DataType b_2 = src_ptr [coef_index ] - src_ptr [coef_index + 2];
3483 const DataType b_1 = src_ptr [coef_index + 1] * 2;
3484 const DataType b_3 = src_ptr [coef_index + 3] * 2;
3486 dest_ptr [ri_0 ] = b_0 + b_1;
3487 dest_ptr [ri_0 + 2 * qlen] = b_0 - b_1;
3488 dest_ptr [ri_0 + 1 * qlen] = b_2 + b_3;
3489 dest_ptr [ri_0 + 3 * qlen] = b_2 - b_3;
3493 while (coef_index < len);
3512 #undef ffft_FFTRealPassInverse_CURRENT_CODEHEADER
3544 #if ! defined (ffft_FFTRealSelect_HEADER_INCLUDED)
3545 #define ffft_FFTRealSelect_HEADER_INCLUDED
3547 #if defined (_MSC_VER)
3572 ffft_FORCEINLINE
static float *
3573 sel_bin (
float *e_ptr,
float *o_ptr);
3613 #if defined (ffft_FFTRealSelect_CURRENT_CODEHEADER)
3614 #error Recursive inclusion of FFTRealSelect code header.
3616 #define ffft_FFTRealSelect_CURRENT_CODEHEADER
3618 #if ! defined (ffft_FFTRealSelect_CODEHEADER_INCLUDED)
3619 #define ffft_FFTRealSelect_CODEHEADER_INCLUDED
3633 float * FFTRealSelect <P>::sel_bin (
float *e_ptr,
float *o_ptr)
3641 inline float * FFTRealSelect <0>::sel_bin (
float *e_ptr,
float *o_ptr)
3654 #undef ffft_FFTRealSelect_CURRENT_CODEHEADER
3687 FFTRealFixLen <LL2>::FFTRealFixLen ()
3689 , _br_data (BR_ARR_SIZE)
3690 , _trigo_data (TRIGO_TABLE_ARR_SIZE)
3701 long FFTRealFixLen <LL2>::get_length ()
const
3710 void FFTRealFixLen <LL2>::do_fft (DataType f [],
const DataType x [])
3715 assert (FFT_LEN_L2 >= 3);
3718 const DataType * cos_ptr = &_trigo_data [0];
3719 const long * br_ptr = &_br_data [0];
3721 FFTRealPassDirect <FFT_LEN_L2 - 1>::process (
3727 TRIGO_TABLE_ARR_SIZE,
3735 inline void FFTRealFixLen <2>::do_fft (DataType f [],
const DataType x [])
3741 f [1] = x [0] - x [2];
3742 f [3] = x [1] - x [3];
3744 const DataType b_0 = x [0] + x [2];
3745 const DataType b_2 = x [1] + x [3];
3753 inline void FFTRealFixLen <1>::do_fft (DataType f [],
const DataType x [])
3759 f [0] = x [0] + x [1];
3760 f [1] = x [0] - x [1];
3765 inline void FFTRealFixLen <0>::do_fft (DataType f [],
const DataType x [])
3777 void FFTRealFixLen <LL2>::do_ifft (
const DataType f [], DataType x [])
3782 assert (FFT_LEN_L2 >= 3);
3786 FFTRealSelect <FFT_LEN_L2 & 1>::sel_bin (&_buffer [0], x);
3788 FFTRealSelect <FFT_LEN_L2 & 1>::sel_bin (x, &_buffer [0]);
3789 const DataType * cos_ptr = &_trigo_data [0];
3790 const long * br_ptr = &_br_data [0];
3792 FFTRealPassInverse <FFT_LEN_L2 - 1>::process (
3798 TRIGO_TABLE_ARR_SIZE,
3806 inline void FFTRealFixLen <2>::do_ifft (
const DataType f [], DataType x [])
3812 const DataType b_0 = f [0] + f [2];
3813 const DataType b_2 = f [0] - f [2];
3815 x [0] = b_0 + f [1] * 2;
3816 x [2] = b_0 - f [1] * 2;
3817 x [1] = b_2 + f [3] * 2;
3818 x [3] = b_2 - f [3] * 2;
3823 inline void FFTRealFixLen <1>::do_ifft (
const DataType f [], DataType x [])
3829 x [0] = f [0] + f [1];
3830 x [1] = f [0] - f [1];
3835 inline void FFTRealFixLen <0>::do_ifft (
const DataType f [], DataType x [])
3848 void FFTRealFixLen <LL2>::rescale (DataType x [])
const
3852 const DataType mul = DataType (1.0 / FFT_LEN);
3856 long i = FFT_LEN - 1;
3867 assert ((FFT_LEN & 3) == 0);
3870 long i = FFT_LEN - 4;
3894 void FFTRealFixLen <LL2>::build_br_lut ()
3897 for (
long cnt = 1; cnt < BR_ARR_SIZE; ++cnt)
3899 long index = cnt << 2;
3902 int bit_cnt = FFT_LEN_L2;
3906 br_index += (index & 1);
3911 while (bit_cnt > 0);
3913 _br_data [cnt] = br_index;
3920 void FFTRealFixLen <LL2>::build_trigo_lut ()
3922 const double mul = (0.5 * PI) / TRIGO_TABLE_ARR_SIZE;
3923 for (
long i = 0; i < TRIGO_TABLE_ARR_SIZE; ++ i)
3925 using namespace std;
3927 _trigo_data [i] = DataType (cos (i * mul));
3934 void FFTRealFixLen <LL2>::build_trigo_osc ()
3936 for (
int i = 0; i < NBR_TRIGO_OSC; ++i)
3938 OscType & osc = _trigo_osc [i];
3940 const long len =
static_cast <long> (TRIGO_TABLE_ARR_SIZE) << (i + 1);
3941 const double mul = (0.5 * PI) / len;
3954 #undef ffft_FFTRealFixLen_CURRENT_CODEHEADER
Definition: FFTReal.h:1664
Definition: FFTReal.h:129
Definition: FFTReal.h:2402
Definition: FFTReal.h:2107
Definition: FFTReal.h:578
Definition: FFTReal.h:2553
Definition: FFTReal.h:3047
Definition: FFTReal.h:3566
Definition: FFTReal.h:2669
Definition: FFTReal.h:377
AudioTools internal: FFT.
Definition: FFTReal.h:61