From f3a9656891d11db6589c40666e43346f91b9b64c Mon Sep 17 00:00:00 2001 From: Joeri Exelmans Date: Sat, 25 Oct 2025 19:27:39 +0200 Subject: [PATCH] important feature: use Web Audio API to get microwave sounds just right. --- src/App/App.tsx | 2 +- src/Plant/Microwave/Microwave.css | 4 ++ src/Plant/Microwave/Microwave.tsx | 62 +++++++++++++++++++++---------- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/App/App.tsx b/src/App/App.tsx index 40e952a..e06bc1a 100644 --- a/src/App/App.tsx +++ b/src/App/App.tsx @@ -399,7 +399,7 @@ export function App() { flex: '0 0 content', overflowY: "auto", overflowX: "visible", - maxWidth: '50vw', + maxWidth: 'min(400px,50vw)', }}>
{ + return fetch(url).then(res => { + return res.arrayBuffer(); + }).then(buf => { + return ctx.decodeAudioData(buf); + }); +} + +function playAudioBufer(buf: AudioBuffer, loop: boolean) { + const src = ctx.createBufferSource(); + src.buffer = buf; + src.connect(ctx.destination); + if (loop) src.loop = true; + src.start(); + return () => src.stop(); +} export function Magnetron({state: {timeDisplay, bell, magnetron}, callbacks}: MicrowaveProps) { const [door, setDoor] = useState("closed"); - const [playBell, setPlayBell] = useState(false); - // a bit hacky: when the bell-state changes to true, we play the bell sound for 610 ms... + const bufRunningPromise = useRef(fetchAudioBuffer(sndRunning)); + const bufBellPromise = useRef(fetchAudioBuffer(sndBell)); + + const refSndBell = useRef(null); + const refSndRunning = useRef(null); + + + // a bit hacky: when the bell-state changes to true, we play the bell sound... useEffect(() => { - let timeout: NodeJS.Timeout; if (bell) { - setPlayBell(true); - timeout = setTimeout(() => { - setPlayBell(false); - }, 610); + bufBellPromise.current.then(buf => { + playAudioBufer(buf, false); + }) } - return () => { if (timeout) clearTimeout(timeout); }; }, [bell]); + useEffect(() => { + if (magnetron === "on") { + const stop = bufRunningPromise.current.then(buf => { + return playAudioBufer(buf, true); + }); + return () => stop.then(stop => stop()); + } + return () => {}; + }, [magnetron]) + preload(imgSmallClosedOff, {as: "image"}); preload(imgSmallClosedOn, {as: "image"}); preload(imgSmallOpenedOff, {as: "image"}); @@ -122,7 +153,7 @@ export function Magnetron({state: {timeDisplay, bell, magnetron}, callbacks}: Mi src: url(${fontDigital}); } `} - + callbacks.incTimePressed()} onMouseUp={() => callbacks.incTimeReleased()} /> - door === "open" ? closeDoor() : openDoor()} + door === "open" ? closeDoor() : openDoor()} /> {timeDisplay} - - {magnetron === "on" && } - - {playBell && } ; }