summaryrefslogtreecommitdiff
path: root/gr-fft/include/gnuradio/fft/fft.h
blob: 6163d2f83ff822fb3d8acc2ff2ab638b6c14695c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* -*- c++ -*- */
/*
 * Copyright 2003,2008,2012,2020 Free Software Foundation, Inc.
 *
 * This file is part of GNU Radio
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *
 */

#ifndef _FFT_FFT_H_
#define _FFT_FFT_H_

/*
 * Wrappers for FFTW single precision 1d dft
 */

#include <gnuradio/fft/api.h>
#include <gnuradio/gr_complex.h>
#include <gnuradio/logger.h>
#include <volk/volk_alloc.hh>
#include <boost/thread.hpp>

namespace gr {
namespace fft {

/*!
 * \brief Export reference to planner mutex for those apps that
 * want to use FFTW w/o using the fft_impl_fftw* classes.
 */
class FFT_API planner
{
public:
    typedef boost::mutex::scoped_lock scoped_lock;
    /*!
     * Return reference to planner mutex
     */
    static boost::mutex& mutex();
};


/*!
  \brief FFT: templated
  \ingroup misc
 */


template <class T, bool forward>
struct fft_inbuf {
    typedef T type;
};

template <>
struct fft_inbuf<float, false> {
    typedef gr_complex type;
};


template <class T, bool forward>
struct fft_outbuf {
    typedef T type;
};

template <>
struct fft_outbuf<float, true> {
    typedef gr_complex type;
};

template <class T, bool forward>
class FFT_API fft
{
    int d_nthreads;
    volk::vector<typename fft_inbuf<T, forward>::type> d_inbuf;
    volk::vector<typename fft_outbuf<T, forward>::type> d_outbuf;
    void* d_plan;
    gr::logger_ptr d_logger;
    gr::logger_ptr d_debug_logger;
    void initialize_plan(int fft_size);

public:
    fft(int fft_size, int nthreads = 1);
    // Copy disabled due to d_plan.
    fft(const fft&) = delete;
    fft& operator=(const fft&) = delete;
    virtual ~fft();

    /*
     * These return pointers to buffers owned by fft_impl_fft_complex
     * into which input and output take place. It's done this way in
     * order to ensure optimal alignment for SIMD instructions.
     */
    typename fft_inbuf<T, forward>::type* get_inbuf() { return d_inbuf.data(); }
    typename fft_outbuf<T, forward>::type* get_outbuf() { return d_outbuf.data(); }

    int inbuf_length() const { return d_inbuf.size(); }
    int outbuf_length() const { return d_outbuf.size(); }

    /*!
     *  Set the number of threads to use for calculation.
     */
    void set_nthreads(int n);

    /*!
     *  Get the number of threads being used by FFTW
     */
    int nthreads() const { return d_nthreads; }

    /*!
     * compute FFT. The input comes from inbuf, the output is placed in
     * outbuf.
     */
    void execute();
};

using fft_complex_fwd = fft<gr_complex, true>;
using fft_complex_rev = fft<gr_complex, false>;
using fft_real_fwd = fft<float, true>;
using fft_real_rev = fft<float, false>;

} /* namespace fft */
} /*namespace gr */

#endif /* _FFT_FFT_H_ */