Files
skills/docs/media/audio/midi/src/gm/xg.md
2026-05-29 08:20:56 +01:00

1.8 KiB

gm/xg

Purpose

Yamaha's XG dialect uses Bank-Select MSB (CC 0) to select instrument variations on top of the GM1 base programs — the inverse of GS, which uses Bank LSB. The XG specification covers hundreds of variations across the full program range; this module exposes a curated set of the canonical XG patches every XG-aware engine should at least be able to label.

The table key encoding intentionally matches gm2Key(program, bankMsb) so consumers can write a single resolver function that handles all three dialects by branching on which CC carried the bank select.

Features

  • XG_VARIATIONS frozen map keyed by program * 256 + bankMsb.
  • Mandatory XG variation set; vendor-specific extensions layer on top.
  • Same key encoding as GS_VARIATIONS and GM_LEVEL2_VARIATIONS — uniform composition.
  • Frozen object to safeguard against accidental mutation.

Usage: Basic

import { XG_VARIATIONS, gm2Key } from "@suaveplan/midi";

console.log(XG_VARIATIONS[gm2Key(56, 16)]); // "Trumpet 2"

Usage: Advanced

import {
  GM_LEVEL1_PATCHES,
  XG_VARIATIONS,
  gm2Key,
} from "@suaveplan/midi";

function xgPatchName(program: number, bankMsb: number): string {
  return (
    XG_VARIATIONS[gm2Key(program, bankMsb)] ??
    GM_LEVEL1_PATCHES[program] ??
    `Program ${program}`
  );
}

API Reference

  • XG_VARIATIONS: Readonly<Record<number, string>> — frozen map; key encoding is program * 256 + bankMsb.

Implementation Notes

Because XG selects on Bank MSB rather than LSB, an engine running multiple dialects in parallel must track both CCs separately and dispatch on the dialect chosen for the channel. The frozen-object idiom keeps the runtime contract immutable: composing { ...XG_VARIATIONS, [gm2Key(80, 64)]: 'Custom Lead' } produces a fresh object without touching the canonical export.