# @suaveplan/react-audio - React surface for the Suaveplan audio family — Phase 2 + Phase 2b (extras) + Phase 3 shipped. Provides provider + hooks + stores + error codes + a11y helpers + Phase-2 primitives (PluginSlot, PluginChainView, PresetManager, knob/slider) + composed-plugin UIs (TransportControls, TrackList/TrackRow, MasterMeter, Mixer, AudioVisualizer, AudioPlayer/BasicPlayer/PremiumPlayer, MicrophoneControls, GLaDOSControls, PluginLoader) + Phase 3 MIDI learn-mode (`` + `useMidiController`). React surface for the Suaveplan audio family. **Phase 1 of 3 — foundation** (provider + hooks + stores + error codes + a11y helpers). Components ship in Phase 2 (`enterprise-react-audio-components`); the MIDI learn-mode panel ships in Phase 3 (`enterprise-react-audio-midi`). ## Documentation tree - [aria-value-text](./src/a11y/aria-value-text/aria-value-text.md) — Pure `aria-valuetext` formatter consumed by Phase-2 parameter controls (knobs, sliders, scrubbers). Returns a screen-re… - [aria-value-text](./src/a11y/aria-value-text/aria-value-text.md) — Pure `aria-valuetext` formatter consumed by Phase-2 parameter controls (knobs, sliders, scrubbers). Returns a screen-re… - [keyboard-bindings](./src/a11y/keyboard-bindings/keyboard-bindings.md) — Pure-value table mapping keyboard keys to parameter-control actions (`fine-decrement`, `coarse-increment`, `page-decrem… - [keyboard-bindings](./src/a11y/keyboard-bindings/keyboard-bindings.md) — Pure-value table mapping keyboard keys to parameter-control actions (`fine-decrement`, `coarse-increment`, `page-decrem… - [audio-player](./src/components/audio-player/audio-player.md) — `` is the generic media-player surface for a live `AudioPlayerPlugin` instance from `@suaveplan/audio-fx-p… - [audio-player](./src/components/audio-player/audio-player.md) — `` is the generic media-player surface for a live `AudioPlayerPlugin` instance from `@suaveplan/audio-fx-p… - [audio-visualizer](./src/components/audio-visualizer/audio-visualizer.md) — `` is a canvas-based visualiser for a published bus. It subscribes through the foundation `useBus` hoo… - [audio-visualizer](./src/components/audio-visualizer/audio-visualizer.md) — `` is a canvas-based visualiser for a published bus. It subscribes through the foundation `useBus` hoo… - [basic-player](./src/components/basic-player/basic-player.md) — `` is the minimal media-player surface for an `AudioPlayerPlugin`. It is implemented as a thin composition… - [basic-player](./src/components/basic-player/basic-player.md) — `` is the minimal media-player surface for an `AudioPlayerPlugin`. It is implemented as a thin composition… - [glados-controls](./src/components/glados-controls/glados-controls.md) — `` is the composed UI for the `GLaDOSPlugin` voice transform from `@suaveplan/audio-fx-plugin-glados`.… - [glados-controls](./src/components/glados-controls/glados-controls.md) — `` is the composed UI for the `GLaDOSPlugin` voice transform from `@suaveplan/audio-fx-plugin-glados`.… - [parameter-keyboard](./src/components/internal/parameter-keyboard.md) — Internal helper consumed by `` and `` to translate a `KeyboardEvent` into a… - [parameter-unit](./src/components/internal/parameter-unit.md) — Internal helper that converts the controlled `ParameterUnit` enum exposed by `@suaveplan/audio-fx-plugin-base` (`"db"`,… - [master-meter](./src/components/master-meter/master-meter.md) — `` is a RAF-sampled master-output level meter. It subscribes to a named sidechain bus through the foundati… - [master-meter](./src/components/master-meter/master-meter.md) — `` is a RAF-sampled master-output level meter. It subscribes to a named sidechain bus through the foundati… - [microphone-controls](./src/components/microphone-controls/microphone-controls.md) — `` is the composed UI for `MicrophoneSimulationPlugin` from `@suaveplan/audio-fx-plugin-microphone`… - [microphone-controls](./src/components/microphone-controls/microphone-controls.md) — `` is the composed UI for `MicrophoneSimulationPlugin` from `@suaveplan/audio-fx-plugin-microphone`… - [midi-controller-setup](./src/components/midi-controller-setup/midi-controller-setup.md) — `` is the Phase-3 learn-mode panel for the Suaveplan React audio stack. It renders the connected c… - [midi-controller-setup](./src/components/midi-controller-setup/midi-controller-setup.md) — `` is the Phase-3 learn-mode panel for the Suaveplan React audio stack. It renders the connected c… - [mixer](./src/components/mixer/mixer.md) — `` is the per-channel strip view for a live `MixerPlugin` instance from `@suaveplan/audio-fx-plugin-mixer`. It r… - [mixer](./src/components/mixer/mixer.md) — `` is the per-channel strip view for a live `MixerPlugin` instance from `@suaveplan/audio-fx-plugin-mixer`. It r… - [plugin-chain-view](./src/components/plugin-chain-view/plugin-chain-view.md) — Reorderable, accessible view of a `PluginChain`. Renders one `` per chain entry, supports HTML5 drag-and-dr… - [plugin-chain-view](./src/components/plugin-chain-view/plugin-chain-view.md) — Reorderable, accessible view of a `PluginChain`. Renders one `` per chain entry, supports HTML5 drag-and-dr… - [plugin-loader](./src/components/plugin-loader/plugin-loader.md) — `` is the dynamic plugin-registration UI over the provider's `PluginRegistry`. It lists every currently-r… - [plugin-loader](./src/components/plugin-loader/plugin-loader.md) — `` is the dynamic plugin-registration UI over the provider's `PluginRegistry`. It lists every currently-r… - [plugin-parameter-knob](./src/components/plugin-parameter-knob/plugin-parameter-knob.md) — Rotary-knob primitive for a single `AudioFxPlugin` parameter. The knob implements the full keyboard contract mandated b… - [plugin-parameter-knob](./src/components/plugin-parameter-knob/plugin-parameter-knob.md) — Rotary-knob primitive for a single `AudioFxPlugin` parameter. The knob implements the full keyboard contract mandated b… - [plugin-parameter-slider](./src/components/plugin-parameter-slider/plugin-parameter-slider.md) — Linear-slider primitive for a single `AudioFxPlugin` parameter. Mirrors ``'s a11y contract and exp… - [plugin-parameter-slider](./src/components/plugin-parameter-slider/plugin-parameter-slider.md) — Linear-slider primitive for a single `AudioFxPlugin` parameter. Mirrors ``'s a11y contract and exp… - [plugin-slot](./src/components/plugin-slot/plugin-slot.md) — Generic renderer for any `AudioFxPlugin`. Reads the plugin's declarative `parameters` array and renders each one throug… - [plugin-slot](./src/components/plugin-slot/plugin-slot.md) — Generic renderer for any `AudioFxPlugin`. Reads the plugin's declarative `parameters` array and renders each one throug… - [premium-player](./src/components/premium-player/premium-player.md) — `` is the full-featured media-player surface — a composition of ``, ``, an… - [premium-player](./src/components/premium-player/premium-player.md) — `` is the full-featured media-player surface — a composition of ``, ``, an… - [preset-manager](./src/components/preset-manager/preset-manager.md) — `ChainSnapshot` save / load / delete UI layered over the provider's preset store. The save path persists the snapshot t… - [preset-manager](./src/components/preset-manager/preset-manager.md) — `ChainSnapshot` save / load / delete UI layered over the provider's preset store. The save path persists the snapshot t… - [track-list](./src/components/track-list/track-list.md) — `` is a composed-plugin UI that renders every track in the provider's `TimelineEngine`. It is the canonical… - [track-list](./src/components/track-list/track-list.md) — `` is a composed-plugin UI that renders every track in the provider's `TimelineEngine`. It is the canonical… - [track-row](./src/components/track-row/track-row.md) — `` is the per-track row primitive consumed by ``. It subscribes to a single `Track` through the fo… - [track-row](./src/components/track-row/track-row.md) — `` is the per-track row primitive consumed by ``. It subscribes to a single `Track` through the fo… - [transport-controls](./src/components/transport-controls/transport-controls.md) — `` is the composed-plugin UI for the provider-owned `Transport` instance. It exposes the spec-mandat… - [transport-controls](./src/components/transport-controls/transport-controls.md) — `` is the composed-plugin UI for the provider-owned `Transport` instance. It exposes the spec-mandat… - [error-codes](./src/error-codes/error-codes.md) — This module is the single source of truth for every error code thrown inside `@suaveplan/react-audio`. The codes are na… - [error-codes](./src/error-codes/error-codes.md) — This module is the single source of truth for every error code thrown inside `@suaveplan/react-audio`. The codes are na… - [hooks](./src/hooks/use-provider-state.md) — Internal helpers shared across every public hook. They centralise the two structured-error throws every engine-dependen… - [use-analyser](./src/hooks/use-analyser/use-analyser.md) — `useAnalyser(opts?)` polls an `AnalyserNode`-shaped source and returns the latest byte-magnitude FFT frame plus the mat… - [use-analyser](./src/hooks/use-analyser/use-analyser.md) — `useAnalyser(opts?)` polls an `AnalyserNode`-shaped source and returns the latest byte-magnitude FFT frame plus the mat… - [use-audio-engine](./src/hooks/use-audio-engine/use-audio-engine.md) — `useAudioEngine()` returns the full resolved `ProviderState` bundle — the adapter, the `TimelineEngine`, the `Transport… - [use-audio-engine](./src/hooks/use-audio-engine/use-audio-engine.md) — `useAudioEngine()` returns the full resolved `ProviderState` bundle — the adapter, the `TimelineEngine`, the `Transport… - [use-audio-fx-plugin](./src/hooks/use-audio-fx-plugin/use-audio-fx-plugin.md) — `useAudioFxPlugin(pluginType)` instantiates a plugin via the provider's `PluginRegistry.create(pluginType)` and memoise… - [use-audio-fx-plugin](./src/hooks/use-audio-fx-plugin/use-audio-fx-plugin.md) — `useAudioFxPlugin(pluginType)` instantiates a plugin via the provider's `PluginRegistry.create(pluginType)` and memoise… - [use-bus](./src/hooks/use-bus/use-bus.md) — `useBus(name)` reads the named sidechain bus from the provider's `ProviderBusRegistry` and subscribes to its publish/cl… - [use-bus](./src/hooks/use-bus/use-bus.md) — `useBus(name)` reads the named sidechain bus from the provider's `ProviderBusRegistry` and subscribes to its publish/cl… - [use-chain-plugin](./src/hooks/use-chain-plugin/use-chain-plugin.md) — `useChainPlugin(trackId, slotIndex)` returns the `AudioFxPlugin` currently occupying a specific slot in a track's `Plug… - [use-chain-plugin](./src/hooks/use-chain-plugin/use-chain-plugin.md) — `useChainPlugin(trackId, slotIndex)` returns the `AudioFxPlugin` currently occupying a specific slot in a track's `Plug… - [use-chain-snapshot](./src/hooks/use-chain-snapshot/use-chain-snapshot.md) — `useChainSnapshot(chain)` exposes chain-level snapshot operations. `get` reads the in-memory `ChainSnapshot`, `restore`… - [use-chain-snapshot](./src/hooks/use-chain-snapshot/use-chain-snapshot.md) — `useChainSnapshot(chain)` exposes chain-level snapshot operations. `get` reads the in-memory `ChainSnapshot`, `restore`… - [use-engine-state](./src/hooks/use-engine-state/use-engine-state.md) — `useEngineState()` reports the ``'s async-init lifecycle phase as one of `'pending' | 'ready' | 'error'`… - [use-engine-state](./src/hooks/use-engine-state/use-engine-state.md) — `useEngineState()` reports the ``'s async-init lifecycle phase as one of `'pending' | 'ready' | 'error'`… - [use-midi-controller](./src/hooks/use-midi-controller/use-midi-controller.md) — `useMidiController(controllerId)` is the React 19 binding for a single `MidiControllerPlugin` from `@suaveplan/audio-co… - [use-midi-controller](./src/hooks/use-midi-controller/use-midi-controller.md) — `useMidiController(controllerId)` is the React 19 binding for a single `MidiControllerPlugin` from `@suaveplan/audio-co… - [use-parameter](./src/hooks/use-parameter/use-parameter.md) — `useParameter(plugin, paramId)` is the canonical read/write hook for a single declared parameter on any `AudioFxPlugin`… - [use-parameter](./src/hooks/use-parameter/use-parameter.md) — `useParameter(plugin, paramId)` is the canonical read/write hook for a single declared parameter on any `AudioFxPlugin`… - [use-playlist](./src/hooks/use-playlist/use-playlist.md) — `usePlaylist(items, opts?)` manages a queue of `PlaylistItem` entries and exposes the standard playlist verbs (`next`,… - [use-playlist](./src/hooks/use-playlist/use-playlist.md) — `usePlaylist(items, opts?)` manages a queue of `PlaylistItem` entries and exposes the standard playlist verbs (`next`,… - [use-plugin-chain](./src/hooks/use-plugin-chain/use-plugin-chain.md) — `usePluginChain(trackId)` returns a handle for the `PluginChain` associated with a track. The provider lazily creates t… - [use-plugin-chain](./src/hooks/use-plugin-chain/use-plugin-chain.md) — `usePluginChain(trackId)` returns a handle for the `PluginChain` associated with a track. The provider lazily creates t… - [use-preset](./src/hooks/use-preset/use-preset.md) — `usePreset(plugin)` exposes plugin-level preset operations as React-friendly callbacks: `get` reads the current preset,… - [use-preset](./src/hooks/use-preset/use-preset.md) — `usePreset(plugin)` exposes plugin-level preset operations as React-friendly callbacks: `get` reads the current preset,… - [use-timeline](./src/hooks/use-timeline/use-timeline.md) — `useTimeline()` returns the provider's single `TimelineEngine` instance, the canonical owner of timeline state — tracks… - [use-timeline](./src/hooks/use-timeline/use-timeline.md) — `useTimeline()` returns the provider's single `TimelineEngine` instance, the canonical owner of timeline state — tracks… - [use-track](./src/hooks/use-track/use-track.md) — `useTrack(trackId)` subscribes to a single track on the `TimelineEngine` by id and re-renders only when that specific t… - [use-track](./src/hooks/use-track/use-track.md) — `useTrack(trackId)` subscribes to a single track on the `TimelineEngine` by id and re-renders only when that specific t… - [use-transport](./src/hooks/use-transport/use-transport.md) — `useTransport()` wraps the provider's `Transport` with a small, React-friendly façade: `{ transport, play, pause, stop,… - [use-transport](./src/hooks/use-transport/use-transport.md) — `useTransport()` wraps the provider's `Transport` with a small, React-friendly façade: `{ transport, play, pause, stop,… - [use-transport-time](./src/hooks/use-transport-time/use-transport-time.md) — `useTransportTime()` returns the transport's current time in seconds, sampled at the provider's configured `sampleRateH… - [use-transport-time](./src/hooks/use-transport-time/use-transport-time.md) — `useTransportTime()` returns the transport's current time in seconds, sampled at the provider's configured `sampleRateH… - [use-provider-state](./src/hooks/use-provider-state.md) — Internal helpers shared across every public hook. They centralise the two structured-error throws every engine-dependen… - [audio-context](./src/provider/audio-context.md) — Declares the React context object (`AudioReactContext`) that `` populates and that every hook reads from… - [audio-provider](./src/provider/audio-provider.md) — `` is the single React component that owns the audio engine bundle for a React subtree. It constructs ex… - [chain-map](./src/provider/chain-map.md) — `ChainMap` is the provider-scoped lazy registry of `PluginChain` instances, keyed by track id. The hook `usePluginChain… - [provider-bus-registry](./src/provider/provider-bus-registry.md) — `ProviderBusRegistry` is a thin wrapper around `DefaultBusRegistry` from `@suaveplan/audio-fx-plugin-base` that adds a… - [provider-options](./src/provider/provider-options.md) — Defines the `AudioProviderOptions` shape consumed by ``, the Zod schema that validates it, and the `pars… - [audio-store](./src/stores/audio-store/audio-store.md) — `useAudioStore` is a slim provider-scoped Zustand store reserved for application-level audio UI overrides (display name… - [audio-store](./src/stores/audio-store/audio-store.md) — `useAudioStore` is a slim provider-scoped Zustand store reserved for application-level audio UI overrides (display name… - [ui-store](./src/stores/ui-store/ui-store.md) — `useUiStore` is the cross-component UI state store for the React audio workspace. It owns presentation-only state — whi… - [ui-store](./src/stores/ui-store/ui-store.md) — `useUiStore` is the cross-component UI state store for the React audio workspace. It owns presentation-only state — whi… - [test-utils](./src/test-utils.md) — Test-only helpers for the `@suaveplan/react-audio` test suite. The module exports three utilities: `makeFakeAudioContex… ## Install ```bash bun add @suaveplan/react-audio ``` Peer deps: `react@^19`, `react-dom@^19`. ## Quick start ```tsx import { AudioProvider, useTransport } from "@suaveplan/react-audio"; function PlayButton() { const { play, stop, transport } = useTransport(); return ( ); } export default function App() { return ( ); } ``` ## What ships in Phase 1 ### Provider - `` — owns one `BrowserTimelineAdapter`, one `TimelineEngine`, one `Transport`, one `ProviderBusRegistry`, one `ChainMap`, and one `PluginRegistry`. Strict-mode safe; disposes cleanly on unmount. ### 13 hooks | Hook | Returns | |------|---------| | `useEngineState()` | `'pending' \| 'ready' \| 'error'` | | `useAudioEngine()` | full `ProviderState` bundle | | `useTimeline()` | `TimelineEngine` | | `useTransport()` | `{ transport, play, pause, stop, seek, setTempo }` | | `useTransportTime()` | current seconds, sampled at frame rate | | `useTrack(trackId)` | `{ track, update, remove }` | | `usePluginChain(trackId)` | chain composition + events | | `useChainPlugin(trackId, slot)` | plugin at slot | | `useAudioFxPlugin(pluginType)` | new plugin from the registry | | `useParameter(plugin, paramId)` | value + set + curve + scheduleAt | | `usePreset(plugin)` | plugin-level preset get/apply/save/load | | `useChainSnapshot(chain)` | chain-level snapshot get/restore/save/load | | `useBus(name)` | sidechain bus by name | ### Stores - `useAudioStore` — UI override store (no engine state mirrored). - `useUiStore` — panel/theme/visualization/selectedTrack/dragState. ### Accessibility helpers - `PARAMETER_KEY_BINDINGS` + `matchKeyBinding(event)` — central keymap consumed by Phase-2 components. - `formatAriaValueText(value, unit, min, max, options?)` — unit-aware `aria-valuetext` formatter. ### Error codes All errors are `ReactAudioError extends SuaveplanError`. Codes: - `REACT_AUDIO.NO_PROVIDER` - `REACT_AUDIO.PROVIDER_PENDING` - `REACT_AUDIO.UNKNOWN_PARAMETER` - `REACT_AUDIO.PRESET_STORE_FAILED` - `REACT_AUDIO.INVALID_OPTIONS` ## Subpath exports ```ts import { AudioProvider } from "@suaveplan/react-audio/provider"; import { useTransport } from "@suaveplan/react-audio/hooks/use-transport"; import { useAudioStore } from "@suaveplan/react-audio/stores"; import { formatAriaValueText } from "@suaveplan/react-audio/a11y"; import { ReactAudioError } from "@suaveplan/react-audio/error-codes"; ``` `./components` is reserved for Phase 2 and is **not** declared in Phase 1. ## Coming next - **Phase 2 (`enterprise-react-audio-components`)** — Storybook-covered components: ``, ``, ``, ``, ``, ``, ``, … - **Phase 3 (`enterprise-react-audio-midi`)** — `useMidiController` hook + `` learn-mode panel. ## License MIT