Revision 8c872ffb host/test/convert_types_test.cpp

b/host/test/convert_types_test.cpp
17 17

  
18 18
#include <uhd/transport/convert_types.hpp>
19 19
#include <boost/test/unit_test.hpp>
20
#include <boost/foreach.hpp>
20 21
#include <boost/cstdint.hpp>
22
#include <boost/asio/buffer.hpp>
21 23
#include <complex>
24
#include <vector>
25
#include <cstdlib>
22 26

  
23 27
using namespace uhd;
24 28

  
25
template <typename host_type, typename dev_type, size_t nsamps>
26
void loopback(
29
//typedefs for complex types
30
typedef std::complex<boost::uint16_t> sc16_t;
31
typedef std::complex<float> fc32_t;
32

  
33
//extract pointer to POD since using &vector.front() throws in MSVC
34
template <typename T> void * pod2ptr(T &pod){
35
    return boost::asio::buffer_cast<void *>(boost::asio::buffer(pod));
36
}
37
template <typename T> const void * pod2ptr(const T &pod){
38
    return boost::asio::buffer_cast<const void *>(boost::asio::buffer(pod));
39
}
40

  
41
/***********************************************************************
42
 * Loopback runner:
43
 *    convert input buffer into intermediate buffer
44
 *    convert intermediate buffer into output buffer
45
 **********************************************************************/
46
template <typename Range> static void loopback(
47
    size_t nsamps,
27 48
    const io_type_t &io_type,
28 49
    const otw_type_t &otw_type,
29
    const host_type *input,
30
    host_type *output
50
    const Range &input,
51
    Range &output
31 52
){
32
    dev_type dev[nsamps];
53
    //item32 is largest device type
54
    std::vector<boost::uint32_t> dev(nsamps);
33 55

  
34 56
    //convert to dev type
35 57
    transport::convert_io_type_to_otw_type(
36
        input, io_type,
37
        dev, otw_type,
58
        pod2ptr(input), io_type,
59
        pod2ptr(dev), otw_type,
38 60
        nsamps
39 61
    );
40 62

  
41 63
    //convert back to host type
42 64
    transport::convert_otw_type_to_io_type(
43
        dev, otw_type,
44
        output, io_type,
65
        pod2ptr(dev), otw_type,
66
        pod2ptr(output), io_type,
45 67
        nsamps
46 68
    );
47 69
}
48 70

  
49
typedef std::complex<boost::uint16_t> sc16_t;
71
/***********************************************************************
72
 * Test short conversion
73
 **********************************************************************/
74
static void test_convert_types_sc16(
75
    size_t nsamps,
76
    const io_type_t &io_type,
77
    const otw_type_t &otw_type
78
){
79
    //fill the input samples
80
    std::vector<sc16_t> input(nsamps), output(nsamps);
81
    BOOST_FOREACH(sc16_t &in, input) in = sc16_t(
82
        std::rand()-(RAND_MAX/2),
83
        std::rand()-(RAND_MAX/2)
84
    );
50 85

  
51
BOOST_AUTO_TEST_CASE(test_convert_types_be_sc16){
52
    sc16_t in_sc16[] = {
53
        sc16_t(0, -1234), sc16_t(4321, 1234),
54
        sc16_t(9876, -4567), sc16_t(8912, 0)
55
    }, out_sc16[4];
86
    //run the loopback and test
87
    loopback(nsamps, io_type, otw_type, input, output);
88
    BOOST_CHECK_EQUAL_COLLECTIONS(input.begin(), input.end(), output.begin(), output.end());
89
}
56 90

  
91
BOOST_AUTO_TEST_CASE(test_convert_types_be_sc16){
57 92
    io_type_t io_type(io_type_t::COMPLEX_INT16);
58 93
    otw_type_t otw_type;
59 94
    otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN;
60 95
    otw_type.width = 16;
61 96

  
62
    loopback<sc16_t, boost::uint32_t, 4>(io_type, otw_type, in_sc16, out_sc16);
63
    BOOST_CHECK_EQUAL_COLLECTIONS(in_sc16, in_sc16+4, out_sc16, out_sc16+4);
97
    //try various lengths to test edge cases
98
    for (size_t nsamps = 0; nsamps < 16; nsamps++){
99
        test_convert_types_sc16(nsamps, io_type, otw_type);
100
    }
64 101
}
65 102

  
66 103
BOOST_AUTO_TEST_CASE(test_convert_types_le_sc16){
67
    sc16_t in_sc16[] = {
68
        sc16_t(0, -1234), sc16_t(4321, 1234),
69
        sc16_t(9876, -4567), sc16_t(8912, 0)
70
    }, out_sc16[4];
71

  
72 104
    io_type_t io_type(io_type_t::COMPLEX_INT16);
73 105
    otw_type_t otw_type;
74 106
    otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN;
75 107
    otw_type.width = 16;
76 108

  
77
    loopback<sc16_t, boost::uint32_t, 4>(io_type, otw_type, in_sc16, out_sc16);
78
    BOOST_CHECK_EQUAL_COLLECTIONS(in_sc16, in_sc16+4, out_sc16, out_sc16+4);
109
    //try various lengths to test edge cases
110
    for (size_t nsamps = 0; nsamps < 16; nsamps++){
111
        test_convert_types_sc16(nsamps, io_type, otw_type);
112
    }
79 113
}
80 114

  
81
typedef std::complex<float> fc32_t;
82

  
83
#define BOOST_CHECK_CLOSE_COMPLEX(a1, a2, p) \
84
    BOOST_CHECK_CLOSE(a1.real(), a2.real(), p); \
85
    BOOST_CHECK_CLOSE(a1.imag(), a2.imag(), p);
115
/***********************************************************************
116
 * Test float conversion
117
 **********************************************************************/
118
static void test_convert_types_fc32(
119
    size_t nsamps,
120
    const io_type_t &io_type,
121
    const otw_type_t &otw_type
122
){
123
    //fill the input samples
124
    std::vector<fc32_t> input(nsamps), output(nsamps);
125
    BOOST_FOREACH(fc32_t &in, input) in = fc32_t(
126
        (std::rand()/float(RAND_MAX/2)) - 1,
127
        (std::rand()/float(RAND_MAX/2)) - 1
128
    );
86 129

  
87
static const float tolerance = float(0.1);
130
    //run the loopback and test
131
    loopback(nsamps, io_type, otw_type, input, output);
132
    for (size_t i = 0; i < nsamps; i++){
133
        BOOST_CHECK_CLOSE_FRACTION(input[i].real(), output[i].real(), float(0.01));
134
        BOOST_CHECK_CLOSE_FRACTION(input[i].imag(), output[i].imag(), float(0.01));
135
    }
136
}
88 137

  
89 138
BOOST_AUTO_TEST_CASE(test_convert_types_be_fc32){
90
    fc32_t in_fc32[] = {
91
        fc32_t(float(0), float(-0.2)), fc32_t(float(0.03), float(-0.16)),
92
        fc32_t(float(1.0), float(.45)), fc32_t(float(0.09), float(0))
93
    }, out_fc32[4];
94

  
95 139
    io_type_t io_type(io_type_t::COMPLEX_FLOAT32);
96 140
    otw_type_t otw_type;
97 141
    otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN;
98 142
    otw_type.width = 16;
99 143

  
100
    loopback<fc32_t, boost::uint32_t, 4>(io_type, otw_type, in_fc32, out_fc32);
101

  
102
    BOOST_CHECK_CLOSE_COMPLEX(in_fc32[0], out_fc32[0], tolerance);
103
    BOOST_CHECK_CLOSE_COMPLEX(in_fc32[1], out_fc32[1], tolerance);
104
    BOOST_CHECK_CLOSE_COMPLEX(in_fc32[2], out_fc32[2], tolerance);
105
    BOOST_CHECK_CLOSE_COMPLEX(in_fc32[3], out_fc32[3], tolerance);
144
    //try various lengths to test edge cases
145
    for (size_t nsamps = 0; nsamps < 16; nsamps++){
146
        test_convert_types_fc32(nsamps, io_type, otw_type);
147
    }
106 148
}
107 149

  
108 150
BOOST_AUTO_TEST_CASE(test_convert_types_le_fc32){
109
    fc32_t in_fc32[] = {
110
        fc32_t(float(0), float(-0.2)), fc32_t(float(0.03), float(-0.16)),
111
        fc32_t(float(1.0), float(.45)), fc32_t(float(0.09), float(0))
112
    }, out_fc32[4];
113

  
114 151
    io_type_t io_type(io_type_t::COMPLEX_FLOAT32);
115 152
    otw_type_t otw_type;
116 153
    otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN;
117 154
    otw_type.width = 16;
118 155

  
119
    loopback<fc32_t, boost::uint32_t, 4>(io_type, otw_type, in_fc32, out_fc32);
120

  
121
    BOOST_CHECK_CLOSE_COMPLEX(in_fc32[0], out_fc32[0], tolerance);
122
    BOOST_CHECK_CLOSE_COMPLEX(in_fc32[1], out_fc32[1], tolerance);
123
    BOOST_CHECK_CLOSE_COMPLEX(in_fc32[2], out_fc32[2], tolerance);
124
    BOOST_CHECK_CLOSE_COMPLEX(in_fc32[3], out_fc32[3], tolerance);
156
    //try various lengths to test edge cases
157
    for (size_t nsamps = 0; nsamps < 16; nsamps++){
158
        test_convert_types_fc32(nsamps, io_type, otw_type);
159
    }
125 160
}

Also available in: Unified diff