Compose N WLED devices into one canvas, driven from MIDI — the wled-midi answer to the club / large-rig use case.
Many WLED instances that should behave as one surface. Point your DAW or controller at one virtual MIDI port; this router fans out to every device. Runs on a Raspberry Pi.
mirror— the same wled-midi look/state hits every device (broadcast), via each one's HTTP JSON API (POST /json/state). Event-driven, low rate. "All strips flash red on the beat."unified— the devices form one pixel canvas (concatenated left→right byoffset). MIDI paints positions on the global canvas (strip semantics: interpolate / keymap / direct, with velocity→brightness, note-off fade and channel→hand colour), and each device is streamed only its slice via a WLED realtime transport —ddp(UDP 4048, default),artnet(ArtDmx, UDP 6454), ore131(sACN, UDP 5568) — all 170 px/universe, set"universe"per device — no HTTP rate cap. "A note sweeps a light across the whole club." Pick via"transport": "ddp" | "artnet" | "e131".
pip install python-rtmidi- Run once —
python3 matrix.py— it writesmatrix-config.json, then edit it:{ "mode": "unified", "devices": [ {"host": "192.168.1.50", "leds": 300, "offset": 0}, {"host": "192.168.1.51", "leds": 300, "offset": 300} ], "fps": 40, "strip": {"posfn": "interpolate", "lo": 21, "hi": 108, "color": [0,255,128], "fade_ms": 250} }offset= where this device starts in the global canvas (px). Total canvas = Σleds.- unified needs each WLED in a realtime-friendly state; DDP overrides the segment while packets flow. mirror just needs the HTTP API reachable.
- Route your DAW/controller MIDI to the
OpenLampMatrixvirtual port.
Per the DDP spec as implemented by real WLED drivers:
each frame, every device gets its canvas slice as DDP packets — header
flags(0x40 | 0x01 push on last) · seq(frame%15+1) · type(0x0B RGB8) · id(1) · offset(4B BE) · len(2B BE),
RGB payload, chunked at 480 px (1440 B) per packet, to UDP 4048. The canvas send is skipped when
nothing changed (idle = no traffic); fades keep sending until pixels reach black.
Set "matrix": {"width": W, "height": H, "serpentine": true} and "posfn": "column" — a note's
pitch maps to a column X and lights the whole vertical column, addressed through the physical
serpentine wiring (odd rows run right-to-left). The canvas stays a linear buffer in physical LED
order, so DDP/Art-Net/E1.31 and WLED need no 2-D config — the router owns the geometry. The 1-D
position functions (interpolate / keymap / direct) keep working and sweep the linear path.
Untested against real WLED hardware (rig offline). The DDP framing + chunking + per-device canvas
slicing are self-tested at the byte level (matrix.py ships that test in its commit). Verify on a
device before a show — a wrong byte fails silently on the wire.
Part of OpenLamp / wled-midi. DDP framing modelled on the LedFx reference. MIT licensed.