first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
# bind-parameter
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`bindParameter` wires a typed `MidiSource` (a controller CC, note-velocity,
or future hardware source) to a parameter on any `AudioFxPlugin` from
`@suaveplan/audio-fx-plugin-base`. It looks the parameter up via the
plugin's O(1) `parameterIndex`, maps the inbound 0–127 byte into the
declared `[min, max]` range honouring the parameter's `scale`
(`linear` / `log` / `exponential`), and dispatches either `setParameter`
or `setParameterCurve` depending on whether a `smoothingMs` was supplied.
The complement `bindPluginPreset` listens for program-change-style CCs and
applies `PresetSnapshot`s by index.
## Features
- Source-aware mapping: linear, logarithmic, exponential parameter scales.
- Optional `smoothingMs` engages `setParameterCurve` so jittery knobs ramp.
- Unknown `paramId` raises `AUDIO_CONTROLLERS.UNKNOWN_PARAMETER`.
- Unbind returns a `UnsubscribeFn` that removes only this binding —
other bindings on the same source keep firing.
- Preset binding for MIDI program-change-style flows.
## Usage: Basic
```ts
const off = bindParameter(eq, "lowShelfGain", { type: "cc", channel: 0, number: 7 }, {
controller,
});
// ...
off();
```
## Usage: Advanced
```ts
const off = bindParameter(
eq,
"lowShelfGain",
{ type: "cc", channel: 0, number: 7 },
{ controller, smoothingMs: 20 }
);
const offPreset = bindPluginPreset(
eq,
{ type: "cc", channel: 0, number: 32 },
presetSnapshots,
{ controller }
);
```
## API Reference
- `bindParameter(plugin, paramId, source, { controller, smoothingMs? })`
→ `UnsubscribeFn`.
- `bindPluginPreset(plugin, source, presets, { controller })` →
`UnsubscribeFn`.
- `MidiSource` — union of `cc` and `note-velocity` shapes.
- `UnsubscribeFn` — `() => void`.
## Implementation Notes
The binding subscribes to the controller's `raw` event so it can observe
even messages that have no `defineMappings` entry. A `(channel, controller)`
filter inside the handler keeps the dispatch O(1). When the parameter
declares `scale: "log"` the mapping does `min * (max/min)^t`, falling back
to `1e-6` if `min === 0` to avoid a division by zero. Preset application
delegates to `plugin.applyPreset`, which performs Zod validation itself —
any failure propagates unchanged.