# 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-analyzer` subpath exporting `AudioAnalyzerPlugin` — tap-point analyser exposing `getFrequencyData()`, `getWaveformData()`, async getters for `tempo`, `pitch`, `spectralFeatures`, `energy`, `key`, plus an `onAnalysisUpdate(callback)` subscription and `applyPreset(name)` for `music | speech | percussion | ambient`. Pass-through processing on the audio path. - ADDED: `./microphone` subpath exporting `MicrophoneSimulationPlugin` and `createMicrophonePlugin(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 typed `MicrophoneConfig`. Includes the structured UI control descriptor (`MicrophoneUISection[]`) so editors can render the simulation's parameter surface without hard-coding it. - ADDED: `./glados` subpath exporting `GLaDOSPlugin` — 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: `./game` subpath exporting `GameAudioPlugin` — 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-player` subpath exporting `AudioPlayerPlugin` — source plugin that decodes an audio asset from a URL into a `Float32Array` PCM buffer (universal path) or routes through `HTMLAudioElement.captureStream()` (browser path via `createAudioNode`). Exposes `load(url, { signal? })`, `play()`, `pause()`, `stop()`, `seek(time)`, `setVolume`, `setLoop`, `setPlaybackRate`, `getState()`. - MODIFIED: package `vite.config.ts` and `package.json` to 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 one `Verified by:` line pointing at a real test path. ## Out of scope - Browser-engine integration (`@suaveplan/audio-engine-browser` wiring `createAudioNode` into 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.js` optional analyser bridge from main-branch — deferred behind a `peerDependenciesMeta.optional` declaration 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 `setParameterCurve` surface — 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.md` plus the implementation under `../suaveplan/packages/browser/audio-plugins-fx/src/plugins//`. | 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: `.ts` (implementation), `.types.ts`, `.test.ts`, `.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.