arduino-audio-tools
FFTReal.h
1 /*****************************************************************************
2 
3  FFTReal.h
4  By Laurent de Soras
5 
6 --- Legal stuff ---
7 
8 This program is free software. It comes without any warranty, to
9 the extent permitted by applicable law. You can redistribute it
10 and/or modify it under the terms of the Do What The Fuck You Want
11 To Public License, Version 2, as published by Sam Hocevar. See
12 http://sam.zoy.org/wtfpl/COPYING for more details.
13 
14 *Tab=3***********************************************************************/
15 #pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion"
16 
17 
18 #if ! defined (ffft_FFTReal_HEADER_INCLUDED)
19 #define ffft_FFTReal_HEADER_INCLUDED
20 
21 #if defined (_MSC_VER)
22  #pragma once
23  #pragma warning (4 : 4250) // "Inherits via dominance."
24 #endif
25 
26 
27 
28 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
29 
30 /*****************************************************************************
31 
32  def.h
33  By Laurent de Soras
34 
35 --- Legal stuff ---
36 
37 This program is free software. It comes without any warranty, to
38 the extent permitted by applicable law. You can redistribute it
39 and/or modify it under the terms of the Do What The Fuck You Want
40 To Public License, Version 2, as published by Sam Hocevar. See
41 http://sam.zoy.org/wtfpl/COPYING for more details.
42 
43 *Tab=3***********************************************************************/
44 
45 
46 
47 #if ! defined (ffft_def_HEADER_INCLUDED)
48 #define ffft_def_HEADER_INCLUDED
49 
50 #if defined (_MSC_VER)
51  #pragma once
52  #pragma warning (4 : 4250) // "Inherits via dominance."
53 #endif
54 
55 
56 
57 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
58 
59 
61 namespace ffft {
62 
63 
64 #ifndef PI
65 const double PI = 3.1415926535897932384626433832795;
66 #endif
67 const double SQRT2 = 1.41421356237309514547462185873883;
68 
69 #if defined (_MSC_VER)
70 
71  #define ffft_FORCEINLINE __forceinline
72 
73 #else
74 
75  #define ffft_FORCEINLINE inline
76 
77 #endif
78 
79 
80 
81 } // namespace ffft
82 
83 
84 
85 #endif // ffft_def_HEADER_INCLUDED
86 
87 
88 
89 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
90 
91 /*****************************************************************************
92 
93  DynArray.h
94  By Laurent de Soras
95 
96 --- Legal stuff ---
97 
98 This program is free software. It comes without any warranty, to
99 the extent permitted by applicable law. You can redistribute it
100 and/or modify it under the terms of the Do What The Fuck You Want
101 To Public License, Version 2, as published by Sam Hocevar. See
102 http://sam.zoy.org/wtfpl/COPYING for more details.
103 
104 *Tab=3***********************************************************************/
105 
106 
107 
108 #if ! defined (ffft_DynArray_HEADER_INCLUDED)
109 #define ffft_DynArray_HEADER_INCLUDED
110 
111 #if defined (_MSC_VER)
112  #pragma once
113  #pragma warning (4 : 4250) // "Inherits via dominance."
114 #endif
115 
116 
117 
118 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
119 
120 
122 namespace ffft
123 {
124 
125 
126 
127 template <class T>
128 class DynArray
129 {
130 
131 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
132 
133 public:
134 
135  typedef T DataType;
136 
137  DynArray ();
138  explicit DynArray (long size);
139  ~DynArray ();
140 
141  inline long size () const;
142  inline void resize (long size);
143 
144  inline const DataType &
145  operator [] (long pos) const;
146  inline DataType &
147  operator [] (long pos);
148 
149 
150 
151 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
152 
153 protected:
154 
155 
156 
157 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
158 
159 private:
160 
161  DataType * _data_ptr;
162  long _len;
163 
164 
165 
166 /*\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\*/
167 
168 private:
169 
170  DynArray (const DynArray &other);
171  DynArray & operator = (const DynArray &other);
172  bool operator == (const DynArray &other);
173  bool operator != (const DynArray &other);
174 
175 }; // class DynArray
176 
177 
178 
179 } // namespace ffft
180 
181 
182 
183 /*****************************************************************************
184 
185  DynArray.hpp
186  By Laurent de Soras
187 
188 --- Legal stuff ---
189 
190 This program is free software. It comes without any warranty, to
191 the extent permitted by applicable law. You can redistribute it
192 and/or modify it under the terms of the Do What The Fuck You Want
193 To Public License, Version 2, as published by Sam Hocevar. See
194 http://sam.zoy.org/wtfpl/COPYING for more details.
195 
196 *Tab=3***********************************************************************/
197 
198 
199 
200 #if defined (ffft_DynArray_CURRENT_CODEHEADER)
201  #error Recursive inclusion of DynArray code header.
202 #endif
203 #define ffft_DynArray_CURRENT_CODEHEADER
204 
205 #if ! defined (ffft_DynArray_CODEHEADER_INCLUDED)
206 #define ffft_DynArray_CODEHEADER_INCLUDED
207 
208 
209 
210 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
211 
212 #include <cassert>
213 
214 
215 
216 namespace ffft
217 {
218 
219 
220 
221 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
222 
223 
224 
225 template <class T>
226 DynArray <T>::DynArray ()
227 : _data_ptr (0)
228 , _len (0)
229 {
230  // Nothing
231 }
232 
233 
234 
235 template <class T>
236 DynArray <T>::DynArray (long size)
237 : _data_ptr (0)
238 , _len (0)
239 {
240  assert (size >= 0);
241  if (size > 0)
242  {
243  _data_ptr = new DataType [size];
244  _len = size;
245  }
246 }
247 
248 
249 
250 template <class T>
251 DynArray <T>::~DynArray ()
252 {
253  delete [] _data_ptr;
254  _data_ptr = 0;
255  _len = 0;
256 }
257 
258 
259 
260 template <class T>
261 long DynArray <T>::size () const
262 {
263  return (_len);
264 }
265 
266 
267 
268 template <class T>
269 void DynArray <T>::resize (long size)
270 {
271  assert (size >= 0);
272  if (size > 0)
273  {
274  DataType * old_data_ptr = _data_ptr;
275  DataType * tmp_data_ptr = new DataType [size];
276 
277  _data_ptr = tmp_data_ptr;
278  _len = size;
279 
280  delete [] old_data_ptr;
281  }
282 }
283 
284 
285 
286 template <class T>
287 const typename DynArray <T>::DataType & DynArray <T>::operator [] (long pos) const
288 {
289  assert (pos >= 0);
290  assert (pos < _len);
291 
292  return (_data_ptr [pos]);
293 }
294 
295 
296 
297 template <class T>
298 typename DynArray <T>::DataType & DynArray <T>::operator [] (long pos)
299 {
300  assert (pos >= 0);
301  assert (pos < _len);
302 
303  return (_data_ptr [pos]);
304 }
305 
306 
307 
308 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
309 
310 
311 
312 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
313 
314 
315 
316 } // namespace ffft
317 
318 
319 
320 #endif // ffft_DynArray_CODEHEADER_INCLUDED
321 
322 #undef ffft_DynArray_CURRENT_CODEHEADER
323 
324 
325 
326 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
327 
328 
329 
330 
331 #endif // ffft_DynArray_HEADER_INCLUDED
332 
333 
334 
335 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
336 
337 /*****************************************************************************
338 
339  OscSinCos.h
340  By Laurent de Soras
341 
342 --- Legal stuff ---
343 
344 This program is free software. It comes without any warranty, to
345 the extent permitted by applicable law. You can redistribute it
346 and/or modify it under the terms of the Do What The Fuck You Want
347 To Public License, Version 2, as published by Sam Hocevar. See
348 http://sam.zoy.org/wtfpl/COPYING for more details.
349 
350 *Tab=3***********************************************************************/
351 
352 
353 
354 #if ! defined (ffft_OscSinCos_HEADER_INCLUDED)
355 #define ffft_OscSinCos_HEADER_INCLUDED
356 
357 #if defined (_MSC_VER)
358  #pragma once
359  #pragma warning (4 : 4250) // "Inherits via dominance."
360 #endif
361 
362 
363 
364 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
365 
366 
367 
368 
369 
370 namespace ffft
371 {
372 
373 
374 
375 template <class T>
377 {
378 
379 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
380 
381 public:
382 
383  typedef T DataType;
384 
385  OscSinCos ();
386 
387  ffft_FORCEINLINE void
388  set_step (double angle_rad);
389 
390  ffft_FORCEINLINE DataType
391  get_cos () const;
392  ffft_FORCEINLINE DataType
393  get_sin () const;
394  ffft_FORCEINLINE void
395  step ();
396  ffft_FORCEINLINE void
397  clear_buffers ();
398 
399 
400 
401 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
402 
403 protected:
404 
405 
406 
407 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
408 
409 private:
410 
411  DataType _pos_cos; // Current phase expressed with sin and cos. [-1 ; 1]
412  DataType _pos_sin; // -
413  DataType _step_cos; // Phase increment per step, [-1 ; 1]
414  DataType _step_sin; // -
415 
416 
417 
418 /*\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\*/
419 
420 private:
421 
422  OscSinCos (const OscSinCos &other);
423  OscSinCos & operator = (const OscSinCos &other);
424  bool operator == (const OscSinCos &other);
425  bool operator != (const OscSinCos &other);
426 
427 }; // class OscSinCos
428 
429 
430 
431 } // namespace ffft
432 
433 
434 
435 /*****************************************************************************
436 
437  OscSinCos.hpp
438  By Laurent de Soras
439 
440 --- Legal stuff ---
441 
442 This program is free software. It comes without any warranty, to
443 the extent permitted by applicable law. You can redistribute it
444 and/or modify it under the terms of the Do What The Fuck You Want
445 To Public License, Version 2, as published by Sam Hocevar. See
446 http://sam.zoy.org/wtfpl/COPYING for more details.
447 
448 *Tab=3***********************************************************************/
449 
450 
451 
452 #if defined (ffft_OscSinCos_CURRENT_CODEHEADER)
453  #error Recursive inclusion of OscSinCos code header.
454 #endif
455 #define ffft_OscSinCos_CURRENT_CODEHEADER
456 
457 #if ! defined (ffft_OscSinCos_CODEHEADER_INCLUDED)
458 #define ffft_OscSinCos_CODEHEADER_INCLUDED
459 
460 
461 
462 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
463 
464 #include <cmath>
465 
466 namespace std { }
467 
468 
469 
470 namespace ffft
471 {
472 
473 
474 
475 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
476 
477 
478 
479 template <class T>
480 OscSinCos <T>::OscSinCos ()
481 : _pos_cos (1)
482 , _pos_sin (0)
483 , _step_cos (1)
484 , _step_sin (0)
485 {
486  // Nothing
487 }
488 
489 
490 
491 template <class T>
492 void OscSinCos <T>::set_step (double angle_rad)
493 {
494  using namespace std;
495 
496  _step_cos = static_cast <DataType> (cos (angle_rad));
497  _step_sin = static_cast <DataType> (sin (angle_rad));
498 }
499 
500 
501 
502 template <class T>
503 typename OscSinCos <T>::DataType OscSinCos <T>::get_cos () const
504 {
505  return (_pos_cos);
506 }
507 
508 
509 
510 template <class T>
511 typename OscSinCos <T>::DataType OscSinCos <T>::get_sin () const
512 {
513  return (_pos_sin);
514 }
515 
516 
517 
518 template <class T>
519 void OscSinCos <T>::step ()
520 {
521  const DataType old_cos = _pos_cos;
522  const DataType old_sin = _pos_sin;
523 
524  _pos_cos = old_cos * _step_cos - old_sin * _step_sin;
525  _pos_sin = old_cos * _step_sin + old_sin * _step_cos;
526 }
527 
528 
529 
530 template <class T>
531 void OscSinCos <T>::clear_buffers ()
532 {
533  _pos_cos = static_cast <DataType> (1);
534  _pos_sin = static_cast <DataType> (0);
535 }
536 
537 
538 
539 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
540 
541 
542 
543 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
544 
545 
546 
547 } // namespace ffft
548 
549 
550 
551 #endif // ffft_OscSinCos_CODEHEADER_INCLUDED
552 
553 #undef ffft_OscSinCos_CURRENT_CODEHEADER
554 
555 
556 
557 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
558 
559 
560 
561 
562 #endif // ffft_OscSinCos_HEADER_INCLUDED
563 
564 
565 
566 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
567 
568 
569 
570 
571 namespace ffft
572 {
573 
574 
575 
576 template <class DT>
577 class FFTReal
578 {
579 
580 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
581 
582 public:
583 
584  enum { MAX_BIT_DEPTH = 30 }; // So length can be represented as long int
585 
586  typedef DT DataType;
587 
588  explicit FFTReal (long length);
589  virtual ~FFTReal () {}
590 
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;
596 
597 
598 
599 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
600 
601 protected:
602 
603 
604 
605 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
606 
607 private:
608 
609  // Over this bit depth, we use direct calculation for sin/cos
610  enum { TRIGO_BD_LIMIT = 12 };
611 
613 
614  void init_br_lut ();
615  void init_trigo_lut ();
616  void init_trigo_osc ();
617 
618  ffft_FORCEINLINE const long *
619  get_br_ptr () const;
620  ffft_FORCEINLINE const DataType *
621  get_trigo_ptr (int level) const;
622  ffft_FORCEINLINE long
623  get_trigo_level_index (int level) const;
624 
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;
631 
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;
638 
639  const long _length;
640  const int _nbr_bits;
642  _br_lut;
644  _trigo_lut;
645  mutable DynArray <DataType>
646  _buffer;
647  mutable DynArray <OscType>
648  _trigo_osc;
649 
650 
651 
652 /*\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\*/
653 
654 private:
655 
656  FFTReal ();
657  FFTReal (const FFTReal &other);
658  FFTReal & operator = (const FFTReal &other);
659  bool operator == (const FFTReal &other);
660  bool operator != (const FFTReal &other);
661 
662 }; // class FFTReal
663 
664 
665 
666 } // namespace ffft
667 
668 
669 
670 /*****************************************************************************
671 
672  FFTReal.hpp
673  By Laurent de Soras
674 
675 --- Legal stuff ---
676 
677 This program is free software. It comes without any warranty, to
678 the extent permitted by applicable law. You can redistribute it
679 and/or modify it under the terms of the Do What The Fuck You Want
680 To Public License, Version 2, as published by Sam Hocevar. See
681 http://sam.zoy.org/wtfpl/COPYING for more details.
682 
683 *Tab=3***********************************************************************/
684 
685 
686 
687 #if defined (ffft_FFTReal_CURRENT_CODEHEADER)
688  #error Recursive inclusion of FFTReal code header.
689 #endif
690 #define ffft_FFTReal_CURRENT_CODEHEADER
691 
692 #if ! defined (ffft_FFTReal_CODEHEADER_INCLUDED)
693 #define ffft_FFTReal_CODEHEADER_INCLUDED
694 
695 
696 
697 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
698 
699 #include <cassert>
700 #include <cmath>
701 
702 
703 
704 namespace ffft
705 {
706 
707 
708 
709 static inline bool FFTReal_is_pow2 (long x)
710 {
711  assert (x > 0);
712 
713  return ((x & -x) == x);
714 }
715 
716 
717 
718 static inline int FFTReal_get_next_pow2 (long x)
719 {
720  --x;
721 
722  int p = 0;
723  while ((x & ~0xFFFFL) != 0)
724  {
725  p += 16;
726  x >>= 16;
727  }
728  while ((x & ~0xFL) != 0)
729  {
730  p += 4;
731  x >>= 4;
732  }
733  while (x > 0)
734  {
735  ++p;
736  x >>= 1;
737  }
738 
739  return (p);
740 }
741 
742 
743 
744 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
745 
746 
747 
748 /*
749 ==============================================================================
750 Name: ctor
751 Input parameters:
752  - length: length of the array on which we want to do a FFT. Range: power of
753  2 only, > 0.
754 Throws: std::bad_alloc
755 ==============================================================================
756 */
757 
758 template <class DT>
759 FFTReal <DT>::FFTReal (long length)
760 : _length (length)
761 , _nbr_bits (FFTReal_get_next_pow2 (length))
762 , _br_lut ()
763 , _trigo_lut ()
764 , _buffer (length)
765 , _trigo_osc ()
766 {
767  assert (FFTReal_is_pow2 (length));
768  assert (_nbr_bits <= MAX_BIT_DEPTH);
769 
770  init_br_lut ();
771  init_trigo_lut ();
772  init_trigo_osc ();
773 }
774 
775 
776 
777 /*
778 ==============================================================================
779 Name: get_length
780 Description:
781  Returns the number of points processed by this FFT object.
782 Returns: The number of points, power of 2, > 0.
783 Throws: Nothing
784 ==============================================================================
785 */
786 
787 template <class DT>
788 long FFTReal <DT>::get_length () const
789 {
790  return (_length);
791 }
792 
793 
794 
795 /*
796 ==============================================================================
797 Name: do_fft
798 Description:
799  Compute the FFT of the array.
800 Input parameters:
801  - x: pointer on the source array (time).
802 Output parameters:
803  - f: pointer on the destination array (frequencies).
804  f [0...length(x)/2] = real values,
805  f [length(x)/2+1...length(x)-1] = negative imaginary values of
806  coefficents 1...length(x)/2-1.
807 Throws: Nothing
808 ==============================================================================
809 */
810 
811 template <class DT>
812 void FFTReal <DT>::do_fft (DataType f [], const DataType x []) const
813 {
814  assert (f != 0);
815  assert (f != use_buffer ());
816  assert (x != 0);
817  assert (x != use_buffer ());
818  assert (x != f);
819 
820  // General case
821  if (_nbr_bits > 2)
822  {
823  compute_fft_general (f, x);
824  }
825 
826  // 4-point FFT
827  else if (_nbr_bits == 2)
828  {
829  f [1] = x [0] - x [2];
830  f [3] = x [1] - x [3];
831 
832  const DataType b_0 = x [0] + x [2];
833  const DataType b_2 = x [1] + x [3];
834 
835  f [0] = b_0 + b_2;
836  f [2] = b_0 - b_2;
837  }
838 
839  // 2-point FFT
840  else if (_nbr_bits == 1)
841  {
842  f [0] = x [0] + x [1];
843  f [1] = x [0] - x [1];
844  }
845 
846  // 1-point FFT
847  else
848  {
849  f [0] = x [0];
850  }
851 }
852 
853 
854 
855 /*
856 ==============================================================================
857 Name: do_ifft
858 Description:
859  Compute the inverse FFT of the array. Note that data must be post-scaled:
860  IFFT (FFT (x)) = x * length (x).
861 Input parameters:
862  - f: pointer on the source array (frequencies).
863  f [0...length(x)/2] = real values
864  f [length(x)/2+1...length(x)-1] = negative imaginary values of
865  coefficents 1...length(x)/2-1.
866 Output parameters:
867  - x: pointer on the destination array (time).
868 Throws: Nothing
869 ==============================================================================
870 */
871 
872 template <class DT>
873 void FFTReal <DT>::do_ifft (const DataType f [], DataType x []) const
874 {
875  assert (f != 0);
876  assert (f != use_buffer ());
877  assert (x != 0);
878  assert (x != use_buffer ());
879  assert (x != f);
880 
881  // General case
882  if (_nbr_bits > 2)
883  {
884  compute_ifft_general (f, x);
885  }
886 
887  // 4-point IFFT
888  else if (_nbr_bits == 2)
889  {
890  const DataType b_0 = f [0] + f [2];
891  const DataType b_2 = f [0] - f [2];
892 
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;
897  }
898 
899  // 2-point IFFT
900  else if (_nbr_bits == 1)
901  {
902  x [0] = f [0] + f [1];
903  x [1] = f [0] - f [1];
904  }
905 
906  // 1-point IFFT
907  else
908  {
909  x [0] = f [0];
910  }
911 }
912 
913 
914 
915 /*
916 ==============================================================================
917 Name: rescale
918 Description:
919  Scale an array by divide each element by its length. This function should
920  be called after FFT + IFFT.
921 Input parameters:
922  - x: pointer on array to rescale (time or frequency).
923 Throws: Nothing
924 ==============================================================================
925 */
926 
927 template <class DT>
928 void FFTReal <DT>::rescale (DataType x []) const
929 {
930  const DataType mul = DataType (1.0 / _length);
931 
932  if (_length < 4)
933  {
934  long i = _length - 1;
935  do
936  {
937  x [i] *= mul;
938  --i;
939  }
940  while (i >= 0);
941  }
942 
943  else
944  {
945  assert ((_length & 3) == 0);
946 
947  // Could be optimized with SIMD instruction sets (needs alignment check)
948  long i = _length - 4;
949  do
950  {
951  x [i + 0] *= mul;
952  x [i + 1] *= mul;
953  x [i + 2] *= mul;
954  x [i + 3] *= mul;
955  i -= 4;
956  }
957  while (i >= 0);
958  }
959 }
960 
961 
962 
963 /*
964 ==============================================================================
965 Name: use_buffer
966 Description:
967  Access the internal buffer, whose length is the FFT one.
968  Buffer content will be erased at each do_fft() / do_ifft() call!
969  This buffer cannot be used as:
970  - source for FFT or IFFT done with this object
971  - destination for FFT or IFFT done with this object
972 Returns:
973  Buffer start address
974 Throws: Nothing
975 ==============================================================================
976 */
977 
978 template <class DT>
979 typename FFTReal <DT>::DataType * FFTReal <DT>::use_buffer () const
980 {
981  return (&_buffer [0]);
982 }
983 
984 
985 
986 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
987 
988 
989 
990 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
991 
992 
993 
994 template <class DT>
995 void FFTReal <DT>::init_br_lut ()
996 {
997  const long length = 1L << _nbr_bits;
998  _br_lut.resize (length);
999 
1000  _br_lut [0] = 0;
1001  long br_index = 0;
1002  for (long cnt = 1; cnt < length; ++cnt)
1003  {
1004  // ++br_index (bit reversed)
1005  long bit = length >> 1;
1006  while (((br_index ^= bit) & bit) == 0)
1007  {
1008  bit >>= 1;
1009  }
1010 
1011  _br_lut [cnt] = br_index;
1012  }
1013 }
1014 
1015 
1016 
1017 template <class DT>
1018 void FFTReal <DT>::init_trigo_lut ()
1019 {
1020  using namespace std;
1021 
1022  if (_nbr_bits > 3)
1023  {
1024  const long total_len = (1L << (_nbr_bits - 1)) - 4;
1025  _trigo_lut.resize (total_len);
1026 
1027  for (int level = 3; level < _nbr_bits; ++level)
1028  {
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);
1033 
1034  for (long i = 0; i < level_len; ++ i)
1035  {
1036  level_ptr [i] = static_cast <DataType> (cos (i * mul));
1037  }
1038  }
1039  }
1040 }
1041 
1042 
1043 
1044 template <class DT>
1045 void FFTReal <DT>::init_trigo_osc ()
1046 {
1047  const int nbr_osc = _nbr_bits - TRIGO_BD_LIMIT;
1048  if (nbr_osc > 0)
1049  {
1050  _trigo_osc.resize (nbr_osc);
1051 
1052  for (int osc_cnt = 0; osc_cnt < nbr_osc; ++osc_cnt)
1053  {
1054  OscType & osc = _trigo_osc [osc_cnt];
1055 
1056  const long len = 1L << (TRIGO_BD_LIMIT + osc_cnt);
1057  const double mul = (0.5 * PI) / len;
1058  osc.set_step (mul);
1059  }
1060  }
1061 }
1062 
1063 
1064 
1065 template <class DT>
1066 const long * FFTReal <DT>::get_br_ptr () const
1067 {
1068  return (&_br_lut [0]);
1069 }
1070 
1071 
1072 
1073 template <class DT>
1074 const typename FFTReal <DT>::DataType * FFTReal <DT>::get_trigo_ptr (int level) const
1075 {
1076  assert (level >= 3);
1077 
1078  return (&_trigo_lut [get_trigo_level_index (level)]);
1079 }
1080 
1081 
1082 
1083 template <class DT>
1084 long FFTReal <DT>::get_trigo_level_index (int level) const
1085 {
1086  assert (level >= 3);
1087 
1088  return ((1L << (level - 1)) - 4);
1089 }
1090 
1091 
1092 
1093 // Transform in several passes
1094 template <class DT>
1095 void FFTReal <DT>::compute_fft_general (DataType f [], const DataType x []) const
1096 {
1097  assert (f != 0);
1098  assert (f != use_buffer ());
1099  assert (x != 0);
1100  assert (x != use_buffer ());
1101  assert (x != f);
1102 
1103  DataType * sf;
1104  DataType * df;
1105 
1106  if ((_nbr_bits & 1) != 0)
1107  {
1108  df = use_buffer ();
1109  sf = f;
1110  }
1111  else
1112  {
1113  df = f;
1114  sf = use_buffer ();
1115  }
1116 
1117  compute_direct_pass_1_2 (df, x);
1118  compute_direct_pass_3 (sf, df);
1119 
1120  for (int pass = 3; pass < _nbr_bits; ++ pass)
1121  {
1122  compute_direct_pass_n (df, sf, pass);
1123 
1124  DataType * const temp_ptr = df;
1125  df = sf;
1126  sf = temp_ptr;
1127  }
1128 }
1129 
1130 
1131 
1132 template <class DT>
1133 void FFTReal <DT>::compute_direct_pass_1_2 (DataType df [], const DataType x []) const
1134 {
1135  assert (df != 0);
1136  assert (x != 0);
1137  assert (df != x);
1138 
1139  const long * const bit_rev_lut_ptr = get_br_ptr ();
1140  long coef_index = 0;
1141  do
1142  {
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];
1147 
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];
1151 
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];
1154 
1155  df2 [0] = sf_0 + sf_2;
1156  df2 [2] = sf_0 - sf_2;
1157 
1158  coef_index += 4;
1159  }
1160  while (coef_index < _length);
1161 }
1162 
1163 
1164 
1165 template <class DT>
1166 void FFTReal <DT>::compute_direct_pass_3 (DataType df [], const DataType sf []) const
1167 {
1168  assert (df != 0);
1169  assert (sf != 0);
1170  assert (df != sf);
1171 
1172  const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
1173  long coef_index = 0;
1174  do
1175  {
1176  DataType v;
1177 
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];
1182 
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;
1186 
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];
1190 
1191  coef_index += 8;
1192  }
1193  while (coef_index < _length);
1194 }
1195 
1196 
1197 
1198 template <class DT>
1199 void FFTReal <DT>::compute_direct_pass_n (DataType df [], const DataType sf [], int pass) const
1200 {
1201  assert (df != 0);
1202  assert (sf != 0);
1203  assert (df != sf);
1204  assert (pass >= 3);
1205  assert (pass < _nbr_bits);
1206 
1207  if (pass <= TRIGO_BD_LIMIT)
1208  {
1209  compute_direct_pass_n_lut (df, sf, pass);
1210  }
1211  else
1212  {
1213  compute_direct_pass_n_osc (df, sf, pass);
1214  }
1215 }
1216 
1217 
1218 
1219 template <class DT>
1220 void FFTReal <DT>::compute_direct_pass_n_lut (DataType df [], const DataType sf [], int pass) const
1221 {
1222  assert (df != 0);
1223  assert (sf != 0);
1224  assert (df != sf);
1225  assert (pass >= 3);
1226  assert (pass < _nbr_bits);
1227 
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);
1233  do
1234  {
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;
1239 
1240  // Extreme coefficients are always real
1241  dfr [0] = sf1r [0] + sf2r [0];
1242  dfi [0] = sf1r [0] - sf2r [0]; // dfr [nbr_coef] =
1243  dfr [h_nbr_coef] = sf1r [h_nbr_coef];
1244  dfi [h_nbr_coef] = sf2r [h_nbr_coef];
1245 
1246  // Others are conjugate complex numbers
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)
1250  {
1251  const DataType c = cos_ptr [i]; // cos (i*PI/nbr_coef);
1252  const DataType s = cos_ptr [h_nbr_coef - i]; // sin (i*PI/nbr_coef);
1253  DataType v;
1254 
1255  v = sf2r [i] * c - sf2i [i] * s;
1256  dfr [i] = sf1r [i] + v;
1257  dfi [-i] = sf1r [i] - v; // dfr [nbr_coef - i] =
1258 
1259  v = sf2r [i] * s + sf2i [i] * c;
1260  dfi [i] = v + sf1i [i];
1261  dfi [nbr_coef - i] = v - sf1i [i];
1262  }
1263 
1264  coef_index += d_nbr_coef;
1265  }
1266  while (coef_index < _length);
1267 }
1268 
1269 
1270 
1271 template <class DT>
1272 void FFTReal <DT>::compute_direct_pass_n_osc (DataType df [], const DataType sf [], int pass) const
1273 {
1274  assert (df != 0);
1275  assert (sf != 0);
1276  assert (df != sf);
1277  assert (pass > TRIGO_BD_LIMIT);
1278  assert (pass < _nbr_bits);
1279 
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)];
1285  do
1286  {
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;
1291 
1292  osc.clear_buffers ();
1293 
1294  // Extreme coefficients are always real
1295  dfr [0] = sf1r [0] + sf2r [0];
1296  dfi [0] = sf1r [0] - sf2r [0]; // dfr [nbr_coef] =
1297  dfr [h_nbr_coef] = sf1r [h_nbr_coef];
1298  dfi [h_nbr_coef] = sf2r [h_nbr_coef];
1299 
1300  // Others are conjugate complex numbers
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)
1304  {
1305  osc.step ();
1306  const DataType c = osc.get_cos ();
1307  const DataType s = osc.get_sin ();
1308  DataType v;
1309 
1310  v = sf2r [i] * c - sf2i [i] * s;
1311  dfr [i] = sf1r [i] + v;
1312  dfi [-i] = sf1r [i] - v; // dfr [nbr_coef - i] =
1313 
1314  v = sf2r [i] * s + sf2i [i] * c;
1315  dfi [i] = v + sf1i [i];
1316  dfi [nbr_coef - i] = v - sf1i [i];
1317  }
1318 
1319  coef_index += d_nbr_coef;
1320  }
1321  while (coef_index < _length);
1322 }
1323 
1324 
1325 
1326 // Transform in several pass
1327 template <class DT>
1328 void FFTReal <DT>::compute_ifft_general (const DataType f [], DataType x []) const
1329 {
1330  assert (f != 0);
1331  assert (f != use_buffer ());
1332  assert (x != 0);
1333  assert (x != use_buffer ());
1334  assert (x != f);
1335 
1336  DataType * sf = const_cast <DataType *> (f);
1337  DataType * df;
1338  DataType * df_temp;
1339 
1340  if (_nbr_bits & 1)
1341  {
1342  df = use_buffer ();
1343  df_temp = x;
1344  }
1345  else
1346  {
1347  df = x;
1348  df_temp = use_buffer ();
1349  }
1350 
1351  for (int pass = _nbr_bits - 1; pass >= 3; -- pass)
1352  {
1353  compute_inverse_pass_n (df, sf, pass);
1354 
1355  if (pass < _nbr_bits - 1)
1356  {
1357  DataType * const temp_ptr = df;
1358  df = sf;
1359  sf = temp_ptr;
1360  }
1361  else
1362  {
1363  sf = df;
1364  df = df_temp;
1365  }
1366  }
1367 
1368  compute_inverse_pass_3 (df, sf);
1369  compute_inverse_pass_1_2 (x, df);
1370 }
1371 
1372 
1373 
1374 template <class DT>
1375 void FFTReal <DT>::compute_inverse_pass_n (DataType df [], const DataType sf [], int pass) const
1376 {
1377  assert (df != 0);
1378  assert (sf != 0);
1379  assert (df != sf);
1380  assert (pass >= 3);
1381  assert (pass < _nbr_bits);
1382 
1383  if (pass <= TRIGO_BD_LIMIT)
1384  {
1385  compute_inverse_pass_n_lut (df, sf, pass);
1386  }
1387  else
1388  {
1389  compute_inverse_pass_n_osc (df, sf, pass);
1390  }
1391 }
1392 
1393 
1394 
1395 template <class DT>
1396 void FFTReal <DT>::compute_inverse_pass_n_lut (DataType df [], const DataType sf [], int pass) const
1397 {
1398  assert (df != 0);
1399  assert (sf != 0);
1400  assert (df != sf);
1401  assert (pass >= 3);
1402  assert (pass < _nbr_bits);
1403 
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);
1409  do
1410  {
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;
1415 
1416  // Extreme coefficients are always real
1417  df1r [0] = sfr [0] + sfi [0]; // + sfr [nbr_coef]
1418  df2r [0] = sfr [0] - sfi [0]; // - sfr [nbr_coef]
1419  df1r [h_nbr_coef] = sfr [h_nbr_coef] * 2;
1420  df2r [h_nbr_coef] = sfi [h_nbr_coef] * 2;
1421 
1422  // Others are conjugate complex numbers
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)
1426  {
1427  df1r [i] = sfr [i] + sfi [-i]; // + sfr [nbr_coef - i]
1428  df1i [i] = sfi [i] - sfi [nbr_coef - i];
1429 
1430  const DataType c = cos_ptr [i]; // cos (i*PI/nbr_coef);
1431  const DataType s = cos_ptr [h_nbr_coef - i]; // sin (i*PI/nbr_coef);
1432  const DataType vr = sfr [i] - sfi [-i]; // - sfr [nbr_coef - i]
1433  const DataType vi = sfi [i] + sfi [nbr_coef - i];
1434 
1435  df2r [i] = vr * c + vi * s;
1436  df2i [i] = vi * c - vr * s;
1437  }
1438 
1439  coef_index += d_nbr_coef;
1440  }
1441  while (coef_index < _length);
1442 }
1443 
1444 
1445 
1446 template <class DT>
1447 void FFTReal <DT>::compute_inverse_pass_n_osc (DataType df [], const DataType sf [], int pass) const
1448 {
1449  assert (df != 0);
1450  assert (sf != 0);
1451  assert (df != sf);
1452  assert (pass > TRIGO_BD_LIMIT);
1453  assert (pass < _nbr_bits);
1454 
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)];
1460  do
1461  {
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;
1466 
1467  osc.clear_buffers ();
1468 
1469  // Extreme coefficients are always real
1470  df1r [0] = sfr [0] + sfi [0]; // + sfr [nbr_coef]
1471  df2r [0] = sfr [0] - sfi [0]; // - sfr [nbr_coef]
1472  df1r [h_nbr_coef] = sfr [h_nbr_coef] * 2;
1473  df2r [h_nbr_coef] = sfi [h_nbr_coef] * 2;
1474 
1475  // Others are conjugate complex numbers
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)
1479  {
1480  df1r [i] = sfr [i] + sfi [-i]; // + sfr [nbr_coef - i]
1481  df1i [i] = sfi [i] - sfi [nbr_coef - i];
1482 
1483  osc.step ();
1484  const DataType c = osc.get_cos ();
1485  const DataType s = osc.get_sin ();
1486  const DataType vr = sfr [i] - sfi [-i]; // - sfr [nbr_coef - i]
1487  const DataType vi = sfi [i] + sfi [nbr_coef - i];
1488 
1489  df2r [i] = vr * c + vi * s;
1490  df2i [i] = vi * c - vr * s;
1491  }
1492 
1493  coef_index += d_nbr_coef;
1494  }
1495  while (coef_index < _length);
1496 }
1497 
1498 
1499 
1500 template <class DT>
1501 void FFTReal <DT>::compute_inverse_pass_3 (DataType df [], const DataType sf []) const
1502 {
1503  assert (df != 0);
1504  assert (sf != 0);
1505  assert (df != sf);
1506 
1507  const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
1508  long coef_index = 0;
1509  do
1510  {
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;
1515 
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];
1518 
1519  const DataType vr = sf [coef_index + 1] - sf [coef_index + 3];
1520  const DataType vi = sf [coef_index + 5] + sf [coef_index + 7];
1521 
1522  df [coef_index + 5] = (vr + vi) * sqrt2_2;
1523  df [coef_index + 7] = (vi - vr) * sqrt2_2;
1524 
1525  coef_index += 8;
1526  }
1527  while (coef_index < _length);
1528 }
1529 
1530 
1531 
1532 template <class DT>
1533 void FFTReal <DT>::compute_inverse_pass_1_2 (DataType x [], const DataType sf []) const
1534 {
1535  assert (x != 0);
1536  assert (sf != 0);
1537  assert (x != sf);
1538 
1539  const long * bit_rev_lut_ptr = get_br_ptr ();
1540  const DataType * sf2 = sf;
1541  long coef_index = 0;
1542  do
1543  {
1544  {
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;
1549 
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;
1554  }
1555  {
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;
1560 
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;
1565  }
1566 
1567  sf2 += 8;
1568  coef_index += 8;
1569  bit_rev_lut_ptr += 8;
1570  }
1571  while (coef_index < _length);
1572 }
1573 
1574 
1575 
1576 } // namespace ffft
1577 
1578 
1579 
1580 #endif // ffft_FFTReal_CODEHEADER_INCLUDED
1581 
1582 #undef ffft_FFTReal_CURRENT_CODEHEADER
1583 
1584 
1585 
1586 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1587 
1588 
1589 
1590 
1591 #endif // ffft_FFTReal_HEADER_INCLUDED
1592 
1593 
1594 
1595 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1596 
1597 /*****************************************************************************
1598 
1599  FFTRealFixLen.h
1600  By Laurent de Soras
1601 
1602 --- Legal stuff ---
1603 
1604 This program is free software. It comes without any warranty, to
1605 the extent permitted by applicable law. You can redistribute it
1606 and/or modify it under the terms of the Do What The Fuck You Want
1607 To Public License, Version 2, as published by Sam Hocevar. See
1608 http://sam.zoy.org/wtfpl/COPYING for more details.
1609 
1610 *Tab=3***********************************************************************/
1611 
1612 
1613 
1614 #if ! defined (ffft_FFTRealFixLen_HEADER_INCLUDED)
1615 #define ffft_FFTRealFixLen_HEADER_INCLUDED
1616 
1617 #if defined (_MSC_VER)
1618  #pragma once
1619  #pragma warning (4 : 4250) // "Inherits via dominance."
1620 #endif
1621 
1622 
1623 
1624 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1625 
1626 /*****************************************************************************
1627 
1628  Array.h
1629  By Laurent de Soras
1630 
1631 --- Legal stuff ---
1632 
1633 This program is free software. It comes without any warranty, to
1634 the extent permitted by applicable law. You can redistribute it
1635 and/or modify it under the terms of the Do What The Fuck You Want
1636 To Public License, Version 2, as published by Sam Hocevar. See
1637 http://sam.zoy.org/wtfpl/COPYING for more details.
1638 
1639 *Tab=3***********************************************************************/
1640 
1641 
1642 
1643 #if ! defined (ffft_Array_HEADER_INCLUDED)
1644 #define ffft_Array_HEADER_INCLUDED
1645 
1646 #if defined (_MSC_VER)
1647  #pragma once
1648  #pragma warning (4 : 4250) // "Inherits via dominance."
1649 #endif
1650 
1651 
1652 
1653 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1654 
1655 
1656 
1657 namespace ffft
1658 {
1659 
1660 
1661 
1662 template <class T, long LEN>
1663 class Array
1664 {
1665 
1666 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1667 
1668 public:
1669 
1670  typedef T DataType;
1671 
1672  Array ();
1673 
1674  inline const DataType &
1675  operator [] (long pos) const;
1676  inline DataType &
1677  operator [] (long pos);
1678 
1679  static inline long
1680  size ();
1681 
1682 
1683 
1684 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1685 
1686 protected:
1687 
1688 
1689 
1690 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1691 
1692 private:
1693 
1694  DataType _data_arr [LEN];
1695 
1696 
1697 
1698 /*\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\*/
1699 
1700 private:
1701 
1702  Array (const Array &other);
1703  Array & operator = (const Array &other);
1704  bool operator == (const Array &other);
1705  bool operator != (const Array &other);
1706 
1707 }; // class Array
1708 
1709 
1710 
1711 } // namespace ffft
1712 
1713 
1714 
1715 /*****************************************************************************
1716 
1717  Array.hpp
1718  By Laurent de Soras
1719 
1720 --- Legal stuff ---
1721 
1722 This program is free software. It comes without any warranty, to
1723 the extent permitted by applicable law. You can redistribute it
1724 and/or modify it under the terms of the Do What The Fuck You Want
1725 To Public License, Version 2, as published by Sam Hocevar. See
1726 http://sam.zoy.org/wtfpl/COPYING for more details.
1727 
1728 *Tab=3***********************************************************************/
1729 
1730 
1731 
1732 #if defined (ffft_Array_CURRENT_CODEHEADER)
1733  #error Recursive inclusion of Array code header.
1734 #endif
1735 #define ffft_Array_CURRENT_CODEHEADER
1736 
1737 #if ! defined (ffft_Array_CODEHEADER_INCLUDED)
1738 #define ffft_Array_CODEHEADER_INCLUDED
1739 
1740 
1741 
1742 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1743 
1744 #include <cassert>
1745 
1746 
1747 
1748 namespace ffft
1749 {
1750 
1751 
1752 
1753 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1754 
1755 
1756 
1757 template <class T, long LEN>
1758 Array <T, LEN>::Array ()
1759 {
1760  // Nothing
1761 }
1762 
1763 
1764 
1765 template <class T, long LEN>
1766 const typename Array <T, LEN>::DataType & Array <T, LEN>::operator [] (long pos) const
1767 {
1768  assert (pos >= 0);
1769  assert (pos < LEN);
1770 
1771  return (_data_arr [pos]);
1772 }
1773 
1774 
1775 
1776 template <class T, long LEN>
1777 typename Array <T, LEN>::DataType & Array <T, LEN>::operator [] (long pos)
1778 {
1779  assert (pos >= 0);
1780  assert (pos < LEN);
1781 
1782  return (_data_arr [pos]);
1783 }
1784 
1785 
1786 
1787 template <class T, long LEN>
1788 long Array <T, LEN>::size ()
1789 {
1790  return (LEN);
1791 }
1792 
1793 
1794 
1795 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1796 
1797 
1798 
1799 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1800 
1801 
1802 
1803 } // namespace ffft
1804 
1805 
1806 
1807 #endif // ffft_Array_CODEHEADER_INCLUDED
1808 
1809 #undef ffft_Array_CURRENT_CODEHEADER
1810 
1811 
1812 
1813 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1814 
1815 
1816 
1817 
1818 #endif // ffft_Array_HEADER_INCLUDED
1819 
1820 
1821 
1822 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1823 
1824 /*****************************************************************************
1825 
1826  DynArray.h
1827  By Laurent de Soras
1828 
1829 --- Legal stuff ---
1830 
1831 This program is free software. It comes without any warranty, to
1832 the extent permitted by applicable law. You can redistribute it
1833 and/or modify it under the terms of the Do What The Fuck You Want
1834 To Public License, Version 2, as published by Sam Hocevar. See
1835 http://sam.zoy.org/wtfpl/COPYING for more details.
1836 
1837 *Tab=3***********************************************************************/
1838 
1839 
1840 
1841 #if ! defined (ffft_DynArray_HEADER_INCLUDED)
1842 #define ffft_DynArray_HEADER_INCLUDED
1843 
1844 #if defined (_MSC_VER)
1845  #pragma once
1846  #pragma warning (4 : 4250) // "Inherits via dominance."
1847 #endif
1848 
1849 
1850 
1851 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1852 
1853 
1854 
1855 namespace ffft
1856 {
1857 
1858 
1859 
1860 template <class T>
1861 class DynArray
1862 {
1863 
1864 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1865 
1866 public:
1867 
1868  typedef T DataType;
1869 
1870  DynArray ();
1871  explicit DynArray (long size);
1872  ~DynArray ();
1873 
1874  inline long size () const;
1875  inline void resize (long size);
1876 
1877  inline const DataType &
1878  operator [] (long pos) const;
1879  inline DataType &
1880  operator [] (long pos);
1881 
1882 
1883 
1884 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1885 
1886 protected:
1887 
1888 
1889 
1890 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1891 
1892 private:
1893 
1894  DataType * _data_ptr;
1895  long _len;
1896 
1897 
1898 
1899 /*\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\*/
1900 
1901 private:
1902 
1903  DynArray (const DynArray &other);
1904  DynArray & operator = (const DynArray &other);
1905  bool operator == (const DynArray &other);
1906  bool operator != (const DynArray &other);
1907 
1908 }; // class DynArray
1909 
1910 
1911 
1912 } // namespace ffft
1913 
1914 
1915 
1916 /*****************************************************************************
1917 
1918  DynArray.hpp
1919  By Laurent de Soras
1920 
1921 --- Legal stuff ---
1922 
1923 This program is free software. It comes without any warranty, to
1924 the extent permitted by applicable law. You can redistribute it
1925 and/or modify it under the terms of the Do What The Fuck You Want
1926 To Public License, Version 2, as published by Sam Hocevar. See
1927 http://sam.zoy.org/wtfpl/COPYING for more details.
1928 
1929 *Tab=3***********************************************************************/
1930 
1931 
1932 
1933 #if defined (ffft_DynArray_CURRENT_CODEHEADER)
1934  #error Recursive inclusion of DynArray code header.
1935 #endif
1936 #define ffft_DynArray_CURRENT_CODEHEADER
1937 
1938 #if ! defined (ffft_DynArray_CODEHEADER_INCLUDED)
1939 #define ffft_DynArray_CODEHEADER_INCLUDED
1940 
1941 
1942 
1943 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1944 
1945 #include <cassert>
1946 
1947 
1948 
1949 namespace ffft
1950 {
1951 
1952 
1953 
1954 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
1955 
1956 
1957 
1958 template <class T>
1959 DynArray <T>::DynArray ()
1960 : _data_ptr (0)
1961 , _len (0)
1962 {
1963  // Nothing
1964 }
1965 
1966 
1967 
1968 template <class T>
1969 DynArray <T>::DynArray (long size)
1970 : _data_ptr (0)
1971 , _len (0)
1972 {
1973  assert (size >= 0);
1974  if (size > 0)
1975  {
1976  _data_ptr = new DataType [size];
1977  _len = size;
1978  }
1979 }
1980 
1981 
1982 
1983 template <class T>
1984 DynArray <T>::~DynArray ()
1985 {
1986  delete [] _data_ptr;
1987  _data_ptr = 0;
1988  _len = 0;
1989 }
1990 
1991 
1992 
1993 template <class T>
1994 long DynArray <T>::size () const
1995 {
1996  return (_len);
1997 }
1998 
1999 
2000 
2001 template <class T>
2002 void DynArray <T>::resize (long size)
2003 {
2004  assert (size >= 0);
2005  if (size > 0)
2006  {
2007  DataType * old_data_ptr = _data_ptr;
2008  DataType * tmp_data_ptr = new DataType [size];
2009 
2010  _data_ptr = tmp_data_ptr;
2011  _len = size;
2012 
2013  delete [] old_data_ptr;
2014  }
2015 }
2016 
2017 
2018 
2019 template <class T>
2020 const typename DynArray <T>::DataType & DynArray <T>::operator [] (long pos) const
2021 {
2022  assert (pos >= 0);
2023  assert (pos < _len);
2024 
2025  return (_data_ptr [pos]);
2026 }
2027 
2028 
2029 
2030 template <class T>
2031 typename DynArray <T>::DataType & DynArray <T>::operator [] (long pos)
2032 {
2033  assert (pos >= 0);
2034  assert (pos < _len);
2035 
2036  return (_data_ptr [pos]);
2037 }
2038 
2039 
2040 
2041 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2042 
2043 
2044 
2045 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2046 
2047 
2048 
2049 } // namespace ffft
2050 
2051 
2052 
2053 #endif // ffft_DynArray_CODEHEADER_INCLUDED
2054 
2055 #undef ffft_DynArray_CURRENT_CODEHEADER
2056 
2057 
2058 
2059 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2060 
2061 
2062 
2063 
2064 #endif // ffft_DynArray_HEADER_INCLUDED
2065 
2066 
2067 
2068 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2069 
2070 /*****************************************************************************
2071 
2072  FFTRealFixLenParam.h
2073  By Laurent de Soras
2074 
2075 --- Legal stuff ---
2076 
2077 This program is free software. It comes without any warranty, to
2078 the extent permitted by applicable law. You can redistribute it
2079 and/or modify it under the terms of the Do What The Fuck You Want
2080 To Public License, Version 2, as published by Sam Hocevar. See
2081 http://sam.zoy.org/wtfpl/COPYING for more details.
2082 
2083 *Tab=3***********************************************************************/
2084 
2085 
2086 
2087 #if ! defined (ffft_FFTRealFixLenParam_HEADER_INCLUDED)
2088 #define ffft_FFTRealFixLenParam_HEADER_INCLUDED
2089 
2090 #if defined (_MSC_VER)
2091  #pragma once
2092  #pragma warning (4 : 4250) // "Inherits via dominance."
2093 #endif
2094 
2095 
2096 
2097 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2098 
2099 
2100 
2101 namespace ffft
2102 {
2103 
2104 
2105 
2107 {
2108 
2109 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2110 
2111 public:
2112 
2113  // Over this bit depth, we use direct calculation for sin/cos
2114  enum { TRIGO_BD_LIMIT = 12 };
2115 
2116  typedef float DataType;
2117 
2118 
2119 
2120 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2121 
2122 protected:
2123 
2124 
2125 
2126 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2127 
2128 private:
2129 
2130 
2131 
2132 /*\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\*/
2133 
2134 private:
2135 
2136  FFTRealFixLenParam ();
2137  FFTRealFixLenParam (const FFTRealFixLenParam &other);
2139  operator = (const FFTRealFixLenParam &other);
2140  bool operator == (const FFTRealFixLenParam &other);
2141  bool operator != (const FFTRealFixLenParam &other);
2142 
2143 }; // class FFTRealFixLenParam
2144 
2145 
2146 
2147 } // namespace ffft
2148 
2149 
2150 
2151 //#include "ffft/FFTRealFixLenParam.hpp"
2152 
2153 
2154 
2155 #endif // ffft_FFTRealFixLenParam_HEADER_INCLUDED
2156 
2157 
2158 
2159 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2160 
2161 /*****************************************************************************
2162 
2163  OscSinCos.h
2164  By Laurent de Soras
2165 
2166 --- Legal stuff ---
2167 
2168 This program is free software. It comes without any warranty, to
2169 the extent permitted by applicable law. You can redistribute it
2170 and/or modify it under the terms of the Do What The Fuck You Want
2171 To Public License, Version 2, as published by Sam Hocevar. See
2172 http://sam.zoy.org/wtfpl/COPYING for more details.
2173 
2174 *Tab=3***********************************************************************/
2175 
2176 
2177 
2178 #if ! defined (ffft_OscSinCos_HEADER_INCLUDED)
2179 #define ffft_OscSinCos_HEADER_INCLUDED
2180 
2181 #if defined (_MSC_VER)
2182  #pragma once
2183  #pragma warning (4 : 4250) // "Inherits via dominance."
2184 #endif
2185 
2186 
2187 
2188 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2189 
2190 
2191 
2192 
2193 
2194 namespace ffft
2195 {
2196 
2197 
2198 
2199 template <class T>
2200 class OscSinCos
2201 {
2202 
2203 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2204 
2205 public:
2206 
2207  typedef T DataType;
2208 
2209  OscSinCos ();
2210 
2211  ffft_FORCEINLINE void
2212  set_step (double angle_rad);
2213 
2214  ffft_FORCEINLINE DataType
2215  get_cos () const;
2216  ffft_FORCEINLINE DataType
2217  get_sin () const;
2218  ffft_FORCEINLINE void
2219  step ();
2220  ffft_FORCEINLINE void
2221  clear_buffers ();
2222 
2223 
2224 
2225 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2226 
2227 protected:
2228 
2229 
2230 
2231 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2232 
2233 private:
2234 
2235  DataType _pos_cos; // Current phase expressed with sin and cos. [-1 ; 1]
2236  DataType _pos_sin; // -
2237  DataType _step_cos; // Phase increment per step, [-1 ; 1]
2238  DataType _step_sin; // -
2239 
2240 
2241 
2242 /*\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\*/
2243 
2244 private:
2245 
2246  OscSinCos (const OscSinCos &other);
2247  OscSinCos & operator = (const OscSinCos &other);
2248  bool operator == (const OscSinCos &other);
2249  bool operator != (const OscSinCos &other);
2250 
2251 }; // class OscSinCos
2252 
2253 
2254 
2255 } // namespace ffft
2256 
2257 
2258 
2259 /*****************************************************************************
2260 
2261  OscSinCos.hpp
2262  By Laurent de Soras
2263 
2264 --- Legal stuff ---
2265 
2266 This program is free software. It comes without any warranty, to
2267 the extent permitted by applicable law. You can redistribute it
2268 and/or modify it under the terms of the Do What The Fuck You Want
2269 To Public License, Version 2, as published by Sam Hocevar. See
2270 http://sam.zoy.org/wtfpl/COPYING for more details.
2271 
2272 *Tab=3***********************************************************************/
2273 
2274 
2275 
2276 #if defined (ffft_OscSinCos_CURRENT_CODEHEADER)
2277  #error Recursive inclusion of OscSinCos code header.
2278 #endif
2279 #define ffft_OscSinCos_CURRENT_CODEHEADER
2280 
2281 #if ! defined (ffft_OscSinCos_CODEHEADER_INCLUDED)
2282 #define ffft_OscSinCos_CODEHEADER_INCLUDED
2283 
2284 
2285 
2286 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2287 
2288 #include <cmath>
2289 
2290 namespace std { }
2291 
2292 
2293 
2294 namespace ffft
2295 {
2296 
2297 
2298 
2299 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2300 
2301 
2302 
2303 template <class T>
2304 OscSinCos <T>::OscSinCos ()
2305 : _pos_cos (1)
2306 , _pos_sin (0)
2307 , _step_cos (1)
2308 , _step_sin (0)
2309 {
2310  // Nothing
2311 }
2312 
2313 
2314 
2315 template <class T>
2316 void OscSinCos <T>::set_step (double angle_rad)
2317 {
2318  using namespace std;
2319 
2320  _step_cos = static_cast <DataType> (cos (angle_rad));
2321  _step_sin = static_cast <DataType> (sin (angle_rad));
2322 }
2323 
2324 
2325 
2326 template <class T>
2327 typename OscSinCos <T>::DataType OscSinCos <T>::get_cos () const
2328 {
2329  return (_pos_cos);
2330 }
2331 
2332 
2333 
2334 template <class T>
2335 typename OscSinCos <T>::DataType OscSinCos <T>::get_sin () const
2336 {
2337  return (_pos_sin);
2338 }
2339 
2340 
2341 
2342 template <class T>
2343 void OscSinCos <T>::step ()
2344 {
2345  const DataType old_cos = _pos_cos;
2346  const DataType old_sin = _pos_sin;
2347 
2348  _pos_cos = old_cos * _step_cos - old_sin * _step_sin;
2349  _pos_sin = old_cos * _step_sin + old_sin * _step_cos;
2350 }
2351 
2352 
2353 
2354 template <class T>
2355 void OscSinCos <T>::clear_buffers ()
2356 {
2357  _pos_cos = static_cast <DataType> (1);
2358  _pos_sin = static_cast <DataType> (0);
2359 }
2360 
2361 
2362 
2363 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2364 
2365 
2366 
2367 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2368 
2369 
2370 
2371 } // namespace ffft
2372 
2373 
2374 
2375 #endif // ffft_OscSinCos_CODEHEADER_INCLUDED
2376 
2377 #undef ffft_OscSinCos_CURRENT_CODEHEADER
2378 
2379 
2380 
2381 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2382 
2383 
2384 
2385 
2386 #endif // ffft_OscSinCos_HEADER_INCLUDED
2387 
2388 
2389 
2390 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2391 
2392 
2393 
2394 
2395 namespace ffft
2396 {
2397 
2398 
2399 
2400 template <int LL2>
2402 {
2403  typedef int CompileTimeCheck1 [(LL2 >= 0) ? 1 : -1];
2404  typedef int CompileTimeCheck2 [(LL2 <= 30) ? 1 : -1];
2405 
2406 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2407 
2408 public:
2409 
2410  typedef FFTRealFixLenParam::DataType DataType;
2411  typedef OscSinCos <DataType> OscType;
2412 
2413  enum { FFT_LEN_L2 = LL2 };
2414  enum { FFT_LEN = 1 << FFT_LEN_L2 };
2415 
2416  FFTRealFixLen ();
2417 
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;
2422 
2423 
2424 
2425 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2426 
2427 protected:
2428 
2429 
2430 
2431 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2432 
2433 private:
2434 
2435  enum { TRIGO_BD_LIMIT = FFTRealFixLenParam::TRIGO_BD_LIMIT };
2436 
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 };
2439 
2440  enum { TRIGO_BD = ((FFT_LEN_L2 - TRIGO_BD_LIMIT) < 0)
2441  ? (int)FFT_LEN_L2
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 };
2445 
2446  enum { NBR_TRIGO_OSC = FFT_LEN_L2 - TRIGO_BD };
2447  enum { TRIGO_OSC_ARR_SIZE = (NBR_TRIGO_OSC > 0) ? NBR_TRIGO_OSC : 1 };
2448 
2449  void build_br_lut ();
2450  void build_trigo_lut ();
2451  void build_trigo_osc ();
2452 
2454  _buffer;
2456  _br_data;
2458  _trigo_data;
2460  _trigo_osc;
2461 
2462 
2463 
2464 /*\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\*/
2465 
2466 private:
2467 
2468  FFTRealFixLen (const FFTRealFixLen &other);
2469  FFTRealFixLen& operator = (const FFTRealFixLen &other);
2470  bool operator == (const FFTRealFixLen &other);
2471  bool operator != (const FFTRealFixLen &other);
2472 
2473 }; // class FFTRealFixLen
2474 
2475 
2476 
2477 } // namespace ffft
2478 
2479 
2480 
2481 /*****************************************************************************
2482 
2483  FFTRealFixLen.hpp
2484  By Laurent de Soras
2485 
2486 --- Legal stuff ---
2487 
2488 This program is free software. It comes without any warranty, to
2489 the extent permitted by applicable law. You can redistribute it
2490 and/or modify it under the terms of the Do What The Fuck You Want
2491 To Public License, Version 2, as published by Sam Hocevar. See
2492 http://sam.zoy.org/wtfpl/COPYING for more details.
2493 
2494 *Tab=3***********************************************************************/
2495 
2496 
2497 
2498 #if defined (ffft_FFTRealFixLen_CURRENT_CODEHEADER)
2499  #error Recursive inclusion of FFTRealFixLen code header.
2500 #endif
2501 #define ffft_FFTRealFixLen_CURRENT_CODEHEADER
2502 
2503 #if ! defined (ffft_FFTRealFixLen_CODEHEADER_INCLUDED)
2504 #define ffft_FFTRealFixLen_CODEHEADER_INCLUDED
2505 
2506 
2507 
2508 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2509 
2510 
2511 /*****************************************************************************
2512 
2513  FFTRealPassDirect.h
2514  By Laurent de Soras
2515 
2516 --- Legal stuff ---
2517 
2518 This program is free software. It comes without any warranty, to
2519 the extent permitted by applicable law. You can redistribute it
2520 and/or modify it under the terms of the Do What The Fuck You Want
2521 To Public License, Version 2, as published by Sam Hocevar. See
2522 http://sam.zoy.org/wtfpl/COPYING for more details.
2523 
2524 *Tab=3***********************************************************************/
2525 
2526 
2527 
2528 #if ! defined (ffft_FFTRealPassDirect_HEADER_INCLUDED)
2529 #define ffft_FFTRealPassDirect_HEADER_INCLUDED
2530 
2531 #if defined (_MSC_VER)
2532  #pragma once
2533  #pragma warning (4 : 4250) // "Inherits via dominance."
2534 #endif
2535 
2536 
2537 
2538 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2539 
2540 
2541 
2542 
2543 
2544 
2545 
2546 namespace ffft
2547 {
2548 
2549 
2550 
2551 template <int PASS>
2553 {
2554 
2555 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2556 
2557 public:
2558 
2559  typedef FFTRealFixLenParam::DataType DataType;
2560  typedef OscSinCos <DataType> OscType;
2561 
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 []);
2564 
2565 
2566 
2567 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2568 
2569 protected:
2570 
2571 
2572 
2573 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2574 
2575 private:
2576 
2577 
2578 
2579 /*\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\*/
2580 
2581 private:
2582 
2583  FFTRealPassDirect ();
2584  FFTRealPassDirect (const FFTRealPassDirect &other);
2586  operator = (const FFTRealPassDirect &other);
2587  bool operator == (const FFTRealPassDirect &other);
2588  bool operator != (const FFTRealPassDirect &other);
2589 
2590 }; // class FFTRealPassDirect
2591 
2592 
2593 
2594 } // namespace ffft
2595 
2596 
2597 
2598 /*****************************************************************************
2599 
2600  FFTRealPassDirect.hpp
2601  By Laurent de Soras
2602 
2603 --- Legal stuff ---
2604 
2605 This program is free software. It comes without any warranty, to
2606 the extent permitted by applicable law. You can redistribute it
2607 and/or modify it under the terms of the Do What The Fuck You Want
2608 To Public License, Version 2, as published by Sam Hocevar. See
2609 http://sam.zoy.org/wtfpl/COPYING for more details.
2610 
2611 *Tab=3***********************************************************************/
2612 
2613 
2614 
2615 #if defined (ffft_FFTRealPassDirect_CURRENT_CODEHEADER)
2616  #error Recursive inclusion of FFTRealPassDirect code header.
2617 #endif
2618 #define ffft_FFTRealPassDirect_CURRENT_CODEHEADER
2619 
2620 #if ! defined (ffft_FFTRealPassDirect_CODEHEADER_INCLUDED)
2621 #define ffft_FFTRealPassDirect_CODEHEADER_INCLUDED
2622 
2623 
2624 
2625 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2626 
2627 /*****************************************************************************
2628 
2629  FFTRealUseTrigo.h
2630  By Laurent de Soras
2631 
2632 --- Legal stuff ---
2633 
2634 This program is free software. It comes without any warranty, to
2635 the extent permitted by applicable law. You can redistribute it
2636 and/or modify it under the terms of the Do What The Fuck You Want
2637 To Public License, Version 2, as published by Sam Hocevar. See
2638 http://sam.zoy.org/wtfpl/COPYING for more details.
2639 
2640 *Tab=3***********************************************************************/
2641 
2642 
2643 
2644 #if ! defined (ffft_FFTRealUseTrigo_HEADER_INCLUDED)
2645 #define ffft_FFTRealUseTrigo_HEADER_INCLUDED
2646 
2647 #if defined (_MSC_VER)
2648  #pragma once
2649  #pragma warning (4 : 4250) // "Inherits via dominance."
2650 #endif
2651 
2652 
2653 
2654 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2655 
2656 
2657 
2658 
2659 
2660 
2661 
2662 namespace ffft
2663 {
2664 
2665 
2666 
2667 template <int ALGO>
2669 {
2670 
2671 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2672 
2673 public:
2674 
2675  typedef FFTRealFixLenParam::DataType DataType;
2676  typedef OscSinCos <DataType> OscType;
2677 
2678  ffft_FORCEINLINE static void
2679  prepare (OscType &osc);
2680  ffft_FORCEINLINE static void
2681  iterate (OscType &osc, DataType &c, DataType &s, const DataType cos_ptr [], long index_c, long index_s);
2682 
2683 
2684 
2685 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2686 
2687 protected:
2688 
2689 
2690 
2691 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2692 
2693 private:
2694 
2695 
2696 
2697 /*\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\*/
2698 
2699 private:
2700 
2701  FFTRealUseTrigo ();
2702  ~FFTRealUseTrigo ();
2703  FFTRealUseTrigo (const FFTRealUseTrigo &other);
2704  FFTRealUseTrigo &
2705  operator = (const FFTRealUseTrigo &other);
2706  bool operator == (const FFTRealUseTrigo &other);
2707  bool operator != (const FFTRealUseTrigo &other);
2708 
2709 }; // class FFTRealUseTrigo
2710 
2711 
2712 
2713 } // namespace ffft
2714 
2715 
2716 
2717 /*****************************************************************************
2718 
2719  FFTRealUseTrigo.hpp
2720  By Laurent de Soras
2721 
2722 --- Legal stuff ---
2723 
2724 This program is free software. It comes without any warranty, to
2725 the extent permitted by applicable law. You can redistribute it
2726 and/or modify it under the terms of the Do What The Fuck You Want
2727 To Public License, Version 2, as published by Sam Hocevar. See
2728 http://sam.zoy.org/wtfpl/COPYING for more details.
2729 
2730 *Tab=3***********************************************************************/
2731 
2732 
2733 
2734 #if defined (ffft_FFTRealUseTrigo_CURRENT_CODEHEADER)
2735  #error Recursive inclusion of FFTRealUseTrigo code header.
2736 #endif
2737 #define ffft_FFTRealUseTrigo_CURRENT_CODEHEADER
2738 
2739 #if ! defined (ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED)
2740 #define ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED
2741 
2742 
2743 
2744 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2745 
2746 
2747 
2748 
2749 
2750 namespace ffft
2751 {
2752 
2753 
2754 
2755 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2756 
2757 
2758 
2759 template <int ALGO>
2760 void FFTRealUseTrigo <ALGO>::prepare (OscType &osc)
2761 {
2762  osc.clear_buffers ();
2763 }
2764 
2765 template <>
2766 inline void FFTRealUseTrigo <0>::prepare (OscType &osc)
2767 {
2768  // Nothing
2769 }
2770 
2771 
2772 
2773 template <int ALGO>
2774 void FFTRealUseTrigo <ALGO>::iterate (OscType &osc, DataType &c, DataType &s, const DataType cos_ptr [], long index_c, long index_s)
2775 {
2776  osc.step ();
2777  c = osc.get_cos ();
2778  s = osc.get_sin ();
2779 }
2780 
2781 template <>
2782 inline void FFTRealUseTrigo <0>::iterate (OscType &osc, DataType &c, DataType &s, const DataType cos_ptr [], long index_c, long index_s)
2783 {
2784  c = cos_ptr [index_c];
2785  s = cos_ptr [index_s];
2786 }
2787 
2788 
2789 
2790 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2791 
2792 
2793 
2794 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2795 
2796 
2797 
2798 } // namespace ffft
2799 
2800 
2801 
2802 #endif // ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED
2803 
2804 #undef ffft_FFTRealUseTrigo_CURRENT_CODEHEADER
2805 
2806 
2807 
2808 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2809 
2810 
2811 
2812 
2813 #endif // ffft_FFTRealUseTrigo_HEADER_INCLUDED
2814 
2815 
2816 
2817 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2818 
2819 
2820 
2821 
2822 namespace ffft
2823 {
2824 
2825 
2826 
2827 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2828 
2829 
2830 
2831 template <>
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 [])
2833 {
2834  // First and second pass at once
2835  const long qlen = len >> 2;
2836 
2837  long coef_index = 0;
2838  do
2839  {
2840  // To do: unroll the loop (2x).
2841  const long ri_0 = br_ptr [coef_index >> 2];
2842  const long ri_1 = ri_0 + 2 * qlen; // bit_rev_lut_ptr [coef_index + 1];
2843  const long ri_2 = ri_0 + 1 * qlen; // bit_rev_lut_ptr [coef_index + 2];
2844  const long ri_3 = ri_0 + 3 * qlen; // bit_rev_lut_ptr [coef_index + 3];
2845 
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];
2849 
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];
2852 
2853  df2 [0] = sf_0 + sf_2;
2854  df2 [2] = sf_0 - sf_2;
2855 
2856  coef_index += 4;
2857  }
2858  while (coef_index < len);
2859 }
2860 
2861 template <>
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 [])
2863 {
2864  // Executes "previous" passes first. Inverts source and destination buffers
2865  FFTRealPassDirect <1>::process (
2866  len,
2867  src_ptr,
2868  dest_ptr,
2869  x_ptr,
2870  cos_ptr,
2871  cos_len,
2872  br_ptr,
2873  osc_list
2874  );
2875 
2876  // Third pass
2877  const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
2878 
2879  long coef_index = 0;
2880  do
2881  {
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];
2886 
2887  DataType v;
2888 
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;
2892 
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];
2896 
2897  coef_index += 8;
2898  }
2899  while (coef_index < len);
2900 }
2901 
2902 template <int PASS>
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 [])
2904 {
2905  // Executes "previous" passes first. Inverts source and destination buffers
2906  FFTRealPassDirect <PASS - 1>::process (
2907  len,
2908  src_ptr,
2909  dest_ptr,
2910  x_ptr,
2911  cos_ptr,
2912  cos_len,
2913  br_ptr,
2914  osc_list
2915  );
2916 
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);
2924 
2925  enum { TRIGO_OSC = PASS - FFTRealFixLenParam::TRIGO_BD_LIMIT };
2926  enum { TRIGO_DIRECT = (TRIGO_OSC >= 0) ? 1 : 0 };
2927 
2928  long coef_index = 0;
2929  do
2930  {
2931  const DataType * const sf = src_ptr + coef_index;
2932  DataType * const df = dest_ptr + coef_index;
2933 
2934  // Extreme coefficients are always real
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];
2939 
2940  FFTRealUseTrigo <TRIGO_DIRECT>::prepare (osc_list [TRIGO_OSC]);
2941 
2942  // Others are conjugate complex numbers
2943  for (long i = 1; i < dist; ++ i)
2944  {
2945  DataType c;
2946  DataType s;
2947  FFTRealUseTrigo <TRIGO_DIRECT>::iterate (
2948  osc_list [TRIGO_OSC],
2949  c,
2950  s,
2951  cos_ptr,
2952  i * table_step,
2953  (dist - i) * table_step
2954  );
2955 
2956  const DataType sf_r_i = sf [c1_r + i];
2957  const DataType sf_i_i = sf [c1_i + i];
2958 
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;
2962 
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;
2966  }
2967 
2968  coef_index += cend;
2969  }
2970  while (coef_index < len);
2971 }
2972 
2973 
2974 
2975 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2976 
2977 
2978 
2979 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2980 
2981 
2982 
2983 } // namespace ffft
2984 
2985 
2986 
2987 #endif // ffft_FFTRealPassDirect_CODEHEADER_INCLUDED
2988 
2989 #undef ffft_FFTRealPassDirect_CURRENT_CODEHEADER
2990 
2991 
2992 
2993 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
2994 
2995 
2996 
2997 
2998 #endif // ffft_FFTRealPassDirect_HEADER_INCLUDED
2999 
3000 
3001 
3002 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3003 
3004 /*****************************************************************************
3005 
3006  FFTRealPassInverse.h
3007  By Laurent de Soras
3008 
3009 --- Legal stuff ---
3010 
3011 This program is free software. It comes without any warranty, to
3012 the extent permitted by applicable law. You can redistribute it
3013 and/or modify it under the terms of the Do What The Fuck You Want
3014 To Public License, Version 2, as published by Sam Hocevar. See
3015 http://sam.zoy.org/wtfpl/COPYING for more details.
3016 
3017 *Tab=3***********************************************************************/
3018 
3019 
3020 
3021 #if ! defined (ffft_FFTRealPassInverse_HEADER_INCLUDED)
3022 #define ffft_FFTRealPassInverse_HEADER_INCLUDED
3023 
3024 #if defined (_MSC_VER)
3025  #pragma once
3026  #pragma warning (4 : 4250) // "Inherits via dominance."
3027 #endif
3028 
3029 
3030 
3031 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3032 
3033 
3034 
3035 
3036 
3037 
3038 
3039 
3040 namespace ffft
3041 {
3042 
3043 
3044 
3045 template <int PASS>
3047 {
3048 
3049 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3050 
3051 public:
3052 
3053  typedef FFTRealFixLenParam::DataType DataType;
3054  typedef OscSinCos <DataType> OscType;
3055 
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 []);
3062 
3063 
3064 
3065 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3066 
3067 protected:
3068 
3069 
3070 
3071 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3072 
3073 private:
3074 
3075 
3076 
3077 /*\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\*/
3078 
3079 private:
3080 
3081  FFTRealPassInverse ();
3082  FFTRealPassInverse (const FFTRealPassInverse &other);
3084  operator = (const FFTRealPassInverse &other);
3085  bool operator == (const FFTRealPassInverse &other);
3086  bool operator != (const FFTRealPassInverse &other);
3087 
3088 }; // class FFTRealPassInverse
3089 
3090 
3091 
3092 } // namespace ffft
3093 
3094 
3095 
3096 /*****************************************************************************
3097 
3098  FFTRealPassInverse.hpp
3099  By Laurent de Soras
3100 
3101 --- Legal stuff ---
3102 
3103 This program is free software. It comes without any warranty, to
3104 the extent permitted by applicable law. You can redistribute it
3105 and/or modify it under the terms of the Do What The Fuck You Want
3106 To Public License, Version 2, as published by Sam Hocevar. See
3107 http://sam.zoy.org/wtfpl/COPYING for more details.
3108 
3109 *Tab=3***********************************************************************/
3110 
3111 
3112 
3113 #if defined (ffft_FFTRealPassInverse_CURRENT_CODEHEADER)
3114  #error Recursive inclusion of FFTRealPassInverse code header.
3115 #endif
3116 #define ffft_FFTRealPassInverse_CURRENT_CODEHEADER
3117 
3118 #if ! defined (ffft_FFTRealPassInverse_CODEHEADER_INCLUDED)
3119 #define ffft_FFTRealPassInverse_CODEHEADER_INCLUDED
3120 
3121 
3122 
3123 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3124 
3125 /*****************************************************************************
3126 
3127  FFTRealUseTrigo.h
3128  By Laurent de Soras
3129 
3130 --- Legal stuff ---
3131 
3132 This program is free software. It comes without any warranty, to
3133 the extent permitted by applicable law. You can redistribute it
3134 and/or modify it under the terms of the Do What The Fuck You Want
3135 To Public License, Version 2, as published by Sam Hocevar. See
3136 http://sam.zoy.org/wtfpl/COPYING for more details.
3137 
3138 *Tab=3***********************************************************************/
3139 
3140 
3141 
3142 #if ! defined (ffft_FFTRealUseTrigo_HEADER_INCLUDED)
3143 #define ffft_FFTRealUseTrigo_HEADER_INCLUDED
3144 
3145 #if defined (_MSC_VER)
3146  #pragma once
3147  #pragma warning (4 : 4250) // "Inherits via dominance."
3148 #endif
3149 
3150 
3151 
3152 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3153 
3154 
3155 
3156 
3157 
3158 
3159 
3160 namespace ffft
3161 {
3162 
3163 
3164 
3165 template <int ALGO>
3166 class FFTRealUseTrigo
3167 {
3168 
3169 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3170 
3171 public:
3172 
3173  typedef FFTRealFixLenParam::DataType DataType;
3174  typedef OscSinCos <DataType> OscType;
3175 
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);
3180 
3181 
3182 
3183 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3184 
3185 protected:
3186 
3187 
3188 
3189 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3190 
3191 private:
3192 
3193 
3194 
3195 /*\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\*/
3196 
3197 private:
3198 
3199  FFTRealUseTrigo ();
3200  ~FFTRealUseTrigo ();
3201  FFTRealUseTrigo (const FFTRealUseTrigo &other);
3202  FFTRealUseTrigo &
3203  operator = (const FFTRealUseTrigo &other);
3204  bool operator == (const FFTRealUseTrigo &other);
3205  bool operator != (const FFTRealUseTrigo &other);
3206 
3207 }; // class FFTRealUseTrigo
3208 
3209 
3210 
3211 } // namespace ffft
3212 
3213 
3214 
3215 /*****************************************************************************
3216 
3217  FFTRealUseTrigo.hpp
3218  By Laurent de Soras
3219 
3220 --- Legal stuff ---
3221 
3222 This program is free software. It comes without any warranty, to
3223 the extent permitted by applicable law. You can redistribute it
3224 and/or modify it under the terms of the Do What The Fuck You Want
3225 To Public License, Version 2, as published by Sam Hocevar. See
3226 http://sam.zoy.org/wtfpl/COPYING for more details.
3227 
3228 *Tab=3***********************************************************************/
3229 
3230 
3231 
3232 #if defined (ffft_FFTRealUseTrigo_CURRENT_CODEHEADER)
3233  #error Recursive inclusion of FFTRealUseTrigo code header.
3234 #endif
3235 #define ffft_FFTRealUseTrigo_CURRENT_CODEHEADER
3236 
3237 #if ! defined (ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED)
3238 #define ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED
3239 
3240 
3241 
3242 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3243 
3244 
3245 
3246 
3247 
3248 namespace ffft
3249 {
3250 
3251 
3252 
3253 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3254 
3255 
3256 
3257 template <int ALGO>
3258 void FFTRealUseTrigo <ALGO>::prepare (OscType &osc)
3259 {
3260  osc.clear_buffers ();
3261 }
3262 
3263 template <>
3264 inline void FFTRealUseTrigo <0>::prepare (OscType &osc)
3265 {
3266  // Nothing
3267 }
3268 
3269 
3270 
3271 template <int ALGO>
3272 void FFTRealUseTrigo <ALGO>::iterate (OscType &osc, DataType &c, DataType &s, const DataType cos_ptr [], long index_c, long index_s)
3273 {
3274  osc.step ();
3275  c = osc.get_cos ();
3276  s = osc.get_sin ();
3277 }
3278 
3279 template <>
3280 inline void FFTRealUseTrigo <0>::iterate (OscType &osc, DataType &c, DataType &s, const DataType cos_ptr [], long index_c, long index_s)
3281 {
3282  c = cos_ptr [index_c];
3283  s = cos_ptr [index_s];
3284 }
3285 
3286 
3287 
3288 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3289 
3290 
3291 
3292 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3293 
3294 
3295 
3296 } // namespace ffft
3297 
3298 
3299 
3300 #endif // ffft_FFTRealUseTrigo_CODEHEADER_INCLUDED
3301 
3302 #undef ffft_FFTRealUseTrigo_CURRENT_CODEHEADER
3303 
3304 
3305 
3306 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3307 
3308 
3309 
3310 
3311 #endif // ffft_FFTRealUseTrigo_HEADER_INCLUDED
3312 
3313 
3314 
3315 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3316 
3317 
3318 
3319 
3320 namespace ffft
3321 {
3322 
3323 
3324 
3325 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3326 
3327 
3328 
3329 template <int PASS>
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 [])
3331 {
3332  process_internal (
3333  len,
3334  dest_ptr,
3335  f_ptr,
3336  cos_ptr,
3337  cos_len,
3338  br_ptr,
3339  osc_list
3340  );
3341  FFTRealPassInverse <PASS - 1>::process_rec (
3342  len,
3343  src_ptr,
3344  dest_ptr,
3345  cos_ptr,
3346  cos_len,
3347  br_ptr,
3348  osc_list
3349  );
3350 }
3351 
3352 
3353 
3354 template <int PASS>
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 [])
3356 {
3357  process_internal (
3358  len,
3359  dest_ptr,
3360  src_ptr,
3361  cos_ptr,
3362  cos_len,
3363  br_ptr,
3364  osc_list
3365  );
3366  FFTRealPassInverse <PASS - 1>::process_rec (
3367  len,
3368  src_ptr,
3369  dest_ptr,
3370  cos_ptr,
3371  cos_len,
3372  br_ptr,
3373  osc_list
3374  );
3375 }
3376 
3377 template <>
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 [])
3379 {
3380  // Stops recursion
3381 }
3382 
3383 
3384 
3385 template <int PASS>
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 [])
3387 {
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);
3395 
3396  enum { TRIGO_OSC = PASS - FFTRealFixLenParam::TRIGO_BD_LIMIT };
3397  enum { TRIGO_DIRECT = (TRIGO_OSC >= 0) ? 1 : 0 };
3398 
3399  long coef_index = 0;
3400  do
3401  {
3402  const DataType * const sf = src_ptr + coef_index;
3403  DataType * const df = dest_ptr + coef_index;
3404 
3405  // Extreme coefficients are always real
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;
3410 
3411  FFTRealUseTrigo <TRIGO_DIRECT>::prepare (osc_list [TRIGO_OSC]);
3412 
3413  // Others are conjugate complex numbers
3414  for (long i = 1; i < dist; ++ i)
3415  {
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];
3418 
3419  DataType c;
3420  DataType s;
3421  FFTRealUseTrigo <TRIGO_DIRECT>::iterate (
3422  osc_list [TRIGO_OSC],
3423  c,
3424  s,
3425  cos_ptr,
3426  i * table_step,
3427  (dist - i) * table_step
3428  );
3429 
3430  const DataType vr = sf [c1_r + i] - sf [c2_r - i];
3431  const DataType vi = sf [c2_r + i] + sf [cend - i];
3432 
3433  df [c2_r + i] = vr * c + vi * s;
3434  df [c2_i + i] = vi * c - vr * s;
3435  }
3436 
3437  coef_index += cend;
3438  }
3439  while (coef_index < len);
3440 }
3441 
3442 template <>
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 [])
3444 {
3445  // Antepenultimate pass
3446  const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
3447 
3448  long coef_index = 0;
3449  do
3450  {
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;
3455 
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];
3458 
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];
3461 
3462  dest_ptr [coef_index + 5] = (vr + vi) * sqrt2_2;
3463  dest_ptr [coef_index + 7] = (vi - vr) * sqrt2_2;
3464 
3465  coef_index += 8;
3466  }
3467  while (coef_index < len);
3468 }
3469 
3470 template <>
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 [])
3472 {
3473  // Penultimate and last pass at once
3474  const long qlen = len >> 2;
3475 
3476  long coef_index = 0;
3477  do
3478  {
3479  const long ri_0 = br_ptr [coef_index >> 2];
3480 
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;
3485 
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;
3490 
3491  coef_index += 4;
3492  }
3493  while (coef_index < len);
3494 }
3495 
3496 
3497 
3498 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3499 
3500 
3501 
3502 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3503 
3504 
3505 
3506 } // namespace ffft
3507 
3508 
3509 
3510 #endif // ffft_FFTRealPassInverse_CODEHEADER_INCLUDED
3511 
3512 #undef ffft_FFTRealPassInverse_CURRENT_CODEHEADER
3513 
3514 
3515 
3516 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3517 
3518 
3519 
3520 
3521 #endif // ffft_FFTRealPassInverse_HEADER_INCLUDED
3522 
3523 
3524 
3525 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3526 
3527 /*****************************************************************************
3528 
3529  FFTRealSelect.h
3530  By Laurent de Soras
3531 
3532 --- Legal stuff ---
3533 
3534 This program is free software. It comes without any warranty, to
3535 the extent permitted by applicable law. You can redistribute it
3536 and/or modify it under the terms of the Do What The Fuck You Want
3537 To Public License, Version 2, as published by Sam Hocevar. See
3538 http://sam.zoy.org/wtfpl/COPYING for more details.
3539 
3540 *Tab=3***********************************************************************/
3541 
3542 
3543 
3544 #if ! defined (ffft_FFTRealSelect_HEADER_INCLUDED)
3545 #define ffft_FFTRealSelect_HEADER_INCLUDED
3546 
3547 #if defined (_MSC_VER)
3548  #pragma once
3549 #endif
3550 
3551 
3552 
3553 /*\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3554 
3555 
3556 
3557 
3558 
3559 namespace ffft
3560 {
3561 
3562 
3563 
3564 template <int P>
3566 {
3567 
3568 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3569 
3570 public:
3571 
3572  ffft_FORCEINLINE static float *
3573  sel_bin (float *e_ptr, float *o_ptr);
3574 
3575 
3576 
3577 /*\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\*/
3578 
3579 private:
3580 
3581  FFTRealSelect ();
3582  ~FFTRealSelect ();
3583  FFTRealSelect (const FFTRealSelect &other);
3584  FFTRealSelect& operator = (const FFTRealSelect &other);
3585  bool operator == (const FFTRealSelect &other);
3586  bool operator != (const FFTRealSelect &other);
3587 
3588 }; // class FFTRealSelect
3589 
3590 
3591 
3592 } // namespace ffft
3593 
3594 
3595 
3596 /*****************************************************************************
3597 
3598  FFTRealSelect.hpp
3599  By Laurent de Soras
3600 
3601 --- Legal stuff ---
3602 
3603 This program is free software. It comes without any warranty, to
3604 the extent permitted by applicable law. You can redistribute it
3605 and/or modify it under the terms of the Do What The Fuck You Want
3606 To Public License, Version 2, as published by Sam Hocevar. See
3607 http://sam.zoy.org/wtfpl/COPYING for more details.
3608 
3609 *Tab=3***********************************************************************/
3610 
3611 
3612 
3613 #if defined (ffft_FFTRealSelect_CURRENT_CODEHEADER)
3614  #error Recursive inclusion of FFTRealSelect code header.
3615 #endif
3616 #define ffft_FFTRealSelect_CURRENT_CODEHEADER
3617 
3618 #if ! defined (ffft_FFTRealSelect_CODEHEADER_INCLUDED)
3619 #define ffft_FFTRealSelect_CODEHEADER_INCLUDED
3620 
3621 
3622 
3623 namespace ffft
3624 {
3625 
3626 
3627 
3628 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3629 
3630 
3631 
3632 template <int P>
3633 float * FFTRealSelect <P>::sel_bin (float *e_ptr, float *o_ptr)
3634 {
3635  return (o_ptr);
3636 }
3637 
3638 
3639 
3640 template <>
3641 inline float * FFTRealSelect <0>::sel_bin (float *e_ptr, float *o_ptr)
3642 {
3643  return (e_ptr);
3644 }
3645 
3646 
3647 
3648 } // namespace ffft
3649 
3650 
3651 
3652 #endif // ffft_FFTRealSelect_CODEHEADER_INCLUDED
3653 
3654 #undef ffft_FFTRealSelect_CURRENT_CODEHEADER
3655 
3656 
3657 
3658 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3659 
3660 
3661 
3662 
3663 #endif // ffft_FFTRealSelect_HEADER_INCLUDED
3664 
3665 
3666 
3667 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3668 
3669 
3670 #include <cassert>
3671 #include <cmath>
3672 
3673 namespace std { }
3674 
3675 
3676 
3677 namespace ffft
3678 {
3679 
3680 
3681 
3682 /*\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3683 
3684 
3685 
3686 template <int LL2>
3687 FFTRealFixLen <LL2>::FFTRealFixLen ()
3688 : _buffer (FFT_LEN)
3689 , _br_data (BR_ARR_SIZE)
3690 , _trigo_data (TRIGO_TABLE_ARR_SIZE)
3691 , _trigo_osc ()
3692 {
3693  build_br_lut ();
3694  build_trigo_lut ();
3695  build_trigo_osc ();
3696 }
3697 
3698 
3699 
3700 template <int LL2>
3701 long FFTRealFixLen <LL2>::get_length () const
3702 {
3703  return (FFT_LEN);
3704 }
3705 
3706 
3707 
3708 // General case
3709 template <int LL2>
3710 void FFTRealFixLen <LL2>::do_fft (DataType f [], const DataType x [])
3711 {
3712  assert (f != 0);
3713  assert (x != 0);
3714  assert (x != f);
3715  assert (FFT_LEN_L2 >= 3);
3716 
3717  // Do the transform in several passes
3718  const DataType * cos_ptr = &_trigo_data [0];
3719  const long * br_ptr = &_br_data [0];
3720 
3721  FFTRealPassDirect <FFT_LEN_L2 - 1>::process (
3722  FFT_LEN,
3723  f,
3724  &_buffer [0],
3725  x,
3726  cos_ptr,
3727  TRIGO_TABLE_ARR_SIZE,
3728  br_ptr,
3729  &_trigo_osc [0]
3730  );
3731 }
3732 
3733 // 4-point FFT
3734 template <>
3735 inline void FFTRealFixLen <2>::do_fft (DataType f [], const DataType x [])
3736 {
3737  assert (f != 0);
3738  assert (x != 0);
3739  assert (x != f);
3740 
3741  f [1] = x [0] - x [2];
3742  f [3] = x [1] - x [3];
3743 
3744  const DataType b_0 = x [0] + x [2];
3745  const DataType b_2 = x [1] + x [3];
3746 
3747  f [0] = b_0 + b_2;
3748  f [2] = b_0 - b_2;
3749 }
3750 
3751 // 2-point FFT
3752 template <>
3753 inline void FFTRealFixLen <1>::do_fft (DataType f [], const DataType x [])
3754 {
3755  assert (f != 0);
3756  assert (x != 0);
3757  assert (x != f);
3758 
3759  f [0] = x [0] + x [1];
3760  f [1] = x [0] - x [1];
3761 }
3762 
3763 // 1-point FFT
3764 template <>
3765 inline void FFTRealFixLen <0>::do_fft (DataType f [], const DataType x [])
3766 {
3767  assert (f != 0);
3768  assert (x != 0);
3769 
3770  f [0] = x [0];
3771 }
3772 
3773 
3774 
3775 // General case
3776 template <int LL2>
3777 void FFTRealFixLen <LL2>::do_ifft (const DataType f [], DataType x [])
3778 {
3779  assert (f != 0);
3780  assert (x != 0);
3781  assert (x != f);
3782  assert (FFT_LEN_L2 >= 3);
3783 
3784  // Do the transform in several passes
3785  DataType * s_ptr =
3786  FFTRealSelect <FFT_LEN_L2 & 1>::sel_bin (&_buffer [0], x);
3787  DataType * d_ptr =
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];
3791 
3792  FFTRealPassInverse <FFT_LEN_L2 - 1>::process (
3793  FFT_LEN,
3794  d_ptr,
3795  s_ptr,
3796  f,
3797  cos_ptr,
3798  TRIGO_TABLE_ARR_SIZE,
3799  br_ptr,
3800  &_trigo_osc [0]
3801  );
3802 }
3803 
3804 // 4-point IFFT
3805 template <>
3806 inline void FFTRealFixLen <2>::do_ifft (const DataType f [], DataType x [])
3807 {
3808  assert (f != 0);
3809  assert (x != 0);
3810  assert (x != f);
3811 
3812  const DataType b_0 = f [0] + f [2];
3813  const DataType b_2 = f [0] - f [2];
3814 
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;
3819 }
3820 
3821 // 2-point IFFT
3822 template <>
3823 inline void FFTRealFixLen <1>::do_ifft (const DataType f [], DataType x [])
3824 {
3825  assert (f != 0);
3826  assert (x != 0);
3827  assert (x != f);
3828 
3829  x [0] = f [0] + f [1];
3830  x [1] = f [0] - f [1];
3831 }
3832 
3833 // 1-point IFFT
3834 template <>
3835 inline void FFTRealFixLen <0>::do_ifft (const DataType f [], DataType x [])
3836 {
3837  assert (f != 0);
3838  assert (x != 0);
3839  assert (x != f);
3840 
3841  x [0] = f [0];
3842 }
3843 
3844 
3845 
3846 
3847 template <int LL2>
3848 void FFTRealFixLen <LL2>::rescale (DataType x []) const
3849 {
3850  assert (x != 0);
3851 
3852  const DataType mul = DataType (1.0 / FFT_LEN);
3853 
3854  if (FFT_LEN < 4)
3855  {
3856  long i = FFT_LEN - 1;
3857  do
3858  {
3859  x [i] *= mul;
3860  --i;
3861  }
3862  while (i >= 0);
3863  }
3864 
3865  else
3866  {
3867  assert ((FFT_LEN & 3) == 0);
3868 
3869  // Could be optimized with SIMD instruction sets (needs alignment check)
3870  long i = FFT_LEN - 4;
3871  do
3872  {
3873  x [i + 0] *= mul;
3874  x [i + 1] *= mul;
3875  x [i + 2] *= mul;
3876  x [i + 3] *= mul;
3877  i -= 4;
3878  }
3879  while (i >= 0);
3880  }
3881 }
3882 
3883 
3884 
3885 /*\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3886 
3887 
3888 
3889 /*\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3890 
3891 
3892 
3893 template <int LL2>
3894 void FFTRealFixLen <LL2>::build_br_lut ()
3895 {
3896  _br_data [0] = 0;
3897  for (long cnt = 1; cnt < BR_ARR_SIZE; ++cnt)
3898  {
3899  long index = cnt << 2;
3900  long br_index = 0;
3901 
3902  int bit_cnt = FFT_LEN_L2;
3903  do
3904  {
3905  br_index <<= 1;
3906  br_index += (index & 1);
3907  index >>= 1;
3908 
3909  -- bit_cnt;
3910  }
3911  while (bit_cnt > 0);
3912 
3913  _br_data [cnt] = br_index;
3914  }
3915 }
3916 
3917 
3918 
3919 template <int LL2>
3920 void FFTRealFixLen <LL2>::build_trigo_lut ()
3921 {
3922  const double mul = (0.5 * PI) / TRIGO_TABLE_ARR_SIZE;
3923  for (long i = 0; i < TRIGO_TABLE_ARR_SIZE; ++ i)
3924  {
3925  using namespace std;
3926 
3927  _trigo_data [i] = DataType (cos (i * mul));
3928  }
3929 }
3930 
3931 
3932 
3933 template <int LL2>
3934 void FFTRealFixLen <LL2>::build_trigo_osc ()
3935 {
3936  for (int i = 0; i < NBR_TRIGO_OSC; ++i)
3937  {
3938  OscType & osc = _trigo_osc [i];
3939 
3940  const long len = static_cast <long> (TRIGO_TABLE_ARR_SIZE) << (i + 1);
3941  const double mul = (0.5 * PI) / len;
3942  osc.set_step (mul);
3943  }
3944 }
3945 
3946 
3947 
3948 } // namespace ffft
3949 
3950 
3951 
3952 #endif // ffft_FFTRealFixLen_CODEHEADER_INCLUDED
3953 
3954 #undef ffft_FFTRealFixLen_CURRENT_CODEHEADER
3955 
3956 
3957 
3958 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
3959 
3960 
3961 
3962 
3963 #endif // ffft_FFTRealFixLen_HEADER_INCLUDED
3964 
3965 
3966 
3967 /*\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
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