Skip to main content

ControlForge Entertainment & Show Control Guide

James M. Belcher Founder, JMB Technical Services LLC April 2026 | ControlForge v1.0.535


1. Overview

ControlForge supports four entertainment/show control protocols for stage lighting, sound, and interactive installations — all callable from Structured Text.

ProtocolFunctionsUse Case
Art-Net7DMX512 lighting via Ethernet (UDP port 6454)
sACN/E1.317Streaming ACN lighting (multicast or unicast)
MIDI14Musical instrument control, show cues
OSC12Open Sound Control (media servers, projectors)

2. Art-Net — DMX Over Ethernet

Control DMX512 lighting fixtures via Art-Net protocol.

(* Create a 512-channel universe *)
u := ARTNET_CREATE_UNIVERSE('main', 0);

(* Set individual channels *)
u := ARTNET_SET_CHANNEL(u, 1, 255); (* Ch 1 = full *)
u := ARTNET_SET_CHANNEL(u, 2, 128); (* Ch 2 = 50% *)

(* Set RGB fixture starting at channel 10 *)
u := ARTNET_SET_RGB(u, 10, 255, 0, 0); (* Red *)

(* Send to Art-Net node *)
ARTNET_SEND_UNIVERSE('10.0.0.200', u);

(* Quick send without universe buffer *)
ARTNET_SEND('10.0.0.200', 0, 255, 128, 64); (* Universe 0, channels 1-3 *)

(* Blackout / full *)
u := ARTNET_BLACKOUT(u); (* All channels → 0 *)
u := ARTNET_FULL(u); (* All channels → 255 *)
FunctionParametersReturnsDescription
ARTNET_CREATE_UNIVERSE(name, num)2HandleCreate 512-channel buffer
ARTNET_SET_CHANNEL(h, ch, val)3HandleSet channel 1-512 (0-255)
ARTNET_SET_RGB(h, start, r, g, b)5HandleSet 3 consecutive RGB channels
ARTNET_SEND(host, universe, vals...)3+BOOLQuick send raw channels
ARTNET_SEND_UNIVERSE(host, h)2BOOLSend universe buffer (port 6454)
ARTNET_BLACKOUT(h)1HandleAll channels → 0
ARTNET_FULL(h)1HandleAll channels → 255

3. sACN/E1.31 — Streaming ACN

ANSI E1.31 streaming DMX — supports multicast and priority.

u := SACN_CREATE_UNIVERSE('wash', 1);
SACN_SET_PRIORITY(u, 150); (* Higher priority wins *)

SACN_SET_CHANNEL(u, 1, 255);
SACN_SET_RGB(u, 10, 0, 255, 0); (* Green *)

(* Unicast *)
SACN_SEND_UNIVERSE('10.0.0.201', u);

(* Multicast — use empty string or multicast address *)
SACN_SEND_UNIVERSE('', u);

(* Quick send *)
SACN_SEND('10.0.0.201', 1, 255, 128, 64);

SACN_BLACKOUT(u);
FunctionParametersReturnsDescription
SACN_CREATE_UNIVERSE(name, num)2HandleCreate universe (priority 100)
SACN_SET_CHANNEL(h, ch, val)3HandleSet channel 1-512 (0-255)
SACN_SET_RGB(h, start, r, g, b)5HandleSet 3 RGB channels
SACN_SET_PRIORITY(h, priority)2HandleSet sACN priority (0-200)
SACN_SEND(host, universe, vals...)3+BOOLQuick send
SACN_SEND_UNIVERSE(host, h)2BOOLSend buffer (multicast if host empty)
SACN_BLACKOUT(h)1HandleAll channels → 0

4. MIDI — Musical Instrument Control

Build and parse MIDI messages for instrument control, show cues, and sound design.

(* Send Note On — middle C, velocity 100, channel 1 *)
msg := MIDI_NOTE_ON(0, 60, 100);

(* Note name conversion *)
note := MIDI_NAME_TO_NOTE('C4'); (* 60 *)
name := MIDI_NOTE_TO_NAME(60); (* "C4" *)

(* Control Change — modulation wheel *)
cc := MIDI_CC(0, 1, 127);

(* Pitch bend — center = 8192 *)
pb := MIDI_PITCH_BEND(0, 8192);

