# `hooks/use-midi-messages` _(no submodules)_ ## Purpose `useMidiMessages(selector, options?)` exposes a bounded ring buffer of the most recent parsed MIDI messages from the selected input. It is a convenience built on top of `useMidiInput` for UI consumers that want to render a live activity feed (e.g. an "incoming messages" panel) or debug a controller wiring problem. The ring buffer trims the oldest entry once `capacity` is exceeded, so the array length is stable and the component can render it directly without further bookkeeping. An optional `filter` whitelist accepts only specific message types into the buffer — handy when a device floods the bus with active- sensing or clock ticks the operator does not want in the visible log. ## Features - Bounded ring buffer, default capacity 64. - Optional `filter: readonly MidiMessageType[]` whitelist. - Rebinds the underlying `port.onMessage` automatically when the port identity changes (plug/unplug, selector switch). - Buffer resets when the underlying port becomes `null`. ## Usage: Basic ```tsx import { useMidiMessages } from "@suaveplan/react-midi"; function ActivityLog() { const msgs = useMidiMessages("first", { capacity: 32 }); return ( ); } ``` ## Usage: Advanced ```tsx function NotesOnly({ portId }: { portId: string }) { // Drop active-sensing/clock noise. const notes = useMidiMessages(portId, { filter: ["noteOn", "noteOff"], capacity: 128, }); return ; } ``` ## API Reference - `useMidiMessages(selector, options?): readonly MidiMessage[]` - `interface UseMidiMessagesOptions { capacity?, filter? }`. ## Implementation Notes The internal state holds the ring buffer as a `readonly MidiMessage[]` rather than a `Map` or a separate write-cursor so consumers can drop straight into a `.map(...)` render. The buffer-replace path always allocates a fresh array (rather than mutating in place) so React detects the state change. The set-of-accepted-types is rebuilt only when the `filter` reference or the joined key changes, not per incoming message.