@musodojo/music-theory-data 31.1.0 → 33.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.
Files changed (95) hide show
  1. package/README.md +58 -7
  2. package/esm/deps/jsr.io/@std/internal/{1.0.13 → 1.0.14}/build_message.d.ts.map +1 -1
  3. package/{script/deps/jsr.io/@std/internal/1.0.13 → esm/deps/jsr.io/@std/internal/1.0.14}/diff.d.ts.map +1 -1
  4. package/{script/deps/jsr.io/@std/internal/1.0.13 → esm/deps/jsr.io/@std/internal/1.0.14}/diff_str.d.ts.map +1 -1
  5. package/{script/deps/jsr.io/@std/internal/1.0.13 → esm/deps/jsr.io/@std/internal/1.0.14}/format.d.ts.map +1 -1
  6. package/esm/deps/jsr.io/@std/internal/{1.0.13 → 1.0.14}/styles.d.ts.map +1 -1
  7. package/esm/deps/jsr.io/@std/internal/{1.0.13 → 1.0.14}/types.d.ts.map +1 -1
  8. package/esm/src/data/chord-progressions/mod.d.ts +28 -16
  9. package/esm/src/data/chord-progressions/mod.d.ts.map +1 -1
  10. package/esm/src/data/chord-progressions/mod.js +180 -65
  11. package/esm/src/data/chords/mod.d.ts +26 -1
  12. package/esm/src/data/chords/mod.d.ts.map +1 -1
  13. package/esm/src/data/chords/mod.js +70 -1
  14. package/esm/src/data/labels/mod.d.ts +1 -0
  15. package/esm/src/data/labels/mod.d.ts.map +1 -1
  16. package/esm/src/data/labels/mod.js +1 -0
  17. package/esm/src/data/labels/note-label-collections.d.ts +1 -25
  18. package/esm/src/data/labels/note-label-collections.d.ts.map +1 -1
  19. package/esm/src/data/labels/note-label-collections.js +1 -77
  20. package/esm/src/data/labels/note-labels.d.ts +1 -1
  21. package/esm/src/data/labels/note-labels.d.ts.map +1 -1
  22. package/esm/src/data/labels/solfege.d.ts +33 -0
  23. package/esm/src/data/labels/solfege.d.ts.map +1 -0
  24. package/esm/src/data/labels/solfege.js +165 -0
  25. package/esm/src/data/note-collections/augmented-variants.d.ts.map +1 -1
  26. package/esm/src/data/note-collections/augmented-variants.js +3 -2
  27. package/esm/src/data/note-collections/mod.d.ts +15 -0
  28. package/esm/src/data/note-collections/mod.d.ts.map +1 -1
  29. package/esm/src/data/note-collections/mod.js +2 -2
  30. package/esm/src/utils/chord-progressions.d.ts +22 -5
  31. package/esm/src/utils/chord-progressions.d.ts.map +1 -1
  32. package/esm/src/utils/chord-progressions.js +70 -7
  33. package/esm/src/utils/chords.d.ts +7 -1
  34. package/esm/src/utils/chords.d.ts.map +1 -1
  35. package/esm/src/utils/chords.js +18 -1
  36. package/esm/src/utils/conversion-registry.d.ts +40 -20
  37. package/esm/src/utils/conversion-registry.d.ts.map +1 -1
  38. package/esm/src/utils/conversion-registry.js +95 -25
  39. package/esm/src/utils/intervals.d.ts +3 -0
  40. package/esm/src/utils/intervals.d.ts.map +1 -1
  41. package/esm/src/utils/intervals.js +23 -0
  42. package/esm/src/utils/midi.d.ts +7 -0
  43. package/esm/src/utils/midi.d.ts.map +1 -1
  44. package/esm/src/utils/midi.js +16 -0
  45. package/esm/src/utils/note-collections.d.ts +9 -1
  46. package/esm/src/utils/note-collections.d.ts.map +1 -1
  47. package/esm/src/utils/note-collections.js +22 -0
  48. package/esm/tests/solfege.test.d.ts.map +1 -0
  49. package/package.json +1 -1
  50. package/script/deps/jsr.io/@std/internal/{1.0.13 → 1.0.14}/build_message.d.ts.map +1 -1
  51. package/{esm/deps/jsr.io/@std/internal/1.0.13 → script/deps/jsr.io/@std/internal/1.0.14}/diff.d.ts.map +1 -1
  52. package/{esm/deps/jsr.io/@std/internal/1.0.13 → script/deps/jsr.io/@std/internal/1.0.14}/diff_str.d.ts.map +1 -1
  53. package/{esm/deps/jsr.io/@std/internal/1.0.13 → script/deps/jsr.io/@std/internal/1.0.14}/format.d.ts.map +1 -1
  54. package/script/deps/jsr.io/@std/internal/{1.0.13 → 1.0.14}/styles.d.ts.map +1 -1
  55. package/script/deps/jsr.io/@std/internal/{1.0.13 → 1.0.14}/types.d.ts.map +1 -1
  56. package/script/src/data/chord-progressions/mod.d.ts +28 -16
  57. package/script/src/data/chord-progressions/mod.d.ts.map +1 -1
  58. package/script/src/data/chord-progressions/mod.js +181 -66
  59. package/script/src/data/chords/mod.d.ts +26 -1
  60. package/script/src/data/chords/mod.d.ts.map +1 -1
  61. package/script/src/data/chords/mod.js +75 -2
  62. package/script/src/data/labels/mod.d.ts +1 -0
  63. package/script/src/data/labels/mod.d.ts.map +1 -1
  64. package/script/src/data/labels/mod.js +1 -0
  65. package/script/src/data/labels/note-label-collections.d.ts +1 -25
  66. package/script/src/data/labels/note-label-collections.d.ts.map +1 -1
  67. package/script/src/data/labels/note-label-collections.js +1 -77
  68. package/script/src/data/labels/note-labels.d.ts +1 -1
  69. package/script/src/data/labels/note-labels.d.ts.map +1 -1
  70. package/script/src/data/labels/solfege.d.ts +33 -0
  71. package/script/src/data/labels/solfege.d.ts.map +1 -0
  72. package/script/src/data/labels/solfege.js +173 -0
  73. package/script/src/data/note-collections/augmented-variants.d.ts.map +1 -1
  74. package/script/src/data/note-collections/augmented-variants.js +3 -2
  75. package/script/src/data/note-collections/mod.d.ts +15 -0
  76. package/script/src/data/note-collections/mod.d.ts.map +1 -1
  77. package/script/src/utils/chord-progressions.d.ts +22 -5
  78. package/script/src/utils/chord-progressions.d.ts.map +1 -1
  79. package/script/src/utils/chord-progressions.js +72 -5
  80. package/script/src/utils/chords.d.ts +7 -1
  81. package/script/src/utils/chords.d.ts.map +1 -1
  82. package/script/src/utils/chords.js +19 -0
  83. package/script/src/utils/conversion-registry.d.ts +40 -20
  84. package/script/src/utils/conversion-registry.d.ts.map +1 -1
  85. package/script/src/utils/conversion-registry.js +98 -26
  86. package/script/src/utils/intervals.d.ts +3 -0
  87. package/script/src/utils/intervals.d.ts.map +1 -1
  88. package/script/src/utils/intervals.js +26 -0
  89. package/script/src/utils/midi.d.ts +7 -0
  90. package/script/src/utils/midi.d.ts.map +1 -1
  91. package/script/src/utils/midi.js +19 -0
  92. package/script/src/utils/note-collections.d.ts +9 -1
  93. package/script/src/utils/note-collections.d.ts.map +1 -1
  94. package/script/src/utils/note-collections.js +25 -0
  95. package/script/tests/solfege.test.d.ts.map +1 -0
