diff options
-rw-r--r-- | host/lib/convert/CMakeLists.txt | 1 | ||||
-rw-r--r-- | host/lib/convert/convert_common.hpp | 3 | ||||
-rw-r--r-- | host/lib/convert/convert_with_tables.cpp | 139 |
3 files changed, 141 insertions, 2 deletions
diff --git a/host/lib/convert/CMakeLists.txt b/host/lib/convert/CMakeLists.txt index 4cc421884..1fe92d93a 100644 --- a/host/lib/convert/CMakeLists.txt +++ b/host/lib/convert/CMakeLists.txt @@ -117,5 +117,6 @@ LIBUHD_PYTHON_GEN_SOURCE( ) LIBUHD_APPEND_SOURCES( + ${CMAKE_CURRENT_SOURCE_DIR}/convert_with_tables.cpp ${CMAKE_CURRENT_SOURCE_DIR}/convert_impl.cpp ) diff --git a/host/lib/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp index ce82f6216..f963e29ee 100644 --- a/host/lib/convert/convert_common.hpp +++ b/host/lib/convert/convert_common.hpp @@ -21,7 +21,6 @@ #include <uhd/convert.hpp> #include <uhd/utils/static.hpp> #include <boost/cstdint.hpp> -#include <boost/bind.hpp> #include <complex> #define _DECLARE_CONVERTER(name, in_form, num_in, out_form, num_out, prio) \ @@ -37,7 +36,7 @@ id.num_inputs = num_in; \ id.output_format = #out_form; \ id.num_outputs = num_out; \ - uhd::convert::register_converter(id, boost::bind(&name::make), prio); \ + uhd::convert::register_converter(id, &name::make, prio); \ } \ void name::operator()( \ const input_type &inputs, const output_type &outputs, const size_t nsamps \ diff --git a/host/lib/convert/convert_with_tables.cpp b/host/lib/convert/convert_with_tables.cpp new file mode 100644 index 000000000..b3702e6ea --- /dev/null +++ b/host/lib/convert/convert_with_tables.cpp @@ -0,0 +1,139 @@ +// +// Copyright 2011 Ettus Research LLC +// +// This program 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 of the License, or +// (at your option) any later version. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include "convert_common.hpp" +#include <uhd/utils/byteswap.hpp> +#include <vector> + +using namespace uhd::convert; + +static const size_t sc16_table_len = size_t(1 << 16); + +#ifdef BOOST_BIG_ENDIAN +# define ITEM32_BE_TO_R16(x) boost::uint16_t(x >> 16) +# define ITEM32_BE_TO_I16(x) boost::uint16_t(x) +# define ITEM32_LE_TO_R16(x) boost::uint16_t(x) +# define ITEM32_LE_TO_I16(x) boost::uint16_t(x >> 16) +#else +# define ITEM32_BE_TO_R16(x) boost::uint16_t(x) +# define ITEM32_BE_TO_I16(x) boost::uint16_t(x >> 16) +# define ITEM32_LE_TO_R16(x) boost::uint16_t(x >> 16) +# define ITEM32_LE_TO_I16(x) boost::uint16_t(x) +#endif + +/*********************************************************************** + * Implementation for sc16 be lookup table + **********************************************************************/ +template <typename type> class convert_sc16_item32_be_1_to_fcxx_1 : public converter{ +public: + convert_sc16_item32_be_1_to_fcxx_1(void): _table(sc16_table_len){} + + void set_scalar(const double scalar){ + for (size_t i = 0; i < sc16_table_len; i++){ + const boost::int16_t val = uhd::ntohx(boost::uint16_t(i & 0xffff)); + _table[i] = type(val*scalar); + } + } + + void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps){ + const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); + std::complex<type> *output = reinterpret_cast<std::complex<type> *>(outputs[0]); + + for (size_t i = 0; i < nsamps; i++){ + const item32_t item_be = input[i]; + output[i] = std::complex<type>( + _table[ITEM32_BE_TO_R16(item_be)], + _table[ITEM32_BE_TO_I16(item_be)] + ); + } + } + +private: + std::vector<type> _table; +}; + +/*********************************************************************** + * Implementation for sc16 le lookup table + **********************************************************************/ +template <typename type> class convert_sc16_item32_le_1_to_fcxx_1 : public converter{ +public: + convert_sc16_item32_le_1_to_fcxx_1(void): _table(sc16_table_len){} + + void set_scalar(const double scalar){ + for (size_t i = 0; i < sc16_table_len; i++){ + const boost::int16_t val = uhd::wtohx(boost::uint16_t(i & 0xffff)); + _table[i] = type(val*scalar); + } + } + + void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps){ + const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); + std::complex<type> *output = reinterpret_cast<std::complex<type> *>(outputs[0]); + + for (size_t i = 0; i < nsamps; i++){ + const item32_t item_le = input[i]; + output[i] = std::complex<type>( + _table[ITEM32_LE_TO_R16(item_le)], + _table[ITEM32_LE_TO_I16(item_le)] + ); + } + } + +private: + std::vector<type> _table; +}; + +/*********************************************************************** + * Factory functions and registration + **********************************************************************/ +static converter::sptr make_convert_sc16_item32_be_1_to_fc32_1(void){ + return converter::sptr(new convert_sc16_item32_be_1_to_fcxx_1<float>()); +} + +static converter::sptr make_convert_sc16_item32_be_1_to_fc64_1(void){ + return converter::sptr(new convert_sc16_item32_be_1_to_fcxx_1<double>()); +} + +static converter::sptr make_convert_sc16_item32_le_1_to_fc32_1(void){ + return converter::sptr(new convert_sc16_item32_le_1_to_fcxx_1<float>()); +} + +static converter::sptr make_convert_sc16_item32_le_1_to_fc64_1(void){ + return converter::sptr(new convert_sc16_item32_le_1_to_fcxx_1<double>()); +} + +UHD_STATIC_BLOCK(register_convert_sc16_item32_1_to_fcxx_1){ + uhd::convert::id_type id; + id.num_inputs = 1; + id.num_outputs = 1; + + id.output_format = "fc32"; + id.input_format = "sc16_item32_be"; + uhd::convert::register_converter(id, &make_convert_sc16_item32_be_1_to_fc32_1, PRIORITY_TABLE); + + id.output_format = "fc64"; + id.input_format = "sc16_item32_be"; + uhd::convert::register_converter(id, &make_convert_sc16_item32_be_1_to_fc64_1, PRIORITY_TABLE); + + id.output_format = "fc32"; + id.input_format = "sc16_item32_le"; + uhd::convert::register_converter(id, &make_convert_sc16_item32_le_1_to_fc32_1, PRIORITY_TABLE); + + id.output_format = "fc64"; + id.input_format = "sc16_item32_le"; + uhd::convert::register_converter(id, &make_convert_sc16_item32_le_1_to_fc64_1, PRIORITY_TABLE); +} |