18#include "AudioTools/CoreAudio/AudioBasic/Collections/Allocator.h"
19#define FFT_CUSTOM_ALLOC audio_tools::DefaultAllocator
22#if ! defined (ffft_FFTReal_HEADER_INCLUDED)
23#define ffft_FFTReal_HEADER_INCLUDED
27 #pragma warning (4 : 4250)
51#if ! defined (ffft_def_HEADER_INCLUDED)
52#define ffft_def_HEADER_INCLUDED
56 #pragma warning (4 : 4250)
69const double PI = 3.1415926535897932384626433832795;
71const double SQRT2 = 1.41421356237309514547462185873883;
75 #define ffft_FORCEINLINE __forceinline
79 #define ffft_FORCEINLINE inline
112#if ! defined (ffft_DynArray_HEADER_INCLUDED)
113#define ffft_DynArray_HEADER_INCLUDED
115#if defined (_MSC_VER)
117 #pragma warning (4 : 4250)
145 inline long size ()
const;
146 inline void resize (
long size);
148 inline const DataType &
149 operator [] (
long pos)
const;
151 operator [] (
long pos);
165 DataType * _data_ptr;
176 bool operator == (
const DynArray &other);
177 bool operator != (
const DynArray &other);
204#if defined (ffft_DynArray_CURRENT_CODEHEADER)
205 #error Recursive inclusion of DynArray code header.
207#define ffft_DynArray_CURRENT_CODEHEADER
209#if ! defined (ffft_DynArray_CODEHEADER_INCLUDED)
210#define ffft_DynArray_CODEHEADER_INCLUDED
230DynArray <T>::DynArray ()
240DynArray <T>::DynArray (
long size)
247#ifdef FFT_CUSTOM_ALLOC
248 _data_ptr = FFT_CUSTOM_ALLOC.createArray<DataType>(size);
250 _data_ptr =
new DataType [size];
259DynArray <T>::~DynArray ()
261#ifdef FFT_CUSTOM_ALLOC
262 FFT_CUSTOM_ALLOC.removeArray<DataType>(_data_ptr, _len);
273long DynArray <T>::size ()
const
281void DynArray <T>::resize (
long size)
286 DataType * old_data_ptr = _data_ptr;
287#ifdef FFT_CUSTOM_ALLOC
288 DataType * tmp_data_ptr = FFT_CUSTOM_ALLOC.createArray<DataType>(size);
290 DataType * tmp_data_ptr =
new DataType [size];
292 _data_ptr = tmp_data_ptr;
295#ifdef FFT_CUSTOM_ALLOC
296 FFT_CUSTOM_ALLOC.removeArray<DataType>(old_data_ptr, _len);
298 delete [] old_data_ptr;
306const typename DynArray <T>::DataType & DynArray <T>::operator [] (
long pos)
const
311 return (_data_ptr [pos]);
317typename DynArray <T>::DataType & DynArray <T>::operator [] (
long pos)
322 return (_data_ptr [pos]);
341#undef ffft_DynArray_CURRENT_CODEHEADER
373#if ! defined (ffft_OscSinCos_HEADER_INCLUDED)
374#define ffft_OscSinCos_HEADER_INCLUDED
376#if defined (_MSC_VER)
378 #pragma warning (4 : 4250)
406 ffft_FORCEINLINE
void
407 set_step (
double angle_rad);
409 ffft_FORCEINLINE DataType
411 ffft_FORCEINLINE DataType
413 ffft_FORCEINLINE
void
415 ffft_FORCEINLINE
void
443 bool operator == (
const OscSinCos &other);
444 bool operator != (
const OscSinCos &other);
471#if defined (ffft_OscSinCos_CURRENT_CODEHEADER)
472 #error Recursive inclusion of OscSinCos code header.
474#define ffft_OscSinCos_CURRENT_CODEHEADER
476#if ! defined (ffft_OscSinCos_CODEHEADER_INCLUDED)
477#define ffft_OscSinCos_CODEHEADER_INCLUDED
502OscSinCos <T>::OscSinCos ()
514void OscSinCos <T>::set_step (
double angle_rad)
518 _step_cos =
static_cast <DataType
> (cos (angle_rad));
519 _step_sin =
static_cast <DataType
> (sin (angle_rad));
525typename OscSinCos <T>::DataType OscSinCos <T>::get_cos ()
const
533typename OscSinCos <T>::DataType OscSinCos <T>::get_sin ()
const
541void OscSinCos <T>::step ()
543 const DataType old_cos = _pos_cos;
544 const DataType old_sin = _pos_sin;
546 _pos_cos = old_cos * _step_cos - old_sin * _step_sin;
547 _pos_sin = old_cos * _step_sin + old_sin * _step_cos;
553void OscSinCos <T>::clear_buffers ()
555 _pos_cos =
static_cast <DataType
> (1);
556 _pos_sin =
static_cast <DataType
> (0);
575#undef ffft_OscSinCos_CURRENT_CODEHEADER
606 enum { MAX_BIT_DEPTH = 30 };
610 explicit FFTReal (
long length);
613 long get_length ()
const;
614 void do_fft (DataType f [],
const DataType x [])
const;
615 void do_ifft (
const DataType f [], DataType x [])
const;
616 void rescale (DataType x [])
const;
617 DataType * use_buffer ()
const;
632 enum { TRIGO_BD_LIMIT = 12 };
634 typedef OscSinCos <DataType>
OscType;
637 void init_trigo_lut ();
638 void init_trigo_osc ();
640 ffft_FORCEINLINE
const long *
642 ffft_FORCEINLINE
const DataType *
643 get_trigo_ptr (
int level)
const;
644 ffft_FORCEINLINE
long
645 get_trigo_level_index (
int level)
const;
647 inline void compute_fft_general (DataType f [],
const DataType x [])
const;
648 inline void compute_direct_pass_1_2 (DataType df [],
const DataType x [])
const;
649 inline void compute_direct_pass_3 (DataType df [],
const DataType sf [])
const;
650 inline void compute_direct_pass_n (DataType df [],
const DataType sf [],
int pass)
const;
651 inline void compute_direct_pass_n_lut (DataType df [],
const DataType sf [],
int pass)
const;
652 inline void compute_direct_pass_n_osc (DataType df [],
const DataType sf [],
int pass)
const;
654 inline void compute_ifft_general (
const DataType f [], DataType x [])
const;
655 inline void compute_inverse_pass_n (DataType df [],
const DataType sf [],
int pass)
const;
656 inline void compute_inverse_pass_n_osc (DataType df [],
const DataType sf [],
int pass)
const;
657 inline void compute_inverse_pass_n_lut (DataType df [],
const DataType sf [],
int pass)
const;
658 inline void compute_inverse_pass_3 (DataType df [],
const DataType sf [])
const;
659 inline void compute_inverse_pass_1_2 (DataType x [],
const DataType sf [])
const;
667 mutable DynArray <DataType>
669 mutable DynArray <OscType>
681 bool operator == (
const FFTReal &other);
682 bool operator != (
const FFTReal &other);
709#if defined (ffft_FFTReal_CURRENT_CODEHEADER)
710 #error Recursive inclusion of FFTReal code header.
712#define ffft_FFTReal_CURRENT_CODEHEADER
714#if ! defined (ffft_FFTReal_CODEHEADER_INCLUDED)
715#define ffft_FFTReal_CODEHEADER_INCLUDED
724static inline bool FFTReal_is_pow2 (
long x)
728 return ((x & -x) == x);
733static inline int FFTReal_get_next_pow2 (
long x)
738 while ((x & ~0xFFFFL) != 0)
743 while ((x & ~0xFL) != 0)
774FFTReal <DT>::FFTReal (
long length)
776, _nbr_bits (FFTReal_get_next_pow2 (length))
782 assert (FFTReal_is_pow2 (length));
783 assert (_nbr_bits <= MAX_BIT_DEPTH);
803long FFTReal <DT>::get_length ()
const
827void FFTReal <DT>::do_fft (DataType f [],
const DataType x [])
const
830 assert (f != use_buffer ());
832 assert (x != use_buffer ());
838 compute_fft_general (f, x);
842 else if (_nbr_bits == 2)
844 f [1] = x [0] - x [2];
845 f [3] = x [1] - x [3];
847 const DataType b_0 = x [0] + x [2];
848 const DataType b_2 = x [1] + x [3];
855 else if (_nbr_bits == 1)
857 f [0] = x [0] + x [1];
858 f [1] = x [0] - x [1];
888void FFTReal <DT>::do_ifft (
const DataType f [], DataType x [])
const
891 assert (f != use_buffer ());
893 assert (x != use_buffer ());
899 compute_ifft_general (f, x);
903 else if (_nbr_bits == 2)
905 const DataType b_0 = f [0] + f [2];
906 const DataType b_2 = f [0] - f [2];
908 x [0] = b_0 + f [1] * 2;
909 x [2] = b_0 - f [1] * 2;
910 x [1] = b_2 + f [3] * 2;
911 x [3] = b_2 - f [3] * 2;
915 else if (_nbr_bits == 1)
917 x [0] = f [0] + f [1];
918 x [1] = f [0] - f [1];
943void FFTReal <DT>::rescale (DataType x [])
const
945 const DataType mul = DataType (1.0 / _length);
949 long i = _length - 1;
960 assert ((_length & 3) == 0);
963 long i = _length - 4;
994typename FFTReal <DT>::DataType * FFTReal <DT>::use_buffer ()
const
996 return (&_buffer [0]);
1010void FFTReal <DT>::init_br_lut ()
1012 const long length = 1L << _nbr_bits;
1013 _br_lut.resize (length);
1017 for (
long cnt = 1; cnt < length; ++cnt)
1020 long bit = length >> 1;
1021 while (((br_index ^= bit) & bit) == 0)
1026 _br_lut [cnt] = br_index;
1033void FFTReal <DT>::init_trigo_lut ()
1035 using namespace std;
1039 const long total_len = (1L << (_nbr_bits - 1)) - 4;
1040 _trigo_lut.resize (total_len);
1042 for (
int level = 3; level < _nbr_bits; ++level)
1044 const long level_len = 1L << (level - 1);
1045 DataType *
const level_ptr =
1046 &_trigo_lut [get_trigo_level_index (level)];
1047 const double mul = PI / (level_len << 1);
1049 for (
long i = 0; i < level_len; ++ i)
1051 level_ptr [i] =
static_cast <DataType
> (cos (i * mul));
1060void FFTReal <DT>::init_trigo_osc ()
1062 const int nbr_osc = _nbr_bits - TRIGO_BD_LIMIT;
1065 _trigo_osc.resize (nbr_osc);
1067 for (
int osc_cnt = 0; osc_cnt < nbr_osc; ++osc_cnt)
1069 OscType & osc = _trigo_osc [osc_cnt];
1071 const long len = 1L << (TRIGO_BD_LIMIT + osc_cnt);
1072 const double mul = (0.5 * PI) / len;
1081const long * FFTReal <DT>::get_br_ptr ()
const
1083 return (&_br_lut [0]);
1089const typename FFTReal <DT>::DataType * FFTReal <DT>::get_trigo_ptr (
int level)
const
1091 assert (level >= 3);
1093 return (&_trigo_lut [get_trigo_level_index (level)]);
1099long FFTReal <DT>::get_trigo_level_index (
int level)
const
1101 assert (level >= 3);
1103 return ((1L << (level - 1)) - 4);
1110void FFTReal <DT>::compute_fft_general (DataType f [],
const DataType x [])
const
1113 assert (f != use_buffer ());
1115 assert (x != use_buffer ());
1121 if ((_nbr_bits & 1) != 0)
1132 compute_direct_pass_1_2 (df, x);
1133 compute_direct_pass_3 (sf, df);
1135 for (
int pass = 3; pass < _nbr_bits; ++ pass)
1137 compute_direct_pass_n (df, sf, pass);
1139 DataType *
const temp_ptr = df;
1148void FFTReal <DT>::compute_direct_pass_1_2 (DataType df [],
const DataType x [])
const
1154 const long *
const bit_rev_lut_ptr = get_br_ptr ();
1155 long coef_index = 0;
1158 const long rev_index_0 = bit_rev_lut_ptr [coef_index];
1159 const long rev_index_1 = bit_rev_lut_ptr [coef_index + 1];
1160 const long rev_index_2 = bit_rev_lut_ptr [coef_index + 2];
1161 const long rev_index_3 = bit_rev_lut_ptr [coef_index + 3];
1163 DataType *
const df2 = df + coef_index;
1164 df2 [1] = x [rev_index_0] - x [rev_index_1];
1165 df2 [3] = x [rev_index_2] - x [rev_index_3];
1167 const DataType sf_0 = x [rev_index_0] + x [rev_index_1];
1168 const DataType sf_2 = x [rev_index_2] + x [rev_index_3];
1170 df2 [0] = sf_0 + sf_2;
1171 df2 [2] = sf_0 - sf_2;
1175 while (coef_index < _length);
1181void FFTReal <DT>::compute_direct_pass_3 (DataType df [],
const DataType sf [])
const
1187 const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
1188 long coef_index = 0;
1193 df [coef_index] = sf [coef_index] + sf [coef_index + 4];
1194 df [coef_index + 4] = sf [coef_index] - sf [coef_index + 4];
1195 df [coef_index + 2] = sf [coef_index + 2];
1196 df [coef_index + 6] = sf [coef_index + 6];
1198 v = (sf [coef_index + 5] - sf [coef_index + 7]) * sqrt2_2;
1199 df [coef_index + 1] = sf [coef_index + 1] + v;
1200 df [coef_index + 3] = sf [coef_index + 1] - v;
1202 v = (sf [coef_index + 5] + sf [coef_index + 7]) * sqrt2_2;
1203 df [coef_index + 5] = v + sf [coef_index + 3];
1204 df [coef_index + 7] = v - sf [coef_index + 3];
1208 while (coef_index < _length);
1214void FFTReal <DT>::compute_direct_pass_n (DataType df [],
const DataType sf [],
int pass)
const
1220 assert (pass < _nbr_bits);
1222 if (pass <= TRIGO_BD_LIMIT)
1224 compute_direct_pass_n_lut (df, sf, pass);
1228 compute_direct_pass_n_osc (df, sf, pass);
1235void FFTReal <DT>::compute_direct_pass_n_lut (DataType df [],
const DataType sf [],
int pass)
const
1241 assert (pass < _nbr_bits);
1243 const long nbr_coef = 1 << pass;
1244 const long h_nbr_coef = nbr_coef >> 1;
1245 const long d_nbr_coef = nbr_coef << 1;
1246 long coef_index = 0;
1247 const DataType *
const cos_ptr = get_trigo_ptr (pass);
1250 const DataType *
const sf1r = sf + coef_index;
1251 const DataType *
const sf2r = sf1r + nbr_coef;
1252 DataType *
const dfr = df + coef_index;
1253 DataType *
const dfi = dfr + nbr_coef;
1256 dfr [0] = sf1r [0] + sf2r [0];
1257 dfi [0] = sf1r [0] - sf2r [0];
1258 dfr [h_nbr_coef] = sf1r [h_nbr_coef];
1259 dfi [h_nbr_coef] = sf2r [h_nbr_coef];
1262 const DataType *
const sf1i = sf1r + h_nbr_coef;
1263 const DataType *
const sf2i = sf1i + nbr_coef;
1264 for (
long i = 1; i < h_nbr_coef; ++ i)
1266 const DataType c = cos_ptr [i];
1267 const DataType s = cos_ptr [h_nbr_coef - i];
1270 v = sf2r [i] * c - sf2i [i] * s;
1271 dfr [i] = sf1r [i] + v;
1272 dfi [-i] = sf1r [i] - v;
1274 v = sf2r [i] * s + sf2i [i] * c;
1275 dfi [i] = v + sf1i [i];
1276 dfi [nbr_coef - i] = v - sf1i [i];
1279 coef_index += d_nbr_coef;
1281 while (coef_index < _length);
1287void FFTReal <DT>::compute_direct_pass_n_osc (DataType df [],
const DataType sf [],
int pass)
const
1292 assert (pass > TRIGO_BD_LIMIT);
1293 assert (pass < _nbr_bits);
1295 const long nbr_coef = 1 << pass;
1296 const long h_nbr_coef = nbr_coef >> 1;
1297 const long d_nbr_coef = nbr_coef << 1;
1298 long coef_index = 0;
1299 OscType & osc = _trigo_osc [pass - (TRIGO_BD_LIMIT + 1)];
1302 const DataType *
const sf1r = sf + coef_index;
1303 const DataType *
const sf2r = sf1r + nbr_coef;
1304 DataType *
const dfr = df + coef_index;
1305 DataType *
const dfi = dfr + nbr_coef;
1307 osc.clear_buffers ();
1310 dfr [0] = sf1r [0] + sf2r [0];
1311 dfi [0] = sf1r [0] - sf2r [0];
1312 dfr [h_nbr_coef] = sf1r [h_nbr_coef];
1313 dfi [h_nbr_coef] = sf2r [h_nbr_coef];
1316 const DataType *
const sf1i = sf1r + h_nbr_coef;
1317 const DataType *
const sf2i = sf1i + nbr_coef;
1318 for (
long i = 1; i < h_nbr_coef; ++ i)
1321 const DataType c = osc.get_cos ();
1322 const DataType s = osc.get_sin ();
1325 v = sf2r [i] * c - sf2i [i] * s;
1326 dfr [i] = sf1r [i] + v;
1327 dfi [-i] = sf1r [i] - v;
1329 v = sf2r [i] * s + sf2i [i] * c;
1330 dfi [i] = v + sf1i [i];
1331 dfi [nbr_coef - i] = v - sf1i [i];
1334 coef_index += d_nbr_coef;
1336 while (coef_index < _length);
1343void FFTReal <DT>::compute_ifft_general (
const DataType f [], DataType x [])
const
1346 assert (f != use_buffer ());
1348 assert (x != use_buffer ());
1351 DataType * sf =
const_cast <DataType *
> (f);
1363 df_temp = use_buffer ();
1366 for (
int pass = _nbr_bits - 1; pass >= 3; -- pass)
1368 compute_inverse_pass_n (df, sf, pass);
1370 if (pass < _nbr_bits - 1)
1372 DataType *
const temp_ptr = df;
1383 compute_inverse_pass_3 (df, sf);
1384 compute_inverse_pass_1_2 (x, df);
1390void FFTReal <DT>::compute_inverse_pass_n (DataType df [],
const DataType sf [],
int pass)
const
1396 assert (pass < _nbr_bits);
1398 if (pass <= TRIGO_BD_LIMIT)
1400 compute_inverse_pass_n_lut (df, sf, pass);
1404 compute_inverse_pass_n_osc (df, sf, pass);
1411void FFTReal <DT>::compute_inverse_pass_n_lut (DataType df [],
const DataType sf [],
int pass)
const
1417 assert (pass < _nbr_bits);
1419 const long nbr_coef = 1 << pass;
1420 const long h_nbr_coef = nbr_coef >> 1;
1421 const long d_nbr_coef = nbr_coef << 1;
1422 long coef_index = 0;
1423 const DataType *
const cos_ptr = get_trigo_ptr (pass);
1426 const DataType *
const sfr = sf + coef_index;
1427 const DataType *
const sfi = sfr + nbr_coef;
1428 DataType *
const df1r = df + coef_index;
1429 DataType *
const df2r = df1r + nbr_coef;
1432 df1r [0] = sfr [0] + sfi [0];
1433 df2r [0] = sfr [0] - sfi [0];
1434 df1r [h_nbr_coef] = sfr [h_nbr_coef] * 2;
1435 df2r [h_nbr_coef] = sfi [h_nbr_coef] * 2;
1438 DataType *
const df1i = df1r + h_nbr_coef;
1439 DataType *
const df2i = df1i + nbr_coef;
1440 for (
long i = 1; i < h_nbr_coef; ++ i)
1442 df1r [i] = sfr [i] + sfi [-i];
1443 df1i [i] = sfi [i] - sfi [nbr_coef - i];
1445 const DataType c = cos_ptr [i];
1446 const DataType s = cos_ptr [h_nbr_coef - i];
1447 const DataType vr = sfr [i] - sfi [-i];
1448 const DataType vi = sfi [i] + sfi [nbr_coef - i];
1450 df2r [i] = vr * c + vi * s;
1451 df2i [i] = vi * c - vr * s;
1454 coef_index += d_nbr_coef;
1456 while (coef_index < _length);
1462void FFTReal <DT>::compute_inverse_pass_n_osc (DataType df [],
const DataType sf [],
int pass)
const
1467 assert (pass > TRIGO_BD_LIMIT);
1468 assert (pass < _nbr_bits);
1470 const long nbr_coef = 1 << pass;
1471 const long h_nbr_coef = nbr_coef >> 1;
1472 const long d_nbr_coef = nbr_coef << 1;
1473 long coef_index = 0;
1474 OscType & osc = _trigo_osc [pass - (TRIGO_BD_LIMIT + 1)];
1477 const DataType *
const sfr = sf + coef_index;
1478 const DataType *
const sfi = sfr + nbr_coef;
1479 DataType *
const df1r = df + coef_index;
1480 DataType *
const df2r = df1r + nbr_coef;
1482 osc.clear_buffers ();
1485 df1r [0] = sfr [0] + sfi [0];
1486 df2r [0] = sfr [0] - sfi [0];
1487 df1r [h_nbr_coef] = sfr [h_nbr_coef] * 2;
1488 df2r [h_nbr_coef] = sfi [h_nbr_coef] * 2;
1491 DataType *
const df1i = df1r + h_nbr_coef;
1492 DataType *
const df2i = df1i + nbr_coef;
1493 for (
long i = 1; i < h_nbr_coef; ++ i)
1495 df1r [i] = sfr [i] + sfi [-i];
1496 df1i [i] = sfi [i] - sfi [nbr_coef - i];
1499 const DataType c = osc.get_cos ();
1500 const DataType s = osc.get_sin ();
1501 const DataType vr = sfr [i] - sfi [-i];
1502 const DataType vi = sfi [i] + sfi [nbr_coef - i];
1504 df2r [i] = vr * c + vi * s;
1505 df2i [i] = vi * c - vr * s;
1508 coef_index += d_nbr_coef;
1510 while (coef_index < _length);
1516void FFTReal <DT>::compute_inverse_pass_3 (DataType df [],
const DataType sf [])
const
1522 const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
1523 long coef_index = 0;
1526 df [coef_index] = sf [coef_index] + sf [coef_index + 4];
1527 df [coef_index + 4] = sf [coef_index] - sf [coef_index + 4];
1528 df [coef_index + 2] = sf [coef_index + 2] * 2;
1529 df [coef_index + 6] = sf [coef_index + 6] * 2;
1531 df [coef_index + 1] = sf [coef_index + 1] + sf [coef_index + 3];
1532 df [coef_index + 3] = sf [coef_index + 5] - sf [coef_index + 7];
1534 const DataType vr = sf [coef_index + 1] - sf [coef_index + 3];
1535 const DataType vi = sf [coef_index + 5] + sf [coef_index + 7];
1537 df [coef_index + 5] = (vr + vi) * sqrt2_2;
1538 df [coef_index + 7] = (vi - vr) * sqrt2_2;
1542 while (coef_index < _length);
1548void FFTReal <DT>::compute_inverse_pass_1_2 (DataType x [],
const DataType sf [])
const
1554 const long * bit_rev_lut_ptr = get_br_ptr ();
1555 const DataType * sf2 = sf;
1556 long coef_index = 0;
1560 const DataType b_0 = sf2 [0] + sf2 [2];
1561 const DataType b_2 = sf2 [0] - sf2 [2];
1562 const DataType b_1 = sf2 [1] * 2;
1563 const DataType b_3 = sf2 [3] * 2;
1565 x [bit_rev_lut_ptr [0]] = b_0 + b_1;
1566 x [bit_rev_lut_ptr [1]] = b_0 - b_1;
1567 x [bit_rev_lut_ptr [2]] = b_2 + b_3;
1568 x [bit_rev_lut_ptr [3]] = b_2 - b_3;
1571 const DataType b_0 = sf2 [4] + sf2 [6];
1572 const DataType b_2 = sf2 [4] - sf2 [6];
1573 const DataType b_1 = sf2 [5] * 2;
1574 const DataType b_3 = sf2 [7] * 2;
1576 x [bit_rev_lut_ptr [4]] = b_0 + b_1;
1577 x [bit_rev_lut_ptr [5]] = b_0 - b_1;
1578 x [bit_rev_lut_ptr [6]] = b_2 + b_3;
1579 x [bit_rev_lut_ptr [7]] = b_2 - b_3;
1584 bit_rev_lut_ptr += 8;
1586 while (coef_index < _length);
1597#undef ffft_FFTReal_CURRENT_CODEHEADER
1629#if ! defined (ffft_FFTRealFixLen_HEADER_INCLUDED)
1630#define ffft_FFTRealFixLen_HEADER_INCLUDED
1632#if defined (_MSC_VER)
1634 #pragma warning (4 : 4250)
1658#if ! defined (ffft_Array_HEADER_INCLUDED)
1659#define ffft_Array_HEADER_INCLUDED
1661#if defined (_MSC_VER)
1663 #pragma warning (4 : 4250)
1677template <
class T,
long LEN>
1689 inline const DataType &
1690 operator [] (
long pos)
const;
1692 operator [] (
long pos);
1709 DataType _data_arr [LEN];
1719 bool operator == (
const Array &other);
1720 bool operator != (
const Array &other);
1747#if defined (ffft_Array_CURRENT_CODEHEADER)
1748 #error Recursive inclusion of Array code header.
1750#define ffft_Array_CURRENT_CODEHEADER
1752#if ! defined (ffft_Array_CODEHEADER_INCLUDED)
1753#define ffft_Array_CODEHEADER_INCLUDED
1769template <
class T,
long LEN>
1770Array <T, LEN>::Array ()
1777template <
class T,
long LEN>
1778const typename Array <T, LEN>::DataType & Array <T, LEN>::operator [] (
long pos)
const
1783 return (_data_arr [pos]);
1788template <
class T,
long LEN>
1789typename Array <T, LEN>::DataType & Array <T, LEN>::operator [] (
long pos)
1794 return (_data_arr [pos]);
1799template <
class T,
long LEN>
1800long Array <T, LEN>::size ()
1821#undef ffft_Array_CURRENT_CODEHEADER
1853#if ! defined (ffft_DynArray_HEADER_INCLUDED)
1854#define ffft_DynArray_HEADER_INCLUDED
1856#if defined (_MSC_VER)
1858 #pragma warning (4 : 4250)
1883 explicit DynArray (
long size);
1886 inline long size ()
const;
1887 inline void resize (
long size);
1889 inline const DataType &
1890 operator [] (
long pos)
const;
1892 operator [] (
long pos);
1906 DataType * _data_ptr;
1915 DynArray (
const DynArray &other);
1916 DynArray & operator = (
const DynArray &other);
1917 bool operator == (
const DynArray &other);
1918 bool operator != (
const DynArray &other);
1945#if defined (ffft_DynArray_CURRENT_CODEHEADER)
1946 #error Recursive inclusion of DynArray code header.
1948#define ffft_DynArray_CURRENT_CODEHEADER
1950#if ! defined (ffft_DynArray_CODEHEADER_INCLUDED)
1951#define ffft_DynArray_CODEHEADER_INCLUDED
1968DynArray <T>::DynArray ()
1978DynArray <T>::DynArray (
long size)
1985#ifdef FFT_CUSTOM_ALLOC
1986 _data_ptr = FFT_CUSTOM_ALLOC.createArray<DataType>(size);
1988 _data_ptr =
new DataType [size];
1997DynArray <T>::~DynArray ()
1999#ifdef FFT_CUSTOM_ALLOC
2000 FFT_CUSTOM_ALLOC.removeArray<T>(_data_ptr, _len);
2002 delete [] _data_ptr;
2011long DynArray <T>::size ()
const
2019void DynArray <T>::resize (
long size)
2024 DataType * old_data_ptr = _data_ptr;
2025#ifdef FFT_CUSTOM_ALLOC
2027 DataType * tmp_data_ptr =
new DataType [size];
2030 _data_ptr = tmp_data_ptr;
2033#ifdef FFT_CUSTOM_ALLOC
2035 delete [] old_data_ptr;
2043const typename DynArray <T>::DataType & DynArray <T>::operator [] (
long pos)
const
2046 assert (pos < _len);
2048 return (_data_ptr [pos]);
2054typename DynArray <T>::DataType & DynArray <T>::operator [] (
long pos)
2057 assert (pos < _len);
2059 return (_data_ptr [pos]);
2078#undef ffft_DynArray_CURRENT_CODEHEADER
2110#if ! defined (ffft_FFTRealFixLenParam_HEADER_INCLUDED)
2111#define ffft_FFTRealFixLenParam_HEADER_INCLUDED
2113#if defined (_MSC_VER)
2115 #pragma warning (4 : 4250)
2137 enum { TRIGO_BD_LIMIT = 12 };
2139 typedef float DataType;
2201#if ! defined (ffft_OscSinCos_HEADER_INCLUDED)
2202#define ffft_OscSinCos_HEADER_INCLUDED
2204#if defined (_MSC_VER)
2206 #pragma warning (4 : 4250)
2234 ffft_FORCEINLINE
void
2235 set_step (
double angle_rad);
2237 ffft_FORCEINLINE DataType
2239 ffft_FORCEINLINE DataType
2241 ffft_FORCEINLINE
void
2243 ffft_FORCEINLINE
void
2269 OscSinCos (
const OscSinCos &other);
2270 OscSinCos & operator = (
const OscSinCos &other);
2271 bool operator == (
const OscSinCos &other);
2272 bool operator != (
const OscSinCos &other);
2299#if defined (ffft_OscSinCos_CURRENT_CODEHEADER)
2300 #error Recursive inclusion of OscSinCos code header.
2302#define ffft_OscSinCos_CURRENT_CODEHEADER
2304#if ! defined (ffft_OscSinCos_CODEHEADER_INCLUDED)
2305#define ffft_OscSinCos_CODEHEADER_INCLUDED
2327OscSinCos <T>::OscSinCos ()
2339void OscSinCos <T>::set_step (
double angle_rad)
2341 using namespace std;
2343 _step_cos =
static_cast <DataType
> (cos (angle_rad));
2344 _step_sin =
static_cast <DataType
> (sin (angle_rad));
2350typename OscSinCos <T>::DataType OscSinCos <T>::get_cos ()
const
2358typename OscSinCos <T>::DataType OscSinCos <T>::get_sin ()
const
2366void OscSinCos <T>::step ()
2368 const DataType old_cos = _pos_cos;
2369 const DataType old_sin = _pos_sin;
2371 _pos_cos = old_cos * _step_cos - old_sin * _step_sin;
2372 _pos_sin = old_cos * _step_sin + old_sin * _step_cos;
2378void OscSinCos <T>::clear_buffers ()
2380 _pos_cos =
static_cast <DataType
> (1);
2381 _pos_sin =
static_cast <DataType
> (0);
2400#undef ffft_OscSinCos_CURRENT_CODEHEADER
2426 typedef int CompileTimeCheck1 [(LL2 >= 0) ? 1 : -1];
2427 typedef int CompileTimeCheck2 [(LL2 <= 30) ? 1 : -1];
2433 typedef FFTRealFixLenParam::DataType DataType;
2434 typedef OscSinCos <DataType>
OscType;
2436 enum { FFT_LEN_L2 = LL2 };
2437 enum { FFT_LEN = 1 << FFT_LEN_L2 };
2441 inline long get_length ()
const;
2442 void do_fft (DataType f [],
const DataType x []);
2443 void do_ifft (
const DataType f [], DataType x []);
2444 void rescale (DataType x [])
const;
2458 enum { TRIGO_BD_LIMIT = FFTRealFixLenParam::TRIGO_BD_LIMIT };
2460 enum { BR_ARR_SIZE_L2 = ((FFT_LEN_L2 - 3) < 0) ? 0 : (FFT_LEN_L2 - 2) };
2461 enum { BR_ARR_SIZE = 1 << BR_ARR_SIZE_L2 };
2463 enum { TRIGO_BD = ((FFT_LEN_L2 - TRIGO_BD_LIMIT) < 0)
2465 : (int)TRIGO_BD_LIMIT };
2466 enum { TRIGO_TABLE_ARR_SIZE_L2 = (LL2 < 4) ? 0 : (TRIGO_BD - 2) };
2467 enum { TRIGO_TABLE_ARR_SIZE = 1 << TRIGO_TABLE_ARR_SIZE_L2 };
2469 enum { NBR_TRIGO_OSC = FFT_LEN_L2 - TRIGO_BD };
2470 enum { TRIGO_OSC_ARR_SIZE = (NBR_TRIGO_OSC > 0) ? NBR_TRIGO_OSC : 1 };
2472 void build_br_lut ();
2473 void build_trigo_lut ();
2474 void build_trigo_osc ();
2482 Array <OscType, TRIGO_OSC_ARR_SIZE>
2521#if defined (ffft_FFTRealFixLen_CURRENT_CODEHEADER)
2522 #error Recursive inclusion of FFTRealFixLen code header.
2524#define ffft_FFTRealFixLen_CURRENT_CODEHEADER
2526#if ! defined (ffft_FFTRealFixLen_CODEHEADER_INCLUDED)
2527#define ffft_FFTRealFixLen_CODEHEADER_INCLUDED
2551#if ! defined (ffft_FFTRealPassDirect_HEADER_INCLUDED)
2552#define ffft_FFTRealPassDirect_HEADER_INCLUDED
2554#if defined (_MSC_VER)
2556 #pragma warning (4 : 4250)
2582 typedef FFTRealFixLenParam::DataType DataType;
2583 typedef OscSinCos <DataType>
OscType;
2585 ffft_FORCEINLINE
static void
2586 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 []);
2638#if defined (ffft_FFTRealPassDirect_CURRENT_CODEHEADER)
2639 #error Recursive inclusion of FFTRealPassDirect code header.
2641#define ffft_FFTRealPassDirect_CURRENT_CODEHEADER
2643#if ! defined (ffft_FFTRealPassDirect_CODEHEADER_INCLUDED)
2644#define ffft_FFTRealPassDirect_CODEHEADER_INCLUDED
2667#if ! defined (ffft_FFTRealUseTrigo_HEADER_INCLUDED)
2668#define ffft_FFTRealUseTrigo_HEADER_INCLUDED
2670#if defined (_MSC_VER)
2672 #pragma warning (4 : 4250)
2698 typedef FFTRealFixLenParam::DataType DataType;
2699 typedef OscSinCos <DataType>
OscType;
2701 ffft_FORCEINLINE
static void
2703 ffft_FORCEINLINE
static void
2704 iterate (
OscType &osc, DataType &c, DataType &s,
const DataType cos_ptr [],
long index_c,
long index_s);
2757#if defined (ffft_FFTRealUseTrigo_CURRENT_CODEHEADER)
2758 #error Recursive inclusion of FFTRealUseTrigo code header.
2760#define ffft_FFTRealUseTrigo_CURRENT_CODEHEADER
2762#if ! defined (ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED)
2763#define ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED
2783void FFTRealUseTrigo <ALGO>::prepare (OscType &osc)
2785 osc.clear_buffers ();
2789inline void FFTRealUseTrigo <0>::prepare (OscType &osc)
2797void FFTRealUseTrigo <ALGO>::iterate (OscType &osc, DataType &c, DataType &s,
const DataType cos_ptr [],
long index_c,
long index_s)
2805inline void FFTRealUseTrigo <0>::iterate (OscType &osc, DataType &c, DataType &s,
const DataType cos_ptr [],
long index_c,
long index_s)
2807 c = cos_ptr [index_c];
2808 s = cos_ptr [index_s];
2827#undef ffft_FFTRealUseTrigo_CURRENT_CODEHEADER
2855inline 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 [])
2858 const long qlen = len >> 2;
2860 long coef_index = 0;
2864 const long ri_0 = br_ptr [coef_index >> 2];
2865 const long ri_1 = ri_0 + 2 * qlen;
2866 const long ri_2 = ri_0 + 1 * qlen;
2867 const long ri_3 = ri_0 + 3 * qlen;
2869 DataType *
const df2 = dest_ptr + coef_index;
2870 df2 [1] = x_ptr [ri_0] - x_ptr [ri_1];
2871 df2 [3] = x_ptr [ri_2] - x_ptr [ri_3];
2873 const DataType sf_0 = x_ptr [ri_0] + x_ptr [ri_1];
2874 const DataType sf_2 = x_ptr [ri_2] + x_ptr [ri_3];
2876 df2 [0] = sf_0 + sf_2;
2877 df2 [2] = sf_0 - sf_2;
2881 while (coef_index < len);
2885inline 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 [])
2888 FFTRealPassDirect <1>::process (
2900 const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
2902 long coef_index = 0;
2905 dest_ptr [coef_index ] = src_ptr [coef_index] + src_ptr [coef_index + 4];
2906 dest_ptr [coef_index + 4] = src_ptr [coef_index] - src_ptr [coef_index + 4];
2907 dest_ptr [coef_index + 2] = src_ptr [coef_index + 2];
2908 dest_ptr [coef_index + 6] = src_ptr [coef_index + 6];
2912 v = (src_ptr [coef_index + 5] - src_ptr [coef_index + 7]) * sqrt2_2;
2913 dest_ptr [coef_index + 1] = src_ptr [coef_index + 1] + v;
2914 dest_ptr [coef_index + 3] = src_ptr [coef_index + 1] - v;
2916 v = (src_ptr [coef_index + 5] + src_ptr [coef_index + 7]) * sqrt2_2;
2917 dest_ptr [coef_index + 5] = v + src_ptr [coef_index + 3];
2918 dest_ptr [coef_index + 7] = v - src_ptr [coef_index + 3];
2922 while (coef_index < len);
2926void 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 [])
2929 FFTRealPassDirect <PASS - 1>::process (
2940 const long dist = 1L << (PASS - 1);
2941 const long c1_r = 0;
2942 const long c1_i = dist;
2943 const long c2_r = dist * 2;
2944 const long c2_i = dist * 3;
2945 const long cend = dist * 4;
2946 const long table_step = cos_len >> (PASS - 1);
2948 enum { TRIGO_OSC = PASS - FFTRealFixLenParam::TRIGO_BD_LIMIT };
2949 enum { TRIGO_DIRECT = (TRIGO_OSC >= 0) ? 1 : 0 };
2951 long coef_index = 0;
2954 const DataType *
const sf = src_ptr + coef_index;
2955 DataType *
const df = dest_ptr + coef_index;
2958 df [c1_r] = sf [c1_r] + sf [c2_r];
2959 df [c2_r] = sf [c1_r] - sf [c2_r];
2960 df [c1_i] = sf [c1_i];
2961 df [c2_i] = sf [c2_i];
2963 FFTRealUseTrigo <TRIGO_DIRECT>::prepare (osc_list [TRIGO_OSC]);
2966 for (
long i = 1; i < dist; ++ i)
2970 FFTRealUseTrigo <TRIGO_DIRECT>::iterate (
2971 osc_list [TRIGO_OSC],
2976 (dist - i) * table_step
2979 const DataType sf_r_i = sf [c1_r + i];
2980 const DataType sf_i_i = sf [c1_i + i];
2982 const DataType v1 = sf [c2_r + i] * c - sf [c2_i + i] * s;
2983 df [c1_r + i] = sf_r_i + v1;
2984 df [c2_r - i] = sf_r_i - v1;
2986 const DataType v2 = sf [c2_r + i] * s + sf [c2_i + i] * c;
2987 df [c2_r + i] = v2 + sf_i_i;
2988 df [cend - i] = v2 - sf_i_i;
2993 while (coef_index < len);
3012#undef ffft_FFTRealPassDirect_CURRENT_CODEHEADER
3044#if ! defined (ffft_FFTRealPassInverse_HEADER_INCLUDED)
3045#define ffft_FFTRealPassInverse_HEADER_INCLUDED
3047#if defined (_MSC_VER)
3049 #pragma warning (4 : 4250)
3076 typedef FFTRealFixLenParam::DataType DataType;
3077 typedef OscSinCos <DataType>
OscType;
3079 ffft_FORCEINLINE
static void
3080 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 []);
3081 ffft_FORCEINLINE
static void
3082 process_rec (
long len, DataType dest_ptr [], DataType src_ptr [],
const DataType cos_ptr [],
long cos_len,
const long br_ptr [],
OscType osc_list []);
3083 ffft_FORCEINLINE
static void
3084 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 []);
3136#if defined (ffft_FFTRealPassInverse_CURRENT_CODEHEADER)
3137 #error Recursive inclusion of FFTRealPassInverse code header.
3139#define ffft_FFTRealPassInverse_CURRENT_CODEHEADER
3141#if ! defined (ffft_FFTRealPassInverse_CODEHEADER_INCLUDED)
3142#define ffft_FFTRealPassInverse_CODEHEADER_INCLUDED
3165#if ! defined (ffft_FFTRealUseTrigo_HEADER_INCLUDED)
3166#define ffft_FFTRealUseTrigo_HEADER_INCLUDED
3168#if defined (_MSC_VER)
3170 #pragma warning (4 : 4250)
3189class FFTRealUseTrigo
3196 typedef FFTRealFixLenParam::DataType DataType;
3197 typedef OscSinCos <DataType> OscType;
3199 ffft_FORCEINLINE
static void
3200 prepare (OscType &osc);
3201 ffft_FORCEINLINE
static void
3202 iterate (OscType &osc, DataType &c, DataType &s,
const DataType cos_ptr [],
long index_c,
long index_s);
3223 ~FFTRealUseTrigo ();
3224 FFTRealUseTrigo (
const FFTRealUseTrigo &other);
3226 operator = (
const FFTRealUseTrigo &other);
3227 bool operator == (
const FFTRealUseTrigo &other);
3228 bool operator != (
const FFTRealUseTrigo &other);
3255#if defined (ffft_FFTRealUseTrigo_CURRENT_CODEHEADER)
3256 #error Recursive inclusion of FFTRealUseTrigo code header.
3258#define ffft_FFTRealUseTrigo_CURRENT_CODEHEADER
3260#if ! defined (ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED)
3261#define ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED
3281void FFTRealUseTrigo <ALGO>::prepare (OscType &osc)
3283 osc.clear_buffers ();
3287inline void FFTRealUseTrigo <0>::prepare (OscType &osc)
3295void FFTRealUseTrigo <ALGO>::iterate (OscType &osc, DataType &c, DataType &s,
const DataType cos_ptr [],
long index_c,
long index_s)
3303inline void FFTRealUseTrigo <0>::iterate (OscType &osc, DataType &c, DataType &s,
const DataType cos_ptr [],
long index_c,
long index_s)
3305 c = cos_ptr [index_c];
3306 s = cos_ptr [index_s];
3325#undef ffft_FFTRealUseTrigo_CURRENT_CODEHEADER
3353void 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 [])
3364 FFTRealPassInverse <PASS - 1>::process_rec (
3378void 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 [])
3389 FFTRealPassInverse <PASS - 1>::process_rec (
3401inline 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 [])
3409void 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 [])
3411 const long dist = 1L << (PASS - 1);
3412 const long c1_r = 0;
3413 const long c1_i = dist;
3414 const long c2_r = dist * 2;
3415 const long c2_i = dist * 3;
3416 const long cend = dist * 4;
3417 const long table_step = cos_len >> (PASS - 1);
3419 enum { TRIGO_OSC = PASS - FFTRealFixLenParam::TRIGO_BD_LIMIT };
3420 enum { TRIGO_DIRECT = (TRIGO_OSC >= 0) ? 1 : 0 };
3422 long coef_index = 0;
3425 const DataType *
const sf = src_ptr + coef_index;
3426 DataType *
const df = dest_ptr + coef_index;
3429 df [c1_r] = sf [c1_r] + sf [c2_r];
3430 df [c2_r] = sf [c1_r] - sf [c2_r];
3431 df [c1_i] = sf [c1_i] * 2;
3432 df [c2_i] = sf [c2_i] * 2;
3434 FFTRealUseTrigo <TRIGO_DIRECT>::prepare (osc_list [TRIGO_OSC]);
3437 for (
long i = 1; i < dist; ++ i)
3439 df [c1_r + i] = sf [c1_r + i] + sf [c2_r - i];
3440 df [c1_i + i] = sf [c2_r + i] - sf [cend - i];
3444 FFTRealUseTrigo <TRIGO_DIRECT>::iterate (
3445 osc_list [TRIGO_OSC],
3450 (dist - i) * table_step
3453 const DataType vr = sf [c1_r + i] - sf [c2_r - i];
3454 const DataType vi = sf [c2_r + i] + sf [cend - i];
3456 df [c2_r + i] = vr * c + vi * s;
3457 df [c2_i + i] = vi * c - vr * s;
3462 while (coef_index < len);
3466inline 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 [])
3469 const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
3471 long coef_index = 0;
3474 dest_ptr [coef_index ] = src_ptr [coef_index] + src_ptr [coef_index + 4];
3475 dest_ptr [coef_index + 4] = src_ptr [coef_index] - src_ptr [coef_index + 4];
3476 dest_ptr [coef_index + 2] = src_ptr [coef_index + 2] * 2;
3477 dest_ptr [coef_index + 6] = src_ptr [coef_index + 6] * 2;
3479 dest_ptr [coef_index + 1] = src_ptr [coef_index + 1] + src_ptr [coef_index + 3];
3480 dest_ptr [coef_index + 3] = src_ptr [coef_index + 5] - src_ptr [coef_index + 7];
3482 const DataType vr = src_ptr [coef_index + 1] - src_ptr [coef_index + 3];
3483 const DataType vi = src_ptr [coef_index + 5] + src_ptr [coef_index + 7];
3485 dest_ptr [coef_index + 5] = (vr + vi) * sqrt2_2;
3486 dest_ptr [coef_index + 7] = (vi - vr) * sqrt2_2;
3490 while (coef_index < len);
3494inline 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 [])
3497 const long qlen = len >> 2;
3499 long coef_index = 0;
3502 const long ri_0 = br_ptr [coef_index >> 2];
3504 const DataType b_0 = src_ptr [coef_index ] + src_ptr [coef_index + 2];
3505 const DataType b_2 = src_ptr [coef_index ] - src_ptr [coef_index + 2];
3506 const DataType b_1 = src_ptr [coef_index + 1] * 2;
3507 const DataType b_3 = src_ptr [coef_index + 3] * 2;
3509 dest_ptr [ri_0 ] = b_0 + b_1;
3510 dest_ptr [ri_0 + 2 * qlen] = b_0 - b_1;
3511 dest_ptr [ri_0 + 1 * qlen] = b_2 + b_3;
3512 dest_ptr [ri_0 + 3 * qlen] = b_2 - b_3;
3516 while (coef_index < len);
3535#undef ffft_FFTRealPassInverse_CURRENT_CODEHEADER
3567#if ! defined (ffft_FFTRealSelect_HEADER_INCLUDED)
3568#define ffft_FFTRealSelect_HEADER_INCLUDED
3570#if defined (_MSC_VER)
3595 ffft_FORCEINLINE
static float *
3596 sel_bin (
float *e_ptr,
float *o_ptr);
3636#if defined (ffft_FFTRealSelect_CURRENT_CODEHEADER)
3637 #error Recursive inclusion of FFTRealSelect code header.
3639#define ffft_FFTRealSelect_CURRENT_CODEHEADER
3641#if ! defined (ffft_FFTRealSelect_CODEHEADER_INCLUDED)
3642#define ffft_FFTRealSelect_CODEHEADER_INCLUDED
3656float * FFTRealSelect <P>::sel_bin (
float *e_ptr,
float *o_ptr)
3664inline float * FFTRealSelect <0>::sel_bin (
float *e_ptr,
float *o_ptr)
3677#undef ffft_FFTRealSelect_CURRENT_CODEHEADER
3707FFTRealFixLen <LL2>::FFTRealFixLen ()
3709, _br_data (BR_ARR_SIZE)
3710, _trigo_data (TRIGO_TABLE_ARR_SIZE)
3721long FFTRealFixLen <LL2>::get_length ()
const
3730void FFTRealFixLen <LL2>::do_fft (DataType f [],
const DataType x [])
3735 assert (FFT_LEN_L2 >= 3);
3738 const DataType * cos_ptr = &_trigo_data [0];
3739 const long * br_ptr = &_br_data [0];
3741 FFTRealPassDirect <FFT_LEN_L2 - 1>::process (
3747 TRIGO_TABLE_ARR_SIZE,
3755inline void FFTRealFixLen <2>::do_fft (DataType f [],
const DataType x [])
3761 f [1] = x [0] - x [2];
3762 f [3] = x [1] - x [3];
3764 const DataType b_0 = x [0] + x [2];
3765 const DataType b_2 = x [1] + x [3];
3773inline void FFTRealFixLen <1>::do_fft (DataType f [],
const DataType x [])
3779 f [0] = x [0] + x [1];
3780 f [1] = x [0] - x [1];
3785inline void FFTRealFixLen <0>::do_fft (DataType f [],
const DataType x [])
3797void FFTRealFixLen <LL2>::do_ifft (
const DataType f [], DataType x [])
3802 assert (FFT_LEN_L2 >= 3);
3806 FFTRealSelect <FFT_LEN_L2 & 1>::sel_bin (&_buffer [0], x);
3808 FFTRealSelect <FFT_LEN_L2 & 1>::sel_bin (x, &_buffer [0]);
3809 const DataType * cos_ptr = &_trigo_data [0];
3810 const long * br_ptr = &_br_data [0];
3812 FFTRealPassInverse <FFT_LEN_L2 - 1>::process (
3818 TRIGO_TABLE_ARR_SIZE,
3826inline void FFTRealFixLen <2>::do_ifft (
const DataType f [], DataType x [])
3832 const DataType b_0 = f [0] + f [2];
3833 const DataType b_2 = f [0] - f [2];
3835 x [0] = b_0 + f [1] * 2;
3836 x [2] = b_0 - f [1] * 2;
3837 x [1] = b_2 + f [3] * 2;
3838 x [3] = b_2 - f [3] * 2;
3843inline void FFTRealFixLen <1>::do_ifft (
const DataType f [], DataType x [])
3849 x [0] = f [0] + f [1];
3850 x [1] = f [0] - f [1];
3855inline void FFTRealFixLen <0>::do_ifft (
const DataType f [], DataType x [])
3868void FFTRealFixLen <LL2>::rescale (DataType x [])
const
3872 const DataType mul = DataType (1.0 / FFT_LEN);
3876 long i = FFT_LEN - 1;
3887 assert ((FFT_LEN & 3) == 0);
3890 long i = FFT_LEN - 4;
3914void FFTRealFixLen <LL2>::build_br_lut ()
3917 for (
long cnt = 1; cnt < BR_ARR_SIZE; ++cnt)
3919 long index = cnt << 2;
3922 int bit_cnt = FFT_LEN_L2;
3926 br_index += (index & 1);
3931 while (bit_cnt > 0);
3933 _br_data [cnt] = br_index;
3940void FFTRealFixLen <LL2>::build_trigo_lut ()
3942 const double mul = (0.5 * PI) / TRIGO_TABLE_ARR_SIZE;
3943 for (
long i = 0; i < TRIGO_TABLE_ARR_SIZE; ++ i)
3945 using namespace std;
3947 _trigo_data [i] = DataType (cos (i * mul));
3954void FFTRealFixLen <LL2>::build_trigo_osc ()
3956 for (
int i = 0; i < NBR_TRIGO_OSC; ++i)
3958 OscType & osc = _trigo_osc [i];
3960 const long len =
static_cast <long> (TRIGO_TABLE_ARR_SIZE) << (i + 1);
3961 const double mul = (0.5 * PI) / len;
3974#undef ffft_FFTRealFixLen_CURRENT_CODEHEADER
Definition FFTReal.h:1679
Definition FFTReal.h:2425
Definition FFTReal.h:2130
Definition FFTReal.h:2576
Definition FFTReal.h:3070
Definition FFTReal.h:3589
Definition FFTReal.h:2692
AudioTools internal: FFT.
Definition FFTReal.h:65