@libraz/libcantus 0.9.2 → 0.9.4

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 (200) hide show
  1. package/README.md +6 -5
  2. package/dist/analyze/index.cjs +41 -1676
  3. package/dist/analyze/index.cjs.map +1 -1
  4. package/dist/analyze/index.d.cts +194 -122
  5. package/dist/analyze/index.d.ts +194 -122
  6. package/dist/analyze/index.js +19 -8
  7. package/dist/chunk-36N73KZ3.cjs +246 -0
  8. package/dist/chunk-36N73KZ3.cjs.map +1 -0
  9. package/dist/chunk-4HLLZPXT.cjs +3077 -0
  10. package/dist/chunk-4HLLZPXT.cjs.map +1 -0
  11. package/dist/chunk-7MGZ7D62.cjs +498 -0
  12. package/dist/chunk-7MGZ7D62.cjs.map +1 -0
  13. package/dist/{chunk-R3S2LUBH.js → chunk-7NKDPF74.js} +660 -305
  14. package/dist/chunk-7NKDPF74.js.map +1 -0
  15. package/dist/chunk-CAN76NCU.cjs +679 -0
  16. package/dist/chunk-CAN76NCU.cjs.map +1 -0
  17. package/dist/{chunk-7Y7WF64D.js → chunk-D2FAJBYL.js} +104 -35
  18. package/dist/chunk-D2FAJBYL.js.map +1 -0
  19. package/dist/{chunk-COKTX2G5.js → chunk-EHVEBWM5.js} +1052 -510
  20. package/dist/chunk-EHVEBWM5.js.map +1 -0
  21. package/dist/chunk-FCANXBAT.cjs +30 -0
  22. package/dist/chunk-FCANXBAT.cjs.map +1 -0
  23. package/dist/chunk-FNDWXRRI.cjs +479 -0
  24. package/dist/chunk-FNDWXRRI.cjs.map +1 -0
  25. package/dist/{chunk-GQKN5KDT.js → chunk-GQSGS2N4.js} +43 -29
  26. package/dist/chunk-GQSGS2N4.js.map +1 -0
  27. package/dist/chunk-HKGYCQ34.js +53 -0
  28. package/dist/chunk-HKGYCQ34.js.map +1 -0
  29. package/dist/chunk-I24MV65U.js +106 -0
  30. package/dist/chunk-I24MV65U.js.map +1 -0
  31. package/dist/{chunk-LN7ZZMD2.js → chunk-KMHOICIY.js} +322 -173
  32. package/dist/chunk-KMHOICIY.js.map +1 -0
  33. package/dist/chunk-LW53AHQU.cjs +1117 -0
  34. package/dist/chunk-LW53AHQU.cjs.map +1 -0
  35. package/dist/chunk-N6IHQUOX.js +1 -0
  36. package/dist/chunk-N6IHQUOX.js.map +1 -0
  37. package/dist/chunk-NKIBQ6PT.js +30 -0
  38. package/dist/chunk-NKIBQ6PT.js.map +1 -0
  39. package/dist/chunk-NP4NA2FB.cjs +106 -0
  40. package/dist/chunk-NP4NA2FB.cjs.map +1 -0
  41. package/dist/chunk-NVE34YGZ.cjs +1449 -0
  42. package/dist/chunk-NVE34YGZ.cjs.map +1 -0
  43. package/dist/{chunk-A4532ZFR.js → chunk-NYYWMV2C.js} +115 -47
  44. package/dist/chunk-NYYWMV2C.js.map +1 -0
  45. package/dist/{chunk-5HTNMQW4.js → chunk-Q2XUP227.js} +310 -118
  46. package/dist/chunk-Q2XUP227.js.map +1 -0
  47. package/dist/chunk-Q6OP4U43.cjs +327 -0
  48. package/dist/chunk-Q6OP4U43.cjs.map +1 -0
  49. package/dist/chunk-RC6GBMCD.cjs +845 -0
  50. package/dist/chunk-RC6GBMCD.cjs.map +1 -0
  51. package/dist/{chunk-XTC3X6MS.js → chunk-RK35RIN7.js} +453 -152
  52. package/dist/chunk-RK35RIN7.js.map +1 -0
  53. package/dist/chunk-RUMU3UA6.cjs +53 -0
  54. package/dist/chunk-RUMU3UA6.cjs.map +1 -0
  55. package/dist/chunk-T64C7ZD7.cjs +1 -0
  56. package/dist/chunk-T64C7ZD7.cjs.map +1 -0
  57. package/dist/chunk-XEBG3G53.js +498 -0
  58. package/dist/chunk-XEBG3G53.js.map +1 -0
  59. package/dist/chunk-YLEMGEFH.js +246 -0
  60. package/dist/chunk-YLEMGEFH.js.map +1 -0
  61. package/dist/chunk-ZEJR4TKL.cjs +173 -0
  62. package/dist/chunk-ZEJR4TKL.cjs.map +1 -0
  63. package/dist/core/index.cjs +130 -431
  64. package/dist/core/index.cjs.map +1 -1
  65. package/dist/core/index.d.cts +331 -17
  66. package/dist/core/index.d.ts +331 -17
  67. package/dist/core/index.js +71 -13
  68. package/dist/{function-2bJW1Zp_.d.ts → function-BtiZb9i9.d.ts} +28 -7
  69. package/dist/{function-r2sh-jOO.d.cts → function-DNugAOrt.d.cts} +28 -7
  70. package/dist/generate/index.cjs +30 -3751
  71. package/dist/generate/index.cjs.map +1 -1
  72. package/dist/generate/index.d.cts +373 -59
  73. package/dist/generate/index.d.ts +373 -59
  74. package/dist/generate/index.js +23 -9
  75. package/dist/{index-DZ1M21do.d.cts → index-6VR8-kit.d.ts} +20 -4
  76. package/dist/index-70p168VM.d.ts +192 -0
  77. package/dist/{index-D_ZTUNKp.d.cts → index-Be74mcon.d.cts} +18 -17
  78. package/dist/index-BtXT6UQ0.d.cts +192 -0
  79. package/dist/{index-BMPxwjwV.d.ts → index-C5UBbQ4G.d.ts} +18 -17
  80. package/dist/{index-BOBXBNwP.d.cts → index-C83mZI1P.d.ts} +93 -8
  81. package/dist/{index-BdeQ1r_p.d.cts → index-D6b6na69.d.cts} +14 -11
  82. package/dist/{index-Cl7mhOFM.d.cts → index-DXd9JikN.d.cts} +92 -10
  83. package/dist/{index-Cl7mhOFM.d.ts → index-DXd9JikN.d.ts} +92 -10
  84. package/dist/index-OG65ocOr.d.cts +272 -0
  85. package/dist/index-OG65ocOr.d.ts +272 -0
  86. package/dist/{index-BreoJRw0.d.ts → index-tJhkmQgE.d.cts} +20 -4
  87. package/dist/{index-CP3wAfEH.d.ts → index-tSQh-xwY.d.ts} +14 -11
  88. package/dist/{index-CM5W4rcm.d.ts → index-y_ak9_Hi.d.cts} +93 -8
  89. package/dist/index.cjs +419 -6848
  90. package/dist/index.cjs.map +1 -1
  91. package/dist/index.d.cts +14 -13
  92. package/dist/index.d.ts +14 -13
  93. package/dist/index.js +132 -27
  94. package/dist/model/index.cjs +8 -2423
  95. package/dist/model/index.cjs.map +1 -1
  96. package/dist/model/index.d.cts +433 -74
  97. package/dist/model/index.d.ts +433 -74
  98. package/dist/model/index.js +6 -7
  99. package/dist/styled-DIRkk9Uz.d.ts +506 -0
  100. package/dist/styled-DJbkJQfj.d.cts +506 -0
  101. package/dist/theory/index.cjs +172 -1676
  102. package/dist/theory/index.cjs.map +1 -1
  103. package/dist/theory/index.d.cts +151 -233
  104. package/dist/theory/index.d.ts +151 -233
  105. package/dist/theory/index.js +31 -7
  106. package/dist/{types-MGP29r3t.d.cts → types-BN6_Q9Kl.d.cts} +11 -2
  107. package/dist/{types-MGP29r3t.d.ts → types-BN6_Q9Kl.d.ts} +11 -2
  108. package/package.json +73 -24
  109. package/dist/chunk-5HTNMQW4.js.map +0 -1
  110. package/dist/chunk-7Y7WF64D.js.map +0 -1
  111. package/dist/chunk-A4532ZFR.js.map +0 -1
  112. package/dist/chunk-BHUT2S5G.js +0 -22
  113. package/dist/chunk-BHUT2S5G.js.map +0 -1
  114. package/dist/chunk-CCBLVAPK.js +0 -42
  115. package/dist/chunk-CCBLVAPK.js.map +0 -1
  116. package/dist/chunk-COKTX2G5.js.map +0 -1
  117. package/dist/chunk-DYWFNC4A.js +0 -152
  118. package/dist/chunk-DYWFNC4A.js.map +0 -1
  119. package/dist/chunk-GQKN5KDT.js.map +0 -1
  120. package/dist/chunk-LN7ZZMD2.js.map +0 -1
  121. package/dist/chunk-MSWFZF7J.js +0 -118
  122. package/dist/chunk-MSWFZF7J.js.map +0 -1
  123. package/dist/chunk-R3S2LUBH.js.map +0 -1
  124. package/dist/chunk-SDM3VJJ5.js +0 -41
  125. package/dist/chunk-SDM3VJJ5.js.map +0 -1
  126. package/dist/chunk-XTC3X6MS.js.map +0 -1
  127. package/dist/chunk-ZXW5YIWK.js +0 -55
  128. package/dist/chunk-ZXW5YIWK.js.map +0 -1
  129. package/dist/index-CGMZNCx6.d.cts +0 -140
  130. package/dist/index-CGMZNCx6.d.ts +0 -140
  131. package/dist/styled-BjXtOFNk.d.cts +0 -282
  132. package/dist/styled-D7BAx3S3.d.ts +0 -282
  133. package/src/analyze/arrange/index.ts +0 -21
  134. package/src/analyze/arrange/internal.ts +0 -125
  135. package/src/analyze/arrange/tension.ts +0 -187
  136. package/src/analyze/arrange/tracks.ts +0 -279
  137. package/src/analyze/detect/index.ts +0 -235
  138. package/src/analyze/functional/borrowed.ts +0 -84
  139. package/src/analyze/functional/cadence.ts +0 -66
  140. package/src/analyze/functional/function.ts +0 -184
  141. package/src/analyze/functional/index.ts +0 -23
  142. package/src/analyze/functional/internal.ts +0 -29
  143. package/src/analyze/functional/roman.ts +0 -393
  144. package/src/analyze/index.ts +0 -49
  145. package/src/analyze/timeline/index.ts +0 -415
  146. package/src/analyze/voice/index.ts +0 -330
  147. package/src/core/index.ts +0 -47
  148. package/src/core/interval/index.ts +0 -81
  149. package/src/core/meter/index.ts +0 -282
  150. package/src/core/pitch/index.ts +0 -311
  151. package/src/core/random/index.ts +0 -53
  152. package/src/core/tuning/index.ts +0 -156
  153. package/src/core/types.ts +0 -29
  154. package/src/generate/bass/index.ts +0 -350
  155. package/src/generate/countermelody/index.ts +0 -379
  156. package/src/generate/drums/beat.ts +0 -266
  157. package/src/generate/drums/euclid.ts +0 -58
  158. package/src/generate/drums/fills.ts +0 -356
  159. package/src/generate/drums/ghost.ts +0 -119
  160. package/src/generate/drums/hihat.ts +0 -285
  161. package/src/generate/drums/hit.ts +0 -31
  162. package/src/generate/drums/index.ts +0 -329
  163. package/src/generate/drums/internal.ts +0 -257
  164. package/src/generate/drums/kick.ts +0 -160
  165. package/src/generate/drums/percussion.ts +0 -121
  166. package/src/generate/drums/rng.ts +0 -7
  167. package/src/generate/drums/swing.ts +0 -71
  168. package/src/generate/groove/index.ts +0 -326
  169. package/src/generate/harmonize/index.ts +0 -440
  170. package/src/generate/index.ts +0 -59
  171. package/src/generate/motif/index.ts +0 -398
  172. package/src/generate/progression/index.ts +0 -370
  173. package/src/generate/reharmony/index.ts +0 -330
  174. package/src/generate/rhythm/index.ts +0 -165
  175. package/src/index.ts +0 -247
  176. package/src/model/chord.ts +0 -423
  177. package/src/model/index.ts +0 -15
  178. package/src/model/interval.ts +0 -82
  179. package/src/model/key.ts +0 -266
  180. package/src/model/note.ts +0 -176
  181. package/src/model/progression.ts +0 -161
  182. package/src/model/shared.ts +0 -12
  183. package/src/theory/chord/index.ts +0 -373
  184. package/src/theory/chordscale/index.ts +0 -374
  185. package/src/theory/counterpoint/index.ts +0 -230
  186. package/src/theory/harmony/index.ts +0 -92
  187. package/src/theory/index.ts +0 -107
  188. package/src/theory/safety/index.ts +0 -419
  189. package/src/theory/scale/degrees.ts +0 -123
  190. package/src/theory/scale/index.ts +0 -28
  191. package/src/theory/scale/key.ts +0 -56
  192. package/src/theory/scale/masks.ts +0 -153
  193. package/src/theory/spelling/index.ts +0 -182
  194. package/src/theory/symbol/index.ts +0 -268
  195. package/src/theory/voicing/index.ts +0 -5
  196. package/src/theory/voicing/internal.ts +0 -168
  197. package/src/theory/voicing/leading.ts +0 -112
  198. package/src/theory/voicing/satb.ts +0 -195
  199. package/src/theory/voicing/styled.ts +0 -176
  200. package/tsconfig.json +0 -23
