pnpm add @audio-ui/core
import { createPianoController, KEYBOARD_VELOCITY, MIN_VELOCITY, BLACK_KEY_DEPTH, keyAt, /* … */ } from "@audio-ui/core/piano";| Adapters | @audio-ui/react/piano, @audio-ui/elements/piano |
|---|
| Export | Kind | What it is |
|---|---|---|
createPianoController | function | A keyboard's behavior with no view attached: which keys sound, by pointer, glide or keyboard, how hard, and where the keyboard's one tab stop is. |
KEYBOARD_VELOCITY | const | What a key played from the keyboard sounds at. |
MIN_VELOCITY | const | The softest a pointer press plays: the very top of a key, not silence. |
PianoController | interface | What createPianoController returns: the snapshot to draw from, and the presses, keys and focus moves of the keyboard. |
PianoNoteOffEventDetails | type | What onNoteOff receives when a key stops: the reason ("press", "glide" or "keyboard") and the event. |
PianoNoteOnEventDetails | type | What onNoteOn receives when a key sounds: its velocity, from 0 to 1, the reason ("press", "glide" or "keyboard"), the event, and cancel() to refuse it. |
PianoOptions | interface | The options of createPianoController: the pitches, their layout and orientation, the notes lit from elsewhere, and the callbacks. |
PianoSnapshot | interface | What a view draws the keyboard from: the pitches and where each key sits, the ones sounding, and the tab stop. |
BLACK_KEY_DEPTH | const | How far across the keyboard a black key reaches; past it, a press lands on a white key. |
KeyLayout | type | How the keys share the keyboard's length: "keyboard" like a piano, white keys side by side with the black ones between them, or "even", one equal share each, the way a piano roll's rows are. |
KeyPlacement | interface | Where a key sits along the keyboard, how much of it it takes, and whether it is black. |
keyAt | function | The key under a point, given as shares of the keyboard: along its length from the low end, across its depth from the back, where black keys are. |
placeKeys | function | Where each of pitches (lowest first) sits along the keyboard. |
Usage
The controller follows the contract every controller shares, with notes in place of a value:
import { createPianoController } from "@audio-ui/core/piano";
const piano = createPianoController({
layout: "keyboard",
minPitch: 48,
maxPitch: 72,
orientation: "horizontal",
onNoteOn: (pitch) => synth.noteOn(pitch),
onNoteOff: (pitch) => synth.noteOff(pitch),
});The piano reports a note on when a key is pressed and a note off when it is released, one per pointer, so two fingers can hold two keys. keyOn(pitch, event) and keyOff(pitch, event) do the same for the keyboard, and navigate(pitch, event) moves focus between keys with the arrows. getSnapshot() gives each key's placements and the active set, which an element draws.
A pointer press sounds harder toward the near end of a key, from MIN_VELOCITY at its very top; a key played from the keyboard sounds at KEYBOARD_VELOCITY.
Layout
placeKeys(pitches, layout) says where each key sits along the keyboard, from 0 to 1: "keyboard" lays white keys side by side with the black ones between them, as on a piano, and "even" gives each key an equal share, as a piano roll's rows are. keyAt(placements, along, across, layout) is the key under a point: past BLACK_KEY_DEPTH across the keyboard, a press lands on a white key.
The Piano draws this controller in React.