summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2012-02-07 11:59:42 -0800
committerJosh Blum <josh@joshknows.com>2012-02-07 11:59:42 -0800
commit893af3dc280a5d85be2a5beb266dba9bb538292c (patch)
tree3b54de36da0ab661d4cef45467fb2f7eb4698229
parent5eec31fab45649b529428cda756d04bcdaeb3134 (diff)
downloaduhd-893af3dc280a5d85be2a5beb266dba9bb538292c.tar.gz
uhd-893af3dc280a5d85be2a5beb266dba9bb538292c.tar.bz2
uhd-893af3dc280a5d85be2a5beb266dba9bb538292c.zip
uhd: added sc8 conversion tests
-rw-r--r--host/lib/convert/convert_common.hpp2
-rw-r--r--host/lib/convert/convert_with_tables.cpp71
-rw-r--r--host/lib/convert/gen_convert_general.py2
-rw-r--r--host/tests/convert_test.cpp74
4 files changed, 139 insertions, 10 deletions
diff --git a/host/lib/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp
index aab59de4b..55bc2e99d 100644
--- a/host/lib/convert/convert_common.hpp
+++ b/host/lib/convert/convert_common.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
diff --git a/host/lib/convert/convert_with_tables.cpp b/host/lib/convert/convert_with_tables.cpp
index 2379739a7..4a3ce29b2 100644
--- a/host/lib/convert/convert_with_tables.cpp
+++ b/host/lib/convert/convert_with_tables.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -27,6 +27,55 @@ static const size_t sc16_table_len = size_t(1 << 16);
typedef boost::uint16_t (*tohost16_type)(boost::uint16_t);
/***********************************************************************
+ * Implementation for sc16 to sc8 lookup table
+ * - Lookup the real and imaginary parts individually
+ **********************************************************************/
+template <bool swap>
+class convert_sc16_1_to_sc8_item32_1 : public converter{
+public:
+ convert_sc16_1_to_sc8_item32_1(void): _table(sc16_table_len){}
+
+ void set_scalar(const double scalar){
+ for (size_t i = 0; i < sc16_table_len; i++){
+ const boost::int16_t val = boost::uint16_t(i);
+ _table[i] = boost::int8_t(boost::math::iround(val * scalar / 32767.));
+ }
+ }
+
+ void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps){
+ const sc16_t *input = reinterpret_cast<const sc16_t *>(inputs[0]);
+ item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
+
+ const size_t num_pairs = nsamps/2;
+ for (size_t i = 0, j = 0; i < num_pairs; i++, j+=2){
+ output[i] = this->lookup(input[j], input[j+1]);
+ }
+
+ if (nsamps != num_pairs*2){
+ output[num_pairs] = this->lookup(input[nsamps-1], 0);;
+ }
+ }
+
+ item32_t lookup(const sc16_t &in0, const sc16_t &in1){
+ if (swap){ //hope this compiles out, its a template constant
+ return
+ (item32_t(_table[size_t(in0.real())]) << 16) |
+ (item32_t(_table[size_t(in0.imag())]) << 24) |
+ (item32_t(_table[size_t(in1.real())]) << 0) |
+ (item32_t(_table[size_t(in1.imag())]) << 8) ;
+ }
+ return
+ (item32_t(_table[size_t(in0.real())]) << 8) |
+ (item32_t(_table[size_t(in0.imag())]) << 0) |
+ (item32_t(_table[size_t(in1.real())]) << 24) |
+ (item32_t(_table[size_t(in1.imag())]) << 16) ;
+ }
+
+private:
+ std::vector<boost::uint8_t> _table;
+};
+
+/***********************************************************************
* Implementation for sc16 lookup table
* - Lookup the real and imaginary parts individually
**********************************************************************/
@@ -121,9 +170,13 @@ private:
#ifdef BOOST_BIG_ENDIAN
# define SHIFT_PAIR0 16, 0
# define SHIFT_PAIR1 0, 16
+# define BE_SWAP false
+# define LE_SWAP true
#else
# define SHIFT_PAIR0 0, 16
# define SHIFT_PAIR1 16, 0
+# define BE_SWAP true
+# define LE_SWAP false
#endif
static converter::sptr make_convert_sc16_item32_be_1_to_fc32_1(void){
@@ -166,6 +219,14 @@ static converter::sptr make_convert_sc8_item32_le_1_to_sc16_1(void){
return converter::sptr(new convert_sc8_item32_1_to_fcxx_1<s16_t, uhd::wtohx, SHIFT_PAIR0>());
}
+static converter::sptr make_convert_sc16_1_to_sc8_item32_be_1(void){
+ return converter::sptr(new convert_sc16_1_to_sc8_item32_1<BE_SWAP>());
+}
+
+static converter::sptr make_convert_sc16_1_to_sc8_item32_le_1(void){
+ return converter::sptr(new convert_sc16_1_to_sc8_item32_1<LE_SWAP>());
+}
+
UHD_STATIC_BLOCK(register_convert_sc16_item32_1_to_fcxx_1){
uhd::convert::id_type id;
id.num_inputs = 1;
@@ -210,4 +271,12 @@ UHD_STATIC_BLOCK(register_convert_sc16_item32_1_to_fcxx_1){
id.output_format = "sc16";
id.input_format = "sc8_item32_le";
uhd::convert::register_converter(id, &make_convert_sc8_item32_le_1_to_sc16_1, PRIORITY_TABLE);
+
+ id.output_format = "sc16";
+ id.input_format = "sc8_item32_be";
+ uhd::convert::register_converter(id, &make_convert_sc16_1_to_sc8_item32_be_1, PRIORITY_TABLE);
+
+ id.output_format = "sc16";
+ id.input_format = "sc8_item32_le";
+ uhd::convert::register_converter(id, &make_convert_sc16_1_to_sc8_item32_le_1, PRIORITY_TABLE);
}
diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py
index a6ae3f810..24729d0d5 100644
--- a/host/lib/convert/gen_convert_general.py
+++ b/host/lib/convert/gen_convert_general.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2011 Ettus Research LLC
+# Copyright 2011-2012 Ettus Research LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/host/tests/convert_test.cpp b/host/tests/convert_test.cpp
index 1a5d30080..519b7b711 100644
--- a/host/tests/convert_test.cpp
+++ b/host/tests/convert_test.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011-2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -67,13 +67,13 @@ template <typename Range> static void loopback(
* Test short conversion
**********************************************************************/
static void test_convert_types_sc16(
- size_t nsamps, convert::id_type &id
+ size_t nsamps, convert::id_type &id, const int extra_div = 1
){
//fill the input samples
std::vector<sc16_t> input(nsamps), output(nsamps);
BOOST_FOREACH(sc16_t &in, input) in = sc16_t(
- std::rand()-(RAND_MAX/2),
- std::rand()-(RAND_MAX/2)
+ short(((std::rand()/double(RAND_MAX/2)) - 1)*32767/extra_div),
+ short(((std::rand()/double(RAND_MAX/2)) - 1)*32767/extra_div)
);
//run the loopback and test
@@ -116,15 +116,15 @@ BOOST_AUTO_TEST_CASE(test_convert_types_le_sc16){
**********************************************************************/
template <typename data_type>
static void test_convert_types_for_floats(
- size_t nsamps, convert::id_type &id
+ size_t nsamps, convert::id_type &id, const double extra_scale = 1.0
){
typedef typename data_type::value_type value_type;
//fill the input samples
std::vector<data_type> input(nsamps), output(nsamps);
BOOST_FOREACH(data_type &in, input) in = data_type(
- (std::rand()/value_type(RAND_MAX/2)) - 1,
- (std::rand()/value_type(RAND_MAX/2)) - 1
+ ((std::rand()/value_type(RAND_MAX/2)) - 1)*extra_scale,
+ ((std::rand()/value_type(RAND_MAX/2)) - 1)*extra_scale
);
//run the loopback and test
@@ -280,3 +280,63 @@ BOOST_AUTO_TEST_CASE(test_convert_types_sc16_to_fc32){
MY_CHECK_CLOSE(input[i].imag()/float(32767), output[i].imag(), float(0.01));
}
}
+
+/***********************************************************************
+ * Test sc8 conversions
+ **********************************************************************/
+BOOST_AUTO_TEST_CASE(test_convert_types_fc64_and_sc8){
+ convert::id_type id;
+ id.input_format = "fc64";
+ id.num_inputs = 1;
+ id.num_outputs = 1;
+
+ //try various lengths to test edge cases
+ id.output_format = "sc8_item32_le";
+ for (size_t nsamps = 1; nsamps < 16; nsamps++){
+ test_convert_types_for_floats<fc64_t>(nsamps, id, 1./256);
+ }
+
+ //try various lengths to test edge cases
+ id.output_format = "sc8_item32_be";
+ for (size_t nsamps = 1; nsamps < 16; nsamps++){
+ test_convert_types_for_floats<fc64_t>(nsamps, id, 1./256);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_convert_types_fc32_and_sc8){
+ convert::id_type id;
+ id.input_format = "fc32";
+ id.num_inputs = 1;
+ id.num_outputs = 1;
+
+ //try various lengths to test edge cases
+ id.output_format = "sc8_item32_le";
+ for (size_t nsamps = 1; nsamps < 16; nsamps++){
+ test_convert_types_for_floats<fc32_t>(nsamps, id, 1./256);
+ }
+
+ //try various lengths to test edge cases
+ id.output_format = "sc8_item32_be";
+ for (size_t nsamps = 1; nsamps < 16; nsamps++){
+ test_convert_types_for_floats<fc32_t>(nsamps, id, 1./256);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_convert_types_sc16_and_sc8){
+ convert::id_type id;
+ id.input_format = "sc16";
+ id.num_inputs = 1;
+ id.num_outputs = 1;
+
+ //try various lengths to test edge cases
+ id.output_format = "sc8_item32_le";
+ for (size_t nsamps = 1; nsamps < 16; nsamps++){
+ test_convert_types_sc16(nsamps, id, 256);
+ }
+
+ //try various lengths to test edge cases
+ id.output_format = "sc8_item32_be";
+ for (size_t nsamps = 1; nsamps < 16; nsamps++){
+ test_convert_types_sc16(nsamps, id, 256);
+ }
+}