(* Program change — select patch *)
pc := MIDI_PROGRAM_CHANGE(0, 42);

(* SysEx message *)
sx := MIDI_SYSEX(16#7E, 16#7F, 16#09, 16#01);

(* Parse incoming MIDI *)
parsed := MIDI_PARSE(16#90, 60, 100);
status := MIDI_GET_STATUS(parsed); (* 16#90 = Note On *)
channel := MIDI_GET_CHANNEL(parsed); (* 0 *)

(* Pack to single integer for serial transmission *)
packed := MIDI_BUILD_NOTE_ON(0, 60, 100);
FunctionParametersReturnsDescription
MIDI_NOTE_ON(ch, note, vel)3ARRAYNote On bytes
MIDI_NOTE_OFF(ch, note, vel)3ARRAYNote Off bytes
MIDI_CC(ch, controller, val)3ARRAYControl Change bytes
MIDI_PITCH_BEND(ch, val)2ARRAYPitch Bend (0-16383)
MIDI_PROGRAM_CHANGE(ch, prog)2ARRAYProgram Change bytes
MIDI_SYSEX(mfr, data...)2+ARRAYSysEx message
MIDI_PARSE(bytes...)1-3HandleParse raw MIDI
MIDI_GET_STATUS(h)1INTStatus byte (without channel)
MIDI_GET_CHANNEL(h)1INTChannel (0-15)
MIDI_NAME_TO_NOTE(name)1INT"C4" → 60
MIDI_NOTE_TO_NAME(note)1STRING60 → "C4"
MIDI_BUILD_NOTE_ON(ch, note, vel)3INTPack to single int
MIDI_BUILD_NOTE_OFF(ch, note, vel)3INTPack to single int
MIDI_BUILD_CC(ch, ctrl, val)3INTPack to single int

5. OSC — Open Sound Control

Control media servers, projection mapping, sound systems, and interactive installations.

(* Simple typed sends *)
OSC_SEND_FLOAT('10.0.0.100:8000', '/master/volume', 0.75);
OSC_SEND_INT('10.0.0.100:8000', '/cue/number', 42);
OSC_SEND_STRING('10.0.0.100:8000', '/display/text', 'WELCOME');
OSC_SEND_BOOL('10.0.0.100:8000', '/projector/enable', TRUE);

(* Auto-detect type *)
OSC_SEND('10.0.0.100:8000', '/fader/1', 0.5);

(* Multi-argument message *)
msg := OSC_MSG_CREATE('/mixer/channel/1');
msg := OSC_MSG_ADD_FLOAT(msg, 0.75); (* Volume *)
msg := OSC_MSG_ADD_INT(msg, 1); (* Mute off *)
msg := OSC_MSG_ADD_STRING(msg, 'Main L'); (* Label *)
OSC_MSG_SEND('10.0.0.100:8000', msg);

(* Bundle — multiple messages, one packet *)
OSC_SEND_BUNDLE('10.0.0.100:8000',
OSC_MSG_CREATE('/ch/1/mix/fader'),
OSC_MSG_CREATE('/ch/2/mix/fader')
);
FunctionParametersReturnsDescription
OSC_SEND(target, addr, val)3BOOLAuto-typed send
OSC_SEND_INT(target, addr, val)3BOOLSend integer
OSC_SEND_FLOAT(target, addr, val)3BOOLSend float
OSC_SEND_STRING(target, addr, val)3BOOLSend string
OSC_SEND_BOOL(target, addr, val)3BOOLSend boolean
OSC_SEND_BUNDLE(target, msgs...)2+BOOLSend message bundle
OSC_MSG_CREATE(addr)1HandleCreate message builder
OSC_MSG_ADD_INT(h, val)2HandleAdd integer argument
OSC_MSG_ADD_FLOAT(h, val)2HandleAdd float argument
OSC_MSG_ADD_STRING(h, val)2HandleAdd string argument
OSC_MSG_ADD_BOOL(h, val)2HandleAdd boolean argument
OSC_MSG_SEND(target, h)2BOOLSend constructed message

ControlForge v1.0.535 | Art-Net (7) + sACN (7) + MIDI (14) + OSC (12) | Entertainment & Show Control

© 2026 JMB Technical Services LLC. All rights reserved. Back to All Guides