first commit
This commit is contained in:
51
docs/media/audio/midi/src/gm/level1.md
Normal file
51
docs/media/audio/midi/src/gm/level1.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# gm/level1
|
||||
|
||||
## Purpose
|
||||
|
||||
The General MIDI Level 1 patch and percussion tables — the canonical instrument-name lookups every GM-compliant playback engine, score editor, and patch-browser needs. Without a shared source of truth, every consumer ends up hand-typing the same 128-entry table with the same handful of typos ("Honky-Tonk Piano" vs "Honky-tonk Piano" being a perennial favourite).
|
||||
|
||||
This module exposes three immutable, exhaustive tables: the 128-entry patch map (`GM_LEVEL1_PATCHES`, program 0..127), the 47-entry percussion map (`GM_LEVEL1_PERCUSSION`, notes 35..81), and the 16-entry family list (`GM_LEVEL1_FAMILIES`, grouped in eight-program blocks). Spelling and capitalisation follow the official MMA specification.
|
||||
|
||||
## Features
|
||||
|
||||
- Frozen `GM_LEVEL1_PATCHES` covering every program 0..127 with the spec-canonical name.
|
||||
- Frozen `GM_LEVEL1_PERCUSSION` covering channel-10 drum notes 35..81.
|
||||
- Frozen `GM_LEVEL1_FAMILIES` for UI grouping (program ÷ 8).
|
||||
- All tables use the MMA canonical capitalisation — diff-compatible with other specs.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { GM_LEVEL1_PATCHES, GM_LEVEL1_PERCUSSION } from "@suaveplan/midi";
|
||||
|
||||
console.log(GM_LEVEL1_PATCHES[0]); // "Acoustic Grand Piano"
|
||||
console.log(GM_LEVEL1_PERCUSSION[36]); // "Bass Drum 1"
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { GM_LEVEL1_FAMILIES, GM_LEVEL1_PATCHES } from "@suaveplan/midi";
|
||||
|
||||
// Build a hierarchical patch browser for a UI tree component.
|
||||
function buildPatchTree() {
|
||||
const tree = GM_LEVEL1_FAMILIES.map((family, i) => ({
|
||||
name: family,
|
||||
patches: Array.from({ length: 8 }, (_, j) => {
|
||||
const program = i * 8 + j;
|
||||
return { program, name: GM_LEVEL1_PATCHES[program]! };
|
||||
}),
|
||||
}));
|
||||
return tree;
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `GM_LEVEL1_PATCHES: Readonly<Record<number, string>>` — frozen map, 128 entries (programs 0..127).
|
||||
- `GM_LEVEL1_PERCUSSION: Readonly<Record<number, string>>` — frozen map, 47 entries (notes 35..81 on channel 10).
|
||||
- `GM_LEVEL1_FAMILIES: readonly string[]` — 16 instrument-family names, indexed by `Math.floor(program / 8)`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
Both maps are declared as `Object.freeze({ ... })` rather than via numeric arrays because programs and percussion notes are sparse from the consumer's perspective — looking up `PERCUSSION[36]` directly is clearer than `PERCUSSION[36 - 35]`. The freeze guarantees downstream compose patterns (`{ ...GM_LEVEL1_PATCHES, 0: 'Custom Piano' }`) produce a new object rather than mutating the canonical table.
|
||||
Reference in New Issue
Block a user