8.3 KiB
Extend audio-plugins-fx with the enterprise extras
Package: @suaveplan/audio-plugins-fx
Status: PROPOSED
Type: feature
Why
The in-flight enterprise-audio-plugins-fx change shipped 19 plugins matching the genesis-original spec: EQ, Filter, Compressor, Limiter, Gate, Reverb, Delay, Chorus, Phaser, Flanger, Tremolo, AutoFilter, Distortion, Sampler, Synthesizer, PitchShifter, Spatial, Mixer, StereoWidener. The enterprise spec at ../suaveplan/enterprise/audio-plugins-fx.md lists five further plugins that the main-branch package ships but genesis does not yet cover: AudioAnalyzer, MicrophoneSimulationPlugin, GLaDOSPlugin, GameAudioPlugin, and AudioPlayerPlugin. These plugins drive the React audio surface (visualisers, voice-effect demos), the React audio player, and the game-audio composite used by the game packages. Without them in genesis, downstream packages cannot be rebuilt at parity with main.
This change adds the five plugins on their own subpaths so consumers can tree-shake to exactly the surface they need, keeps every plugin universal-tier under the same AudioFxPlugin contract that the existing 19 already satisfy, and routes any browser-only fast paths through the optional createAudioNode / getWorkletProcessor hooks declared in the base contract.
What changes
- ADDED:
./audio-analyzersubpath exportingAudioAnalyzerPlugin— tap-point analyser exposinggetFrequencyData(),getWaveformData(), async getters fortempo,pitch,spectralFeatures,energy,key, plus anonAnalysisUpdate(callback)subscription andapplyPreset(name)formusic | speech | percussion | ambient. Pass-through processing on the audio path. - ADDED:
./microphonesubpath exportingMicrophoneSimulationPluginandcreateMicrophonePlugin(options)factory — source plugin (io.inputs[0].count === 0,outputs.count === 1) that synthesises a microphone-coloured signal from white-noise + oscillator + frequency-resonance-distortion + dynamics + wow-and-flutter stages, all configurable via a typedMicrophoneConfig. Includes the structured UI control descriptor (MicrophoneUISection[]) so editors can render the simulation's parameter surface without hard-coding it. - ADDED:
./gladossubpath exportingGLaDOSPlugin— voice-effect chain combining pitch shift, formant shift, robotic intensity, distortion, reverb, and low-pass filtering with named presets (glados-mainline | glados-test-chamber | glados-cake-deception | wheatley | cave-johnson | robotic-generic). Insert plugin (io.inputs[0].count === outputs[0].count === "preserve"). - ADDED:
./gamesubpath exportingGameAudioPlugin— composite plugin for game audio: spatial sources (createSpatialSource, position/orientation/Doppler/occlusion), music-layer mixing (addMusicLayer,crossfadeMusicLayers), and proximity voice chat (enableProximityVoiceChat,addVoiceChatParticipant, distance-based attenuation, bandwidth optimisation tier). Effects bus with blendable voice effects. - ADDED:
./audio-playersubpath exportingAudioPlayerPlugin— source plugin that decodes an audio asset from a URL into aFloat32ArrayPCM buffer (universal path) or routes throughHTMLAudioElement.captureStream()(browser path viacreateAudioNode). Exposesload(url, { signal? }),play(),pause(),stop(),seek(time),setVolume,setLoop,setPlaybackRate,getState(). - MODIFIED: package
vite.config.tsandpackage.jsonto declare the five new subpath exports. - MODIFIED:
openspec/specs/audio-plugins-fx/spec.md— folded delta adds five new Requirement blocks, each with at least oneVerified by:line pointing at a real test path.
Out of scope
- Browser-engine integration (
@suaveplan/audio-engine-browserwiringcreateAudioNodeinto a Web Audio graph) — separate change in that package. - React bindings (
@suaveplan/react-audio-analyzer-viz,@suaveplan/react-audio-player) — handled in their own packages once these plugins land. - The
essentia.jsoptional analyser bridge from main-branch — deferred behind apeerDependenciesMeta.optionaldeclaration in a follow-up; the universal analyser uses the built-in browser-equivalent FFT path only. - Worklet hot-reload, oversampling on Compressor/Distortion/PitchShifter, mid/side processing on EQ/Compressor/Reverb, the convolution IR library, parameter-automation lanes beyond the existing universal
setParameterCurvesurface — all listed in the enterprise plan's §4 enhancements, all deferred to dedicated change proposals so this one stays scoped to "add the missing plugins". - The package split into per-plugin packages (
split-audio-plugins-fx) — a separate in-flight change; lands after this one once the surface is complete.
Source mapping
REQUIRED. This change derives from
../suaveplan/enterprise/audio-plugins-fx.mdplus the implementation under../suaveplan/packages/browser/audio-plugins-fx/src/plugins/<name>/.
| Requirement | Source lines | Notes |
|---|---|---|
| Audio analyzer plugin | enterprise/audio-plugins-fx.md §1 line 11; packages/browser/audio-plugins-fx/src/plugins/audio-analyzer/audio-analyzer.ts:28-870 |
Reworded for universal tier; FFT path stays, essentia bridge deferred |
| Microphone simulation plugin | enterprise/audio-plugins-fx.md §1 line 11; packages/browser/audio-plugins-fx/src/plugins/microphone/microphone.ts:10-490 |
UI section descriptor preserved verbatim |
| GLaDOS voice-effect plugin | enterprise/audio-plugins-fx.md §1 line 11; packages/browser/audio-plugins-fx/src/plugins/glados/glados.ts:21-700 |
Preset set expanded per §4.7 (Wheatley, Cave Johnson, robotic-generic) |
| Game audio plugin | enterprise/audio-plugins-fx.md §1 line 11; packages/browser/audio-plugins-fx/src/plugins/game/game-audio.ts:22-820 |
Composite of spatial + music-layer + proximity-voice surfaces |
| Audio player plugin | enterprise/audio-plugins-fx.md §1 line 11; packages/browser/audio-plugins-fx/src/plugins/audio-player/audio-player.ts:18-413 |
Universal decode path replaces HTMLAudioElement-only impl from main |
Requirements with no source line
| Requirement | Justification |
|---|---|
AbortSignal on every async load entry point |
Aligns with the genesis-side loadImpulseResponse / loadSample precedent — no main-branch equivalent because main's load(url) ignores abort |
Universal-tier purity (no browser globals on the BlockProcessor path) |
New constraint introduced by the genesis package design; the main-branch plugins assume an AudioContext and are not portable |
| Zod boundary validation on every plugin's options + preset shape | Already required by the existing enterprise-audio-plugins-fx change for the first 19 plugins; this extension keeps the policy consistent |
Verification approach
Each new plugin lands with the same five-file co-location pattern the existing 19 already use: <name>.ts (implementation), <name>.types.ts, <name>.test.ts, <name>.md, plus schemas/{schemas.ts, schemas.md, index.ts} and index.ts. Tests run under vitest with no mocks — the audio path uses real Float32Array arithmetic, the URL loaders use data: URLs the same way ReverbPlugin.loadImpulseResponse already does, and any browser-only paths are exercised via happy-dom polyfills.
src/plugins/audio-analyzer/audio-analyzer.test.ts— covers analyzer surface (FFT, presets, callback subscription).src/plugins/microphone/microphone.test.ts— covers source-plugin behaviour (output non-silent, options validated, UI section descriptor preserved).src/plugins/glados/glados.test.ts— covers voice-chain wiring, parameter setters, preset application.src/plugins/game/game-audio.test.ts— covers spatial source lifecycle, music-layer crossfade, proximity-voice attenuation.src/plugins/audio-player/audio-player.test.ts— covers load / play / stop / seek / loop / playbackRate, AbortSignal handling.bunx turbo test:coverage --filter=@suaveplan/audio-plugins-fx— must hit 100/100/100/100 on every new module the same way the existing 19 do.
Migration impact
None — additive only. The five new subpath exports do not modify or remove any existing export. Consumers of the existing 19 plugins continue to work without changes. The split-audio-plugins-fx change (in-flight) will relocate every plugin including these five into its own package, but the API surface stays stable across that move.