@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,9 +1,10 @@
1
- import { T as TimeSignature } from '../index-Cl7mhOFM.js';
2
- import { K as KeyScale, N as NoteEvent } from '../types-MGP29r3t.js';
3
- import { C as Chord, a as ChordQuality, b as ChordSpan } from '../index-CM5W4rcm.js';
4
- import { H as HarmonyRole } from '../index-CP3wAfEH.js';
5
- import { b as ChordTimeline } from '../index-BMPxwjwV.js';
6
- import { B as BorrowedSource, H as HarmonicFunction } from '../function-2bJW1Zp_.js';
1
+ import { B as BorrowedSource, H as HarmonicFunction } from '../function-BtiZb9i9.js';
2
+ import { K as KeyScale, N as NoteEvent } from '../types-BN6_Q9Kl.js';
3
+ import { b as ChordSegment, C as Chord, a as ChordQuality, c as ChordSpan } from '../index-C83mZI1P.js';
4
+ export { d as ChordToneRole, P as PitchSpelling } from '../index-C83mZI1P.js';
5
+ import { a as ChordTimeline } from '../index-C5UBbQ4G.js';
6
+ import { T as TimeSignature } from '../index-DXd9JikN.js';
7
+ import { H as HarmonyRole } from '../index-tSQh-xwY.js';
7
8
 
8
9
  /**
9
10
  * Deterministic bass-line generation over a chord placement.
@@ -22,19 +23,24 @@ import { B as BorrowedSource, H as HarmonicFunction } from '../function-2bJW1Zp_
22
23
  /**
23
24
  * A chord sounding over a half-open beat span `[startBeat, endBeat)`.
24
25
  *
26
+ * The same record {@link ChordSegment} names, so a timeline segment can be fed
27
+ * straight to the bass generator.
28
+ *
25
29
  * @category Composition
26
30
  */
27
- type BassSegment = {
28
- startBeat: number;
29
- endBeat: number;
30
- chord: Chord;
31
- };
31
+ type BassSegment = ChordSegment;
32
+ /**
33
+ * Every bass-line idiom, in declaration order.
34
+ *
35
+ * @category Composition
36
+ */
37
+ declare const BASS_STYLES: readonly ["root", "rootFifth", "pop", "walking", "arpeggio"];
32
38
  /**
33
39
  * The bass-line idiom to generate.
34
40
  *
35
41
  * @category Composition
36
42
  */
37
- type BassStyle = 'root' | 'rootFifth' | 'pop' | 'walking' | 'arpeggio';
43
+ type BassStyle = (typeof BASS_STYLES)[number];
38
44
  /**
39
45
  * Options controlling {@link generateBassLine}.
40
46
  *
@@ -42,7 +48,7 @@ type BassStyle = 'root' | 'rootFifth' | 'pop' | 'walking' | 'arpeggio';
42
48
  */
