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

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_PRESETS
  • ReverbPlugin + ReverbType, ReverbPluginConfig, REVERB_DURATIONS
  • DelayPlugin + DelayPluginConfig
  • CompressorPlugin + CompressorPluginConfig
  • PitchShifterPlugin + PitchShifterConfig, PitchShifterPreset
  • SynthesizerPlugin + oscillator/envelope/voice-pool types, SynthesizerPreset
  • AudioAnalyzerPlugin + 9 analysis types (FFTData, BeatInfo, KeyInfo, SpectralFeatures, etc.)
  • MicrophoneSimulationPlugin + createMicrophonePlugin + 7 mic types, MicrophonePreset
  • MixerPlugin + 5 mixer types, MixerPreset (with complete sends round-trip)
  • GLaDOSPlugin + 6 GLaDOS types, GLaDOSPreset
  • GameAudioPlugin + 9 game audio types, GameAudioPreset
  • AudioPlayerPlugin + 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.