AI-directed generative MIDI — play anything, Opus arranges the band.
Conductr is a browser-based instrument that generates four tracks of real-time MIDI output (drums, bass, melody, harmony), driven by your playing and shaped by a Claude Opus 4.6 AI musical director. Say "make it funky" and the arrangement changes. Play softly and the band pulls back. No audio synthesis — connect to any DAW or synth via Web MIDI.
Conductr operates on three timescales simultaneously:
| Layer | Timescale | What it does |
|---|---|---|
| C Engine (WASM) | ~15 ms per step | Deterministic note generation — Euclidean drums, walking bass, constrained-walk melody, diatonic harmony |
| Performance Analyzer | Every ~4 seconds | Extracts features from your playing — density, velocity trend, pitch range, silence ratio |
| Opus 4.6 Director | Every ~8 seconds | Reads the performance summary and outputs arrangement decisions — density, complexity, scale, feel |
The critical design insight: the engine never waits for Opus. Opus shapes the next phrase, not the current note. API latency is musically invisible — the band keeps playing while the director thinks.
- AI musical director — Opus 4.6 acts as an arranger, not a composer. It receives performance summaries and makes high-level decisions (energy, feel, scale, which tracks to feature)
- Voice commands — say "build to a climax" or "strip it down to drums" via Web Speech API
- Text commands — type "switch to minor" or "jazz feel" for instant arrangement changes
- 3D city visualization — procedurally generated cityscape reacts to the music in real time (Three.js + bloom post-processing)
- MIDI clock sync — slave to your DAW's transport (internal, auto-detect, or external clock modes)
- Fallback director — rule-based energy mapping when the API is unavailable — the instrument always works
- Deterministic C engine — same seed = same pattern. Lock a groove you like. ~3.6 KB total memory, zero heap allocation
- Physical MIDI input — connect a controller via Web MIDI and play into the system
You ──┐
│ notes / velocity / timing
▼
┌─────────────────────┐ ┌──────────────────────────┐
│ Performance Analyzer │───────▶│ Opus 4.6 Musical │
│ (JS, every ~4 sec) │ perf │ Director (async API) │
│ │ data │ │
│ density, velocity, │ │ "Building energy — │
│ pitch range, silence │ │ adding syncopation │
│ │ │ and drive" │
└─────────────────────┘ └────────────┬─────────────┘
│ params + intent
▼
┌──────────────────────────┐
│ Param Interpolator (JS) │
│ smooth transition over │
│ N bars │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ libgenseq (C → WASM) │
│ ~15 ms per step │
│ 3.6 KB, deterministic │
└────────────┬─────────────┘
│ MIDI events
▼
┌──────────────────────────┐
│ Web MIDI API Output │
│ Ch 10: Drums │
│ Ch 1: Bass │
│ Ch 2: Melody │
│ Ch 3: Harmony │
└────────────┬─────────────┘
│
▼
DAW / Synth / Hardware
Opus 4.6 is an arranger, not a note-by-note composer. Every ~8 seconds (or immediately on voice/text command), it receives a performance summary and the current engine state, then outputs:
{
"musical_intent": "Building energy — adding syncopation and drive",
"params": {
"drum_density": 95, "bass_movement": 80,
"melody_complexity": 70, "swing": 45,
"scale": "dorian", "track_mute": [false, false, false, false]
},
"transition": "gradual_2bars",
"suggestion": "Try holding a sustained chord — I'll open up the melody"
}The director maintains a conversation history (last 10 exchanges) so it tracks the musical arc of your performance. It knows what it did 30 seconds ago and builds on it — creating contrast, development, and surprise.
When the API is unavailable, a fallback rule-based director maps your playing energy directly to engine parameters: play louder → denser arrangement, stop playing → the band strips back.
| Component | Technology |
|---|---|
| Generative engine | C (compiled to WASM via Emscripten) |
| Browser app | Vanilla JavaScript, Vite |
| 3D visualization | Three.js + UnrealBloomPass post-processing |
| MIDI I/O | Web MIDI API |
| Voice input | Web Speech API |
| AI director | Claude Opus 4.6 (Anthropic API) |
| Timing | Web Worker clock (not setInterval) |
No frameworks. No React. No build-time AI. The entire generative core is 1,134 lines of C. The web app is 3,656 lines of vanilla JS. Total codebase: ~4,800 LOC.
- C compiler (gcc or clang)
- Emscripten (
emccon PATH) - Node.js 18+
- A Chromium-based browser (Web MIDI + Web Speech APIs)
- An Anthropic API key (optional — fallback director works without it)
# 1. Build the C engine to WASM
cd engine
make wasm # outputs web/public/wasm/genseq.{js,wasm}
# 2. Install web dependencies
cd ../web
npm install
# 3. Configure API key (optional)
cp .env.example .env
# Edit .env and paste your Anthropic key
# 4. Start dev server
npm run dev # opens http://localhost:5173Open the page in Chrome, pick a MIDI output port, and hit Play.
| Channel | Track |
|---|---|
| Ch 10 | Drums (GM standard) |
| Ch 1 | Bass |
| Ch 2 | Melody |
| Ch 3 | Harmony |
| Ch 5 | User input echo |
conductr/
├── engine/ Pure C library — 1,134 LOC
│ ├── include/genseq.h Public API + all type definitions
│ ├── src/
│ │ ├── genseq.c Tick loop, transport, pattern swap
│ │ ├── gen_drums.c Euclidean rhythm generation
│ │ ├── gen_bass.c Template + scale-constrained bass
│ │ ├── gen_melody.c Constrained random-walk melody
│ │ ├── gen_harmony.c Diatonic interval offset harmony
│ │ ├── music_utils.c Scale/MIDI conversion, quantize
│ │ └── rng.c xorshift32 PRNG (11 lines)
│ ├── test/ 4 test files (euclidean, scale, generators, integration)
│ └── Makefile
├── web/ Browser app — 3,656 LOC
│ ├── src/
│ │ ├── app.js Entry point, wires everything together
│ │ ├── engine-bridge.js JS ↔ WASM bridge (HEAPU8 memory reads)
│ │ ├── musical-director.js Opus 4.6 API integration
│ │ ├── fallback-director.js Rule-based director (no API needed)
│ │ ├── performance-analyzer.js 8-sec sliding window feature extraction
│ │ ├── param-interpolator.js Smooth parameter transitions
│ │ ├── midi-output.js Web MIDI API output
│ │ ├── midi-input.js Web MIDI API input
│ │ ├── midi-clock.js External MIDI clock sync
│ │ ├── clock-worker.js Web Worker tick clock
│ │ ├── input-pads.js Virtual pads + keyboard input
│ │ ├── input-voice.js Web Speech API voice commands
│ │ ├── ui.js DOM updates, pattern grid, controls
│ │ └── viz/ 3D city visualization (Three.js)
│ │ ├── city-viz.js WebGL renderer + bloom post-processing
│ │ ├── city-scene.js Procedural city generation
│ │ ├── highway-system.js Animated track paths
│ │ ├── pulse-pool.js Custom shader particle system
│ │ ├── mood-camera.js Dynamic camera presets
│ │ └── atmosphere.js Fog + lighting mapped to music
│ ├── index.html
│ ├── package.json
│ └── vite.config.js
├── docs/overview.md Full design document
└── LICENSE Apache 2.0