@pepperhorn/chordl-guitar 0.2.0 → 0.3.1
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/README.md +82 -0
- package/dist/chordLookup.d.ts +3 -0
- package/dist/chordLookup.js +29 -62
- package/dist/chordLookup.js.map +1 -1
- package/dist/chordNames.d.ts +24 -0
- package/dist/chordNames.js +55 -0
- package/dist/chordNames.js.map +1 -0
- package/dist/experience.d.ts +129 -0
- package/dist/experience.js +164 -0
- package/dist/experience.js.map +1 -0
- package/dist/guitarPosition.d.ts +33 -0
- package/dist/guitarPosition.js +115 -0
- package/dist/guitarPosition.js.map +1 -0
- package/dist/index.d.ts +13 -2
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/instruments.js +12 -6
- package/dist/instruments.js.map +1 -1
- package/dist/pitch.d.ts +6 -0
- package/dist/pitch.js +16 -10
- package/dist/pitch.js.map +1 -1
- package/dist/staticPresets.d.ts +61 -5
- package/dist/staticPresets.js +95 -34
- package/dist/staticPresets.js.map +1 -1
- package/dist/top3Generated.d.ts +29 -0
- package/dist/top3Generated.js +553 -0
- package/dist/top3Generated.js.map +1 -0
- package/dist/voicingGenerator.d.ts +94 -0
- package/dist/voicingGenerator.js +642 -0
- package/dist/voicingGenerator.js.map +1 -0
- package/dist/voicingReview.d.ts +35 -0
- package/dist/voicingReview.js +90 -0
- package/dist/voicingReview.js.map +1 -0
- package/package.json +7 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"experience.js","sourceRoot":"","sources":["../src/experience.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAIvD,uEAAuE;AACvE,MAAM,CAAC,MAAM,iBAAiB,GAAsB;IAClD,UAAU;IACV,UAAU;IACV,aAAa;CACd,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,KAAoB;IAChD,IAAI,KAAK,CAAC,WAAW;QAAE,OAAO,UAAU,CAAC;IACzC,IAAI,CAAC,KAAK,CAAC,QAAQ;QAAE,OAAO,UAAU,CAAC;IACvC,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,YAAY,CAAC,KAAe,EAAE,QAAgB;IAC5D,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAClD,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3E,2EAA2E;IAC3E,qDAAqD;IACrD,IAAI,QAAQ,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,aAAa,CAAC;IACtD,oEAAoE;IACpE,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QAAE,OAAO,UAAU,CAAC;IACvE,OAAO,UAAU,CAAC;AACpB,CAAC;AA6BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAsB,EACtB,KAAsB,EACtB,MAA0B;IAE1B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC;IACvE,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC;IACtC,MAAM,OAAO,GAAG,CAAC,CAAS,EAAmB,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACvF,MAAM,IAAI,GAAG,CAAC,KAAsB,EAAE,EAAE,CAAC,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1E,uEAAuE;IACvE,MAAM,EAAE,GAAG,CAAC,KAAsB,EAAE,SAAkB,EAAE,EAAE,CACxD,KAAK;SACF,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;SAChB,MAAM,CACL,CAAC,CAAC,EAAE,EAAE,CACJ,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC;QAC/B,CAAC,CAAC,SAAS,IAAI,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CACnD,CAAC;IAEN,wBAAwB;IACxB,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACpC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC;IAC1E,CAAC;IACD,qCAAqC;IACrC,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACvC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,KAAK,KAAK,EAAE,CAAC;IACpF,CAAC;IACD,wEAAwE;IACxE,2EAA2E;IAC3E,0EAA0E;IAC1E,2EAA2E;IAC3E,2EAA2E;IAC3E,2EAA2E;IAC3E,2EAA2E;IAC3E,0EAA0E;IAC1E,2EAA2E;IAC3E,mDAAmD;IACnD,MAAM,KAAK,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrD,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,iBAAiB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1D,MAAM,KAAK,GAAG,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAC9C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC;gBAC3B,iBAAiB,EAAE,GAAG,KAAK,KAAK;gBAChC,WAAW,EAAE,KAAK,CAAC,KAAK;aACzB,CAAC;QACJ,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CACb,wEAAwE;QACtE,sEAAsE,CACzE,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAoE,EACpE,QAAkB,EAClB,MAAqB,EACrB,KAAsB;IAEtB,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IAClF,OAAO,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ChordsDbPosition } from "./instruments.js";
|
|
2
|
+
import type { GuitarReview } from "./voicingReview.js";
|
|
3
|
+
import type { ToneOptions, GeneratedPosition } from "./voicingGenerator.js";
|
|
4
|
+
export interface SpelledChord {
|
|
5
|
+
/** Root, spelled: "C", "F#", "Bb". */
|
|
6
|
+
root: string;
|
|
7
|
+
/** Chord tones, spelled; letters decide degrees (D# is #9, Eb is b3). */
|
|
8
|
+
pitchClasses: string[];
|
|
9
|
+
/** Slash bass, spelled. Omit (or equal the root) for root position. */
|
|
10
|
+
bass?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface LibraryPosition extends ChordsDbPosition {
|
|
13
|
+
generated: false;
|
|
14
|
+
source: "chords-db" | "power-chord";
|
|
15
|
+
/** chords-db suffix the shape came from. */
|
|
16
|
+
suffix?: string;
|
|
17
|
+
review: GuitarReview;
|
|
18
|
+
}
|
|
19
|
+
export type GuitarPosition = LibraryPosition | GeneratedPosition;
|
|
20
|
+
/** The chords-db suffix carrying exactly this chord, or null. */
|
|
21
|
+
export declare function chordsDbSuffixFor(chord: SpelledChord): string | null;
|
|
22
|
+
/**
|
|
23
|
+
* Every chords-db six-string position that spells the chord (see
|
|
24
|
+
* `positionSpellsChord`), in chords-db's order — the alternatives elsewhere on
|
|
25
|
+
* the neck. The first is the one `guitarPositionFor` prints. Empty when
|
|
26
|
+
* chords-db has no entry for the chord or none of its positions spells it.
|
|
27
|
+
*/
|
|
28
|
+
export declare function guitarLibraryPositionsFor(chord: SpelledChord, options?: ToneOptions): LibraryPosition[];
|
|
29
|
+
/**
|
|
30
|
+
* The best guitar position for a spelled chord, or null if none is playable
|
|
31
|
+
* under the generator's constraints.
|
|
32
|
+
*/
|
|
33
|
+
export declare function guitarPositionFor(chord: SpelledChord, options?: ToneOptions): GuitarPosition | null;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One guitar position for any spelled chord: chords-db when it has a shape
|
|
3
|
+
* that actually spells the chord, the regular power-chord shape for "5", and
|
|
4
|
+
* the voicing generator for everything else.
|
|
5
|
+
*
|
|
6
|
+
* chords-db is checked, not trusted blindly: its first C9 position has no b7
|
|
7
|
+
* and one of its C13 positions stacks the 11 on the major 3rd. A position is
|
|
8
|
+
* taken only if `positionSpellsChord` accepts it under the same rule table the
|
|
9
|
+
* generator obeys; otherwise the next position is tried, then the generator.
|
|
10
|
+
*/
|
|
11
|
+
import guitarDb from "./generated/guitar.slim.json" with { type: "json" };
|
|
12
|
+
import { powerChordPosition } from "./powerChords.js";
|
|
13
|
+
import { analyzeChordTones, generateGuitarVoicings, positionSpellsChord, } from "./voicingGenerator.js";
|
|
14
|
+
import { reviewGuitarPosition } from "./voicingReview.js";
|
|
15
|
+
const GUITAR_DB = guitarDb;
|
|
16
|
+
// chords-db suffix → pitch classes above the root (the chord's definition, not
|
|
17
|
+
// any one position's subset).
|
|
18
|
+
const DB_SUFFIX_PCS = {
|
|
19
|
+
major: [0, 4, 7], minor: [0, 3, 7], dim: [0, 3, 6], dim7: [0, 3, 6, 9],
|
|
20
|
+
sus2: [0, 2, 7], sus4: [0, 5, 7], "7sus4": [0, 5, 7, 10], aug: [0, 4, 8],
|
|
21
|
+
"6": [0, 4, 7, 9], "69": [0, 2, 4, 7, 9], "7": [0, 4, 7, 10], "7b5": [0, 4, 6, 10],
|
|
22
|
+
aug7: [0, 4, 8, 10], "9": [0, 2, 4, 7, 10], "9b5": [0, 2, 4, 6, 10], aug9: [0, 2, 4, 8, 10],
|
|
23
|
+
"7b9": [0, 1, 4, 7, 10], "7#9": [0, 3, 4, 7, 10], "11": [0, 2, 4, 5, 7, 10],
|
|
24
|
+
"9#11": [0, 2, 4, 6, 7, 10], "13": [0, 2, 4, 7, 9, 10], maj7: [0, 4, 7, 11],
|
|
25
|
+
maj7b5: [0, 4, 6, 11], "maj7#5": [0, 4, 8, 11], maj9: [0, 2, 4, 7, 11],
|
|
26
|
+
maj11: [0, 2, 4, 5, 7, 11], maj13: [0, 2, 4, 7, 9, 11], m6: [0, 3, 7, 9],
|
|
27
|
+
m69: [0, 2, 3, 7, 9], m7: [0, 3, 7, 10], m7b5: [0, 3, 6, 10], m9: [0, 2, 3, 7, 10],
|
|
28
|
+
m11: [0, 2, 3, 5, 7, 10], mmaj7: [0, 3, 7, 11], mmaj7b5: [0, 3, 6, 11],
|
|
29
|
+
mmaj9: [0, 2, 3, 7, 11], mmaj11: [0, 2, 3, 5, 7, 11], add9: [0, 2, 4, 7], madd9: [0, 2, 3, 7],
|
|
30
|
+
};
|
|
31
|
+
const DB_KEY_BY_PC = ["C", "Csharp", "D", "Eb", "E", "F", "Fsharp", "G", "Ab", "A", "Bb", "B"];
|
|
32
|
+
const LETTER_PC = { C: 0, D: 2, E: 4, F: 5, G: 7, A: 9, B: 11 };
|
|
33
|
+
function pcOf(note) {
|
|
34
|
+
let v = LETTER_PC[note.charAt(0).toUpperCase()];
|
|
35
|
+
for (const ch of note.slice(1))
|
|
36
|
+
v += ch === "#" ? 1 : ch === "b" ? -1 : 0;
|
|
37
|
+
return ((v % 12) + 12) % 12;
|
|
38
|
+
}
|
|
39
|
+
const sameSet = (a, b) => a.length === b.length && a.every((x) => b.includes(x));
|
|
40
|
+
function relativeSet(chord) {
|
|
41
|
+
const r = pcOf(chord.root);
|
|
42
|
+
return [...new Set([chord.root, ...chord.pitchClasses].map((n) => (pcOf(n) - r + 12) % 12))];
|
|
43
|
+
}
|
|
44
|
+
function isSlash(chord) {
|
|
45
|
+
return chord.bass !== undefined && pcOf(chord.bass) !== pcOf(chord.root);
|
|
46
|
+
}
|
|
47
|
+
/** The chords-db suffix carrying exactly this chord, or null. */
|
|
48
|
+
export function chordsDbSuffixFor(chord) {
|
|
49
|
+
const set = relativeSet(chord);
|
|
50
|
+
const entries = GUITAR_DB.chords[DB_KEY_BY_PC[pcOf(chord.root)]] ?? [];
|
|
51
|
+
if (isSlash(chord)) {
|
|
52
|
+
const quality = sameSet(set, [0, 4, 7]) ? "" : sameSet(set, [0, 3, 7]) ? "m" : null;
|
|
53
|
+
if (quality === null)
|
|
54
|
+
return null;
|
|
55
|
+
const bassPc = pcOf(chord.bass);
|
|
56
|
+
const hit = entries.find((e) => e.suffix.startsWith(`${quality}/`) && e.suffix.indexOf("/") === quality.length &&
|
|
57
|
+
pcOf(e.suffix.slice(quality.length + 1)) === bassPc);
|
|
58
|
+
return hit ? hit.suffix : null;
|
|
59
|
+
}
|
|
60
|
+
for (const [suffix, pcs] of Object.entries(DB_SUFFIX_PCS)) {
|
|
61
|
+
if (sameSet(set, pcs) && entries.some((e) => e.suffix === suffix))
|
|
62
|
+
return suffix;
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Every chords-db six-string position that spells the chord (see
|
|
68
|
+
* `positionSpellsChord`), in chords-db's order — the alternatives elsewhere on
|
|
69
|
+
* the neck. The first is the one `guitarPositionFor` prints. Empty when
|
|
70
|
+
* chords-db has no entry for the chord or none of its positions spells it.
|
|
71
|
+
*/
|
|
72
|
+
export function guitarLibraryPositionsFor(chord, options = {}) {
|
|
73
|
+
// The written bass (even one equal to the root) stays in the analysis: it is
|
|
74
|
+
// what stops rootless level 3 from dropping the root. Only suffix lookup and
|
|
75
|
+
// the power-chord template treat a root bass as root position.
|
|
76
|
+
const analysis = analyzeChordTones(chord.root, chord.pitchClasses, chord.bass, options);
|
|
77
|
+
const suffix = chordsDbSuffixFor(chord);
|
|
78
|
+
if (!suffix)
|
|
79
|
+
return [];
|
|
80
|
+
const entry = GUITAR_DB.chords[DB_KEY_BY_PC[pcOf(chord.root)]].find((e) => e.suffix === suffix);
|
|
81
|
+
return entry.positions
|
|
82
|
+
.filter((p) => positionSpellsChord(p, analysis))
|
|
83
|
+
.map((p) => ({
|
|
84
|
+
...p, generated: false, source: "chords-db", suffix,
|
|
85
|
+
review: reviewGuitarPosition(p, analysis, { level: options.level, origin: "chords-db" }),
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The best guitar position for a spelled chord, or null if none is playable
|
|
90
|
+
* under the generator's constraints.
|
|
91
|
+
*/
|
|
92
|
+
export function guitarPositionFor(chord, options = {}) {
|
|
93
|
+
const library = guitarLibraryPositionsFor(chord, options)[0];
|
|
94
|
+
if (library)
|
|
95
|
+
return library;
|
|
96
|
+
const analysis = analyzeChordTones(chord.root, chord.pitchClasses, chord.bass, options);
|
|
97
|
+
if (!isSlash(chord) && sameSet(relativeSet(chord), [0, 7])) {
|
|
98
|
+
const pos = powerChordPosition(pcOf(chord.root), { stringSet: "E" });
|
|
99
|
+
if (pos)
|
|
100
|
+
return {
|
|
101
|
+
...pos, generated: false, source: "power-chord",
|
|
102
|
+
review: reviewGuitarPosition(pos, analysis, { level: options.level, origin: "template:power-chord" }),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const p = generateGuitarVoicings(chord.pitchClasses, { ...options, root: chord.root, bass: chord.bass, limit: 1 })[0];
|
|
106
|
+
if (!p)
|
|
107
|
+
return null;
|
|
108
|
+
if (chordsDbSuffixFor(chord)) {
|
|
109
|
+
p.review = reviewGuitarPosition(p, analysis, {
|
|
110
|
+
level: options.level, origin: "search", dbPositionRejected: true,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return p;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=guitarPosition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guitarPosition.js","sourceRoot":"","sources":["../src/guitarPosition.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,12 @@ export { INSTRUMENTS, dbPositionToChord } from "./instruments.js";
|
|
|
2
2
|
export type { InstrumentId, InstrumentConfig, ChordsDb, ChordsDbEntry, ChordsDbPosition, } from "./instruments.js";
|
|
3
3
|
export { lookupGuitarChord, hasGuitarChord } from "./chordLookup.js";
|
|
4
4
|
export type { GuitarChordResult } from "./chordLookup.js";
|
|
5
|
-
export { GUITAR_TOP3_PRESETS, lookupTop3Chord } from "./staticPresets.js";
|
|
5
|
+
export { GUITAR_TOP3_PRESETS, lookupTop3Chord, findTop3Preset, TOP3_UNRESOLVED, } from "./staticPresets.js";
|
|
6
6
|
export type { StaticPreset } from "./staticPresets.js";
|
|
7
|
-
export {
|
|
7
|
+
export type { Top3Source } from "./top3Generated.js";
|
|
8
|
+
export { positionToMidi, positionToSoundingStrings, rootPitchClass } from "./pitch.js";
|
|
9
|
+
export type { SoundingString } from "./pitch.js";
|
|
10
|
+
export { toDbSuffix, splitLabel } from "./chordNames.js";
|
|
8
11
|
export { positionFacts, duplicateVoicingMap } from "./voicingFacts.js";
|
|
9
12
|
export type { Inversion, PositionFacts } from "./voicingFacts.js";
|
|
10
13
|
export { matchesShapeClass, canonicalPositionIndex, selectVoicings, SHAPE_CLASS_LADDER, } from "./voicingSelect.js";
|
|
@@ -12,3 +15,11 @@ export type { ShapeClass, CanonicalOptions, VoicingChoice, SelectVoicingsOptions
|
|
|
12
15
|
export { powerChordPosition, powerChordShape } from "./powerChords.js";
|
|
13
16
|
export type { PowerChordStringSet, PowerChordOptions } from "./powerChords.js";
|
|
14
17
|
export { bassShapeFor, violinShapeFor, violinCoverage } from "./generatedShapes.js";
|
|
18
|
+
export { EXPERIENCE_LADDER, levelForFacts, levelForTop3, selectForExperience, selectForResult, } from "./experience.js";
|
|
19
|
+
export type { ExperienceLevel, ExperienceQuery, ExperienceSelection, } from "./experience.js";
|
|
20
|
+
export { generateGuitarVoicings, analyzeChordTones, positionSpellsChord, fingeringFor, VOICING_RULES, } from "./voicingGenerator.js";
|
|
21
|
+
export type { GeneratedPosition, GenerateOptions, ToneOptions, ChordTone, ChordToneAnalysis, Fingering, ToneRole, VoicingRule, } from "./voicingGenerator.js";
|
|
22
|
+
export { guitarPositionFor, guitarLibraryPositionsFor, chordsDbSuffixFor } from "./guitarPosition.js";
|
|
23
|
+
export type { GuitarPosition, LibraryPosition, SpelledChord } from "./guitarPosition.js";
|
|
24
|
+
export { reviewGuitarPosition } from "./voicingReview.js";
|
|
25
|
+
export type { GuitarReview, ReasonCode, TeachingLevel, ReviewOptions } from "./voicingReview.js";
|
package/dist/index.js
CHANGED
|
@@ -5,10 +5,15 @@
|
|
|
5
5
|
// rendering. Based on pepperhorn/frames.
|
|
6
6
|
export { INSTRUMENTS, dbPositionToChord } from "./instruments.js";
|
|
7
7
|
export { lookupGuitarChord, hasGuitarChord } from "./chordLookup.js";
|
|
8
|
-
export { GUITAR_TOP3_PRESETS, lookupTop3Chord } from "./staticPresets.js";
|
|
9
|
-
export { positionToMidi, rootPitchClass } from "./pitch.js";
|
|
8
|
+
export { GUITAR_TOP3_PRESETS, lookupTop3Chord, findTop3Preset, TOP3_UNRESOLVED, } from "./staticPresets.js";
|
|
9
|
+
export { positionToMidi, positionToSoundingStrings, rootPitchClass } from "./pitch.js";
|
|
10
|
+
export { toDbSuffix, splitLabel } from "./chordNames.js";
|
|
10
11
|
export { positionFacts, duplicateVoicingMap } from "./voicingFacts.js";
|
|
11
12
|
export { matchesShapeClass, canonicalPositionIndex, selectVoicings, SHAPE_CLASS_LADDER, } from "./voicingSelect.js";
|
|
12
13
|
export { powerChordPosition, powerChordShape } from "./powerChords.js";
|
|
13
14
|
export { bassShapeFor, violinShapeFor, violinCoverage } from "./generatedShapes.js";
|
|
15
|
+
export { EXPERIENCE_LADDER, levelForFacts, levelForTop3, selectForExperience, selectForResult, } from "./experience.js";
|
|
16
|
+
export { generateGuitarVoicings, analyzeChordTones, positionSpellsChord, fingeringFor, VOICING_RULES, } from "./voicingGenerator.js";
|
|
17
|
+
export { guitarPositionFor, guitarLibraryPositionsFor, chordsDbSuffixFor } from "./guitarPosition.js";
|
|
18
|
+
export { reviewGuitarPosition } from "./voicingReview.js";
|
|
14
19
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,yCAAyC;AAEzC,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AASlE,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGrE,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,yCAAyC;AAEzC,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AASlE,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGrE,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAE,cAAc,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGvF,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGvE,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,cAAc,EACd,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAS5B,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGvE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEpF,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,eAAe,GAChB,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,aAAa,GACd,MAAM,uBAAuB,CAAC;AAY/B,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGtG,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/instruments.js
CHANGED
|
@@ -72,7 +72,15 @@ export const INSTRUMENTS = {
|
|
|
72
72
|
*/
|
|
73
73
|
export function dbPositionToChord(pos, stringCount, title) {
|
|
74
74
|
const fingers = [];
|
|
75
|
-
const
|
|
75
|
+
const barreContacts = pos.barres.map(fret => {
|
|
76
|
+
const atFret = pos.frets.flatMap((f, i) => f === fret ? [i] : []);
|
|
77
|
+
const repeated = atFret.find(i => pos.fingers[i] > 0 &&
|
|
78
|
+
atFret.filter(j => pos.fingers[j] === pos.fingers[i]).length > 1);
|
|
79
|
+
// A mini-barre can share a fret with another finger. Older database
|
|
80
|
+
// entries without finger labels retain their fret-based bounds.
|
|
81
|
+
return repeated === undefined ? atFret : atFret.filter(i => pos.fingers[i] === pos.fingers[repeated]);
|
|
82
|
+
});
|
|
83
|
+
const covered = new Set(barreContacts.flat());
|
|
76
84
|
pos.frets.forEach((fret, dbIdx) => {
|
|
77
85
|
// chords-db lists strings low→high; svguitar numbers strings high→low.
|
|
78
86
|
const stringNum = stringCount - dbIdx;
|
|
@@ -85,16 +93,14 @@ export function dbPositionToChord(pos, stringCount, title) {
|
|
|
85
93
|
return;
|
|
86
94
|
}
|
|
87
95
|
// Skip strings covered by a barre — the barre draws them.
|
|
88
|
-
if (
|
|
96
|
+
if (covered.has(dbIdx))
|
|
89
97
|
return;
|
|
90
98
|
const fingerNum = pos.fingers[dbIdx];
|
|
91
99
|
const text = fingerNum && fingerNum > 0 ? String(fingerNum) : undefined;
|
|
92
100
|
fingers.push(text ? [stringNum, fret, text] : [stringNum, fret]);
|
|
93
101
|
});
|
|
94
|
-
const barres = pos.barres.map((fret) => {
|
|
95
|
-
const playingIdxs =
|
|
96
|
-
.map((f, i) => (f === fret ? i : -1))
|
|
97
|
-
.filter((i) => i >= 0);
|
|
102
|
+
const barres = pos.barres.map((fret, index) => {
|
|
103
|
+
const playingIdxs = barreContacts[index];
|
|
98
104
|
const stringNums = playingIdxs.map((i) => stringCount - i);
|
|
99
105
|
const fromString = Math.max(...stringNums);
|
|
100
106
|
const toString = Math.min(...stringNums);
|
package/dist/instruments.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instruments.js","sourceRoot":"","sources":["../src/instruments.ts"],"names":[],"mappings":"AA+BA,MAAM,CAAC,MAAM,WAAW,GAA2C;IACjE,MAAM,EAAE;QACN,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,wCAAwC;QACrD,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;QACtC,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;KACnC;IACD,OAAO,EAAE;QACP,EAAE,EAAE,SAAS;QACb,KAAK,EAAE,SAAS;QAChB,WAAW,EAAE,4BAA4B;QACzC,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;QAC5B,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;KAC3B;IACD,aAAa,EAAE;QACb,EAAE,EAAE,aAAa;QACjB,KAAK,EAAE,gBAAgB;QACvB,WAAW,EACT,8EAA8E;YAC9E,uCAAuC;QACzC,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;QACtC,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;KACnC;IACD,KAAK,EAAE;QACL,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,uEAAuE;YACvE,sEAAsE;YACtE,gEAAgE;QAClE,OAAO,EAAE,CAAC;QACV,wEAAwE;QACxE,0EAA0E;QAC1E,uDAAuD;QACvD,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;QAC5B,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;KAC3B;IACD,KAAK,EAAE;QACL,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,sCAAsC;QACnD,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;QACjC,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;KAC/B;IACD,MAAM,EAAE;QACN,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,QAAQ;QACf,WAAW,EACT,+EAA+E;YAC/E,2EAA2E;YAC3E,mFAAmF;QACrF,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;QAC5B,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;KAC3B;CACF,CAAC;AA+BF;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAqB,EACrB,WAAmB,EACnB,KAAc;IAEd,MAAM,OAAO,GAAqB,EAAE,CAAC;IACrC,MAAM,
|
|
1
|
+
{"version":3,"file":"instruments.js","sourceRoot":"","sources":["../src/instruments.ts"],"names":[],"mappings":"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"}
|
package/dist/pitch.d.ts
CHANGED
|
@@ -7,6 +7,12 @@
|
|
|
7
7
|
* no midi field at all, so derivation is required regardless.
|
|
8
8
|
*/
|
|
9
9
|
import type { ChordsDbPosition } from "./instruments.js";
|
|
10
|
+
export interface SoundingString {
|
|
11
|
+
/** Zero-based physical string index in low-to-high instrument order. */
|
|
12
|
+
stringIndex: number;
|
|
13
|
+
midi: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function positionToSoundingStrings(pos: ChordsDbPosition, openMidi: number[]): SoundingString[];
|
|
10
16
|
/**
|
|
11
17
|
* Sounding MIDI pitches for a chords-db position.
|
|
12
18
|
*
|
package/dist/pitch.js
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
export function positionToSoundingStrings(pos, openMidi) {
|
|
2
|
+
const out = [];
|
|
3
|
+
pos.frets.forEach((fret, stringIndex) => {
|
|
4
|
+
if (fret === -1)
|
|
5
|
+
return;
|
|
6
|
+
const open = openMidi[stringIndex];
|
|
7
|
+
if (open === undefined)
|
|
8
|
+
return;
|
|
9
|
+
out.push({
|
|
10
|
+
stringIndex,
|
|
11
|
+
midi: fret === 0 ? open : open + pos.baseFret + fret - 1,
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
return out;
|
|
15
|
+
}
|
|
1
16
|
/**
|
|
2
17
|
* Sounding MIDI pitches for a chords-db position.
|
|
3
18
|
*
|
|
@@ -14,16 +29,7 @@
|
|
|
14
29
|
* @returns sounding pitches only, in chords-db string order
|
|
15
30
|
*/
|
|
16
31
|
export function positionToMidi(pos, openMidi) {
|
|
17
|
-
|
|
18
|
-
pos.frets.forEach((fret, i) => {
|
|
19
|
-
if (fret === -1)
|
|
20
|
-
return;
|
|
21
|
-
const open = openMidi[i];
|
|
22
|
-
if (open === undefined)
|
|
23
|
-
return;
|
|
24
|
-
out.push(fret === 0 ? open : open + pos.baseFret + fret - 1);
|
|
25
|
-
});
|
|
26
|
-
return out;
|
|
32
|
+
return positionToSoundingStrings(pos, openMidi).map(({ midi }) => midi);
|
|
27
33
|
}
|
|
28
34
|
const PITCH_CLASSES = {
|
|
29
35
|
C: 0, "B#": 0,
|
package/dist/pitch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pitch.js","sourceRoot":"","sources":["../src/pitch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pitch.js","sourceRoot":"","sources":["../src/pitch.ts"],"names":[],"mappings":"AAgBA,MAAM,UAAU,yBAAyB,CACvC,GAAqB,EACrB,QAAkB;IAElB,MAAM,GAAG,GAAqB,EAAE,CAAC;IACjC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE;QACtC,IAAI,IAAI,KAAK,CAAC,CAAC;YAAE,OAAO;QACxB,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;QACnC,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO;QAC/B,GAAG,CAAC,IAAI,CAAC;YACP,WAAW;YACX,IAAI,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC;SACzD,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,GAAqB,EAAE,QAAkB;IACtE,OAAO,yBAAyB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,aAAa,GAA2B;IAC5C,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;IACb,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACd,CAAC,EAAE,CAAC;IACJ,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACd,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACX,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;IACb,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACd,CAAC,EAAE,CAAC;IACJ,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACd,CAAC,EAAE,CAAC;IACJ,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;IAChB,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;CACd,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACjD,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1D,MAAM,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AACtC,CAAC"}
|
package/dist/staticPresets.d.ts
CHANGED
|
@@ -1,16 +1,72 @@
|
|
|
1
1
|
import type { Chord } from "svguitar";
|
|
2
|
+
import { TOP3_UNRESOLVED } from "./top3Generated.js";
|
|
3
|
+
import type { Top3Source } from "./top3Generated.js";
|
|
4
|
+
import type { ExperienceLevel } from "./experience.js";
|
|
2
5
|
export interface StaticPreset {
|
|
3
6
|
key: string;
|
|
4
7
|
suffix: string;
|
|
5
8
|
chord: Chord;
|
|
9
|
+
/**
|
|
10
|
+
* Where the shape came from: a hand-authored beginner preset, a window taken
|
|
11
|
+
* from a stored chords-db voicing, or one built from the chord's pitch classes.
|
|
12
|
+
*/
|
|
13
|
+
source?: Top3Source;
|
|
14
|
+
/** How hard the shape is to play. Derived; see src/experience.ts. */
|
|
15
|
+
level: ExperienceLevel;
|
|
16
|
+
/**
|
|
17
|
+
* True when the shape is playable but not a faithful spelling — it drops the
|
|
18
|
+
* root, or its three notes also name another chord. A caller may present these
|
|
19
|
+
* differently; nothing here treats them as second class.
|
|
20
|
+
*/
|
|
21
|
+
approximate?: boolean;
|
|
6
22
|
}
|
|
7
23
|
/**
|
|
8
|
-
*
|
|
24
|
+
* Where a shape's diagram window starts, and its frets within that window.
|
|
9
25
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
26
|
+
* The generated table stores absolute frets, measured from the nut. Two thirds
|
|
27
|
+
* of it sits past the drawn window, so a diagram has to say which window it is:
|
|
28
|
+
*
|
|
29
|
+
* - within `DIAGRAM_FRETS` of the nut, the window is the nut. Frets stay as
|
|
30
|
+
* they are, and open strings are drawn as open strings.
|
|
31
|
+
* - anything higher slides. The window starts at the shape's lowest fretted
|
|
32
|
+
* fret and each fret becomes `f - position + 1`.
|
|
33
|
+
*
|
|
34
|
+
* -1 and 0 are sentinels and are never offset. A slid window never carries a 0:
|
|
35
|
+
* the generator does not emit a shape that mixes an open string with a note past
|
|
36
|
+
* the window, because no window could show both.
|
|
37
|
+
*/
|
|
38
|
+
export declare function top3Window(frets: readonly number[]): {
|
|
39
|
+
position: number;
|
|
40
|
+
frets: number[];
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Beginner voicings on the top three strings (G B E), for all 12 roots.
|
|
44
|
+
*
|
|
45
|
+
* Generated — see src/top3Generated.ts and scripts/build-top3.mjs for how each
|
|
46
|
+
* shape was chosen, and docs/superpowers/specs/2026-09-07-guitar-top3-generated-voicings-design.md
|
|
47
|
+
* for why. Every entry is checked against pitch-class arithmetic, and against
|
|
48
|
+
* every other entry, by staticPresets.test.ts: a wrong shape is unrecoverable
|
|
49
|
+
* once printed, and a shape that duplicates another chord's is a wrong shape.
|
|
50
|
+
*
|
|
51
|
+
* This replaces twenty hand-authored entries that covered 7 of 12 roots and, in
|
|
52
|
+
* five cases, dropped the root — which made `Am7` print C major, `Fmaj7` print
|
|
53
|
+
* A minor and `Dm7` print F major.
|
|
13
54
|
*/
|
|
14
55
|
export declare const GUITAR_TOP3_PRESETS: StaticPreset[];
|
|
15
|
-
/**
|
|
56
|
+
/**
|
|
57
|
+
* Find a preset by any spelling of its root and any alias of its quality.
|
|
58
|
+
*
|
|
59
|
+
* Suffixes go through the same `toDbSuffix` the six-string lookup uses, because
|
|
60
|
+
* the table is keyed with chords-db's own suffix names — so `ø`, `M7`, `°7`,
|
|
61
|
+
* `sus` and `6/9` resolve here exactly as they do there, rather than through a
|
|
62
|
+
* second, smaller copy of that knowledge.
|
|
63
|
+
*/
|
|
64
|
+
export declare function findTop3Preset(key: string, suffix: string): StaticPreset | null;
|
|
65
|
+
/**
|
|
66
|
+
* Look up a top-3 shape. Returns null rather than guessing at an unknown chord.
|
|
67
|
+
*
|
|
68
|
+
* A null here is a fact, not a gap: the altered dominants in `TOP3_UNRESOLVED`
|
|
69
|
+
* need four notes to exist, and three strings cannot carry them.
|
|
70
|
+
*/
|
|
16
71
|
export declare function lookupTop3Chord(key: string, suffix: string): Chord | null;
|
|
72
|
+
export { TOP3_UNRESOLVED };
|
package/dist/staticPresets.js
CHANGED
|
@@ -1,48 +1,109 @@
|
|
|
1
|
+
import { INSTRUMENTS } from "./instruments.js";
|
|
2
|
+
import { rootPitchClass } from "./pitch.js";
|
|
3
|
+
import { toDbSuffix } from "./chordNames.js";
|
|
4
|
+
import { TOP3_GENERATED, TOP3_UNRESOLVED } from "./top3Generated.js";
|
|
1
5
|
/** Strings 4-6 are always muted for top-3 voicings. */
|
|
2
6
|
const MUTED_LOW = [[4, "x"], [5, "x"], [6, "x"]];
|
|
3
|
-
|
|
4
|
-
|
|
7
|
+
/** How many frets a `guitar-top3` diagram draws. */
|
|
8
|
+
const DIAGRAM_FRETS = INSTRUMENTS["guitar-top3"].frets;
|
|
9
|
+
/**
|
|
10
|
+
* Where a shape's diagram window starts, and its frets within that window.
|
|
11
|
+
*
|
|
12
|
+
* The generated table stores absolute frets, measured from the nut. Two thirds
|
|
13
|
+
* of it sits past the drawn window, so a diagram has to say which window it is:
|
|
14
|
+
*
|
|
15
|
+
* - within `DIAGRAM_FRETS` of the nut, the window is the nut. Frets stay as
|
|
16
|
+
* they are, and open strings are drawn as open strings.
|
|
17
|
+
* - anything higher slides. The window starts at the shape's lowest fretted
|
|
18
|
+
* fret and each fret becomes `f - position + 1`.
|
|
19
|
+
*
|
|
20
|
+
* -1 and 0 are sentinels and are never offset. A slid window never carries a 0:
|
|
21
|
+
* the generator does not emit a shape that mixes an open string with a note past
|
|
22
|
+
* the window, because no window could show both.
|
|
23
|
+
*/
|
|
24
|
+
export function top3Window(frets) {
|
|
25
|
+
const fretted = frets.filter((f) => f > 0);
|
|
26
|
+
const highest = fretted.length ? Math.max(...fretted) : 0;
|
|
27
|
+
if (highest <= DIAGRAM_FRETS)
|
|
28
|
+
return { position: 1, frets: [...frets] };
|
|
29
|
+
const position = Math.min(...fretted);
|
|
30
|
+
return { position, frets: frets.map((f) => (f > 0 ? f - position + 1 : f)) };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* One generated row → an svguitar shape, in the window it is drawn in.
|
|
34
|
+
*
|
|
35
|
+
* The table lists frets low → high as [G, B, E], which is chords-db's string
|
|
36
|
+
* order. svguitar numbers strings from the highest pitch, so those same three
|
|
37
|
+
* are svguitar 3, 2 and 1. This is the relabelling, and it is the only one:
|
|
38
|
+
* `dbPositionToChord` remains the single function that inverts string order.
|
|
39
|
+
*/
|
|
40
|
+
function toPreset(entry) {
|
|
41
|
+
const finger = (stringNo, fret, label) => (label ? [stringNo, fret, label] : [stringNo, fret]);
|
|
42
|
+
const window = top3Window(entry.frets);
|
|
5
43
|
return {
|
|
6
|
-
key,
|
|
7
|
-
suffix,
|
|
44
|
+
key: entry.key,
|
|
45
|
+
suffix: entry.suffix,
|
|
8
46
|
chord: {
|
|
9
|
-
fingers: [
|
|
47
|
+
fingers: [
|
|
48
|
+
finger(3, window.frets[0], entry.fingers[0]),
|
|
49
|
+
finger(2, window.frets[1], entry.fingers[1]),
|
|
50
|
+
finger(1, window.frets[2], entry.fingers[2]),
|
|
51
|
+
...MUTED_LOW,
|
|
52
|
+
],
|
|
10
53
|
barres: [],
|
|
54
|
+
position: window.position,
|
|
11
55
|
},
|
|
56
|
+
source: entry.source,
|
|
57
|
+
level: entry.level,
|
|
58
|
+
...(entry.approximate ? { approximate: true } : {}),
|
|
12
59
|
};
|
|
13
60
|
}
|
|
14
61
|
/**
|
|
15
|
-
*
|
|
62
|
+
* Beginner voicings on the top three strings (G B E), for all 12 roots.
|
|
63
|
+
*
|
|
64
|
+
* Generated — see src/top3Generated.ts and scripts/build-top3.mjs for how each
|
|
65
|
+
* shape was chosen, and docs/superpowers/specs/2026-09-07-guitar-top3-generated-voicings-design.md
|
|
66
|
+
* for why. Every entry is checked against pitch-class arithmetic, and against
|
|
67
|
+
* every other entry, by staticPresets.test.ts: a wrong shape is unrecoverable
|
|
68
|
+
* once printed, and a shape that duplicates another chord's is a wrong shape.
|
|
69
|
+
*
|
|
70
|
+
* This replaces twenty hand-authored entries that covered 7 of 12 roots and, in
|
|
71
|
+
* five cases, dropped the root — which made `Am7` print C major, `Fmaj7` print
|
|
72
|
+
* A minor and `Dm7` print F major.
|
|
73
|
+
*/
|
|
74
|
+
export const GUITAR_TOP3_PRESETS = TOP3_GENERATED.map(toPreset);
|
|
75
|
+
/**
|
|
76
|
+
* Indexed by pitch class, not by spelling.
|
|
77
|
+
*
|
|
78
|
+
* The table stores roots as chords-db spells them — `C#` and `F#`, but `Eb`,
|
|
79
|
+
* `Ab` and `Bb` — which is not what a user types, and matching the string meant
|
|
80
|
+
* `Db`, `D#`, `G#` and `A#` reached nothing at all. A pitch class has no
|
|
81
|
+
* spelling, so `rootPitchClass` — the package's one root parser, which already
|
|
82
|
+
* knows every enharmonic down to `Cb` and `B#` — resolves both sides.
|
|
83
|
+
*/
|
|
84
|
+
const BY_PITCH_CLASS = new Map(GUITAR_TOP3_PRESETS.map((p) => [`${rootPitchClass(p.key)} ${p.suffix}`, p]));
|
|
85
|
+
/**
|
|
86
|
+
* Find a preset by any spelling of its root and any alias of its quality.
|
|
87
|
+
*
|
|
88
|
+
* Suffixes go through the same `toDbSuffix` the six-string lookup uses, because
|
|
89
|
+
* the table is keyed with chords-db's own suffix names — so `ø`, `M7`, `°7`,
|
|
90
|
+
* `sus` and `6/9` resolve here exactly as they do there, rather than through a
|
|
91
|
+
* second, smaller copy of that knowledge.
|
|
92
|
+
*/
|
|
93
|
+
export function findTop3Preset(key, suffix) {
|
|
94
|
+
const pc = rootPitchClass(key);
|
|
95
|
+
if (pc === null)
|
|
96
|
+
return null;
|
|
97
|
+
return BY_PITCH_CLASS.get(`${pc} ${toDbSuffix(suffix)}`) ?? null;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Look up a top-3 shape. Returns null rather than guessing at an unknown chord.
|
|
16
101
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* staticPresets.test.ts, because a wrong shape is unrecoverable once printed.
|
|
102
|
+
* A null here is a fact, not a gap: the altered dominants in `TOP3_UNRESOLVED`
|
|
103
|
+
* need four notes to exist, and three strings cannot carry them.
|
|
20
104
|
*/
|
|
21
|
-
export const GUITAR_TOP3_PRESETS = [
|
|
22
|
-
top3("C", "major", [0], [1, "1"], [0]),
|
|
23
|
-
top3("G", "major", [0], [0], [3, "3"]),
|
|
24
|
-
top3("D", "major", [2, "1"], [3, "3"], [2, "2"]),
|
|
25
|
-
top3("A", "major", [2, "1"], [2, "2"], [0]),
|
|
26
|
-
top3("E", "minor", [0], [0], [0]),
|
|
27
|
-
top3("A", "minor", [2, "2"], [1, "1"], [0]),
|
|
28
|
-
top3("D", "minor", [2, "2"], [3, "3"], [1, "1"]),
|
|
29
|
-
top3("E", "major", [1, "1"], [0], [0]),
|
|
30
|
-
top3("C", "7", [3, "3"], [1, "1"], [0]),
|
|
31
|
-
top3("G", "7", [0], [0], [1, "1"]),
|
|
32
|
-
top3("B", "minor", [4, "3"], [3, "2"], [2, "1"]),
|
|
33
|
-
top3("F", "major", [2, "2"], [1, "1"], [1, "1"]),
|
|
34
|
-
top3("D", "7", [2, "2"], [1, "1"], [2, "3"]),
|
|
35
|
-
top3("E", "7", [1, "1"], [3, "3"], [0]),
|
|
36
|
-
top3("A", "7", [0], [2, "2"], [0]),
|
|
37
|
-
top3("A", "m7", [0], [1, "1"], [0]),
|
|
38
|
-
top3("D", "m7", [2, "2"], [1, "1"], [1, "1"]),
|
|
39
|
-
top3("E", "m7", [0], [3, "3"], [0]),
|
|
40
|
-
top3("F", "maj7", [2, "2"], [1, "1"], [0]),
|
|
41
|
-
top3("G", "minor", [3, "1"], [3, "2"], [3, "3"]),
|
|
42
|
-
];
|
|
43
|
-
/** Look up a top-3 shape. Returns null rather than guessing at an unknown chord. */
|
|
44
105
|
export function lookupTop3Chord(key, suffix) {
|
|
45
|
-
|
|
46
|
-
return hit ? hit.chord : null;
|
|
106
|
+
return findTop3Preset(key, suffix)?.chord ?? null;
|
|
47
107
|
}
|
|
108
|
+
export { TOP3_UNRESOLVED };
|
|
48
109
|
//# sourceMappingURL=staticPresets.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staticPresets.js","sourceRoot":"","sources":["../src/staticPresets.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"staticPresets.js","sourceRoot":"","sources":["../src/staticPresets.ts"],"names":[],"mappings":"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"}
|