summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/lib/general
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-core/src/lib/general')
-rw-r--r--gnuradio-core/src/lib/general/gr_burst_tagger.cc38
-rw-r--r--gnuradio-core/src/lib/general/gr_burst_tagger.h11
-rw-r--r--gnuradio-core/src/lib/general/gr_burst_tagger.i4
-rw-r--r--gnuradio-core/src/lib/general/gr_delay.cc89
-rw-r--r--gnuradio-core/src/lib/general/gr_delay.h20
-rw-r--r--gnuradio-core/src/lib/general/gr_delay.i2
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vcc.cc22
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vcc.h13
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vcc.i12
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc27
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h15
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vfc.cc27
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vfc.h17
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vfc.i12
-rw-r--r--gnuradio-core/src/lib/general/gri_fft.cc70
-rw-r--r--gnuradio-core/src/lib/general/gri_fft.h39
16 files changed, 353 insertions, 65 deletions
diff --git a/gnuradio-core/src/lib/general/gr_burst_tagger.cc b/gnuradio-core/src/lib/general/gr_burst_tagger.cc
index 4b3847b08..bd713d663 100644
--- a/gnuradio-core/src/lib/general/gr_burst_tagger.cc
+++ b/gnuradio-core/src/lib/general/gr_burst_tagger.cc
@@ -43,10 +43,39 @@ gr_burst_tagger::gr_burst_tagger(size_t itemsize)
std::stringstream str;
str << name() << unique_id();
- d_key = pmt::pmt_string_to_symbol("burst");
+ d_true_key = pmt::pmt_string_to_symbol("burst");
+ d_true_value = pmt::PMT_T;
+
+ d_false_key = pmt::pmt_string_to_symbol("burst");
+ d_false_value = pmt::PMT_F;
+
d_id = pmt::pmt_string_to_symbol(str.str());
}
+void
+gr_burst_tagger::set_true_tag (const std::string &key, bool value)
+{
+ d_true_key = pmt::pmt_string_to_symbol(key);
+ if(value == true) {
+ d_true_value = pmt::PMT_T;
+ }
+ else {
+ d_true_value = pmt::PMT_F;
+ }
+}
+
+void
+gr_burst_tagger::set_false_tag (const std::string &key, bool value)
+{
+ d_false_key = pmt::pmt_string_to_symbol(key);
+ if(value == true) {
+ d_false_value = pmt::PMT_T;
+ }
+ else {
+ d_false_value = pmt::PMT_F;
+ }
+}
+
gr_burst_tagger::~gr_burst_tagger()
{
}
@@ -66,18 +95,15 @@ gr_burst_tagger::work(int noutput_items,
if(trigger[i] > 0) {
if(d_state == false) {
d_state = true;
- pmt::pmt_t value = pmt::PMT_T;
- add_item_tag(0, nitems_written(0)+i, d_key, value, d_id);
+ add_item_tag(0, nitems_written(0)+i, d_true_key, d_true_value, d_id);
}
}
else {
if(d_state == true) {
d_state = false;
- pmt::pmt_t value = pmt::PMT_F;
- add_item_tag(0, nitems_written(0)+i, d_key, value, d_id);
+ add_item_tag(0, nitems_written(0)+i, d_false_key, d_false_value, d_id);
}
}
}
-
return noutput_items;
}
diff --git a/gnuradio-core/src/lib/general/gr_burst_tagger.h b/gnuradio-core/src/lib/general/gr_burst_tagger.h
index 7547ba9cc..663a146f2 100644
--- a/gnuradio-core/src/lib/general/gr_burst_tagger.h
+++ b/gnuradio-core/src/lib/general/gr_burst_tagger.h
@@ -40,14 +40,21 @@ class GR_CORE_API gr_burst_tagger : public gr_sync_block
{
size_t d_itemsize;
bool d_state;
- pmt::pmt_t d_key;
+ pmt::pmt_t d_true_key;
+ pmt::pmt_t d_true_value;
+
+ pmt::pmt_t d_false_key;
+ pmt::pmt_t d_false_value;
+
pmt::pmt_t d_id;
-
+
friend GR_CORE_API gr_burst_tagger_sptr gr_make_burst_tagger(size_t itemsize);
gr_burst_tagger(size_t itemsize);
public:
~gr_burst_tagger();
+ void set_true_tag (const std::string &key, bool value);
+ void set_false_tag (const std::string &key, bool value);
int work(int noutput_items,
gr_vector_const_void_star &input_items,
diff --git a/gnuradio-core/src/lib/general/gr_burst_tagger.i b/gnuradio-core/src/lib/general/gr_burst_tagger.i
index ebf1eea8c..868941fc6 100644
--- a/gnuradio-core/src/lib/general/gr_burst_tagger.i
+++ b/gnuradio-core/src/lib/general/gr_burst_tagger.i
@@ -28,4 +28,8 @@ class gr_burst_tagger : public gr_sync_block
{
private:
gr_burst_tagger(size_t itemsize);
+
+ public:
+ void set_true_tag(const std::string &key, bool value);
+ void set_false_tag(const std::string &key, bool value);
};
diff --git a/gnuradio-core/src/lib/general/gr_delay.cc b/gnuradio-core/src/lib/general/gr_delay.cc
index b06346f59..aedd461f8 100644
--- a/gnuradio-core/src/lib/general/gr_delay.cc
+++ b/gnuradio-core/src/lib/general/gr_delay.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2007,2010 Free Software Foundation, Inc.
+ * Copyright 2007,2010,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -35,30 +35,95 @@ gr_make_delay (size_t itemsize, int delay)
}
gr_delay::gr_delay (size_t itemsize, int delay)
- : gr_sync_block ("delay",
- gr_make_io_signature (1, -1, itemsize),
- gr_make_io_signature (1, -1, itemsize)),
+ : gr_block ("delay",
+ gr_make_io_signature (1, -1, itemsize),
+ gr_make_io_signature (1, -1, itemsize)),
d_itemsize(itemsize)
{
set_delay(delay);
+ d_delta = 0;
+}
+
+void
+gr_delay::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ // make sure all inputs have noutput_items available
+ unsigned ninputs = ninput_items_required.size ();
+ for (unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = noutput_items;
+}
+
+void
+gr_delay::set_delay (int d)
+{
+ // only set a new delta if there is a change in the delay; this
+ // protects from quickly-repeated calls to this function that would
+ // end with d_delta=0.
+ if(d != delay()) {
+ gruel::scoped_lock l(d_mutex_delay);
+ int old = delay();
+ set_history(d+1);
+ d_delta += delay() - old;
+ }
}
int
-gr_delay::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
+gr_delay::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
{
+ gruel::scoped_lock l(d_mutex_delay);
assert(input_items.size() == output_items.size());
const char *iptr;
char *optr;
+ int cons, ret;
- for(size_t i = 0; i < input_items.size(); i++) {
- iptr = (const char *) input_items[i];
- optr = (char *) output_items[i];
+ // No change in delay; just memcpy ins to outs
+ if(d_delta == 0) {
+ for(size_t i = 0; i < input_items.size(); i++) {
+ iptr = (const char *) input_items[i];
+ optr = (char *) output_items[i];
+ std::memcpy(optr, iptr, noutput_items*d_itemsize);
+ }
+ cons = noutput_items;
+ ret = noutput_items;
+ }
- memcpy(optr, iptr, noutput_items*d_itemsize);
+ // Skip over d_delta items on the input
+ else if(d_delta < 0) {
+ int n_to_copy, n_adj;
+ int delta = -d_delta;
+ n_to_copy = std::max(0, noutput_items-delta);
+ n_adj = std::min(delta, noutput_items);
+ for(size_t i = 0; i < input_items.size(); i++) {
+ iptr = (const char *) input_items[i];
+ optr = (char *) output_items[i];
+ std::memcpy(optr, iptr+delta*d_itemsize, n_to_copy*d_itemsize);
+ }
+ cons = noutput_items;
+ ret = n_to_copy;
+ delta -= n_adj;
+ d_delta = -delta;
}
- return noutput_items;
+ //produce but not consume (inserts zeros)
+ else { // d_delta > 0
+ int n_from_input, n_padding;
+ n_from_input = std::max(0, noutput_items-d_delta);
+ n_padding = std::min(d_delta, noutput_items);
+ for(size_t i = 0; i < input_items.size(); i++) {
+ iptr = (const char *) input_items[i];
+ optr = (char *) output_items[i];
+ std::memset(optr, 0, n_padding*d_itemsize);
+ std::memcpy(optr, iptr, n_from_input*d_itemsize);
+ }
+ cons = n_from_input;
+ ret = noutput_items;
+ d_delta -= n_padding;
+ }
+
+ consume_each(cons);
+ return ret;
}
diff --git a/gnuradio-core/src/lib/general/gr_delay.h b/gnuradio-core/src/lib/general/gr_delay.h
index 14de9af1f..55f525c38 100644
--- a/gnuradio-core/src/lib/general/gr_delay.h
+++ b/gnuradio-core/src/lib/general/gr_delay.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2007 Free Software Foundation, Inc.
+ * Copyright 2007,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -24,7 +24,8 @@
#define INCLUDED_GR_DELAY_H
#include <gr_core_api.h>
-#include <gr_sync_block.h>
+#include <gr_block.h>
+#include <gruel/thread.h>
class gr_delay;
typedef boost::shared_ptr<gr_delay> gr_delay_sptr;
@@ -35,21 +36,26 @@ GR_CORE_API gr_delay_sptr gr_make_delay (size_t itemsize, int delay);
* \brief delay the input by a certain number of samples
* \ingroup misc_blk
*/
-class GR_CORE_API gr_delay : public gr_sync_block
+class GR_CORE_API gr_delay : public gr_block
{
friend GR_CORE_API gr_delay_sptr gr_make_delay (size_t itemsize, int delay);
gr_delay (size_t itemsize, int delay);
+ void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
size_t d_itemsize;
+ int d_delta;
+ gruel::mutex d_mutex_delay;
public:
int delay () const { return history()-1; }
- void set_delay (int delay) { set_history(delay+1); }
+ void set_delay (int delay);
- int work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
};
#endif
diff --git a/gnuradio-core/src/lib/general/gr_delay.i b/gnuradio-core/src/lib/general/gr_delay.i
index a527d008f..2e62a222f 100644
--- a/gnuradio-core/src/lib/general/gr_delay.i
+++ b/gnuradio-core/src/lib/general/gr_delay.i
@@ -24,7 +24,7 @@ GR_SWIG_BLOCK_MAGIC(gr,delay)
gr_delay_sptr gr_make_delay (size_t itemsize, int delay);
-class gr_delay : public gr_sync_block
+class gr_delay : public gr_block
{
private:
gr_delay (size_t itemsize, int delay);
diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.cc b/gnuradio-core/src/lib/general/gr_fft_vcc.cc
index d07f6fa07..f744acb93 100644
--- a/gnuradio-core/src/lib/general/gr_fft_vcc.cc
+++ b/gnuradio-core/src/lib/general/gr_fft_vcc.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2007,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2007,2008,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -32,9 +32,12 @@
#include <string.h>
gr_fft_vcc_sptr
-gr_make_fft_vcc (int fft_size, bool forward,const std::vector<float> &window, bool shift)
+gr_make_fft_vcc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift, int nthreads)
{
- return gr_make_fft_vcc_fftw(fft_size, forward, window, shift);
+ return gr_make_fft_vcc_fftw(fft_size, forward,
+ window, shift, nthreads);
}
gr_fft_vcc::gr_fft_vcc (const std::string &name,
@@ -62,3 +65,16 @@ gr_fft_vcc::set_window(const std::vector<float> &window)
else
return false;
}
+
+void
+gr_fft_vcc::set_nthreads(int n)
+{
+ throw std::runtime_error("gr_fft_vcc::set_nthreads not implemented.");
+}
+
+int
+gr_fft_vcc::nthreads() const
+{
+ throw std::runtime_error("gr_fft_vcc::nthreads not implemented.");
+ return 0;
+}
diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.h b/gnuradio-core/src/lib/general/gr_fft_vcc.h
index a7c8e1162..ceabeb681 100644
--- a/gnuradio-core/src/lib/general/gr_fft_vcc.h
+++ b/gnuradio-core/src/lib/general/gr_fft_vcc.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2007,2008 Free Software Foundation, Inc.
+ * Copyright 2004,2007,2008,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -30,7 +30,9 @@ class gr_fft_vcc;
typedef boost::shared_ptr<gr_fft_vcc> gr_fft_vcc_sptr;
GR_CORE_API gr_fft_vcc_sptr
-gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift=false);
+gr_make_fft_vcc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift=false, int nthreads=1);
/*!
* \brief Compute forward or reverse FFT. complex vector in / complex vector out.
@@ -42,7 +44,9 @@ class GR_CORE_API gr_fft_vcc : public gr_sync_block
{
protected:
friend GR_CORE_API gr_fft_vcc_sptr
- gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift);
+ gr_make_fft_vcc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift);
unsigned int d_fft_size;
std::vector<float> d_window;
@@ -55,6 +59,9 @@ protected:
public:
~gr_fft_vcc ();
+ virtual void set_nthreads(int n);
+ virtual int nthreads() const;
+
bool set_window(const std::vector<float> &window);
};
diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.i b/gnuradio-core/src/lib/general/gr_fft_vcc.i
index f35316e70..26d8b89a3 100644
--- a/gnuradio-core/src/lib/general/gr_fft_vcc.i
+++ b/gnuradio-core/src/lib/general/gr_fft_vcc.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2007,2008,2010 Free Software Foundation, Inc.
+ * Copyright 2004,2007,2008,2010,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -23,13 +23,19 @@
GR_SWIG_BLOCK_MAGIC(gr, fft_vcc)
gr_fft_vcc_sptr
-gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift=false);
+gr_make_fft_vcc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift=false, int nthreads=1);
class gr_fft_vcc : public gr_sync_block
{
protected:
- gr_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift);
+ gr_fft_vcc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift);
public:
bool set_window(const std::vector<float> &window);
+ void set_nthreads(int n);
+ int nthreads() const;
};
diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc
index 8a6b2fe8a..a99beb965 100644
--- a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc
+++ b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc
@@ -31,16 +31,21 @@
#include <string.h>
gr_fft_vcc_sptr
-gr_make_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &window, bool shift)
+gr_make_fft_vcc_fftw (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift, int nthreads)
{
- return gnuradio::get_initial_sptr(new gr_fft_vcc_fftw (fft_size, forward, window, shift));
+ return gnuradio::get_initial_sptr(new gr_fft_vcc_fftw
+ (fft_size, forward, window,
+ shift, nthreads));
}
gr_fft_vcc_fftw::gr_fft_vcc_fftw (int fft_size, bool forward,
- const std::vector<float> &window, bool shift)
+ const std::vector<float> &window,
+ bool shift, int nthreads)
: gr_fft_vcc("fft_vcc_fftw", fft_size, forward, window, shift)
{
- d_fft = new gri_fft_complex (d_fft_size, forward);
+ d_fft = new gri_fft_complex (d_fft_size, forward, nthreads);
}
gr_fft_vcc_fftw::~gr_fft_vcc_fftw ()
@@ -48,6 +53,18 @@ gr_fft_vcc_fftw::~gr_fft_vcc_fftw ()
delete d_fft;
}
+void
+gr_fft_vcc_fftw::set_nthreads(int n)
+{
+ d_fft->set_nthreads(n);
+}
+
+int
+gr_fft_vcc_fftw::nthreads() const
+{
+ return d_fft->nthreads();
+}
+
int
gr_fft_vcc_fftw::work (int noutput_items,
gr_vector_const_void_star &input_items,
@@ -70,7 +87,7 @@ gr_fft_vcc_fftw::work (int noutput_items,
if(!d_forward && d_shift){
unsigned int offset = (!d_forward && d_shift)?(d_fft_size/2):0;
int fft_m_offset = d_fft_size - offset;
- for (unsigned int i = 0; i < offset; i++) // apply window
+ for (int i = 0; i < offset; i++) // apply window
dst[i+fft_m_offset] = in[i] * d_window[i];
for (unsigned int i = offset; i < d_fft_size; i++) // apply window
dst[i-offset] = in[i] * d_window[i];
diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h
index 8535d133c..82b7512d7 100644
--- a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h
+++ b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h
@@ -29,7 +29,9 @@
class gri_fft_complex;
GR_CORE_API gr_fft_vcc_sptr
-gr_make_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &window, bool shift=false);
+gr_make_fft_vcc_fftw (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift=false, int nthreads=1);
/*!
* \brief Compute forward or reverse FFT. complex vector in / complex vector out.
@@ -40,15 +42,22 @@ gr_make_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &wind
class GR_CORE_API gr_fft_vcc_fftw : public gr_fft_vcc
{
friend GR_CORE_API gr_fft_vcc_sptr
- gr_make_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &window, bool shift);
+ gr_make_fft_vcc_fftw (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift, int nthreads);
gri_fft_complex *d_fft;
- gr_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &window, bool shift);
+ gr_fft_vcc_fftw (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift, int nthreads=1);
public:
~gr_fft_vcc_fftw ();
+ void set_nthreads(int n);
+ int nthreads() const;
+
int work (int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
diff --git a/gnuradio-core/src/lib/general/gr_fft_vfc.cc b/gnuradio-core/src/lib/general/gr_fft_vfc.cc
index 561c63740..5fbe732dc 100644
--- a/gnuradio-core/src/lib/general/gr_fft_vfc.cc
+++ b/gnuradio-core/src/lib/general/gr_fft_vfc.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2010 Free Software Foundation, Inc.
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -40,12 +40,17 @@
gr_fft_vfc_sptr
-gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> &window)
+gr_make_fft_vfc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads)
{
- return gnuradio::get_initial_sptr(new gr_fft_vfc (fft_size, forward, window));
+ return gnuradio::get_initial_sptr(new gr_fft_vfc (fft_size, forward,
+ window, nthreads));
}
-gr_fft_vfc::gr_fft_vfc (int fft_size, bool forward, const std::vector<float> &window)
+gr_fft_vfc::gr_fft_vfc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads)
: gr_sync_block ("fft_vfc",
gr_make_io_signature (1, 1, fft_size * sizeof (float)),
gr_make_io_signature (1, 1, fft_size * sizeof (gr_complex))),
@@ -56,7 +61,7 @@ gr_fft_vfc::gr_fft_vfc (int fft_size, bool forward, const std::vector<float> &wi
throw std::invalid_argument ("fft_vfc: forward must == true");
}
- d_fft = new gri_fft_complex (d_fft_size, forward);
+ d_fft = new gri_fft_complex (d_fft_size, forward, nthreads);
set_window(window);
}
@@ -66,6 +71,18 @@ gr_fft_vfc::~gr_fft_vfc ()
delete d_fft;
}
+void
+gr_fft_vfc::set_nthreads(int n)
+{
+ d_fft->set_nthreads(n);
+}
+
+int
+gr_fft_vfc::nthreads() const
+{
+ return d_fft->nthreads();
+}
+
int
gr_fft_vfc::work (int noutput_items,
gr_vector_const_void_star &input_items,
diff --git a/gnuradio-core/src/lib/general/gr_fft_vfc.h b/gnuradio-core/src/lib/general/gr_fft_vfc.h
index 6cf6b9037..84ae08f08 100644
--- a/gnuradio-core/src/lib/general/gr_fft_vfc.h
+++ b/gnuradio-core/src/lib/general/gr_fft_vfc.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2010 Free Software Foundation, Inc.
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -32,7 +32,9 @@ class gr_fft_vfc;
typedef boost::shared_ptr<gr_fft_vfc> gr_fft_vfc_sptr;
GR_CORE_API gr_fft_vfc_sptr
-gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> &window);
+gr_make_fft_vfc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads=1);
/*!
* \brief Compute forward FFT. float vector in / complex vector out.
@@ -42,17 +44,24 @@ gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> &window);
class GR_CORE_API gr_fft_vfc : public gr_sync_block
{
friend GR_CORE_API gr_fft_vfc_sptr
- gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> &window);
+ gr_make_fft_vfc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads);
unsigned int d_fft_size;
std::vector<float> d_window;
gri_fft_complex *d_fft;
- gr_fft_vfc (int fft_size, bool forward, const std::vector<float> &window);
+ gr_fft_vfc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads=1);
public:
~gr_fft_vfc ();
+ void set_nthreads(int n);
+ int nthreads() const;
+
int work (int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
diff --git a/gnuradio-core/src/lib/general/gr_fft_vfc.i b/gnuradio-core/src/lib/general/gr_fft_vfc.i
index 149745b58..4783ae1fe 100644
--- a/gnuradio-core/src/lib/general/gr_fft_vfc.i
+++ b/gnuradio-core/src/lib/general/gr_fft_vfc.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2010 Free Software Foundation, Inc.
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -23,14 +23,20 @@
GR_SWIG_BLOCK_MAGIC(gr, fft_vfc)
gr_fft_vfc_sptr
-gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> &window)
+gr_make_fft_vfc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads=1)
throw(std::exception);
class gr_fft_vfc : public gr_sync_block
{
protected:
- gr_fft_vfc (int fft_size, bool forward, const std::vector<float> &window);
+ gr_fft_vfc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads=1);
public:
bool set_window(const std::vector<float> &window);
+ void set_nthreads(int n);
+ int nthreads() const;
};
diff --git a/gnuradio-core/src/lib/general/gri_fft.cc b/gnuradio-core/src/lib/general/gri_fft.cc
index 0df1af25d..63e307776 100644
--- a/gnuradio-core/src/lib/general/gri_fft.cc
+++ b/gnuradio-core/src/lib/general/gri_fft.cc
@@ -78,6 +78,22 @@ gri_fftw_import_wisdom ()
}
static void
+gri_fftw_config_threading (int nthreads)
+{
+ static int fftw_threads_inited = 0;
+
+#ifdef FFTW3F_THREADS
+ if (fftw_threads_inited == 0)
+ {
+ fftw_threads_inited = 1;
+ fftwf_init_threads();
+ }
+
+ fftwf_plan_with_nthreads(nthreads);
+#endif
+}
+
+static void
gri_fftw_export_wisdom ()
{
const char *filename = wisdom_filename ();
@@ -94,7 +110,7 @@ gri_fftw_export_wisdom ()
// ----------------------------------------------------------------
-gri_fft_complex::gri_fft_complex (int fft_size, bool forward)
+gri_fft_complex::gri_fft_complex (int fft_size, bool forward, int nthreads)
{
// Hold global mutex during plan construction and destruction.
gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex());
@@ -115,7 +131,10 @@ gri_fft_complex::gri_fft_complex (int fft_size, bool forward)
throw std::runtime_error ("fftwf_malloc");
}
+ d_nthreads = nthreads;
+ gri_fftw_config_threading (nthreads);
gri_fftw_import_wisdom (); // load prior wisdom from disk
+
d_plan = fftwf_plan_dft_1d (fft_size,
reinterpret_cast<fftwf_complex *>(d_inbuf),
reinterpret_cast<fftwf_complex *>(d_outbuf),
@@ -139,6 +158,18 @@ gri_fft_complex::~gri_fft_complex ()
fftwf_free (d_outbuf);
}
+void
+gri_fft_complex::set_nthreads(int n)
+{
+ if (n <= 0)
+ throw std::out_of_range ("gri_fftw: invalid number of threads");
+ d_nthreads = n;
+
+#ifdef FFTW3F_THREADS
+ fftwf_plan_with_nthreads(d_nthreads);
+#endif
+}
+
void
gri_fft_complex::execute ()
{
@@ -147,7 +178,7 @@ gri_fft_complex::execute ()
// ----------------------------------------------------------------
-gri_fft_real_fwd::gri_fft_real_fwd (int fft_size)
+gri_fft_real_fwd::gri_fft_real_fwd (int fft_size, int nthreads)
{
// Hold global mutex during plan construction and destruction.
gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex());
@@ -168,7 +199,10 @@ gri_fft_real_fwd::gri_fft_real_fwd (int fft_size)
throw std::runtime_error ("fftwf_malloc");
}
+ d_nthreads = nthreads;
+ gri_fftw_config_threading (nthreads);
gri_fftw_import_wisdom (); // load prior wisdom from disk
+
d_plan = fftwf_plan_dft_r2c_1d (fft_size,
d_inbuf,
reinterpret_cast<fftwf_complex *>(d_outbuf),
@@ -191,6 +225,18 @@ gri_fft_real_fwd::~gri_fft_real_fwd ()
fftwf_free (d_outbuf);
}
+void
+gri_fft_real_fwd::set_nthreads(int n)
+{
+ if (n <= 0)
+ throw std::out_of_range ("gri_fftw: invalid number of threads");
+ d_nthreads = n;
+
+#ifdef FFTW3F_THREADS
+ fftwf_plan_with_nthreads(d_nthreads);
+#endif
+}
+
void
gri_fft_real_fwd::execute ()
{
@@ -199,7 +245,7 @@ gri_fft_real_fwd::execute ()
// ----------------------------------------------------------------
-gri_fft_real_rev::gri_fft_real_rev (int fft_size)
+gri_fft_real_rev::gri_fft_real_rev (int fft_size, int nthreads)
{
// Hold global mutex during plan construction and destruction.
gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex());
@@ -220,11 +266,13 @@ gri_fft_real_rev::gri_fft_real_rev (int fft_size)
throw std::runtime_error ("fftwf_malloc");
}
+ d_nthreads = nthreads;
+ gri_fftw_config_threading (nthreads);
+ gri_fftw_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.
-
- gri_fftw_import_wisdom (); // load prior wisdom from disk
d_plan = fftwf_plan_dft_c2r_1d (fft_size,
reinterpret_cast<fftwf_complex *>(d_inbuf),
d_outbuf,
@@ -244,6 +292,18 @@ gri_fft_real_rev::~gri_fft_real_rev ()
fftwf_free (d_outbuf);
}
+void
+gri_fft_real_rev::set_nthreads(int n)
+{
+ if (n <= 0)
+ throw std::out_of_range ("gri_fftw: invalid number of threads");
+ d_nthreads = n;
+
+#ifdef FFTW3F_THREADS
+ fftwf_plan_with_nthreads(d_nthreads);
+#endif
+}
+
void
gri_fft_real_rev::execute ()
{
diff --git a/gnuradio-core/src/lib/general/gri_fft.h b/gnuradio-core/src/lib/general/gri_fft.h
index 91a82fb55..ed80badf1 100644
--- a/gnuradio-core/src/lib/general/gri_fft.h
+++ b/gnuradio-core/src/lib/general/gri_fft.h
@@ -49,12 +49,13 @@ public:
*/
class GR_CORE_API gri_fft_complex {
int d_fft_size;
+ int d_nthreads;
gr_complex *d_inbuf;
gr_complex *d_outbuf;
void *d_plan;
public:
- gri_fft_complex (int fft_size, bool forward = true);
+ gri_fft_complex (int fft_size, bool forward = true, int nthreads=1);
virtual ~gri_fft_complex ();
/*
@@ -69,6 +70,16 @@ public:
int outbuf_length () const { return d_fft_size; }
/*!
+ * Set the number of threads to use for caclulation.
+ */
+ 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 ();
@@ -80,12 +91,13 @@ public:
*/
class GR_CORE_API gri_fft_real_fwd {
int d_fft_size;
+ int d_nthreads;
float *d_inbuf;
gr_complex *d_outbuf;
void *d_plan;
public:
- gri_fft_real_fwd (int fft_size);
+ gri_fft_real_fwd (int fft_size, int nthreads=1);
virtual ~gri_fft_real_fwd ();
/*
@@ -100,6 +112,16 @@ public:
int outbuf_length () const { return d_fft_size / 2 + 1; }
/*!
+ * Set the number of threads to use for caclulation.
+ */
+ 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 ();
@@ -111,12 +133,13 @@ public:
*/
class GR_CORE_API gri_fft_real_rev {
int d_fft_size;
+ int d_nthreads;
gr_complex *d_inbuf;
float *d_outbuf;
void *d_plan;
public:
- gri_fft_real_rev (int fft_size);
+ gri_fft_real_rev (int fft_size, int nthreads=1);
virtual ~gri_fft_real_rev ();
/*
@@ -131,6 +154,16 @@ public:
int outbuf_length () const { return d_fft_size; }
/*!
+ * Set the number of threads to use for caclulation.
+ */
+ 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 ();