Blog TouchDesigner 13 min read

TouchDesigner Show Control From a Gamepad Over OSC

Send gamepad data into TouchDesigner over OSC: OSC In CHOP parameters, address scoping, queue tuning, and the chain that makes stick data usable.

By Aidxn Design

There is a specific moment in TouchDesigner work where MIDI stops being enough. You are riding a parameter slowly — a camera dolly over ninety seconds, a blur that creeps up through a build, a displacement field opening across a whole track — and you can see the steps. Not hear them, see them, because a 7-bit control change carries 128 values and a slow sweep spends about a second on each one. That is the moment to move to OSC, and TouchDesigner is the best-equipped application in the entire visual software landscape to receive it. This guide is about that route specifically: not the MIDI setup, which we cover elsewhere, but what changes when the gamepad speaks OSC instead.

TL;DR
  • The receiver is the OSC In CHOP, which accepts OSC messages from any spec-compliant sender over UDP.
  • Key parameters: port, protocol, oscaddressscope, stripsegments, and the queue trio maxqueue / queuevariance / adjusttime.
  • OSC is connectionless — it accepts messages from any number of sources at once, which is how multi-controller rigs stay simple.
  • Shape the signal immediately with Lag, Filter and Math CHOPs before anything downstream sees it.
  • OSC output is Pro-tier. The free tier is one controller, one MIDI port, three saved presets.

When is OSC genuinely worth the extra setup?

When the sweep is slow, when the control crosses a network, or when you want addresses that describe themselves rather than numbers you have to look up.

Signal flow diagram: Gamepad to Bridge to OSC over UDP to OSC In CHOP. Gamepad raw axes Bridge float, not 7-bit CC OSC over UDP named addresses OSC In CHOP TouchDesigner
The OSC route keeps the value floating-point from end to end, which is the whole reason to leave MIDI behind.

Three honest triggers, and if none of them apply you should stay on MIDI.

Visible quantisation. This is the big one. MIDI CC is seven bits, so 128 discrete values across the whole travel of a trigger. For a fast gesture that is invisible. For a ninety-second ramp it is a visible staircase, and no amount of smoothing downstream fully recovers information the protocol never carried. OSC carries floating-point values, so the staircase disappears at the source rather than being papered over.

Network distribution. OSC runs over UDP, which means the controller does not have to be attached to the machine doing the rendering. In a multi-machine installation — an operator position out front, render nodes in a rack — that is not a convenience, it is the only sane architecture. MIDI can cross a network too, but it needs a session layer that OSC simply does not require. Our comparison of RTP-MIDI versus USB MIDI covers that alternative, and the network MIDI setup guide has the practical steps if you want to stay on MIDI.

Readable addresses. /gamepad/lstick/x tells you what it is. CC 3 does not. In a project you will open in a year, or hand to somebody else, that difference compounds. It is a maintainability argument rather than a technical one and it is probably the most underrated reason to make the switch.

The broader protocol trade-off is laid out in OSC versus MIDI from a gamepad; this article assumes you have already decided.

What do the OSC In CHOP parameters actually do?

Port and Protocol get the data in, address scoping and prefix stripping decide what the channels are called, and the queue parameters decide how it behaves under load.

The documentation describes OSC In as connection-less, meaning it can accept multiple messages from any number of sources at the same time, and notes that you must specify a port number which OSC In will look for incoming messages on — and that this port must not have anything running on it before OSC In attempts to use it. That warning is the cause of roughly half of all "my OSC In CHOP shows nothing" problems.

ParameterInternal nameWhat it doesWhat to set it to for a gamepad
Network PortportThe UDP port OSC In listens onA port nothing else uses. Pick one, document it, and never change it mid-project.
ProtocolprotocolMessaging (UDP) or Multi-Cast Messaging (UDP)Plain Messaging for one machine. Multicast only if several machines need the same stream and your switch passes it.
Network AddressnetaddressMulticast group address when listening multicastLeave alone unless you deliberately chose multicast.
OSC Address ScopeoscaddressscopePattern-matches which addresses become channelsScope to your controller's prefix so unrelated OSC traffic never pollutes the CHOP.
Strip Prefix SegmentsstripsegmentsRemoves leading address segments when naming channelsEnough to turn /gamepad/lstick/x into something short and readable.
Maximum QueuemaxqueueCaps the message queue sizeSmall for responsiveness on a quiet local link; larger if you see dropouts on a busy network.
Queue VariancequeuevarianceAcceptable range around the target queue sizeLeave at default until you have a measured problem.
Queue Adjust TimeadjusttimeHow often the queue is correctedLeave at default. This is a last-resort tuning knob, not a first one.

There is also a Pulse Mode behaviour worth knowing about: it reads a single sample of any incoming message when it arrives and shows the pulse reset values the rest of the time, which the documentation suggests for syncing beats between TouchDesigner and other applications. For gamepad button events that is often exactly the shape you want — a one-frame spike rather than a held value.

How should you name the OSC addresses?

Hierarchically, by device then control then axis, so that address scoping and prefix stripping both have something to work with.

