From dd782308940e4b206e798eb2f0fa203b6e8c7f07 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 12 Nov 2011 15:45:52 -0800 Subject: convert: made conversion functions into classes so they can keep state --- host/include/uhd/convert.hpp | 39 ++++++++++++++++++------ host/lib/convert/convert_common.hpp | 26 ++++++++-------- host/lib/convert/convert_impl.cpp | 4 +-- host/lib/convert/gen_convert_general.py | 10 ------ host/lib/transport/super_recv_packet_handler.hpp | 13 +++----- host/lib/transport/super_send_packet_handler.hpp | 13 +++----- host/tests/convert_test.cpp | 24 +++++++++++---- 7 files changed, 72 insertions(+), 57 deletions(-) (limited to 'host') diff --git a/host/include/uhd/convert.hpp b/host/include/uhd/convert.hpp index c42edfdec..6cc729819 100644 --- a/host/include/uhd/convert.hpp +++ b/host/include/uhd/convert.hpp @@ -20,17 +20,35 @@ #include #include +#include #include #include #include namespace uhd{ namespace convert{ - typedef uhd::ref_vector output_type; - typedef uhd::ref_vector input_type; + //! A conversion class that implements a conversion from inputs -> outputs. + class converter{ + public: + typedef boost::shared_ptr sptr; + typedef uhd::ref_vector output_type; + typedef uhd::ref_vector input_type; - //! input vectors, output vectors, num samples, scale factor - typedef boost::function function_type; + //! Set the scale factor (used in floating point conversions) + virtual void set_scalar(const double) = 0; + + //! The public conversion method to convert inputs -> outputs + UHD_INLINE void conv(const input_type &in, const output_type &out, const size_t num){ + if (num != 0) (*this)(in, out, num); + } + + private: + //! Callable method: input vectors, output vectors, num samples + virtual void operator()(const input_type&, const output_type&, const size_t) = 0; + }; + + //! Conversion factory function typedef + typedef boost::function function_type; /*! * Describe the priority of a converter function. @@ -43,7 +61,8 @@ namespace uhd{ namespace convert{ PRIORITY_GENERAL = 0, PRIORITY_LIBORC = 1, PRIORITY_SIMD = 2, - PRIORITY_CUSTOM = 3, + PRIORITY_TABLE = 3, + PRIORITY_CUSTOM = 4, PRIORITY_EMPTY = -1, }; @@ -62,19 +81,19 @@ namespace uhd{ namespace convert{ /*! * Register a converter function. * \param id identify the conversion - * \param fcn a pointer to the converter + * \param fcn makes a new converter * \param prio the function priority */ UHD_API void register_converter( const id_type &id, - function_type fcn, - priority_type prio + const function_type &fcn, + const priority_type prio ); /*! - * Get a converter function. + * Get a converter factory function. * \param id identify the conversion - * \return the converter function + * \return the converter factory function */ UHD_API function_type get_converter(const id_type &id); diff --git a/host/lib/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp index 34fb848c3..ce82f6216 100644 --- a/host/lib/convert/convert_common.hpp +++ b/host/lib/convert/convert_common.hpp @@ -21,30 +21,30 @@ #include #include #include +#include #include -#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, \ - const size_t nsamps, const double scale_factor \ - ); \ - UHD_STATIC_BLOCK(__register_##fcn##_##prio){ \ +#define _DECLARE_CONVERTER(name, in_form, num_in, out_form, num_out, prio) \ + struct name : public uhd::convert::converter{ \ + static sptr make(void){return sptr(new name());} \ + double scale_factor; \ + void set_scalar(const double s){scale_factor = s;} \ + void operator()(const input_type&, const output_type&, const size_t); \ + }; \ + UHD_STATIC_BLOCK(__register_##name##_##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); \ + uhd::convert::register_converter(id, boost::bind(&name::make), prio); \ } \ - static void fcn( \ - const uhd::convert::input_type &inputs, \ - const uhd::convert::output_type &outputs, \ - const size_t nsamps, const double scale_factor \ + void name::operator()( \ + const input_type &inputs, const output_type &outputs, const size_t nsamps \ ) #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) + _DECLARE_CONVERTER(__convert_##in_form##_##num_in##_##out_form##_##num_out##_##prio, in_form, num_in, out_form, num_out, prio) /*********************************************************************** * Typedefs diff --git a/host/lib/convert/convert_impl.cpp b/host/lib/convert/convert_impl.cpp index f05be6ada..12ad54486 100644 --- a/host/lib/convert/convert_impl.cpp +++ b/host/lib/convert/convert_impl.cpp @@ -69,8 +69,8 @@ UHD_SINGLETON_FCN(fcn_table_type, get_table); **********************************************************************/ void uhd::convert::register_converter( const id_type &id, - function_type fcn, - priority_type prio + const function_type &fcn, + const priority_type prio ){ //get a reference to the function table fcn_table_type &table = get_table(); diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py index 52b4212b4..a1bc7aaaf 100644 --- a/host/lib/convert/gen_convert_general.py +++ b/host/lib/convert/gen_convert_general.py @@ -33,8 +33,6 @@ DECLARE_CONVERTER(item32, 1, sc16_item32_$(end), 1, PRIORITY_GENERAL){ const item32_t *input = reinterpret_cast(inputs[0]); item32_t *output = reinterpret_cast(outputs[0]); - if (scale_factor == 0){} //avoids unused warning - for (size_t i = 0; i < nsamps; i++){ output[i] = $(to_wire)(input[i]); } @@ -44,8 +42,6 @@ DECLARE_CONVERTER(sc16_item32_$(end), 1, item32, 1, PRIORITY_GENERAL){ const item32_t *input = reinterpret_cast(inputs[0]); item32_t *output = reinterpret_cast(outputs[0]); - if (scale_factor == 0){} //avoids unused warning - for (size_t i = 0; i < nsamps; i++){ output[i] = $(to_host)(input[i]); } @@ -103,8 +99,6 @@ DECLARE_CONVERTER($(cpu_type), $(width), sc16_item16_usrp1, 1, PRIORITY_GENERAL) #end for boost::uint16_t *output = reinterpret_cast(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++] = $(to_wire)(boost::int16_t(input$(w)[i].real()$(do_scale))); @@ -119,8 +113,6 @@ DECLARE_CONVERTER(sc16_item16_usrp1, 1, $(cpu_type), $(width), PRIORITY_GENERAL) $(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( @@ -138,8 +130,6 @@ DECLARE_CONVERTER(sc8_item16_usrp1, 1, $(cpu_type), $(width), PRIORITY_GENERAL){ $(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) { diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp index 57aae96b1..05cad93ea 100644 --- a/host/lib/transport/super_recv_packet_handler.hpp +++ b/host/lib/transport/super_recv_packet_handler.hpp @@ -71,7 +71,6 @@ public: { this->resize(size); set_alignment_failure_threshold(1000); - this->set_scale_factor(1/32767.); } //! Resize the number of transport channels @@ -124,7 +123,8 @@ public: //! Set the conversion routine for all channels void set_converter(const uhd::convert::id_type &id){ _io_buffs.resize(id.num_outputs); - _converter = uhd::convert::get_converter(id); + _converter = uhd::convert::get_converter(id)(); + this->set_scale_factor(1/32767.); //update after setting converter _bytes_per_otw_item = uhd::convert::get_bytes_per_item(id.input_format); _bytes_per_cpu_item = uhd::convert::get_bytes_per_item(id.output_format); } @@ -136,7 +136,7 @@ public: //! Set the scale factor used in float conversion void set_scale_factor(const double scale_factor){ - _scale_factor = scale_factor; + _converter->set_scalar(scale_factor); } /******************************************************************* @@ -207,8 +207,7 @@ private: std::vector _io_buffs; //used in conversion size_t _bytes_per_otw_item; //used in conversion size_t _bytes_per_cpu_item; //used in conversion - uhd::convert::function_type _converter; //used in conversion - double _scale_factor; + uhd::convert::converter::sptr _converter; //used in conversion //! information stored for a received buffer struct per_buffer_info_type{ @@ -523,9 +522,7 @@ private: } //copy-convert the samples from the recv buffer - if (nsamps_to_copy_per_io_buff != 0) _converter( - buff_info.copy_buff, _io_buffs, nsamps_to_copy_per_io_buff, _scale_factor - ); + _converter->conv(buff_info.copy_buff, _io_buffs, nsamps_to_copy_per_io_buff); //update the rx copy buffer to reflect the bytes copied buff_info.copy_buff += bytes_to_copy; diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp index c3ffcc861..5ed8e0143 100644 --- a/host/lib/transport/super_send_packet_handler.hpp +++ b/host/lib/transport/super_send_packet_handler.hpp @@ -56,7 +56,6 @@ public: _next_packet_seq(0) { this->resize(size); - this->set_scale_factor(32767.); } //! Resize the number of transport channels @@ -100,7 +99,8 @@ public: //! Set the conversion routine for all channels void set_converter(const uhd::convert::id_type &id){ _io_buffs.resize(id.num_inputs); - _converter = uhd::convert::get_converter(id); + _converter = uhd::convert::get_converter(id)(); + this->set_scale_factor(32767.); //update after setting converter _bytes_per_otw_item = uhd::convert::get_bytes_per_item(id.output_format); _bytes_per_cpu_item = uhd::convert::get_bytes_per_item(id.input_format); } @@ -116,7 +116,7 @@ public: //! Set the scale factor used in float conversion void set_scale_factor(const double scale_factor){ - _scale_factor = scale_factor; + _converter->set_scalar(scale_factor); } /******************************************************************* @@ -202,11 +202,10 @@ private: std::vector _io_buffs; //used in conversion size_t _bytes_per_otw_item; //used in conversion size_t _bytes_per_cpu_item; //used in conversion - uhd::convert::function_type _converter; //used in conversion + uhd::convert::converter::sptr _converter; //used in conversion size_t _max_samples_per_packet; std::vector _zero_buffs; size_t _next_packet_seq; - double _scale_factor; /******************************************************************* * Send a single packet: @@ -239,9 +238,7 @@ private: otw_mem += if_packet_info.num_header_words32; //copy-convert the samples into the send buffer - if (nsamps_per_buff != 0) _converter( - _io_buffs, otw_mem, nsamps_per_buff, _scale_factor - ); + _converter->conv(_io_buffs, otw_mem, nsamps_per_buff); //commit the samples to the zero-copy interface size_t num_bytes_total = (_header_offset_words32+if_packet_info.num_packet_words32)*sizeof(boost::uint32_t); diff --git a/host/tests/convert_test.cpp b/host/tests/convert_test.cpp index b63ff6752..1a5d30080 100644 --- a/host/tests/convert_test.cpp +++ b/host/tests/convert_test.cpp @@ -53,10 +53,14 @@ template static void loopback( std::vector output0(1, &interm[0]), output1(1, &output[0]); //convert to intermediate type - convert::get_converter(in_id)(input0, output0, nsamps, 32767.); + convert::converter::sptr c0 = convert::get_converter(in_id)(); + c0->set_scalar(32767.); + c0->conv(input0, output0, nsamps); //convert back to host type - convert::get_converter(out_id)(input1, output1, nsamps, 1/32767.); + convert::converter::sptr c1 = convert::get_converter(out_id)(); + c1->set_scalar(1/32767.); + c1->conv(input1, output1, nsamps); } /*********************************************************************** @@ -216,10 +220,14 @@ BOOST_AUTO_TEST_CASE(test_convert_types_fc32_to_sc16){ std::vector output0(1, &interm[0]), output1(1, &output[0]); //convert float to intermediate - convert::get_converter(in_id)(input0, output0, nsamps, 32767.); + convert::converter::sptr c0 = convert::get_converter(in_id)(); + c0->set_scalar(32767.); + c0->conv(input0, output0, nsamps); //convert intermediate to short - convert::get_converter(out_id)(input1, output1, nsamps, 1/32767.); + convert::converter::sptr c1 = convert::get_converter(out_id)(); + c1->set_scalar(1/32767.); + c1->conv(input1, output1, nsamps); //test that the inputs and outputs match for (size_t i = 0; i < nsamps; i++){ @@ -257,10 +265,14 @@ BOOST_AUTO_TEST_CASE(test_convert_types_sc16_to_fc32){ std::vector output0(1, &interm[0]), output1(1, &output[0]); //convert short to intermediate - convert::get_converter(in_id)(input0, output0, nsamps, 32767.); + convert::converter::sptr c0 = convert::get_converter(in_id)(); + c0->set_scalar(32767.); + c0->conv(input0, output0, nsamps); //convert intermediate to float - convert::get_converter(out_id)(input1, output1, nsamps, 1/32767.); + convert::converter::sptr c1 = convert::get_converter(out_id)(); + c1->set_scalar(1/32767.); + c1->conv(input1, output1, nsamps); //test that the inputs and outputs match for (size_t i = 0; i < nsamps; i++){ -- cgit v1.2.3