@libraz/libcantus 0.9.2 → 0.9.3

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 (126) hide show
  1. package/README.md +4 -3
  2. package/dist/analyze/index.cjs +315 -42
  3. package/dist/analyze/index.cjs.map +1 -1
  4. package/dist/analyze/index.d.cts +11 -99
  5. package/dist/analyze/index.d.ts +11 -99
  6. package/dist/analyze/index.js +6 -6
  7. package/dist/chunk-2ZWMSJH6.js +30 -0
  8. package/dist/chunk-2ZWMSJH6.js.map +1 -0
  9. package/dist/{chunk-R3S2LUBH.js → chunk-4MHA432G.js} +316 -184
  10. package/dist/chunk-4MHA432G.js.map +1 -0
  11. package/dist/chunk-62QZKCJQ.js +49 -0
  12. package/dist/chunk-62QZKCJQ.js.map +1 -0
  13. package/dist/chunk-AKLYPWIN.js +83 -0
  14. package/dist/chunk-AKLYPWIN.js.map +1 -0
  15. package/dist/{chunk-XTC3X6MS.js → chunk-C5XYKUVG.js} +100 -12
  16. package/dist/chunk-C5XYKUVG.js.map +1 -0
  17. package/dist/{chunk-LN7ZZMD2.js → chunk-CHMXELDS.js} +33 -14
  18. package/dist/chunk-CHMXELDS.js.map +1 -0
  19. package/dist/{chunk-A4532ZFR.js → chunk-EH6EM37U.js} +60 -4
  20. package/dist/chunk-EH6EM37U.js.map +1 -0
  21. package/dist/chunk-FBQK3ZQN.js +131 -0
  22. package/dist/chunk-FBQK3ZQN.js.map +1 -0
  23. package/dist/{chunk-5HTNMQW4.js → chunk-GOAW4VYL.js} +87 -21
  24. package/dist/chunk-GOAW4VYL.js.map +1 -0
  25. package/dist/{chunk-MSWFZF7J.js → chunk-I5R7ZBJS.js} +90 -6
  26. package/dist/chunk-I5R7ZBJS.js.map +1 -0
  27. package/dist/{chunk-GQKN5KDT.js → chunk-IT2O4XFE.js} +4 -9
  28. package/dist/chunk-IT2O4XFE.js.map +1 -0
  29. package/dist/{chunk-7Y7WF64D.js → chunk-MIWO425M.js} +6 -4
  30. package/dist/chunk-MIWO425M.js.map +1 -0
  31. package/dist/chunk-N6IHQUOX.js +1 -0
  32. package/dist/chunk-N6IHQUOX.js.map +1 -0
  33. package/dist/{chunk-COKTX2G5.js → chunk-SGU7SPLK.js} +29 -12
  34. package/dist/chunk-SGU7SPLK.js.map +1 -0
  35. package/dist/core/index.cjs +230 -14
  36. package/dist/core/index.cjs.map +1 -1
  37. package/dist/core/index.d.cts +56 -4
  38. package/dist/core/index.d.ts +56 -4
  39. package/dist/core/index.js +24 -4
  40. package/dist/{function-2bJW1Zp_.d.ts → function-DVH4Eusr.d.ts} +1 -1
  41. package/dist/{function-r2sh-jOO.d.cts → function-DYt4iKsn.d.cts} +1 -1
  42. package/dist/generate/index.cjs +830 -494
  43. package/dist/generate/index.cjs.map +1 -1
  44. package/dist/generate/index.d.cts +11 -5
  45. package/dist/generate/index.d.ts +11 -5
  46. package/dist/generate/index.js +9 -9
  47. package/dist/{index-BOBXBNwP.d.cts → index-BNlGP86A.d.cts} +1 -1
  48. package/dist/{index-CP3wAfEH.d.ts → index-Bg5dYMmZ.d.ts} +1 -1
  49. package/dist/{index-CM5W4rcm.d.ts → index-Bt4tOUD9.d.ts} +1 -1
  50. package/dist/index-CnZCo29u.d.cts +108 -0
  51. package/dist/{index-D_ZTUNKp.d.cts → index-CpOsP1y9.d.cts} +2 -2
  52. package/dist/{index-DZ1M21do.d.cts → index-CxqBQtH1.d.cts} +2 -1
  53. package/dist/{index-BdeQ1r_p.d.cts → index-Dikst44v.d.cts} +1 -1
  54. package/dist/{index-BMPxwjwV.d.ts → index-DxvARIP2.d.ts} +2 -2
  55. package/dist/{index-BreoJRw0.d.ts → index-Jc0Ryi79.d.ts} +2 -1
  56. package/dist/index-JnF4v9bx.d.ts +108 -0
  57. package/dist/index.cjs +818 -283
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/index.d.cts +9 -8
  60. package/dist/index.d.ts +9 -8
  61. package/dist/index.js +34 -13
  62. package/dist/model/index.cjs +170 -31
  63. package/dist/model/index.cjs.map +1 -1
  64. package/dist/model/index.d.cts +6 -5
  65. package/dist/model/index.d.ts +6 -5
  66. package/dist/model/index.js +6 -6
  67. package/dist/{styled-D7BAx3S3.d.ts → styled-DZ7GjShb.d.ts} +1 -1
  68. package/dist/{styled-BjXtOFNk.d.cts → styled-ZTbdaVFM.d.cts} +1 -1
  69. package/dist/theory/index.cjs +180 -34
  70. package/dist/theory/index.cjs.map +1 -1
  71. package/dist/theory/index.d.cts +6 -6
  72. package/dist/theory/index.d.ts +6 -6
  73. package/dist/theory/index.js +6 -5
  74. package/package.json +50 -19
  75. package/src/analyze/arrange/internal.ts +3 -1
  76. package/src/analyze/arrange/tension.ts +15 -3
  77. package/src/analyze/arrange/tracks.ts +36 -3
  78. package/src/analyze/detect/index.ts +46 -9
  79. package/src/analyze/functional/roman.ts +14 -5
  80. package/src/analyze/index.ts +1 -1
  81. package/src/analyze/timeline/index.ts +43 -7
  82. package/src/analyze/voice/index.ts +11 -2
  83. package/src/core/event-index/index.ts +104 -0
  84. package/src/core/index.ts +14 -0
  85. package/src/core/meter/index.ts +24 -4
  86. package/src/core/random/index.ts +26 -3
  87. package/src/core/tuning/index.ts +36 -6
  88. package/src/core/validation/index.ts +119 -0
  89. package/src/generate/bass/index.ts +23 -0
  90. package/src/generate/countermelody/index.ts +167 -76
  91. package/src/generate/drums/euclid.ts +10 -3
  92. package/src/generate/drums/index.ts +56 -24
  93. package/src/generate/drums/percussion.ts +1 -1
  94. package/src/generate/groove/index.ts +25 -0
  95. package/src/generate/harmonize/index.ts +55 -44
  96. package/src/generate/index.ts +0 -1
  97. package/src/generate/motif/index.ts +45 -21
  98. package/src/generate/progression/index.ts +8 -16
  99. package/src/generate/reharmony/index.ts +1 -8
  100. package/src/generate/rhythm/index.ts +11 -1
  101. package/src/index.ts +13 -247
  102. package/src/model/chord.ts +29 -10
  103. package/src/theory/chord/index.ts +4 -2
  104. package/src/theory/harmony/index.ts +6 -21
  105. package/src/theory/index.ts +6 -1
  106. package/src/theory/safety/index.ts +71 -2
  107. package/src/theory/spelling/index.ts +70 -3
  108. package/src/theory/voicing/satb.ts +25 -4
  109. package/src/theory/voicing/styled.ts +26 -3
  110. package/dist/chunk-5HTNMQW4.js.map +0 -1
  111. package/dist/chunk-7Y7WF64D.js.map +0 -1
  112. package/dist/chunk-A4532ZFR.js.map +0 -1
  113. package/dist/chunk-BHUT2S5G.js +0 -22
  114. package/dist/chunk-BHUT2S5G.js.map +0 -1
  115. package/dist/chunk-CCBLVAPK.js +0 -42
  116. package/dist/chunk-CCBLVAPK.js.map +0 -1
  117. package/dist/chunk-COKTX2G5.js.map +0 -1
  118. package/dist/chunk-GQKN5KDT.js.map +0 -1
  119. package/dist/chunk-LN7ZZMD2.js.map +0 -1
  120. package/dist/chunk-MSWFZF7J.js.map +0 -1
  121. package/dist/chunk-R3S2LUBH.js.map +0 -1
  122. package/dist/chunk-SDM3VJJ5.js +0 -41
  123. package/dist/chunk-SDM3VJJ5.js.map +0 -1
  124. package/dist/chunk-XTC3X6MS.js.map +0 -1
  125. package/dist/chunk-ZXW5YIWK.js +0 -55
  126. package/dist/chunk-ZXW5YIWK.js.map +0 -1
