diff options
Diffstat (limited to 'gnuradio-core/src/lib/general')
-rw-r--r-- | gnuradio-core/src/lib/general/Makefile.am | 3 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/general.i | 2 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_transcendental.cc | 153 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_transcendental.h | 48 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_transcendental.i | 33 |
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> |