@libraz/libcantus 0.9.4 → 1.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 (186) hide show
  1. package/README.md +61 -261
  2. package/README_ja.md +115 -0
  3. package/dist/analyze/index.cjs +54 -7
  4. package/dist/analyze/index.cjs.map +1 -1
  5. package/dist/analyze/index.d.cts +213 -456
  6. package/dist/analyze/index.d.ts +213 -456
  7. package/dist/analyze/index.js +56 -9
  8. package/dist/chunk-3JXCW6DX.cjs +3220 -0
  9. package/dist/chunk-3JXCW6DX.cjs.map +1 -0
  10. package/dist/chunk-4A2RMUCC.js +7647 -0
  11. package/dist/chunk-4A2RMUCC.js.map +1 -0
  12. package/dist/chunk-6XPTBE7Y.cjs +49 -0
  13. package/dist/chunk-6XPTBE7Y.cjs.map +1 -0
  14. package/dist/chunk-AFM2ULJH.cjs +5121 -0
  15. package/dist/chunk-AFM2ULJH.cjs.map +1 -0
  16. package/dist/chunk-E3F4AHAH.cjs +690 -0
  17. package/dist/chunk-E3F4AHAH.cjs.map +1 -0
  18. package/dist/chunk-ELCTZUJJ.js +379 -0
  19. package/dist/chunk-ELCTZUJJ.js.map +1 -0
  20. package/dist/chunk-FVSI36UV.js +690 -0
  21. package/dist/chunk-FVSI36UV.js.map +1 -0
  22. package/dist/chunk-GEDTJHAC.cjs +1 -0
  23. package/dist/chunk-GEDTJHAC.cjs.map +1 -0
  24. package/dist/chunk-GOZG57ER.js +3220 -0
  25. package/dist/chunk-GOZG57ER.js.map +1 -0
  26. package/dist/chunk-H3VORETI.js +2243 -0
  27. package/dist/chunk-H3VORETI.js.map +1 -0
  28. package/dist/chunk-H42UHPYW.js +1577 -0
  29. package/dist/chunk-H42UHPYW.js.map +1 -0
  30. package/dist/chunk-HFPS7JFD.js +1 -0
  31. package/dist/chunk-INHVXP6Z.js +3053 -0
  32. package/dist/chunk-INHVXP6Z.js.map +1 -0
  33. package/dist/chunk-K4ZJUGF4.cjs +379 -0
  34. package/dist/chunk-K4ZJUGF4.cjs.map +1 -0
  35. package/dist/chunk-KNJEKLKV.js +49 -0
  36. package/dist/chunk-KNJEKLKV.js.map +1 -0
  37. package/dist/chunk-M4CWTJWJ.cjs +7647 -0
  38. package/dist/chunk-M4CWTJWJ.cjs.map +1 -0
  39. package/dist/chunk-MXO72PLY.cjs +211 -0
  40. package/dist/chunk-MXO72PLY.cjs.map +1 -0
  41. package/dist/chunk-NLEU4QSE.cjs +360 -0
  42. package/dist/chunk-NLEU4QSE.cjs.map +1 -0
  43. package/dist/chunk-OE6WK2Y2.cjs +1577 -0
  44. package/dist/chunk-OE6WK2Y2.cjs.map +1 -0
  45. package/dist/chunk-Q2WGKJNN.cjs +1064 -0
  46. package/dist/chunk-Q2WGKJNN.cjs.map +1 -0
  47. package/dist/chunk-QYQQ5J6E.js +1 -0
  48. package/dist/chunk-QYQQ5J6E.js.map +1 -0
  49. package/dist/chunk-RHIJ3S4I.cjs +1 -0
  50. package/dist/chunk-RHIJ3S4I.cjs.map +1 -0
  51. package/dist/chunk-TTCLJX6D.js +211 -0
  52. package/dist/chunk-TTCLJX6D.js.map +1 -0
  53. package/dist/chunk-UADYAYAT.cjs +3053 -0
  54. package/dist/chunk-UADYAYAT.cjs.map +1 -0
  55. package/dist/chunk-VOHZB45S.js +5121 -0
  56. package/dist/chunk-VOHZB45S.js.map +1 -0
  57. package/dist/chunk-VTI6FOLB.js +1064 -0
  58. package/dist/chunk-VTI6FOLB.js.map +1 -0
  59. package/dist/chunk-WWURE4XT.cjs +2243 -0
  60. package/dist/chunk-WWURE4XT.cjs.map +1 -0
  61. package/dist/chunk-YH3BIKHH.js +360 -0
  62. package/dist/chunk-YH3BIKHH.js.map +1 -0
  63. package/dist/core/index.cjs +103 -6
  64. package/dist/core/index.cjs.map +1 -1
  65. package/dist/core/index.d.cts +96 -345
  66. package/dist/core/index.d.ts +96 -345
  67. package/dist/core/index.js +104 -7
  68. package/dist/generate/index.cjs +89 -10
  69. package/dist/generate/index.cjs.map +1 -1
  70. package/dist/generate/index.d.cts +437 -1095
  71. package/dist/generate/index.d.ts +437 -1095
  72. package/dist/generate/index.js +94 -15
  73. package/dist/index-9wcMhG73.d.ts +1095 -0
  74. package/dist/{index-D6b6na69.d.cts → index-B4o55NDr.d.cts} +13 -9
  75. package/dist/index-B9MNZboQ.d.cts +770 -0
  76. package/dist/index-B9MNZboQ.d.ts +770 -0
  77. package/dist/index-BGFW-8P2.d.cts +2307 -0
  78. package/dist/index-BO6xE9YU.d.cts +1804 -0
  79. package/dist/index-BkGmlyI3.d.cts +470 -0
  80. package/dist/index-CCNJRG-P.d.cts +1095 -0
  81. package/dist/index-CGpRv5sl.d.cts +643 -0
  82. package/dist/index-C_8o--VE.d.cts +1242 -0
  83. package/dist/index-CgHqxdps.d.ts +2307 -0
  84. package/dist/index-Chbst3Jx.d.ts +1343 -0
  85. package/dist/index-Cj49F892.d.ts +470 -0
  86. package/dist/{index-tSQh-xwY.d.ts → index-CunYKLiu.d.ts} +13 -9
  87. package/dist/index-D57QRbVn.d.ts +1804 -0
  88. package/dist/index-DInQqT8Q.d.cts +66 -0
  89. package/dist/index-DInQqT8Q.d.ts +66 -0
  90. package/dist/index-Dzr13q3d.d.cts +1343 -0
  91. package/dist/index-G1uwGGWQ.d.ts +643 -0
  92. package/dist/index-szBv3496.d.ts +1242 -0
  93. package/dist/index.cjs +358 -15
  94. package/dist/index.cjs.map +1 -1
  95. package/dist/index.d.cts +17 -15
  96. package/dist/index.d.ts +17 -15
  97. package/dist/index.js +407 -64
  98. package/dist/masks-DYbE485J.d.cts +445 -0
  99. package/dist/masks-DYbE485J.d.ts +445 -0
  100. package/dist/model/index.cjs +39 -7
  101. package/dist/model/index.cjs.map +1 -1
  102. package/dist/model/index.d.cts +4685 -243
  103. package/dist/model/index.d.ts +4685 -243
  104. package/dist/model/index.js +40 -8
  105. package/dist/positional-Cptlj-xs.d.ts +287 -0
  106. package/dist/positional-DvH_sd8u.d.cts +287 -0
  107. package/dist/theory/index.cjs +101 -7
  108. package/dist/theory/index.cjs.map +1 -1
  109. package/dist/theory/index.d.cts +513 -173
  110. package/dist/theory/index.d.ts +513 -173
  111. package/dist/theory/index.js +118 -24
  112. package/package.json +16 -11
  113. package/dist/chunk-36N73KZ3.cjs +0 -246
  114. package/dist/chunk-36N73KZ3.cjs.map +0 -1
  115. package/dist/chunk-4HLLZPXT.cjs +0 -3077
  116. package/dist/chunk-4HLLZPXT.cjs.map +0 -1
  117. package/dist/chunk-7MGZ7D62.cjs +0 -498
  118. package/dist/chunk-7MGZ7D62.cjs.map +0 -1
  119. package/dist/chunk-7NKDPF74.js +0 -3077
  120. package/dist/chunk-7NKDPF74.js.map +0 -1
  121. package/dist/chunk-CAN76NCU.cjs +0 -679
  122. package/dist/chunk-CAN76NCU.cjs.map +0 -1
  123. package/dist/chunk-D2FAJBYL.js +0 -479
  124. package/dist/chunk-D2FAJBYL.js.map +0 -1
  125. package/dist/chunk-EHVEBWM5.js +0 -1449
  126. package/dist/chunk-EHVEBWM5.js.map +0 -1
  127. package/dist/chunk-FCANXBAT.cjs +0 -30
  128. package/dist/chunk-FCANXBAT.cjs.map +0 -1
  129. package/dist/chunk-FNDWXRRI.cjs +0 -479
  130. package/dist/chunk-FNDWXRRI.cjs.map +0 -1
  131. package/dist/chunk-GQSGS2N4.js +0 -173
  132. package/dist/chunk-GQSGS2N4.js.map +0 -1
  133. package/dist/chunk-HKGYCQ34.js +0 -53
  134. package/dist/chunk-HKGYCQ34.js.map +0 -1
  135. package/dist/chunk-I24MV65U.js +0 -106
  136. package/dist/chunk-I24MV65U.js.map +0 -1
  137. package/dist/chunk-KMHOICIY.js +0 -679
  138. package/dist/chunk-KMHOICIY.js.map +0 -1
  139. package/dist/chunk-LW53AHQU.cjs +0 -1117
  140. package/dist/chunk-LW53AHQU.cjs.map +0 -1
  141. package/dist/chunk-N6IHQUOX.js +0 -1
  142. package/dist/chunk-NKIBQ6PT.js +0 -30
  143. package/dist/chunk-NKIBQ6PT.js.map +0 -1
  144. package/dist/chunk-NP4NA2FB.cjs +0 -106
  145. package/dist/chunk-NP4NA2FB.cjs.map +0 -1
  146. package/dist/chunk-NVE34YGZ.cjs +0 -1449
  147. package/dist/chunk-NVE34YGZ.cjs.map +0 -1
  148. package/dist/chunk-NYYWMV2C.js +0 -327
  149. package/dist/chunk-NYYWMV2C.js.map +0 -1
  150. package/dist/chunk-Q2XUP227.js +0 -845
  151. package/dist/chunk-Q2XUP227.js.map +0 -1
  152. package/dist/chunk-Q6OP4U43.cjs +0 -327
  153. package/dist/chunk-Q6OP4U43.cjs.map +0 -1
  154. package/dist/chunk-RC6GBMCD.cjs +0 -845
  155. package/dist/chunk-RC6GBMCD.cjs.map +0 -1
  156. package/dist/chunk-RK35RIN7.js +0 -1117
  157. package/dist/chunk-RK35RIN7.js.map +0 -1
  158. package/dist/chunk-RUMU3UA6.cjs +0 -53
  159. package/dist/chunk-RUMU3UA6.cjs.map +0 -1
  160. package/dist/chunk-T64C7ZD7.cjs +0 -1
  161. package/dist/chunk-T64C7ZD7.cjs.map +0 -1
  162. package/dist/chunk-XEBG3G53.js +0 -498
  163. package/dist/chunk-XEBG3G53.js.map +0 -1
  164. package/dist/chunk-YLEMGEFH.js +0 -246
  165. package/dist/chunk-YLEMGEFH.js.map +0 -1
  166. package/dist/chunk-ZEJR4TKL.cjs +0 -173
  167. package/dist/chunk-ZEJR4TKL.cjs.map +0 -1
  168. package/dist/function-BtiZb9i9.d.ts +0 -208
  169. package/dist/function-DNugAOrt.d.cts +0 -208
  170. package/dist/index-6VR8-kit.d.ts +0 -143
  171. package/dist/index-70p168VM.d.ts +0 -192
  172. package/dist/index-Be74mcon.d.cts +0 -152
  173. package/dist/index-BtXT6UQ0.d.cts +0 -192
  174. package/dist/index-C5UBbQ4G.d.ts +0 -152
  175. package/dist/index-C83mZI1P.d.ts +0 -242
  176. package/dist/index-DXd9JikN.d.cts +0 -246
  177. package/dist/index-DXd9JikN.d.ts +0 -246
  178. package/dist/index-OG65ocOr.d.cts +0 -272
  179. package/dist/index-OG65ocOr.d.ts +0 -272
  180. package/dist/index-tJhkmQgE.d.cts +0 -143
  181. package/dist/index-y_ak9_Hi.d.cts +0 -242
  182. package/dist/styled-DIRkk9Uz.d.ts +0 -506
  183. package/dist/styled-DJbkJQfj.d.cts +0 -506
  184. package/dist/types-BN6_Q9Kl.d.cts +0 -39
  185. package/dist/types-BN6_Q9Kl.d.ts +0 -39
  186. /package/dist/{chunk-N6IHQUOX.js.map → chunk-HFPS7JFD.js.map} +0 -0
