1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2006 - INRIA - Allan CORNET
4 * Copyright (C) 2012 - INRIA - Serge STEER
5 *
6 * Copyright (C) 2012 - 2016 - Scilab Enterprises
7 *
8 * This file is hereby licensed under the terms of the GNU GPL v2.0,
9 * pursuant to article 5.3.4 of the CeCILL v.2.1.
10 * This file was originally licensed under the terms of the CeCILL v2.1,
11 * and continues to be available under such terms.
12 * For more information, see the COPYING file which you should have received
13 * along with this program.
14 *
15 */
16 #include "callfftw.h"
17 /*--------------------------------------------------------------------------*/
18 #include "dynamiclibrary.h"
19 #include "getshortpathname.h"
20 #include "sci_malloc.h"
21 #include "charEncoding.h"
22 /*--------------------------------------------------------------------------*/
23 typedef void (*PROC_FFTW_EXECUTE_SPLIT_DFT) (const fftw_plan p, double *ri, double *ii, double *ro, double *io);
24 typedef void (*PROC_FFTW_EXECUTE_SPLIT_DFT_C2R) (const fftw_plan p, double *ri, double *ii, double *ro);
25 typedef void (*PROC_FFTW_EXECUTE_SPLIT_DFT_R2C) (const fftw_plan p, double *ri, double *ro, double *io);
26 typedef void (*PROC_FFTW_EXECUTE_SPLIT_DFT_R2R) (const fftw_plan p, double *ri, double *ro);
27 typedef fftw_plan (*PROC_FFTW_PLAN_GURU_SPLIT_DFT) (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro, double *io, unsigned flags);
28 typedef fftw_plan (*PROC_FFTW_PLAN_GURU_SPLIT_DFT_C2R) (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro, unsigned flags);
29 typedef fftw_plan (*PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2C) (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ro, double *io, unsigned flags);
30 typedef fftw_plan (*PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2R) (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ro, fftw_r2r_kind *kind, unsigned flags);
31 typedef void (*PROC_FFTW_DESTROY_PLAN) (fftw_plan p);
32 typedef char *(*PROC_FFTW_EXPORT_WISDOM_TO_STRING) (void);
33 typedef int (*PROC_FFTW_IMPORT_WISDOM_FROM_STRING) (const char *input_string);
34 typedef void (*PROC_FFTW_FORGET_WISDOM) (void);
35 /*--------------------------------------------------------------------------*/
36 static DynLibHandle hinstLib = NULL;
37 static PROC_FFTW_EXECUTE_SPLIT_DFT MY_FFTW_EXECUTE_SPLIT_DFT = NULL;
38 static PROC_FFTW_EXECUTE_SPLIT_DFT_C2R MY_FFTW_EXECUTE_SPLIT_DFT_C2R = NULL;
39 static PROC_FFTW_EXECUTE_SPLIT_DFT_R2C MY_FFTW_EXECUTE_SPLIT_DFT_R2C = NULL;
40 static PROC_FFTW_EXECUTE_SPLIT_DFT_R2R MY_FFTW_EXECUTE_SPLIT_DFT_R2R = NULL;
41 static PROC_FFTW_PLAN_GURU_SPLIT_DFT MY_FFTW_PLAN_GURU_SPLIT_DFT = NULL;
42 static PROC_FFTW_PLAN_GURU_SPLIT_DFT_C2R MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R = NULL;
43 static PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2C MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C = NULL;
44 static PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2R MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R = NULL;
45 static PROC_FFTW_DESTROY_PLAN MY_FFTW_DESTROY_PLAN = NULL;
46 static PROC_FFTW_EXPORT_WISDOM_TO_STRING MY_FFTW_EXPORT_WISDOM_TO_STRING = NULL;
47 static PROC_FFTW_IMPORT_WISDOM_FROM_STRING MY_FFTW_IMPORT_WISDOM_FROM_STRING = NULL;
48 static PROC_FFTW_FORGET_WISDOM MY_FFTW_FORGET_WISDOM = NULL;
49 /*--------------------------------------------------------------------------*/
IsLoadedFFTW(void)50 BOOL IsLoadedFFTW(void)
51 {
52 if ( (MY_FFTW_EXECUTE_SPLIT_DFT) && (MY_FFTW_PLAN_GURU_SPLIT_DFT) && (MY_FFTW_DESTROY_PLAN) &&
53 (MY_FFTW_EXPORT_WISDOM_TO_STRING) && (MY_FFTW_IMPORT_WISDOM_FROM_STRING) &&
54 (MY_FFTW_FORGET_WISDOM) )
55 {
56 return TRUE;
57 }
58 return FALSE;
59 }
60 /*--------------------------------------------------------------------------*/
LoadFFTWLibrary(const char * libraryname)61 BOOL LoadFFTWLibrary(const char* libraryname)
62 {
63
64 if (libraryname == NULL)
65 {
66 return FALSE;
67 }
68 if (hinstLib == NULL)
69 {
70 #ifdef _MSC_VER
71 {
72 wchar_t * wclibraryname = to_wide_string(libraryname);
73 if (wclibraryname)
74 {
75 hinstLib = LoadDynLibraryW(wclibraryname);
76 FREE(wclibraryname);
77 wclibraryname = NULL;
78 }
79 }
80 #else
81 hinstLib = LoadDynLibrary(libraryname);
82 #endif
83 MY_FFTW_EXECUTE_SPLIT_DFT = NULL;
84 MY_FFTW_EXECUTE_SPLIT_DFT_C2R = NULL;
85 MY_FFTW_EXECUTE_SPLIT_DFT_R2C = NULL;
86 MY_FFTW_EXECUTE_SPLIT_DFT_R2R = NULL;
87
88 MY_FFTW_PLAN_GURU_SPLIT_DFT = NULL;
89 MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R = NULL;
90 MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C = NULL;
91 MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R = NULL;
92
93 MY_FFTW_DESTROY_PLAN = NULL;
94
95 MY_FFTW_EXPORT_WISDOM_TO_STRING = NULL;
96 MY_FFTW_IMPORT_WISDOM_FROM_STRING = NULL;
97 MY_FFTW_FORGET_WISDOM = NULL;
98
99 MY_FFTW_EXECUTE_SPLIT_DFT = (PROC_FFTW_EXECUTE_SPLIT_DFT) GetDynLibFuncPtr(hinstLib, "fftw_execute_split_dft");
100 MY_FFTW_EXECUTE_SPLIT_DFT_C2R = (PROC_FFTW_EXECUTE_SPLIT_DFT_C2R) GetDynLibFuncPtr(hinstLib, "fftw_execute_split_dft_c2r");
101 MY_FFTW_EXECUTE_SPLIT_DFT_R2C = (PROC_FFTW_EXECUTE_SPLIT_DFT_R2C) GetDynLibFuncPtr(hinstLib, "fftw_execute_split_dft_r2c");
102 MY_FFTW_EXECUTE_SPLIT_DFT_R2R = (PROC_FFTW_EXECUTE_SPLIT_DFT_R2R) GetDynLibFuncPtr(hinstLib, "fftw_execute_r2r");
103
104 MY_FFTW_PLAN_GURU_SPLIT_DFT = (PROC_FFTW_PLAN_GURU_SPLIT_DFT) GetDynLibFuncPtr(hinstLib, "fftw_plan_guru_split_dft");
105 MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R = (PROC_FFTW_PLAN_GURU_SPLIT_DFT_C2R) GetDynLibFuncPtr(hinstLib, "fftw_plan_guru_split_dft_c2r");
106 MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C = (PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2C) GetDynLibFuncPtr(hinstLib, "fftw_plan_guru_split_dft_r2c");
107 MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R = (PROC_FFTW_PLAN_GURU_SPLIT_DFT_R2R) GetDynLibFuncPtr(hinstLib, "fftw_plan_guru_r2r");
108
109
110 MY_FFTW_DESTROY_PLAN = (PROC_FFTW_DESTROY_PLAN) GetDynLibFuncPtr(hinstLib, "fftw_destroy_plan");
111
112 MY_FFTW_EXPORT_WISDOM_TO_STRING = (PROC_FFTW_EXPORT_WISDOM_TO_STRING) GetDynLibFuncPtr(hinstLib, "fftw_export_wisdom_to_string");
113 MY_FFTW_IMPORT_WISDOM_FROM_STRING = (PROC_FFTW_IMPORT_WISDOM_FROM_STRING) GetDynLibFuncPtr(hinstLib, "fftw_import_wisdom_from_string");
114 MY_FFTW_FORGET_WISDOM = (PROC_FFTW_FORGET_WISDOM) GetDynLibFuncPtr(hinstLib, "fftw_forget_wisdom");
115 }
116
117 return IsLoadedFFTW();
118 }
119 /*--------------------------------------------------------------------------*/
DisposeFFTWLibrary(void)120 BOOL DisposeFFTWLibrary(void)
121 {
122 BOOL fFreeResult;
123
124 if (hinstLib)
125 {
126 fFreeResult = FreeDynLibrary(hinstLib);
127 hinstLib = NULL;
128 }
129
130 if (MY_FFTW_EXECUTE_SPLIT_DFT)
131 {
132 MY_FFTW_EXECUTE_SPLIT_DFT = NULL;
133 }
134 if (MY_FFTW_EXECUTE_SPLIT_DFT_C2R)
135 {
136 MY_FFTW_EXECUTE_SPLIT_DFT_C2R = NULL;
137 }
138 if (MY_FFTW_EXECUTE_SPLIT_DFT_R2C)
139 {
140 MY_FFTW_EXECUTE_SPLIT_DFT_R2C = NULL;
141 }
142 if (MY_FFTW_EXECUTE_SPLIT_DFT_R2R)
143 {
144 MY_FFTW_EXECUTE_SPLIT_DFT_R2R = NULL;
145 }
146
147 if (MY_FFTW_PLAN_GURU_SPLIT_DFT)
148 {
149 MY_FFTW_PLAN_GURU_SPLIT_DFT = NULL;
150 }
151 if (MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R)
152 {
153 MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R = NULL;
154 }
155 if (MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C)
156 {
157 MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C = NULL;
158 }
159 if (MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R)
160 {
161 MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R = NULL;
162 }
163
164 if (MY_FFTW_DESTROY_PLAN)
165 {
166 MY_FFTW_DESTROY_PLAN = NULL;
167 }
168
169 if (MY_FFTW_EXPORT_WISDOM_TO_STRING)
170 {
171 MY_FFTW_EXPORT_WISDOM_TO_STRING = NULL;
172 }
173 if (MY_FFTW_IMPORT_WISDOM_FROM_STRING)
174 {
175 MY_FFTW_IMPORT_WISDOM_FROM_STRING = NULL;
176 }
177 if (MY_FFTW_FORGET_WISDOM)
178 {
179 MY_FFTW_FORGET_WISDOM = NULL;
180 }
181
182 if ( !MY_FFTW_EXECUTE_SPLIT_DFT && !MY_FFTW_EXECUTE_SPLIT_DFT_C2R &&
183 !MY_FFTW_EXECUTE_SPLIT_DFT_R2C && !MY_FFTW_EXECUTE_SPLIT_DFT_R2R &&
184 !MY_FFTW_PLAN_GURU_SPLIT_DFT && !MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R &&
185 !MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C && !MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R &&
186 !MY_FFTW_DESTROY_PLAN &&
187 !MY_FFTW_EXPORT_WISDOM_TO_STRING && !MY_FFTW_IMPORT_WISDOM_FROM_STRING &&
188 !MY_FFTW_FORGET_WISDOM )
189 {
190 return TRUE;
191 }
192
193 return FALSE;
194 }
195 /*--------------------------------------------------------------------------*/
call_fftw_execute_split_dft(const fftw_plan p,double * ri,double * ii,double * ro,double * io)196 void call_fftw_execute_split_dft (const fftw_plan p, double *ri, double *ii, double *ro, double *io)
197 {
198 if (MY_FFTW_EXECUTE_SPLIT_DFT)
199 {
200 (MY_FFTW_EXECUTE_SPLIT_DFT)(p, ri, ii, ro, io);
201 }
202 }
203 /*--------------------------------------------------------------------------*/
call_fftw_execute_split_dft_c2r(const fftw_plan p,double * ri,double * ii,double * ro)204 void call_fftw_execute_split_dft_c2r (const fftw_plan p, double *ri, double *ii, double *ro)
205 {
206 if (MY_FFTW_EXECUTE_SPLIT_DFT_C2R)
207 {
208 (MY_FFTW_EXECUTE_SPLIT_DFT_C2R)(p, ri, ii, ro);
209 }
210 }
211 /*--------------------------------------------------------------------------*/
call_fftw_execute_split_dft_r2c(const fftw_plan p,double * ri,double * ro,double * io)212 void call_fftw_execute_split_dft_r2c (const fftw_plan p, double *ri, double *ro, double *io)
213 {
214 if (MY_FFTW_EXECUTE_SPLIT_DFT_R2C)
215 {
216 (MY_FFTW_EXECUTE_SPLIT_DFT_R2C)(p, ri, ro, io);
217 }
218 }
219 /*--------------------------------------------------------------------------*/
call_fftw_execute_split_dft_r2r(const fftw_plan p,double * ri,double * ro)220 void call_fftw_execute_split_dft_r2r (const fftw_plan p, double *ri, double *ro)
221 {
222 if (MY_FFTW_EXECUTE_SPLIT_DFT_R2R)
223 {
224 (MY_FFTW_EXECUTE_SPLIT_DFT_R2R)(p, ri, ro);
225 }
226 }
227 /*--------------------------------------------------------------------------*/
call_fftw_plan_guru_split_dft(int rank,const fftw_iodim * dims,int howmany_rank,const fftw_iodim * howmany_dims,double * ri,double * ii,double * ro,double * io,unsigned flags)228 fftw_plan call_fftw_plan_guru_split_dft (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro, double *io, unsigned flags)
229 {
230 if (MY_FFTW_PLAN_GURU_SPLIT_DFT)
231 {
232 return (fftw_plan)(MY_FFTW_PLAN_GURU_SPLIT_DFT)(rank, dims, howmany_rank, howmany_dims, ri, ii, ro, io, flags);
233 }
234 else
235 {
236 return NULL;
237 }
238 }
239 /*--------------------------------------------------------------------------*/
call_fftw_plan_guru_split_dft_c2r(int rank,const fftw_iodim * dims,int howmany_rank,const fftw_iodim * howmany_dims,double * ri,double * ii,double * ro,unsigned flags)240 fftw_plan call_fftw_plan_guru_split_dft_c2r (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ii, double *ro, unsigned flags)
241 {
242 if (MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R)
243 {
244 return (fftw_plan)(MY_FFTW_PLAN_GURU_SPLIT_DFT_C2R)(rank, dims, howmany_rank, howmany_dims, ri, ii, ro, flags);
245 }
246 else
247 {
248 return NULL;
249 }
250 }
251 /*--------------------------------------------------------------------------*/
call_fftw_plan_guru_split_dft_r2c(int rank,const fftw_iodim * dims,int howmany_rank,const fftw_iodim * howmany_dims,double * ri,double * ro,double * io,unsigned flags)252 fftw_plan call_fftw_plan_guru_split_dft_r2c (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ro, double *io, unsigned flags)
253 {
254 if (MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C)
255 {
256 return (fftw_plan)(MY_FFTW_PLAN_GURU_SPLIT_DFT_R2C)(rank, dims, howmany_rank, howmany_dims, ri, ro, io, flags);
257 }
258 else
259 {
260 return NULL;
261 }
262 }
263 /*--------------------------------------------------------------------------*/
call_fftw_plan_guru_split_dft_r2r(int rank,const fftw_iodim * dims,int howmany_rank,const fftw_iodim * howmany_dims,double * ri,double * ro,fftw_r2r_kind * kind,unsigned flags)264 fftw_plan call_fftw_plan_guru_split_dft_r2r (int rank, const fftw_iodim *dims, int howmany_rank, const fftw_iodim *howmany_dims, double *ri, double *ro, fftw_r2r_kind *kind, unsigned flags)
265 {
266 if (MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R)
267 {
268 return (fftw_plan)(MY_FFTW_PLAN_GURU_SPLIT_DFT_R2R)(rank, dims, howmany_rank, howmany_dims, ri, ro, kind, flags);
269 }
270 else
271 {
272 return NULL;
273 }
274 }
275
276 /*--------------------------------------------------------------------------*/
call_fftw_destroy_plan(fftw_plan p)277 void call_fftw_destroy_plan (fftw_plan p)
278 {
279 if (MY_FFTW_DESTROY_PLAN)
280 {
281 (MY_FFTW_DESTROY_PLAN)(p);
282 }
283 }
284 /*--------------------------------------------------------------------------*/
call_fftw_export_wisdom_to_string(void)285 char *call_fftw_export_wisdom_to_string (void)
286 {
287 if (MY_FFTW_EXPORT_WISDOM_TO_STRING)
288 {
289 return (char *)(MY_FFTW_EXPORT_WISDOM_TO_STRING)();
290 }
291 return NULL;
292 }
293 /*--------------------------------------------------------------------------*/
call_fftw_import_wisdom_from_string(const char * input_string)294 int call_fftw_import_wisdom_from_string (const char *input_string)
295 {
296 if (MY_FFTW_IMPORT_WISDOM_FROM_STRING)
297 {
298 return (int)(MY_FFTW_IMPORT_WISDOM_FROM_STRING)(input_string);
299 }
300 return 0;
301 }
302 /*--------------------------------------------------------------------------*/
call_fftw_forget_wisdom(void)303 void call_fftw_forget_wisdom (void)
304 {
305 if (MY_FFTW_FORGET_WISDOM)
306 {
307 (MY_FFTW_FORGET_WISDOM)();
308 }
309 }
310 /*--------------------------------------------------------------------------*/
311