Hi all, The gr-uhd driver, tags samples when center frequency changes and some other events):
https://github.com/gnuradio/gnuradio/blob/8b23f906844c9784c784934ae06dfdfe10d31a1f/gr-uhd/lib/usrp_source_impl.cc#L619 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;