Files
2026-05-27 23:29:53 +01:00

7.4 KiB

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