@@ -1,6 +1,33 @@
1
- export { B as BarPosition, T as TimeSignature, b as barPositionToBeat, a as beatToBarPosition, c as beatsPerBar, f as formatTimeSignature, i as isCompound, d as isStrongBeat, m as metricWeight, p as parseTimeSignature, e as pulsesPerBar, t as tuplet } from '../index-Cl7mhOFM.cjs';
1
+ import { N as NoteEvent } from '../types-MGP29r3t.cjs';
2
+ export { K as KeyScale } from '../types-MGP29r3t.cjs';
3
+ import { T as TimeSignature } from '../index-Cl7mhOFM.cjs';
4
+ export { B as BarPosition, b as barPositionToBeat, a as beatToBarPosition, c as beatsPerBar, f as formatTimeSignature, i as isCompound, d as isStrongBeat, m as metricWeight, p as parseTimeSignature, e as pulsesPerBar, t as tuplet } from '../index-Cl7mhOFM.cjs';
2
5
  export { N as NoteData, S as SpelledInterval, f as formatNote, m as midiToNote, n as noteToMidi, a as noteToPitchClass, p as parseNote, s as spelledInterval } from '../index-CGMZNCx6.cjs';
3
- export { K as KeyScale, N as NoteEvent } from '../types-MGP29r3t.cjs';
6
+
7
+ /** A validated note retaining its position in the caller's original array. */
8
+ type IndexedNoteEvent = {
9
+ note: NoteEvent;
10
+ originalIndex: number;
11
+ endBeat: number;
12
+ };
13
+ /** Binary-searchable, stable-sorted index over note onsets and active spans. */
14
+ type NoteEventIndex = {
15
+ notes: IndexedNoteEvent[];
16
+ /** Latest-onset note sounding at `beat`, with later input order winning ties. */
17
+ at: (beat: number) => IndexedNoteEvent | undefined;
18
+ /** Whether one or more notes attack at `beat`. */
19
+ attacksAt: (beat: number) => boolean;
20
+ /** Unique attack beats strictly inside `(startBeat, endBeat)`. */
21
+ onsetsBetween: (startBeat: number, endBeat: number) => number[];
22
+ };
23
+ /**
24
+ * Validate and stable-sort note events once, then expose logarithmic onset and
25
+ * active-note lookups. Non-positive-duration notes may be retained for callers
26
+ * that intentionally filter them later, but never count as sounding.
27
+ */
28
+ declare function createNoteEventIndex(events: NoteEvent[], options?: {
29
+ allowNonPositiveDuration?: boolean;
30
+ }): NoteEventIndex;
4
31
 
