Files
skills/plugins/document-navigator/docs/media/audio-fx/audio-fx-plugin-spessasynth/README.md
admin 9bf56a806b Move docs/ package mirror into document-navigator plugin
Relocate the ~6k-file docs tree from the repo root into
plugins/document-navigator/docs/ so the plugin is self-contained and
portable. docs/superpowers/ (specs and plans) stays at the repo root.

Moved via cp+rm rather than git mv because directory rename() fails with
EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the
identical-content files at commit time.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 01:10:00 +01:00

5.8 KiB
Raw Blame History

@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 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 — Defines the stable SPESSASYNTH.* error-code namespace used by every other module in `@suaveplan/audio-fx-plugin-spess…
    • error-codes — Defines the stable SPESSASYNTH.* error-code namespace used by every other module in `@suaveplan/audio-fx-plugin-spess…
  • loader — Lazy entry point for the SF2/SF3/DLS SoundFont pipeline. The loader is the only place in the package where `spessas…
    • soundfont-loader — Lazy entry point for the SF2/SF3/DLS SoundFont pipeline. The loader is the only place in the package where `spessas…
  • midi-router — Routes MidiMessage events from a MidiPortLike (or a direct handle() call) into the upstream `SpessaSynthProcessor…
    • midi-router — Routes MidiMessage events from a MidiPortLike (or a direct handle() call) into the upstream `SpessaSynthProcessor…
  • parameters — Declares the parameter surface the SpessaSynthPlugin exposes to the host chain: 16 GM channels × 5 controls (volume…
    • parameters — Declares the parameter surface the SpessaSynthPlugin exposes to the host chain: 16 GM channels × 5 controls (volume…
  • plugin — SpessaSynthPlugin is the AudioFxPlugin implementation that wraps the SpessaSynth SF2/SF3 SoundFont engine. It is a…
    • spessasynth-plugin — SpessaSynthPlugin is the AudioFxPlugin implementation that wraps the SpessaSynth SF2/SF3 SoundFont engine. It is a…
  • register — Provides the one-call helper registerSpessaSynthPlugin(registry) that attaches the SpessaSynth plugin factory to a `P…
    • register — Provides the one-call helper registerSpessaSynthPlugin(registry) that attaches the SpessaSynth plugin factory to a `P…
  • telemetry — OpenTelemetry instrument bridge for the SpessaSynth plugin. Exposes three instruments under the meter `@suaveplan/audio…
    • telemetry — OpenTelemetry instrument bridge for the SpessaSynth plugin. Exposes three instruments under the meter `@suaveplan/audio…
  • voice-manager — Owns the polyphony cap and the voice-stealing policy layered on top of the upstream SpessaSynthProcessor. The process…
    • voice-manager — Owns the polyphony cap and the voice-stealing policy layered on top of the upstream SpessaSynthProcessor. The process…

Quickstart

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

// 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

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

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.