Recipes

Copy-paste audio recipes.

Common webaudio-kit patterns for tones, sweeps, master volume, analyser UI, test mode, and browser autoplay behavior.

browser autoplay behavior
Patterns

Start from the smallest useful snippet.

Keep playback inside user actions, keep gains conservative, and avoid medical claims.

Enable Audio Button

Use this when alert cues or monitoring sounds need an explicit first-run user gesture and visible browser autoplay status for idle, suspended, running, and failed unlock states.

Enable Audio Button
import { AudioProvider, useAudioUnlock } from "@webaudio-kit/react";

function EnableAudioButton() {
  const audio = useAudioUnlock();

  return (
    <div>
      <button
        disabled={audio.isUnlocking || audio.isUnlocked}
        onClick={() => void audio.unlock().catch(() => undefined)}
        type="button"
      >
        {audio.isUnlocked ? "Audio enabled" : "Enable Audio"}
      </button>
      <p>Status: {audio.status}</p>
      {audio.error ? <p>unlock failed</p> : null}
    </div>
  );
}

export function App() {
  return (
    <AudioProvider>
      <EnableAudioButton />
    </AudioProvider>
  );
}
Live recipe demoEnable audio
idleidle

Calls unlock from a user action and keeps browser autoplay status visible before alert cues run.

idlenot readyno error

Tone Button

Use this when a UI needs one audible confirmation tone.

Tone Button
import { AudioProvider, useTone } from "@webaudio-kit/react";

function ToneButton() {
  const tone = useTone({ frequency: 440, gain: 0.14, type: "sine" });

  return (
    <button type="button" onClick={() => void tone.play({ durationMs: 600 })}>
      {tone.isPlaying ? "Restart tone" : "Play tone"}
    </button>
  );
}

export function App() {
  return (
    <AudioProvider>
      <ToneButton />
    </AudioProvider>
  );
}
Live recipe demo440 Hz confirmation
idleidle

Short confirmation tone using the same gain from the snippet.

Frequency Sweep Control

Use a bounded sweep when you need to prove scheduling and frequency ramping.

Frequency Sweep Control
import { AudioProvider, useFrequencySweep } from "@webaudio-kit/react";

function SweepControl() {
  const sweep = useFrequencySweep({
    from: 250,
    to: 8000,
    durationMs: 2400,
    gain: 0.1,
  });

  return <button onClick={() => void sweep.play()}>Run sweep</button>;
}
Live recipe demo250 Hz to 8000 Hz
idleidle

Runs the bounded sweep from the recipe through the provider graph.

250 Hz8000 Hz2400 ms

Monitoring Alert Cues

Map incident severity to conservative cue profiles, then fire playback only when severity changes.

Monitoring Alert Cues
import {
  AudioProvider,
  useAudioContext,
  useFrequencySweep,
  useTone,
  useVolume,
} from "@webaudio-kit/react";
import { useEffect, useRef, useState } from "react";

const severityProfiles = {
  healthy: null,
  warning: {
    kind: "tone",
    options: {
      frequency: 760,
      durationMs: 130,
      gain: 0.09,
      type: "triangle",
      pattern: { repeat: 2, gapMs: 100 },
    },
  },
  critical: {
    kind: "sweep",
    options: {
      from: 520,
      to: 1800,
      durationMs: 620,
      gain: 0.1,
      type: "sawtooth",
      pattern: { repeat: 2, gapMs: 140 },
    },
  },
};

function MonitoringAlertCues({ severity }) {
  const audio = useAudioContext();
  const tone = useTone();
  const sweep = useFrequencySweep();
  const volume = useVolume();
  const previousSeverityRef = useRef("healthy");
  const [muted, setMuted] = useState(false);

  useEffect(() => {
    const previousSeverity = previousSeverityRef.current;
    previousSeverityRef.current = severity;

    if (muted || previousSeverity === severity) return;

    const profile = severityProfiles[severity];
    if (!profile) return audio.stopAll();
    if (profile.kind === "tone") void tone.play(profile.options);
    else void sweep.play(profile.options);
  }, [audio, muted, severity, sweep, tone]);

  async function setMutedOutput(nextMuted) {
    setMuted(nextMuted);
    await volume.setGain(nextMuted ? 0 : 0.2);
  }

  return (
    <>
      <button onClick={() => audio.stopAll()}>Acknowledge</button>
      <button onClick={() => void setMutedOutput(!muted)}>
        {muted ? "Unmute" : "Mute"}
      </button>
    </>
  );
}
Live recipe demoSeverity cue profile
idleidle

