fix : sound overlap issue (#38)

This commit is contained in:
Speedauge
2025-06-08 17:34:32 +02:00
committed by GitHub
parent 3128c7b882
commit 91876d11e3

View File

@@ -1,37 +1,40 @@
import { Move } from "chess.js"; import { Move } from "chess.js";
let audioContext: AudioContext | null = null; let ctx: AudioContext | null = null;
let audio: HTMLAudioElement | null = null; const bufferCache = new Map<string, AudioBuffer>();
const playSound = async (url: string) => { const urls = {
if (!audio) { move: "/sounds/move.mp3",
audioContext = new AudioContext(); capture: "/sounds/capture.mp3",
audio = new Audio(); illegal: "/sounds/illegal-move.mp3"
const source = audioContext.createMediaElementSource(audio); } as const;
const volume = audioContext.createGain(); type Sound = keyof typeof urls;
volume.gain.value = 0.3;
source.connect(volume);
volume.connect(audioContext.destination);
}
audio.src = url; async function play(sound: Sound) {
try { try {
await audio.play(); ctx ??= new (window.AudioContext || (window as any).webkitAudioContext)();
if (ctx.state === "suspended") await ctx.resume();
let buf = bufferCache.get(urls[sound]);
if (!buf) {
const res = await fetch(urls[sound]);
buf = await ctx.decodeAudioData(await res.arrayBuffer());
bufferCache.set(urls[sound], buf);
}
const src = ctx.createBufferSource();
src.buffer = buf;
src.connect(ctx.destination);
src.start();
} catch { } catch {
console.warn("Audio play failed"); if ("vibrate" in navigator) navigator.vibrate(50);
} }
};
export const playCaptureSound = () => playSound("/sounds/capture.mp3");
export const playIllegalMoveSound = () => playSound("/sounds/error.mp3");
export const playMoveSound = () => playSound("/sounds/move.mp3");
export const playSoundFromMove = async (move: Move | null) => {
if (!move) {
playIllegalMoveSound();
} else if (move.captured) {
playCaptureSound();
} else {
playMoveSound();
} }
};
export const playCaptureSound = () => play("capture");
export const playIllegalMoveSound = () => play("illegal");
export const playMoveSound = () => play("move");
export async function playSoundFromMove(move: Move | null) {
if (!move) return playIllegalMoveSound();
if (move.captured) return playCaptureSound();
return playMoveSound();
}