@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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"experience.js","sourceRoot":"","sources":["../src/experience.ts"],"names":[],"mappings":"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"}
@@ -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 { positionToMidi, rootPitchClass } from "./pitch.js";
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,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1E,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5D,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"}
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"}
@@ -72,7 +72,15 @@ export const INSTRUMENTS = {
72
72
  */
73
73
  export function dbPositionToChord(pos, stringCount, title) {
74
74
  const fingers = [];
75
- const barreFrets = new Set(pos.barres);
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 (barreFrets.has(fret))
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 = pos.frets
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);
@@ -1 +1 @@
1
- {"version":3,"file":"instruments.js","sourceRoot":"","sources":["../src/instruments.ts"],"names":[],"mappings":"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"}
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
- const out = [];
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":"AAUA;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,GAAqB,EAAE,QAAkB;IACtE,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QAC5B,IAAI,IAAI,KAAK,CAAC,CAAC;YAAE,OAAO;QACxB,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO;QAC/B,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,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"}
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"}
@@ -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
- * Hand-authored beginner voicings on the top three strings (G B E).
24
+ * Where a shape's diagram window starts, and its frets within that window.
9
25
  *
10
- * chords-db has no three-string voicings, so these cannot be derived — the table
11
- * is the sole source. Every entry is checked against pitch-class arithmetic by
12
- * staticPresets.test.ts, because a wrong shape is unrecoverable once printed.
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
- /** Look up a top-3 shape. Returns null rather than guessing at an unknown chord. */
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 };
@@ -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
- function top3(key, suffix, g, b, e) {
4
- const finger = (s, [fret, label]) => label ? [s, fret, label] : [s, fret];
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: [finger(3, g), finger(2, b), finger(1, e), ...MUTED_LOW],
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
- * Hand-authored beginner voicings on the top three strings (G B E).
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
- * chords-db has no three-string voicings, so these cannot be derived — the table
18
- * is the sole source. Every entry is checked against pitch-class arithmetic by
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
- const hit = GUITAR_TOP3_PRESETS.find((p) => p.key === key && p.suffix === suffix);
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":"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"}
1
+ {"version":3,"file":"staticPresets.js","sourceRoot":"","sources":["../src/staticPresets.ts"],"names":[],"mappings":"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"}