Address design is the part people improvise and then regret. A sensible scheme for a single controller:

/pad1/stick/left/x
/pad1/stick/left/y
/pad1/stick/right/x
/pad1/stick/right/y
/pad1/trigger/l2
/pad1/trigger/r2
/pad1/touch/x
/pad1/touch/y
/pad1/button/cross
/pad1/button/circle
/pad1/button/square
/pad1/button/triangle
/pad1/dpad/up
/pad1/dpad/down
/pad1/dpad/left
/pad1/dpad/right
/pad1/shoulder/l1
/pad1/shoulder/r1

Why this shape works. Setting OSC Address Scope to the /pad1 prefix means a second controller on /pad2 is trivially separable into a second CHOP, or trivially mergeable into the first by widening the scope. Setting Strip Prefix Segments to remove the first segment gives you channels named stick/left/x rather than the full path. And the device-first ordering means a multi-controller rig does not require renaming anything — you add a device, not a convention.

Resist the temptation to put semantics in the address — /pad1/blur_amount rather than /pad1/trigger/r2. The controller does not know what the trigger does, and the moment you reassign it in the project the address becomes a lie. Addresses describe hardware; the network describes meaning.

What does the signal chain after OSC In look like?

Scope, then filter, then scale, then branch — and never let a raw input channel drive a visible parameter directly.

This is the part that separates a demo from a show. Raw controller data is not suitable for driving anything. It is noisy near rest, linear where it should be curved, and bounded in a range nobody downstream cares about. Fix all three immediately, once, at the top of the network.

  1. Select. A Select CHOP after OSC In pulls out the channels a given part of the network needs. Branch early rather than carrying eighteen channels through every operator.
  2. Smooth. A Lag CHOP for asymmetric attack and release, or a Filter CHOP for a straightforward moving average. Lag is usually right for performance gestures because you want a fast rise and a slow fall; Filter is right for noise reduction on a stick.
  3. Scale and curve. A Math CHOP to get the range right, with exponent adjustments where the parameter is perceptually non-linear. Blur radius, scale and brightness all want curves; position usually does not.
  4. Rate, where you want velocity rather than position. A Speed CHOP turns a stick deflection into an accumulating value, which is how you get "push to scrub" rather than "push to set". This is the single most useful trick with a self-centring stick and the TouchDesigner equivalent of QLC+'s Relative mode.
  5. Events. A Trigger CHOP or a CHOP Execute DAT for buttons that should fire a script rather than move a value.

Build that chain once as a component, expose its parameters, and reuse it. Every controller input in the project should pass through the same shaping before it reaches anything, which means one place to fix a problem instead of thirty.

What is the right mapping for a TouchDesigner show?

Continuous generative parameters on the analog inputs, scene and state changes on the buttons, and one button reserved for recentring the accumulators.

