Controllers
Hardware and tablets as two-way nodes: pads, faders, LEDs, keys, pedals, GPI boxes.
MIDI Controller (pads, faders, LED feedback)#
Add Controller → MIDI Controller (right-click the Patch; its own menu between Add Processor and Add Output). A pad / fader controller as a two-way node: everything you press or move comes out of its State pin, and its pad LEDs show ShowKontrol state.
- Profile: Novation Launchpad Mini MK3 · Launchpad X · Launchpad Pro MK3 · Akai APC40 mkII · APC mini mk2 · Behringer X-Touch Compact · Novation Launch Control XL (MK1/MK2, not the 2025 XL 3). Each is a JSON file in
Documents/TC Supply/TEMPLATE/MIDI CONTROLLER(note/CC numbers, start-up SysEx, how LEDs take colour); copy and rename one to describe another controller, the built-in files are rewritten by app updates. - MIDI Port: Auto finds the device by name (a Launchpad's MIDI port, never its DAW port). Unplug it and plug it back in: it is found again, set up again and every LED repainted. The node face says waiting for … while it is away; its pads read released.
- Programmer Mode (on): sends the profile's start-up message (Launchpad Programmer mode, APC40 host mode, X-Touch Standard mode + layer A) so every pad reports and every LED is ours; deleting / disabling the node hands the device back.
- Keys (State pin):
midictl.<Name>.padN(1 while held, 0 released),midictl.<Name>.faderN/.knobN(0..1),.lastPad,.connected,.device,.profile. Wire State to Triggers (midictl.Pads.pad3, State On) → Actions, a Countdown's Start pin, a Counter … The Layout row shows how the profile numbers its pads (grids: top-left = pad 1, row by row; then the extra buttons). - Feedback rows (the + / trash list): each row lights one Pad when its condition holds, Deck Playing / Deck On Air / Deck Loaded / Tempo Master (Master or a player; no wire needed), Cue Active (a deck's cue list, any cue or one label), E-STOP, Data Key (Is On / Is Off / Equals / … on a key from what is wired to In, or
deckN.<key>, or a Countdown / Counter key such ascountdown.warningwith no wire at all), Pad Pressed, Always. On / Off Colour and When On (Solid / Flash / Pulse, the device's own animation). The first active row of a pad wins. The defaults light pads 1-8 green while decks 1-8 play. - RGB is sent as true colour where the device takes it (Launchpads, APC mini mk2 pads), else the nearest of the device's 128 palette colours (APC40), on / blink for single-colour buttons, red + green levels on the Launch Control XL. Only pads whose colour changed go out.
- Light Pressed Pads + Echo Colour, Unbound Pads colour, LED Rate.
- Learn Pad: Add a Feedback row, switch Learn on, press a pad, it goes into that row.
- Input needs macOS (CoreMIDI through the MBS plugin); on Windows the node drives LEDs only for now.
OSC Surface (TouchOSC, Open Stage Control, Lemur)#
Add Controller → OSC, also listed as Add Source → OSC, the node is called OSC Input (internally and in older shows it is the OSC Surface node; keys stay oscsurf.<Name>.*; new nodes are named OSCInput, shown as "OSC Input". The same node, ShowKontrol's general OSC input: any app or desk sending OSC to its port, not only tablets). A tablet layout as a two-way node: every control you touch comes out of its State pin, and feedback rows send LEDs, colours, values and texts back to the tablet.
- Listen Port (8000), the tablet's send port. Reply To: Sender (every tablet heard within the Tablet Timeout, at the Reply Port, 9000, TouchOSC's usual 8000 / 9000 pair) or a Fixed Host. Several tablets and several OSC Surface nodes can share one port.
- Keys (State pin):
oscsurf.<Name>.<address>with the slashes turned into dots,/1/fader1→oscsurf.Tablet.1.fader1= the first argument (a number, or the text of a string argument);.2.3.4= the next arguments (XY pads). Plus.lastAddress,.lastValue,.clientIP,.connected(1 = heard within the timeout),.messages. OSC bundles are unpacked. - Seen lists the addresses received so far, newest first, the quick way to find what a control sends (watch their values in the Live Data monitor). Learn Address: Add a Feedback row, switch Learn on, touch a control, its address goes into that row.
- KEYS drawer + Add Key (the node's settings panel, below the rows,
the same look and flow as the Triggers drawer): one row per OSC address you have added, with how many Triggers and Actions hang off it inside the node and its live value. + Add Key opens a menu: the addresses this node has received (newest first, a check = already a key), Type Address… (a field over the button, Return adds, Esc cancels) and Learn (next received) (a blue "Learning…" row; touch a control on the tablet, click the row to stop). Picking one registers the key and jumps INTO the node's interior in the Patch with a new Trigger already watching oscsurf.<Name>.<address> wired from the Data block (which carries the node's State), selected and ready for Actions, Event On Receive when nothing was heard yet (every message fires, a bare /go too), State On for a button (last value 0 / 1), On Change for a fader or text (change it on the Trigger if needed). Every address also publishes <key>.rxCount (messages received). Clicking a key row jumps to that key's Trigger; ✕ removes the key, if Triggers hang off it you choose Remove All (its Triggers and the Actions only they feed; cannot be undone), Keep Triggers or Cancel. Close in the Patch returns to the OSC node, selected, drawer showing. The interior works like a Device's: double-click the node to open it, unwired chain ends appear as extra out-pins on the node, a chain into Output adds its keys to the State pin. Keys and the interior save with the show; renaming the node updates the key Triggers' paths.
- Feedback rows (+ / trash): each sends ONE message to its OSC Address, Send = Value (On / Off value; numbers go as floats), Colour (On / Off colour, see Colour Format), Text (with
$VARIABLESand${keys}, e.g.$TITLEor$COUNTDOWNto a label) or Key Value (a data key's live value, a tablet fader that follows a DJM channel). When = the MIDI Controller's conditions (Deck Playing / On Air / Loaded, Tempo Master, Cue Active, E-STOP, Data Key, Always) plus Data Key Value (always on; use with Key Value) and Control On (the row's own address as the tablet sent it, an echo). Rows with the same address and kind: the first active one wins. Only changes are sent, plus everything again every Resend All seconds and whenever a tablet (re)appears. - Colour Format: TouchOSC Mk1 (
<address>/color+ the nearest colour name), Open Stage Control (/EDIT <id> {"colorWidget": "#rrggbb"}), RGBA Floats or Hex String to the address itself, TouchOSC Mk2 and Lemur can set a colour only from the control's script (onReceiveOSC). - No "generate TouchOSC layout": build the layout in the TouchOSC editor and pick up its addresses with Learn / Seen.
Mackie Control (X-Touch, X-Touch One, Platform M+ …)#
Add Controller → Mackie Control. A DAW control surface in MC / Mackie Control mode over USB MIDI: motor faders, V-Pots with LED rings, the buttons and their LEDs, the scribble-strip LCDs and the timecode display.
- Model: Behringer X-Touch / X-Touch Extender / X-Touch One, iCON Platform M+ / X+, Mackie Control (Logic Control) / XT, sets the SysEx id (extenders answer as 15), the X-Touch One's single strip and the port names MIDI Port Auto looks for (hot-plug safe, like the MIDI Controller). Strips 1-8. Handshake (on) answers the original Mackie units' challenge; X-Touch and iCON do not need it.
- Strips (Strip 1-8): Bound To Deck (LCD top
DECK n, bottom the LCD Bottom template read against the deck,${metadata.title}by default; the fader follows Fader Follows,mixer.chN.faderby default, wire the DJM's Device node to In), Data Key (LCD shows the key's name and value, the fader follows it) or None. Range = the followed key's full scale (DJM: 0..255). LCD Top overrides the upper text; six characters fit per strip, accents are dropped. - Motor Faders (on): the faders FOLLOW their key; touch one and it is yours (
mackie.<Name>.faderN,…Touch), let go and it returns. Master Fader Followsmixer.masterLevelby default. - Timecode Display: Master Deck / Deck 1-8 (HH MM SS FF of the deck), Bars/Beats (Master), Countdown, Time of Day or Off; the two Assignment digits say which (D1-D8, CD, TD) and the SMPTE / Beats LEDs follow. Display FPS sets the frame digits.
- V-Pot Rings (Dot / Fill / Boost/Cut / Spread / Off) show each V-Pot's value
mackie.<Name>.vpotN(0..1, V-Pot Ticks clicks end to end); the jog wheel counts in.jog(+.jogDelta). - Scribble Colours (X-Touch, firmware 1.22+): each strip's LCD in its Colour: Track Colour = the colour of the track cued on the deck.
- Buttons: Every button is a key, 1 while held,
.rec1-8.solo1-8.mute1-8.select1-8.vpotPush1-8, transport.play.stop.rewind.ffwd.record,.f1-.f8,.up.down.left.right,.zoom.scrub.shift.marker.cycle.bankLeft… and.lastButton. Nothing is hard-wired: wire State to a Trigger (e.g.mackie.XTouch.play, State On) → an Action to make a button do something. - Feedback rows (+ / trash) light button LEDs: Button, Lights When (the MIDI Controller's conditions + Button Held), When On On / Blink. The defaults light Select 1-8 while decks 1-8 play and Play while the master deck plays. Light Held Buttons echoes presses; Learn Button puts the next pressed button into the last row.
- Deleting / disabling the node blanks the surface and parks the faders.
- HUI mode is not built (a different protocol); level meters are not driven (no per-deck audio level to show). Input needs macOS (the MIDI Controller's CoreMIDI input); on Windows the surface only receives.
Stream Deck node (Patch Keys)#
Add Controller → Stream Deck. Turns Stream Deck keys into Patch inputs and lets the Patch paint them, the Stream Deck plugin's Patch Key action on one side (see Stream Deck under Remote Control), this node on the other.
- Setup: Web Server on, Allow Remote Control on, an Access Token set (Utility → Remote → Web Server); the plugin paired (Utility → Remote → Stream Deck). In the Stream Deck app drag ShowKontrol → Patch Key onto the keys the Patch should see. The node face says what is missing: Web Server off, needs Allow Remote Control + Access Token, waiting for the Stream Deck plugin, no Stream Deck connected, else the Stream Deck(s) and how many Patch Keys point at this node.
- Key numbers: A Patch Key on Auto is numbered by its place on the device, row by row from the top-left = 1 (Stream Deck MK.2: 1-15, XL: 1-32, Mini: 1-6). A number set in the key's own settings wins (use that in Multi Actions and on pages that repeat a layout).
- Stream Deck: Any or one named device (two Stream Decks, two nodes). A Patch Key names its node (blank = every Stream Deck node).
- Keys (State pin):
streamdeck.<Name>.keyN(1 while held, 0 released; 1-32 always exist),.lastKey,.connected(a Stream Deck is there),.devices,.keys(Patch Keys pointing here),.device(the one pressed last). Wire State to a Trigger (streamdeck.Keys.key5, State On) → Actions, a Countdown's Start pin, a Router … - Feedback rows (the + / trash list): each row paints one Key when its condition holds, the MIDI Controller's conditions (Deck Playing / On Air / Loaded / Tempo Master, Cue Active, E-STOP, Data Key, Key Pressed, Always), in its On Colour with its On Title (
$VARIABLESwork:$BPM,$COUNTDOWN…), When On Solid or Flash; otherwise Off Colour / Off Title. A blank title = the key's own label, else its number. The first active row of a key wins. Keys no row mentions use Unbound Keys. - Light Pressed Keys + Echo Colour, Feedback Rate (2-30 Hz; faces reach the plugin at most at the Web Server's rate, only when changed).
- Learn Key: Add a Feedback row, switch Learn on, press a Patch Key.
- If the plugin goes quiet for 10 s (Stream Deck app quit, Mac asleep) its held keys are released.
Hotkeys (keyboard, foot pedals, presentation clickers)#
Add Controller → Hotkeys. Keys and key combinations as data keys, the Mac keyboard, a USB foot pedal or a presentation clicker (they are keyboards too: Page Down / Page Up, the arrows, B or Period, F5 / Shift+F5, Esc).
- Bindings (the + / trash list): Key (letters, digits, F1-F20, arrows, Page Up / Down, Home / End, Space, Return, Esc, keypad …), Modifiers (None, Any (with or without, for pedals) or an exact combination such as Ctrl+Shift), Label. Two bindings with the same label drive one key (Page Down and Right both
next). New nodes start with Page Down =nextand Page Up =prev. - Keys (State pin):
hotkeys.<Name>.<Label>(1 while held, 0 released),.lastKey(the label pressed last),.pressCount,.active(any binding held),.permission,.scope. - Listen: When ShowKontrol Is Frontmost (no permission needed) or System-Wide (also keys typed into other apps, needs ShowKontrol ticked in System Settings → Privacy & Security → Accessibility; the Permission row shows Accessibility and Input Monitoring, Open Privacy Settings jumps there; keys arrive within 2 s of allowing it).
- Swallow Keys (frontmost only): a bound key is used up, the window in front does not also see it (a pedal's Page Down does not scroll the Patch). Keys typed into other apps cannot be swallowed. Ctrl+Esc (lock) and Cmd+Q are never swallowed.
- Typing is safe: While a text field has the focus, bindings WITHOUT a modifier are ignored (the letters go into the field); Cmd+… bindings still work.
- Work While Locked: Off = the node ignores keys while the machine is locked (Ctrl+Esc).
- Learn Key: Add a Binding row, switch Learn on, press the key (or the pedal / clicker button), key and modifiers go into that row.
- A key held while ShowKontrol loses the focus (frontmost scope) reads released. macOS only for now.
Game Controller (Xbox, PlayStation, Switch Pro pads)#
Add Controller → Game Controller. A game pad as a two-way node: every button and stick comes out of its State pin, and its light bar / rumble follow ShowKontrol state. USB or Bluetooth, pair it in macOS System Settings → Bluetooth first.
- Controller: Any (the first pad connected), Player 1-4 (the Nth connected pad, for two or more identical pads; PlayStation / Switch pads light that player LED when Show Player Number is on) or a pad by name. Unplug / switch it off and back on: it is found again; while it is away its buttons read 0, sticks 0 and the node face says waiting for ….
- Keys (State pin):
gamepad.<Name>.abxylbrbltrtdpadUpdpadDowndpadLeftdpadRightmenu(Start / Options / +)options(Back / View / Share / Create / −)l3r3homeshare(Xbox Series)touchpad(PlayStation), 1 while held, 0 released; stickslxlyrxry(−1..1, up and right = +);ltValuertValue(0..1, the analog triggers,lt/rtread 1 past the Trigger Threshold);connected,controller(its name),type(DualSense, Xbox One …),player,battery(0..1, −1 = unknown / wired),charging,lastButton. Wire State to Triggers (gamepad.Pad.a, State On) → Actions, a Countdown's Start … - Stick Dead Zone (0.12): a resting stick reads exactly 0; beyond the zone the travel is rescaled so full deflection still reads 1.
- Feedback rows (the + / trash list), each: Do Light Bar (the colour while the condition holds, DualShock 4 / DualSense; the first active row wins, Light Bar Idle otherwise) or Rumble (one pulse of Pulse (ms) at Strength each time the condition becomes true). When: Deck Playing / On Air / Loaded / Tempo Master, Cue Active, E-STOP, Data Key (a wired key,
deckN.<key>, a Countdown key or another controller's key), Button Pressed, Always, the same conditions as the MIDI Controller's rows. - MacOS: Apple's GameController framework (macOS 11+); input keeps flowing while ShowKontrol is in the background. Windows: XInput pads only (Xbox and XInput-compatible; PlayStation pads via Steam Input / DS4Windows), rumble but no light bar .
Serial GPI (Arduino, relay and contact-closure boxes)#
Add Controller → Serial GPI. A box on a USB serial port: its contact inputs come out of the State pin, its outputs (tally lamps, a GO light, relays) follow ShowKontrol state.
- Port: Auto (USB serial) = the first USB serial device (Arduino, FTDI, CH340, CP210x), or pick one. Unplug the box: its inputs read 0 and the node face says waiting for …; plug it back in and it is reopened and every output re-sent. Baud: 115200 for the SKGPI sketch, 9600 for KMTronic.
- Protocol:
- ShowKontrol Text: The free SKGPI Arduino sketch : 8 inputs with pull-ups (a contact to GND, closed = 1), 4 outputs, optional analog inputs and RGB pixels. Lines
IN n 0|1,A n valuein;OUT n 0|1,RGB n r g bout. The box switches its outputs off by itself if ShowKontrol goes silent for 5 s. - Raw Line: Any device that sends text lines: each line is
gpi.<Name>.line(+lineCount), and the Line Map turns lines into keys, one rule per line:<regex> => <key>(value = the first( )capture, else 1) or<regex> => <key> = <value>, e.g.^GO$ => go. Output rows send a text line (Send On / Send Off, with Line End). - Numato GPIO: Numato Lab USB GPIO modules: inputs polled with
gpio readallevery Poll (ms), ADC Channels (e.g.0,1) read withadc read, outputsgpio set / clear; pins as printed (IO0 =in0); the output rows' pins become outputs, all others inputs. Invert Inputs for contacts to GND (the pin reads 1 while open). - KMTronic Relay: KMTronic USB relay boards (outputs only).
- ShowKontrol Text: The free SKGPI Arduino sketch : 8 inputs with pull-ups (a contact to GND, closed = 1), 4 outputs, optional analog inputs and RGB pixels. Lines
- Inputs / Analog Inputs: How many keys exist from the start (
in1…,analog1…; Numato from 0). Debounce (ms) (20): an input must hold its new state that long beforeinNchanges. - Output rows (the + / trash list): Output n is ON while ANY of its rows' condition holds, Deck Playing / On Air (a tally lamp per deck) / Loaded / Tempo Master, Cue Active, E-STOP, Data Key, Input On (mirror one of the box's inputs), Always. Text protocol: Drive RGB Colour sends the On / Off colour instead. Only changes are sent; disabling or deleting the node switches its outputs off.
- Keys:
gpi.<Name>.inNanalogNlinelineCountconnectedportdevice(the box's HELLO) + the Line Map's keys. Works on macOS and Windows .
