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