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