diff options
author | mormj <34754695+mormj@users.noreply.github.com> | 2020-11-03 16:51:44 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-03 16:51:44 -0500 |
commit | ed95e8d45cfc6cd3e026298dadf4d2e8f9f1c3b8 (patch) | |
tree | a15c82b2a2c2baa623434ad2c3a4c51416002082 /gr-fft/lib | |
parent | 0f780e26d6545338b6c4a1b34405822a9a6ec706 (diff) |
Move FFT functions and blocks to templates (#3903)
* fft: refactor fft classes as templates
In order to reduce code duplication construct fft objects and blocks
with template paramters.
Separate forward and reverse as a template
parameter
Maintain the real fft block forward as r2c and reverse as r2c as well
Co-authored-by: Andrej Rode <mail@andrejro.de>
Diffstat (limited to 'gr-fft/lib')
-rw-r--r-- | gr-fft/lib/CMakeLists.txt | 3 | ||||
-rw-r--r-- | gr-fft/lib/ctrlport_probe_psd_impl.cc | 2 | ||||
-rw-r--r-- | gr-fft/lib/ctrlport_probe_psd_impl.h | 2 | ||||
-rw-r--r-- | gr-fft/lib/fft.cc | 149 | ||||
-rw-r--r-- | gr-fft/lib/fft_v_fftw.cc | 217 | ||||
-rw-r--r-- | gr-fft/lib/fft_v_fftw.h (renamed from gr-fft/lib/fft_vcc_fftw.h) | 28 | ||||
-rw-r--r-- | gr-fft/lib/fft_vcc_fftw.cc | 125 | ||||
-rw-r--r-- | gr-fft/lib/fft_vfc_fftw.cc | 94 | ||||
-rw-r--r-- | gr-fft/lib/fft_vfc_fftw.h | 45 |
9 files changed, 275 insertions, 390 deletions
diff --git a/gr-fft/lib/CMakeLists.txt b/gr-fft/lib/CMakeLists.txt index e8ec301eab..48495f03f8 100644 --- a/gr-fft/lib/CMakeLists.txt +++ b/gr-fft/lib/CMakeLists.txt @@ -10,8 +10,7 @@ ######################################################################## add_library(gnuradio-fft fft.cc - fft_vcc_fftw.cc - fft_vfc_fftw.cc + fft_v_fftw.cc goertzel_fc_impl.cc goertzel.cc window.cc diff --git a/gr-fft/lib/ctrlport_probe_psd_impl.cc b/gr-fft/lib/ctrlport_probe_psd_impl.cc index 824d326cf5..8b0bfc5516 100644 --- a/gr-fft/lib/ctrlport_probe_psd_impl.cc +++ b/gr-fft/lib/ctrlport_probe_psd_impl.cc @@ -33,7 +33,7 @@ ctrlport_probe_psd_impl::ctrlport_probe_psd_impl(const std::string& id, d_id(id), d_desc(desc), d_len(len), - d_fft(len, true, 1) + d_fft(len, 1) { set_length(len); } diff --git a/gr-fft/lib/ctrlport_probe_psd_impl.h b/gr-fft/lib/ctrlport_probe_psd_impl.h index dc82acff4d..2f2d2c3455 100644 --- a/gr-fft/lib/ctrlport_probe_psd_impl.h +++ b/gr-fft/lib/ctrlport_probe_psd_impl.h @@ -30,7 +30,7 @@ private: boost::condition_variable condition_buffer_ready; std::vector<gr_complex> d_buffer; - gr::fft::fft_complex d_fft; + gr::fft::fft_complex_fwd d_fft; public: ctrlport_probe_psd_impl(const std::string& id, const std::string& desc, int len); diff --git a/gr-fft/lib/fft.cc b/gr-fft/lib/fft.cc index dca635265b..9fc0a22f46 100644 --- a/gr-fft/lib/fft.cc +++ b/gr-fft/lib/fft.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2003,2008,2011,2012 Free Software Foundation, Inc. + * Copyright 2003,2008,2011,2012,2020 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -141,7 +141,9 @@ static void export_wisdom() // ---------------------------------------------------------------- -fft_complex::fft_complex(int fft_size, bool forward, int nthreads) + +template <class T, bool forward> +fft<T, forward>::fft(int fft_size, int nthreads) : d_nthreads(nthreads), d_inbuf(fft_size), d_outbuf(fft_size) { gr::configure_default_loggers(d_logger, d_debug_logger, "fft_complex"); @@ -159,137 +161,57 @@ fft_complex::fft_complex(int fft_size, bool forward, int nthreads) lock_wisdom(); import_wisdom(); // load prior wisdom from disk - d_plan = fftwf_plan_dft_1d(fft_size, - reinterpret_cast<fftwf_complex*>(d_inbuf.data()), - reinterpret_cast<fftwf_complex*>(d_outbuf.data()), - forward ? FFTW_FORWARD : FFTW_BACKWARD, - FFTW_MEASURE); - + initialize_plan(fft_size); if (d_plan == NULL) { GR_LOG_ERROR(d_logger, "creating plan failed"); - throw std::runtime_error("fftwf_plan_dft_1d failed"); + throw std::runtime_error("Creating fftw plan failed"); } export_wisdom(); // store new wisdom to disk unlock_wisdom(); } -fft_complex::~fft_complex() +template <> +void fft<gr_complex, true>::initialize_plan(int fft_size) { - // Hold global mutex during plan construction and destruction. - planner::scoped_lock lock(planner::mutex()); - - fftwf_destroy_plan((fftwf_plan)d_plan); + d_plan = fftwf_plan_dft_1d(fft_size, + reinterpret_cast<fftwf_complex*>(d_inbuf.data()), + reinterpret_cast<fftwf_complex*>(d_outbuf.data()), + FFTW_FORWARD, + FFTW_MEASURE); } -void fft_complex::set_nthreads(int n) +template <> +void fft<gr_complex, false>::initialize_plan(int fft_size) { - if (n <= 0) { - throw std::out_of_range("gr::fft: invalid number of threads"); - } - d_nthreads = n; - -#ifdef FFTW3F_THREADS - fftwf_plan_with_nthreads(d_nthreads); -#endif + d_plan = fftwf_plan_dft_1d(fft_size, + reinterpret_cast<fftwf_complex*>(d_inbuf.data()), + reinterpret_cast<fftwf_complex*>(d_outbuf.data()), + FFTW_BACKWARD, + FFTW_MEASURE); } -void fft_complex::execute() { fftwf_execute((fftwf_plan)d_plan); } - -// ---------------------------------------------------------------- -fft_real_fwd::fft_real_fwd(int fft_size, int nthreads) - : d_nthreads(nthreads), d_inbuf(fft_size), d_outbuf(fft_size / 2 + 1) +template <> +void fft<float, true>::initialize_plan(int fft_size) { - gr::configure_default_loggers(d_logger, d_debug_logger, "fft_real_fwd"); - - // Hold global mutex during plan construction and destruction. - planner::scoped_lock lock(planner::mutex()); - - static_assert(sizeof(fftwf_complex) == sizeof(gr_complex), - "The size of fftwf_complex is not equal to gr_complex"); - - if (fft_size <= 0) { - throw std::out_of_range("gr::fft: invalid fft_size"); - } - - config_threading(nthreads); - lock_wisdom(); - import_wisdom(); // load prior wisdom from disk - d_plan = fftwf_plan_dft_r2c_1d(fft_size, d_inbuf.data(), reinterpret_cast<fftwf_complex*>(d_outbuf.data()), FFTW_MEASURE); - - if (d_plan == NULL) { - GR_LOG_ERROR(d_logger, "creating plan failed"); - throw std::runtime_error("fftwf_plan_dft_r2c_1d failed"); - } - export_wisdom(); // store new wisdom to disk - unlock_wisdom(); -} - -fft_real_fwd::~fft_real_fwd() -{ - // Hold global mutex during plan construction and destruction. - planner::scoped_lock lock(planner::mutex()); - - fftwf_destroy_plan((fftwf_plan)d_plan); } -void fft_real_fwd::set_nthreads(int n) +template <> +void fft<float, false>::initialize_plan(int fft_size) { - if (n <= 0) { - throw std::out_of_range( - "gr::fft::fft_real_fwd::set_nthreads: invalid number of threads"); - } - d_nthreads = n; - -#ifdef FFTW3F_THREADS - fftwf_plan_with_nthreads(d_nthreads); -#endif -} - -void fft_real_fwd::execute() { fftwf_execute((fftwf_plan)d_plan); } - -// ---------------------------------------------------------------- - -fft_real_rev::fft_real_rev(int fft_size, int nthreads) - : d_nthreads(nthreads), d_inbuf(fft_size / 2 + 1), d_outbuf(fft_size) -{ - gr::configure_default_loggers(d_logger, d_debug_logger, "fft_real_rev"); - - // Hold global mutex during plan construction and destruction. - planner::scoped_lock lock(planner::mutex()); - - static_assert(sizeof(fftwf_complex) == sizeof(gr_complex), - "The size of fftwf_complex is not equal to gr_complex"); - - if (fft_size <= 0) { - throw std::out_of_range("gr::fft::fft_real_rev: invalid fft_size"); - } - - config_threading(nthreads); - lock_wisdom(); - import_wisdom(); // load prior wisdom from disk - - // FIXME If there's ever a chance that the planning functions - // will be called in multiple threads, we've got to ensure single - // threaded access. They are not thread-safe. d_plan = fftwf_plan_dft_c2r_1d(fft_size, reinterpret_cast<fftwf_complex*>(d_inbuf.data()), d_outbuf.data(), FFTW_MEASURE); - - if (d_plan == NULL) { - GR_LOG_ERROR(d_logger, "creating plan failed"); - throw std::runtime_error("fftwf_plan_dft_c2r_1d failed"); - } - export_wisdom(); // store new wisdom to disk - unlock_wisdom(); } -fft_real_rev::~fft_real_rev() + +template <class T, bool forward> +fft<T, forward>::~fft() { // Hold global mutex during plan construction and destruction. planner::scoped_lock lock(planner::mutex()); @@ -297,11 +219,11 @@ fft_real_rev::~fft_real_rev() fftwf_destroy_plan((fftwf_plan)d_plan); } -void fft_real_rev::set_nthreads(int n) +template <class T, bool forward> +void fft<T, forward>::set_nthreads(int n) { if (n <= 0) { - throw std::out_of_range( - "gr::fft::fft_real_rev::set_nthreads: invalid number of threads"); + throw std::out_of_range("gr::fft: invalid number of threads"); } d_nthreads = n; @@ -310,7 +232,16 @@ void fft_real_rev::set_nthreads(int n) #endif } -void fft_real_rev::execute() { fftwf_execute((fftwf_plan)d_plan); } +template <class T, bool forward> +void fft<T, forward>::execute() +{ + fftwf_execute((fftwf_plan)d_plan); +} + +template class fft<gr_complex, true>; +template class fft<gr_complex, false>; +template class fft<float, true>; +template class fft<float, false>; } /* namespace fft */ } /* namespace gr */ diff --git a/gr-fft/lib/fft_v_fftw.cc b/gr-fft/lib/fft_v_fftw.cc new file mode 100644 index 0000000000..387e63b458 --- /dev/null +++ b/gr-fft/lib/fft_v_fftw.cc @@ -0,0 +1,217 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2007,2008,2010,2012,2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "fft_v_fftw.h" +#include <math.h> +#include <string.h> +#include <volk/volk.h> + +namespace gr { +namespace fft { + +template <class T, bool forward> +typename fft_v<T, forward>::sptr fft_v<T, forward>::make(int fft_size, + const std::vector<float>& window, + bool shift, + int nthreads) +{ + return gnuradio::get_initial_sptr( + new fft_v_fftw<T, forward>(fft_size, window, shift, nthreads)); +} + +template <class T, bool forward> +fft_v_fftw<T, forward>::fft_v_fftw(int fft_size, + const std::vector<float>& window, + bool shift, + int nthreads) + : sync_block("fft_v_fftw", + io_signature::make(1, 1, fft_size * sizeof(T)), + io_signature::make(1, 1, fft_size * sizeof(gr_complex))), + d_fft_size(fft_size), + d_fft(fft_size, nthreads), + d_shift(shift) +{ + if (!set_window(window)) + throw std::runtime_error("fft_v: window not the same length as fft_size"); +} + +template <class T, bool forward> +void fft_v_fftw<T, forward>::set_nthreads(int n) +{ + d_fft.set_nthreads(n); +} + +template <class T, bool forward> +int fft_v_fftw<T, forward>::nthreads() const +{ + return d_fft.nthreads(); +} + +template <class T, bool forward> +bool fft_v_fftw<T, forward>::set_window(const std::vector<float>& window) +{ + if (window.empty() || window.size() == d_fft_size) { + d_window = window; + return true; + } else + return false; +} + +template <> +void fft_v_fftw<gr_complex, true>::fft_and_shift(const gr_complex* in, gr_complex* out) +{ + if (!d_window.empty()) { + gr_complex* dst = d_fft.get_inbuf(); + volk_32fc_32f_multiply_32fc(&dst[0], in, &d_window[0], d_fft_size); + } else { + memcpy(d_fft.get_inbuf(), in, sizeof(gr_complex) * d_fft_size); + } + d_fft.execute(); + if (d_shift) { + unsigned int len = (unsigned int)(ceil(d_fft_size / 2.0)); + memcpy( + &out[0], &d_fft.get_outbuf()[len], sizeof(gr_complex) * (d_fft_size - len)); + memcpy(&out[d_fft_size - len], &d_fft.get_outbuf()[0], sizeof(gr_complex) * len); + } else { + + memcpy(out, d_fft.get_outbuf(), sizeof(gr_complex) * d_fft_size); + } +} + +template <> +void fft_v_fftw<gr_complex, false>::fft_and_shift(const gr_complex* in, gr_complex* out) +{ + if (!d_window.empty()) { + gr_complex* dst = d_fft.get_inbuf(); + if (d_shift) { + unsigned int offset = d_fft_size / 2; + int fft_m_offset = d_fft_size - offset; + volk_32fc_32f_multiply_32fc(&dst[fft_m_offset], &in[0], &d_window[0], offset); + volk_32fc_32f_multiply_32fc( + &dst[0], &in[offset], &d_window[offset], d_fft_size - offset); + } else { + volk_32fc_32f_multiply_32fc(&dst[0], in, &d_window[0], d_fft_size); + } + } else { + if (d_shift) { // apply an ifft shift on the data + gr_complex* dst = d_fft.get_inbuf(); + unsigned int len = + (unsigned int)(floor(d_fft_size / 2.0)); // half length of complex array + memcpy(&dst[0], &in[len], sizeof(gr_complex) * (d_fft_size - len)); + memcpy(&dst[d_fft_size - len], &in[0], sizeof(gr_complex) * len); + } else { + memcpy(d_fft.get_inbuf(), in, sizeof(gr_complex) * d_fft_size); + } + } + d_fft.execute(); + memcpy(out, d_fft.get_outbuf(), sizeof(gr_complex) * d_fft_size); +} + +template <> +void fft_v_fftw<float, true>::fft_and_shift(const float* in, gr_complex* out) +{ + // copy input into optimally aligned buffer + if (!d_window.empty()) { + gr_complex* dst = d_fft.get_inbuf(); + for (unsigned int i = 0; i < d_fft_size; i++) // apply window + dst[i] = in[i] * d_window[i]; + } else { + gr_complex* dst = d_fft.get_inbuf(); + for (unsigned int i = 0; i < d_fft_size; i++) // float to complex conversion + dst[i] = in[i]; + } + + d_fft.execute(); + if (d_shift) { + unsigned int len = (unsigned int)(ceil(d_fft_size / 2.0)); + memcpy( + &out[0], &d_fft.get_outbuf()[len], sizeof(gr_complex) * (d_fft_size - len)); + memcpy(&out[d_fft_size - len], &d_fft.get_outbuf()[0], sizeof(gr_complex) * len); + } else { + + memcpy(out, d_fft.get_outbuf(), sizeof(gr_complex) * d_fft_size); + } +} + +template <> +void fft_v_fftw<float, false>::fft_and_shift(const float* in, gr_complex* out) +{ + // copy input into optimally aligned buffer + if (!d_window.empty()) { + gr_complex* dst = d_fft.get_inbuf(); + if (d_shift) { + unsigned int len = + (unsigned int)(floor(d_fft_size / 2.0)); // half length of complex array + for (unsigned int i = 0; i < len; i++) { + dst[i] = in[len + i] * d_window[len + i]; + } + for (unsigned int i = len; i < d_fft_size; i++) { + dst[i] = in[i - len] * d_window[i - len]; + } + } else { + for (unsigned int i = 0; i < d_fft_size; i++) // apply window + dst[i] = in[i] * d_window[i]; + } + + } else { + gr_complex* dst = d_fft.get_inbuf(); + if (d_shift) { + unsigned int len = + (unsigned int)(floor(d_fft_size / 2.0)); // half length of complex array + for (unsigned int i = 0; i < len; i++) { + dst[i] = in[len + i]; + } + for (unsigned int i = len; i < d_fft_size; i++) { + dst[i] = in[i - len]; + } + } else { + for (unsigned int i = 0; i < d_fft_size; i++) // float to complex conversion + dst[i] = in[i]; + } + } + + // compute the fft + d_fft.execute(); + + // copy result to output stream + memcpy(out, d_fft.get_outbuf(), sizeof(gr_complex) * d_fft_size); +} + +template <class T, bool forward> +int fft_v_fftw<T, forward>::work(int noutput_items, + gr_vector_const_void_star& input_items, + gr_vector_void_star& output_items) +{ + auto in = reinterpret_cast<const T*>(input_items[0]); + auto out = reinterpret_cast<gr_complex*>(output_items[0]); + + int count = 0; + + while (count++ < noutput_items) { + + fft_and_shift(in, out); + + in += d_fft_size; + out += d_fft_size; + } + + return noutput_items; +} + +template class fft_v<gr_complex, true>; +template class fft_v<gr_complex, false>; +template class fft_v<float, true>; +template class fft_v<float, false>; +} /* namespace fft */ +} /* namespace gr */ diff --git a/gr-fft/lib/fft_vcc_fftw.h b/gr-fft/lib/fft_v_fftw.h index 54ed49337f..95f17c58c1 100644 --- a/gr-fft/lib/fft_vcc_fftw.h +++ b/gr-fft/lib/fft_v_fftw.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2007,2008,2012 Free Software Foundation, Inc. + * Copyright 2004,2007,2008,2012,2020 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -8,30 +8,32 @@ * */ -#ifndef INCLUDED_FFT_FFT_VCC_FFTW_IMPL_H -#define INCLUDED_FFT_FFT_VCC_FFTW_IMPL_H +#ifndef INCLUDED_FFT_FFT_V_FFTW_IMPL_H +#define INCLUDED_FFT_FFT_V_FFTW_IMPL_H #include <gnuradio/fft/fft.h> -#include <gnuradio/fft/fft_vcc.h> +#include <gnuradio/fft/fft_v.h> namespace gr { namespace fft { -class FFT_API fft_vcc_fftw : public fft_vcc +template <class T, bool forward> +class FFT_API fft_v_fftw : public fft_v<T, forward> { private: const unsigned int d_fft_size; - const bool d_forward; - fft_complex d_fft; + fft<gr_complex, forward> d_fft; std::vector<float> d_window; const bool d_shift; + void fft_and_shift(const T* in, gr_complex* out); public: - fft_vcc_fftw(int fft_size, - bool forward, - const std::vector<float>& window, - bool shift, - int nthreads = 1); + fft_v_fftw(int fft_size, + const std::vector<float>& window, + bool shift, + int nthreads = 1); + + ~fft_v_fftw() {} void set_nthreads(int n) override; int nthreads() const override; @@ -45,4 +47,4 @@ public: } /* namespace fft */ } /* namespace gr */ -#endif /* INCLUDED_FFT_FFT_VCC_FFTW_IMPL_H */ +#endif /* INCLUDED_FFT_FFT_V_FFTW_IMPL_H */ diff --git a/gr-fft/lib/fft_vcc_fftw.cc b/gr-fft/lib/fft_vcc_fftw.cc deleted file mode 100644 index 076d7a63fd..0000000000 --- a/gr-fft/lib/fft_vcc_fftw.cc +++ /dev/null @@ -1,125 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2007,2008,2010,2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "fft_vcc_fftw.h" -#include <math.h> -#include <string.h> -#include <volk/volk.h> - -namespace gr { -namespace fft { - -fft_vcc::sptr fft_vcc::make(int fft_size, - bool forward, - const std::vector<float>& window, - bool shift, - int nthreads) -{ - return gnuradio::make_block_sptr<fft_vcc_fftw>( - fft_size, forward, window, shift, nthreads); -} - -fft_vcc_fftw::fft_vcc_fftw(int fft_size, - bool forward, - const std::vector<float>& window, - bool shift, - int nthreads) - : sync_block("fft_vcc_fftw", - io_signature::make(1, 1, fft_size * sizeof(gr_complex)), - io_signature::make(1, 1, fft_size * sizeof(gr_complex))), - d_fft_size(fft_size), - d_forward(forward), - d_fft(fft_size, forward, nthreads), - d_shift(shift) -{ - if (!set_window(window)) - throw std::runtime_error("fft_vcc: window not the same length as fft_size"); -} - -void fft_vcc_fftw::set_nthreads(int n) { d_fft.set_nthreads(n); } - -int fft_vcc_fftw::nthreads() const { return d_fft.nthreads(); } - -bool fft_vcc_fftw::set_window(const std::vector<float>& window) -{ - if (window.empty() || window.size() == d_fft_size) { - d_window = window; - return true; - } else - return false; -} - -int fft_vcc_fftw::work(int noutput_items, - gr_vector_const_void_star& input_items, - gr_vector_void_star& output_items) -{ - const gr_complex* in = (const gr_complex*)input_items[0]; - gr_complex* out = (gr_complex*)output_items[0]; - - unsigned int input_data_size = input_signature()->sizeof_stream_item(0); - unsigned int output_data_size = output_signature()->sizeof_stream_item(0); - - int count = 0; - - while (count++ < noutput_items) { - - // copy input into optimally aligned buffer - if (!d_window.empty()) { - gr_complex* dst = d_fft.get_inbuf(); - if (!d_forward && d_shift) { - unsigned int offset = d_fft_size / 2; - int fft_m_offset = d_fft_size - offset; - volk_32fc_32f_multiply_32fc( - &dst[fft_m_offset], &in[0], &d_window[0], offset); - volk_32fc_32f_multiply_32fc( - &dst[0], &in[offset], &d_window[offset], d_fft_size - offset); - } else { - volk_32fc_32f_multiply_32fc(&dst[0], in, &d_window[0], d_fft_size); - } - } else { - if (!d_forward && d_shift) { // apply an ifft shift on the data - gr_complex* dst = d_fft.get_inbuf(); - unsigned int len = (unsigned int)(floor( - d_fft_size / 2.0)); // half length of complex array - memcpy(&dst[0], &in[len], sizeof(gr_complex) * (d_fft_size - len)); - memcpy(&dst[d_fft_size - len], &in[0], sizeof(gr_complex) * len); - } else { - memcpy(d_fft.get_inbuf(), in, input_data_size); - } - } - - // compute the fft - d_fft.execute(); - - // copy result to our output - if (d_forward && d_shift) { // apply a fft shift on the data - unsigned int len = (unsigned int)(ceil(d_fft_size / 2.0)); - memcpy(&out[0], - &d_fft.get_outbuf()[len], - sizeof(gr_complex) * (d_fft_size - len)); - memcpy( - &out[d_fft_size - len], &d_fft.get_outbuf()[0], sizeof(gr_complex) * len); - } else { - memcpy(out, d_fft.get_outbuf(), output_data_size); - } - - in += d_fft_size; - out += d_fft_size; - } - - return noutput_items; -} - -} /* namespace fft */ -} /* namespace gr */ diff --git a/gr-fft/lib/fft_vfc_fftw.cc b/gr-fft/lib/fft_vfc_fftw.cc deleted file mode 100644 index 77d5d9caf2..0000000000 --- a/gr-fft/lib/fft_vfc_fftw.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2007,2008,2010,2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "fft_vfc_fftw.h" -#include <gnuradio/io_signature.h> -#include <math.h> -#include <string.h> - -namespace gr { -namespace fft { - -fft_vfc::sptr -fft_vfc::make(int fft_size, bool forward, const std::vector<float>& window, int nthreads) -{ - return gnuradio::make_block_sptr<fft_vfc_fftw>(fft_size, forward, window, nthreads); -} - -fft_vfc_fftw::fft_vfc_fftw(int fft_size, - bool forward, - const std::vector<float>& window, - int nthreads) - : sync_block("fft_vfc_fftw", - io_signature::make(1, 1, fft_size * sizeof(float)), - io_signature::make(1, 1, fft_size * sizeof(gr_complex))), - d_fft_size(fft_size), - d_fft(fft_size, forward, nthreads) -{ - if (!set_window(window)) - throw std::runtime_error("fft_vfc: window not the same length as fft_size"); -} - -void fft_vfc_fftw::set_nthreads(int n) { d_fft.set_nthreads(n); } - -int fft_vfc_fftw::nthreads() const { return d_fft.nthreads(); } - -bool fft_vfc_fftw::set_window(const std::vector<float>& window) -{ - if (window.empty() || window.size() == d_fft_size) { - d_window = window; - return true; - } else - return false; -} - -int fft_vfc_fftw::work(int noutput_items, - gr_vector_const_void_star& input_items, - gr_vector_void_star& output_items) -{ - const float* in = (const float*)input_items[0]; - gr_complex* out = (gr_complex*)output_items[0]; - - unsigned int output_data_size = output_signature()->sizeof_stream_item(0); - - int count = 0; - - while (count++ < noutput_items) { - - // copy input into optimally aligned buffer - if (!d_window.empty()) { - gr_complex* dst = d_fft.get_inbuf(); - for (unsigned int i = 0; i < d_fft_size; i++) // apply window - dst[i] = in[i] * d_window[i]; - } else { - gr_complex* dst = d_fft.get_inbuf(); - for (unsigned int i = 0; i < d_fft_size; i++) // float to complex conversion - dst[i] = in[i]; - } - - // compute the fft - d_fft.execute(); - - // copy result to output stream - memcpy(out, d_fft.get_outbuf(), output_data_size); - - in += d_fft_size; - out += d_fft_size; - } - - return noutput_items; -} - -} /* namespace fft */ -} /* namespace gr */ diff --git a/gr-fft/lib/fft_vfc_fftw.h b/gr-fft/lib/fft_vfc_fftw.h deleted file mode 100644 index f641a80808..0000000000 --- a/gr-fft/lib/fft_vfc_fftw.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2007,2008,2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#ifndef INCLUDED_FFT_FFT_VFC_FFTW_IMPL_H -#define INCLUDED_FFT_FFT_VFC_FFTW_IMPL_H - -#include <gnuradio/fft/fft.h> -#include <gnuradio/fft/fft_vfc.h> - -namespace gr { -namespace fft { - -class FFT_API fft_vfc_fftw : public fft_vfc -{ -private: - const unsigned int d_fft_size; - fft_complex d_fft; - std::vector<float> d_window; - -public: - fft_vfc_fftw(int fft_size, - bool forward, - const std::vector<float>& window, - int nthreads = 1); - - void set_nthreads(int n) override; - int nthreads() const override; - bool set_window(const std::vector<float>& window) override; - - int work(int noutput_items, - gr_vector_const_void_star& input_items, - gr_vector_void_star& output_items) override; -}; - -} /* namespace fft */ -} /* namespace gr */ - -#endif /* INCLUDED_FFT_FFT_VFC_FFTW_IMPL_H */ |