first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
# `<MasterMeter>`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`<MasterMeter>` is a RAF-sampled master-output level meter. It
subscribes to a named sidechain bus through the foundation `useBus`
hook (`"master"` by default) and continuously reads the bus's
block-aligned PCM into a scratch buffer at the configured interval,
deriving per-channel peak and RMS levels in dB and a slow-decaying
peak-hold envelope. When no publisher exists for the bus, every
channel shows silence (`-∞` dB) so consumers always see something.
The meter is intentionally side-effect-free with respect to the audio
graph: it only reads. Nothing inside `<MasterMeter>` ever writes to the
bus or mutates engine state, which keeps it safe to drop into any
layout that already has a publisher upstream.
## Features
- Subscribes to any named bus via `useBus(busName)`.
- Per-channel peak + RMS in dB, plus a peak-hold envelope.
- Configurable channel count, sample-tick rate, and hold time.
- Reads up to `Math.min(meterChannels, busChannels)` per tick so
publisher-wider and meter-wider mismatches do not blow up.
- `role="meter"` + `aria-label` for screen readers.
- `data-bus` and `data-channel` attributes for theming hooks.
## Usage: Basic Example
```tsx
import { AudioProvider, MasterMeter } from "@suaveplan/react-audio";
export function App() {
return (
<AudioProvider>
<MasterMeter />
</AudioProvider>
);
}
```
## Usage: Advanced Example
```tsx
import { AudioProvider, MasterMeter } from "@suaveplan/react-audio";
export function AuxMeter() {
return (
<AudioProvider>
<MasterMeter
busName="auxA"
channels={1}
sampleRateHz={120}
peakHoldMs={2000}
className="aux-meter"
/>
</AudioProvider>
);
}
```
## API Reference
| Prop | Type | Default | Notes |
| -------------- | ------------------- | ----------- | ------------------------------------------------------ |
| `className` | `string \| undef` | — | Forwarded to the outer `<div>`. |
| `busName` | `string \| undef` | `"master"` | Name of the bus to subscribe to. |
| `channels` | `number \| undef` | `2` | Number of channel rows to render. |
| `sampleRateHz` | `number \| undef` | `60` | UI sample tick rate. Clamped to `>= 1`. |
| `peakHoldMs` | `number \| undef` | `1000` | Peak-hold decay time in milliseconds. |
## Implementation Notes
The component allocates one persistent scratch `Float32Array[]` per
mount sized to `channelCount × 128` so the per-tick read does not
allocate. Bus channel mismatches are handled by reading only the
narrower side: if the publisher is wider than the meter, only the
leading channels are read; if the meter is wider than the publisher,
the trailing channels keep their zero-fill from the scratch buffer's
last write (which corresponds to silence on next dB conversion). The
peak-hold envelope uses one mutable record per channel keeping the
current hold value and its expiry timestamp; the value is replaced
either when a louder peak arrives or when the hold window expires,
which gives the visually slow decay typical of professional meters.