Runs warning or critical severity profiles with repeat patterns and conservative gain. Use acknowledge to cancel scheduled cues.

warningcriticalstopAll()

Controlled Volume Slider

Use provider gain as the controlled value, safe bounds for the slider, and storageKey when a browser preference should persist.

Controlled Volume Slider
import { useVolumeControl } from "@webaudio-kit/react";

function ControlledVolumeSlider() {
  const volume = useVolumeControl({
    label: "Master volume",
    maxGain: 0.5,
    storageKey: "app-master-gain",
  });

  return (
    <>
      <input {...volume.inputProps} />
      <span>{volume.gain.toFixed(2)}</span>
      <button onClick={() => void volume.resetGain()}>Reset volume</button>
    </>
  );
}
Live recipe demoShared master gain
idleidle

Stop All Cues

Use provider cancellation when an acknowledge button must stop active and scheduled playback, not just mute output.

Stop All Cues
import { useAudioContext, useTone, useVolume } from "@webaudio-kit/react";

function AlertControls() {
  const audio = useAudioContext();
  const volume = useVolume();
  const alertTone = useTone();

  return (
    <>
      <button
        type="button"
        onClick={() =>
          void alertTone.play({
            frequency: 880,
            durationMs: 120,
            gain: 0.12,
            pattern: { repeat: 3, gapMs: 90 },
          })
        }
      >
        Start alert
      </button>
      <button type="button" onClick={() => audio.stopAll()}>
        Stop all cues
      </button>
      <button type="button" onClick={() => void volume.setGain(0)}>
        Mute output
      </button>
    </>
  );
}
Live recipe demoProvider stop all
idleidle

Start a cue, then stop every active or scheduled provider-owned playback handle.

Waveform And Spectrum Panel

Render both analyser views so developers can see that the provider graph is live.

Waveform And Spectrum Panel
import { SpectrumCanvas, WaveformCanvas } from "@webaudio-kit/react";

function SignalPanel() {
  return (
    <>
      <WaveformCanvas aria-label="Waveform analyser" />
      <SpectrumCanvas aria-label="Spectrum analyser" />
    </>
  );
}
Live recipe demoWaveform and spectrum
idleidle

Ping the analyser and watch both reusable canvas components react.

Audio Test Mode

Run short low-gain steps for tone output, pan, sweep scheduling, noise buffers, and analyser routing.

Audio Test Mode
import { useAudioTestMode } from "@webaudio-kit/react";

function AudioSelfCheck() {
  const testMode = useAudioTestMode();

  return (
    <>
      <p>{testMode.previewStep?.label ?? "Idle"}</p>
      <p>Preview index: {testMode.previewStepIndex}</p>
      <button onClick={() => void testMode.run()}>Run test mode</button>
      <button onClick={testMode.stop}>Stop</button>
    </>
  );
}
Live recipe demoLow-gain sequence
idleidle
  1. Center tone320ms
  2. Left pan320ms
  3. Right pan320ms
  4. Short sweep700ms
  5. Pink noise450ms

Safe Autoplay Pattern

Create and resume audio from a click, tap, or keyboard handler. Browser autoplay behavior is the main rule.

Safe Autoplay Pattern
import { AudioProvider, useTone } from "@webaudio-kit/react";

function StartAudioButton() {
  const tone = useTone({ frequency: 660, gain: 0.08, durationMs: 300 });

  return (
    <button type="button" onClick={() => void tone.play()}>
      Start audio from user action
    </button>
  );
}
Live recipe demoAutoplay-safe start
idleidle

This button is the user action that lets the provider create and resume browser audio.

Scope boundary

Not medical software. These recipes are browser audio prototypes and are not diagnosis, screening, or calibrated audiology workflows.