diff options
Diffstat (limited to 'gr-fft')
-rw-r--r-- | gr-fft/include/gnuradio/fft/fft_vcc.h | 33 | ||||
-rw-r--r-- | gr-fft/include/gnuradio/fft/fft_vfc.h | 36 | ||||
-rw-r--r-- | gr-fft/lib/fft.cc | 37 | ||||
-rw-r--r-- | gr-fft/python/fft/CMakeLists.txt | 3 |
4 files changed, 92 insertions, 17 deletions
diff --git a/gr-fft/include/gnuradio/fft/fft_vcc.h b/gr-fft/include/gnuradio/fft/fft_vcc.h index 1e09521b4f..28f6d1d0d4 100644 --- a/gr-fft/include/gnuradio/fft/fft_vcc.h +++ b/gr-fft/include/gnuradio/fft/fft_vcc.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2007,2008,2012 Free Software Foundation, Inc. + * Copyright 2004,2007,2008,2012,2018 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -32,6 +32,29 @@ namespace gr { /*! * \brief Compute forward or reverse FFT. complex vector in / complex vector out. * \ingroup fourier_analysis_blk + * + * The FFT operation is defined for a vector \f$x\f$ with \f$N\f$ uniformly + * sampled points by + * + * \f[ X(a) = \sum_{k=0}^{N-1} x(a) \cdot e^{-j 2\pi k a / N} \f] + * + * \f$ X = FFT\{x\} \f$ is the the FFT transform of \f$x(a)\f$, \f$j\f$ is + * the imaginary unit, \f$k\f$ and \f$a\f$ range from \f$0\f$ to \f$N-1\f$. + * + * The IFFT operation is defined for a vector \f$y\f$ with \f$N\f$ + * uniformly sampled points by + * + * \f[ Y(b) = \sum_{k=0}^{N-1} y(b) \cdot e^{j 2\pi k b / N} \f] + * + * \f$Y = IFFT\{y\}\f$ is the the inverse FFT transform of \f$y(b)\f$, + * \f$j\f$ is the imaginary unit, \f$k\f$ and \f$b\f$ range from \f$0\f$ to + * \f$N-1\f$. + * + * \b Note, that due to the underlying FFTW library, the output of a FFT + * followed by an IFFT (or the other way arround) will be scaled i.e. + * \f$FFT\{ \, IFFT\{x\} \,\} = N \cdot x \neq x\f$. + * + * \see http://www.fftw.org/faq/section3.html#whyscaled */ class FFT_API fft_vcc : virtual public sync_block { @@ -39,7 +62,13 @@ namespace gr { // gr::fft::fft_vcc::sptr typedef boost::shared_ptr<fft_vcc> sptr; - + /*! \brief + * \param[in] fft_size N. + * \param[in] forward True performs FFT, False performs IFFT. + * \param[in] window Window function to be used. + * \param[in] shifted True moves DC carrier to the middle. + * \param[in] nthreads Number of underlying threads. + */ static sptr make(int fft_size, bool forward, const std::vector<float> &window, bool shift=false, int nthreads=1); diff --git a/gr-fft/include/gnuradio/fft/fft_vfc.h b/gr-fft/include/gnuradio/fft/fft_vfc.h index 91ed81fb17..5639465ab5 100644 --- a/gr-fft/include/gnuradio/fft/fft_vfc.h +++ b/gr-fft/include/gnuradio/fft/fft_vfc.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2010,2012 Free Software Foundation, Inc. + * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -30,16 +30,46 @@ namespace gr { namespace fft { /*! - * \brief Compute forward or reverse FFT. float vector in / complex vector out. + * \brief Compute forward or reverse FFT. complex vector in / complex vector out. * \ingroup fourier_analysis_blk + * + * The FFT operation is defined for a vector \f$x\f$ with \f$N\f$ uniformly + * sampled points by + * + * \f[ X(a) = \sum_{k=0}^{N-1} x(a) \cdot e^{-j 2\pi k a / N} \f] + * + * \f$ X = FFT\{x\} \f$ is the the FFT transform of \f$x(a)\f$, \f$j\f$ is + * the imaginary unit, \f$k\f$ and \f$a\f$ range from \f$0\f$ to \f$N-1\f$. + * + * The IFFT operation is defined for a vector \f$y\f$ with \f$N\f$ + * uniformly sampled points by + * + * \f[ Y(b) = \sum_{k=0}^{N-1} y(b) \cdot e^{j 2\pi k b / N} \f] + * + * \f$Y = IFFT\{y\}\f$ is the the inverse FFT transform of \f$y(b)\f$, + * \f$j\f$ is the imaginary unit, \f$k\f$ and \f$b\f$ range from \f$0\f$ to + * \f$N-1\f$. + * + * \b Note, that due to the underlying FFTW library, the output of a FFT + * followed by an IFFT (or the other way arround) will be scaled i.e. + * \f$FFT\{ \, IFFT\{x\} \,\} = N \cdot x \neq x\f$. + * + * \see http://www.fftw.org/faq/section3.html#whyscaled */ - class FFT_API fft_vfc : virtual public sync_block + class FFT_API fft_vfc : virtual public sync_block { public: // gr::fft::fft_vfc::sptr typedef boost::shared_ptr<fft_vfc> sptr; + /*! \brief + * \param[in] fft_size N. + * \param[in] forward True performs FFT, False performs IFFT. + * \param[in] window Window function to be used. + * \param[in] shifted True moves DC carrier to the middle. + * \param[in] nthreads Number of underlying threads. + */ static sptr make(int fft_size, bool forward, const std::vector<float> &window, int nthreads=1); diff --git a/gr-fft/lib/fft.cc b/gr-fft/lib/fft.cc index 871ad9bcaa..718cd0990f 100644 --- a/gr-fft/lib/fft.cc +++ b/gr-fft/lib/fft.cc @@ -56,7 +56,8 @@ namespace fs = boost::filesystem; namespace gr { namespace fft { static boost::mutex wisdom_thread_mutex; - boost::interprocess::file_lock wisdom_lock; + boost::interprocess::file_lock wisdom_lock; + static bool wisdom_lock_init_done = false; // Modify while holding 'wisdom_thread_mutex' gr_complex * malloc_complex(int size) @@ -99,15 +100,36 @@ namespace gr { } static void + wisdom_lock_init() + { + if (wisdom_lock_init_done) + return; + + const std::string wisdom_lock_file = wisdom_filename() + ".lock"; + // std::cerr << "Creating FFTW wisdom lockfile: " << wisdom_lock_file << std::endl; + int fd = open(wisdom_lock_file.c_str(), + O_WRONLY | O_CREAT | O_NOCTTY | O_NONBLOCK, + 0666); + if (fd < 0) { + throw std::runtime_error("Failed to create FFTW wisdom lockfile: " + wisdom_lock_file); + } + close(fd); + wisdom_lock = boost::interprocess::file_lock(wisdom_lock_file.c_str()); + wisdom_lock_init_done = true; + } + + static void lock_wisdom() { - wisdom_thread_mutex.lock(); - wisdom_lock.lock(); + wisdom_thread_mutex.lock(); + wisdom_lock_init(); + wisdom_lock.lock(); } static void unlock_wisdom() { + // Assumes 'lock_wisdom' has already been called (i.e. this file_lock is valid) wisdom_lock.unlock(); wisdom_thread_mutex.unlock(); } @@ -163,15 +185,6 @@ namespace gr { { // Hold global mutex during plan construction and destruction. planner::scoped_lock lock(planner::mutex()); - const std::string wisdom_lock_file = wisdom_filename() + ".lock"; - int fd = open(wisdom_lock_file.c_str(), - O_WRONLY | O_CREAT | O_NOCTTY | O_NONBLOCK, - 0666); - if (fd < 0) { - throw std::exception(); - } - close(fd); - wisdom_lock = boost::interprocess::file_lock(wisdom_lock_file.c_str()); assert (sizeof (fftwf_complex) == sizeof (gr_complex)); diff --git a/gr-fft/python/fft/CMakeLists.txt b/gr-fft/python/fft/CMakeLists.txt index f08aebc11d..acf81ca050 100644 --- a/gr-fft/python/fft/CMakeLists.txt +++ b/gr-fft/python/fft/CMakeLists.txt @@ -35,6 +35,9 @@ if(ENABLE_TESTING) set(GR_TEST_LIBRARY_DIRS "") set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/gnuradio-runtime/python + ${CMAKE_BINARY_DIR}/gnuradio-runtime/swig + ${CMAKE_BINARY_DIR}/gr-blocks/swig + ${CMAKE_BINARY_DIR}/gr-fft/swig ) include(GrTest) file(GLOB py_qa_test_files "qa_*.py") |