Input

A MIDI keyboard and the microphone: the notes of the page's MIDI input, and the microphone as an analyser.

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

Built by Ouest Labs, the source code is available on GitHub.
RSS