A procession climbs Penrose's impossible stairs while a Shepard tone rises forever.
Four landings joined by flights of eight, eight, two and two shallow steps move the path by (3, 3) per lap while it climbs 6, and the parallel projection is chosen so that exactly that vector points at the viewer and vanishes: the step after the last lands on the first, and the blocks are simply painted back to front with walls that fade into the paper. The sound is the same loop for the ear. A Shepard tone stacks sine partials an octave apart under one fixed bell of loudness over log frequency; slide them all up and the ones leaving the top fade out as new ones fade in at the bottom, so the pitch class climbs without ever getting higher. Every two steps are one semitone, so a lap is an octave, and the panel draws the live spectrum with each partial sliding up through the bell. Partial frequencies and gains are scheduled ahead on the audio clock in short ramps, and a partial jumps from top to bottom only where the bell has made it silent.
Try it. Click for sound. Click the stairs (or press R or space) to reverse the climb, Walk and Slow change the pace, the up and down arrows set the speed, Scale plays one discrete Shepard tone per semitone climbed, and Tritone plays Diana Deutsch's tritone paradox, pairs half an octave apart that some listeners hear rising and others falling. M mutes.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a Shepard tone staircase with JavaScript, the HTML canvas element and the Web Audio API: an impossible staircase that climbs forever, paired with a tone that rises forever. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
Start simple:
- Make a canvas that fills the window, stays sharp on high-DPI screens (scale by devicePixelRatio), and resizes with the window.
- Only after the first click, create an AudioContext with about nine sine oscillators. Oscillator i plays 16.35 Hz times 2 to the power (i + phase), wrapped into a nine-octave range. Its gain is a fixed bell curve over log frequency, exp(-0.5 * ((octave - 4.7) / 1.25) squared), so partials fade in at the bottom and out at the top.
- Increase phase slowly. Every frame, schedule short exponentialRampToValueAtTime and linearRampToValueAtTime segments a little ahead on the audio clock, and jump a wrapping partial with setValueAtTime while its gain is nearly zero.
- Draw the spectrum: the bell, and each partial as a bar at its log frequency, as tall as its gain.
Once that works, make it beautiful:
- Draw Penrose stairs in a parallel projection: twelve blocks walking +x four times, +y four times, -x twice and -y twice, each a third of a unit higher. Use screen x = (x - y) * a and screen y = (x + y) * b - z * b, which makes the lap vector (2, 2, 4) project to nothing, so the last step lands on the first. Paint blocks back to front sorted by x + y, with walls that fade into the paper.
- Label the steps with pitch classes and walk a few little figures up them in time with the phase.
- Add a button to reverse direction and a mode that plays discrete Shepard tones, one per step.
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 Diana Deutsch's tritone paradox, a Risset rhythm that speeds up forever, or a spiral pitch helix view.