Skip to content
This repository was archived by the owner on Oct 16, 2026. It is now read-only.

DMXRouter 1.11.0

Choose a tag to compare

@fiverecords fiverecords released this 13 May 10:06
· 5 commits to main since this release
67ce6a7

This release adds bidirectional OSC and MIDI bridging between DMX and the outside world — any process engine input can now receive OSC or MIDI from an external source and feed it into the merge as if it were a DMX source, and any output can emit OSC or MIDI alongside or instead of Art-Net / sACN. Both directions are first-class peers of DMX: every merge mode, every failsafe path, every test pattern, every fixture override layer applies to OSC and MIDI sources and destinations identically to network DMX. That symmetry — DMXRouter as a peer to dedicated DMX↔OSC and DMX↔MIDI converter boxes in either direction, configured per-engine rather than per-box, with the same engine-level reliability features the DMX side already had — is what motivates the version bump to v1.11. The remaining sections (PSN, VLAN, About / Licenses) cover changes that accumulated alongside.

OSC / MIDI ↔ DMX Bridge

  • A process engine output can now be configured to emit OSC or MIDI instead of DMX, routing the merged channel data to any compatible receiver — TouchOSC, Reaper, QLab, Ableton Live, Resolume, samplers, video loopers, a DAW with a virtual MIDI port, or any custom integration — alongside or instead of Art-Net / sACN. Each output in the engine editor has a new "OSC/MIDI…" button in the rightmost Bridge column: clicking it opens a per-output configuration dialog with two protocol radios (OSC, MIDI) at the top and the corresponding form below. DMX is the absence of a bridge rather than a peer of the radios — to switch a non-DMX output back to DMX the dialog exposes a "Revert to DMX" action button next to OK / Cancel that's visible only when the current state is already non-DMX. OSC reveals destination host, UDP port (default 9000), an address-scheme template with {u} and {c} placeholders for universe and channel (default /dmx/u{u}/c{c} produces /dmx/u1/c47 for universe 1 channel 47), and a value-format selector (32-bit big-endian integer 0–255 for receivers that want raw DMX, or 32-bit big-endian float 0.0–1.0 for audio-domain receivers that expect normalised values); MIDI reveals a port selector populated with the system's MIDI output ports (including any virtual port via loopMIDI on Windows, the IAC bus on macOS or snd-virmidi on Linux), a MIDI channel 1–16, and a message-type chooser between Control Change and Note On/Off. Control Change is the continuous mode: every DMX value change emits a CC message on the mapped CC number with the value right-shifted to 7-bit — DMX channel 1 maps to the configured first CC, channel 2 to the next CC up, and so on through CC 127, with channels beyond CC 127 silently dropped. Use it for MIDI mixers, DAW plugin automation, and any receiver expecting smooth value streams. Note On/Off is the trigger mode: each DMX channel maps to a MIDI note number starting from a configured first note (default 60 = middle C), and the sender watches for the DMX value crossing a configurable trigger threshold (default 1, meaning any non-zero value fires). When the channel rises through the threshold from below, a Note On is emitted with a velocity captured at the moment of the crossing — either proportional to the DMX value at that instant, or a configurable fixed velocity (default 100) for cue-trigger use cases that want every fire at the same strength; when the value falls back below the threshold, a Note Off is emitted. There is no retrigger while a note is held — a sustained-above-threshold channel produces a single Note On and a single Note Off when it eventually drops, which matches how samplers, video loopers, and lighting consoles that take MIDI Note as cue triggers expect to behave. Cleanup is explicit: when an output that's emitting Note Ons is removed, reconfigured to a different message type or channel, has its port changed, or is flipped to a different bridge protocol (Note → CC, Note → OSC) or back to DMX, the sender sends "All Sound Off" on the affected channel before reconfiguring so samplers don't get stranded with held notes — shutdown does the same flush. Once an output is flipped to OSC or MIDI, the DMX-specific columns of its row (Net/Subnet/Universe address, Interface, Tx Mode, Priority, Delay, Dest IP) become read-only and the Bridge button label changes to show the destination at a glance ("OSC: 192.168.1.50:9000" with a blue tint, or "MIDI CC: loopMIDI Port" / "MIDI Note: loopMIDI Port" with a purple tint); the button text reads "OSC/MIDI…" in plain styling while the output is still DMX. The routing table in the main window mirrors the same distinction — non-DMX outputs render as their destination plus a "[OSC]", "[MIDI CC]" or "[MIDI Note]" tag rather than the DMX-universe-and-interface format. When the engine stops emitting (disabled, removed, or Hold failsafe) the OSC/MIDI receiver retains the last value it got; neither protocol has a "stream presence" concept like sACN, so the operator's intent is to keep the receiver state where the engine left it. Failsafe modes that substitute frame content (Output Zeros, Output Full, Output Scene) flow through normally — Output Zeros transitions every previously-non-zero channel to zero exactly once on OSC and CC outputs, and releases every held Note On with a Note Off on Note outputs.

  • A process engine input can now be configured to receive OSC or MIDI from an external source and feed it into the merge engine as if it were a DMX source on the row's universe — the symmetric counterpart of the output-side bridge. Each input row has a new Bridge button in the rightmost Bridge column ("OSC/MIDI…" when the input is still DMX, "OSC :9000" or "MIDI " once configured): clicking it opens a per-input configuration dialog with two protocol radios (OSC, MIDI) at the top and the corresponding form below. As on the output side, DMX is the absence of a bridge rather than a peer of the radios — a "Revert to DMX" action button next to OK / Cancel is visible only when the current state is already non-DMX. OSC mode opens a UDP listener bound to a configurable port (default 9000) and interface (default all NICs, with "Localhost only" as a convenience option and named NICs for multi-network rigs) and parses every incoming address against a path-scheme template — {c} extracts the DMX channel number from the address, and an optional {u} filters by the row's universe so multiple OSC sources can share the same listener safely. A value-decoding selector picks how the OSC payload is interpreted: Auto reads the typetag (,i as 0..255 int, ,f as 0..1 float scaled ×255 — accepts whichever the sender produces, ideal when you don't control the sender's format), Int forces every message to be read as a 32-bit int clamped to 0..255, and Float forces every message to be read as a 32-bit float in 0..1 range and scaled to 0..255. MIDI mode opens an input port (listed alongside the same hardware and virtual port set the output side offers) and converts Note On/Off or Control Change messages into DMX channel values, scaled 0..127 ×2 → 0..254, with a channel filter (1..16, or "Any" for any channel) and configurable first-CC / first-Note offsets that decide which DMX channel CC 0 or Note 0 maps to — set first-CC to 16 to keep DMX channels 1..16 free for other inputs to merge with the MIDI feed. In Note mode, Note On with velocity > 0 writes velocity × 2, Note Off (or Note On with velocity 0) writes 0. The decoded values feed the merge engine on the input's configured universe like any other DMX source — every merge mode (LTP, HTP, Priority, Backup, XFade, Switch, Custom), every failsafe path, every test-pattern substitution and every fixture override layer works against OSC and MIDI inputs identically to network DMX. Once an input is flipped to OSC or MIDI, the DMX-routing cells of its row (Net/Subnet/Absolute, Interface, Source IP) become read-only and the Bridge button label changes to show the protocol and primary destination at a glance ("OSC :9000" with a blue tint, "MIDI loopMIDI Port" with a purple tint); the universe spin stays editable because that's where the OSC/MIDI data lands in the engine. Clicking OK on the bridge dialog applies the changes to the running engine immediately — the receiver binds its socket or opens its MIDI port the moment the dialog closes, so the operator can tweak the path scheme or first-CC offset and hear the receiver respond without closing the parent Edit Engine dialog. Disabling the engine releases the OSC / MIDI listener immediately — the bound UDP port and the open MIDI handle are freed at the OS level so a second engine can pick up the same port without restart — and re-enabling the engine re-opens them transparently from the same configuration.

  • For OSC outputs that need different addresses per channel — Resolume's /composition/layers/1/opacity continuous fade alongside /composition/columns/3/connect one-shot trigger, QLab cues at distinct paths, custom integrations where each receiver registers a unique address — the path-scheme template can be replaced with an explicit per-channel mapping table. A "Use custom per-channel mapping" checkbox at the bottom of the OSC configuration dialog reveals a five-column table — Channel, Path, Mode, Value, Threshold — where each row defines one DMX-channel-to-OSC-address binding independently of the others. Six modes are available per row: Pass int and Pass float forward the live DMX value to the configured path as a 32-bit int 0–255 or normalised float 0.0–1.0 on every change, the same payload shapes the template-mode value format produces but with per-row routing; Fixed int and Fixed float send a configured constant value to the path whenever the source DMX channel changes value, useful for sending a known "switch on" payload that doesn't depend on the fader's current position; Trigger int and Trigger float send the configured constant value only when the source channel rises through a configurable threshold (1 = any non-zero, 128 = mid-fader), with no event on the falling edge — the analogue of MIDI Note On without an explicit Note Off, suited to Resolume clip-launch and QLab GO triggers. The same source channel can appear in multiple rows so a single fader can fan out to several OSC addresses with different modes — one Pass float for opacity and one Trigger int for a connect command on the same fader is a common Resolume pattern. Empty paths are silently skipped so a row-in-progress doesn't produce traffic; the Add / Remove / Up / Down toolbar edits the list without leaving the dialog; Import / Export buttons read and write the mapping list to a standalone JSON file that's independent of DMXRouter profiles, useful for sharing a Resolume or QLab address library between rigs or for keeping a hand-edited mapping set outside the profile. Toggling the checkbox off restores the template scheme + value format above without losing the configured rows — they stay stashed in the output and reappear when the checkbox is flipped back on. The mode toggle is exclusive: when custom mode is active, unmapped channels stay silent on the OSC side rather than falling through to the template — useful for keeping mapped paths the only source of OSC traffic from that output.

  • USB MIDI ports unplugged mid-session now reconnect automatically when the device reappears, and virtual ports created after the application has started — loopMIDI on Windows, IAC bus on macOS, snd-virmidi on Linux — are picked up without re-opening the bridge dialog. The typical scenarios this fixes: a USB MIDI controller's cable gets knocked loose mid-show and replugged seconds later — the bridge silently reconnects and the receiver picks up where it left off; a virtual MIDI loop is created in loopMIDI to bridge a DAW after DMXRouter is already running — the new port becomes selectable in the next bridge dialog open without restarting the application, and existing outputs whose configured port matches the new arrival snap onto it immediately. On the output side, when a port reappears the sender re-emits a full snapshot of the universe's channel values rather than only the next diff, so the receiver state catches up to the engine in one frame instead of drifting until every channel happens to change; for Note On/Off outputs the previously-held notes get re-asserted on the new connection so a sampler doesn't end up silent on channels that had been triggered but not released.

  • Known scope of MIDI and OSC in this release: MIDI Control Change uses linear DMX-channel-to-CC mapping at 7-bit precision (DMX 0–255 right-shifted to MIDI 0–127), one CC per DMX channel starting from the configured first CC, channels beyond CC 127 silently dropped. MIDI Note On/Off emits exactly one note event per threshold crossing (no retrigger while held), with velocity proportional to the DMX value at the crossing moment or a fixed value. One MIDI port per output, no Pitch Bend, no Aftertouch, no Program Change, no SysEx, no 14-bit CC pairs. OSC outputs bypass the per-output Delay setting and test-pattern playback, so a configured Delay is ignored on OSC outputs and test patterns substitute only on DMX outputs of the same engine. The desktop dialog is the supported configuration surface for both protocols on both sides — the web routing editor doesn't yet expose the OSC / MIDI forms. The About dialog credits libremidi (Jean-Michaël Celerier and contributors), which provides MIDI through the host's native subsystem. On Linux, the binary now links directly against libasound2 (ALSA) so the MIDI bridge can enumerate ports — desktop distros ship the library preinstalled, but minimal / server / container images may need sudo apt install libasound2 (or the alsa-lib equivalent on Fedora / Arch) for the app to launch; the README install section spells out the exact package per distro.

