SigLab — offline signal workbench

SigLab is GopherTrunk’s standalone signal-analysis workbench. It runs entirely offline against recorded IQ captures — no SDR, no daemon, no network — so it is the natural home for diagnosing a marginal capture, proving out a demod change, or building a regression fixture.

Everything SigLab shows comes from the same decode pipeline the live daemon uses (see the Architecture reference), so what you see in the lab is what you get on the air.

SigLab has three front-ends, all built from one binary:

Surface Command Best for
Terminal app (TUI) gophertrunk siglab quick one-capture replay + dashboard in a shell
Browser console gophertrunk siglab serve rich visualization, synthesis, and comparing captures
Demod benchmark gophertrunk siglab sweep measuring demodulator quality across an SNR ladder

It needs no opt-in build tag and is part of the default install — on Windows the installer also drops a Signal Lab console Start-Menu shortcut alongside the standard and Config Builder consoles (see the Windows user guide).

What it does

  • Replay a raw IQ capture (u8 or f32) through the production decoder and watch live decode events stream past.
  • Identify the protocol of an unknown capture — ranked candidates rather than a guess.
  • Grade a decode against acceptance criteria (the test surface), the way you would build or check a regression fixture.
  • Synthesize an idealized or deliberately impaired capture (SNR, carrier offset/drift, multipath, DC, I/Q imbalance) to use as a clean reference.
  • Capture a fixed-length raw-IQ recording from a live tuner — only when the console is served by a running daemon with an SDR — then analyze it immediately and download the .cfile.
  • Visualize the result: symbol histogram, constellation, PSD, spectrogram/waterfall, eye diagram, symbol scope, sync-landscape heatmap, receiver-state series, grants, and an event timeline.
  • Compare several analyzed captures — overlay their power spectra and diff their metrics — against each other or against a synthesized ideal.
  • Export the structured result (JSON / JSONL / YAML / CSV) from the engine’s own serializers.

Terminal app: gophertrunk siglab

A self-contained replay/analysis TUI for a single capture.

gophertrunk siglab -in capture.cfile -sample-rate 2400000
gophertrunk siglab -in capture.cfile -protocol p25p1 -format u8 -auto-tune
Flag Default Meaning
-in <path> (required) raw IQ capture file
-protocol <p> (pick in the TUI) protocol to decode — empty prompts a picker
-format u8\|f32 f32 sample format of the capture
-sample-rate <Hz> 2400000 IQ sample rate of the capture
-freq <Hz> 0 informational nominal centre frequency
-auto-tune off estimate the carrier offset and tune to 0 Hz before demod

Pick a protocol (if you didn’t pass one), watch the decode run, read the signal-quality dashboard, and press e to export a JSON report.

If the reported effective baud drifts more than ~2 % from the protocol’s expected symbol rate, the capture’s true sample rate probably doesn’t match -sample-rate — fix the rate and re-run before trusting the metrics.

Browser console: gophertrunk siglab serve

A standalone, fully offline web console served at http://127.0.0.1:8099/. It ships the same RF analysis bundled into the binary — no Node.js at runtime, no CDN assets — and is the richest way to visualize and compare captures.

gophertrunk siglab serve              # serve on 127.0.0.1:8099
gophertrunk siglab serve -open        # ...and open it in your browser
gophertrunk siglab serve -addr 0.0.0.0:9000
Flag Default Meaning
-addr host:port 127.0.0.1:8099 listen address
-open off open the console in the system browser once it is up
-tmp-dir <dir> fresh temp dir directory for staged capture uploads
-max-upload <bytes> 512 MiB maximum capture upload size (0 = default)

A typical session: upload (or synthesize) a capture, configure the engine (protocol, sample rate, tune, auto-tune, conjugate, IQ-correct, P25 deep knobs), run it with a live event stream, read the results dashboard, then compare it against another capture or a synthesized ideal and export.

The running daemon mounts the same /api/v1/siglab/* routes, so if you already have a daemon up you can reach the console (and the live-capture surface) there instead of starting a separate server.

Demod benchmark: gophertrunk siglab sweep

Synthesizes P25 Phase 1 at a ladder of injected SNRs on both demod paths, decodes each through the production pipeline, and prints the measured demod-quality curve (lock, EVM, estimated SNR) against the theoretical symbol-error-rate reference. It’s the on-demand companion to the gated sweep regression test — the answer to “did my demod change actually help?”

gophertrunk siglab sweep                                            # both paths, 2–30 dB
gophertrunk siglab sweep -snr-min 6 -snr-max 20 -snr-step 1 -csv sweep.csv
Flag Default Meaning
-snr-min <dB> 2 minimum injected SNR
-snr-max <dB> 30 maximum injected SNR
-snr-step <dB> 2 SNR step
-seed <n> 0x5175 AWGN seed (reproducible draws)
-csv <path> (none) also write the sweep as CSV

See Demod calibration for how to read the curve.

SigLab vs. the bare subcommands

SigLab wraps a workbench of lower-level subcommands that you can also drive directly when scripting:

  • gophertrunk capture — record raw IQ off a live SDR to a .cfile.
  • gophertrunk replay / analyze — decode a capture offline and export it.
  • gophertrunk identify — auto-detect a capture’s protocol, then analyze it.
  • gophertrunk gen — synthesize a test IQ capture + metadata.
  • gophertrunk test — grade a decode against acceptance criteria.
  • gophertrunk spectrum — a capture’s power spectrum and detected carriers.

The TUI and browser console are friendlier front-ends onto exactly these. To discover and map an unknown trunked system from captures, reach for Hunt instead.

Supported protocols

SigLab decodes every protocol the engine knows, including P25 Phase 1/2, DMR (Tier I/II/III), NXDN, dPMR, YSF, TETRA, EDACS, MPT-1327, D-STAR, and LTR. Pass the protocol name to -protocol, or let identify / the TUI picker rank the candidates for you.

Notes & gotchas

  • Match the sample rate. Most “it won’t lock” surprises are a wrong -sample-rate. Watch the effective-baud deviation warning.
  • The capture, not the rate, decides quality. Both down-converters normalize to the per-protocol channel rate, so the decode path is rate-invariant to the capture rate. A symptom that only appears at a higher capture rate but reproduces in offline replay points at the captured samples (front-end overload / intermod / gain staging), not GopherTrunk’s DSP.
  • f32 vs u8. GopherTrunk’s own capture writes interleaved f32; many SDR tools (and .cu8/.cfile from rtl_sdr) write u8. Set -format to match.