ForgeSDR

GPU-accelerated signals intelligence for software-defined radio.

Capture, detect, classify and alert on the whole band at once, on Linux, from a Jetson to a workstation.

C++20 / CUDA core Python and C++ plugins SigMF recording Web UI

What it does

GPU DSP core

forged runs the radios and the signal chain on the GPU: spectrum, digital down-conversion taps, a polyphase channelizer that splits a whole band into narrow channels for about the cost of one, and coherent multi-tuner streams.

Many radios, one band

RTL-SDR, KrakenSDR and bladeRF, plus radios on other machines over mutual TLS. Several tuners stitch into one wide span; a KrakenSDR calibrates against its noise source for phase-aligned channels.

Decoders as plugins

FT8, BPSK31, CW, ADS-B, ISM bursts and utility meters, LoRa and LoRaWAN. Plugins are separate processes that read the core's streams from shared memory, zero-copy, and publish streams of their own.

Recording that labels itself

SigMF recordings, by channel or raw, written with io_uring. Decoders annotate them, a CFAR detector marks what nobody explains, and the result becomes training data.

A classifier from your own air

Labeled windows are cut into datasets and train a 1-D ResNet over raw IQ, exported to ONNX. Probing tools check that the model learned the modulation and not the receiver.

Pipelines you can see

forgemgr runs pipelines as systemd units from a web UI: a graph editor with typed wires, live rates and health on every node, waterfalls and plugin output, across several machines.

Plays well with others

An rtl_tcp bridge serves the running radio to gqrx, rtl_433, SDR++ and friends, each client with its own frequency and rate, while the core and its plugins keep working.

Built for Linux

memfd rings, futex wake-ups, io_uring and systemd used directly. No Python on the sample-rate path: high-rate DSP stays on the GPU or in C++.

From antenna to alert

  1. Radios RTL-SDR · KrakenSDR · bladeRF · network sources · SigMF replay
  2. forged GPU spectrum · DDC taps · channelizer · coherence · recorder
  3. Streams Shared-memory rings, local or over mutual TLS
  4. Plugins Decode · label · detect · classify · schedule
  5. Results Decodes, detections, labeled recordings, datasets, models

A plugin in ten lines

Plugins attach to the core's streams through a control socket and get blocks as zero-copy arrays. The same plugin runs on another machine with --socket tls://node:7700.

There is a Python SDK and a C++ SDK. Only plugins you allow may retune the radio or start recordings; everything else is read-only.

from forgesdr_sdk import Plugin, run

class Peak(Plugin):
    name = "peak"
    subscribe = ["spectrum"]

    def on_block(self, stream, block):
        i = block.data.argmax()
        f = block.freqs()[i] / 1e6
        self.log(f"peak at {f:.4f} MHz")

if __name__ == "__main__":
    run(Peak)