@libraz/libcantus 0.9.3 → 0.9.5

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 (201) hide show
  1. package/README.md +29 -20
  2. package/README_ja.md +268 -0
  3. package/dist/analyze/index.cjs +39 -1947
  4. package/dist/analyze/index.cjs.map +1 -1
  5. package/dist/analyze/index.d.cts +161 -91
  6. package/dist/analyze/index.d.ts +161 -91
  7. package/dist/analyze/index.js +19 -8
  8. package/dist/chunk-2A2QMA74.cjs +261 -0
  9. package/dist/chunk-2A2QMA74.cjs.map +1 -0
  10. package/dist/chunk-2PTFGVD7.js +261 -0
  11. package/dist/chunk-2PTFGVD7.js.map +1 -0
  12. package/dist/chunk-357ZDPVU.cjs +162 -0
  13. package/dist/chunk-357ZDPVU.cjs.map +1 -0
  14. package/dist/chunk-3KX76RLG.js +1548 -0
  15. package/dist/chunk-3KX76RLG.js.map +1 -0
  16. package/dist/chunk-4VZ5MZAM.cjs +889 -0
  17. package/dist/chunk-4VZ5MZAM.cjs.map +1 -0
  18. package/dist/{chunk-C5XYKUVG.js → chunk-7EONYVI5.js} +471 -171
  19. package/dist/chunk-7EONYVI5.js.map +1 -0
  20. package/dist/{chunk-IT2O4XFE.js → chunk-7JEP3MFY.js} +42 -34
  21. package/dist/chunk-7JEP3MFY.js.map +1 -0
  22. package/dist/{chunk-4MHA432G.js → chunk-AID75RN3.js} +572 -250
  23. package/dist/chunk-AID75RN3.js.map +1 -0
  24. package/dist/chunk-BSLTLGM3.cjs +497 -0
  25. package/dist/chunk-BSLTLGM3.cjs.map +1 -0
  26. package/dist/chunk-CU6VG2YM.cjs +109 -0
  27. package/dist/chunk-CU6VG2YM.cjs.map +1 -0
  28. package/dist/{chunk-EH6EM37U.js → chunk-DZMHIGI4.js} +81 -59
  29. package/dist/chunk-DZMHIGI4.js.map +1 -0
  30. package/dist/{chunk-AKLYPWIN.js → chunk-EDOTEABK.js} +45 -19
  31. package/dist/chunk-EDOTEABK.js.map +1 -0
  32. package/dist/{chunk-2ZWMSJH6.js → chunk-HN2OEUN2.js} +7 -4
  33. package/dist/chunk-HN2OEUN2.js.map +1 -0
  34. package/dist/{chunk-MIWO425M.js → chunk-KBTTEX7Q.js} +128 -43
  35. package/dist/chunk-KBTTEX7Q.js.map +1 -0
  36. package/dist/chunk-KQN2ZYND.cjs +724 -0
  37. package/dist/chunk-KQN2ZYND.cjs.map +1 -0
  38. package/dist/chunk-MPTVJIVG.cjs +3176 -0
  39. package/dist/chunk-MPTVJIVG.cjs.map +1 -0
  40. package/dist/chunk-MTMZTMWM.cjs +53 -0
  41. package/dist/chunk-MTMZTMWM.cjs.map +1 -0
  42. package/dist/{chunk-CHMXELDS.js → chunk-NNB67XA2.js} +372 -197
  43. package/dist/chunk-NNB67XA2.js.map +1 -0
  44. package/dist/chunk-OL3IHHSJ.cjs +1204 -0
  45. package/dist/chunk-OL3IHHSJ.cjs.map +1 -0
  46. package/dist/chunk-PI3UXRWK.cjs +528 -0
  47. package/dist/chunk-PI3UXRWK.cjs.map +1 -0
  48. package/dist/chunk-R2VVFAIN.js +528 -0
  49. package/dist/chunk-R2VVFAIN.js.map +1 -0
  50. package/dist/chunk-T64C7ZD7.cjs +1 -0
  51. package/dist/chunk-T64C7ZD7.cjs.map +1 -0
  52. package/dist/chunk-WFDXOLUB.cjs +337 -0
  53. package/dist/chunk-WFDXOLUB.cjs.map +1 -0
  54. package/dist/chunk-WTAN4ACG.cjs +1548 -0
  55. package/dist/chunk-WTAN4ACG.cjs.map +1 -0
  56. package/dist/chunk-YFJXS3AU.cjs +33 -0
  57. package/dist/chunk-YFJXS3AU.cjs.map +1 -0
  58. package/dist/{chunk-GOAW4VYL.js → chunk-YUE6TJ4M.js} +315 -145
  59. package/dist/chunk-YUE6TJ4M.js.map +1 -0
  60. package/dist/{chunk-62QZKCJQ.js → chunk-ZGLJM4A4.js} +10 -6
  61. package/dist/chunk-ZGLJM4A4.js.map +1 -0
  62. package/dist/core/index.cjs +140 -647
  63. package/dist/core/index.cjs.map +1 -1
  64. package/dist/core/index.d.cts +313 -41
  65. package/dist/core/index.d.ts +313 -41
  66. package/dist/core/index.js +64 -16
  67. package/dist/{function-DVH4Eusr.d.ts → function-CxixTB02.d.cts} +122 -10
  68. package/dist/{function-DYt4iKsn.d.cts → function-DTCt675z.d.ts} +122 -10
  69. package/dist/generate/index.cjs +28 -4085
  70. package/dist/generate/index.cjs.map +1 -1
  71. package/dist/generate/index.d.cts +374 -66
  72. package/dist/generate/index.d.ts +374 -66
  73. package/dist/generate/index.js +23 -9
  74. package/dist/{index-Jc0Ryi79.d.ts → index-B2Ulxxpo.d.cts} +21 -5
  75. package/dist/{index-CpOsP1y9.d.cts → index-BkYJ0xMq.d.cts} +18 -17
  76. package/dist/{index-CxqBQtH1.d.cts → index-BuaB-ypt.d.ts} +21 -5
  77. package/dist/index-CAN7v-kw.d.ts +199 -0
  78. package/dist/{index-Bt4tOUD9.d.ts → index-COw1Ky9g.d.ts} +93 -8
  79. package/dist/{index-Dikst44v.d.cts → index-Cfx8xgH0.d.ts} +14 -11
  80. package/dist/{index-DxvARIP2.d.ts → index-DRtIhlJj.d.ts} +18 -17
  81. package/dist/{index-Cl7mhOFM.d.cts → index-DXd9JikN.d.cts} +92 -10
  82. package/dist/{index-Cl7mhOFM.d.ts → index-DXd9JikN.d.ts} +92 -10
  83. package/dist/index-alrRninU.d.cts +199 -0
  84. package/dist/{index-BNlGP86A.d.cts → index-oTQbYYIs.d.cts} +93 -8
  85. package/dist/index-tR9jTn26.d.cts +275 -0
  86. package/dist/index-tR9jTn26.d.ts +275 -0
  87. package/dist/{index-Bg5dYMmZ.d.ts → index-x2vcsduE.d.cts} +14 -11
  88. package/dist/index.cjs +429 -7383
  89. package/dist/index.cjs.map +1 -1
  90. package/dist/index.d.cts +15 -15
  91. package/dist/index.d.ts +15 -15
  92. package/dist/index.js +121 -27
  93. package/dist/model/index.cjs +8 -2562
  94. package/dist/model/index.cjs.map +1 -1
  95. package/dist/model/index.d.cts +471 -81
  96. package/dist/model/index.d.ts +471 -81
  97. package/dist/model/index.js +6 -7
  98. package/dist/styled-Bl0ZK28h.d.ts +543 -0
  99. package/dist/styled-Crv6SA4S.d.cts +543 -0
  100. package/dist/theory/index.cjs +172 -1822
  101. package/dist/theory/index.cjs.map +1 -1
  102. package/dist/theory/index.d.cts +151 -233
  103. package/dist/theory/index.d.ts +151 -233
  104. package/dist/theory/index.js +30 -7
  105. package/dist/{types-MGP29r3t.d.cts → types-BN6_Q9Kl.d.cts} +11 -2
  106. package/dist/{types-MGP29r3t.d.ts → types-BN6_Q9Kl.d.ts} +11 -2
  107. package/package.json +34 -13
  108. package/dist/chunk-2ZWMSJH6.js.map +0 -1
  109. package/dist/chunk-4MHA432G.js.map +0 -1
  110. package/dist/chunk-62QZKCJQ.js.map +0 -1
  111. package/dist/chunk-AKLYPWIN.js.map +0 -1
  112. package/dist/chunk-C5XYKUVG.js.map +0 -1
  113. package/dist/chunk-CHMXELDS.js.map +0 -1
  114. package/dist/chunk-DYWFNC4A.js +0 -152
  115. package/dist/chunk-DYWFNC4A.js.map +0 -1
  116. package/dist/chunk-EH6EM37U.js.map +0 -1
  117. package/dist/chunk-FBQK3ZQN.js +0 -131
  118. package/dist/chunk-FBQK3ZQN.js.map +0 -1
  119. package/dist/chunk-GOAW4VYL.js.map +0 -1
  120. package/dist/chunk-I5R7ZBJS.js +0 -202
  121. package/dist/chunk-I5R7ZBJS.js.map +0 -1
  122. package/dist/chunk-IT2O4XFE.js.map +0 -1
  123. package/dist/chunk-MIWO425M.js.map +0 -1
  124. package/dist/chunk-SGU7SPLK.js +0 -924
  125. package/dist/chunk-SGU7SPLK.js.map +0 -1
  126. package/dist/index-CGMZNCx6.d.cts +0 -140
  127. package/dist/index-CGMZNCx6.d.ts +0 -140
  128. package/dist/index-CnZCo29u.d.cts +0 -108
  129. package/dist/index-JnF4v9bx.d.ts +0 -108
  130. package/dist/styled-DZ7GjShb.d.ts +0 -282
  131. package/dist/styled-ZTbdaVFM.d.cts +0 -282
  132. package/src/analyze/arrange/index.ts +0 -21
  133. package/src/analyze/arrange/internal.ts +0 -127
  134. package/src/analyze/arrange/tension.ts +0 -199
  135. package/src/analyze/arrange/tracks.ts +0 -312
  136. package/src/analyze/detect/index.ts +0 -272
  137. package/src/analyze/functional/borrowed.ts +0 -84
  138. package/src/analyze/functional/cadence.ts +0 -66
  139. package/src/analyze/functional/function.ts +0 -184
  140. package/src/analyze/functional/index.ts +0 -23
  141. package/src/analyze/functional/internal.ts +0 -29
  142. package/src/analyze/functional/roman.ts +0 -402
  143. package/src/analyze/index.ts +0 -49
  144. package/src/analyze/timeline/index.ts +0 -451
  145. package/src/analyze/voice/index.ts +0 -339
  146. package/src/core/event-index/index.ts +0 -104
  147. package/src/core/index.ts +0 -61
  148. package/src/core/interval/index.ts +0 -81
  149. package/src/core/meter/index.ts +0 -302
  150. package/src/core/pitch/index.ts +0 -311
  151. package/src/core/random/index.ts +0 -76
  152. package/src/core/tuning/index.ts +0 -186
  153. package/src/core/types.ts +0 -29
  154. package/src/core/validation/index.ts +0 -119
  155. package/src/generate/bass/index.ts +0 -373
  156. package/src/generate/countermelody/index.ts +0 -470
  157. package/src/generate/drums/beat.ts +0 -266
  158. package/src/generate/drums/euclid.ts +0 -65
  159. package/src/generate/drums/fills.ts +0 -356
  160. package/src/generate/drums/ghost.ts +0 -119
  161. package/src/generate/drums/hihat.ts +0 -285
  162. package/src/generate/drums/hit.ts +0 -31
  163. package/src/generate/drums/index.ts +0 -361
  164. package/src/generate/drums/internal.ts +0 -257
  165. package/src/generate/drums/kick.ts +0 -160
  166. package/src/generate/drums/percussion.ts +0 -121
  167. package/src/generate/drums/rng.ts +0 -7
  168. package/src/generate/drums/swing.ts +0 -71
  169. package/src/generate/groove/index.ts +0 -351
  170. package/src/generate/harmonize/index.ts +0 -451
  171. package/src/generate/index.ts +0 -58
  172. package/src/generate/motif/index.ts +0 -422
  173. package/src/generate/progression/index.ts +0 -362
  174. package/src/generate/reharmony/index.ts +0 -323
  175. package/src/generate/rhythm/index.ts +0 -175
  176. package/src/index.ts +0 -13
  177. package/src/model/chord.ts +0 -442
  178. package/src/model/index.ts +0 -15
  179. package/src/model/interval.ts +0 -82
  180. package/src/model/key.ts +0 -266
  181. package/src/model/note.ts +0 -176
  182. package/src/model/progression.ts +0 -161
  183. package/src/model/shared.ts +0 -12
  184. package/src/theory/chord/index.ts +0 -375
  185. package/src/theory/chordscale/index.ts +0 -374
  186. package/src/theory/counterpoint/index.ts +0 -230
  187. package/src/theory/harmony/index.ts +0 -77
  188. package/src/theory/index.ts +0 -112
  189. package/src/theory/safety/index.ts +0 -488
  190. package/src/theory/scale/degrees.ts +0 -123
  191. package/src/theory/scale/index.ts +0 -28
  192. package/src/theory/scale/key.ts +0 -56
  193. package/src/theory/scale/masks.ts +0 -153
  194. package/src/theory/spelling/index.ts +0 -249
  195. package/src/theory/symbol/index.ts +0 -268
  196. package/src/theory/voicing/index.ts +0 -5
  197. package/src/theory/voicing/internal.ts +0 -168
  198. package/src/theory/voicing/leading.ts +0 -112
  199. package/src/theory/voicing/satb.ts +0 -216
  200. package/src/theory/voicing/styled.ts +0 -199
  201. package/tsconfig.json +0 -23
