Designed for desktop browsers.
Bells are instruments of distance. Their sound travels far, and that distance is tinged with a special kind of melancholy—the kind that comes after a struggle. I have wanted a music which studies this journey within sound itself: the collision of waves harmonic and inharmonic, and the long decay that follows. Distance gives resonance.
What resonates? Open answers that question in a multitude of ways. As a generative piece, every tone is a new physical event, ringing in a particular way and gesturing towards the next. As a browser installation, wherever I go, I carry that distance with me.
Open renders low, slow bell tones anchored to familiar harmony. Yet the tones themselves are inharmonic. To frame this tension: while the music resolves from moment to moment, it remains unresolved within the moment itself.
The sounds do not ask for your full attention. Rather, they sit alongside whatever else is happening: the light in your room, the noise outside, or the work you are doing.
Open is meant to run quietly in the background: no logins, no accounts. Only your last tone and duration are remembered locally. Each run is unique. Its performance remains available for WAV export until you press Play again or close the page.
When set to "Infinite", the engine generates new harmonic movement according to a set of rules:
- Circle of Fifths: Harmonic centers shift gradually between related keys.
- Contour Constraints: A bounded random walk keeps the melody between A2 and G#4. Notes that exceed the range are octave-shifted downward.
- Tension Mapping: Cadence choices and resets at the start of an arc update a tension value. Phrase position and tension influence the next cadence; tension also shapes FM brightness, the use of fractured ratios, and whether a drone includes a third.
Open is built purely on the standard Web Audio API without external libraries, utilizing a custom procedural engine to synthesize the environment live.
- Drone Voicing: To prevent low-end mud, the engine analyzes tension and melody in real-time. It forces the drone to collapse into a neutral "Open Fifth" when the melody is complex, and only allows the warm "Third" interval to bloom when the harmony is stable.
- Synthesis (FM Drift): Notes are generated by Frequency Modulation oscillator pairs. To replicate the physical imperfections of cast metal, each note triggers a cluster of voices with highly dynamic FM ratios, drifting unpredictably between 1.5 and 4.0 in stable passages. Under higher harmonic tension, voices instead draw from a separate set of irrational ratios (√2, φ, and others) for a more fractured, inharmonic color. This introduces a wild, inharmonic metallic smear to the attack, while a gentle lowpass filter — tuned for a smooth rolloff rather than a resonant peak — quickly tames the high end so the note settles into a dark, woody tone.
- Moving Resonators: Three slowly moving bandpass filters add a quiet layer of changing overtones to the direct sound and reverb input. Their motion continues through notes and decays.
- Stereo Drift: Each bell strike and bass note starts centered and has a 65% chance of drifting gently to its own stereo position over the note’s duration. Panning uses a separate random stream and feeds both the direct sound and reverb.
- Glacial Pacing: The engine limits event density to preserve long spaces between strikes and allow the reverb tail to breathe. The scheduler will never exceed roughly 15 strikes per minute.
- Physics: The engine models physical decay by reducing the Modulation Index (brightness) faster than the Amplitude (volume). The sound starts complex and fades into a pure sine wave.
- Delayed Entry: The scheduler begins slightly before the first audible event, avoiding an abrupt “start button” feeling.
- Acoustics:
- Impulse Response: A custom convolution reverb with a 10-second impulse response. Its noise envelope uses a decay-curve exponent of 2.8.
- Pre-Delay (15ms): Reverb arrives close to the dry strike while preserving the 10ms bell attack.
- Filter (4200Hz): The reverb return is low-passed to remove digital harshness while keeping the upper harmonics.
Each press of Play creates a new performance.
- Launch: Click "Play" to start the generative engine.
- Tone: Use the slider to set the fundamental frequency (Safety floor: 110Hz).
- Length: Select Short, Medium, Long, Very Long, or Infinite before pressing Play. Short begins seeking its natural ending after 1 minute; Medium after 5 minutes; Long after 10 minutes; Very Long after 30 minutes. These are starting points for the ending, not fixed runtimes: resolving the phrase and allowing the sound to decay can take longer. Infinite continues until stopped. Tone and length changes apply to the next run.
Because there are no project files, you save the audio, not the session.
- Live Recording: Press
Shift + Rto capture the current mix in real time; press it again to save. The browser selects the recording format, saved as.webm,.ogg, or.m4a. Recording also finishes automatically after a natural ending and its remaining audio tail. - Export WAV: Press
Shift + Eto save the current or most recent performance from its beginning as a lossless, 16-bit PCM.wavfile. The WAV uses the same planned notes, FM variations, stereo movement, resonators, reverb, and natural ending as live playback. You can export while listening or after Stop; stopping early does not shorten the planned performance. Repeated exports preserve it until the next Play or page close. WAV filenames include a run identifier shared by every export of that performance, followed by the export timestamp:open-run-<run-id>-<timestamp>.wav. - Timing: Export reproduces the intended performance, excluding browser stalls and manual Stop fades. A timed run includes its complete natural ending and reverb tail, so its WAV can be appreciably longer than the selected time. Infinite exports the same first 30 minutes of planned events plus their remaining decay, while live playback continues. To generate a new performance, press Play again.
- Rendering: WAV rendering runs independently through
OfflineAudioContext, with encoding in a worker. The browser tab title shows preparation, rendering, encoding, and completion or failure. Longer runs take time to render; pressing Shift + E again while busy does not queue another export. The shortcut also works while the length menu or tone slider has focus. It uses the sample rate captured from the live audio context (commonly 44.1 or 48 kHz). Export does not interrupt playback. Small rendering differences across browsers or devices are possible; the performance is shared, rather than a recording of the device output.
Long exports need memory. For 30 minutes of stereo audio alone, the uncompressed render buffer is about 635 MB at 44.1 kHz or 691 MB at 48 kHz; the WAV adds about 318 MB or 346 MB. The natural ending, decay, browser, and synthesis add overhead. Leave plenty of available memory and close other demanding tabs or apps before a long export. Available system memory does not guarantee the browser can complete it; if an export fails or the tab closes, start a shorter run and try again. These are calculated data sizes, not measured peak RAM requirements.
MIT License
Copyright (c) 2026 Aaron Koppel
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.