# sysex/manufacturers ## Purpose The manufacturer-id registry maps the bytes that follow `F0` in a SysEx frame to a human-readable name. The MIDI Manufacturers Association assigns each vendor either a one-byte id (legacy, range 0x01..0x7D) or a three-byte id starting with `0x00` (modern allocations, the bulk of post-1995 vendors). This module owns the canonical mapping plus a `lookupManufacturer` helper that handles both forms. The registry is intentionally a representative subset of the well-known assignments — synth makers, DAW makers, accessory makers — not the complete MMA database. Downstream packages that need additional ids can layer them via `Object.assign({}, MANUFACTURERS, { CUSTOM: { name, id } })` since the base object is frozen. ## Features - One-byte ids for legacy vendors (Roland 0x41, Korg 0x42, Yamaha 0x43, etc.). - Three-byte ids for modern vendors (Native Instruments `00 21 09`, Ableton `00 21 1D`). - `SYSEX_UNIVERSAL_NON_REALTIME = 0x7E` and `SYSEX_UNIVERSAL_REALTIME = 0x7F` constants. - `lookupManufacturer(idBytes)` for runtime resolution from arbitrary byte arrays. ## Usage: Basic ```ts import { lookupManufacturer } from "@suaveplan/midi"; console.log(lookupManufacturer([0x41])); // "Roland" console.log(lookupManufacturer([0x00, 0x21, 0x09])); // "Native Instruments" console.log(lookupManufacturer([0x6F])); // undefined ``` ## Usage: Advanced ```ts import { MANUFACTURERS, lookupManufacturer, SYSEX_UNIVERSAL_REALTIME } from "@suaveplan/midi"; // Filter sysex messages by manufacturer. function isUniversalRealtime(idBytes: readonly number[]): boolean { return idBytes.length === 1 && idBytes[0] === SYSEX_UNIVERSAL_REALTIME; } // Extend the registry for a private vendor id. const EXTENDED = Object.freeze({ ...MANUFACTURERS, MY_BRAND: { name: "My Brand", id: [0x00, 0x7F, 0x01] as const }, }); function nameOf(idBytes: readonly number[]): string | undefined { for (const entry of Object.values(EXTENDED)) { if ( entry.id.length === idBytes.length && entry.id.every((b, i) => b === idBytes[i]) ) return entry.name; } return lookupManufacturer(idBytes); } ``` ## API Reference - `MANUFACTURERS: Readonly>` — frozen registry keyed by friendly constant. - `ManufacturerEntry { name: string; id: ManufacturerId }`. - `ManufacturerId = readonly [number] | readonly [0x00, number, number]`. - `lookupManufacturer(idBytes: readonly number[]): string | undefined`. - `SYSEX_UNIVERSAL_NON_REALTIME: 0x7E`, `SYSEX_UNIVERSAL_REALTIME: 0x7F`. ## Implementation Notes `lookupManufacturer` walks `Object.values(MANUFACTURERS)` linearly because the registry is small (under 100 entries) and the cost of building / maintaining a `Map` keyed by stringified bytes would dwarf the lookup itself. The function uses `continue` to skip length mismatches and a labelled `match` boolean to track byte equality — avoiding a nested `every` call keeps the function within the strict-mode statement budget and produces no garbage objects per lookup.