5
32
  /**
6
33
  * Counterpoint classification of a harmonic interval.
@@ -202,9 +229,34 @@ declare const JUST_RATIOS: Record<number, [number, number]>;
202
229
  * (positive means the just interval is wider).
203
230
  *
204
231
  * @param semitoneClass Semitone class in [0, 12].
205
- * @returns The deviation in cents, or NaN if the class has no listed ratio.
232
+ * @returns The deviation in cents.
233
+ * @throws If `semitoneClass` is not an integer in [0, 12].
206
234
  * @category Pitch & Intervals
207
235
  */
208
236
  declare function justDeviationCents(semitoneClass: number): number;
209
237
 
210
- export { IntervalQuality, JUST_RATIOS, type Rng, TWELVE_TET, type Tuning, centsBetweenFreq, centsOfSteps, classifyInterval, createRng, edo, frequencyOf, isConsonantInterval, isPerfectInterval, justDeviationCents, nearestStep, ratioToCents };
238
+ /** Default upper bound for synchronous event/window/candidate generation. */
239
+ declare const DEFAULT_GENERATION_BUDGET = 1000000;
240
+ /** Require a finite JavaScript number and return it unchanged. */
241
+ declare function assertFiniteNumber(value: number, name: string): number;
242
+ /** Require an integer in the inclusive range `[min, max]`. */
243
+ declare function assertInteger(value: number, name: string, min?: number, max?: number): number;
244
+ /** Require a positive safe integer, optionally capped by `max`. */
245
+ declare function assertPositiveInt(value: number, name: string, max?: number): number;
246
+ /** Require a finite number in the inclusive range `[min, max]`. */
247
+ declare function assertRange(value: number, min: number, max: number, name: string): number;
248
+ /** Reject work estimates that would exceed a synchronous generation budget. */
249
+ declare function assertGenerationBudget(estimated: number, name: string, limit?: number): number;
250
+ /** Validate a time signature, including additive grouping, before any early return. */
251
+ declare function assertTimeSignature(ts: TimeSignature, name?: string): TimeSignature;
252
+ /** Validate the finite fields of one timeline note event. */
253
+ declare function assertNoteEvent(event: NoteEvent, name?: string, options?: {
254
+ allowNonPositiveDuration?: boolean;
255
+ }): NoteEvent;
256
+ /** Validate an event array and its allocation budget without copying it. */
257
+ declare function assertNoteEvents(events: NoteEvent[], name?: string, options?: {
258
+ allowNonPositiveDuration?: boolean;
259
+ budget?: number;
260
+ }): NoteEvent[];
261
+
262
+ export { DEFAULT_GENERATION_BUDGET, type IndexedNoteEvent, IntervalQuality, JUST_RATIOS, NoteEvent, type NoteEventIndex, type Rng, TWELVE_TET, TimeSignature, type Tuning, assertFiniteNumber, assertGenerationBudget, assertInteger, assertNoteEvent, assertNoteEvents, assertPositiveInt, assertRange, assertTimeSignature, centsBetweenFreq, centsOfSteps, classifyInterval, createNoteEventIndex, createRng, edo, frequencyOf, isConsonantInterval, isPerfectInterval, justDeviationCents, nearestStep, ratioToCents };
@@ -1,6 +1,33 @@
1
- export { B as BarPosition, T as TimeSignature, b as barPositionToBeat, a as beatToBarPosition, c as beatsPerBar, f as formatTimeSignature, i as isCompound, d as isStrongBeat, m as metricWeight, p as parseTimeSignature, e as pulsesPerBar, t as tuplet } from '../index-Cl7mhOFM.js';
1
+ import { N as NoteEvent } from '../types-MGP29r3t.js';
2
+ export { K as KeyScale } from '../types-MGP29r3t.js';
3
+ import { T as TimeSignature } from '../index-Cl7mhOFM.js';
4
+ export { B as BarPosition, b as barPositionToBeat, a as beatToBarPosition, c as beatsPerBar, f as formatTimeSignature, i as isCompound, d as isStrongBeat, m as metricWeight, p as parseTimeSignature, e as pulsesPerBar, t as tuplet } from '../index-Cl7mhOFM.js';
2
5
  export { N as NoteData, S as SpelledInterval, f as formatNote, m as midiToNote, n as noteToMidi, a as noteToPitchClass, p as parseNote, s as spelledInterval } from '../index-CGMZNCx6.js';
