aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/transport
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/transport')
-rwxr-xr-xhost/lib/transport/gen_vrt_if_packet.py51
-rw-r--r--host/lib/transport/super_recv_packet_handler.hpp152
-rw-r--r--host/lib/transport/super_send_packet_handler.hpp165
3 files changed, 181 insertions, 187 deletions
diff --git a/host/lib/transport/gen_vrt_if_packet.py b/host/lib/transport/gen_vrt_if_packet.py
index 5f048d8c7..245a7ddbd 100755
--- a/host/lib/transport/gen_vrt_if_packet.py
+++ b/host/lib/transport/gen_vrt_if_packet.py
@@ -70,6 +70,10 @@ static pred_table_type get_pred_unpack_table(void){
static const pred_table_type pred_unpack_table(get_pred_unpack_table());
+//maps trailer bits to num empty bytes
+//maps num empty bytes to trailer bits
+static const size_t occ_table[] = {0, 2, 1, 3};
+
########################################################################
#def gen_code($XE_MACRO, $suffix)
########################################################################
@@ -122,14 +126,6 @@ void vrt::if_hdr_pack_$(suffix)(
#set $num_header_words += 1
#set $flags |= (0x1 << 20);
#end if
- ########## Trailer ##########
- #if $pred & $tlr_p
- //packet_buff[$num_header_words+if_packet_info.num_payload_words32] = $(XE_MACRO)(if_packet_info.tlr);
- #set $flags |= (0x1 << 26);
- #set $num_trailer_words = 1;
- #else
- #set $num_trailer_words = 0;
- #end if
########## Burst Flags ##########
#if $pred & $eob_p
#set $flags |= (0x1 << 24);
@@ -137,6 +133,18 @@ void vrt::if_hdr_pack_$(suffix)(
#if $pred & $sob_p
#set $flags |= (0x1 << 25);
#end if
+ ########## Trailer ##########
+ #if $pred & $tlr_p
+ {
+ const size_t empty_bytes = if_packet_info.num_payload_words32*sizeof(boost::uint32_t) - if_packet_info.num_payload_bytes;
+ if_packet_info.tlr |= (0x3 << 22) | (occ_table[empty_bytes & 0x3] << 10);
+ }
+ packet_buff[$num_header_words+if_packet_info.num_payload_words32] = $(XE_MACRO)(if_packet_info.tlr);
+ #set $flags |= (0x1 << 26);
+ #set $num_trailer_words = 1;
+ #else
+ #set $num_trailer_words = 0;
+ #end if
########## Variables ##########
if_packet_info.num_header_words32 = $num_header_words;
if_packet_info.num_packet_words32 = $($num_header_words + $num_trailer_words) + if_packet_info.num_payload_words32;
@@ -172,6 +180,8 @@ void vrt::if_hdr_unpack_$(suffix)(
const pred_type pred = pred_unpack_table[pred_table_index(vrt_hdr_word)];
+ size_t empty_bytes = 0;
+
switch(pred){
#for $pred in range(2**7)
case $pred:
@@ -211,15 +221,6 @@ void vrt::if_hdr_unpack_$(suffix)(
#else
if_packet_info.has_tsf = false;
#end if
- ########## Trailer ##########
- #if $pred & $tlr_p
- if_packet_info.has_tlr = true;
- if_packet_info.tlr = $(XE_MACRO)(packet_buff[packet_words32-1]);
- #set $num_trailer_words = 1;
- #else
- if_packet_info.has_tlr = false;
- #set $num_trailer_words = 0;
- #end if
########## Burst Flags ##########
#if $pred & $eob_p
if_packet_info.eob = true;
@@ -231,12 +232,28 @@ void vrt::if_hdr_unpack_$(suffix)(
#else
if_packet_info.sob = false;
#end if
+ ########## Trailer ##########
+ #if $pred & $tlr_p
+ if_packet_info.has_tlr = true;
+ if_packet_info.tlr = $(XE_MACRO)(packet_buff[packet_words32-1]);
+ #set $num_trailer_words = 1;
+ {
+ const int indicators = (if_packet_info.tlr >> 20) & (if_packet_info.tlr >> 8);
+ if ((indicators & (1 << 0)) != 0) if_packet_info.eob = true;
+ if ((indicators & (1 << 1)) != 0) if_packet_info.sob = true;
+ empty_bytes = occ_table[(indicators >> 2) & 0x3];
+ }
+ #else
+ if_packet_info.has_tlr = false;
+ #set $num_trailer_words = 0;
+ #end if
########## Variables ##########
//another failure case
if (packet_words32 < $($num_header_words + $num_trailer_words))
throw uhd::value_error("bad vrt header or invalid packet length");
if_packet_info.num_header_words32 = $num_header_words;
if_packet_info.num_payload_words32 = packet_words32 - $($num_header_words + $num_trailer_words);
+ if_packet_info.num_payload_bytes = if_packet_info.num_payload_words32*sizeof(boost::uint32_t) - empty_bytes;
break;
#end for
}
diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp
index 541c588e6..57aae96b1 100644
--- a/host/lib/transport/super_recv_packet_handler.hpp
+++ b/host/lib/transport/super_recv_packet_handler.hpp
@@ -21,15 +21,12 @@
#include <uhd/config.hpp>
#include <uhd/exception.hpp>
#include <uhd/convert.hpp>
-#include <uhd/device.hpp>
+#include <uhd/stream.hpp>
#include <uhd/utils/msg.hpp>
#include <uhd/utils/byteswap.hpp>
-#include <uhd/types/io_type.hpp>
-#include <uhd/types/otw_type.hpp>
#include <uhd/types/metadata.hpp>
#include <uhd/transport/vrt_if_packet.hpp>
#include <uhd/transport/zero_copy.hpp>
-#include <boost/thread/mutex.hpp>
#include <boost/dynamic_bitset.hpp>
#include <boost/foreach.hpp>
#include <boost/function.hpp>
@@ -124,24 +121,12 @@ public:
_props.at(xport_chan).get_buff = get_buff;
}
- /*!
- * Setup the conversion functions (homogeneous across transports).
- * Here, we load a table of converters for all possible io types.
- * This makes the converter look-up an O(1) operation.
- * \param otw_type the channel data type
- * \param width the streams per channel (usually 1)
- */
- void set_converter(const uhd::otw_type_t &otw_type, const size_t width = 1){
- _io_buffs.resize(width);
- _converters.resize(128);
- for (size_t io_type = 0; io_type < _converters.size(); io_type++){
- try{
- _converters[io_type] = uhd::convert::get_converter_otw_to_cpu(
- io_type_t::tid_t(io_type), otw_type, 1, width
- );
- }catch(const uhd::value_error &){} //we expect this, not all io_types valid...
- }
- _bytes_per_item = otw_type.get_sample_size();
+ //! 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);
+ _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);
}
//! Set the transport channel's overflow handler
@@ -149,11 +134,6 @@ public:
_props.at(xport_chan).handle_overflow = handle_overflow;
}
- //! Get a scoped lock object for this instance
- boost::mutex::scoped_lock get_scoped_lock(void){
- return boost::mutex::scoped_lock(_mutex);
- }
-
//! Set the scale factor used in float conversion
void set_scale_factor(const double scale_factor){
_scale_factor = scale_factor;
@@ -165,15 +145,12 @@ public:
* Dispatch into combinations of single packet receive calls.
******************************************************************/
UHD_INLINE size_t recv(
- const uhd::device::recv_buffs_type &buffs,
+ const uhd::rx_streamer::buffs_type &buffs,
const size_t nsamps_per_buff,
uhd::rx_metadata_t &metadata,
- const uhd::io_type_t &io_type,
- uhd::device::recv_mode_t recv_mode,
- double timeout
+ const double timeout,
+ const bool one_packet
){
- boost::mutex::scoped_lock lock(_mutex);
-
//handle metadata queued from a previous receive
if (_queue_error_for_next_call){
_queue_error_for_next_call = false;
@@ -183,48 +160,34 @@ public:
if (_queue_metadata.error_code != rx_metadata_t::ERROR_CODE_TIMEOUT) return 0;
}
- switch(recv_mode){
+ size_t accum_num_samps = recv_one_packet(
+ buffs, nsamps_per_buff, metadata, timeout
+ );
- ////////////////////////////////////////////////////////////////
- case uhd::device::RECV_MODE_ONE_PACKET:{
- ////////////////////////////////////////////////////////////////
- return recv_one_packet(buffs, nsamps_per_buff, metadata, io_type, timeout);
- }
-
- ////////////////////////////////////////////////////////////////
- case uhd::device::RECV_MODE_FULL_BUFF:{
- ////////////////////////////////////////////////////////////////
- size_t accum_num_samps = recv_one_packet(
- buffs, nsamps_per_buff, metadata, io_type, timeout
- );
+ if (one_packet) return accum_num_samps;
- //first recv had an error code set, return immediately
- if (metadata.error_code != rx_metadata_t::ERROR_CODE_NONE) return accum_num_samps;
+ //first recv had an error code set, return immediately
+ if (metadata.error_code != rx_metadata_t::ERROR_CODE_NONE) return accum_num_samps;
- //loop until buffer is filled or error code
- while(accum_num_samps < nsamps_per_buff){
- size_t num_samps = recv_one_packet(
- buffs, nsamps_per_buff - accum_num_samps, _queue_metadata,
- io_type, timeout, accum_num_samps*io_type.size
- );
+ //loop until buffer is filled or error code
+ while(accum_num_samps < nsamps_per_buff){
+ size_t num_samps = recv_one_packet(
+ buffs, nsamps_per_buff - accum_num_samps, _queue_metadata,
+ timeout, accum_num_samps*_bytes_per_cpu_item
+ );
- //metadata had an error code set, store for next call and return
- if (_queue_metadata.error_code != rx_metadata_t::ERROR_CODE_NONE){
- _queue_error_for_next_call = true;
- break;
- }
- accum_num_samps += num_samps;
+ //metadata had an error code set, store for next call and return
+ if (_queue_metadata.error_code != rx_metadata_t::ERROR_CODE_NONE){
+ _queue_error_for_next_call = true;
+ break;
}
- return accum_num_samps;
+ accum_num_samps += num_samps;
}
-
- default: throw uhd::value_error("unknown recv mode");
- }//switch(recv_mode)
+ return accum_num_samps;
}
private:
- boost::mutex _mutex;
vrt_unpacker_type _vrt_unpacker;
size_t _header_offset_words32;
double _tick_rate, _samp_rate;
@@ -242,8 +205,9 @@ private:
};
std::vector<xport_chan_props_type> _props;
std::vector<void *> _io_buffs; //used in conversion
- size_t _bytes_per_item; //used in conversion
- std::vector<uhd::convert::function_type> _converters; //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;
//! information stored for a received buffer
@@ -363,7 +327,7 @@ private:
info.alignment_time = info[index].time;
info.indexes_todo.set();
info.indexes_todo.reset(index);
- info.data_bytes_to_copy = info[index].ifpi.num_payload_words32*sizeof(boost::uint32_t);
+ info.data_bytes_to_copy = info[index].ifpi.num_payload_bytes;
}
//if the sequence id matches:
@@ -471,7 +435,7 @@ private:
std::swap(curr_info, next_info); //save progress from curr -> next
curr_info.metadata.has_time_spec = prev_info.metadata.has_time_spec;
curr_info.metadata.time_spec = prev_info.metadata.time_spec + time_spec_t(0,
- prev_info[index].ifpi.num_payload_words32*sizeof(boost::uint32_t)/_bytes_per_item, _samp_rate);
+ prev_info[index].ifpi.num_payload_words32*sizeof(boost::uint32_t)/_bytes_per_otw_item, _samp_rate);
curr_info.metadata.more_fragments = false;
curr_info.metadata.fragment_offset = 0;
curr_info.metadata.start_of_burst = false;
@@ -507,13 +471,8 @@ private:
curr_info.metadata.time_spec = curr_info[0].time;
curr_info.metadata.more_fragments = false;
curr_info.metadata.fragment_offset = 0;
- /* TODO SOB on RX not supported in hardware
- static const int tlr_sob_flags = (1 << 21) | (1 << 9); //enable and indicator bits
- curr_info.metadata.start_of_burst = curr_info[0].ifpi.has_tlr and (int(curr_info[0].ifpi.tlr & tlr_sob_flags) != 0);
- */
- curr_info.metadata.start_of_burst = false;
- static const int tlr_eob_flags = (1 << 20) | (1 << 8); //enable and indicator bits
- curr_info.metadata.end_of_burst = curr_info[0].ifpi.has_tlr and (int(curr_info[0].ifpi.tlr & tlr_eob_flags) != 0);
+ curr_info.metadata.start_of_burst = curr_info[0].ifpi.sob;
+ curr_info.metadata.end_of_burst = curr_info[0].ifpi.eob;
curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_NONE;
}
@@ -525,11 +484,10 @@ private:
* Then copy-convert available data into the user's IO buffers.
******************************************************************/
UHD_INLINE size_t recv_one_packet(
- const uhd::device::recv_buffs_type &buffs,
+ const uhd::rx_streamer::buffs_type &buffs,
const size_t nsamps_per_buff,
uhd::rx_metadata_t &metadata,
- const uhd::io_type_t &io_type,
- double timeout,
+ const double timeout,
const size_t buffer_offset_bytes = 0
){
//get the next buffer if the current one has expired
@@ -551,9 +509,9 @@ private:
metadata.time_spec += time_spec_t(0, info.fragment_offset_in_samps, _samp_rate);
//extract the number of samples available to copy
- const size_t nsamps_available = info.data_bytes_to_copy/_bytes_per_item;
+ const size_t nsamps_available = info.data_bytes_to_copy/_bytes_per_otw_item;
const size_t nsamps_to_copy = std::min(nsamps_per_buff*_io_buffs.size(), nsamps_available);
- const size_t bytes_to_copy = nsamps_to_copy*_bytes_per_item;
+ const size_t bytes_to_copy = nsamps_to_copy*_bytes_per_otw_item;
const size_t nsamps_to_copy_per_io_buff = nsamps_to_copy/_io_buffs.size();
size_t buff_index = 0;
@@ -565,7 +523,9 @@ private:
}
//copy-convert the samples from the recv buffer
- _converters[io_type.tid](buff_info.copy_buff, _io_buffs, nsamps_to_copy_per_io_buff, _scale_factor);
+ if (nsamps_to_copy_per_io_buff != 0) _converter(
+ buff_info.copy_buff, _io_buffs, nsamps_to_copy_per_io_buff, _scale_factor
+ );
//update the rx copy buffer to reflect the bytes copied
buff_info.copy_buff += bytes_to_copy;
@@ -589,6 +549,34 @@ private:
}
};
+class recv_packet_streamer : public recv_packet_handler, public rx_streamer{
+public:
+ recv_packet_streamer(const size_t max_num_samps){
+ _max_num_samps = max_num_samps;
+ }
+
+ size_t get_num_channels(void) const{
+ return this->size();
+ }
+
+ size_t get_max_num_samps(void) const{
+ return _max_num_samps;
+ }
+
+ size_t recv(
+ const rx_streamer::buffs_type &buffs,
+ const size_t nsamps_per_buff,
+ uhd::rx_metadata_t &metadata,
+ const double timeout,
+ const bool one_packet
+ ){
+ return recv_packet_handler::recv(buffs, nsamps_per_buff, metadata, timeout, one_packet);
+ }
+
+private:
+ size_t _max_num_samps;
+};
+
}}} //namespace
#endif /* INCLUDED_LIBUHD_TRANSPORT_SUPER_RECV_PACKET_HANDLER_HPP */
diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp
index a99adcb5f..c3ffcc861 100644
--- a/host/lib/transport/super_send_packet_handler.hpp
+++ b/host/lib/transport/super_send_packet_handler.hpp
@@ -21,16 +21,13 @@
#include <uhd/config.hpp>
#include <uhd/exception.hpp>
#include <uhd/convert.hpp>
-#include <uhd/device.hpp>
+#include <uhd/stream.hpp>
#include <uhd/utils/msg.hpp>
#include <uhd/utils/byteswap.hpp>
-#include <uhd/types/io_type.hpp>
-#include <uhd/types/otw_type.hpp>
#include <uhd/types/metadata.hpp>
#include <uhd/transport/vrt_if_packet.hpp>
#include <uhd/transport/zero_copy.hpp>
#include <boost/thread/thread_time.hpp>
-#include <boost/thread/mutex.hpp>
#include <boost/foreach.hpp>
#include <boost/function.hpp>
#include <iostream>
@@ -100,24 +97,12 @@ public:
_props.at(xport_chan).get_buff = get_buff;
}
- /*!
- * Setup the conversion functions (homogeneous across transports).
- * Here, we load a table of converters for all possible io types.
- * This makes the converter look-up an O(1) operation.
- * \param otw_type the channel data type
- * \param width the streams per channel (usually 1)
- */
- void set_converter(const uhd::otw_type_t &otw_type, const size_t width = 1){
- _io_buffs.resize(width);
- _converters.resize(128);
- for (size_t io_type = 0; io_type < _converters.size(); io_type++){
- try{
- _converters[io_type] = uhd::convert::get_converter_cpu_to_otw(
- io_type_t::tid_t(io_type), otw_type, 1, width
- );
- }catch(const uhd::value_error &){} //we expect this, not all io_types valid...
- }
- _bytes_per_item = otw_type.get_sample_size();
+ //! 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);
+ _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);
}
/*!
@@ -129,11 +114,6 @@ public:
_max_samples_per_packet = num_samps;
}
- //! Get a scoped lock object for this instance
- boost::mutex::scoped_lock get_scoped_lock(void){
- return boost::mutex::scoped_lock(_mutex);
- }
-
//! Set the scale factor used in float conversion
void set_scale_factor(const double scale_factor){
_scale_factor = scale_factor;
@@ -145,15 +125,11 @@ public:
* Dispatch into combinations of single packet send calls.
******************************************************************/
UHD_INLINE size_t send(
- const uhd::device::send_buffs_type &buffs,
+ const uhd::tx_streamer::buffs_type &buffs,
const size_t nsamps_per_buff,
const uhd::tx_metadata_t &metadata,
- const uhd::io_type_t &io_type,
- uhd::device::send_mode_t send_mode,
- double timeout
+ const double timeout
){
- boost::mutex::scoped_lock lock(_mutex);
-
//translate the metadata to vrt if packet info
vrt::if_packet_info_t if_packet_info;
if_packet_info.has_sid = false;
@@ -166,74 +142,56 @@ public:
if_packet_info.sob = metadata.start_of_burst;
if_packet_info.eob = metadata.end_of_burst;
- if (nsamps_per_buff <= _max_samples_per_packet) send_mode = uhd::device::SEND_MODE_ONE_PACKET;
- switch(send_mode){
-
- ////////////////////////////////////////////////////////////////
- case uhd::device::SEND_MODE_ONE_PACKET:{
- ////////////////////////////////////////////////////////////////
+ if (nsamps_per_buff <= _max_samples_per_packet){
//TODO remove this code when sample counts of zero are supported by hardware
#ifndef SSPH_DONT_PAD_TO_ONE
if (nsamps_per_buff == 0) return send_one_packet(
- _zero_buffs, 1, if_packet_info, io_type, timeout
+ _zero_buffs, 1, if_packet_info, timeout
) & 0x0;
#endif
- return send_one_packet(
- buffs,
- std::min(nsamps_per_buff, _max_samples_per_packet),
- if_packet_info, io_type, timeout
- );
+ return send_one_packet(buffs, nsamps_per_buff, if_packet_info, timeout);
}
+ size_t total_num_samps_sent = 0;
- ////////////////////////////////////////////////////////////////
- case uhd::device::SEND_MODE_FULL_BUFF:{
- ////////////////////////////////////////////////////////////////
- size_t total_num_samps_sent = 0;
+ //false until final fragment
+ if_packet_info.eob = false;
- //false until final fragment
- if_packet_info.eob = false;
+ const size_t num_fragments = (nsamps_per_buff-1)/_max_samples_per_packet;
+ const size_t final_length = ((nsamps_per_buff-1)%_max_samples_per_packet)+1;
- const size_t num_fragments = (nsamps_per_buff-1)/_max_samples_per_packet;
- const size_t final_length = ((nsamps_per_buff-1)%_max_samples_per_packet)+1;
+ //loop through the following fragment indexes
+ for (size_t i = 0; i < num_fragments; i++){
- //loop through the following fragment indexes
- for (size_t i = 0; i < num_fragments; i++){
-
- //send a fragment with the helper function
- const size_t num_samps_sent = send_one_packet(
- buffs, _max_samples_per_packet,
- if_packet_info, io_type, timeout,
- total_num_samps_sent*io_type.size
- );
- total_num_samps_sent += num_samps_sent;
- if (num_samps_sent == 0) return total_num_samps_sent;
-
- //setup metadata for the next fragment
- const time_spec_t time_spec = metadata.time_spec + time_spec_t(0, total_num_samps_sent, _samp_rate);
- if_packet_info.tsi = boost::uint32_t(time_spec.get_full_secs());
- if_packet_info.tsf = boost::uint64_t(time_spec.get_tick_count(_tick_rate));
- if_packet_info.sob = false;
+ //send a fragment with the helper function
+ const size_t num_samps_sent = send_one_packet(
+ buffs, _max_samples_per_packet,
+ if_packet_info, timeout,
+ total_num_samps_sent*_bytes_per_cpu_item
+ );
+ total_num_samps_sent += num_samps_sent;
+ if (num_samps_sent == 0) return total_num_samps_sent;
- }
+ //setup metadata for the next fragment
+ const time_spec_t time_spec = metadata.time_spec + time_spec_t(0, total_num_samps_sent, _samp_rate);
+ if_packet_info.tsi = boost::uint32_t(time_spec.get_full_secs());
+ if_packet_info.tsf = boost::uint64_t(time_spec.get_tick_count(_tick_rate));
+ if_packet_info.sob = false;
- //send the final fragment with the helper function
- if_packet_info.eob = metadata.end_of_burst;
- return total_num_samps_sent + send_one_packet(
- buffs, final_length,
- if_packet_info, io_type, timeout,
- total_num_samps_sent*io_type.size
- );
}
- default: throw uhd::value_error("unknown send mode");
- }//switch(send_mode)
+ //send the final fragment with the helper function
+ if_packet_info.eob = metadata.end_of_burst;
+ return total_num_samps_sent + send_one_packet(
+ buffs, final_length,
+ if_packet_info, timeout,
+ total_num_samps_sent*_bytes_per_cpu_item
+ );
}
private:
- boost::mutex _mutex;
vrt_packer_type _vrt_packer;
size_t _header_offset_words32;
double _tick_rate, _samp_rate;
@@ -242,8 +200,9 @@ private:
};
std::vector<xport_chan_props_type> _props;
std::vector<const void *> _io_buffs; //used in conversion
- size_t _bytes_per_item; //used in conversion
- std::vector<uhd::convert::function_type> _converters; //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
size_t _max_samples_per_packet;
std::vector<const void *> _zero_buffs;
size_t _next_packet_seq;
@@ -253,15 +212,15 @@ private:
* Send a single packet:
******************************************************************/
UHD_INLINE size_t send_one_packet(
- const uhd::device::send_buffs_type &buffs,
+ const uhd::tx_streamer::buffs_type &buffs,
const size_t nsamps_per_buff,
vrt::if_packet_info_t &if_packet_info,
- const uhd::io_type_t &io_type,
- double timeout,
+ const double timeout,
const size_t buffer_offset_bytes = 0
){
//load the rest of the if_packet_info in here
- if_packet_info.num_payload_words32 = (nsamps_per_buff*_io_buffs.size()*_bytes_per_item)/sizeof(boost::uint32_t);
+ if_packet_info.num_payload_bytes = nsamps_per_buff*_io_buffs.size()*_bytes_per_otw_item;
+ if_packet_info.num_payload_words32 = (if_packet_info.num_payload_bytes + 3/*round up*/)/sizeof(boost::uint32_t);
if_packet_info.packet_count = _next_packet_seq;
size_t buff_index = 0;
@@ -280,7 +239,9 @@ private:
otw_mem += if_packet_info.num_header_words32;
//copy-convert the samples into the send buffer
- _converters[io_type.tid](_io_buffs, otw_mem, nsamps_per_buff, _scale_factor);
+ if (nsamps_per_buff != 0) _converter(
+ _io_buffs, otw_mem, nsamps_per_buff, _scale_factor
+ );
//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);
@@ -292,6 +253,34 @@ private:
}
};
+class send_packet_streamer : public send_packet_handler, public tx_streamer{
+public:
+ send_packet_streamer(const size_t max_num_samps){
+ _max_num_samps = max_num_samps;
+ this->set_max_samples_per_packet(_max_num_samps);
+ }
+
+ size_t get_num_channels(void) const{
+ return this->size();
+ }
+
+ size_t get_max_num_samps(void) const{
+ return _max_num_samps;
+ }
+
+ size_t send(
+ const tx_streamer::buffs_type &buffs,
+ const size_t nsamps_per_buff,
+ const uhd::tx_metadata_t &metadata,
+ const double timeout
+ ){
+ return send_packet_handler::send(buffs, nsamps_per_buff, metadata, timeout);
+ }
+
+private:
+ size_t _max_num_samps;
+};
+
}}} //namespace
#endif /* INCLUDED_LIBUHD_TRANSPORT_SUPER_SEND_PACKET_HANDLER_HPP */