Ambient Sound Online
[ Inside This App ]

Hysteresis: How to Stop a Sound From Flickering On and Off

Max Ramozov · October 2026

Ocean starts playing right away. Free, no sign-up.

Short answer: If something switches on when a value crosses one line, it will flicker whenever the value hovers near that line. Use two lines: one to switch on and a different one to switch off, with a gap between them. Inside the gap nothing changes. That is hysteresis.

One line flickers, two lines hold

The bug

In my app a sound starts when two shapes overlap. My first rule was the obvious one: if the distance between them is less than a limit, they are touching.

It worked until two shapes drifted past each other slowly. At the edge of contact their distance wobbles by a tiny amount from frame to frame. Each wobble crossed the limit, so the app thought they had touched, parted, touched and parted, many times a second. One meeting came out as a stutter.

Nothing was wrong with the sound. One line was being asked to do two jobs.

The fix

Give "start" and "stop" their own lines. Two shapes have to get properly close before the sound starts. Once it has started, they have to move clearly apart before it stops. In between, the answer is "whatever it was a moment ago".

// Illustrative numbers. Any two values with a gap between them will do.
const START_AT = 0.8;  // must come this close to begin
const STOP_AT  = 1.0;  // must move this far apart to end

const reach = radiusA + radiusB;
const limit = reach * (wasTouching ? STOP_AT : START_AT);
const touching = distance < limit;

The only state you need is whether the pair was touching on the last frame.

Where the idea comes from

Electronics. A Schmitt trigger is a circuit that turns a noisy, wobbling signal into a clean on or off by using two thresholds. With one threshold, noise near it makes the output switch back and forth. With two, the signal has to travel all the way to the other threshold before anything changes.

A room thermostat does the same thing. It doesn't switch the heating on and off every time the temperature crosses the exact setting. It waits for a real swing.

It is useful outside sound

I now see the same bug everywhere: a hover effect that flashes when the cursor sits on an edge, a "scrolled past" header that jitters, a loading spinner that blinks during a brief stall. Whenever a smooth, slightly noisy value drives an on-or-off decision, two thresholds beat one.

Sources

Try it: in Ocean, watch two shapes that are only just touching. The line between them holds steady. It is free and starts in one click.

Open Ocean, free