# web-audio

> Web Audio Lib

```bash
npx shadcn@latest add @audio-ui/web-audio
```

```ts
import { WebAudio, webAudio } from "@/lib/web-audio";
```

- Files: `lib/web-audio.ts`
- Depends on: nothing; npm: nothing
- Used by: `arrangement-engine`, `block-audio-editor`, `block-device-chain`, `block-drum-rack`, `block-drum-synth`, `block-mixer`, `block-piano-roll`, `block-sampler`, `block-synth-panel`, `block-timeline`, `block-waveform-player`, `pad-demo`, `sequencer`, `spectrum-analyzer-demo`, `use-device-loop`, `use-master-bus`, `use-microphone`, `use-noise-through-eq`, `use-piano-roll-playback`, `use-transport-clock`, `use-web-audio`, `web`

| Export | Kind | What it is |
| --- | --- | --- |
| `WebAudio` | class | The page's one AudioContext: the factory every hook and block that starts sound gets it from, so a page never makes two. |
| `webAudio` | const |  |

## Usage

A page has one `AudioContext`, shared by every hook and engine on it, made the first time something asks for it. Ask for it where you need it:

```tsx
import { webAudio } from "@/lib/web-audio";

const ctx = webAudio.getContext(); // null on the server
```

To make it with options of its own, such as how much latency it trades for steadiness, configure it before anything asks for it. They do not change a context already made, so a change takes the next page load:

```tsx
webAudio.configure({ latencyHint: "playback" });
```

Browsers start a context suspended until the user does something on the page. `webAudio.resume()` gives the context and resumes it unless it already runs: call it from the gesture that starts the sound, such as a play button, a pad struck or a MIDI note, without waiting for it, so the note starts on the press.

```tsx
const play = () => {
  webAudio.resume();
  transport.play();
};
```

Where a context comes from is one rule. An engine or a lib takes it as a parameter (`createDelayEngine(ctx, state)`), so it also renders on an `OfflineAudioContext`. A hook given a node (a destination, an analyser) works on that node's context, the graph it plays into. Everything else, a block or a hook that starts sound from nothing, asks `webAudio`, and never makes a context of its own.