@@ -1,7 +1,10 @@
1
- import { chordProgressionBarGroups, chordProgressions, } from "../data/chord-progressions/mod.js";
2
- import { getChordQualityNoteCollectionKey } from "../data/chords/mod.js";
1
+ import { chordProgressionBarGroups, chordProgressionCategoryGroups, chordProgressions, } from "../data/chord-progressions/mod.js";
2
+ import { getChordCollectionChordSuffix } from "../data/chords/mod.js";
3
3
  import { getNoteNamesForRootAndIntervals, normalizeRootNoteString, } from "./note-names.js";
4
+ import { getRomanNumeralForScaleIndexAndChordCollectionKey } from "./chords.js";
4
5
  const BAR_DURATION_EPSILON = 0.000000001;
6
+ const DIATONIC_SCALE_DEGREES = 7;
7
+ const INTERVAL_LABEL_REGEX = /^(𝄫|♭|♮|♯|𝄪)?(\d+)$/;
5
8
  /** Returns whether a string is one of the built-in chord progression keys. */
6
9
  export function isValidChordProgressionKey(key) {
7
10
  return Object.prototype.hasOwnProperty.call(chordProgressions, key);
@@ -14,8 +17,9 @@ function resolveProgression(progressionOrKey) {
14
17
  function createChordProgressionChordReference(chord, chordRootNote) {
15
18
  return {
16
19
  rootNote: chordRootNote,
17
- chordName: chordRootNote + chord.quality,
18
- noteCollectionKey: getChordQualityNoteCollectionKey(chord.quality),
20
+ chordName: chordRootNote +
21
+ getChordCollectionChordSuffix(chord.chordCollectionKey),
22
+ noteCollectionKey: chord.chordCollectionKey,
19
23
  };
20
24
  }
21
25
  function getResolvedChordProgressionChordReferences(rootNote, progressionOrKey) {
@@ -33,26 +37,85 @@ function getResolvedChordProgressionChordReferences(rootNote, progressionOrKey)
33
37
  }];
34
38
  });
35
39
  }
40
+ function getRomanAccidentalForIntervalLabel(accidental) {
41
+ switch (accidental) {
42
+ case undefined:
43
+ case "":
44
+ case "♮":
45
+ return "";
46
+ case "𝄫":
47
+ case "♭":
48
+ case "♯":
49
+ case "𝄪":
50
+ return accidental;
51
+ default:
52
+ throw new Error(`Invalid chord degree accidental: ${accidental}`);
53
+ }
54
+ }
55
+ /** Returns the direct tonic-relative Roman symbol for a progression chord. */
56
+ export function getChordProgressionChordDirectRomanSymbol(chord) {
57
+ const match = chord.degree.match(INTERVAL_LABEL_REGEX);
58
+ if (!match) {
59
+ throw new Error(`Invalid chord degree: ${chord.degree}`);
60
+ }
61
+ const [, rawAccidental, degreeLabel] = match;
62
+ const degree = Number(degreeLabel);
63
+ if (!Number.isInteger(degree) || degree < 1) {
64
+ throw new Error(`Invalid chord degree: ${chord.degree}`);
65
+ }
66
+ const scaleIndex = (degree - 1) % DIATONIC_SCALE_DEGREES;
67
+ const romanSymbol = getRomanNumeralForScaleIndexAndChordCollectionKey(scaleIndex, chord.chordCollectionKey);
68
+ if (romanSymbol === undefined) {
69
+ throw new Error(`Unhandled chord collection: ${chord.chordCollectionKey}`);
70
+ }
71
+ const accidental = getRomanAccidentalForIntervalLabel(rawAccidental);
72
+ return `${accidental}${romanSymbol}`;
73
+ }
36
74
  /** Returns the spelled chord names for a progression in the requested root. */
37
75
  export function getChordProgressionChordNames(rootNote, progressionOrKey) {
38
76
  const progression = resolveProgression(progressionOrKey);
39
77
  if (!progression)
40
78
  return [];
41
79
  const noteNames = getNoteNamesForRootAndIntervals(rootNote, progression.chords.map((chord) => chord.degree));
42
- return progression.chords.map((chord, index) => noteNames[index] + chord.quality);
80
+ return progression.chords.map((chord, index) => noteNames[index] + getChordCollectionChordSuffix(chord.chordCollectionKey));
43
81
  }
44
- /** Returns the roman symbols authored for a chord progression. */
82
+ /**
83
+ * Returns direct tonic-relative Roman symbols derived from each chord's
84
+ * `degree` and `chordCollectionKey`.
85
+ */
86
+ export function getChordProgressionDirectRomanSymbols(progressionOrKey) {
87
+ const progression = resolveProgression(progressionOrKey);
88
+ if (!progression)
89
+ return [];
90
+ return progression.chords.map((chord) => getChordProgressionChordDirectRomanSymbol(chord));
91
+ }
92
+ /**
93
+ * Returns Roman symbols suitable for theory display, preferring optional
94
+ * harmonic-function analysis labels when present.
95
+ */
45
96
  export function getChordProgressionRomanSymbols(progressionOrKey) {
46
97
  const progression = resolveProgression(progressionOrKey);
47
98
  if (!progression)
48
99
  return [];
49
- return progression.chords.map((chord) => chord.romanSymbol);
100
+ return progression.chords.map((chord) => chord.analysis?.romanSymbol ?? getChordProgressionChordDirectRomanSymbol(chord));
101
+ }
102
+ /**
103
+ * Returns Roman symbols suitable for display, preferring optional
104
+ * harmonic-function analysis labels when present.
105
+ */
106
+ export function getChordProgressionDisplayRomanSymbols(progressionOrKey) {
107
+ return getChordProgressionRomanSymbols(progressionOrKey);
50
108
  }