@@ -1,9 +1,10 @@
1
- import { T as TimeSignature } from '../index-Cl7mhOFM.cjs';
2
- import { K as KeyScale, N as NoteEvent } from '../types-MGP29r3t.cjs';
3
- import { C as Chord, a as ChordQuality, b as ChordSpan } from '../index-BNlGP86A.cjs';
4
- import { H as HarmonyRole } from '../index-Dikst44v.cjs';
5
- import { b as ChordTimeline } from '../index-CpOsP1y9.cjs';
6
- import { B as BorrowedSource, H as HarmonicFunction } from '../function-DYt4iKsn.cjs';
1
+ import { B as BorrowedSource, H as HarmonicFunction } from '../function-CxixTB02.cjs';
2
+ import { K as KeyScale, N as NoteEvent } from '../types-BN6_Q9Kl.cjs';
3
+ import { b as ChordSegment, C as Chord, a as ChordQuality, c as ChordSpan } from '../index-oTQbYYIs.cjs';
4
+ export { d as ChordToneRole, P as PitchSpelling } from '../index-oTQbYYIs.cjs';
5
+ import { a as ChordTimeline } from '../index-BkYJ0xMq.cjs';
6
+ import { T as TimeSignature } from '../index-DXd9JikN.cjs';
7
+ import { H as HarmonyRole } from '../index-x2vcsduE.cjs';
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-DYt4iKsn
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,13 +110,28 @@ 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;
108
132
  /**
109
- * Exact chord-change beats exposed by the caller's timeline. The generator
110
- * also probes its half-beat grid, but callback discontinuities between grid
111
- * points are not introspectable and should be listed here.
133
+ * Exact chord-change beats the `chordAt` callback does not expose. Ignored
134
+ * when `timeline` is given, since a timeline lists its own boundaries.
112
135
  */
