Revision 52e20f9e
| b/host/include/uhd/convert.hpp | ||
|---|---|---|
| 19 | 19 |
#define INCLUDED_UHD_CONVERT_HPP |
| 20 | 20 |
|
| 21 | 21 |
#include <uhd/config.hpp> |
| 22 |
#include <uhd/types/io_type.hpp> |
|
| 23 |
#include <uhd/types/otw_type.hpp> |
|
| 24 | 22 |
#include <uhd/types/ref_vector.hpp> |
| 25 | 23 |
#include <boost/function.hpp> |
| 24 |
#include <boost/operators.hpp> |
|
| 26 | 25 |
#include <string> |
| 27 | 26 |
|
| 28 | 27 |
namespace uhd{ namespace convert{
|
| 29 | 28 |
|
| 30 | 29 |
typedef uhd::ref_vector<void *> output_type; |
| 31 | 30 |
typedef uhd::ref_vector<const void *> input_type; |
| 32 |
typedef boost::function<void(const input_type&, const output_type&, size_t, double)> function_type; |
|
| 31 |
|
|
| 32 |
//! input vectors, output vectors, num samples, scale factor |
|
| 33 |
typedef boost::function<void(const input_type&, const output_type&, const size_t, const double)> function_type; |
|
| 33 | 34 |
|
| 34 | 35 |
/*! |
| 35 | 36 |
* Describe the priority of a converter function. |
| ... | ... | |
| 45 | 46 |
PRIORITY_EMPTY = -1, |
| 46 | 47 |
}; |
| 47 | 48 |
|
| 49 |
//! Identify a conversion routine in the registry |
|
| 50 |
struct id_type : boost::equality_comparable<id_type>{
|
|
| 51 |
std::string input_markup; |
|
| 52 |
size_t num_inputs; |
|
| 53 |
std::string output_markup; |
|
| 54 |
size_t num_outputs; |
|
| 55 |
std::string args; |
|
| 56 |
std::string to_pp_string(void) const; |
|
| 57 |
}; |
|
| 58 |
|
|
| 59 |
//! Implement equality_comparable interface |
|
| 60 |
UHD_API bool operator==(const id_type &, const id_type &); |
|
| 61 |
|
|
| 48 | 62 |
/*! |
| 49 |
* Register a converter function that converts cpu type to/from otw type.
|
|
| 50 |
* \param markup representing the signature
|
|
| 63 |
* Register a converter function. |
|
| 64 |
* \param id identify the conversion
|
|
| 51 | 65 |
* \param fcn a pointer to the converter |
| 52 | 66 |
* \param prio the function priority |
| 53 | 67 |
*/ |
| 54 | 68 |
UHD_API void register_converter( |
| 55 |
const std::string &markup,
|
|
| 69 |
const id_type &id,
|
|
| 56 | 70 |
function_type fcn, |
| 57 | 71 |
priority_type prio |
| 58 | 72 |
); |
| 59 | 73 |
|
| 60 | 74 |
/*! |
| 61 |
* Get a converter function that converts cpu to otw. |
|
| 62 |
* \param io_type the type of the input samples |
|
| 63 |
* \param otw_type the type of the output samples |
|
| 64 |
* \param num_input_buffs the number of inputs |
|
| 65 |
* \param num_output_buffs the number of outputs |
|
| 75 |
* Get a converter function. |
|
| 76 |
* \param id identify the conversion |
|
| 77 |
* \return the converter function |
|
| 66 | 78 |
*/ |
| 67 |
UHD_API const function_type &get_converter_cpu_to_otw( |
|
| 68 |
const io_type_t &io_type, |
|
| 69 |
const otw_type_t &otw_type, |
|
| 70 |
size_t num_input_buffs, |
|
| 71 |
size_t num_output_buffs |
|
| 72 |
); |
|
| 79 |
UHD_API function_type get_converter(const id_type &id); |
|
| 73 | 80 |
|
| 74 | 81 |
/*! |
| 75 |
* Get a converter function that converts otw to cpu. |
|
| 76 |
* \param io_type the type of the input samples |
|
| 77 |
* \param otw_type the type of the output samples |
|
| 78 |
* \param num_input_buffs the number of inputs |
|
| 79 |
* \param num_output_buffs the number of outputs |
|
| 82 |
* Register the size of a particular item. |
|
| 83 |
* \param markup the item markup |
|
| 84 |
* \param size the size in bytes |
|
| 80 | 85 |
*/ |
| 81 |
UHD_API const function_type &get_converter_otw_to_cpu( |
|
| 82 |
const io_type_t &io_type, |
|
| 83 |
const otw_type_t &otw_type, |
|
| 84 |
size_t num_input_buffs, |
|
| 85 |
size_t num_output_buffs |
|
| 86 |
UHD_API void register_bytes_per_item( |
|
| 87 |
const std::string &markup, const size_t size |
|
| 86 | 88 |
); |
| 87 | 89 |
|
| 90 |
//! Convert an item markup to a size in bytes |
|
| 91 |
UHD_API size_t get_bytes_per_item(const std::string &markup); |
|
| 92 |
|
|
| 88 | 93 |
}} //namespace |
| 89 | 94 |
|
| 90 | 95 |
#endif /* INCLUDED_UHD_CONVERT_HPP */ |
| b/host/lib/convert/CMakeLists.txt | ||
|---|---|---|
| 112 | 112 |
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
|
| 113 | 113 |
|
| 114 | 114 |
LIBUHD_PYTHON_GEN_SOURCE( |
| 115 |
${CMAKE_CURRENT_SOURCE_DIR}/gen_convert_pred.py
|
|
| 116 |
${CMAKE_CURRENT_BINARY_DIR}/convert_pred.hpp
|
|
| 117 |
) |
|
| 118 |
|
|
| 119 |
INCLUDE(AddFileDependencies) |
|
| 120 |
ADD_FILE_DEPENDENCIES( |
|
| 121 |
${CMAKE_CURRENT_SOURCE_DIR}/convert_impl.cpp
|
|
| 122 |
${CMAKE_CURRENT_BINARY_DIR}/convert_pred.hpp
|
|
| 123 |
) |
|
| 124 |
|
|
| 125 |
LIBUHD_PYTHON_GEN_SOURCE( |
|
| 126 | 115 |
${CMAKE_CURRENT_SOURCE_DIR}/gen_convert_general.py
|
| 127 | 116 |
${CMAKE_CURRENT_BINARY_DIR}/convert_general.cpp
|
| 128 | 117 |
) |
| b/host/lib/convert/convert_common.hpp | ||
|---|---|---|
| 23 | 23 |
#include <boost/cstdint.hpp> |
| 24 | 24 |
#include <complex> |
| 25 | 25 |
|
| 26 |
#define DECLARE_CONVERTER(fcn, prio) \
|
|
| 26 |
#define _DECLARE_CONVERTER(fcn, in_mark, num_in, out_mark, num_out, prio) \
|
|
| 27 | 27 |
static void fcn( \ |
| 28 | 28 |
const uhd::convert::input_type &inputs, \ |
| 29 | 29 |
const uhd::convert::output_type &outputs, \ |
| 30 |
size_t nsamps, double scale_factor \ |
|
| 30 |
const size_t nsamps, \ |
|
| 31 |
const double scale_factor \ |
|
| 31 | 32 |
); \ |
| 32 |
UHD_STATIC_BLOCK(register_##fcn##_##prio){ \
|
|
| 33 |
uhd::convert::register_converter(#fcn, fcn, prio); \ |
|
| 33 |
UHD_STATIC_BLOCK(__register_##fcn##_##prio){ \
|
|
| 34 |
uhd::convert::id_type id; \ |
|
| 35 |
id.input_markup = #in_mark; \ |
|
| 36 |
id.num_inputs = num_in; \ |
|
| 37 |
id.output_markup = #out_mark; \ |
|
| 38 |
id.num_outputs = num_out; \ |
|
| 39 |
uhd::convert::register_converter(id, fcn, prio); \ |
|
| 34 | 40 |
} \ |
| 35 | 41 |
static void fcn( \ |
| 36 | 42 |
const uhd::convert::input_type &inputs, \ |
| 37 | 43 |
const uhd::convert::output_type &outputs, \ |
| 38 |
size_t nsamps, double scale_factor \ |
|
| 44 |
const size_t nsamps, \ |
|
| 45 |
const double scale_factor \ |
|
| 39 | 46 |
) |
| 40 | 47 |
|
| 48 |
#define DECLARE_CONVERTER(in_mark, num_in, out_mark, num_out, prio) \ |
|
| 49 |
_DECLARE_CONVERTER(__convert_##in_mark##_##num_in##_##out_mark##_##num_out, in_mark, num_in, out_mark, num_out, prio) |
|
| 50 |
|
|
| 41 | 51 |
/*********************************************************************** |
| 42 | 52 |
* Typedefs |
| 43 | 53 |
**********************************************************************/ |
| 44 | 54 |
typedef std::complex<double> fc64_t; |
| 45 | 55 |
typedef std::complex<float> fc32_t; |
| 56 |
typedef std::complex<boost::int32_t> sc32_t; |
|
| 46 | 57 |
typedef std::complex<boost::int16_t> sc16_t; |
| 47 | 58 |
typedef std::complex<boost::int8_t> sc8_t; |
| 59 |
typedef double f64_t; |
|
| 60 |
typedef float f32_t; |
|
| 61 |
typedef boost::int32_t s32_t; |
|
| 62 |
typedef boost::int16_t s16_t; |
|
| 63 |
typedef boost::int8_t s8_t; |
|
| 64 |
|
|
| 48 | 65 |
typedef boost::uint32_t item32_t; |
| 49 | 66 |
|
| 50 | 67 |
/*********************************************************************** |
| b/host/lib/convert/convert_fc32_with_sse2.cpp | ||
|---|---|---|
| 21 | 21 |
|
| 22 | 22 |
using namespace uhd::convert; |
| 23 | 23 |
|
| 24 |
DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
|
|
| 24 |
DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_CUSTOM){
|
|
| 25 | 25 |
const fc32_t *input = reinterpret_cast<const fc32_t *>(inputs[0]); |
| 26 | 26 |
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); |
| 27 | 27 |
|
| ... | ... | |
| 64 | 64 |
} |
| 65 | 65 |
} |
| 66 | 66 |
|
| 67 |
DECLARE_CONVERTER(convert_fc32_1_to_item32_1_bswap, PRIORITY_CUSTOM){
|
|
| 67 |
DECLARE_CONVERTER(fc32, 1, sc16_item32_be, 1, PRIORITY_CUSTOM){
|
|
| 68 | 68 |
const fc32_t *input = reinterpret_cast<const fc32_t *>(inputs[0]); |
| 69 | 69 |
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); |
| 70 | 70 |
|
| ... | ... | |
| 106 | 106 |
} |
| 107 | 107 |
} |
| 108 | 108 |
|
| 109 |
DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
|
|
| 109 |
DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_CUSTOM){
|
|
| 110 | 110 |
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); |
| 111 | 111 |
fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]); |
| 112 | 112 |
|
| ... | ... | |
| 151 | 151 |
} |
| 152 | 152 |
} |
| 153 | 153 |
|
| 154 |
DECLARE_CONVERTER(convert_item32_1_to_fc32_1_bswap, PRIORITY_CUSTOM){
|
|
| 154 |
DECLARE_CONVERTER(sc16_item32_be, 1, fc32, 1, PRIORITY_CUSTOM){
|
|
| 155 | 155 |
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); |
| 156 | 156 |
fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]); |
| 157 | 157 |
|
| b/host/lib/convert/convert_fc64_with_sse2.cpp | ||
|---|---|---|
| 21 | 21 |
|
| 22 | 22 |
using namespace uhd::convert; |
| 23 | 23 |
|
| 24 |
DECLARE_CONVERTER(convert_fc64_1_to_item32_1_nswap, PRIORITY_CUSTOM){
|
|
| 24 |
DECLARE_CONVERTER(fc64, 1, sc16_item32_le, 1, PRIORITY_CUSTOM){
|
|
| 25 | 25 |
const fc64_t *input = reinterpret_cast<const fc64_t *>(inputs[0]); |
| 26 | 26 |
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); |
| 27 | 27 |
|
| ... | ... | |
| 68 | 68 |
} |
| 69 | 69 |
} |
| 70 | 70 |
|
| 71 |
DECLARE_CONVERTER(convert_fc64_1_to_item32_1_bswap, PRIORITY_CUSTOM){
|
|
| 71 |
DECLARE_CONVERTER(fc64, 1, sc16_item32_be, 1, PRIORITY_CUSTOM){
|
|
| 72 | 72 |
const fc64_t *input = reinterpret_cast<const fc64_t *>(inputs[0]); |
| 73 | 73 |
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); |
| 74 | 74 |
|
| ... | ... | |
| 114 | 114 |
} |
| 115 | 115 |
} |
| 116 | 116 |
|
| 117 |
DECLARE_CONVERTER(convert_item32_1_to_fc64_1_nswap, PRIORITY_CUSTOM){
|
|
| 117 |
DECLARE_CONVERTER(sc16_item32_le, 1, fc64, 1, PRIORITY_CUSTOM){
|
|
| 118 | 118 |
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); |
| 119 | 119 |
fc64_t *output = reinterpret_cast<fc64_t *>(outputs[0]); |
| 120 | 120 |
|
| ... | ... | |
| 163 | 163 |
} |
| 164 | 164 |
} |
| 165 | 165 |
|
| 166 |
DECLARE_CONVERTER(convert_item32_1_to_fc64_1_bswap, PRIORITY_CUSTOM){
|
|
| 166 |
DECLARE_CONVERTER(sc16_item32_be, 1, fc64, 1, PRIORITY_CUSTOM){
|
|
| 167 | 167 |
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); |
| 168 | 168 |
fc64_t *output = reinterpret_cast<fc64_t *>(outputs[0]); |
| 169 | 169 |
|
| b/host/lib/convert/convert_impl.cpp | ||
|---|---|---|
| 18 | 18 |
#include <uhd/convert.hpp> |
| 19 | 19 |
#include <uhd/utils/log.hpp> |
| 20 | 20 |
#include <uhd/utils/static.hpp> |
| 21 |
#include <uhd/types/dict.hpp> |
|
| 21 | 22 |
#include <uhd/exception.hpp> |
| 23 |
#include <boost/cstdint.hpp> |
|
| 24 |
#include <boost/format.hpp> |
|
| 25 |
#include <complex> |
|
| 22 | 26 |
|
| 23 | 27 |
using namespace uhd; |
| 24 | 28 |
|
| 25 |
#include "convert_pred.hpp" |
|
| 29 |
bool convert::operator==(const convert::id_type &lhs, const convert::id_type &rhs){
|
|
| 30 |
return |
|
| 31 |
(lhs.input_markup == rhs.input_markup) and |
|
| 32 |
(lhs.num_inputs == rhs.num_inputs) and |
|
| 33 |
(lhs.output_markup == rhs.output_markup) and |
|
| 34 |
(lhs.num_outputs == rhs.num_outputs) and |
|
| 35 |
(lhs.args == rhs.args) |
|
| 36 |
; |
|
| 37 |
} |
|
| 38 |
|
|
| 39 |
std::string convert::id_type::to_pp_string(void) const{
|
|
| 40 |
return str(boost::format( |
|
| 41 |
"conversion ID\n" |
|
| 42 |
" Input markup: %s\n" |
|
| 43 |
" Num inputs: %d\n" |
|
| 44 |
" Output markup: %s\n" |
|
| 45 |
" Num outputs: %d\n" |
|
| 46 |
" Optional args: %s\n" |
|
| 47 |
) |
|
| 48 |
% this->input_markup |
|
| 49 |
% this->num_inputs |
|
| 50 |
% this->output_markup |
|
| 51 |
% this->num_outputs |
|
| 52 |
% this->args |
|
| 53 |
); |
|
| 54 |
} |
|
| 26 | 55 |
|
| 27 | 56 |
/*********************************************************************** |
| 28 | 57 |
* Define types for the function tables |
| ... | ... | |
| 30 | 59 |
struct fcn_table_entry_type{
|
| 31 | 60 |
convert::priority_type prio; |
| 32 | 61 |
convert::function_type fcn; |
| 33 |
fcn_table_entry_type(void) |
|
| 34 |
: prio(convert::PRIORITY_EMPTY), fcn(NULL){
|
|
| 35 |
/* NOP */ |
|
| 36 |
} |
|
| 37 | 62 |
}; |
| 38 |
typedef std::vector<fcn_table_entry_type> fcn_table_type; |
|
| 39 | 63 |
|
| 40 | 64 |
/*********************************************************************** |
| 41 | 65 |
* Setup the table registry |
| 42 | 66 |
**********************************************************************/ |
| 43 |
UHD_SINGLETON_FCN(fcn_table_type, get_cpu_to_otw_table); |
|
| 44 |
UHD_SINGLETON_FCN(fcn_table_type, get_otw_to_cpu_table); |
|
| 45 |
|
|
| 46 |
fcn_table_type &get_table(dir_type dir){
|
|
| 47 |
switch(dir){
|
|
| 48 |
case DIR_OTW_TO_CPU: return get_otw_to_cpu_table(); |
|
| 49 |
case DIR_CPU_TO_OTW: return get_cpu_to_otw_table(); |
|
| 50 |
} |
|
| 51 |
UHD_THROW_INVALID_CODE_PATH(); |
|
| 52 |
} |
|
| 67 |
typedef uhd::dict<convert::id_type, fcn_table_entry_type> fcn_table_type; |
|
| 68 |
UHD_SINGLETON_FCN(fcn_table_type, get_table); |
|
| 53 | 69 |
|
| 54 | 70 |
/*********************************************************************** |
| 55 | 71 |
* The registry functions |
| 56 | 72 |
**********************************************************************/ |
| 57 | 73 |
void uhd::convert::register_converter( |
| 58 |
const std::string &markup,
|
|
| 74 |
const id_type &id,
|
|
| 59 | 75 |
function_type fcn, |
| 60 | 76 |
priority_type prio |
| 61 | 77 |
){
|
| 62 |
//extract the predicate and direction from the markup |
|
| 63 |
dir_type dir; |
|
| 64 |
pred_type pred = make_pred(markup, dir); |
|
| 65 |
|
|
| 66 | 78 |
//get a reference to the function table |
| 67 |
fcn_table_type &table = get_table(dir); |
|
| 68 |
|
|
| 69 |
//resize the table so that its at least pred+1 |
|
| 70 |
if (table.size() <= pred) table.resize(pred+1); |
|
| 79 |
fcn_table_type &table = get_table(); |
|
| 71 | 80 |
|
| 72 | 81 |
//register the function if higher priority |
| 73 |
if (table[pred].prio < prio){
|
|
| 74 |
table[pred].fcn = fcn;
|
|
| 75 |
table[pred].prio = prio;
|
|
| 82 |
if (not table.has_key(id) or table[id].prio < prio){
|
|
| 83 |
table[id].fcn = fcn;
|
|
| 84 |
table[id].prio = prio;
|
|
| 76 | 85 |
} |
| 77 | 86 |
|
| 78 | 87 |
//----------------------------------------------------------------// |
| 79 |
UHD_LOGV(always) << "register_converter: " << markup << std::endl
|
|
| 88 |
UHD_LOGV(always) << "register_converter: " << id.to_pp_string() << std::endl
|
|
| 80 | 89 |
<< " prio: " << prio << std::endl |
| 81 |
<< " pred: " << pred << std::endl |
|
| 82 |
<< " dir: " << dir << std::endl |
|
| 83 | 90 |
<< std::endl |
| 84 | 91 |
; |
| 85 | 92 |
//----------------------------------------------------------------// |
| ... | ... | |
| 88 | 95 |
/*********************************************************************** |
| 89 | 96 |
* The converter functions |
| 90 | 97 |
**********************************************************************/ |
| 91 |
const convert::function_type &convert::get_converter_cpu_to_otw( |
|
| 92 |
const io_type_t &io_type, |
|
| 93 |
const otw_type_t &otw_type, |
|
| 94 |
size_t num_input_buffs, |
|
| 95 |
size_t num_output_buffs |
|
| 96 |
){
|
|
| 97 |
pred_type pred = make_pred(io_type, otw_type, num_input_buffs, num_output_buffs); |
|
| 98 |
return get_cpu_to_otw_table().at(pred).fcn; |
|
| 98 |
convert::function_type convert::get_converter(const id_type &id){
|
|
| 99 |
if (get_table().has_key(id)) return get_table()[id].fcn; |
|
| 100 |
throw uhd::key_error("Cannot find a conversion routine for " + id.to_pp_string());
|
|
| 99 | 101 |
} |
| 100 | 102 |
|
| 101 |
const convert::function_type &convert::get_converter_otw_to_cpu( |
|
| 102 |
const io_type_t &io_type, |
|
| 103 |
const otw_type_t &otw_type, |
|
| 104 |
size_t num_input_buffs, |
|
| 105 |
size_t num_output_buffs |
|
| 103 |
/*********************************************************************** |
|
| 104 |
* Mappings for item markup to byte size for all items we can |
|
| 105 |
**********************************************************************/ |
|
| 106 |
typedef uhd::dict<std::string, size_t> item_size_type; |
|
| 107 |
UHD_SINGLETON_FCN(item_size_type, get_item_size_table); |
|
| 108 |
|
|
| 109 |
void register_bytes_per_item( |
|
| 110 |
const std::string &markup, const size_t size |
|
| 106 | 111 |
){
|
| 107 |
pred_type pred = make_pred(io_type, otw_type, num_input_buffs, num_output_buffs); |
|
| 108 |
return get_otw_to_cpu_table().at(pred).fcn; |
|
| 112 |
get_item_size_table()[markup] = size; |
|
| 113 |
} |
|
| 114 |
|
|
| 115 |
size_t convert::get_bytes_per_item(const std::string &markup){
|
|
| 116 |
if (get_item_size_table().has_key(markup)) return get_item_size_table()[markup]; |
|
| 117 |
throw uhd::key_error("Cannot find an item size " + markup);
|
|
| 118 |
} |
|
| 119 |
|
|
| 120 |
UHD_STATIC_BLOCK(convert_register_item_sizes){
|
|
| 121 |
//register standard complex types |
|
| 122 |
get_item_size_table()["fc64"] = sizeof(std::complex<double>); |
|
| 123 |
get_item_size_table()["fc32"] = sizeof(std::complex<float>); |
|
| 124 |
get_item_size_table()["sc32"] = sizeof(std::complex<boost::int32_t>); |
|
| 125 |
get_item_size_table()["sc16"] = sizeof(std::complex<boost::int16_t>); |
|
| 126 |
get_item_size_table()["sc8"] = sizeof(std::complex<boost::int8_t>); |
|
| 127 |
|
|
| 128 |
//register standard real types |
|
| 129 |
get_item_size_table()["f64"] = sizeof(double); |
|
| 130 |
get_item_size_table()["f32"] = sizeof(float); |
|
| 131 |
get_item_size_table()["s32"] = sizeof(boost::int32_t); |
|
| 132 |
get_item_size_table()["s16"] = sizeof(boost::int16_t); |
|
| 133 |
get_item_size_table()["s8"] = sizeof(boost::int8_t); |
|
| 109 | 134 |
} |
| b/host/lib/convert/gen_convert_general.py | ||
|---|---|---|
| 29 | 29 |
""" |
| 30 | 30 |
|
| 31 | 31 |
TMPL_CONV_TO_FROM_ITEM32_1 = """ |
| 32 |
DECLARE_CONVERTER(convert_$(cpu_type)_1_to_item32_1_$(swap), PRIORITY_GENERAL){
|
|
| 32 |
DECLARE_CONVERTER($(cpu_type), 1, sc16_item32_$(end), 1, PRIORITY_GENERAL){
|
|
| 33 | 33 |
const $(cpu_type)_t *input = reinterpret_cast<const $(cpu_type)_t *>(inputs[0]); |
| 34 | 34 |
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); |
| 35 | 35 |
|
| 36 | 36 |
for (size_t i = 0; i < nsamps; i++){
|
| 37 |
output[i] = $(swap_fcn)($(cpu_type)_to_item32(input[i], float(scale_factor)));
|
|
| 37 |
output[i] = $(to_wire)($(cpu_type)_to_item32(input[i], float(scale_factor)));
|
|
| 38 | 38 |
} |
| 39 | 39 |
} |
| 40 | 40 |
|
| 41 |
DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_1_$(swap), PRIORITY_GENERAL){
|
|
| 41 |
DECLARE_CONVERTER(sc16_item32_$(end), 1, $(cpu_type), 1, PRIORITY_GENERAL){
|
|
| 42 | 42 |
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); |
| 43 | 43 |
$(cpu_type)_t *output = reinterpret_cast<$(cpu_type)_t *>(outputs[0]); |
| 44 | 44 |
|
| 45 | 45 |
for (size_t i = 0; i < nsamps; i++){
|
| 46 |
output[i] = item32_to_$(cpu_type)($(swap_fcn)(input[i]), float(scale_factor));
|
|
| 46 |
output[i] = item32_to_$(cpu_type)($(to_host)(input[i]), float(scale_factor));
|
|
| 47 | 47 |
} |
| 48 | 48 |
} |
| 49 | 49 |
""" |
| 50 | 50 |
TMPL_CONV_TO_FROM_ITEM32_X = """ |
| 51 |
DECLARE_CONVERTER(convert_$(cpu_type)_$(width)_to_item32_1_$(swap), PRIORITY_GENERAL){
|
|
| 51 |
DECLARE_CONVERTER($(cpu_type), $(width), sc16_item32_$(end), 1, PRIORITY_GENERAL){
|
|
| 52 | 52 |
#for $w in range($width) |
| 53 | 53 |
const $(cpu_type)_t *input$(w) = reinterpret_cast<const $(cpu_type)_t *>(inputs[$(w)]); |
| 54 | 54 |
#end for |
| ... | ... | |
| 56 | 56 |
|
| 57 | 57 |
for (size_t i = 0, j = 0; i < nsamps; i++){
|
| 58 | 58 |
#for $w in range($width) |
| 59 |
output[j++] = $(swap_fcn)($(cpu_type)_to_item32(input$(w)[i], float(scale_factor)));
|
|
| 59 |
output[j++] = $(to_wire)($(cpu_type)_to_item32(input$(w)[i], float(scale_factor)));
|
|
| 60 | 60 |
#end for |
| 61 | 61 |
} |
| 62 | 62 |
} |
| 63 | 63 |
|
| 64 |
DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_$(width)_$(swap), PRIORITY_GENERAL){
|
|
| 64 |
DECLARE_CONVERTER(sc16_item32_$(end), 1, $(cpu_type), $(width), PRIORITY_GENERAL){
|
|
| 65 | 65 |
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); |
| 66 | 66 |
#for $w in range($width) |
| 67 | 67 |
$(cpu_type)_t *output$(w) = reinterpret_cast<$(cpu_type)_t *>(outputs[$(w)]); |
| ... | ... | |
| 69 | 69 |
|
| 70 | 70 |
for (size_t i = 0, j = 0; i < nsamps; i++){
|
| 71 | 71 |
#for $w in range($width) |
| 72 |
output$(w)[i] = item32_to_$(cpu_type)($(swap_fcn)(input[j++]), float(scale_factor));
|
|
| 72 |
output$(w)[i] = item32_to_$(cpu_type)($(to_host)(input[j++]), float(scale_factor));
|
|
| 73 | 73 |
#end for |
| 74 | 74 |
} |
| 75 | 75 |
} |
| ... | ... | |
| 84 | 84 |
file = os.path.basename(__file__) |
| 85 | 85 |
output = parse_tmpl(TMPL_HEADER, file=file) |
| 86 | 86 |
for width in 1, 2, 3, 4: |
| 87 |
for swap, swap_fcn in (('nswap', ''), ('bswap', 'uhd::byteswap')):
|
|
| 87 |
for end, to_host, to_wire in ( |
|
| 88 |
('be', 'uhd::ntohx', 'uhd::htonx'),
|
|
| 89 |
('le', 'uhd::wtohx', 'uhd::htowx'),
|
|
| 90 |
): |
|
| 88 | 91 |
for cpu_type in 'fc64', 'fc32', 'sc16': |
| 89 | 92 |
output += parse_tmpl( |
| 90 | 93 |
TMPL_CONV_TO_FROM_ITEM32_1 if width == 1 else TMPL_CONV_TO_FROM_ITEM32_X, |
| 91 |
width=width, swap=swap, swap_fcn=swap_fcn, cpu_type=cpu_type
|
|
| 94 |
width=width, end=end, to_host=to_host, to_wire=to_wire, cpu_type=cpu_type
|
|
| 92 | 95 |
) |
| 93 | 96 |
open(sys.argv[1], 'w').write(output) |
| /dev/null | ||
|---|---|---|
| 1 |
#!/usr/bin/env python |
|
| 2 |
# |
|
| 3 |
# Copyright 2011-2011 Ettus Research LLC |
|
| 4 |
# |
|
| 5 |
# This program is free software: you can redistribute it and/or modify |
|
| 6 |
# it under the terms of the GNU General Public License as published by |
|
| 7 |
# the Free Software Foundation, either version 3 of the License, or |
|
| 8 |
# (at your option) any later version. |
|
| 9 |
# |
|
| 10 |
# This program is distributed in the hope that it will be useful, |
|
| 11 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 12 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 13 |
# GNU General Public License for more details. |
|
| 14 |
# |
|
| 15 |
# You should have received a copy of the GNU General Public License |
|
| 16 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
| 17 |
# |
|
| 18 |
|
|
| 19 |
TMPL_TEXT = """ |
|
| 20 |
#import time |
|
| 21 |
/*********************************************************************** |
|
| 22 |
* This file was generated by $file on $time.strftime("%c")
|
|
| 23 |
**********************************************************************/ |
|
| 24 |
\#include <uhd/exception.hpp> |
|
| 25 |
\#include <boost/tokenizer.hpp> |
|
| 26 |
\#include <boost/lexical_cast.hpp> |
|
| 27 |
\#include <boost/detail/endian.hpp> |
|
| 28 |
\#include <boost/cstdint.hpp> |
|
| 29 |
\#include <string> |
|
| 30 |
\#include <vector> |
|
| 31 |
|
|
| 32 |
typedef size_t pred_type; |
|
| 33 |
typedef std::vector<pred_type> pred_vector_type; |
|
| 34 |
|
|
| 35 |
enum dir_type{
|
|
| 36 |
DIR_OTW_TO_CPU = 0, |
|
| 37 |
DIR_CPU_TO_OTW = 1 |
|
| 38 |
}; |
|
| 39 |
|
|
| 40 |
struct pred_error : uhd::value_error{
|
|
| 41 |
pred_error(const std::string &what): |
|
| 42 |
uhd::value_error("convert::make_pred: " + what)
|
|
| 43 |
{
|
|
| 44 |
/* NOP */ |
|
| 45 |
} |
|
| 46 |
}; |
|
| 47 |
|
|
| 48 |
pred_type make_pred(const std::string &markup, dir_type &dir){
|
|
| 49 |
pred_type pred = 0; |
|
| 50 |
|
|
| 51 |
try{
|
|
| 52 |
boost::tokenizer<boost::char_separator<char> > tokenizer(markup, boost::char_separator<char>("_"));
|
|
| 53 |
std::vector<std::string> tokens(tokenizer.begin(), tokenizer.end()); |
|
| 54 |
//token 0 is <convert> |
|
| 55 |
std::string inp_type = tokens.at(1); |
|
| 56 |
std::string num_inps = tokens.at(2); |
|
| 57 |
//token 3 is <to> |
|
| 58 |
std::string out_type = tokens.at(4); |
|
| 59 |
std::string num_outs = tokens.at(5); |
|
| 60 |
std::string swap_type = tokens.at(6); |
|
| 61 |
|
|
| 62 |
std::string cpu_type, otw_type; |
|
| 63 |
if (inp_type.find("item") == std::string::npos){
|
|
| 64 |
cpu_type = inp_type; |
|
| 65 |
otw_type = out_type; |
|
| 66 |
dir = DIR_CPU_TO_OTW; |
|
| 67 |
} |
|
| 68 |
else{
|
|
| 69 |
cpu_type = out_type; |
|
| 70 |
otw_type = inp_type; |
|
| 71 |
dir = DIR_OTW_TO_CPU; |
|
| 72 |
} |
|
| 73 |
|
|
| 74 |
if (cpu_type == "fc64") pred |= $ph.fc64_p; |
|
| 75 |
else if (cpu_type == "fc32") pred |= $ph.fc32_p; |
|
| 76 |
else if (cpu_type == "sc16") pred |= $ph.sc16_p; |
|
| 77 |
else if (cpu_type == "sc8") pred |= $ph.sc8_p; |
|
| 78 |
else throw pred_error("unhandled io type " + cpu_type);
|
|
| 79 |
|
|
| 80 |
if (otw_type == "item32") pred |= $ph.item32_p; |
|
| 81 |
else throw pred_error("unhandled otw type " + otw_type);
|
|
| 82 |
|
|
| 83 |
int num_inputs = boost::lexical_cast<int>(num_inps); |
|
| 84 |
int num_outputs = boost::lexical_cast<int>(num_outs); |
|
| 85 |
|
|
| 86 |
switch(num_inputs*num_outputs){ //FIXME treated as one value
|
|
| 87 |
case 1: pred |= $ph.chan1_p; break; |
|
| 88 |
case 2: pred |= $ph.chan2_p; break; |
|
| 89 |
case 3: pred |= $ph.chan3_p; break; |
|
| 90 |
case 4: pred |= $ph.chan4_p; break; |
|
| 91 |
default: throw pred_error("unhandled number of channels");
|
|
| 92 |
} |
|
| 93 |
|
|
| 94 |
if (swap_type == "bswap") pred |= $ph.bswap_p; |
|
| 95 |
else if (swap_type == "nswap") pred |= $ph.nswap_p; |
|
| 96 |
else throw pred_error("unhandled swap type");
|
|
| 97 |
|
|
| 98 |
} |
|
| 99 |
catch(...){
|
|
| 100 |
throw pred_error("could not parse markup: " + markup);
|
|
| 101 |
} |
|
| 102 |
|
|
| 103 |
return pred; |
|
| 104 |
} |
|
| 105 |
|
|
| 106 |
#define pred_table_wildcard pred_type(~0) |
|
| 107 |
#define pred_table_max_size size_t(128) |
|
| 108 |
#define pred_table_index(e) (pred_type(e) & 0x7f) |
|
| 109 |
|
|
| 110 |
static pred_vector_type get_pred_byte_order_table(void){
|
|
| 111 |
pred_vector_type table(pred_table_max_size, pred_table_wildcard); |
|
| 112 |
\#ifdef BOOST_BIG_ENDIAN |
|
| 113 |
table[pred_table_index(otw_type_t::BO_BIG_ENDIAN)] = $ph.nswap_p; |
|
| 114 |
table[pred_table_index(otw_type_t::BO_LITTLE_ENDIAN)] = $ph.bswap_p; |
|
| 115 |
\#else |
|
| 116 |
table[pred_table_index(otw_type_t::BO_BIG_ENDIAN)] = $ph.bswap_p; |
|
| 117 |
table[pred_table_index(otw_type_t::BO_LITTLE_ENDIAN)] = $ph.nswap_p; |
|
| 118 |
\#endif |
|
| 119 |
table[pred_table_index(otw_type_t::BO_NATIVE)] = $ph.nswap_p; |
|
| 120 |
return table; |
|
| 121 |
} |
|
| 122 |
|
|
| 123 |
static pred_vector_type get_pred_io_type_table(void){
|
|
| 124 |
pred_vector_type table(pred_table_max_size, pred_table_wildcard); |
|
| 125 |
table[pred_table_index(io_type_t::COMPLEX_FLOAT64)] = $ph.fc64_p; |
|
| 126 |
table[pred_table_index(io_type_t::COMPLEX_FLOAT32)] = $ph.fc32_p; |
|
| 127 |
table[pred_table_index(io_type_t::COMPLEX_INT16)] = $ph.sc16_p; |
|
| 128 |
return table; |
|
| 129 |
} |
|
| 130 |
|
|
| 131 |
static pred_vector_type get_pred_num_io_table(void){
|
|
| 132 |
pred_vector_type table(pred_table_max_size, pred_table_wildcard); |
|
| 133 |
table[1] = $ph.chan1_p; |
|
| 134 |
table[2] = $ph.chan2_p; |
|
| 135 |
table[3] = $ph.chan3_p; |
|
| 136 |
table[4] = $ph.chan4_p; |
|
| 137 |
return table; |
|
| 138 |
} |
|
| 139 |
|
|
| 140 |
UHD_INLINE pred_type make_pred( |
|
| 141 |
const io_type_t &io_type, |
|
| 142 |
const otw_type_t &otw_type, |
|
| 143 |
size_t num_inputs, |
|
| 144 |
size_t num_outputs |
|
| 145 |
){
|
|
| 146 |
pred_type pred = $ph.item32_p; //only item32 supported as of now |
|
| 147 |
|
|
| 148 |
static const pred_vector_type pred_byte_order_table(get_pred_byte_order_table()); |
|
| 149 |
pred |= pred_byte_order_table[pred_table_index(otw_type.byteorder)]; |
|
| 150 |
|
|
| 151 |
static const pred_vector_type pred_io_type_table(get_pred_io_type_table()); |
|
| 152 |
pred |= pred_io_type_table[pred_table_index(io_type.tid)]; |
|
| 153 |
|
|
| 154 |
static const pred_vector_type pred_num_io_table(get_pred_num_io_table()); |
|
| 155 |
pred |= pred_num_io_table[pred_table_index(num_inputs*num_outputs)]; |
|
| 156 |
|
|
| 157 |
if (pred == pred_table_wildcard) throw pred_error( |
|
| 158 |
"unhanded input combination for make_pred()" |
|
| 159 |
); |
|
| 160 |
|
|
| 161 |
return pred; |
|
| 162 |
} |
|
| 163 |
""" |
|
| 164 |
|
|
| 165 |
def parse_tmpl(_tmpl_text, **kwargs): |
|
| 166 |
from Cheetah.Template import Template |
|
| 167 |
return str(Template(_tmpl_text, kwargs)) |
|
| 168 |
|
|
| 169 |
class ph: |
|
| 170 |
bswap_p = 0b00001 |
|
| 171 |
nswap_p = 0b00000 |
|
| 172 |
item32_p = 0b00000 |
|
| 173 |
sc8_p = 0b00000 |
|
| 174 |
sc16_p = 0b00010 |
|
| 175 |
fc32_p = 0b00100 |
|
| 176 |
fc64_p = 0b00110 |
|
| 177 |
chan1_p = 0b00000 |
|
| 178 |
chan2_p = 0b01000 |
|
| 179 |
chan3_p = 0b10000 |
|
| 180 |
chan4_p = 0b11000 |
|
| 181 |
|
|
| 182 |
if __name__ == '__main__': |
|
| 183 |
import sys, os |
|
| 184 |
file = os.path.basename(__file__) |
|
| 185 |
open(sys.argv[1], 'w').write(parse_tmpl(TMPL_TEXT, file=file, ph=ph)) |
|
Also available in: Unified diff