diff options
| -rw-r--r-- | host/include/uhd/transport/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/include/uhd/transport/convert_types.hpp | 37 | ||||
| -rw-r--r-- | host/include/uhd/transport/convert_types.ipp | 43 | ||||
| -rwxr-xr-x | host/lib/transport/gen_convert_types.py | 105 | 
4 files changed, 166 insertions, 20 deletions
| diff --git a/host/include/uhd/transport/CMakeLists.txt b/host/include/uhd/transport/CMakeLists.txt index 93e9a6485..01856454f 100644 --- a/host/include/uhd/transport/CMakeLists.txt +++ b/host/include/uhd/transport/CMakeLists.txt @@ -22,6 +22,7 @@ INSTALL(FILES      bounded_buffer.hpp      bounded_buffer.ipp      convert_types.hpp +    convert_types.ipp      if_addrs.hpp      udp_simple.hpp      udp_zero_copy.hpp diff --git a/host/include/uhd/transport/convert_types.hpp b/host/include/uhd/transport/convert_types.hpp index a4d999240..dc7fa6c1a 100644 --- a/host/include/uhd/transport/convert_types.hpp +++ b/host/include/uhd/transport/convert_types.hpp @@ -21,6 +21,7 @@  #include <uhd/config.hpp>  #include <uhd/types/io_type.hpp>  #include <uhd/types/otw_type.hpp> +#include <vector>  namespace uhd{ namespace transport{ @@ -40,6 +41,23 @@ UHD_API void convert_io_type_to_otw_type(  );  /*! + * Convert IO samples to OWT samples + interleave. + * + * \param io_buffs buffers containing samples + * \param io_type the type of these samples + * \param otw_buff memory to write converted samples + * \param otw_type the type of these samples + * \param nsamps_per_io_buff samples per io_buff + */ +UHD_API void convert_io_type_to_otw_type( +    const std::vector<const void *> &io_buffs, +    const io_type_t &io_type, +    void *otw_buff, +    const otw_type_t &otw_type, +    size_t nsamps_per_io_buff +); + +/*!   * Convert OTW samples to IO samples.   *   * \param otw_buff memory containing samples @@ -54,6 +72,25 @@ UHD_API void convert_otw_type_to_io_type(      size_t num_samps  ); +/*! + * Convert OTW samples to IO samples + de-interleave. + * + * \param otw_buff memory containing samples + * \param otw_type the type of these samples + * \param io_buffs buffers to write converted samples + * \param io_type the type of these samples + * \param nsamps_per_io_buff samples per io_buff + */ +UHD_API void convert_otw_type_to_io_type( +    const void *otw_buff, +    const otw_type_t &otw_type, +    std::vector<void *> &io_buffs, +    const io_type_t &io_type, +    size_t nsamps_per_io_buff +); +  }} //namespace +#include <uhd/transport/convert_types.ipp> +  #endif /* INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_HPP */ diff --git a/host/include/uhd/transport/convert_types.ipp b/host/include/uhd/transport/convert_types.ipp new file mode 100644 index 000000000..914ca6f17 --- /dev/null +++ b/host/include/uhd/transport/convert_types.ipp @@ -0,0 +1,43 @@ +// +// Copyright 2010 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/>. +// + +#ifndef INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_IPP +#define INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_IPP + +UHD_INLINE void uhd::transport::convert_io_type_to_otw_type( +    const void *io_buff, const io_type_t &io_type, +    void *otw_buff, const otw_type_t &otw_type, +    size_t num_samps +){ +    std::vector<const void *> buffs(1, io_buff); +    return uhd::transport::convert_io_type_to_otw_type( +        buffs, io_type, otw_buff, otw_type, num_samps +    ); +} + +UHD_INLINE void uhd::transport::convert_otw_type_to_io_type( +    const void *otw_buff, const otw_type_t &otw_type, +    void *io_buff, const io_type_t &io_type, +    size_t num_samps +){ +    std::vector<void *> buffs(1, io_buff); +    return uhd::transport::convert_otw_type_to_io_type( +        otw_buff, otw_type, buffs, io_type, num_samps +    ); +} + +#endif /* INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_IPP */ diff --git a/host/lib/transport/gen_convert_types.py b/host/lib/transport/gen_convert_types.py index 17d8ffde0..adbd22868 100755 --- a/host/lib/transport/gen_convert_types.py +++ b/host/lib/transport/gen_convert_types.py @@ -36,7 +36,8 @@ using namespace uhd;   **********************************************************************/  UHD_INLINE boost::uint8_t get_pred(      const io_type_t &io_type, -    const otw_type_t &otw_type +    const otw_type_t &otw_type, +    size_t num_chans  ){      boost::uint8_t pred = 0; @@ -63,6 +64,14 @@ UHD_INLINE boost::uint8_t get_pred(      default: throw std::runtime_error("unhandled io type id");      } +    switch(num_chans){ +    case 1: pred |= $ph.chan1_p; break; +    case 2: pred |= $ph.chan2_p; break; +    case 3: pred |= $ph.chan3_p; break; +    case 4: pred |= $ph.chan4_p; break; +    default: throw std::runtime_error("unhandled number of channels"); +    } +      return pred;  } @@ -70,17 +79,37 @@ UHD_INLINE boost::uint8_t get_pred(   * Convert host type to device type   **********************************************************************/  void transport::convert_io_type_to_otw_type( -    const void *io_buff, const io_type_t &io_type, -    void *otw_buff, const otw_type_t &otw_type, -    size_t num_samps +    const std::vector<const void *> &io_buffs, +    const io_type_t &io_type, +    void *otw_buff, +    const otw_type_t &otw_type, +    size_t nsamps_per_io_buff  ){ -    switch(get_pred(io_type, otw_type)){ +    switch(get_pred(io_type, otw_type, io_buffs.size())){      #for $pred in range(2**$ph.nbits)      case $pred:          #set $out_type = $ph.get_dev_type($pred)          #set $in_type = $ph.get_host_type($pred) -        #set $converter = '_'.join([$in_type, 'to', $out_type, $ph.get_swap_type($pred)]) -        $(converter)((const $(in_type)_t *)io_buff, ($(out_type)_t *)otw_buff, num_samps); +        #set $num_chans = $ph.get_num_chans($pred) +        #set $converter = '_'.join([$in_type, 'to', $out_type]) +        #if $num_chans == 1 +        $(converter)_$ph.get_swap_type($pred)( +            reinterpret_cast<const $(in_type)_t *>(io_buffs.front()), +            reinterpret_cast<$(out_type)_t *>(otw_buff), +            nsamps_per_io_buff +        ); +        #else +        for (size_t i = 0; i < nsamps_per_io_buff; i++){ +            #for $j in range($num_chans) +            reinterpret_cast<$(out_type)_t *>(otw_buff)[i*$num_chans + $j] = +                #if $ph.get_swap_type($pred) == 'bswap' +                uhd::byteswap($(converter)(reinterpret_cast<const $(in_type)_t *>(io_buffs[$j])[i])); +                #else +                $(converter)(reinterpret_cast<const $(in_type)_t *>(io_buffs[$j])[i]); +                #end if +            #end for +        } +        #end if          break;      #end for      } @@ -90,17 +119,37 @@ void transport::convert_io_type_to_otw_type(   * Convert device type to host type   **********************************************************************/  void transport::convert_otw_type_to_io_type( -    const void *otw_buff, const otw_type_t &otw_type, -    void *io_buff, const io_type_t &io_type, -    size_t num_samps +    const void *otw_buff, +    const otw_type_t &otw_type, +    std::vector<void *> &io_buffs, +    const io_type_t &io_type, +    size_t nsamps_per_io_buff  ){ -    switch(get_pred(io_type, otw_type)){ +    switch(get_pred(io_type, otw_type, io_buffs.size())){      #for $pred in range(2**$ph.nbits)      case $pred:          #set $out_type = $ph.get_host_type($pred)          #set $in_type = $ph.get_dev_type($pred) -        #set $converter = '_'.join([$in_type, 'to', $out_type, $ph.get_swap_type($pred)]) -        $(converter)((const $(in_type)_t *)otw_buff, ($(out_type)_t *)io_buff, num_samps); +        #set $num_chans = $ph.get_num_chans($pred) +        #set $converter = '_'.join([$in_type, 'to', $out_type]) +        #if $num_chans == 1 +        $(converter)_$ph.get_swap_type($pred)( +            reinterpret_cast<const $(in_type)_t *>(otw_buff), +            reinterpret_cast<$(out_type)_t *>(io_buffs.front()), +            nsamps_per_io_buff +        ); +        #else +        for (size_t i = 0; i < nsamps_per_io_buff; i++){ +            #for $j in range($num_chans) +            reinterpret_cast<$(out_type)_t *>(io_buffs[$j])[i] = +                #if $ph.get_swap_type($pred) == 'bswap' +                $(converter)(uhd::byteswap(reinterpret_cast<const $(in_type)_t *>(otw_buff)[i*$num_chans + $j])); +                #else +                $(converter)(reinterpret_cast<const $(in_type)_t *>(otw_buff)[i*$num_chans + $j]); +                #end if +            #end for +        } +        #end if          break;      #end for      } @@ -118,27 +167,43 @@ class ph:      item32_p = 0b00000      sc16_p   = 0b00010      fc32_p   = 0b00000 +    chan1_p  = 0b00000 +    chan2_p  = 0b00100 +    chan3_p  = 0b01000 +    chan4_p  = 0b01100 -    nbits = 2 #see above +    nbits = 4 #see above      @staticmethod -    def has(pred, flag): return (pred & flag) == flag +    def has(pred, mask, flag): return (pred & mask) == flag      @staticmethod      def get_swap_type(pred): -        if ph.has(pred, ph.bswap_p): return 'bswap' -        if ph.has(pred, ph.nswap_p): return 'nswap' +        mask = 0b1 +        if ph.has(pred, mask, ph.bswap_p): return 'bswap' +        if ph.has(pred, mask, ph.nswap_p): return 'nswap'          raise NotImplementedError      @staticmethod      def get_dev_type(pred): -        if ph.has(pred, ph.item32_p): return 'item32' +        mask = 0b0 +        if ph.has(pred, mask, ph.item32_p): return 'item32'          raise NotImplementedError      @staticmethod      def get_host_type(pred): -        if ph.has(pred, ph.sc16_p): return 'sc16' -        if ph.has(pred, ph.fc32_p): return 'fc32' +        mask = 0b10 +        if ph.has(pred, mask, ph.sc16_p): return 'sc16' +        if ph.has(pred, mask, ph.fc32_p): return 'fc32' +        raise NotImplementedError + +    @staticmethod +    def get_num_chans(pred): +        mask = 0b1100 +        if ph.has(pred, mask, ph.chan1_p): return 1 +        if ph.has(pred, mask, ph.chan2_p): return 2 +        if ph.has(pred, mask, ph.chan3_p): return 3 +        if ph.has(pred, mask, ph.chan4_p): return 4          raise NotImplementedError  if __name__ == '__main__': | 
