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,59 @@
# `synthesizer/schemas`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Zod schemas validating the construction-time options, waveform enum, and preset payload of `SynthesizerPlugin`. These run on the public boundary so any malformed object is rejected with `AUDIO_FX.INVALID_OPTIONS` / `AUDIO_FX.INVALID_PRESET` before it can corrupt runtime state.
Separating schemas from the plugin module lets `index.ts` re-export them so callers can introspect the option surface (for forms, RPC validation, or storybook controls) without importing the audio implementation.
## Features
- `SynthWaveformSchema` — `z.enum(["sine", "square", "sawtooth", "triangle"])` reused in both options and preset payloads.
- `SynthesizerPluginOptionsSchema` — validates the eight optional `initial*` fields plus `polyphony` (integer 1..32).
- `SynthesizerPresetDataSchema` — `.strict()` object carrying only the non-numeric `waveform`.
- All numeric fields use `z.number().finite()` so `NaN` and `Infinity` cannot sneak through.
## Usage: Basic Example
```ts
import { SynthesizerPluginOptionsSchema } from "@suaveplan/audio-fx-plugin-synthesizer";
const parsed = SynthesizerPluginOptionsSchema.parse({
initialWaveform: "sawtooth",
});
```
## Usage: Advanced Example
```ts
import {
SynthWaveformSchema,
SynthesizerPluginOptionsSchema,
SynthesizerPresetDataSchema,
} from "@suaveplan/audio-fx-plugin-synthesizer";
// Render a waveform dropdown from the schema.
const waveforms = SynthWaveformSchema.options;
for (const wf of waveforms) ui.addOption(wf);
// Validate a wire preset blob before applying.
function isSynthPreset(blob: unknown): boolean {
return SynthesizerPresetDataSchema.safeParse(blob).success;
}
```
## API Reference
- `SynthWaveformSchema: z.ZodEnum<["sine", "square", "sawtooth", "triangle"]>`
- `SynthesizerPluginOptionsSchema: z.ZodObject<{ initialWaveform?, initialAttackSec?, initialDecaySec?, initialSustain?, initialReleaseSec?, initialCutoffHz?, initialResonance?, initialPortamentoMs?, polyphony? }>`
- `SynthesizerPresetDataSchema: z.ZodObject<{ waveform: SynthWaveform }, "strict">`
## Implementation Notes
The `SynthWaveformSchema` is exported as a named schema (not inlined) so the same value is reused by `SynthesizerPluginOptionsSchema.initialWaveform` and `SynthesizerPresetDataSchema.waveform`. That guarantees both validation paths agree byte-for-byte on the legal waveform set — adding a fifth waveform (e.g., `"pulse"`) is a one-line change in `schemas.ts`.
`polyphony` is bounded at 32 because the voice pool's stealing scan is `O(polyphony)` per attack; 32 voices is comfortably within the per-event budget of a real-time renderer but going much higher would warrant a heap-based stealing structure. The lower bound of 1 makes the plugin a valid monosynth (every triggerAttack steals the previous voice), which is a useful configuration in its own right.