Field Guide · concept

Also known as: tags, tagged stream, stream tags

A stream tag is a key/value metadata item pinned to a specific sample index inside a DSP stream.1 Where an ordinary stream carries only sample values, a tag lets a block attach information — a timestamp, a burst start, a new sample rate, a detected frame boundary — to one exact sample and have it travel with the data downstream. Tags bridge the gap between raw sample streams and asynchronous messages: the metadata stays perfectly aligned to the sample it describes, no matter how the stream is buffered or delayed.

rx_time sob sample index increases →
Each tag is anchored to one sample index and carries a key/value pair (here a receive timestamp and a start-of-burst marker) that propagates downstream with the stream.

How it works

A tag has three parts: the absolute sample offset it is attached to (counted from the start of the stream), a key identifying what it means, and a value. In GNU Radio both key and value are PMTs, so a value can be a number, a string, or a structured dictionary. Any block can add a tag at the sample it is currently producing, read tags on its input, and — crucially — the runtime propagates tags automatically: as samples flow downstream, their tags move with them, and blocks that change the sample rate shift each tag’s offset so it still points at the right sample.

That propagation is the whole value of tags. Because the metadata is bound to a sample rather than delivered out of band, it survives buffering, threading, and rate changes without drifting out of alignment. A tag placed on the first sample of a burst is still on the first sample of that burst after the stream has been filtered, decimated, and requeued several blocks later.

Propagation policy is configurable per block: all-to-all (default, copy input tags to outputs), one-to-one (for rate-preserving blocks), or none (the block manages tags itself, typical for a resampler or a framer that re-derives its own markers).

In practice

Common uses include:

  • Timestamps — an rx_time tag on the first sample from a device pins wall-clock or GPS-disciplined time to the stream, so downstream events can be time-stamped precisely.
  • Bursty / packetized datasob/eob (start/end of burst) tags, or a length tag on a tagged stream block, mark where a packet begins and ends so a framer can operate on variable-length chunks within a continuous stream.
  • Rate and frequency changes — a tag announces a new sample rate or a retune so downstream filters can adapt at the exact sample the change takes effect.

Tags are also the natural in-flowgraph counterpart to file-level metadata formats like SigMF: SigMF annotations describe events at sample offsets in a recording, which map almost directly onto stream tags when that recording is played back through a flowgraph.

Relevance to SDR

Tags solve a recurring SDR problem: some facts about a signal are only known at one instant (when the burst started, when the radio was tuned, what time it was) and must stay welded to that instant through the rest of the pipeline. Doing this with side channels invites off-by-N misalignment as buffers and rates change; tags make correct-by-construction alignment the runtime’s job.

GopherTrunk is pure Go and does not use GNU Radio’s tag system, so it has no rx_time/sob PMT tags as such. It achieves the same alignment guarantees structurally instead — burst and frame boundaries are carried by the framing stage that produced them, and timestamps travel alongside the decoded events rather than as separate stream annotations. The concept is still the right lens for understanding metadata-that-must-follow-a- sample, and it maps directly onto how annotated IQ recordings are described and replayed.

Sources

  1. Stream Tags — GNU Radio Wiki, on tags anchored to sample offsets, PMT key/value pairs, and tag propagation policies. 

See also