Initial Commit
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
<!-- markdownlint-disable MD024 -->
|
||||
|
||||
# Capability Spec Delta: react-audio (enterprise-react-audio-midi)
|
||||
|
||||
**Package**: `@suaveplan/react-audio`
|
||||
**Status**: PROPOSED — Phase 3 of 3 (MIDI learn-mode)
|
||||
**Blocked on**: Phases 1 and 2 shipping first.
|
||||
|
||||
> Every requirement carries `**Verified by:**`.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: MidiControllerSetup learn-mode panel
|
||||
|
||||
`<MidiControllerSetup>` SHALL render the connected controllers from the provider's `MidiControllerRegistry` (sourced via `@suaveplan/audio-controllers`) and expose a learn-mode UI: the user selects a target parameter on a plugin, presses a control on the hardware, and the panel calls `bindParameter(plugin, paramId, capturedSource, { smoothingMs })` from `@suaveplan/audio-controllers`. Captured bindings SHALL be persisted via the provider's preset store (the same store used by `<PresetManager>`) and re-bound on next mount. An `Unbind` button SHALL invoke the unsubscribe function returned by `bindParameter`. The package SHALL also export the `useMidiController(controllerId)` hook returning the controller instance + a `learn(target)` method.
|
||||
|
||||
#### Scenario: learn captures the next CC and binds it
|
||||
|
||||
- **WHEN** a user selects `eq.lowShelfGain` as the target and the fake-device fixture emits `CC 1/7 = 64`
|
||||
- **THEN** `bindParameter(eq, 'lowShelfGain', { type: 'cc', channel: 1, number: 7 })` is called and the panel shows the binding
|
||||
|
||||
#### Scenario: unbind removes the binding
|
||||
|
||||
- **WHEN** a user clicks `Unbind` on an active binding
|
||||
- **THEN** subsequent CC events for that source no longer call `setParameter` on the plugin
|
||||
|
||||
#### Scenario: useMidiController hook subscribes to connection-state changes
|
||||
|
||||
- **WHEN** the controller transitions `disconnected → connecting → connected`
|
||||
- **THEN** the component using `useMidiController(controllerId)` re-renders once per transition with the new state
|
||||
|
||||
**Verified by:** `src/components/midi-controller-setup/midi-controller-setup.test.tsx::"learn captures the next CC and binds it"` AND `src/components/midi-controller-setup/midi-controller-setup.test.tsx::"unbind removes the binding"` AND `src/hooks/use-midi-controller/use-midi-controller.test.tsx::"re-renders on connection-state transitions"`
|
||||
|
||||
<!-- markdownlint-enable MD024 -->
|
||||
Reference in New Issue
Block a user