43
49
  type BassLineOptions = {
44
50
  /** Chord placement to follow; need not be pre-sorted. */
45
- segments: BassSegment[];
51
+ segments: readonly BassSegment[];
46
52
  /** Key/scale context, used for diatonic approach tones in `walking`. */
47
53
  key: KeyScale;
48
54
  /**
@@ -59,6 +65,8 @@ type BassLineOptions = {
59
65
  style?: BassStyle;
60
66
  /**
61
67
  * Target register as a base MIDI octave; roots land around `octave*12+12`.
68
+ * An octave pickup in the `pop` style may drop a note into the octave below
69
+ * that band, which is where such a pickup belongs.
62
70
  *
63
71
  * @defaultValue 2
64
72
  */
@@ -102,9 +110,30 @@ declare function generateBassLine(opts: BassLineOptions): NoteEvent[];
102
110
  */
103
111
  type CounterMelodyOptions = {
104
112
  /** The lead line to write against, in ascending onset order. */
105
- melody: NoteEvent[];
106
- /** Chord sounding at an absolute beat position, or null when none applies. */
107
- chordAt: (beat: number) => Chord | null;
113
+ melody: readonly NoteEvent[];
114
+ /**
115
+ * The harmony to write against. A timeline carries its own segment
116
+ * boundaries, so a chord change anywhere — including off the generator's
117
+ * half-beat probe grid — is seen; prefer it over `chordAt`.
118
+ *
119
+ * Exactly one of `timeline` and `chordAt` is required; `timeline` wins when
120
+ * both are given.
121
+ */
122
+ timeline?: ChordTimeline;
123
+ /**
124
+ * Chord sounding at an absolute beat position, or null when none applies.
125
+ *
126
+ * A callback is opaque: the generator cannot see where it changes, so it
127
+ * probes a half-beat grid and otherwise relies on `chordChangeBeats`. A held
128
+ * counter note that spans an unseen change is not checked against the new
129
+ * chord.
130
+ */
131
+ chordAt?: (beat: number) => Chord | null;
132
+ /**
133
+ * Exact chord-change beats the `chordAt` callback does not expose. Ignored
134
+ * when `timeline` is given, since a timeline lists its own boundaries.
135
+ */
136
+ chordChangeBeats?: number[];
108
137
  /** Key/scale context for scale-tone decisions. */
109
138
  key: KeyScale;
110
139
  /**
@@ -137,7 +166,11 @@ type CounterMelodyOptions = {
137
166
  /** Highest MIDI pitch the counter line may use (default derived from `register`). */
138
167
  pitchHigh?: number;
139
168
  /**
140
- * PRNG seed; the same seed always yields the same line.
169
+ * PRNG seed. It places the `'complement'` onsets and breaks ties between
170
+ * equally good candidate pitches; the same seed always yields the same line.
171
+ * Where the constraints leave only one good answer — which is common with
172
+ * `rhythm: 'follow'`, whose onsets are fixed by the melody — changing the seed
173
+ * changes nothing.
141
174
  *
142
175
  * @defaultValue 0
143
176
  */
@@ -153,8 +186,10 @@ type CounterMelodyOptions = {
153
186
  * consonant tensions against the sounding melody note), rejecting candidates
154
187
  * that would form a parallel perfect interval with the melody or sit on the
155
188
  * wrong side of it, then scored to favour contrary or oblique motion, imperfect
156
- * consonance, and stepwise movement. Ties break toward the lower pitch, so a
157
- * given seed always yields the same line. Notes extend to the next counter
189
+ * consonance, and stepwise movement. Ties are broken by a seeded perturbation far
190
+ * below any real score difference (see `TIE_BREAK_JITTER`), so the same
191
+ * seed always yields the same line while a different seed can only reshuffle
192
+ * candidates that were already equally good. Notes extend to the next counter
158
193
  * onset (the last to the melody's end) at a velocity slightly under the melody.
159
194
  *
160
195
  * @param opts The lead line, chord context callback, key, and generation knobs.
@@ -173,22 +208,92 @@ type CounterMelodyOptions = {
173
208
  */
174
209
  declare function generateCounterMelody(opts: CounterMelodyOptions): NoteEvent[];
175
210
 
176
- /** A single percussion onset. */
211
+ /**
212
+ * The percussion voices the generator emits, as General MIDI note numbers.
213
+ *
214
+ * A {@link DrumHit} carries only its pitch, so splitting a kit across tracks —
215
+ * kick to one, snare to another — means comparing against these numbers. They
216
+ * are published so that comparison is a named constant covered by semver
217
+ * rather than a hard-coded 36.
218
+ *
219
+ * @example
220
+ * ```ts
221
+ * import { DRUM_NOTES, generateDrums } from '@libraz/libcantus';
222
+ * const hits = generateDrums({ bars: 1, bpm: 120, style: 'standard', section: 'verse', density: 0.5 });
223
+ * const kick = hits.filter((hit) => hit.pitch === DRUM_NOTES.kick);
224
+ * ```
225
+ * @category Composition
226
+ */
227
+ declare const DRUM_NOTES: {
228
+ readonly kick: 36;
229
+ readonly snare: 38;
230
+ readonly sideStick: 37;
231
+ readonly handClap: 39;
232
+ readonly closedHiHat: 42;
233
+ readonly pedalHiHat: 44;
234
+ readonly openHiHat: 46;
235
+ readonly crash: 49;
236
+ readonly ride: 51;
237
+ readonly tambourine: 54;
238
+ readonly highTom: 50;
239
+ readonly midTom: 47;
240
+ readonly lowTom: 45;
241
+ readonly shaker: 82;
242
+ };
243
+ /**
244
+ * A percussion voice name, one key of {@link DRUM_NOTES}.
245
+ *
246
+ * @category Composition
247
+ */
248
+ type DrumVoice = keyof typeof DRUM_NOTES;
249
+ /**
250
+ * The voice a percussion note number names.
251
+ *
252
+ * @param pitch The General MIDI note number.
253
+ * @returns The voice, or undefined for a note this generator never emits.
254
+ * @category Composition
255
+ */
256
+ declare function drumVoiceOf(pitch: number): DrumVoice | undefined;
257
+ /**
258
+ * A single percussion onset.
259
+ *
260
+ * @category Composition
261
+ */
177
262
  type DrumHit = {
263
+ /** General MIDI note number; {@link drumVoiceOf} names it. */
178
264
  pitch: number;
179
265
  startBeat: number;
180
266
  durationBeat: number;
181
267
  velocity: number;
182
268
  };
183
269
 
270
+ /** Every groove feel, in declaration order. */
271
+ declare const DRUM_FEELS: readonly ["straight", "swing", "shuffle"];
184
272
  /** Groove feel controlling off-beat swing. */
185
- type Feel = 'straight' | 'swing' | 'shuffle';
186
- /** Public groove style identifiers. */
187
- type GrooveStyle = 'standard' | 'funk' | 'shuffle' | 'bossa' | 'trap' | 'halftime' | 'breakbeat' | 'house' | 'synthpop';
188
- /** Public role identifiers gating which voices are present. */
189
- type DrumRole = 'full' | 'ambient' | 'minimal' | 'fxOnly';
273
+ type Feel = (typeof DRUM_FEELS)[number];
274
+ /**
275
+ * Every public groove style, in declaration order. The type is derived from
276
+ * this list so the runtime guard and the type can never disagree.
277
+ */
278
+ declare const GROOVE_STYLES: readonly ["standard", "funk", "shuffle", "bossa", "trap", "halftime", "breakbeat", "house", "synthpop"];
279
+ /**
280
+ * Public groove style identifiers.
281
+ *
282
+ * @category Composition
283
+ */
284
+ type GrooveStyle = (typeof GROOVE_STYLES)[number];
285
+ /** Every public role, in declaration order. */
286
+ declare const DRUM_ROLES: readonly ["full", "ambient", "minimal", "fxOnly"];
287
+ /**
288
+ * Public role identifiers gating which voices are present.
289
+ *
290
+ * @category Composition
291
+ */
292
+ type DrumRole = (typeof DRUM_ROLES)[number];
293
+ /** Every public section, in declaration order. */
294
+ declare const PUBLIC_SECTIONS: readonly ["intro", "verse", "prechorus", "chorus", "bridge", "outro"];
190
295
  /** Public section identifiers. */
191
- type PublicSection = 'intro' | 'verse' | 'prechorus' | 'chorus' | 'bridge' | 'outro';
296
+ type PublicSection = (typeof PUBLIC_SECTIONS)[number];
192
297
 
193
298
  /**
194
299
  * Groove feel (the swing/straight rhythmic character) for {@link generateDrums}.
@@ -230,6 +335,12 @@ type EuclideanKick = {
230
335
  * @category Composition
231
336
  */
232
337
  type DrumsOptions = {
338
+ /**
339
+ * Number of bars to generate. Bars are four quarter-note beats long: the
340
+ * patterns are written for 4/4 and there is no meter option, so a `bars`
341
+ * count shared with a meter-aware generator such as
342
+ * {@link generateRhythm} only lines up when that generator is also in 4/4.
343
+ */
233
344
  bars: number;
234
345
  bpm: number;
235
346
  style: GrooveStyle;
@@ -238,12 +349,26 @@ type DrumsOptions = {
238
349
  /**
239
350
  * Replace the final bar with a fill.
240
351
  *
352
+ * A pre-chorus leading into a chorus builds instead: the two-bar lift takes
353
+ * precedence over the fill, since the buildup already marks the phrase end.
354
+ * Set `nextSection` to anything but `'chorus'` to get the fill.
355
+ *
241
356
  * @defaultValue false
242
357
  */
243
358
  fills?: boolean;
244
359
  feel?: GrooveFeel;
245
360
  /**
246
- * Voicing role; `'fxOnly'` suppresses the main kick/snare/ghost/fill voices.
361
+ * Voicing role, from busiest to sparsest:
362
+ *
363
+ * - `'full'`: every voice, backbeat snare at full weight.
364
+ * - `'ambient'`: side-stick backbeat, ride instead of hi-hat.
365
+ * - `'minimal'`: side-stick backbeat quieter still, pedal hi-hat, no
366
+ * auxiliary percussion.
367
+ * - `'fxOnly'`: no kick, snare, ghost notes, timekeeping hi-hat, or fills —
368
+ * only the fx and auxiliary voices.
369
+ *
370
+ * The ordering holds in every style and section: a busier role never emits
371
+ * fewer or quieter voices than a sparser one.
247
372
  *
248
373
  * @defaultValue `'full'`
249
374
  */
@@ -280,8 +405,12 @@ type DrumsOptions = {
280
405
  * overrides the kick with an evenly-spread Euclidean pattern. Output is fully
281
406
  * determined by the options plus `seed`.
282
407
  *
408
+ * The patterns are 4/4 only — backbeats, hi-hat subdivisions, and fills are all
409
+ * written against a four-beat bar — so beat positions are quarter notes and bar
410
+ * `n` starts at beat `4n`.
411
+ *
283
412
  * @param opts Generation options.
284
- * @returns Percussion onsets in bar order.
413
+ * @returns Percussion onsets in onset order, ties broken by pitch.
285
414
  *
286
415
  * @example
287
416
  * ```ts
@@ -371,9 +500,12 @@ type HumanizeOptions = {
371
500
  * const events = [{ pitch: 60, startBeat: 0, durationBeat: 1, velocity: 80 }];
372
501
  * humanize(events, { seed: 1, timing: 0.03 }); // copies with jittered timing and accented velocity
373
502
  * ```
503
+ * Notes with a zero or negative duration never sound and are dropped, so the
504
+ * result can be shorter than the input.
505
+ *
374
506
  * @category Rhythm & Meter
375
507
  */
376
- declare function humanize(events: NoteEvent[], opts?: HumanizeOptions): NoteEvent[];
508
+ declare function humanize(events: readonly NoteEvent[], opts?: HumanizeOptions): NoteEvent[];
377
509
  /**
378
510
  * The recorded feel at a single grid slot: an average timing deviation and velocity.
379
511
  *
@@ -420,10 +552,12 @@ type GrooveTemplate = {
420
552
  * @param events The (typically "groovy", human-played) events to analyze.
421
553
  * @param ts The time signature, used to compute the bar length.
422
554
  * @param subdivision Grid resolution: equal grid steps per quarter-note beat.
555
+ * Defaults to a sixteenth-note grid, which is where the timing deviations a
556
+ * template records — swing, push, drag — are audible.
423
557
  * @returns The extracted groove template.
424
558
  * @category Rhythm & Meter
425
559
  */
426
- declare function extractGrooveTemplate(events: NoteEvent[], ts: TimeSignature, subdivision: number): GrooveTemplate;
560
+ declare function extractGrooveTemplate(events: readonly NoteEvent[], ts: TimeSignature, subdivision?: number): GrooveTemplate;
427
561
  /**
428
562
  * Apply a groove template to a set of (typically quantized) note events: each
429
563
  * event is snapped to its grid slot and then offset by that slot's recorded
@@ -458,7 +592,7 @@ declare function extractGrooveTemplate(events: NoteEvent[], ts: TimeSignature, s
458
592
  * ```
459
593
  * @category Rhythm & Meter
460
594
  */
461
- declare function applyGrooveTemplate(events: NoteEvent[], template: GrooveTemplate, ts: TimeSignature): NoteEvent[];
595
+ declare function applyGrooveTemplate(events: readonly NoteEvent[], template: GrooveTemplate, ts: TimeSignature): NoteEvent[];
462
596
 
463
597
  /**
464
598
  * Broad production style a progression preset suits.
@@ -480,10 +614,55 @@ type ProgFunction = 'loop' | 'tensionBuild' | 'cadenceStrong' | 'stable';
480
614
  type ProgressionPreset = {
481
615
  id: string;
482
616
  name: string;
483
- degrees: number[];
617
+ /**
618
+ * The chord roots, in order, as {@link ProgressionDegree} codes: 0..6 for the
619
+ * key's own scale degrees and {@link BORROWED_DEGREES} for the borrowed ones.
620
+ */
621
+ degrees: ProgressionDegree[];
484
622
  functional: ProgFunction;
485
623
  styles: ProgStyle[];
486
624
  };
625
+ /**
626
+ * The borrowed (non-diatonic) chord roots a preset can name, as their semitone
627
+ * offset above the tonic.
628
+ *
629
+ * Scale degrees 0..6 address the key's own chords; these codes continue the
630
+ * numbering for the chromatic chords a pop progression borrows, so a preset is
631
+ * one flat list of degree codes.
632
+ *
633
+ * @example
634
+ * ```ts
635
+ * import { BORROWED_DEGREES, generateProgression, majorKey } from '@libraz/libcantus';
636
+ * generateProgression({
637
+ * key: majorKey(0),
638
+ * style: 'rock',
639
+ * bars: 4,
640
+ * preset: { degrees: [0, BORROWED_DEGREES.bVII, 3, 0] },
641
+ * });
642
+ * ```
643
+ * @category Composition
644
+ */
645
+ declare const BORROWED_DEGREES: {
646
+ /** Flat submediant: bVI. */
647
+ readonly bVI: 8;
648
+ /** Flat subtonic: bVII. */
649
+ readonly bVII: 10;
650
+ /** Flat mediant: bIII. */
651
+ readonly bIII: 11;
652
+ /** Minor subdominant borrowed from the parallel minor: iv. */
653
+ readonly iv: 12;
654
+ /** Neapolitan: bII. */
655
+ readonly bII: 13;
656
+ /** Sharp subdominant, the diminished #IV. */
657
+ readonly sharpIV: 14;
658
+ };
659
+ /**
660
+ * A chord root in a preset: a scale degree 0..6, or one of
661
+ * {@link BORROWED_DEGREES}.
662
+ *
663
+ * @category Composition
664
+ */
665
+ type ProgressionDegree = number;
487
666
  /**
488
667
  * Options controlling {@link generateProgression}.
489
668
  *
@@ -491,9 +670,21 @@ type ProgressionPreset = {
491
670
  */
492
671
  type ProgressionOptions = {
493
672
  key: KeyScale;
673
+ /**
674
+ * Which pool of built-in presets to choose from. Ignored when `preset` names
675
+ * the progression outright.
676
+ */
494
677
  style: ProgStyle;
495
678
  bars: number;
679
+ /** Pick a specific built-in preset by id instead of choosing one by style. */
496
680
  presetId?: string;
681
+ /**
682
+ * Use this progression rather than a built-in one. Only `degrees` is
683
+ * required; see {@link BORROWED_DEGREES} for the non-diatonic codes.
684
+ */
685
+ preset?: Partial<ProgressionPreset> & {
686
+ degrees: ProgressionDegree[];
687
+ };
497
688
  ext?: ChordQuality | 'auto';
498
689
  reharmonize?: boolean;
499
690
  /**
@@ -515,23 +706,44 @@ declare function progressions(): ProgressionPreset[];
515
706
  * @category Composition
516
707
  */
517
708
  declare function progressionsByStyle(style: ProgStyle): ProgressionPreset[];
709
+ /**
710
+ * The preset {@link generateProgression} would choose for a style and seed.
711
+ *
712
+ * The choice is otherwise invisible: the generator returns chords, not the
713
+ * preset it drew them from, so a caller who wants to show or reproduce it has
714
+ * no way to name it.
715
+ *
716
+ * @param style The style pool to choose from.
717
+ * @param seed The same seed the generator would be given.
718
+ * @returns The preset that seed selects.
719
+ * @throws If no preset claims the style.
720
+ * @example
721
+ * ```ts
722
+ * import { pickProgressionPreset } from '@libraz/libcantus';
723
+ * pickProgressionPreset('dance', 3).name;
724
+ * ```
725
+ * @category Composition
726
+ */
727
+ declare function pickProgressionPreset(style: ProgStyle, seed?: number): ProgressionPreset;
518
728
  /**
519
729
  * Generate a chord progression laid out one chord per bar.
520
730
  *
521
731
  * A preset is chosen by `presetId` when given, otherwise deterministically from
522
- * the presets matching `style`, seeded by `seed`. An unknown `presetId` is a
523
- * caller error and throws rather than silently falling back to a random preset.
524
- * The preset's degrees cycle to
732
+ * the presets matching `style`, seeded by `seed`. An unknown `presetId`, or a
733
+ * `style` no preset claims, is a caller error and throws rather than silently
734
+ * falling back to a random preset. The preset's degrees cycle to
525
735
  * fill `bars`; each bar is four beats, so `startBeat` is `barIndex * 4`. Chord
526
736
  * roots come from the key's diatonic scale-degree mapping. When `ext` is
527
737
  * omitted or `'auto'`, each chord takes its diatonic triad quality; otherwise
528
- * `ext` is forced on every chord. When `reharmonize` is set, some chords are
738
+ * `ext` is forced on every chord — except a chord replaced by `reharmonize`,
739
+ * which is a secondary dominant and is therefore always a `dom7`; those carry
740
+ * `secondaryDominant: true`. When `reharmonize` is set, some chords are
529
741
  * deterministically replaced with the secondary dominant (V7) of the following
530
742
  * chord, flagged with `secondaryDominant`.
531
743
  *
532
744
  * @param opts Generation options.
533
745
  * @returns One chord per bar in timeline order.
534
- * @throws If `presetId` is given but does not match any built-in preset.
746
+ * @throws If `presetId` matches no built-in preset, or `style` matches none.
535
747
  *
536
748
  * @example
537
749
  * ```ts
@@ -555,15 +767,72 @@ type MelodyNote = NoteEvent;
555
767
  *
556
768
  * @category Reharmonization
557
769
  */
770
+ type HarmonizePlacement = {
771
+ /**
772
+ * Search a range of transpositions and keep the best-fitting one. The result
773
+ * reports the shift it chose in `transposeSemitones`.
774
+ *
775
+ * @defaultValue false
776
+ */
777
+ transposeSearch: boolean;
778
+ /**
779
+ * Search octave placements as well, so a melody written too high or too low
780
+ * is moved into a comfortable register.
781
+ *
782
+ * @defaultValue false
783
+ */
784
+ octaveSearch: boolean;
785
+ };
786
+ /**
787
+ * Options controlling {@link harmonizeMelody}.
788
+ *
789
+ * Only `melody` is required; every other knob has the default a first call
790
+ * wants.
791
+ *
792
+ * @category Reharmonization
793
+ */
558
794
  type HarmonizeOptions = {
559
- melody: MelodyNote[];
560
- key: KeyScale | 'infer';
561
- harmonicRhythm: number;
562
- reharmonize: 'diatonic' | 'secondaryDominant' | 'borrowed';
563
- placement: {
564
- transposeSearch: boolean;
565
- octaveSearch: boolean;
566
- };
795
+ /** The melody to harmonize, in ascending onset order. */
796
+ melody: readonly MelodyNote[];
797
+ /**
798
+ * The key to harmonize in, or `'infer'` to estimate it from the melody's
799
+ * pitch-class weighting — which is what a caller who has only a melody
800
+ * wants, and so the default.
801
+ *
802
+ * @defaultValue `'infer'`
803
+ */
804
+ key?: KeyScale | 'infer';
805
+ /**
806
+ * Length of each chord slot in beats. Any positive value is honoured, as in
807
+ * {@link chordTimelineFromNotes}; a value fine enough to make the search
808
+ * explode is rejected by the generation budget rather than rounded up.
809
+ *
810
+ * @defaultValue 2
811
+ */
812
+ harmonicRhythm?: number;
813
+ /**
814
+ * Time signature used to weight metric accents; defaults to 4/4. A waltz or
815
+ * a jig harmonized against a 4/4 accent grid gets its chords placed on the
816
+ * wrong beats, and the error accumulates bar by bar.
817
+ *
818
+ * @defaultValue `4/4`
819
+ */
820
+ ts?: TimeSignature;
821
+ /**
822
+ * How far beyond the key's own triads the chord vocabulary reaches:
823
+ * `'diatonic'` uses only them, `'secondaryDominant'` adds the dominants that
824
+ * tonicize each degree, and `'borrowed'` adds the parallel mode's chords too.
825
+ *
826
+ * @defaultValue `'diatonic'`
827
+ */
828
+ reharmonize?: 'diatonic' | 'secondaryDominant' | 'borrowed';
829
+ /**
830
+ * Whether to search transpositions and octave placements for the melody.
831
+ * Both are off by default, so the melody is harmonized where it was written.
832
+ *
833
+ * @defaultValue both false
834
+ */
835
+ placement?: HarmonizePlacement;
567
836
  /**
568
837
  * Seed for the deterministic tie-break perturbation.
569
838
  *
@@ -597,26 +866,23 @@ type HarmonizeResult = {
597
866
  * ties toward placements that keep the melody in a comfortable register.
598
867
  *
599
868
  * The `seed` drives a deterministic tie-break only: it perturbs candidates by a
600
- * magnitude far below any real cost difference (see {@link TIE_BREAK_JITTER}),
869
+ * magnitude far below any real cost difference (see `TIE_BREAK_JITTER`),
601
870
  * so it can decide between chords or paths of otherwise-equal cost but never
602
871
  * overrides melody fit or functional flow. For a well-determined melody the
603
872
  * result is identical across seeds; the same seed always yields the same result.
604
873
  *
605
- * @param opts Melody, key (or `'infer'`), harmonic rhythm, reharmonization
606
- * strength, height-search flags, and seed.
874
+ * @param opts The melody and, optionally, the key, harmonic rhythm,
875
+ * reharmonization strength, placement search, meter, and seed. Only `melody`
876
+ * is required.
607
877
  * @returns The chosen transpose, key, chord path, and per-note roles.
608
878
  * @example
609
879
  * ```ts
610
- * import { harmonizeMelody, majorKey } from '@libraz/libcantus';
880
+ * import { harmonizeMelody } from '@libraz/libcantus';
611
881
  * const result = harmonizeMelody({
612
882
  * melody: [
613
883
  * { pitch: 60, startBeat: 0, durationBeat: 1 },
614
884
  * { pitch: 64, startBeat: 1, durationBeat: 1 },
615
885
  * ],
616
- * key: majorKey(0),
617
- * harmonicRhythm: 1,
618
- * reharmonize: 'diatonic',
619
- * placement: { transposeSearch: false, octaveSearch: false },
620
886
  * });
621
887
  * result.chords; // one ChordSpan per harmonic-rhythm segment
622
888
  * ```
@@ -662,7 +928,15 @@ type MotifContour = 'arch' | 'ascending' | 'descending' | 'wave';
662
928
  type MotifOptions = {
663
929
  key: KeyScale;
664
930
  chord?: Chord | null;
931
+ /** Length of the motif in bars of `ts`. */
665
932
  bars: number;
933
+ /**
934
+ * Meter the bars are counted in. It sets the bar length, so a motif shares a
935
+ * bar grid with the other generators instead of assuming four beats.
936
+ *
937
+ * @defaultValue 4/4
938
+ */
939
+ ts?: TimeSignature;
666
940
  /**
667
941
  * Melodic contour shape the line follows.
668
942
  *
@@ -707,6 +981,23 @@ type MotifOptions = {
707
981
  * @category Composition
708
982
  */
709
983
  declare function generateMotif(opts: MotifOptions): MotifCell;
984
+ /**
985
+ * Turn a motif cell into note events.
986
+ *
987
+ * A {@link MotifNote} already carries the {@link NoteEvent} fields, but a cell
988
+ * wraps them in an object; this unwraps it, so a motif can be humanized,
989
+ * grooved, or written out like any other line.
990
+ *
991
+ * @param cell The motif to convert.
992
+ * @returns The cell's notes, copied, in the order they are stored.
993
+ * @example
994
+ * ```ts
995
+ * import { generateMotif, humanize, majorKey, motifToNoteEvents } from '@libraz/libcantus';
996
+ * humanize(motifToNoteEvents(generateMotif({ key: majorKey(0), bars: 2 })));
997
+ * ```
998
+ * @category Composition
999
+ */
1000
+ declare function motifToNoteEvents(cell: MotifCell): NoteEvent[];
710
1001
  /**
711
1002
  * Apply a transformation to a motif cell.
712
1003
  *
@@ -725,6 +1016,7 @@ declare function generateMotif(opts: MotifOptions): MotifCell;
725
1016
  * @param key Key context for the diatonic transforms; without it,
726
1017
  * `transposeDiatonic` and `sequence` shift chromatically by semitones.
727
1018
  * @returns The transformed cell.
1019
+ * @throws If a transformed pitch would fall outside the MIDI range 0..127.
728
1020
  *
729
1021
  * @example
730
1022
  * ```ts
@@ -746,7 +1038,8 @@ declare function transformMotif(cell: MotifCell, t: MotifTransform, amount?: num
746
1038
  * @param cell The source motif.
747
1039
  * @param timeline Chord segments to snap against.
748
1040
  * @param key Key context (used to keep snapped pitches sensible).
749
- * @param bars Number of four-beat bars to fill.
1041
+ * @param bars Number of bars to fill.
1042
+ * @param ts Meter the bars are counted in; defaults to 4/4.
750
1043
  * @returns The developed, harmony-aware cell.
751
1044
  *
752
1045
  * @example
@@ -759,7 +1052,7 @@ declare function transformMotif(cell: MotifCell, t: MotifTransform, amount?: num
759
1052
  *
760
1053
  * @category Composition
761
1054
  */
762
- declare function developMotif(cell: MotifCell, timeline: ChordTimeline, key: KeyScale, bars: number): MotifCell;
1055
+ declare function developMotif(cell: MotifCell, timeline: ChordTimeline, key: KeyScale, bars: number, ts?: TimeSignature): MotifCell;
763
1056
 
764
1057
  /**
765
1058
  * Reharmonization: chord substitution, modal-interchange palettes, and negative
@@ -775,7 +1068,7 @@ declare function developMotif(cell: MotifCell, timeline: ChordTimeline, key: Key
775
1068
  *
776
1069
  * @category Reharmonization
777
1070
  */
778
- type SubstitutionType = 'tritone' | 'relative' | 'borrowed' | 'chromatic-mediant' | 'secondary-dominant';
1071
+ type SubstitutionType = 'tritone' | 'relative' | 'borrowed' | 'chromaticMediant' | 'secondaryDominant';
779
1072
  /**
780
1073
  * A proposed chord substitution with its relationship, numeral, and function.
781
1074
  *
@@ -807,11 +1100,11 @@ type SubstituteOptions = {
807
1100
  * original chord and each other:
808
1101
  *
809
1102
  * - `tritone`: for a dominant-type chord, the dominant seventh a tritone away.
810
- * - `secondary-dominant`: for a stable target, the dominant seventh a fifth
1103
+ * - `secondaryDominant`: for a stable target, the dominant seventh a fifth
811
1104
  * above its root (tonicizing it).
812
1105
  * - `relative`: a diatonic triad a third away that shares two common tones.
813
1106
  * - `borrowed`: a triad from the parallel mode with the same harmonic function.
814
- * - `chromatic-mediant`: a major/minor triad a third away sharing one common
1107
+ * - `chromaticMediant`: a major/minor triad a third away sharing one common
815
1108
  * tone.
816
1109
  *
817
1110
  * Each result carries its Roman numeral and harmonic function in `key`. When
@@ -900,6 +1193,27 @@ type RhythmEvent = {
900
1193
  /** Duration in quarter-note beats, extending to the next onset. */
901
1194
  duration: number;
902
1195
  };
1196
+ /**
1197
+ * Turn rhythm events into note events at a fixed pitch.
1198
+ *
1199
+ * {@link RhythmEvent} names its fields `position`/`duration` because a rhythm
1200
+ * has no pitch; every other generator in the library speaks {@link NoteEvent}.
1201
+ * This is the bridge, so a generated rhythm can be humanized, grooved, or
1202
+ * written out like any other line.
1203
+ *
1204
+ * @param events The rhythm events to convert.
1205
+ * @param pitch The MIDI pitch to give every note.
1206
+ * @param velocity Velocity for every note; defaults to a mezzo-forte 96.
1207
+ * @returns The note events, in the order given.
1208
+ * @example
1209
+ * ```ts
1210
+ * import { generateRhythm, humanize, rhythmToNoteEvents } from '@libraz/libcantus';
1211
+ * const rhythm = generateRhythm({ numerator: 4, denominator: 4 }, { bars: 2 });
1212
+ * humanize(rhythmToNoteEvents(rhythm, 38));
1213
+ * ```
1214
+ * @category Rhythm & Meter
1215
+ */
1216
+ declare function rhythmToNoteEvents(events: RhythmEvent[], pitch: number, velocity?: number): NoteEvent[];
903
1217
  /**
904
1218
  * Options controlling {@link generateRhythm}.
905
1219
  *
@@ -977,4 +1291,4 @@ declare function generateRhythm(ts: TimeSignature, opts?: RhythmOptions): Rhythm
977
1291
  */
978
1292
  declare function rhythmDensity(events: RhythmEvent[], ts: TimeSignature): number;
979
1293
 
980
- export { type BassLineOptions, type BassSegment, type BassStyle, type BorrowedChord, ChordSpan, type CounterMelodyOptions, type DrumHit, type DrumRole, type DrumsOptions, type EuclideanKick, type GrooveFeel, type GrooveSlot, type GrooveStyle, type GrooveTemplate, type HarmonizeOptions, type HarmonizeResult, type HumanizeOptions, type MelodyNote, type MotifCell, type MotifContour, type MotifNote, type MotifOptions, type MotifTransform, type ProgFunction, type ProgStyle, type ProgressionOptions, type ProgressionPreset, type RhythmEvent, type RhythmOptions, type Section, type SubstituteOptions, type Substitution, type SubstitutionType, applyGrooveTemplate, developMotif, extractGrooveTemplate, generateBassLine, generateCounterMelody, generateDrums, generateMotif, generateProgression, generateRhythm, harmonizeMelody, humanize, modalInterchangePalette, negativeHarmonyMirror, onsetWeightCurve, progressions, progressionsByStyle, rhythmDensity, substituteChord, transformMotif };
1294
+ export { BASS_STYLES, BORROWED_DEGREES, type BassLineOptions, type BassSegment, type BassStyle, type BorrowedChord, BorrowedSource, Chord as ChordData, ChordQuality, ChordSegment, ChordSpan, ChordTimeline, type CounterMelodyOptions, DRUM_NOTES, type DrumHit, type DrumRole, type DrumVoice, type DrumsOptions, type EuclideanKick, type GrooveFeel, type GrooveSlot, type GrooveStyle, type GrooveTemplate, HarmonicFunction, type HarmonizeOptions, type HarmonizePlacement, type HarmonizeResult, HarmonyRole, type HumanizeOptions, KeyScale, type MelodyNote, type MotifCell, type MotifContour, type MotifNote, type MotifOptions, type MotifTransform, NoteEvent, type ProgFunction, type ProgStyle, type ProgressionDegree, type ProgressionOptions, type ProgressionPreset, type RhythmEvent, type RhythmOptions, type Section, type SubstituteOptions, type Substitution, type SubstitutionType, TimeSignature, applyGrooveTemplate, developMotif, drumVoiceOf, extractGrooveTemplate, generateBassLine, generateCounterMelody, generateDrums, generateMotif, generateProgression, generateRhythm, harmonizeMelody, humanize, modalInterchangePalette, motifToNoteEvents, negativeHarmonyMirror, onsetWeightCurve, pickProgressionPreset, progressions, progressionsByStyle, rhythmDensity, rhythmToNoteEvents, substituteChord, transformMotif };