@@ -1,506 +0,0 @@
1
- import { C as Chord } from './index-y_ak9_Hi.cjs';
2
- import { K as KeyScale } from './types-BN6_Q9Kl.cjs';
3
-
4
- declare function maskFromOffsets(offsets: readonly number[]): number;
5
- /**
6
- * Mode mask for the major (Ionian) scale: offsets {0, 2, 4, 5, 7, 9, 11}.
7
- *
8
- * @category Scales
9
- */
10
- declare const MAJOR_MASK = 2741;
11
- /**
12
- * Mode mask for the natural minor (Aeolian) scale: offsets {0, 2, 3, 5, 7, 8, 10}.
13
- *
14
- * @category Scales
15
- */
16
- declare const NATURAL_MINOR_MASK = 1453;
17
- /**
18
- * Harmonic minor: natural minor with a raised seventh — offsets {0,2,3,5,7,8,11}.
19
- *
20
- * @category Scales
21
- */
22
- declare const HARMONIC_MINOR_MASK: number;
23
- /**
24
- * Ascending melodic minor: offsets {0,2,3,5,7,9,11}.
25
- *
26
- * @category Scales
27
- */
28
- declare const MELODIC_MINOR_MASK: number;
29
- /**
30
- * Dorian mode: offsets {0,2,3,5,7,9,10}.
31
- *
32
- * @category Scales
33
- */
34
- declare const DORIAN_MASK: number;
35
- /**
36
- * Phrygian mode: offsets {0,1,3,5,7,8,10}.
37
- *
38
- * @category Scales
39
- */
40
- declare const PHRYGIAN_MASK: number;
41
- /**
42
- * Lydian mode: offsets {0,2,4,6,7,9,11}.
43
- *
44
- * @category Scales
45
- */
46
- declare const LYDIAN_MASK: number;
47
- /**
48
- * Mixolydian mode: offsets {0,2,4,5,7,9,10}.
49
- *
50
- * @category Scales
51
- */
52
- declare const MIXOLYDIAN_MASK: number;
53
- /**
54
- * Locrian mode: offsets {0,1,3,5,6,8,10}.
55
- *
56
- * @category Scales
57
- */
58
- declare const LOCRIAN_MASK: number;
59
- /**
60
- * Major pentatonic: offsets {0,2,4,7,9}.
61
- *
62
- * @category Scales
63
- */
64
- declare const MAJOR_PENTATONIC_MASK: number;
65
- /**
66
- * Minor pentatonic: offsets {0,3,5,7,10}.
67
- *
68
- * @category Scales
69
- */
70
- declare const MINOR_PENTATONIC_MASK: number;
71
- /**
72
- * Hexatonic blues scale: minor pentatonic plus the flat-fifth — {0,3,5,6,7,10}.
73
- *
74
- * @category Scales
75
- */
76
- declare const BLUES_MASK: number;
77
- /**
78
- * Whole-tone scale: offsets {0,2,4,6,8,10}.
79
- *
80
- * @category Scales
81
- */
82
- declare const WHOLE_TONE_MASK: number;
83
- /**
84
- * Octatonic (half-step first): offsets {0,1,3,4,6,7,9,10}.
85
- *
86
- * @category Scales
87
- */
88
- declare const OCTATONIC_HALF_WHOLE_MASK: number;
89
- /**
90
- * Octatonic (whole-step first): offsets {0,2,3,5,6,8,9,11}.
91
- *
92
- * @category Scales
93
- */
94
- declare const OCTATONIC_WHOLE_HALF_MASK: number;
95
- /**
96
- * Chromatic scale: all twelve pitch classes.
97
- *
98
- * @category Scales
99
- */
100
- declare const CHROMATIC_MASK = 4095;
101
- /**
102
- * Lydian dominant (melodic minor's fourth mode): offsets {0,2,4,6,7,9,10}.
103
- *
104
- * The scale over an unaltered dominant with a raised eleventh.
105
- *
106
- * @category Scales
107
- */
108
- declare const LYDIAN_DOMINANT_MASK: number;
109
- /**
110
- * Mixolydian b13, the aeolian dominant (melodic minor's fifth mode): offsets
111
- * {0,2,4,5,7,8,10}.
112
- *
113
- * The scale over a dominant with a flat thirteenth.
114
- *
115
- * @category Scales
116
- */
117
- declare const MIXOLYDIAN_B13_MASK: number;
118
- /**
119
- * Locrian natural 2 (melodic minor's sixth mode): offsets {0,2,3,5,6,8,10}.
120
- *
121
- * The scale over a half-diminished chord used as a minor ii.
122
- *
123
- * @category Scales
124
- */
125
- declare const LOCRIAN_NATURAL2_MASK: number;
126
- /**
127
- * The altered scale, or superlocrian (melodic minor's seventh mode): offsets
128
- * {0,1,3,4,6,8,10}.
129
- *
130
- * The scale over an altered dominant: every tension raised or lowered.
131
- *
132
- * @category Scales
133
- */
134
- declare const ALTERED_MASK: number;
135
- /**
136
- * Phrygian dominant (harmonic minor's fifth mode): offsets {0,1,4,5,7,8,10}.
137
- *
138
- * The scale over the dominant of a minor key, and the characteristic sound of
139
- * the flamenco and maqam repertoires.
140
- *
141
- * @category Scales
142
- */
143
- declare const PHRYGIAN_DOMINANT_MASK: number;
144
- /**
145
- * Named scale masks addressable by {@link scaleByName}.
146
- *
147
- * @category Scales
148
- */
149
- declare const NAMED_SCALES: Readonly<{
150
- major: 2741;
151
- ionian: 2741;
152
- naturalMinor: 1453;
153
- aeolian: 1453;
154
- harmonicMinor: number;
155
- melodicMinor: number;
156
- dorian: number;
157
- phrygian: number;
158
- lydian: number;
159
- mixolydian: number;
160
- locrian: number;
161
- lydianDominant: number;
162
- mixolydianB13: number;
163
- locrianNatural2: number;
164
- altered: number;
165
- phrygianDominant: number;
166
- majorPentatonic: number;
167
- minorPentatonic: number;
168
- blues: number;
169
- wholeTone: number;
170
- octatonicHalfWhole: number;
171
- octatonicWholeHalf: number;
172
- chromatic: 4095;
173
- }>;
174
- /**
175
- * The name of a built-in scale, as accepted by {@link scaleByName},
176
- * {@link avoidNotes}, and {@link availableTensions}.
177
- *
178
- * @category Scales
179
- */
180
- type ScaleName = keyof typeof NAMED_SCALES;
181
- /**
182
- * A scale name that completes to the built-in names but still accepts any
183
- * string, so a caller with a name from configuration is not forced to cast.
184
- *
185
- * @category Scales
186
- */
187
- type ScaleNameInput = ScaleName | (string & {});
188
- /**
189
- * The mask of a named scale, or undefined when the name is not one.
190
- *
191
- * Looking the name up through this helper is what keeps `'constructor'` or
192
- * `'toString'` from resolving to something inherited from `Object.prototype`
193
- * and producing a scale whose mask is a function.
194
- *
195
- * @param name The scale name.
196
- * @returns The 12-bit mask, or undefined for an unknown name.
197
- * @category Scales
198
- */
199
- declare function namedScaleMask(name: ScaleNameInput): number | undefined;
200
- /**
201
- * The mask of a named scale, rejecting an unknown name.
202
- *
203
- * Every public entry point that takes a scale name funnels through here, so a
204
- * typo is reported the same way everywhere instead of being answered with an
205
- * empty result that also means "this scale has none".
206
- *
207
- * @param name The scale name.
208
- * @param label What the name is, for the error message.
209
- * @returns The 12-bit mask.
210
- * @throws If the name is not a built-in scale.
211
- * @category Scales
212
- */
213
- declare function requireScaleMask(name: ScaleNameInput, label?: string): number;
214
-
215
- /**
216
- * Test whether every chord pitch class is contained in a scale.
217
- *
218
- * @param chordPcs The chord's pitch classes (0..11).
219
- * @param scaleMask The scale's 12-bit mode mask.
220
- * @param scaleRootPc The pitch class the mask is rooted on.
221
- * @returns True if the scale is a superset of the chord.
222
- *
223
- * @category Scales
224
- */
225
- declare function scaleMatchesChord(chordPcs: number[], scaleMask: number, scaleRootPc: number): boolean;
226
- /**
227
- * A named scale rooted on a pitch class that fits over a chord.
228
- *
229
- * @category Scales
230
- */
231
- type ChordScaleMatch = {
232
- name: string;
233
- rootPc: number;
234
- };
235
- /**
236
- * List the scales that fit over a chord, best fit first.
237
- *
238
- * Only the chord root is considered as the scale root, matching the
239
- * conventional chord-scale relationship. Every entry of {@link NAMED_SCALES}
240
- * whose pitch-class set is a superset of the chord's is returned once per
241
- * distinct pitch-class set (aliased masks such as major/ionian report only the
242
- * modal name), ranked by fewest extra scale tones beyond the chord, then by
243
- * scale size (heptatonic before larger scales), then by conventional
244
- * preference. For bare triads and smaller chords, heptatonic scales rank before
245
- * pentatonics and other sizes: a pentatonic adds no modal color over a triad,
246
- * so the seven-note modes are the more useful answer. The chromatic scale is
247
- * only returned as a fallback when no other scale contains the chord.
248
- *
249
- * The ranking is by fit, so the first entry is the tightest-fitting scale
250
- * rather than the idiomatic choice: a four-note chord that a pentatonic covers
251
- * exactly puts that pentatonic ahead of the mode a player would name. Read the
252
- * whole list, or pick by name, when the idiomatic scale is what is wanted;
253
- * {@link scalesForChanges} makes that choice for a progression.
254
- *
255
- * @param chord The chord to fit scales over.
256
- * @returns The matching scales rooted on the chord root, best fit first.
257
- *
258
- * @example
259
- * ```ts
260
- * import { makeChord, chordScales } from '@libraz/libcantus';
261
- * const scales = chordScales(makeChord(0, 'maj7'));
262
- * // scales for Cmaj7, best fit first; each is { name, rootPc: 0 }
263
- * ```
264
- *
265
- * @category Scales
266
- */
267
- declare function chordScales(chord: Chord): ChordScaleMatch[];
268
- /**
269
- * List a scale's avoid notes over a chord.
270
- *
271
- * An avoid note is a non-chord scale tone that lies a semitone directly above a
272
- * chord tone; sounding it against the chord clashes. The scale is rooted on the
273
- * chord root. If the scale does not contain the chord, no avoid notes exist.
274
- *
275
- * @param chord The chord providing the chord tones.
276
- * @param scaleName A key of {@link NAMED_SCALES}.
277
- * @returns The avoid-note pitch classes, sorted ascending in [0, 11].
278
- * @throws If `scaleName` is not a built-in scale. An empty result already
279
- * means "this scale has no avoid notes over this chord"; answering a typo
280
- * the same way would make the two indistinguishable.
281
- *
282
- * @category Scales
283
- */
284
- declare function avoidNotes(chord: Chord, scaleName: ScaleNameInput): number[];
285
- /**
286
- * List a scale's available tensions over a chord.
287
- *
288
- * Available tensions are scale tones that are neither chord tones nor avoid
289
- * notes, i.e. the usable color tones (typically the 9/11/13 region). The scale
290
- * is rooted on the chord root. If the scale does not contain the chord, there
291
- * are no available tensions.
292
- *
293
- * @param chord The chord providing the chord tones.
294
- * @param scaleName A key of {@link NAMED_SCALES}.
295
- * @returns The available-tension pitch classes, sorted ascending in [0, 11].
296
- * @throws If `scaleName` is not a built-in scale, as {@link avoidNotes} does.
297
- *
298
- * @example
299
- * ```ts
300
- * import { makeChord, availableTensions } from '@libraz/libcantus';
301
- * availableTensions(makeChord(0, 'maj7'), 'ionian'); // [2, 9] — color tones over Cmaj7
302
- * ```
303
- *
304
- * @category Scales
305
- */
306
- declare function availableTensions(chord: Chord, scaleName: ScaleNameInput): number[];
307
- /**
308
- * A scale fit over a chord together with its avoid notes and tensions.
309
- *
310
- * @category Scales
311
- */
312
- type ChordScaleReportEntry = {
313
- name: string;
314
- rootPc: number;
315
- avoid: number[];
316
- tensions: number[];
317
- };
318
- /**
319
- * Report the best-fitting scales for a chord with their avoid notes and tensions.
320
- *
321
- * Combines {@link chordScales}, {@link avoidNotes}, and {@link availableTensions}
322
- * into a single ergonomic result, ordered best fit first.
323
- *
324
- * @param chord The chord to analyze.
325
- * @param limit Optional maximum number of scales to report; all by default.
326
- * @returns One entry per reported scale, best fit first.
327
- *
328
- * @category Scales
329
- */
330
- declare function chordScaleReport(chord: Chord, limit?: number): ChordScaleReportEntry[];
331
- /**
332
- * A chord paired with the scale chosen for it by {@link scalesForChanges}.
333
- *
334
- * @category Scales
335
- */
336
- type ScaleChoice = {
337
- chord: Chord;
338
- scale: ChordScaleMatch;
339
- };
340
- /**
341
- * Choose one scale per chord across a progression, favoring continuity.
342
- *
343
- * Each chord's {@link chordScales} candidates form a stage in a Viterbi-style
344
- * dynamic program. The transition cost between adjacent choices is the number
345
- * of pitch classes that differ between their pitch-class sets (the symmetric
346
- * difference), plus a small penalty for straying from a chord's best-fit scale
347
- * so that ties break toward the tighter fit. The minimum-total-cost path is
348
- * returned, one {@link ScaleChoice} per input chord in the original order.
349
- *
350
- * @param chords The chord sequence to choose scales for.
351
- * @returns One scale choice per chord, in input order.
352
- *
353
- * @category Scales
354
- */
355
- declare function scalesForChanges(chords: Chord[]): ScaleChoice[];
356
-
357
- /**
358
- * An inclusive MIDI pitch range for a single voice.
359
- *
360
- * @category Voicing & Counterpoint
361
- */
362
- type VoiceRange = {
363
- readonly min: number;
364
- readonly max: number;
365
- };
366
- /**
367
- * Default four-voice SATB ranges, ascending (index 0 = lowest):
368
- * bass E2–C4 (40–60), tenor C3–G4 (48–67), alto G3–D5 (55–74),
369
- * soprano C4–G5 (60–79).
370
- *
371
- * @category Voicing & Counterpoint
372
- */
373
- declare const SATB_RANGES: readonly Readonly<VoiceRange>[];
374
- /**
375
- * Options controlling {@link voiceChord} and {@link voiceProgression}.
376
- *
377
- * @category Voicing & Counterpoint
378
- */
379
- type VoicingOptions = {
380
- /**
381
- * Number of voices to realize. Ignored when `ranges` is given.
382
- *
383
- * @defaultValue 4
384
- */
385
- voices?: number;
386
- /** Explicit per-voice ranges, ascending (index 0 = lowest). Takes precedence over `voices`. */
387
- ranges?: VoiceRange[];
388
- /**
389
- * Maximum spacing in semitones between adjacent upper voices.
390
- *
391
- * @defaultValue 12
392
- */
393
- maxSpacing?: number;
394
- /**
395
- * Maximum number of chords {@link voiceProgression} will voice. The search
396
- * per chord is bounded internally, so the cost of a progression is linear in
397
- * its length; this is the guard against an unbounded caller, not a limit on
398
- * the search.
399
- *
400
- * @defaultValue 1000000
401
- */
402
- budget?: number;
403
- /**
404
- * The prevailing key. Supplying it enables the rules that only make sense
405
- * relative to a tonic: the leading tone is neither doubled nor left
406
- * unresolved. Without it, voicings are chosen from chord structure and
407
- * voice-leading distance alone.
408
- */
409
- key?: KeyScale;
410
- };
411
- /**
412
- * Realize a single chord as one MIDI pitch per voice, ascending (index 0 =
413
- * lowest). The bass voice takes the chord's `bassPc` when set, otherwise the
414
- * root; upper voices take chord pitch classes, doubling the root or fifth as
415
- * needed to fill all voices. The result stays inside each voice's range, keeps
416
- * adjacent upper voices within `maxSpacing`, avoids voice crossing, and is
417
- * deterministic: a compact close-position voicing centered in the ranges.
418
- *
419
- * @param chord The chord to voice.
420
- * @param opts Voicing options; defaults to four voices in {@link SATB_RANGES}.
421
- * @returns MIDI pitches, ascending, one per voice.
422
- * @throws If no voicing fits the given ranges.
423
- * @example
424
- * ```ts
425
- * import { parseChordSymbol, voiceChord } from '@libraz/libcantus';
426
- * const chord = parseChordSymbol('Cmaj7');
427
- * voiceChord(chord); // four ascending MIDI pitches within the SATB ranges
428
- * ```
429
- * @category Voicing & Counterpoint
430
- */
431
- declare function voiceChord(chord: Chord, opts?: VoicingOptions): number[];
432
- declare function voiceProgression(chords: readonly Chord[], opts?: VoicingOptions): number[][];
433
-
434
- /**
435
- * A tertian voicing style for {@link voiceChordStyled}.
436
- *
437
- * - `close`: the plain close-position tertian stack.
438
- * - `drop2`: the second voice from the top dropped an octave (drop-2 voicing).
439
- * - `drop3`: the third voice from the top dropped an octave (drop-3 voicing).
440
- * - `shell`: root plus guide tones (third and seventh) for seventh chords, or
441
- * root/third/fifth for triads; the fifth and tensions are omitted.
442
- * - `rootless`: the root omitted, keeping third/fifth/seventh and tensions
443
- * (a typical left-hand jazz voicing).
444
- *
445
- * @category Voicing & Counterpoint
446
- */
447
- type VoicingStyle = 'close' | 'drop2' | 'drop3' | 'shell' | 'rootless';
448
- /**
449
- * Options controlling {@link voiceChordStyled}.
450
- *
451
- * @category Voicing & Counterpoint
452
- */
453
- type StyledVoicingOptions = {
454
- /**
455
- * Voicing style to build.
456
- *
457
- * @defaultValue 'close'
458
- */
459
- style?: VoicingStyle;
460
- /** Constrain the highest voice to this pitch class (0..11) when given. */
461
- topNote?: number;
462
- /**
463
- * Base octave in scientific pitch notation: octave 4 starts the stack near
464
- * middle C (MIDI 60), i.e. near `12 * (octave + 1)`.
465
- *
466
- * @defaultValue 4
467
- */
468
- octave?: number;
469
- /**
470
- * Omit the root regardless of style (relevant for jazz voicings).
471
- *
472
- * @defaultValue false
473
- */
474
- rootless?: boolean;
475
- };
476
- /**
477
- * Realize a single chord as an explicit tertian voicing in a chosen style,
478
- * independent of the SATB range search used by {@link voiceChord}.
479
- *
480
- * The chord tones are stacked in close position from the bass (`bassPc`, else
481
- * `rootPc`) in the given scientific-pitch `octave` upward (octave 4 starts the
482
- * bass near C4 = MIDI 60, matching {@link midiToNote} and the bass module).
483
- * When `topNote` is given the stack is rotated so the highest voice's pitch
484
- * class equals that note (or the nearest chord tone). The chosen
485
- * {@link VoicingStyle} then transforms the stack, and the result is returned as
486
- * ascending MIDI pitches (index 0 = lowest).
487
- *
488
- * Every returned pitch is a valid MIDI number: an octave whose stack would run
489
- * off either end of the 0..127 range is rejected rather than voiced out of
490
- * range, matching {@link nextVoicing}, which clamps its derived ranges.
491
- *
492
- * @param chord The chord to voice.
493
- * @param opts Styled voicing options; defaults to a close voicing at octave 4.
494
- * @returns MIDI pitches, ascending, one per retained voice.
495
- * @throws If the voicing would not fit inside MIDI 0..127 at the given octave.
496
- * @example
497
- * ```ts
498
- * import { parseChordSymbol, voiceChordStyled } from '@libraz/libcantus';
499
- * const chord = parseChordSymbol('Dm7');
500
- * voiceChordStyled(chord, { style: 'drop2' }); // ascending MIDI pitches, drop-2 voicing
501
- * ```
502
- * @category Voicing & Counterpoint
503
- */
504
- declare function voiceChordStyled(chord: Chord, opts?: StyledVoicingOptions): number[];
505
-
506
- export { ALTERED_MASK as A, BLUES_MASK as B, CHROMATIC_MASK as C, DORIAN_MASK as D, scaleMatchesChord as E, scalesForChanges as F, voiceChord as G, HARMONIC_MINOR_MASK as H, voiceChordStyled as I, voiceProgression as J, LOCRIAN_MASK as L, MAJOR_MASK as M, NAMED_SCALES as N, OCTATONIC_HALF_WHOLE_MASK as O, PHRYGIAN_DOMINANT_MASK as P, SATB_RANGES as S, type VoiceRange as V, WHOLE_TONE_MASK as W, type ChordScaleMatch as a, type ChordScaleReportEntry as b, LOCRIAN_NATURAL2_MASK as c, LYDIAN_DOMINANT_MASK as d, LYDIAN_MASK as e, MAJOR_PENTATONIC_MASK as f, MELODIC_MINOR_MASK as g, MINOR_PENTATONIC_MASK as h, MIXOLYDIAN_B13_MASK as i, MIXOLYDIAN_MASK as j, NATURAL_MINOR_MASK as k, OCTATONIC_WHOLE_HALF_MASK as l, PHRYGIAN_MASK as m, type ScaleChoice as n, type ScaleName as o, type ScaleNameInput as p, type StyledVoicingOptions as q, type VoicingOptions as r, type VoicingStyle as s, availableTensions as t, avoidNotes as u, chordScaleReport as v, chordScales as w, maskFromOffsets as x, namedScaleMask as y, requireScaleMask as z };
@@ -1,39 +0,0 @@
1
- /**
2
- * A key/scale definition anchored on a root pitch class.
3
- *
4
- * `modeMask12` is a 12-bit mask where bit `n` set means the pitch class
5
- * `(rootPc + n) % 12` belongs to the scale. Bit 0 (the root) is always set;
6
- * {@link maskFromOffsets} enforces this so the root is always a scale tone.
7
- *
8
- * @category Core
9
- */
10
- type KeyScale = {
11
- rootPc: number;
12
- modeMask12: number;
13
- };
14
- /**
15
- * A single sounding note on a beat-indexed timeline: an absolute MIDI pitch, an
16
- * onset and duration measured in quarter-note beats, and an optional MIDI
17
- * velocity. This is the library-wide interchange shape for note events read
18
- * from or written to a DAW/MIDI track; the harmonizer's `MelodyNote` and the
19
- * analysis `VoiceNote` are specializations of it.
20
- *
21
- * @category Core
22
- */
23
- type NoteEvent = {
24
- /** MIDI pitch in [0, 127] (middle C = 60). */
25
- pitch: number;
26
- /**
27
- * Onset in quarter-note beats, absolute from the start of the timeline, and
28
- * never negative: beat 0 is the start of the music, so a pickup bar is
29
- * written as the first bar rather than as negative time. Shift the whole
30
- * timeline if the downbeat needs to land later.
31
- */
32
- startBeat: number;
33
- /** Duration in quarter-note beats. */
34
- durationBeat: number;
35
- /** MIDI velocity in [0, 127], when known. */
36
- velocity?: number;
37
- };
38
-
39
- export type { KeyScale as K, NoteEvent as N };
@@ -1,39 +0,0 @@
1
- /**
2
- * A key/scale definition anchored on a root pitch class.
3
- *
4
- * `modeMask12` is a 12-bit mask where bit `n` set means the pitch class
5
- * `(rootPc + n) % 12` belongs to the scale. Bit 0 (the root) is always set;
6
- * {@link maskFromOffsets} enforces this so the root is always a scale tone.
7
- *
8
- * @category Core
9
- */
10
- type KeyScale = {
11
- rootPc: number;
12
- modeMask12: number;
13
- };
14
- /**
15
- * A single sounding note on a beat-indexed timeline: an absolute MIDI pitch, an
16
- * onset and duration measured in quarter-note beats, and an optional MIDI
17
- * velocity. This is the library-wide interchange shape for note events read
18
- * from or written to a DAW/MIDI track; the harmonizer's `MelodyNote` and the
19
- * analysis `VoiceNote` are specializations of it.
20
- *
21
- * @category Core
22
- */
23
- type NoteEvent = {
24
- /** MIDI pitch in [0, 127] (middle C = 60). */
25
- pitch: number;
26
- /**
27
- * Onset in quarter-note beats, absolute from the start of the timeline, and
28
- * never negative: beat 0 is the start of the music, so a pickup bar is
29
- * written as the first bar rather than as negative time. Shift the whole
30
- * timeline if the downbeat needs to land later.
31
- */
32
- startBeat: number;
33
- /** Duration in quarter-note beats. */
34
- durationBeat: number;
35
- /** MIDI velocity in [0, 127], when known. */
36
- velocity?: number;
37
- };
38
-
39
- export type { KeyScale as K, NoteEvent as N };