AETHER
Guide

How Aether works

A generative ambient soundscape, built from nine layers synthesized live in the browser — no samples, no loops. Here's what every control does, and a few notes on why some of it works the way it does.

Launch Aether →
Getting started

Nothing is recorded

Tap the orb to start. Everything is off by default — turn on whichever layers you want from the mixer underneath it. The space bar also toggles play/pause.

Every sound you hear — the drone, the rain, the bells — is generated fresh by the Web Audio API the moment you press play. There's no audio file anywhere in the app. Reload the page and it's the same instrument, but never quite the same performance: the generative layers pick new notes and patterns each time.

The mixer

Nine layers, three families

The slider is that layer's volume — how loud it sits in the mix, from silent at 0% up to full at 100%. That's all it does; it doesn't change what the layer plays or how it generates its pattern. (For the generative layers — Bells, Arp — that's what Reseed is for.) The switch next to it is just on/off, and jumps the slider to a sensible starting volume.

The nine layers fall into three roles, color-coded the same way the app's own visualizer colors its low, mid, and high frequency bands.

Harmonic bed — the tone everything else sits on
DroneFive sine and triangle partials tuned to the current key's root, fifth, and octave, each slowly breathing in volume. The steady low hum underneath everything.
PadA slow, choir-like chord — three detuned sawtooth voices per note — that drifts to a new chord every 15–25 seconds, in step with Bells and Arp. See "Giving the generators a memory" below.
SubTwo sine waves an octave apart at the root note, swelling slowly. Felt more than heard — the floor of the mix.
Texture — filtered noise, shaped into weather
RainPink noise through a highpass and a peaking filter, with a slow intensity flutter — the character of steady rainfall.
WavesBrown noise through a lowpass filter that opens and closes on two independent slow cycles, so the "surf" never quite repeats itself.
WindPink noise through a bandpass filter that wanders in frequency — an airy, breathing gust rather than a fixed hiss.
Generative — melodic, and different every time
BellsIndividual plucked notes, picked at irregular intervals from a pentatonic scale — mostly drawn toward the current shared chord, occasionally wandering off it.
ArpShort melodic phrases played on a physically modeled plucked string, not a synthesized tone. See "The feedback loop that exploded" below.
ShimmerQuiet, high overtones two-plus octaves above the drone, swelling and fading over 30–40 second cycles.
Key & harmony

Five keys, one shared chord

The key selector (C, D, E, G, A) retunes Drone, Pad, Sub, and Shimmer live, without restarting anything. Bells and the Arp phrase generator both read the current key too, picking their notes from a minor pentatonic scale built on it.

More than that: Bells, Arp, and the Pad's chord all orbit a single, slowly-drifting tonal center, rather than each picking notes on its own. That's a deliberate design decision, not just a scale choice — the full story is under "Giving the generators a memory."

Everything else

Presets, Reseed, and the master controls

Presets — five one-tap starting points (Rainfall, Deep Ocean, Nebula, Rainforest, Sanctuary), each setting a key and a specific layer mix. Touch any slider afterward and the preset highlight clears — you've made it your own from there.

Reseed — Bells and Arp draw from a repeatable-but-varying pattern generator. Reseed gives them a fresh pattern to draw from, without restarting the piece.

Volume & Space — Volume is overall loudness. Space controls how much signal is sent to a shared reverb; turning it up moves the whole mix into a larger virtual room.

Getting it elsewhere

Web, installable, or native Android

In a browser

Just open the app — nothing to install. On mobile, use "Add to Home screen" to install it as a standalone, installable, offline-capable app.

Native Android app

A fully offline Android build exists outside the Play Store — no ads, no tracking, no network permission at all. Two ways to get it:

Sideload the latest build directly: https://thomasehardt.github.io/aether/aether-latest.apk

Or add the self-hosted F-Droid repo in the F-Droid app for real update notifications: https://thomasehardt.github.io/aether/fdroid-repo/repo

Source

Aether is MIT-licensed and the full source (web app, Android project, this page) lives at github.com/thomasehardt/aether.

How it's built

A few notes for the curious

Some of the more interesting decisions and mistakes along the way.

Nothing here is a recording

The entire instrument is oscillators — sine, triangle, sawtooth — and three colors of noise (white, pink, brown), run through filters and envelopes built fresh in the browser's Web Audio graph every time you press play. There isn't a single sample anywhere in the app, which is also why the whole thing fits in one HTML file.

The feedback loop that exploded

The Arp layer was originally a filtered triangle wave — a generic synth "pluck." Making it sound like an actual plucked string called for real physical modeling: Karplus-Strong synthesis, where a burst of noise is fed into a short delay line wired back into itself, and the loop's own resonance becomes the string's pitch and timbre.

The first version used a resonant filter (a BiquadFilterNode) as the damping stage inside that feedback loop. Chrome immediately logged a warning: "BiquadFilterNode: state is bad, probably due to unstable filter." Rendering the exact same construct offline and inspecting the raw samples confirmed it — the signal's peak amplitude went from about 1 to over 1024 within two seconds. Not a decaying pluck. A runaway feedback loop.

The fix was to go back to the original 1983 Karplus-Strong paper's own damping stage: a simple two-tap moving average, pure delay-and-gain math with no resonance possible, so the loop's total gain can never exceed the feedback coefficient at any frequency. Provably stable — and simpler than what it replaced.

The filter on the wrong side

Shimmer's high, airy overtones were disappearing entirely, no matter how much gain got added upstream. The instinct was "it's too quiet, turn it up" — which changed nothing, repeatedly.

Measuring the actual output energy directly, instead of guessing from the code, found the signal flatlined at the noise floor regardless of gain. The real bug: the highpass filter meant to keep Shimmer's tone airy was set to a cutoff above the pitch of Shimmer's own oscillators — so it was eating almost the entire signal before any gain stage ever saw it. No amount of gain fixes a filter on the wrong side of its own source.

Giving the generators a memory

Bells and Arp originally picked notes completely independently, uniformly at random from the scale. Technically harmonic — same scale — but they never sounded like they were listening to each other.

The fix was a single piece of shared state: a tonal center that drifts by one scale step every 15–25 seconds. Bells' note choice and Arp's melodic phrases both lean toward it, and the Pad's chord follows the same center. Three generative layers now drift through the same loose chord progression together, without ever being told to play the "same" notes.

Written by an AI, on purpose

The overwhelming majority of Aether's code, sound design, and this page itself were written by Claude, an AI agent made by Anthropic — directed and reviewed by a human throughout, including catching and fixing both bugs above by actually measuring behavior rather than trusting that the code looked right. The full commit history, with Claude's co-authorship marked on each one, is public in the source repository.