GNU Radio Manual and C++ API Reference  3.8.1.0
The Free & Open Software Radio Ecosystem
fft_filter.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2010,2012,2014 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
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 3, or (at your option)
10  * any later version.
11  *
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.
16  *
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.
21  */
22 
23 #ifndef INCLUDED_FILTER_FFT_FILTER_H
24 #define INCLUDED_FILTER_FFT_FILTER_H
25 
26 #include <gnuradio/fft/fft.h>
27 #include <gnuradio/filter/api.h>
28 #include <gnuradio/gr_complex.h>
29 #include <vector>
30 
31 namespace gr {
32 namespace filter {
33 namespace kernel {
34 
35 /*!
36  * \brief Fast FFT filter with float input, float output and float taps
37  * \ingroup filter_blk
38  *
39  * \details
40  * This block performs fast convolution using the
41  * overlap-and-save algorithm. The filtering is performand in
42  * the frequency domain instead of the time domain (see
43  * gr::filter::kernel::fir_filter_fff). For an input signal x
44  * and filter coefficients (taps) t, we compute y as:
45  *
46  * \code
47  * y = ifft(fft(x)*fft(t))
48  * \endcode
49  *
50  * This kernel computes the FFT of the taps when they are set to
51  * only perform this operation once. The FFT of the input signal
52  * x is done every time.
53  *
54  * Because this is designed as a very low-level kernel
55  * operation, it is designed for speed and avoids certain checks
56  * in the filter() function itself. The filter function expects
57  * that the input signal is a multiple of d_nsamples in the
58  * class that's computed internally to be as fast as
59  * possible. The function set_taps will return the value of
60  * nsamples that can be used externally to check this
61  * boundary. Notice that all implementations of the fft_filter
62  * GNU Radio blocks (e.g., gr::filter::fft_filter_fff) use this
63  * value of nsamples to compute the value to call
64  * gr::block::set_output_multiple that ensures the scheduler
65  * always passes this block the right number of samples.
66  */
68 {
69 private:
70  int d_ntaps;
71  int d_nsamples;
72  int d_fftsize; // fftsize = ntaps + nsamples - 1
73  int d_decimation;
74  fft::fft_real_fwd* d_fwdfft; // forward "plan"
75  fft::fft_real_rev* d_invfft; // inverse "plan"
76  int d_nthreads; // number of FFTW threads to use
77  std::vector<float> d_tail; // state carried between blocks for overlap-add
78  std::vector<float> d_taps; // stores time domain taps
79  gr_complex* d_xformed_taps; // Fourier xformed taps
80 
81  void compute_sizes(int ntaps);
82  int tailsize() const { return d_ntaps - 1; }
83 
84 public:
85  /*!
86  * \brief Construct an FFT filter for float vectors with the given taps and decimation
87  * rate.
88  *
89  * This is the basic implementation for performing FFT filter for fast convolution
90  * in other blocks (e.g., gr::filter::fft_filter_fff).
91  *
92  * \param decimation The decimation rate of the filter (int)
93  * \param taps The filter taps (vector of float)
94  * \param nthreads The number of threads for the FFT to use (int)
95  */
96  fft_filter_fff(int decimation, const std::vector<float>& taps, int nthreads = 1);
97 
98  ~fft_filter_fff();
99 
100  /*!
101  * \brief Set new taps for the filter.
102  *
103  * Sets new taps and resets the class properties to handle different sizes
104  * \param taps The filter taps (complex)
105  */
106  int set_taps(const std::vector<float>& taps);
107 
108  /*!
109  * \brief Set number of threads to use.
110  */
111  void set_nthreads(int n);
112 
113  /*!
114  * \brief Returns the taps.
115  */
116  std::vector<float> taps() const;
117 
118  /*!
119  * \brief Returns the number of taps in the filter.
120  */
121  unsigned int ntaps() const;
122 
123  /*!
124  * \brief Get number of threads being used.
125  */
126  int nthreads() const;
127 
128  /*!
129  * \brief Perform the filter operation
130  *
131  * \param nitems The number of items to produce
132  * \param input The input vector to be filtered
133  * \param output The result of the filter operation
134  */
135  int filter(int nitems, const float* input, float* output);
136 };
137 
138 
139 /*!
140  * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps
141  * \ingroup filter_blk
142  *
143  * \details
144  * This block performs fast convolution using the
145  * overlap-and-save algorithm. The filtering is performand in
146  * the frequency domain instead of the time domain (see
147  * gr::filter::kernel::fir_filter_ccc). For an input signal x
148  * and filter coefficients (taps) t, we compute y as:
149  *
150  * \code
151  * y = ifft(fft(x)*fft(t))
152  * \endcode
153  *
154  * This kernel computes the FFT of the taps when they are set to
155  * only perform this operation once. The FFT of the input signal
156  * x is done every time.
157  *
158  * Because this is designed as a very low-level kernel
159  * operation, it is designed for speed and avoids certain checks
160  * in the filter() function itself. The filter function expects
161  * that the input signal is a multiple of d_nsamples in the
162  * class that's computed internally to be as fast as
163  * possible. The function set_taps will return the value of
164  * nsamples that can be used externally to check this
165  * boundary. Notice that all implementations of the fft_filter
166  * GNU Radio blocks (e.g., gr::filter::fft_filter_ccc) use this
167  * value of nsamples to compute the value to call
168  * gr::block::set_output_multiple that ensures the scheduler
169  * always passes this block the right number of samples.
170  */
172 {
173 private:
174  int d_ntaps;
175  int d_nsamples;
176  int d_fftsize; // fftsize = ntaps + nsamples - 1
177  int d_decimation;
178  fft::fft_complex* d_fwdfft; // forward "plan"
179  fft::fft_complex* d_invfft; // inverse "plan"
180  int d_nthreads; // number of FFTW threads to use
181  std::vector<gr_complex> d_tail; // state carried between blocks for overlap-add
182  std::vector<gr_complex> d_taps; // stores time domain taps
183  gr_complex* d_xformed_taps; // Fourier xformed taps
184 
185  void compute_sizes(int ntaps);
186  int tailsize() const { return d_ntaps - 1; }
187 
188 public:
189  /*!
190  * \brief Construct an FFT filter for complex vectors with the given taps and
191  * decimation rate.
192  *
193  * This is the basic implementation for performing FFT filter for fast convolution
194  * in other blocks (e.g., gr::filter::fft_filter_ccc).
195  *
196  * \param decimation The decimation rate of the filter (int)
197  * \param taps The filter taps (vector of complex)
198  * \param nthreads The number of threads for the FFT to use (int)
199  */
200  fft_filter_ccc(int decimation, const std::vector<gr_complex>& taps, int nthreads = 1);
201 
202  ~fft_filter_ccc();
203 
204  /*!
205  * \brief Set new taps for the filter.
206  *
207  * Sets new taps and resets the class properties to handle different sizes
208  * \param taps The filter taps (complex)
209  */
210  int set_taps(const std::vector<gr_complex>& taps);
211 
212  /*!
213  * \brief Set number of threads to use.
214  */
215  void set_nthreads(int n);
216 
217  /*!
218  * \brief Returns the taps.
219  */
220  std::vector<gr_complex> taps() const;
221 
222  /*!
223  * \brief Returns the number of taps in the filter.
224  */
225  unsigned int ntaps() const;
226 
227  /*!
228  * \brief Get number of threads being used.
229  */
230  int nthreads() const;
231 
232  /*!
233  * \brief Perform the filter operation
234  *
235  * \param nitems The number of items to produce
236  * \param input The input vector to be filtered
237  * \param output The result of the filter operation
238  */
239  int filter(int nitems, const gr_complex* input, gr_complex* output);
240 };
241 
242 
243 /*!
244  * \brief Fast FFT filter with gr_complex input, gr_complex output and float taps
245  * \ingroup filter_blk
246  *
247  * \details
248  * This block performs fast convolution using the
249  * overlap-and-save algorithm. The filtering is performand in
250  * the frequency domain instead of the time domain (see
251  * gr::filter::kernel::fir_filter_ccf). For an input signal x
252  * and filter coefficients (taps) t, we compute y as:
253  *
254  * \code
255  * y = ifft(fft(x)*fft(t))
256  * \endcode
257  *
258  * This kernel computes the FFT of the taps when they are set to
259  * only perform this operation once. The FFT of the input signal
260  * x is done every time.
261  *
262  * Because this is designed as a very low-level kernel
263  * operation, it is designed for speed and avoids certain checks
264  * in the filter() function itself. The filter function expects
265  * that the input signal is a multiple of d_nsamples in the
266  * class that's computed internally to be as fast as
267  * possible. The function set_taps will return the value of
268  * nsamples that can be used externally to check this
269  * boundary. Notice that all implementations of the fft_filter
270  * GNU Radio blocks (e.g., gr::filter::fft_filter_ccf) use this
271  * value of nsamples to compute the value to call
272  * gr::block::set_output_multiple that ensures the scheduler
273  * always passes this block the right number of samples.
274  */
276 {
277 private:
278  int d_ntaps;
279  int d_nsamples;
280  int d_fftsize; // fftsize = ntaps + nsamples - 1
281  int d_decimation;
282  fft::fft_complex* d_fwdfft; // forward "plan"
283  fft::fft_complex* d_invfft; // inverse "plan"
284  int d_nthreads; // number of FFTW threads to use
285  std::vector<gr_complex> d_tail; // state carried between blocks for overlap-add
286  std::vector<float> d_taps; // stores time domain taps
287  gr_complex* d_xformed_taps; // Fourier xformed taps
288 
289  void compute_sizes(int ntaps);
290  int tailsize() const { return d_ntaps - 1; }
291 
292 public:
293  /*!
294  * \brief Construct an FFT filter for complex vectors with the given taps and
295  * decimation rate.
296  *
297  * This is the basic implementation for performing FFT filter for fast convolution
298  * in other blocks (e.g., gr::filter::fft_filter_ccf).
299  *
300  * \param decimation The decimation rate of the filter (int)
301  * \param taps The filter taps (float)
302  * \param nthreads The number of threads for the FFT to use (int)
303  */
304  fft_filter_ccf(int decimation, const std::vector<float>& taps, int nthreads = 1);
305 
306  ~fft_filter_ccf();
307 
308  /*!
309  * \brief Set new taps for the filter.
310  *
311  * Sets new taps and resets the class properties to handle different sizes
312  * \param taps The filter taps (complex)
313  */
314  int set_taps(const std::vector<float>& taps);
315 
316  /*!
317  * \brief Set number of threads to use.
318  */
319  void set_nthreads(int n);
320 
321  /*!
322  * \brief Returns the taps.
323  */
324  std::vector<float> taps() const;
325 
326  /*!
327  * \brief Returns the number of taps in the filter.
328  */
329  unsigned int ntaps() const;
330 
331  /*!
332  * \brief Returns the actual size of the filter.
333  *
334  * \details This value could be equal to ntaps, but we ofter
335  * build a longer filter to allow us to calculate a more
336  * efficient FFT. This value is the actual size of the filters
337  * used in the calculation of the overlap-and-save operation.
338  */
339  unsigned int filtersize() const;
340 
341  /*!
342  * \brief Get number of threads being used.
343  */
344  int nthreads() const;
345 
346  /*!
347  * \brief Perform the filter operation
348  *
349  * \param nitems The number of items to produce
350  * \param input The input vector to be filtered
351  * \param output The result of the filter operation
352  */
353  int filter(int nitems, const gr_complex* input, gr_complex* output);
354 };
355 
356 } /* namespace kernel */
357 } /* namespace filter */
358 } /* namespace gr */
359 
360 #endif /* INCLUDED_FILTER_FFT_FILTER_H */
FFT: complex in, complex out.
Definition: fft.h:72
Fast FFT filter with gr_complex input, gr_complex output and float taps.
Definition: fft_filter.h:275
std::complex< float > gr_complex
Definition: gr_complex.h:27
GNU Radio logging wrapper for log4cpp library (C++ port of log4j)
Definition: basic_block.h:43
FFT: real in, complex out.
Definition: fft.h:116
Fast FFT filter with float input, float output and float taps.
Definition: fft_filter.h:67
FFT: complex in, float out.
Definition: fft.h:160
Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps.
Definition: fft_filter.h:171
static const float taps[NSTEPS+1][NTAPS]
Definition: interpolator_taps.h:9
#define FILTER_API
Definition: gr-filter/include/gnuradio/filter/api.h:30