3
- export { K as KeyScale, N as NoteEvent } from '../types-MGP29r3t.js';
6
+
7
+ /** A validated note retaining its position in the caller's original array. */
8
+ type IndexedNoteEvent = {
9
+ note: NoteEvent;
10
+ originalIndex: number;
11
+ endBeat: number;
12
+ };
13
+ /** Binary-searchable, stable-sorted index over note onsets and active spans. */
14
+ type NoteEventIndex = {
15
+ notes: IndexedNoteEvent[];
16
+ /** Latest-onset note sounding at `beat`, with later input order winning ties. */
17
+ at: (beat: number) => IndexedNoteEvent | undefined;
18
+ /** Whether one or more notes attack at `beat`. */
19
+ attacksAt: (beat: number) => boolean;
20
+ /** Unique attack beats strictly inside `(startBeat, endBeat)`. */
21
+ onsetsBetween: (startBeat: number, endBeat: number) => number[];
22
+ };
23
+ /**
24
+ * Validate and stable-sort note events once, then expose logarithmic onset and
25
+ * active-note lookups. Non-positive-duration notes may be retained for callers
26
+ * that intentionally filter them later, but never count as sounding.
27
+ */
28
+ declare function createNoteEventIndex(events: NoteEvent[], options?: {
29
+ allowNonPositiveDuration?: boolean;
30
+ }): NoteEventIndex;
4
31
 
