Universal Controller MIDI

Advanced

Latency tuning

Squeeze every millisecond out of the bridge — poll rate, deadzones, OS scheduler priority, and the wired-vs-wireless ceiling you can't beat.

Updated

Latency tuning is the difference between "feels great" and "feels rubbery". The bridge ships with safe defaults — but if you're playing live, finger-drumming, or chasing sub-5 ms feel, there are four knobs that matter.

Poll rate

The input loop reads gamepad state at a fixed cadence. Default is 500 Hz (2 ms per cycle) — well below human perception. You can push it to 1000 Hz in Settings → Performance, which halves the worst-case input-to-MIDI gap.

Don't go above 1000 Hz. Most controllers report at 250–1000 Hz internally, so polling faster only burns CPU. Symptom of over-polling: fan spins up, no perceptible latency win.

{
  "poll_hz": 1000,
  "deadzone": 0.04,
  "scheduler_priority": "high",
  "midi_buffer_size": 64
}
stage total ms HID 2 ms poll 4 ms MIDI emit 0.5 ms DAW buffer 5–10 ms
Latency budget waterfall — each stage stacks into total round-trip time you can tune individually.

Latency contributions per stage

Total round-trip from finger press to audible note is the sum of every link in the chain. Here's what each one costs, wired vs wireless:

StageUSBBLEWhat it is
Controller scan0.5–1 ms0.5–1 msInternal ADC + HID report build
Transport0.5–1 ms7.5–15 msUSB poll vs BLE connection interval
OS HID driver0.5–1 ms1–3 msKernel HID stack delivery
Bridge poll cycle0–2 ms0–2 ms500–1000 Hz read interval
MIDI / OSC encode<0.1 ms<0.1 msBytes packed, queue write
Virtual port → DAW0.5–1 ms0.5–1 msCoreMIDI / WinMM hop
DAW audio buffer3–11 ms3–11 ms128–512 samples at 44.1 kHz
Total typical5–17 ms13–33 msPress to audible

Deadzone

A deadzone of 0.0 means every micro-jitter from the analog stick fires a CC event. The MIDI bus floods, the DAW chokes, automation gets noisy. Default is 0.04 (4%). For tight playing, drop to 0.02. For ambient pad sweeps where you want stability, 0.08 is fine. See deadzones for the full breakdown.

OS scheduler priority

By default the bridge runs at normal priority. On macOS you can promote the audio thread to QoS user-interactive in Settings → Performance — same priority bucket Logic uses for its audio engine. On Windows, "high" priority works; "realtime" is overkill and starves other processes.

# macOS — verify QoS class on the running poll thread
ps -M $(pgrep -x ucm) | awk '{print $5, $6, $7}'

# Linux — pin to a CPU core, bump priority
sudo chrt -f -p 80 $(pgrep -x ucm)
sudo taskset -p 0x2 $(pgrep -x ucm)

# Windows PowerShell — set High priority
Get-Process ucm | ForEach-Object { $_.PriorityClass = "High" }

The hard ceiling

Best-case wired latency: ~3 ms (USB report → poll → CoreMIDI → DAW). Best-case BLE-MIDI: ~10 ms. You can't beat the radio. If 3 ms isn't fast enough, you're chasing a problem that lives in your audio buffer, not the bridge.

Verify

The bridge's Visualise tab shows live event timing. Press a button rapidly and the trace should land bang on the grid. If you see jitter wider than 4 ms wired, something else is hogging the CPU. Hand-in-hand with Bluetooth troubleshooting if the link itself is the bottleneck.

Real-world scenarios

  1. Finger-drumming pads. USB, 1000 Hz poll, deadzone 0.02, buffer 64. Total ~6 ms — indistinguishable from a Push 3. Below this you're chasing milliseconds humans can't perceive.
  2. Live filter sweeps. 500 Hz poll is plenty (sticks don't move that fast). What kills you here is the DAW's automation smoothing — disable it, let raw MIDI through.
  3. Hardware synth into outboard. Bridge → USB MIDI interface → hardware. No DAW buffer in the chain at all. Typical ~4 ms end-to-end. Best feel you can get.
  4. Wireless ambient set. BLE acceptable. Set poll_hz: 500 to save battery, accept 15–20 ms — your filter sweeps don't notice.
  5. OSC into Resolume. Same machine, localhost UDP, <1 ms transport. Visual frame budget at 60 fps is 16.6 ms anyway — you have huge headroom.
Edit this page on GitHub Updated
ESC

Type to search.