@libraz/libcantus 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -65
- package/README_ja.md +28 -66
- package/dist/analyze/index.cjs +11 -7
- package/dist/analyze/index.cjs.map +1 -1
- package/dist/analyze/index.d.cts +79 -144
- package/dist/analyze/index.d.ts +79 -144
- package/dist/analyze/index.js +20 -16
- package/dist/{chunk-TTCLJX6D.js → chunk-57WB2EDF.js} +10 -8
- package/dist/chunk-57WB2EDF.js.map +1 -0
- package/dist/chunk-5JJ6EHEZ.cjs +457 -0
- package/dist/chunk-5JJ6EHEZ.cjs.map +1 -0
- package/dist/{chunk-AFM2ULJH.cjs → chunk-5KW7DNCJ.cjs} +1567 -1067
- package/dist/chunk-5KW7DNCJ.cjs.map +1 -0
- package/dist/chunk-7GOKQJTQ.js +145 -0
- package/dist/chunk-7GOKQJTQ.js.map +1 -0
- package/dist/{chunk-H3VORETI.js → chunk-AWEMD747.js} +487 -592
- package/dist/chunk-AWEMD747.js.map +1 -0
- package/dist/{chunk-4A2RMUCC.js → chunk-DKICR7AN.js} +1216 -611
- package/dist/chunk-DKICR7AN.js.map +1 -0
- package/dist/{chunk-INHVXP6Z.js → chunk-FPBZFNCD.js} +1159 -415
- package/dist/chunk-FPBZFNCD.js.map +1 -0
- package/dist/{chunk-M4CWTJWJ.cjs → chunk-GDKE6RQW.cjs} +1453 -848
- package/dist/chunk-GDKE6RQW.cjs.map +1 -0
- package/dist/chunk-H66ARFU5.js +363 -0
- package/dist/chunk-H66ARFU5.js.map +1 -0
- package/dist/{chunk-YH3BIKHH.js → chunk-HOHFYGKW.js} +146 -49
- package/dist/chunk-HOHFYGKW.js.map +1 -0
- package/dist/chunk-HSY2VQXZ.js +2272 -0
- package/dist/chunk-HSY2VQXZ.js.map +1 -0
- package/dist/{chunk-E3F4AHAH.cjs → chunk-J772DL3B.cjs} +221 -134
- package/dist/chunk-J772DL3B.cjs.map +1 -0
- package/dist/chunk-K6OZXIR6.js +1 -0
- package/dist/{chunk-VTI6FOLB.js → chunk-PQL7E5F6.js} +709 -133
- package/dist/chunk-PQL7E5F6.js.map +1 -0
- package/dist/chunk-Q6R3QAZD.cjs +3329 -0
- package/dist/chunk-Q6R3QAZD.cjs.map +1 -0
- package/dist/{chunk-MXO72PLY.cjs → chunk-QCXYKSZS.cjs} +21 -19
- package/dist/chunk-QCXYKSZS.cjs.map +1 -0
- package/dist/{chunk-VOHZB45S.js → chunk-R5VUXQMP.js} +1321 -821
- package/dist/chunk-R5VUXQMP.js.map +1 -0
- package/dist/chunk-R7B5N2JK.cjs +363 -0
- package/dist/chunk-R7B5N2JK.cjs.map +1 -0
- package/dist/{chunk-WWURE4XT.cjs → chunk-RVS4G4MR.cjs} +624 -729
- package/dist/chunk-RVS4G4MR.cjs.map +1 -0
- package/dist/chunk-TT6PKMPR.cjs +145 -0
- package/dist/chunk-TT6PKMPR.cjs.map +1 -0
- package/dist/chunk-UGLFDG7L.cjs +1 -0
- package/dist/chunk-UGLFDG7L.cjs.map +1 -0
- package/dist/chunk-VLE5R7PF.js +3329 -0
- package/dist/chunk-VLE5R7PF.js.map +1 -0
- package/dist/{chunk-FVSI36UV.js → chunk-X6RJAHII.js} +197 -110
- package/dist/chunk-X6RJAHII.js.map +1 -0
- package/dist/{chunk-Q2WGKJNN.cjs → chunk-XKSO2V5I.cjs} +699 -123
- package/dist/chunk-XKSO2V5I.cjs.map +1 -0
- package/dist/chunk-XVMJO3QF.cjs +2272 -0
- package/dist/chunk-XVMJO3QF.cjs.map +1 -0
- package/dist/{chunk-UADYAYAT.cjs → chunk-YPB3A3EY.cjs} +1309 -565
- package/dist/chunk-YPB3A3EY.cjs.map +1 -0
- package/dist/{index-C_8o--VE.d.cts → coerce-CJlgULrQ.d.cts} +210 -199
- package/dist/{index-szBv3496.d.ts → coerce-wwdELNYS.d.ts} +210 -199
- package/dist/core/index.cjs +9 -5
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +122 -108
- package/dist/core/index.d.ts +122 -108
- package/dist/core/index.js +32 -28
- package/dist/generate/index.cjs +8 -8
- package/dist/generate/index.d.cts +168 -84
- package/dist/generate/index.d.ts +168 -84
- package/dist/generate/index.js +7 -7
- package/dist/{index-CGpRv5sl.d.cts → index-9eoQs2C1.d.ts} +34 -19
- package/dist/{index-Dzr13q3d.d.cts → index-B3WCj_Hm.d.cts} +135 -58
- package/dist/{index-BO6xE9YU.d.cts → index-BUtIf2go.d.ts} +460 -254
- package/dist/{index-CCNJRG-P.d.cts → index-BaoKVVhE.d.cts} +293 -56
- package/dist/{index-Chbst3Jx.d.ts → index-BpWOhkkE.d.ts} +135 -58
- package/dist/{index-BGFW-8P2.d.cts → index-BzLNkmA7.d.cts} +196 -114
- package/dist/{index-CunYKLiu.d.ts → index-CBCP84rv.d.cts} +1 -1
- package/dist/{index-BkGmlyI3.d.cts → index-Ci3xyows.d.ts} +60 -23
- package/dist/{index-9wcMhG73.d.ts → index-CnHQgqNh.d.ts} +293 -56
- package/dist/{index-B4o55NDr.d.cts → index-CnIdP4EZ.d.ts} +1 -1
- package/dist/{index-B9MNZboQ.d.ts → index-Cy15oTvh.d.cts} +52 -22
- package/dist/{index-B9MNZboQ.d.cts → index-Cy15oTvh.d.ts} +52 -22
- package/dist/{index-D57QRbVn.d.ts → index-DTsKaPaC.d.cts} +460 -254
- package/dist/{index-Cj49F892.d.ts → index-D_hzxD8w.d.cts} +60 -23
- package/dist/{index-CgHqxdps.d.ts → index-DpC-mDlV.d.ts} +196 -114
- package/dist/{index-G1uwGGWQ.d.ts → index-cHvbYgJI.d.cts} +34 -19
- package/dist/index.cjs +42 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -14
- package/dist/index.d.ts +14 -14
- package/dist/index.js +82 -54
- package/dist/{masks-DYbE485J.d.ts → masks-C8TWLFIi.d.cts} +49 -2
- package/dist/{masks-DYbE485J.d.cts → masks-O73Rhj5d.d.ts} +49 -2
- package/dist/model/index.cjs +19 -12
- package/dist/model/index.cjs.map +1 -1
- package/dist/model/index.d.cts +502 -181
- package/dist/model/index.d.ts +502 -181
- package/dist/model/index.js +18 -11
- package/dist/{positional-Cptlj-xs.d.ts → positional-DJgs6ltD.d.ts} +85 -8
- package/dist/{positional-DvH_sd8u.d.cts → positional-DMZer-FM.d.cts} +85 -8
- package/dist/theory/index.cjs +35 -6
- package/dist/theory/index.cjs.map +1 -1
- package/dist/theory/index.d.cts +257 -62
- package/dist/theory/index.d.ts +257 -62
- package/dist/theory/index.js +41 -12
- package/package.json +6 -5
- package/dist/chunk-3JXCW6DX.cjs +0 -3220
- package/dist/chunk-3JXCW6DX.cjs.map +0 -1
- package/dist/chunk-4A2RMUCC.js.map +0 -1
- package/dist/chunk-6XPTBE7Y.cjs +0 -49
- package/dist/chunk-6XPTBE7Y.cjs.map +0 -1
- package/dist/chunk-AFM2ULJH.cjs.map +0 -1
- package/dist/chunk-E3F4AHAH.cjs.map +0 -1
- package/dist/chunk-ELCTZUJJ.js +0 -379
- package/dist/chunk-ELCTZUJJ.js.map +0 -1
- package/dist/chunk-FVSI36UV.js.map +0 -1
- package/dist/chunk-GOZG57ER.js +0 -3220
- package/dist/chunk-GOZG57ER.js.map +0 -1
- package/dist/chunk-H3VORETI.js.map +0 -1
- package/dist/chunk-H42UHPYW.js +0 -1577
- package/dist/chunk-H42UHPYW.js.map +0 -1
- package/dist/chunk-HFPS7JFD.js +0 -1
- package/dist/chunk-INHVXP6Z.js.map +0 -1
- package/dist/chunk-K4ZJUGF4.cjs +0 -379
- package/dist/chunk-K4ZJUGF4.cjs.map +0 -1
- package/dist/chunk-KNJEKLKV.js +0 -49
- package/dist/chunk-KNJEKLKV.js.map +0 -1
- package/dist/chunk-M4CWTJWJ.cjs.map +0 -1
- package/dist/chunk-MXO72PLY.cjs.map +0 -1
- package/dist/chunk-NLEU4QSE.cjs +0 -360
- package/dist/chunk-NLEU4QSE.cjs.map +0 -1
- package/dist/chunk-OE6WK2Y2.cjs +0 -1577
- package/dist/chunk-OE6WK2Y2.cjs.map +0 -1
- package/dist/chunk-Q2WGKJNN.cjs.map +0 -1
- package/dist/chunk-RHIJ3S4I.cjs +0 -1
- package/dist/chunk-RHIJ3S4I.cjs.map +0 -1
- package/dist/chunk-TTCLJX6D.js.map +0 -1
- package/dist/chunk-UADYAYAT.cjs.map +0 -1
- package/dist/chunk-VOHZB45S.js.map +0 -1
- package/dist/chunk-VTI6FOLB.js.map +0 -1
- package/dist/chunk-WWURE4XT.cjs.map +0 -1
- package/dist/chunk-YH3BIKHH.js.map +0 -1
- /package/dist/{chunk-HFPS7JFD.js.map → chunk-K6OZXIR6.js.map} +0 -0
package/dist/generate/index.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
3
|
-
import { e as ChordSegment, c as ChordLike, K as KeyLike } from '../
|
|
4
|
-
export { b as ChordData, d as ChordQuality, g as ChordSpan,
|
|
5
|
-
export { B as BorrowedSource, e as ChordTimeline, H as HarmonicFunction } from '../index-
|
|
6
|
-
import { f as StringedProfile, P as PercussionProfile, c as Limb } from '../positional-
|
|
7
|
-
export { I as InstrumentProfile, a as InstrumentProfileCommon, d as PositionalRng, S as SeedPath } from '../positional-
|
|
8
|
-
import {
|
|
9
|
-
export {
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { h as NoteEvent, a as Articulation, b as IntervalLike } from '../index-Cy15oTvh.js';
|
|
2
|
+
export { I as IntervalData, c as IntervalQualityLabel, e as KeyScale, g as NoteData, S as SpelledInterval } from '../index-Cy15oTvh.js';
|
|
3
|
+
import { e as ChordSegment, c as ChordLike, K as KeyLike } from '../coerce-wwdELNYS.js';
|
|
4
|
+
export { b as ChordData, d as ChordQuality, g as ChordSpan, i as ChordToneRole, k as KeyVariant, l as PitchSpelling, m as ProfileWeights, n as ResolvedKey, q as SpelledKeyLike, r as SpelledKeyScale } from '../coerce-wwdELNYS.js';
|
|
5
|
+
export { B as BorrowedSource, e as ChordTimeline, H as HarmonicFunction } from '../index-BpWOhkkE.js';
|
|
6
|
+
import { f as StringedProfile, P as PercussionProfile, c as Limb } from '../positional-DJgs6ltD.js';
|
|
7
|
+
export { I as InstrumentProfile, a as InstrumentProfileCommon, d as PositionalRng, S as SeedPath } from '../positional-DJgs6ltD.js';
|
|
8
|
+
import { b as MeterLike } from '../index-Ci3xyows.js';
|
|
9
|
+
export { M as MeterChange, c as MeterMap, T as TimeSignature } from '../index-Ci3xyows.js';
|
|
10
|
+
export { H as HarmonyRole } from '../index-CnIdP4EZ.js';
|
|
11
|
+
import { r as Genre, q as GenerationContextInput, a4 as Vocabulary, s as GridEvent, m as DrumStyle, $ as Section, n as DrumVoice, t as GrooveFeel, k as DrumHit, H as HarmonizeOptions, y as HarmonizeResult } from '../index-DpC-mDlV.js';
|
|
12
|
+
export { B as BAR_STEPS, a as BASS_STYLES, b as BEAT_STEPS, c as BORROWED_DEGREES, d as BassLineOptions, e as BassSegment, f as BassStyle, g as BorrowedChord, C as Complexity, h as CounterMelodyOptions, D as DRUM_NOTES, i as DeformOptions, j as Draw, l as DrumRole, o as DrumsOptions, E as EuclideanKick, G as GENRES, p as GenerationContext, u as GrooveSlot, v as GrooveStyle, w as GrooveTemplate, x as HarmonizePlacement, z as HumanizeOptions, M as MelodyNote, A as MotifCell, F as MotifContour, I as MotifNote, J as MotifOptions, K as MotifTransform, O as ORNAMENT_STYLES, L as OrnamentOptions, N as OrnamentStyle, P as PROVENANCE_BASES, Q as ProgFunction, R as ProgStyle, S as ProgressionDegree, T as ProgressionOptions, U as ProgressionPreset, V as Provenance, W as ProvenanceBasis, X as ResolvedContext, Y as RhythmEvent, Z as RhythmOptions, _ as STEP_BEATS, a0 as SubstituteOptions, a1 as Substitution, a2 as SubstitutionType, a3 as SyncopateOptions, a5 as VocabularyQuery, a6 as applyGrooveTemplate, a7 as assertVocabulary, a8 as deform, a9 as developMotif, aa as double, ab as doubleTime, ac as drumVoiceOf, ad as extractGrooveTemplate, ae as fitsQuery, af as generateBassLine, ag as generateCounterMelody, ah as generateDrums, ai as generateMotif, aj as generateProgression, ak as generateRhythm, al as gridMetricWeight, am as halfTime, an as humanize, ao as mergeVocabulary, ap as modalInterchangePalette, aq as motifToNoteEvents, ar as negativeHarmonyMirror, as as onsetWeightCurve, at as ornament, au as ornamentBy, av as pickProgressionPreset, aw as pickVocabulary, ax as progressions, ay as progressionsByStyle, az as resolveContext, aA as rhythmDensity, aB as rhythmToNoteEvents, aC as selectVocabulary, aD as substituteChord, aE as syncopate, aF as thin, aG as transformMotif, aH as vocabularyOfKind, aI as withinCeiling } from '../index-DpC-mDlV.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* The playing-difficulty ceiling, as the generators apply it.
|
|
@@ -47,65 +48,15 @@ declare function sustainsStrokes(stepBeats: number, bpm: number | undefined, dif
|
|
|
47
48
|
declare function sustainsShift(semitones: number, stepBeats: number, bpm: number | undefined, difficulty: number | undefined): boolean;
|
|
48
49
|
|
|
49
50
|
/**
|
|
50
|
-
*
|
|
51
|
-
* chord-relative degrees and beat positions and deformed to fit the progression
|
|
52
|
-
* actually in front of them.
|
|
51
|
+
* Lay the figures of the dictionary over a chord progression.
|
|
53
52
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
53
|
+
* A segment takes a figure its genre plays, chosen by a draw addressed to that
|
|
54
|
+
* segment, and the figure's degrees are read against the chord sounding under
|
|
55
|
+
* it. What the figures are is `licks-data.ts`; which pitch a degree asks for is
|
|
56
|
+
* `degrees.ts`. This module is what places them: which segment takes one, how
|
|
57
|
+
* it is fitted to the span, and how one figure leads into the next.
|
|
58
58
|
*/
|
|
59
59
|
|
|
60
|
-
/**
|
|
61
|
-
* One note of a lick, relative to the chord it is played over.
|
|
62
|
-
*
|
|
63
|
-
* A degree is 1-based and counts up from the chord's root: 1 is the root, 3 the
|
|
64
|
-
* third, 8 the octave. Degrees the chord itself names — the third, fifth and
|
|
65
|
-
* seventh — are taken from the chord, so the same figure comes out major over a
|
|
66
|
-
* major chord and minor over a minor one; the rest are taken from the key. That
|
|
67
|
-
* is what lets a figure be written once and fit a whole progression.
|
|
68
|
-
*
|
|
69
|
-
* @category Composition
|
|
70
|
-
*/
|
|
71
|
-
type LickNote = GridEvent & {
|
|
72
|
-
/** Chord degree, 1-based; 8 is the octave above the root. */
|
|
73
|
-
degree: number;
|
|
74
|
-
/** Chromatic alteration in semitones, for a flattened or raised degree. */
|
|
75
|
-
alter?: number;
|
|
76
|
-
/** Sounding length in sixteenths; one step when absent. */
|
|
77
|
-
lengthSteps?: number;
|
|
78
|
-
/** How the note is played, when it is more than a plain note. */
|
|
79
|
-
articulation?: Articulation;
|
|
80
|
-
};
|
|
81
|
-
/**
|
|
82
|
-
* A lick: its notes and how long the whole figure lasts.
|
|
83
|
-
*
|
|
84
|
-
* @category Composition
|
|
85
|
-
*/
|
|
86
|
-
type LickMaterial = {
|
|
87
|
-
/** Length of the figure in sixteenths. */
|
|
88
|
-
lengthSteps: number;
|
|
89
|
-
notes: LickNote[];
|
|
90
|
-
};
|
|
91
|
-
/**
|
|
92
|
-
* A lick with the conditions it fits.
|
|
93
|
-
*
|
|
94
|
-
* @category Composition
|
|
95
|
-
*/
|
|
96
|
-
type BassLick = Vocabulary<LickMaterial>;
|
|
97
|
-
/**
|
|
98
|
-
* Whether a caller's material is a bass lick.
|
|
99
|
-
*
|
|
100
|
-
* @category Composition
|
|
101
|
-
*/
|
|
102
|
-
declare function isLickMaterial(material: unknown): material is LickMaterial;
|
|
103
|
-
/**
|
|
104
|
-
* The built-in bass licks, in declaration order.
|
|
105
|
-
*
|
|
106
|
-
* @category Composition
|
|
107
|
-
*/
|
|
108
|
-
declare const BASS_LICKS: readonly BassLick[];
|
|
109
60
|
/**
|
|
110
61
|
* Options controlling {@link placeLicks}.
|
|
111
62
|
*
|
|
@@ -122,8 +73,8 @@ type PlaceLicksOptions = {
|
|
|
122
73
|
* `ctx: { complexity: { difficulty } }`; the context wins over both.
|
|
123
74
|
*/
|
|
124
75
|
difficulty?: number;
|
|
125
|
-
/** Time signature; defaults to 4/4. */
|
|
126
|
-
ts?:
|
|
76
|
+
/** Time signature, in any form that names one; defaults to 4/4. */
|
|
77
|
+
ts?: MeterLike;
|
|
127
78
|
/**
|
|
128
79
|
* Target register as a base MIDI octave; roots land around `octave*12+12`.
|
|
129
80
|
*
|
|
@@ -147,9 +98,10 @@ type PlaceLicksOptions = {
|
|
|
147
98
|
*/
|
|
148
99
|
ctx?: GenerationContextInput;
|
|
149
100
|
/**
|
|
150
|
-
* Maximum number of segments {@link placeLicks} may lay figures over
|
|
151
|
-
* figure is placed per segment, so
|
|
152
|
-
*
|
|
101
|
+
* Maximum number of segments {@link placeLicks} may lay figures over, and of
|
|
102
|
+
* bars those segments span. One figure is placed per bar of a segment, so
|
|
103
|
+
* both are counted: this is the guard against an unbounded caller — a segment
|
|
104
|
+
* running to a beat far past the music — rather than a limit on any search.
|
|
153
105
|
*
|
|
154
106
|
* @defaultValue 1000000
|
|
155
107
|
*/
|
|
@@ -171,8 +123,10 @@ type PlaceLicksOptions = {
|
|
|
171
123
|
* key name such as `'C major'` is read as that key.
|
|
172
124
|
* @param opts Genre, density, ceiling and seed.
|
|
173
125
|
* @returns Bass notes sorted by onset, non-overlapping.
|
|
174
|
-
* @throws If a segment has a non-positive duration,
|
|
175
|
-
* this library names.
|
|
126
|
+
* @throws If a segment has a non-positive duration, two segments overlap, or
|
|
127
|
+
* the genre is not one this library names. A bass part is monophonic, so
|
|
128
|
+
* overlapping segments are refused here exactly as {@link generateBassLine}
|
|
129
|
+
* refuses them rather than being laid over each other.
|
|
176
130
|
*
|
|
177
131
|
* @example
|
|
178
132
|
* ```ts
|
|
@@ -190,6 +144,74 @@ declare function placeLicks(timeline: readonly (Omit<ChordSegment, 'chord'> & {
|
|
|
190
144
|
chord: ChordLike;
|
|
191
145
|
})[], key: KeyLike, opts: PlaceLicksOptions): NoteEvent[];
|
|
192
146
|
|
|
147
|
+
/**
|
|
148
|
+
* The bass lick dictionary: the figures a bass player reaches for, held as
|
|
149
|
+
* chord-relative degrees and beat positions and deformed to fit the progression
|
|
150
|
+
* actually in front of them.
|
|
151
|
+
*
|
|
152
|
+
* Provenance: no entry reproduces a bass line from a particular song. Each is a
|
|
153
|
+
* figure that belongs to nobody — the descending soul walk-down, the octave
|
|
154
|
+
* slap, the boogie shuffle — of the kind every player of that music already
|
|
155
|
+
* plays, and each records the ground it qualifies under.
|
|
156
|
+
*/
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* One note of a lick, relative to the chord it is played over.
|
|
160
|
+
*
|
|
161
|
+
* A degree is 1-based and counts up from the chord's root: 1 is the root, 3 the
|
|
162
|
+
* third, 8 the octave. Degrees the chord itself names — the third, fifth and
|
|
163
|
+
* seventh — are taken from the chord, so the same figure comes out major over a
|
|
164
|
+
* major chord and minor over a minor one. A degree the chord's quality settles
|
|
165
|
+
* without stating it follows the quality: the third of a suspended chord is the
|
|
166
|
+
* tone the suspension put there, and a seventh chord's remaining degrees are
|
|
167
|
+
* its own chord scale's. Only what the harmony leaves open is taken from the
|
|
168
|
+
* key. That is what lets a figure be written once and fit a whole progression.
|
|
169
|
+
*
|
|
170
|
+
* @category Composition
|
|
171
|
+
*/
|
|
172
|
+
type LickNote = GridEvent & {
|
|
173
|
+
/** Chord degree, 1-based; 8 is the octave above the root. */
|
|
174
|
+
degree: number;
|
|
175
|
+
/** Chromatic alteration in semitones, for a flattened or raised degree. */
|
|
176
|
+
alter?: number;
|
|
177
|
+
/**
|
|
178
|
+
* Sounding length in sixteenths. Absent, the note sounds to the next onset,
|
|
179
|
+
* as a line written by {@link generateBassLine} does: the built-in figures
|
|
180
|
+
* name no length, so a figure is legato unless it says otherwise.
|
|
181
|
+
*/
|
|
182
|
+
lengthSteps?: number;
|
|
183
|
+
/** How the note is played, when it is more than a plain note. */
|
|
184
|
+
articulation?: Articulation;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* A lick: its notes and how long the whole figure lasts.
|
|
188
|
+
*
|
|
189
|
+
* @category Composition
|
|
190
|
+
*/
|
|
191
|
+
type LickMaterial = {
|
|
192
|
+
/** Length of the figure in sixteenths. */
|
|
193
|
+
lengthSteps: number;
|
|
194
|
+
notes: LickNote[];
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* A lick with the conditions it fits.
|
|
198
|
+
*
|
|
199
|
+
* @category Composition
|
|
200
|
+
*/
|
|
201
|
+
type BassLick = Vocabulary<LickMaterial>;
|
|
202
|
+
/**
|
|
203
|
+
* Whether a caller's material is a bass lick.
|
|
204
|
+
*
|
|
205
|
+
* @category Composition
|
|
206
|
+
*/
|
|
207
|
+
declare function isLickMaterial(material: unknown): material is LickMaterial;
|
|
208
|
+
/**
|
|
209
|
+
* The built-in bass licks, in declaration order.
|
|
210
|
+
*
|
|
211
|
+
* @category Composition
|
|
212
|
+
*/
|
|
213
|
+
declare const BASS_LICKS: readonly BassLick[];
|
|
214
|
+
|
|
193
215
|
/**
|
|
194
216
|
* Imitative entries: a second voice restating what the first has just sung.
|
|
195
217
|
*
|
|
@@ -207,8 +229,10 @@ declare const IMITATION_ANSWERS: readonly ["real", "tonal"];
|
|
|
207
229
|
*
|
|
208
230
|
* A `real` answer transposes literally, keeping every interval of the subject
|
|
209
231
|
* and leaving the key where the interval puts it. A `tonal` answer counts scale
|
|
210
|
-
* degrees instead, so the answer stays in the key
|
|
211
|
-
*
|
|
232
|
+
* degrees instead, so the answer stays in the key: every interval keeps the
|
|
233
|
+
* number of degrees it spanned in the subject, and only its quality changes as
|
|
234
|
+
* the key's own pattern of steps and half steps asks — a major third answered by
|
|
235
|
+
* a minor one.
|
|
212
236
|
*
|
|
213
237
|
* @category Composition
|
|
214
238
|
*/
|
|
@@ -280,7 +304,9 @@ type ImitationOptions = {
|
|
|
280
304
|
* @param opts Where the answer enters, at what interval, and in what key.
|
|
281
305
|
* @returns The imitation as note events sorted by onset; `[]` when the chosen
|
|
282
306
|
* span holds no sounding notes. Notes with a zero or negative duration never
|
|
283
|
-
* sound and are not copied, so the answer can be shorter than the span.
|
|
307
|
+
* sound and are not copied, so the answer can be shorter than the span. Every
|
|
308
|
+
* other field of a copied note — its articulation, and its velocity through
|
|
309
|
+
* `velocityScale` — comes across with it.
|
|
284
310
|
* @throws If the span is reversed, the answer is not a known kind, or a
|
|
285
311
|
* transposed pitch leaves the MIDI range.
|
|
286
312
|
* @example
|
|
@@ -344,9 +370,14 @@ type FillArchetype = {
|
|
|
344
370
|
/** Strokes per beat of the bar, indexed 0..3. */
|
|
345
371
|
atBeat: readonly (readonly FillStroke[])[];
|
|
346
372
|
/**
|
|
347
|
-
* Whether
|
|
348
|
-
*
|
|
349
|
-
*
|
|
373
|
+
* Whether the archetype stops where its own strokes stop, rather than holding
|
|
374
|
+
* its last beat over the beats of the bar it does not write.
|
|
375
|
+
*
|
|
376
|
+
* It answers for an archetype shorter than the bar it is placed in, so the
|
|
377
|
+
* built-in archetypes — written beat by beat against the four-beat bar
|
|
378
|
+
* {@link generateDrums} accepts — are unaffected by it; a caller's archetype
|
|
379
|
+
* that writes fewer beats is where it decides anything. Most figures read
|
|
380
|
+
* naturally when held, but a half-time gesture is bar-long and stops there.
|
|
350
381
|
*/
|
|
351
382
|
boundToBar?: boolean;
|
|
352
383
|
};
|
|
@@ -425,6 +456,11 @@ declare const KICK_FIGURES: Readonly<Record<DrumStyle, KickFigure>>;
|
|
|
425
456
|
* hand at the same instant is what makes a pattern unplayable, and a voice no
|
|
426
457
|
* limb reaches is not on the kit at all.
|
|
427
458
|
*
|
|
459
|
+
* The auxiliary percussion — hand-claps, tambourine, shaker — is dubbed over
|
|
460
|
+
* the kit on a pass of its own, so it sounds through a backbeat whose snare and
|
|
461
|
+
* hi-hat already take both hands, and the four limbs stay the bound on the
|
|
462
|
+
* groove itself.
|
|
463
|
+
*
|
|
428
464
|
* @example
|
|
429
465
|
* ```ts
|
|
430
466
|
* import { DRUM_KIT, generateDrums, playability } from '@libraz/libcantus';
|
|
@@ -511,8 +547,8 @@ type DrumPatternOptions = {
|
|
|
511
547
|
genre: Genre;
|
|
512
548
|
/** Section the pattern plays in, matched against each entry's own sections. */
|
|
513
549
|
section?: Section;
|
|
514
|
-
/** Time signature; defaults to 4/4. */
|
|
515
|
-
ts?:
|
|
550
|
+
/** Time signature, in any form that names one; defaults to 4/4. */
|
|
551
|
+
ts?: MeterLike;
|
|
516
552
|
/**
|
|
517
553
|
* The generation context. `bpm` is the tempo, `complexity.rhythmic` thins the
|
|
518
554
|
* figure below its middle setting and syncopates it above,
|
|
@@ -631,6 +667,54 @@ type ClassifiedMelodyTone = {
|
|
|
631
667
|
* ```
|
|
632
668
|
* @category Reharmonization
|
|
633
669
|
*/
|
|
634
|
-
declare function classifyMelodyTones(melody: readonly NoteEvent[], ts:
|
|
670
|
+
declare function classifyMelodyTones(melody: readonly NoteEvent[], ts: MeterLike): ClassifiedMelodyTone[];
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* Harmonize a melody with a min-cost chord progression.
|
|
674
|
+
*
|
|
675
|
+
* The melody's ornaments are classified first, from the melody and the metre
|
|
676
|
+
* alone (see {@link classifyMelodyTones}); the chords then have to explain the
|
|
677
|
+
* structural tones only, so a passing tone no longer buys itself a chord. The
|
|
678
|
+
* melody is segmented by `harmonicRhythm`; each segment is scored against the
|
|
679
|
+
* candidate chords the harmonic dial opens — the key's own triads, then the
|
|
680
|
+
* secondary dominants, then the parallel mode's chords, one at a time as
|
|
681
|
+
* `ctx.complexity.harmonic` rises from 0 to 1 — by the fit of those structural
|
|
682
|
+
* tones, and a Viterbi search picks the lowest-cost path using a
|
|
683
|
+
* functional-flow transition cost and a cadence bonus at the end of the melody
|
|
684
|
+
* it is given — one cadence, at the close, unless `phraseEnds` names the closes
|
|
685
|
+
* inside a longer line, and then one at each of them as well. Runs of the same
|
|
686
|
+
* chord are reported once, so the chord count follows the harmony rather than
|
|
687
|
+
* the grid.
|
|
688
|
+
*
|
|
689
|
+
* With `placement.transposeSearch` the melody is moved into the key it is
|
|
690
|
+
* harmonized in, and `transposeSemitones` reports how far; with
|
|
691
|
+
* `placement.octaveSearch` it is moved by octaves into a comfortable register,
|
|
692
|
+
* which leaves the key and the chords untouched. Both may be set, and the
|
|
693
|
+
* reported shift is their sum.
|
|
694
|
+
*
|
|
695
|
+
* The `seed` drives a deterministic tie-break only: it perturbs candidates by a
|
|
696
|
+
* magnitude far below any real cost difference (see `TIE_BREAK_JITTER`),
|
|
697
|
+
* so it can decide between chords or paths of otherwise-equal cost but never
|
|
698
|
+
* overrides melody fit or functional flow. For a well-determined melody the
|
|
699
|
+
* result is identical across seeds; the same seed always yields the same result.
|
|
700
|
+
*
|
|
701
|
+
* @param opts The melody and, optionally, the generation context, key, harmonic
|
|
702
|
+
* rhythm, reharmonization strength, placement search, meter, and seed. Only
|
|
703
|
+
* `melody` is required.
|
|
704
|
+
* @returns The chosen transpose, key, chord path, and per-note roles.
|
|
705
|
+
* @example
|
|
706
|
+
* ```ts
|
|
707
|
+
* import { harmonizeMelody } from '@libraz/libcantus';
|
|
708
|
+
* const result = harmonizeMelody({
|
|
709
|
+
* melody: [
|
|
710
|
+
* { pitch: 60, startBeat: 0, durationBeat: 1 },
|
|
711
|
+
* { pitch: 64, startBeat: 1, durationBeat: 1 },
|
|
712
|
+
* ],
|
|
713
|
+
* });
|
|
714
|
+
* result.chords; // one ChordSpan per chord change, on the harmonic-rhythm grid
|
|
715
|
+
* ```
|
|
716
|
+
* @category Reharmonization
|
|
717
|
+
*/
|
|
718
|
+
declare function harmonizeMelody(opts: HarmonizeOptions): HarmonizeResult;
|
|
635
719
|
|
|
636
|
-
export { Articulation, BASS_LICKS, type BassLick, ChordLike, ChordSegment, type ClassifiedMelodyTone, DRUM_KIT, DRUM_PATTERNS, DrumHit, type DrumPattern, type DrumPatternOptions, type DrumStroke, DrumStyle, type DrumVocabulary, DrumVoice, FILL_ARCHETYPES, FILL_TYPES, type FillArchetype, type FillStroke, type FillType, type FillVelocity, GenerationContextInput, Genre, GridEvent, GrooveFeel, type ImitationAnswer, type ImitationOptions, IntervalLike, KICK_FIGURES, KICK_STEPS, KeyLike, type KickFigure, type KickPattern, type KickSlot, type LickMaterial, type LickNote, Limb, MAX_DIFFICULTY, MIN_DIFFICULTY, type MelodyToneRole, NoteEvent, PercussionProfile, type PlaceLicksOptions, Section, StringedProfile,
|
|
720
|
+
export { Articulation, BASS_LICKS, type BassLick, ChordLike, ChordSegment, type ClassifiedMelodyTone, DRUM_KIT, DRUM_PATTERNS, DrumHit, type DrumPattern, type DrumPatternOptions, type DrumStroke, DrumStyle, type DrumVocabulary, DrumVoice, FILL_ARCHETYPES, FILL_TYPES, type FillArchetype, type FillStroke, type FillType, type FillVelocity, GenerationContextInput, Genre, GridEvent, GrooveFeel, HarmonizeOptions, HarmonizeResult, type ImitationAnswer, type ImitationOptions, IntervalLike, KICK_FIGURES, KICK_STEPS, KeyLike, type KickFigure, type KickPattern, type KickSlot, type LickMaterial, type LickNote, Limb, MAX_DIFFICULTY, MIN_DIFFICULTY, type MelodyToneRole, MeterLike, NoteEvent, PercussionProfile, type PlaceLicksOptions, Section, StringedProfile, Vocabulary, classifyMelodyTones, harmonizeMelody, imitate, isDrumPattern, isFillArchetype, isLickMaterial, placeDrumPattern, placeLicks, sustainsShift, sustainsStrokes };
|
package/dist/generate/index.js
CHANGED
|
@@ -66,13 +66,13 @@ import {
|
|
|
66
66
|
transformMotif,
|
|
67
67
|
vocabularyOfKind,
|
|
68
68
|
withinCeiling
|
|
69
|
-
} from "../chunk-
|
|
70
|
-
import "../chunk-
|
|
71
|
-
import "../chunk-
|
|
72
|
-
import "../chunk-
|
|
73
|
-
import "../chunk-
|
|
74
|
-
import "../chunk-
|
|
75
|
-
import "../chunk-
|
|
69
|
+
} from "../chunk-R5VUXQMP.js";
|
|
70
|
+
import "../chunk-VLE5R7PF.js";
|
|
71
|
+
import "../chunk-X6RJAHII.js";
|
|
72
|
+
import "../chunk-7GOKQJTQ.js";
|
|
73
|
+
import "../chunk-H66ARFU5.js";
|
|
74
|
+
import "../chunk-FPBZFNCD.js";
|
|
75
|
+
import "../chunk-PQL7E5F6.js";
|
|
76
76
|
export {
|
|
77
77
|
BAR_STEPS,
|
|
78
78
|
BASS_LICKS,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { e as StringFingering, c as Limb,
|
|
1
|
+
import { h as NoteEvent } from './index-Cy15oTvh.js';
|
|
2
|
+
import { e as StringFingering, c as Limb, b as InstrumentProfileLike } from './positional-DJgs6ltD.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* What makes a passage hard or impossible on an instrument.
|
|
@@ -89,6 +89,9 @@ type PlayabilityReport = {
|
|
|
89
89
|
* @param profile The instrument to play it on.
|
|
90
90
|
* @param bpm Tempo in quarter-note beats per minute; enables the third layer.
|
|
91
91
|
* @returns Difficulty, the issues found, and each note's string/fret or limb.
|
|
92
|
+
* @throws If the notes are not note events, the tempo is not a finite positive
|
|
93
|
+
* number of beats per minute, or the profile describes no instrument — a neck
|
|
94
|
+
* with no strings or a kit no limb reaches, whatever the passage holds.
|
|
92
95
|
*
|
|
93
96
|
* @example
|
|
94
97
|
* ```ts
|
|
@@ -98,7 +101,7 @@ type PlayabilityReport = {
|
|
|
98
101
|
* ```
|
|
99
102
|
* @category Core
|
|
100
103
|
*/
|
|
101
|
-
declare function playability(notes: readonly NoteEvent[], profile:
|
|
104
|
+
declare function playability(notes: readonly NoteEvent[], profile: InstrumentProfileLike, bpm?: number): PlayabilityReport;
|
|
102
105
|
|
|
103
106
|
/**
|
|
104
107
|
* Note values: the written durations a score shows — a base value, its
|
|
@@ -176,7 +179,8 @@ type SpelledDuration = {
|
|
|
176
179
|
* import { durationToBeats } from '@libraz/libcantus';
|
|
177
180
|
* durationToBeats('quarter'); // 1
|
|
178
181
|
* durationToBeats({ base: 'quarter', dots: 1 }); // 1.5
|
|
179
|
-
* durationToBeats({ base: 'eighth', tuplet: { actual: 3, normal: 2 } }); // 1
|
|
182
|
+
* durationToBeats({ base: 'eighth', tuplet: { actual: 3, normal: 2 } }) * 3; // 1 — three
|
|
183
|
+
* // eighth-note triplets fill the beat two eighths would
|
|
180
184
|
* ```
|
|
181
185
|
* @category Rhythm & Meter
|
|
182
186
|
*/
|
|
@@ -192,8 +196,10 @@ declare function durationToBeats(duration: NoteValue | DurationData, options?: {
|
|
|
192
196
|
* values are preferred to dotted ones and both to tuplets, and within the
|
|
193
197
|
* tuplets triplets come before quintuplets and septuplets.
|
|
194
198
|
*
|
|
195
|
-
* Lengths are matched within 1e-6
|
|
196
|
-
* still reads as a triplet.
|
|
199
|
+
* Lengths are matched within 1e-6 quarter notes, so a rounded decimal such as
|
|
200
|
+
* 0.3333333 still reads as a triplet. The tolerance is measured in quarter
|
|
201
|
+
* notes whatever `beatUnit` names, so a longer beat unit narrows it in
|
|
202
|
+
* proportion: under `{ beatUnit: 'whole' }` it is 2.5e-7 of a beat.
|
|
197
203
|
*
|
|
198
204
|
* @param beats The length in beats.
|
|
199
205
|
* @param options `beatUnit` sets what one beat is; a quarter note by default.
|
|
@@ -219,9 +225,12 @@ declare function beatsToDuration(beats: number, options?: {
|
|
|
219
225
|
* else is broken into undotted values, longest first, and a value immediately
|
|
220
226
|
* followed by its own half is then written as a dot instead: 5 beats reads as a
|
|
221
227
|
* whole note tied to a quarter, and 1.9375 beats as a double-dotted quarter tied
|
|
222
|
-
* to a dotted thirty-second. The
|
|
223
|
-
*
|
|
224
|
-
*
|
|
228
|
+
* to a dotted thirty-second. The dot is only written where it leaves the chain
|
|
229
|
+
* in longest-first order, so 10 beats reads as two whole notes tied to a half
|
|
230
|
+
* rather than as a whole note tied to a longer dotted whole. The chain knows
|
|
231
|
+
* nothing of barlines or beat grouping — an engraver splits further at those —
|
|
232
|
+
* and it uses no tuplets, so a length off the plain grid and with no single
|
|
233
|
+
* spelling has no chain either.
|
|
225
234
|
*
|
|
226
235
|
* @param beats The length in beats.
|
|
227
236
|
* @param options `beatUnit` sets what one beat is; a quarter note by default.
|
|
@@ -246,16 +255,18 @@ declare function beatsToTiedDurations(beats: number, options?: {
|
|
|
246
255
|
* @category Core
|
|
247
256
|
*/
|
|
248
257
|
type IndexedNoteEvent = {
|
|
249
|
-
note: Readonly<NoteEvent>;
|
|
250
|
-
originalIndex: number;
|
|
251
|
-
endBeat: number;
|
|
258
|
+
readonly note: Readonly<NoteEvent>;
|
|
259
|
+
readonly originalIndex: number;
|
|
260
|
+
readonly endBeat: number;
|
|
252
261
|
};
|
|
253
262
|
/**
|
|
254
263
|
* Which note wins when several sound from the same onset.
|
|
255
264
|
*
|
|
256
265
|
* `'highest'` and `'lowest'` name a voice, so the answer does not depend on the
|
|
257
266
|
* order the caller happened to store the chord in; `'last'` takes the one
|
|
258
|
-
* latest in the input array.
|
|
267
|
+
* latest in the input array. Two notes of the same pitch name no voice apart,
|
|
268
|
+
* so both voice tie-breaks settle a unison on the lower `originalIndex` and
|
|
269
|
+
* name the same note.
|
|
259
270
|
*
|
|
260
271
|
* @category Core
|
|
261
272
|
*/
|
|
@@ -300,9 +311,10 @@ type NoteEventIndexOptions = {
|
|
|
300
311
|
name?: string;
|
|
301
312
|
};
|
|
302
313
|
/**
|
|
303
|
-
* Validate and stable-sort note events once, then expose
|
|
304
|
-
*
|
|
305
|
-
*
|
|
314
|
+
* Validate and stable-sort note events once, then expose onset and active-note
|
|
315
|
+
* lookups that cost `O(log n + k)`, where `k` is how many notes share the onset
|
|
316
|
+
* the answer comes from. Non-positive-duration notes may be retained for
|
|
317
|
+
* callers that intentionally filter them later, but never count as sounding.
|
|
306
318
|
*
|
|
307
319
|
* @category Core
|
|
308
320
|
*/
|
|
@@ -356,7 +368,8 @@ type TempoMap = readonly TempoEvent[];
|
|
|
356
368
|
* @param beat Position in quarter-note beats.
|
|
357
369
|
* @param map The tempo map; its first event is the time origin.
|
|
358
370
|
* @returns Elapsed seconds, 0 at the map's first event and negative before it.
|
|
359
|
-
* @throws If the map is empty, unsorted, or carries a
|
|
371
|
+
* @throws If the map is empty, unsorted, or carries a tempo outside 0.1..1000
|
|
372
|
+
* quarter-note beats per minute.
|
|
360
373
|
* @example
|
|
361
374
|
* ```ts
|
|
362
375
|
* import { beatsToSeconds } from '@libraz/libcantus';
|
|
@@ -433,7 +446,9 @@ declare function tempoAt(beat: number, map: TempoMap): number;
|
|
|
433
446
|
* back quantized.
|
|
434
447
|
*
|
|
435
448
|
* A position before the first downbeat is a negative tick count, which is how a
|
|
436
|
-
* pickup crosses the MIDI boundary and comes back.
|
|
449
|
+
* pickup crosses the MIDI boundary and comes back. A position that rounds to
|
|
450
|
+
* the downbeat from below comes back as positive zero: `-0` and `0` are the
|
|
451
|
+
* same tick, and only one of them keys as it under `Object.is`.
|
|
437
452
|
*
|
|
438
453
|
* @param beat Position or length in quarter-note beats.
|
|
439
454
|
* @param ppq Pulses (ticks) per quarter note, e.g. 96, 480, or 960.
|
|
@@ -628,7 +643,7 @@ declare function ratioToCents(numerator: number, denominator: number): number;
|
|
|
628
643
|
*
|
|
629
644
|
* @category Pitch & Intervals
|
|
630
645
|
*/
|
|
631
|
-
declare const JUST_RATIOS: Readonly<Record<
|
|
646
|
+
declare const JUST_RATIOS: Readonly<Record<0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12, readonly [number, number]>>;
|
|
632
647
|
/**
|
|
633
648
|
* Cents by which a five-limit just interval departs from its 12-TET tempering
|
|
634
649
|
* (positive means the just interval is wider).
|