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

174 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Tasks: enterprise-audio-plugins-fx
**Change ID**: enterprise-audio-plugins-fx
**Package**: `@suaveplan/audio-plugins-fx`
**Target path**: `packages/audio/audio-plugins-fx`
**Prerequisite packages on Verdaccio**: `@suaveplan/audio-core`, `@suaveplan/audio-transport`, `@suaveplan/schema-registry`, `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/opentelemetry`, `@suaveplan/events`
> No behavior change is permitted to ship without a corresponding spec scenario AND a `**Verified by:**` test. Every task below must reflect work actually done.
---
## 1. Scaffold
- [ ] 1.1 Create directory tree per `design.md` §13. All feature subdirs (`base/`, `chain/`, `registry/`, `plugins/<name>/`, `presets/<name>/`, `__benchmarks__/`, `tests/`, `tests/bundle-size/`).
- [ ] 1.2 Write `package.json` at version `0.1.0` with `"type": "module"`, `"sideEffects": false`, deps `@suaveplan/audio-core workspace:^`, `@suaveplan/audio-transport workspace:^`, `@suaveplan/schema-registry workspace:^`, `@suaveplan/error workspace:^`, `@suaveplan/types workspace:^`, `@suaveplan/opentelemetry workspace:^`, `@suaveplan/events workspace:^`, `zod catalog:forms`, `tslib catalog:build`.
- [ ] 1.3 Write a full `exports` map: `.`, `./base`, `./chain`, `./registry`, and one entry per plugin path: `./eq`, `./filter`, `./compressor`, `./limiter`, `./gate`, `./reverb`, `./delay`, `./chorus`, `./phaser`, `./flanger`, `./tremolo`, `./auto-filter`, `./distortion`, `./pitch-shifter`, `./synthesizer`, `./sampler`, `./mixer`, `./widener`, `./spatial-positional`, `./proximity-voice`, `./music-layer-mixer`, `./voice-transform`, `./microphone`, `./glados`, `./audio-player`. Plus `./presets/*` lazy.
- [ ] 1.4 Write `tsconfig.json`, `vitest.config.ts` via `createTestConfig()`, lint/typecheck/test/test:coverage/build/docs:check scripts.
---
## 2. Error codes + Zod schemas
- [ ] 2.1 Write `src/error-codes.ts` — `defineCodes("AUDIO_FX", [...])` for every code listed in the "Structured error codes" requirement (17 codes total). Export `AudioFxErrorCode`, `AUDIO_FX_ERROR_METADATA`, `registerAudioFxErrorCodes()`, and `AudioError` class.
- [ ] 2.2 Write `src/error-codes.test.ts` — every registered code reachable from a real call site (per Requirement "Structured error codes").
- [ ] 2.3 Write `src/error-codes.md`.
---
## 3. Base contract (`src/base/`)
- [ ] 3.1 Write `src/base/plugin-io.ts` — `PluginIo`, `ChannelSpec`, `ChannelLayout`, `validateChainIo()` helper. + `.types.ts`, `.test.ts`, `.md`.
- [ ] 3.2 Write `src/base/capabilities.ts` — `PluginCapabilities` interface + `deriveCapabilities()` helper that cross-checks method presence. + `.types.ts`, `.test.ts`, `.md`.
- [ ] 3.3 Write `src/base/parameter-schedule.ts` — curve + transport-time schedule evaluator, sample-accurate; shared queue per parameter id. + `.test.ts`, `.md`.
- [ ] 3.4 Write `src/base/preset.ts` — `PresetSnapshot` type, Zod-validated `getPreset`/`applyPreset` reference implementation. + `.types.ts`, `.test.ts`, `.md`.
- [ ] 3.5 Write `src/base/audio-fx-plugin.ts` — `AudioFxPlugin` interface, `AbstractAudioFxPlugin` reference class (parameter storage, schedule evaluation, latency emission, capabilities defaults). + `.types.ts`, `.test.ts`, `.md`.
- [ ] 3.6 Write `src/base/index.ts` barrel (explicit named re-exports only).
---
## 4. Chain primitive (`src/chain/`)
- [ ] 4.1 Write `src/chain/ambient-state.ts` — `AmbientState` type, `defaultAmbientState()`, immutable patch-merge reducer. + `.types.ts`, `.test.ts`, `.md`.
- [ ] 4.2 Write `src/chain/bus-registry.ts` — `BusRegistry` interface, `SidechainBus`, `SidechainPublisher`, `DefaultBusRegistry` reference implementation. + `.types.ts`, `.test.ts`, `.md`.
- [ ] 4.3 Write `src/chain/chain-context.ts` — `ChainContext` factory; produces stable per-plugin context with `PluginHandle` peer views. + `.types.ts`, `.test.ts`, `.md`.
- [ ] 4.4 Write `src/chain/pdc.ts` — PDC summing helper + per-plugin `onLatencyChanged` subscription manager. + `.test.ts`, `.md`.
- [ ] 4.5 Write `src/chain/bypass-wrapper.ts` — chain-level bypass implementation; passthrough buffer reuse without allocation. + `.test.ts`, `.md`.
- [ ] 4.6 Write `src/chain/chain-snapshot.ts` — Zod-validated `ChainSnapshot` shape, `snapshot`/`restore` against a `PluginRegistry`. + `.test.ts`, `.md`.
- [ ] 4.7 Write `src/chain/plugin-chain.ts` — `PluginChain` class implementing composition (`add`/`remove`/`move`/`replace` with crossfade/`bypass`), lifecycle (`setup`/`process`/`reset`/`dispose`), inspection (`plugins`/`findById`/`getEffectiveLatencySamples`/`getEffectiveOutputChannels`), event surface. ≤300 lines (split helpers as needed). + `.types.ts`, `.test.ts`, `.md`.
- [ ] 4.8 Write `src/chain/index.ts` barrel.
---
## 5. Registry (`src/registry/`)
- [ ] 5.1 Write `src/registry/plugin-registry.ts` — `PluginRegistry` class; `register`/`has`/`create`/`list`. + `.types.ts`, `.test.ts`, `.md`.
- [ ] 5.2 Each first-party plugin's barrel SHALL self-register its default factory at module load — but registration SHALL be opt-in: consumers import `@suaveplan/audio-plugins-fx/registry/auto-register` to get all factories pre-registered, otherwise nothing auto-registers (preserves `sideEffects: false`).
---
## 6. Tier-1 DSP plugins (universal)
- [ ] 6.1 `EQPlugin` — 8-band parametric, shelves, HP/LP, presets `flat`/`vocal`/`bass`/`podcast`. `createAudioNode` returns BiquadFilterNode chain. + tests + `.md` + `.schemas.ts`.
- [ ] 6.2 `FilterPlugin` — biquad / IIR / state-variable modes. + tests + `.md` + `.schemas.ts`.
- [ ] 6.3 `CompressorPlugin` — threshold/knee/ratio/attack/release, soft-knee, sidechain (via `setSidechain`), mid/side mode (reads `ChainContext.ambient.track.layout`). `createAudioNode` returns `DynamicsCompressorNode`. + tests + `.md` + `.schemas.ts`.
- [ ] 6.4 `LimiterPlugin` — brick-wall, lookahead with `onLatencyChanged` for dynamic latency. `BlockProcessor` only. + tests + `.md` + `.schemas.ts`.
- [ ] 6.5 `GatePlugin` — threshold/attack/hold/release. + tests + `.md` + `.schemas.ts`.
---
## 7. Tier-2 time-based plugins
- [ ] 7.1 `ReverbPlugin` — IR convolver + algorithmic fallback, `loadImpulseResponse(url, { signal })` with AbortSignal, presets `room`/`hall`/`plate`/`cathedral`. `wet` parameter. + tests + `.md` + `.schemas.ts`.
- [ ] 7.2 `DelayPlugin` — feedback / ping-pong / BPM-sync (reads `ChainContext.ambient.transport.tempo`). + tests + `.md` + `.schemas.ts`.
- [ ] 7.3 `ChorusPlugin`, `PhaserPlugin`, `FlangerPlugin` — each implementing the time-based requirement. + tests + `.md` + `.schemas.ts`.
---
## 8. Tier-3 modulation + distortion + pitch + voice
- [ ] 8.1 `TremoloPlugin`, `AutoFilterPlugin` — phase-continuous LFOs. + tests + `.md` + `.schemas.ts`.
- [ ] 8.2 `DistortionPlugin` — waveshaper / bitcrusher / overdrive modes. + tests + `.md` + `.schemas.ts`.
- [ ] 8.3 `PitchShifterPlugin` — phase-vocoder, worklet processor, `getLatencySamples()` reports FFT-frame latency. + tests + `.md` + `.schemas.ts` + worklet file.
---
## 9. Synth + sampler + mixer + widener
- [ ] 9.1 `SynthesizerPlugin` — oscillator / ADSR / voice pool / portamento / `triggerAttack`/`triggerRelease`/`triggerAttackRelease`. + tests + `.md` + `.schemas.ts`.
- [ ] 9.2 `SamplerPlugin` — `loadSample(note, url, { signal })`, polyphonic playback. + tests + `.md` + `.schemas.ts`.
- [ ] 9.3 `MixerPlugin` — channel strips, sends/returns, master VU, per-channel EQ. + tests + `.md` + `.schemas.ts`.
- [ ] 9.4 `StereoWidenerPlugin` — mid/side width. + tests + `.md` + `.schemas.ts`.
---
## 10. Game-audio building blocks
- [ ] 10.1 `SpatialPositionalPlugin` — distance attenuation, amplitude panning, HRTF via `createAudioNode` (PannerNode). Reads `ChainContext.ambient.listener` with parameter fallback. + tests + `.md` + `.schemas.ts`.
- [ ] 10.2 `ProximityVoicePlugin` — distance-based attenuation, VAD, optional spatial blend. + tests + `.md` + `.schemas.ts`.
- [ ] 10.3 `MusicLayerMixerPlugin` — source plugin (`io.inputs[0].count === 0`), `loadLayer(id, buffer)`, weights from `ambient.extension.gameState`, crossfade. + tests + `.md` + `.schemas.ts`.
- [ ] 10.4 `VoiceTransformPlugin` — pitch + formant + ring-mod + distortion + reverb combo, presets `child`/`giant`/`robot`/`monster`/`echo`. + tests + `.md` + `.schemas.ts`.
---
## 11. Upstream-port plugins
- [ ] 11.1 `MicrophonePlugin` — full mic processing chain (frequency, resonance, distortion, noise, dynamics, character, output gain) with worklet for the browser path. Presets `vintage`/`radio`/`podcast`/`telephone`/`clean`. + tests + `.md` + `.schemas.ts` + worklet file.
- [ ] 11.2 `GLaDOSPlugin` — character vocoder built on phase-vocoder + formant + ring-mod + band-pass + bit-crusher. Presets `glados-default`/`glados-cake`/`glados-deception`/`wheatley`. + tests + `.md` + `.schemas.ts` + worklet file.
- [ ] 11.3 `AudioPlayerPlugin` — track-style source plugin, `load`/`play`/`pause`/`stop`/`seek`/`getCurrentTime`/`getDuration`, `loop` + `playbackRate` parameters, `'ended'` event. + tests + `.md` + `.schemas.ts`.
---
## 12. Presets
- [ ] 12.1 `src/presets/reverb/cathedrals.ts`, `rooms.ts`, `plates.ts` — IR descriptor packs (lazy subpath imports).
- [ ] 12.2 `src/presets/synth/leads.ts`, `pads.ts`, `basses.ts`.
- [ ] 12.3 `src/presets/glados/defaults.ts`.
- [ ] 12.4 Register every preset schema with `@suaveplan/schema-registry`.
---
## 13. Benchmarks
- [ ] 13.1 `src/__benchmarks__/eq.bench.ts` — 1 s stereo through 8-band EQ.
- [ ] 13.2 `src/__benchmarks__/reverb.bench.ts` — 1 s through 10 s IR + algorithmic.
- [ ] 13.3 `src/__benchmarks__/synth.bench.ts` — render 32-voice polyphonic synth.
- [ ] 13.4 `src/__benchmarks__/chain.bench.ts` — 8-plugin serial chain vs raw `BlockProcessor` loop; chain overhead ≤ 5 %.
---
## 14. Integration + purity + bundle-size tests
- [ ] 14.1 `tests/integration.test.ts` — end-to-end chain with ambient + bus: load tracks A and B, A taps `kick` bus, B's compressor side-chains from `kick`, verify ducking; verify chain snapshot round-trip; verify PDC alignment.
- [ ] 14.2 `tests/purity.test.ts` — built `dist/` references no browser/Node globals on the processing path; no global state mutation at import time.
- [ ] 14.3 `tests/exports.test.ts` — every subpath export resolves; every feature barrel uses explicit named re-exports (no `export *`); the parameterIndex / parameters cross-check across every plugin.
- [ ] 14.4 `tests/bundle-size/eq.size.test.ts`, `reverb.size.test.ts`, `synth.size.test.ts`, `chain.size.test.ts` — assert tree-shaken bundles do not include unrelated plugins.
- [ ] 14.5 `tests/property.test.ts` (fast-check) — gain plugin: 0 dB ⇒ identity, -∞ dB ⇒ silence; bypass ⇒ bit-identity; chain order invariance for known commutative pairs.
---
## 15. Verify
- [ ] 15.1 `bunx turbo lint typecheck test --filter=@suaveplan/audio-plugins-fx` — green.
- [ ] 15.2 `bunx turbo test:coverage --filter=@suaveplan/audio-plugins-fx` — 100/100/100/100.
- [ ] 15.3 `bunx turbo build --filter=@suaveplan/audio-plugins-fx` — green.
- [ ] 15.4 Banned-pattern scan: `grep -rnE "@deprecated|TODO|FIXME|ts-ignore|ts-expect-error|\\.skip|\\.only|console\\.log|\\bany\\b" packages/audio/audio-plugins-fx/src/ --include="*.ts"` — empty (only false-positive matches on word `any` allowed in comments).
- [ ] 15.5 Runner-import scan: `grep -rnE "from ['\"](vitest|bun:test)['\"]" packages/audio/audio-plugins-fx/src/ packages/audio/audio-plugins-fx/tests/ --include="*.ts"` — empty.
- [ ] 15.6 File-size sweep: every src file ≤ 300 lines, every test file ≤ 500 lines.
- [ ] 15.7 Missing `.md` scan empty.
- [ ] 15.8 `README.md` at package root with quick-start, chain example, ambient-state example, sidechain example, and links to every co-located `.md`.
---
## 16. Spec reconciliation (pre-archive)
- [ ] 16.1 Walk every `### Requirement` and `#### Scenario` in `specs/audio-plugins-fx/spec.md`; grep `src/` and confirm each named class, function, error code, event, and parameter exists.
- [ ] 16.2 Walk every `**Verified by:**` line; confirm the named test file exists AND the test name matches verbatim.
- [ ] 16.3 Confirm every entry in `AUDIO_FX_ERROR_METADATA` is reachable from a real call site exercised by a test.
---
## 17. Root docs
- [ ] 17.1 Run `bun scripts/folder-reorg/generate-manifest.ts` to refresh `MANIFEST.md`.
- [ ] 17.2 Flip `STATUS.md` row `@suaveplan/audio-plugins-fx` from `–` to `✅`.
- [ ] 17.3 Update `SUMMARY.md` paragraph to reflect the shipped surface.
- [ ] 17.4 `bunx markdownlint-cli2 --fix` over touched files; second pass without `--fix` must exit 0.
---
## 18. Archive
- [ ] 18.1 Fold `specs/audio-plugins-fx/spec.md` into `openspec/specs/audio-plugins-fx/spec.md`.
- [ ] 18.2 Move `openspec/changes/enterprise-audio-plugins-fx/` → `openspec/archive/YYYY-MM-DD-enterprise-audio-plugins-fx/`.