1 /*
2     This file is part of GNU APL, a free implementation of the
3     ISO/IEC Standard 13751, "Programming Language APL, Extended"
4 
5     Copyright (C) 2008-2017  Dr. Jürgen Sauermann
6 
7     This program is free software: you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation, either version 3 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #ifndef __Quad_FFT_DEFINED__
22 #define __Quad_FFT_DEFINED__
23 
24 #include <math.h>
25 
26 #include "QuadFunction.hh"
27 #include "Value.hh"
28 
29 /// The class implementing ⎕FFT
30 class Quad_FFT : public QuadFunction
31 {
32 public:
33    /// Constructor.
Quad_FFT()34    Quad_FFT()
35       : QuadFunction(TOK_Quad_FFT),
36         system_wisdom_loaded(false)
37    {}
38 
39    static Quad_FFT * fun;          ///< Built-in function.
40    static Quad_FFT  _fun;          ///< Built-in function.
41 
42 protected:
43    /// overloaded Function::eval_AB()
44    Token eval_AB(Value_P A, Value_P B);
45 
46    /// overloaded Function::eval_B()
47    Token eval_B(Value_P B);
48 
49    /// window function for sample n of N with parameters a = a0, a1, ...
50    typedef double (*window_function)(ShapeItem n, ShapeItem N);
51 
52    /// compute forward or backward FFT
53    Token do_fft(int dir, Value_P B, window_function win);
54 
55    /// return the values of the window function \b win for length \b N
56    Token do_window(Value_P B, window_function win);
57 
58    /// initialize \b in from B
59    static void init_in(void * in, Value_P B, window_function win);
60 
61    /// return the no window value for sample n of N
no_window(ShapeItem n,ShapeItem N)62    static double no_window(ShapeItem n, ShapeItem N)
63       { return 1.0; }
64 
65    /// return the Hann window value for sample n of N
hann_window(ShapeItem n,ShapeItem N)66    static double hann_window(ShapeItem n, ShapeItem N)
67       { return 0.5 - 0.5*cos(2*n*M_PI / (N-1)); }
68 
69    /// return the Hamming window value for sample n of N
hamming_window(ShapeItem n,ShapeItem N)70    static double hamming_window(ShapeItem n, ShapeItem N)
71       { return 0.54 - 0.46*cos(2*n*M_PI / (N-1)); }
72 
73    /// return the Hann window value for sample n of N
blackman_window(ShapeItem n,ShapeItem N)74    static double blackman_window(ShapeItem n, ShapeItem N)
75       { return 0.42 - 0.5*cos(2*n*M_PI / (N-1)) + 0.08*cos(4*M_PI*n / (N-1)); }
76 
77    /// return the Blackman-Harris window value for sample n of N
blackman_harris_window(ShapeItem n,ShapeItem N)78    static double blackman_harris_window(ShapeItem n, ShapeItem N)
79       { return 0.35875
80              - 0.48829*cos(2*n*M_PI / (N-1))
81              + 0.14128*cos(4*n*M_PI / (N-1))
82              - 0.01168*cos(6*n*M_PI / (N-1)); }
83 
84    /// return the Blackman-Nuttallwindow value for sample n of N
blackman_nuttall_window(ShapeItem n,ShapeItem N)85    static double blackman_nuttall_window(ShapeItem n, ShapeItem N)
86       { return 0.3635819
87              - 0.4891775*cos(2*n*M_PI / (N-1))
88              + 0.1365995*cos(4*n*M_PI / (N-1))
89              - 0.0106411*cos(6*n*M_PI / (N-1)); }
90 
91    /// return the Flat-Top window value for sample n of N
flat_top(ShapeItem n,ShapeItem N)92    static double flat_top(ShapeItem n, ShapeItem N)
93       { return 1.0
94              - 1.93 *cos(2*n*M_PI / (N-1))
95              + 1.29 *cos(4*n*M_PI / (N-1))
96              - 0.388*cos(6*n*M_PI / (N-1))
97              + 0.028*cos(8*n*M_PI / (N-1)); }
98 
99    /// set up a multi-dimensional window for shape sh, using the window
100    /// function \b win
101    static void fill_window(double * result, const Shape & shape,
102                            window_function win);
103 
104    /// true if fftw_import_system_wisdom() was called
105    bool system_wisdom_loaded;
106 };
107 
108 #endif // __Quad_FFT_DEFINED__
109