aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-08-30 16:00:35 -0700
committerJosh Blum <josh@joshknows.com>2010-08-30 16:00:35 -0700
commit99494305b35adf5c4f89b4888192c723f32d9da2 (patch)
tree02753f7bad5fb3d5d9b0c3478b2cc1014d78faf2
parent79ea83d6b352a7865ff6143ba77fcc0956c6452f (diff)
downloaduhd-99494305b35adf5c4f89b4888192c723f32d9da2.tar.gz
uhd-99494305b35adf5c4f89b4888192c723f32d9da2.tar.bz2
uhd-99494305b35adf5c4f89b4888192c723f32d9da2.zip
uhd: added interleave/de-interleave type conversion routines
-rw-r--r--host/include/uhd/transport/CMakeLists.txt1
-rw-r--r--host/include/uhd/transport/convert_types.hpp37
-rw-r--r--host/include/uhd/transport/convert_types.ipp43
-rwxr-xr-xhost/lib/transport/gen_convert_types.py105
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__':