Reviewing and Labelling Recordings
Before recordings can be curated into a training dataset, they need to be reviewed for quality and — if they weren’t captured in a controlled campaign — labelled with the signal content they contain.
RIA Hub stores recordings in SigMF format: a .sigmf-data file (raw IQ samples) paired with a .sigmf-meta file (JSON metadata and annotations). Labels live entirely in the .sigmf-meta file, which is committed to your repository like any other file.
Use this guide when you want to:
- Visually inspect recordings using the Library’s spectrograms, constellations, and PSD plots
- Understand which labels are written automatically during a Campaign Control run
- Add or correct recording-level labels (quality flags, descriptions) for uncontrolled captures
- Add time-frequency annotations that specify which modulation type occupies which part of the recording — required for the Curator to assign class labels when slicing
How labelling works:
- Controlled captures (from Campaign Control) are labelled at collection time — the conductor writes transmitter ID, modulation, channel, and other metadata into the
.sigmf-metaautomatically. You only need to review quality. - Uncontrolled captures (field recordings, third-party data) require manual annotation. You edit the
.sigmf-metafile directly, either through the RIA Hub web interface or via git.
What you’ll need
Section titled “What you’ll need”- Recordings indexed in the RIA Hub Library (uploaded to a repository and automatically parsed on commit)
- For manual labelling: access to edit files in the recording repository (web UI or git)
This guide covers three workflows:
- Reviewing recordings visually in the Library
- Labels set automatically during a Campaign Control run
- Manual labelling — adding or correcting labels by editing the
.sigmf-metafile directly
Part 1 — Reviewing recordings in the Library
Section titled “Part 1 — Reviewing recordings in the Library”After recordings are uploaded to a repository (either by the Conductor or manually), they are indexed and appear in the Library.
Open the Library
Section titled “Open the Library”Click Library in the top navigation. Select the Recordings tab to see all indexed recordings across your repositories.
Use the Repository, Directory, and Branch filters to narrow down to the recordings you want to review.
Inspect a recording
Section titled “Inspect a recording”Click any row in the table to open the Quick View panel. This shows:
| Tab | What it shows |
|---|---|
| Spectrogram | Time vs. frequency power map — the fastest way to spot interference, missing signals, or unexpected activity |
| Constellation | IQ scatter plot — useful for recognising modulation shape and checking for phase errors |
| PSD | Power Spectral Density — shows the frequency distribution of energy |
| Time Series | Raw I and Q amplitude over time |
| FFT / Frequency Spectrum | Single-frame frequency view |
| 3D Spectrogram | Depth-enhanced time-frequency view |
What to look for
Section titled “What to look for”Good recording:
- Signal clearly visible above the noise floor in the spectrogram
- Constellation points cluster into recognisable shapes (BPSK has two lobes, QPSK has four, etc.)
- No obvious clipping (flat tops in the time series) or saturation artefacts
Bad recording (consider rejecting):
- Flat or near-flat spectrogram with no discernible signal — receiver may have been off-frequency or signal absent
- Heavy clipping — gain was too high
- Interference from another source overlapping the signal of interest
- Very short duration relative to the expected capture length (truncated file)
Part 2 — Labels set at capture time (Conductor)
Section titled “Part 2 — Labels set at capture time (Conductor)”When a capture campaign runs via Campaign Control, several metadata fields are written into the .sigmf-meta file automatically:
| SigMF field | Where it comes from |
|---|---|
core:sample_rate | Recorder configuration |
core:hw | Recorder device type (e.g. pluto) |
core:author | Campaign metadata |
core:description | Set from the campaign description or transmitter ID |
ria:device_id | The device_id tag you set in the output configuration |
ria:campaign_id | The campaign ID assigned at deploy time |
Annotation core:label | Set per-step from the transmitter schedule (channel, modulation, traffic type) |
This means controlled captures are labelled at collection time — you know exactly what signal was being transmitted at each step because the conductor wrote that into the SigMF annotations. You still need to review recordings for quality, but you generally do not need to add labels manually.
Part 3 — Manual labelling and rejection
Section titled “Part 3 — Manual labelling and rejection”For recordings captured outside a conductor campaign — field captures, third-party datasets, or any scenario where the signal content was not known in advance — you need to add labels by hand.
Labels live in the .sigmf-meta file in your repository. You can edit this file through the RIA Hub web interface or via git on your local machine.
Recording-level label fields
Section titled “Recording-level label fields”Open the .sigmf-meta file and look for the "global" section. The most useful fields for labelling are:
{ "global": { "core:description": "QPSK signal at 915 MHz, clean capture, usable", "core:author": "your-name", "core:comment": "Captured with Pluto at 0 dBm TX power" }}To mark a recording as rejected or low quality, add a ria:quality field with a value your team agrees on, for example:
{ "global": { "ria:quality": "rejected", "core:comment": "Gain too high — heavy clipping throughout" }}Because the Library filters and the Curator recording browser both expose metadata as searchable columns, adding a consistent ria:quality field lets you filter out rejected recordings when building datasets.
Adding time-frequency annotations
Section titled “Adding time-frequency annotations”For uncontrolled captures where multiple signal types appear within a single recording, you can annotate specific regions using the SigMF annotations array. Each annotation marks a time window (and optionally a frequency range) with a label.
{ "annotations": [ { "core:sample_start": 0, "core:sample_count": 65536, "core:freq_lower_edge": 914500000, "core:freq_upper_edge": 915500000, "core:label": "QPSK", "core:comment": "Clean QPSK burst, usable" }, { "core:sample_start": 65536, "core:sample_count": 32768, "core:freq_lower_edge": 914000000, "core:freq_upper_edge": 916000000, "core:label": "interference", "core:comment": "Unknown narrowband interferer — do not use for training" } ]}| Field | Required | Description |
|---|---|---|
core:sample_start | Yes | Index of the first sample in this annotation |
core:sample_count | Yes | Number of samples covered |
core:freq_lower_edge | No | Lower frequency boundary in Hz |
core:freq_upper_edge | No | Upper frequency boundary in Hz |
core:label | No | Short label string (used by the Curator as the class name) |
core:comment | No | Free-text note |
How to edit the .sigmf-meta file
Section titled “How to edit the .sigmf-meta file”In the RIA Hub web interface:
- Navigate to your repository
- Browse to the
.sigmf-metafile - Click the edit (pencil) icon
- Make your changes to the JSON
- Write a commit message and commit directly to the branch
Via git:
git clone <your-repo-url># Edit the .sigmf-meta file in your editorgit add path/to/recording.sigmf-metagit commit -m "Add labels for recording batch 2026-05"git pushAfter committing, RIA Hub re-indexes the file automatically and the updated metadata appears in the Library within a few seconds.
Next steps
Section titled “Next steps”Once your recordings are labelled and any bad captures are flagged:
- Use the Curator to build a dataset — Curating a Dataset explains how to filter by metadata and configure slicing
- Use the Inspector to verify class balance and signal quality in the output — Inspecting a Dataset