# useBake

> Changes the samples of a sound as edited: renders what a track's clips play, hands the channels to an operation and puts the result back as one step of undo, with Reverse, Repeat, Add silence, Normalize, Pan, Filter, Stretch, Pitch and Speed over it.

```bash
npx shadcn@latest add @audio-ui/use-bake
```

```ts
import { renderEdited, useBake } from "@/hooks/use-bake";
```

- Files: `hooks/use-bake.ts`
- Depends on: `arrangement`, `arrangement-engine`, `clip-player`; npm: `@audio-ui/engine`
- Used by: `block-audio-editor`, `use-sound-report`

| Export | Kind | What it is |
| --- | --- | --- |
| `BakedSound` | interface | A sound as plain samples: what an operation reads and writes. |
| `renderEdited` | function | What the track's clips play over the whole arrangement, as plain channels: the cuts, fades and gains made, not the track's devices. |
| `useBake` | function | Changes the samples of the sound as edited. |

## Usage

An edit of the arrangement (a cut, a fade, a gain) leaves the recording as it was. An operation on samples (a reverse, a filter, a resample) needs the sound as it plays. `useBake` renders what the track's clips play over the whole arrangement, gives its channels to your operation, and hands the result to `onBaked`, which puts it on the track as a sound of its own: one step of undo.

```tsx
import { useBake } from "@/hooks/use-bake";

const { bake, filter, normalize, pad, pan, repeat, reverse, shift, speed, stretch } = useBake({
  doc, // the arrangement's document
  onBaked, // (sound, label) => void: puts the sound on the track as a step of the history
  recordings,
  sampleRate: 48_000, // the rate the edited sound is rendered at
  setStatus, // what the editor says while it works
  stop, // stops what plays
  track: "track-1",
});

<MenuItem onClick={reverse}>Reverse</MenuItem>;
<MenuItem onClick={() => repeat(4)}>Repeat 4 times</MenuItem>;
<MenuItem onClick={() => pad(1, "end")}>Add 1 s of silence</MenuItem>;
<MenuItem onClick={() => normalize({ lufs: -16 })}>Normalize to -16 LUFS</MenuItem>;
<MenuItem onClick={() => pan(-0.5)}>Half left</MenuItem>;
<MenuItem onClick={() => filter("highpass", 80)}>Thin the lows</MenuItem>;
<MenuItem onClick={() => stretch(1.5, "transient")}>1.5 times as long, pitch kept</MenuItem>;
<MenuItem onClick={() => shift(-2, "formant")}>Down 2 semitones, voice kept</MenuItem>;
<MenuItem onClick={() => speed(2)}>Twice as fast, pitch with it</MenuItem>;

// Any operation: channels in, channels out.
bake("Resample", ({ channels, sampleRate }) => ({
  channels: resampleChannels(channels, sampleRate, 44_100),
  sampleRate: 44_100,
}));
```

`reverse`, `repeat(times)`, `pad(seconds, where)`, `normalize(target)`, `pan(value)`, `filter(type, frequency)`, `stretch(factor, method)`, `shift(semitones, method)` and `speed(value)` are the operations of `reverseChannels`, `repeatChannels`, `padChannels`, `normalizeChannels`, `panChannels`, `filterChannels`, `stretchChannels`, `shiftChannels` and `speedChannels` of [`@audio-ui/engine/files`](/docs/engine/files). A browser that cannot render offline says so through `setStatus`.
