Statistics
| Branch: | Tag: | Revision:

root / host / test / convert_types_test.cpp @ 8c872ffb

History | View | Annotate | Download (5.1 kB)

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

    
27
using namespace uhd;
28

    
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,
48
    const io_type_t &io_type,
49
    const otw_type_t &otw_type,
50
    const Range &input,
51
    Range &output
52
){
53
    //item32 is largest device type
54
    std::vector<boost::uint32_t> dev(nsamps);
55

    
56
    //convert to dev type
57
    transport::convert_io_type_to_otw_type(
58
        pod2ptr(input), io_type,
59
        pod2ptr(dev), otw_type,
60
        nsamps
61
    );
62

    
63
    //convert back to host type
64
    transport::convert_otw_type_to_io_type(
65
        pod2ptr(dev), otw_type,
66
        pod2ptr(output), io_type,
67
        nsamps
68
    );
69
}
70

    
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
    );
85

    
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
}
90

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

    
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
    }
101
}
102

    
103
BOOST_AUTO_TEST_CASE(test_convert_types_le_sc16){
104
    io_type_t io_type(io_type_t::COMPLEX_INT16);
105
    otw_type_t otw_type;
106
    otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN;
107
    otw_type.width = 16;
108

    
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
    }
113
}
114

    
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
    );
129

    
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
}
137

    
138
BOOST_AUTO_TEST_CASE(test_convert_types_be_fc32){
139
    io_type_t io_type(io_type_t::COMPLEX_FLOAT32);
140
    otw_type_t otw_type;
141
    otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN;
142
    otw_type.width = 16;
143

    
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
    }
148
}
149

    
150
BOOST_AUTO_TEST_CASE(test_convert_types_le_fc32){
151
    io_type_t io_type(io_type_t::COMPLEX_FLOAT32);
152
    otw_type_t otw_type;
153
    otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN;
154
    otw_type.width = 16;
155

    
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
    }
160
}