Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102// WebAudio synth of the AIM "buddy in / buddy out" door sounds. The real AIM// samples are copyrighted, so these are originals built to evoke them: a wooden// door CREAK (swept band-pass noise with stick-slip amplitude wobble) plus a// low thunk/latch. Open = creak rising + soft settle; close = creak falling// into a heavier slam. All generated on the fly — no audio files.
let ctx = null;let master = null;let noiseBuf = null;let enabled = true;
export function setEnabled(on) { enabled = on; }export function isEnabled() { return enabled; }
function ensure() { if (ctx) return ctx; const AC = window.AudioContext || window.webkitAudioContext; if (!AC) return null; ctx = new AC(); master = ctx.createGain(); master.gain.value = 0.9; master.connect(ctx.destination); // 1s of white noise to feed the creak filter. const len = ctx.sampleRate; noiseBuf = ctx.createBuffer(1, len, ctx.sampleRate); const d = noiseBuf.getChannelData(0); for (let i = 0; i < len; i++) d[i] = Math.random() * 2 - 1; return ctx;}
// Must be called from a user gesture (the handle submit) to satisfy autoplay.export function unlock() { ensure(); if (ctx && ctx.state === 'suspended') ctx.resume();}
// A creak: band-pass-filtered noise whose center frequency sweeps f0->f1, with a// sawtooth LFO chewing the amplitude to give the dry stick-slip "rrrr" texture.function creak(t0, dur, f0, f1, peak, lfoHz) { const src = ctx.createBufferSource(); src.buffer = noiseBuf; src.loop = true;
const bp = ctx.createBiquadFilter(); bp.type = 'bandpass'; bp.Q.value = 7; bp.frequency.setValueAtTime(f0, t0); bp.frequency.exponentialRampToValueAtTime(f1, t0 + dur);
const env = ctx.createGain(); env.gain.setValueAtTime(0.0001, t0); env.gain.exponentialRampToValueAtTime(peak, t0 + 0.035); env.gain.exponentialRampToValueAtTime(0.0001, t0 + dur);
// stick-slip tremolo: LFO (-depth..+depth) summed onto a base gain. const trem = ctx.createGain(); trem.gain.value = 0.55; const lfo = ctx.createOscillator(); lfo.type = 'sawtooth'; lfo.frequency.setValueAtTime(lfoHz, t0); lfo.frequency.linearRampToValueAtTime(lfoHz * 0.6, t0 + dur); const lfoDepth = ctx.createGain(); lfoDepth.gain.value = 0.5; lfo.connect(lfoDepth).connect(trem.gain);
src.connect(bp).connect(env).connect(trem).connect(master); src.start(t0); src.stop(t0 + dur + 0.05); lfo.start(t0); lfo.stop(t0 + dur + 0.05);}
// A wooden thunk/latch: short pitched triangle blip that drops in pitch.function thunk(t0, freq, dur, peak) { const o = ctx.createOscillator(); o.type = 'triangle'; o.frequency.setValueAtTime(freq * 1.5, t0); o.frequency.exponentialRampToValueAtTime(freq, t0 + dur); const g = ctx.createGain(); g.gain.setValueAtTime(0.0001, t0); g.gain.exponentialRampToValueAtTime(peak, t0 + 0.008); g.gain.exponentialRampToValueAtTime(0.0001, t0 + dur); o.connect(g).connect(master); o.start(t0); o.stop(t0 + dur + 0.02);}
// Door swings OPEN: a latch tick, a creak that rises, a soft settle.export function doorOpen() { if (!enabled || !ensure()) return; const t = ctx.currentTime; thunk(t, 520, 0.04, 0.18); // latch lifts creak(t + 0.02, 0.34, 300, 760, 0.5, 28); // hinge creak, rising thunk(t + 0.34, 130, 0.13, 0.3); // door settles open}
// Door clicks SHUT: a faster falling creak into a heavier low slam + latch.export function doorClose() { if (!enabled || !ensure()) return; const t = ctx.currentTime; creak(t, 0.24, 720, 300, 0.45, 40); // hinge creak, falling thunk(t + 0.22, 95, 0.17, 0.55); // the slam thunk(t + 0.33, 780, 0.04, 0.2); // latch clicks}