Files
skills/plugins/document-navigator/docs/ui/react/react-audio/README.md
2026-06-09 21:06:27 +01:00

21 KiB

@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 (<MidiControllerSetup> + 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 — Pure aria-valuetext formatter consumed by Phase-2 parameter controls (knobs, sliders, scrubbers). Returns a screen-re…
    • aria-value-text — Pure aria-valuetext formatter consumed by Phase-2 parameter controls (knobs, sliders, scrubbers). Returns a screen-re…
  • keyboard-bindings — Pure-value table mapping keyboard keys to parameter-control actions (fine-decrement, coarse-increment, `page-decrem…
    • keyboard-bindings — Pure-value table mapping keyboard keys to parameter-control actions (fine-decrement, coarse-increment, `page-decrem…
  • audio-player — <AudioPlayer> is the generic media-player surface for a live AudioPlayerPlugin instance from `@suaveplan/audio-fx-p…
    • audio-player — <AudioPlayer> is the generic media-player surface for a live AudioPlayerPlugin instance from `@suaveplan/audio-fx-p…
  • audio-visualizer — <AudioVisualizer> is a canvas-based visualiser for a published bus. It subscribes through the foundation useBus hoo…
    • audio-visualizer — <AudioVisualizer> is a canvas-based visualiser for a published bus. It subscribes through the foundation useBus hoo…
  • basic-player — <BasicPlayer> is the minimal media-player surface for an AudioPlayerPlugin. It is implemented as a thin composition…
    • basic-player — <BasicPlayer> is the minimal media-player surface for an AudioPlayerPlugin. It is implemented as a thin composition…
  • glados-controls — <GLaDOSControls> is the composed UI for the GLaDOSPlugin voice transform from @suaveplan/audio-fx-plugin-glados.…
    • glados-controls — <GLaDOSControls> is the composed UI for the GLaDOSPlugin voice transform from @suaveplan/audio-fx-plugin-glados.…
  • parameter-keyboard — Internal helper consumed by <PluginParameterKnob> and <PluginParameterSlider> to translate a KeyboardEvent into a…
  • parameter-unit — Internal helper that converts the controlled ParameterUnit enum exposed by @suaveplan/audio-fx-plugin-base ("db",…
  • master-meter — <MasterMeter> is a RAF-sampled master-output level meter. It subscribes to a named sidechain bus through the foundati…
    • master-meter — <MasterMeter> is a RAF-sampled master-output level meter. It subscribes to a named sidechain bus through the foundati…
  • microphone-controls — <MicrophoneControls> is the composed UI for MicrophoneSimulationPlugin from @suaveplan/audio-fx-plugin-microphone…
    • microphone-controls — <MicrophoneControls> is the composed UI for MicrophoneSimulationPlugin from @suaveplan/audio-fx-plugin-microphone…
  • midi-controller-setup — <MidiControllerSetup> is the Phase-3 learn-mode panel for the Suaveplan React audio stack. It renders the connected c…
    • midi-controller-setup — <MidiControllerSetup> is the Phase-3 learn-mode panel for the Suaveplan React audio stack. It renders the connected c…
  • mixer — <Mixer> is the per-channel strip view for a live MixerPlugin instance from @suaveplan/audio-fx-plugin-mixer. It r…
    • mixer — <Mixer> is the per-channel strip view for a live MixerPlugin instance from @suaveplan/audio-fx-plugin-mixer. It r…
  • plugin-chain-view — Reorderable, accessible view of a PluginChain. Renders one <PluginSlot> per chain entry, supports HTML5 drag-and-dr…
    • plugin-chain-view — Reorderable, accessible view of a PluginChain. Renders one <PluginSlot> per chain entry, supports HTML5 drag-and-dr…
  • plugin-loader — <PluginLoader> is the dynamic plugin-registration UI over the provider's PluginRegistry. It lists every currently-r…
    • plugin-loader — <PluginLoader> is the dynamic plugin-registration UI over the provider's PluginRegistry. It lists every currently-r…
  • plugin-parameter-knob — Rotary-knob primitive for a single AudioFxPlugin parameter. The knob implements the full keyboard contract mandated b…
    • plugin-parameter-knob — Rotary-knob primitive for a single AudioFxPlugin parameter. The knob implements the full keyboard contract mandated b…
  • plugin-parameter-slider — Linear-slider primitive for a single AudioFxPlugin parameter. Mirrors <PluginParameterKnob>'s a11y contract and exp…
    • plugin-parameter-slider — Linear-slider primitive for a single AudioFxPlugin parameter. Mirrors <PluginParameterKnob>'s a11y contract and exp…
  • plugin-slot — Generic renderer for any AudioFxPlugin. Reads the plugin's declarative parameters array and renders each one throug…
    • plugin-slot — Generic renderer for any AudioFxPlugin. Reads the plugin's declarative parameters array and renders each one throug…
  • premium-player — <PremiumPlayer> is the full-featured media-player surface — a composition of <AudioPlayer>, <AudioVisualizer>, an…
    • premium-player — <PremiumPlayer> is the full-featured media-player surface — a composition of <AudioPlayer>, <AudioVisualizer>, an…
  • preset-manager — ChainSnapshot save / load / delete UI layered over the provider's preset store. The save path persists the snapshot t…
    • preset-manager — ChainSnapshot save / load / delete UI layered over the provider's preset store. The save path persists the snapshot t…
  • track-list — <TrackList> is a composed-plugin UI that renders every track in the provider's TimelineEngine. It is the canonical…
    • track-list — <TrackList> is a composed-plugin UI that renders every track in the provider's TimelineEngine. It is the canonical…
  • track-row — <TrackRow> is the per-track row primitive consumed by <TrackList>. It subscribes to a single Track through the fo…
    • track-row — <TrackRow> is the per-track row primitive consumed by <TrackList>. It subscribes to a single Track through the fo…
  • transport-controls — <TransportControls> is the composed-plugin UI for the provider-owned Transport instance. It exposes the spec-mandat…
    • transport-controls — <TransportControls> is the composed-plugin UI for the provider-owned Transport instance. It exposes the spec-mandat…
  • error-codes — This module is the single source of truth for every error code thrown inside @suaveplan/react-audio. The codes are na…
    • error-codes — This module is the single source of truth for every error code thrown inside @suaveplan/react-audio. The codes are na…
  • hooks — Internal helpers shared across every public hook. They centralise the two structured-error throws every engine-dependen…
    • use-analyser — useAnalyser(opts?) polls an AnalyserNode-shaped source and returns the latest byte-magnitude FFT frame plus the mat…
      • use-analyser — useAnalyser(opts?) polls an AnalyserNode-shaped source and returns the latest byte-magnitude FFT frame plus the mat…
    • use-audio-engine — useAudioEngine() returns the full resolved ProviderState bundle — the adapter, the TimelineEngine, the `Transport…
      • use-audio-engine — useAudioEngine() returns the full resolved ProviderState bundle — the adapter, the TimelineEngine, the `Transport…
    • use-audio-fx-plugin — useAudioFxPlugin(pluginType) instantiates a plugin via the provider's PluginRegistry.create(pluginType) and memoise…
      • use-audio-fx-plugin — useAudioFxPlugin(pluginType) instantiates a plugin via the provider's PluginRegistry.create(pluginType) and memoise…
    • use-bus — useBus(name) reads the named sidechain bus from the provider's ProviderBusRegistry and subscribes to its publish/cl…
      • use-bus — useBus(name) reads the named sidechain bus from the provider's ProviderBusRegistry and subscribes to its publish/cl…
    • use-chain-plugin — useChainPlugin(trackId, slotIndex) returns the AudioFxPlugin currently occupying a specific slot in a track's `Plug…
      • use-chain-plugin — useChainPlugin(trackId, slotIndex) returns the AudioFxPlugin currently occupying a specific slot in a track's `Plug…
    • use-chain-snapshot — useChainSnapshot(chain) exposes chain-level snapshot operations. get reads the in-memory ChainSnapshot, restore…
      • use-chain-snapshot — useChainSnapshot(chain) exposes chain-level snapshot operations. get reads the in-memory ChainSnapshot, restore…
    • use-engine-state — useEngineState() reports the <AudioProvider>'s async-init lifecycle phase as one of 'pending' | 'ready' | 'error'…
      • use-engine-state — useEngineState() reports the <AudioProvider>'s async-init lifecycle phase as one of 'pending' | 'ready' | 'error'…
    • use-midi-controller — useMidiController(controllerId) is the React 19 binding for a single MidiControllerPlugin from `@suaveplan/audio-co…
      • use-midi-controller — useMidiController(controllerId) is the React 19 binding for a single MidiControllerPlugin from `@suaveplan/audio-co…
    • use-parameter — useParameter(plugin, paramId) is the canonical read/write hook for a single declared parameter on any AudioFxPlugin…
      • use-parameter — useParameter(plugin, paramId) is the canonical read/write hook for a single declared parameter on any AudioFxPlugin…
    • use-playlist — usePlaylist(items, opts?) manages a queue of PlaylistItem entries and exposes the standard playlist verbs (next,…
      • use-playlist — usePlaylist(items, opts?) manages a queue of PlaylistItem entries and exposes the standard playlist verbs (next,…
    • use-plugin-chain — usePluginChain(trackId) returns a handle for the PluginChain associated with a track. The provider lazily creates t…
      • use-plugin-chain — usePluginChain(trackId) returns a handle for the PluginChain associated with a track. The provider lazily creates t…
    • use-preset — usePreset(plugin) exposes plugin-level preset operations as React-friendly callbacks: get reads the current preset,…
      • use-preset — usePreset(plugin) exposes plugin-level preset operations as React-friendly callbacks: get reads the current preset,…
    • use-timeline — useTimeline() returns the provider's single TimelineEngine instance, the canonical owner of timeline state — tracks…
      • use-timeline — useTimeline() returns the provider's single TimelineEngine instance, the canonical owner of timeline state — tracks…
    • use-track — useTrack(trackId) subscribes to a single track on the TimelineEngine by id and re-renders only when that specific t…
      • use-track — useTrack(trackId) subscribes to a single track on the TimelineEngine by id and re-renders only when that specific t…
    • use-transport — useTransport() wraps the provider's Transport with a small, React-friendly façade: `{ transport, play, pause, stop,…
      • use-transport — useTransport() wraps the provider's Transport with a small, React-friendly façade: `{ transport, play, pause, stop,…
    • use-transport-time — useTransportTime() returns the transport's current time in seconds, sampled at the provider's configured `sampleRateH…
      • use-transport-time — useTransportTime() returns the transport's current time in seconds, sampled at the provider's configured `sampleRateH…
    • use-provider-state — Internal helpers shared across every public hook. They centralise the two structured-error throws every engine-dependen…
  • audio-context — Declares the React context object (AudioReactContext) that <AudioProvider> populates and that every hook reads from…
  • audio-provider — <AudioProvider> is the single React component that owns the audio engine bundle for a React subtree. It constructs ex…
  • chain-map — ChainMap is the provider-scoped lazy registry of PluginChain instances, keyed by track id. The hook `usePluginChain…
  • provider-bus-registry — ProviderBusRegistry is a thin wrapper around DefaultBusRegistry from @suaveplan/audio-fx-plugin-base that adds a…
  • provider-options — Defines the AudioProviderOptions shape consumed by <AudioProvider>, the Zod schema that validates it, and the `pars…
  • audio-store — useAudioStore is a slim provider-scoped Zustand store reserved for application-level audio UI overrides (display name…
    • audio-store — useAudioStore is a slim provider-scoped Zustand store reserved for application-level audio UI overrides (display name…
  • ui-store — useUiStore is the cross-component UI state store for the React audio workspace. It owns presentation-only state — whi…
    • ui-store — useUiStore is the cross-component UI state store for the React audio workspace. It owns presentation-only state — whi…
  • test-utils — Test-only helpers for the @suaveplan/react-audio test suite. The module exports three utilities: `makeFakeAudioContex…

Install

bun add @suaveplan/react-audio

Peer deps: react@^19, react-dom@^19.

Quick start

import { AudioProvider, useTransport } from "@suaveplan/react-audio";

function PlayButton() {
    const { play, stop, transport } = useTransport();
    return (
        <button type="button" onClick={() => (transport.state === "playing" ? stop() : play())}>
            {transport.state === "playing" ? "Stop" : "Play"}
        </button>
    );
}

export default function App() {
    return (
        <AudioProvider options={{ adapter: { sampleRate: 48000 } }}>
            <PlayButton />
        </AudioProvider>
    );
}

What ships in Phase 1

Provider

  • <AudioProvider> — 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

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: <TransportControls>, <TrackList>, <PluginChainView>, <PluginSlot>, <MasterMeter>, <Mixer>, <PresetManager>, …
  • Phase 3 (enterprise-react-audio-midi) — useMidiController hook + <MidiControllerSetup> learn-mode panel.

License

MIT