51
109
  /** Returns all built-in chord progression keys with the requested total bar count. */
52
110
  export function getChordProgressionKeysForTotalBars(totalBars) {
53
111
  return chordProgressionBarGroups.find((group) => group.totalBars === totalBars)
54
112
  ?.progressionKeys.slice() ?? [];
55
113
  }
114
+ /** Returns all built-in chord progression keys in the requested musical category. */
115
+ export function getChordProgressionKeysForCategory(category) {
116
+ return chordProgressionCategoryGroups.find((group) => group.category === category)
117
+ ?.progressionKeys.slice() ?? [];
118
+ }
56
119
  /** Returns each distinct chord name in a progression, preserving first-seen order. */
57
120
  export function getChordProgressionUniqueChordNames(rootNote, progressionOrKey) {
58
121
  return Array.from(new Set(getChordProgressionChordNames(rootNote, progressionOrKey)));
@@ -1,8 +1,9 @@
1
- import { type NoteCollectionKey } from "../data/note-collections/mod.js";
1
+ import { type ChordCollectionKey, type NoteCollectionKey } from "../data/note-collections/mod.js";
2
2
  import type { ChordQuality, RomanSeventhChord, RomanTriad, SeventhChord, Triad } from "../types/chords";
3
3
  import { type NoteCollectionKeyTransformOptions, type RootAndNoteCollectionKeyTransformOptions } from "./intervals.js";
4
4
  import { type RootNote } from "../data/labels/note-labels.js";
5
5
  export declare function getRomanNumeralForScaleIndexAndChordQuality(scaleIndex: number, quality: ChordQuality): string | undefined;
6
+ export declare function getRomanNumeralForScaleIndexAndChordCollectionKey(scaleIndex: number, chordCollectionKey: ChordCollectionKey): string | undefined;
6
7
  /**
7
8
  * Converts standard triad qualities (e.g., "M", "m") into their corresponding Roman numeral representations
8
9
  * based on their scale degree index.
@@ -19,6 +20,11 @@ export declare function getRomanTriads(triads: Triad[]): RomanTriad[];
19
20
  * @returns An array of string-based Roman numeral seventh chords (e.g., "IM7", "ii7", "vii°7").
20
21
  */
21
22
  export declare function getRomanSeventhChords(sevenths: SeventhChord[]): RomanSeventhChord[];
23
+ /**
24
+ * Checks whether a note collection has authored modal harmony data.
25
+ * Collections without authored harmony intentionally return undefined chord placeholders.
26
+ */
27
+ export declare function hasAuthoredNoteCollectionHarmony(noteCollectionKey: NoteCollectionKey): boolean;
22
28
  /**
23
29
  * Retrieves the triads for a given note collection key.
24
30
  */
@@ -1 +1 @@
1
- {"version":3,"file":"chords.d.ts","sourceRoot":"","sources":["../../../src/src/utils/chords.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,KAAK,EACN,MAAM,iBAAiB,CAAC;AAmBzB,OAAO,EAEL,KAAK,iCAAiC,EACtC,KAAK,wCAAwC,EAC9C,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAEL,KAAK,QAAQ,EACd,MAAM,+BAA+B,CAAC;AAEvC,wBAAgB,2CAA2C,CACzD,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,GACpB,MAAM,GAAG,SAAS,CAYpB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,EAAE,CAQ5D;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,YAAY,EAAE,GACvB,iBAAiB,EAAE,CAQrB;AA0KD;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,iCAAsC,GAC9C,CAAC,KAAK,GAAG,SAAS,CAAC,EAAE,CAMvB;AAED;;GAEG;AACH,wBAAgB,oCAAoC,CAClD,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,iCAAsC,GAC9C,CAAC,YAAY,GAAG,SAAS,CAAC,EAAE,CAM9B;AAED;;GAEG;AACH,wBAAgB,kCAAkC,CAChD,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,iCAAsC,GAC9C,CAAC,UAAU,GAAG,SAAS,CAAC,EAAE,CAO5B;AAED;;GAEG;AACH,wBAAgB,yCAAyC,CACvD,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,iCAAsC,GAC9C,CAAC,iBAAiB,GAAG,SAAS,CAAC,EAAE,CAOnC;AAED;;;GAGG;AACH,wBAAgB,oCAAoC,CAClD,QAAQ,EAAE,QAAQ,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,wCAA6C,GACrD,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAsBxB;AAED;;;GAGG;AACH,wBAAgB,2CAA2C,CACzD,QAAQ,EAAE,QAAQ,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,wCAA6C,GACrD,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAsBxB;AAED;;;;GAIG;AACH,wBAAgB,yCAAyC,CACvD,QAAQ,EAAE,QAAQ,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,wCAA6C,GACrD,CAAC,UAAU,GAAG,SAAS,CAAC,EAAE,CAY5B;AAED;;;;GAIG;AACH,wBAAgB,gDAAgD,CAC9D,QAAQ,EAAE,QAAQ,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,wCAA6C,GACrD,CAAC,iBAAiB,GAAG,SAAS,CAAC,EAAE,CAYnC"}
1
+ {"version":3,"file":"chords.d.ts","sourceRoot":"","sources":["../../../src/src/utils/chords.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EAEvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,KAAK,EACN,MAAM,iBAAiB,CAAC;AAmBzB,OAAO,EAEL,KAAK,iCAAiC,EACtC,KAAK,wCAAwC,EAC9C,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAEL,KAAK,QAAQ,EACd,MAAM,+BAA+B,CAAC;AAEvC,wBAAgB,2CAA2C,CACzD,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,GACpB,MAAM,GAAG,SAAS,CAYpB;AAED,wBAAgB,iDAAiD,CAC/D,UAAU,EAAE,MAAM,EAClB,kBAAkB,EAAE,kBAAkB,GACrC,MAAM,GAAG,SAAS,CAUpB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,EAAE,CAQ5D;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,YAAY,EAAE,GACvB,iBAAiB,EAAE,CAQrB;AAyED;;;GAGG;AACH,wBAAgB,gCAAgC,CAC9C,iBAAiB,EAAE,iBAAiB,GACnC,OAAO,CAET;AAmGD;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,iCAAsC,GAC9C,CAAC,KAAK,GAAG,SAAS,CAAC,EAAE,CAMvB;AAED;;GAEG;AACH,wBAAgB,oCAAoC,CAClD,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,iCAAsC,GAC9C,CAAC,YAAY,GAAG,SAAS,CAAC,EAAE,CAM9B;AAED;;GAEG;AACH,wBAAgB,kCAAkC,CAChD,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,iCAAsC,GAC9C,CAAC,UAAU,GAAG,SAAS,CAAC,EAAE,CAO5B;AAED;;GAEG;AACH,wBAAgB,yCAAyC,CACvD,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,iCAAsC,GAC9C,CAAC,iBAAiB,GAAG,SAAS,CAAC,EAAE,CAOnC;AAED;;;GAGG;AACH,wBAAgB,oCAAoC,CAClD,QAAQ,EAAE,QAAQ,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,wCAA6C,GACrD,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAsBxB;AAED;;;GAGG;AACH,wBAAgB,2CAA2C,CACzD,QAAQ,EAAE,QAAQ,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,wCAA6C,GACrD,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAsBxB;AAED;;;;GAIG;AACH,wBAAgB,yCAAyC,CACvD,QAAQ,EAAE,QAAQ,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,wCAA6C,GACrD,CAAC,UAAU,GAAG,SAAS,CAAC,EAAE,CAY5B;AAED;;;;GAIG;AACH,wBAAgB,gDAAgD,CAC9D,QAAQ,EAAE,QAAQ,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,GAAE,wCAA6C,GACrD,CAAC,iBAAiB,GAAG,SAAS,CAAC,EAAE,CAYnC"}
@@ -1,4 +1,4 @@
1
- import { chordQualityRomanRenderings, diatonicSeventhChords, diatonicTriads, harmonicMinorSeventhChords, harmonicMinorTriads, lowerCaseRomanNumerals, melodicMinorSeventhChords, melodicMinorTriads, upperCaseRomanNumerals, } from "../data/chords/mod.js";
1
+ import { chordQualityRomanRenderings, diatonicSeventhChords, diatonicTriads, getChordCollectionSymbolRendering, harmonicMinorSeventhChords, harmonicMinorTriads, lowerCaseRomanNumerals, melodicMinorSeventhChords, melodicMinorTriads, upperCaseRomanNumerals, } from "../data/chords/mod.js";
2
2
  import { noteCollections, } from "../data/note-collections/mod.js";
3
3
  import { rotateArrayLeft, rotateArrayRight } from "./rotate-array.js";
4
4
  import { harmonicMinorModes, } from "../data/note-collections/harmonic-minor-modes.js";
@@ -21,6 +21,16 @@ export function getRomanNumeralForScaleIndexAndChordQuality(scaleIndex, quality)
21
21
  return undefined;
22
22
  return romanNumeral + rendering.suffix;
23
23
  }
24
+ export function getRomanNumeralForScaleIndexAndChordCollectionKey(scaleIndex, chordCollectionKey) {
25
+ const rendering = getChordCollectionSymbolRendering(chordCollectionKey);
26
+ const numerals = rendering.numeralCase === "lower"
27
+ ? lowerCaseRomanNumerals
28
+ : upperCaseRomanNumerals;
29
+ const romanNumeral = numerals[scaleIndex];
30
+ if (romanNumeral === undefined)
31
+ return undefined;
32
+ return romanNumeral + rendering.romanSuffix;
33
+ }
24
34
  /**
25
35
  * Converts standard triad qualities (e.g., "M", "m") into their corresponding Roman numeral representations
26
36
  * based on their scale degree index.
@@ -109,6 +119,13 @@ function getModeData(modeKey) {
109
119
  }
110
120
  return undefined;
111
121
  }
122
+ /**
123
+ * Checks whether a note collection has authored modal harmony data.
124
+ * Collections without authored harmony intentionally return undefined chord placeholders.
125
+ */
126
+ export function hasAuthoredNoteCollectionHarmony(noteCollectionKey) {
127
+ return getModeData(noteCollectionKey) !== undefined;
128
+ }
112
129
  function getUndefinedChordPlaceholders(intervals, fillChromatic) {
113
130
  if (fillChromatic) {
114
131
  return createChromaticTuple(Array.from({ length: 12 }, () => undefined));
@@ -1,13 +1,12 @@
1
- import type { RootNote } from "../data/labels/note-labels.js";
1
+ import type { ChromaticTuple } from "../data/chromatic.js";
2
+ import type { Interval, NoteName, RootNote } from "../data/labels/note-labels.js";
2
3
  import type { NoteCollectionKey } from "../data/note-collections/mod.js";
3
- import type { Interval } from "../data/labels/note-labels.js";
4
4
  import type { RomanSeventhChord, RomanTriad } from "../types/chords";
5
- import type { NoteName } from "../data/labels/note-labels.js";
6
5
  /**
7
6
  * Options specifically tailored for robust Conversion Registry UI usage.
8
7
  * Requires `fillChromatic: true` and `rotateToRootInteger0: true` to ensure
9
- * all returned arrays are 12 elements long and uniformly anchored to C=0,
10
- * making them easy to align in a UI like a fretboard.
8
+ * all returned arrays are 12 elements long and indexed by absolute pitch class
9
+ * where C is index 0. The selected root appears at its pitch-class index.
11
10
  */
12
11
  export interface ConversionRegistryOptions {
13
12
  fillChromatic: true;
@@ -17,25 +16,46 @@ export interface ConversionRegistryOptions {
17
16
  /**
18
17
  * A generic function signature for all registry entries.
19
18
  */
20
- export type ConversionFunction<T> = (rootNote: RootNote, noteCollectionKey: NoteCollectionKey, options: ConversionRegistryOptions) => readonly (T | undefined)[];
21
- export interface ConversionRegistryEntry<T> {
22
- id: string;
19
+ export type ConversionFunction<T> = (rootNote: RootNote, noteCollectionKey: NoteCollectionKey, options: ConversionRegistryOptions) => ChromaticTuple<T | undefined>;
20
+ export type ConversionInputKind = "rootAndNoteCollection";
21
+ export type ConversionOutputKind = "noteNames" | "intervals" | "chordNames" | "romanNumerals";
22
+ export type ConversionOutputShape = "chromatic-12";
23
+ export type ConversionOutputIndexing = "absolutePitchClassC0";
24
+ export type ConversionEmptySlot = "none" | "undefined";
25
+ export type ConversionAvailabilityFunction = (rootNote: RootNote, noteCollectionKey: NoteCollectionKey) => boolean;
26
+ export interface ConversionRegistryEntry<T, TId extends string = string> {
27
+ id: TId;
23
28
  name: string;
24
29
  shortName: string;
25
30
  description: string;
26
31
  example: string;
32
+ inputKind: ConversionInputKind;
33
+ outputKind: ConversionOutputKind;
34
+ outputShape: ConversionOutputShape;
35
+ outputIndexing: ConversionOutputIndexing;
36
+ allowsEmptySlots: boolean;
37
+ emptySlot: ConversionEmptySlot;
38
+ isAvailable?: ConversionAvailabilityFunction;
39
+ unavailableReason?: string;
27
40
  get: ConversionFunction<T>;
28
41
  }
29
- export declare const conversions: {
30
- rootAndNoteCollection: {
31
- noteNames: ConversionRegistryEntry<NoteName | string>;
32
- intervals: ConversionRegistryEntry<Interval>;
33
- extensions: ConversionRegistryEntry<Interval>;
34
- compoundIntervals: ConversionRegistryEntry<Interval>;
35
- triads: ConversionRegistryEntry<string>;
36
- seventhChords: ConversionRegistryEntry<string>;
37
- romanTriads: ConversionRegistryEntry<RomanTriad>;
38
- romanSeventhChords: ConversionRegistryEntry<RomanSeventhChord>;
39
- };
40
- };
42
+ export interface RootAndNoteCollectionConversions {
43
+ noteNames: ConversionRegistryEntry<NoteName, "note-names">;
44
+ intervals: ConversionRegistryEntry<Interval, "intervals">;
45
+ extensions: ConversionRegistryEntry<Interval, "extensions">;
46
+ compoundIntervals: ConversionRegistryEntry<Interval, "compound-intervals">;
47
+ triads: ConversionRegistryEntry<string, "triads">;
48
+ seventhChords: ConversionRegistryEntry<string, "seventh-chords">;
49
+ romanTriads: ConversionRegistryEntry<RomanTriad, "roman-triads">;
50
+ romanSeventhChords: ConversionRegistryEntry<RomanSeventhChord, "roman-seventh-chords">;
51
+ }
52
+ export interface ConversionRegistry {
53
+ rootAndNoteCollection: RootAndNoteCollectionConversions;
54
+ }
55
+ export declare const conversions: ConversionRegistry;
56
+ export declare const rootAndNoteCollectionConversions: RootAndNoteCollectionConversions;
57
+ export type RootAndNoteCollectionConversionKey = keyof typeof rootAndNoteCollectionConversions;
58
+ export type RootAndNoteCollectionConversion = typeof rootAndNoteCollectionConversions[RootAndNoteCollectionConversionKey];
59
+ export declare function isRootAndNoteCollectionConversionAvailable(conversion: RootAndNoteCollectionConversion, rootNote: RootNote, noteCollectionKey: NoteCollectionKey): boolean;
60
+ export declare function getAvailableRootAndNoteCollectionConversions(rootNote: RootNote, noteCollectionKey: NoteCollectionKey): RootAndNoteCollectionConversion[];
41
61
  //# sourceMappingURL=conversion-registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversion-registry.d.ts","sourceRoot":"","sources":["../../../src/src/utils/conversion-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAc9D;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,IAAI,CAAC;IACpB,oBAAoB,EAAE,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,CAClC,QAAQ,EAAE,QAAQ,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,EAAE,yBAAyB,KAC/B,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;AAEhC,MAAM,WAAW,uBAAuB,CAAC,CAAC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;CAC5B;AAED,eAAO,MAAM,WAAW;;mBAWf,uBAAuB,CAAC,QAAQ,GAAG,MAAM,CAAC;mBAU1C,uBAAuB,CAAC,QAAQ,CAAC;oBAUjC,uBAAuB,CAAC,QAAQ,CAAC;2BAUjC,uBAAuB,CAAC,QAAQ,CAAC;gBAUjC,uBAAuB,CAAC,MAAM,CAAC;uBAU/B,uBAAuB,CAAC,MAAM,CAAC;qBAU/B,uBAAuB,CAAC,UAAU,CAAC;4BAUnC,uBAAuB,CAAC,iBAAiB,CAAC;;CAElD,CAAC"}
1
+ {"version":3,"file":"conversion-registry.d.ts","sourceRoot":"","sources":["../../../src/src/utils/conversion-registry.ts"],"names":[],"mappings":"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"}
@@ -1,71 +1,141 @@
1
+ import { getRomanSeventhChordsForRootAndNoteCollectionKey, getRomanTriadsForRootAndNoteCollectionKey, getSeventhChordsForRootAndNoteCollectionKey, getTriadsForRootAndNoteCollectionKey, hasAuthoredNoteCollectionHarmony, } from "./chords.js";
2
+ import { createChromaticTuple } from "./chromatic.js";
1
3
  import { getNoteNamesForRootAndNoteCollectionKey } from "./note-names.js";
2
4
  import { getCompoundIntervalsForRootAndNoteCollectionKey, getExtensionsForRootAndNoteCollectionKey, getIntervalsForRootAndNoteCollectionKey, } from "./intervals.js";
3
- import { getRomanSeventhChordsForRootAndNoteCollectionKey, getRomanTriadsForRootAndNoteCollectionKey, getSeventhChordsForRootAndNoteCollectionKey, getTriadsForRootAndNoteCollectionKey, } from "./chords.js";
5
+ const authoredHarmonyUnavailableReason = "This note collection does not have authored modal harmony data.";
6
+ const isAuthoredHarmonyAvailable = (_rootNote, noteCollectionKey) => hasAuthoredNoteCollectionHarmony(noteCollectionKey);
7
+ const absolutePitchClassC0 = "absolutePitchClassC0";
8
+ function createConversionResult(values) {
9
+ return createChromaticTuple(values);
10
+ }
4
11
  export const conversions = {
5
12
  rootAndNoteCollection: {
6
13
  noteNames: {
7
14
  id: "note-names",
8
15
  name: "Note Names",
9
16
  shortName: "Notes",
10
- description: "Returns the specific note names (e.g., 'C', 'E♭', 'G') for the root and collection.",
11
- example: "C, E♭, G",
12
- get: (root, key, opts) => getNoteNamesForRootAndNoteCollectionKey(root, key, opts),
17
+ description: "Returns 12 absolute pitch-class slots for the root and collection, indexed so C is slot 0.",
18
+ example: "C, D♭, D, E♭, E, F, G♭, G, A♭, A, B♭, B",
19
+ inputKind: "rootAndNoteCollection",
20
+ outputKind: "noteNames",
21
+ outputShape: "chromatic-12",
22
+ outputIndexing: absolutePitchClassC0,
23
+ allowsEmptySlots: false,
24
+ emptySlot: "none",
25
+ get: (root, key, opts) => createConversionResult(getNoteNamesForRootAndNoteCollectionKey(root, key, opts)),
13
26
  },
14
27
  intervals: {
15
28
  id: "intervals",
16
29
  name: "Intervals",
17
30
  shortName: "Intervals",
18
- description: "Returns the relative intervals (e.g., '1', '♭3', '5') for the collection.",
19
- example: "1, ♭3, 5",
20
- get: (root, key, opts) => getIntervalsForRootAndNoteCollectionKey(root, key, opts),
31
+ description: "Returns 12 absolute pitch-class slots labeled with intervals relative to the root, indexed so C is slot 0.",
32
+ example: "1, ♭2, 2, ♭3, 3, 4, ♭5, 5, ♭6, 6, ♭7, 7",
33
+ inputKind: "rootAndNoteCollection",
34
+ outputKind: "intervals",
35
+ outputShape: "chromatic-12",
36
+ outputIndexing: absolutePitchClassC0,
37
+ allowsEmptySlots: false,
38
+ emptySlot: "none",
39
+ get: (root, key, opts) => createConversionResult(getIntervalsForRootAndNoteCollectionKey(root, key, opts)),
21
40
  },
22
41
  extensions: {
23
42
  id: "extensions",
24
43
  name: "Extensions",
25
44
  shortName: "Extensions",
26
- description: "Returns intervals with simple intervals converted to extensions where applicable (e.g., '2' becomes '9').",
27
- example: "9, 11, ♭13",
28
- get: (root, key, opts) => getExtensionsForRootAndNoteCollectionKey(root, key, opts),
45
+ description: "Returns 12 chromatic interval slots with simple intervals converted to extensions where applicable.",
46
+ example: "1, ♭9, 9, ♭3, 3, 11, ♭5, 5, ♭13, 13, ♭7, 7",
47
+ inputKind: "rootAndNoteCollection",
48
+ outputKind: "intervals",
49
+ outputShape: "chromatic-12",
50
+ outputIndexing: absolutePitchClassC0,
51
+ allowsEmptySlots: false,
52
+ emptySlot: "none",
53
+ get: (root, key, opts) => createConversionResult(getExtensionsForRootAndNoteCollectionKey(root, key, opts)),
29
54
  },
30
55
  compoundIntervals: {
31
56
  id: "compound-intervals",
32
57
  name: "Compound Intervals",
33
58
  shortName: "Compound",
34
- description: "Returns intervals converted to their compound equivalents (e.g., '3' becomes '10').",
35
- example: "10, 12, 14",
36
- get: (root, key, opts) => getCompoundIntervalsForRootAndNoteCollectionKey(root, key, opts),
59
+ description: "Returns 12 chromatic interval slots with simple intervals converted to compound equivalents.",
60
+ example: "1, ♭9, 9, ♭10, 10, 11, ♭12, 12, ♭13, 13, ♭14, 14",
61
+ inputKind: "rootAndNoteCollection",
62
+ outputKind: "intervals",
63
+ outputShape: "chromatic-12",
64
+ outputIndexing: absolutePitchClassC0,
65
+ allowsEmptySlots: false,
66
+ emptySlot: "none",
67
+ get: (root, key, opts) => createConversionResult(getCompoundIntervalsForRootAndNoteCollectionKey(root, key, opts)),
37
68
  },
38
69
  triads: {
39
70
  id: "triads",
40
71
  name: "Triads",
41
72
  shortName: "Triads",
42
- description: "Returns the triads with prepended note names (e.g., 'Cm', 'E♭M').",
43
- example: "Cm, E♭M",
44
- get: (root, key, opts) => getTriadsForRootAndNoteCollectionKey(root, key, opts),
73
+ description: "Returns 12 chromatic triad-name slots for note collections with authored modal harmony.",
74
+ example: "CM, -, Dm, -, Em, FM, -, GM, -, Am, -, B°",
75
+ inputKind: "rootAndNoteCollection",
76
+ outputKind: "chordNames",
77
+ outputShape: "chromatic-12",
78
+ outputIndexing: absolutePitchClassC0,
79
+ allowsEmptySlots: true,
80
+ emptySlot: "undefined",
81
+ isAvailable: isAuthoredHarmonyAvailable,
82
+ unavailableReason: authoredHarmonyUnavailableReason,
83
+ get: (root, key, opts) => createConversionResult(getTriadsForRootAndNoteCollectionKey(root, key, opts)),
45
84
  },
46
85
  seventhChords: {
47
86
  id: "seventh-chords",
48
87
  name: "Seventh Chords",
49
88
  shortName: "Sevenths",
50
- description: "Returns the seventh chords with prepended note names (e.g., 'Cm7', 'E♭M7').",
51
- example: "Cm7, E♭M7",
52
- get: (root, key, opts) => getSeventhChordsForRootAndNoteCollectionKey(root, key, opts),
89
+ description: "Returns 12 chromatic seventh-chord-name slots for note collections with authored modal harmony.",
90
+ example: "CM7, -, Dm7, -, Em7, FM7, -, G7, -, Am7, -, Bø7",
91
+ inputKind: "rootAndNoteCollection",
92
+ outputKind: "chordNames",
93
+ outputShape: "chromatic-12",
94
+ outputIndexing: absolutePitchClassC0,
95
+ allowsEmptySlots: true,
96
+ emptySlot: "undefined",
97
+ isAvailable: isAuthoredHarmonyAvailable,
98
+ unavailableReason: authoredHarmonyUnavailableReason,
99
+ get: (root, key, opts) => createConversionResult(getSeventhChordsForRootAndNoteCollectionKey(root, key, opts)),
53
100
  },
54
101
  romanTriads: {
55
102
  id: "roman-triads",
56
103
  name: "Roman Numeral Triads",
57
104
  shortName: "Roman Triads",
58
- description: "Returns the Roman numeral representation of the triads (e.g., 'I', 'ii', 'iii').",
59
- example: "I, ii, iii",
60
- get: (root, key, opts) => getRomanTriadsForRootAndNoteCollectionKey(root, key, opts),
105
+ description: "Returns 12 chromatic Roman numeral triad slots for note collections with authored modal harmony.",
106
+ example: "I, -, ii, -, iii, IV, -, V, -, vi, -, vii°",
107
+ inputKind: "rootAndNoteCollection",
108
+ outputKind: "romanNumerals",
109
+ outputShape: "chromatic-12",
110
+ outputIndexing: absolutePitchClassC0,
111
+ allowsEmptySlots: true,
112
+ emptySlot: "undefined",
113
+ isAvailable: isAuthoredHarmonyAvailable,
114
+ unavailableReason: authoredHarmonyUnavailableReason,
115
+ get: (root, key, opts) => createConversionResult(getRomanTriadsForRootAndNoteCollectionKey(root, key, opts)),
61
116
  },
62
117
  romanSeventhChords: {
63
118
  id: "roman-seventh-chords",
64
119
  name: "Roman Numeral Seventh Chords",
65
120
  shortName: "Roman Sevenths",
66
- description: "Returns the Roman numeral representation of the seventh chords (e.g., 'I7', 'ii7', 'iii7').",
67
- example: "I7, ii7, iii7",
68
- get: (root, key, opts) => getRomanSeventhChordsForRootAndNoteCollectionKey(root, key, opts),
121
+ description: "Returns 12 chromatic Roman numeral seventh-chord slots for note collections with authored modal harmony.",
122
+ example: "IM7, -, iim7, -, iiim7, IVM7, -, V7, -, vim7, -, viiø7",
123
+ inputKind: "rootAndNoteCollection",
124
+ outputKind: "romanNumerals",
125
+ outputShape: "chromatic-12",
126
+ outputIndexing: absolutePitchClassC0,
127
+ allowsEmptySlots: true,
128
+ emptySlot: "undefined",
129
+ isAvailable: isAuthoredHarmonyAvailable,
130
+ unavailableReason: authoredHarmonyUnavailableReason,
131
+ get: (root, key, opts) => createConversionResult(getRomanSeventhChordsForRootAndNoteCollectionKey(root, key, opts)),
69
132
  },
70
133
  },
71
134
  };
135
+ export const rootAndNoteCollectionConversions = conversions.rootAndNoteCollection;
136
+ export function isRootAndNoteCollectionConversionAvailable(conversion, rootNote, noteCollectionKey) {
137
+ return conversion.isAvailable?.(rootNote, noteCollectionKey) ?? true;
138
+ }
139
+ export function getAvailableRootAndNoteCollectionConversions(rootNote, noteCollectionKey) {
140
+ return Object.values(rootAndNoteCollectionConversions).filter((conversion) => isRootAndNoteCollectionConversionAvailable(conversion, rootNote, noteCollectionKey));
141
+ }
@@ -1,6 +1,7 @@
1
1
  import { type CompoundInterval, type Interval, type IntervalQuality, type RootNote, type SimpleInterval } from "../data/labels/note-labels.js";
2
2
  import type { ChromaticIndex, ChromaticTuple } from "../data/chromatic.js";
3
3
  import { type NoteCollectionKey } from "../data/note-collections/mod.js";
4
+ export declare const DIATONIC_STEPS_PER_OCTAVE = 7;
4
5
  export type ChromaticIntervalTuple = ChromaticTuple<Interval>;
5
6
  export declare function isOctaveInterval(interval: Interval): boolean;
6
7
  /**
@@ -52,6 +53,8 @@ export declare function normalizeCompoundIntervalString(name: string): CompoundI
52
53
  * Parses an array of strings and returns an array of canonical `CompoundInterval`s.
53
54
  */
54
55
  export declare function normalizeCompoundIntervalStringArray(names: readonly string[]): CompoundInterval[];
56
+ export declare function getIntervalLabelDegree(intervalLabel: string): number | undefined;
57
+ export declare function shiftIntervalLabelByOctaves(intervalLabel: string, octaveOffset: number): string;
55
58
  /**
56
59
  * Sorts an array of intervals in ascending order based on their integer value.
57
60
  * This is a pure function and returns a new sorted array, leaving the original array unchanged.
@@ -1 +1 @@
1
- {"version":3,"file":"intervals.d.ts","sourceRoot":"","sources":["../../../src/src/utils/intervals.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"intervals.d.ts","sourceRoot":"","sources":["../../../src/src/utils/intervals.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,8 @@ import { normalizeAccidentalString } from "./accidentals.js";
6
6
  import { isValidNoteCollectionKey } from "./note-collections.js";
7
7
  import { createChromaticTuple, normalizeChromaticIndex } from "./chromatic.js";
8
8
  const INTERVAL_NUMBER_REGEX = /\d+$/;
9
+ const INTERVAL_LABEL_REGEX = /^([^\d]*)(\d+)$/;
10
+ export const DIATONIC_STEPS_PER_OCTAVE = 7;
9
11
  export function isOctaveInterval(interval) {
10
12
  return interval === "8" || interval === "♮8";
11
13
  }
@@ -135,6 +137,27 @@ export function normalizeCompoundIntervalStringArray(names) {
135
137
  .map((name) => normalizeCompoundIntervalString(name))
136
138
  .filter((name) => name !== undefined);
137
139
  }
140
+ export function getIntervalLabelDegree(intervalLabel) {
141
+ const match = intervalLabel.match(INTERVAL_LABEL_REGEX);
142
+ if (!match)
143
+ return undefined;
144
+ const degree = Number(match[2]);
145
+ return Number.isInteger(degree) && degree > 0 ? degree : undefined;
146
+ }
147
+ export function shiftIntervalLabelByOctaves(intervalLabel, octaveOffset) {
148
+ if (octaveOffset === 0)
149
+ return intervalLabel;
150
+ const match = intervalLabel.match(INTERVAL_LABEL_REGEX);
151
+ if (!match)
152
+ return intervalLabel;
153
+ const [, accidental = "", degreeLabel] = match;
154
+ const degree = Number(degreeLabel);
155
+ if (!Number.isInteger(degree) || degree < 1)
156
+ return intervalLabel;
157
+ const shiftedDegree = degree +
158
+ octaveOffset * DIATONIC_STEPS_PER_OCTAVE;
159
+ return shiftedDegree >= 1 ? `${accidental}${shiftedDegree}` : intervalLabel;
160
+ }
138
161
  /**
139
162
  * Sorts an array of intervals in ascending order based on their integer value.
140
163
  * This is a pure function and returns a new sorted array, leaving the original array unchanged.
@@ -1,5 +1,12 @@
1
1
  import { type Interval, type NoteName } from "../data/labels/note-labels.js";
2
2
  import type { MidiNoteNumber } from "../types/midi";
3
+ export declare function getMidiOctave(midi: number): number;
4
+ export type MidiNoteSpelling = "flat" | "sharp";
5
+ export interface FormatMidiNoteOptions {
6
+ spelling?: MidiNoteSpelling;
7
+ }
8
+ export declare function formatMidiNote(midi: number, options?: FormatMidiNoteOptions): string;
9
+ export declare function formatSpelledMidiNote(noteName: string, midi: number): string;
3
10
  /**
4
11
  * Calculates a MIDI note number based on a starting musical note (represented by its integer value and octave)
5
12
  * and an interval to apply to it.
@@ -1 +1 @@
1
- {"version":3,"file":"midi.d.ts","sourceRoot":"","sources":["../../../src/src/utils/midi.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EAEb,KAAK,QAAQ,EAEd,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,QAAQ,GACjB,cAAc,GAAG,SAAS,CAM5B;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,QAAQ,GACjB,cAAc,GAAG,SAAS,CAQ5B;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,QAAQ,GACjB,cAAc,GAAG,SAAS,CAI5B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,MAAM,GACvB,cAAc,GAAG,SAAS,CAI5B"}
1
+ {"version":3,"file":"midi.d.ts","sourceRoot":"","sources":["../../../src/src/utils/midi.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EAEb,KAAK,QAAQ,EAEd,MAAM,+BAA+B,CAAC;AAGvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,qBAA0B,GAClC,MAAM,CAQR;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,MAAM,CAER;AAED;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,QAAQ,GACjB,cAAc,GAAG,SAAS,CAM5B;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,QAAQ,GACjB,cAAc,GAAG,SAAS,CAQ5B;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,QAAQ,GACjB,cAAc,GAAG,SAAS,CAI5B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,MAAM,GACvB,cAAc,GAAG,SAAS,CAI5B"}
@@ -1,4 +1,20 @@
1
1
  import { intervalToIntegerMap, noteNameToIntegerMap, } from "../data/labels/note-labels.js";
2
+ import { noteLabelCollections } from "../data/labels/note-label-collections.js";
3
+ import { normalizeChromaticIndex } from "./chromatic.js";
4
+ export function getMidiOctave(midi) {
5
+ return Math.floor(midi / 12) - 1;
6
+ }
7
+ export function formatMidiNote(midi, options = {}) {
8
+ const { spelling = "flat" } = options;
9
+ const labels = spelling === "sharp"
10
+ ? noteLabelCollections.noteNamesSharp.labels
11
+ : noteLabelCollections.noteNamesFlat.labels;
12
+ const noteName = labels[normalizeChromaticIndex(midi)];
13
+ return `${noteName}${getMidiOctave(midi)}`;
14
+ }
15
+ export function formatSpelledMidiNote(noteName, midi) {
16
+ return noteName === "" ? "" : `${noteName}${getMidiOctave(midi)}`;
17
+ }
2
18
  /**
3
19
  * Calculates a MIDI note number based on a starting musical note (represented by its integer value and octave)
4
20
  * and an interval to apply to it.
@@ -1,5 +1,6 @@
1
1
  import { type NoteCollectionKey } from "../data/note-collections/mod.js";
2
- import type { Interval } from "../data/labels/note-labels.js";
2
+ import type { ChromaticIndex } from "../data/chromatic.js";
3
+ import { type Interval } from "../data/labels/note-labels.js";
3
4
  import type { CollectionCategory, NoteCollection } from "../types/note-collections";
4
5
  /**
5
6
  * Checks if a given string is a valid `NoteCollectionKey`.
@@ -7,6 +8,13 @@ import type { CollectionCategory, NoteCollection } from "../types/note-collectio
7
8
  * @returns `true` if the key is a valid `NoteCollectionKey`, `false` otherwise.
8
9
  */
9
10
  export declare function isValidNoteCollectionKey(key: string): key is NoteCollectionKey;
11
+ export interface GetNoteCollectionPitchClassesParams {
12
+ rootNote: string;
13
+ noteCollectionKey: NoteCollectionKey | string;
14
+ }
15
+ export declare function getNoteCollectionPitchClasses({ rootNote: rawRootNote, noteCollectionKey, }: GetNoteCollectionPitchClassesParams): ReadonlySet<ChromaticIndex> | undefined;
16
+ export declare const noteCollectionDisplayNames: ReadonlyMap<string, string>;
17
+ export declare function getNoteCollectionDisplayName(noteCollectionKey: NoteCollectionKey | string): string;
10
18
  /** Search options for finding a note collection. */
11
19
  export interface SearchOptions {
12
20
  /** A text string to search against collection names, aliases, and characteristics. */
@@ -1 +1 @@
1
- {"version":3,"file":"note-collections.d.ts","sourceRoot":"","sources":["../../../src/src/utils/note-collections.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,KAAK,EACV,kBAAkB,EAClB,cAAc,EACf,MAAM,2BAA2B,CAAC;AAEnC;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,GACV,GAAG,IAAI,iBAAiB,CAE1B;AAoDD,oDAAoD;AACpD,MAAM,WAAW,aAAa;IAC5B,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,gFAAgF;IAChF,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,oGAAoG;IACpG,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,aAAa,GACrB,cAAc,EAAE,CAmGlB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,aAAa,GACrB,cAAc,GAAG,SAAS,CAE5B"}
1
+ {"version":3,"file":"note-collections.d.ts","sourceRoot":"","sources":["../../../src/src/utils/note-collections.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EACL,KAAK,QAAQ,EAEd,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EACV,kBAAkB,EAClB,cAAc,EACf,MAAM,2BAA2B,CAAC;AAInC;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,GACV,GAAG,IAAI,iBAAiB,CAE1B;AAED,MAAM,WAAW,mCAAmC;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,iBAAiB,GAAG,MAAM,CAAC;CAC/C;AAED,wBAAgB,6BAA6B,CAAC,EAC5C,QAAQ,EAAE,WAAW,EACrB,iBAAiB,GAClB,EAAE,mCAAmC,GAClC,WAAW,CAAC,cAAc,CAAC,GAC3B,SAAS,CAeZ;AAED,eAAO,MAAM,0BAA0B,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAKlE,CAAC;AAEF,wBAAgB,4BAA4B,CAC1C,iBAAiB,EAAE,iBAAiB,GAAG,MAAM,GAC5C,MAAM,CAER;AAoDD,oDAAoD;AACpD,MAAM,WAAW,aAAa;IAC5B,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,gFAAgF;IAChF,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,oGAAoG;IACpG,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,aAAa,GACrB,cAAc,EAAE,CAmGlB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,aAAa,GACrB,cAAc,GAAG,SAAS,CAE5B"}