diff --git a/index.html b/index.html
index dc453e9..b07dacb 100644
--- a/index.html
+++ b/index.html
@@ -647,13 +647,14 @@ function makeCrackle() {
/* the bed: crackle whenever no music is playing. Decided from state, called whenever state changes. */
function bed() {
clearTimeout(crackle.timer);
- crackle.timer = setTimeout(() => { const want = state.primed && !state.playing && !state.holding && state.audio.paused; if (want) crackleOn(); else crackleOff(); }, 300);
+ crackle.timer = setTimeout(() => { const want = !state.playing && !state.holding && state.audio.paused; if (want) crackleOn(); else crackleOff(); }, 300);
}
function crackleOn() {
if (crackle.on || state.holding) return;
crackle.el ||= makeCrackle(); crackle.on = true;
const base = crackle.base ?? crackle.el.volume, t0 = performance.now();
- crackle.el.volume = 0; crackle.el.currentTime = 0; crackle.el.play().catch(() => {});
+ crackle.el.volume = 0; crackle.el.currentTime = 0;
+ crackle.el.play().catch(() => { crackle.on = false; clearInterval(crackle.ramp); }); // refused without a gesture: the first tap calls again
clearInterval(crackle.ramp);
crackle.ramp = setInterval(() => { const k = Math.min(1, (performance.now() - t0) / 600); if (!crackle.on) { clearInterval(crackle.ramp); return; } crackle.el.volume = base * k; if (k >= 1) clearInterval(crackle.ramp); }, 40);
}
@@ -675,11 +676,13 @@ function prime() {
state.audio.play().then(() => { state.playing = true; state.primed = true; crackleOff(); setPlayIcon(); vizStart(); }).catch(() => { state.needTap = true; $("#cover").classList.add("tap"); });
return;
}
+ if (!crackle.on) bed();
if (state.primed || state.current || (state.audio.src && !state.audio.paused)) return;
try { state.audio.src = SILENCE; const p = state.audio.play(); if (p && p.then) p.then(() => { state.primed = true; bed(); }).catch(() => {}); } catch {}
try { crackle.el ||= makeCrackle(); if (!crackle.on) crackleOn(); } catch {}
}
for (const ev of ["pointerdown", "touchend", "keydown"]) document.addEventListener(ev, prime, { capture: true, passive: true });
+setTimeout(bed, 400); // the room tone, from the start where the browser lets it
/* iOS routes sound through Web Audio the moment the element is wired to an analyser, and suspends Web Audio when
the screen locks (and obeys the mute switch). So on iOS the cover pulses to the beat from the sheet instead,
and the music stays a plain