Files
skills/docs/media/audio-fx/audio-fx-plugin-synthesizer/src/schemas/schemas.md
2026-05-29 08:20:56 +01:00

2.9 KiB

synthesizer/schemas

(no submodules)

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

import { SynthesizerPluginOptionsSchema } from "@suaveplan/audio-fx-plugin-synthesizer";

const parsed = SynthesizerPluginOptionsSchema.parse({
    initialWaveform: "sawtooth",
});

Usage: Advanced Example

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.