Monorepo for Aesthetic.Computer aesthetic.computer

The machine's drum head learns to be rubbed, not only hit: AC Native already had the whole strike side of TrackDrum — Bessel eigenmodes excited at the contact point, resting fingers damping the modes they sit on, five concentric instruments across the head — but the friction was still Mac-only, so a finger dragged across the pad on the machine made either a chain of strikes or nothing at all. That gesture is not a note. There is no note-off to wait for and no duration to schedule; the sound exists exactly as long as a finger keeps moving, and every property of it follows where that finger is. So it lands as one continuous voice mixed after the modal strikes rather than as an entry in the note pool, with the control side re-stating it each frame and the voice slewing to whatever it was last told. master

The DSP is its own dependency-free unit, src/scratch_voice.c, for the same reason gm_synth.c and fluoddity_voice.c are: audio.c cannot be compiled without ALSA, so anything living inside it can only be checked on the hardware it ships to. Split out, the friction builds and auditions on a laptop. Two low-passed copies of one noise source subtracted from each other make a band whose centre and width follow the material under the finger; a tanh makes the grip bite instead of hiss; and a sine head carrier is frequency-modulated by the friction itself — that last detail is the one worth not losing in a rewrite, because without it this is a filtered noise sweep and sounds like one, and with it the head wobbles because the rubbing is uneven rather than because an LFO said so. Control lives in the piece, matching how MenuBandPercussion splits it on macOS. pieces/notepat.mjs measures the gesture and maps it: the fastest-moving finger owns the rub (one head, one voice — a second sliding finger is more of the same hand, not a second surface), speed moves the head's pitch in OCTAVES rather than hertz so a brisk drag sweeps a couple of octaves instead of crowding the top of the range, resting fingers raise tension and shorten the release exactly as they damp a strike, and the seams between materials have more tooth than the fields either side, so crossing one is louder than sliding along it. The material contours are the same numbers as the strike bands, so rubbing and hitting agree about where the skin stops and the rim starts. The release is driven from the no-motion path as well as on lift — a finger held still on the head has stopped rubbing, and without that the voice would sing forever. tools/scratch-audition.c sits beside pitch-audit.c and surface-audit.c and renders the gestures that would betray a broken port: a drag from the middle to the metal edge, one spot rubbed at rising speed, a step through the five materials, and a finger stopping dead. Measured through the timbre analyzer, both laws hold monotonically — gesture speed 526 → 684 Hz, centre-to-edge 308 → 1475 Hz — no non-finite samples anywhere, and the release take falls to exactly zero, which is the one assertion the harness fails on. Verified as far as a Mac allows: scratch_voice.c compiles clean under -Wall -Wextra, the piece parses, and the audition passes. audio.c and js-bindings.c need Linux (ALSA, quickjs) and are unbuilt here; the wiring in both is small and mechanical, but it is unbuilt, and this ships nothing until `ac-os oven` runs. Also ran the synth core through the project's own gate while in the neighbourhood: tools/pitch-audit.c reports PASS 91 / FAIL 4 / uncertain 33 both before and after the brass work in fd481fdf1, so that change is neutral there. The four are pre-existing and worth their own pass — Drawbar, Percussive and Rock Organ plus Bagpipe all sound a full octave below the note they were asked for, the same class of bug as the web synth's square.