6.5 KiB
OpenSpec Change: enterprise-browser-audio-plugins-fx
- Change ID: enterprise-browser-audio-plugins-fx
- Package:
@suaveplan/audio-plugins-fx - Category: browser
- Target path:
browser/audio/audio-plugins-fx - Status: IN PROGRESS
- Date: 2026-04-24
- Reference spec:
/mnt/s/web/suaveplan/enterprise/audio-plugins-fx.md
Summary
Deliver @suaveplan/audio-plugins-fx on the genesis branch from scratch at enterprise quality. The package ships twelve AudioPlugin subclasses built on @suaveplan/audio-engine, each exposed from its own subpath entry point for surgical tree-shaking: EQ (multi-band parametric with presets), Reverb (IR convolver), Delay, Compressor, Pitch Shifter (AudioWorklet), Synthesizer (oscillators/envelopes/voice pool), Audio Analyzer (FFT/tempo/key/spectral), Microphone (simulation), Mixer (channel strips, sends), GLaDOS voice effect, Game Audio (spatial/proximity/music layers), and Audio Player. Together these provide the core DSP surface for the monorepo's audio UI packages.
Current-state audit (genesis)
The package does not exist on genesis yet — fresh build.
Available workspace deps on genesis
| Package | Role |
|---|---|
@suaveplan/audio-engine (workspace:^) |
AudioPlugin base class, AudioGraph, AudioWorkletManager, PluginRegistry |
@suaveplan/error (workspace:^) |
Typed errors for DSP failures, preset validation |
@suaveplan/types (workspace:^) |
LoggerLike, injectable clock |
@suaveplan/events (workspace:^) |
Typed event maps per plugin |
@suaveplan/schema-registry (workspace:^) |
Register preset Zod schemas |
zod (catalog:forms) |
Schema for every *Preset type |
@opentelemetry/api (catalog:observability) |
Latency histograms, CPU counters per plugin |
standardized-audio-context (catalog:browser) |
Web Audio context shim |
tslib (catalog:build) |
Runtime helpers |
Optional peer: essentia.js — declared in optionalDependencies, loaded via dynamic feature-detected import.
Dev deps: vitest, @vitest/coverage-istanbul (catalog:testing), @suaveplan/testing workspace:^.
Preserved public API surface (from main branch)
Twelve plugin classes with their full config/types/preset surfaces — all preserved verbatim:
EQPlugin+EQBand,EQPluginConfig,EQ_PRESETSReverbPlugin+ReverbType,ReverbPluginConfig,REVERB_DURATIONSDelayPlugin+DelayPluginConfigCompressorPlugin+CompressorPluginConfigPitchShifterPlugin+PitchShifterConfig,PitchShifterPresetSynthesizerPlugin+ oscillator/envelope/voice-pool types,SynthesizerPresetAudioAnalyzerPlugin+ 9 analysis types (FFTData,BeatInfo,KeyInfo,SpectralFeatures, etc.)MicrophoneSimulationPlugin+createMicrophonePlugin+ 7 mic types,MicrophonePresetMixerPlugin+ 5 mixer types,MixerPreset(with complete sends round-trip)GLaDOSPlugin+ 6 GLaDOS types,GLaDOSPresetGameAudioPlugin+ 9 game audio types,GameAudioPresetAudioPlayerPlugin+AudioPlayerConfig
Twelve subpath exports: ./eq, ./reverb, ./delay, ./compressor, ./pitch-shifter, ./synthesizer, ./audio-analyzer, ./microphone, ./mixer, ./glados, ./game, ./audio-player.
New additions for genesis
1. Structured errors via @suaveplan/error
Error codes: DSP_INIT_FAILED, DSP_PROCESSING_FAILED, PRESET_VALIDATION_FAILED, WORKLET_REQUIRED, ESSENTIA_UNAVAILABLE, SIDECHAIN_UNAVAILABLE.
2. Mixer sends round-trip
MixerPlugin.getPreset() / applyPreset() fully serializes and restores send states (the main-branch TODO is resolved).
3. PitchShifter worklet URL helper + fallback
Export resolvePitchShifterWorkletUrl() helper for Vite/Webpack consumers. Add ScriptProcessorNode fallback path for environments without AudioWorklet support.
4. Preset Zod schemas
Zod schemas for every *Preset type registered in @suaveplan/schema-registry. Runtime validation on applyPreset() calls.
5. essentia.js optional dep
Declared in optionalDependencies. Dynamic import with try/catch fallback; removes @ts-expect-error at call sites. AudioAnalyzerPlugin works without essentia.js (no beat/key detection).
6. OTel latency histograms
Per-plugin histogram audio.plugin_processing_ms{plugin}, counter audio.plugin_cpu_usage{plugin}.
7. Per-subpath bundle-size snapshots
Twelve snapshot tests asserting independent tree-shake (importing ./eq does not pull in ./synthesizer).
8. Sidechain support + mid/side
CompressorPlugin supports a first-class sidechain input. EQPlugin and CompressorPlugin expose mid/side processing mode.
9. Preset marketplace entry points
@suaveplan/audio-plugins-fx/presets/reverb/cathedrals (and similar) for optional preset packs shipped as separate lazy entry points.
File layout
Each plugin follows the five-file co-located pattern. Large plugins are split into dsp.ts, state.ts, preset.ts, params.ts, plugin.ts sub-modules each ≤ 300 lines. Tests are .test.ts (not .spec.ts).
browser/audio/audio-plugins-fx/
package.json
tsconfig.json
vitest.config.ts
src/
index.ts
error-codes.ts
plugins/
eq/ (eq-plugin, eq-presets, eq-params, eq-dsp)
reverb/ (reverb-plugin, reverb-dsp, reverb-ir, reverb-presets)
delay/ (delay-plugin, delay-dsp)
compressor/ (compressor-plugin, compressor-dsp, compressor-sidechain)
pitch-shifter/ (pitch-shifter-plugin, pitch-shifter-dsp, pitch-shifter-worklet-url, worklet-fallback)
synthesizer/ (synthesizer-plugin, oscillator, envelope, voice-pool, synth-presets)
audio-analyzer/(audio-analyzer-plugin, fft, beat-detector, key-detector, essentia-bridge)
microphone/ (microphone-plugin, mic-simulation, mic-presets)
mixer/ (mixer-plugin, channel-strip, mixer-sends, mixer-presets)
glados/ (glados-plugin, glados-dsp, glados-presets)
game/ (game-audio-plugin, spatial-audio, proximity-voice, music-layers, game-presets)
audio-player/ (audio-player-plugin, audio-player-controls)
worklets/
pitch-shifter.ts (AudioWorklet processor)
presets/
reverb/
cathedrals.ts
tests/
integration.test.ts
bundle-size/
eq.size.test.ts
(... one per subpath)
Impact
Downstream: @suaveplan/react-audio, @suaveplan/react-audio-player, @suaveplan/r3f-audio, game packages.
Prerequisites: @suaveplan/audio-engine published to Verdaccio.