Chladni listens to your microphone or system audio, pulls it apart into features, and uses those features to steer a chemical reaction simulated on the GPU. The result is rendered as a lit, extruded landscape that breathes with the music.
It is named after Ernst Chladni, who in 1787 discovered that sand on a vibrating plate settles along the lines where the plate is not moving. This does roughly the same thing, with a lot more arithmetic.
How it works
Audio comes in through a tap into a lock-free ring buffer, so the render thread never waits on the audio thread. Each frame, the analyzer extracts:
- FFT band energies — low, mid, and high, driving different simulation parameters
- Spectral centroid — the "brightness" of the sound, mapped to palette and feed rate
- Onset detection — transients that kick the system out of equilibrium
- A comb-filter beat tracker — estimates tempo and phase so slower motion can lock to the beat
Those values feed a Gray–Scott reaction–diffusion system running as a Metal compute shader over a ping-pong pair of textures. Gray–Scott is two chemicals, one feeding on the other; small changes to the feed and kill rates move it between spots, stripes, worms, and total dissolution. Audio makes those changes.
The field is then rendered by a ray marcher that treats the chemical concentration as a heightfield, so you are looking at an actual extruded surface with real depth, not a flat texture. Bloom, tone mapping, and motion blur finish the frame.
| Stage | Runs on | Notes | | --- | --- | --- | | Audio tap → ring buffer | Audio thread | Lock-free, never blocks | | FFT + feature extraction | CPU | Per-frame, cheap | | Gray–Scott step | GPU compute | Ping-pong textures | | Ray march + post | GPU render | Bloom · tonemap · motion blur |
Building it
Requirements: macOS 13 or later, Xcode command-line tools (for xcrun metal),
and CMake 3.24+. Apple Silicon is the primary target; Intel Macs work as a
secondary target.
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
open build/Chladni.app
Using it
Press S at any time to drop a PNG screenshot into ~/Pictures/Chladni/.
Ambient mode takes over the whole screen, reacts to the microphone, and exits the moment you touch the keyboard or mouse — it is meant to be left running on a second display at a party.
Three presets ship in assets/presets/:
default.json— balanced, responds across the whole spectrumambient.json— slow, low contrast, for background usetechno.json— hard onset response, locked to the beat tracker
Presets are plain JSON. Copy one, change the numbers, and it shows up in the app.
Status
Working and fun to use, still being tuned. The parameter space is enormous and I keep finding regions of it that look better than what I had before. There is no signed release build yet, so for now it is a build-it-yourself project.