@pepperhorn/chordl-core 0.5.2 → 0.6.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/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/theory/scale-library.d.ts +60 -0
- package/dist/theory/scale-library.js +253 -0
- package/dist/theory/scale-library.js.map +1 -0
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -50,3 +50,5 @@ export { midiOf, placeAscending, spanOf, constrainVoicing } from "./theory/hand-
|
|
|
50
50
|
export type { HandConstraints, PlacedNote, ConstrainedNote, ConstrainVoicingInput, ConstrainedVoicing, } from "./theory/hand-constraints.js";
|
|
51
51
|
export { generateConstrainedVariants } from "./theory/constrained-variants.js";
|
|
52
52
|
export type { ConstrainedVariant, GenerateConstrainedOptions, } from "./theory/constrained-variants.js";
|
|
53
|
+
export { spellScale, stepPatternOf, validateStepPattern, degreeLabelsOf, modeSource, modeAt, scaleExcerpt, excerptLabel, diatonicChords, preferredRoot, modeDemo, } from "./theory/scale-library.js";
|
|
54
|
+
export type { StepToken, ScaleDef } from "./theory/scale-library.js";
|
package/dist/index.js
CHANGED
|
@@ -40,4 +40,6 @@ export { encodeChordSheet, decodeChordSheet } from "./chord-sheet/codec.js";
|
|
|
40
40
|
// Hand Constraints
|
|
41
41
|
export { midiOf, placeAscending, spanOf, constrainVoicing } from "./theory/hand-constraints.js";
|
|
42
42
|
export { generateConstrainedVariants } from "./theory/constrained-variants.js";
|
|
43
|
+
// Host-supplied scale library
|
|
44
|
+
export { spellScale, stepPatternOf, validateStepPattern, degreeLabelsOf, modeSource, modeAt, scaleExcerpt, excerptLabel, diatonicChords, preferredRoot, modeDemo, } from "./theory/scale-library.js";
|
|
43
45
|
//# 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":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export type StepToken = "H" | "W" | "m3" | "M3";
|
|
2
|
+
export type ScaleDef = {
|
|
3
|
+
slug: string;
|
|
4
|
+
name: string;
|
|
5
|
+
intervals: string[];
|
|
6
|
+
steps: StepToken[];
|
|
7
|
+
degreeLabels?: string[];
|
|
8
|
+
modeParent?: string;
|
|
9
|
+
modeDegree?: number;
|
|
10
|
+
relativeExampleRoot?: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function spellScale(def: ScaleDef, root: string): string[];
|
|
13
|
+
export declare function stepPatternOf(intervals: string[]): StepToken[];
|
|
14
|
+
export declare function validateStepPattern(intervals: string[], steps: StepToken[]): boolean;
|
|
15
|
+
export declare function degreeLabelsOf(intervals: string[]): string[];
|
|
16
|
+
/** Major-key signature cost: Db=5 < C#=7; Eb=3 < D#=9, etc.
|
|
17
|
+
* F#/Gb both cost six: the explicit Task 9 preference is F#.
|
|
18
|
+
* With a definition, rank its actual spelled notes: avoid double accidentals,
|
|
19
|
+
* then minimize accidental count, then avoid Cb/Fb/E#/B# roots. Remaining ties
|
|
20
|
+
* keep the conventional one-argument spelling.
|
|
21
|
+
*/
|
|
22
|
+
export declare function preferredRoot(pc: number, def?: ScaleDef): string;
|
|
23
|
+
export declare function modeSource(mode: ScaleDef, root: string, defs: ScaleDef[]): {
|
|
24
|
+
parent: ScaleDef;
|
|
25
|
+
parentRoot: string;
|
|
26
|
+
};
|
|
27
|
+
export declare function modeAt(parent: ScaleDef, parentRoot: string, degree: number, defs: ScaleDef[]): {
|
|
28
|
+
mode: ScaleDef;
|
|
29
|
+
root: string;
|
|
30
|
+
};
|
|
31
|
+
/** Inclusive degree range; each extra octave extends the upper endpoint by
|
|
32
|
+
* one scale length. Pitch-class strings intentionally carry no octave number.
|
|
33
|
+
* Down reverses the same range; up-down visits the upper endpoint only once.
|
|
34
|
+
*/
|
|
35
|
+
export declare function scaleExcerpt(def: ScaleDef, root: string, from: number, to: number, octaves?: number, direction?: "up" | "down" | "up-down"): string[];
|
|
36
|
+
export declare function excerptLabel(def: ScaleDef, root: string, from: number, to: number): string;
|
|
37
|
+
export declare function diatonicChords(def: ScaleDef, root: string, stack: 3 | 4 | 5): {
|
|
38
|
+
degree: number;
|
|
39
|
+
roman: string;
|
|
40
|
+
symbol: string;
|
|
41
|
+
root: string;
|
|
42
|
+
slug: string;
|
|
43
|
+
}[];
|
|
44
|
+
export declare function modeDemo(mode: ScaleDef, defs: ScaleDef[]): {
|
|
45
|
+
title: string;
|
|
46
|
+
steps: StepToken[];
|
|
47
|
+
degreeLabels: string[];
|
|
48
|
+
parallel: {
|
|
49
|
+
root: "C";
|
|
50
|
+
notes: string[];
|
|
51
|
+
question: string;
|
|
52
|
+
answer: string;
|
|
53
|
+
};
|
|
54
|
+
relative: {
|
|
55
|
+
notes: string[];
|
|
56
|
+
root: string;
|
|
57
|
+
question: string;
|
|
58
|
+
answer: string;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/** Host-supplied scale definitions; no catalogue or Directus dependency. */
|
|
2
|
+
import { Interval, Note } from "tonal";
|
|
3
|
+
import { spellWithPreference } from "../engine/note-spelling.js";
|
|
4
|
+
const ROMANS = ["I", "II", "III", "IV", "V", "VI", "VII"];
|
|
5
|
+
const STEPS = ["H", "W", "m3", "M3"];
|
|
6
|
+
const mod12 = (n) => ((n % 12) + 12) % 12;
|
|
7
|
+
/** Bridge formula-sheet tokens to the existing Tonal spelling/label helpers. */
|
|
8
|
+
function tonalInterval(token) {
|
|
9
|
+
const match = /^([b#]*)([1-7])$/.exec(token);
|
|
10
|
+
if (!match)
|
|
11
|
+
throw new Error(`Invalid scale interval: ${token}`);
|
|
12
|
+
const degree = Number(match[2]);
|
|
13
|
+
const alt = [...match[1]].reduce((sum, c) => sum + (c === "#" ? 1 : -1), 0);
|
|
14
|
+
const perfect = [1, 4, 5].includes(degree);
|
|
15
|
+
const quality = alt > 0 ? "A".repeat(alt)
|
|
16
|
+
: alt === 0 ? (perfect ? "P" : "M")
|
|
17
|
+
: !perfect && alt === -1 ? "m"
|
|
18
|
+
: "d".repeat(-alt - (perfect ? 0 : 1));
|
|
19
|
+
return `${degree}${quality}`;
|
|
20
|
+
}
|
|
21
|
+
function pitches(intervals) {
|
|
22
|
+
if (!intervals.length)
|
|
23
|
+
throw new Error("A scale needs intervals");
|
|
24
|
+
const result = intervals.map(i => Interval.semitones(tonalInterval(i)));
|
|
25
|
+
if (result[0] !== 0 || result.some((n, i) => !Number.isFinite(n) || n < 0 || n >= 12 || (i > 0 && n <= result[i - 1]))) {
|
|
26
|
+
throw new Error("Scale intervals must ascend from the tonic within one octave");
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
function checkRoot(root) {
|
|
31
|
+
if (!/^[A-G][b#]*$/.test(root) || Note.get(root).empty)
|
|
32
|
+
throw new Error(`Invalid scale root: ${root}`);
|
|
33
|
+
return Note.chroma(root);
|
|
34
|
+
}
|
|
35
|
+
export function spellScale(def, root) {
|
|
36
|
+
checkRoot(root);
|
|
37
|
+
pitches(def.intervals);
|
|
38
|
+
return def.intervals.map(i => Note.transpose(root, tonalInterval(i)));
|
|
39
|
+
}
|
|
40
|
+
export function stepPatternOf(intervals) {
|
|
41
|
+
const pcs = pitches(intervals);
|
|
42
|
+
return pcs.map((pc, i) => {
|
|
43
|
+
const gap = (pcs[i + 1] ?? 12) - pc;
|
|
44
|
+
const step = STEPS[gap - 1];
|
|
45
|
+
if (!step)
|
|
46
|
+
throw new Error(`Unsupported scale step: ${gap} semitones`);
|
|
47
|
+
return step;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
export function validateStepPattern(intervals, steps) {
|
|
51
|
+
try {
|
|
52
|
+
const derived = stepPatternOf(intervals);
|
|
53
|
+
return steps.length === derived.length && steps.every((s, i) => s === derived[i]);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function degreeLabelsOf(intervals) {
|
|
60
|
+
return intervals.map(token => {
|
|
61
|
+
tonalInterval(token); // Validate the formula token before reading its degree.
|
|
62
|
+
// Preserve the written prefix: Tonal's diminished 7th is bb7, whereas a
|
|
63
|
+
// diminished 5th is b5. A quality-only label helper loses that distinction.
|
|
64
|
+
const prefix = token.slice(0, -1).replace(/b/g, "♭");
|
|
65
|
+
return prefix + ROMANS[Number(token.slice(-1)) - 1];
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/** Major-key signature cost: Db=5 < C#=7; Eb=3 < D#=9, etc.
|
|
69
|
+
* F#/Gb both cost six: the explicit Task 9 preference is F#.
|
|
70
|
+
* With a definition, rank its actual spelled notes: avoid double accidentals,
|
|
71
|
+
* then minimize accidental count, then avoid Cb/Fb/E#/B# roots. Remaining ties
|
|
72
|
+
* keep the conventional one-argument spelling.
|
|
73
|
+
*/
|
|
74
|
+
export function preferredRoot(pc, def) {
|
|
75
|
+
if (!Number.isInteger(pc))
|
|
76
|
+
throw new Error("Pitch class must be an integer");
|
|
77
|
+
const normalized = mod12(pc);
|
|
78
|
+
const conventional = spellWithPreference(Note.pitchClass(Note.fromMidiSharps(60 + normalized)), "C", normalized !== 6);
|
|
79
|
+
if (!def)
|
|
80
|
+
return conventional;
|
|
81
|
+
return rootCandidates(normalized).map(root => ({ root, cost: spellingCost(spellScale(def, root)) }))
|
|
82
|
+
.sort((a, b) => a.cost.doubles - b.cost.doubles || a.cost.accidentals - b.cost.accidentals
|
|
83
|
+
|| Number(["Cb", "Fb", "E#", "B#"].includes(a.root)) - Number(["Cb", "Fb", "E#", "B#"].includes(b.root))
|
|
84
|
+
|| Number(b.root === conventional) - Number(a.root === conventional))[0].root;
|
|
85
|
+
}
|
|
86
|
+
function spellingCost(notes) {
|
|
87
|
+
return notes.reduce((cost, note) => {
|
|
88
|
+
const count = Math.abs(Note.get(note).alt);
|
|
89
|
+
return { doubles: cost.doubles + (count > 1 ? 1 : 0), accidentals: cost.accidentals + count };
|
|
90
|
+
}, { doubles: 0, accidentals: 0 });
|
|
91
|
+
}
|
|
92
|
+
/** Candidate roots have at most one accidental; a double-accidental root
|
|
93
|
+
* cannot give a scale free of double accidentals, since it is the first note.
|
|
94
|
+
*/
|
|
95
|
+
function rootCandidates(pc) {
|
|
96
|
+
return [..."CDEFGAB"].flatMap(letter => ["", "b", "#"].map(acc => letter + acc))
|
|
97
|
+
.filter(root => Note.chroma(root) === mod12(pc));
|
|
98
|
+
}
|
|
99
|
+
function practicalParentRoot(pc, parent) {
|
|
100
|
+
return rootCandidates(pc).map(root => ({ root, cost: spellingCost(spellScale(parent, root)) }))
|
|
101
|
+
.sort((a, b) => a.cost.doubles - b.cost.doubles || a.cost.accidentals - b.cost.accidentals
|
|
102
|
+
|| Number(b.root.includes("b")) - Number(a.root.includes("b")))[0].root;
|
|
103
|
+
}
|
|
104
|
+
function modeDegree(mode) {
|
|
105
|
+
const degree = mode.modeDegree;
|
|
106
|
+
if (!Number.isInteger(degree) || degree < 1 || degree > 7)
|
|
107
|
+
throw new Error(`Missing or invalid mode degree: ${mode.slug}`);
|
|
108
|
+
return degree;
|
|
109
|
+
}
|
|
110
|
+
export function modeSource(mode, root, defs) {
|
|
111
|
+
const degree = modeDegree(mode);
|
|
112
|
+
const parent = defs.find(d => d.slug === mode.modeParent);
|
|
113
|
+
if (!parent)
|
|
114
|
+
throw new Error(`Missing mode parent: ${mode.modeParent}`);
|
|
115
|
+
const offset = pitches(parent.intervals)[degree - 1];
|
|
116
|
+
if (offset === undefined)
|
|
117
|
+
throw new Error("Mode degree exceeds parent scale");
|
|
118
|
+
const pc = checkRoot(root) - offset;
|
|
119
|
+
// Preserve the mode root's letter at its parent degree. Only impractical
|
|
120
|
+
// parent keys (>7 written accidentals or a double accidental) are respelled.
|
|
121
|
+
const letterRoot = Note.transpose(root, `-${tonalInterval(parent.intervals[degree - 1])}`);
|
|
122
|
+
const cost = spellingCost(spellScale(parent, letterRoot));
|
|
123
|
+
const parentRoot = cost.doubles || cost.accidentals > 7 ? practicalParentRoot(pc, parent) : letterRoot;
|
|
124
|
+
return { parent, parentRoot };
|
|
125
|
+
}
|
|
126
|
+
export function modeAt(parent, parentRoot, degree, defs) {
|
|
127
|
+
if (!Number.isInteger(degree) || degree < 1 || degree > 7)
|
|
128
|
+
throw new Error("Mode degree must be 1–7");
|
|
129
|
+
const mode = defs.find(d => d.modeParent === parent.slug && d.modeDegree === degree);
|
|
130
|
+
if (!mode)
|
|
131
|
+
throw new Error(`Missing mode ${degree} of ${parent.slug}`);
|
|
132
|
+
const root = spellScale(parent, parentRoot)[degree - 1];
|
|
133
|
+
if (!root)
|
|
134
|
+
throw new Error("Mode degree exceeds parent scale");
|
|
135
|
+
return { mode, root };
|
|
136
|
+
}
|
|
137
|
+
function checkRange(from, to) {
|
|
138
|
+
if (!Number.isInteger(from) || !Number.isInteger(to) || from < 1 || to < from) {
|
|
139
|
+
throw new Error("Excerpt degrees must be positive integers with from <= to");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/** Inclusive degree range; each extra octave extends the upper endpoint by
|
|
143
|
+
* one scale length. Pitch-class strings intentionally carry no octave number.
|
|
144
|
+
* Down reverses the same range; up-down visits the upper endpoint only once.
|
|
145
|
+
*/
|
|
146
|
+
export function scaleExcerpt(def, root, from, to, octaves = 1, direction = "up") {
|
|
147
|
+
checkRange(from, to);
|
|
148
|
+
if (!Number.isInteger(octaves) || octaves < 1)
|
|
149
|
+
throw new Error("Octaves must be a positive integer");
|
|
150
|
+
if (!["up", "down", "up-down"].includes(direction))
|
|
151
|
+
throw new Error("Invalid excerpt direction");
|
|
152
|
+
const notes = spellScale(def, root);
|
|
153
|
+
const last = to + (octaves - 1) * notes.length;
|
|
154
|
+
const up = Array.from({ length: last - from + 1 }, (_, i) => notes[(from + i - 1) % notes.length]);
|
|
155
|
+
if (direction === "down")
|
|
156
|
+
return up.reverse();
|
|
157
|
+
return direction === "up-down" ? [...up, ...up.slice(0, -1).reverse()] : up;
|
|
158
|
+
}
|
|
159
|
+
export function excerptLabel(def, root, from, to) {
|
|
160
|
+
checkRange(from, to);
|
|
161
|
+
const title = `${root} ${def.name}`;
|
|
162
|
+
return from === 1 && to === def.intervals.length ? title : `Notes ${from}–${to} of ${title}`;
|
|
163
|
+
}
|
|
164
|
+
// Symbol → CRF modifier slug (same convention as chords.slug):
|
|
165
|
+
// major → (no modifier); m → m; dim → dim; aug → aug;
|
|
166
|
+
// maj7 → maj7; 7 → 7; m7 → m7; m7b5 → m7-flat5;
|
|
167
|
+
// dim7 → dim7; mMaj7 → m-maj7; maj7#5 → maj7-sharp5.
|
|
168
|
+
// Natural ninths replace 7 with 9; (b9)/(#9) append -flat9/-sharp9.
|
|
169
|
+
function modifierSlug(symbol) {
|
|
170
|
+
return symbol.replace(/mMaj/g, "m-maj").replace(/[()]/g, "")
|
|
171
|
+
.replace(/b/g, "-flat").replace(/#/g, "-sharp");
|
|
172
|
+
}
|
|
173
|
+
export function diatonicChords(def, root, stack) {
|
|
174
|
+
if (def.intervals.length !== 7)
|
|
175
|
+
throw new Error("Diatonic chords require a seven-note scale");
|
|
176
|
+
if (![3, 4, 5].includes(stack))
|
|
177
|
+
throw new Error("Chord stack must be 3, 4, or 5");
|
|
178
|
+
const pcs = pitches(def.intervals);
|
|
179
|
+
const notes = spellScale(def, root);
|
|
180
|
+
const labels = degreeLabelsOf(def.intervals).map(label => label.replace(/#/g, "♯"));
|
|
181
|
+
return notes.map((chordRoot, i) => {
|
|
182
|
+
const tones = Array.from({ length: stack }, (_, j) => mod12(pcs[(i + j * 2) % 7] - pcs[i]));
|
|
183
|
+
const third = tones[1], fifth = tones[2];
|
|
184
|
+
const diminished = third === 3 && fifth === 6;
|
|
185
|
+
const augmented = third === 4 && fifth === 8;
|
|
186
|
+
const minor = third === 3;
|
|
187
|
+
if (![3, 4].includes(third) || ![6, 7, 8].includes(fifth))
|
|
188
|
+
throw new Error("Unsupported diatonic chord quality");
|
|
189
|
+
let suffix = diminished ? "dim" : augmented ? "aug" : minor ? "m" : "";
|
|
190
|
+
const degreeRoman = minor ? labels[i].toLowerCase() : labels[i];
|
|
191
|
+
let roman = degreeRoman;
|
|
192
|
+
if (diminished)
|
|
193
|
+
roman += "°";
|
|
194
|
+
if (augmented)
|
|
195
|
+
roman += "+";
|
|
196
|
+
if (stack >= 4) {
|
|
197
|
+
const seventh = tones[3];
|
|
198
|
+
if (![9, 10, 11].includes(seventh))
|
|
199
|
+
throw new Error("Unsupported diatonic seventh");
|
|
200
|
+
if (diminished && seventh === 9)
|
|
201
|
+
suffix = "dim7";
|
|
202
|
+
else {
|
|
203
|
+
if (seventh === 9)
|
|
204
|
+
throw new Error("Unsupported diminished seventh quality");
|
|
205
|
+
suffix = minor ? (seventh === 11 ? "mMaj7" : "m7") : (seventh === 11 ? "maj7" : "7");
|
|
206
|
+
if (fifth === 6)
|
|
207
|
+
suffix += "b5";
|
|
208
|
+
if (fifth === 8)
|
|
209
|
+
suffix += "#5";
|
|
210
|
+
}
|
|
211
|
+
roman = diminished && seventh === 10 ? `${degreeRoman}ø7` : `${roman}${seventh === 11 ? "maj7" : "7"}`;
|
|
212
|
+
}
|
|
213
|
+
if (stack === 5) {
|
|
214
|
+
const ninth = tones[4];
|
|
215
|
+
if (ninth === 2) {
|
|
216
|
+
suffix = suffix.replace("7", "9");
|
|
217
|
+
roman = roman.replace("7", "9");
|
|
218
|
+
}
|
|
219
|
+
else if (ninth === 1 || ninth === 3) {
|
|
220
|
+
const alteration = ninth === 1 ? "b9" : "#9";
|
|
221
|
+
suffix += `(${alteration})`;
|
|
222
|
+
roman += `(${alteration})`;
|
|
223
|
+
}
|
|
224
|
+
else
|
|
225
|
+
throw new Error("Unsupported diatonic ninth");
|
|
226
|
+
}
|
|
227
|
+
const rootSlug = (chordRoot[0].toLowerCase() + chordRoot.slice(1).replace(/b/g, "-flat").replace(/#/g, "-sharp"));
|
|
228
|
+
return { degree: i + 1, roman, symbol: chordRoot + suffix, root: chordRoot, slug: suffix ? `${rootSlug}-${modifierSlug(suffix)}` : rootSlug };
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
export function modeDemo(mode, defs) {
|
|
232
|
+
const degree = modeDegree(mode);
|
|
233
|
+
const ordinal = degree === 1 ? "st" : degree === 2 ? "nd" : degree === 3 ? "rd" : "th";
|
|
234
|
+
const { parent } = modeSource(mode, "C", defs);
|
|
235
|
+
const relativeRoot = mode.relativeExampleRoot ?? (degree === 1 ? "G" : spellScale(parent, "C")[degree - 1]);
|
|
236
|
+
const example = (root) => ({
|
|
237
|
+
root, notes: spellScale(mode, root),
|
|
238
|
+
question: `${root} is the ${ROMANS[degree - 1]} (${ordinal} degree) of?`,
|
|
239
|
+
answer: modeSource(mode, root, defs).parentRoot,
|
|
240
|
+
});
|
|
241
|
+
return {
|
|
242
|
+
title: `${degree}${ordinal} Degree - ${mode.name}`,
|
|
243
|
+
steps: [...mode.steps], degreeLabels: mode.degreeLabels ? [...mode.degreeLabels] : degreeLabelsOf(mode.intervals),
|
|
244
|
+
parallel: { ...example("C"), root: "C" },
|
|
245
|
+
relative: (() => {
|
|
246
|
+
const relative = example(relativeRoot);
|
|
247
|
+
const parentNotes = spellScale(parent, relative.answer);
|
|
248
|
+
const start = degree - 1;
|
|
249
|
+
return { ...relative, notes: [...parentNotes.slice(start), ...parentNotes.slice(0, start)] };
|
|
250
|
+
})(),
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=scale-library.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scale-library.js","sourceRoot":"","sources":["../../src/theory/scale-library.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type TextSize = "base" | "lg" | "xl" | "2xl";
|
|
|
5
5
|
export type NoteNameMode = "pitch-class" | "midi" | "degree" | "pitch-class+degree" | "midi+degree";
|
|
6
6
|
export type WhiteNote = "C" | "D" | "E" | "F" | "G" | "A" | "B";
|
|
7
7
|
export type NoteName = string;
|
|
8
|
-
export type PlaybackInstrument = "acoustic_grand_piano" | "electric_guitar_clean" | "ukulele";
|
|
8
|
+
export type PlaybackInstrument = "acoustic_grand_piano" | "electric_guitar_clean" | "ukulele" | "electric_bass_finger";
|
|
9
9
|
export interface ColorTheme {
|
|
10
10
|
name: string;
|
|
11
11
|
whiteKey: (note: string, highlighted: boolean) => string;
|