// createSound decodes an encoded clip (Ogg/Vorbis or WAV) once, then every // play() starts a voice with no re-decode - cheap enough for rapid SFX. It is // reactive-owned: the decoded clip is released and its voices stopped when the // owning component unmounts, so there is nothing to clean up by hand. // // The source is a Uint8Array of encoded bytes. Here they come from a // `with { type: "binary" }` import (see binary-import.tsx), so the clip is // baked into the bundle and available synchronously. Bytes loaded at runtime // (flux:fs, fetch) work the same once you have them. // // overlap defaults to true: tapping faster than the clip length stacks voices // instead of restarting. The second sound sets overlap: false - each play() // cuts off the previous voice, the single-voice behavior you want for e.g. a // selection tick. playing() is a signal: true from play() until stop() (it // does not flip back when a clip ends naturally). // // Sounds you can compute need no bytes at all: createPcmSound takes raw // samples (here a 60 ms sine sweep in an Int16Array) and gives the same handle // - generate it, do not ship it. Same reactive ownership as createSound. // // For a long track (music, ambience) do not load bytes at all: pass a file // path to createSoundStream from the same module, which decodes from disk on // demand and stays off the heap. Same play()/stop()/playing() surface, // always single-voice. import { render } from "@solidrt/core" import { createPcmSound, createSound } from "@solidrt/core/audio" import blipBytes from "./blip.wav" with { type: "binary" } const RATE = 44100 // A short sweep from 880 Hz down to 440 Hz with a linear fade-out. function sweep(): Int16Array { let n = Math.round(RATE * 0.06) let out = new Int16Array(n) let phase = 0 for (let i = 0; i < n; i++) { let t = i / n phase += (2 * Math.PI * (880 - 440 * t)) / RATE out[i] = Math.round(Math.sin(phase) * (1 - t) * 0.6 * 32767) } return out } function Button(props: { label: string; onTap: () => void }) { return ( {props.label} ) } function App() { let blip = createSound(blipBytes, { gain: 0.8 }) let tick = createSound(blipBytes, { overlap: false }) let synth = createPcmSound(sweep(), RATE) return (