3 * Copyright 2003 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio 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 2, or (at your option)
12 * GNU Radio 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.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
25 #include <gr_complex.h>
35 static char *filename = ".gr_fftw_wisdom";
37 char *home = getenv ("HOME");
39 char *p = new char[strlen (home) + strlen (filename) + 2];
49 gri_fftw_import_wisdom ()
51 char *filename = wisdom_filename ();
52 FILE *fp = fopen (filename, "r");
54 int r = fftwf_import_wisdom_from_file (fp);
57 fprintf (stderr, "gri_fftw: can't import wisdom from %s\n", filename);
64 gri_fftw_export_wisdom ()
66 char *filename = wisdom_filename ();
67 FILE *fp = fopen (filename, "w");
69 fftwf_export_wisdom_to_file (fp);
73 fprintf (stderr, "gri_fftw: ");
79 // ----------------------------------------------------------------
81 gri_fft_complex::gri_fft_complex (int fft_size, bool forward)
83 assert (sizeof (fftwf_complex) == sizeof (gr_complex));
86 throw std::out_of_range ("gri_fftw: invalid fft_size");
88 d_fft_size = fft_size;
89 d_inbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * inbuf_length ());
91 throw std::runtime_error ("fftwf_malloc");
93 d_outbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * outbuf_length ());
96 throw std::runtime_error ("fftwf_malloc");
99 // FIXME If there's ever a chance that the planning functions
100 // will be called in multiple threads, we've got to ensure single
101 // threaded access. They are not thread-safe.
103 gri_fftw_import_wisdom (); // load prior wisdom from disk
104 d_plan = fftwf_plan_dft_1d (fft_size,
105 reinterpret_cast<fftwf_complex *>(d_inbuf),
106 reinterpret_cast<fftwf_complex *>(d_outbuf),
107 forward ? FFTW_FORWARD : FFTW_BACKWARD,
110 if (d_plan == NULL) {
111 fprintf(stderr, "gri_fft_complex: error creating plan\n");
112 throw std::runtime_error ("fftwf_plan_dft_1d failed");
114 gri_fftw_export_wisdom (); // store new wisdom to disk
117 gri_fft_complex::~gri_fft_complex ()
119 fftwf_destroy_plan ((fftwf_plan) d_plan);
120 fftwf_free (d_inbuf);
121 fftwf_free (d_outbuf);
125 gri_fft_complex::execute ()
127 fftwf_execute ((fftwf_plan) d_plan);
130 // ----------------------------------------------------------------
132 gri_fft_real_fwd::gri_fft_real_fwd (int fft_size)
134 assert (sizeof (fftwf_complex) == sizeof (gr_complex));
137 throw std::out_of_range ("gri_fftw: invalid fft_size");
139 d_fft_size = fft_size;
140 d_inbuf = (float *) fftwf_malloc (sizeof (float) * inbuf_length ());
142 throw std::runtime_error ("fftwf_malloc");
144 d_outbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * outbuf_length ());
146 fftwf_free (d_inbuf);
147 throw std::runtime_error ("fftwf_malloc");
150 // FIXME If there's ever a chance that the planning functions
151 // will be called in multiple threads, we've got to ensure single
152 // threaded access. They are not thread-safe.
154 gri_fftw_import_wisdom (); // load prior wisdom from disk
155 d_plan = fftwf_plan_dft_r2c_1d (fft_size,
157 reinterpret_cast<fftwf_complex *>(d_outbuf),
160 if (d_plan == NULL) {
161 fprintf(stderr, "gri_fft_real_fwd: error creating plan\n");
162 throw std::runtime_error ("fftwf_plan_dft_r2c_1d failed");
164 gri_fftw_export_wisdom (); // store new wisdom to disk
167 gri_fft_real_fwd::~gri_fft_real_fwd ()
169 fftwf_destroy_plan ((fftwf_plan) d_plan);
170 fftwf_free (d_inbuf);
171 fftwf_free (d_outbuf);
175 gri_fft_real_fwd::execute ()
177 fftwf_execute ((fftwf_plan) d_plan);
180 // ----------------------------------------------------------------
182 gri_fft_real_rev::gri_fft_real_rev (int fft_size)
184 assert (sizeof (fftwf_complex) == sizeof (gr_complex));
187 throw std::out_of_range ("gri_fftw: invalid fft_size");
189 d_fft_size = fft_size;
190 d_inbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * inbuf_length ());
192 throw std::runtime_error ("fftwf_malloc");
194 d_outbuf = (float *) fftwf_malloc (sizeof (float) * outbuf_length ());
196 fftwf_free (d_inbuf);
197 throw std::runtime_error ("fftwf_malloc");
200 // FIXME If there's ever a chance that the planning functions
201 // will be called in multiple threads, we've got to ensure single
202 // threaded access. They are not thread-safe.
204 gri_fftw_import_wisdom (); // load prior wisdom from disk
205 d_plan = fftwf_plan_dft_c2r_1d (fft_size,
206 reinterpret_cast<fftwf_complex *>(d_inbuf),
210 if (d_plan == NULL) {
211 fprintf(stderr, "gri_fft_real_rev: error creating plan\n");
212 throw std::runtime_error ("fftwf_plan_dft_c2r_1d failed");
214 gri_fftw_export_wisdom (); // store new wisdom to disk
217 gri_fft_real_rev::~gri_fft_real_rev ()
219 fftwf_destroy_plan ((fftwf_plan) d_plan);
220 fftwf_free (d_inbuf);
221 fftwf_free (d_outbuf);
225 gri_fft_real_rev::execute ()
227 fftwf_execute ((fftwf_plan) d_plan);