Arrangement
Transport and mixer
EQ and filters
Modulation
Utility
Instruments
A MIDI keyboard
pnpm dlx shadcn@latest add @audio-ui/use-midi-input
useMidiInput hears the page's MIDI input: every component that calls it hears the same devices, and connecting from one connects them all. Browsers ask for permission, so connect from a click, with requestAccess or with the ready-made button (npx shadcn@latest add @audio-ui/midi-connect-control).
import { useMidiInput } from "@/hooks/use-midi-input";
const midi = useMidiInput({
onNoteOff: (pitch) => voices.releaseNote(pitch, envelope),
onNoteOn: (pitch, velocity) => voices.triggerNote(pitch, envelope, velocity),
onPitchBend: voices.setPitchBend,
});
<button onClick={midi.requestAccess} type="button">Connect MIDI</button>
<Piano activeNotes={midi.activeNotes} maxPitch={72} minPitch={48} />activeNotes lights the keys held on the device, on a Piano or a Piano roll.
Options · 3
Returns · 6
Without React, @audio-ui/core/midi reads the messages themselves and the MIDI files.
The microphone
pnpm dlx shadcn@latest add @audio-ui/use-microphone
useMicrophone taps the microphone into an AnalyserNode on the page's audio context. The signal is raw: echo cancellation, noise suppression and automatic gain are off, since they flatten a tuner or a meter. The analyser is never connected to the speakers.
import { useMicrophone } from "@/hooks/use-microphone";
const mic = useMicrophone();
// Memoized: a new array restarts the sampling.
const analysers = useMemo(() => (mic.analyser ? [mic.analyser] : []), [mic.analyser]);
const levels = useAudioLevels(analysers);
<button onClick={mic.isListening ? mic.stop : mic.start} type="button">
{mic.isListening ? "Stop" : "Listen"}
</button>
<Meter aria-label="Microphone" source={levels} />Give the analyser to anything that reads one: levels and spectra, or the pitch a Tuner shows.
Returns · 5
null otherwise.