Blog Creative 9 min read

Csound + Gamepad — Real-Time Score Control with midictrl

Drive a Csound orchestra live from a PS5 or Xbox gamepad. Real-time score, midictrl on every CC, and held instruments that breathe under your thumb.

By Aidxn Design

Csound gamepad control is the kind of thing the Csound community has been quietly doing for years without writing a Medium post about it. The language has had real-time MIDI input since the 1990s — long before any of the modern DAWs — and that means every CC your DualSense or Xbox controller emits can be soldered straight into an orchestra. No mapping editor, no Max patch, no JUCE shim. Just midictrl and an instr block. This guide shows how to wire a PS5 controller into a live Csound score, hold a note open under your thumb, and bake the resulting performance to disk.

TL;DR
  • What you build: a Csound orchestra that reads gamepad CCs with midictrl and runs from a real-time score.
  • What you need: Csound 6.18+, Universal Controller MIDI, any DualSense or Xbox controller.
  • Time: 25 minutes if you've never touched Csound. 5 if you have.
  • Why it's good: deterministic, scriptable, renders to WAV. Live performance you can re-render bit-for-bit later.

Why Csound is the sleeper choice for gamepad performance

Csound is a music-N descendant. It splits an instrument's recipe (the orchestra) from when notes happen (the score). For a live gamepad performance, you put a single long note in the score and let the gamepad drive every parameter of the orchestra. The orchestra never knows the difference between a CC sent from a hardware MIDI controller and one sent from a gamepad bridge. That's the whole trick. The official MIDI control reference is worth bookmarking — it's terse, accurate, and unchanged since the late 2000s. Boring is good when you're routing CCs.

Set up the bridge and the Csound MIDI input

Open Universal Controller MIDI. Enable the virtual MIDI device output on the gamepad page (it's called "Gamepad Out" by default). On macOS this exposes a CoreMIDI port; on Windows it sits on top of a tiny WinMM virtual port the bridge ships with. No loopMIDI required.

Then launch Csound with two flags — -M picks the MIDI input device, -odac sends audio to the default output. List the port number first if you've forgotten it:

csound --midi-devices
# <PORT> 1 Gamepad Out
# <PORT> 2 IAC Driver Bus 1

csound -M1 -odac stickbox.csd

The minimal gamepad orchestra

Here's a Csound CSD that maps the left stick to filter cutoff/resonance, the right stick to detune and FM index, and L2/R2 to amp envelope shape. The score holds i 1 open for a full hour so you can perform until your wrist gives out.

<CsoundSynthesizer>
<CsOptions>
-M1 -odac
</CsOptions>

<CsInstruments>
sr      = 48000
ksmps   = 64
nchnls  = 2
0dbfs   = 1

; Gamepad CC map (matches the Universal Controller MIDI defaults)
;   CC 16 = left X    CC 17 = left Y
;   CC 18 = right X   CC 19 = right Y
;   CC 20 = L2        CC 21 = R2

instr 1
    ; Read sticks and triggers as k-rate values 0–1
    kLx     midictrl 16, 0, 1
    kLy     midictrl 17, 0, 1
    kRx     midictrl 18, 0, 1
    kRy     midictrl 19, 0, 1
    kL2     midictrl 20, 0, 1
    kR2     midictrl 21, 0, 1

    ; FM carrier + modulator
    kFreq   = 60 + kLx * 600          ; left X → root pitch
    kIdx    = kRy * 12                 ; right Y → FM index
    kRatio  = 1 + kRx * 3              ; right X → C:M ratio
    aFM     foscili 0.4, kFreq, 1, kRatio, kIdx, 1

    ; Resonant low-pass
    kCut    = 200 + kLy * 8000
    kRes    expcurve kL2, 8            ; L2 → resonance, exponential
    aOut    moogladder aFM, kCut, kRes

    ; R2 = amp
    aOut    = aOut * kR2

    outs    aOut, aOut
endin
</CsInstruments>

<CsScore>
f 1 0 8192 10 1                        ; sine
i 1 0 3600                             ; hold instr 1 for an hour
e
</CsScore>
</CsoundSynthesizer>

Save as stickbox.csd and run it. The gamepad now drives every audible parameter. Crucially: nothing in the score changes when you move a stick — only the k-rate values inside instr 1. That's the difference between a Csound performance and a MIDI track.

Wire face buttons to instrument triggers

Buttons feel better as note-on events than CCs. Map the four DualSense face buttons to MIDI channels 2, 3, 4, 5 in the bridge (one channel each, note 60 every time). Then massign them to fresh instruments. Pull-trigger detection becomes trivial.

; In <CsInstruments>, before instr 1
    massign 2, 11   ; Cross    → instr 11
    massign 3, 12   ; Circle   → instr 12
    massign 4, 13   ; Square   → instr 13
    massign 5, 14   ; Triangle → instr 14

instr 11   ; Cross — kick
    aEnv expon 1, 0.18, 0.001
    aSig oscili aEnv, 55
    outs aSig, aSig
endin

instr 12   ; Circle — snare hit
    aN  noise 0.8, 0
    aEnv expon 1, 0.12, 0.001
    outs aN*aEnv, aN*aEnv
endin

Buttons now fire one-shot Csound instruments while instr 1 keeps holding under your thumbs. That is, with respect, the cleanest design pattern in computer music: persistent pad + transient triggers, both driven from a $70 controller.

Default CC map at a glance

Gamepad inputBridge MIDICsound opcodeMapped to
Left stick X / YCC 16 / 17, ch 1midictrl 16 / 17Root pitch / filter cutoff
Right stick X / YCC 18 / 19, ch 1midictrl 18 / 19C:M ratio / FM index
L2 / R2 triggersCC 20 / 21, ch 1midictrl 20 / 21Resonance / amplitude
Face buttons ×4Note 60, ch 2–5massign 2–5, 11–14One-shot percussion instruments
D-pad ×4Note 60, ch 6–9massign 6–9Preset switch / score event toggles

Record the take with one flag swap

Every Csound performance is deterministic given identical CC streams. The bridge can log MIDI to a .mid file while you play, then you re-render the same orchestra with that file as the input. But for a quick capture, just replace -odac with -o take.wav in the CsOptions block and run live. Csound writes the audio as you perform.

<CsOptions>
-M1 -o take.wav -W
</CsOptions>

-W picks 16-bit WAV. Use -3 for 24-bit, -f for 32-bit float. The render finishes when you ctrl-C Csound. That's it — a gamepad performance, baked to disk, no DAW in the chain. See also our notes on gamepad to Eurorack CV for the same idea in hardware, and the Vital wavetable mapping post for a softer-edged synthesis target.

Why this beats a DAW for sound design

Csound has no inserts, no plugin scan, no auto-save corruption. The orchestra file is plain text. The gamepad bridge is offline. The whole rig fits in 200 lines and a $89 licence for Universal Controller MIDI. If you've ever wanted to perform synthesis instead of arrange it, this is the route. Pull up the bridge, hit run, and play the orchestra like an instrument.

Keep reading

More setup walkthroughs