Files
suaveplan/openspec/archive/2026-05-15-superseded-enterprise-browser-audio-controllers/tasks.md
2026-05-27 23:29:53 +01:00

6.4 KiB

Tasks: enterprise-browser-audio-controllers

Change ID: enterprise-browser-audio-controllers Package: @suaveplan/audio-controllers Target path: browser/audio/audio-controllers Prerequisite packages on Verdaccio: @suaveplan/audio-engine, @suaveplan/error, @suaveplan/types, @suaveplan/events


1. Scaffold

  • Create browser/audio/audio-controllers/ directory tree per layout in proposal.md.
  • Write package.json at version 0.1.0:
    • "sideEffects": false
    • exports: top-level "." plus subpaths for each controller and sequencer
    • 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
    • devDependencies: vitest catalog:testing, @vitest/coverage-istanbul catalog:testing, @suaveplan/testing workspace:^, @playwright/test catalog:testing
  • Write tsconfig.json and vitest.config.ts (pool: forks).

2. Error codes (src/error-codes.ts)

  • Define MidiControllerErrorCode: MIDI_UNAVAILABLE, MIDI_PERMISSION_DENIED, MIDI_DEVICE_DISCONNECTED, MIDI_SYSEX_REJECTED, CONTROLLER_PRESET_INVALID, SAMPLE_LOADER_FAILED.
  • Export registerMidiControllerErrorCodes() and call eagerly.

3. Base class (src/base/midi-controller-plugin/)

  • Implement abstract MidiControllerPlugin extends AudioPlugin:
    • requestMIDIAccess(sysex?: boolean): calls navigator.requestMIDIAccess; throws typed MIDI_UNAVAILABLE / MIDI_PERMISSION_DENIED on failure.
    • onStateChange(event: MIDIConnectionEvent): detects disconnect / reconnect, emits typed events, auto-rebinds.
    • flushLEDs(updates: LEDUpdate[]): diff engine with per-frame byte budget.
    • defineMappings(mappings: CCMapping[]): CC-learn DSL storage.
    • Protected EventEmitter<MidiControllerEventMap> member — all subclasses use it.
  • Write midi-controller-plugin.test.ts: permission flow, hot-plug disconnect + reconnect, LED flush budget.
  • Write midi-controller-plugin.md.

4. Shared sequencer (src/sequencer/sequencer/)

  • Implement Sequencer: audio-clock-synced step grid, tempo (BPM), step on/off, playback start/stop/reset.
  • Clock source: inject via constructor (accepts AudioContext for currentTime-based scheduling, not setInterval).
  • Write sequencer.test.ts, sequencer.md.

5. KontrolS88Plugin (src/plugins/kontrol-s88/)

  • mapping.ts: CC/note-number → parameter map, type-safe DSL.
  • state.ts: KeyState[], TransportState machine.
  • arpeggio.ts: ArpMode implementations (up/down/random/chord), clock-synced via shared Sequencer.
  • scale.ts: ScaleMode quantizer (major, minor, chromatic, etc.), chord voicing.
  • led.ts: per-key LED feedback, batch flush.
  • preset.ts: KontrolS88Preset Zod schema, serialize/deserialize.
  • kontrol-s88.ts: plugin orchestrator, hooks into MidiControllerPlugin base.
  • kontrol-s88.test.ts: MIDI byte → state, state → MIDI out, velocity curve, scale transform, arpeggio clock, preset round-trip, hot-plug disconnect + reconnect.
  • kontrol-s88.md.

6. MaschinePlugin (src/plugins/maschine/)

  • mapping.ts: pad/CC/button mapping.
  • state.ts: pad grid state, group states.
  • sequencer.ts: 16-step sequencer per pad using shared Sequencer.
  • sample-loader.ts: real SampleLoader interface — no placeholder; loads via AudioContext.decodeAudioData.
  • preset.ts: MaschinePreset Zod schema.
  • maschine.ts: plugin orchestrator. Event system wired via EventEmitter — no placeholder comments.
  • maschine.test.ts: pad velocity, step grid, sample load, preset round-trip.
  • maschine.md.

7. TraktorS4Plugin (src/plugins/traktor-s4/)

  • mapping.ts: CC/button mapping per channel.
  • deck.ts: DeckState, load/play/pause/cue/sync, pitch/tempo.
  • mixer.ts: channel volumes, EQ per channel, master gain.
  • led.ts: LED ring/button feedback.
  • preset.ts: TraktorS4Preset Zod schema.
  • traktor-s4.ts: plugin orchestrator. Event system wired — no placeholder comments.
  • traktor-s4.test.ts: crossfader, deck sync, mixer state, preset round-trip.
  • traktor-s4.md.

8. Learn mode (src/learn/learn-mode/)

  • Implement LearnMode: listens for MIDI CC events, stores custom remapping, persists via injected StorageAdapter.
  • Default adapter: in-memory; inject @suaveplan/storage-browser for durable persistence.
  • Write learn-mode.test.ts, learn-mode.md.

9. SysEx fuzz test (tests/integration.test.ts)

  • Write a property-based test (fast-check) that feeds malformed SysEx byte arrays to onMIDIMessage on each controller and verifies the plugin does not crash and emits a typed MIDI_SYSEX_REJECTED event or safely ignores.

10. Playwright E2E (tests/e2e/)

  • Write E2E spec using a virtual MIDI device (Web MIDI API mock via Playwright page context) for each controller:
    • KontrolS88: MIDI note-on → KeyState update, arpeggio output, LED feedback.
    • Maschine: pad velocity → step sequencer trigger.
    • TraktorS4: crossfader CC → mixer state.
  • Verify hot-plug: simulate device disconnect + reconnect event.

11. OTel metrics

  • Wire in MidiControllerPlugin base:
    • Counter midi.messages_in_total{controller}, midi.messages_out_total{controller}
    • Counter led.frames_total{controller}
    • Histogram midi.input_to_audio_latency_ms{controller}

12. Docs

  • Write .md for every exported module (≥200 words, API reference, examples).
  • Write README.md with controller matrix table (every supported CC/note/pad per device), preset-pack list, MIDI permission guidance.

13. Verify and publish

  • bunx turbo lint typecheck test --filter=@suaveplan/audio-controllers — green.
  • bunx turbo test:coverage --filter=@suaveplan/audio-controllers — 100%.
  • bun run docs:check --filter=@suaveplan/audio-controllers — zero errors.
  • No TODO, placeholder, any, ts-ignore, vi.mock, .skip in src/.
  • Playwright E2E green for all three controllers.
  • bun scripts/publish.ts --package @suaveplan/audio-controllers.
  • Archive to openspec/archive/2026-04-24-enterprise-browser-audio-controllers/.