# useSynthVoices

> Polyphonic synth voices on the Web Audio API: start and release notes with an envelope, a velocity and a pitch bend.

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

```ts
import { useSynthVoices } from "@/hooks/use-synth-voices";
```

- Files: `hooks/use-synth-voices.ts`
- Depends on: `envelope-ramp`; npm: `@audio-ui/engine`
- Used by: `block-piano-roll`, `piano-roll-playback-demo`, `spectrum-analyzer-demo`, `use-piano-roll-playback`

| Export | Kind | What it is |
| --- | --- | --- |
| `UseSynthVoicesOptions` | interface |  |
| `UseSynthVoicesReturn` | interface |  |
| `useSynthVoices` | function | A polyphonic pool of oscillator+gain voices, one per held note, each shaped by an Envelope's points: attack/decay plays up to `SUSTAIN_SPLIT_X` and holds there while the note is down, release plays the rest on note-off. |

## Usage

`useSynthVoices` plays notes on a pool of voices, one per held pitch: an oscillator through a gain shaped by an envelope. The attack and the decay play when the note starts and hold at the sustain level; the release plays when it ends.

```tsx
import { useMasterBus } from "@/hooks/use-master-bus";
import { useSynthVoices } from "@/hooks/use-synth-voices";

const output = useMasterBus(0.7);
const voices = useSynthVoices({ destination: output, oscillatorType: "triangle" });

<Piano
  onNoteOff={(pitch) => voices.releaseNote(pitch, envelope)}
  onNoteOn={(pitch) => voices.triggerNote(pitch, envelope)}
/>;
```

`envelope` is the points of an [Envelope](/docs/components/base/envelope), `{ x, y }` from 0 to 1, so the shape a user draws is the shape the note plays: the points before the middle (`x` 0.5) are the attack and the decay, the points after it the release. Give `time` to `triggerNote` and `releaseNote` to schedule a note ahead, as a [transport clock](/docs/guides/clock-and-time) does; leave it out to play now.

**Options**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `destination` | `AudioNode \| null` |  | Where the voices play, such as the master bus. |
| `oscillatorType` | `OscillatorType` | `"sawtooth"` | The waveform: `"sine"`, `"triangle"`, `"sawtooth"` or `"square"`. |
| `attackDecaySeconds` | `number` | `0.4` | How long the first half of the envelope lasts. |
| `releaseSeconds` | `number` | `0.3` | How long the second half lasts. |
| `peakGain` | `number` | `0.25` | A voice's gain at the top of the envelope, at full velocity. |

**Returns**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `triggerNote` | `(pitch, envelope, velocity?, time?) => void` |  | Starts a voice. `velocity` is 0 to 1. No-op if the pitch already sounds. |
| `releaseNote` | `(pitch, envelope, time?) => void` |  | Plays the release and stops the voice. |
| `releaseAll` | `() => void` |  | Stops every voice at once: on stop, on a seek, on unmount. |
| `setPitchBend` | `(semitones) => void` |  | Retunes every voice, as a pitch bend wheel does. 0 is back to pitch. |
