Files
shahikitchen-prod/infrastructure/audio/web-audio-sound-adapter.ts
T

102 lines
2.5 KiB
TypeScript

/** Infrastructure adapter: Web Audio API sound effects. */
let audioContext: AudioContext | null = null;
function getAudioContext(): AudioContext | null {
if (typeof window === 'undefined') return null;
if (!audioContext) {
try {
audioContext = new (window.AudioContext || (window as Window & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext!)();
} catch {
return null;
}
}
return audioContext;
}
export function playHoverSound() {
const ctx = getAudioContext();
if (!ctx) return;
try {
const osc = ctx.createOscillator();
const gain = ctx.createGain();
const filter = ctx.createBiquadFilter();
osc.type = 'sine';
osc.frequency.value = 1100;
filter.type = 'lowpass';
filter.frequency.value = 1400;
gain.gain.value = 0.04;
osc.connect(filter);
filter.connect(gain);
gain.connect(ctx.destination);
osc.start();
gain.gain.linearRampToValueAtTime(0.001, ctx.currentTime + 0.12);
setTimeout(() => osc.stop(), 150);
} catch {
// Silent fail
}
}
export function playAddSound() {
const ctx = getAudioContext();
if (!ctx) return;
try {
const osc = ctx.createOscillator();
const gain = ctx.createGain();
const filter = ctx.createBiquadFilter();
osc.type = 'sine';
osc.frequency.value = 1080;
filter.type = 'lowpass';
filter.frequency.value = 1550;
gain.gain.value = 0.022;
osc.connect(filter);
filter.connect(gain);
gain.connect(ctx.destination);
osc.start();
gain.gain.linearRampToValueAtTime(0.001, ctx.currentTime + 0.08);
setTimeout(() => osc.stop(), 120);
} catch {
// Silent fail
}
}
export function playSuccessSound() {
const ctx = getAudioContext();
if (!ctx) return;
try {
const notes = [523, 659, 784, 1046];
notes.forEach((freq, i) => {
setTimeout(() => {
try {
const osc = ctx.createOscillator();
const gain = ctx.createGain();
const filter = ctx.createBiquadFilter();
osc.type = 'sine';
osc.frequency.value = freq;
filter.type = 'lowpass';
filter.frequency.value = 2000;
gain.gain.value = 0.07;
osc.connect(filter);
filter.connect(gain);
gain.connect(ctx.destination);
osc.start();
gain.gain.linearRampToValueAtTime(0.001, ctx.currentTime + 0.5);
setTimeout(() => osc.stop(), 600);
} catch {
// Silent fail
}
}, i * 120);
});
} catch {
// Silent fail
}
}