The current discourse around AI in electronic music — staged most recently in by in MusicRadar, — sets up a binary: opaque generators like Suno and Udio on one side, "irrevocably human" output on the other, with self-trained models like Reinier Zonneveld's B2B clone and Holly Herndon's Holly+ as the moderate middle.
That's the wrong axis.
The artists quoted in the piece aren't really angry about generators. They're angry about opacity — training sets nobody consented to, no attribution back to source, century-old copyright trying to shape itself around a new kind of object. The AFEM AI Principles spell out the actual ask: consent, contracts, moral rights, credit and pay.
That's a transparency complaint, and once you frame it that way a different cell in the table opens up.
| Opaque | Transparent | |
|---|---|---|
| Statistical | Suno, Udio | Holly+, self-trained models |
| Structural | — | a Petri net |
A self-trained model is better than Suno because the training set is known. But it's still a weights file. The generator is a black box you trust because you trust the artist.
A structural generator is a third thing entirely.
beats.bitwrap.io is generative music with the generator visible, and every piece of it is a file you can open. Drum patterns are Euclidean rhythms encoded as token rings: Bjorklund spreads k hits over n steps, one token circulates a ring of n places, and only the transitions at hit positions carry a MIDI note (euclidean.go; the ring mechanics are worked through in Petri Nets as a Music Sequencer). The melody is a four-bar motif drawn from the seed with a phrase grammar — two bars of question ending away from the tonic, two of answer forced home to it, strong beats snapped to a tone of the bar's chord (theme.go); the older path, still there behind a flag, walks a Markov chain with chord tones on strong beats and stepwise motion on weak ones (markov.go). Either way the choosing happens once, at generation time, and what plays is a ring with exactly one transition per step. The bass depends on the genre's groove: in jazz, blues and lofi it walks root, third, fifth and then a half-step chromatic approach into the next bar's root; in bossa it rocks between root and low fifth; elsewhere it plays the bar's chord root on a rhythm derived from the kick pattern. Song structure is a set of linear control nets, one per track, that mute and unmute it at section boundaries (structure.go).
There is no training data and there are no trained weights. The probabilities that do exist — a 70/30 split between chord tone and step on a medium beat, say — are hand-set constants in the source. The "creativity" lives in structural choices — which arcs, which transitions, which guards — and those choices are the artifact. Same genre and same seed give the same nets, so the same note events: the motif draws from a seeded mulberry32 stream that the browser's JavaScript port replays draw for draw, and theme_parity_test.go pins the techno / seed-42 motif that both sides must reproduce (not re-run for this revision). That is a claim about the notes, not the audio. Synthesis happens in the listener's browser, and nothing in the repo compares rendered sound across machines.
I'd call that a difference in kind rather than taste: a generator you can read is a different object from one you can only sample from.
One of the more interesting beats in the MusicRadar piece is Jay Ahern's offhand observation that modular synthesizers were the original generative music-makers. The article uses this to defang the AI panic — it's just another tool — but the comparison is sharper than that.
My reading is that Petri nets are the natural formal model of modular patching: modules running concurrently, signals as tokens moving between them, a clock or gate deciding what fires. A Buchla 200 patch reads as a Petri net, informally — but there is no worked encoding of a real patch on this blog yet, so that is an analogy I'm making, not a result. beats.bitwrap.io makes the Petri-net side of it explicit and playable in a browser.
This is the rhetorical wedge. The pro-AI camp says "tools are tools, get over it." The anti-AI camp says "but the training data is stolen." Both arguments are about statistical generators. A structural generator is older than either camp's object and has neither problem.
The principles read very differently when you hold them up against a Petri net instead of a weights file.
Take consent first. Consent asks that training data be a closed term in a known context, and a Petri net has no training data at all — the model is the source, and there is no pile of uncredited inputs sitting upstream of the output.
Credit and pay rest on attribution, and attribution is past-tense witnessing. Every note that played is a transition that fired, and because generation is deterministic the whole firing sequence can be replayed from the share link that names the track — a content-addressed ?cid= envelope carrying genre, seed and mix (how the share format works). The fossil record has the bones still articulated. (For the formal version of why "past" is the right word here, see the tense decomposition.)
Moral rights follow from the same fact. The generator is the artist's structural choice — these arcs, these hand-set probabilities, this motif grammar, this Euclidean ring — and there is no laundering layer between intent and output. You could still land on a phrase someone else wrote (a four-on-the-floor kick belongs to everybody), but not by copying it, because no one else's song is in the model.
The hard regulatory question Ahern hints at — AI will probably be needed to regulate AI — only exists when the generator is statistical. For a structural generator, the audit is the source.
Sam Thurlow in the same piece talks about AI "declining the friction between ideation and realization." That phrase only makes sense if the model is a separate object you sample from — something you have to coax toward what you want.
In a Petri net there is no such gap. The model is the realization. Resize a ring while it plays and the rebuilt subnet swaps in at the next bar boundary; change the structure and you hear a different beat, deterministically. There's no ideation/realization distance because the structure is the music.
This connects to a longer thread on this blog: the case for small models over large ones — finite, formal, inspectable objects that do one thing the same way every time. LLMs are good at fuzzy work. For composition, where you actually want to know why the kick lands on beat three, the small model has the advantage by construction.
Ahern closes the MusicRadar piece hoping AI will help "bust genres open." It's a generous reading.
A Petri net would do this differently. Genre in beats.bitwrap.io is a parameter set — BPM, scale, root note, Euclidean hits-per-steps for each drum, melody and bass density, swing, humanize, and the variety switches (ghost notes, walking bass, call-and-response, modal interchange, tension curves) — declared per genre in composer.go. The same Euclidean(k, n, …) constructor builds techno's kick (4 hits over 16 steps) and bossa's hihat (6 over 8); only the numbers differ. The trait editor lets you tune or toggle those traits on any preset before the next Generate, and the result is still rings and control nets, never an average of two recordings.
What the app does not do yet is interpolate between two genres' structures. The genres are discrete presets, and the Feel pad, which plots all nineteen of them as a constellation, morphs between four corner snapshots rather than between two genres' nets. So structural genre-crossing is the claim this section rests on and not yet a demonstrated one. What it would inherit, if built, is the licensing position: nothing upstream of it needs a license.
The phrase I keep wanting is generator you can read. The audit is the source. The discourse keeps trying to draw the line between AI and human — but the load-bearing line was always between statistical and structural, and the structural side is older than the argument; modular patching was already doing it informally.
Go listen to one at beats.bitwrap.io. Hit Share and the ?cid= link it mints is the score.
For readers of the August version (revised 2026-10-05):
theme.go), with the Markov path kept as the legacy option. The bass walks chromatically only in jazz, blues and lofi; the earlier text said it did everywhere. Song structure is one linear control net per track, not a single net. Each claim now links the file it comes from.Related: Petri Nets as a Music Sequencer · A browser music sequencer where every note is a Petri-net transition firing · From Petri-net toy to jambox · Small Models > LLMs