mod audio gen
This commit is contained in:
@@ -1685,16 +1685,14 @@ function getCtx() {{
|
||||
}}
|
||||
|
||||
function unlockAudio() {{
|
||||
// Must be called synchronously inside a user gesture handler.
|
||||
// Plays a 1-sample silent buffer — the most reliable iOS unlock method.
|
||||
const ctx = getCtx();
|
||||
// Silent 1-sample buffer — synchronous iOS unlock
|
||||
const buf = ctx.createBuffer(1, 1, ctx.sampleRate);
|
||||
const src = ctx.createBufferSource();
|
||||
src.buffer = buf;
|
||||
src.connect(ctx.destination);
|
||||
src.start(0);
|
||||
// resume() is async; return the promise so callers can chain.
|
||||
return ctx.state === 'suspended' ? ctx.resume() : Promise.resolve();
|
||||
if (ctx.state === 'suspended') ctx.resume(); // fire-and-forget, no .then()
|
||||
}}
|
||||
|
||||
function beep(freq, dur, vol) {{
|
||||
@@ -1723,31 +1721,27 @@ function staleChime() {{
|
||||
}}
|
||||
|
||||
function testSound() {{
|
||||
// Called directly from onclick — gesture is active here.
|
||||
unlockAudio().then(() => {{
|
||||
beep(880, 0.15, 0.4);
|
||||
setTimeout(() => beep(1100, 0.15, 0.4), 180);
|
||||
setTimeout(() => beep(880, 0.3, 0.4), 360);
|
||||
}});
|
||||
// Everything synchronous inside the gesture — no .then()
|
||||
unlockAudio();
|
||||
// Small offset gives resume() time to complete before beeps fire
|
||||
setTimeout(() => beep(880, 0.15, 0.4), 80);
|
||||
setTimeout(() => beep(1100, 0.15, 0.4), 260);
|
||||
setTimeout(() => beep(880, 0.3, 0.4), 440);
|
||||
}}
|
||||
|
||||
function toggleAudio() {{
|
||||
// Called directly from onclick — gesture is active here.
|
||||
unlockAudio().then(() => {{
|
||||
audioEnabled = !audioEnabled;
|
||||
localStorage.setItem('audioEnabled', audioEnabled);
|
||||
if (!audioEnabled) {{
|
||||
stopWarning();
|
||||
audioArmed = false; warningActive = false;
|
||||
document.getElementById('btn-confirm').style.display = 'none';
|
||||
stopStaleWarning();
|
||||
staleActive = false; staleConfirmed = false;
|
||||
document.getElementById('btn-confirm-stale').style.display = 'none';
|
||||
}} else {{
|
||||
if (lastStatus === 'scanning' && !audioArmed) audioArmed = true;
|
||||
}}
|
||||
updateAudioUI();
|
||||
}});
|
||||
unlockAudio(); // synchronous, inside gesture
|
||||
audioEnabled = !audioEnabled;
|
||||
localStorage.setItem('audioEnabled', audioEnabled);
|
||||
if (!audioEnabled) {{
|
||||
stopWarning(); audioArmed = false; warningActive = false;
|
||||
document.getElementById('btn-confirm').style.display = 'none';
|
||||
stopStaleWarning(); staleActive = false; staleConfirmed = false;
|
||||
document.getElementById('btn-confirm-stale').style.display = 'none';
|
||||
}} else {{
|
||||
if (lastStatus === 'scanning' && !audioArmed) audioArmed = true;
|
||||
}}
|
||||
updateAudioUI();
|
||||
}}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user