ControlOSC addressChainDrives
R2 trigger/pad1/trigger/r2Lag → Math (exponent)Master effect intensity. Spring return means it always resolves to zero.
L2 trigger/pad1/trigger/l2Lag (fast attack, slow release)Feedback amount. The asymmetric lag is what makes a stab decay rather than cut.
Left stick X / Y/pad1/stick/left/*Filter → SpeedCamera orbit. Speed turns deflection into continuous rotation, which is what a stick is for.
Right stick X/pad1/stick/right/xFilter → MathNoise field evolution rate. Bidirectional from centre, so left can mean reverse.
Right stick Y/pad1/stick/right/yFilter → Math (exponent)Particle count or instance density. Heavily curved because density is perceptually logarithmic.
Touchpad X / Y/pad1/touch/*Filter onlyAbsolute 2D position for an effect origin. No Speed CHOP — absolute means absolute.
Cross/pad1/button/crossTrigger CHOPAdvance scene. One frame spike, not a held value.
Circle/pad1/button/circleCHOP Execute DATFire a Python callback — anything that is logic rather than a value.
Square/pad1/button/squareDirect booleanToggle a render switch. Simple state, no shaping needed.
Triangle/pad1/button/triangleTrigger CHOP → resetRecentre every Speed CHOP accumulator. Non-negotiable in any rig that accumulates.
D-pad/pad1/dpad/*Trigger CHOPPreset or bank navigation, four directions.
L1 / R1/pad1/shoulder/*Direct booleanShift layer and global bypass. Bypass is your panic button.

The recentre binding on Triangle is the one people leave out and then regret. Any network built on Speed CHOPs accumulates drift, and once a camera has orbited somewhere nonsensical there is no gesture that gets it back. Give yourself a button.

How does this differ from the MIDI route?

Structurally it does not — both land as CHOP channels — but OSC gives you resolution, names and network reach that MIDI cannot.

If you have already built a network around the MIDI In CHOP, the migration is less work than you expect, because everything downstream of the input operator stays the same. Swap the input, fix the channel names, keep the shaping chain. We cover the MIDI route in full in TouchDesigner DualSense controller mapping, and it remains the right starting point — build on MIDI, move to OSC when you have a reason.

The reason most people eventually find is the second machine. A rig that was one laptop becomes an operator position plus a render node, and at that point the controller has to reach across a network. Derivative's OSC user guide covers the surrounding concepts, and the OSC Out CHOP is how you send values back out — to a media server, a lighting desk, or a second TouchDesigner instance.

One caution worth stating plainly: OSC output is a Pro-tier capability in Universal Controller MIDI. The free tier covers one controller, one virtual MIDI port and three saved presets, which is a complete MIDI rig but not an OSC one. Build and prove the show on MIDI first — if the quantisation never bothers you, you have saved yourself a protocol.

What breaks, and in what order do you check it?

Port conflicts, address scope filters and firewall rules — almost always in that order.

  • No channels at all. Something else already holds the port. The documentation is explicit that the port must be free before OSC In attempts to use it. Change the port on both ends and retest before investigating anything else.
  • Channels appear, then vanish. Your OSC Address Scope pattern is narrower than you think, or the sender changed an address. Widen the scope temporarily to see everything arriving, then narrow it back once you know what the addresses really are.
  • Nothing arrives across the network. Firewall. UDP on your chosen port, both directions, on both machines. This is almost never a TouchDesigner problem and almost always an operating system one.
  • Values arrive but lag behind the hand. Start with your Lag and Filter settings before touching the queue parameters — smoothing you added is far more likely to be the cause than message queuing is.
  • Values are jittery at rest. That is stick drift arriving faithfully. Fix it at the bridge with a deadzone; the drift guide explains why filtering downstream is the wrong answer.
  • Everything is fine locally and awful on the venue network. Wi-Fi, almost certainly. Run the control link on wire. If you cannot, the survival tips in the Ableton Link venue Wi-Fi section apply to any UDP control traffic, not just Link.

How do you run two controllers over OSC?

Give each one its own address prefix and let the connectionless nature of OSC In do the rest — you do not need a second port or a second CHOP unless you want one.

This is one of OSC's quiet advantages over MIDI and it is worth understanding properly, because the MIDI equivalent is considerably more awkward. The documentation notes that OSC In is based on a connection-less system, meaning it can accept multiple messages from any number of sources at the same time. Two senders on one port is not a conflict, it is the normal case.

So a two-controller rig looks like this. Controller one sends on /pad1/..., controller two on /pad2/..., both to the same UDP port. One OSC In CHOP receives everything. If you want them combined — two performers driving one generative system — you are already done. If you want them separate, add a second OSC In CHOP on the same port with a different OSC Address Scope, or use Select CHOPs downstream to split the channel list.

Compare that to MIDI, where two controllers means either two virtual ports or careful channel discipline, and where the host has to be configured to listen to both. The OSC version requires no configuration change at all when you add the second device — you add an address prefix, and the network handles it.

Two practical notes. Keep the prefixes short and stable, because Strip Prefix Segments operates on segment counts and a prefix of inconsistent depth will produce inconsistent channel names. And never reuse a prefix, even temporarily during testing, or you will silently merge two devices' channels and spend an hour working out why a stick is jittering.

Multi-controller output is a Pro-tier bridge capability, as is OSC itself. The equivalent MIDI approach, including the port-per-device discipline, is covered in running two DualSense controllers.

FAQ

How do you get OSC into TouchDesigner?

Use the OSC In CHOP, which accepts Open Sound Control messages from any third-party application adhering to the OSC specification. Set its Network Port parameter to the port your sender is using, and make sure nothing else is already bound to that port.

Should I use OSC or MIDI for a gamepad in TouchDesigner?

MIDI for buttons and coarse parameters, OSC for anything continuous where 128 steps is visibly not enough or where control crosses a network. OSC carries floating-point values and named addresses, which both matter for smooth long sweeps.

What transport does the OSC In CHOP use?

UDP. The OSC CHOPs in TouchDesigner use the UDP transport protocol, and the Protocol parameter offers plain Messaging and Multi-Cast Messaging variants of it.

Why is my OSC In CHOP showing no channels?

Either nothing is arriving on that port, something else already had the port bound before OSC In tried to use it, or your OSC Address Scope pattern is filtering out everything. Check in that order.

How do I control the channel names coming from OSC?

OSC In CHOP exposes Strip Prefix Segments, which removes leading segments of the OSC address when generating the channel name, and OSC Address Scope, which pattern-matches which addresses are admitted at all.

Is OSC output free in Universal Controller MIDI?

No, OSC output is a Pro feature. The free tier covers one controller, one virtual MIDI port and three saved presets, which is enough for the MIDI route but not the OSC one.

Can one gamepad drive TouchDesigner on a different machine?

Yes — that is one of the main reasons to choose OSC over MIDI. OSC runs over UDP across the network, so the controller can be on the operator machine and the render node somewhere else entirely.

Start on MIDI, graduate to OSC

The honest path is to build the show on MIDI and move the controls that need it onto OSC when the staircase shows up. Download Universal Controller MIDI, get a stable MIDI In CHOP working first, then switch the two or three parameters that actually need floating point.

Keep reading

More setup walkthroughs