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,65 @@
# `hooks/use-rpn`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`useRPN(selector)` wraps the universal RPN reducer and exposes the
consolidated `RPNChange` as React state. RPN ("Registered Parameter
Number") covers the well-known parameters such as pitch-bend range,
fine/coarse tuning, channel pressure sensitivity, and modulation
depth. Like NRPN it arrives over the wire as a four-CC dance — CC
101 (param MSB), CC 100 (param LSB), CC 6 (data MSB), CC 38 (data
LSB) — and the hook folds that into one React event per dance.
## Features
- Folds CC 101/100/6/38 into one `RPNChange` per dance.
- Per-port reducer — fresh state on port identity change.
- Returns `null` until the first completed dance.
## Usage: Basic
```tsx
import { useRPN } from "@suaveplan/react-midi";
function PitchBendRange() {
const change = useRPN("first");
// RPN (0,0) is "Pitch Bend Sensitivity".
if (!change) return <p>(no RPN yet)</p>;
return (
<p>
RPN ({change.paramHigh}.{change.paramLow}) → {change.value}
</p>
);
}
```
## Usage: Advanced
```tsx
function useChannelTuning() {
const change = useRPN("first");
// RPN (0,1) = fine-tuning; RPN (0,2) = coarse-tuning.
return change?.paramHigh === 0 ? change : null;
}
```
## API Reference
- `useRPN(selector: string | "first"): RPNChange | null`
## Implementation Notes
The hook mirrors `useNRPN` exactly, replacing only the reducer class
and the parameter-MSB CC numbers (101 instead of 99). The reducer's
data-MSB/LSB CCs (6 and 38) are shared with NRPN — devices follow
the convention of sending a fresh paramHigh selector to switch
between the two address spaces, which the reducer handles via its
"new paramHigh resets partial state" rule. Consumers that need to
listen to *both* NRPN and RPN streams from the same port simply
compose the two hooks side by side; the underlying input adapter
fans the parsed messages out to both subscriptions without
double-binding the Web MIDI `onmidimessage` slot.