export type Sounds = Record export enum Sound { Bass, Snare, HitHatClosed, } export function all(): Array { return [Sound.HitHatClosed, Sound.Snare, Sound.Bass] } const audioContext = new AudioContext() let lazy: undefined | Sounds = undefined export async function load(): Promise { if (lazy !== undefined) { return lazy } else { let [bass, snare, hitHatClosed] = await Promise.all([ fetchSound('/sounds/bass.opus'), fetchSound('/sounds/snare.opus'), fetchSound('/sounds/hit-hat-closed.opus') ]) lazy = { [Sound.Bass]: bass, [Sound.Snare]: snare, [Sound.HitHatClosed]: hitHatClosed } return lazy } } async function fetchSound(name: string): Promise { return await fetch(name) .then(res => res.arrayBuffer()) .then(ArrayBuffer => audioContext.decodeAudioData(ArrayBuffer)) } export function play(sounds: Sounds, sound: Sound): void { const source = audioContext.createBufferSource() source.buffer = sounds[sound] source.connect(audioContext.destination) source.start() }