Hi all,
I have been quiet here for a while because I was busy turning a Zynthian into
something I can play without looking at a screen. It works now, so here it is.
Build guide: Generative-Techno ZynthianMaschine MKII — an eight-channel generative groovebox
Video (no hands — see below): https://youtu.be/VJs85sTF880
What it is
A Raspberry Pi 4 running ZynthianOS Oram-2601-1, a Native Instruments
Maschine MK2 over USB, and nothing else. No audio interface - every measurement
in the project was made on the Pi’s own headphone jack at 48 kHz.
Eight channels, always alive: five euclidean drum channels and three
Turing-machine voices. Nothing is created or torn down while you play, so
there is no chain-building mid-set and no dropout when you change your mind. A
channel can switch between drum and voice behaviour without swapping its
engine.
You do not draw patterns. You set hits, rotation and randomness, and the
generator writes the notes.
The part that matters for Zynthian people
It writes into zynseq, not into a sequencer of its own.
That was the single most important design decision and it is what makes the
thing feel like part of Zynthian rather than a thing bolted onto it:
- patterns persist in ordinary Zynthian snapshots
- the touchscreen pattern editor mirrors exactly what the pads show, live
- banks are scenes, saved in the snapshot, and a set lands on the bank it was
saved on
the whole instrument is a ctrldev driver plus a HID daemon.
No fork of zynthian-ui. Upstream files that must change are patched by a script inside
my repo, not edited in place
The Maschine daemon descends from William Light’s maschine.rs via my earlier
MaschineMK2\_linux. It talks to the driver over OSC on loopback, and it is
what paints the pad LEDs and both displays.
The generative side
The three voices are Turing machines - a shift register clocked once per pass,
mutated one bit at a time, read as pitch. Set MELODY to 0 and the loop freezes
bit-identically for as long as you leave it. A voice can run a bounded random
walk instead, which strolls where the register jumps, and one voice can be fed
another’s register so the two drift toward each other without ever converging. A
slow chord walker moves the root all three share, along the scale rather than
chromatically, so three independent lines become a progression.
The drums evolve too: RHYTHM lets steps appear and disappear bar to bar, and
tapping a pad writes into that same register rather than editing the pattern -
a tap takes a step away where there is one and puts one in where there is not.
So a hand-chosen rhythm survives ROTATE, and HITS or LENGTH put the plain
euclidean line back.
Pads are pressure-sensitive: squeeze a held pad on a voice and the filter opens
for as long as you press. And because the driver counts bars, a gesture can land
on a boundary instead of under your finger - ARM composes a macro with a length
(a drop, thinner odds, half or double time, a break, a ratchet ramp), it fires on
the bar and resolves by itself. A bar-synced LFO can be bound to any timbre knob.
SHIFT + REC captures the master to a WAV on the Pi.
The honest part
Two things I would rather say here than have someone find:
- A modulated LV2 plugin hosted with a GUI burns about 70–75% of a core doing
nothing. I measured this last week on silence. It is not the DSP - the audio
threads are identical with and without the modulator, and 99.9% of the cost is
userspace injalv.gtk3, charged per parameter write, not a latched loop. The only fix that costs nothing musically is hosting those plugins without a GUI, and I have not worked out yet whether Zynthian can be told to do that per-instance. If anyone here knows, I would very much like to hear it - that is half of why I am posting. - Nothing here is proved by a document. This project has a rule that a spec,
a status file or a sentence I wrote an hour ago is a claim, not evidence - because
I shipped three predicted numbers once, straight into a manifest, a test and
three guide pages, and all three were wrong. So: the test suites (driver, daemon,
tools, system files, installer dry-runs) all run with no Pi and no controller
attached, twelve AST guards read the driver’s source to answer questions no
running instance can, and the installer suite shadowsssh,scpand
systemctlwith stubs that fail if called - so a dry run that actually executes
something breaks my build instead of someone’s rig.
The video is scripted: the run was generated, then the panel you see is that same
run played back, so the pads, both displays and every lamp are what the hardware
actually showed. I would rather say that than have you assume I have four hands.