94 lines
2.0 KiB
TypeScript
94 lines
2.0 KiB
TypeScript
import { createSharedComposable } from '@vueuse/core'
|
|
import { Howl } from 'howler'
|
|
|
|
const CONNECTION_SOUNDS = Object.keys(import.meta.glob('@/../public/sfx/connection/*.ogg')).map(path => path.replace('../public', ''))
|
|
|
|
console.log('CONNECTION_SOUNDS', CONNECTION_SOUNDS)
|
|
|
|
function hashStringToNumber(str: string, cap: number): number {
|
|
let hash = 0
|
|
for (let i = 0; i < str.length; i++) {
|
|
hash = (hash * 31 + str.charCodeAt(i)) | 0
|
|
}
|
|
return Math.abs(hash) % cap
|
|
}
|
|
|
|
const oneShots: Howl[] = []
|
|
|
|
type SfxEvent = 'mic-on' | 'mic-off' | 'stream-on' | 'stream-off' | 'connection'
|
|
|
|
const EVENT_VOLUME: Record<SfxEvent, number> = {
|
|
'mic-on': 0.2,
|
|
'mic-off': 0.2,
|
|
'stream-on': 0.03,
|
|
'stream-off': 0.03,
|
|
'connection': 0.1,
|
|
}
|
|
|
|
// TODO: refactor this shit
|
|
export const useSfx = createSharedComposable(() => {
|
|
const { outputMuted } = useApp()
|
|
|
|
async function play(src: string, volume = 0.2): Promise<void> {
|
|
return new Promise((resolve) => {
|
|
const howl = new Howl({
|
|
src,
|
|
autoplay: true,
|
|
loop: false,
|
|
volume,
|
|
})
|
|
|
|
howl.on('end', () => {
|
|
resolve()
|
|
})
|
|
})
|
|
}
|
|
|
|
async function playOneShot(src: string, volume = 0.2): Promise<void> {
|
|
for (const oneShot of oneShots) {
|
|
oneShot.stop()
|
|
}
|
|
|
|
oneShots.length = 0
|
|
|
|
return new Promise((resolve) => {
|
|
const howl = new Howl({
|
|
src,
|
|
autoplay: true,
|
|
loop: false,
|
|
volume,
|
|
})
|
|
|
|
oneShots.push(howl)
|
|
|
|
howl.on('end', () => {
|
|
resolve()
|
|
})
|
|
})
|
|
}
|
|
|
|
async function playEvent(event: SfxEvent) {
|
|
switch (event) {
|
|
default:
|
|
await playOneShot(`/sfx/${event}.ogg`, EVENT_VOLUME[event])
|
|
break
|
|
}
|
|
}
|
|
|
|
async function playRandomConnectionSound(seed: string) {
|
|
await playEvent('stream-on')
|
|
|
|
if (outputMuted.value)
|
|
return
|
|
|
|
await play(CONNECTION_SOUNDS[hashStringToNumber(seed, CONNECTION_SOUNDS.length)]!, 0.1)
|
|
}
|
|
|
|
return {
|
|
playOneShot,
|
|
play,
|
|
playRandomConnectionSound,
|
|
playEvent,
|
|
}
|
|
})
|