waveloop: what fable left mewaveloop: what fable left me<br>Over the two days we had Fable 5, it made me a music visualizer. This is the realization of something I have daydreamed about for as long as I can remember.
You can see it here: Waveloop<br>The idea is that a music visualizer should viscerally reveal the harmonic and melodic structure of the music. Most visualizers fail to do this — you get a vague sense of loudness, and maybe the bass/treble split, but that's it.<br>How can we do better? As we all know, the foundation of Western diatonic music theory is ¹²√2, the ratio between the frequencies of successive semitones. (I ignore other temperaments; they are all close enough to 12-TET.) Twelve of these takes you to the next octave, and notes that are a whole number of octaves apart are considered to be in the same pitch class.<br>Waveloop captures this cyclic structure in a chromatic circle, 30° per semitone, one revolution per octave. Any instant in the music is captured as a spiral stacked histogram, showing you how much of each pitch class is present. The layers of the histogram are different colors capturing different octaves: muted blues and greens for the bass, fiery orange and red and violet for mid-tones, and sparkly gold and sky for treble, tracing a spiral through oklch.<br>This representation has some nice properties:<br>You can read intervals simply as angles. Here are the intervals:<br>m2 30°M2 60°m3 90°M3 120°P4 150°TT 180°P5 210°m6 240°M6 270°m7 300°M7 330°<br>You can tell the quality of a chord from its shape. Transposing rotates the shape; inversion leaves it unchanged. Here are some common chord qualities:<br>maj 0 · 4 · 7min 0 · 3 · 7dim 0 · 3 · 6aug 0 · 4 · 8sus4 0 · 5 · 7sus2 0 · 2 · 7dom7 0 · 4 · 7 · 10maj7 0 · 4 · 7 · 11min7 0 · 3 · 7 · 10<br>Waveloop primarily operates on an offline basis, where it precomputes a CQT for a particular track, but Fable also gave me a live mic mode. When I turn it on, I find that it's able to identify ukulele chords I play pretty quickly and reliably.<br>We've been without Fable for about week now, and to remind myself of what once was, I took a look at some of the waveloop code.<br>The thing that struck me first is that it is dense. While previous models wrote code like a perfectly reasonable upwardly mobile engineer at a FAANG who is on their way to receiving a steady stream of promotions until they cap out at L5, this model writes more like how I'd imagine Terry Davis would have written code alone in his room.<br>Take a look at this comment at the top of the waveloop file. It wastes no words describing in obvious terms the code it just wrote. The comments seem more like maximally information dense recordings of intent, lockfiles from which something resembling the rest of the code could in principle be derived.<br>/* The visualizer is a pitch-class wheel: angle = fract(log2(f / 440)), so<br>every octave of a note lands on the same spoke (A at 12 o'clock, ascending<br>clockwise). The CPU keeps ~5 seconds of per-register-band emission history<br>and rasterizes it every frame into the RGBA radial trail map sampled here<br>(REGS vertically stacked blocks, T axis = radius; rgb = premultiplied<br>register color with fade baked in, a = faded energy): each history row<br>sits at the radius its own stored amplitude has carried it to, so motion<br>is amplitude-driven - the loudest components shoot across the whole window<br>while quiet accompaniment and noise linger near the ring, and the main<br>line visually outruns everything else (see rasterTrails below).
Color is continuous Oklch, computed CPU-side per FFT bin (hue encodes<br>absolute frequency on a log scale, red at 20 Hz to violet at 20 kHz;<br>lightness climbs the register axis - dark bass, fully saturated mids around<br>common fundamentals, pale sparkly treble).
Display energies live in 0..EMAX (loud fundamentals overshoot 1 instead<br>of clipping at the old AGC ceiling); the trail map stores sqrt(v / EMAX)<br>in alpha (and rgb premultiplied by that encoded alpha) so the u8 texture<br>keeps low-end precision while carrying the extra headroom.
Because the bands stay separate all the way to the screen, a pitch class<br>sounding in several octaves renders as a stacked histogram on the rim<br>(low register innermost), with color gliding continuously through the<br>register ramp up the stack (u_rim carries the inverse CDF of each angle's<br>register distribution) instead of cutting between a few band colors;<br>register lives in the stack position and hue, never in the speed.
The field extends past the farthest screen corner, and radius is a concave<br>function of age, so material surges off the rim and decelerates as it drifts<br>outward. */The writing is deeply technical. This model doesn't shy away from drawing upon all its knowledge. It casually refers to alpha premultiplication and fundamental frequencies in...