summaryrefslogtreecommitdiff
path: root/gr-fft/lib
diff options
context:
space:
mode:
authormormj <34754695+mormj@users.noreply.github.com>2020-11-03 16:51:44 -0500
committerGitHub <noreply@github.com>2020-11-03 16:51:44 -0500
commited95e8d45cfc6cd3e026298dadf4d2e8f9f1c3b8 (patch)
treea15c82b2a2c2baa623434ad2c3a4c51416002082 /gr-fft/lib
parent0f780e26d6545338b6c4a1b34405822a9a6ec706 (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.txt3
-rw-r--r--gr-fft/lib/ctrlport_probe_psd_impl.cc2
-rw-r--r--gr-fft/lib/ctrlport_probe_psd_impl.h2
-rw-r--r--gr-fft/lib/fft.cc149
-rw-r--r--gr-fft/lib/fft_v_fftw.cc217
-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.cc125
-rw-r--r--gr-fft/lib/fft_vfc_fftw.cc94
-rw-r--r--gr-fft/lib/fft_vfc_fftw.h45
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 */