Revision 99494305
| b/host/include/uhd/transport/CMakeLists.txt | ||
|---|---|---|
| 22 | 22 |
bounded_buffer.hpp |
| 23 | 23 |
bounded_buffer.ipp |
| 24 | 24 |
convert_types.hpp |
| 25 |
convert_types.ipp |
|
| 25 | 26 |
if_addrs.hpp |
| 26 | 27 |
udp_simple.hpp |
| 27 | 28 |
udp_zero_copy.hpp |
| b/host/include/uhd/transport/convert_types.hpp | ||
|---|---|---|
| 21 | 21 |
#include <uhd/config.hpp> |
| 22 | 22 |
#include <uhd/types/io_type.hpp> |
| 23 | 23 |
#include <uhd/types/otw_type.hpp> |
| 24 |
#include <vector> |
|
| 24 | 25 |
|
| 25 | 26 |
namespace uhd{ namespace transport{
|
| 26 | 27 |
|
| ... | ... | |
| 40 | 41 |
); |
| 41 | 42 |
|
| 42 | 43 |
/*! |
| 44 |
* Convert IO samples to OWT samples + interleave. |
|
| 45 |
* |
|
| 46 |
* \param io_buffs buffers containing samples |
|
| 47 |
* \param io_type the type of these samples |
|
| 48 |
* \param otw_buff memory to write converted samples |
|
| 49 |
* \param otw_type the type of these samples |
|
| 50 |
* \param nsamps_per_io_buff samples per io_buff |
|
| 51 |
*/ |
|
| 52 |
UHD_API void convert_io_type_to_otw_type( |
|
| 53 |
const std::vector<const void *> &io_buffs, |
|
| 54 |
const io_type_t &io_type, |
|
| 55 |
void *otw_buff, |
|
| 56 |
const otw_type_t &otw_type, |
|
| 57 |
size_t nsamps_per_io_buff |
|
| 58 |
); |
|
| 59 |
|
|
| 60 |
/*! |
|
| 43 | 61 |
* Convert OTW samples to IO samples. |
| 44 | 62 |
* |
| 45 | 63 |
* \param otw_buff memory containing samples |
| ... | ... | |
| 54 | 72 |
size_t num_samps |
| 55 | 73 |
); |
| 56 | 74 |
|
| 75 |
/*! |
|
| 76 |
* Convert OTW samples to IO samples + de-interleave. |
|
| 77 |
* |
|
| 78 |
* \param otw_buff memory containing samples |
|
| 79 |
* \param otw_type the type of these samples |
|
| 80 |
* \param io_buffs buffers to write converted samples |
|
| 81 |
* \param io_type the type of these samples |
|
| 82 |
* \param nsamps_per_io_buff samples per io_buff |
|
| 83 |
*/ |
|
| 84 |
UHD_API void convert_otw_type_to_io_type( |
|
| 85 |
const void *otw_buff, |
|
| 86 |
const otw_type_t &otw_type, |
|
| 87 |
std::vector<void *> &io_buffs, |
|
| 88 |
const io_type_t &io_type, |
|
| 89 |
size_t nsamps_per_io_buff |
|
| 90 |
); |
|
| 91 |
|
|
| 57 | 92 |
}} //namespace |
| 58 | 93 |
|
| 94 |
#include <uhd/transport/convert_types.ipp> |
|
| 95 |
|
|
| 59 | 96 |
#endif /* INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_HPP */ |
| b/host/include/uhd/transport/convert_types.ipp | ||
|---|---|---|
| 1 |
// |
|
| 2 |
// Copyright 2010 Ettus Research LLC |
|
| 3 |
// |
|
| 4 |
// This program is free software: you can redistribute it and/or modify |
|
| 5 |
// it under the terms of the GNU General Public License as published by |
|
| 6 |
// the Free Software Foundation, either version 3 of the License, or |
|
| 7 |
// (at your option) any later version. |
|
| 8 |
// |
|
| 9 |
// This program is distributed in the hope that it will be useful, |
|
| 10 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
// GNU General Public License for more details. |
|
| 13 |
// |
|
| 14 |
// You should have received a copy of the GNU General Public License |
|
| 15 |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
| 16 |
// |
|
| 17 |
|
|
| 18 |
#ifndef INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_IPP |
|
| 19 |
#define INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_IPP |
|
| 20 |
|
|
| 21 |
UHD_INLINE void uhd::transport::convert_io_type_to_otw_type( |
|
| 22 |
const void *io_buff, const io_type_t &io_type, |
|
| 23 |
void *otw_buff, const otw_type_t &otw_type, |
|
| 24 |
size_t num_samps |
|
| 25 |
){
|
|
| 26 |
std::vector<const void *> buffs(1, io_buff); |
|
| 27 |
return uhd::transport::convert_io_type_to_otw_type( |
|
| 28 |
buffs, io_type, otw_buff, otw_type, num_samps |
|
| 29 |
); |
|
| 30 |
} |
|
| 31 |
|
|
| 32 |
UHD_INLINE void uhd::transport::convert_otw_type_to_io_type( |
|
| 33 |
const void *otw_buff, const otw_type_t &otw_type, |
|
| 34 |
void *io_buff, const io_type_t &io_type, |
|
| 35 |
size_t num_samps |
|
| 36 |
){
|
|
| 37 |
std::vector<void *> buffs(1, io_buff); |
|
| 38 |
return uhd::transport::convert_otw_type_to_io_type( |
|
| 39 |
otw_buff, otw_type, buffs, io_type, num_samps |
|
| 40 |
); |
|
| 41 |
} |
|
| 42 |
|
|
| 43 |
#endif /* INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_IPP */ |
|
| b/host/lib/transport/gen_convert_types.py | ||
|---|---|---|
| 36 | 36 |
**********************************************************************/ |
| 37 | 37 |
UHD_INLINE boost::uint8_t get_pred( |
| 38 | 38 |
const io_type_t &io_type, |
| 39 |
const otw_type_t &otw_type |
|
| 39 |
const otw_type_t &otw_type, |
|
| 40 |
size_t num_chans |
|
| 40 | 41 |
){
|
| 41 | 42 |
boost::uint8_t pred = 0; |
| 42 | 43 |
|
| ... | ... | |
| 63 | 64 |
default: throw std::runtime_error("unhandled io type id");
|
| 64 | 65 |
} |
| 65 | 66 |
|
| 67 |
switch(num_chans){
|
|
| 68 |
case 1: pred |= $ph.chan1_p; break; |
|
| 69 |
case 2: pred |= $ph.chan2_p; break; |
|
| 70 |
case 3: pred |= $ph.chan3_p; break; |
|
| 71 |
case 4: pred |= $ph.chan4_p; break; |
|
| 72 |
default: throw std::runtime_error("unhandled number of channels");
|
|
| 73 |
} |
|
| 74 |
|
|
| 66 | 75 |
return pred; |
| 67 | 76 |
} |
| 68 | 77 |
|
| ... | ... | |
| 70 | 79 |
* Convert host type to device type |
| 71 | 80 |
**********************************************************************/ |
| 72 | 81 |
void transport::convert_io_type_to_otw_type( |
| 73 |
const void *io_buff, const io_type_t &io_type, |
|
| 74 |
void *otw_buff, const otw_type_t &otw_type, |
|
| 75 |
size_t num_samps |
|
| 82 |
const std::vector<const void *> &io_buffs, |
|
| 83 |
const io_type_t &io_type, |
|
| 84 |
void *otw_buff, |
|
| 85 |
const otw_type_t &otw_type, |
|
| 86 |
size_t nsamps_per_io_buff |
|
| 76 | 87 |
){
|
| 77 |
switch(get_pred(io_type, otw_type)){
|
|
| 88 |
switch(get_pred(io_type, otw_type, io_buffs.size())){
|
|
| 78 | 89 |
#for $pred in range(2**$ph.nbits) |
| 79 | 90 |
case $pred: |
| 80 | 91 |
#set $out_type = $ph.get_dev_type($pred) |
| 81 | 92 |
#set $in_type = $ph.get_host_type($pred) |
| 82 |
#set $converter = '_'.join([$in_type, 'to', $out_type, $ph.get_swap_type($pred)]) |
|
| 83 |
$(converter)((const $(in_type)_t *)io_buff, ($(out_type)_t *)otw_buff, num_samps); |
|
| 93 |
#set $num_chans = $ph.get_num_chans($pred) |
|
| 94 |
#set $converter = '_'.join([$in_type, 'to', $out_type]) |
|
| 95 |
#if $num_chans == 1 |
|
| 96 |
$(converter)_$ph.get_swap_type($pred)( |
|
| 97 |
reinterpret_cast<const $(in_type)_t *>(io_buffs.front()), |
|
| 98 |
reinterpret_cast<$(out_type)_t *>(otw_buff), |
|
| 99 |
nsamps_per_io_buff |
|
| 100 |
); |
|
| 101 |
#else |
|
| 102 |
for (size_t i = 0; i < nsamps_per_io_buff; i++){
|
|
| 103 |
#for $j in range($num_chans) |
|
| 104 |
reinterpret_cast<$(out_type)_t *>(otw_buff)[i*$num_chans + $j] = |
|
| 105 |
#if $ph.get_swap_type($pred) == 'bswap' |
|
| 106 |
uhd::byteswap($(converter)(reinterpret_cast<const $(in_type)_t *>(io_buffs[$j])[i])); |
|
| 107 |
#else |
|
| 108 |
$(converter)(reinterpret_cast<const $(in_type)_t *>(io_buffs[$j])[i]); |
|
| 109 |
#end if |
|
| 110 |
#end for |
|
| 111 |
} |
|
| 112 |
#end if |
|
| 84 | 113 |
break; |
| 85 | 114 |
#end for |
| 86 | 115 |
} |
| ... | ... | |
| 90 | 119 |
* Convert device type to host type |
| 91 | 120 |
**********************************************************************/ |
| 92 | 121 |
void transport::convert_otw_type_to_io_type( |
| 93 |
const void *otw_buff, const otw_type_t &otw_type, |
|
| 94 |
void *io_buff, const io_type_t &io_type, |
|
| 95 |
size_t num_samps |
|
| 122 |
const void *otw_buff, |
|
| 123 |
const otw_type_t &otw_type, |
|
| 124 |
std::vector<void *> &io_buffs, |
|
| 125 |
const io_type_t &io_type, |
|
| 126 |
size_t nsamps_per_io_buff |
|
| 96 | 127 |
){
|
| 97 |
switch(get_pred(io_type, otw_type)){
|
|
| 128 |
switch(get_pred(io_type, otw_type, io_buffs.size())){
|
|
| 98 | 129 |
#for $pred in range(2**$ph.nbits) |
| 99 | 130 |
case $pred: |
| 100 | 131 |
#set $out_type = $ph.get_host_type($pred) |
| 101 | 132 |
#set $in_type = $ph.get_dev_type($pred) |
| 102 |
#set $converter = '_'.join([$in_type, 'to', $out_type, $ph.get_swap_type($pred)]) |
|
| 103 |
$(converter)((const $(in_type)_t *)otw_buff, ($(out_type)_t *)io_buff, num_samps); |
|
| 133 |
#set $num_chans = $ph.get_num_chans($pred) |
|
| 134 |
#set $converter = '_'.join([$in_type, 'to', $out_type]) |
|
| 135 |
#if $num_chans == 1 |
|
| 136 |
$(converter)_$ph.get_swap_type($pred)( |
|
| 137 |
reinterpret_cast<const $(in_type)_t *>(otw_buff), |
|
| 138 |
reinterpret_cast<$(out_type)_t *>(io_buffs.front()), |
|
| 139 |
nsamps_per_io_buff |
|
| 140 |
); |
|
| 141 |
#else |
|
| 142 |
for (size_t i = 0; i < nsamps_per_io_buff; i++){
|
|
| 143 |
#for $j in range($num_chans) |
|
| 144 |
reinterpret_cast<$(out_type)_t *>(io_buffs[$j])[i] = |
|
| 145 |
#if $ph.get_swap_type($pred) == 'bswap' |
|
| 146 |
$(converter)(uhd::byteswap(reinterpret_cast<const $(in_type)_t *>(otw_buff)[i*$num_chans + $j])); |
|
| 147 |
#else |
|
| 148 |
$(converter)(reinterpret_cast<const $(in_type)_t *>(otw_buff)[i*$num_chans + $j]); |
|
| 149 |
#end if |
|
| 150 |
#end for |
|
| 151 |
} |
|
| 152 |
#end if |
|
| 104 | 153 |
break; |
| 105 | 154 |
#end for |
| 106 | 155 |
} |
| ... | ... | |
| 118 | 167 |
item32_p = 0b00000 |
| 119 | 168 |
sc16_p = 0b00010 |
| 120 | 169 |
fc32_p = 0b00000 |
| 170 |
chan1_p = 0b00000 |
|
| 171 |
chan2_p = 0b00100 |
|
| 172 |
chan3_p = 0b01000 |
|
| 173 |
chan4_p = 0b01100 |
|
| 121 | 174 |
|
| 122 |
nbits = 2 #see above
|
|
| 175 |
nbits = 4 #see above
|
|
| 123 | 176 |
|
| 124 | 177 |
@staticmethod |
| 125 |
def has(pred, flag): return (pred & flag) == flag
|
|
| 178 |
def has(pred, mask, flag): return (pred & mask) == flag
|
|
| 126 | 179 |
|
| 127 | 180 |
@staticmethod |
| 128 | 181 |
def get_swap_type(pred): |
| 129 |
if ph.has(pred, ph.bswap_p): return 'bswap' |
|
| 130 |
if ph.has(pred, ph.nswap_p): return 'nswap' |
|
| 182 |
mask = 0b1 |
|
| 183 |
if ph.has(pred, mask, ph.bswap_p): return 'bswap' |
|
| 184 |
if ph.has(pred, mask, ph.nswap_p): return 'nswap' |
|
| 131 | 185 |
raise NotImplementedError |
| 132 | 186 |
|
| 133 | 187 |
@staticmethod |
| 134 | 188 |
def get_dev_type(pred): |
| 135 |
if ph.has(pred, ph.item32_p): return 'item32' |
|
| 189 |
mask = 0b0 |
|
| 190 |
if ph.has(pred, mask, ph.item32_p): return 'item32' |
|
| 136 | 191 |
raise NotImplementedError |
| 137 | 192 |
|
| 138 | 193 |
@staticmethod |
| 139 | 194 |
def get_host_type(pred): |
| 140 |
if ph.has(pred, ph.sc16_p): return 'sc16' |
|
| 141 |
if ph.has(pred, ph.fc32_p): return 'fc32' |
|
| 195 |
mask = 0b10 |
|
| 196 |
if ph.has(pred, mask, ph.sc16_p): return 'sc16' |
|
| 197 |
if ph.has(pred, mask, ph.fc32_p): return 'fc32' |
|
| 198 |
raise NotImplementedError |
|
| 199 |
|
|
| 200 |
@staticmethod |
|
| 201 |
def get_num_chans(pred): |
|
| 202 |
mask = 0b1100 |
|
| 203 |
if ph.has(pred, mask, ph.chan1_p): return 1 |
|
| 204 |
if ph.has(pred, mask, ph.chan2_p): return 2 |
|
| 205 |
if ph.has(pred, mask, ph.chan3_p): return 3 |
|
| 206 |
if ph.has(pred, mask, ph.chan4_p): return 4 |
|
| 142 | 207 |
raise NotImplementedError |
| 143 | 208 |
|
| 144 | 209 |
if __name__ == '__main__': |
Also available in: Unified diff