@musodojo/music-theory-data 19.0.3 → 20.1.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/README.md CHANGED
@@ -3,43 +3,101 @@
3
3
  **The musician-friendly TypeScript library for modes, scales, chords, and
4
4
  more.**
5
5
 
6
- > **Note:** This library is currently under review for accuracy. Please verify
7
- > data before use in a critical application.
8
-
9
6
  ## Community & Support
10
7
 
11
- Have a question, a suggestion, or want to report a bug? I'd love to hear from
12
- you!
8
+ Have a question, a suggestion, or want to report a bug? Get in touch!
13
9
 
14
10
  - **💬 Ask a Question or Share an Idea:** Use
15
11
  [GitHub Discussions](https://github.com/conor-dowdall/music-theory-data/discussions).
16
- - **🐞 Report a Bug or Request a Feature:** Open a
12
+ - **🐞 Report a Bug or Flaw in the Data:** Open a
17
13
  [GitHub Issue](https://github.com/conor-dowdall/music-theory-data/issues).
18
14
 
19
- ## Verified Note Collections
15
+ ## Available Note Collections
20
16
 
21
17
  - ✅ Diatonic Modes
22
18
  - ✅ Pentatonic Variants
23
19
  - ✅ Major Variants
24
20
  - ✅ Minor Variants
25
- - 🛠️ Dominant Variants
21
+ - Dominant Variants
26
22
  - ✅ Harmonic Minor Modes
27
23
  - ✅ Melodic Minor Modes
28
- - 🛠️ Diminished Variants
29
- - 🛠️ Augmented Variants
30
- - 🛠️ Other Note Collections
24
+ - Diminished Variants
25
+ - Augmented Variants
26
+ - Other Note Collections
31
27
 
32
28
  ## Features
33
29
 
34
- - **Rich Data Structures:** Access detailed information for scales, modes,
35
- chords, and more, including intervals, integer notations, and common names.
36
- - **Practical Utility Functions:** Helpers for common tasks like generating note
37
- names from a root note and a collection key.
38
30
  - **Fully Typed:** Written in TypeScript with comprehensive type definitions for
39
31
  a great developer experience.
40
32
  - **Deno First, NPM Ready:** A modern Deno module that is also published to npm
41
33
  for use in Node.js projects.
42
34
 
35
+ ### Rich Data Structures
36
+
37
+ Access detailed information for scales, modes, chords, and more, including
38
+ intervals, integer notations, and common names.
39
+
40
+ ```ts
41
+ // src/data/note-collections/diatonic-modes.ts
42
+ const ionian: ModalScaleCollection = {
43
+ category: "scale",
44
+ rotation: 0,
45
+ parentScale: "ionian",
46
+ primaryName: "Major",
47
+ names: [
48
+ "Major",
49
+ "Ionian",
50
+ "Major Scale",
51
+ "Ionian Mode",
52
+ "Diatonic Major",
53
+ ],
54
+ intervals: ["1", "2", "3", "4", "5", "6", "7", "8"],
55
+ integers: [0, 2, 4, 5, 7, 9, 11],
56
+ type: [
57
+ "major",
58
+ "ionian",
59
+ "mode",
60
+ "scale",
61
+ "church mode",
62
+ "diatonic mode",
63
+ "heptatonic",
64
+ "first diatonic mode",
65
+ "do mode",
66
+ ],
67
+ characteristics: [
68
+ "bright",
69
+ "happy",
70
+ "stable",
71
+ "uplifting",
72
+ "consonant",
73
+ "western",
74
+ "foundational",
75
+ "simple",
76
+ "pop music",
77
+ "major tonality",
78
+ "commonly used western scale",
79
+ ],
80
+ pattern: ["whole", "whole", "half", "whole", "whole", "whole", "half"],
81
+ patternShort: ["W", "W", "H", "W", "W", "W", "H"],
82
+ } as const;
83
+ ```
84
+
85
+ ### Practical Utility Functions
86
+
87
+ Helpers for common tasks like generating note names from a root note and a set
88
+ of intervals.
89
+
90
+ ```ts
91
+ // src/utils/note-names.ts
92
+ export function getNoteNamesFromRootAndIntervals(
93
+ rootNote: RootNote,
94
+ intervals: readonly Interval[],
95
+ options: TransformIntervalsOptions = {},
96
+ ): NoteName[] {
97
+ //...
98
+ }
99
+ ```
100
+
43
101
  ## Installation
44
102
 
45
103
  ### Deno / JSR
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@musodojo/music-theory-data",
3
- "version": "19.0.3",
3
+ "version": "20.1.0",
4
4
  "description": "The musician-friendly TypeScript library for modes, scales, chords, and more.",
5
5
  "keywords": [
6
6
  "music",
@@ -482,7 +482,6 @@ export const intervalQualityToIntegerMap: ReadonlyMap<
482
482
  ][],
483
483
  );
484
484
 
485
- //TODO: add beyond an octave
486
485
  const _intervalToIntervalQualityMap = {
487
486
  "𝄫1": "dd1",
488
487
  "♭1": "d1",
@@ -491,14 +490,14 @@ const _intervalToIntervalQualityMap = {
491
490
  "♯1": "A1",
492
491
  "𝄪1": "AA1",
493
492
 
494
- "𝄫2": "dd2",
493
+ "𝄫2": "d2",
495
494
  "♭2": "m2",
496
495
  "2": "M2",
497
496
  "♮2": "M2",
498
497
  "♯2": "A2",
499
498
  "𝄪2": "AA2",
500
499
 
501
- "𝄫3": "dd3",
500
+ "𝄫3": "d3",
502
501
  "♭3": "m3",
503
502
  "3": "M3",
504
503
  "♮3": "M3",
@@ -519,19 +518,75 @@ const _intervalToIntervalQualityMap = {
519
518
  "♯5": "A5",
520
519
  "𝄪5": "AA5",
521
520
 
522
- "𝄫6": "dd6",
521
+ "𝄫6": "d6",
523
522
  "♭6": "m6",
524
523
  "6": "M6",
525
524
  "♮6": "M6",
526
525
  "♯6": "A6",
527
526
  "𝄪6": "AA6",
528
527
 
529
- "𝄫7": "dd7",
528
+ "𝄫7": "d7",
530
529
  "♭7": "m7",
531
530
  "7": "M7",
532
531
  "♮7": "M7",
533
532
  "♯7": "A7",
534
533
  "𝄪7": "AA7",
534
+
535
+ "𝄫8": "dd8",
536
+ "♭8": "d8",
537
+ "8": "P8",
538
+ "♮8": "P8",
539
+ "♯8": "A8",
540
+ "𝄪8": "AA8",
541
+
542
+ "𝄫9": "d9",
543
+ "♭9": "m9",
544
+ "9": "M9",
545
+ "♮9": "M9",
546
+ "♯9": "A9",
547
+ "𝄪9": "AA9",
548
+
549
+ "𝄫10": "d10",
550
+ "♭10": "m10",
551
+ "10": "M10",
552
+ "♮10": "M10",
553
+ "♯10": "A10",
554
+ "𝄪10": "AA10",
555
+
556
+ "𝄫11": "dd11",
557
+ "♭11": "d11",
558
+ "11": "P11",
559
+ "♮11": "P11",
560
+ "♯11": "A11",
561
+ "𝄪11": "AA11",
562
+
563
+ "𝄫12": "dd12",
564
+ "♭12": "d12",
565
+ "12": "P12",
566
+ "♮12": "P12",
567
+ "♯12": "A12",
568
+ "𝄪12": "AA12",
569
+
570
+ "𝄫13": "d13",
571
+ "♭13": "m13",
572
+ "13": "M13",
573
+ "♮13": "M13",
574
+ "♯13": "A13",
575
+ "𝄪13": "AA13",
576
+
577
+ "𝄫14": "d14",
578
+ "♭14": "m14",
579
+ "14": "M14",
580
+ "♮14": "M14",
581
+ "♯14": "A14",
582
+ "𝄪14": "AA14",
583
+
584
+ "𝄫15": "dd15",
585
+ "♭15": "d15",
586
+ "15": "P15",
587
+ "♮15": "P15",
588
+ "♯15": "A15",
589
+ "𝄪15": "AA15",
535
590
  } as const;
536
591
 
537
592
  export const intervalToIntervalQualityMap: ReadonlyMap<
@@ -544,7 +599,6 @@ export const intervalToIntervalQualityMap: ReadonlyMap<
544
599
  ][],
545
600
  );
546
601
 
547
- //TODO: add beyond an octave
548
602
  const _intervalQualityToIntervalMap = {
549
603
  "dd1": "𝄫1",
550
604
  "d1": "♭1",
@@ -552,15 +606,13 @@ const _intervalQualityToIntervalMap = {
552
606
  "A1": "♯1",
553
607
  "AA1": "𝄪1",
554
608
 
555
- "dd2": "𝄫2",
556
- "d2": "♭2",
609
+ "d2": "𝄫2",
557
610
  "m2": "♭2",
558
611
  "M2": "2",
559
612
  "A2": "♯2",
560
613
  "AA2": "𝄪2",
561
614
 
562
- "dd3": "𝄫3",
563
- "d3": "♭3",
615
+ "d3": "𝄫3",
564
616
  "m3": "♭3",
565
617
  "M3": "3",
566
618
  "A3": "♯3",
@@ -578,19 +630,65 @@ const _intervalQualityToIntervalMap = {
578
630
  "A5": "♯5",
579
631
  "AA5": "𝄪5",
580
632
 
581
- "dd6": "𝄫6",
582
- "d6": "♭6",
633
+ "d6": "𝄫6",
583
634
  "m6": "♭6",
584
635
  "M6": "6",
585
636
  "A6": "♯6",
586
637
  "AA6": "𝄪6",
587
638
 
588
- "dd7": "𝄫7",
589
- "d7": "♭7",
639
+ "d7": "𝄫7",
590
640
  "m7": "♭7",
591
641
  "M7": "7",
592
642
  "A7": "♯7",
593
643
  "AA7": "𝄪7",
644
+
645
+ "dd8": "𝄫8",
646
+ "d8": "♭8",
647
+ "P8": "8",
648
+ "A8": "♯8",
649
+ "AA8": "𝄪8",
650
+
651
+ "d9": "𝄫9",
652
+ "m9": "♭9",
653
+ "M9": "9",
654
+ "A9": "♯9",
655
+ "AA9": "𝄪9",
656
+
657
+ "d10": "𝄫10",
658
+ "m10": "♭10",
659
+ "M10": "10",
660
+ "A10": "♯10",
661
+ "AA10": "𝄪10",
662
+
663
+ "dd11": "𝄫11",
664
+ "d11": "♭11",
665
+ "P11": "11",
666
+ "A11": "♯11",
667
+ "AA11": "𝄪11",
668
+
669
+ "dd12": "𝄫12",
670
+ "d12": "♭12",
671
+ "P12": "12",
672
+ "A12": "♯12",
673
+ "AA12": "𝄪12",
674
+
675
+ "d13": "𝄫13",
676
+ "m13": "♭13",
677
+ "M13": "13",
678
+ "A13": "♯13",
679
+ "AA13": "𝄪13",
680
+
681
+ "d14": "𝄫14",
682
+ "m14": "♭14",
683
+ "M14": "14",
684
+ "A14": "♯14",
685
+ "AA14": "𝄪14",
686
+
687
+ "dd15": "𝄫15",
688
+ "d15": "♭15",
689
+ "P15": "15",
690
+ "A15": "♯15",
691
+ "AA15": "𝄪15",
594
692
  } as const;
595
693
 
596
694
  export const intervalQualityToIntervalMap: ReadonlyMap<
@@ -6,7 +6,7 @@ const augmentedTriad: ChordCollection = {
6
6
  names: ["aug", "+", "Augmented Triad"],
7
7
  intervals: ["1", "3", "♯5"],
8
8
  integers: [0, 4, 8],
9
- type: ["augmented", "chord", "arpeggio", "triad", "symmetrical"],
9
+ type: ["augmented", "chord", "arpeggio", "triad"],
10
10
  characteristics: ["tense", "unstable", "dreamy", "dissonant"],
11
11
  pattern: ["major third", "major third"],
12
12
  patternShort: ["M3", "M3"],
@@ -20,66 +20,13 @@ const augmented7: ChordCollection = {
20
20
  integers: [0, 4, 8, 10],
21
21
  type: ["augmented", "dominant", "chord", "arpeggio", "tetrad"],
22
22
  characteristics: ["tense", "unstable", "dissonant", "dominant function"],
23
- pattern: ["major third", "major third", "minor second"],
24
- patternShort: ["M3", "M3", "m2"],
25
- } as const;
26
-
27
- const italian6: ChordCollection = {
28
- category: "chord",
29
- primaryName: "It+6",
30
- names: ["It+6", "Italian 6th"],
31
- intervals: ["1", "3", "♭6"],
32
- integers: [0, 4, 8],
33
- type: ["augmented", "chord", "arpeggio", "triad", "classical"],
34
- characteristics: [
35
- "classical harmony",
36
- "pre-dominant function",
37
- "chromatic",
38
- ],
39
- pattern: ["major third", "diminished fourth"],
40
- patternShort: ["M3", "d4"],
41
- } as const;
42
-
43
- const french6: ChordCollection = {
44
- category: "chord",
45
- primaryName: "Fr+6",
46
- names: ["Fr+6", "French 6th"],
47
- intervals: ["1", "3", "♯4", "♭6"],
48
- integers: [0, 4, 6, 8],
49
- type: ["augmented", "chord", "arpeggio", "tetrad", "classical"],
50
- characteristics: [
51
- "classical harmony",
52
- "pre-dominant function",
53
- "chromatic",
54
- "contains a tritone",
55
- ],
56
- pattern: ["major third", "minor second", "major second"],
57
- patternShort: ["M3", "m2", "M2"],
58
- } as const;
59
-
60
- const german6: ChordCollection = {
61
- category: "chord",
62
- primaryName: "Ger+6",
63
- names: ["Ger+6", "German 6th"],
64
- intervals: ["1", "3", "5", "♭6"],
65
- integers: [0, 4, 7, 8],
66
- type: ["augmented", "chord", "arpeggio", "tetrad", "classical"],
67
- characteristics: [
68
- "classical harmony",
69
- "pre-dominant function",
70
- "chromatic",
71
- "enharmonically equivalent to a dominant 7th",
72
- ],
73
- pattern: ["major third", "minor third", "augmented unison"],
74
- patternShort: ["M3", "m3", "A1"],
23
+ pattern: ["major third", "major third", "major second"],
24
+ patternShort: ["M3", "M3", "M2"],
75
25
  } as const;
76
26
 
77
27
  export const _augmentedVariants = {
78
28
  augmentedTriad,
79
29
  augmented7,
80
- italian6,
81
- french6,
82
- german6,
83
30
  } as const;
84
31
 
85
32
  export type AugmentedVariantKey = keyof typeof _augmentedVariants;
@@ -60,7 +60,7 @@ const halfWholeDiminished: ModalScaleCollection = {
60
60
  parentScale: "wholeHalfDiminished",
61
61
  primaryName: "Half Whole Diminished",
62
62
  names: ["Half Whole Diminished", "Dominant Diminished"],
63
- intervals: ["1", "♭2", "♭3", "3", "♯4", "5", "6", "♭7", "8"],
63
+ intervals: ["1", "♭2", "♯2", "3", "♯4", "5", "6", "♭7", "8"],
64
64
  integers: [0, 1, 3, 4, 6, 7, 9, 10],
65
65
  type: ["diminished", "dominant", "scale", "symmetrical", "octatonic"],
66
66
  characteristics: [
@@ -33,7 +33,7 @@ const dominant9: ChordCollection = {
33
33
  primaryName: "9",
34
34
  names: ["9", "dom9", "Dominant 9th", "Dominant Ninth"],
35
35
  intervals: ["1", "3", "5", "♭7", "9"],
36
- integers: [0, 2, 4, 7, 10],
36
+ integers: [0, 4, 7, 10, 14],
37
37
  type: ["dominant", "major", "chord", "arpeggio", "pentad"],
38
38
  characteristics: [
39
39
  "unstable",
@@ -53,7 +53,7 @@ const dominant11: ChordCollection = {
53
53
  primaryName: "11",
54
54
  names: ["11", "dom11", "Dominant 11th", "Dominant Eleventh"],
55
55
  intervals: ["1", "3", "5", "♭7", "9", "11"],
56
- integers: [0, 2, 4, 5, 7, 10],
56
+ integers: [0, 4, 7, 10, 14, 17],
57
57
  type: ["dominant", "major", "chord", "arpeggio", "hexad"],
58
58
  characteristics: [
59
59
  "unstable",
@@ -81,7 +81,7 @@ const dominant13: ChordCollection = {
81
81
  primaryName: "13",
82
82
  names: ["13", "dom13", "Dominant 13th", "Dominant Thirteenth"],
83
83
  intervals: ["1", "3", "5", "♭7", "9", "11", "13"],
84
- integers: [0, 2, 4, 5, 7, 9, 10],
84
+ integers: [0, 4, 7, 10, 14, 17, 21],
85
85
  type: ["dominant", "major", "chord", "arpeggio", "heptad"],
86
86
  characteristics: [
87
87
  "unstable",
@@ -100,9 +100,9 @@ const dominant13: ChordCollection = {
100
100
  "minor third",
101
101
  "major third",
102
102
  "minor third",
103
- "minor third",
103
+ "major third",
104
104
  ],
105
- patternShort: ["M3", "m3", "m3", "M3", "m3", "m3"],
105
+ patternShort: ["M3", "m3", "m3", "M3", "m3", "M3"],
106
106
  } as const;
107
107
 
108
108
  const dominantPentatonic: NonModalScaleCollection = {
@@ -1,9 +1,34 @@
1
1
  import type {
2
+ ChordCollection,
3
+ NonModalScaleCollection,
2
4
  NoteCollection,
3
- ScaleCollection,
4
5
  } from "../../types/note-collections.d.ts";
5
6
 
6
- const chromatic: ScaleCollection = {
7
+ const rootAndFifth: ChordCollection = {
8
+ category: "chord",
9
+ primaryName: "Root and Fifth",
10
+ names: ["Root and Fifth", "Power Chord"],
11
+ intervals: ["1", "5"],
12
+ integers: [0, 7],
13
+ type: ["chord", "power chord"],
14
+ characteristics: ["rock", "blues", "metal"],
15
+ pattern: ["perfect fifth"],
16
+ patternShort: ["P5"],
17
+ };
18
+
19
+ const bluesPentatonic: NonModalScaleCollection = {
20
+ category: "scale",
21
+ primaryName: "Blues Pentatonic",
22
+ names: ["Blues Pentatonic"],
23
+ intervals: ["1", "♭3", "4", "♭5", "5", "♭7", "8"],
24
+ integers: [0, 3, 5, 6, 7, 10],
25
+ type: ["blues", "pentatonic", "scale", "gapped scale"],
26
+ characteristics: ["bluesy", "rock"],
27
+ pattern: ["minor third", "whole", "half", "half", "minor third", "whole"],
28
+ patternShort: ["m3", "W", "H", "H", "m3", "W"],
29
+ };
30
+
31
+ const chromatic: NonModalScaleCollection = {
7
32
  category: "scale",
8
33
  primaryName: "Chromatic",
9
34
  names: ["Chromatic", "Twelve-Tone Scale"],
@@ -47,7 +72,7 @@ const chromatic: ScaleCollection = {
47
72
  patternShort: ["H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H"],
48
73
  } as const;
49
74
 
50
- const wholeTone: ScaleCollection = {
75
+ const wholeTone: NonModalScaleCollection = {
51
76
  category: "scale",
52
77
  primaryName: "Whole Tone Scale",
53
78
  names: ["Whole Tone Scale"],
@@ -63,11 +88,13 @@ const wholeTone: ScaleCollection = {
63
88
  "often used in film scores",
64
89
  "associated with composers like Debussy and Ravel",
65
90
  ],
66
- pattern: ["whole", "whole", "whole", "whole", "whole"],
67
- patternShort: ["W", "W", "W", "W", "W"],
91
+ pattern: ["whole", "whole", "whole", "whole", "whole", "whole"],
92
+ patternShort: ["W", "W", "W", "W", "W", "W"],
68
93
  } as const;
69
94
 
70
95
  export const _otherNoteCollections = {
96
+ rootAndFifth,
97
+ bluesPentatonic,
71
98
  chromatic,
72
99
  wholeTone,
73
100
  } as const;
@@ -8,13 +8,13 @@ export type MidiNoteSequenceDirection =
8
8
  | "ascending-descending"
9
9
  | "descending-ascending";
10
10
 
11
- // TODO: add property `restsAtEnd` to add null values to array end
12
11
  export interface MidiNoteSequenceOptions {
13
12
  rootNoteMidi: MidiNoteNumber;
14
13
  intervals: Interval[];
15
14
  direction: MidiNoteSequenceDirection;
16
15
  startFromIndex?: number;
17
16
  filterOutOctave?: boolean;
17
+ restsAtEnd?: number;
18
18
  numNotes?: number;
19
19
  numOctaves?: number;
20
20
  extraNotes?: number;
@@ -109,6 +109,7 @@ export function getMidiNoteSequence(
109
109
  filterOutOctave = true,
110
110
  numNotes,
111
111
  numOctaves = 1,
112
+ restsAtEnd = 0,
112
113
  extraNotes = 0,
113
114
  } = options;
114
115
 
@@ -164,5 +165,7 @@ export function getMidiNoteSequence(
164
165
  }
165
166
  }
166
167
 
168
+ if (restsAtEnd > 0) sequence.push(...Array(restsAtEnd).fill(null));
169
+
167
170
  return sequence;
168
171
  }
@@ -1,76 +0,0 @@
1
- // Diminished
2
- {
3
- name: "dim / o / Diminished Triad",
4
- sequence: [0, 3, 6],
5
- },
6
- {
7
- name: "dim7 / o7 / Diminished 7th",
8
- sequence: [0, 3, 6, 9],
9
- },
10
- {
11
- name: "m7♭5 / ø7 / Half Diminished 7th",
12
- sequence: [0, 3, 6, 10],
13
- },
14
- {
15
- name: "Whole Half Diminished",
16
- sequence: [0, 2, 3, 5, 6, 8, 9, 11],
17
- },
18
- {
19
- name: "Half Whole / Dominant Diminished",
20
- sequence: [0, 1, 3, 4, 6, 7, 9, 10],
21
- },
22
-
23
- // Augmented
24
- {
25
- name: "aug / + / Augmented Triad",
26
- sequence: [0, 4, 8],
27
- },
28
- {
29
- name: "It+6 / Italian 6th",
30
- sequence: [0, 4, 10],
31
- },
32
- {
33
- name: "Fr+6 / French 6th",
34
- sequence: [0, 4, 6, 10],
35
- },
36
- {
37
- name: "Ger+6 / German 6th",
38
- sequence: [0, 4, 7, 10],
39
- },
40
- {
41
- name: "aug7 / +7 / 7♯5 / Augmented Seventh",
42
- sequence: [0, 4, 8, 10],
43
- },
44
-
45
- // Other
46
- {
47
- name: "R / Root",
48
- category: "Other",
49
- sequence: [0],
50
- },
51
- {
52
- name: "Chromatic",
53
- category: "Other",
54
- sequence: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
55
- },
56
- {
57
- name: "Blank",
58
- category: "Other",
59
- sequence: [],
60
- },
61
- {
62
- name: "Root and 5th",
63
- category: "Other",
64
- sequence: [0, 7],
65
- },
66
- {
67
- name: "Blues",
68
- category: "Other",
69
- sequence: [0, 3, 5, 6, 7, 10],
70
- },
71
- {
72
- name: "Whole Tone",
73
- category: "Other",
74
- sequence: [0, 2, 4, 6, 8, 10],
75
- },
76
- ];