@pepperhorn/chordl-guitar 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 PepperHorn Music / Creative Ranges Foundation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,18 @@
1
+ import type { Chord } from "svguitar";
2
+ import type { ChordsDbPosition, InstrumentId } from "./instruments.js";
3
+ export interface GuitarChordResult {
4
+ /** The chord label as given. */
5
+ label: string;
6
+ instrument: InstrumentId;
7
+ /** Raw chords-db positions (low→high frets, baseFret, barres, fingers). */
8
+ positions: ChordsDbPosition[];
9
+ /** svguitar Chord objects, one per position, ready to render. */
10
+ shapes: Chord[];
11
+ }
12
+ /**
13
+ * Look up all stored shapes for a chord label. Returns null when the chord or
14
+ * instrument isn't supported.
15
+ */
16
+ export declare function lookupGuitarChord(label: string, instrument?: InstrumentId): GuitarChordResult | null;
17
+ /** True when at least one shape exists for the label. */
18
+ export declare function hasGuitarChord(label: string, instrument?: InstrumentId): boolean;
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Chord label → guitar chord shapes (all positions).
3
+ *
4
+ * chordl produces chord symbols like "Am", "G7", "Cmaj7", "F#m7b5"; this maps
5
+ * them to shapes and returns every position, so callers can offer alternate
6
+ * fret placements. Unknown chords return null — shapes are never invented.
7
+ *
8
+ * Three sources feed this, and a caller should not have to know which one
9
+ * answered:
10
+ *
11
+ * 1. hand-authored top-3-string presets (the `guitar-top3` instrument),
12
+ * 2. chords-db, for the instruments that have a library,
13
+ * 3. generated power chords, which chords-db cannot carry — it has no "5"
14
+ * suffix — but which are perfectly regular and so need no curation.
15
+ *
16
+ * All three emit through `dbPositionToChord`, so renderers see one contract.
17
+ */
18
+ // Generated by scripts/build-data.mjs from @tombatossals/chords-db (MIT), with
19
+ // the unused midi/capo position fields stripped — see that script for why.
20
+ import guitarDb from "./generated/guitar.slim.json" with { type: "json" };
21
+ import ukuleleDb from "./generated/ukulele.slim.json" with { type: "json" };
22
+ import { INSTRUMENTS, dbPositionToChord, } from "./instruments.js";
23
+ import { rootPitchClass } from "./pitch.js";
24
+ import { powerChordPosition } from "./powerChords.js";
25
+ import { GUITAR_TOP3_PRESETS } from "./staticPresets.js";
26
+ const GUITAR_DB = guitarDb;
27
+ const UKULELE_DB = ukuleleDb;
28
+ // chords-db ships guitar and ukulele voicing libraries.
29
+ function dbFor(instrument) {
30
+ if (instrument === "guitar")
31
+ return GUITAR_DB;
32
+ if (instrument === "ukulele")
33
+ return UKULELE_DB;
34
+ return null;
35
+ }
36
+ // chordl roots → candidate chords-db root keys, most-likely first. chords-db
37
+ // spells accidentals inconsistently across instruments (guitar uses "Csharp"/
38
+ // "Fsharp"; ukulele uses "Db"/"Gb"), so each accidental lists both spellings
39
+ // and findEntry picks whichever the active library actually has.
40
+ const ROOT_TO_DB_KEYS = {
41
+ C: ["C"], "B#": ["C"],
42
+ "C#": ["Csharp", "Db"], Db: ["Db", "Csharp"],
43
+ D: ["D"],
44
+ "D#": ["Eb", "Dsharp"], Eb: ["Eb", "Dsharp"],
45
+ E: ["E"], Fb: ["E"],
46
+ F: ["F"], "E#": ["F"],
47
+ "F#": ["Fsharp", "Gb"], Gb: ["Gb", "Fsharp"],
48
+ G: ["G"],
49
+ "G#": ["Ab", "Gsharp"], Ab: ["Ab", "Gsharp"],
50
+ A: ["A"],
51
+ "A#": ["Bb", "Asharp"], Bb: ["Bb", "Asharp"],
52
+ B: ["B"], Cb: ["B"],
53
+ };
54
+ // chordl suffix → chords-db suffix. Most match verbatim; only the triads and a
55
+ // couple of aliases need translating.
56
+ function toDbSuffix(suffix) {
57
+ const s = suffix.trim();
58
+ if (s === "" || s === "maj" || s === "M")
59
+ return "major";
60
+ if (s === "m" || s === "min" || s === "-")
61
+ return "minor";
62
+ if (s === "min7")
63
+ return "m7";
64
+ if (s === "M7")
65
+ return "maj7";
66
+ if (s === "°")
67
+ return "dim";
68
+ if (s === "°7")
69
+ return "dim7";
70
+ if (s === "ø" || s === "ø7")
71
+ return "m7b5";
72
+ // chords-db spells the 6/9 voicings without the slash.
73
+ if (s === "6/9")
74
+ return "69";
75
+ if (s === "m6/9")
76
+ return "m69";
77
+ // Bare "sus" (and "7sus") carry no extension number; sus4 is the convention.
78
+ if (s === "sus")
79
+ return "sus4";
80
+ if (s === "7sus")
81
+ return "7sus4";
82
+ return s; // m7, maj7, 7, dim7, sus4, 6, 9, 11, 13, m7b5, ... match verbatim
83
+ }
84
+ function splitLabel(label) {
85
+ const m = label.trim().match(/^([A-Ga-g][#b]?)(.*)$/);
86
+ if (!m)
87
+ return null;
88
+ const root = m[1].charAt(0).toUpperCase() + m[1].slice(1);
89
+ return { root, suffix: m[2] };
90
+ }
91
+ function findEntry(db, label) {
92
+ const parsed = splitLabel(label);
93
+ if (!parsed)
94
+ return null;
95
+ const candidates = ROOT_TO_DB_KEYS[parsed.root];
96
+ if (!candidates)
97
+ return null;
98
+ const dbSuffix = toDbSuffix(parsed.suffix);
99
+ // Pick the root spelling this library actually uses (guitar vs ukulele
100
+ // differ). Prefer a spelling that carries the requested suffix: no root is
101
+ // currently listed under both spellings, but chords-db is a floating
102
+ // dependency and picking purely by presence would hide the other spelling.
103
+ const spellings = candidates.map((k) => db.chords[k]).filter(Boolean);
104
+ const entries = spellings.find((e) => e.some((x) => x.suffix === dbSuffix)) ?? spellings[0];
105
+ if (!entries)
106
+ return null;
107
+ return entries.find((e) => e.suffix === dbSuffix) ?? null;
108
+ }
109
+ // ── Power chords ────────────────────────────────────────────────────────────
110
+ /** Root on the 6th string, then on the 5th — two real placements, not two spellings. */
111
+ const POWER_STRING_SETS = ["E", "A"];
112
+ /**
113
+ * A bare fifth: root + fifth, no third. `D5` is the common spelling; the parser
114
+ * also produces it for "D power chord" style input, so matching the resolved
115
+ * suffix here (rather than the raw text) covers every route in.
116
+ */
117
+ function isFifth(suffix) {
118
+ return suffix.trim() === "5";
119
+ }
120
+ function powerChordPositions(label) {
121
+ const pc = rootPitchClass(label);
122
+ if (pc == null)
123
+ return [];
124
+ return POWER_STRING_SETS
125
+ .map((stringSet) => powerChordPosition(pc, { stringSet }))
126
+ .filter((p) => p !== null);
127
+ }
128
+ // ── Top-3-string presets ────────────────────────────────────────────────────
129
+ /**
130
+ * The preset table spells qualities in words where chords-db uses symbols, so a
131
+ * chordl label has to be translated before lookup. Only the suffixes the table
132
+ * actually carries are mapped; anything else finds nothing, which is correct —
133
+ * falling back to a six-string shape under a three-string label would be a lie.
134
+ */
135
+ function toPresetSuffix(suffix) {
136
+ const s = suffix.trim();
137
+ if (s === "")
138
+ return "major";
139
+ if (s === "m" || s === "min")
140
+ return "minor";
141
+ return s; // 7, m7, maj7 match the table verbatim
142
+ }
143
+ /**
144
+ * Presets are authored as svguitar shapes, but callers expect chords-db-style
145
+ * positions (that is what carries `baseFret` for the "fret N" caption). Convert
146
+ * back: svguitar numbers strings high-to-low from 1, positions run low-to-high.
147
+ */
148
+ function presetToPosition(preset) {
149
+ const frets = new Array(6).fill(-1);
150
+ const fingers = new Array(6).fill(0);
151
+ for (const f of preset.chord.fingers) {
152
+ const [stringNo, fret, label] = f;
153
+ const idx = 6 - stringNo;
154
+ if (idx < 0 || idx > 5)
155
+ continue;
156
+ if (fret === "x") {
157
+ frets[idx] = -1;
158
+ continue;
159
+ }
160
+ frets[idx] = typeof fret === "number" ? fret : -1;
161
+ const n = Number(label);
162
+ fingers[idx] = Number.isFinite(n) ? n : 0;
163
+ }
164
+ // Every preset is written in absolute frets from the nut, all within reach of
165
+ // first position, so the diagram window always starts at the nut.
166
+ return { frets, fingers, baseFret: 1, barres: [] };
167
+ }
168
+ function findPreset(label) {
169
+ const parsed = splitLabel(label);
170
+ if (!parsed)
171
+ return null;
172
+ const suffix = toPresetSuffix(parsed.suffix);
173
+ return (GUITAR_TOP3_PRESETS.find((p) => p.key === parsed.root && p.suffix === suffix) ?? null);
174
+ }
175
+ /**
176
+ * Look up all stored shapes for a chord label. Returns null when the chord or
177
+ * instrument isn't supported.
178
+ */
179
+ export function lookupGuitarChord(label, instrument = "guitar") {
180
+ const strings = INSTRUMENTS[instrument]?.strings;
181
+ if (strings == null)
182
+ return null;
183
+ const toResult = (positions) => positions.length === 0
184
+ ? null
185
+ : {
186
+ label,
187
+ instrument,
188
+ positions,
189
+ shapes: positions.map((pos) => dbPositionToChord(pos, strings, label)),
190
+ };
191
+ // 1. Hand-authored beats generated: the preset table is the only source of
192
+ // three-string voicings, and it does not fall back to chords-db.
193
+ if (instrument === "guitar-top3") {
194
+ const preset = findPreset(label);
195
+ return preset ? toResult([presetToPosition(preset)]) : null;
196
+ }
197
+ // 2. chords-db, for the instruments that ship a library.
198
+ const db = dbFor(instrument);
199
+ const entry = db ? findEntry(db, label) : null;
200
+ if (entry && entry.positions.length > 0)
201
+ return toResult(entry.positions);
202
+ // 3. Power chords, which chords-db has no suffix for. Guitar only — a
203
+ // reentrant ukulele tuning makes root+fifth a different problem.
204
+ const parsed = splitLabel(label);
205
+ if (instrument === "guitar" && parsed && isFifth(parsed.suffix)) {
206
+ return toResult(powerChordPositions(label));
207
+ }
208
+ return null;
209
+ }
210
+ /** True when at least one shape exists for the label. */
211
+ export function hasGuitarChord(label, instrument = "guitar") {
212
+ return lookupGuitarChord(label, instrument) !== null;
213
+ }
214
+ //# sourceMappingURL=chordLookup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chordLookup.js","sourceRoot":"","sources":["../src/chordLookup.ts"],"names":[],"mappings":"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"}