audiocn-svelte
Esc

Start typing to search the docs

useWebAudioMixer

Binds mixer state to a Web Audio graph, with ducking, monitor sends, a limited master and meters.

2 min read · 366 words

$ pnpm dlx shadcn-svelte@latest add https://juddisjudd.github.io/audiocn-svelte/r/use-web-audio-mixer.json

Usage

<script lang="ts">
	import { LevelMeter } from "#lib/components/ui/level-meter/index.js";
	import { useAudioPlayer } from "#lib/hooks/use-audio-player.svelte.js";
	import { useMicrophone } from "#lib/hooks/use-microphone.svelte.js";
	import { useMixer } from "#lib/hooks/use-mixer.svelte.js";
	import { useWebAudioMixer } from "#lib/hooks/use-web-audio-mixer.svelte.js";

	const mixer = useMixer({
		channels: [{ id: "mic" }, { id: "music", monitor: true }],
	});
	const microphone = useMicrophone({ enabled: true });
	const player = useAudioPlayer({ src: "/music.mp3" });

	const graph = useWebAudioMixer(mixer, () => ({
		inputs: { mic: microphone.stream, music: player.element },
		ducking: { trigger: "mic", targets: ["music"] },
	}));
</script>

<LevelMeter source={graph.meters.mic} />
<LevelMeter source={graph.master.meter} />

Call it during component setup. Pass the options as a getter, as above, so the graph follows microphone.stream when it opens. meters, visuals, output, destination and context are getters, so read them from the returned object.

The System Audio Mixer block is built on it.

The graph

Each channel runs through a gain, a ducking stage and a stereo panner. The panner feeds the master bus, and a monitor send feeds the speakers. The master bus runs through an optional peak limiter into a MediaStream for recording.

input → gain → duck → pan ─┬─→ master → limiter → output stream
                           └─→ monitor send → speakers
  • Mute and solo are gain ramps, so they never click. Channels are built silent and fade in, so a muted channel is never heard while it is created.
  • A duck holds for 200 ms after the trigger's last loud frame, then releases. It also releases when the trigger channel goes away mid-duck.
  • monitor decides whether a channel is heard in the speakers. It is off by default so a microphone does not feed back; turn it on for music and sounds.
  • A media element used as an input is taken over by the mixer while mounted, and routed back to the speakers afterwards.

Options

PropTypeDefault
inputs

One input per channel id.

Record<string, MediaStream | HTMLMediaElement | AudioNode | null>—
ducking

{ trigger, targets, thresholdDb = -35, amountDb = -12, attackMs = 50, releaseMs = 400 }.

DuckingOptions | DuckingOptions[]—
limiter

A peak limiter on the master.

booleantrue
analyser

Settings for the meters.

{ fftSize?, bands?, historySize?, smoothing? }—
enabled

Build the graph.

booleantrue

Returns

PropTypeDefault
meters

Post-fader stereo meter per channel.

Record<string, FrameSource<MeterFrame>>—
visuals

Post-fader visual frames per channel.

Record<string, FrameSource<VisualFrame>>—
master

After the limiter.

{ meter, visual }—
output

The mix, for MediaRecorder or WebRTC.

MediaStream | null—
destination

The master bus input, for your own nodes.

AudioNode | null—
context AudioContext | null—

The sources stay the same while the graph is rebuilt, so components never need to resubscribe.

Last updated on October 7, 2026