PixelParade: a music video, computed

PixelParade is an 86-second chiptune instrumental generated with Suno: a bright pulse arpeggio in G major at 105 BPM, with a band that comes and goes around it. On Saturday I wanted a music video for it. I left the work to Codex and Claude and tried to give them as few instructions as possible. By the evening there were three. Every frame is computed from the song itself, and nothing in the picture is improvised by a browser FFT at playback time.

Watch it

WICK, the third and final version (rendered here at 810×810; the master is 1080×1080 at 60 fps).

A single pixel flame, Wick, crosses a sleeping plain of dark tiles. Every note of the arpeggio lights the tile under its step. After the first held breath in the music, the lit trail stands up and follows. The march doubles, a shadow rolls in and the floor burns away, the tiles return, the opening is remembered, and after the third breath 2,048 walkers rise at once. In the last bars the camera climbs and shows that the route they walked was the shape of the melody all along.

You can also play it live in the browser, with all three versions to pick from. That player renders in real time on your GPU (WebGL2 required), so it can differ slightly from the offline render.

Listening first

The video starts as measurements, not ideas. The track is split into drums, bass, “other” and “vocals” stems with Demucs, and from there everything is Go: a beat grid (105 BPM, first beat at 0.038 s, median onset distance from the 16th grid 8 ms), onsets labelled kick, snare or hat, band energies at 100 Hz, the two near-silent gaps before the drops, and the melody of the arpeggio. A second pass, cmd/story, turns that into a musical skeleton: key (G major, Krumhansl correlation 0.88), chords per half bar, phrases from bar self-similarity (A B C D E D′ A B B′ F), and recurring motifs with their transposed returns. It even writes a MIDI file to load next to the WAV in a DAW.

Envelopes of the mix and the four stems over 86 seconds, with a spectrogram below
The aligned stem analysis. The drops at 9 and 64 s, the breakdown at 37 s and the settle at 82 s are easy to see.

The most useful finding was that loudness hardly moves (loudness range 4.4 LU). The drama is in who is present: with kick and bass the low band holds over half of the energy, without them about a tenth. That is what the videos animate.

Three versions in a day

The first commit landed at 1:24 on Saturday morning; by 3 a.m. there was a finished, verified v1 master, a neon geometric parade drawn with SVG and Canvas in Remotion. Before noon v2 replaced it with raw WebGL2 shader worlds and a ribbon that follows the melody. Both reacted to the music well, but neither told a story. So v3 started differently: from the music to a story, and only then to code.

From the music to a story

First came a “music reading”: an instrument cast with personas (the arpeggio as protagonist, the kick as footfalls, a ghostly vox pad that calls before each turn), a bar map, and the rhymes the song is built on. The fill and silence before the drop at 9.18 s returns almost identically at 64.04 s; the lone opening comes back at 54.9 s, but on G instead of E minor, as an answer to its own question.

From that, three competing treatments were written: Ember Bell, a spark forged into a bell in a night foundry; Upwelling, a plankton spark carried to its first sunrise; and WICK, the procession. WICK won and became a production script of about 11,000 words, in which every number is either measured or a marked design constant.

My favourite part of it is the route. Its shape is the arpeggio’s 12-note figure drawn as a skyline: twelve columns, ten tiles wide, with heights from the scale degrees of the notes. Wick moves exactly one tile per note, and the outline is exactly as long as the melody: 441 tiles, so Wick steps onto the last one on the final G. The three silences in the song are “held breaths”: motion freezes, but light keeps changing, so the frozen world can dim while it waits.

Top-down view of the glowing route: twelve columns of different heights, like a skyline
The last shot: the route seen from above is the arpeggio’s own contour.

Every frame a function of time

The rule behind all three versions is that a frame depends only on song time and the recorded features. There is no simulation history and nothing reads the wall clock. In WICK that covers 25,600 tiles, whose light events are baked into data textures and cooled in the shader from yellow through amber and crimson to purple, and 2,048 walkers whose poses are computed directly from the time. Scenes blend through dissolves, burns, light washes or an iris, so there are no hard cuts.

That rule is what makes the rest testable. A validator checks timeline coverage, route and walker continuity, tile events, the camera and the absence of wall-clock APIs. The still renderer renders frames out of order to prove the capture is deterministic. The master renders in nine resumable sections guarded by a fingerprint of the sources, and a Go verifier decodes the result and compares its soundtrack against the original WAV.

Back into algo-dsp

The analysis code started inside the project, but key detection, chords, self-similarity and motifs are not specific to one song. In the evening it moved into the music packages of algo-dsp (released as v0.8.0), and the MIDI writer became its own small midi module. PixelParade lost about 1,400 lines in the process, and the other projects gained a music analysis toolkit.

Trying it

The browser player is the quickest way. The source, analysis reports, the treatments and the script are on GitHub; with Bun installed, bun install and bun run studio open all three compositions in Remotion Studio.