
{"id":2139,"date":"2026-10-03T21:30:00","date_gmt":"2026-10-03T19:30:00","guid":{"rendered":"https:\/\/www.pcjv.de\/?p=2139"},"modified":"2026-10-04T19:44:21","modified_gmt":"2026-10-04T17:44:21","slug":"pixelparade","status":"publish","type":"post","link":"https:\/\/www.pcjv.de\/?p=2139","title":{"rendered":"PixelParade: a music video, computed"},"content":{"rendered":"\n\n<p class=\"wp-block-paragraph\">PixelParade is an 86-second chiptune instrumental generated with <a href=\"https:\/\/suno.com\/\" target=\"_blank\" rel=\"noopener\">Suno<\/a>: 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.<\/p>\n\n\n<!--more-->\n\n\n<h2 class=\"wp-block-heading\">Watch it<\/h2>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"720\" style=\"aspect-ratio: 720 \/ 720;\" width=\"720\" controls preload=\"metadata\" poster=\"\/wordpress\/wp-content\/uploads\/pixelparade-poster.jpg\" src=\"\/wordpress\/wp-content\/uploads\/pixelparade-wick.mp4\"><\/video><figcaption class=\"wp-element-caption\">WICK, the third and final version (rendered here at 810\u00d7810; the master is 1080\u00d71080 at 60 fps).<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can also <a href=\"https:\/\/cwbudde.github.io\/PixelParade\/\" target=\"_blank\" rel=\"noopener\">play it live in the browser<\/a>, 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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Listening first<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The video starts as measurements, not ideas. The track is split into drums, bass, &#8220;other&#8221; and &#8220;vocals&#8221; 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, <code>cmd\/story<\/code>, 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&prime; A B B&prime; F), and recurring motifs with their transposed returns. It even writes a MIDI file to load next to the WAV in a DAW.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"\/wordpress\/wp-content\/uploads\/pixelparade-analysis.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1400\" height=\"1050\" src=\"\/wordpress\/wp-content\/uploads\/pixelparade-analysis.jpg\" alt=\"Envelopes of the mix and the four stems over 86 seconds, with a spectrogram below\" class=\"wp-image-2134\" srcset=\"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-analysis.jpg 1400w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-analysis-300x225.jpg 300w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-analysis-1024x768.jpg 1024w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-analysis-768x576.jpg 768w\" sizes=\"auto, (max-width: 1400px) 100vw, 1400px\" \/><\/a><figcaption class=\"wp-element-caption\">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.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Three versions in a day<\/h2>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-3 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><a href=\"\/wordpress\/wp-content\/uploads\/pixelparade-v1.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"900\" data-id=\"2135\" src=\"\/wordpress\/wp-content\/uploads\/pixelparade-v1.jpg\" alt=\"v1: neon geometric shapes\" class=\"wp-image-2135\" srcset=\"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-v1.jpg 900w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-v1-300x300.jpg 300w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-v1-150x150.jpg 150w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-v1-768x768.jpg 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><figcaption class=\"wp-element-caption\">v1: SVG\/Canvas neon parade<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"\/wordpress\/wp-content\/uploads\/pixelparade-v2.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"900\" data-id=\"2136\" src=\"\/wordpress\/wp-content\/uploads\/pixelparade-v2.jpg\" alt=\"v2: WebGL shader world with a melody ribbon\" class=\"wp-image-2136\" srcset=\"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-v2.jpg 900w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-v2-300x300.jpg 300w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-v2-150x150.jpg 150w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-v2-768x768.jpg 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><figcaption class=\"wp-element-caption\">v2: WebGL2 shader worlds<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"\/wordpress\/wp-content\/uploads\/pixelparade-v3.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"900\" data-id=\"2137\" src=\"\/wordpress\/wp-content\/uploads\/pixelparade-v3.jpg\" alt=\"v3: walkers marching across a tile plain\" class=\"wp-image-2137\" srcset=\"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-v3.jpg 900w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-v3-300x300.jpg 300w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-v3-150x150.jpg 150w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-v3-768x768.jpg 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><figcaption class=\"wp-element-caption\">v3: WICK in React Three Fiber<\/figcaption><\/figure>\n<\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">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 <a href=\"https:\/\/www.remotion.dev\/\" target=\"_blank\" rel=\"noopener\">Remotion<\/a>. 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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">From the music to a story<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">First came a &#8220;music reading&#8221;: 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.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">From that, three competing treatments were written: <em>Ember Bell<\/em>, a spark forged into a bell in a night foundry; <em>Upwelling<\/em>, a plankton spark carried to its first sunrise; and <em>WICK<\/em>, 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.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">My favourite part of it is the route. Its shape is the arpeggio&#8217;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 &#8220;held breaths&#8221;: motion freezes, but light keeps changing, so the frozen world can dim while it waits.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"900\" src=\"\/wordpress\/wp-content\/uploads\/pixelparade-route.jpg\" alt=\"Top-down view of the glowing route: twelve columns of different heights, like a skyline\" class=\"wp-image-2138\" style=\"width:600px\" srcset=\"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-route.jpg 900w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-route-300x300.jpg 300w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-route-150x150.jpg 150w, https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/pixelparade-route-768x768.jpg 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><figcaption class=\"wp-element-caption\">The last shot: the route seen from above is the arpeggio&#8217;s own contour.<\/figcaption><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">Every frame a function of time<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Back into algo-dsp<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">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 <a href=\"https:\/\/github.com\/cwbudde\/algo-dsp\" target=\"_blank\" rel=\"noopener\">algo-dsp<\/a> (released as v0.8.0), and the MIDI writer became its own small <a href=\"https:\/\/github.com\/cwbudde\/midi\" target=\"_blank\" rel=\"noopener\">midi<\/a> module. PixelParade lost about 1,400 lines in the process, and the other projects gained a music analysis toolkit.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Trying it<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/cwbudde.github.io\/PixelParade\/\" target=\"_blank\" rel=\"noopener\">browser player<\/a> is the quickest way. The source, analysis reports, the treatments and the script are on <a href=\"https:\/\/github.com\/CWBudde\/PixelParade\" target=\"_blank\" rel=\"noopener\">GitHub<\/a>; with Bun installed, <code>bun install<\/code> and <code>bun run studio<\/code> open all three compositions in Remotion Studio.<\/p>\n\n\n","protected":false},"excerpt":{"rendered":"<p>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. [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":2166,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[41,43],"tags":[],"class_list":["post-2139","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-go","category-typescript"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>PixelParade: a music video, computed - Christian&#039;s private site<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.pcjv.de\/?p=2139\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2139#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2139\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"PixelParade: a music video, computed\",\"datePublished\":\"2026-10-03T19:30:00+00:00\",\"dateModified\":\"2026-10-04T17:44:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2139\"},\"wordCount\":994,\"image\":{\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2139#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.pcjv.de\\\/wordpress\\\/wp-content\\\/uploads\\\/teaser-pixelparade.jpg\",\"articleSection\":[\"Go\",\"TypeScript\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2139\",\"url\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2139\",\"name\":\"PixelParade: a music video, computed - Christian&#039;s private site\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2139#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2139#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.pcjv.de\\\/wordpress\\\/wp-content\\\/uploads\\\/teaser-pixelparade.jpg\",\"datePublished\":\"2026-10-03T19:30:00+00:00\",\"dateModified\":\"2026-10-04T17:44:21+00:00\",\"author\":{\"@id\":\"\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2139#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.pcjv.de\\\/?p=2139\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2139#primaryimage\",\"url\":\"https:\\\/\\\/www.pcjv.de\\\/wordpress\\\/wp-content\\\/uploads\\\/teaser-pixelparade.jpg\",\"contentUrl\":\"https:\\\/\\\/www.pcjv.de\\\/wordpress\\\/wp-content\\\/uploads\\\/teaser-pixelparade.jpg\",\"width\":480,\"height\":360},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/?p=2139#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.pcjv.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PixelParade: a music video, computed\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.pcjv.de\\\/#website\",\"url\":\"https:\\\/\\\/www.pcjv.de\\\/\",\"name\":\"Christian&#039;s private site\",\"description\":\"Private site of Christian-W. Budde\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.pcjv.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"PixelParade: a music video, computed - Christian&#039;s private site","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.pcjv.de\/?p=2139","twitter_misc":{"Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.pcjv.de\/?p=2139#article","isPartOf":{"@id":"https:\/\/www.pcjv.de\/?p=2139"},"author":{"name":"","@id":""},"headline":"PixelParade: a music video, computed","datePublished":"2026-10-03T19:30:00+00:00","dateModified":"2026-10-04T17:44:21+00:00","mainEntityOfPage":{"@id":"https:\/\/www.pcjv.de\/?p=2139"},"wordCount":994,"image":{"@id":"https:\/\/www.pcjv.de\/?p=2139#primaryimage"},"thumbnailUrl":"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/teaser-pixelparade.jpg","articleSection":["Go","TypeScript"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.pcjv.de\/?p=2139","url":"https:\/\/www.pcjv.de\/?p=2139","name":"PixelParade: a music video, computed - Christian&#039;s private site","isPartOf":{"@id":"https:\/\/www.pcjv.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.pcjv.de\/?p=2139#primaryimage"},"image":{"@id":"https:\/\/www.pcjv.de\/?p=2139#primaryimage"},"thumbnailUrl":"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/teaser-pixelparade.jpg","datePublished":"2026-10-03T19:30:00+00:00","dateModified":"2026-10-04T17:44:21+00:00","author":{"@id":""},"breadcrumb":{"@id":"https:\/\/www.pcjv.de\/?p=2139#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.pcjv.de\/?p=2139"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.pcjv.de\/?p=2139#primaryimage","url":"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/teaser-pixelparade.jpg","contentUrl":"https:\/\/www.pcjv.de\/wordpress\/wp-content\/uploads\/teaser-pixelparade.jpg","width":480,"height":360},{"@type":"BreadcrumbList","@id":"https:\/\/www.pcjv.de\/?p=2139#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.pcjv.de\/"},{"@type":"ListItem","position":2,"name":"PixelParade: a music video, computed"}]},{"@type":"WebSite","@id":"https:\/\/www.pcjv.de\/#website","url":"https:\/\/www.pcjv.de\/","name":"Christian&#039;s private site","description":"Private site of Christian-W. Budde","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.pcjv.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"_links":{"self":[{"href":"https:\/\/www.pcjv.de\/index.php?rest_route=\/wp\/v2\/posts\/2139","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pcjv.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pcjv.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pcjv.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2139"}],"version-history":[{"count":1,"href":"https:\/\/www.pcjv.de\/index.php?rest_route=\/wp\/v2\/posts\/2139\/revisions"}],"predecessor-version":[{"id":2157,"href":"https:\/\/www.pcjv.de\/index.php?rest_route=\/wp\/v2\/posts\/2139\/revisions\/2157"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pcjv.de\/index.php?rest_route=\/wp\/v2\/media\/2166"}],"wp:attachment":[{"href":"https:\/\/www.pcjv.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2139"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pcjv.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2139"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pcjv.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2139"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}