PSN Viewer

  • PSN port discovery now keeps only port 56565 (the spec default, where every PSN product emits at minimum) open continuously, and opens the rest of the Spotme range 56566-56820 briefly on operator gestures to discover new chassis — replacing the v1.10.1 behaviour of holding all 256 ports of the SpotMe range bound for the entire life of the process. The previous design was observed on at least one Windows Defender deployment to trigger a behavioural heuristic on unsigned binaries a few minutes into a session (sustained binding of a wide sequential port range reads as suspicious to a heuristic that doesn't know what PSN is) even though VirusTotal and direct AV scans came up clean. The new design preserves the "every Spotme appears in the panel without operator configuration" property: at startup with PSN enabled, and again the first time the operator opens the PSN dock, the receiver opens the full range for a three-second probe window; every Spotme that's already emitting shows up, and the ones with real traffic stick around. A new "Rescan" button in the PSN toolbar re-runs the probe on demand — useful for chassis that come online mid-show, when a server has been swapped out, or after a network reconfiguration. A discovered port stays open as long as it keeps emitting; if it goes silent for thirty seconds its socket closes automatically and it disappears from the panel. Operators who deliberately want the v1.10.1 always-bound behaviour can type the explicit range 56565-56820 into the Ports field; an explicit list is interpreted as a deliberate "these are the ports I want" gesture and the receiver does NOT layer discovery on top of it. Auto-discovery mode is signalled by leaving the Ports field empty — the placeholder text reads "auto" instead of the v1.10.1 default. Upgrading installations are migrated to the new empty / auto form on first launch so the new behaviour applies without having to clear the field by hand. Reported by Niels via Facebook — his Windows Defender flagged v1.10.1 after a few minutes of use even though every direct scan came up clean.

  • The Servers panel and the trackers table both have sortable columns now — click any sortable header to reorder, click again to flip direction. The Servers panel sorts by Server (system name), Address (IPv4 numerically, so 192.168.1.2 lands before 192.168.1.10), Port (separates main from backup of the same Spotme chassis), and Trackers (the count column — quickest way to find "where's the live data" on a multi-server rig). Status and Last-seen stay non-sortable because both flip on the refresh timer and sorting them would re-shuffle rows mid-glance. The trackers table gains Followers to its existing Server / ID / Name sortable set, so the operator can group all the bound trackers together at one click — typical workflow when checking which trackers are actually wired into the patch. The numeric position / speed / orientation / validity columns remain non-sortable for the same reason as the Servers panel's Status: they update at the receiver's frame rate and a click would chase rows around the table. Tie-breakers on every sortable column give a stable order — two trackers (or servers) with the same primary value land in the same relative positions on every refresh rather than shuffling.

VLAN Management

  • Each VLAN in the table can now carry its own custom background colour, settable via a new "Set Color..." button next to "Set IP..." in the VLAN Manager. Clicking the button opens a colour picker pre-seeded with the VLAN's current colour, so the picker opens on the chip the operator already sees rather than a fresh white. The custom colour propagates everywhere a VLAN chip is rendered — the routing table, interface dropdowns across the app (Routing Table, Process Engine editor, Show Cue, Add Process Engine, Network panel), and the web UI — so the operator picks once and every surface follows. Foreground (text) colour is derived automatically from the chosen background's luminance so the operator only has to pick one value and the chip always reads. Right-clicking the button opens a "Reset VLAN N to default colour" entry that returns the VLAN to its industry-standard group preset (for the 1 / 200 / 300 / … / 2000 IDs) or to the neutral dark-blue fallback (for any other custom ID); the reset entry is greyed out when no custom colour is set. The colour persists in the profile so a custom palette survives reload, and cross-platform profile portability is preserved — a custom-coloured profile saved on Windows loads on macOS / Linux with every colour intact. The Set Color button works regardless of whether the vSwitch is currently up, because colour is a pure UI / profile property — operators can pre-colour their VLANs offline before bringing the virtual switch up.

About / Licenses

  • The full text of every third-party licence used by DMXRouter is now embedded directly in the binary — Help → About → "View Full Licenses" opens a tabbed dialog with the complete licence text for Qt (LGPL v3), zlib, and libremidi rendered in monospace with copy support. No external file or internet lookup is required: the texts ship inside the executable, so an operator running DMXRouter on an air-gapped show network can read every applicable licence at any time. Discoverability mirrors the conventions of Chrome (chrome://credits), Firefox (about:license), and most macOS applications (Help → Licenses) so the entry point is where licence-conscious operators already look. This addresses the "complete copy of the licence" expectations of LGPLv3, BSD-2-Clause, modified-MIT, and zlib licences without operators having to track down per-file LICENSE documents in the install tree.