Whole songs from one line of bit arithmetic, drawn as a tapestry of bytes.
A bytebeat is a formula in the sample counter t, evaluated 8000 times a second, whose low 8 bits are the audio sample. Formulas are tokenized and parsed by a small Pratt parser with C operator precedence and compiled into a tree of closures with constant folding, and the same closure feeds both the audio callback and the picture. Each column of the tapestry is a power-of-two run of consecutive samples, one byte per pixel, so the shifts in the formula line up with the grid and the music's self-similar structure appears as nested squares, checkerboards and plaid. Since a bytebeat is a pure function of t, the future is drawn too, to the right of the playhead, and a new formula repaints outward from 'now'.
Try it. Click for sound. Type in the formula bar to edit it live (errors are underlined and the last good formula keeps playing), or step through presets with the arrows or Up and Down. Mutate (or Tab) nudges a number, and the buttons change the color map, the column height and the sample rate. Drag the tapestry to scrub through time or click it to jump. Escape toggles the autopilot, which types its own formulas.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a bytebeat player and visualizer with JavaScript, the HTML canvas element and the Web Audio API. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
A bytebeat is a formula in t, the sample counter, such as t*(42&t>>10). Evaluate it 8000 times a second, keep the low 8 bits of the result, and that byte is the audio sample.
Start simple:
- Add a text input for the formula and a high-DPI canvas filling the rest of the window.
- Write a small tokenizer and a recursive descent (or Pratt) parser for numbers, t, parentheses and the operators + - * / % & | ^ << >> with C's precedence. Instead of eval, compile the parse tree into nested closures, a fast function of t. Show parse errors and keep playing the last formula that worked.
- On the first click, create an AudioContext and a ScriptProcessorNode (or an AudioWorklet). Advance t by 8000 / sampleRate per output sample, recompute the byte when floor(t) changes, and output (byte - 128) / 128 at a gentle volume.
Once that works, make it beautiful:
- Draw the byte stream as a picture: each column is 256 consecutive samples from top to bottom, columns run left to right, and each byte becomes one pixel through a color map. Write the pixels into ImageData on a small offscreen canvas and draw it scaled up with smoothing off.
- Scroll the picture so a playhead stays fixed, and because the formula is a pure function of t, draw the future to the right of the playhead too.
- Add a few presets and a button that mutates a random number in the formula.
Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as switchable column heights to reveal different structure, a stepped oscilloscope of the last few hundred samples, or dragging the picture to scrub through time.