# usePolyphony

> An instrument whose engine plays one voice, played as chords: as many engines as notes sound at once, made into a destination, each following the state, every note on a voice of its own.

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

```ts
import { usePolyphony } from "@/hooks/use-polyphony";
```

- Files: `hooks/use-polyphony.ts`
- Depends on: `polyphony`, `use-device-engines`; npm: `@audio-ui/engine`
- Used by: `block-electric-piano`, `block-fm-synth`, `block-guitar`, `block-organ`, `block-poly-synth`, `block-sampler`, `block-string-machine`, `block-tape-keys`

| Export | Kind | What it is |
| --- | --- | --- |
| `PolyphonyEngine` | type | What a voice needs of an instrument's engine: it plays one note at a time. |
| `UsePolyphonyOptions` | interface |  |
| `UsePolyphonyReturn` | interface |  |
| `usePolyphony` | function | An instrument whose engine plays one voice, played as chords: `voices` engines made into `destination` (`useDeviceEngines`), each note on a voice of its own (`createPolyphony`). |

## Usage

The engine of an instrument [device](/docs/devices) plays one voice. `usePolyphony` plays chords on it: it makes as many engines as notes sound at once into a destination, keeps every one following the state, and gives each note a voice of its own: the one that holds it, else a free one, else the one held longest, whose note is let go first. The engines are disposed when the destination changes and on unmount.

```tsx
import { createPolySynthEngine } from "@/components/audio-ui/devices/poly-synth/engine";
import { PolySynthPanel } from "@/components/audio-ui/devices/poly-synth/panel";
import { useMasterBus } from "@/hooks/use-master-bus";
import { usePolyphony } from "@/hooks/use-polyphony";

const output = useMasterBus(1);
const { noteOff, noteOn } = usePolyphony({
  create: createPolySynthEngine,
  destination: output,
  state,
});

<PolySynthPanel
  onNoteOff={() => noteOff("panel")}
  onNoteOn={(note) => noteOn(note, "panel")}
  onValueChange={setState}
  value={state}
/>;
```

A note is named by an id its note off gives again, such as `midi-60` for a key of a MIDI keyboard. To schedule notes ahead on the audio clock, or outside React, `createPolyphony(engines)` from `@/lib/polyphony` (installed with the hook) does the same with engines you made and connected: `noteOn(note, id, at?)`, `noteOff(id, at?)` and `release(at?)`. The [arrangement](/docs/components/base/arrangement)'s engine plays a MIDI track's instrument this way.

**Options**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `create` | `(ctx, state) => Engine` |  | Makes the engine of one voice, such as `createPolySynthEngine`. |
| `destination` | `AudioNode \| null` |  | Where every voice plays, such as the master bus. The voices are made on its context once it is there. |
| `state` | `State` |  | The instrument's state: every voice follows it. |
| `voices` | `number` | `8` | How many notes sound at once. One more takes the voice held longest. |

**Returns**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `noteOn` | `(note, id) => void` |  | Starts the note `id` now, on a voice of its own. `note` is the engine's own, such as `{ frequency, velocity }`. |
| `noteOff` | `(id) => void` |  | Lets go of the note `id`. A note no voice holds lets nothing go. |
| `engines` | `readonly Engine[]` |  | The engine of each voice, empty until the destination is there: to give them all the same thing, such as a sample to play. |
