# Tasks: enterprise-browser-audio-plugins-fx **Change ID**: enterprise-browser-audio-plugins-fx **Package**: `@suaveplan/audio-plugins-fx` **Target path**: `browser/audio/audio-plugins-fx` **Prerequisite packages on Verdaccio**: `@suaveplan/audio-engine`, `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events` --- ## 1. Scaffold - [ ] Create `browser/audio/audio-plugins-fx/` directory tree per layout in `proposal.md`. - [ ] Write `package.json` at version `0.1.0`: - `"sideEffects": false` - Twelve subpath exports: `./eq`, `./reverb`, `./delay`, `./compressor`, `./pitch-shifter`, `./synthesizer`, `./audio-analyzer`, `./microphone`, `./mixer`, `./glados`, `./game`, `./audio-player` - `dependencies`: `@suaveplan/audio-engine workspace:^`, `@suaveplan/error workspace:^`, `@suaveplan/types workspace:^`, `@suaveplan/events workspace:^`, `standardized-audio-context catalog:browser`, `zod catalog:forms`, `@opentelemetry/api catalog:observability`, `tslib catalog:build` - `optionalDependencies`: `essentia.js` (version from Bun catalog if available, else explicit) - `devDependencies`: `vitest catalog:testing`, `@vitest/coverage-istanbul catalog:testing`, `@suaveplan/testing workspace:^` - [ ] Write `tsconfig.json` extending `@suaveplan/typescript-config/library-browser.json`. - [ ] Write `vitest.config.ts` with `pool: 'forks'`, `fileParallelism: false`. --- ## 2. Error codes (`src/error-codes.ts`) - [ ] Define `AudioFxErrorCode`: `DSP_INIT_FAILED`, `DSP_PROCESSING_FAILED`, `PRESET_VALIDATION_FAILED`, `WORKLET_REQUIRED`, `ESSENTIA_UNAVAILABLE`, `SIDECHAIN_UNAVAILABLE`. - [ ] Export `registerAudioFxErrorCodes()` and call eagerly. --- ## 3. EQ plugin (`src/plugins/eq/`) - [ ] Implement `EQPlugin` with multi-band parametric EQ, biquad filter nodes, `EQ_PRESETS`. - [ ] Split into `eq-dsp.ts` (filter nodes, freq/gain/Q), `eq-params.ts` (parameter definitions), `eq-presets.ts`, `eq-plugin.ts`. - [ ] Add `EQBand` and `EQPluginConfig` Zod schemas. - [ ] Write tests for each sub-module (≤500 lines each), `eq-plugin.md`. --- ## 4. Reverb plugin (`src/plugins/reverb/`) - [ ] Implement `ReverbPlugin` with IR convolver + `REVERB_DURATIONS`, dry/wet mix. - [ ] Split into `reverb-dsp.ts`, `reverb-ir.ts` (impulse response loader), `reverb-presets.ts`, `reverb-plugin.ts`. - [ ] Write tests, `reverb-plugin.md`. --- ## 5. Delay plugin (`src/plugins/delay/`) - [ ] Implement `DelayPlugin` with feedback loop and wet/dry mix. - [ ] Write `delay-plugin.test.ts`, `delay-plugin.md`. --- ## 6. Compressor plugin (`src/plugins/compressor/`) - [ ] Implement `CompressorPlugin` with standard Web Audio `DynamicsCompressorNode` params. - [ ] Add sidechain input: `CompressorPlugin.setSidechainSource(node)` with `SIDECHAIN_UNAVAILABLE` error when not wired. - [ ] Add mid/side processing mode. - [ ] Write tests, `compressor-plugin.md`. --- ## 7. Pitch Shifter plugin (`src/plugins/pitch-shifter/`) - [ ] Implement `PitchShifterPlugin` as AudioWorklet host. - [ ] Add `worklets/pitch-shifter.ts` processor. - [ ] Export `resolvePitchShifterWorkletUrl()` helper for Vite/Webpack: `new URL('../worklets/pitch-shifter.js', import.meta.url).href`. - [ ] Add `ScriptProcessorNode` fallback path (in `worklet-fallback.ts`) when AudioWorklet unavailable. - [ ] Write tests for both paths, `pitch-shifter-plugin.md`. --- ## 8. Synthesizer plugin (`src/plugins/synthesizer/`) - [ ] Implement full `SynthesizerPlugin`: oscillators (sine/square/sawtooth/triangle), ADSR envelope, voice pool (polyphony), filter. - [ ] Split into `oscillator.ts` (≤300), `envelope.ts` (≤300), `voice-pool.ts` (≤300), `synth-presets.ts`, `synthesizer-plugin.ts`. - [ ] Add `SynthesizerPreset` Zod schema. - [ ] Write tests per sub-module, `synthesizer-plugin.md`. --- ## 9. Audio Analyzer plugin (`src/plugins/audio-analyzer/`) - [ ] Implement `AudioAnalyzerPlugin` with FFT (`AnalyserNode`), tempo BPM estimation, key detection. - [ ] Add `essentia-bridge.ts`: dynamic `import('essentia.js')` with try/catch; export `isEssentiaAvailable()`. When unavailable, key/spectral features return `null`. - [ ] No `@ts-expect-error`; type the dynamic import result with an explicit interface. - [ ] Write tests with and without essentia stub (real interface, not vi.mock), `audio-analyzer-plugin.md`. --- ## 10. Microphone plugin (`src/plugins/microphone/`) - [ ] Implement `MicrophoneSimulationPlugin` + `createMicrophonePlugin` factory. - [ ] Add `MicrophonePreset` Zod schema. - [ ] Write tests, `microphone-plugin.md`. --- ## 11. Mixer plugin (`src/plugins/mixer/`) - [ ] Implement `MixerPlugin` with channel strips, sends, routing, master gain. - [ ] Fully implement send-state round-trip in `mixer-sends.ts` — no TODO. - [ ] Add `MixerPreset` Zod schema. - [ ] Split into `channel-strip.ts` (≤300), `mixer-sends.ts` (≤300), `mixer-presets.ts`, `mixer-plugin.ts`. - [ ] Write regression test: `applyPreset(getPreset())` round-trips sends exactly. - [ ] Write `mixer-plugin.md`. --- ## 12. GLaDOS plugin (`src/plugins/glados/`) - [ ] Implement `GLaDOSPlugin` with voice-effect chain (ring modulator + pitch shift + bitcrusher) and `GLaDOSPreset` options. - [ ] Add Wheatley, Cave Johnson, generic robotic presets. - [ ] Split into `glados-dsp.ts`, `glados-presets.ts`, `glados-plugin.ts`. - [ ] Add `GLaDOSPreset` Zod schema. - [ ] Write tests, `glados-plugin.md`. --- ## 13. Game Audio plugin (`src/plugins/game/`) - [ ] Implement `GameAudioPlugin`: `PannerNode`-based 3D spatial audio, proximity voice chat (gain-by-distance), music layer system, HUD voice channel. - [ ] Game-audio ducking bus: music auto-ducks when VoIP speaks. - [ ] Split into `spatial-audio.ts`, `proximity-voice.ts`, `music-layers.ts`, `game-audio-plugin.ts`. - [ ] Add `GameAudioPreset` Zod schema. - [ ] Write tests per sub-module, `game-audio-plugin.md`. --- ## 14. Audio Player plugin (`src/plugins/audio-player/`) - [ ] Implement `AudioPlayerPlugin` with load/play/pause/stop/seek, loop, playback rate, volume. - [ ] Write `audio-player-plugin.test.ts`, `audio-player-plugin.md`. --- ## 15. Bundle-size snapshot tests (`tests/bundle-size/`) - [ ] One snapshot test per subpath: build the entry point and assert that the emitted chunk does not contain symbols from other plugins (tree-shake isolation). Use `rollup` or `esbuild` in the test script. --- ## 16. Integration test (`tests/integration.test.ts`) - [ ] Load all twelve plugins into a single `AudioEngine` instance; verify no cross-plugin contamination. - [ ] Preset round-trip test for every plugin with a Zod schema. - [ ] Mixer sends round-trip regression. - [ ] PitchShifter worklet URL helper returns a URL string. --- ## 17. Docs - [ ] Write `.md` for every plugin module (≥200 words, simple + advanced examples, API reference). - [ ] Write `README.md` with purpose, subpath table, preset schema table, worklet bundling notes, deps table. --- ## 18. Verify and publish - [ ] `bunx turbo lint typecheck test --filter=@suaveplan/audio-plugins-fx` — green. - [ ] `bunx turbo test:coverage --filter=@suaveplan/audio-plugins-fx` — 100% on touched modules. - [ ] `bun run docs:check --filter=@suaveplan/audio-plugins-fx` — zero errors. - [ ] No `TODO`, `FIXME`, `any`, `ts-ignore`, `ts-expect-error`, `vi.mock`, `.skip` in `src/`. - [ ] All twelve subpath tree-shake snapshots green. - [ ] Mixer sends round-trip regression test passes. - [ ] `bun scripts/publish.ts --package @suaveplan/audio-plugins-fx`. - [ ] Archive to `openspec/archive/2026-04-24-enterprise-browser-audio-plugins-fx/`.