113
136
  chordChangeBeats?: number[];
114
137
  /** Key/scale context for scale-tone decisions. */
@@ -143,7 +166,11 @@ type CounterMelodyOptions = {
143
166
  /** Highest MIDI pitch the counter line may use (default derived from `register`). */
144
167
  pitchHigh?: number;
145
168
  /**
146
- * 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.
147
174
  *
148
175
  * @defaultValue 0
149
176
  */
@@ -159,8 +186,10 @@ type CounterMelodyOptions = {
159
186
  * consonant tensions against the sounding melody note), rejecting candidates
160
187
  * that would form a parallel perfect interval with the melody or sit on the
161
188
  * wrong side of it, then scored to favour contrary or oblique motion, imperfect
162
- * consonance, and stepwise movement. Ties break toward the lower pitch, so a
163
- * 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
164
193
  * onset (the last to the melody's end) at a velocity slightly under the melody.
165
194
  *
166
195
  * @param opts The lead line, chord context callback, key, and generation knobs.
@@ -179,22 +208,92 @@ type CounterMelodyOptions = {
179
208
  */
180
209
  declare function generateCounterMelody(opts: CounterMelodyOptions): NoteEvent[];
181
210
 
182
- /** 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: Readonly<{
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
+ */
183
262
  type DrumHit = {
263
+ /** General MIDI note number; {@link drumVoiceOf} names it. */
184
264
  pitch: number;
185
265
  startBeat: number;
186
266
  durationBeat: number;
187
267
  velocity: number;
188
268
  };
189
269
 
270
+ /** Every groove feel, in declaration order. */
271
+ declare const DRUM_FEELS: readonly ["straight", "swing", "shuffle"];
190
272
  /** Groove feel controlling off-beat swing. */
191
- type Feel = 'straight' | 'swing' | 'shuffle';
192
- /** Public groove style identifiers. */
193
- type GrooveStyle = 'standard' | 'funk' | 'shuffle' | 'bossa' | 'trap' | 'halftime' | 'breakbeat' | 'house' | 'synthpop';
194
- /** Public role identifiers gating which voices are present. */
195
- 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"];
196
295
  /** Public section identifiers. */
197
- type PublicSection = 'intro' | 'verse' | 'prechorus' | 'chorus' | 'bridge' | 'outro';
296
+ type PublicSection = (typeof PUBLIC_SECTIONS)[number];
198
297
 
199
298
  /**
200
299
  * Groove feel (the swing/straight rhythmic character) for {@link generateDrums}.
@@ -236,20 +335,40 @@ type EuclideanKick = {
236
335
  * @category Composition
237
336
  */
238
337
  type DrumsOptions = {
338
+ /**
339
+ * Number of bars to generate.
340
+ */
239
341
  bars: number;
240
342
  bpm: number;
241
343
  style: GrooveStyle;
242
344
  section: Section;
243
345
  density: number;
346
+ /** Time signature; defaults to 4/4. */
347
+ ts?: TimeSignature;
244
348
  /**
245
349
  * Replace the final bar with a fill.
246
350
  *
351
+ * A pre-chorus leading into a chorus builds instead: the two-bar lift takes
352
+ * precedence over the fill, since the buildup already marks the phrase end.
353
+ * Set `nextSection` to anything but `'chorus'` to get the fill.
354
+ *
247
355
  * @defaultValue false
248
356
  */
249
357
  fills?: boolean;
250
358
  feel?: GrooveFeel;
251
359
  /**
252
- * Voicing role; `'fxOnly'` suppresses the main kick/snare/ghost/fill voices.
360
+ * Voicing role, from busiest to sparsest:
361
+ *
362
+ * - `'full'`: every voice, backbeat snare at full weight.
363
+ * - `'ambient'`: side-stick backbeat, ride instead of hi-hat.
364
+ * - `'minimal'`: side-stick backbeat quieter still, pedal hi-hat, no
365
+ * auxiliary percussion.
366
+ * - `'fxOnly'`: no kick, snare, ghost notes, timekeeping hi-hat, or fills —
367
+ * only the fx and auxiliary voices.
368
+ *
369
+ * Roles express orchestration priority and peak dynamics, not a strict hit
370
+ * count: style-specific ride, foot-hi-hat, and auxiliary patterns may make a
371
+ * sparser role emit more individual onsets in a particular bar.
253
372
  *
254
373
  * @defaultValue `'full'`
255
374
  */
@@ -286,8 +405,12 @@ type DrumsOptions = {
286
405
  * overrides the kick with an evenly-spread Euclidean pattern. Output is fully
287
406
  * determined by the options plus `seed`.
288
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
+ *
289
412
  * @param opts Generation options.
290
- * @returns Percussion onsets in bar order.
413
+ * @returns Percussion onsets in onset order, ties broken by pitch.
291
414
  *
292
415
  * @example
293
416
  * ```ts
@@ -377,9 +500,12 @@ type HumanizeOptions = {
377
500
  * const events = [{ pitch: 60, startBeat: 0, durationBeat: 1, velocity: 80 }];
378
501
  * humanize(events, { seed: 1, timing: 0.03 }); // copies with jittered timing and accented velocity
379
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
+ *
380
506
  * @category Rhythm & Meter
381
507
  */
382
- declare function humanize(events: NoteEvent[], opts?: HumanizeOptions): NoteEvent[];
508
+ declare function humanize(events: readonly NoteEvent[], opts?: HumanizeOptions): NoteEvent[];
383
509
  /**
384
510
  * The recorded feel at a single grid slot: an average timing deviation and velocity.
385
511
  *
@@ -426,10 +552,12 @@ type GrooveTemplate = {
426
552
  * @param events The (typically "groovy", human-played) events to analyze.
427
553
  * @param ts The time signature, used to compute the bar length.
428
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.
429
557
  * @returns The extracted groove template.
430
558
  * @category Rhythm & Meter
431
559
  */
432
- declare function extractGrooveTemplate(events: NoteEvent[], ts: TimeSignature, subdivision: number): GrooveTemplate;
560
+ declare function extractGrooveTemplate(events: readonly NoteEvent[], ts: TimeSignature, subdivision?: number): GrooveTemplate;
433
561
  /**
434
562
  * Apply a groove template to a set of (typically quantized) note events: each
435
563
  * event is snapped to its grid slot and then offset by that slot's recorded
@@ -437,6 +565,8 @@ declare function extractGrooveTemplate(events: NoteEvent[], ts: TimeSignature, s
437
565
  * Velocity is set to the slot's recorded average when it recorded one (a
438
566
  * non-`null` velocity, including a genuine 0); otherwise the event's own
439
567
  * velocity is left untouched.
568
+ * Non-positive-duration input artefacts are omitted, so output positions do
569
+ * not retain a one-to-one correspondence with the input array.
440
570
  *
441
571
  * If the template carries a time signature (see {@link GrooveTemplate.ts}) it
442
572
  * must match `ts`, since a differing bar length would misalign the per-bar
@@ -464,7 +594,7 @@ declare function extractGrooveTemplate(events: NoteEvent[], ts: TimeSignature, s
464
594
  * ```
465
595
  * @category Rhythm & Meter
466
596
  */
467
- declare function applyGrooveTemplate(events: NoteEvent[], template: GrooveTemplate, ts: TimeSignature): NoteEvent[];
597
+ declare function applyGrooveTemplate(events: readonly NoteEvent[], template: GrooveTemplate, ts: TimeSignature): NoteEvent[];
468
598
 
469
599
  /**
470
600
  * Broad production style a progression preset suits.
@@ -486,10 +616,56 @@ type ProgFunction = 'loop' | 'tensionBuild' | 'cadenceStrong' | 'stable';
486
616
  type ProgressionPreset = {
487
617
  id: string;
488
618
  name: string;
489
- degrees: number[];
619
+ /**
620
+ * The chord roots, in order, as {@link ProgressionDegree} codes: 0..6 for the
621
+ * key's own scale degrees and {@link BORROWED_DEGREES} for the borrowed ones.
622
+ */
623
+ degrees: ProgressionDegree[];
490
624
  functional: ProgFunction;
491
625
  styles: ProgStyle[];
492
626
  };
627
+ /**
628
+ * The borrowed (non-diatonic) chord roots a preset can name, as their semitone
629
+ * code for a borrowed degree. These are stable identifiers, not semitone
630
+ * offsets: their pitch-class offsets are resolved internally.
631
+ *
632
+ * Scale degrees 0..6 address the key's own chords; these codes continue the
633
+ * numbering for the chromatic chords a pop progression borrows, so a preset is
634
+ * one flat list of degree codes.
635
+ *
636
+ * @example
637
+ * ```ts
638
+ * import { BORROWED_DEGREES, generateProgression, majorKey } from '@libraz/libcantus';
639
+ * generateProgression({
640
+ * key: majorKey(0),
641
+ * style: 'rock',
642
+ * bars: 4,
643
+ * preset: { degrees: [0, BORROWED_DEGREES.bVII, 3, 0] },
644
+ * });
645
+ * ```
646
+ * @category Composition
647
+ */
648
+ declare const BORROWED_DEGREES: Readonly<{
649
+ /** Flat submediant: bVI. */
650
+ readonly bVI: 8;
651
+ /** Flat subtonic: bVII. */
652
+ readonly bVII: 10;
653
+ /** Flat mediant: bIII. */
654
+ readonly bIII: 11;
655
+ /** Minor subdominant borrowed from the parallel minor: iv. */
656
+ readonly iv: 12;
657
+ /** Neapolitan: bII. */
658
+ readonly bII: 13;
659
+ /** Sharp subdominant, the diminished #IV. */
660
+ readonly sharpIV: 14;
661
+ }>;
662
+ /**
663
+ * A chord root in a preset: a scale degree 0..6, or one of
664
+ * {@link BORROWED_DEGREES}.
665
+ *
666
+ * @category Composition
667
+ */
668
+ type ProgressionDegree = number;
493
669
  /**
494
670
  * Options controlling {@link generateProgression}.
495
671
  *
@@ -497,9 +673,21 @@ type ProgressionPreset = {
497
673
  */
498
674
  type ProgressionOptions = {
499
675
  key: KeyScale;
676
+ /**
677
+ * Which pool of built-in presets to choose from. Ignored when `preset` names
678
+ * the progression outright.
679
+ */
500
680
  style: ProgStyle;
501
681
  bars: number;
682
+ /** Pick a specific built-in preset by id instead of choosing one by style. */
502
683
  presetId?: string;
684
+ /**
685
+ * Use this progression rather than a built-in one. Only `degrees` is
686
+ * required; see {@link BORROWED_DEGREES} for the non-diatonic codes.
687
+ */
688
+ preset?: Partial<ProgressionPreset> & {
689
+ degrees: ProgressionDegree[];
690
+ };
503
691
  ext?: ChordQuality | 'auto';
504
692
  reharmonize?: boolean;
505
693
  /**
@@ -521,23 +709,44 @@ declare function progressions(): ProgressionPreset[];
521
709
  * @category Composition
522
710
  */
523
711
  declare function progressionsByStyle(style: ProgStyle): ProgressionPreset[];
712
+ /**
713
+ * The preset {@link generateProgression} would choose for a style and seed.
714
+ *
715
+ * The choice is otherwise invisible: the generator returns chords, not the
716
+ * preset it drew them from, so a caller who wants to show or reproduce it has
717
+ * no way to name it.
718
+ *
719
+ * @param style The style pool to choose from.
720
+ * @param seed The same seed the generator would be given.
721
+ * @returns The preset that seed selects.
722
+ * @throws If no preset claims the style.
723
+ * @example
724
+ * ```ts
725
+ * import { pickProgressionPreset } from '@libraz/libcantus';
726
+ * pickProgressionPreset('dance', 3).name;
727
+ * ```
728
+ * @category Composition
729
+ */
730
+ declare function pickProgressionPreset(style: ProgStyle, seed?: number): ProgressionPreset;
524
731
  /**
525
732
  * Generate a chord progression laid out one chord per bar.
526
733
  *
527
734
  * A preset is chosen by `presetId` when given, otherwise deterministically from
528
- * the presets matching `style`, seeded by `seed`. An unknown `presetId` is a
529
- * caller error and throws rather than silently falling back to a random preset.
530
- * The preset's degrees cycle to
735
+ * the presets matching `style`, seeded by `seed`. An unknown `presetId`, or a
736
+ * `style` no preset claims, is a caller error and throws rather than silently
737
+ * falling back to a random preset. The preset's degrees cycle to
531
738
  * fill `bars`; each bar is four beats, so `startBeat` is `barIndex * 4`. Chord
532
739
  * roots come from the key's diatonic scale-degree mapping. When `ext` is
533
740
  * omitted or `'auto'`, each chord takes its diatonic triad quality; otherwise
534
- * `ext` is forced on every chord. When `reharmonize` is set, some chords are
741
+ * `ext` is forced on every chord — except a chord replaced by `reharmonize`,
742
+ * which is a secondary dominant and is therefore always a `dom7`; those carry
743
+ * `secondaryDominant: true`. When `reharmonize` is set, some chords are
535
744
  * deterministically replaced with the secondary dominant (V7) of the following
536
745
  * chord, flagged with `secondaryDominant`.
537
746
  *
538
747
  * @param opts Generation options.
539
748
  * @returns One chord per bar in timeline order.
540
- * @throws If `presetId` is given but does not match any built-in preset.
749
+ * @throws If `presetId` matches no built-in preset, or `style` matches none.
541
750
  *
542
751
  * @example
543
752
  * ```ts
@@ -561,15 +770,72 @@ type MelodyNote = NoteEvent;
561
770
  *
562
771
  * @category Reharmonization
563
772
  */
773
+ type HarmonizePlacement = {
774
+ /**
775
+ * Search a range of transpositions and keep the best-fitting one. The result
776
+ * reports the shift it chose in `transposeSemitones`.
777
+ *
778
+ * @defaultValue false
779
+ */
780
+ transposeSearch: boolean;
781
+ /**
782
+ * Search octave placements as well, so a melody written too high or too low
783
+ * is moved into a comfortable register.
784
+ *
785
+ * @defaultValue false
786
+ */
787
+ octaveSearch: boolean;
788
+ };
789
+ /**
790
+ * Options controlling {@link harmonizeMelody}.
791
+ *
792
+ * Only `melody` is required; every other knob has the default a first call
793
+ * wants.
794
+ *
795
+ * @category Reharmonization
796
+ */
564
797
  type HarmonizeOptions = {
565
- melody: MelodyNote[];
566
- key: KeyScale | 'infer';
567
- harmonicRhythm: number;
568
- reharmonize: 'diatonic' | 'secondaryDominant' | 'borrowed';
569
- placement: {
570
- transposeSearch: boolean;
571
- octaveSearch: boolean;
572
- };
798
+ /** The melody to harmonize, in ascending onset order. */
799
+ melody: readonly MelodyNote[];
800
+ /**
801
+ * The key to harmonize in, or `'infer'` to estimate it from the melody's
802
+ * pitch-class weighting — which is what a caller who has only a melody
803
+ * wants, and so the default.
804
+ *
805
+ * @defaultValue `'infer'`
806
+ */
807
+ key?: KeyScale | 'infer';
808
+ /**
809
+ * Length of each chord slot in beats. Any positive value is honoured, as in
810
+ * {@link chordTimelineFromNotes}; a value fine enough to make the search
811
+ * explode is rejected by the generation budget rather than rounded up.
812
+ *
813
+ * @defaultValue 2
814
+ */
815
+ harmonicRhythm?: number;
816
+ /**
817
+ * Time signature used to weight metric accents; defaults to 4/4. A waltz or
818
+ * a jig harmonized against a 4/4 accent grid gets its chords placed on the
819
+ * wrong beats, and the error accumulates bar by bar.
820
+ *
821
+ * @defaultValue `4/4`
822
+ */
823
+ ts?: TimeSignature;
824
+ /**
825
+ * How far beyond the key's own triads the chord vocabulary reaches:
826
+ * `'diatonic'` uses only them, `'secondaryDominant'` adds the dominants that
827
+ * tonicize each degree, and `'borrowed'` adds the parallel mode's chords too.
828
+ *
829
+ * @defaultValue `'diatonic'`
830
+ */
831
+ reharmonize?: 'diatonic' | 'secondaryDominant' | 'borrowed';
832
+ /**
833
+ * Whether to search transpositions and octave placements for the melody.
834
+ * Both are off by default, so the melody is harmonized where it was written.
835
+ *
836
+ * @defaultValue both false
837
+ */
838
+ placement?: HarmonizePlacement;
573
839
  /**
574
840
  * Seed for the deterministic tie-break perturbation.
575
841
  *
@@ -603,26 +869,23 @@ type HarmonizeResult = {
603
869
  * ties toward placements that keep the melody in a comfortable register.
604
870
  *
605
871
  * The `seed` drives a deterministic tie-break only: it perturbs candidates by a
606
- * magnitude far below any real cost difference (see {@link TIE_BREAK_JITTER}),
872
+ * magnitude far below any real cost difference (see `TIE_BREAK_JITTER`),
607
873
  * so it can decide between chords or paths of otherwise-equal cost but never
608
874
  * overrides melody fit or functional flow. For a well-determined melody the
609
875
  * result is identical across seeds; the same seed always yields the same result.
610
876
  *
611
- * @param opts Melody, key (or `'infer'`), harmonic rhythm, reharmonization
612
- * strength, height-search flags, and seed.
877
+ * @param opts The melody and, optionally, the key, harmonic rhythm,
878
+ * reharmonization strength, placement search, meter, and seed. Only `melody`
879
+ * is required.
613
880
  * @returns The chosen transpose, key, chord path, and per-note roles.
614
881
  * @example
615
882
  * ```ts
616
- * import { harmonizeMelody, majorKey } from '@libraz/libcantus';
883
+ * import { harmonizeMelody } from '@libraz/libcantus';
617
884
  * const result = harmonizeMelody({
618
885
  * melody: [
619
886
  * { pitch: 60, startBeat: 0, durationBeat: 1 },
620
887
  * { pitch: 64, startBeat: 1, durationBeat: 1 },
621
888
  * ],
622
- * key: majorKey(0),
623
- * harmonicRhythm: 1,
624
- * reharmonize: 'diatonic',
625
- * placement: { transposeSearch: false, octaveSearch: false },
626
889
  * });
627
890
  * result.chords; // one ChordSpan per harmonic-rhythm segment
628
891
  * ```
@@ -668,7 +931,15 @@ type MotifContour = 'arch' | 'ascending' | 'descending' | 'wave';
668
931
  type MotifOptions = {
669
932
  key: KeyScale;
670
933
  chord?: Chord | null;
934
+ /** Length of the motif in bars of `ts`. */
671
935
  bars: number;
936
+ /**
937
+ * Meter the bars are counted in. It sets the bar length, so a motif shares a
938
+ * bar grid with the other generators instead of assuming four beats.
939
+ *
940
+ * @defaultValue 4/4
941
+ */
942
+ ts?: TimeSignature;
672
943
  /**
673
944
  * Melodic contour shape the line follows.
674
945
  *
@@ -713,6 +984,23 @@ type MotifOptions = {
713
984
  * @category Composition
714
985
  */
715
986
  declare function generateMotif(opts: MotifOptions): MotifCell;
987
+ /**
988
+ * Turn a motif cell into note events.
989
+ *
990
+ * A {@link MotifNote} already carries the {@link NoteEvent} fields, but a cell
991
+ * wraps them in an object; this unwraps it, so a motif can be humanized,
992
+ * grooved, or written out like any other line.
993
+ *
994
+ * @param cell The motif to convert.
995
+ * @returns The cell's notes, copied, in the order they are stored.
996
+ * @example
997
+ * ```ts
998
+ * import { generateMotif, humanize, majorKey, motifToNoteEvents } from '@libraz/libcantus';
999
+ * humanize(motifToNoteEvents(generateMotif({ key: majorKey(0), bars: 2 })));
1000
+ * ```
1001
+ * @category Composition
1002
+ */
1003
+ declare function motifToNoteEvents(cell: MotifCell): NoteEvent[];
716
1004
  /**
717
1005
  * Apply a transformation to a motif cell.
718
1006
  *
@@ -731,6 +1019,7 @@ declare function generateMotif(opts: MotifOptions): MotifCell;
731
1019
  * @param key Key context for the diatonic transforms; without it,
732
1020
  * `transposeDiatonic` and `sequence` shift chromatically by semitones.
733
1021
  * @returns The transformed cell.
1022
+ * @throws If a transformed pitch would fall outside the MIDI range 0..127.
734
1023
  *
735
1024
  * @example
736
1025
  * ```ts
@@ -752,7 +1041,8 @@ declare function transformMotif(cell: MotifCell, t: MotifTransform, amount?: num
752
1041
  * @param cell The source motif.
753
1042
  * @param timeline Chord segments to snap against.
754
1043
  * @param key Key context (used to keep snapped pitches sensible).
755
- * @param bars Number of four-beat bars to fill.
1044
+ * @param bars Number of bars to fill.
1045
+ * @param ts Meter the bars are counted in; defaults to 4/4.
756
1046
  * @returns The developed, harmony-aware cell.
757
1047
  *
758
1048
  * @example
@@ -765,7 +1055,7 @@ declare function transformMotif(cell: MotifCell, t: MotifTransform, amount?: num
765
1055
  *
766
1056
  * @category Composition
767
1057
  */
768
- declare function developMotif(cell: MotifCell, timeline: ChordTimeline, key: KeyScale, bars: number): MotifCell;
1058
+ declare function developMotif(cell: MotifCell, timeline: ChordTimeline, key: KeyScale, bars: number, ts?: TimeSignature): MotifCell;
769
1059
 
770
1060
  /**
771
1061
  * Reharmonization: chord substitution, modal-interchange palettes, and negative
@@ -781,7 +1071,7 @@ declare function developMotif(cell: MotifCell, timeline: ChordTimeline, key: Key
781
1071
  *
782
1072
  * @category Reharmonization
783
1073
  */
784
- type SubstitutionType = 'tritone' | 'relative' | 'borrowed' | 'chromatic-mediant' | 'secondary-dominant';
1074
+ type SubstitutionType = 'tritone' | 'relative' | 'borrowed' | 'chromaticMediant' | 'secondaryDominant';
785
1075
  /**
786
1076
  * A proposed chord substitution with its relationship, numeral, and function.
787
1077
  *
@@ -813,11 +1103,9 @@ type SubstituteOptions = {
813
1103
  * original chord and each other:
814
1104
  *
815
1105
  * - `tritone`: for a dominant-type chord, the dominant seventh a tritone away.
816
- * - `secondary-dominant`: for a stable target, the dominant seventh a fifth
817
- * above its root (tonicizing it).
818
1106
  * - `relative`: a diatonic triad a third away that shares two common tones.
819
1107
  * - `borrowed`: a triad from the parallel mode with the same harmonic function.
820
- * - `chromatic-mediant`: a major/minor triad a third away sharing one common
1108
+ * - `chromaticMediant`: a major/minor triad a third away sharing one common
821
1109
  * tone.
822
1110
  *
823
1111
  * Each result carries its Roman numeral and harmonic function in `key`. When
@@ -906,6 +1194,27 @@ type RhythmEvent = {
906
1194
  /** Duration in quarter-note beats, extending to the next onset. */
907
1195
  duration: number;
908
1196
  };
1197
+ /**
1198
+ * Turn rhythm events into note events at a fixed pitch.
1199
+ *
1200
+ * {@link RhythmEvent} names its fields `position`/`duration` because a rhythm
1201
+ * has no pitch; every other generator in the library speaks {@link NoteEvent}.
1202
+ * This is the bridge, so a generated rhythm can be humanized, grooved, or
1203
+ * written out like any other line.
1204
+ *
1205
+ * @param events The rhythm events to convert.
1206
+ * @param pitch The MIDI pitch to give every note.
1207
+ * @param velocity Velocity for every note; defaults to a mezzo-forte 96.
1208
+ * @returns The note events, in the order given.
1209
+ * @example
1210
+ * ```ts
1211
+ * import { generateRhythm, humanize, rhythmToNoteEvents } from '@libraz/libcantus';
1212
+ * const rhythm = generateRhythm({ numerator: 4, denominator: 4 }, { bars: 2 });
1213
+ * humanize(rhythmToNoteEvents(rhythm, 38));
1214
+ * ```
1215
+ * @category Rhythm & Meter
1216
+ */
1217
+ declare function rhythmToNoteEvents(events: RhythmEvent[], pitch: number, velocity?: number): NoteEvent[];
909
1218
  /**
910
1219
  * Options controlling {@link generateRhythm}.
911
1220
  *
@@ -934,8 +1243,7 @@ type RhythmOptions = {
934
1243
  subdivision?: number;
935
1244
  /**
936
1245
  * Overall onset density in [0, 1]. Scales the per-slot onset probability, so
937
- * higher values fill more grid slots. Values outside [0, 1] are clamped into
938
- * range.
1246
+ * higher values fill more grid slots. Values outside [0, 1] are rejected.
939
1247
  *
940
1248
  * @defaultValue 0.5
941
1249
  */
@@ -959,7 +1267,7 @@ declare function onsetWeightCurve(weight: number): number;
959
1267
  * and sampled from the seeded PRNG. Every bar's downbeat is always an onset, so
960
1268
  * a pattern of any length has a reliable pulse independent of the seed. Each
961
1269
  * event's duration extends to the next onset, and the last event extends to the
962
- * end of the span. `density` is clamped to [0, 1].
1270
+ * end of the span. `density` must be in [0, 1].
963
1271
  *
964
1272
  * @param ts The time signature.
965
1273
  * @param opts Generation options.
@@ -983,4 +1291,4 @@ declare function generateRhythm(ts: TimeSignature, opts?: RhythmOptions): Rhythm
983
1291
  */
984
1292
  declare function rhythmDensity(events: RhythmEvent[], ts: TimeSignature): number;
985
1293
 
986
- export { type BassLineOptions, type BassSegment, type BassStyle, type BorrowedChord, 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 };