Hi all,
The gr-uhd driver, tags samples when center frequency changes and some other events):
I've been able to make a minimal patch to the soapy driver (see following), that does the same thing for all other SDRs supported by soapy (the patch is for proof of concept/illustrative purposes only - I appreciate that it isn't compatible with the contribution guidelines).
My question - would a suitable patch that provides these tags, be acceptable to the maintainers? I can appreciate that it's possible that there are flow graphs that just happen to use these same tags perhaps for other purposes - perhaps I could then add a flag to make them optional? In any case, the gr-uhd driver appears to always send them, already.
Thanks,
diff --git a/gr-soapy/lib/block_impl.h b/gr-soapy/lib/block_impl.h
index a1e95fdd0..74b2beffe 100644
--- a/gr-soapy/lib/block_impl.h
+++ b/gr-soapy/lib/block_impl.h
@@ -90,6 +90,7 @@ protected:
public:
bool start() override;
bool stop() override;
+ bool _tag_now;
/*** Begin public API implementation ***/
diff --git a/gr-soapy/lib/source_impl.cc b/gr-soapy/lib/source_impl.cc
index f76d4437f..93aa06bb2 100644
--- a/gr-soapy/lib/source_impl.cc
+++ b/gr-soapy/lib/source_impl.cc
@@ -47,6 +47,10 @@ source_impl::source_impl(const std::string& device,
{
}
+static const pmt::pmt_t TIME_KEY = pmt::string_to_symbol("rx_time");
+static const pmt::pmt_t FREQ_KEY = pmt::string_to_symbol("rx_freq");
+static const pmt::pmt_t RATE_KEY = pmt::string_to_symbol("rx_rate");
+
int source_impl::general_work(int noutput_items,
__GR_ATTR_UNUSED gr_vector_int& ninput_items,
__GR_ATTR_UNUSED gr_vector_const_void_star& input_items,
@@ -57,6 +61,11 @@ int source_impl::general_work(int noutput_items,
const long timeout_us = 500000; // 0.5 sec
int nout = 0;
+ std::stringstream str;
+ str << name() << unique_id();
+ pmt::pmt_t _id = pmt::string_to_symbol(str.str());
+ std::time_t time_now = std::time(nullptr);
+
for (;;) {
// No command handlers while reading
@@ -66,6 +75,25 @@ int source_impl::general_work(int noutput_items,
result = d_device->readStream(
d_stream, output_items.data(), noutput_items, flags, time_ns, timeout_us);
}
+ if (_tag_now) {
+ _tag_now = false;
+ // create a timestamp pmt for the first sample
+ // TODO: use timestamp from radio hardware, and < 1s granularity?
+ const pmt::pmt_t val =
+ pmt::make_tuple(pmt::from_uint64(time_now),
+ pmt::from_double(0));
+ // create a tag set for each channel
+ for (size_t i = 0; i < 1; i++) { // TODO: get actual number of channels.
+ this->add_item_tag(i, nitems_written(0), TIME_KEY, val, _id);
+ this->add_item_tag(
+ i, nitems_written(0), RATE_KEY, pmt::from_double(this->get_sample_rate(i)), _id);
+ this->add_item_tag(i,
+ nitems_written(0),
+ FREQ_KEY,
+ pmt::from_double(this->get_frequency(i)),
+ _id);
+ }
+ }
if (result >= 0) {
nout = result;