aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/convert
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-11-07 18:47:29 -0800
committerJosh Blum <josh@joshknows.com>2011-11-07 18:47:29 -0800
commite219ad10a6e86cd4edc748f2218e01a9890e108c (patch)
tree372f2e426781de9885889bec6aa98697006268ec /host/lib/convert
parent8ff8f206d317e8d9c026fef9228a80edc241f9d4 (diff)
parent11f1390bbde65c60f45962acb128cac1ce21e474 (diff)
downloaduhd-e219ad10a6e86cd4edc748f2218e01a9890e108c.tar.gz
uhd-e219ad10a6e86cd4edc748f2218e01a9890e108c.tar.bz2
uhd-e219ad10a6e86cd4edc748f2218e01a9890e108c.zip
Merge branch 'uhd_next'
Diffstat (limited to 'host/lib/convert')
-rw-r--r--host/lib/convert/CMakeLists.txt11
-rw-r--r--host/lib/convert/convert_common.hpp99
-rw-r--r--host/lib/convert/convert_fc32_with_sse2.cpp24
-rw-r--r--host/lib/convert/convert_fc64_with_sse2.cpp16
-rw-r--r--host/lib/convert/convert_impl.cpp124
-rw-r--r--host/lib/convert/convert_with_neon.cpp8
-rw-r--r--host/lib/convert/convert_with_orc.cpp12
-rw-r--r--host/lib/convert/gen_convert_general.py138
-rw-r--r--host/lib/convert/gen_convert_pred.py185
9 files changed, 305 insertions, 312 deletions
diff --git a/host/lib/convert/CMakeLists.txt b/host/lib/convert/CMakeLists.txt
index b260cb247..4cc421884 100644
--- a/host/lib/convert/CMakeLists.txt
+++ b/host/lib/convert/CMakeLists.txt
@@ -112,17 +112,6 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
LIBUHD_PYTHON_GEN_SOURCE(
- ${CMAKE_CURRENT_SOURCE_DIR}/gen_convert_pred.py
- ${CMAKE_CURRENT_BINARY_DIR}/convert_pred.hpp
-)
-
-INCLUDE(AddFileDependencies)
-ADD_FILE_DEPENDENCIES(
- ${CMAKE_CURRENT_SOURCE_DIR}/convert_impl.cpp
- ${CMAKE_CURRENT_BINARY_DIR}/convert_pred.hpp
-)
-
-LIBUHD_PYTHON_GEN_SOURCE(
${CMAKE_CURRENT_SOURCE_DIR}/gen_convert_general.py
${CMAKE_CURRENT_BINARY_DIR}/convert_general.cpp
)
diff --git a/host/lib/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp
index 7f513b124..34fb848c3 100644
--- a/host/lib/convert/convert_common.hpp
+++ b/host/lib/convert/convert_common.hpp
@@ -23,43 +23,58 @@
#include <boost/cstdint.hpp>
#include <complex>
-#define DECLARE_CONVERTER(fcn, prio) \
+#define _DECLARE_CONVERTER(fcn, in_form, num_in, out_form, num_out, prio) \
static void fcn( \
const uhd::convert::input_type &inputs, \
const uhd::convert::output_type &outputs, \
- size_t nsamps, double scale_factor \
+ const size_t nsamps, const double scale_factor \
); \
- UHD_STATIC_BLOCK(register_##fcn##_##prio){ \
- uhd::convert::register_converter(#fcn, fcn, prio); \
+ UHD_STATIC_BLOCK(__register_##fcn##_##prio){ \
+ uhd::convert::id_type id; \
+ id.input_format = #in_form; \
+ id.num_inputs = num_in; \
+ id.output_format = #out_form; \
+ id.num_outputs = num_out; \
+ uhd::convert::register_converter(id, fcn, prio); \
} \
static void fcn( \
const uhd::convert::input_type &inputs, \
const uhd::convert::output_type &outputs, \
- size_t nsamps, double scale_factor \
+ const size_t nsamps, const double scale_factor \
)
+#define DECLARE_CONVERTER(in_form, num_in, out_form, num_out, prio) \
+ _DECLARE_CONVERTER(__convert_##in_form##_##num_in##_##out_form##_##num_out, in_form, num_in, out_form, num_out, prio)
+
/***********************************************************************
* Typedefs
**********************************************************************/
typedef std::complex<double> fc64_t;
typedef std::complex<float> fc32_t;
+typedef std::complex<boost::int32_t> sc32_t;
typedef std::complex<boost::int16_t> sc16_t;
typedef std::complex<boost::int8_t> sc8_t;
+typedef double f64_t;
+typedef float f32_t;
+typedef boost::int32_t s32_t;
+typedef boost::int16_t s16_t;
+typedef boost::int8_t s8_t;
+
typedef boost::uint32_t item32_t;
/***********************************************************************
- * Convert complex short buffer to items32
+ * Convert complex short buffer to items32 sc16
**********************************************************************/
-static UHD_INLINE item32_t sc16_to_item32(sc16_t num, double){
+static UHD_INLINE item32_t sc16_to_item32_sc16(sc16_t num, double){
boost::uint16_t real = num.real();
boost::uint16_t imag = num.imag();
return (item32_t(real) << 16) | (item32_t(imag) << 0);
}
/***********************************************************************
- * Convert items32 buffer to complex short
+ * Convert items32 sc16 buffer to complex short
**********************************************************************/
-static UHD_INLINE sc16_t item32_to_sc16(item32_t item, double){
+static UHD_INLINE sc16_t item32_sc16_to_sc16(item32_t item, double){
return sc16_t(
boost::int16_t(item >> 16),
boost::int16_t(item >> 0)
@@ -67,41 +82,83 @@ static UHD_INLINE sc16_t item32_to_sc16(item32_t item, double){
}
/***********************************************************************
- * Convert complex float buffer to items32 (no swap)
+ * Convert complex float buffer to items32 sc16
**********************************************************************/
-static UHD_INLINE item32_t fc32_to_item32(fc32_t num, float scale_factor){
- boost::uint16_t real = boost::int16_t(num.real()*scale_factor);
- boost::uint16_t imag = boost::int16_t(num.imag()*scale_factor);
+static UHD_INLINE item32_t fc32_to_item32_sc16(fc32_t num, double scale_factor){
+ boost::uint16_t real = boost::int16_t(num.real()*float(scale_factor));
+ boost::uint16_t imag = boost::int16_t(num.imag()*float(scale_factor));
return (item32_t(real) << 16) | (item32_t(imag) << 0);
}
/***********************************************************************
- * Convert items32 buffer to complex float
+ * Convert items32 sc16 buffer to complex float
**********************************************************************/
-static UHD_INLINE fc32_t item32_to_fc32(item32_t item, float scale_factor){
+static UHD_INLINE fc32_t item32_sc16_to_fc32(item32_t item, double scale_factor){
return fc32_t(
- float(boost::int16_t(item >> 16)*scale_factor),
- float(boost::int16_t(item >> 0)*scale_factor)
+ float(boost::int16_t(item >> 16)*float(scale_factor)),
+ float(boost::int16_t(item >> 0)*float(scale_factor))
);
}
/***********************************************************************
- * Convert complex double buffer to items32 (no swap)
+ * Convert complex double buffer to items32 sc16
**********************************************************************/
-static UHD_INLINE item32_t fc64_to_item32(fc64_t num, double scale_factor){
+static UHD_INLINE item32_t fc64_to_item32_sc16(fc64_t num, double scale_factor){
boost::uint16_t real = boost::int16_t(num.real()*scale_factor);
boost::uint16_t imag = boost::int16_t(num.imag()*scale_factor);
return (item32_t(real) << 16) | (item32_t(imag) << 0);
}
/***********************************************************************
- * Convert items32 buffer to complex double
+ * Convert items32 sc16 buffer to complex double
**********************************************************************/
-static UHD_INLINE fc64_t item32_to_fc64(item32_t item, double scale_factor){
+static UHD_INLINE fc64_t item32_sc16_to_fc64(item32_t item, double scale_factor){
return fc64_t(
float(boost::int16_t(item >> 16)*scale_factor),
float(boost::int16_t(item >> 0)*scale_factor)
);
}
+/***********************************************************************
+ * Convert items32 sc8 buffer to complex short
+ **********************************************************************/
+static UHD_INLINE void item32_sc8_to_sc16(item32_t item, sc16_t &out0, sc16_t &out1, double){
+ out0 = sc16_t(
+ boost::int8_t(item >> 8),
+ boost::int8_t(item >> 0)
+ );
+ out1 = sc16_t(
+ boost::int8_t(item >> 24),
+ boost::int8_t(item >> 16)
+ );
+}
+
+/***********************************************************************
+ * Convert items32 sc8 buffer to complex float
+ **********************************************************************/
+static UHD_INLINE void item32_sc8_to_fc32(item32_t item, fc32_t &out0, fc32_t &out1, double scale_factor){
+ out0 = fc32_t(
+ float(boost::int8_t(item >> 8)*float(scale_factor)),
+ float(boost::int8_t(item >> 0)*float(scale_factor))
+ );
+ out1 = fc32_t(
+ float(boost::int8_t(item >> 24)*float(scale_factor)),
+ float(boost::int8_t(item >> 16)*float(scale_factor))
+ );
+}
+
+/***********************************************************************
+ * Convert items32 sc8 buffer to complex double
+ **********************************************************************/
+static UHD_INLINE void item32_sc8_to_fc64(item32_t item, fc64_t &out0, fc64_t &out1, double scale_factor){
+ out0 = fc64_t(
+ float(boost::int8_t(item >> 8)*scale_factor),
+ float(boost::int8_t(item >> 0)*scale_factor)
+ );
+ out1 = fc64_t(
+ float(boost::int8_t(item >> 24)*scale_factor),
+ float(boost::int8_t(item >> 16)*scale_factor)
+ );
+}
+
#endif /* INCLUDED_LIBUHD_CONVERT_COMMON_HPP */
diff --git a/host/lib/convert/convert_fc32_with_sse2.cpp b/host/lib/convert/convert_fc32_with_sse2.cpp
index 676e1561c..24a939d6c 100644
--- a/host/lib/convert/convert_fc32_with_sse2.cpp
+++ b/host/lib/convert/convert_fc32_with_sse2.cpp
@@ -21,7 +21,7 @@
using namespace uhd::convert;
-DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
+DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_SIMD){
const fc32_t *input = reinterpret_cast<const fc32_t *>(inputs[0]);
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
@@ -51,7 +51,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
//dispatch according to alignment
switch (size_t(input) & 0xf){
case 0x8:
- output[i] = fc32_to_item32(input[i], float(scale_factor)); i++;
+ output[i] = fc32_to_item32_sc16(input[i], float(scale_factor)); i++;
case 0x0:
convert_fc32_1_to_item32_1_nswap_guts(_)
break;
@@ -60,11 +60,11 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = fc32_to_item32(input[i], float(scale_factor));
+ output[i] = fc32_to_item32_sc16(input[i], float(scale_factor));
}
}
-DECLARE_CONVERTER(convert_fc32_1_to_item32_1_bswap, PRIORITY_CUSTOM){
+DECLARE_CONVERTER(fc32, 1, sc16_item32_be, 1, PRIORITY_SIMD){
const fc32_t *input = reinterpret_cast<const fc32_t *>(inputs[0]);
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
@@ -93,7 +93,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_bswap, PRIORITY_CUSTOM){
//dispatch according to alignment
switch (size_t(input) & 0xf){
case 0x8:
- output[i] = uhd::byteswap(fc32_to_item32(input[i], float(scale_factor))); i++;
+ output[i] = uhd::byteswap(fc32_to_item32_sc16(input[i], float(scale_factor))); i++;
case 0x0:
convert_fc32_1_to_item32_1_bswap_guts(_)
break;
@@ -102,11 +102,11 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_bswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = uhd::byteswap(fc32_to_item32(input[i], float(scale_factor)));
+ output[i] = uhd::byteswap(fc32_to_item32_sc16(input[i], float(scale_factor)));
}
}
-DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
+DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_SIMD){
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]);
@@ -138,7 +138,7 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
//dispatch according to alignment
switch (size_t(output) & 0xf){
case 0x8:
- output[i] = item32_to_fc32(input[i], float(scale_factor)); i++;
+ output[i] = item32_sc16_to_fc32(input[i], float(scale_factor)); i++;
case 0x0:
convert_item32_1_to_fc32_1_nswap_guts(_)
break;
@@ -147,11 +147,11 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = item32_to_fc32(input[i], float(scale_factor));
+ output[i] = item32_sc16_to_fc32(input[i], float(scale_factor));
}
}
-DECLARE_CONVERTER(convert_item32_1_to_fc32_1_bswap, PRIORITY_CUSTOM){
+DECLARE_CONVERTER(sc16_item32_be, 1, fc32, 1, PRIORITY_SIMD){
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]);
@@ -182,7 +182,7 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_bswap, PRIORITY_CUSTOM){
//dispatch according to alignment
switch (size_t(output) & 0xf){
case 0x8:
- output[i] = item32_to_fc32(uhd::byteswap(input[i]), float(scale_factor)); i++;
+ output[i] = item32_sc16_to_fc32(uhd::byteswap(input[i]), float(scale_factor)); i++;
case 0x0:
convert_item32_1_to_fc32_1_bswap_guts(_)
break;
@@ -191,6 +191,6 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_bswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = item32_to_fc32(uhd::byteswap(input[i]), float(scale_factor));
+ output[i] = item32_sc16_to_fc32(uhd::byteswap(input[i]), float(scale_factor));
}
}
diff --git a/host/lib/convert/convert_fc64_with_sse2.cpp b/host/lib/convert/convert_fc64_with_sse2.cpp
index 4d28396a4..837bb584e 100644
--- a/host/lib/convert/convert_fc64_with_sse2.cpp
+++ b/host/lib/convert/convert_fc64_with_sse2.cpp
@@ -21,7 +21,7 @@
using namespace uhd::convert;
-DECLARE_CONVERTER(convert_fc64_1_to_item32_1_nswap, PRIORITY_CUSTOM){
+DECLARE_CONVERTER(fc64, 1, sc16_item32_le, 1, PRIORITY_SIMD){
const fc64_t *input = reinterpret_cast<const fc64_t *>(inputs[0]);
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
@@ -64,11 +64,11 @@ DECLARE_CONVERTER(convert_fc64_1_to_item32_1_nswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = fc64_to_item32(input[i], scale_factor);
+ output[i] = fc64_to_item32_sc16(input[i], scale_factor);
}
}
-DECLARE_CONVERTER(convert_fc64_1_to_item32_1_bswap, PRIORITY_CUSTOM){
+DECLARE_CONVERTER(fc64, 1, sc16_item32_be, 1, PRIORITY_SIMD){
const fc64_t *input = reinterpret_cast<const fc64_t *>(inputs[0]);
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
@@ -110,11 +110,11 @@ DECLARE_CONVERTER(convert_fc64_1_to_item32_1_bswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = uhd::byteswap(fc64_to_item32(input[i], scale_factor));
+ output[i] = uhd::byteswap(fc64_to_item32_sc16(input[i], scale_factor));
}
}
-DECLARE_CONVERTER(convert_item32_1_to_fc64_1_nswap, PRIORITY_CUSTOM){
+DECLARE_CONVERTER(sc16_item32_le, 1, fc64, 1, PRIORITY_SIMD){
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
fc64_t *output = reinterpret_cast<fc64_t *>(outputs[0]);
@@ -159,11 +159,11 @@ DECLARE_CONVERTER(convert_item32_1_to_fc64_1_nswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = item32_to_fc64(input[i], scale_factor);
+ output[i] = item32_sc16_to_fc64(input[i], scale_factor);
}
}
-DECLARE_CONVERTER(convert_item32_1_to_fc64_1_bswap, PRIORITY_CUSTOM){
+DECLARE_CONVERTER(sc16_item32_be, 1, fc64, 1, PRIORITY_SIMD){
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
fc64_t *output = reinterpret_cast<fc64_t *>(outputs[0]);
@@ -207,6 +207,6 @@ DECLARE_CONVERTER(convert_item32_1_to_fc64_1_bswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = item32_to_fc64(uhd::byteswap(input[i]), scale_factor);
+ output[i] = item32_sc16_to_fc64(uhd::byteswap(input[i]), scale_factor);
}
}
diff --git a/host/lib/convert/convert_impl.cpp b/host/lib/convert/convert_impl.cpp
index 9b2cdcdc9..df03b44f9 100644
--- a/host/lib/convert/convert_impl.cpp
+++ b/host/lib/convert/convert_impl.cpp
@@ -18,11 +18,37 @@
#include <uhd/convert.hpp>
#include <uhd/utils/log.hpp>
#include <uhd/utils/static.hpp>
+#include <uhd/types/dict.hpp>
#include <uhd/exception.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/format.hpp>
+#include <complex>
using namespace uhd;
-#include "convert_pred.hpp"
+bool convert::operator==(const convert::id_type &lhs, const convert::id_type &rhs){
+ return true
+ and (lhs.input_format == rhs.input_format)
+ and (lhs.num_inputs == rhs.num_inputs)
+ and (lhs.output_format == rhs.output_format)
+ and (lhs.num_outputs == rhs.num_outputs)
+ ;
+}
+
+std::string convert::id_type::to_pp_string(void) const{
+ return str(boost::format(
+ "conversion ID\n"
+ " Input format: %s\n"
+ " Num inputs: %d\n"
+ " Output format: %s\n"
+ " Num outputs: %d\n"
+ )
+ % this->input_format
+ % this->num_inputs
+ % this->output_format
+ % this->num_outputs
+ );
+}
/***********************************************************************
* Define types for the function tables
@@ -30,56 +56,34 @@ using namespace uhd;
struct fcn_table_entry_type{
convert::priority_type prio;
convert::function_type fcn;
- fcn_table_entry_type(void)
- : prio(convert::PRIORITY_EMPTY), fcn(NULL){
- /* NOP */
- }
};
-typedef std::vector<fcn_table_entry_type> fcn_table_type;
/***********************************************************************
* Setup the table registry
**********************************************************************/
-UHD_SINGLETON_FCN(fcn_table_type, get_cpu_to_otw_table);
-UHD_SINGLETON_FCN(fcn_table_type, get_otw_to_cpu_table);
-
-fcn_table_type &get_table(dir_type dir){
- switch(dir){
- case DIR_OTW_TO_CPU: return get_otw_to_cpu_table();
- case DIR_CPU_TO_OTW: return get_cpu_to_otw_table();
- }
- UHD_THROW_INVALID_CODE_PATH();
-}
+typedef uhd::dict<convert::id_type, fcn_table_entry_type> fcn_table_type;
+UHD_SINGLETON_FCN(fcn_table_type, get_table);
/***********************************************************************
* The registry functions
**********************************************************************/
void uhd::convert::register_converter(
- const std::string &markup,
+ const id_type &id,
function_type fcn,
priority_type prio
){
- //extract the predicate and direction from the markup
- dir_type dir;
- pred_type pred = make_pred(markup, dir);
-
//get a reference to the function table
- fcn_table_type &table = get_table(dir);
-
- //resize the table so that its at least pred+1
- if (table.size() <= pred) table.resize(pred+1);
+ fcn_table_type &table = get_table();
//register the function if higher priority
- if (table[pred].prio < prio){
- table[pred].fcn = fcn;
- table[pred].prio = prio;
+ if (not table.has_key(id) or table[id].prio < prio){
+ table[id].fcn = fcn;
+ table[id].prio = prio;
}
//----------------------------------------------------------------//
- UHD_LOGV(always) << "register_converter: " << markup << std::endl
+ UHD_LOGV(always) << "register_converter: " << id.to_pp_string() << std::endl
<< " prio: " << prio << std::endl
- << " pred: " << pred << std::endl
- << " dir: " << dir << std::endl
<< std::endl
;
//----------------------------------------------------------------//
@@ -88,22 +92,50 @@ void uhd::convert::register_converter(
/***********************************************************************
* The converter functions
**********************************************************************/
-const convert::function_type &convert::get_converter_cpu_to_otw(
- const io_type_t &io_type,
- const otw_type_t &otw_type,
- size_t num_input_buffs,
- size_t num_output_buffs
-){
- pred_type pred = make_pred(io_type, otw_type, num_input_buffs, num_output_buffs);
- return get_cpu_to_otw_table().at(pred).fcn;
+convert::function_type convert::get_converter(const id_type &id){
+ if (get_table().has_key(id)) return get_table()[id].fcn;
+ throw uhd::key_error("Cannot find a conversion routine for " + id.to_pp_string());
}
-const convert::function_type &convert::get_converter_otw_to_cpu(
- const io_type_t &io_type,
- const otw_type_t &otw_type,
- size_t num_input_buffs,
- size_t num_output_buffs
+/***********************************************************************
+ * Mappings for item format to byte size for all items we can
+ **********************************************************************/
+typedef uhd::dict<std::string, size_t> item_size_type;
+UHD_SINGLETON_FCN(item_size_type, get_item_size_table);
+
+void register_bytes_per_item(
+ const std::string &format, const size_t size
){
- pred_type pred = make_pred(io_type, otw_type, num_input_buffs, num_output_buffs);
- return get_otw_to_cpu_table().at(pred).fcn;
+ get_item_size_table()[format] = size;
+}
+
+size_t convert::get_bytes_per_item(const std::string &format){
+ if (get_item_size_table().has_key(format)) return get_item_size_table()[format];
+
+ //OK. I am sorry about this.
+ //We didnt find a match, so lets find a match for the first term.
+ //This is partially a hack because of the way I append strings.
+ //But as long as life is kind, we can keep this.
+ const size_t pos = format.find("_");
+ if (pos != std::string::npos){
+ return get_bytes_per_item(format.substr(0, pos));
+ }
+
+ throw uhd::key_error("Cannot find an item size:\n" + format);
+}
+
+UHD_STATIC_BLOCK(convert_register_item_sizes){
+ //register standard complex types
+ get_item_size_table()["fc64"] = sizeof(std::complex<double>);
+ get_item_size_table()["fc32"] = sizeof(std::complex<float>);
+ get_item_size_table()["sc32"] = sizeof(std::complex<boost::int32_t>);
+ get_item_size_table()["sc16"] = sizeof(std::complex<boost::int16_t>);
+ get_item_size_table()["sc8"] = sizeof(std::complex<boost::int8_t>);
+
+ //register standard real types
+ get_item_size_table()["f64"] = sizeof(double);
+ get_item_size_table()["f32"] = sizeof(float);
+ get_item_size_table()["s32"] = sizeof(boost::int32_t);
+ get_item_size_table()["s16"] = sizeof(boost::int16_t);
+ get_item_size_table()["s8"] = sizeof(boost::int8_t);
}
diff --git a/host/lib/convert/convert_with_neon.cpp b/host/lib/convert/convert_with_neon.cpp
index e5f08cad9..c7ad62104 100644
--- a/host/lib/convert/convert_with_neon.cpp
+++ b/host/lib/convert/convert_with_neon.cpp
@@ -20,7 +20,7 @@
using namespace uhd::convert;
-DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
+DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_SIMD){
const fc32_t *input = reinterpret_cast<const fc32_t *>(inputs[0]);
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
@@ -37,10 +37,10 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
}
for (; i < nsamps; i++)
- output[i] = fc32_to_item32(input[i], float(scale_factor));
+ output[i] = fc32_to_item32_sc16(input[i], scale_factor);
}
-DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
+DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_SIMD){
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]);
@@ -57,5 +57,5 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
}
for (; i < nsamps; i++)
- output[i] = item32_to_fc32(input[i], float(scale_factor));
+ output[i] = item32_sc16_to_fc32(input[i], scale_factor);
}
diff --git a/host/lib/convert/convert_with_orc.cpp b/host/lib/convert/convert_with_orc.cpp
index 844c2595c..0c46bcf1e 100644
--- a/host/lib/convert/convert_with_orc.cpp
+++ b/host/lib/convert/convert_with_orc.cpp
@@ -29,26 +29,26 @@ extern void _convert_sc16_1_to_item32_1_nswap_orc(void *, const void *, float, i
extern void _convert_item32_1_to_sc16_1_nswap_orc(void *, const void *, float, int);
}
-DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_LIBORC){
+DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_LIBORC){
_convert_fc32_1_to_item32_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
}
-DECLARE_CONVERTER(convert_fc32_1_to_item32_1_bswap, PRIORITY_LIBORC){
+DECLARE_CONVERTER(fc32, 1, sc16_item32_be, 1, PRIORITY_LIBORC){
_convert_fc32_1_to_item32_1_bswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
}
-DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_LIBORC){
+DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_LIBORC){
_convert_item32_1_to_fc32_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
}
-DECLARE_CONVERTER(convert_item32_1_to_fc32_1_bswap, PRIORITY_LIBORC){
+DECLARE_CONVERTER(sc16_item32_be, 1, fc32, 1, PRIORITY_LIBORC){
_convert_item32_1_to_fc32_1_bswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
}
-DECLARE_CONVERTER(convert_sc16_1_to_item32_1_nswap, PRIORITY_LIBORC){
+DECLARE_CONVERTER(sc16, 1, sc16_item32_le, 1, PRIORITY_LIBORC){
_convert_sc16_1_to_item32_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
}
-DECLARE_CONVERTER(convert_item32_1_to_sc16_1_nswap, PRIORITY_LIBORC){
+DECLARE_CONVERTER(sc16_item32_le, 1, sc16, 1, PRIORITY_LIBORC){
_convert_item32_1_to_sc16_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
}
diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py
index 8c3138bda..52b4212b4 100644
--- a/host/lib/convert/gen_convert_general.py
+++ b/host/lib/convert/gen_convert_general.py
@@ -28,48 +28,127 @@ TMPL_HEADER = """
using namespace uhd::convert;
"""
-TMPL_CONV_TO_FROM_ITEM32_1 = """
-DECLARE_CONVERTER(convert_$(cpu_type)_1_to_item32_1_$(swap), PRIORITY_GENERAL){
+TMPL_CONV_GEN2_ITEM32 = """
+DECLARE_CONVERTER(item32, 1, sc16_item32_$(end), 1, PRIORITY_GENERAL){
+ const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
+ item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
+
+ if (scale_factor == 0){} //avoids unused warning
+
+ for (size_t i = 0; i < nsamps; i++){
+ output[i] = $(to_wire)(input[i]);
+ }
+}
+
+DECLARE_CONVERTER(sc16_item32_$(end), 1, item32, 1, PRIORITY_GENERAL){
+ const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
+ item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
+
+ if (scale_factor == 0){} //avoids unused warning
+
+ for (size_t i = 0; i < nsamps; i++){
+ output[i] = $(to_host)(input[i]);
+ }
+}
+"""
+
+TMPL_CONV_GEN2_COMPLEX = """
+DECLARE_CONVERTER($(cpu_type), 1, sc16_item32_$(end), 1, PRIORITY_GENERAL){
const $(cpu_type)_t *input = reinterpret_cast<const $(cpu_type)_t *>(inputs[0]);
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
for (size_t i = 0; i < nsamps; i++){
- output[i] = $(swap_fcn)($(cpu_type)_to_item32(input[i], float(scale_factor)));
+ output[i] = $(to_wire)($(cpu_type)_to_item32_sc16(input[i], scale_factor));
}
}
-DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_1_$(swap), PRIORITY_GENERAL){
+DECLARE_CONVERTER(sc16_item32_$(end), 1, $(cpu_type), 1, PRIORITY_GENERAL){
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
$(cpu_type)_t *output = reinterpret_cast<$(cpu_type)_t *>(outputs[0]);
for (size_t i = 0; i < nsamps; i++){
- output[i] = item32_to_$(cpu_type)($(swap_fcn)(input[i]), float(scale_factor));
+ output[i] = item32_sc16_to_$(cpu_type)($(to_host)(input[i]), scale_factor);
+ }
+}
+
+DECLARE_CONVERTER(sc8_item32_$(end), 1, $(cpu_type), 1, PRIORITY_GENERAL){
+ const item32_t *input = reinterpret_cast<const item32_t *>(size_t(inputs[0]) & ~0x3);
+ $(cpu_type)_t *output = reinterpret_cast<$(cpu_type)_t *>(outputs[0]);
+ $(cpu_type)_t dummy;
+ size_t num_samps = nsamps;
+
+ if ((size_t(inputs[0]) & 0x3) != 0){
+ const item32_t item0 = $(to_host)(*input++);
+ item32_sc8_to_$(cpu_type)(item0, dummy, *output++, scale_factor);
+ num_samps--;
+ }
+
+ const size_t num_pairs = num_samps/2;
+ for (size_t i = 0, j = 0; i < num_pairs; i++, j+=2){
+ const item32_t item_i = $(to_host)(input[i]);
+ item32_sc8_to_$(cpu_type)(item_i, output[j], output[j+1], scale_factor);
+ }
+
+ if (num_samps != num_pairs*2){
+ const item32_t item_n = $(to_host)(input[num_pairs]);
+ item32_sc8_to_$(cpu_type)(item_n, output[num_samps-1], dummy, scale_factor);
}
}
"""
-TMPL_CONV_TO_FROM_ITEM32_X = """
-DECLARE_CONVERTER(convert_$(cpu_type)_$(width)_to_item32_1_$(swap), PRIORITY_GENERAL){
+
+TMPL_CONV_USRP1_COMPLEX = """
+DECLARE_CONVERTER($(cpu_type), $(width), sc16_item16_usrp1, 1, PRIORITY_GENERAL){
#for $w in range($width)
const $(cpu_type)_t *input$(w) = reinterpret_cast<const $(cpu_type)_t *>(inputs[$(w)]);
#end for
- item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
+ boost::uint16_t *output = reinterpret_cast<boost::uint16_t *>(outputs[0]);
+
+ if (scale_factor == 0){} //avoids unused warning
for (size_t i = 0, j = 0; i < nsamps; i++){
#for $w in range($width)
- output[j++] = $(swap_fcn)($(cpu_type)_to_item32(input$(w)[i], float(scale_factor)));
+ output[j++] = $(to_wire)(boost::int16_t(input$(w)[i].real()$(do_scale)));
+ output[j++] = $(to_wire)(boost::int16_t(input$(w)[i].imag()$(do_scale)));
#end for
}
}
-DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_$(width)_$(swap), PRIORITY_GENERAL){
- const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
+DECLARE_CONVERTER(sc16_item16_usrp1, 1, $(cpu_type), $(width), PRIORITY_GENERAL){
+ const boost::uint16_t *input = reinterpret_cast<const boost::uint16_t *>(inputs[0]);
+ #for $w in range($width)
+ $(cpu_type)_t *output$(w) = reinterpret_cast<$(cpu_type)_t *>(outputs[$(w)]);
+ #end for
+
+ if (scale_factor == 0){} //avoids unused warning
+
+ for (size_t i = 0, j = 0; i < nsamps; i++){
+ #for $w in range($width)
+ output$(w)[i] = $(cpu_type)_t(
+ boost::int16_t($(to_host)(input[j+0]))$(do_scale),
+ boost::int16_t($(to_host)(input[j+1]))$(do_scale)
+ );
+ j += 2;
+ #end for
+ }
+}
+
+DECLARE_CONVERTER(sc8_item16_usrp1, 1, $(cpu_type), $(width), PRIORITY_GENERAL){
+ const boost::uint16_t *input = reinterpret_cast<const boost::uint16_t *>(inputs[0]);
#for $w in range($width)
$(cpu_type)_t *output$(w) = reinterpret_cast<$(cpu_type)_t *>(outputs[$(w)]);
#end for
+ if (scale_factor == 0){} //avoids unused warning
+
for (size_t i = 0, j = 0; i < nsamps; i++){
#for $w in range($width)
- output$(w)[i] = item32_to_$(cpu_type)($(swap_fcn)(input[j++]), float(scale_factor));
+ {
+ const boost::uint16_t num = $(to_host)(input[j++]);
+ output$(w)[i] = $(cpu_type)_t(
+ boost::int8_t(num)$(do_scale),
+ boost::int8_t(num >> 8)$(do_scale)
+ );
+ }
#end for
}
}
@@ -83,11 +162,32 @@ if __name__ == '__main__':
import sys, os
file = os.path.basename(__file__)
output = parse_tmpl(TMPL_HEADER, file=file)
- for width in 1, 2, 3, 4:
- for swap, swap_fcn in (('nswap', ''), ('bswap', 'uhd::byteswap')):
- for cpu_type in 'fc64', 'fc32', 'sc16':
- output += parse_tmpl(
- TMPL_CONV_TO_FROM_ITEM32_1 if width == 1 else TMPL_CONV_TO_FROM_ITEM32_X,
- width=width, swap=swap, swap_fcn=swap_fcn, cpu_type=cpu_type
- )
+
+ #generate complex converters for all gen2 platforms
+ for end, to_host, to_wire in (
+ ('be', 'uhd::ntohx', 'uhd::htonx'),
+ ('le', 'uhd::wtohx', 'uhd::htowx'),
+ ):
+ for cpu_type in 'fc64', 'fc32', 'sc16':
+ output += parse_tmpl(
+ TMPL_CONV_GEN2_COMPLEX,
+ end=end, to_host=to_host, to_wire=to_wire, cpu_type=cpu_type
+ )
+ output += parse_tmpl(
+ TMPL_CONV_GEN2_ITEM32,
+ end=end, to_host=to_host, to_wire=to_wire
+ )
+
+ #generate complex converters for usrp1 format
+ for width in 1, 2, 4:
+ for cpu_type, do_scale in (
+ ('fc64', '*scale_factor'),
+ ('fc32', '*float(scale_factor)'),
+ ('sc16', ''),
+ ):
+ output += parse_tmpl(
+ TMPL_CONV_USRP1_COMPLEX,
+ width=width, to_host='uhd::wtohx', to_wire='uhd::htowx',
+ cpu_type=cpu_type, do_scale=do_scale
+ )
open(sys.argv[1], 'w').write(output)
diff --git a/host/lib/convert/gen_convert_pred.py b/host/lib/convert/gen_convert_pred.py
deleted file mode 100644
index 360fbcf44..000000000
--- a/host/lib/convert/gen_convert_pred.py
+++ /dev/null
@@ -1,185 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2011-2011 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
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-
-TMPL_TEXT = """
-#import time
-/***********************************************************************
- * This file was generated by $file on $time.strftime("%c")
- **********************************************************************/
-\#include <uhd/exception.hpp>
-\#include <boost/tokenizer.hpp>
-\#include <boost/lexical_cast.hpp>
-\#include <boost/detail/endian.hpp>
-\#include <boost/cstdint.hpp>
-\#include <string>
-\#include <vector>
-
-typedef size_t pred_type;
-typedef std::vector<pred_type> pred_vector_type;
-
-enum dir_type{
- DIR_OTW_TO_CPU = 0,
- DIR_CPU_TO_OTW = 1
-};
-
-struct pred_error : uhd::value_error{
- pred_error(const std::string &what):
- uhd::value_error("convert::make_pred: " + what)
- {
- /* NOP */
- }
-};
-
-pred_type make_pred(const std::string &markup, dir_type &dir){
- pred_type pred = 0;
-
- try{
- boost::tokenizer<boost::char_separator<char> > tokenizer(markup, boost::char_separator<char>("_"));
- std::vector<std::string> tokens(tokenizer.begin(), tokenizer.end());
- //token 0 is <convert>
- std::string inp_type = tokens.at(1);
- std::string num_inps = tokens.at(2);
- //token 3 is <to>
- std::string out_type = tokens.at(4);
- std::string num_outs = tokens.at(5);
- std::string swap_type = tokens.at(6);
-
- std::string cpu_type, otw_type;
- if (inp_type.find("item") == std::string::npos){
- cpu_type = inp_type;
- otw_type = out_type;
- dir = DIR_CPU_TO_OTW;
- }
- else{
- cpu_type = out_type;
- otw_type = inp_type;
- dir = DIR_OTW_TO_CPU;
- }
-
- if (cpu_type == "fc64") pred |= $ph.fc64_p;
- else if (cpu_type == "fc32") pred |= $ph.fc32_p;
- else if (cpu_type == "sc16") pred |= $ph.sc16_p;
- else if (cpu_type == "sc8") pred |= $ph.sc8_p;
- else throw pred_error("unhandled io type " + cpu_type);
-
- if (otw_type == "item32") pred |= $ph.item32_p;
- else throw pred_error("unhandled otw type " + otw_type);
-
- int num_inputs = boost::lexical_cast<int>(num_inps);
- int num_outputs = boost::lexical_cast<int>(num_outs);
-
- switch(num_inputs*num_outputs){ //FIXME treated as one value
- case 1: pred |= $ph.chan1_p; break;
- case 2: pred |= $ph.chan2_p; break;
- case 3: pred |= $ph.chan3_p; break;
- case 4: pred |= $ph.chan4_p; break;
- default: throw pred_error("unhandled number of channels");
- }
-
- if (swap_type == "bswap") pred |= $ph.bswap_p;
- else if (swap_type == "nswap") pred |= $ph.nswap_p;
- else throw pred_error("unhandled swap type");
-
- }
- catch(...){
- throw pred_error("could not parse markup: " + markup);
- }
-
- return pred;
-}
-
-#define pred_table_wildcard pred_type(~0)
-#define pred_table_max_size size_t(128)
-#define pred_table_index(e) (pred_type(e) & 0x7f)
-
-static pred_vector_type get_pred_byte_order_table(void){
- pred_vector_type table(pred_table_max_size, pred_table_wildcard);
- \#ifdef BOOST_BIG_ENDIAN
- table[pred_table_index(otw_type_t::BO_BIG_ENDIAN)] = $ph.nswap_p;
- table[pred_table_index(otw_type_t::BO_LITTLE_ENDIAN)] = $ph.bswap_p;
- \#else
- table[pred_table_index(otw_type_t::BO_BIG_ENDIAN)] = $ph.bswap_p;
- table[pred_table_index(otw_type_t::BO_LITTLE_ENDIAN)] = $ph.nswap_p;
- \#endif
- table[pred_table_index(otw_type_t::BO_NATIVE)] = $ph.nswap_p;
- return table;
-}
-
-static pred_vector_type get_pred_io_type_table(void){
- pred_vector_type table(pred_table_max_size, pred_table_wildcard);
- table[pred_table_index(io_type_t::COMPLEX_FLOAT64)] = $ph.fc64_p;
- table[pred_table_index(io_type_t::COMPLEX_FLOAT32)] = $ph.fc32_p;
- table[pred_table_index(io_type_t::COMPLEX_INT16)] = $ph.sc16_p;
- return table;
-}
-
-static pred_vector_type get_pred_num_io_table(void){
- pred_vector_type table(pred_table_max_size, pred_table_wildcard);
- table[1] = $ph.chan1_p;
- table[2] = $ph.chan2_p;
- table[3] = $ph.chan3_p;
- table[4] = $ph.chan4_p;
- return table;
-}
-
-UHD_INLINE pred_type make_pred(
- const io_type_t &io_type,
- const otw_type_t &otw_type,
- size_t num_inputs,
- size_t num_outputs
-){
- pred_type pred = $ph.item32_p; //only item32 supported as of now
-
- static const pred_vector_type pred_byte_order_table(get_pred_byte_order_table());
- pred |= pred_byte_order_table[pred_table_index(otw_type.byteorder)];
-
- static const pred_vector_type pred_io_type_table(get_pred_io_type_table());
- pred |= pred_io_type_table[pred_table_index(io_type.tid)];
-
- static const pred_vector_type pred_num_io_table(get_pred_num_io_table());
- pred |= pred_num_io_table[pred_table_index(num_inputs*num_outputs)];
-
- if (pred == pred_table_wildcard) throw pred_error(
- "unhanded input combination for make_pred()"
- );
-
- return pred;
-}
-"""
-
-def parse_tmpl(_tmpl_text, **kwargs):
- from Cheetah.Template import Template
- return str(Template(_tmpl_text, kwargs))
-
-class ph:
- bswap_p = 0b00001
- nswap_p = 0b00000
- item32_p = 0b00000
- sc8_p = 0b00000
- sc16_p = 0b00010
- fc32_p = 0b00100
- fc64_p = 0b00110
- chan1_p = 0b00000
- chan2_p = 0b01000
- chan3_p = 0b10000
- chan4_p = 0b11000
-
-if __name__ == '__main__':
- import sys, os
- file = os.path.basename(__file__)
- open(sys.argv[1], 'w').write(parse_tmpl(TMPL_TEXT, file=file, ph=ph))