# @suaveplan/audio-fx-plugin-spessasynth - SF2/SF3 SoundFont synthesizer plugin for the @suaveplan/audio-fx-plugin-* family. SF2/SF3 SoundFont synthesizer plugin for the `@suaveplan/audio-fx-plugin-*` family. Wraps the MIT-licensed [SpessaSynth](https://github.com/spessasus/SpessaSynth) engine as a standard `AudioFxPlugin`, so it composes inside any `PluginChain`, accepts MIDI from a `MidiPortLike` consumer, and exposes its 16-channel parameter surface through the same automation / snapshot / preset machinery every other plugin uses. `spessasynth_lib` is declared as an `optionalDependencies` entry and pulled in only via lazy `import()` inside the loader, so consumers who never call `init()` pay zero bundle cost. ## Documentation tree - [error-codes](./src/error-codes/error-codes.md) — Defines the stable `SPESSASYNTH.*` error-code namespace used by every other module in `@suaveplan/audio-fx-plugin-spess… - [error-codes](./src/error-codes/error-codes.md) — Defines the stable `SPESSASYNTH.*` error-code namespace used by every other module in `@suaveplan/audio-fx-plugin-spess… - [loader](./src/loader/soundfont-loader.md) — Lazy entry point for the SF2/SF3/DLS SoundFont pipeline. The loader is the **only** place in the package where `spessas… - [soundfont-loader](./src/loader/soundfont-loader.md) — Lazy entry point for the SF2/SF3/DLS SoundFont pipeline. The loader is the **only** place in the package where `spessas… - [midi-router](./src/midi-router/midi-router.md) — Routes `MidiMessage` events from a `MidiPortLike` (or a direct `handle()` call) into the upstream `SpessaSynthProcessor… - [midi-router](./src/midi-router/midi-router.md) — Routes `MidiMessage` events from a `MidiPortLike` (or a direct `handle()` call) into the upstream `SpessaSynthProcessor… - [parameters](./src/parameters/parameters.md) — Declares the parameter surface the `SpessaSynthPlugin` exposes to the host chain: 16 GM channels × 5 controls (`volume`… - [parameters](./src/parameters/parameters.md) — Declares the parameter surface the `SpessaSynthPlugin` exposes to the host chain: 16 GM channels × 5 controls (`volume`… - [plugin](./src/plugin/spessasynth-plugin.md) — `SpessaSynthPlugin` is the `AudioFxPlugin` implementation that wraps the SpessaSynth SF2/SF3 SoundFont engine. It is a… - [spessasynth-plugin](./src/plugin/spessasynth-plugin.md) — `SpessaSynthPlugin` is the `AudioFxPlugin` implementation that wraps the SpessaSynth SF2/SF3 SoundFont engine. It is a… - [register](./src/register/register.md) — Provides the one-call helper `registerSpessaSynthPlugin(registry)` that attaches the SpessaSynth plugin factory to a `P… - [register](./src/register/register.md) — Provides the one-call helper `registerSpessaSynthPlugin(registry)` that attaches the SpessaSynth plugin factory to a `P… - [telemetry](./src/telemetry/telemetry.md) — OpenTelemetry instrument bridge for the SpessaSynth plugin. Exposes three instruments under the meter `@suaveplan/audio… - [telemetry](./src/telemetry/telemetry.md) — OpenTelemetry instrument bridge for the SpessaSynth plugin. Exposes three instruments under the meter `@suaveplan/audio… - [voice-manager](./src/voice-manager/voice-manager.md) — Owns the polyphony cap and the voice-stealing policy layered on top of the upstream `SpessaSynthProcessor`. The process… - [voice-manager](./src/voice-manager/voice-manager.md) — Owns the polyphony cap and the voice-stealing policy layered on top of the upstream `SpessaSynthProcessor`. The process… ## Quickstart ```ts import { SpessaSynthPlugin } from "@suaveplan/audio-fx-plugin-spessasynth"; const plugin = new SpessaSynthPlugin(); await plugin.init({ soundFontUrl: "/assets/gm.sf2", sampleRate: 48_000, }); await plugin.setup( { sampleRate: 48_000, channels: 2, blockSize: 128 }, chainContext ); plugin.sendMidi({ type: "noteOn", channel: 0, note: 60, velocity: 100 }); const out: Float32Array[] = [ new Float32Array(128), new Float32Array(128), ]; plugin.process([], out, { blockOffsetSamples: 0, sampleRate: 48_000, channels: 2, opts: {}, }); ``` ## SF2 loading ```ts // From a URL (browser): await plugin.init({ soundFontUrl: "/assets/gm.sf2" }); // From an in-memory blob (offline render / tests): await plugin.init({ soundFontBytes: sf2Bytes }); // With an AbortController: await plugin.init({ soundFontUrl, signal: ac.signal }); ``` ## Control-surface integration ```ts import { SpessaSynthPlugin, channelParameterId, MASTER_GAIN_ID, } from "@suaveplan/audio-fx-plugin-spessasynth"; // A control-surface knob driving channel-0 volume in real time: controlSurface.onKnobMove((value) => { plugin.setParameter(channelParameterId(0, "volume"), value); }); // Automate the master gain over half a second: plugin.setParameterCurve(MASTER_GAIN_ID, { type: "linear", value: 0, duration: 0.5, }); ``` ## Registry ```ts import { PluginRegistry } from "@suaveplan/audio-fx-plugin-base/registry"; import { registerSpessaSynthPlugin } from "@suaveplan/audio-fx-plugin-spessasynth/register"; const registry = new PluginRegistry(); registerSpessaSynthPlugin(registry); // Now `chain.restore(snapshot, registry)` can rehydrate any snapshot // containing a SpessaSynth slot. ``` ## Modules - `error-codes` — `SPESSASYNTH.*` codes via `defineCodes`. - `loader` — lazy `import("spessasynth_lib")`, SF2/SF3/DLS magic sniff, parse. - `midi-router` — channel-voice + program-change + NRPN/RPN reassembly. - `parameters` — 16-channel × 5-control + master gain (81 parameters). - `voice-manager` — polyphony cap + voice-stealing. - `plugin` — `SpessaSynthPlugin` (the `AudioFxPlugin` implementation). - `telemetry` — OTel counter + histogram + observable gauge. - `register` — registry helper for snapshot-restore. ## License MIT.