@musodojo/music-theory-data 14.0.2 → 15.0.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/package.json +2 -2
- package/src/data/note-collections/augmented.ts +82 -0
- package/src/data/note-collections/diminished.ts +73 -0
- package/src/data/note-collections/minor-variants.ts +101 -0
- package/src/data/note-collections/mod.ts +39 -5
- package/src/data/note-collections/pentatonics.ts +93 -0
- package/src/data/note-collections/todo.txt +1 -132
- package/src/utils/note-collections.ts +36 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@musodojo/music-theory-data",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "15.0.0",
|
|
4
4
|
"description": "The musician-friendly TypeScript library for modes, scales, chords, and more.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"music",
|
|
@@ -10,4 +10,4 @@
|
|
|
10
10
|
"author": "Conor Dowdall",
|
|
11
11
|
"type": "module",
|
|
12
12
|
"main": "src/mod.ts"
|
|
13
|
-
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { NoteCollection } from "../../types/note-collections.d.ts";
|
|
2
|
+
|
|
3
|
+
const augmentedTriad: NoteCollection = {
|
|
4
|
+
primaryName: "aug",
|
|
5
|
+
names: ["aug", "+", "Augmented Triad"],
|
|
6
|
+
intervals: ["1", "3", "♯5"],
|
|
7
|
+
integers: [0, 4, 8],
|
|
8
|
+
type: ["augmented", "chord", "arpeggio", "triad", "symmetrical"],
|
|
9
|
+
characteristics: ["tense", "unstable", "dreamy", "dissonant"],
|
|
10
|
+
pattern: ["major third", "major third"],
|
|
11
|
+
patternShort: ["M3", "M3"],
|
|
12
|
+
} as const;
|
|
13
|
+
|
|
14
|
+
const italian6: NoteCollection = {
|
|
15
|
+
primaryName: "It+6",
|
|
16
|
+
names: ["It+6", "Italian 6th"],
|
|
17
|
+
intervals: ["1", "3", "♭6"],
|
|
18
|
+
integers: [0, 4, 8],
|
|
19
|
+
type: ["augmented", "chord", "arpeggio", "triad", "classical"],
|
|
20
|
+
characteristics: [
|
|
21
|
+
"classical harmony",
|
|
22
|
+
"pre-dominant function",
|
|
23
|
+
"chromatic",
|
|
24
|
+
],
|
|
25
|
+
pattern: ["major third", "diminished fourth"],
|
|
26
|
+
patternShort: ["M3", "d4"],
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
29
|
+
const french6: NoteCollection = {
|
|
30
|
+
primaryName: "Fr+6",
|
|
31
|
+
names: ["Fr+6", "French 6th"],
|
|
32
|
+
intervals: ["1", "3", "♯4", "♭6"],
|
|
33
|
+
integers: [0, 4, 6, 8],
|
|
34
|
+
type: ["augmented", "chord", "arpeggio", "tetrad", "classical"],
|
|
35
|
+
characteristics: [
|
|
36
|
+
"classical harmony",
|
|
37
|
+
"pre-dominant function",
|
|
38
|
+
"chromatic",
|
|
39
|
+
"contains a tritone",
|
|
40
|
+
],
|
|
41
|
+
pattern: ["major third", "minor second", "major second"],
|
|
42
|
+
patternShort: ["M3", "m2", "M2"],
|
|
43
|
+
} as const;
|
|
44
|
+
|
|
45
|
+
const german6: NoteCollection = {
|
|
46
|
+
primaryName: "Ger+6",
|
|
47
|
+
names: ["Ger+6", "German 6th"],
|
|
48
|
+
intervals: ["1", "3", "5", "♭6"],
|
|
49
|
+
integers: [0, 4, 7, 8],
|
|
50
|
+
type: ["augmented", "chord", "arpeggio", "tetrad", "classical"],
|
|
51
|
+
characteristics: [
|
|
52
|
+
"classical harmony",
|
|
53
|
+
"pre-dominant function",
|
|
54
|
+
"chromatic",
|
|
55
|
+
"enharmonically equivalent to a dominant 7th",
|
|
56
|
+
],
|
|
57
|
+
pattern: ["major third", "minor third", "augmented unison"],
|
|
58
|
+
patternShort: ["M3", "m3", "A1"],
|
|
59
|
+
} as const;
|
|
60
|
+
|
|
61
|
+
const augmented7: NoteCollection = {
|
|
62
|
+
primaryName: "aug7",
|
|
63
|
+
names: ["aug7", "+7", "7♯5", "Augmented Seventh"],
|
|
64
|
+
intervals: ["1", "3", "♯5", "♭7"],
|
|
65
|
+
integers: [0, 4, 8, 10],
|
|
66
|
+
type: ["augmented", "dominant", "chord", "arpeggio", "tetrad"],
|
|
67
|
+
characteristics: ["tense", "unstable", "dissonant", "dominant function"],
|
|
68
|
+
pattern: ["major third", "major third", "minor second"],
|
|
69
|
+
patternShort: ["M3", "M3", "m2"],
|
|
70
|
+
} as const;
|
|
71
|
+
|
|
72
|
+
export const _augmented = {
|
|
73
|
+
augmentedTriad,
|
|
74
|
+
italian6,
|
|
75
|
+
french6,
|
|
76
|
+
german6,
|
|
77
|
+
augmented7,
|
|
78
|
+
} as const;
|
|
79
|
+
|
|
80
|
+
export type AugmentedKey = keyof typeof _augmented;
|
|
81
|
+
|
|
82
|
+
export const augmented: Record<AugmentedKey, NoteCollection> = _augmented;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { NoteCollection } from "../../types/note-collections.d.ts";
|
|
2
|
+
|
|
3
|
+
const diminishedTriad: NoteCollection = {
|
|
4
|
+
primaryName: "dim",
|
|
5
|
+
names: ["dim", "°", "Diminished Triad"],
|
|
6
|
+
intervals: ["1", "♭3", "♭5"],
|
|
7
|
+
integers: [0, 3, 6],
|
|
8
|
+
type: ["diminished", "chord", "arpeggio", "triad"],
|
|
9
|
+
characteristics: ["tense", "unstable", "dissonant"],
|
|
10
|
+
pattern: ["minor third", "minor third"],
|
|
11
|
+
patternShort: ["m3", "m3"],
|
|
12
|
+
} as const;
|
|
13
|
+
|
|
14
|
+
const diminished7: NoteCollection = {
|
|
15
|
+
primaryName: "dim7",
|
|
16
|
+
names: ["dim7", "°7", "Diminished 7th"],
|
|
17
|
+
intervals: ["1", "♭3", "♭5", "𝄫7"],
|
|
18
|
+
integers: [0, 3, 6, 9],
|
|
19
|
+
type: ["diminished", "chord", "arpeggio", "tetrad", "symmetrical"],
|
|
20
|
+
characteristics: ["very tense", "unstable", "symmetrical", "passing chord"],
|
|
21
|
+
pattern: ["minor third", "minor third", "minor third"],
|
|
22
|
+
patternShort: ["m3", "m3", "m3"],
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
25
|
+
const halfDiminished7: NoteCollection = {
|
|
26
|
+
primaryName: "m7♭5",
|
|
27
|
+
names: ["m7♭5", "ø7", "Half Diminished 7th"],
|
|
28
|
+
intervals: ["1", "♭3", "♭5", "♭7"],
|
|
29
|
+
integers: [0, 3, 6, 10],
|
|
30
|
+
type: ["diminished", "minor", "chord", "arpeggio", "tetrad"],
|
|
31
|
+
characteristics: ["tense", "jazzy", "leading to minor"],
|
|
32
|
+
pattern: ["minor third", "minor third", "major third"],
|
|
33
|
+
patternShort: ["m3", "m3", "M3"],
|
|
34
|
+
} as const;
|
|
35
|
+
|
|
36
|
+
const wholeHalfDiminished: NoteCollection = {
|
|
37
|
+
primaryName: "Whole Half Diminished",
|
|
38
|
+
names: ["Whole Half Diminished"],
|
|
39
|
+
intervals: ["1", "2", "♭3", "4", "♭5", "♭6", "6", "7"],
|
|
40
|
+
integers: [0, 2, 3, 5, 6, 8, 9, 11],
|
|
41
|
+
type: ["diminished", "scale", "symmetrical", "octatonic"],
|
|
42
|
+
characteristics: ["tense", "jazzy", "symmetrical", "alternating tones"],
|
|
43
|
+
pattern: ["whole", "half", "whole", "half", "whole", "half", "whole", "half"],
|
|
44
|
+
patternShort: ["W", "H", "W", "H", "W", "H", "W", "H"],
|
|
45
|
+
} as const;
|
|
46
|
+
|
|
47
|
+
const halfWholeDiminished: NoteCollection = {
|
|
48
|
+
primaryName: "Half Whole Diminished",
|
|
49
|
+
names: ["Half Whole Diminished", "Dominant Diminished"],
|
|
50
|
+
intervals: ["1", "♭2", "♭3", "3", "♯4", "5", "6", "♭7"],
|
|
51
|
+
integers: [0, 1, 3, 4, 6, 7, 9, 10],
|
|
52
|
+
type: ["diminished", "dominant", "scale", "symmetrical", "octatonic"],
|
|
53
|
+
characteristics: [
|
|
54
|
+
"tense",
|
|
55
|
+
"jazzy",
|
|
56
|
+
"symmetrical",
|
|
57
|
+
"used over dominant 7th chords",
|
|
58
|
+
],
|
|
59
|
+
pattern: ["half", "whole", "half", "whole", "half", "whole", "half", "whole"],
|
|
60
|
+
patternShort: ["H", "W", "H", "W", "H", "W", "H", "W"],
|
|
61
|
+
} as const;
|
|
62
|
+
|
|
63
|
+
export const _diminished = {
|
|
64
|
+
diminishedTriad,
|
|
65
|
+
diminished7,
|
|
66
|
+
halfDiminished7,
|
|
67
|
+
wholeHalfDiminished,
|
|
68
|
+
halfWholeDiminished,
|
|
69
|
+
} as const;
|
|
70
|
+
|
|
71
|
+
export type DiminishedKey = keyof typeof _diminished;
|
|
72
|
+
|
|
73
|
+
export const diminished: Record<DiminishedKey, NoteCollection> = _diminished;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { NoteCollection } from "../../types/note-collections.d.ts";
|
|
2
|
+
|
|
3
|
+
const minor: NoteCollection = {
|
|
4
|
+
primaryName: "m",
|
|
5
|
+
names: ["m", "min", "Minor", "Minor Triad"],
|
|
6
|
+
intervals: ["1", "♭3", "5"],
|
|
7
|
+
integers: [0, 3, 7],
|
|
8
|
+
type: ["minor", "chord", "arpeggio", "triad"],
|
|
9
|
+
characteristics: [
|
|
10
|
+
"sad",
|
|
11
|
+
"melancholic",
|
|
12
|
+
"dark",
|
|
13
|
+
"the most basic minor chord",
|
|
14
|
+
],
|
|
15
|
+
pattern: ["minor third", "major third"],
|
|
16
|
+
patternShort: ["m3", "M3"],
|
|
17
|
+
} as const;
|
|
18
|
+
|
|
19
|
+
const minor6: NoteCollection = {
|
|
20
|
+
primaryName: "m6",
|
|
21
|
+
names: ["m6", "min6", "Minor 6th", "Minor Sixth"],
|
|
22
|
+
intervals: ["1", "♭3", "5", "6"],
|
|
23
|
+
integers: [0, 3, 7, 9],
|
|
24
|
+
type: ["minor", "chord", "arpeggio", "tetrad"],
|
|
25
|
+
characteristics: [
|
|
26
|
+
"jazzy",
|
|
27
|
+
"soulful",
|
|
28
|
+
"less dissonant than m7",
|
|
29
|
+
"dorian feel",
|
|
30
|
+
],
|
|
31
|
+
pattern: ["minor third", "major third", "major second"],
|
|
32
|
+
patternShort: ["m3", "M3", "M2"],
|
|
33
|
+
} as const;
|
|
34
|
+
|
|
35
|
+
const minor7: NoteCollection = {
|
|
36
|
+
primaryName: "m7",
|
|
37
|
+
names: ["m7", "min7", "Minor 7th", "Minor Seventh"],
|
|
38
|
+
intervals: ["1", "♭3", "5", "♭7"],
|
|
39
|
+
integers: [0, 3, 7, 10],
|
|
40
|
+
type: ["minor", "chord", "arpeggio", "tetrad"],
|
|
41
|
+
characteristics: ["smooth", "jazzy", "versatile", "foundational minor chord"],
|
|
42
|
+
pattern: ["minor third", "major third", "minor third"],
|
|
43
|
+
patternShort: ["m3", "M3", "m3"],
|
|
44
|
+
} as const;
|
|
45
|
+
|
|
46
|
+
const minor9: NoteCollection = {
|
|
47
|
+
primaryName: "m9",
|
|
48
|
+
names: ["m9", "min9", "Minor 9th", "Minor Ninth"],
|
|
49
|
+
intervals: ["1", "♭3", "5", "♭7", "9"],
|
|
50
|
+
integers: [0, 2, 3, 7, 10],
|
|
51
|
+
type: ["minor", "chord", "arpeggio", "pentad"],
|
|
52
|
+
characteristics: ["rich", "lush", "sophisticated", "common in jazz"],
|
|
53
|
+
pattern: ["minor third", "major third", "minor third", "major third"],
|
|
54
|
+
patternShort: ["m3", "M3", "m3", "M3"],
|
|
55
|
+
} as const;
|
|
56
|
+
|
|
57
|
+
const minorAdd9: NoteCollection = {
|
|
58
|
+
primaryName: "m(add9)",
|
|
59
|
+
names: ["m(add9)", "min(add9)", "Minor add 9"],
|
|
60
|
+
intervals: ["1", "♭3", "5", "9"],
|
|
61
|
+
integers: [0, 2, 3, 7],
|
|
62
|
+
type: ["minor", "chord", "arpeggio", "tetrad"],
|
|
63
|
+
characteristics: [
|
|
64
|
+
"open",
|
|
65
|
+
"modern",
|
|
66
|
+
"adds color without the 7th",
|
|
67
|
+
"pop and rock music",
|
|
68
|
+
],
|
|
69
|
+
pattern: ["minor third", "major third", "perfect fifth"],
|
|
70
|
+
patternShort: ["m3", "M3", "P5"],
|
|
71
|
+
} as const;
|
|
72
|
+
|
|
73
|
+
const minor6Add9: NoteCollection = {
|
|
74
|
+
primaryName: "m6/9",
|
|
75
|
+
names: ["m6/9", "min6/9", "Minor 6/9"],
|
|
76
|
+
intervals: ["1", "♭3", "5", "6", "9"],
|
|
77
|
+
integers: [0, 2, 3, 7, 9],
|
|
78
|
+
type: ["minor", "chord", "arpeggio", "pentad"],
|
|
79
|
+
characteristics: [
|
|
80
|
+
"rich",
|
|
81
|
+
"jazzy",
|
|
82
|
+
"dorian flavor",
|
|
83
|
+
"sophisticated minor sound",
|
|
84
|
+
],
|
|
85
|
+
pattern: ["minor third", "major third", "major second", "perfect fourth"],
|
|
86
|
+
patternShort: ["m3", "M3", "M2", "P4"],
|
|
87
|
+
} as const;
|
|
88
|
+
|
|
89
|
+
export const _minorVariants = {
|
|
90
|
+
minor,
|
|
91
|
+
minor6,
|
|
92
|
+
minor7,
|
|
93
|
+
minor9,
|
|
94
|
+
minorAdd9,
|
|
95
|
+
minor6Add9,
|
|
96
|
+
} as const;
|
|
97
|
+
|
|
98
|
+
export type MinorVariantKey = keyof typeof _minorVariants;
|
|
99
|
+
|
|
100
|
+
export const minorVariants: Record<MinorVariantKey, NoteCollection> =
|
|
101
|
+
_minorVariants;
|
|
@@ -1,23 +1,35 @@
|
|
|
1
1
|
import { diatonicModes } from "./diatonic-modes.ts";
|
|
2
2
|
import { harmonicMinorModes } from "./harmonic-minor-modes.ts";
|
|
3
3
|
import { melodicMinorModes } from "./melodic-minor-modes.ts";
|
|
4
|
+
import { minorVariants } from "./minor-variants.ts";
|
|
4
5
|
import { dominantVariants } from "./dominant-variants.ts";
|
|
5
6
|
import { majorVariants } from "./major-variants.ts";
|
|
7
|
+
import { pentatonics } from "./pentatonics.ts";
|
|
8
|
+
import { diminished } from "./diminished.ts";
|
|
9
|
+
import { augmented } from "./augmented.ts";
|
|
6
10
|
import { otherNoteCollections } from "./other-collections.ts";
|
|
7
11
|
|
|
8
12
|
export { diatonicModes } from "./diatonic-modes.ts";
|
|
9
13
|
export { dominantVariants } from "./dominant-variants.ts";
|
|
10
14
|
export { harmonicMinorModes } from "./harmonic-minor-modes.ts";
|
|
11
15
|
export { majorVariants } from "./major-variants.ts";
|
|
16
|
+
export { minorVariants } from "./minor-variants.ts";
|
|
12
17
|
export { melodicMinorModes } from "./melodic-minor-modes.ts";
|
|
18
|
+
export { pentatonics } from "./pentatonics.ts";
|
|
19
|
+
export { diminished } from "./diminished.ts";
|
|
20
|
+
export { augmented } from "./augmented.ts";
|
|
13
21
|
export { otherNoteCollections } from "./other-collections.ts";
|
|
14
22
|
|
|
15
23
|
export const noteCollections = {
|
|
16
24
|
...diatonicModes,
|
|
17
25
|
...harmonicMinorModes,
|
|
18
26
|
...melodicMinorModes,
|
|
19
|
-
...dominantVariants,
|
|
20
27
|
...majorVariants,
|
|
28
|
+
...minorVariants,
|
|
29
|
+
...dominantVariants,
|
|
30
|
+
...pentatonics,
|
|
31
|
+
...diminished,
|
|
32
|
+
...augmented,
|
|
21
33
|
...otherNoteCollections,
|
|
22
34
|
} as const;
|
|
23
35
|
|
|
@@ -27,8 +39,12 @@ export const groupedNoteCollections = {
|
|
|
27
39
|
diatonicModes,
|
|
28
40
|
harmonicMinorModes,
|
|
29
41
|
melodicMinorModes,
|
|
30
|
-
dominantVariants,
|
|
31
42
|
majorVariants,
|
|
43
|
+
minorVariants,
|
|
44
|
+
dominantVariants,
|
|
45
|
+
pentatonics,
|
|
46
|
+
diminished,
|
|
47
|
+
augmented,
|
|
32
48
|
otherNoteCollections,
|
|
33
49
|
} as const;
|
|
34
50
|
|
|
@@ -56,15 +72,33 @@ export const noteCollectionGroupsMetadata: Record<
|
|
|
56
72
|
description:
|
|
57
73
|
"Seven-note scales derived from the melodic minor scale, each starting on a different scale degree.",
|
|
58
74
|
},
|
|
75
|
+
majorVariants: {
|
|
76
|
+
displayName: "Major Variants",
|
|
77
|
+
description:
|
|
78
|
+
"Chord structures based on the major triad, including sixth and major seventh harmonies.",
|
|
79
|
+
},
|
|
80
|
+
minorVariants: {
|
|
81
|
+
displayName: "Minor Variants",
|
|
82
|
+
description:
|
|
83
|
+
"Chord structures based on the minor triad, including sixth and seventh harmonies.",
|
|
84
|
+
},
|
|
59
85
|
dominantVariants: {
|
|
60
86
|
displayName: "Dominant Variants",
|
|
61
87
|
description:
|
|
62
88
|
"Chord structures based on the dominant seventh chord, including extended harmonies (9ths, 11ths, 13ths).",
|
|
63
89
|
},
|
|
64
|
-
|
|
65
|
-
displayName: "
|
|
90
|
+
pentatonics: {
|
|
91
|
+
displayName: "Pentatonic Scales",
|
|
92
|
+
description: "Five-note scales used widely in folk, blues, and rock music.",
|
|
93
|
+
},
|
|
94
|
+
diminished: {
|
|
95
|
+
displayName: "Diminished",
|
|
96
|
+
description: "Tense and dissonant chords and scales built on minor thirds.",
|
|
97
|
+
},
|
|
98
|
+
augmented: {
|
|
99
|
+
displayName: "Augmented",
|
|
66
100
|
description:
|
|
67
|
-
"
|
|
101
|
+
"Unstable and dreamy chords and scales, including classical augmented sixth chords.",
|
|
68
102
|
},
|
|
69
103
|
otherNoteCollections: {
|
|
70
104
|
displayName: "Other",
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { NoteCollection } from "../../types/note-collections.d.ts";
|
|
2
|
+
|
|
3
|
+
const majorPentatonic: NoteCollection = {
|
|
4
|
+
primaryName: "Major Pentatonic",
|
|
5
|
+
names: ["Major Pentatonic"],
|
|
6
|
+
intervals: ["1", "2", "3", "5", "6"],
|
|
7
|
+
integers: [0, 2, 4, 7, 9],
|
|
8
|
+
type: ["major", "pentatonic", "scale", "gapped scale"],
|
|
9
|
+
characteristics: [
|
|
10
|
+
"open",
|
|
11
|
+
"positive",
|
|
12
|
+
"simple",
|
|
13
|
+
"found in many cultures",
|
|
14
|
+
"folk music",
|
|
15
|
+
"country music",
|
|
16
|
+
],
|
|
17
|
+
pattern: ["whole", "whole", "minor third", "whole"],
|
|
18
|
+
patternShort: ["W", "W", "m3", "W"],
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
21
|
+
const suspendedPentatonic: NoteCollection = {
|
|
22
|
+
primaryName: "Suspended Pentatonic",
|
|
23
|
+
names: ["Suspended Pentatonic", "Egyptian Pentatonic"],
|
|
24
|
+
intervals: ["1", "2", "4", "5", "♭7"],
|
|
25
|
+
integers: [0, 2, 5, 7, 10],
|
|
26
|
+
type: ["suspended", "pentatonic", "scale", "gapped scale"],
|
|
27
|
+
characteristics: ["open", "stable", "neutral", "neither major nor minor"],
|
|
28
|
+
pattern: ["whole", "minor third", "whole", "minor third"],
|
|
29
|
+
patternShort: ["W", "m3", "W", "m3"],
|
|
30
|
+
} as const;
|
|
31
|
+
|
|
32
|
+
const bluesMinorPentatonic: NoteCollection = {
|
|
33
|
+
primaryName: "Blues Minor Pentatonic",
|
|
34
|
+
names: ["Blues Minor Pentatonic"],
|
|
35
|
+
intervals: ["1", "♭3", "4", "♭5", "♭7"],
|
|
36
|
+
integers: [0, 3, 5, 6, 10],
|
|
37
|
+
type: ["minor", "pentatonic", "scale", "gapped scale", "blues"],
|
|
38
|
+
characteristics: ["bluesy", "tense", "minor with a blue note"],
|
|
39
|
+
pattern: ["minor third", "whole", "half", "minor third"],
|
|
40
|
+
patternShort: ["m3", "W", "H", "m3"],
|
|
41
|
+
} as const;
|
|
42
|
+
|
|
43
|
+
const bluesMajorPentatonic: NoteCollection = {
|
|
44
|
+
primaryName: "Blues Major Pentatonic",
|
|
45
|
+
names: ["Blues Major Pentatonic"],
|
|
46
|
+
intervals: ["1", "2", "♭3", "5", "6"],
|
|
47
|
+
integers: [0, 2, 3, 7, 9],
|
|
48
|
+
type: ["major", "pentatonic", "scale", "gapped scale", "blues"],
|
|
49
|
+
characteristics: ["bluesy", "country", "major with a blue note"],
|
|
50
|
+
pattern: ["whole", "half", "major third", "whole"],
|
|
51
|
+
patternShort: ["W", "H", "M3", "W"],
|
|
52
|
+
} as const;
|
|
53
|
+
|
|
54
|
+
const minorPentatonic: NoteCollection = {
|
|
55
|
+
primaryName: "Minor Pentatonic",
|
|
56
|
+
names: ["Minor Pentatonic"],
|
|
57
|
+
intervals: ["1", "♭3", "4", "5", "♭7"],
|
|
58
|
+
integers: [0, 3, 5, 7, 10],
|
|
59
|
+
type: ["minor", "pentatonic", "scale", "gapped scale"],
|
|
60
|
+
characteristics: [
|
|
61
|
+
"bluesy",
|
|
62
|
+
"rock",
|
|
63
|
+
"versatile",
|
|
64
|
+
"found in many cultures",
|
|
65
|
+
"relative of major pentatonic",
|
|
66
|
+
],
|
|
67
|
+
pattern: ["minor third", "whole", "whole", "minor third"],
|
|
68
|
+
patternShort: ["m3", "W", "W", "m3"],
|
|
69
|
+
} as const;
|
|
70
|
+
|
|
71
|
+
const dominantPentatonic: NoteCollection = {
|
|
72
|
+
primaryName: "Dominant Pentatonic",
|
|
73
|
+
names: ["Dominant Pentatonic"],
|
|
74
|
+
intervals: ["1", "2", "3", "5", "♭7"],
|
|
75
|
+
integers: [0, 2, 4, 7, 10],
|
|
76
|
+
type: ["dominant", "pentatonic", "scale", "gapped scale"],
|
|
77
|
+
characteristics: ["bluesy", "dominant feel", "mixolydian flavor"],
|
|
78
|
+
pattern: ["whole", "whole", "minor third", "minor third"],
|
|
79
|
+
patternShort: ["W", "W", "m3", "m3"],
|
|
80
|
+
} as const;
|
|
81
|
+
|
|
82
|
+
export const _pentatonics = {
|
|
83
|
+
majorPentatonic,
|
|
84
|
+
suspendedPentatonic,
|
|
85
|
+
bluesMinorPentatonic,
|
|
86
|
+
bluesMajorPentatonic,
|
|
87
|
+
minorPentatonic,
|
|
88
|
+
dominantPentatonic,
|
|
89
|
+
} as const;
|
|
90
|
+
|
|
91
|
+
export type PentatonicKey = keyof typeof _pentatonics;
|
|
92
|
+
|
|
93
|
+
export const pentatonics: Record<PentatonicKey, NoteCollection> = _pentatonics;
|
|
@@ -2,45 +2,27 @@
|
|
|
2
2
|
export default [
|
|
3
3
|
{
|
|
4
4
|
name: "m / Minor",
|
|
5
|
-
category: "Minor",
|
|
6
5
|
sequence: [0, 3, 7],
|
|
7
6
|
},
|
|
8
7
|
{
|
|
9
8
|
name: "m6 / Minor Major 6th",
|
|
10
|
-
category: "Minor",
|
|
11
9
|
sequence: [0, 3, 7, 9],
|
|
12
10
|
},
|
|
13
11
|
{
|
|
14
12
|
name: "m7 / Minor 7th",
|
|
15
|
-
category: "Minor",
|
|
16
13
|
sequence: [0, 3, 7, 10],
|
|
17
14
|
},
|
|
18
15
|
{
|
|
19
16
|
name: "m9 / Minor 9th",
|
|
20
|
-
category: "Minor",
|
|
21
17
|
sequence: [0, 2, 3, 7, 10],
|
|
22
|
-
labels: {
|
|
23
|
-
Quality: { 2: "M9" },
|
|
24
|
-
Relative: { 2: "9" },
|
|
25
|
-
},
|
|
26
18
|
},
|
|
27
19
|
{
|
|
28
20
|
name: "m(add9) / Minor add 9",
|
|
29
|
-
category: "Minor",
|
|
30
21
|
sequence: [0, 2, 3, 7],
|
|
31
|
-
labels: {
|
|
32
|
-
Quality: { 2: "M9" },
|
|
33
|
-
Relative: { 2: "9" },
|
|
34
|
-
},
|
|
35
22
|
},
|
|
36
23
|
{
|
|
37
24
|
name: "m6/9 / Minor 6/9",
|
|
38
|
-
category: "Minor",
|
|
39
25
|
sequence: [0, 2, 3, 7, 9],
|
|
40
|
-
labels: {
|
|
41
|
-
Quality: { 2: "M9" },
|
|
42
|
-
Relative: { 2: "9" },
|
|
43
|
-
},
|
|
44
26
|
},
|
|
45
27
|
];
|
|
46
28
|
|
|
@@ -49,188 +31,75 @@ export default [
|
|
|
49
31
|
export default [
|
|
50
32
|
{
|
|
51
33
|
name: "Major Pentatonic",
|
|
52
|
-
category: "Pentatonic",
|
|
53
34
|
sequence: [0, 2, 4, 7, 9],
|
|
54
35
|
},
|
|
55
36
|
{
|
|
56
37
|
name: "Suspended Pentatonic",
|
|
57
|
-
category: "Pentatonic",
|
|
58
38
|
sequence: [0, 2, 5, 7, 10],
|
|
59
39
|
},
|
|
60
40
|
{
|
|
61
41
|
name: "Blues Minor Pentatonic",
|
|
62
|
-
category: "Pentatonic",
|
|
63
42
|
sequence: [0, 3, 5, 8, 10],
|
|
64
43
|
},
|
|
65
44
|
{
|
|
66
45
|
name: "Blues Major Pentatonic",
|
|
67
|
-
category: "Pentatonic",
|
|
68
46
|
sequence: [0, 2, 5, 7, 9],
|
|
69
47
|
},
|
|
70
48
|
{
|
|
71
49
|
name: "Minor Pentatonic",
|
|
72
|
-
category: "Pentatonic",
|
|
73
50
|
sequence: [0, 3, 5, 7, 10],
|
|
74
51
|
},
|
|
75
52
|
{
|
|
76
53
|
name: "Dominant Pentatonic",
|
|
77
|
-
category: "Pentatonic",
|
|
78
54
|
sequence: [0, 2, 4, 7, 10],
|
|
79
55
|
},
|
|
80
56
|
];
|
|
81
57
|
|
|
82
58
|
|
|
83
|
-
// OTHER
|
|
84
|
-
export default [
|
|
85
59
|
// Diminished
|
|
86
60
|
{
|
|
87
61
|
name: "dim / o / Diminished Triad",
|
|
88
|
-
category: "Diminished",
|
|
89
62
|
sequence: [0, 3, 6],
|
|
90
63
|
},
|
|
91
64
|
{
|
|
92
65
|
name: "dim7 / o7 / Diminished 7th",
|
|
93
|
-
category: "Diminished",
|
|
94
66
|
sequence: [0, 3, 6, 9],
|
|
95
|
-
labels: {
|
|
96
|
-
Quality: { 9: "d7" },
|
|
97
|
-
Relative: { 9: "♭♭7" },
|
|
98
|
-
Extension: { 9: "♭♭7" },
|
|
99
|
-
},
|
|
100
67
|
},
|
|
101
68
|
{
|
|
102
69
|
name: "m7♭5 / ø7 / Half Diminished 7th",
|
|
103
|
-
category: "Diminished",
|
|
104
70
|
sequence: [0, 3, 6, 10],
|
|
105
71
|
},
|
|
106
72
|
{
|
|
107
73
|
name: "Whole Half Diminished",
|
|
108
|
-
category: "Diminished",
|
|
109
74
|
sequence: [0, 2, 3, 5, 6, 8, 9, 11],
|
|
110
|
-
labels: {
|
|
111
|
-
Quality: { 8: "A5" },
|
|
112
|
-
Relative: { 8: "♯5" },
|
|
113
|
-
Extension: { 8: "♯5" },
|
|
114
|
-
},
|
|
115
75
|
},
|
|
116
76
|
{
|
|
117
77
|
name: "Half Whole / Dominant Diminished",
|
|
118
|
-
category: "Diminished",
|
|
119
78
|
sequence: [0, 1, 3, 4, 6, 7, 9, 10],
|
|
120
|
-
labels: {
|
|
121
|
-
Quality: { 3: "A2", 6: "A4" },
|
|
122
|
-
Relative: { 3: "♯2", 6: "♯4" },
|
|
123
|
-
Extension: { 3: "♯9", 6: "♯11" },
|
|
124
|
-
},
|
|
125
79
|
},
|
|
80
|
+
|
|
126
81
|
// Augmented
|
|
127
82
|
{
|
|
128
83
|
name: "aug / + / Augmented Triad",
|
|
129
|
-
category: "Augmented",
|
|
130
84
|
sequence: [0, 4, 8],
|
|
131
|
-
labels: {
|
|
132
|
-
Quality: { 8: "A5" },
|
|
133
|
-
Relative: { 8: "♯5" },
|
|
134
|
-
Extension: { 8: "♯5" },
|
|
135
|
-
},
|
|
136
85
|
},
|
|
137
86
|
{
|
|
138
87
|
name: "It+6 / Italian 6th",
|
|
139
|
-
category: "Augmented",
|
|
140
88
|
sequence: [0, 4, 10],
|
|
141
|
-
labels: {
|
|
142
|
-
Quality: { 10: "A6" },
|
|
143
|
-
Relative: { 10: "♯6" },
|
|
144
|
-
Extension: { 10: "♯13" },
|
|
145
|
-
},
|
|
146
89
|
},
|
|
147
90
|
{
|
|
148
91
|
name: "Fr+6 / French 6th",
|
|
149
|
-
category: "Augmented",
|
|
150
92
|
sequence: [0, 4, 6, 10],
|
|
151
|
-
labels: {
|
|
152
|
-
Quality: { 10: "A6" },
|
|
153
|
-
Relative: { 10: "♯6" },
|
|
154
|
-
Extension: { 10: "♯13" },
|
|
155
|
-
},
|
|
156
93
|
},
|
|
157
94
|
{
|
|
158
95
|
name: "Ger+6 / German 6th",
|
|
159
|
-
category: "Augmented",
|
|
160
96
|
sequence: [0, 4, 7, 10],
|
|
161
|
-
labels: {
|
|
162
|
-
Quality: { 10: "A6" },
|
|
163
|
-
Relative: { 10: "♯6" },
|
|
164
|
-
Extension: { 10: "♯13" },
|
|
165
|
-
},
|
|
166
97
|
},
|
|
167
98
|
{
|
|
168
99
|
name: "aug7 / +7 / 7♯5 / Augmented Seventh",
|
|
169
|
-
category: "Augmented",
|
|
170
100
|
sequence: [0, 4, 8, 10],
|
|
171
|
-
labels: {
|
|
172
|
-
Quality: { 8: "A5" },
|
|
173
|
-
Relative: { 8: "♯5" },
|
|
174
|
-
Extension: { 8: "♯5" },
|
|
175
|
-
},
|
|
176
101
|
},
|
|
177
102
|
|
|
178
|
-
// Harmonic Minor
|
|
179
|
-
{
|
|
180
|
-
name: "Harmonic Minor",
|
|
181
|
-
category: "Harmonic Minor",
|
|
182
|
-
sequence: [0, 2, 3, 5, 7, 8, 11],
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
name: "Locrian ♯6",
|
|
186
|
-
category: "Harmonic Minor",
|
|
187
|
-
sequence: [0, 1, 3, 5, 6, 9, 10],
|
|
188
|
-
},
|
|
189
|
-
{
|
|
190
|
-
name: "Ionian ♯5",
|
|
191
|
-
category: "Harmonic Minor",
|
|
192
|
-
sequence: [0, 2, 4, 5, 8, 9, 11],
|
|
193
|
-
labels: {
|
|
194
|
-
Quality: { 8: "A5" },
|
|
195
|
-
Relative: { 8: "♯5" },
|
|
196
|
-
Extension: { 8: "♯5" },
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
{
|
|
200
|
-
name: "Dorian ♯4",
|
|
201
|
-
category: "Harmonic Minor",
|
|
202
|
-
sequence: [0, 2, 3, 6, 7, 9, 10],
|
|
203
|
-
labels: {
|
|
204
|
-
Quality: { 6: "A4" },
|
|
205
|
-
Relative: { 6: "♯4" },
|
|
206
|
-
Extension: { 6: "♯11" },
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
name: "Phrygian Dominant",
|
|
211
|
-
category: "Harmonic Minor",
|
|
212
|
-
sequence: [0, 1, 4, 5, 7, 8, 10],
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
name: "Lydian ♯2",
|
|
216
|
-
category: "Harmonic Minor",
|
|
217
|
-
sequence: [0, 3, 4, 6, 7, 9, 11],
|
|
218
|
-
labels: {
|
|
219
|
-
Quality: { 3: "A2", 6: "A4" },
|
|
220
|
-
Relative: { 3: "♯2", 6: "♯4" },
|
|
221
|
-
Extension: { 3: "♯9", 6: "♯11" },
|
|
222
|
-
},
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
name: "Super Locrian ♭♭7",
|
|
226
|
-
category: "Harmonic Minor",
|
|
227
|
-
sequence: [0, 1, 3, 4, 6, 8, 9],
|
|
228
|
-
labels: {
|
|
229
|
-
Quality: { 4: "d4", 9: "d7" },
|
|
230
|
-
Relative: { 4: "♭4", 9: "♭♭7" },
|
|
231
|
-
Extension: { 4: "♭11", 9: "♭♭7" },
|
|
232
|
-
},
|
|
233
|
-
},
|
|
234
103
|
// Other
|
|
235
104
|
{
|
|
236
105
|
name: "R / Root",
|
|
@@ -109,18 +109,37 @@ export function searchNoteCollections(
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// 2. Apply prioritized text search on the filtered candidates
|
|
112
|
-
const prioritizedResults = new Set<NoteCollection>();
|
|
113
112
|
const normalizedQuery = normalizeSearchTerm(query);
|
|
114
113
|
|
|
115
114
|
if (!normalizedQuery) {
|
|
116
115
|
return candidates;
|
|
117
116
|
}
|
|
118
117
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
|
|
118
|
+
const searchWords = normalizedQuery.split(" ");
|
|
119
|
+
|
|
120
|
+
// Filter candidates to those that contain all search words
|
|
121
|
+
const textFilteredCandidates = candidates.filter((theme) => {
|
|
122
|
+
const searchableText = [
|
|
123
|
+
theme.primaryName,
|
|
124
|
+
...theme.names,
|
|
125
|
+
...theme.type,
|
|
126
|
+
...theme.characteristics,
|
|
127
|
+
]
|
|
128
|
+
.map(normalizeSearchTerm)
|
|
129
|
+
.join(" ");
|
|
130
|
+
|
|
131
|
+
return searchWords.every((word) => {
|
|
132
|
+
const isCaseSensitiveWord = word === "M" || word === "m";
|
|
133
|
+
const regex = new RegExp(
|
|
134
|
+
`\\b${word}\\b`,
|
|
135
|
+
isCaseSensitiveWord ? "" : "i",
|
|
136
|
+
);
|
|
137
|
+
return regex.test(searchableText);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// 3. Prioritize the filtered results
|
|
142
|
+
const prioritizedResults = new Set<NoteCollection>();
|
|
124
143
|
|
|
125
144
|
const passes = [
|
|
126
145
|
// Pass 1: Exact match on primaryName
|
|
@@ -129,30 +148,29 @@ export function searchNoteCollections(
|
|
|
129
148
|
// Pass 2: Exact match on any name
|
|
130
149
|
(theme: NoteCollection) =>
|
|
131
150
|
theme.names.some((name) => normalizeSearchTerm(name) === normalizedQuery),
|
|
132
|
-
// Pass 3:
|
|
151
|
+
// Pass 3: Primary name starts with the query
|
|
133
152
|
(theme: NoteCollection) =>
|
|
134
|
-
|
|
135
|
-
// Pass 4:
|
|
153
|
+
normalizeSearchTerm(theme.primaryName).startsWith(normalizedQuery),
|
|
154
|
+
// Pass 4: Any name starts with the query
|
|
136
155
|
(theme: NoteCollection) =>
|
|
137
|
-
theme.names.some((name) =>
|
|
138
|
-
|
|
139
|
-
(theme: NoteCollection) =>
|
|
140
|
-
theme.type.some((t) => searchRegex.test(normalizeSearchTerm(t))),
|
|
141
|
-
// Pass 8: Whole word match on any characteristic
|
|
142
|
-
(theme: NoteCollection) =>
|
|
143
|
-
theme.characteristics.some((c) =>
|
|
144
|
-
searchRegex.test(normalizeSearchTerm(c))
|
|
156
|
+
theme.names.some((name) =>
|
|
157
|
+
normalizeSearchTerm(name).startsWith(normalizedQuery)
|
|
145
158
|
),
|
|
146
159
|
];
|
|
147
160
|
|
|
148
161
|
for (const pass of passes) {
|
|
149
|
-
for (const theme of
|
|
162
|
+
for (const theme of textFilteredCandidates) {
|
|
150
163
|
if (pass(theme)) {
|
|
151
164
|
prioritizedResults.add(theme);
|
|
152
165
|
}
|
|
153
166
|
}
|
|
154
167
|
}
|
|
155
168
|
|
|
169
|
+
// Add the remaining text-filtered candidates that didn't match a priority pass
|
|
170
|
+
for (const theme of textFilteredCandidates) {
|
|
171
|
+
prioritizedResults.add(theme);
|
|
172
|
+
}
|
|
173
|
+
|
|
156
174
|
return Array.from(prioritizedResults);
|
|
157
175
|
}
|
|
158
176
|
|