5
32
  /**
6
33
  * Counterpoint classification of a harmonic interval.
@@ -202,9 +229,34 @@ declare const JUST_RATIOS: Record<number, [number, number]>;
202
229
  * (positive means the just interval is wider).
203
230
  *
204
231
  * @param semitoneClass Semitone class in [0, 12].
205
- * @returns The deviation in cents, or NaN if the class has no listed ratio.
232
+ * @returns The deviation in cents.
233
+ * @throws If `semitoneClass` is not an integer in [0, 12].
206
234
  * @category Pitch & Intervals
207
235
  */
208
236
  declare function justDeviationCents(semitoneClass: number): number;
209
237
 
210
- export { IntervalQuality, JUST_RATIOS, type Rng, TWELVE_TET, type Tuning, centsBetweenFreq, centsOfSteps, classifyInterval, createRng, edo, frequencyOf, isConsonantInterval, isPerfectInterval, justDeviationCents, nearestStep, ratioToCents };
238
+ /** Default upper bound for synchronous event/window/candidate generation. */
239
+ declare const DEFAULT_GENERATION_BUDGET = 1000000;
240
+ /** Require a finite JavaScript number and return it unchanged. */
241
+ declare function assertFiniteNumber(value: number, name: string): number;
242
+ /** Require an integer in the inclusive range `[min, max]`. */
243
+ declare function assertInteger(value: number, name: string, min?: number, max?: number): number;
244
+ /** Require a positive safe integer, optionally capped by `max`. */
245
+ declare function assertPositiveInt(value: number, name: string, max?: number): number;
246
+ /** Require a finite number in the inclusive range `[min, max]`. */
247
+ declare function assertRange(value: number, min: number, max: number, name: string): number;
248
+ /** Reject work estimates that would exceed a synchronous generation budget. */
249
+ declare function assertGenerationBudget(estimated: number, name: string, limit?: number): number;
250
+ /** Validate a time signature, including additive grouping, before any early return. */
251
+ declare function assertTimeSignature(ts: TimeSignature, name?: string): TimeSignature;
252
+ /** Validate the finite fields of one timeline note event. */
253
+ declare function assertNoteEvent(event: NoteEvent, name?: string, options?: {
254
+ allowNonPositiveDuration?: boolean;
255
+ }): NoteEvent;
256
+ /** Validate an event array and its allocation budget without copying it. */
257
+ declare function assertNoteEvents(events: NoteEvent[], name?: string, options?: {
258
+ allowNonPositiveDuration?: boolean;
259
+ budget?: number;
260
+ }): NoteEvent[];
261
+
262
+ export { DEFAULT_GENERATION_BUDGET, type IndexedNoteEvent, IntervalQuality, JUST_RATIOS, NoteEvent, type NoteEventIndex, type Rng, TWELVE_TET, TimeSignature, type Tuning, assertFiniteNumber, assertGenerationBudget, assertInteger, assertNoteEvent, assertNoteEvents, assertPositiveInt, assertRange, assertTimeSignature, centsBetweenFreq, centsOfSteps, classifyInterval, createNoteEventIndex, createRng, edo, frequencyOf, isConsonantInterval, isPerfectInterval, justDeviationCents, nearestStep, ratioToCents };
@@ -8,14 +8,15 @@ import {
8
8
  justDeviationCents,
9
9
  nearestStep,
10
10
  ratioToCents
11
- } from "../chunk-ZXW5YIWK.js";
11
+ } from "../chunk-AKLYPWIN.js";
12
12
  import {
13
13
  createRng
14
- } from "../chunk-BHUT2S5G.js";
14
+ } from "../chunk-62QZKCJQ.js";
15
15
  import {
16
16
  barPositionToBeat,
17
17
  beatToBarPosition,
18
18
  beatsPerBar,
19
+ createNoteEventIndex,
19
20
  formatTimeSignature,
20
21
  isCompound,
21
22
  isStrongBeat,
@@ -23,7 +24,7 @@ import {
23
24
  parseTimeSignature,
24
25
  pulsesPerBar,
25
26
  tuplet
26
- } from "../chunk-MSWFZF7J.js";
27
+ } from "../chunk-I5R7ZBJS.js";
27
28
  import {
28
29
  formatNote,
29
30
  midiToNote,
@@ -33,21 +34,40 @@ import {
33
34
  spelledInterval
34
35
  } from "../chunk-DYWFNC4A.js";
35
36
  import {
37
+ DEFAULT_GENERATION_BUDGET,
36
38
  IntervalQuality,
39
+ assertFiniteNumber,
40
+ assertGenerationBudget,
41
+ assertInteger,
42
+ assertNoteEvent,
43
+ assertNoteEvents,
44
+ assertPositiveInt,
45
+ assertRange,
46
+ assertTimeSignature,
37
47
  classifyInterval,
38
48
  isConsonantInterval,
39
49
  isPerfectInterval
40
- } from "../chunk-CCBLVAPK.js";
50
+ } from "../chunk-FBQK3ZQN.js";
41
51
  export {
52
+ DEFAULT_GENERATION_BUDGET,
42
53
  IntervalQuality,
43
54
  JUST_RATIOS,
44
55
  TWELVE_TET,
56
+ assertFiniteNumber,
57
+ assertGenerationBudget,
58
+ assertInteger,
59
+ assertNoteEvent,
60
+ assertNoteEvents,
61
+ assertPositiveInt,
62
+ assertRange,
63
+ assertTimeSignature,
45
64
  barPositionToBeat,
46
65
  beatToBarPosition,
47
66
  beatsPerBar,
48
67
  centsBetweenFreq,
49
68
  centsOfSteps,
50
69
  classifyInterval,
70
+ createNoteEventIndex,
51
71
  createRng,
52
72
  edo,
53
73
  formatNote,
@@ -1,5 +1,5 @@
1
1
  import { K as KeyScale } from './types-MGP29r3t.js';
2
- import { C as Chord } from './index-CM5W4rcm.js';
2
+ import { C as Chord } from './index-Bt4tOUD9.js';
3
3
 
4
4
  /**
5
5
  * Borrowed chords (modal interchange) and the Neapolitan.
@@ -1,5 +1,5 @@
1
1
  import { K as KeyScale } from './types-MGP29r3t.cjs';
2
- import { C as Chord } from './index-BOBXBNwP.cjs';
2
+ import { C as Chord } from './index-BNlGP86A.cjs';
3
3
 
4
4
  /**
5
5
  * Borrowed chords (modal interchange) and the Neapolitan.