aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-08-30 12:33:13 -0700
committerJosh Blum <josh@joshknows.com>2010-08-30 12:33:13 -0700
commit79ea83d6b352a7865ff6143ba77fcc0956c6452f (patch)
tree0718d0c33ea403b569173e45b7beddafbd7935b7
parentd77765c8dd92724c57272eae387ce838d6992a03 (diff)
downloaduhd-79ea83d6b352a7865ff6143ba77fcc0956c6452f.tar.gz
uhd-79ea83d6b352a7865ff6143ba77fcc0956c6452f.tar.bz2
uhd-79ea83d6b352a7865ff6143ba77fcc0956c6452f.zip
uhd: fixed short conversion (IQ swap) and added test between short/float
-rw-r--r--host/lib/transport/convert_types_impl.hpp27
-rwxr-xr-xhost/lib/transport/gen_convert_types.py2
-rw-r--r--host/test/convert_types_test.cpp84
3 files changed, 105 insertions, 8 deletions
diff --git a/host/lib/transport/convert_types_impl.hpp b/host/lib/transport/convert_types_impl.hpp
index fdc859883..90618dec6 100644
--- a/host/lib/transport/convert_types_impl.hpp
+++ b/host/lib/transport/convert_types_impl.hpp
@@ -42,36 +42,51 @@ typedef boost::uint32_t item32_t;
/***********************************************************************
* Convert complex short buffer to items32
**********************************************************************/
+static UHD_INLINE item32_t sc16_to_item32(sc16_t num){
+ boost::uint16_t real = num.real();
+ boost::uint16_t imag = num.imag();
+ return (item32_t(real) << 16) | (item32_t(imag) << 0);
+}
+
static UHD_INLINE void sc16_to_item32_nswap(
const sc16_t *input, item32_t *output, size_t nsamps
){
- std::memcpy(output, input, nsamps*sizeof(item32_t));
+ for (size_t i = 0; i < nsamps; i++){
+ output[i] = sc16_to_item32(input[i]);
+ }
}
static UHD_INLINE void sc16_to_item32_bswap(
const sc16_t *input, item32_t *output, size_t nsamps
){
- const item32_t *item32_input = (const item32_t *)input;
for (size_t i = 0; i < nsamps; i++){
- output[i] = uhd::byteswap(item32_input[i]);
+ output[i] = uhd::byteswap(sc16_to_item32(input[i]));
}
}
/***********************************************************************
* Convert items32 buffer to complex short
**********************************************************************/
+static UHD_INLINE sc16_t item32_to_sc16(item32_t item){
+ return sc16_t(
+ boost::int16_t(item >> 16),
+ boost::int16_t(item >> 0)
+ );
+}
+
static UHD_INLINE void item32_to_sc16_nswap(
const item32_t *input, sc16_t *output, size_t nsamps
){
- std::memcpy(output, input, nsamps*sizeof(item32_t));
+ for (size_t i = 0; i < nsamps; i++){
+ output[i] = item32_to_sc16(input[i]);
+ }
}
static UHD_INLINE void item32_to_sc16_bswap(
const item32_t *input, sc16_t *output, size_t nsamps
){
- item32_t *item32_output = (item32_t *)output;
for (size_t i = 0; i < nsamps; i++){
- item32_output[i] = uhd::byteswap(input[i]);
+ output[i] = item32_to_sc16(uhd::byteswap(input[i]));
}
}
diff --git a/host/lib/transport/gen_convert_types.py b/host/lib/transport/gen_convert_types.py
index 951b634d9..17d8ffde0 100755
--- a/host/lib/transport/gen_convert_types.py
+++ b/host/lib/transport/gen_convert_types.py
@@ -95,7 +95,7 @@ void transport::convert_otw_type_to_io_type(
size_t num_samps
){
switch(get_pred(io_type, otw_type)){
- #for $pred in range(4)
+ #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)
diff --git a/host/test/convert_types_test.cpp b/host/test/convert_types_test.cpp
index d132a708b..2148302b6 100644
--- a/host/test/convert_types_test.cpp
+++ b/host/test/convert_types_test.cpp
@@ -27,7 +27,7 @@
using namespace uhd;
//typedefs for complex types
-typedef std::complex<boost::uint16_t> sc16_t;
+typedef std::complex<boost::int16_t> sc16_t;
typedef std::complex<float> fc32_t;
//extract pointer to POD since using &vector.front() throws in MSVC
@@ -158,3 +158,85 @@ BOOST_AUTO_TEST_CASE(test_convert_types_le_fc32){
test_convert_types_fc32(nsamps, io_type, otw_type);
}
}
+
+/***********************************************************************
+ * Test float to short conversion loopback
+ **********************************************************************/
+BOOST_AUTO_TEST_CASE(test_convert_types_fc32_to_sc16){
+ io_type_t io_type_in(io_type_t::COMPLEX_FLOAT32);
+ io_type_t io_type_out(io_type_t::COMPLEX_INT16);
+
+ otw_type_t otw_type;
+ otw_type.byteorder = otw_type_t::BO_NATIVE;
+ otw_type.width = 16;
+
+ const size_t nsamps = 13;
+ std::vector<fc32_t> input(nsamps);
+ BOOST_FOREACH(fc32_t &in, input) in = fc32_t(
+ (std::rand()/float(RAND_MAX/2)) - 1,
+ (std::rand()/float(RAND_MAX/2)) - 1
+ );
+
+ //convert float to dev
+ std::vector<boost::uint32_t> tmp(nsamps);
+ transport::convert_io_type_to_otw_type(
+ pod2ptr(input), io_type_in,
+ pod2ptr(tmp), otw_type,
+ nsamps
+ );
+
+ //convert dev to short
+ std::vector<sc16_t> output(nsamps);
+ transport::convert_otw_type_to_io_type(
+ pod2ptr(tmp), otw_type,
+ pod2ptr(output), io_type_out,
+ nsamps
+ );
+
+ //test that the inputs and outputs match
+ for (size_t i = 0; i < nsamps; i++){
+ BOOST_CHECK_CLOSE_FRACTION(input[i].real(), output[i].real()/float(32767), float(0.01));
+ BOOST_CHECK_CLOSE_FRACTION(input[i].imag(), output[i].imag()/float(32767), float(0.01));
+ }
+}
+
+/***********************************************************************
+ * Test short to float conversion loopback
+ **********************************************************************/
+BOOST_AUTO_TEST_CASE(test_convert_types_sc16_to_fc32){
+ io_type_t io_type_in(io_type_t::COMPLEX_INT16);
+ io_type_t io_type_out(io_type_t::COMPLEX_FLOAT32);
+
+ otw_type_t otw_type;
+ otw_type.byteorder = otw_type_t::BO_NATIVE;
+ otw_type.width = 16;
+
+ const size_t nsamps = 13;
+ std::vector<sc16_t> input(nsamps);
+ BOOST_FOREACH(sc16_t &in, input) in = sc16_t(
+ std::rand()-(RAND_MAX/2),
+ std::rand()-(RAND_MAX/2)
+ );
+
+ //convert short to dev
+ std::vector<boost::uint32_t> tmp(nsamps);
+ transport::convert_io_type_to_otw_type(
+ pod2ptr(input), io_type_in,
+ pod2ptr(tmp), otw_type,
+ nsamps
+ );
+
+ //convert dev to float
+ std::vector<fc32_t> output(nsamps);
+ transport::convert_otw_type_to_io_type(
+ pod2ptr(tmp), otw_type,
+ pod2ptr(output), io_type_out,
+ nsamps
+ );
+
+ //test that the inputs and outputs match
+ for (size_t i = 0; i < nsamps; i++){
+ BOOST_CHECK_CLOSE_FRACTION(input[i].real()/float(32767), output[i].real(), float(0.01));
+ BOOST_CHECK_CLOSE_FRACTION(input[i].imag()/float(32767), output[i].imag(), float(0.01));
+ }
+}