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); +} | 
