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/Makefile.am3
-rw-r--r--gnuradio-core/src/lib/general/general.i2
-rw-r--r--gnuradio-core/src/lib/general/gr_transcendental.cc153
-rw-r--r--gnuradio-core/src/lib/general/gr_transcendental.h48
-rw-r--r--gnuradio-core/src/lib/general/gr_transcendental.i33
5 files changed, 239 insertions, 0 deletions
diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am
index 5915ff45b..0e52b7b79 100644
--- a/gnuradio-core/src/lib/general/Makefile.am
+++ b/gnuradio-core/src/lib/general/Makefile.am
@@ -139,6 +139,7 @@ libgeneral_la_SOURCES = \
gr_test.cc \
gr_threshold_ff.cc \
gr_throttle.cc \
+ gr_transcendental.cc \
gr_uchar_to_float.cc \
gr_vco_f.cc \
gr_vector_to_stream.cc \
@@ -290,6 +291,7 @@ grinclude_HEADERS = \
gr_test.h \
gr_threshold_ff.h \
gr_throttle.h \
+ gr_transcendental.h \
gr_uchar_to_float.h \
gr_vco.h \
gr_vco_f.h \
@@ -437,6 +439,7 @@ swiginclude_HEADERS = \
gr_test.i \
gr_threshold_ff.i \
gr_throttle.i \
+ gr_transcendental.i \
gr_uchar_to_float.i \
gr_vco_f.i \
gr_vector_to_stream.i \
diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i
index 3e9a01a66..0a3200741 100644
--- a/gnuradio-core/src/lib/general/general.i
+++ b/gnuradio-core/src/lib/general/general.i
@@ -70,6 +70,7 @@
#include <gr_nlog10_ff.h>
#include <gr_fake_channel_coder_pp.h>
#include <gr_throttle.h>
+#include <gr_transcendental.h>
#include <gr_stream_mux.h>
#include <gr_stream_to_streams.h>
#include <gr_streams_to_stream.h>
@@ -182,6 +183,7 @@
%include "gr_nlog10_ff.i"
%include "gr_fake_channel_coder_pp.i"
%include "gr_throttle.i"
+%include "gr_transcendental.i"
%include "gr_stream_mux.i"
%include "gr_stream_to_streams.i"
%include "gr_streams_to_stream.i"
diff --git a/gnuradio-core/src/lib/general/gr_transcendental.cc b/gnuradio-core/src/lib/general/gr_transcendental.cc
new file mode 100644
index 000000000..46dc0055b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_transcendental.cc
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_transcendental.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <complex> //complex math
+#include <cmath> //real math
+#include <map>
+
+/***********************************************************************
+ * work function creation and registration
+ **********************************************************************/
+typedef int(*work_fcn_type)(int, gr_vector_const_void_star &, gr_vector_void_star &);
+struct map_val_type{
+ work_fcn_type work_fcn;
+ size_t io_size;
+};
+typedef std::map<std::string, map_val_type> map_type;
+
+//construct map on first use idiom
+static map_type &get_map(void){
+ static map_type map;
+ return map;
+}
+
+//static initialization of this object registers a function
+struct gr_transcendental_registrant{
+ gr_transcendental_registrant(
+ const std::string &key,
+ const work_fcn_type &work_fcn,
+ const size_t io_size
+ ){
+ map_val_type val;
+ val.work_fcn = work_fcn;
+ val.io_size = io_size;
+ get_map()[key] = val;
+ }
+};
+
+//macro to create a work function and register it
+#define REGISTER_FUNCTION(__fcn__, __type__, __key__) \
+ static int __key__ ## _work( \
+ int noutput_items, \
+ gr_vector_const_void_star &input_items, \
+ gr_vector_void_star &output_items \
+ ){ \
+ const __type__ *in = (const __type__ *) input_items[0]; \
+ __type__ *out = (__type__ *) output_items[0]; \
+ for (size_t i = 0; i < size_t(noutput_items); i++){ \
+ out[i] = std::__fcn__(in[i]); \
+ } \
+ return noutput_items; \
+ } \
+ gr_transcendental_registrant __key__ ## _registrant(#__key__, &__key__ ## _work, sizeof(__type__));
+
+//register work functions for real types
+#define REGISTER_REAL_FUNCTIONS(__fcn__) \
+ REGISTER_FUNCTION(__fcn__, float, __fcn__ ## _float) \
+ REGISTER_FUNCTION(__fcn__, double, __fcn__ ## _double)
+
+//register work functions for complex types
+#define REGISTER_COMPLEX_FUNCTIONS(__fcn__) \
+ REGISTER_FUNCTION(__fcn__, std::complex<float>, __fcn__ ## _complex_float) \
+ REGISTER_FUNCTION(__fcn__, std::complex<double>, __fcn__ ## _complex_double)
+
+//register both complex and real
+#define REGISTER_FUNCTIONS(__fcn__) \
+ REGISTER_REAL_FUNCTIONS(__fcn__) \
+ REGISTER_COMPLEX_FUNCTIONS(__fcn__)
+
+//create and register transcendental work functions
+REGISTER_FUNCTIONS(cos)
+REGISTER_FUNCTIONS(sin)
+REGISTER_FUNCTIONS(tan)
+REGISTER_REAL_FUNCTIONS(acos)
+REGISTER_REAL_FUNCTIONS(asin)
+REGISTER_REAL_FUNCTIONS(atan)
+REGISTER_FUNCTIONS(cosh)
+REGISTER_FUNCTIONS(sinh)
+REGISTER_FUNCTIONS(tanh)
+REGISTER_FUNCTIONS(exp)
+REGISTER_FUNCTIONS(log)
+REGISTER_FUNCTIONS(log10)
+REGISTER_FUNCTIONS(sqrt)
+
+/***********************************************************************
+ * implementation block simply calls into the function pointer
+ **********************************************************************/
+class gr_transcendental_impl : public gr_transcendental{
+public:
+ gr_transcendental_impl(
+ const work_fcn_type &work_fcn, const size_t io_size
+ ):
+ gr_sync_block(
+ "transcendental",
+ gr_make_io_signature(1, 1, io_size),
+ gr_make_io_signature(1, 1, io_size)
+ ),
+ _work_fcn(work_fcn)
+ {
+ // NOP
+ }
+
+ int work(
+ int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items
+ ){
+ return _work_fcn(noutput_items, input_items, output_items);
+ }
+
+private:
+ const work_fcn_type &_work_fcn;
+};
+
+/***********************************************************************
+ * factory function to make transcendental block
+ **********************************************************************/
+gr_transcendental::sptr gr_make_transcendental(
+ const std::string &name,
+ const std::string &type
+){
+ //search for an entry in the map
+ const std::string key = name + "_" + type;
+ const bool has_key = get_map().count(key) != 0;
+ if (!has_key) throw std::runtime_error(
+ "could not find transcendental function for " + key
+ );
+
+ //make a new block with found work function
+ return gr_transcendental::sptr(new gr_transcendental_impl(
+ get_map()[key].work_fcn, get_map()[key].io_size
+ ));
+}
diff --git a/gnuradio-core/src/lib/general/gr_transcendental.h b/gnuradio-core/src/lib/general/gr_transcendental.h
new file mode 100644
index 000000000..1b237c44a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_transcendental.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_TRANSCENDENTAL_H
+#define INCLUDED_GR_TRANSCENDENTAL_H
+
+#include <gr_sync_block.h>
+#include <string>
+
+/*!
+ * \brief A block that performs various transcendental math operations.
+ *
+ * Possible function names can be found in the cmath library.
+ * IO may be either complex or real, double or single precision.
+ *
+ * Possible type strings: float, double, complex_float, complex_double
+ *
+ * output[i] = trans_fcn(input[i])
+ */
+class gr_transcendental : virtual public gr_sync_block{
+public:
+ typedef boost::shared_ptr<gr_transcendental> sptr;
+};
+
+gr_transcendental::sptr gr_make_transcendental(
+ const std::string &name,
+ const std::string &type = "float"
+);
+
+#endif /* INCLUDED_GR_TRANSCENDENTAL_H */
diff --git a/gnuradio-core/src/lib/general/gr_transcendental.i b/gnuradio-core/src/lib/general/gr_transcendental.i
new file mode 100644
index 000000000..1eea73f40
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_transcendental.i
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+////////////////////////////////////////////////////////////////////////
+// block headers
+////////////////////////////////////////////////////////////////////////
+%{
+#include <gr_transcendental.h>
+%}
+
+////////////////////////////////////////////////////////////////////////
+// block magic
+////////////////////////////////////////////////////////////////////////
+GR_SWIG_BLOCK_MAGIC(gr,transcendental)
+%include <gr_transcendental.h>