diff options
| author | Josh Blum <josh@joshknows.com> | 2012-02-17 18:18:26 -0800 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2012-02-17 18:18:26 -0800 | 
| commit | 3ddbcb6078593c39cb0e4bc8f9769f818a61466f (patch) | |
| tree | 408e3f6a64e31b7d830b9f884ecebdaf100a5d2d /host/lib/convert/convert_with_tables.cpp | |
| parent | 1fab7e9d477aa98e489400c25a08358952c69c90 (diff) | |
| parent | ace4489066d1621a09e70650a00d736f0b03ed8c (diff) | |
| download | uhd-3ddbcb6078593c39cb0e4bc8f9769f818a61466f.tar.gz uhd-3ddbcb6078593c39cb0e4bc8f9769f818a61466f.tar.bz2 uhd-3ddbcb6078593c39cb0e4bc8f9769f818a61466f.zip  | |
Merge branch 'next'
Diffstat (limited to 'host/lib/convert/convert_with_tables.cpp')
| -rw-r--r-- | host/lib/convert/convert_with_tables.cpp | 100 | 
1 files changed, 97 insertions, 3 deletions
diff --git a/host/lib/convert/convert_with_tables.cpp b/host/lib/convert/convert_with_tables.cpp index c45415d5d..4a3ce29b2 100644 --- a/host/lib/convert/convert_with_tables.cpp +++ b/host/lib/convert/convert_with_tables.cpp @@ -1,5 +1,5 @@  // -// Copyright 2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -17,6 +17,7 @@  #include "convert_common.hpp"  #include <uhd/utils/byteswap.hpp> +#include <boost/math/special_functions/round.hpp>  #include <vector>  using namespace uhd::convert; @@ -26,6 +27,55 @@ static const size_t sc16_table_len = size_t(1 << 16);  typedef boost::uint16_t (*tohost16_type)(boost::uint16_t);  /*********************************************************************** + * Implementation for sc16 to sc8 lookup table + *  - Lookup the real and imaginary parts individually + **********************************************************************/ +template <bool swap> +class convert_sc16_1_to_sc8_item32_1 : public converter{ +public: +    convert_sc16_1_to_sc8_item32_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 = boost::uint16_t(i); +            _table[i] = boost::int8_t(boost::math::iround(val * scalar / 32767.)); +        } +    } + +    void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps){ +        const sc16_t *input = reinterpret_cast<const sc16_t *>(inputs[0]); +        item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); + +        const size_t num_pairs = nsamps/2; +        for (size_t i = 0, j = 0; i < num_pairs; i++, j+=2){ +            output[i] = this->lookup(input[j], input[j+1]); +        } + +        if (nsamps != num_pairs*2){ +            output[num_pairs] = this->lookup(input[nsamps-1], 0);; +        } +    } + +    item32_t lookup(const sc16_t &in0, const sc16_t &in1){ +        if (swap){ //hope this compiles out, its a template constant +            return +            (item32_t(_table[size_t(in0.real())]) << 16) | +            (item32_t(_table[size_t(in0.imag())]) << 24) | +            (item32_t(_table[size_t(in1.real())]) << 0) | +            (item32_t(_table[size_t(in1.imag())]) << 8) ; +        } +        return +            (item32_t(_table[size_t(in0.real())]) << 8) | +            (item32_t(_table[size_t(in0.imag())]) << 0) | +            (item32_t(_table[size_t(in1.real())]) << 24) | +            (item32_t(_table[size_t(in1.imag())]) << 16) ; +    } + +private: +    std::vector<boost::uint8_t> _table; +}; + +/***********************************************************************   * Implementation for sc16 lookup table   *  - Lookup the real and imaginary parts individually   **********************************************************************/ @@ -67,11 +117,19 @@ class convert_sc8_item32_1_to_fcxx_1 : public converter{  public:      convert_sc8_item32_1_to_fcxx_1(void): _table(sc16_table_len){} +    //special case for sc16 type, 32767 undoes float normalization +    static type conv(const boost::int8_t &num, const double scalar){ +        if (sizeof(type) == sizeof(s16_t)){ +            return type(boost::math::iround(num*scalar*32767)); +        } +        return type(num*scalar); +    } +      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)); -            const type real = type(boost::int8_t(val >> 8)*scalar); -            const type imag = type(boost::int8_t(val >> 0)*scalar); +            const type real = conv(boost::int8_t(val >> 8), scalar); +            const type imag = conv(boost::int8_t(val >> 0), scalar);              _table[i] = std::complex<type>(real, imag);          }      } @@ -112,9 +170,13 @@ private:  #ifdef BOOST_BIG_ENDIAN  #  define SHIFT_PAIR0 16, 0  #  define SHIFT_PAIR1 0, 16 +#  define BE_SWAP false +#  define LE_SWAP true  #else  #  define SHIFT_PAIR0 0, 16  #  define SHIFT_PAIR1 16, 0 +#  define BE_SWAP true +#  define LE_SWAP false  #endif  static converter::sptr make_convert_sc16_item32_be_1_to_fc32_1(void){ @@ -149,6 +211,22 @@ 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, SHIFT_PAIR0>());  } +static converter::sptr make_convert_sc8_item32_be_1_to_sc16_1(void){ +    return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<s16_t, uhd::ntohx, SHIFT_PAIR1>()); +} + +static converter::sptr make_convert_sc8_item32_le_1_to_sc16_1(void){ +    return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<s16_t, uhd::wtohx, SHIFT_PAIR0>()); +} + +static converter::sptr make_convert_sc16_1_to_sc8_item32_be_1(void){ +    return converter::sptr(new convert_sc16_1_to_sc8_item32_1<BE_SWAP>()); +} + +static converter::sptr make_convert_sc16_1_to_sc8_item32_le_1(void){ +    return converter::sptr(new convert_sc16_1_to_sc8_item32_1<LE_SWAP>()); +} +  UHD_STATIC_BLOCK(register_convert_sc16_item32_1_to_fcxx_1){      uhd::convert::id_type id;      id.num_inputs = 1; @@ -185,4 +263,20 @@ UHD_STATIC_BLOCK(register_convert_sc16_item32_1_to_fcxx_1){      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); + +    id.output_format = "sc16"; +    id.input_format = "sc8_item32_be"; +    uhd::convert::register_converter(id, &make_convert_sc8_item32_be_1_to_sc16_1, PRIORITY_TABLE); + +    id.output_format = "sc16"; +    id.input_format = "sc8_item32_le"; +    uhd::convert::register_converter(id, &make_convert_sc8_item32_le_1_to_sc16_1, PRIORITY_TABLE); + +    id.output_format = "sc16"; +    id.input_format = "sc8_item32_be"; +    uhd::convert::register_converter(id, &make_convert_sc16_1_to_sc8_item32_be_1, PRIORITY_TABLE); + +    id.output_format = "sc16"; +    id.input_format = "sc8_item32_le"; +    uhd::convert::register_converter(id, &make_convert_sc16_1_to_sc8_item32_le_1, PRIORITY_TABLE);  }  | 
