Spectrally shapeable liquid sound explorer. A JavaScript remix of Kees van den Doel's Liquid Simulator [van den Doel 2005].
Nearly all liquid sounds (dripping, streaming, rain, waterfalls, pouring) originate from the acoustic radiation of air bubbles in water [1]. A single bubble produces a damped sinusoidal impulse response [1, Eq. 1]:
ι(t) = a sin(2πft) e−dt
where f is the resonant frequency, d the damping factor, and a the amplitude. The frequency is set by the bubble radius r via the Minnaert relation, f ≈ 3/r (r in meters, f in Hz) [1, Eq. 2; 4]. The damping factor depends on viscous, radiative, and thermal losses [1, Eq. 3]:
d = 0.13/r + 0.0072 r−3/2
This nonlinear relationship means small high-frequency bubbles decay in a few milliseconds while large low-frequency ones ring for tens of milliseconds, giving liquid sounds their characteristic shimmery texture. Complex liquid sounds emerge from the superposition of many bubble events drawn stochastically from a distribution of sizes.
This demo provides a bank of N = 50 independently triggered damped-sinusoidal bubble voices with log-spaced radii. Shape the spectral character by adjusting how bubble events are distributed and weighted across the bank.
Inspired by the "Complex Liquid Sound Simulator" Java applet by Kees van den Doel (University of British Columbia). Remixed from scratch in JavaScript/Web Audio for CS 448Z, Spring 2026.
Rate (bubbles/sec): Total bubble creation rate Λ. Rates up to about 1,000/sec range from dripping to intimate streaming or light rain. At rates up to 10,000/sec, the sound is quite dense but individual droplets are still audible. At rates approaching 100,000/sec, individual events merge into blended soundscapes such as heavy rain or waterfalls [1, Sec. 6].
Size Distribution (γ): Controls the relative creation rates of different bubble sizes via λ̃k = 1/rγ [1, Eq. 8]. Values from γ = 0 to γ ≈ 3 produce sounds of streaming water; values above γ ≈ 5 sound like rain [1, Sec. 6].
Brightness (α, lower = brighter): Controls how excitation energy is distributed across bubble sizes via amplitude ak = D·rkα [1, Eq. 6]. The full model includes a depth factor D = rndβ [1, Eq. 7] with β ≈ 10 modeling attenuation of deeply submerged bubbles; this demo simplifies by treating all bubbles at equal depth (D = 1). Assuming uniform inward fluid velocity at bubble creation, α ≈ 1.5 is physically predicted [1, Eq. 4]. Smaller α brightens the sound by giving small (high-frequency) bubbles relatively more energy, creating the illusion of proximity. Larger α darkens the sound by favoring large (low-frequency) bubbles, creating a sense of distance [1, Sec. 6].
Min/Max Radius: The range of bubble radii in the population. Removing the smallest bubbles (~0.2 mm) always degrades the liquid character of streaming and dripping sounds [1, Sec. 6]. Removing large bubbles and keeping only small radii with high ξ creates nozzle or straw-blowing sounds. Extending up to 5 cm creates the effect of a waterfall or large river.
Rise Factor (ξ): Controls the pitch rise of bubbles formed close to the water surface. As a bubble rises, the effective mass of the surrounding water shell decreases, which raises the bubble's resonant frequency [1, Sec. 3]. The frequency rises as f(t) = f0(1 + σt) with σ = ξ·d [1, Sec. 4]. For water drops, ξ ≈ 0.1 gives a realistic chirp. Higher values create faster pitch sweeps resembling air blown into water through a straw [1, Fig. 5], for which the paper reports ξ ≈ 10.
Rise Probability: The fraction of bubble events that exhibit a rising pitch. In the paper [1, Sec. 5], this is modeled as a depth-factor threshold; here it is simplified to a probability. Higher values mean more bubbles chirp. A value near 0.9 improves realism for sparse sounds such as dripping. Setting rise probability to 1.0 with non-zero ξ makes all bubbles rise, creating the effect of air injected violently into water [1, Sec. 6].
Master Volume: Output level.