@@ -1,282 +0,0 @@
1
- import { C as Chord } from './index-BOBXBNwP.cjs';
2
-
3
- /**
4
- * Test whether every chord pitch class is contained in a scale.
5
- *
6
- * @param chordPcs The chord's pitch classes (0..11).
7
- * @param scaleMask The scale's 12-bit mode mask.
8
- * @param scaleRootPc The pitch class the mask is rooted on.
9
- * @returns True if the scale is a superset of the chord.
10
- *
11
- * @category Scales
12
- */
13
- declare function scaleMatchesChord(chordPcs: number[], scaleMask: number, scaleRootPc: number): boolean;
14
- /**
15
- * A named scale rooted on a pitch class that fits over a chord.
16
- *
17
- * @category Scales
18
- */
19
- type ChordScaleMatch = {
20
- name: string;
21
- rootPc: number;
22
- };
23
- /**
24
- * List the scales that fit over a chord, best fit first.
25
- *
26
- * Only the chord root is considered as the scale root, matching the
27
- * conventional chord-scale relationship. Every entry of {@link NAMED_SCALES}
28
- * whose pitch-class set is a superset of the chord's is returned once per
29
- * distinct pitch-class set (aliased masks such as major/ionian report only the
30
- * modal name), ranked by fewest extra scale tones beyond the chord, then by
31
- * scale size (heptatonic before larger scales), then by scale name. For bare
32
- * triads and smaller chords, heptatonic scales rank before pentatonics and
33
- * other sizes: a pentatonic adds no modal color over a triad, so the seven-note
34
- * modes are the more useful answer. The chromatic scale is only returned as a
35
- * fallback when no other scale contains the chord.
36
- *
37
- * @param chord The chord to fit scales over.
38
- * @returns The matching scales rooted on the chord root, best fit first.
39
- *
40
- * @example
41
- * ```ts
42
- * import { makeChord, chordScales } from '@libraz/libcantus';
43
- * const scales = chordScales(makeChord(0, 'maj7'));
44
- * // scales for Cmaj7, best fit first; each is { name, rootPc: 0 }
45
- * ```
46
- *
47
- * @category Scales
48
- */
49
- declare function chordScales(chord: Chord): ChordScaleMatch[];
50
- /**
51
- * List a scale's avoid notes over a chord.
52
- *
53
- * An avoid note is a non-chord scale tone that lies a semitone directly above a
54
- * chord tone; sounding it against the chord clashes. The scale is rooted on the
55
- * chord root. If the scale does not contain the chord, no avoid notes exist.
56
- *
57
- * @param chord The chord providing the chord tones.
58
- * @param scaleName A key of {@link NAMED_SCALES}.
59
- * @returns The avoid-note pitch classes, sorted ascending in [0, 11].
60
- *
61
- * @category Scales
62
- */
63
- declare function avoidNotes(chord: Chord, scaleName: string): number[];
64
- /**
65
- * List a scale's available tensions over a chord.
66
- *
67
- * Available tensions are scale tones that are neither chord tones nor avoid
68
- * notes, i.e. the usable color tones (typically the 9/11/13 region). The scale
69
- * is rooted on the chord root. If the scale does not contain the chord, there
70
- * are no available tensions.
71
- *
72
- * @param chord The chord providing the chord tones.
73
- * @param scaleName A key of {@link NAMED_SCALES}.
74
- * @returns The available-tension pitch classes, sorted ascending in [0, 11].
75
- *
76
- * @example
77
- * ```ts
78
- * import { makeChord, availableTensions } from '@libraz/libcantus';
79
- * availableTensions(makeChord(0, 'maj7'), 'ionian'); // [2, 9] — color tones over Cmaj7
80
- * ```
81
- *
82
- * @category Scales
83
- */
84
- declare function availableTensions(chord: Chord, scaleName: string): number[];
85
- /**
86
- * A scale fit over a chord together with its avoid notes and tensions.
87
- *
88
- * @category Scales
89
- */
90
- type ChordScaleReportEntry = {
91
- name: string;
92
- rootPc: number;
93
- avoid: number[];
94
- tensions: number[];
95
- };
96
- /**
97
- * Report the best-fitting scales for a chord with their avoid notes and tensions.
98
- *
99
- * Combines {@link chordScales}, {@link avoidNotes}, and {@link availableTensions}
100
- * into a single ergonomic result, ordered best fit first.
101
- *
102
- * @param chord The chord to analyze.
103
- * @param limit Optional maximum number of scales to report; all by default.
104
- * @returns One entry per reported scale, best fit first.
105
- *
106
- * @category Scales
107
- */
108
- declare function chordScaleReport(chord: Chord, limit?: number): ChordScaleReportEntry[];
109
- /**
110
- * A chord paired with the scale chosen for it by {@link scalesForChanges}.
111
- *
112
- * @category Scales
113
- */
114
- type ScaleChoice = {
115
- chord: Chord;
116
- scale: ChordScaleMatch;
117
- };
118
- /**
119
- * Choose one scale per chord across a progression, favoring continuity.
120
- *
121
- * Each chord's {@link chordScales} candidates form a stage in a Viterbi-style
122
- * dynamic program. The transition cost between adjacent choices is the number
123
- * of pitch classes that differ between their pitch-class sets (the symmetric
124
- * difference), plus a small penalty for straying from a chord's best-fit scale
125
- * so that ties break toward the tighter fit. The minimum-total-cost path is
126
- * returned, one {@link ScaleChoice} per input chord in the original order.
127
- *
128
- * @param chords The chord sequence to choose scales for.
129
- * @returns One scale choice per chord, in input order.
130
- *
131
- * @category Scales
132
- */
133
- declare function scalesForChanges(chords: Chord[]): ScaleChoice[];
134
-
135
- /**
136
- * An inclusive MIDI pitch range for a single voice.
137
- *
138
- * @category Voicing & Counterpoint
139
- */
140
- type VoiceRange = {
141
- min: number;
142
- max: number;
143
- };
144
- /**
145
- * Default four-voice SATB ranges, ascending (index 0 = lowest):
146
- * bass E2–C4 (40–60), tenor C3–G4 (48–67), alto G3–D5 (55–74),
147
- * soprano C4–G5 (60–79).
148
- *
149
- * @category Voicing & Counterpoint
150
- */
151
- declare const SATB_RANGES: readonly VoiceRange[];
152
- /**
153
- * Options controlling {@link voiceChord} and {@link voiceProgression}.
154
- *
155
- * @category Voicing & Counterpoint
156
- */
157
- type VoicingOptions = {
158
- /**
159
- * Number of voices to realize. Ignored when `ranges` is given.
160
- *
161
- * @defaultValue 4
162
- */
163
- voices?: number;
164
- /** Explicit per-voice ranges, ascending (index 0 = lowest). Takes precedence over `voices`. */
165
- ranges?: VoiceRange[];
166
- /**
167
- * Maximum spacing in semitones between adjacent upper voices.
168
- *
169
- * @defaultValue 12
170
- */
171
- maxSpacing?: number;
172
- };
173
- /**
174
- * Realize a single chord as one MIDI pitch per voice, ascending (index 0 =
175
- * lowest). The bass voice takes the chord's `bassPc` when set, otherwise the
176
- * root; upper voices take chord pitch classes, doubling the root or fifth as
177
- * needed to fill all voices. The result stays inside each voice's range, keeps
178
- * adjacent upper voices within `maxSpacing`, avoids voice crossing, and is
179
- * deterministic: a compact close-position voicing centered in the ranges.
180
- *
181
- * @param chord The chord to voice.
182
- * @param opts Voicing options; defaults to four voices in {@link SATB_RANGES}.
183
- * @returns MIDI pitches, ascending, one per voice.
184
- * @throws If no voicing fits the given ranges.
185
- * @example
186
- * ```ts
187
- * import { parseChordSymbol, voiceChord } from '@libraz/libcantus';
188
- * const chord = parseChordSymbol('Cmaj7');
189
- * voiceChord(chord); // four ascending MIDI pitches within the SATB ranges
190
- * ```
191
- * @category Voicing & Counterpoint
192
- */
193
- declare function voiceChord(chord: Chord, opts?: VoicingOptions): number[];
194
- /**
195
- * Voice a chord progression with smooth voice leading. The first chord is
196
- * voiced with {@link voiceChord}; each subsequent chord picks, from a bounded
197
- * deterministic candidate set, the voicing minimizing the voice-leading cost
198
- * from the previous voicing plus a large penalty per counterpoint violation
199
- * (parallel perfects/octaves, voice crossing, voice overlap, and over-wide
200
- * upper-voice spacing).
201
- *
202
- * @param chords The chords to voice in order.
203
- * @param opts Voicing options; defaults to four voices in {@link SATB_RANGES}.
204
- * @returns One voicing per chord, each ascending with one MIDI pitch per voice.
205
- * @throws If any chord admits no voicing within the given ranges.
206
- * @example
207
- * ```ts
208
- * import { parseChordSymbol, voiceProgression } from '@libraz/libcantus';
209
- * const chords = ['C', 'Am', 'F', 'G'].map((s) => parseChordSymbol(s));
210
- * voiceProgression(chords); // one four-voice voicing per chord, smoothly led
211
- * ```
212
- * @category Voicing & Counterpoint
213
- */
214
- declare function voiceProgression(chords: Chord[], opts?: VoicingOptions): number[][];
215
-
216
- /**
217
- * A tertian voicing style for {@link voiceChordStyled}.
218
- *
219
- * - `close`: the plain close-position tertian stack.
220
- * - `drop2`: the second voice from the top dropped an octave (drop-2 voicing).
221
- * - `drop3`: the third voice from the top dropped an octave (drop-3 voicing).
222
- * - `shell`: root plus guide tones (third and seventh) for seventh chords, or
223
- * root/third/fifth for triads; the fifth and tensions are omitted.
224
- * - `rootless`: the root omitted, keeping third/fifth/seventh and tensions
225
- * (a typical left-hand jazz voicing).
226
- *
227
- * @category Voicing & Counterpoint
228
- */
229
- type VoicingStyle = 'close' | 'drop2' | 'drop3' | 'shell' | 'rootless';
230
- /**
231
- * Options controlling {@link voiceChordStyled}.
232
- *
233
- * @category Voicing & Counterpoint
234
- */
235
- type StyledVoicingOptions = {
236
- /**
237
- * Voicing style to build.
238
- *
239
- * @defaultValue 'close'
240
- */
241
- style?: VoicingStyle;
242
- /** Constrain the highest voice to this pitch class (0..11) when given. */
243
- topNote?: number;
244
- /**
245
- * Base octave for the close stack; the stack begins near `12 * octave`.
246
- *
247
- * @defaultValue 4
248
- */
249
- octave?: number;
250
- /**
251
- * Omit the root regardless of style (relevant for jazz voicings).
252
- *
253
- * @defaultValue false
254
- */
255
- rootless?: boolean;
256
- };
257
- /**
258
- * Realize a single chord as an explicit tertian voicing in a chosen style,
259
- * independent of the SATB range search used by {@link voiceChord}.
260
- *
261
- * The chord tones are stacked in close position from the bass (`bassPc`, else
262
- * `rootPc`) in the given scientific-pitch `octave` upward (octave 4 starts the
263
- * bass near C4 = MIDI 60, matching {@link midiToNote} and the bass module).
264
- * When `topNote` is given the stack is rotated so the highest voice's pitch
265
- * class equals that note (or the nearest chord tone). The chosen
266
- * {@link VoicingStyle} then transforms the stack, and the result is returned as
267
- * ascending MIDI pitches (index 0 = lowest).
268
- *
269
- * @param chord The chord to voice.
270
- * @param opts Styled voicing options; defaults to a close voicing at octave 4.
271
- * @returns MIDI pitches, ascending, one per retained voice.
272
- * @example
273
- * ```ts
274
- * import { parseChordSymbol, voiceChordStyled } from '@libraz/libcantus';
275
- * const chord = parseChordSymbol('Dm7');
276
- * voiceChordStyled(chord, { style: 'drop2' }); // ascending MIDI pitches, drop-2 voicing
277
- * ```
278
- * @category Voicing & Counterpoint
279
- */
280
- declare function voiceChordStyled(chord: Chord, opts?: StyledVoicingOptions): number[];
281
-
282
- export { type ChordScaleMatch as C, SATB_RANGES as S, type VoiceRange as V, type ChordScaleReportEntry as a, type ScaleChoice as b, type StyledVoicingOptions as c, type VoicingOptions as d, type VoicingStyle as e, availableTensions as f, avoidNotes as g, chordScaleReport as h, chordScales as i, scalesForChanges as j, voiceChordStyled as k, voiceProgression as l, scaleMatchesChord as s, voiceChord as v };
@@ -1,282 +0,0 @@
1
- import { C as Chord } from './index-CM5W4rcm.js';
2
-
3
- /**
4
- * Test whether every chord pitch class is contained in a scale.
5
- *
6
- * @param chordPcs The chord's pitch classes (0..11).
7
- * @param scaleMask The scale's 12-bit mode mask.
8
- * @param scaleRootPc The pitch class the mask is rooted on.
9
- * @returns True if the scale is a superset of the chord.
10
- *
11
- * @category Scales
12
- */
13
- declare function scaleMatchesChord(chordPcs: number[], scaleMask: number, scaleRootPc: number): boolean;
14
- /**
15
- * A named scale rooted on a pitch class that fits over a chord.
16
- *
17
- * @category Scales
18
- */
19
- type ChordScaleMatch = {
20
- name: string;
21
- rootPc: number;
22
- };
23
- /**
24
- * List the scales that fit over a chord, best fit first.
25
- *
26
- * Only the chord root is considered as the scale root, matching the
27
- * conventional chord-scale relationship. Every entry of {@link NAMED_SCALES}
28
- * whose pitch-class set is a superset of the chord's is returned once per
29
- * distinct pitch-class set (aliased masks such as major/ionian report only the
30
- * modal name), ranked by fewest extra scale tones beyond the chord, then by
31
- * scale size (heptatonic before larger scales), then by scale name. For bare
32
- * triads and smaller chords, heptatonic scales rank before pentatonics and
33
- * other sizes: a pentatonic adds no modal color over a triad, so the seven-note
34
- * modes are the more useful answer. The chromatic scale is only returned as a
35
- * fallback when no other scale contains the chord.
36
- *
37
- * @param chord The chord to fit scales over.
38
- * @returns The matching scales rooted on the chord root, best fit first.
39
- *
40
- * @example
41
- * ```ts
42
- * import { makeChord, chordScales } from '@libraz/libcantus';
43
- * const scales = chordScales(makeChord(0, 'maj7'));
44
- * // scales for Cmaj7, best fit first; each is { name, rootPc: 0 }
45
- * ```
46
- *
47
- * @category Scales
48
- */
49
- declare function chordScales(chord: Chord): ChordScaleMatch[];
50
- /**
51
- * List a scale's avoid notes over a chord.
52
- *
53
- * An avoid note is a non-chord scale tone that lies a semitone directly above a
54
- * chord tone; sounding it against the chord clashes. The scale is rooted on the
55
- * chord root. If the scale does not contain the chord, no avoid notes exist.
56
- *
57
- * @param chord The chord providing the chord tones.
58
- * @param scaleName A key of {@link NAMED_SCALES}.
59
- * @returns The avoid-note pitch classes, sorted ascending in [0, 11].
60
- *
61
- * @category Scales
62
- */
63
- declare function avoidNotes(chord: Chord, scaleName: string): number[];
64
- /**
65
- * List a scale's available tensions over a chord.
66
- *
67
- * Available tensions are scale tones that are neither chord tones nor avoid
68
- * notes, i.e. the usable color tones (typically the 9/11/13 region). The scale
69
- * is rooted on the chord root. If the scale does not contain the chord, there
70
- * are no available tensions.
71
- *
72
- * @param chord The chord providing the chord tones.
73
- * @param scaleName A key of {@link NAMED_SCALES}.
74
- * @returns The available-tension pitch classes, sorted ascending in [0, 11].
75
- *
76
- * @example
77
- * ```ts
78
- * import { makeChord, availableTensions } from '@libraz/libcantus';
79
- * availableTensions(makeChord(0, 'maj7'), 'ionian'); // [2, 9] — color tones over Cmaj7
80
- * ```
81
- *
82
- * @category Scales
83
- */
84
- declare function availableTensions(chord: Chord, scaleName: string): number[];
85
- /**
86
- * A scale fit over a chord together with its avoid notes and tensions.
87
- *
88
- * @category Scales
89
- */
90
- type ChordScaleReportEntry = {
91
- name: string;
92
- rootPc: number;
93
- avoid: number[];
94
- tensions: number[];
95
- };
96
- /**
97
- * Report the best-fitting scales for a chord with their avoid notes and tensions.
98
- *
99
- * Combines {@link chordScales}, {@link avoidNotes}, and {@link availableTensions}
100
- * into a single ergonomic result, ordered best fit first.
101
- *
102
- * @param chord The chord to analyze.
103
- * @param limit Optional maximum number of scales to report; all by default.
104
- * @returns One entry per reported scale, best fit first.
105
- *
106
- * @category Scales
107
- */
108
- declare function chordScaleReport(chord: Chord, limit?: number): ChordScaleReportEntry[];
109
- /**
110
- * A chord paired with the scale chosen for it by {@link scalesForChanges}.
111
- *
112
- * @category Scales
113
- */
114
- type ScaleChoice = {
115
- chord: Chord;
116
- scale: ChordScaleMatch;
117
- };
118
- /**
119
- * Choose one scale per chord across a progression, favoring continuity.
120
- *
121
- * Each chord's {@link chordScales} candidates form a stage in a Viterbi-style
122
- * dynamic program. The transition cost between adjacent choices is the number
123
- * of pitch classes that differ between their pitch-class sets (the symmetric
124
- * difference), plus a small penalty for straying from a chord's best-fit scale
125
- * so that ties break toward the tighter fit. The minimum-total-cost path is
126
- * returned, one {@link ScaleChoice} per input chord in the original order.
127
- *
128
- * @param chords The chord sequence to choose scales for.
129
- * @returns One scale choice per chord, in input order.
130
- *
131
- * @category Scales
132
- */
133
- declare function scalesForChanges(chords: Chord[]): ScaleChoice[];
134
-
135
- /**
136
- * An inclusive MIDI pitch range for a single voice.
137
- *
138
- * @category Voicing & Counterpoint
139
- */
140
- type VoiceRange = {
141
- min: number;
142
- max: number;
143
- };
144
- /**
145
- * Default four-voice SATB ranges, ascending (index 0 = lowest):
146
- * bass E2–C4 (40–60), tenor C3–G4 (48–67), alto G3–D5 (55–74),
147
- * soprano C4–G5 (60–79).
148
- *
149
- * @category Voicing & Counterpoint
150
- */
151
- declare const SATB_RANGES: readonly VoiceRange[];
152
- /**
153
- * Options controlling {@link voiceChord} and {@link voiceProgression}.
154
- *
155
- * @category Voicing & Counterpoint
156
- */
157
- type VoicingOptions = {
158
- /**
159
- * Number of voices to realize. Ignored when `ranges` is given.
160
- *
161
- * @defaultValue 4
162
- */
163
- voices?: number;
164
- /** Explicit per-voice ranges, ascending (index 0 = lowest). Takes precedence over `voices`. */
165
- ranges?: VoiceRange[];
166
- /**
167
- * Maximum spacing in semitones between adjacent upper voices.
168
- *
169
- * @defaultValue 12
170
- */
171
- maxSpacing?: number;
172
- };
173
- /**
174
- * Realize a single chord as one MIDI pitch per voice, ascending (index 0 =
175
- * lowest). The bass voice takes the chord's `bassPc` when set, otherwise the
176
- * root; upper voices take chord pitch classes, doubling the root or fifth as
177
- * needed to fill all voices. The result stays inside each voice's range, keeps
178
- * adjacent upper voices within `maxSpacing`, avoids voice crossing, and is
179
- * deterministic: a compact close-position voicing centered in the ranges.
180
- *
181
- * @param chord The chord to voice.
182
- * @param opts Voicing options; defaults to four voices in {@link SATB_RANGES}.
183
- * @returns MIDI pitches, ascending, one per voice.
184
- * @throws If no voicing fits the given ranges.
185
- * @example
186
- * ```ts
187
- * import { parseChordSymbol, voiceChord } from '@libraz/libcantus';
188
- * const chord = parseChordSymbol('Cmaj7');
189
- * voiceChord(chord); // four ascending MIDI pitches within the SATB ranges
190
- * ```
191
- * @category Voicing & Counterpoint
192
- */
193
- declare function voiceChord(chord: Chord, opts?: VoicingOptions): number[];
194
- /**
195
- * Voice a chord progression with smooth voice leading. The first chord is
196
- * voiced with {@link voiceChord}; each subsequent chord picks, from a bounded
197
- * deterministic candidate set, the voicing minimizing the voice-leading cost
198
- * from the previous voicing plus a large penalty per counterpoint violation
199
- * (parallel perfects/octaves, voice crossing, voice overlap, and over-wide
200
- * upper-voice spacing).
201
- *
202
- * @param chords The chords to voice in order.
203
- * @param opts Voicing options; defaults to four voices in {@link SATB_RANGES}.
204
- * @returns One voicing per chord, each ascending with one MIDI pitch per voice.
205
- * @throws If any chord admits no voicing within the given ranges.
206
- * @example
207
- * ```ts
208
- * import { parseChordSymbol, voiceProgression } from '@libraz/libcantus';
209
- * const chords = ['C', 'Am', 'F', 'G'].map((s) => parseChordSymbol(s));
210
- * voiceProgression(chords); // one four-voice voicing per chord, smoothly led
211
- * ```
212
- * @category Voicing & Counterpoint
213
- */
214
- declare function voiceProgression(chords: Chord[], opts?: VoicingOptions): number[][];
215
-
216
- /**
217
- * A tertian voicing style for {@link voiceChordStyled}.
218
- *
219
- * - `close`: the plain close-position tertian stack.
220
- * - `drop2`: the second voice from the top dropped an octave (drop-2 voicing).
221
- * - `drop3`: the third voice from the top dropped an octave (drop-3 voicing).
222
- * - `shell`: root plus guide tones (third and seventh) for seventh chords, or
223
- * root/third/fifth for triads; the fifth and tensions are omitted.
224
- * - `rootless`: the root omitted, keeping third/fifth/seventh and tensions
225
- * (a typical left-hand jazz voicing).
226
- *
227
- * @category Voicing & Counterpoint
228
- */
229
- type VoicingStyle = 'close' | 'drop2' | 'drop3' | 'shell' | 'rootless';
230
- /**
231
- * Options controlling {@link voiceChordStyled}.
232
- *
233
- * @category Voicing & Counterpoint
234
- */
235
- type StyledVoicingOptions = {
236
- /**
237
- * Voicing style to build.
238
- *
239
- * @defaultValue 'close'
240
- */
241
- style?: VoicingStyle;
242
- /** Constrain the highest voice to this pitch class (0..11) when given. */
243
- topNote?: number;
244
- /**
245
- * Base octave for the close stack; the stack begins near `12 * octave`.
246
- *
247
- * @defaultValue 4
248
- */
249
- octave?: number;
250
- /**
251
- * Omit the root regardless of style (relevant for jazz voicings).
252
- *
253
- * @defaultValue false
254
- */
255
- rootless?: boolean;
256
- };
257
- /**
258
- * Realize a single chord as an explicit tertian voicing in a chosen style,
259
- * independent of the SATB range search used by {@link voiceChord}.
260
- *
261
- * The chord tones are stacked in close position from the bass (`bassPc`, else
262
- * `rootPc`) in the given scientific-pitch `octave` upward (octave 4 starts the
263
- * bass near C4 = MIDI 60, matching {@link midiToNote} and the bass module).
264
- * When `topNote` is given the stack is rotated so the highest voice's pitch
265
- * class equals that note (or the nearest chord tone). The chosen
266
- * {@link VoicingStyle} then transforms the stack, and the result is returned as
267
- * ascending MIDI pitches (index 0 = lowest).
268
- *
269
- * @param chord The chord to voice.
270
- * @param opts Styled voicing options; defaults to a close voicing at octave 4.
271
- * @returns MIDI pitches, ascending, one per retained voice.
272
- * @example
273
- * ```ts
274
- * import { parseChordSymbol, voiceChordStyled } from '@libraz/libcantus';
275
- * const chord = parseChordSymbol('Dm7');
276
- * voiceChordStyled(chord, { style: 'drop2' }); // ascending MIDI pitches, drop-2 voicing
277
- * ```
278
- * @category Voicing & Counterpoint
279
- */
280
- declare function voiceChordStyled(chord: Chord, opts?: StyledVoicingOptions): number[];
281
-
282
- export { type ChordScaleMatch as C, SATB_RANGES as S, type VoiceRange as V, type ChordScaleReportEntry as a, type ScaleChoice as b, type StyledVoicingOptions as c, type VoicingOptions as d, type VoicingStyle as e, availableTensions as f, avoidNotes as g, chordScaleReport as h, chordScales as i, scalesForChanges as j, voiceChordStyled as k, voiceProgression as l, scaleMatchesChord as s, voiceChord as v };
@@ -1,21 +0,0 @@
1
- /**
2
- * Arrangement analysis: the capstone that ties the timeline, per-voice analysis,
3
- * functional harmony, and safety modules together for a whole multi-track piece.
4
- *
5
- * A chord timeline and key are inferred once from every track's notes pooled
6
- * together; each track is then analysed against that shared harmony, notes that
7
- * clash with the sounding chord are collected as conflicts, and a coarse tension
8
- * curve is sampled across the piece.
9
- */
10
-
11
- export type { TensionPoint } from './tension.js';
12
- export { tensionCurve } from './tension.js';
13
- export type {
14
- ArrangementAnalysis,
15
- ArrangementOptions,
16
- ArrangementTrack,
17
- Conflict,
18
- TrackAnalysis,
19
- TrackRole,
20
- } from './tracks.js';
21
- export { analyzeArrangement } from './tracks.js';