diff options
| author | Josh Blum <josh@joshknows.com> | 2010-08-30 12:33:13 -0700 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2010-08-30 12:33:13 -0700 | 
| commit | 79ea83d6b352a7865ff6143ba77fcc0956c6452f (patch) | |
| tree | 0718d0c33ea403b569173e45b7beddafbd7935b7 | |
| parent | d77765c8dd92724c57272eae387ce838d6992a03 (diff) | |
| download | uhd-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.hpp | 27 | ||||
| -rwxr-xr-x | host/lib/transport/gen_convert_types.py | 2 | ||||
| -rw-r--r-- | host/test/convert_types_test.cpp | 84 | 
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)); +    } +} | 
