diff options
Diffstat (limited to 'host')
-rw-r--r-- | host/lib/convert/convert_with_tables.cpp | 112 |
1 files changed, 95 insertions, 17 deletions
diff --git a/host/lib/convert/convert_with_tables.cpp b/host/lib/convert/convert_with_tables.cpp index 00bec95af..ac12b4440 100644 --- a/host/lib/convert/convert_with_tables.cpp +++ b/host/lib/convert/convert_with_tables.cpp @@ -27,16 +27,17 @@ typedef boost::uint16_t (*tohost16_type)(boost::uint16_t); /*********************************************************************** * Implementation for sc16 lookup table + * - Lookup the real and imaginary parts individually **********************************************************************/ -template <typename type, tohost16_type tohost, size_t real_shift, size_t imag_shift> +template <typename type, tohost16_type tohost, size_t lo_shift, size_t hi_shift> class convert_sc16_item32_1_to_fcxx_1 : public converter{ public: convert_sc16_item32_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 = tohost(boost::uint16_t(i & 0xffff)); - _table[i] = type(val*scalar); + const boost::uint16_t val = tohost(boost::uint16_t(i & 0xffff)); + _table[i] = type(boost::int16_t(val)*scalar); } } @@ -47,8 +48,8 @@ public: for (size_t i = 0; i < nsamps; i++){ const item32_t item = input[i]; output[i] = std::complex<type>( - _table[boost::uint16_t(item >> real_shift)], - _table[boost::uint16_t(item >> imag_shift)] + _table[boost::uint16_t(item >> lo_shift)], + _table[boost::uint16_t(item >> hi_shift)] ); } } @@ -58,35 +59,96 @@ private: }; /*********************************************************************** + * Implementation for sc8 lookup table + * - Lookup the real and imaginary parts together + **********************************************************************/ +template <typename type, tohost16_type tohost, size_t lo_shift, size_t hi_shift> +class convert_sc8_item32_1_to_fcxx_1 : public converter{ +public: + convert_sc8_item32_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::uint16_t val = tohost(boost::uint16_t(i & 0xffff)); + _table[i] = std::complex<type>(boost::int8_t(val >> 8)*scalar, boost::int8_t(val >> 0)*scalar); + } + } + + void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps){ + const item32_t *input = reinterpret_cast<const item32_t *>(size_t(inputs[0]) & ~0x3); + std::complex<type> *output = reinterpret_cast<std::complex<type> *>(outputs[0]); + + size_t num_samps = nsamps; + + if ((size_t(inputs[0]) & 0x3) != 0){ + const item32_t item0 = *input++; + *output++ = _table[boost::uint16_t(item0 >> hi_shift)]; + num_samps--; + } + + const size_t num_pairs = num_samps/2; + for (size_t i = 0, j = 0; i < num_pairs; i++, j+=2){ + const item32_t item_i = (input[i]); + output[j] = _table[boost::uint16_t(item_i >> lo_shift)]; + output[j + 1] = _table[boost::uint16_t(item_i >> hi_shift)]; + } + + if (num_samps != num_pairs*2){ + const item32_t item_n = input[num_pairs]; + output[num_samps-1] = _table[boost::uint16_t(item_n >> lo_shift)]; + } + } + +private: + std::vector<std::complex<type> > _table; +}; + +/*********************************************************************** * Factory functions and registration **********************************************************************/ #ifdef BOOST_BIG_ENDIAN -# define ITEM32_BE_TO_R16 16 -# define ITEM32_BE_TO_I16 0 -# define ITEM32_LE_TO_R16 0 -# define ITEM32_LE_TO_I16 16 +# define BE_LO_SHIFT 16 +# define BE_HI_SHIFT 0 +# define LE_LO_SHIFT 0 +# define LE_HI_SHIFT 16 #else -# define ITEM32_BE_TO_R16 0 -# define ITEM32_BE_TO_I16 16 -# define ITEM32_LE_TO_R16 16 -# define ITEM32_LE_TO_I16 0 +# define BE_LO_SHIFT 0 +# define BE_HI_SHIFT 16 +# define LE_LO_SHIFT 16 +# define LE_HI_SHIFT 0 #endif static converter::sptr make_convert_sc16_item32_be_1_to_fc32_1(void){ - return converter::sptr(new convert_sc16_item32_1_to_fcxx_1<float, uhd::ntohx, ITEM32_BE_TO_R16, ITEM32_BE_TO_I16>()); + return converter::sptr(new convert_sc16_item32_1_to_fcxx_1<float, uhd::ntohx, BE_LO_SHIFT, BE_HI_SHIFT>()); } static converter::sptr make_convert_sc16_item32_be_1_to_fc64_1(void){ - return converter::sptr(new convert_sc16_item32_1_to_fcxx_1<double, uhd::ntohx, ITEM32_BE_TO_R16, ITEM32_BE_TO_I16>()); + return converter::sptr(new convert_sc16_item32_1_to_fcxx_1<double, uhd::ntohx, BE_LO_SHIFT, BE_HI_SHIFT>()); } static converter::sptr make_convert_sc16_item32_le_1_to_fc32_1(void){ - return converter::sptr(new convert_sc16_item32_1_to_fcxx_1<float, uhd::wtohx, ITEM32_LE_TO_R16, ITEM32_LE_TO_I16>()); + return converter::sptr(new convert_sc16_item32_1_to_fcxx_1<float, uhd::wtohx, LE_LO_SHIFT, LE_HI_SHIFT>()); } static converter::sptr make_convert_sc16_item32_le_1_to_fc64_1(void){ - return converter::sptr(new convert_sc16_item32_1_to_fcxx_1<double, uhd::wtohx, ITEM32_LE_TO_R16, ITEM32_LE_TO_I16>()); + return converter::sptr(new convert_sc16_item32_1_to_fcxx_1<double, uhd::wtohx, LE_LO_SHIFT, LE_HI_SHIFT>()); +} + +static converter::sptr make_convert_sc8_item32_be_1_to_fc32_1(void){ + return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<float, uhd::ntohx, BE_LO_SHIFT, BE_HI_SHIFT>()); +} + +static converter::sptr make_convert_sc8_item32_be_1_to_fc64_1(void){ + return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<double, uhd::ntohx, BE_LO_SHIFT, BE_HI_SHIFT>()); +} + +static converter::sptr make_convert_sc8_item32_le_1_to_fc32_1(void){ + return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<float, uhd::wtohx, LE_LO_SHIFT, LE_HI_SHIFT>()); +} + +static converter::sptr make_convert_sc8_item32_le_1_to_fc64_1(void){ + return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<double, uhd::wtohx, LE_LO_SHIFT, LE_HI_SHIFT>()); } UHD_STATIC_BLOCK(register_convert_sc16_item32_1_to_fcxx_1){ @@ -109,4 +171,20 @@ UHD_STATIC_BLOCK(register_convert_sc16_item32_1_to_fcxx_1){ 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); + + id.output_format = "fc32"; + id.input_format = "sc8_item32_be"; + uhd::convert::register_converter(id, &make_convert_sc8_item32_be_1_to_fc32_1, PRIORITY_TABLE); + + id.output_format = "fc64"; + id.input_format = "sc8_item32_be"; + uhd::convert::register_converter(id, &make_convert_sc8_item32_be_1_to_fc64_1, PRIORITY_TABLE); + + id.output_format = "fc32"; + id.input_format = "sc8_item32_le"; + uhd::convert::register_converter(id, &make_convert_sc8_item32_le_1_to_fc32_1, PRIORITY_TABLE); + + id.output_format = "fc64"; + id.input_format = "sc8_item32_le"; + uhd::convert::register_converter(id, &make_convert_sc8_item32_le_1_to_fc64_1, PRIORITY_TABLE); } |