useGainNode
A gain node on the shared AudioContext, wired from an input to a destination, with click-free level changes.
The blocks use this hook for every level control and bus: the microphone gain in Mic Setup, the soundboard's master bus, and the output of useSound.
$ pnpm dlx shadcn-svelte@latest add https://juddisjudd.github.io/audiocn-svelte/r/use-gain-node.json$ npx shadcn-svelte@latest add https://juddisjudd.github.io/audiocn-svelte/r/use-gain-node.json$ yarn dlx shadcn-svelte@latest add https://juddisjudd.github.io/audiocn-svelte/r/use-gain-node.json$ bunx --bun shadcn-svelte@latest add https://juddisjudd.github.io/audiocn-svelte/r/use-gain-node.jsonUsage
<script lang="ts">
import { useGainNode } from "#lib/hooks/use-gain-node.svelte.js";
import { useMicrophone } from "#lib/hooks/use-microphone.svelte.js";
import { dbToGain } from "#lib/audio/decibels.js";
let { gainDb }: { gainDb: number } = $props();
const microphone = useMicrophone({ enabled: true });
// The microphone, through a gain stage, to the speakers.
useGainNode(() => ({ gain: dbToGain(gainDb), input: microphone.stream }));
</script>Call it during component setup. Pass the options as a getter, as above, so the node follows gain, input and destination as they change.
Routing
inputtakes aMediaStream, which the hook wraps in a source node, or anyAudioNode. Leave it out to feed the node yourself.destinationis where the node plays. Leave it out for the speakers, passnullto route it yourself, or pass a node such as a mixer input or aMediaStreamAudioDestinationNode.- The hook returns the node, so you can connect more to it, or pass it to
useAudioAnalyserto meter the level after gain. It returnsnullduring server rendering and in browsers without Web Audio. The node stays the same for the life of the component.
Levels
gain is linear: use dbToGain from #lib/audio/decibels.js for decibels. Changes ramp with a short time constant (timeConstant, default 10 ms), so they never click. A new node starts at its gain instead of ramping up from unity, so a muted node is never heard as it starts.
Each connection lives in an effect and is undone on cleanup, so unmounting the component disconnects the node.
| Prop | Type | Default |
|---|---|---|
input What feeds the node. | MediaStream | AudioNode | null | — |
gain Linear gain. | number | 1 |
destination Where the node plays; null routes nowhere. | AudioNode | null | the speakers |
timeConstant Ramp time constant, in seconds. | number | 0.01 |