Deterministic beat generator powered by Petri nets. No AI, no LLMs — just math, music theory, and token flow.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
A deterministic beat generator powered by Petri nets. No AI, no LLMs, no neural networks — just math, music theory, and token flow.
Petri nets are mathematical models where tokens circulate through places and transitions fire when conditions are met. beats-btw uses this to generate music:檢視完整 README ↗A deterministic beat generator powered by Petri nets. No AI, no LLMs, no neural networks — just math, music theory, and token flow.
Live at beats.bitwrap.io
Petri nets are mathematical models where tokens circulate through places and transitions fire when conditions are met. beats-btw uses this to generate music:
Everything is 100% deterministic given the same seed. Same genre + same seed = same track, every time. The generation uses seeded PRNGs, Euclidean geometry, music theory rules, and graph traversal — no machine learning, no sampling, no probabilistic models beyond explicit Markov chains with hand-tuned transition weights.
Browser Main Thread Web Worker
────────────────── ──────────────
petri-note.js (UI) ◄─ postMessage ─► sequencer-worker.js
tone-engine.js (audio) ├── pflow.js (Petri net engine)
└── generator/ (beat generation)
The sequencer runs in a Web Worker so timing stays accurate even when the tab is backgrounded. The worker posts transition-fired messages to the main thread, which plays sounds via Tone.js. Zero backend involvement during playback.
See docs/categorical-index.md for a full category-theory-style index — beat at the root, generators / instruments / macros / control actions / arrange / perform / share as branches, with file:line anchors for every leaf.
19 genre presets with distinct scales, chord progressions, drum patterns, and instrument palettes:
techno house jazz ambient dnb edm speedcore dubstep country blues synthwave trance lofi reggae funk bossa trap garage metal
Each genre defines BPM, scale type, root note, Euclidean drum parameters, melody density, swing, humanize, and variety features (ghost notes, walking bass, call/response, modal interchange, tension curves).
hit1–hit4 slots that live as real muted tracks in the mixer and fire on every beat via their own Petri nets. Each slot has a curated stinger instrument set (airhorn / laser / subdrop / booj + percussion / stabs / bells / bass hits / short leads) and a schema-reserved option for silent placeholder. A Fire pad per slot routes through the track's channel strip (vol / pan / filter apply, bypasses mute). Optional FX-pair dropdown fires any macro alongside the sound.make build # Build Go binary (embeds public/ files)
make run # Build and serve on :8089
make dev # Serve from disk (hot reload) on :8089
Requires Go 1.23+. No npm, no node_modules, no bundler.
embedtype: 'module')Two JSON-Schema documents ship with the app:
/schema/beats-share — content-negotiated envelope for share-v1 payloads (@context, @type: BeatsShare, v, genre, seed, plus optional overrides). JSON-LD context at /schema/beats-share.context.jsonld./schema/petri-note — the nested project shape: nets, places, transitions, arcs, MIDI bindings, track metadata.A third, richer reference schema with Scenes / inter-net connections / inhibitor arcs / silent transitions ships in schema/ as a test fixture for the petri-note v1 JSON-LD shape — it is not the wire format; see CLAUDE.md → Three schemas in this repo for which to use when.
Worked examples:
examples/minimal.json — smallest valid share, just genre + seedexamples/overrides.json — realistic composer share with tempo/fx/feel overridesexamples/hand-authored.json — raw-nets template (genre: "wrapped")examples/macro-orchestrated.json — 6-net demo with a conductor net that fires macros at tick positionsexamples/voltage-rush.json — 140 BPM hard-energy hand-authored trackexamples/phantom-aqueduct.json — long-form A/B riff-variant demo (activate-slot)The same Go binary runs in two modes. By default (./beats-bitwrap-io) it serves this website's static files plus the content-addressed share store at /o/{cid}. With -authoring it additionally exposes a full Petri-net sequencer over HTTP + WebSocket, server-side MIDI output (CoreMIDI / ALSA), and an mcp subcommand that speaks MCP over stdio so Claude Code can compose, audition, and seal tracks from the agent side.
make build
./beats-bitwrap-io -authoring -addr :8080
# then in Claude Code:
claude mcp add beats-btw ./beats-bitwrap-io mcp
Hand-authored tracks round-trip through POST /api/project-share {"mirror":["https://beats.bitwrap.io"]} — seals the local project as a share-v1 envelope with raw nets and PUTs the canonical bytes to the public store in one call. See CLAUDE.md → Running locally for hand-authored tracks for the full set of HTTP routes + MCP tools + MIDI flags.
The share-v1 format is an IR — any producer that emits valid JSON against the schema gets byte-identical playback. Open the in-app help menu (?) and follow Using with AI to copy a ready-made prompt into Claude / ChatGPT / any chat model; the model replies with a share-v1 blob. Determinism lives in the IR, not the generator, so the same blob plays the same track forever, offline, with no model in the loop.
A prompt is a wish. A Petri net is a score.
The entire sequencer is a Petri net executor — every note that plays is a transition firing, every rhythm is tokens circulating through places. Carl Adam Petri's 1962 formalism is the runtime, not just an inspiration.
Within that framework:
MIT
unboundSpace play/stop · G generate · S shuffle · F Feel · M Stage · J Auto-DJ Run · A animate-only · P panic · B FX bypass · R FX reset · T tap tempo · , / . BPM −1 / +1 · 1–4 toggle hit tracks · [ / ] prev / next track · ←↑→↓ nudge hovered slider · ? help.?cid=… URL that captures the full listening experience (genre + seed + mix + FX + Feel + Auto-DJ + Fire pads + loop region). Short-link mode uploads canonical JSON to the server; self-contained mode inlines a gzipped payload so the link works offline or if the store is purged.structure (loop / ab / drop / build / jam / minimal / standard / extended) + arrangeSeed, velocityDeltas + maxVariants (variant-clone tuning), fadeIn (roles taper in over intro), drumBreak (drum-only midpoint break), sections (author-authored blueprint), feelCurve (XY puck morphs between Chill/Drive/Ambient/Euphoric at section starts), macroCurve (schedules fire-macro events at section boundaries). A 1 kB envelope reconstitutes a 3 MB arranged track. Full Go/JS parity — same directives expand the same way whether hit by the server or by the client's in-process JS port.