Roadmap
Questa pagina è in inglese: in italiano ci sono per ora i tutorial e il glossario; menu, ricerca e navigazione sono in italiano.
What is ready, what is being built, and what comes next. Updated whenever a status changes (last update: 2026-10-09).
Legend: ✅ done (implemented, tested, verified) · 🔄 in progress · 📝 specified (behavioural spec reviewed, ready to implement) · ⬜ planned · 💡 proposed (to be confirmed)
At a glance
Section titled “At a glance”Foundations (repo, licence, CI, docs, CMake) ██████████████████████ 100% ✅Core foundations (base, timecode, time, cmd) ██████████████████████ 100% ✅Networked audio and redundancy ████████████████████░░ 90% 🔄Live engine domains (setlist, show control…) ████████████████████░░ 90% 🔄Adapters (JUCE, Tracktion, protocols) ██████████████░░░░░░░░ 65% 🔄User interface ███████████████████░░░ 88% 🔄Media and production ████████░░░░░░░░░░░░░░ 35% 🔄AI, education and research ██████░░░░░░░░░░░░░░░░ 25% 🔄General music apps (dsp, synth, engine, edit) ████████████████████░░ 93% 🔄Independence (permissive backend stack) ███████████░░░░░░░░░░░ 50% 🔄Percentages count specified and implemented requirements, not lines of code.
Stability at 0.1.0 (decision
0020):
stable base, time, timecode, commands, midi, dsp; every other
module and every adapter is experimental. Each module README’s summary
block has its Stability line; modules.md
has the table.
The roadmap covers the whole framework: shuffle_engine and its satellite repositories (satellites.md). Rows and boxes marked with a satellite’s name (shuffle_juce, shuffle_ai, shuffle_edu, …) are built there.
The map
Section titled “The map”flowchart LR
classDef done fill:#2e7d32,stroke:#1b5e20,color:#ffffff
classDef wip fill:#f9a825,stroke:#f57f17,color:#000000
classDef spec fill:#1565c0,stroke:#0d47a1,color:#ffffff
classDef todo fill:#eceff1,stroke:#90a4ae,color:#37474f
classDef idea fill:#ffffff,stroke:#9e9e9e,color:#616161,stroke-dasharray: 5 5
subgraph P0["0 · Foundations"]
repo["repo, licence, REUSE"]:::done
ci["CI: 5 platforms + WebAssembly"]:::done
docs["docs site, decisions"]:::done
cmake["CMake + project generator"]:::done
end
subgraph P1["1 · Core foundations"]
base["base"]:::done
timecode["timecode"]:::done
time["time"]:::done
commands["commands + recorder"]:::done
resilience["resilience rules"]:::spec
end
subgraph P2["2 · Network"]
netaudio["netaudio (AES67, PTP)"]:::done
redundancy["resample + redundancy"]:::done
remote["remote"]:::todo
osc["osc"]:::done
end
subgraph P3["3 · Live engine"]
midi["midi"]:::done
tempo["tempo"]:::todo
routing["routing (audio + MIDI)"]:::done
setlist["setlist"]:::done
showcontrol["showcontrol"]:::done
cues["cues (theatre model)"]:::done
sync["sync (MIDI clock out)"]:::wip
looper["looper (retroactive capture)"]:::done
more["voiceover, lyrics, harmony,<br/>tuning, events"]:::todo
end
subgraph P4["4 · Adapters"]
sockets["OS sockets (UDP, TCP, interfaces)"]:::done
codecs["codecs (FLAC, Vorbis, Opus, MP3)"]:::done
juce["JUCE 9 platform, MIDI<br/>(shuffle_juce)"]:::done
jplug["JUCE 9 plugins (VST3, AU, LV2)<br/>(shuffle_juce)"]:::done
jaudio["JUCE 9 audio devices (own engine)<br/>(shuffle_juce)"]:::done
jnet["JUCE 9 net (HTTP)<br/>(shuffle_juce)"]:::todo
te["Tracktion devices, engine<br/>(shuffle_juce)"]:::wip
tep["Tracktion plugins<br/>(shuffle_juce)"]:::todo
proto["OSCQuery, web, Companion, MCP<br/>(shuffle_protocols)"]:::todo
end
subgraph P5["5 · UI"]
uimodel["ui_model"]:::wip
uitheme["ui_theme"]:::wip
uilayout["ui_layout + DirectWrite measurer"]:::done
uibridge["ui_bridge (web / native UI)"]:::wip
uimodelspec["ui_model (interaction)"]:::spec
uirendercore["ui_render + Direct2D renderer<br/>(draw list, Renderer2D)"]:::done
uiwidgets["ui_widgets + Win32 window<br/>(widgets, screens, PlatformWindow)"]:::done
uirender["Apple, Android, Linux, web<br/>renderers and windows"]:::todo
ui["timeline, waveform, mixer,<br/>transport, stage…"]:::todo
end
subgraph P6["6 · Media & production"]
video["video<br/>(shuffle_media)"]:::done
videofx["video_fx + Direct3D 11 renderer<br/>(shuffle_media)"]:::done
videomf["Media Foundation decode, export,<br/>presenter (shuffle_media)"]:::wip
videoplat["AVFoundation, MediaCodec,<br/>WebCodecs, FFmpeg (shuffle_media)"]:::todo
media["documents, lighting, hwcontrol<br/>(shuffle_media), package"]:::todo
end
subgraph P7["7 · AI, education, research"]
ai["inference, neural, llm, mir<br/>(shuffle_ai)"]:::spec
aitasks["ai_tasks + audio.cpp adapter<br/>(shuffle_ai)"]:::done
assistant["assistant"]:::todo
edu["compose, spectral, spatial, notation<br/>(shuffle_edu)"]:::todo
pd["Pure Data / Max integration"]:::todo
py["Python: bindings + remote client<br/>(shuffle_python)"]:::spec
end
subgraph P11["Showcases"]
scoresync["Score Sync, Windows<br/>(shuffle_showcase)"]:::done
showcases["Pro Meter, Live Set, Visual Live…<br/>(shuffle_showcase)"]:::todo
end
subgraph P10["No-code applications"]
studio["Studio builder + Player<br/>(shuffle_studio)"]:::spec
end
subgraph P9["General music apps"]
loudness["loudness"]:::done
dsp["dsp"]:::done
synth["synth"]:::wip
engine["engine"]:::wip
formats["formats"]:::wip
end
subgraph P8["8 · Independence"]
stack["own engine, Visage"]:::todo
plibremidi["libremidi MIDI 1.0 and 2.0"]:::done
pminiaudio["miniaudio audio devices"]:::done
pwebaudio["Web Audio in the browser"]:::done
pcodecs["permissive codecs"]:::done
pplatform["platform ports<br/>on std + OS"]:::done
pplugins["CLAP, VST3, LV2, AU hosting"]:::done
end
P0 --> P1 --> P2 & P3
P3 --> P4 --> P5 --> P6
P1 --> P7
P4 --> P8
P1 --> P9
P5 --> P10
P6 --> P11
Phase by phase
Section titled “Phase by phase”0 · Foundations — ✅ done
Section titled “0 · Foundations — ✅ done”| Item | Status | Where |
|---|---|---|
| Repository, Apache-2.0 licence (0021), REUSE compliance, contributor licence agreement (1.0) | ✅ | LICENSE.md |
| Repository rules check (licence headers, layering, forbidden terms) | ✅ | tools/check_repo.py |
| CI: Windows, macOS, Linux, iOS, Android, WebAssembly, docs | ✅ | .github/workflows/ci.yml |
| Documentation site (Quarto) and decision records 0001–0021 | ✅ | decisions |
CMake support: shuffle_engine_add_app, find_package, FetchContent, project generator (core / JUCE 9 / Tracktion backends verified) |
✅ | using-cmake.md |
| Tested examples | ✅ | examples/; JUCE, Tracktion and AI examples in their satellites |
Guides for agents and contributors, llms.txt |
✅ | AGENTS.md |
Versioning and releases: SemVer policy, CHANGELOG.md, shuffle/base/Version.h, tools/bump_version.py, release workflow (source archives, SBOM, checksums) |
✅ | releasing.md |
1 · Core foundations — 🔄
Section titled “1 · Core foundations — 🔄”| Module | Status | Requirements | Tests | Notes |
|---|---|---|---|---|
base |
✅ | — | 52 | ports: MIDI out and in (source, directory), instrument chains, task queue, audio output and input topology, MIDI endpoint topology, output stage, events, feature gate, clock, datagram and stream sockets, displays, system appearance, frame clock; lock-free queue; fakes and contract suites |
timecode |
✅ | 120 / 120 | 243 | 11 rates (high rates as frame pairs), MTC and LTC out to named endpoints (16 destinations, unpatched and held reports), cue conflicts, monitor; LTC decoding and MTC receive, lock, freewheel, jumps, smoothed position, rate identification, followers with start, stop, resume and drift rules, triggers, timecode-in switch, command table; ~7.7 µs per block with 16 streams, LTC decoding ~3.8 µs per 512-sample block |
time |
✅ | 40 / 40 | 99 | flicks, positions and durations, ranges, tempo maps with key signatures and map edits, section anchors, quantised jumps, launch grids, musical count, TAI scheduling; ~40 ns per conversion, ~380 ns per launch boundary |
commands (+ recorder, generated protocols) |
✅ | 81 / 81 | 197 | catalogue lookup ~37 ns, phrase parsing ~9 µs on 500 commands; OSCQuery, OpenAPI, Companion, MCP tools, GBNF generated with access class, show-mode availability and GO flag; GO protection (~30 ns per check), show mode, inhibit registry, access levels and clients, collaborative editing (revisions, authors, per-author undo, request identifiers), duplicate filtering (~26 ns per message), composite target for several domains in one session |
resilience (rules + fault injection) |
📝 | 8 | — | applied by every module |
2 · Network — 🔄
Section titled “2 · Network — 🔄”| Module | Status | Requirements | Notes |
|---|---|---|---|
netaudio |
✅ | 140 / 160 (ASRC, IPv6, NMOS later) | AES67 / RAVENNA / ST 2110-30, PTP follower, SDP, SAP, mDNS/RTSP, RTP-MIDI; 334 tests; RTP receive ~0.5 µs per packet, servo update ~6 ns |
resample |
✅ | — | shared real-time resampler, ~134 dB S/(N+D), 20 µs per 128-frame block for 16 channels; kernel cut-off for fixed-ratio conversion in dsp |
redundancy |
✅ | 75 / 75 | stream health, failover, synchronous start, command distribution; 134 tests; open issues RD-OI1..7 for the next spec revision |
remote |
⬜ | — | discovery, remote views and control |
osc |
✅ | 63 / 63 | OSC 1.0/1.1 wire format, bundles and time tags, bounded patterns, scheduled dispatch, UDP and TCP (size prefix, SLIP) framing, OscEndpoint; 78 tests, 1 million-input fuzz run; decode ~150 ns and encode ~34 ns per 16-float message — spec, README |
3 · Live engine — 🔄
Section titled “3 · Live engine — 🔄”| Module | Status | What it brings |
|---|---|---|
midi |
✅ | 142 / 142 requirements, 161 tests (open issue MI-R130 to check against the UMP translation tables): byte-stream parser, note gates and held-note activity, tracked outputs with timed sends and panic, activity monitor, trigger matching and learn (an owner such as learn-action declares the messages it keeps from bindings), tolerant binding persistence, MSC receive and encode, UMP and MIDI 1.0/2.0 translation, RPN/NRPN, chase, sequence playback timing, command table; gate ~16 ns per message, matching ~0.6 µs against 2 000 bindings, MSC decode ~41 ns — spec, README |
tempo |
⬜ | tempo estimation, click and beat analysis |
routing |
✅ | 171 / 171 requirements, 138 tests: named audio and MIDI endpoints with this machine’s patch kept apart from the show, device and port matching, declared fallbacks, backup devices, health; matrices, buses, inserts, gangs, solo, audition, monitor mixes, output maximums; live inputs with drift compensation; lock-free routing program with sample-exact ramps and loudness programme meters; MIDI routes with held-note safety, merge, feedback detection; published virtual ports; 49 commands; ≈ 50 µs per 128-frame block for 16 sources × 32 outputs, ≈ 1.2 µs per MIDI event through 64 routes — spec, README |
setlist |
✅ | 76 / 76 requirements, 118 tests: set list with stable identities, navigation with one-shot next and skips, transitions as end-of-song plans (segue proven sample-exact at 44.1/48/96 kHz), switch protection with repeat-to-confirm, show mode as the performance lock, background loading with cancellation and notices, quantised start/stop/switch on the song or session count, roll-in, live re-arrangement, tempo sync follow/lead with peer start/stop rules and rejoin watchdog, follow timecode, playhead segments and loop passes (TransportCursor), click on a named output, coalesced saves and autosave; the current song’s music for cues (ShowMusic implements MusicPosition: map, arrangement, position, jumps with their count); engine ports with fakes that simulate an engine and contract suites; ≈ 51 ns per transport block, ≈ 9 µs to rebuild the plans of a 40-song set list — spec, README |
sync |
🔄 | our own open tempo-sync protocol (wired PTP sample-aligned, Wi-Fi, BLE, USB, internet relay, MIDI clock), Ableton Link bridge optional. Done: the MIDI clock output, 15 / 43 requirements (SY-R29 to SY-R43), 30 tests: pulses from the tempo map with ramps, clock while stopped, Start / Song Position Pointer + Continue / Stop, latency through the device timing (MIDI latency up to ±500 ms), timed delivery by platform::TimingThread or block delivery, engine node, sync.* commands; ~125 ns per block for 8 outputs, send error p99 13 to 132 µs on a quiet machine; example midi/clock. The tempo session (SY-R1 to SY-R28) is still 📝 — spec, README |
looper |
✅ | 48 / 48 requirements, 49 tests: an always-on input history and retroactive capture of the last bars, beats or seconds through the round trip; record, overdub, replace, multiply, one level of undo with fills and merges within a work budget; switched off and on at run time with its memory freed; reverse, half and double speed; now, at-sample and quantised actions split on their sample; volumes, mute groups, scenes, fades, panic; device class presets with memory budgets; engine node and 17 looper.* commands; 7.6 µs per 256-sample block for 8 stereo tracks and an overdub; example looper/retro_capture — spec, README |
showcontrol |
✅ | 145 / 145 requirements, 146 tests: actions of every kind with stable codes, destinations and patches on named MIDI outputs and hosts, message building through midi and osc, templates filled at the fire instant, value curves (modes, own timing and loops, curvature, beat points, cues fade shapes), sample-accurate timeline fires on the audio thread with a lock-free hand-off, chase, recall on locate, note-offs on every discontinuity, repeats, spaced groups, matrix with quantised cells, learn with binding suppression, eight output inhibit switches, lint, import by identity, durable tolerant persistence with migration, MIDI file playback with chase and in-block offsets (MidiOutputPort::sendAt), time inserts and deletes on every curve timing; 49 commands; ports TimelineEvents, HostResolver, TimecodeActions, CommandRunner (and FileStore in base); ≈ 60 ns per timeline fire, ≈ 20 ns per sequential curve step — spec, README |
cues |
✅ | 171 / 175 requirements done (4 delegated: script and MIDI loop/note-off behaviour under CueTarget contract suites, MIDI binding creation in midi), 198 tests: lists, playheads and GO, waits and continue rules on a deterministic schedule of TAI instants (no drift), groups (timeline, playlist with clamped crossfades, first child with entering, random with SplitMix64), retrigger and press/release rules, fades along curves (logarithmic included) and ducks computed per block with no allocation, panic/pause/resume/reset, wall-clock triggers with catch-up, load to time and start from a position, preview and GO auditions, control cues, health and lint, safe opening, key and timecode bindings, grids with scenes and follow actions, quantised launch on the musical count, waits until musical anchors re-resolved when the music is republished, leave loop on a musical boundary, content following tempo, record mode, published fallback table, bulk edit, find, performance report CSV; 73 commands; ports CueTarget, CueParameters, MusicPosition, CivilTime with fakes and contract suites; ≈ 3.2 µs per block for 256 fades, ≈ 1.1 ms to resolve 2 000 cues — spec, README, show-control.md |
voiceover, lyrics, harmony, tuning, events |
⬜ | spoken cues, timed lyrics, chords, tuner, timeline events |
4 · Adapters — 🔄
Section titled “4 · Adapters — 🔄”| Adapter | Status | Implements |
|---|---|---|
| JUCE 9 platform / MIDI | ✅ | shuffle_juce_platform: JuceTaskQueue, ControlTimer, JuceWorkerPool, JuceClock (local only), JuceFileStore (atomic writes), JuceSettingsStore (properties file saved on a worker); shuffle_juce_midi: JuceMidiOutput (real-time send through a preallocated queue, UMP declared unsupported), JuceMidiInput (bytes with Clock timestamps), JuceMidiDevices (directories with persistent ids, MIDI rescans as DeviceEvents); every platform and MIDI contract suite passes, MIDI suites on real ports skip when a machine has none; 51 tests, example juce/platform; in shuffle_juce — README |
| JUCE 9 plugins | ✅ | shuffle_juce_plugins: JucePluginHost (PluginHost on JUCE’s headless formats, VST3 / AU / LV2; in-process scan on a worker with a dead man’s pedal so a crashing plugin is skipped from the next scan; known plugins and skipped files in the SettingsStore; asynchronous instantiation, state save and restore; names resolved with ambiguity reported), JucePluginInstance (layout negotiation and channel mapping, MIDI and SysEx with offsets, parameters 0..1 with names, transport as the play head, latency through a listener, allocation-free process), PluginInsert (InsertProcessor); no audio device needed; the PluginHost and InsertProcessor contract suites pass on in-process test plugins; 27 tests, example juce/plugins; in shuffle_juce — README |
| JUCE 9 audio devices | ✅ | shuffle_juce_audio, the framework’s own engine on JUCE’s audio drivers without Tracktion (and without opening MIDI): JuceAudioDevices (AudioDeviceChannels with keys "<driver type>:<device name>", channel labels, rates; AudioDeviceSwitch posted through TaskQueue, the previous device reopened on failure; DeviceEvents on the drivers’ notifications), EngineAudioCallback (one Engine::process per device callback with flush-to-zero and denormals-are-zero, DS-R16; device inputs to the engine and to routing’s device block; xruns to the overload monitor; the engine prepared on the control thread; output stages run by the engine; the device’s latencies with every block; no allocation, tested), JuceProcessingThreads (ProcessingThreads on real-time JUCE threads, audio workgroups); the AudioDeviceChannels, AudioDeviceSwitch, DeviceEvents, OutputStageHost and ProcessingThreads contract suites pass on a fake driver and on this machine’s devices; 26 tests, example juce/play; in shuffle_juce — README |
| JUCE 9 web interfaces | ✅ | shuffle_juce_webui: JuceWebUiHost (WebUiHost on juce::WebBrowserComponent: packaged content through the resource provider under a strict CSP, navigation kept on the content origin, one frozen bridge endpoint, page start reported before page scripts run, availability naming what is missing; WebView2 linked when its SDK is found); passes the WebUiHost contract suite and a full bridge handshake on WebView2 ([engine], skipped without a display); declared limits: no permission, developer-tools or crash events in JUCE’s API; 5 tests, example juce/webui; in shuffle_juce — README |
| JUCE 9 network | ⬜ | HttpClient; in shuffle_juce |
| Tracktion devices / engine | 🔄 | shuffle_te_devices: TeOutputStageHost (global output hook), TeAudioDevices (AudioDeviceChannels, AudioDeviceSwitch, DeviceEvents); shuffle_te_engine: TeSongSessionFactory / TeSongSession (one Edit per song, read on workers, built on the control thread), TeTransport (the core TransportCursor in a graph node per song steering Tracktion’s play head; rate 1 only, in-block discontinuities rendered from the next block), per-song TimelineEvents, TeMixControl (song gain), TeLiveSession, TeAudioCueTarget with cue levels, TeAudioWriters; every contract suite of these ports passes on Tracktion’s hosted device (35 tests), example tracktion/song; not yet: TempoMap port, input recording, AudioFileProbe, routing inside the engine; in shuffle_juce — README |
| Tracktion plugins | ⬜ | PluginHost, InsertProcessor on Tracktion plugins; in shuffle_juce |
| Platform ports without JUCE | ✅ | shuffle_platform, plain C++20 on the standard library and a small OS layer: ControlLoop (TaskQueue, timers with handles, run on the caller’s thread or its own, no nested loops), ControlTimer, ThreadWorkerPool, SteadyClock, OsFileStore (atomic writes and replaces, path safety), JsonSettingsStore (one JSON file saved on a worker, coalesced), OsSystemAppearance and OsDisplayInfo (Windows, macOS; declared unavailable where a toolkit is needed); every platform contract suite passes; 60 tests, example platform/settings — README |
| OS sockets | ✅ | shuffle_net_sockets, plain C++20 without JUCE: DatagramSocket (unicast, multicast, broadcast, group isolation, DSCP, kernel receive timestamps on the Clock’s base), StreamSocket, NetworkInterfaces (timestamping capability, change polling), SteadyClock; contract suites on real sockets, waitReady over many listeners and connections with a cross-thread StreamWakeup; 23 tests, example net/osc_udp — README |
| WebSocket and HTTP surface of the UI bridge | ✅ | shuffle_net_websocket, plain C++20 on shuffle_net_sockets, no third-party library: WebSocketServer (the websocket transport of ui_bridge and the CMD-R40 surface as protocol version 0: RFC 6455 handshake with the shuffle.ui.1 subprotocol, origin allow list with 403 recorded, credentials in hello checked by the composition root, hello timeout, ping keep-alive closing dead peers, fragments and control frames, size and connection limits; loopback by default, other interfaces only with the machine setting and, without TLS, the explicit clear-text allowance shown as a warning; HTTP GET of in-memory files or a folder with the CSP of ui_bridge; its own network thread, messages to the control thread through TaskQueue), WebSocketClient and httpGet for native controllers; RFC 6455 vectors, fuzzed frame reader, the same bridge messages as the fake channel over loopback; 26 tests, loopback round trip ~76 µs, example ui_bridge/websocket — README |
| Codec libraries | ✅ | shuffle_codecs, plain C++20 without JUCE: OpenCodecs (CodecProvider) with FLAC read and write (libFLAC), Vorbis read and write (libvorbis), Opus read and write from any input rate (libopus and core/resample), MP3 read (dr_mp3); exact priming and decoder delays measured by the contract round trips, sample-accurate seeks, FLAC MD5 check; AAC and ALAC left to platform codecs; 32 tests, FLAC 24-bit decode ~460 × real time, example formats/transcode — README |
| miniaudio audio devices | ✅ | shuffle_miniaudio, the framework’s own engine on miniaudio without JUCE: MiniaudioDevices (AudioDeviceChannels with keys "<backend>:<device name>", AudioDeviceSwitch posted through TaskQueue with the previous device reopened on failure, DeviceEvents on a polled device list and the open device’s notifications), EngineAudioCallback (one Engine::process per device block inside flush-to-zero, DS-R16; device inputs to the engine and routing; output stages run by the engine; the device’s latencies with every block; no allocation, tested), OsProcessingThreads (ProcessingThreads on std::thread with MMCSS, QoS or SCHED_FIFO); the AudioDeviceChannels, AudioDeviceSwitch, DeviceEvents, OutputStageHost and ProcessingThreads contract suites pass on miniaudio’s null backend; 24 tests, example miniaudio/play — README |
| Web Audio in the browser | ✅ | shuffle_webaudio, the framework’s own engine in an AudioWorkletProcessor (WebAssembly, no SharedArrayBuffer, no COOP/COEP): WebAudioOutput (one Engine::process per render quantum; getOutputTimestamp() filtered into the device’s mapping and baseLatency + outputLatency as its latency with every block, so time::heardAt is the instant a sample is heard on the page’s clock, EN-R157, EN-R158), WebClock, WebTasks; the worklet script with a loader of standalone modules (page, worklet, Node.js) and the page’s side (gesture start, iOS audio session, timestamps, calls); 17 tests and a worklet test under Node.js; Score Sync Lite runs on it — README |
| libremidi MIDI devices | ✅ | shuffle_libremidi, MIDI without JUCE on libremidi 5.4.3 (BSD-2-Clause): LibremidiDevices (MidiOutputDirectory, MidiInputDirectory with driver type, persistent unique id, protocol and groups; DeviceEvents on libremidi’s hotplug observer through TaskQueue); outputs with real-time sendNow and sendUmp (preallocated queue, one sender thread, no allocation, tested) and true UMP on Windows MIDI Services, CoreMIDI UMP and ALSA UMP, MIDI 1.0 on WinMM, CoreMIDI, ALSA, Android AMidi and Web MIDI; inputs with raw bytes or whole UMP packets on the Clock; the five MIDI contract suites pass on real ports, loopback tests through virtual ports or a loopback driver; 31 tests, example libremidi/ports — README |
| Plugin hosting without JUCE | ✅ | shuffle_plugin_host, plain C++20 on the plugin formats themselves (CLAP and VST3 interface headers, MIT; lilv, ISC, for LV2 where it is installed; AudioToolbox for AU on macOS): NativePluginHost (PluginHost: one worker job scans every format with a dead man’s pedal in the FileStore, so a crashing plugin is skipped from the next scan; known plugins and skipped candidates in the SettingsStore; unchanged candidates not loaded again; code loaded on a worker and instances created on the control thread; state on the control thread; names resolved with ambiguity reported), per-format instances with sample-accurate parameters (CLAP, VST3, AU; LV2 per call), MIDI in and out with offsets (VST3 controllers through the plugin’s MIDI mapping), the transport, latency, tail, the plugin’s own bypass, state, parameter values readable without a lock and an allocation-free process, PluginInsert (InsertProcessor, a placeholder when the plugin cannot run); the PluginHost and InsertProcessor contract suites pass with our own CLAP, VST3 and LV2 test plugins (CLAP and VST3 on Windows, all three on Linux under RealtimeSanitizer with the real-time checks as errors); AU written for macOS CI; plugin editors still to host; 30 tests (36 with LV2), example plugin_host/list — README |
| OSCQuery, HTTP/WebSocket, Companion, MCP | ⬜ | generated protocol surfaces; in shuffle_protocols |
| AI audio tasks on audio.cpp | ✅ | shuffle_ai_audiocpp, plain C++20 without JUCE, desktop only and off by default: SpeechSource, SpeechToText (with voice-activity detection), StemSeparator, AudioToMidi on audio.cpp’s C ABI; local model folders checked by SHA-256, licence policy and consent, load on demand, unload, memory limit; no network; in shuffle_ai — README |
| Local and hosted language models | ⬜ | LanguageModel; in shuffle_ai |
5 · User interface — 🔄
Section titled “5 · User interface — 🔄”| Module | Status | What it brings |
|---|---|---|
ui_model |
🔄 | 175 / 185 requirements in full, 9 in part, UM-R182 (the wasm transport) waits for ui_bridge; 145 test cases: time axis with limits, pixel-quantised pans, zoom around an anchor and saved-view repair; the shared UI playback clock and follow modes; ruler levels and tick cache; snapping by priority with a magnetic distance and grid quantising; hit-testing per input kind; the gesture state machine with auto-scroll and no drift; item gestures (move, copy, trim, stretch, fades, gain, create, split, delete) committed as one request through a gesture-to-command binding table checked at start-up; selection, keyboard and focus; layout solver with whole-pixel rounding, rails and saved-state migration; virtual lists and trees with diff and scroll anchor; waveform level of detail; meters; mixer strips, fader law and rate-limited continuous requests; piano roll; position fields and tap tempo; overlays and call-outs; display assignment; accessibility tree with the roles of the widget catalogue, named by stable names; ui.* commands; ports DisplayInfo, SystemAppearance, FrameClock in base; hit test ~155 ns among 100 000 items, snap ~56 ns, layout of 100 nodes ~2.3 µs, waveform plan of 3 840 columns ~37 µs — spec, README |
ui_bridge |
🔄 | 94 / 112 requirements in full, 10 in part; 83 test cases (and 26 of the WebSocket transport in shuffle_net_websocket): handshake with versions, capabilities and catalogue changes; every call through the command session (validate, preview, submit, plans, confirm, cancel, undo, redo, resolve, text snapshot, catalogue, topics); the closed list of error codes with fixing messages; topics as snapshots then JSON Merge Patch deltas computed and serialised once per publication, keyed collections, throttling, read-your-writes, resync, ended subscriptions, the session and ui.theme topics; events with gap reports; backpressure with stale subscriptions, inbound rate limits, visibility; streams as binary or base64 frames with latest-wins and budgets; version 0 (the CMD-R40 WebSocket surface); the in-process transport (WebUiPage) and the webview security decisions; a framework-free JavaScript client with TypeScript declarations generated from the catalogue (golden files, strict tsc check) and its fixed runtime, built into the library for serving; the WebSocket transport (shuffle_net_websocket); ports BridgeChannel, TopicSource, StreamSource, WebUiHost with fakes and contract suites; validate round trip ~4.3 µs in process and ~76 µs over loopback WebSocket, 500-song delta ~22 µs; not yet TLS for the WebSocket server, the WebAssembly binding, shared-memory streams, binary reads — spec, README, guide |
ui_theme |
🔄 | 110 / 124 requirements in full, 13 in part (their toolkit or layout half), UT-R114 (adapter contract tests) waits for a toolkit adapter; 95 test cases: 39 colour roles and three built-in theme families (Deep Field default, Nightjar, Monolith), each a Dark and a Light scheme with its own palette, plus High Contrast, the contrast matrix with WCAG 2.2 maths and composited translucent tokens, reports with fixes, derived schemes, the surface ladder and dim stage surfaces; brand accents derived in OKLCH; categorical palette, domain token sets, item colours and inks; type scale, spacing, radii, elevation, densities, hit targets, zoom, pixel snapping, stage readout sizing; paint recipes for every component, variant and state with the precedence rules, and by part for sliders, faders, knobs, XY pads, meters (peak, RMS and loudness zones, hold, clip latch), readouts, status pills, progress, scrollbars, tooltips and timeline marks, their contrast pairs checked on every scheme; motion tokens, easing, the pulse, reduced motion and a frame-clock animator; the title-bar hit-test model, safe areas, forced colours; accessible names from command descriptors; ui.set_theme, ui.set_scheme, ui.set_density, ui.set_zoom, ui.set_reduced_motion; export as design tokens and CSS, part colours included; tables built in ~0.16 µs, a recipe resolved in ~0.13 µs without allocating |
ui_layout |
✅ | 53 / 53 requirements; 47 test cases and 4 of the DirectWrite measurer: stacks with grow, shrink, minimums and overflow reports, wrapping rows, grids (automatic column count, fixed, fit and flexible tracks, spans), overlays, breakpoints from the spacing scale (narrow, medium, wide by density), whole-pixel edges that never clip content; one text-fitting rule (step down the type ladder, wrap at UAX #14 opportunities, ellipsis at a word boundary or a grapheme, values never ellipsize and report the width they need, truncation reported for accessibility); TextMeasurer port with a fake and contract suite, MeasureCache (warm layouts measure and allocate nothing), checkLayout and checkSizes for overlap, clipping and hit targets; DirectWrite adapter shuffle_text_dwrite; a 204-element control surface in ~60 µs — spec, README |
ui_render |
✅ | the draw-list half of the native widgets (README, spec UW-R128 to UW-R158, UW-R173 to UW-R185, UW-R192): 56 test cases and 6 of the Direct2D renderer: the draw list with 23 op kinds, conservative bounds, groups with content keys copied when unchanged, validation naming the first bad op, text and binary forms that round-trip exactly; text runs carrying ui_layout’s fitted lines; damage merged into at most 8 rectangles (every row of §4.14) with the buffer-age history; the resource table; the Renderer2D port with a fake on the CPU reference rasteriser and a contract suite; outlines and coverage shared by the reference and every renderer; the 13 reference scenes at four scales; the 214-widget control surface (full build ~143 µs, steady build with damage ~33 µs, 329 KiB); shuffle_render_d2d (Direct2D, DirectWrite, DXGI flip model, WARP) matching every scene within UT-R114 on the GPU and on WARP, partial redraw equal to full with buffer ages 1 to 3, device loss, no allocation in 100 warm frames, a 3 840 × 2 160 frame in ~1.2 ms CPU and ~1.0 ms GPU, a steady frame in ~0.12 ms CPU and ~0.05 ms GPU; example ui_render/surface |
ui_widgets |
✅ | implemented, experimental (README): 134 test cases and 5 of the Win32 window: the catalogue of §3.6 from data (C++ constant data and JSON in the Studio vocabulary, every build problem reported at once with the messages of §4.20); two-way, pending and refused values; pointer, pen, touch and the keys of §4.11 with the consequential rule; menus, dialogs and the toolbar’s “More”; text fields with input methods; the accessibility tree with ranges; damage with group copying in runs; the per-window host (no frame when idle); the reference screens of §4.15 and §4.16 checked at every breakpoint and size; 100 warm frames without an allocation; full build ~120 µs, steady build with damage ~27 µs (~33 µs with the update) and hover hit-test ~0.75 µs for the 214-widget surface (the targets of UW-R173 met); golden draw lists of every kind, variant and state at two scales in two schemes (UW-R193); shuffle_window_win32 (per-monitor DPI v2, WM_POINTER, IMM32, custom title bars, UI Automation, a vertical-blank FrameClock); example ui_widgets/control_surface. Specified with 196 requirements (spec), revised on ui_layout as implemented (breakpoints narrow, medium, wide; a text role per part; readouts as value texts) with its open issues on ui_layout, ui_theme (parts), ui_model (roles) and the Studio vocabulary (toggle events) resolved: the native widget toolkit on top of ui_model, ui_layout and ui_theme, so applications compose screens instead of writing drawing code: a catalogue for music applications (buttons, toggles, switches, segmented controls, faders with the decibel law and fine mode, sliders, knobs, peak, RMS and loudness meters, critical readouts, XY pads, virtualised lists and tables, cue and set lists, tabs, menus, popovers, non-modal dialogs, text fields with input methods, timeline, lane headers, waveforms, scroll containers, status pills, toolbars), states, keyboard, pointer, touch and pen input, accessibility roles per platform, text fitting and pseudo-localisation, scale, motion and contrast; screens as data with the Studio binding vocabulary (the Score Sync control window as the example); a plain-data draw list with damage regions; the Renderer2D port with a CPU reference rasteriser and reference scenes for conformance; the PlatformWindow port; performance targets for a 200-widget surface at 3 840 × 2 160 and 120 Hz; adapters shuffle_render_d2d and shuffle_window_win32 first |
All view models and interaction logic in pure C++, toolkit-free and tested without a GUI; every change is a command, one gesture is one undo step.
UIs written with web technologies (or, later, a native declarative toolkit) drive the engine through the command catalogue; the embedded webview path works end to end on JUCE (examples/juce/webui in shuffle_juce).
ui_theme is implemented in the core (README,
spec); its toolkit half and the adapter contract
tests (UT-R114) come with the native widgets, as the Renderer2D and
window adapters of ui_widgets and their conformance runs.
ui_model (all geometry and interaction logic, tested) first, then the
native widgets: ui_widgets (spec) draws every
widget as pure C++ into a draw list that a Renderer2D adapter paints
(Direct2D and Win32 first), and replaces the per-toolkit widget modules
planned before; the widget areas (base, overlays, lists, timeline,
waveform, lanes, arrangement, MIDI editor, mixer, transport, rack, stage,
media, settings) become its kinds and compositions. Layout primitives and
text fitting come from ui_layout. See modules.md.
6 · Media and production — 🔄
Section titled “6 · Media and production — 🔄”| Item | Status |
|---|---|
video (147 requirements: 125 in full, 15 in part; the optional FFmpeg adapter VD-R140 to VD-R146 not yet): frame-accurate mapping between song position, timecode and frames, playback following the transport or timecode, overlays as data (streamers, punches, counters), export plans with burn-in, video cues; examples video/score_sync, video/score_sync_live; in shuffle_media — spec, README |
✅ |
video_fx (154 requirements: 135 in full, 19 in part): layers and programmes, effects in linear light, blend modes, transitions, looks, modulation on the tempo map, a photosensitivity guard, CPU reference renderer; example video_fx/beat_looks; in shuffle_media — spec, README |
✅ |
shuffle_fx_d3d11: the video_fx renderer on Direct3D 11, conformant with the reference renderer; in shuffle_media |
✅ |
shuffle_video_mf (Windows): Media Foundation hardware and CPU decoding, Direct3D 11 swap-chain presenter, MP4 export without audio; in shuffle_media |
🔄 |
Video on macOS and iOS (AVFoundation, Metal), Android (MediaCodec), browsers (WebCodecs), optional LGPL FFmpeg; GPU renderers of video_fx beyond Direct3D 11; in shuffle_media |
⬜ |
documents, lighting (Art-Net, sACN, GDTF), hwcontrol (mixers, effects, loopers), in shuffle_media; package (show export/import, DAWproject) |
⬜ |
7 · AI, education and research — 🔄
Section titled “7 · AI, education and research — 🔄”| Item | Status |
|---|---|
ai_tasks (20 requirements, 32 tests): SpeechSource, SpeechToText, StemSeparator, AudioToMidi with fakes and contract suites; model manifests with SHA-256, licence policy and consent as settings; in shuffle_ai — spec, README |
✅ |
shuffle_ai_audiocpp: the four task ports on audio.cpp (desktop, CPU, off by default), tested with PocketTTS, Moonshine, Silero VAD, HTDemucs, MuScriptor; example ai/spoken_cue; in shuffle_ai — README |
✅ |
inference (68), neural (57), llm (127), mir (93) — specs reviewed, in shuffle_ai |
📝 |
assistant (show assistant on llm), in shuffle_ai |
⬜ |
compose, spectral, spatial, notation, in shuffle_edu |
⬜ |
| Pure Data inside apps (libpd), Max and Pd externals, Faust | ⬜ |
| Classroom mode, curriculum of 10 examples, notebooks | ⬜ |
Python library (shuffle-engine native bindings, shuffle-remote client), 77 requirements — spec, in shuffle_python |
📝 |
See education.md in shuffle_edu.
No-code applications — 📝
Section titled “No-code applications — 📝”| Item | Status |
|---|---|
| Application document (100 requirements) and the SHUFFLE Player that runs it on desktop, mobile and the web — spec, in shuffle_studio | 📝 |
SHUFFLE Studio, the web builder editing through studio.* commands: page, graph and rule editors, live preview, AI-assisted creation, C++ export (64 requirements) — spec, in shuffle_studio |
📝 |
Built on ui_model, ui_theme and ui_bridge; phases: document and
Player, page editor, graph and rule editors, AI generation and C++ export.
General music applications — 🔄
Section titled “General music applications — 🔄”| Module | Status | What it brings |
|---|---|---|
loudness |
✅ | 73 / 73 requirements, 96 tests (open item: the IEC 60268-10 burst tables): BS.1770-4 / EBU R 128 loudness with exact K-weighting, gated histogram, true peak, lock-free readings; PPM, VU, RMS and peak meters; stereo field and delay estimation; file statistics; targets and normalisation; command table; ~10.7 µs per 512-frame stereo block — spec, README |
dsp |
✅ | 141 / 141 requirements (140 in the core, DS-R16 in the audio I/O adapters shuffle_miniaudio and shuffle_juce_audio; open item: windowed-sinc speed above 1), 172 test cases: block contract (prepare errors, block-split invariance, reset, non-finite and misuse handling, no allocation) checked over every block; smoothers identical to routing and cues ramps; varispeed interpolators sharing resample’s kernel (identical output), fixed-ratio conversion with exact integer ratios; cookbook biquads, Butterworth cascades, TPT filter, one-pole, DC blocker; BLEP/BLAMP oscillators, mip-mapped wavetables, PCG32 noise (white, Gaussian, pink, brown), LFOs, ADSR; delay lines, dry/wet; compressor, look-ahead limiter with true peak, gate; 24-band EQ; FDN reverb; oversampled waveshapers; own FFT behind the FourierTransform port; partitioned convolution; 128-frame stereo calls: biquad ~0.5 µs, TPT ~1.2 µs, FDN 8 lines ~6.3 µs, 2 s convolution ~175 µs — spec, README |
synth |
🔄 | 102 / 103 requirements (SN-R97: a change of sound source needs a new instrument), 118 test cases: voices with capacity and fade reserve, three stealing policies with release voices first, outer-note protection, same-note rule; mono/legato with priorities and portamento; sustain, sostenuto, soft; MPE zones, MCM and RPN 0, per-note expression with tracking, legacy mode; MIDI 2.0 per-note bend, controllers, management, absolute pitch; MPE allocator and merger; tuning tables, Scala .scl / .kbm from bytes; sample-accurate rendering invariant to the block partition; modulation matrix; subtractive, sampler (zones, layers, round robin, loops, crossfades, release samples) and wavetable sources; presets and commands; no allocation on the audio path; 64 subtractive voices ~239 µs per 256-sample block (spec targets not yet met) — spec, README |
formats |
🔄 | 120 / 129 requirements in full and 9 in part (chained Ogg, lazy fragment index, crash clean-up of temporaries, CUESHEET and QuickTime chapter tracks, AIFF/CAF/Ogg tag edits, 32-bit mapping window, cancellation of long writes), 390 test cases, codecs through adapters/codecs (FLAC, Vorbis, Opus, MP3 read; AAC and ALAC wait for platform codecs): content probing with ID3 skip and the three-header rule; WAV/RF64/BW64 (pad bytes, size repairs, ds64), AIFF/AIFF-C, CAF (pakt, chan layouts, ambisonics), native FLAC (CRC-8/16 framing, seek table and bisection), Ogg (CRC, resync, Opus TOC and Vorbis block durations), MP4 (sample tables, edit lists, fragments, tracks, encryption), ADTS and MP3 (LAME tag, bit-reservoir pre-roll, lazy index, exact-length scan); one presentation timeline for priming, padding and edit lists; sample-accurate seeks verified; PCM conversions in every layout (in place too) with TPDF dither; writers for WAV (RF64 promotion, recording mode), AIFF, CAF, FLAC, Ogg Opus/Vorbis, MP4 and CAF ALAC with exact gapless data; every metadata source with unknown items kept, tag edits without touching the audio; buffered reader for the audio thread; SMF reading and writing; DAWproject values and archive safety; codecs behind CodecProvider with fakes and contract suites — spec, README |
engine |
🔄 | 129 / 156 requirements in full and 26 in part (EN-R141 AudioFileProbe waits for formats), 109 test cases: graph with typed pins, buses, sends and delay-node feedback; validation with every problem and its fix; compile off the audio thread, atomic swap with state carry-over, ramps in and out; deterministic order; latency compensation with render lead and monitoring; block contract and sub-block splitting; single-threaded reference and work-stealing parallel schedule, bit-identical (1 000 random graphs); overload ladder; isolated plugin nodes; audio items (CU-R168 mapping, bit-exact unity, rate, stretch, tempo following without drift), MIDI items on the midi rules; plugin boundary; aligned recording; offline render identical to real time; taps and the output stage host; the setlist, cues, routing and base contract suites pass against it; 256 gain nodes ~46 µs, 4 workers ×4.8 — spec, README |
formats (spec, 129 requirements) is implemented in part (120 in full, 9 in part; AAC and ALAC codecs to come);
engine, the framework’s own audio graph (spec, 156
requirements), is implemented in part (129 in full, 26 in part); dsp is
implemented and synth (spec, 103 requirements) is
implemented but for SN-R97’s change of sound source.
dsp, synth, engine, edit, automation, render, loudness,
library, plugin: the domains that let the framework build DAWs, plugins,
instruments, DJ apps, players and notation software. See
applications.md; dsp and plugin come first because
every other kind of application needs them.
8 · Independence — 🔄
Section titled “8 · Independence — 🔄”The codec adapter (shuffle_codecs: libFLAC, libvorbis, libopus, dr_mp3) is
the first piece of the permissive stack; the miniaudio adapter (shuffle_miniaudio:
audio devices, the engine’s device callback, real-time processing threads)
runs the framework’s own engine with no JUCE at all; the platform adapter
(shuffle_platform: control loop, timers, workers, clock, files, settings,
appearance, displays on the standard library and the OS) gives an
application its control thread and persistence without JUCE; the libremidi
adapter (shuffle_libremidi: MIDI 1.0 and MIDI 2.0 ports, UMP on Windows MIDI
Services, CoreMIDI and ALSA, real-time sends) gives it MIDI without JUCE; the
plugin host adapter (shuffle_plugin_host: CLAP, VST3, LV2 and AU hosting on
the formats themselves) gives it plugins without JUCE.
Next: adapters on the permissive stack (virtual MIDI ports, Asio, own engine on
dr_libs / r8brain / Signalsmith Stretch, plugin editors, Visage or
ThorVG/Skia) so the framework stands without JUCE and Tracktion. See
replacing-backends.md.
Capabilities for applications
Section titled “Capabilities for applications”The ten capabilities of vision.md and what they wait for:
| Capability | Status | Waiting for |
|---|---|---|
| Show flight recorder | ✅ core | adapters (file sink, protocol surfaces) |
| Show linter and simulator | ⬜ | commands, live engine domains |
| Cues anchored to music | ✅ core | time ✅, setlist ✅, cues ✅: setlist::ShowMusic publishes the song’s map, arrangement and jumps through MusicPosition; an engine adapter for real transports |
| Live re-arrangement | 🔄 | time ✅, setlist ✅, engine adapter |
| Hot-standby twin | 🔄 | time ✅, commands, redundancy, netaudio |
| Rig admission check | ⬜ | benchmarks per module, budgets |
| Personal distributed rig | ⬜ | remote, protocol surfaces |
| Self-healing show | 📝 | resilience rules in every module |
| Show programming in words | ⬜ | commands, assistant |
| Open, git-native show format | ⬜ | package |
Theatre and show-control parity
Section titled “Theatre and show-control parity”27 capabilities for cue-list production (P1 10, P2 11, P3 6) with their owning modules: see show-control.md. P1 items join phase 3 (live engine) and phase 4 (adapters).
Next steps
Section titled “Next steps”-
In
shuffle_media(video,video_fxand their Windows adapters are implemented): the picture adapters of the other platforms (AVFoundation and Metal, MediaCodec, WebCodecs), the optionalvideo_ffmpegadapter (desktop only, off by default, LGPL FFmpeg loaded dynamically and supplied by the user, never bundled) for formats and platforms the system decoders do not cover (Linux, professional codecs), and thevideo_fxGPU renderers beyond Direct3D 11.ui_themeis implemented in the core: its toolkit half and adapter contract tests follow with the native widgets (ui_widgets, specified). -
Connect timecode input and chase to
cues,setlistandroutingas they are implemented (the core hands followers’ actions to their domains and reads endpoints through the topology ports); thetimecode,timeandcommandsrevisions are implemented. -
Specify
renderandplugin(editis specified: spec, 89 requirements); completeengine(the partial requirements of its README,AudioFileProbeonformats) and bring its compile and item benchmarks to table 4.12 (dspis implemented,synthall but SN-R97); bring the synth benchmarks to the targets of its table 4.12. -
netaudioASRC oncore/resample; redundancy spec open issues RD-OI1..7. -
Implement
inference,mir,neural,llmfrom their reviewed specs (in shuffle_ai). -
Tracktion adapters (in shuffle_juce): plugins (
PluginHost,InsertProcessor), input recording, aTempoMapport, the routing program inside the engine (Tracktion devices and engine, OS sockets, JUCE platform, MIDI and audio devices are done). -
Generated protocol surfaces (OSCQuery, web, Companion, MCP), in shuffle_protocols.
-
Native widgets:
ui_layout,ui_renderwith its Direct2D renderer, andui_widgetswith the Win32 window adapter and the Score Sync control window as a screen, the golden draw lists per kind (UW-R193) and the performance targets of UW-R173 (done); next the other platforms’ renderers and windows. Theeditdomain binds its commands to theui_modelgestures. Text measurers beyond DirectWrite (Core Text, FreeType with HarfBuzz, Android, the browser) follow the renderers. 9a. Showcases (satellite repositoryshuffle_showcase): small, beautiful, complete apps that show the framework at a glance and double as end-to-end proof and marketing material, in this order:- Score Sync (done on Windows): a film plays with frame-accurate streamers and punches following the tempo map, a low-latency click, separate conductor and audience views, control from a phone through the web UI, export with burned-in markers. Other platforms follow shuffle_media’s picture adapters.
- Pro Meter: loudness, true peak, stereo field, spectrum.
- Live Set: set list, GO from a phone, gapless segues.
- Visual Live: video and effects that react to live music; needs
the GPU effects of
video_fxinshuffle_media. - MPE Synth.
- Stage Cues: theatre cue list, fades, timecode chase.
- Plugin Rack: CLAP/VST3/LV2 without JUCE.
- AI Stage Assistant: voice commands, stems, audio to MIDI.
- Phone Orchestra: synchronised phones in the browser.
- Browser Demo in WebAssembly.
- Built Without Code: a showcase made in
shuffle_studioas a document, without C++. - Python Notebook: the framework driven from
shuffle_python.
Each starts in seconds with demo content, uses only the public API and the
ui_themelook, and ships a 30-60 s video and a gallery page. Needsui_theme, the native widgets and WebAssembly beyondui_bridge; the web-based ones can start onceui_themeexists. 9b.pluginmodule in the core: export synths and effects built withdsp/synth/engineas CLAP, VST3 and LV2 plugins (and AU on Apple), so SHUFFLE content runs in DAWs and on embedded hosts. 9c. Satellite repositoryshuffle_embedded: embedded Linux targets (Raspberry Pi 4/5, Elk Audio OS, Yocto), JACK and dual-kernel real-time audio adapters, board I/O (GPIO, encoders, displays), tests on real hardware. Other satellites (satellites.md):shuffle_juce,shuffle_ai,shuffle_edu,shuffle_media,shuffle_protocols,shuffle_python,shuffle_studio. 9d. Satellite repositoryshuffle_studio: implement the application document and the SHUFFLE Player (desktop and browser hosts) fromspecs/app_document.md, then the Studio page editor, the graph and rule editors, and AI generation with C++ export (specs/studio.md). Needs the WebAssembly binding ofui_bridge(its WebSocket server is done), and the domains’ topics and streams declared (AD-OI1). Target: Score Sync built as a document without code. -
Developer course from zero (
docs/course/): a sequence of short lessons, each with a goal, the concepts it needs, an exercise and a solution that is an example built and run by CI (examples/course/NN), so the course can never fall behind the API. Tracks: C++ native, web UI, AI-assisted. Lessons: setup and first build; ports, fakes and the composition root; commands and snapshots; time and the tempo map; sound through the engine and the real-time rules; MIDI in and out; routing and named outputs; files and recording; a set list with cues; a web UI; plugins and DSP; testing your app with contract suites; shipping on desktop, mobile and the web; capstone: a small live show. Built on the developer guide and the API reference; distinct from the music-education curriculum of education.md in shuffle_edu.
Quality before v0.1.0
Section titled “Quality before v0.1.0”A per-release quality report (quality.md): requirement
coverage, code coverage (llvm-cov), static analysis with clang-tidy
(bugprone, SEI CERT C++, security, performance), dependency vulnerabilities
and SBOM, collected by tools/ci_local.py quality and attached to the
release. When the repositories become public: Coverity Scan, SonarQube
Cloud, OpenSSF Scorecard and Best Practices, OSS-Fuzz, signed releases with build attestations.
After 0.1.0
Section titled “After 0.1.0”Planned for the versions after the first tag:
- Commands for redundancy actions: the redundancy operations an operator takes during a show (beyond the three commands of RD-R65) reachable as commands, so a remote, a script or an assistant can run them.
netaudiocommands and an example: joining, leaving and inspecting AES67 / RAVENNA / ST 2110-30 streams through commands, with an example inexamples/built and run by CI.- Loudness meters on engine taps (EN-R130): the
loudnessprogramme and loudness meters run onenginetaps and published per block.
Free applications
Section titled “Free applications”Besides the showcases (which demonstrate the framework), SHUFFLE will ship
complete free applications for musicians, each in its own repository
under shuffle_apps/. They use only the public API, follow the same rules
(commands, Deep Field theme, local CI) and are not showcases.
- RC-600 manager (
shuffle_apps/shuffle_bossrc600, first): an editor and librarian for the BOSS RC-600 loop station — read, edit and safely write the pedal’s USB backup (memories, ASSIGN slots, settings), compare and copy memories, and test the pedal over MIDI. Specified first, then built on the SHUFFLE engine and widgets. - Live looping companion (
shuffle_apps/shuffle_livelooper, a separate app): a stage companion for live looping — songs as timelines of sections, large stage cues, backing audio, control of the looper over MIDI and retroactive capture of the last bars played. Ported onto SHUFFLE after the RC-600 manager. - Further apps follow (folders already reserved:
shuffle_karaoke,shuffle_show).
© 2026 Umberto Sorbo. Il software è distribuito con la Apache License, Version 2.0, e fornito “così com’è”, senza garanzie o condizioni di alcun tipo; leggi l’esclusione di responsabilità.
SHUFFLE Framework e il logo di SHUFFLE Framework sono marchi di Umberto Sorbo; la licenza non concede alcun diritto su di essi (marchi). Gli altri nomi appartengono ai rispettivi titolari. Caratteri: IBM Plex Sans e JetBrains Mono, SIL Open Font License 1.1.
Contatti: shuffleframework@gmail.com · Instagram @shuffleframework. Problemi di sicurezza: scrivi allo stesso indirizzo con “Security” nell’oggetto, non in una issue pubblica.