Local LLM gamepad integration is the quiet sound-design upgrade we did not know we needed. The problem: every producer has hundreds of unnamed presets called "Init 47", "Pad 12", or "Bass Wobble Final v2". The fix: bind the DualSense touchpad to "save preset", route the parameter snapshot through a local Llama or Ghost Pepper model, get back a sensible name in 400 ms. No internet, no API key, no flow break. This guide wires Ollama (or LM Studio) into Universal Controller MIDI for instant gamepad-fired preset naming.
- What it is: a gamepad button that saves the current synth state and gets a named preset back in under half a second.
- Stack: DualSense → Universal Controller MIDI → script that reads DAW state → local Ollama → preset file.
- Why local: 400 ms round-trip, no API cost, no privacy concerns, runs offline at a gig.
- Model: Llama 3.2 3B for sensible names, Ghost Pepper for more characterful ones.
Why we built this
Naming presets is the worst kind of admin: low-stakes, high-friction, easy to skip. You crank a sound you like, you save it, you type "Bass 47" because typing anything better breaks your flow. Three months later you have 300 presets and zero idea what any of them sound like. Most producers solve this by tagging by feel and folder; some give up. We solved it by handing the naming to a tiny model that lives on the same machine and answers in milliseconds.
What "small fast model" actually means
For preset naming, the task is short: input is roughly 30 parameter values, output is two to four words. You do not need GPT-4. A 3B-parameter model running on consumer hardware does this in 400 ms with no warm-up if it is already loaded. On an M3 Pro, Llama 3.2 3B holds the whole context in memory and generates ten tokens in about 350 ms.
| Model | Size | M3 Pro speed | Personality |
|---|---|---|---|
| Llama 3.2 3B | 2.0 GB | ~350 ms / 10 tokens | Sensible, professional |
| Qwen 2.5 3B | 1.9 GB | ~380 ms / 10 tokens | Concise, slightly clinical |
| Ghost Pepper 7B | 4.1 GB | ~700 ms / 10 tokens | Creative, occasionally weird |
| Phi-3.5 Mini | 2.2 GB | ~400 ms / 10 tokens | Sensible, sometimes generic |
The end-to-end flow
It is simpler than it sounds. The gamepad fires one MIDI note. The script picks up the note, reads the current synth state from your DAW (via OSC or a sysex dump), formats a one-line prompt, calls the local Ollama HTTP endpoint, gets a string back, writes a preset file with that string as the filename.
DualSense touchpad click
│
▼
Universal Controller MIDI ──► Note 80, channel 1
│
▼
preset-namer.mjs ──► reads OSC state from DAW
│
▼
Ollama /api/generate (local) ──► "Velvet Hex" (string)
│
▼
~/Music/Presets/Serum/Velvet Hex.fxp The Node script
Sixty lines, no exotic dependencies. Reads MIDI, polls OSC for the current synth state, sends the prompt to Ollama, writes the preset.
// preset-namer.mjs
import easymidi from 'easymidi';
import fs from 'node:fs/promises';
import { Client } from 'node-osc';
import ollama from 'ollama';
const SYNTH_OSC_PORT = 8000;
const PRESET_DIR = `${process.env.HOME}/Music/Presets/Serum`;
const input = new easymidi.Input('Universal Controller MIDI');
let lastSnapshot = {};
const osc = new Client('127.0.0.1', SYNTH_OSC_PORT);
osc.on('message', (m) => {
lastSnapshot[m[0]] = m[1];
});
input.on('noteon', async (m) => {
if (m.note !== 80) return;
const prompt = formatPrompt(lastSnapshot);
const res = await ollama.generate({
model: 'llama3.2:3b',
prompt,
options: { temperature: 0.85, num_predict: 12 },
});
const name = res.response.trim().replace(/[/\\:*?"<>|]/g, '');
await fs.writeFile(
`${PRESET_DIR}/${name}.fxp`,
serialise(lastSnapshot)
);
console.log('Saved preset:', name);
});
function formatPrompt(snap) {
const lines = Object.entries(snap)
.map(([k, v]) => `${k}=${v}`).join('\n');
return `Name this synth preset in 2-4 words. Be evocative, not generic. No numbers, no "preset", no "patch". Just the name.
Parameters:
${lines}
Name:`;
}
function serialise(snap) {
return Buffer.from(JSON.stringify(snap));
} What good prompt design looks like for naming
The model needs constraints, or it will write essays. "No numbers", "no preset", "no patch" are the three big ones — without those you get back "Pad Preset 1" every time. Adding "Be evocative, not generic" pushes a Llama 3.2 toward "Velvet Hex" instead of "Warm Pad". A temperature of 0.85 is the sweet spot — high enough for personality, low enough to avoid nonsense like "Vorpalfish Buzzcannon".
Why a local model wins for this task
- Latency. 400 ms beats anything you can do over a network. By the time a cloud round-trip happens, you have lost the moment.
- No API key. One less thing to manage, one less thing to leak in a screen recording.
- No per-request cost. Two hundred presets in a session is two hundred saves. At cloud rates, that is a small annoyance every month.
- Works offline. Gig wifi is unreliable. A local model is not.
- Privacy. Your sound design parameters never leave your machine. Probably nobody cares, but still.
Ghost Pepper vs vanilla Llama for naming
Vanilla Llama 3.2 3B gives you sensible, slightly bland names: "Warm Wave", "Glass Pad", "Deep Bass". Ghost Pepper — a community fine-tune with more personality — gives you names like "Velvet Hex", "Sermon of Tides", "Bruised Iridescence". Whether that is good or insufferable depends on you and your folder structure. We use vanilla Llama for production work and Ghost Pepper for experimental sound design where weird names help recall.
OSC vs sysex for reading synth state
If your synth or DAW supports OSC (Bitwig, Ableton via Max, anything with the OSC standard), use that — it is faster and easier to parse than sysex. If you are on Serum or Vital, both expose state via VST3 plugin parameters that you can pull through your DAW's automation lane and forward via OSC. Pure sysex works too but is fiddly. Read your synth's documentation; if it has Reaper or OSC support, take the OSC path.
The verdict
Naming presets is one of those tiny friction points that compounds invisibly across years of producing. Throwing a 3B model and a gamepad button at the problem is the kind of disproportionate solution that ends up saving real time. It pairs cleanly with the Serum macro mapping from the same rig — design the sound with the gamepad, save it with the same gamepad, name it with a local model in under half a second. Universal Controller MIDI handles the trigger; Ollama handles the model; your library finally gets organised.