@libraz/libcantus 0.9.0 → 0.9.2
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 +25 -2
- package/dist/analyze/index.cjs +1697 -0
- package/dist/analyze/index.cjs.map +1 -0
- package/dist/analyze/index.d.cts +429 -0
- package/dist/analyze/index.d.ts +429 -0
- package/dist/analyze/index.js +51 -0
- package/dist/analyze/index.js.map +1 -0
- package/dist/chunk-5HTNMQW4.js +653 -0
- package/dist/chunk-5HTNMQW4.js.map +1 -0
- package/dist/chunk-7Y7WF64D.js +410 -0
- package/dist/chunk-7Y7WF64D.js.map +1 -0
- package/dist/chunk-A4532ZFR.js +259 -0
- package/dist/chunk-A4532ZFR.js.map +1 -0
- package/dist/chunk-BHUT2S5G.js +22 -0
- package/dist/chunk-BHUT2S5G.js.map +1 -0
- package/dist/chunk-CCBLVAPK.js +42 -0
- package/dist/chunk-CCBLVAPK.js.map +1 -0
- package/dist/chunk-COKTX2G5.js +907 -0
- package/dist/chunk-COKTX2G5.js.map +1 -0
- package/dist/chunk-DYWFNC4A.js +152 -0
- package/dist/chunk-DYWFNC4A.js.map +1 -0
- package/dist/chunk-GQKN5KDT.js +159 -0
- package/dist/chunk-GQKN5KDT.js.map +1 -0
- package/dist/chunk-LN7ZZMD2.js +530 -0
- package/dist/chunk-LN7ZZMD2.js.map +1 -0
- package/dist/chunk-MSWFZF7J.js +118 -0
- package/dist/chunk-MSWFZF7J.js.map +1 -0
- package/dist/chunk-R3S2LUBH.js +2722 -0
- package/dist/chunk-R3S2LUBH.js.map +1 -0
- package/dist/chunk-SDM3VJJ5.js +41 -0
- package/dist/chunk-SDM3VJJ5.js.map +1 -0
- package/dist/chunk-XTC3X6MS.js +816 -0
- package/dist/chunk-XTC3X6MS.js.map +1 -0
- package/dist/chunk-ZXW5YIWK.js +55 -0
- package/dist/chunk-ZXW5YIWK.js.map +1 -0
- package/dist/core/index.cjs +432 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +210 -0
- package/dist/core/index.d.ts +210 -0
- package/dist/core/index.js +73 -0
- package/dist/core/index.js.map +1 -0
- package/dist/function-2bJW1Zp_.d.ts +187 -0
- package/dist/function-r2sh-jOO.d.cts +187 -0
- package/dist/generate/index.cjs +3787 -0
- package/dist/generate/index.cjs.map +1 -0
- package/dist/generate/index.d.cts +980 -0
- package/dist/generate/index.d.ts +980 -0
- package/dist/generate/index.js +52 -0
- package/dist/generate/index.js.map +1 -0
- package/dist/index-BMPxwjwV.d.ts +151 -0
- package/dist/index-BOBXBNwP.d.cts +157 -0
- package/dist/index-BdeQ1r_p.d.cts +56 -0
- package/dist/index-BreoJRw0.d.ts +127 -0
- package/dist/index-CGMZNCx6.d.cts +140 -0
- package/dist/index-CGMZNCx6.d.ts +140 -0
- package/dist/index-CM5W4rcm.d.ts +157 -0
- package/dist/index-CP3wAfEH.d.ts +56 -0
- package/dist/index-Cl7mhOFM.d.cts +164 -0
- package/dist/index-Cl7mhOFM.d.ts +164 -0
- package/dist/index-DZ1M21do.d.cts +127 -0
- package/dist/index-D_ZTUNKp.d.cts +151 -0
- package/dist/index.cjs +5277 -4893
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -2621
- package/dist/index.d.ts +14 -2621
- package/dist/index.js +170 -6152
- package/dist/index.js.map +1 -1
- package/dist/model/index.cjs +2435 -0
- package/dist/model/index.cjs.map +1 -0
- package/dist/model/index.d.cts +630 -0
- package/dist/model/index.d.ts +630 -0
- package/dist/model/index.js +21 -0
- package/dist/model/index.js.map +1 -0
- package/dist/styled-BjXtOFNk.d.cts +282 -0
- package/dist/styled-D7BAx3S3.d.ts +282 -0
- package/dist/theory/index.cjs +1677 -0
- package/dist/theory/index.cjs.map +1 -0
- package/dist/theory/index.d.cts +535 -0
- package/dist/theory/index.d.ts +535 -0
- package/dist/theory/index.js +149 -0
- package/dist/theory/index.js.map +1 -0
- package/dist/types-MGP29r3t.d.cts +30 -0
- package/dist/types-MGP29r3t.d.ts +30 -0
- package/package.json +31 -1
- package/src/analyze/arrange/index.ts +21 -0
- package/src/analyze/arrange/internal.ts +125 -0
- package/src/analyze/arrange/tension.ts +187 -0
- package/src/analyze/arrange/tracks.ts +279 -0
- package/src/{detect → analyze/detect}/index.ts +82 -23
- package/src/analyze/functional/borrowed.ts +84 -0
- package/src/analyze/functional/cadence.ts +66 -0
- package/src/analyze/functional/function.ts +184 -0
- package/src/analyze/functional/index.ts +23 -0
- package/src/analyze/functional/internal.ts +29 -0
- package/src/analyze/functional/roman.ts +393 -0
- package/src/analyze/index.ts +49 -0
- package/src/{timeline → analyze/timeline}/index.ts +87 -24
- package/src/{analysis → analyze/voice}/index.ts +81 -12
- package/src/core/index.ts +47 -0
- package/src/{interval → core/interval}/index.ts +15 -1
- package/src/{meter → core/meter}/index.ts +108 -5
- package/src/{pitch → core/pitch}/index.ts +58 -3
- package/src/{random → core/random}/index.ts +13 -1
- package/src/{tuning → core/tuning}/index.ts +28 -1
- package/src/{bass → generate/bass}/index.ts +66 -17
- package/src/{countermelody → generate/countermelody}/index.ts +54 -24
- package/src/{drums → generate/drums}/fills.ts +31 -20
- package/src/{drums → generate/drums}/index.ts +127 -9
- package/src/{drums → generate/drums}/internal.ts +7 -1
- package/src/{drums → generate/drums}/rng.ts +2 -2
- package/src/{drums → generate/drums}/swing.ts +7 -2
- package/src/{groove → generate/groove}/index.ts +118 -22
- package/src/{harmonize → generate/harmonize}/index.ts +96 -23
- package/src/generate/index.ts +59 -0
- package/src/{motif → generate/motif}/index.ts +94 -17
- package/src/{progression → generate/progression}/index.ts +61 -27
- package/src/{reharmony → generate/reharmony}/index.ts +46 -15
- package/src/{rhythm → generate/rhythm}/index.ts +47 -13
- package/src/index.ts +130 -116
- package/src/model/chord.ts +423 -0
- package/src/model/index.ts +5 -947
- package/src/model/interval.ts +82 -0
- package/src/model/key.ts +266 -0
- package/src/model/note.ts +176 -0
- package/src/model/progression.ts +161 -0
- package/src/model/shared.ts +12 -0
- package/src/{chord → theory/chord}/index.ts +85 -4
- package/src/{chordscale → theory/chordscale}/index.ts +67 -9
- package/src/{counterpoint → theory/counterpoint}/index.ts +23 -2
- package/src/{harmony → theory/harmony}/index.ts +19 -2
- package/src/theory/index.ts +107 -0
- package/src/{safety → theory/safety}/index.ts +59 -12
- package/src/theory/scale/degrees.ts +123 -0
- package/src/theory/scale/index.ts +28 -0
- package/src/theory/scale/key.ts +56 -0
- package/src/theory/scale/masks.ts +153 -0
- package/src/{spelling → theory/spelling}/index.ts +21 -3
- package/src/{symbol → theory/symbol}/index.ts +91 -36
- package/src/theory/voicing/index.ts +5 -0
- package/src/theory/voicing/internal.ts +168 -0
- package/src/theory/voicing/leading.ts +112 -0
- package/src/theory/voicing/satb.ts +195 -0
- package/src/theory/voicing/styled.ts +176 -0
- package/src/arrange/index.ts +0 -409
- package/src/functional/index.ts +0 -602
- package/src/scale/index.ts +0 -215
- package/src/voicing/index.ts +0 -523
- /package/src/{types.ts → core/types.ts} +0 -0
- /package/src/{drums → generate/drums}/beat.ts +0 -0
- /package/src/{drums → generate/drums}/euclid.ts +0 -0
- /package/src/{drums → generate/drums}/ghost.ts +0 -0
- /package/src/{drums → generate/drums}/hihat.ts +0 -0
- /package/src/{drums → generate/drums}/hit.ts +0 -0
- /package/src/{drums → generate/drums}/kick.ts +0 -0
- /package/src/{drums → generate/drums}/percussion.ts +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,2621 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* velocity. This is the library-wide interchange shape for note events read
|
|
16
|
-
* from or written to a DAW/MIDI track; the harmonizer's `MelodyNote` and the
|
|
17
|
-
* analysis `VoiceNote` are specializations of it.
|
|
18
|
-
*/
|
|
19
|
-
type NoteEvent = {
|
|
20
|
-
/** MIDI pitch (middle C = 60). */
|
|
21
|
-
pitch: number;
|
|
22
|
-
/** Onset in quarter-note beats, absolute from the start of the timeline. */
|
|
23
|
-
startBeat: number;
|
|
24
|
-
/** Duration in quarter-note beats. */
|
|
25
|
-
durationBeat: number;
|
|
26
|
-
/** MIDI velocity in [0, 127], when known. */
|
|
27
|
-
velocity?: number;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
/** Chord quality identifiers understood by the chord builder. */
|
|
31
|
-
type ChordQuality = 'maj' | 'min' | 'dim' | 'aug' | 'maj7' | 'min7' | 'dom7' | 'dim7' | 'm7b5' | 'minMaj7' | 'aug7' | 'augMaj7' | 'majb5' | '6' | 'min6' | '6/9' | 'sus2' | 'sus4' | 'add9' | 'add11' | 'maj9' | 'min9' | 'dom9' | '7b9' | '7#9' | '7#11' | '7b13' | '11' | '13' | '5';
|
|
32
|
-
/** A chord expressed as a root pitch class plus semitone offsets. */
|
|
33
|
-
type Chord$1 = {
|
|
34
|
-
rootPc: number;
|
|
35
|
-
quality: ChordQuality;
|
|
36
|
-
intervals: number[];
|
|
37
|
-
bassPc?: number;
|
|
38
|
-
};
|
|
39
|
-
/** All chord qualities the builder understands, longest templates last. */
|
|
40
|
-
declare function chordQualities(): ChordQuality[];
|
|
41
|
-
/**
|
|
42
|
-
* Build a chord rooted on a diatonic scale degree.
|
|
43
|
-
*
|
|
44
|
-
* The root pitch class is the degree's diatonic pitch class in `key`; the
|
|
45
|
-
* quality's interval template is attached unchanged. Degrees beyond the scale
|
|
46
|
-
* length wrap around.
|
|
47
|
-
*
|
|
48
|
-
* @param degree 0-based scale degree of the chord root.
|
|
49
|
-
* @param ext Chord quality to apply.
|
|
50
|
-
* @param key Key context supplying the diatonic root.
|
|
51
|
-
* @returns The constructed chord.
|
|
52
|
-
*/
|
|
53
|
-
declare function chordFromDegree(degree: number, ext: ChordQuality, key: KeyScale): Chord$1;
|
|
54
|
-
/**
|
|
55
|
-
* Build a chord from an explicit root pitch class and quality.
|
|
56
|
-
*
|
|
57
|
-
* @param rootPc Root pitch class (0..11).
|
|
58
|
-
* @param quality Chord quality supplying the interval template.
|
|
59
|
-
* @param bassPc Optional slash-chord bass pitch class.
|
|
60
|
-
* @returns The constructed chord.
|
|
61
|
-
*/
|
|
62
|
-
declare function makeChord(rootPc: number, quality: ChordQuality, bassPc?: number): Chord$1;
|
|
63
|
-
/**
|
|
64
|
-
* Get the sorted, deduplicated pitch classes of a chord.
|
|
65
|
-
*
|
|
66
|
-
* @param chord The chord to enumerate.
|
|
67
|
-
* @returns The chord's pitch classes, sorted ascending in [0, 11].
|
|
68
|
-
*/
|
|
69
|
-
declare function chordPitchClasses(chord: Chord$1): number[];
|
|
70
|
-
/**
|
|
71
|
-
* Determine a pitch's harmonic role within a chord.
|
|
72
|
-
*
|
|
73
|
-
* The role is derived from the pitch's interval above the chord root, reduced
|
|
74
|
-
* modulo 12. A major sixth (9) reads as a `sixth` for sixth chords but as a
|
|
75
|
-
* `seventh` for a diminished-seventh chord; ninths and other tensions have no
|
|
76
|
-
* basic role and return null.
|
|
77
|
-
*
|
|
78
|
-
* @param pitch MIDI pitch or bare pitch class.
|
|
79
|
-
* @param chord The chord providing the root reference.
|
|
80
|
-
* @returns The chord-tone role, or null if the pitch has no basic role.
|
|
81
|
-
*/
|
|
82
|
-
declare function chordToneRole(pitch: number, chord: Chord$1): 'root' | 'third' | 'fifth' | 'sixth' | 'seventh' | null;
|
|
83
|
-
/**
|
|
84
|
-
* Build the diatonic triad rooted on a scale degree by stacking scale thirds.
|
|
85
|
-
*
|
|
86
|
-
* Unlike {@link chordFromDegree}, the chord quality is derived from the scale
|
|
87
|
-
* rather than supplied, so degrees yield their scale-correct triads (e.g. a
|
|
88
|
-
* diminished triad on the leading tone of a major key). Intended for heptatonic
|
|
89
|
-
* scales; other scales stack by scale step regardless.
|
|
90
|
-
*
|
|
91
|
-
* @param degree 0-based scale degree of the chord root.
|
|
92
|
-
* @param key Key/scale context.
|
|
93
|
-
* @returns The diatonic triad.
|
|
94
|
-
*/
|
|
95
|
-
declare function diatonicTriad(degree: number, key: KeyScale): Chord$1;
|
|
96
|
-
/**
|
|
97
|
-
* Build the diatonic seventh chord rooted on a scale degree.
|
|
98
|
-
*
|
|
99
|
-
* @param degree 0-based scale degree of the chord root.
|
|
100
|
-
* @param key Key/scale context.
|
|
101
|
-
* @returns The diatonic seventh chord.
|
|
102
|
-
*/
|
|
103
|
-
declare function diatonicSeventh(degree: number, key: KeyScale): Chord$1;
|
|
104
|
-
|
|
105
|
-
/** Severity policy: `strict` counterpoint vs. lenient `pop` voice-leading. */
|
|
106
|
-
type SafetyProfile = 'strict' | 'pop';
|
|
107
|
-
/** Overall placeability verdict for a candidate pitch. */
|
|
108
|
-
declare enum NoteSafety {
|
|
109
|
-
Safe = 0,
|
|
110
|
-
Warning = 1,
|
|
111
|
-
Dissonant = 2
|
|
112
|
-
}
|
|
113
|
-
/** Bit flags describing why a pitch received its verdict. */
|
|
114
|
-
declare enum ReasonFlag {
|
|
115
|
-
ChordTone = 1,
|
|
116
|
-
Tension = 2,
|
|
117
|
-
AvoidNote = 4,
|
|
118
|
-
ScaleTone = 8,
|
|
119
|
-
NonScale = 16,
|
|
120
|
-
OutOfRange = 32,
|
|
121
|
-
Tritone = 64,
|
|
122
|
-
LargeLeap = 128,
|
|
123
|
-
MinorSecond = 256,
|
|
124
|
-
MajorSeventh = 512,
|
|
125
|
-
VerticalDissonance = 1024,
|
|
126
|
-
ParallelPerfect = 2048,
|
|
127
|
-
HiddenParallel = 4096,
|
|
128
|
-
VoiceCrossing = 8192,
|
|
129
|
-
Suspension = 16384,
|
|
130
|
-
NeedsResolution = 32768
|
|
131
|
-
}
|
|
132
|
-
/** A neighbouring voice's current and previous pitch. */
|
|
133
|
-
type VoiceSnapshot = {
|
|
134
|
-
pitch: number;
|
|
135
|
-
prevPitch?: number;
|
|
136
|
-
};
|
|
137
|
-
/** Everything needed to evaluate one candidate pitch. */
|
|
138
|
-
type SafetyQuery = {
|
|
139
|
-
profile: SafetyProfile;
|
|
140
|
-
candidatePitch: number;
|
|
141
|
-
prevPitch?: number;
|
|
142
|
-
chord: Chord$1 | null;
|
|
143
|
-
key: KeyScale;
|
|
144
|
-
otherVoices: VoiceSnapshot[];
|
|
145
|
-
strongBeat: boolean;
|
|
146
|
-
vocalLow?: number;
|
|
147
|
-
vocalHigh?: number;
|
|
148
|
-
};
|
|
149
|
-
/** The verdict, reason flags, and optional resolution guidance. */
|
|
150
|
-
type SafetyResult = {
|
|
151
|
-
safety: NoteSafety;
|
|
152
|
-
reasons: number;
|
|
153
|
-
resolveTo?: number;
|
|
154
|
-
suggestions?: number[];
|
|
155
|
-
rationale?: string;
|
|
156
|
-
};
|
|
157
|
-
/**
|
|
158
|
-
* Evaluate the safety of placing a candidate pitch in a voice.
|
|
159
|
-
*
|
|
160
|
-
* Reasons are merged from harmonic context (chord tone / tension / avoid / scale)
|
|
161
|
-
* and counterpoint (vertical dissonance, parallels, voice crossing). The `strict`
|
|
162
|
-
* profile treats avoid notes and parallels as dissonant; `pop` treats them as
|
|
163
|
-
* warnings. The final verdict is the worst severity among the reasons.
|
|
164
|
-
*
|
|
165
|
-
* @param q The candidate and its harmonic/voice-leading context.
|
|
166
|
-
* @returns The verdict, reason bitmask, and optional resolution guidance.
|
|
167
|
-
*/
|
|
168
|
-
declare function evaluateSafety(q: SafetyQuery): SafetyResult;
|
|
169
|
-
/**
|
|
170
|
-
* Enumerate placeable pitches in a range, chord tones first, descending.
|
|
171
|
-
*
|
|
172
|
-
* @param q The safety context minus the candidate pitch.
|
|
173
|
-
* @param pitchLow Lowest MIDI pitch to consider (inclusive).
|
|
174
|
-
* @param pitchHigh Highest MIDI pitch to consider (inclusive).
|
|
175
|
-
* @returns Placeable pitches (non-dissonant), chord tones before others, each group descending.
|
|
176
|
-
*/
|
|
177
|
-
declare function enumerateSafePitches(q: Omit<SafetyQuery, 'candidatePitch'>, pitchLow: number, pitchHigh: number): number[];
|
|
178
|
-
|
|
179
|
-
/** A theory annotation attached to a note. */
|
|
180
|
-
type TheoryLabel = {
|
|
181
|
-
kind: 'chordTone';
|
|
182
|
-
role: 'root' | 'third' | 'fifth' | 'sixth' | 'seventh';
|
|
183
|
-
} | {
|
|
184
|
-
kind: 'tension';
|
|
185
|
-
degree: 9 | 11 | 13;
|
|
186
|
-
} | {
|
|
187
|
-
kind: 'avoid';
|
|
188
|
-
} | {
|
|
189
|
-
kind: 'passing';
|
|
190
|
-
} | {
|
|
191
|
-
kind: 'neighbor';
|
|
192
|
-
} | {
|
|
193
|
-
kind: 'suspension';
|
|
194
|
-
type: 'sus4-3' | 'sus7-6' | 'sus9-8' | 'sus2-3';
|
|
195
|
-
resolveTo: number;
|
|
196
|
-
} | {
|
|
197
|
-
kind: 'anticipation';
|
|
198
|
-
} | {
|
|
199
|
-
kind: 'escape';
|
|
200
|
-
} | {
|
|
201
|
-
kind: 'needsResolution';
|
|
202
|
-
resolveTo: number;
|
|
203
|
-
} | {
|
|
204
|
-
kind: 'leadingTone';
|
|
205
|
-
resolveTo: number;
|
|
206
|
-
};
|
|
207
|
-
/** A note with its theory labels and a short rationale. */
|
|
208
|
-
type AnalyzedNote = {
|
|
209
|
-
noteId: number;
|
|
210
|
-
labels: TheoryLabel[];
|
|
211
|
-
rationale?: string;
|
|
212
|
-
};
|
|
213
|
-
/** A single note in a monophonic voice: a {@link NoteEvent} with a stable id. */
|
|
214
|
-
type VoiceNote = NoteEvent & {
|
|
215
|
-
id: number;
|
|
216
|
-
};
|
|
217
|
-
/**
|
|
218
|
-
* Label every note of a voice with its theory roles.
|
|
219
|
-
*
|
|
220
|
-
* Each note is classified against the chord sounding at its beat. Chord tones
|
|
221
|
-
* get a role label; non-chord tones are matched, in order, as suspensions
|
|
222
|
-
* (prepared by an identical consonant pitch and resolving by step), passing
|
|
223
|
-
* tones, neighbors, anticipations, and escape tones, then fall back to tension,
|
|
224
|
-
* avoid, or an unresolved-dissonance label. Leading-tone resolutions are noted
|
|
225
|
-
* additionally.
|
|
226
|
-
*
|
|
227
|
-
* @param voice The monophonic voice, in time order.
|
|
228
|
-
* @param chordAtBeat Chord sounding at a given beat, or null.
|
|
229
|
-
* @param key Key context for leading-tone detection.
|
|
230
|
-
* @param otherVoicesAtBeat Other sounding voices at a given beat.
|
|
231
|
-
* @returns One annotation per input note.
|
|
232
|
-
*/
|
|
233
|
-
declare function analyzeVoice(voice: VoiceNote[], chordAtBeat: (beat: number) => Chord$1 | null, key: KeyScale, otherVoicesAtBeat: (beat: number) => VoiceSnapshot[]): AnalyzedNote[];
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Meter and time signatures: bar/beat arithmetic, simple vs. compound meters,
|
|
237
|
-
* metric-accent hierarchy, and tuplet subdivision.
|
|
238
|
-
*
|
|
239
|
-
* Positions and durations are measured in quarter-note beats, matching the rest
|
|
240
|
-
* of the library's beat convention (four quarter-note beats per bar in 4/4).
|
|
241
|
-
*/
|
|
242
|
-
/** A time signature as a numerator over a note-value denominator. */
|
|
243
|
-
type TimeSignature = {
|
|
244
|
-
numerator: number;
|
|
245
|
-
denominator: number;
|
|
246
|
-
};
|
|
247
|
-
/** A position expressed as a bar index and a quarter-note offset within the bar. */
|
|
248
|
-
type BarPosition = {
|
|
249
|
-
bar: number;
|
|
250
|
-
/** Quarter-note offset from the start of the bar. */
|
|
251
|
-
beat: number;
|
|
252
|
-
};
|
|
253
|
-
/**
|
|
254
|
-
* Parse a time signature such as `"4/4"` or `"6/8"`.
|
|
255
|
-
*
|
|
256
|
-
* @param text The signature text.
|
|
257
|
-
* @returns The parsed time signature.
|
|
258
|
-
* @throws If the text is not `n/d` with positive integers.
|
|
259
|
-
*/
|
|
260
|
-
declare function parseTimeSignature(text: string): TimeSignature;
|
|
261
|
-
/** Render a time signature as `"n/d"`. */
|
|
262
|
-
declare function formatTimeSignature(ts: TimeSignature): string;
|
|
263
|
-
/**
|
|
264
|
-
* Whether a meter is compound: its main pulses each divide into three, as in
|
|
265
|
-
* 6/8, 9/8, 12/8, or 6/4. Compound meters are those whose numerator is a
|
|
266
|
-
* multiple of three greater than three, independent of the denominator. Meters
|
|
267
|
-
* like 3/8 and 3/4 (simple triples, numerator 3) are not compound.
|
|
268
|
-
*
|
|
269
|
-
* @param ts The time signature.
|
|
270
|
-
* @returns True for compound meters.
|
|
271
|
-
*/
|
|
272
|
-
declare function isCompound(ts: TimeSignature): boolean;
|
|
273
|
-
/**
|
|
274
|
-
* Length of a bar in quarter-note beats.
|
|
275
|
-
*
|
|
276
|
-
* @param ts The time signature.
|
|
277
|
-
* @returns The bar length in quarter notes.
|
|
278
|
-
*/
|
|
279
|
-
declare function beatsPerBar(ts: TimeSignature): number;
|
|
280
|
-
/**
|
|
281
|
-
* Number of main pulses (felt beats) per bar: the numerator for simple meters,
|
|
282
|
-
* a third of it for compound meters.
|
|
283
|
-
*
|
|
284
|
-
* @param ts The time signature.
|
|
285
|
-
* @returns The pulse count per bar.
|
|
286
|
-
*/
|
|
287
|
-
declare function pulsesPerBar(ts: TimeSignature): number;
|
|
288
|
-
/**
|
|
289
|
-
* Convert an absolute quarter-note position to a bar index and in-bar offset.
|
|
290
|
-
*
|
|
291
|
-
* @param beatInQuarters Absolute position in quarter-note beats.
|
|
292
|
-
* @param ts The time signature.
|
|
293
|
-
* @returns The bar and in-bar quarter-note offset.
|
|
294
|
-
*/
|
|
295
|
-
declare function beatToBarPosition(beatInQuarters: number, ts: TimeSignature): BarPosition;
|
|
296
|
-
/**
|
|
297
|
-
* Convert a bar index and in-bar offset back to an absolute quarter-note
|
|
298
|
-
* position.
|
|
299
|
-
*
|
|
300
|
-
* @param pos The bar position.
|
|
301
|
-
* @param ts The time signature.
|
|
302
|
-
* @returns The absolute position in quarter-note beats.
|
|
303
|
-
*/
|
|
304
|
-
declare function barPositionToBeat(pos: BarPosition, ts: TimeSignature): number;
|
|
305
|
-
/**
|
|
306
|
-
* Metric weight of a position within its bar, on a 0–3 scale:
|
|
307
|
-
* 3 the downbeat, 2 a secondary strong pulse (the bar's midpoint in even
|
|
308
|
-
* meters), 1 any other main pulse, and 0 an off-pulse subdivision.
|
|
309
|
-
*
|
|
310
|
-
* @param beatInQuarters Absolute or in-bar quarter-note position.
|
|
311
|
-
* @param ts The time signature.
|
|
312
|
-
* @returns The metric weight (0–3).
|
|
313
|
-
*/
|
|
314
|
-
declare function metricWeight(beatInQuarters: number, ts: TimeSignature): number;
|
|
315
|
-
/**
|
|
316
|
-
* Whether a position is metrically accented (weight 2 or more — a downbeat or a
|
|
317
|
-
* secondary strong pulse).
|
|
318
|
-
*
|
|
319
|
-
* @param beatInQuarters Absolute or in-bar quarter-note position.
|
|
320
|
-
* @param ts The time signature.
|
|
321
|
-
* @returns True on strong beats.
|
|
322
|
-
*/
|
|
323
|
-
declare function isStrongBeat(beatInQuarters: number, ts: TimeSignature): boolean;
|
|
324
|
-
/**
|
|
325
|
-
* Subdivide a span into `count` equal tuplet durations (e.g. an eighth-note
|
|
326
|
-
* triplet is `tuplet(1, 3)`).
|
|
327
|
-
*
|
|
328
|
-
* @param totalBeats Total span in quarter-note beats.
|
|
329
|
-
* @param count Number of equal parts.
|
|
330
|
-
* @returns `count` equal durations summing to `totalBeats`.
|
|
331
|
-
* @throws If `count` is not a positive integer.
|
|
332
|
-
*/
|
|
333
|
-
declare function tuplet(totalBeats: number, count: number): number[];
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* Functional harmony: Roman-numeral parsing and formatting, harmonic function
|
|
337
|
-
* (tonic / subdominant / dominant), and cadence detection.
|
|
338
|
-
*
|
|
339
|
-
* Roots are pitch classes measured against the key tonic, so borrowed and
|
|
340
|
-
* chromatic chords are handled by their semitone offset rather than requiring a
|
|
341
|
-
* spelled key signature.
|
|
342
|
-
*/
|
|
343
|
-
|
|
344
|
-
/** The three broad harmonic functions of tonal music. */
|
|
345
|
-
type HarmonicFunction = 'tonic' | 'subdominant' | 'dominant';
|
|
346
|
-
/** A recognized cadence type, or null when a chord pair forms none. */
|
|
347
|
-
type Cadence = 'authentic' | 'plagal' | 'half' | 'deceptive' | null;
|
|
348
|
-
/** Whether a key's scale has a minor third and no major third (a minor key). */
|
|
349
|
-
declare function isMinorKey(key: KeyScale): boolean;
|
|
350
|
-
/**
|
|
351
|
-
* Build the chord denoted by a Roman numeral in a key.
|
|
352
|
-
*
|
|
353
|
-
* Supports accidentals (`bVII`, `#iv`), case-based triad quality, the `o`/`ø`/`+`
|
|
354
|
-
* suffixes, sevenths (`V7`, `viio7`, `Imaj7`), figured-bass inversions
|
|
355
|
-
* (`V6`, `V64`, `V65`, `V43`, `V42`), and applied/secondary chords via a slash
|
|
356
|
-
* (`V7/V`, `viio/ii`). The target after the slash is read as a scale degree
|
|
357
|
-
* whose root becomes a local major tonic for the applied chord. Inverted chords
|
|
358
|
-
* carry a `bassPc`.
|
|
359
|
-
*
|
|
360
|
-
* The `ø` glyph always denotes the half-diminished seventh (`iiø` == `iiø7` ==
|
|
361
|
-
* `m7b5`), since no half-diminished triad exists. Root-position extension
|
|
362
|
-
* figures map to fixed qualities (`V9` -> `dom9`, `V11` -> `11`, `V13` -> `13`).
|
|
363
|
-
* A figure string that is neither a recognized inversion nor a supported
|
|
364
|
-
* extension throws rather than silently degrading to a triad.
|
|
365
|
-
*
|
|
366
|
-
* @param text The Roman numeral.
|
|
367
|
-
* @param key The prevailing key.
|
|
368
|
-
* @returns The chord.
|
|
369
|
-
*/
|
|
370
|
-
declare function romanToChord(text: string, key: KeyScale): Chord$1;
|
|
371
|
-
/**
|
|
372
|
-
* Render a chord as a Roman numeral relative to a key.
|
|
373
|
-
*
|
|
374
|
-
* Diatonic roots take their scale-degree numeral directly, so numerals are
|
|
375
|
-
* correct in both major and minor keys (and any custom scale). The quality
|
|
376
|
-
* selects the case and suffix; chromatic roots receive a flat/sharp spelling by
|
|
377
|
-
* convention. When the chord carries a `bassPc` on a chord tone, a figured-bass
|
|
378
|
-
* inversion (`6`, `64`, `65`, `43`, `42`) is emitted.
|
|
379
|
-
*
|
|
380
|
-
* @param chord The chord to name.
|
|
381
|
-
* @param key The prevailing key.
|
|
382
|
-
* @returns The Roman numeral string.
|
|
383
|
-
*/
|
|
384
|
-
declare function chordToRoman(chord: Chord$1, key: KeyScale): string;
|
|
385
|
-
/**
|
|
386
|
-
* The harmonic function of a chord in a key, from its root's offset above the
|
|
387
|
-
* tonic. The mapping follows common-practice major-key function and is a useful
|
|
388
|
-
* approximation in minor and for borrowed chords.
|
|
389
|
-
*
|
|
390
|
-
* @param chord The chord.
|
|
391
|
-
* @param key The prevailing key.
|
|
392
|
-
* @returns The harmonic function.
|
|
393
|
-
*/
|
|
394
|
-
declare function functionOf(chord: Chord$1, key: KeyScale): HarmonicFunction;
|
|
395
|
-
/** The origin of a recognized non-diatonic chord, or null when none applies. */
|
|
396
|
-
type BorrowedSource = 'parallel-minor' | 'parallel-major' | 'neapolitan' | null;
|
|
397
|
-
/** The result of {@link analyzeChord}: function, borrowing, and Roman numeral. */
|
|
398
|
-
type ChordAnalysis = {
|
|
399
|
-
function: HarmonicFunction;
|
|
400
|
-
borrowed: boolean;
|
|
401
|
-
source: BorrowedSource;
|
|
402
|
-
roman: string;
|
|
403
|
-
};
|
|
404
|
-
/**
|
|
405
|
-
* Whether every pitch class of a chord belongs to the key's scale.
|
|
406
|
-
*
|
|
407
|
-
* The test is strict against the key's own mode mask: in a natural-minor key
|
|
408
|
-
* the harmonic-minor dominant (major V) is *not* diatonic, since the raised
|
|
409
|
-
* leading tone lies outside the mask. Borrowing predicates treat that case as
|
|
410
|
-
* an in-key alteration separately (see {@link isBorrowedChord}).
|
|
411
|
-
*
|
|
412
|
-
* @param chord The chord to test.
|
|
413
|
-
* @param key The prevailing key.
|
|
414
|
-
* @returns True if all chord pitch classes are scale tones.
|
|
415
|
-
*/
|
|
416
|
-
declare function isDiatonic(chord: Chord$1, key: KeyScale): boolean;
|
|
417
|
-
/**
|
|
418
|
-
* The parallel key: same tonic, opposite mode.
|
|
419
|
-
*
|
|
420
|
-
* A key with a minor third (natural/harmonic/melodic minor, dorian, phrygian)
|
|
421
|
-
* maps to the parallel major; any other key maps to the parallel natural minor.
|
|
422
|
-
*
|
|
423
|
-
* @param key The key to mirror.
|
|
424
|
-
* @returns The parallel major or natural-minor key on the same tonic.
|
|
425
|
-
*/
|
|
426
|
-
declare function parallelKey(key: KeyScale): KeyScale;
|
|
427
|
-
/**
|
|
428
|
-
* Whether a chord is borrowed from the parallel mode (modal interchange).
|
|
429
|
-
*
|
|
430
|
-
* True when the chord is not diatonic to `key` but is diatonic to its
|
|
431
|
-
* {@link parallelKey} — e.g. iv, bVI, or bVII in a major key, or the Picardy
|
|
432
|
-
* tonic and major IV in a minor key. Two non-diatonic families are excluded:
|
|
433
|
-
* chords diatonic to neither mode (they are chromatic, not borrowed), and, in
|
|
434
|
-
* a minor key, chords explained by the harmonic minor scale (the major
|
|
435
|
-
* dominant and raised-leading-tone chords), which are in-key alterations
|
|
436
|
-
* rather than interchange even though they happen to fit the parallel major.
|
|
437
|
-
*
|
|
438
|
-
* @param chord The chord to test.
|
|
439
|
-
* @param key The prevailing key.
|
|
440
|
-
* @returns True if the chord is borrowed from the parallel mode.
|
|
441
|
-
*/
|
|
442
|
-
declare function isBorrowedChord(chord: Chord$1, key: KeyScale): boolean;
|
|
443
|
-
/**
|
|
444
|
-
* Identify where a non-diatonic chord comes from.
|
|
445
|
-
*
|
|
446
|
-
* The Neapolitan (major triad on b2) is recognized first, since it sits
|
|
447
|
-
* outside both parallel modes; parallel-mode borrowing follows the
|
|
448
|
-
* {@link isBorrowedChord} rules. Diatonic chords, harmonic-minor alterations,
|
|
449
|
-
* and unrecognized chromatic chords all yield null.
|
|
450
|
-
*
|
|
451
|
-
* @param chord The chord to classify.
|
|
452
|
-
* @param key The prevailing key.
|
|
453
|
-
* @returns The borrowing source, or null.
|
|
454
|
-
*/
|
|
455
|
-
declare function borrowedSource(chord: Chord$1, key: KeyScale): BorrowedSource;
|
|
456
|
-
/**
|
|
457
|
-
* Analyze a chord in a key: harmonic function, borrowing, and Roman numeral.
|
|
458
|
-
*
|
|
459
|
-
* The function is quality-aware (see the predicates behind it), the source
|
|
460
|
-
* follows {@link borrowedSource}, and the numeral comes from
|
|
461
|
-
* {@link chordToRoman}. `borrowed` is true whenever a source is identified —
|
|
462
|
-
* including the Neapolitan, which the stricter parallel-mode predicate
|
|
463
|
-
* {@link isBorrowedChord} does not count.
|
|
464
|
-
*
|
|
465
|
-
* @param chord The chord to analyze.
|
|
466
|
-
* @param key The prevailing key.
|
|
467
|
-
* @returns The chord analysis.
|
|
468
|
-
*/
|
|
469
|
-
declare function analyzeChord(chord: Chord$1, key: KeyScale): ChordAnalysis;
|
|
470
|
-
/**
|
|
471
|
-
* Classify the cadence formed by moving from one chord to the next.
|
|
472
|
-
*
|
|
473
|
-
* - authentic: V (dominant a fifth above the tonic) to I
|
|
474
|
-
* - plagal: IV (a fourth above the tonic) to I
|
|
475
|
-
* - deceptive: V to the submediant (diatonic vi or borrowed bVI in major, VI in
|
|
476
|
-
* minor)
|
|
477
|
-
* - half: any chord other than the dominant itself to V
|
|
478
|
-
*
|
|
479
|
-
* A static V-to-V repeat with no root motion is not a cadence and yields null.
|
|
480
|
-
*
|
|
481
|
-
* @param from The penultimate chord.
|
|
482
|
-
* @param to The final chord.
|
|
483
|
-
* @param key The prevailing key.
|
|
484
|
-
* @returns The cadence type, or null.
|
|
485
|
-
*/
|
|
486
|
-
declare function detectCadence(from: Chord$1, to: Chord$1, key: KeyScale): Cadence;
|
|
487
|
-
/**
|
|
488
|
-
* The secondary dominant (V7) that tonicizes a scale degree.
|
|
489
|
-
*
|
|
490
|
-
* @param targetDegree 0-based scale degree to tonicize.
|
|
491
|
-
* @param key The prevailing key.
|
|
492
|
-
* @returns A dominant-seventh chord a fifth above the target's root.
|
|
493
|
-
*/
|
|
494
|
-
declare function secondaryDominant(targetDegree: number, key: KeyScale): Chord$1;
|
|
495
|
-
|
|
496
|
-
/** Broad production style a progression preset suits. */
|
|
497
|
-
type ProgStyle = 'minimal' | 'dance' | 'idol' | 'rock';
|
|
498
|
-
/** Harmonic-function role of a progression as a whole. */
|
|
499
|
-
type ProgFunction = 'loop' | 'tensionBuild' | 'cadenceStrong' | 'stable';
|
|
500
|
-
/** A named chord-progression preset expressed in scale degrees. */
|
|
501
|
-
type ProgressionPreset = {
|
|
502
|
-
id: string;
|
|
503
|
-
name: string;
|
|
504
|
-
degrees: number[];
|
|
505
|
-
functional: ProgFunction;
|
|
506
|
-
styles: ProgStyle[];
|
|
507
|
-
};
|
|
508
|
-
/** A chord placed on the timeline by {@link generateProgression}. */
|
|
509
|
-
type GeneratedChord = {
|
|
510
|
-
rootPc: number;
|
|
511
|
-
quality: ChordQuality;
|
|
512
|
-
startBeat: number;
|
|
513
|
-
bassPc?: number;
|
|
514
|
-
/** 0-based scale degree of the chord root, when known. */
|
|
515
|
-
degree?: number;
|
|
516
|
-
/** True when the chord is a secondary dominant tonicizing another degree. */
|
|
517
|
-
secondaryDominant?: boolean;
|
|
518
|
-
};
|
|
519
|
-
/** Options controlling {@link generateProgression}. */
|
|
520
|
-
type GenerateProgressionOptions = {
|
|
521
|
-
key: KeyScale;
|
|
522
|
-
style: ProgStyle;
|
|
523
|
-
bars: number;
|
|
524
|
-
presetId?: string;
|
|
525
|
-
ext?: ChordQuality | 'auto';
|
|
526
|
-
reharmonize?: boolean;
|
|
527
|
-
seed?: number;
|
|
528
|
-
};
|
|
529
|
-
/** All built-in progression presets. */
|
|
530
|
-
declare function progressions(): ProgressionPreset[];
|
|
531
|
-
/** Presets whose style list includes the given style. */
|
|
532
|
-
declare function progressionsByStyle(style: ProgStyle): ProgressionPreset[];
|
|
533
|
-
/**
|
|
534
|
-
* Generate a chord progression laid out one chord per bar.
|
|
535
|
-
*
|
|
536
|
-
* A preset is chosen by `presetId` when given, otherwise deterministically from
|
|
537
|
-
* the presets matching `style`, seeded by `seed`. The preset's degrees cycle to
|
|
538
|
-
* fill `bars`; each bar is four beats, so `startBeat` is `barIndex * 4`. Chord
|
|
539
|
-
* roots come from the key's diatonic scale-degree mapping. When `ext` is
|
|
540
|
-
* omitted or `'auto'`, each chord takes its diatonic triad quality; otherwise
|
|
541
|
-
* `ext` is forced on every chord. When `reharmonize` is set, some chords are
|
|
542
|
-
* deterministically replaced with the secondary dominant (V7) of the following
|
|
543
|
-
* chord, flagged with `secondaryDominant`.
|
|
544
|
-
*
|
|
545
|
-
* @param opts Generation options.
|
|
546
|
-
* @returns One chord per bar in timeline order.
|
|
547
|
-
*/
|
|
548
|
-
declare function generateProgression(opts: GenerateProgressionOptions): GeneratedChord[];
|
|
549
|
-
|
|
550
|
-
/** A chord occupying a half-open beat span. */
|
|
551
|
-
type ChordSegment = {
|
|
552
|
-
startBeat: number;
|
|
553
|
-
endBeat: number;
|
|
554
|
-
chord: Chord$1;
|
|
555
|
-
};
|
|
556
|
-
/** A beat-indexed sequence of chord segments. */
|
|
557
|
-
type ChordTimeline = {
|
|
558
|
-
/** The chord sounding at a beat, or null when no segment covers it. */
|
|
559
|
-
at: (beat: number) => Chord$1 | null;
|
|
560
|
-
segments: ChordSegment[];
|
|
561
|
-
};
|
|
562
|
-
/**
|
|
563
|
-
* Build a chord timeline from placed chords.
|
|
564
|
-
*
|
|
565
|
-
* Each chord spans from its `startBeat` to the next chord's `startBeat`; the last
|
|
566
|
-
* chord runs to `totalBeats`. Segments with no positive length (from duplicate
|
|
567
|
-
* onsets or a last chord at or past `totalBeats`) are dropped. `at(beat)` returns
|
|
568
|
-
* the covering segment's chord, or null when the beat lies outside every segment.
|
|
569
|
-
*
|
|
570
|
-
* @param chords Placed chords in time order.
|
|
571
|
-
* @param totalBeats End of the timeline in beats.
|
|
572
|
-
* @returns A queryable chord timeline.
|
|
573
|
-
*/
|
|
574
|
-
declare function chordTimelineFromChords(chords: GeneratedChord[], totalBeats: number): ChordTimeline;
|
|
575
|
-
/** Options controlling {@link chordTimelineFromNotes}. */
|
|
576
|
-
type ChordTimelineOptions = {
|
|
577
|
-
/** Key context; inferred from the notes with {@link detectKey} when omitted. */
|
|
578
|
-
key?: KeyScale;
|
|
579
|
-
/** Time signature used for metric accents; defaults to 4/4. */
|
|
580
|
-
ts?: TimeSignature;
|
|
581
|
-
/** Window length in beats per chord slot; defaults to one bar of `ts`. */
|
|
582
|
-
harmonicRhythm?: number;
|
|
583
|
-
/** End of the analyzed span in beats; defaults to the end of the last note. */
|
|
584
|
-
totalBeats?: number;
|
|
585
|
-
};
|
|
586
|
-
/** The result of {@link chordTimelineFromNotes}. */
|
|
587
|
-
type ChordTimelineResult = {
|
|
588
|
-
/** The inferred timeline, with adjacent identical chords merged. */
|
|
589
|
-
timeline: ChordTimeline;
|
|
590
|
-
/** The key used for the analysis (given or inferred). */
|
|
591
|
-
key: KeyScale;
|
|
592
|
-
/** One confidence value in [0, 1] per segment, in segment order. */
|
|
593
|
-
segmentConfidence: number[];
|
|
594
|
-
};
|
|
595
|
-
/**
|
|
596
|
-
* Infer a chord timeline from raw multi-track notes.
|
|
597
|
-
*
|
|
598
|
-
* The span `[0, totalBeats)` is sliced into `harmonicRhythm`-beat windows; each
|
|
599
|
-
* window's chord is inferred from a pitch-class weight histogram of the notes
|
|
600
|
-
* overlapping it (weight = overlap duration x velocity x metric-accent bonus
|
|
601
|
-
* for onsets in the window). Adjacent windows carrying the identical chord are
|
|
602
|
-
* merged into one segment; windows with no notes produce no segment, so
|
|
603
|
-
* `at(beat)` returns null there. Each segment carries a confidence in [0, 1]:
|
|
604
|
-
* the fraction of the window weight explained by chord tones, reduced when the
|
|
605
|
-
* match is inexact, and duration-weighted across merged windows.
|
|
606
|
-
*
|
|
607
|
-
* @param notes The notes to analyze (any number of tracks, flattened).
|
|
608
|
-
* @param opts Analysis options; see {@link ChordTimelineOptions}.
|
|
609
|
-
* @returns The inferred timeline, the key used, and per-segment confidences.
|
|
610
|
-
* @throws If `harmonicRhythm` is not positive.
|
|
611
|
-
*/
|
|
612
|
-
declare function chordTimelineFromNotes(notes: NoteEvent[], opts?: ChordTimelineOptions): ChordTimelineResult;
|
|
613
|
-
/** A cadence found between two consecutive timeline segments. */
|
|
614
|
-
type CadenceHit = {
|
|
615
|
-
/** The beat where the cadence arrives (the second chord's onset). */
|
|
616
|
-
atBeat: number;
|
|
617
|
-
type: Exclude<Cadence, null>;
|
|
618
|
-
from: Chord$1;
|
|
619
|
-
to: Chord$1;
|
|
620
|
-
};
|
|
621
|
-
/**
|
|
622
|
-
* Find cadences between consecutive segments of a chord timeline.
|
|
623
|
-
*
|
|
624
|
-
* Each adjacent segment pair is classified with {@link detectCadence}; pairs
|
|
625
|
-
* forming no cadence are skipped.
|
|
626
|
-
*
|
|
627
|
-
* @param timeline The chord timeline to scan.
|
|
628
|
-
* @param key The prevailing key.
|
|
629
|
-
* @returns The cadences found, in time order.
|
|
630
|
-
*/
|
|
631
|
-
declare function detectCadences(timeline: ChordTimeline, key: KeyScale): CadenceHit[];
|
|
632
|
-
|
|
633
|
-
/**
|
|
634
|
-
* Arrangement analysis: the capstone that ties the timeline, per-voice analysis,
|
|
635
|
-
* functional harmony, and safety modules together for a whole multi-track piece.
|
|
636
|
-
*
|
|
637
|
-
* A chord timeline and key are inferred once from every track's notes pooled
|
|
638
|
-
* together; each track is then analysed against that shared harmony, notes that
|
|
639
|
-
* clash with the sounding chord are collected as conflicts, and a coarse tension
|
|
640
|
-
* curve is sampled across the piece.
|
|
641
|
-
*/
|
|
642
|
-
|
|
643
|
-
/** The musical role a track plays in the arrangement. */
|
|
644
|
-
type TrackRole = 'melody' | 'harmony' | 'bass' | 'other';
|
|
645
|
-
/** One input track: its notes plus optional name and role. */
|
|
646
|
-
type ArrangementTrack = {
|
|
647
|
-
name?: string;
|
|
648
|
-
role?: TrackRole;
|
|
649
|
-
notes: NoteEvent[];
|
|
650
|
-
};
|
|
651
|
-
/** A track after analysis: its resolved name, role, and per-note annotations. */
|
|
652
|
-
type TrackAnalysis = {
|
|
653
|
-
name: string;
|
|
654
|
-
role: TrackRole;
|
|
655
|
-
/** One {@link AnalyzedNote} per note, labelled against the inferred chords. */
|
|
656
|
-
notes: AnalyzedNote[];
|
|
657
|
-
};
|
|
658
|
-
/** A note that clashes with the harmony sounding beneath it. */
|
|
659
|
-
type Conflict = {
|
|
660
|
-
beat: number;
|
|
661
|
-
trackName: string;
|
|
662
|
-
pitch: number;
|
|
663
|
-
/** The clash severity: {@link NoteSafety.Warning} or {@link NoteSafety.Dissonant}. */
|
|
664
|
-
safety: NoteSafety;
|
|
665
|
-
/** {@link import('../safety/index.js').SafetyResult.reasons} bitmask. */
|
|
666
|
-
reasons: number;
|
|
667
|
-
rationale?: string;
|
|
668
|
-
};
|
|
669
|
-
/** The full result of {@link analyzeArrangement}. */
|
|
670
|
-
type ArrangementAnalysis = {
|
|
671
|
-
key: KeyScale;
|
|
672
|
-
timeline: ChordTimeline;
|
|
673
|
-
segmentConfidence: number[];
|
|
674
|
-
cadences: CadenceHit[];
|
|
675
|
-
tracks: TrackAnalysis[];
|
|
676
|
-
/** Notes clashing with the sounding harmony, worst severity first. */
|
|
677
|
-
conflicts: Conflict[];
|
|
678
|
-
};
|
|
679
|
-
/** Options controlling {@link analyzeArrangement} and {@link tensionCurve}. */
|
|
680
|
-
type ArrangementOptions = {
|
|
681
|
-
/** Key context; inferred from the pooled notes when omitted. */
|
|
682
|
-
key?: KeyScale;
|
|
683
|
-
/** Time signature; defaults to 4/4. */
|
|
684
|
-
ts?: TimeSignature;
|
|
685
|
-
/** Chord-slot length in beats; defaults to one bar of `ts`. */
|
|
686
|
-
harmonicRhythm?: number;
|
|
687
|
-
/** Safety profile used for conflict detection; defaults to `pop`. */
|
|
688
|
-
profile?: SafetyProfile;
|
|
689
|
-
};
|
|
690
|
-
/**
|
|
691
|
-
* Analyse a whole arrangement against a single inferred harmony.
|
|
692
|
-
*
|
|
693
|
-
* The chord timeline and key are inferred from the pooled notes of every track
|
|
694
|
-
* (see {@link chordTimelineFromNotes}); pooling all voices is robust even when
|
|
695
|
-
* roles are absent or a track doubles the harmony, so it is preferred over
|
|
696
|
-
* deriving the harmony from a subset. Each track is then labelled note-by-note
|
|
697
|
-
* against that harmony with {@link analyzeVoice}, seeing the other tracks as its
|
|
698
|
-
* accompaniment, and every note is re-checked with {@link evaluateSafety}: those
|
|
699
|
-
* that are not {@link NoteSafety.Safe} against the sounding chord become
|
|
700
|
-
* conflicts, sorted worst severity first and then by beat.
|
|
701
|
-
*
|
|
702
|
-
* @param tracks The tracks to analyse.
|
|
703
|
-
* @param opts Analysis options; see {@link ArrangementOptions}.
|
|
704
|
-
* @returns The inferred harmony, per-track annotations, cadences, and conflicts.
|
|
705
|
-
*/
|
|
706
|
-
declare function analyzeArrangement(tracks: ArrangementTrack[], opts?: ArrangementOptions): ArrangementAnalysis;
|
|
707
|
-
/** A tension reading sampled at a beat. */
|
|
708
|
-
type TensionPoint = {
|
|
709
|
-
beat: number;
|
|
710
|
-
/** Combined tension in [0, 1]. */
|
|
711
|
-
tension: number;
|
|
712
|
-
};
|
|
713
|
-
/**
|
|
714
|
-
* Sample the harmonic tension of an arrangement at regular beats.
|
|
715
|
-
*
|
|
716
|
-
* At each sample beat the tension combines three normalized terms:
|
|
717
|
-
* - the sounding chord's harmonic function (dominant `1`, subdominant `0.5`,
|
|
718
|
-
* tonic or no chord `0`), weighted {@link FUNCTION_WEIGHT};
|
|
719
|
-
* - the dissonance of the sounding notes — the larger of the share of sounding
|
|
720
|
-
* pitches that are not chord tones and the share that {@link evaluateSafety}
|
|
721
|
-
* rates {@link NoteSafety.Dissonant} — weighted {@link DISSONANCE_WEIGHT};
|
|
722
|
-
* - the registral span of the sounding notes, saturating at
|
|
723
|
-
* {@link SPAN_SATURATION} semitones, weighted {@link SPAN_WEIGHT}.
|
|
724
|
-
*
|
|
725
|
-
* The weighted sum is clamped to [0, 1]. The harmony is inferred from all tracks
|
|
726
|
-
* pooled together, so the result is deterministic and self-contained.
|
|
727
|
-
*
|
|
728
|
-
* @param tracks The tracks to sample.
|
|
729
|
-
* @param opts Analysis options plus an optional `step` (default one beat).
|
|
730
|
-
* @returns One {@link TensionPoint} per sampled beat, in beat order.
|
|
731
|
-
* @throws If `step` is not positive.
|
|
732
|
-
*/
|
|
733
|
-
declare function tensionCurve(tracks: ArrangementTrack[], opts?: ArrangementOptions & {
|
|
734
|
-
step?: number;
|
|
735
|
-
}): TensionPoint[];
|
|
736
|
-
|
|
737
|
-
/**
|
|
738
|
-
* Deterministic bass-line generation over a chord placement.
|
|
739
|
-
*
|
|
740
|
-
* Given a sequence of chord segments and a key, this builds a monophonic bass
|
|
741
|
-
* line in a chosen low register. Several idiomatic styles are supported, from a
|
|
742
|
-
* single held root per segment to a quarter-note walking line that leads by
|
|
743
|
-
* step into each chord change. All pitches are kept in a narrow bass band and
|
|
744
|
-
* consecutive notes move by small intervals; given a seed the output is fully
|
|
745
|
-
* reproducible.
|
|
746
|
-
*
|
|
747
|
-
* Positions and durations are measured in quarter-note beats, matching the
|
|
748
|
-
* library-wide convention.
|
|
749
|
-
*/
|
|
750
|
-
|
|
751
|
-
/** A chord sounding over a half-open beat span `[startBeat, endBeat)`. */
|
|
752
|
-
type BassSegment = {
|
|
753
|
-
startBeat: number;
|
|
754
|
-
endBeat: number;
|
|
755
|
-
chord: Chord$1;
|
|
756
|
-
};
|
|
757
|
-
/** The bass-line idiom to generate. */
|
|
758
|
-
type BassStyle = 'root' | 'rootFifth' | 'pop' | 'walking' | 'arpeggio';
|
|
759
|
-
/** Options controlling {@link generateBassLine}. */
|
|
760
|
-
type BassLineOptions = {
|
|
761
|
-
/** Chord placement to follow; need not be pre-sorted. */
|
|
762
|
-
segments: BassSegment[];
|
|
763
|
-
/** Key/scale context, used for diatonic approach tones in `walking`. */
|
|
764
|
-
key: KeyScale;
|
|
765
|
-
/** Time signature; used for metric accents. Default 4/4. */
|
|
766
|
-
ts?: TimeSignature;
|
|
767
|
-
/** Bass-line idiom. Default `'root'`. */
|
|
768
|
-
style?: BassStyle;
|
|
769
|
-
/** Target register as a base MIDI octave; roots land around `octave*12+12`. Default 2. */
|
|
770
|
-
octave?: number;
|
|
771
|
-
/** Seed for the deterministic PRNG. Default 0. */
|
|
772
|
-
seed?: number;
|
|
773
|
-
};
|
|
774
|
-
/**
|
|
775
|
-
* Generate a bass line following a chord placement.
|
|
776
|
-
*
|
|
777
|
-
* Each segment contributes notes in the chosen bass register per the selected
|
|
778
|
-
* style; consecutive notes are kept within roughly a fifth. Every note's
|
|
779
|
-
* duration extends to the next onset (the final note extends to the last
|
|
780
|
-
* segment's end). Given a seed the output is fully reproducible.
|
|
781
|
-
*
|
|
782
|
-
* @param opts Segments, key, and generation options.
|
|
783
|
-
* @returns Bass notes sorted by onset, non-overlapping.
|
|
784
|
-
*/
|
|
785
|
-
declare function generateBassLine(opts: BassLineOptions): NoteEvent[];
|
|
786
|
-
|
|
787
|
-
/**
|
|
788
|
-
* Test whether every chord pitch class is contained in a scale.
|
|
789
|
-
*
|
|
790
|
-
* @param chordPcs The chord's pitch classes (0..11).
|
|
791
|
-
* @param scaleMask The scale's 12-bit mode mask.
|
|
792
|
-
* @param scaleRootPc The pitch class the mask is rooted on.
|
|
793
|
-
* @returns True if the scale is a superset of the chord.
|
|
794
|
-
*/
|
|
795
|
-
declare function scaleMatchesChord(chordPcs: number[], scaleMask: number, scaleRootPc: number): boolean;
|
|
796
|
-
/** A named scale rooted on a pitch class that fits over a chord. */
|
|
797
|
-
type ChordScaleMatch = {
|
|
798
|
-
name: string;
|
|
799
|
-
rootPc: number;
|
|
800
|
-
};
|
|
801
|
-
/**
|
|
802
|
-
* List the scales that fit over a chord, best fit first.
|
|
803
|
-
*
|
|
804
|
-
* Only the chord root is considered as the scale root, matching the
|
|
805
|
-
* conventional chord-scale relationship. Every entry of {@link NAMED_SCALES}
|
|
806
|
-
* whose pitch-class set is a superset of the chord's is returned, ranked by
|
|
807
|
-
* fewest extra scale tones beyond the chord, then by scale size (heptatonic
|
|
808
|
-
* before larger scales), then by scale name. The chromatic scale is only
|
|
809
|
-
* returned as a fallback when no other scale contains the chord.
|
|
810
|
-
*
|
|
811
|
-
* @param chord The chord to fit scales over.
|
|
812
|
-
* @returns The matching scales rooted on the chord root, best fit first.
|
|
813
|
-
*/
|
|
814
|
-
declare function chordScales(chord: Chord$1): ChordScaleMatch[];
|
|
815
|
-
/**
|
|
816
|
-
* List a scale's avoid notes over a chord.
|
|
817
|
-
*
|
|
818
|
-
* An avoid note is a non-chord scale tone that lies a semitone directly above a
|
|
819
|
-
* chord tone; sounding it against the chord clashes. The scale is rooted on the
|
|
820
|
-
* chord root. If the scale does not contain the chord, no avoid notes exist.
|
|
821
|
-
*
|
|
822
|
-
* @param chord The chord providing the chord tones.
|
|
823
|
-
* @param scaleName A key of {@link NAMED_SCALES}.
|
|
824
|
-
* @returns The avoid-note pitch classes, sorted ascending in [0, 11].
|
|
825
|
-
*/
|
|
826
|
-
declare function avoidNotes(chord: Chord$1, scaleName: string): number[];
|
|
827
|
-
/**
|
|
828
|
-
* List a scale's available tensions over a chord.
|
|
829
|
-
*
|
|
830
|
-
* Available tensions are scale tones that are neither chord tones nor avoid
|
|
831
|
-
* notes, i.e. the usable color tones (typically the 9/11/13 region). The scale
|
|
832
|
-
* is rooted on the chord root. If the scale does not contain the chord, there
|
|
833
|
-
* are no available tensions.
|
|
834
|
-
*
|
|
835
|
-
* @param chord The chord providing the chord tones.
|
|
836
|
-
* @param scaleName A key of {@link NAMED_SCALES}.
|
|
837
|
-
* @returns The available-tension pitch classes, sorted ascending in [0, 11].
|
|
838
|
-
*/
|
|
839
|
-
declare function availableTensions(chord: Chord$1, scaleName: string): number[];
|
|
840
|
-
/** A scale fit over a chord together with its avoid notes and tensions. */
|
|
841
|
-
type ChordScaleReportEntry = {
|
|
842
|
-
name: string;
|
|
843
|
-
rootPc: number;
|
|
844
|
-
avoid: number[];
|
|
845
|
-
tensions: number[];
|
|
846
|
-
};
|
|
847
|
-
/**
|
|
848
|
-
* Report the best-fitting scales for a chord with their avoid notes and tensions.
|
|
849
|
-
*
|
|
850
|
-
* Combines {@link chordScales}, {@link avoidNotes}, and {@link availableTensions}
|
|
851
|
-
* into a single ergonomic result, ordered best fit first.
|
|
852
|
-
*
|
|
853
|
-
* @param chord The chord to analyze.
|
|
854
|
-
* @param limit Optional maximum number of scales to report; all by default.
|
|
855
|
-
* @returns One entry per reported scale, best fit first.
|
|
856
|
-
*/
|
|
857
|
-
declare function chordScaleReport(chord: Chord$1, limit?: number): ChordScaleReportEntry[];
|
|
858
|
-
/** A chord paired with the scale chosen for it by {@link scalesForChanges}. */
|
|
859
|
-
type ScaleChoice = {
|
|
860
|
-
chord: Chord$1;
|
|
861
|
-
scale: ChordScaleMatch;
|
|
862
|
-
};
|
|
863
|
-
/**
|
|
864
|
-
* Choose one scale per chord across a progression, favoring continuity.
|
|
865
|
-
*
|
|
866
|
-
* Each chord's {@link chordScales} candidates form a stage in a Viterbi-style
|
|
867
|
-
* dynamic program. The transition cost between adjacent choices is the number
|
|
868
|
-
* of pitch classes that differ between their pitch-class sets (the symmetric
|
|
869
|
-
* difference), plus a small penalty for straying from a chord's best-fit scale
|
|
870
|
-
* so that ties break toward the tighter fit. The minimum-total-cost path is
|
|
871
|
-
* returned, one {@link ScaleChoice} per input chord in the original order.
|
|
872
|
-
*
|
|
873
|
-
* @param chords The chord sequence to choose scales for.
|
|
874
|
-
* @returns One scale choice per chord, in input order.
|
|
875
|
-
*/
|
|
876
|
-
declare function scalesForChanges(chords: Chord$1[]): ScaleChoice[];
|
|
877
|
-
|
|
878
|
-
/** Options controlling {@link generateCounterMelody}. */
|
|
879
|
-
type CounterMelodyOptions = {
|
|
880
|
-
/** The lead line to write against, in ascending onset order. */
|
|
881
|
-
melody: NoteEvent[];
|
|
882
|
-
/** Chord sounding at an absolute beat position, or null when none applies. */
|
|
883
|
-
chordAt: (beat: number) => Chord$1 | null;
|
|
884
|
-
/** Key/scale context for scale-tone decisions. */
|
|
885
|
-
key: KeyScale;
|
|
886
|
-
/** Meter used for strong-beat decisions (default 4/4). */
|
|
887
|
-
ts?: TimeSignature;
|
|
888
|
-
/** Which side of the melody the counter line occupies (default `'below'`). */
|
|
889
|
-
register?: 'above' | 'below';
|
|
890
|
-
/**
|
|
891
|
-
* Onset strategy: `'complement'` (default) moves where the melody holds or
|
|
892
|
-
* rests and reinforces some strong beats; `'follow'` mirrors melody onsets.
|
|
893
|
-
*/
|
|
894
|
-
rhythm?: 'complement' | 'follow';
|
|
895
|
-
/** Safety profile applied to candidate pitches (default `'pop'`). */
|
|
896
|
-
profile?: 'strict' | 'pop';
|
|
897
|
-
/** Lowest MIDI pitch the counter line may use (default derived from `register`). */
|
|
898
|
-
pitchLow?: number;
|
|
899
|
-
/** Highest MIDI pitch the counter line may use (default derived from `register`). */
|
|
900
|
-
pitchHigh?: number;
|
|
901
|
-
/** PRNG seed; the same seed always yields the same line (default 0). */
|
|
902
|
-
seed?: number;
|
|
903
|
-
};
|
|
904
|
-
/**
|
|
905
|
-
* Generate a counter melody against a lead line.
|
|
906
|
-
*
|
|
907
|
-
* Onsets are chosen per `rhythm`: `'follow'` places one counter note on each
|
|
908
|
-
* melody onset; `'complement'` fills melody rests and sustains and reinforces
|
|
909
|
-
* an occasional strong beat, spaced at least a beat apart. Each onset's pitch
|
|
910
|
-
* is picked from the safe pitches in the counter register (chord tones and
|
|
911
|
-
* consonant tensions against the sounding melody note), rejecting candidates
|
|
912
|
-
* that would form a parallel perfect interval with the melody or sit on the
|
|
913
|
-
* wrong side of it, then scored to favour contrary or oblique motion, imperfect
|
|
914
|
-
* consonance, and stepwise movement. Ties break toward the lower pitch, so a
|
|
915
|
-
* given seed always yields the same line. Notes extend to the next counter
|
|
916
|
-
* onset (the last to the melody's end) at a velocity slightly under the melody.
|
|
917
|
-
*
|
|
918
|
-
* @param opts The lead line, chord context callback, key, and generation knobs.
|
|
919
|
-
* @returns The counter line as note events sorted by onset; `[]` for an empty melody.
|
|
920
|
-
*/
|
|
921
|
-
declare function generateCounterMelody(opts: CounterMelodyOptions): NoteEvent[];
|
|
922
|
-
|
|
923
|
-
/**
|
|
924
|
-
* Whether an upper voice has crossed below a lower voice.
|
|
925
|
-
*
|
|
926
|
-
* @param upperPitch Pitch of the nominally higher voice.
|
|
927
|
-
* @param lowerPitch Pitch of the nominally lower voice.
|
|
928
|
-
* @returns True when the upper voice sits below the lower voice.
|
|
929
|
-
*/
|
|
930
|
-
declare function createsVoiceCrossing(upperPitch: number, lowerPitch: number): boolean;
|
|
931
|
-
/**
|
|
932
|
-
* Whether two simultaneous pitches form a dissonance.
|
|
933
|
-
*
|
|
934
|
-
* @param a First pitch.
|
|
935
|
-
* @param b Second pitch.
|
|
936
|
-
* @param twoVoice When true, the perfect fourth counts as dissonant.
|
|
937
|
-
* @returns True when the vertical interval is dissonant.
|
|
938
|
-
*/
|
|
939
|
-
declare function createsVerticalDissonance(a: number, b: number, twoVoice: boolean): boolean;
|
|
940
|
-
/**
|
|
941
|
-
* Whether a melodic move is a forbidden leap: a tritone, either seventh (minor
|
|
942
|
-
* or major), or any leap wider than an octave.
|
|
943
|
-
*
|
|
944
|
-
* Operates on the raw absolute distance, so compound leaps are not reduced to
|
|
945
|
-
* their simple class before the octave check.
|
|
946
|
-
*
|
|
947
|
-
* @param prev Starting pitch.
|
|
948
|
-
* @param cur Ending pitch.
|
|
949
|
-
* @returns True when the leap is forbidden in strict counterpoint.
|
|
950
|
-
*/
|
|
951
|
-
declare function isForbiddenMelodicLeap(prev: number, cur: number): boolean;
|
|
952
|
-
/**
|
|
953
|
-
* Whether two voices move into consecutive perfect intervals of the same kind
|
|
954
|
-
* (fifth-to-fifth, octave-to-octave, unison-to-unison).
|
|
955
|
-
*
|
|
956
|
-
* Both true parallels (similar motion) and anti-parallels — the same perfect
|
|
957
|
-
* class reached by contrary motion, e.g. octave to octave with the voices moving
|
|
958
|
-
* in opposite directions — are flagged, as both are forbidden in strict two-voice
|
|
959
|
-
* counterpoint. The rule requires that both voices actually move: oblique motion
|
|
960
|
-
* (either voice stationary) and the no-change case (identical pitches) are excluded.
|
|
961
|
-
*
|
|
962
|
-
* A fifth expanding to a twelfth counts (same perfect class); a fifth moving to
|
|
963
|
-
* an octave does not (different perfect kinds — the direct/hidden case owned by
|
|
964
|
-
* {@link createsHiddenParallelPerfect}).
|
|
965
|
-
*/
|
|
966
|
-
declare function createsParallelPerfect(aPrev: number, aCur: number, bPrev: number, bCur: number): boolean;
|
|
967
|
-
/**
|
|
968
|
-
* Whether two voices move in consecutive parallel octaves (or unisons) by
|
|
969
|
-
* similar motion.
|
|
970
|
-
*/
|
|
971
|
-
declare function createsParallelOctave(aPrev: number, aCur: number, bPrev: number, bCur: number): boolean;
|
|
972
|
-
/**
|
|
973
|
-
* Whether two voices move in consecutive parallel unisons — both landing on the
|
|
974
|
-
* same pitch, having shared a pitch on the previous move.
|
|
975
|
-
*/
|
|
976
|
-
declare function createsParallelUnison(aPrev: number, aCur: number, bPrev: number, bCur: number): boolean;
|
|
977
|
-
/**
|
|
978
|
-
* Whether two voices reach a perfect interval by similar motion from an
|
|
979
|
-
* imperfect one (a hidden/direct fifth or octave).
|
|
980
|
-
*
|
|
981
|
-
* The traditional step exception is applied: the approach is allowed when the
|
|
982
|
-
* upper of the two voices moves by step, so only leaps into the perfect
|
|
983
|
-
* interval are flagged.
|
|
984
|
-
*/
|
|
985
|
-
declare function createsHiddenParallelPerfect(aPrev: number, aCur: number, bPrev: number, bCur: number): boolean;
|
|
986
|
-
/**
|
|
987
|
-
* Whether two voices overlap: the upper voice descends below where the lower
|
|
988
|
-
* voice just was, or the lower voice rises above where the upper voice just was.
|
|
989
|
-
* Distinct from a simultaneous voice crossing.
|
|
990
|
-
*
|
|
991
|
-
* @param upperPrev Previous pitch of the upper voice.
|
|
992
|
-
* @param upperCur Current pitch of the upper voice.
|
|
993
|
-
* @param lowerPrev Previous pitch of the lower voice.
|
|
994
|
-
* @param lowerCur Current pitch of the lower voice.
|
|
995
|
-
*/
|
|
996
|
-
declare function createsVoiceOverlap(upperPrev: number, upperCur: number, lowerPrev: number, lowerCur: number): boolean;
|
|
997
|
-
/**
|
|
998
|
-
* Whether two adjacent upper voices are spaced more than a maximum apart
|
|
999
|
-
* (commonly an octave). Bass-to-tenor spacing is conventionally exempt, so this
|
|
1000
|
-
* is meant for the upper voice pairs.
|
|
1001
|
-
*
|
|
1002
|
-
* @param upperPitch Pitch of the higher voice.
|
|
1003
|
-
* @param lowerPitch Pitch of the lower voice.
|
|
1004
|
-
* @param maxSemitones Maximum allowed spacing in semitones (default an octave).
|
|
1005
|
-
*/
|
|
1006
|
-
declare function exceedsSpacing(upperPitch: number, lowerPitch: number, maxSemitones?: number): boolean;
|
|
1007
|
-
/**
|
|
1008
|
-
* Whether a leading tone resolves correctly upward to the tonic.
|
|
1009
|
-
*
|
|
1010
|
-
* @param prev The leading-tone pitch.
|
|
1011
|
-
* @param cur The following pitch.
|
|
1012
|
-
* @param key Key context supplying the tonic.
|
|
1013
|
-
* @returns True when `prev` is the leading tone and `cur` is the tonic a step above.
|
|
1014
|
-
*/
|
|
1015
|
-
declare function isLeadingToneResolution(prev: number, cur: number, key: KeyScale): boolean;
|
|
1016
|
-
|
|
1017
|
-
/**
|
|
1018
|
-
* Recognition: infer a chord name from a set of pitches, or a key from a set of
|
|
1019
|
-
* pitch classes. This is the inverse direction of the chord/scale builders,
|
|
1020
|
-
* which only go name -> notes.
|
|
1021
|
-
*/
|
|
1022
|
-
|
|
1023
|
-
/** A candidate chord interpretation of a pitch set. */
|
|
1024
|
-
type ChordMatch = {
|
|
1025
|
-
rootPc: number;
|
|
1026
|
-
quality: ChordQuality;
|
|
1027
|
-
/** Chord tones absent from the input (an incomplete voicing). */
|
|
1028
|
-
missingPcs: number[];
|
|
1029
|
-
/** Input pitch classes not belonging to the chord. */
|
|
1030
|
-
extraPcs: number[];
|
|
1031
|
-
/** True when the input pitch-class set equals the chord exactly. */
|
|
1032
|
-
exact: boolean;
|
|
1033
|
-
/** Inversion implied by the lowest note: 0 root position, 1 first, ... */
|
|
1034
|
-
inversion: number;
|
|
1035
|
-
/** Bass pitch class when inverted (the lowest note is not the root). */
|
|
1036
|
-
bassPc?: number;
|
|
1037
|
-
};
|
|
1038
|
-
/** A candidate key interpretation of a pitch-class set. */
|
|
1039
|
-
type KeyMatch = {
|
|
1040
|
-
key: KeyScale;
|
|
1041
|
-
mode: 'major' | 'minor';
|
|
1042
|
-
/** Fraction of input pitch classes that are in the scale, in [0, 1]. */
|
|
1043
|
-
fit: number;
|
|
1044
|
-
};
|
|
1045
|
-
/**
|
|
1046
|
-
* Identify chords matching a set of pitches.
|
|
1047
|
-
*
|
|
1048
|
-
* Every input pitch class is tried as a root against every known chord quality.
|
|
1049
|
-
* A match is reported when all of the chord's tones are present in the input, or
|
|
1050
|
-
* when the only absent tone is the perfect fifth (a common omission in shell
|
|
1051
|
-
* voicings); matches are ranked best-first by fewest extra notes, then fewest
|
|
1052
|
-
* missing notes, then most specific (largest) chord. An exact match (no extras,
|
|
1053
|
-
* no missing) is flagged and ranked first.
|
|
1054
|
-
*
|
|
1055
|
-
* @param pitches MIDI pitches or bare pitch classes (octave-agnostic).
|
|
1056
|
-
* @returns Ranked chord interpretations (may be empty).
|
|
1057
|
-
*/
|
|
1058
|
-
declare function detectChord(pitches: number[]): ChordMatch[];
|
|
1059
|
-
/**
|
|
1060
|
-
* The single best chord interpretation of a pitch set, or null if none.
|
|
1061
|
-
*
|
|
1062
|
-
* @param pitches MIDI pitches or bare pitch classes.
|
|
1063
|
-
* @returns The top-ranked chord, or null when nothing matches.
|
|
1064
|
-
*/
|
|
1065
|
-
declare function detectChordBest(pitches: number[]): Chord$1 | null;
|
|
1066
|
-
/**
|
|
1067
|
-
* Rank major and minor keys by how well they contain a set of pitch classes.
|
|
1068
|
-
*
|
|
1069
|
-
* The tonic is weighted so that, among equally-fitting keys, the one whose root
|
|
1070
|
-
* appears in the input is preferred. Returns all 24 keys ranked best-first.
|
|
1071
|
-
*
|
|
1072
|
-
* @param pitches MIDI pitches or bare pitch classes.
|
|
1073
|
-
* @returns Ranked key interpretations.
|
|
1074
|
-
*/
|
|
1075
|
-
declare function detectKey(pitches: number[]): KeyMatch[];
|
|
1076
|
-
|
|
1077
|
-
/** A single percussion onset. */
|
|
1078
|
-
type DrumHit = {
|
|
1079
|
-
pitch: number;
|
|
1080
|
-
startBeat: number;
|
|
1081
|
-
durationBeat: number;
|
|
1082
|
-
velocity: number;
|
|
1083
|
-
};
|
|
1084
|
-
|
|
1085
|
-
/** Groove feel controlling off-beat swing. */
|
|
1086
|
-
type Feel = 'straight' | 'swing' | 'shuffle';
|
|
1087
|
-
/** Public groove style identifiers. */
|
|
1088
|
-
type GrooveStyle = 'standard' | 'funk' | 'shuffle' | 'bossa' | 'trap' | 'halftime' | 'breakbeat';
|
|
1089
|
-
/** Public role identifiers gating which voices are present. */
|
|
1090
|
-
type DrumRole = 'full' | 'ambient' | 'minimal' | 'fxOnly';
|
|
1091
|
-
/** Public section identifiers. */
|
|
1092
|
-
type PublicSection = 'intro' | 'verse' | 'prechorus' | 'chorus' | 'bridge' | 'outro';
|
|
1093
|
-
|
|
1094
|
-
type GrooveFeel = Feel;
|
|
1095
|
-
|
|
1096
|
-
/** Public section identifiers for {@link generateDrums}. */
|
|
1097
|
-
type Section = PublicSection;
|
|
1098
|
-
/** Options controlling {@link generateDrums}. */
|
|
1099
|
-
type DrumGenOptions = {
|
|
1100
|
-
bars: number;
|
|
1101
|
-
bpm: number;
|
|
1102
|
-
style: GrooveStyle;
|
|
1103
|
-
section: Section;
|
|
1104
|
-
density: number;
|
|
1105
|
-
fills?: boolean;
|
|
1106
|
-
feel?: GrooveFeel;
|
|
1107
|
-
role?: DrumRole;
|
|
1108
|
-
seed?: number;
|
|
1109
|
-
};
|
|
1110
|
-
/**
|
|
1111
|
-
* Generate a drum performance as a flat list of onsets.
|
|
1112
|
-
*
|
|
1113
|
-
* Every voice (kick, snare, ghost snares, closed/open/foot hi-hats, ride, toms,
|
|
1114
|
-
* crash, and auxiliary percussion) is emitted as a {@link DrumHit} distinguished
|
|
1115
|
-
* by its General MIDI pitch. Groove style selects an internal style and feel;
|
|
1116
|
-
* `density` sets the backing-density level; `section` shapes kick, hi-hat, ghost,
|
|
1117
|
-
* and percussion density. 16th-note hi-hats drop to 8ths at or above 150 BPM.
|
|
1118
|
-
* When `fills` is true the final bar is replaced with a fill. Output is fully
|
|
1119
|
-
* determined by the options plus `seed`.
|
|
1120
|
-
*
|
|
1121
|
-
* @param opts Generation options.
|
|
1122
|
-
* @returns Percussion onsets in bar order.
|
|
1123
|
-
*/
|
|
1124
|
-
declare function generateDrums(opts: DrumGenOptions): DrumHit[];
|
|
1125
|
-
|
|
1126
|
-
/**
|
|
1127
|
-
* Groove and humanization: nudging quantized note events toward a more human
|
|
1128
|
-
* feel, and capturing/replaying the timing-and-velocity "feel" of a
|
|
1129
|
-
* performance as a reusable groove template.
|
|
1130
|
-
*
|
|
1131
|
-
* Positions and durations are measured in quarter-note beats, matching the
|
|
1132
|
-
* library-wide convention. Randomness, where used, always goes through the
|
|
1133
|
-
* seeded PRNG from the `random` module so results are fully reproducible.
|
|
1134
|
-
*/
|
|
1135
|
-
|
|
1136
|
-
/** Options controlling {@link humanize}. */
|
|
1137
|
-
type HumanizeOptions = {
|
|
1138
|
-
/** Time signature used to derive metric accents. Default 4/4. */
|
|
1139
|
-
ts?: TimeSignature;
|
|
1140
|
-
/** Maximum timing jitter in quarter-note beats, applied as ±this value. Default 0.02. */
|
|
1141
|
-
timing?: number;
|
|
1142
|
-
/** Maximum velocity jitter (MIDI units), applied as ±this value. Default 8. */
|
|
1143
|
-
velocity?: number;
|
|
1144
|
-
/** How much louder strong beats get relative to weak ones, in MIDI velocity units. Default 12. */
|
|
1145
|
-
accent?: number;
|
|
1146
|
-
/** Velocity assumed for events with no `velocity` of their own. Default 80. */
|
|
1147
|
-
baseVelocity?: number;
|
|
1148
|
-
/** Seed for the deterministic PRNG. Default 0. */
|
|
1149
|
-
seed?: number;
|
|
1150
|
-
};
|
|
1151
|
-
/**
|
|
1152
|
-
* Humanize a sequence of note events by nudging their timing and velocity
|
|
1153
|
-
* with small, deterministic (seeded) randomness plus a metric-accent shape:
|
|
1154
|
-
* events on strong beats (see {@link metricWeight}) come out louder on
|
|
1155
|
-
* average than events on weak ones.
|
|
1156
|
-
*
|
|
1157
|
-
* Each returned event is a copy; `startBeat` is jittered within
|
|
1158
|
-
* `[-timing, +timing]` beats and clamped to be non-negative, and `velocity`
|
|
1159
|
-
* is the event's own velocity (or `baseVelocity` if it has none) plus an
|
|
1160
|
-
* accent term scaled by the event's metric weight plus a jitter within
|
|
1161
|
-
* `[-velocity, +velocity]`, clamped to `[1, 127]` and rounded. The metric
|
|
1162
|
-
* weight is computed from each event's original (pre-jitter) `startBeat`.
|
|
1163
|
-
* `pitch` and `durationBeat` pass through unchanged, and the output keeps the
|
|
1164
|
-
* input order.
|
|
1165
|
-
*
|
|
1166
|
-
* @param events The events to humanize.
|
|
1167
|
-
* @param opts Humanization options.
|
|
1168
|
-
* @returns Humanized copies of `events`, in input order.
|
|
1169
|
-
*/
|
|
1170
|
-
declare function humanize(events: NoteEvent[], opts?: HumanizeOptions): NoteEvent[];
|
|
1171
|
-
/** The recorded feel at a single grid slot: an average timing deviation and velocity. */
|
|
1172
|
-
type GrooveSlot = {
|
|
1173
|
-
/** Average `actualStartBeat - quantizedBeat` (in quarter-note beats) for events landing on this slot. */
|
|
1174
|
-
timingOffset: number;
|
|
1175
|
-
/** Average velocity of events landing on this slot; 0 if none did. */
|
|
1176
|
-
velocity: number;
|
|
1177
|
-
};
|
|
1178
|
-
/** A per-bar grid of timing and velocity deviations captured from a performance. */
|
|
1179
|
-
type GrooveTemplate = {
|
|
1180
|
-
/** Grid resolution: equal grid steps per quarter-note beat. */
|
|
1181
|
-
subdivision: number;
|
|
1182
|
-
/** Number of grid slots per bar (`beatsPerBar(ts) * subdivision`). */
|
|
1183
|
-
slotsPerBar: number;
|
|
1184
|
-
/** One entry per grid slot, in slot-index order (slot 0 is the downbeat). */
|
|
1185
|
-
slots: GrooveSlot[];
|
|
1186
|
-
};
|
|
1187
|
-
/**
|
|
1188
|
-
* Extract a groove template from a set of note events: for each grid slot,
|
|
1189
|
-
* the average timing deviation from the quantized grid and the average
|
|
1190
|
-
* velocity of events landing on it. Slots with no events default to
|
|
1191
|
-
* `{ timingOffset: 0, velocity: 0 }`.
|
|
1192
|
-
*
|
|
1193
|
-
* @param events The (typically "groovy", human-played) events to analyze.
|
|
1194
|
-
* @param ts The time signature, used to compute the bar length.
|
|
1195
|
-
* @param subdivision Grid resolution: equal grid steps per quarter-note beat.
|
|
1196
|
-
* @returns The extracted groove template.
|
|
1197
|
-
*/
|
|
1198
|
-
declare function extractGrooveTemplate(events: NoteEvent[], ts: TimeSignature, subdivision: number): GrooveTemplate;
|
|
1199
|
-
/**
|
|
1200
|
-
* Apply a groove template to a set of (typically quantized) note events: each
|
|
1201
|
-
* event is snapped to its grid slot and then offset by that slot's recorded
|
|
1202
|
-
* timing deviation, pushing stiff timing toward the template's feel.
|
|
1203
|
-
* Velocity is set to the slot's recorded average when it recorded any
|
|
1204
|
-
* (`velocity > 0`); otherwise the event's own velocity is left untouched.
|
|
1205
|
-
*
|
|
1206
|
-
* @param events The events to reshape.
|
|
1207
|
-
* @param template The groove template, from {@link extractGrooveTemplate}.
|
|
1208
|
-
* @param ts The time signature, used to compute the bar length.
|
|
1209
|
-
* @returns Reshaped copies of `events`, in input order.
|
|
1210
|
-
*/
|
|
1211
|
-
declare function applyGrooveTemplate(events: NoteEvent[], template: GrooveTemplate, ts: TimeSignature): NoteEvent[];
|
|
1212
|
-
|
|
1213
|
-
/** Harmonic role a pitch plays within a chord. */
|
|
1214
|
-
type HarmonyRole = 'root' | 'third' | 'fifth' | 'sixth' | 'seventh' | 'tension' | 'doubling';
|
|
1215
|
-
/**
|
|
1216
|
-
* How firmly a pitch is locked to the chord's identity.
|
|
1217
|
-
*
|
|
1218
|
-
* - `identity`: moving it produces a different chord (the root).
|
|
1219
|
-
* - `quality`: moving it flips the chord quality (the third).
|
|
1220
|
-
* - `voicing`: it can move freely without changing chord identity or quality.
|
|
1221
|
-
*/
|
|
1222
|
-
type LockLevel = 'identity' | 'quality' | 'voicing';
|
|
1223
|
-
/** A pitch's role, lock level, and owning chord. */
|
|
1224
|
-
type VoicedRole = {
|
|
1225
|
-
role: HarmonyRole;
|
|
1226
|
-
lock: LockLevel;
|
|
1227
|
-
belongsToChordId: number;
|
|
1228
|
-
};
|
|
1229
|
-
/**
|
|
1230
|
-
* Classify a pitch's harmonic role and lock level within a chord.
|
|
1231
|
-
*
|
|
1232
|
-
* The role comes from the pitch's interval class above the chord root: root (0),
|
|
1233
|
-
* third (3/4), fifth (6/7/8), seventh (10/11), and 9/11/13 tensions (2/5/9, and
|
|
1234
|
-
* the flat ninth 1). The root locks the chord identity, the third locks its
|
|
1235
|
-
* quality, and everything else is free voicing. In a suspended chord (a chord
|
|
1236
|
-
* whose intervals include a 4th (5) or 2nd (2) but no third), the suspended tone
|
|
1237
|
-
* takes the third's place as the quality-defining tone and is locked to
|
|
1238
|
-
* `quality`, since moving it changes the chord. Detecting an octave doubling
|
|
1239
|
-
* requires the surrounding voicing, which this single-pitch query does not carry,
|
|
1240
|
-
* so `doubling` is part of the type but not returned here.
|
|
1241
|
-
*
|
|
1242
|
-
* @param pitch MIDI pitch or bare pitch class.
|
|
1243
|
-
* @param chord The chord providing the root reference.
|
|
1244
|
-
* @param chordId Identifier stored on the result (defaults to 0).
|
|
1245
|
-
* @returns The pitch's role, lock level, and owning chord id.
|
|
1246
|
-
*/
|
|
1247
|
-
declare function roleOf(pitch: number, chord: Chord$1, chordId?: number): VoicedRole;
|
|
1248
|
-
|
|
1249
|
-
/** A melody note supplied to the harmonizer: a {@link NoteEvent}. */
|
|
1250
|
-
type MelodyNote = NoteEvent;
|
|
1251
|
-
/** Options controlling {@link harmonizeMelody}. */
|
|
1252
|
-
type HarmonizeOptions = {
|
|
1253
|
-
melody: MelodyNote[];
|
|
1254
|
-
key: KeyScale | 'infer';
|
|
1255
|
-
harmonicRhythm: number;
|
|
1256
|
-
reharmonize: 'diatonic' | 'secondaryDominant' | 'borrowed';
|
|
1257
|
-
placement: {
|
|
1258
|
-
transposeSearch: boolean;
|
|
1259
|
-
octaveSearch: boolean;
|
|
1260
|
-
};
|
|
1261
|
-
seed?: number;
|
|
1262
|
-
};
|
|
1263
|
-
/** The chosen transpose, key, chord path, and per-note roles. */
|
|
1264
|
-
type HarmonizeResult = {
|
|
1265
|
-
transposeSemitones: number;
|
|
1266
|
-
key: KeyScale;
|
|
1267
|
-
chords: GeneratedChord[];
|
|
1268
|
-
melodyRoles: {
|
|
1269
|
-
noteIndex: number;
|
|
1270
|
-
role: HarmonyRole;
|
|
1271
|
-
}[];
|
|
1272
|
-
};
|
|
1273
|
-
/**
|
|
1274
|
-
* Harmonize a melody with a min-cost chord progression.
|
|
1275
|
-
*
|
|
1276
|
-
* The melody is segmented by `harmonicRhythm`; each segment is scored against
|
|
1277
|
-
* diatonic (and, per `reharmonize`, secondary-dominant and borrowed) candidate
|
|
1278
|
-
* chords by melody fit, and a Viterbi search picks the lowest-cost path using a
|
|
1279
|
-
* functional-flow transition cost. When `placement.transposeSearch`/`octaveSearch`
|
|
1280
|
-
* is set, the whole melody is transposed across a range and the best
|
|
1281
|
-
* `(transpose, progression)` pair is returned; a small tessitura cost breaks
|
|
1282
|
-
* ties toward placements that keep the melody in a comfortable register.
|
|
1283
|
-
*
|
|
1284
|
-
* @param opts Melody, key (or `'infer'`), harmonic rhythm, reharmonization
|
|
1285
|
-
* strength, height-search flags, and seed.
|
|
1286
|
-
* @returns The chosen transpose, key, chord path, and per-note roles.
|
|
1287
|
-
*/
|
|
1288
|
-
declare function harmonizeMelody(opts: HarmonizeOptions): HarmonizeResult;
|
|
1289
|
-
|
|
1290
|
-
/** Counterpoint classification of a harmonic interval. */
|
|
1291
|
-
declare enum IntervalQuality {
|
|
1292
|
-
PerfectConsonance = 0,
|
|
1293
|
-
ImperfectConsonance = 1,
|
|
1294
|
-
Dissonance = 2
|
|
1295
|
-
}
|
|
1296
|
-
/**
|
|
1297
|
-
* Classify an interval for counterpoint evaluation.
|
|
1298
|
-
*
|
|
1299
|
-
* The interval is reduced modulo 12, so compound intervals classify as their
|
|
1300
|
-
* simple equivalents. The perfect fourth (5) is context-dependent: with
|
|
1301
|
-
* `twoVoice` (the default) it classifies as a dissonance, matching
|
|
1302
|
-
* {@link isConsonantInterval}; otherwise it is an imperfect consonance.
|
|
1303
|
-
*
|
|
1304
|
-
* @param semitones Interval size in semitones (may be negative or compound).
|
|
1305
|
-
* @param twoVoice When true, the perfect fourth is treated as dissonant.
|
|
1306
|
-
* @returns The counterpoint quality of the interval.
|
|
1307
|
-
*/
|
|
1308
|
-
declare function classifyInterval(semitones: number, twoVoice?: boolean): IntervalQuality;
|
|
1309
|
-
/**
|
|
1310
|
-
* Test whether an interval is a perfect interval (unison/octave or fifth).
|
|
1311
|
-
*
|
|
1312
|
-
* @param semitones Interval size in semitones (may be negative or compound).
|
|
1313
|
-
* @returns True for the unison/octave (0) and the perfect fifth (7) mod 12.
|
|
1314
|
-
*/
|
|
1315
|
-
declare function isPerfectInterval(semitones: number): boolean;
|
|
1316
|
-
/**
|
|
1317
|
-
* Test whether an interval is consonant.
|
|
1318
|
-
*
|
|
1319
|
-
* The consonant set is {0, 3, 4, 5, 7, 8, 9} mod 12. In two-voice counterpoint
|
|
1320
|
-
* the perfect fourth (5) is treated as a dissonance, so `twoVoice` set to true
|
|
1321
|
-
* excludes it.
|
|
1322
|
-
*
|
|
1323
|
-
* @param semitones Interval size in semitones (may be negative or compound).
|
|
1324
|
-
* @param twoVoice When true, the perfect fourth is treated as dissonant.
|
|
1325
|
-
* @returns True if the interval is consonant in the given context.
|
|
1326
|
-
*/
|
|
1327
|
-
declare function isConsonantInterval(semitones: number, twoVoice?: boolean): boolean;
|
|
1328
|
-
|
|
1329
|
-
/**
|
|
1330
|
-
* Pitch spelling: letter-name notes, enharmonic-aware conversion, and spelled
|
|
1331
|
-
* intervals.
|
|
1332
|
-
*
|
|
1333
|
-
* The rest of the library works in pitch classes (0..11), which cannot tell a
|
|
1334
|
-
* G# from an Ab or an augmented fourth from a diminished fifth. This module adds
|
|
1335
|
-
* an explicit spelling layer — a note is a diatonic letter plus a chromatic
|
|
1336
|
-
* alteration — so interval quality (P/M/m/A/d) and enharmonic identity are
|
|
1337
|
-
* preserved.
|
|
1338
|
-
*/
|
|
1339
|
-
/**
|
|
1340
|
-
* A spelled note: a diatonic letter, a chromatic alteration, and an optional
|
|
1341
|
-
* octave.
|
|
1342
|
-
*
|
|
1343
|
-
* - `letter` is 0..6 for C..B.
|
|
1344
|
-
* - `alter` is the number of semitones of alteration: -2 double-flat, -1 flat,
|
|
1345
|
-
* 0 natural, +1 sharp, +2 double-sharp.
|
|
1346
|
-
* - `octave` follows scientific pitch notation (middle C = C4 = MIDI 60). When
|
|
1347
|
-
* absent, the note denotes a bare pitch class.
|
|
1348
|
-
*/
|
|
1349
|
-
type Note$1 = {
|
|
1350
|
-
letter: number;
|
|
1351
|
-
alter: number;
|
|
1352
|
-
octave?: number;
|
|
1353
|
-
};
|
|
1354
|
-
/** A spelled interval: a diatonic number, a quality label, and its semitone span. */
|
|
1355
|
-
type SpelledInterval = {
|
|
1356
|
-
/** Diatonic size: 1 = unison, 2 = second, ... 8 = octave, and beyond. */
|
|
1357
|
-
number: number;
|
|
1358
|
-
/** Quality label: 'P', 'M', 'm', or repeated 'A'/'d' for (multiply) aug/dim. */
|
|
1359
|
-
quality: string;
|
|
1360
|
-
/** Signed semitone distance from the first note to the second. */
|
|
1361
|
-
semitones: number;
|
|
1362
|
-
};
|
|
1363
|
-
/**
|
|
1364
|
-
* Parse scientific pitch notation into a {@link Note}.
|
|
1365
|
-
*
|
|
1366
|
-
* Accepts a letter (case-insensitive) followed by any number of same-direction
|
|
1367
|
-
* accidentals and an optional octave, e.g. `"C"`, `"C#4"`, `"Bb"`, `"F##3"`,
|
|
1368
|
-
* `"Ebb2"`. Both `#` and `x` (double-sharp) are accepted for sharps; `b` for
|
|
1369
|
-
* flats. Mixing sharps and flats (e.g. `"C#b"`) is rejected.
|
|
1370
|
-
*
|
|
1371
|
-
* @param text The note text.
|
|
1372
|
-
* @returns The parsed note.
|
|
1373
|
-
* @throws If the text is not a valid note.
|
|
1374
|
-
*/
|
|
1375
|
-
declare function parseNote(text: string): Note$1;
|
|
1376
|
-
/**
|
|
1377
|
-
* Render a {@link Note} as scientific pitch notation.
|
|
1378
|
-
*
|
|
1379
|
-
* @param note The note to format.
|
|
1380
|
-
* @returns The note text, including the octave when present.
|
|
1381
|
-
*/
|
|
1382
|
-
declare function formatNote(note: Note$1): string;
|
|
1383
|
-
/**
|
|
1384
|
-
* Pitch class (0..11) of a note, ignoring octave.
|
|
1385
|
-
*
|
|
1386
|
-
* @param note The note.
|
|
1387
|
-
* @returns The pitch class.
|
|
1388
|
-
*/
|
|
1389
|
-
declare function noteToPitchClass(note: Note$1): number;
|
|
1390
|
-
/**
|
|
1391
|
-
* MIDI number of a note (middle C = C4 = 60).
|
|
1392
|
-
*
|
|
1393
|
-
* @param note The note; must carry an octave.
|
|
1394
|
-
* @returns The MIDI number.
|
|
1395
|
-
* @throws If the note has no octave.
|
|
1396
|
-
*/
|
|
1397
|
-
declare function noteToMidi(note: Note$1): number;
|
|
1398
|
-
/**
|
|
1399
|
-
* Name a MIDI number as a {@link Note}, choosing sharp or flat spelling.
|
|
1400
|
-
*
|
|
1401
|
-
* @param midi The MIDI number.
|
|
1402
|
-
* @param spelling Whether to prefer sharps or flats for black keys.
|
|
1403
|
-
* @returns The spelled note, with octave.
|
|
1404
|
-
*/
|
|
1405
|
-
declare function midiToNote(midi: number, spelling?: 'sharp' | 'flat'): Note$1;
|
|
1406
|
-
/**
|
|
1407
|
-
* The spelled interval from one note to another.
|
|
1408
|
-
*
|
|
1409
|
-
* When both notes carry octaves, the interval reflects their full signed
|
|
1410
|
-
* distance (so `C4 -> C5` is a perfect octave). When either lacks an octave the
|
|
1411
|
-
* interval is measured within a single ascending octave from `a` to `b`.
|
|
1412
|
-
*
|
|
1413
|
-
* @param a The lower/first note.
|
|
1414
|
-
* @param b The upper/second note.
|
|
1415
|
-
* @returns The diatonic number, quality, and semitone span.
|
|
1416
|
-
*/
|
|
1417
|
-
declare function spelledInterval(a: Note$1, b: Note$1): SpelledInterval;
|
|
1418
|
-
|
|
1419
|
-
/** An inclusive MIDI pitch range for a single voice. */
|
|
1420
|
-
type VoiceRange = {
|
|
1421
|
-
min: number;
|
|
1422
|
-
max: number;
|
|
1423
|
-
};
|
|
1424
|
-
/**
|
|
1425
|
-
* Default four-voice SATB ranges, ascending (index 0 = lowest):
|
|
1426
|
-
* bass E2–C4 (40–60), tenor C3–G4 (48–67), alto G3–D5 (55–74),
|
|
1427
|
-
* soprano C4–G5 (60–79).
|
|
1428
|
-
*/
|
|
1429
|
-
declare const SATB_RANGES: readonly VoiceRange[];
|
|
1430
|
-
/** Options controlling {@link voiceChord} and {@link voiceProgression}. */
|
|
1431
|
-
type VoicingOptions = {
|
|
1432
|
-
/** Number of voices to realize (default 4). Ignored when `ranges` is given. */
|
|
1433
|
-
voices?: number;
|
|
1434
|
-
/** Explicit per-voice ranges, ascending (index 0 = lowest). Takes precedence over `voices`. */
|
|
1435
|
-
ranges?: VoiceRange[];
|
|
1436
|
-
/** Maximum spacing in semitones between adjacent upper voices (default 12). */
|
|
1437
|
-
maxSpacing?: number;
|
|
1438
|
-
};
|
|
1439
|
-
/**
|
|
1440
|
-
* Total voice-leading cost between two voicings: the sum of absolute semitone
|
|
1441
|
-
* motion across voices. The arrays must be the same length; when they differ
|
|
1442
|
-
* the voicings are not comparable and the cost is `Infinity`.
|
|
1443
|
-
*
|
|
1444
|
-
* @param from The previous voicing, one MIDI pitch per voice.
|
|
1445
|
-
* @param to The next voicing, one MIDI pitch per voice.
|
|
1446
|
-
* @returns The summed absolute motion, or `Infinity` when lengths differ.
|
|
1447
|
-
*/
|
|
1448
|
-
declare function voiceLeadingCost(from: number[], to: number[]): number;
|
|
1449
|
-
/**
|
|
1450
|
-
* Realize a single chord as one MIDI pitch per voice, ascending (index 0 =
|
|
1451
|
-
* lowest). The bass voice takes the chord's `bassPc` when set, otherwise the
|
|
1452
|
-
* root; upper voices take chord pitch classes, doubling the root or fifth as
|
|
1453
|
-
* needed to fill all voices. The result stays inside each voice's range, keeps
|
|
1454
|
-
* adjacent upper voices within `maxSpacing`, avoids voice crossing, and is
|
|
1455
|
-
* deterministic: a compact close-position voicing centered in the ranges.
|
|
1456
|
-
*
|
|
1457
|
-
* @param chord The chord to voice.
|
|
1458
|
-
* @param opts Voicing options; defaults to four voices in {@link SATB_RANGES}.
|
|
1459
|
-
* @returns MIDI pitches, ascending, one per voice.
|
|
1460
|
-
* @throws If no voicing fits the given ranges.
|
|
1461
|
-
*/
|
|
1462
|
-
declare function voiceChord(chord: Chord$1, opts?: VoicingOptions): number[];
|
|
1463
|
-
/**
|
|
1464
|
-
* Voice a chord progression with smooth voice leading. The first chord is
|
|
1465
|
-
* voiced with {@link voiceChord}; each subsequent chord picks, from a bounded
|
|
1466
|
-
* deterministic candidate set, the voicing minimizing the voice-leading cost
|
|
1467
|
-
* from the previous voicing plus a large penalty per counterpoint violation
|
|
1468
|
-
* (parallel perfects/octaves, voice crossing, voice overlap, and over-wide
|
|
1469
|
-
* upper-voice spacing).
|
|
1470
|
-
*
|
|
1471
|
-
* @param chords The chords to voice in order.
|
|
1472
|
-
* @param opts Voicing options; defaults to four voices in {@link SATB_RANGES}.
|
|
1473
|
-
* @returns One voicing per chord, each ascending with one MIDI pitch per voice.
|
|
1474
|
-
* @throws If any chord admits no voicing within the given ranges.
|
|
1475
|
-
*/
|
|
1476
|
-
declare function voiceProgression(chords: Chord$1[], opts?: VoicingOptions): number[][];
|
|
1477
|
-
/**
|
|
1478
|
-
* A tertian voicing style for {@link voiceChordStyled}.
|
|
1479
|
-
*
|
|
1480
|
-
* - `close`: the plain close-position tertian stack.
|
|
1481
|
-
* - `drop2`: the second voice from the top dropped an octave (drop-2 voicing).
|
|
1482
|
-
* - `drop3`: the third voice from the top dropped an octave (drop-3 voicing).
|
|
1483
|
-
* - `shell`: root plus guide tones (third and seventh) for seventh chords, or
|
|
1484
|
-
* root/third/fifth for triads; the fifth and tensions are omitted.
|
|
1485
|
-
* - `rootless`: the root omitted, keeping third/fifth/seventh and tensions
|
|
1486
|
-
* (a typical left-hand jazz voicing).
|
|
1487
|
-
*/
|
|
1488
|
-
type VoicingStyle = 'close' | 'drop2' | 'drop3' | 'shell' | 'rootless';
|
|
1489
|
-
/** Options controlling {@link voiceChordStyled}. */
|
|
1490
|
-
type StyledVoicingOptions = {
|
|
1491
|
-
/** Voicing style to build (default `close`). */
|
|
1492
|
-
style?: VoicingStyle;
|
|
1493
|
-
/** Constrain the highest voice to this pitch class (0..11) when given. */
|
|
1494
|
-
topNote?: number;
|
|
1495
|
-
/** Base octave for the close stack; the stack begins near `12 * octave` (default 4). */
|
|
1496
|
-
octave?: number;
|
|
1497
|
-
/** Omit the root regardless of style (relevant for jazz voicings). */
|
|
1498
|
-
rootless?: boolean;
|
|
1499
|
-
};
|
|
1500
|
-
/**
|
|
1501
|
-
* Realize a single chord as an explicit tertian voicing in a chosen style,
|
|
1502
|
-
* independent of the SATB range search used by {@link voiceChord}.
|
|
1503
|
-
*
|
|
1504
|
-
* The chord tones are stacked in close position from the bass (`bassPc`, else
|
|
1505
|
-
* `rootPc`) in the given scientific-pitch `octave` upward (octave 4 starts the
|
|
1506
|
-
* bass near C4 = MIDI 60, matching {@link midiToNote} and the bass module).
|
|
1507
|
-
* When `topNote` is given the stack is rotated so the highest voice's pitch
|
|
1508
|
-
* class equals that note (or the nearest chord tone). The chosen
|
|
1509
|
-
* {@link VoicingStyle} then transforms the stack, and the result is returned as
|
|
1510
|
-
* ascending MIDI pitches (index 0 = lowest).
|
|
1511
|
-
*
|
|
1512
|
-
* @param chord The chord to voice.
|
|
1513
|
-
* @param opts Styled voicing options; defaults to a close voicing at octave 4.
|
|
1514
|
-
* @returns MIDI pitches, ascending, one per retained voice.
|
|
1515
|
-
*/
|
|
1516
|
-
declare function voiceChordStyled(chord: Chord$1, opts?: StyledVoicingOptions): number[];
|
|
1517
|
-
/**
|
|
1518
|
-
* Voice a single chord to follow smoothly from an arbitrary current voicing.
|
|
1519
|
-
*
|
|
1520
|
-
* Candidate voicings of `chord` are enumerated within ranges taken from `opts`,
|
|
1521
|
-
* or — when neither `voices` nor `ranges` is given — from a one-octave window
|
|
1522
|
-
* around each pitch of `current` (so the result matches `current`'s voice
|
|
1523
|
-
* count). Each candidate is scored by structural quality, voice-leading motion
|
|
1524
|
-
* from `current`, and a large penalty per counterpoint violation; the lowest
|
|
1525
|
-
* scoring candidate is returned, ascending.
|
|
1526
|
-
*
|
|
1527
|
-
* @param current The current voicing to lead from, ascending (index 0 = lowest).
|
|
1528
|
-
* @param chord The next chord to voice.
|
|
1529
|
-
* @param opts Voicing options; when omitted, ranges follow `current`'s span.
|
|
1530
|
-
* @returns The chosen voicing, ascending with one MIDI pitch per voice.
|
|
1531
|
-
* @throws If no voicing fits the derived ranges.
|
|
1532
|
-
*/
|
|
1533
|
-
declare function nextVoicing(current: number[], chord: Chord$1, opts?: VoicingOptions): number[];
|
|
1534
|
-
|
|
1535
|
-
/**
|
|
1536
|
-
* Fluent, immutable object model over the functional core.
|
|
1537
|
-
*
|
|
1538
|
-
* Each class wraps one of the library's plain data types (spelled notes,
|
|
1539
|
-
* chords, key/scales) and delegates every operation to the existing pure
|
|
1540
|
-
* functions. All instances are immutable: fields are read-only, transforming
|
|
1541
|
-
* methods return new instances, and getters hand out defensive copies of any
|
|
1542
|
-
* mutable data.
|
|
1543
|
-
*/
|
|
1544
|
-
|
|
1545
|
-
/**
|
|
1546
|
-
* An immutable spelled note: a diatonic letter plus a chromatic alteration and
|
|
1547
|
-
* an optional octave. Wraps the plain note object and delegates to the pitch
|
|
1548
|
-
* module; every transformation returns a new instance.
|
|
1549
|
-
*/
|
|
1550
|
-
declare class Note {
|
|
1551
|
-
#private;
|
|
1552
|
-
/**
|
|
1553
|
-
* Wrap a plain note object.
|
|
1554
|
-
*
|
|
1555
|
-
* @param data The spelled note; it is copied, never retained or mutated.
|
|
1556
|
-
*/
|
|
1557
|
-
constructor(data: Note$1);
|
|
1558
|
-
/**
|
|
1559
|
-
* Parse scientific pitch notation (e.g. `'C#4'`, `'Bb'`, `'F##3'`).
|
|
1560
|
-
*
|
|
1561
|
-
* @param name The note text.
|
|
1562
|
-
* @returns The parsed note.
|
|
1563
|
-
* @throws If the text is not a valid note.
|
|
1564
|
-
*/
|
|
1565
|
-
static of(name: string): Note;
|
|
1566
|
-
/**
|
|
1567
|
-
* Name a MIDI number (middle C = C4 = 60) as a note.
|
|
1568
|
-
*
|
|
1569
|
-
* @param midi The MIDI number.
|
|
1570
|
-
* @param spelling Whether to prefer sharps or flats for black keys.
|
|
1571
|
-
* @returns The spelled note, with octave.
|
|
1572
|
-
*/
|
|
1573
|
-
static fromMidi(midi: number, spelling?: 'sharp' | 'flat'): Note;
|
|
1574
|
-
/**
|
|
1575
|
-
* Wrap an existing plain note object.
|
|
1576
|
-
*
|
|
1577
|
-
* @param data The plain note.
|
|
1578
|
-
* @returns The wrapped note.
|
|
1579
|
-
*/
|
|
1580
|
-
static fromData(data: Note$1): Note;
|
|
1581
|
-
/** The note rendered as scientific pitch notation, e.g. `'G4'` or `'Bb'`. */
|
|
1582
|
-
get name(): string;
|
|
1583
|
-
/** The pitch class (0..11), ignoring octave. */
|
|
1584
|
-
get pitchClass(): number;
|
|
1585
|
-
/**
|
|
1586
|
-
* The MIDI number (middle C = C4 = 60).
|
|
1587
|
-
*
|
|
1588
|
-
* @throws If the note has no octave and therefore no fixed pitch.
|
|
1589
|
-
*/
|
|
1590
|
-
get midi(): number;
|
|
1591
|
-
/** The diatonic letter number: 0..6 for C..B. */
|
|
1592
|
-
get letter(): number;
|
|
1593
|
-
/** The chromatic alteration in semitones: -1 flat, 0 natural, +1 sharp, ... */
|
|
1594
|
-
get alter(): number;
|
|
1595
|
-
/** The octave (scientific pitch notation), or undefined for a bare pitch class. */
|
|
1596
|
-
get octave(): number | undefined;
|
|
1597
|
-
/** A copy of the underlying plain note object. */
|
|
1598
|
-
get data(): Note$1;
|
|
1599
|
-
/**
|
|
1600
|
-
* Transpose by a signed number of semitones.
|
|
1601
|
-
*
|
|
1602
|
-
* When the note carries an octave the transposition happens in MIDI space and
|
|
1603
|
-
* the result is spelled with a sharp preference. An octave-less note stays
|
|
1604
|
-
* octave-less: only its pitch class is moved.
|
|
1605
|
-
*
|
|
1606
|
-
* @param semitones The signed semitone offset.
|
|
1607
|
-
* @returns The transposed note.
|
|
1608
|
-
*/
|
|
1609
|
-
transpose(semitones: number): Note;
|
|
1610
|
-
/**
|
|
1611
|
-
* The spelled interval from this note to another.
|
|
1612
|
-
*
|
|
1613
|
-
* @param other The second note.
|
|
1614
|
-
* @returns The diatonic number, quality, and semitone span.
|
|
1615
|
-
*/
|
|
1616
|
-
intervalTo(other: Note): SpelledInterval;
|
|
1617
|
-
/**
|
|
1618
|
-
* Whether another note has the same letter, alteration, and octave.
|
|
1619
|
-
*
|
|
1620
|
-
* @param other The note to compare.
|
|
1621
|
-
* @returns True if the spellings are identical.
|
|
1622
|
-
*/
|
|
1623
|
-
equals(other: Note): boolean;
|
|
1624
|
-
}
|
|
1625
|
-
/**
|
|
1626
|
-
* An immutable spelled interval value: a diatonic number, a quality label, and
|
|
1627
|
-
* a signed semitone span. A thin convenience wrapper over the pitch module's
|
|
1628
|
-
* plain interval result.
|
|
1629
|
-
*/
|
|
1630
|
-
declare class Interval {
|
|
1631
|
-
#private;
|
|
1632
|
-
private constructor();
|
|
1633
|
-
/**
|
|
1634
|
-
* The spelled interval between two notes.
|
|
1635
|
-
*
|
|
1636
|
-
* @param a The first note.
|
|
1637
|
-
* @param b The second note.
|
|
1638
|
-
* @returns The interval from `a` to `b`.
|
|
1639
|
-
*/
|
|
1640
|
-
static between(a: Note, b: Note): Interval;
|
|
1641
|
-
/**
|
|
1642
|
-
* Build an interval from explicit components.
|
|
1643
|
-
*
|
|
1644
|
-
* @param numberValue Diatonic size: 1 = unison, 2 = second, ... 8 = octave.
|
|
1645
|
-
* @param quality Quality label: `'P'`, `'M'`, `'m'`, or repeated `'A'`/`'d'`.
|
|
1646
|
-
* @param semitones Signed semitone span.
|
|
1647
|
-
* @returns The interval.
|
|
1648
|
-
*/
|
|
1649
|
-
static of(numberValue: number, quality: string, semitones: number): Interval;
|
|
1650
|
-
/** Diatonic size: 1 = unison, 2 = second, ... 8 = octave, and beyond. */
|
|
1651
|
-
get number(): number;
|
|
1652
|
-
/** Quality label: `'P'`, `'M'`, `'m'`, or repeated `'A'`/`'d'`. */
|
|
1653
|
-
get quality(): string;
|
|
1654
|
-
/** Signed semitone span. */
|
|
1655
|
-
get semitones(): number;
|
|
1656
|
-
/** A readable label composed of quality and number, e.g. `'P5'` or `'M3'`. */
|
|
1657
|
-
get name(): string;
|
|
1658
|
-
}
|
|
1659
|
-
/**
|
|
1660
|
-
* An immutable key/scale: a `KeyScale` (root pitch class plus mode mask) paired
|
|
1661
|
-
* with a spelled tonic that anchors letter-name spelling. Acts as the factory
|
|
1662
|
-
* for key-aware chords.
|
|
1663
|
-
*/
|
|
1664
|
-
declare class Key {
|
|
1665
|
-
#private;
|
|
1666
|
-
/**
|
|
1667
|
-
* Wrap a key/scale and its spelled tonic.
|
|
1668
|
-
*
|
|
1669
|
-
* @param scale The key/scale; its root is normalized to a pitch class.
|
|
1670
|
-
* @param tonic The spelled tonic anchoring letter-name spelling.
|
|
1671
|
-
*/
|
|
1672
|
-
constructor(scale: KeyScale, tonic: Note);
|
|
1673
|
-
/**
|
|
1674
|
-
* A major key.
|
|
1675
|
-
*
|
|
1676
|
-
* @param root Tonic as a note name (e.g. `'Eb'`) or a pitch class; numeric
|
|
1677
|
-
* roots are spelled with a sharp preference.
|
|
1678
|
-
* @returns The major key.
|
|
1679
|
-
*/
|
|
1680
|
-
static major(root: string | number): Key;
|
|
1681
|
-
/**
|
|
1682
|
-
* A natural-minor key.
|
|
1683
|
-
*
|
|
1684
|
-
* @param root Tonic as a note name or a pitch class; numeric roots are
|
|
1685
|
-
* spelled with a flat preference.
|
|
1686
|
-
* @returns The minor key.
|
|
1687
|
-
*/
|
|
1688
|
-
static minor(root: string | number): Key;
|
|
1689
|
-
/**
|
|
1690
|
-
* A key on a named scale (e.g. `'dorian'`, `'harmonicMinor'`).
|
|
1691
|
-
*
|
|
1692
|
-
* @param name The scale name, a key of the scale module's named-scale table.
|
|
1693
|
-
* @param root Tonic as a note name or a pitch class.
|
|
1694
|
-
* @returns The key.
|
|
1695
|
-
* @throws If the name is not a known scale.
|
|
1696
|
-
*/
|
|
1697
|
-
static named(name: string, root: string | number): Key;
|
|
1698
|
-
/**
|
|
1699
|
-
* Wrap an existing `KeyScale`, synthesizing a spelled tonic when none is
|
|
1700
|
-
* given (flat-preferred for minor-third scales, sharp-preferred otherwise).
|
|
1701
|
-
*
|
|
1702
|
-
* @param scale The key/scale to wrap.
|
|
1703
|
-
* @param tonic Optional spelled tonic.
|
|
1704
|
-
* @returns The key.
|
|
1705
|
-
*/
|
|
1706
|
-
static of(scale: KeyScale, tonic?: Note): Key;
|
|
1707
|
-
/** A copy of the underlying plain `KeyScale`. */
|
|
1708
|
-
get scale(): KeyScale;
|
|
1709
|
-
/** The spelled tonic. */
|
|
1710
|
-
get tonic(): Note;
|
|
1711
|
-
/** The tonic pitch class (0..11). */
|
|
1712
|
-
get rootPc(): number;
|
|
1713
|
-
/** Whether the scale has a minor third and no major third. */
|
|
1714
|
-
get isMinor(): boolean;
|
|
1715
|
-
/**
|
|
1716
|
-
* The scale's pitch classes in ascending scale-degree order (degree 0 first).
|
|
1717
|
-
*
|
|
1718
|
-
* @returns One pitch class per scale degree.
|
|
1719
|
-
*/
|
|
1720
|
-
pitchClasses(): number[];
|
|
1721
|
-
/**
|
|
1722
|
-
* The spelled scale, one note per degree (e.g. C D E F G A B for C major).
|
|
1723
|
-
*
|
|
1724
|
-
* @returns Spelled octave-less notes in scale-degree order.
|
|
1725
|
-
*/
|
|
1726
|
-
notes(): Note[];
|
|
1727
|
-
/**
|
|
1728
|
-
* Alias of {@link Key.notes}.
|
|
1729
|
-
*
|
|
1730
|
-
* @returns Spelled octave-less notes in scale-degree order.
|
|
1731
|
-
*/
|
|
1732
|
-
spell(): Note[];
|
|
1733
|
-
/**
|
|
1734
|
-
* The spelled scale as letter-name strings.
|
|
1735
|
-
*
|
|
1736
|
-
* @returns One name per scale degree.
|
|
1737
|
-
*/
|
|
1738
|
-
noteNames(): string[];
|
|
1739
|
-
/**
|
|
1740
|
-
* Build a chord on a scale degree, carrying this key as context.
|
|
1741
|
-
*
|
|
1742
|
-
* With an explicit quality the quality's interval template is attached to the
|
|
1743
|
-
* degree's diatonic root; without one the scale-correct diatonic triad is
|
|
1744
|
-
* stacked (e.g. a diminished triad on the leading tone of a major key).
|
|
1745
|
-
*
|
|
1746
|
-
* @param degree 0-based scale degree of the chord root.
|
|
1747
|
-
* @param quality Optional chord quality.
|
|
1748
|
-
* @returns The chord, with this key attached.
|
|
1749
|
-
*/
|
|
1750
|
-
chord(degree: number, quality?: ChordQuality): Chord;
|
|
1751
|
-
/**
|
|
1752
|
-
* The diatonic triad on a scale degree, carrying this key as context.
|
|
1753
|
-
*
|
|
1754
|
-
* @param degree 0-based scale degree of the chord root.
|
|
1755
|
-
* @returns The triad, with this key attached.
|
|
1756
|
-
*/
|
|
1757
|
-
diatonicTriad(degree: number): Chord;
|
|
1758
|
-
/**
|
|
1759
|
-
* The diatonic seventh chord on a scale degree, carrying this key as context.
|
|
1760
|
-
*
|
|
1761
|
-
* @param degree 0-based scale degree of the chord root.
|
|
1762
|
-
* @returns The seventh chord, with this key attached.
|
|
1763
|
-
*/
|
|
1764
|
-
diatonicSeventh(degree: number): Chord;
|
|
1765
|
-
/**
|
|
1766
|
-
* Build the chord denoted by a Roman numeral in this key (including applied
|
|
1767
|
-
* chords such as `'V7/V'`), carrying this key as context.
|
|
1768
|
-
*
|
|
1769
|
-
* @param text The Roman numeral.
|
|
1770
|
-
* @returns The chord, with this key attached.
|
|
1771
|
-
* @throws If the numeral is not valid.
|
|
1772
|
-
*/
|
|
1773
|
-
roman(text: string): Chord;
|
|
1774
|
-
/**
|
|
1775
|
-
* Whether a pitch belongs to the scale.
|
|
1776
|
-
*
|
|
1777
|
-
* @param x A MIDI pitch, bare pitch class, or note.
|
|
1778
|
-
* @returns True if the pitch class is a scale tone.
|
|
1779
|
-
*/
|
|
1780
|
-
contains(x: number | Note): boolean;
|
|
1781
|
-
}
|
|
1782
|
-
/**
|
|
1783
|
-
* An immutable chord: a root pitch class, quality, interval template, and
|
|
1784
|
-
* optional slash bass, optionally carrying a {@link Key} context. Analysis
|
|
1785
|
-
* methods (`roman`, `function`, `analyze`, ...) use an explicitly passed key
|
|
1786
|
-
* first and fall back to the carried context.
|
|
1787
|
-
*/
|
|
1788
|
-
declare class Chord {
|
|
1789
|
-
#private;
|
|
1790
|
-
/**
|
|
1791
|
-
* Wrap a plain chord object.
|
|
1792
|
-
*
|
|
1793
|
-
* @param data The chord; it is copied, never retained or mutated.
|
|
1794
|
-
* @param key Optional key context for analysis methods.
|
|
1795
|
-
*/
|
|
1796
|
-
constructor(data: Chord$1, key?: Key);
|
|
1797
|
-
/**
|
|
1798
|
-
* Build a chord from a root and quality.
|
|
1799
|
-
*
|
|
1800
|
-
* @param root Root as a note name (e.g. `'Eb'`) or a pitch class.
|
|
1801
|
-
* @param quality The chord quality.
|
|
1802
|
-
* @param bass Optional slash-chord bass pitch class.
|
|
1803
|
-
* @returns The chord (without key context).
|
|
1804
|
-
*/
|
|
1805
|
-
static of(root: string | number, quality: ChordQuality, bass?: number): Chord;
|
|
1806
|
-
/**
|
|
1807
|
-
* Wrap an existing plain chord object.
|
|
1808
|
-
*
|
|
1809
|
-
* @param data The plain chord.
|
|
1810
|
-
* @returns The wrapped chord (without key context).
|
|
1811
|
-
*/
|
|
1812
|
-
static from(data: Chord$1): Chord;
|
|
1813
|
-
/**
|
|
1814
|
-
* Parse a lead-sheet chord symbol (e.g. `'Cmaj7'`, `'F#m7b5'`, `'C/G'`).
|
|
1815
|
-
*
|
|
1816
|
-
* @param symbol The chord symbol.
|
|
1817
|
-
* @returns The chord (without key context).
|
|
1818
|
-
* @throws If the root or quality is not recognized.
|
|
1819
|
-
*/
|
|
1820
|
-
static parse(symbol: string): Chord;
|
|
1821
|
-
/**
|
|
1822
|
-
* Identify the chords matching a set of pitches, best interpretation first.
|
|
1823
|
-
*
|
|
1824
|
-
* @param pitches MIDI pitches or bare pitch classes.
|
|
1825
|
-
* @returns Ranked chord interpretations (may be empty).
|
|
1826
|
-
*/
|
|
1827
|
-
static detect(pitches: number[]): Chord[];
|
|
1828
|
-
/**
|
|
1829
|
-
* The single best chord interpretation of a pitch set.
|
|
1830
|
-
*
|
|
1831
|
-
* @param pitches MIDI pitches or bare pitch classes.
|
|
1832
|
-
* @returns The top-ranked chord, or null when nothing matches.
|
|
1833
|
-
*/
|
|
1834
|
-
static detectBest(pitches: number[]): Chord | null;
|
|
1835
|
-
/** The root pitch class (0..11). */
|
|
1836
|
-
get rootPc(): number;
|
|
1837
|
-
/** The chord quality. */
|
|
1838
|
-
get quality(): ChordQuality;
|
|
1839
|
-
/** A copy of the semitone offsets above the root. */
|
|
1840
|
-
get intervals(): number[];
|
|
1841
|
-
/** The slash-chord bass pitch class, or undefined in root position. */
|
|
1842
|
-
get bassPc(): number | undefined;
|
|
1843
|
-
/** A copy of the underlying plain chord object. */
|
|
1844
|
-
get data(): Chord$1;
|
|
1845
|
-
/** The carried key context, if any. */
|
|
1846
|
-
get key(): Key | undefined;
|
|
1847
|
-
/**
|
|
1848
|
-
* A copy of this chord carrying the given key context.
|
|
1849
|
-
*
|
|
1850
|
-
* @param key The key context to attach.
|
|
1851
|
-
* @returns The new chord.
|
|
1852
|
-
*/
|
|
1853
|
-
withKey(key: Key): Chord;
|
|
1854
|
-
/**
|
|
1855
|
-
* The chord's sorted, deduplicated pitch classes.
|
|
1856
|
-
*
|
|
1857
|
-
* @returns Pitch classes ascending in [0, 11].
|
|
1858
|
-
*/
|
|
1859
|
-
pitchClasses(): number[];
|
|
1860
|
-
/**
|
|
1861
|
-
* The chord's Roman numeral in a key.
|
|
1862
|
-
*
|
|
1863
|
-
* @param key Key to analyze in; falls back to the carried context.
|
|
1864
|
-
* @returns The Roman numeral string.
|
|
1865
|
-
* @throws If no key is given and none is carried.
|
|
1866
|
-
*/
|
|
1867
|
-
roman(key?: Key): string;
|
|
1868
|
-
/**
|
|
1869
|
-
* The chord's harmonic function (tonic / subdominant / dominant) in a key.
|
|
1870
|
-
*
|
|
1871
|
-
* @param key Key to analyze in; falls back to the carried context.
|
|
1872
|
-
* @returns The harmonic function.
|
|
1873
|
-
* @throws If no key is given and none is carried.
|
|
1874
|
-
*/
|
|
1875
|
-
function(key?: Key): HarmonicFunction;
|
|
1876
|
-
/**
|
|
1877
|
-
* Full functional analysis: function, borrowing, and Roman numeral.
|
|
1878
|
-
*
|
|
1879
|
-
* @param key Key to analyze in; falls back to the carried context.
|
|
1880
|
-
* @returns The chord analysis.
|
|
1881
|
-
* @throws If no key is given and none is carried.
|
|
1882
|
-
*/
|
|
1883
|
-
analyze(key?: Key): ChordAnalysis;
|
|
1884
|
-
/**
|
|
1885
|
-
* Whether the chord is borrowed from the parallel mode (modal interchange).
|
|
1886
|
-
*
|
|
1887
|
-
* @param key Key to analyze in; falls back to the carried context.
|
|
1888
|
-
* @returns True if the chord is borrowed.
|
|
1889
|
-
* @throws If no key is given and none is carried.
|
|
1890
|
-
*/
|
|
1891
|
-
isBorrowed(key?: Key): boolean;
|
|
1892
|
-
/**
|
|
1893
|
-
* The origin of a non-diatonic chord (parallel mode or Neapolitan), or null.
|
|
1894
|
-
*
|
|
1895
|
-
* @param key Key to analyze in; falls back to the carried context.
|
|
1896
|
-
* @returns The borrowing source, or null.
|
|
1897
|
-
* @throws If no key is given and none is carried.
|
|
1898
|
-
*/
|
|
1899
|
-
borrowedSource(key?: Key): BorrowedSource;
|
|
1900
|
-
/**
|
|
1901
|
-
* The chord rendered as a lead-sheet symbol (e.g. `'Cmaj7'`, `'F#m7'`, `'C/G'`).
|
|
1902
|
-
*
|
|
1903
|
-
* @param opts Set `flats: true` to spell the root/bass with flats.
|
|
1904
|
-
* @returns The chord symbol.
|
|
1905
|
-
*/
|
|
1906
|
-
symbol(opts?: {
|
|
1907
|
-
flats?: boolean;
|
|
1908
|
-
}): string;
|
|
1909
|
-
/**
|
|
1910
|
-
* Realize the chord as one MIDI pitch per voice, ascending.
|
|
1911
|
-
*
|
|
1912
|
-
* @param opts Voicing options; defaults to four SATB voices.
|
|
1913
|
-
* @returns MIDI pitches, ascending, one per voice.
|
|
1914
|
-
* @throws If no voicing fits the given ranges.
|
|
1915
|
-
*/
|
|
1916
|
-
voice(opts?: VoicingOptions): number[];
|
|
1917
|
-
/**
|
|
1918
|
-
* Realize the chord as a single styled voicing (`close`, `drop2`, `drop3`,
|
|
1919
|
-
* `shell`, or `rootless`), optionally constraining the top voice.
|
|
1920
|
-
*
|
|
1921
|
-
* @param opts Styled-voicing options; defaults to a close-position voicing.
|
|
1922
|
-
* @returns MIDI pitches, ascending.
|
|
1923
|
-
*/
|
|
1924
|
-
styledVoicing(opts?: StyledVoicingOptions): number[];
|
|
1925
|
-
/**
|
|
1926
|
-
* The negative-harmony mirror of the chord about the key's tonic–dominant
|
|
1927
|
-
* axis (major becomes minor and vice versa).
|
|
1928
|
-
*
|
|
1929
|
-
* @param key Key providing the reflection axis; falls back to the carried
|
|
1930
|
-
* context.
|
|
1931
|
-
* @returns The mirrored chord, keeping any key context.
|
|
1932
|
-
* @throws If no key is given and none is carried.
|
|
1933
|
-
*/
|
|
1934
|
-
negativeHarmony(key?: Key): Chord;
|
|
1935
|
-
/**
|
|
1936
|
-
* The n-th inversion: a copy whose bass is the chord tone `n` steps above the
|
|
1937
|
-
* root in the interval template (`invert(1)` puts the third in the bass).
|
|
1938
|
-
* `n` wraps around the template length; negative values count backwards.
|
|
1939
|
-
*
|
|
1940
|
-
* @param n The inversion number.
|
|
1941
|
-
* @returns The inverted chord, keeping any key context.
|
|
1942
|
-
* @throws If the chord has no intervals.
|
|
1943
|
-
*/
|
|
1944
|
-
invert(n: number): Chord;
|
|
1945
|
-
/**
|
|
1946
|
-
* The named scales that fit over this chord, best fit first, rooted on the
|
|
1947
|
-
* chord root.
|
|
1948
|
-
*
|
|
1949
|
-
* @returns The matching scales.
|
|
1950
|
-
*/
|
|
1951
|
-
scales(): ChordScaleMatch[];
|
|
1952
|
-
/**
|
|
1953
|
-
* The available tensions (usable non-chord, non-avoid scale tones) of a
|
|
1954
|
-
* scale over this chord.
|
|
1955
|
-
*
|
|
1956
|
-
* @param scaleName A named scale, rooted on the chord root.
|
|
1957
|
-
* @returns Tension pitch classes, ascending in [0, 11].
|
|
1958
|
-
*/
|
|
1959
|
-
tensions(scaleName: string): number[];
|
|
1960
|
-
/**
|
|
1961
|
-
* The avoid notes (scale tones a semitone above a chord tone) of a scale
|
|
1962
|
-
* over this chord.
|
|
1963
|
-
*
|
|
1964
|
-
* @param scaleName A named scale, rooted on the chord root.
|
|
1965
|
-
* @returns Avoid-note pitch classes, ascending in [0, 11].
|
|
1966
|
-
*/
|
|
1967
|
-
avoidNotes(scaleName: string): number[];
|
|
1968
|
-
/**
|
|
1969
|
-
* Spell the chord tones with letter names, root first, in the key's spelling.
|
|
1970
|
-
*
|
|
1971
|
-
* @param key Key providing the spelled tonic; falls back to the carried
|
|
1972
|
-
* context.
|
|
1973
|
-
* @returns Spelled octave-less notes in the chord's own (tertian) order.
|
|
1974
|
-
* @throws If no key is given and none is carried.
|
|
1975
|
-
*/
|
|
1976
|
-
spell(key?: Key): Note[];
|
|
1977
|
-
/**
|
|
1978
|
-
* Start a progression with this chord followed by others, carrying this
|
|
1979
|
-
* chord's key context (if any).
|
|
1980
|
-
*
|
|
1981
|
-
* @param others The chords following this one.
|
|
1982
|
-
* @returns The progression.
|
|
1983
|
-
*/
|
|
1984
|
-
progressionTo(...others: Chord[]): Progression;
|
|
1985
|
-
/**
|
|
1986
|
-
* Whether another chord has the same root, quality, intervals, and bass.
|
|
1987
|
-
* Key context is not compared.
|
|
1988
|
-
*
|
|
1989
|
-
* @param other The chord to compare.
|
|
1990
|
-
* @returns True if the chord data is identical.
|
|
1991
|
-
*/
|
|
1992
|
-
equals(other: Chord): boolean;
|
|
1993
|
-
/**
|
|
1994
|
-
* The plain chord data, for JSON serialization.
|
|
1995
|
-
*
|
|
1996
|
-
* @returns A copy of the underlying plain chord object.
|
|
1997
|
-
*/
|
|
1998
|
-
toJSON(): Chord$1;
|
|
1999
|
-
}
|
|
2000
|
-
/**
|
|
2001
|
-
* An immutable ordered sequence of chords, optionally carrying a {@link Key}
|
|
2002
|
-
* context shared by its analysis methods.
|
|
2003
|
-
*/
|
|
2004
|
-
declare class Progression {
|
|
2005
|
-
#private;
|
|
2006
|
-
/**
|
|
2007
|
-
* Wrap a chord sequence.
|
|
2008
|
-
*
|
|
2009
|
-
* @param chords The chords in order; the array is copied.
|
|
2010
|
-
* @param key Optional key context for analysis methods.
|
|
2011
|
-
*/
|
|
2012
|
-
constructor(chords: readonly Chord[], key?: Key);
|
|
2013
|
-
/** A copy of the chord sequence. */
|
|
2014
|
-
get chords(): readonly Chord[];
|
|
2015
|
-
/** The carried key context, if any. */
|
|
2016
|
-
get key(): Key | undefined;
|
|
2017
|
-
/** The number of chords. */
|
|
2018
|
-
get length(): number;
|
|
2019
|
-
/**
|
|
2020
|
-
* A copy of this progression with a chord appended.
|
|
2021
|
-
*
|
|
2022
|
-
* @param chord The chord to append.
|
|
2023
|
-
* @returns The new progression.
|
|
2024
|
-
*/
|
|
2025
|
-
add(chord: Chord): Progression;
|
|
2026
|
-
/**
|
|
2027
|
-
* A copy of this progression carrying the given key context.
|
|
2028
|
-
*
|
|
2029
|
-
* @param key The key context to attach.
|
|
2030
|
-
* @returns The new progression.
|
|
2031
|
-
*/
|
|
2032
|
-
withKey(key: Key): Progression;
|
|
2033
|
-
/**
|
|
2034
|
-
* Voice the progression with smooth voice leading.
|
|
2035
|
-
*
|
|
2036
|
-
* @param opts Voicing options; defaults to four SATB voices.
|
|
2037
|
-
* @returns One ascending voicing (MIDI pitches) per chord.
|
|
2038
|
-
* @throws If any chord admits no voicing within the given ranges.
|
|
2039
|
-
*/
|
|
2040
|
-
voice(opts?: VoicingOptions): number[][];
|
|
2041
|
-
/**
|
|
2042
|
-
* The Roman numeral of each chord in a key.
|
|
2043
|
-
*
|
|
2044
|
-
* @param key Key to analyze in; falls back to the carried context.
|
|
2045
|
-
* @returns One numeral per chord.
|
|
2046
|
-
* @throws If no key is given and none is carried.
|
|
2047
|
-
*/
|
|
2048
|
-
roman(key?: Key): string[];
|
|
2049
|
-
/**
|
|
2050
|
-
* The harmonic function of each chord in a key.
|
|
2051
|
-
*
|
|
2052
|
-
* @param key Key to analyze in; falls back to the carried context.
|
|
2053
|
-
* @returns One function per chord.
|
|
2054
|
-
* @throws If no key is given and none is carried.
|
|
2055
|
-
*/
|
|
2056
|
-
functions(key?: Key): HarmonicFunction[];
|
|
2057
|
-
/**
|
|
2058
|
-
* Analyze every chord and classify the closing cadence.
|
|
2059
|
-
*
|
|
2060
|
-
* The cadence is detected on the final chord pair and is null when the
|
|
2061
|
-
* progression has fewer than two chords.
|
|
2062
|
-
*
|
|
2063
|
-
* @param key Key to analyze in; falls back to the carried context.
|
|
2064
|
-
* @returns Per-chord analyses and the closing cadence.
|
|
2065
|
-
* @throws If no key is given and none is carried.
|
|
2066
|
-
*/
|
|
2067
|
-
analyze(key?: Key): {
|
|
2068
|
-
chords: ChordAnalysis[];
|
|
2069
|
-
cadence: Cadence;
|
|
2070
|
-
};
|
|
2071
|
-
}
|
|
2072
|
-
|
|
2073
|
-
/** A transformation applicable to a motif cell. */
|
|
2074
|
-
type MotifTransform = 'transposeDiatonic' | 'transposeChromatic' | 'invert' | 'retrograde' | 'augment' | 'diminish' | 'sequence';
|
|
2075
|
-
/** A single note within a motif cell. */
|
|
2076
|
-
type MotifNote = {
|
|
2077
|
-
pitch: number;
|
|
2078
|
-
startBeat: number;
|
|
2079
|
-
durationBeat: number;
|
|
2080
|
-
};
|
|
2081
|
-
/** A short melodic cell. */
|
|
2082
|
-
type MotifCell = {
|
|
2083
|
-
notes: MotifNote[];
|
|
2084
|
-
};
|
|
2085
|
-
/** Melodic contour shape for {@link generateMotif}. */
|
|
2086
|
-
type MotifContour = 'arch' | 'ascending' | 'descending' | 'wave';
|
|
2087
|
-
/** Options controlling {@link generateMotif}. */
|
|
2088
|
-
type GenerateMotifOptions = {
|
|
2089
|
-
key: KeyScale;
|
|
2090
|
-
chord?: Chord$1 | null;
|
|
2091
|
-
bars: number;
|
|
2092
|
-
contour?: MotifContour;
|
|
2093
|
-
seed?: number;
|
|
2094
|
-
};
|
|
2095
|
-
/**
|
|
2096
|
-
* Generate a short seed motif over `bars`.
|
|
2097
|
-
*
|
|
2098
|
-
* The melody follows the requested contour in diatonic steps from the tonic,
|
|
2099
|
-
* snapped to the key. When a chord is supplied, notes landing on bar downbeats
|
|
2100
|
-
* are pulled to the nearest chord tone. Output is deterministic for a given seed.
|
|
2101
|
-
*
|
|
2102
|
-
* @param opts Key, optional chord, length, contour, and seed.
|
|
2103
|
-
* @returns The generated motif cell.
|
|
2104
|
-
*/
|
|
2105
|
-
declare function generateMotif(opts: GenerateMotifOptions): MotifCell;
|
|
2106
|
-
/**
|
|
2107
|
-
* Apply a transformation to a motif cell.
|
|
2108
|
-
*
|
|
2109
|
-
* `invert` reflects pitches about the first note (chromatic, self-inverse);
|
|
2110
|
-
* `retrograde` mirrors onsets about the cell span, preserving rests (self-inverse);
|
|
2111
|
-
* `augment`/`diminish` scale time by `amount ?? 2` and its reciprocal;
|
|
2112
|
-
* `transposeChromatic` adds `amount` semitones; `transposeDiatonic` shifts by
|
|
2113
|
-
* `amount` scale degrees when a `key` is given, or — with no `key` — falls back
|
|
2114
|
-
* to a chromatic shift of `amount` semitones; `sequence` appends a shifted copy
|
|
2115
|
-
* (by `amount` diatonic degrees with a `key`, or by `amount` semitones without
|
|
2116
|
-
* one, since it delegates to `transposeDiatonic`).
|
|
2117
|
-
*
|
|
2118
|
-
* @param cell The cell to transform.
|
|
2119
|
-
* @param t The transformation.
|
|
2120
|
-
* @param amount Optional parameter (semitones, degrees, or time factor).
|
|
2121
|
-
* @param key Key context for the diatonic transforms; without it,
|
|
2122
|
-
* `transposeDiatonic` and `sequence` shift chromatically by semitones.
|
|
2123
|
-
* @returns The transformed cell.
|
|
2124
|
-
*/
|
|
2125
|
-
declare function transformMotif(cell: MotifCell, t: MotifTransform, amount?: number, key?: KeyScale): MotifCell;
|
|
2126
|
-
/**
|
|
2127
|
-
* Lay a motif across `bars` and snap it to a chord timeline.
|
|
2128
|
-
*
|
|
2129
|
-
* The cell is tiled back-to-back to fill the requested span; each note is then
|
|
2130
|
-
* pulled to the nearest chord tone of the segment sounding at its onset, so the
|
|
2131
|
-
* developed line spells the underlying harmony.
|
|
2132
|
-
*
|
|
2133
|
-
* @param cell The source motif.
|
|
2134
|
-
* @param timeline Chord segments to snap against.
|
|
2135
|
-
* @param key Key context (used to keep snapped pitches sensible).
|
|
2136
|
-
* @param bars Number of four-beat bars to fill.
|
|
2137
|
-
* @returns The developed, harmony-aware cell.
|
|
2138
|
-
*/
|
|
2139
|
-
declare function developMotif(cell: MotifCell, timeline: ChordTimeline, key: KeyScale, bars: number): MotifCell;
|
|
2140
|
-
|
|
2141
|
-
/**
|
|
2142
|
-
* Deterministic seeded pseudo-random number generation shared across the
|
|
2143
|
-
* generative modules (rhythm, drums, bass, groove, counter-melody). A single
|
|
2144
|
-
* mulberry32 core exposes the small set of samplers those modules need; given a
|
|
2145
|
-
* seed the stream is fully reproducible.
|
|
2146
|
-
*/
|
|
2147
|
-
/** A deterministic PRNG with the sampling helpers the generators need. */
|
|
2148
|
-
type Rng = {
|
|
2149
|
-
/** Next float in [0, 1). */
|
|
2150
|
-
next: () => number;
|
|
2151
|
-
/** True with probability `p`. */
|
|
2152
|
-
prob: (p: number) => boolean;
|
|
2153
|
-
/** Integer in the inclusive range [lo, hi]. */
|
|
2154
|
-
range: (lo: number, hi: number) => number;
|
|
2155
|
-
/** Float in [lo, hi). */
|
|
2156
|
-
float: (lo: number, hi: number) => number;
|
|
2157
|
-
};
|
|
2158
|
-
/**
|
|
2159
|
-
* Create a seeded PRNG (mulberry32) exposing the shared samplers.
|
|
2160
|
-
*
|
|
2161
|
-
* @param seed The 32-bit seed; the same seed always yields the same stream.
|
|
2162
|
-
* @returns The seeded generator.
|
|
2163
|
-
*/
|
|
2164
|
-
declare function createRng(seed: number): Rng;
|
|
2165
|
-
|
|
2166
|
-
/**
|
|
2167
|
-
* Reharmonization: chord substitution, modal-interchange palettes, and negative
|
|
2168
|
-
* harmony. These transforms take an existing chord (or a key) and propose
|
|
2169
|
-
* alternative harmonies that preserve a chosen relationship — a shared function,
|
|
2170
|
-
* a common tone, a tonicizing dominant, or a reflection across the key axis.
|
|
2171
|
-
*
|
|
2172
|
-
* Roots are pitch classes (0..11); no spelled key signature is required.
|
|
2173
|
-
*/
|
|
2174
|
-
|
|
2175
|
-
/** The kind of substitution relationship a candidate realizes. */
|
|
2176
|
-
type SubstitutionType = 'tritone' | 'relative' | 'borrowed' | 'chromatic-mediant' | 'secondary-dominant';
|
|
2177
|
-
/** A proposed chord substitution with its relationship, numeral, and function. */
|
|
2178
|
-
type Substitution = {
|
|
2179
|
-
chord: Chord$1;
|
|
2180
|
-
type: SubstitutionType;
|
|
2181
|
-
roman: string;
|
|
2182
|
-
function: HarmonicFunction;
|
|
2183
|
-
};
|
|
2184
|
-
/** Options controlling which substitutions {@link substituteChord} returns. */
|
|
2185
|
-
type SubstituteOptions = {
|
|
2186
|
-
/**
|
|
2187
|
-
* Melody pitch classes that must remain chord tones. When given, only
|
|
2188
|
-
* substitutions whose pitch classes contain every listed pitch class are
|
|
2189
|
-
* kept, so the melody stays consonant against the new harmony.
|
|
2190
|
-
*/
|
|
2191
|
-
melodyPcs?: number[];
|
|
2192
|
-
};
|
|
2193
|
-
/**
|
|
2194
|
-
* Propose substitutions for a chord within a key.
|
|
2195
|
-
*
|
|
2196
|
-
* Candidates are generated by several relationships and deduplicated against the
|
|
2197
|
-
* original chord and each other:
|
|
2198
|
-
*
|
|
2199
|
-
* - `tritone`: for a dominant-type chord, the dominant seventh a tritone away.
|
|
2200
|
-
* - `secondary-dominant`: for a stable target, the dominant seventh a fifth
|
|
2201
|
-
* above its root (tonicizing it).
|
|
2202
|
-
* - `relative`: a diatonic triad a third away that shares two common tones.
|
|
2203
|
-
* - `borrowed`: a triad from the parallel mode with the same harmonic function.
|
|
2204
|
-
* - `chromatic-mediant`: a major/minor triad a third away sharing one common
|
|
2205
|
-
* tone.
|
|
2206
|
-
*
|
|
2207
|
-
* Each result carries its Roman numeral and harmonic function in `key`. When
|
|
2208
|
-
* `opts.melodyPcs` is given, only substitutions whose pitch classes contain all
|
|
2209
|
-
* of those pitch classes are returned.
|
|
2210
|
-
*
|
|
2211
|
-
* @param chord The chord to reharmonize.
|
|
2212
|
-
* @param key The prevailing key.
|
|
2213
|
-
* @param opts Optional melody-preservation constraint.
|
|
2214
|
-
* @returns The deduplicated substitution candidates.
|
|
2215
|
-
*/
|
|
2216
|
-
declare function substituteChord(chord: Chord$1, key: KeyScale, opts?: SubstituteOptions): Substitution[];
|
|
2217
|
-
/** A borrowed chord in the modal-interchange palette of a key. */
|
|
2218
|
-
type BorrowedChord = {
|
|
2219
|
-
chord: Chord$1;
|
|
2220
|
-
roman: string;
|
|
2221
|
-
source: BorrowedSource;
|
|
2222
|
-
};
|
|
2223
|
-
/**
|
|
2224
|
-
* The modal-interchange palette of a key.
|
|
2225
|
-
*
|
|
2226
|
-
* Lists the diatonic triads of the {@link parallelKey} that are not diatonic to
|
|
2227
|
-
* `key` (the classic borrowed chords such as `iv`, `bVI`, and `bVII` in a major
|
|
2228
|
-
* key), plus the Neapolitan (a major triad on the flat second degree). Each
|
|
2229
|
-
* carries its Roman numeral and {@link borrowedSource} relative to `key`.
|
|
2230
|
-
*
|
|
2231
|
-
* @param key The prevailing key.
|
|
2232
|
-
* @returns The borrowed-chord palette.
|
|
2233
|
-
*/
|
|
2234
|
-
declare function modalInterchangePalette(key: KeyScale): BorrowedChord[];
|
|
2235
|
-
/**
|
|
2236
|
-
* Reflect a chord across the tonic–dominant axis of a key (negative harmony).
|
|
2237
|
-
*
|
|
2238
|
-
* Every pitch class `p` maps to `(2*T + 7 - p) mod 12`, where `T` is the key
|
|
2239
|
-
* tonic — the reflection that swaps the tonic with the dominant. The mirrored
|
|
2240
|
-
* pitch classes (including the bass, if set) are reassembled into a chord by
|
|
2241
|
-
* {@link detectChordBest}; when no chord is recognized, the mirrored root and
|
|
2242
|
-
* the original quality are used as a fallback.
|
|
2243
|
-
*
|
|
2244
|
-
* @param chord The chord to reflect.
|
|
2245
|
-
* @param key The prevailing key.
|
|
2246
|
-
* @returns The negative-harmony counterpart of the chord.
|
|
2247
|
-
*/
|
|
2248
|
-
declare function negativeHarmonyMirror(chord: Chord$1, key: KeyScale): Chord$1;
|
|
2249
|
-
|
|
2250
|
-
/**
|
|
2251
|
-
* Deterministic rhythm generation over a metric grid.
|
|
2252
|
-
*
|
|
2253
|
-
* Builds a fixed-resolution grid across one or more bars of a time signature
|
|
2254
|
-
* and decides, per grid slot, whether it becomes a note onset. Onset
|
|
2255
|
-
* probability follows the metric-accent hierarchy from the `meter` module, so
|
|
2256
|
-
* strong positions (downbeats, secondary pulses) are favored over weak
|
|
2257
|
-
* off-pulse subdivisions. Given a seed the output is fully reproducible.
|
|
2258
|
-
*
|
|
2259
|
-
* Positions and durations are measured in quarter-note beats, matching the
|
|
2260
|
-
* library-wide convention.
|
|
2261
|
-
*/
|
|
2262
|
-
|
|
2263
|
-
/** A single rhythmic note: an onset position and how long it sounds. */
|
|
2264
|
-
type RhythmEvent = {
|
|
2265
|
-
/** Onset position in quarter-note beats, absolute from the start of the span. */
|
|
2266
|
-
position: number;
|
|
2267
|
-
/** Duration in quarter-note beats, extending to the next onset. */
|
|
2268
|
-
duration: number;
|
|
2269
|
-
};
|
|
2270
|
-
/** Options controlling {@link generateRhythm}. */
|
|
2271
|
-
type RhythmOptions = {
|
|
2272
|
-
/** Seed for the deterministic PRNG. Default 0. */
|
|
2273
|
-
seed?: number;
|
|
2274
|
-
/** Number of bars to generate. Default 1. */
|
|
2275
|
-
bars?: number;
|
|
2276
|
-
/**
|
|
2277
|
-
* Grid resolution as the number of equal grid steps per quarter-note beat.
|
|
2278
|
-
* The default of 2 yields an eighth-note grid; 4 yields a sixteenth-note
|
|
2279
|
-
* grid, 3 an eighth-note triplet grid, and so on.
|
|
2280
|
-
*/
|
|
2281
|
-
subdivision?: number;
|
|
2282
|
-
/**
|
|
2283
|
-
* Overall onset density in [0, 1]. Scales the per-slot onset probability, so
|
|
2284
|
-
* higher values fill more grid slots. Default 0.5.
|
|
2285
|
-
*/
|
|
2286
|
-
density?: number;
|
|
2287
|
-
};
|
|
2288
|
-
/**
|
|
2289
|
-
* Map a metric weight (0–3 from {@link metricWeight}) to a base onset
|
|
2290
|
-
* probability before density scaling. Strong positions are much more likely to
|
|
2291
|
-
* carry an onset than weak ones; the curve is intentionally small and explicit
|
|
2292
|
-
* so its behavior is easy to inspect and test.
|
|
2293
|
-
*
|
|
2294
|
-
* @param weight The metric weight, 0 (off-pulse) to 3 (downbeat).
|
|
2295
|
-
* @returns A base onset probability in [0, 1].
|
|
2296
|
-
*/
|
|
2297
|
-
declare function onsetWeightCurve(weight: number): number;
|
|
2298
|
-
/**
|
|
2299
|
-
* Generate a deterministic rhythmic pattern over `bars` bars of a time
|
|
2300
|
-
* signature. A grid is built at the chosen subdivision; each slot becomes an
|
|
2301
|
-
* onset with a probability derived from its metric weight scaled by `density`
|
|
2302
|
-
* and sampled from the seeded PRNG. The first slot (the downbeat) is always an
|
|
2303
|
-
* onset. Each event's duration extends to the next onset, and the last event
|
|
2304
|
-
* extends to the end of the span.
|
|
2305
|
-
*
|
|
2306
|
-
* @param ts The time signature.
|
|
2307
|
-
* @param opts Generation options.
|
|
2308
|
-
* @returns Onset events sorted by position, non-overlapping, covering the span.
|
|
2309
|
-
*/
|
|
2310
|
-
declare function generateRhythm(ts: TimeSignature, opts?: RhythmOptions): RhythmEvent[];
|
|
2311
|
-
/**
|
|
2312
|
-
* Onset density of a generated pattern: the mean number of onsets per bar.
|
|
2313
|
-
*
|
|
2314
|
-
* @param events Events from {@link generateRhythm}.
|
|
2315
|
-
* @param ts The time signature.
|
|
2316
|
-
* @returns The onset count divided by the number of bars the events span.
|
|
2317
|
-
*/
|
|
2318
|
-
declare function rhythmDensity(events: RhythmEvent[], ts: TimeSignature): number;
|
|
2319
|
-
|
|
2320
|
-
/**
|
|
2321
|
-
* Build a 12-bit mode mask from a list of semitone offsets above the root.
|
|
2322
|
-
*
|
|
2323
|
-
* Bit 0 (the root) is always set, enforcing the `KeyScale` invariant that the
|
|
2324
|
-
* root is a scale tone even when the offset list omits 0.
|
|
2325
|
-
*/
|
|
2326
|
-
declare function maskFromOffsets(offsets: readonly number[]): number;
|
|
2327
|
-
/** Mode mask for the major (Ionian) scale: offsets {0, 2, 4, 5, 7, 9, 11}. */
|
|
2328
|
-
declare const MAJOR_MASK = 2741;
|
|
2329
|
-
/** Mode mask for the natural minor (Aeolian) scale: offsets {0, 2, 3, 5, 7, 8, 10}. */
|
|
2330
|
-
declare const NATURAL_MINOR_MASK = 1453;
|
|
2331
|
-
/** Harmonic minor: natural minor with a raised seventh — offsets {0,2,3,5,7,8,11}. */
|
|
2332
|
-
declare const HARMONIC_MINOR_MASK: number;
|
|
2333
|
-
/** Ascending melodic minor: offsets {0,2,3,5,7,9,11}. */
|
|
2334
|
-
declare const MELODIC_MINOR_MASK: number;
|
|
2335
|
-
/** Dorian mode: offsets {0,2,3,5,7,9,10}. */
|
|
2336
|
-
declare const DORIAN_MASK: number;
|
|
2337
|
-
/** Phrygian mode: offsets {0,1,3,5,7,8,10}. */
|
|
2338
|
-
declare const PHRYGIAN_MASK: number;
|
|
2339
|
-
/** Lydian mode: offsets {0,2,4,6,7,9,11}. */
|
|
2340
|
-
declare const LYDIAN_MASK: number;
|
|
2341
|
-
/** Mixolydian mode: offsets {0,2,4,5,7,9,10}. */
|
|
2342
|
-
declare const MIXOLYDIAN_MASK: number;
|
|
2343
|
-
/** Locrian mode: offsets {0,1,3,5,6,8,10}. */
|
|
2344
|
-
declare const LOCRIAN_MASK: number;
|
|
2345
|
-
/** Major pentatonic: offsets {0,2,4,7,9}. */
|
|
2346
|
-
declare const MAJOR_PENTATONIC_MASK: number;
|
|
2347
|
-
/** Minor pentatonic: offsets {0,3,5,7,10}. */
|
|
2348
|
-
declare const MINOR_PENTATONIC_MASK: number;
|
|
2349
|
-
/** Hexatonic blues scale: minor pentatonic plus the flat-fifth — {0,3,5,6,7,10}. */
|
|
2350
|
-
declare const BLUES_MASK: number;
|
|
2351
|
-
/** Whole-tone scale: offsets {0,2,4,6,8,10}. */
|
|
2352
|
-
declare const WHOLE_TONE_MASK: number;
|
|
2353
|
-
/** Octatonic (half-step first): offsets {0,1,3,4,6,7,9,10}. */
|
|
2354
|
-
declare const OCTATONIC_HALF_WHOLE_MASK: number;
|
|
2355
|
-
/** Octatonic (whole-step first): offsets {0,2,3,5,6,8,9,11}. */
|
|
2356
|
-
declare const OCTATONIC_WHOLE_HALF_MASK: number;
|
|
2357
|
-
/** Chromatic scale: all twelve pitch classes. */
|
|
2358
|
-
declare const CHROMATIC_MASK = 4095;
|
|
2359
|
-
/** Named scale masks addressable by {@link scaleByName}. */
|
|
2360
|
-
declare const NAMED_SCALES: Record<string, number>;
|
|
2361
|
-
/** Build a `KeyScale` for a major key on the given root pitch class. */
|
|
2362
|
-
declare function majorKey(rootPc: number): KeyScale;
|
|
2363
|
-
/** Build a `KeyScale` for a natural-minor key on the given root pitch class. */
|
|
2364
|
-
declare function minorKey(rootPc: number): KeyScale;
|
|
2365
|
-
/**
|
|
2366
|
-
* Build a `KeyScale` from a named scale (see {@link NAMED_SCALES}).
|
|
2367
|
-
*
|
|
2368
|
-
* @param name The scale name, e.g. `'dorian'` or `'harmonicMinor'`.
|
|
2369
|
-
* @param rootPc The root pitch class.
|
|
2370
|
-
* @returns The key/scale.
|
|
2371
|
-
* @throws If the name is not a known scale.
|
|
2372
|
-
*/
|
|
2373
|
-
declare function scaleByName(name: string, rootPc: number): KeyScale;
|
|
2374
|
-
/**
|
|
2375
|
-
* Test whether a pitch belongs to the scale.
|
|
2376
|
-
*
|
|
2377
|
-
* @param pitch MIDI pitch or bare pitch class.
|
|
2378
|
-
* @param key The key/scale to test against.
|
|
2379
|
-
* @returns True if the pitch class is a member of the scale.
|
|
2380
|
-
*/
|
|
2381
|
-
declare function isScaleTone(pitch: number, key: KeyScale): boolean;
|
|
2382
|
-
/**
|
|
2383
|
-
* Find the nearest MIDI pitch whose pitch class is in the scale.
|
|
2384
|
-
*
|
|
2385
|
-
* The search expands symmetrically outward from `pitch`. On a tie (equal
|
|
2386
|
-
* distance above and below) the lower pitch is returned.
|
|
2387
|
-
*
|
|
2388
|
-
* @param pitch MIDI pitch to snap.
|
|
2389
|
-
* @param key The key/scale to snap to.
|
|
2390
|
-
* @returns The nearest in-scale MIDI pitch.
|
|
2391
|
-
*/
|
|
2392
|
-
declare function nearestScaleTone(pitch: number, key: KeyScale): number;
|
|
2393
|
-
/**
|
|
2394
|
-
* Get the 0-based scale degree of a pitch.
|
|
2395
|
-
*
|
|
2396
|
-
* @param pitch MIDI pitch or bare pitch class.
|
|
2397
|
-
* @param key The key/scale to measure against.
|
|
2398
|
-
* @returns The 0-based degree, or -1 if the pitch is not in the scale.
|
|
2399
|
-
*/
|
|
2400
|
-
declare function pitchToScaleDegree(pitch: number, key: KeyScale): number;
|
|
2401
|
-
/**
|
|
2402
|
-
* List the pitch classes of a key's scale.
|
|
2403
|
-
*
|
|
2404
|
-
* @param key The key/scale to enumerate.
|
|
2405
|
-
* @returns The member pitch classes, sorted ascending in [0, 11].
|
|
2406
|
-
*/
|
|
2407
|
-
declare function diatonicPitchClasses(key: KeyScale): number[];
|
|
2408
|
-
/**
|
|
2409
|
-
* List the pitch classes of a key's scale in ascending scale-degree order.
|
|
2410
|
-
*
|
|
2411
|
-
* Degree 0 is the root; degrees follow the mask bits in offset order rather
|
|
2412
|
-
* than sorted pitch-class order.
|
|
2413
|
-
*
|
|
2414
|
-
* @param key The key/scale to enumerate.
|
|
2415
|
-
* @returns The member pitch classes ordered by scale degree.
|
|
2416
|
-
*/
|
|
2417
|
-
declare function scaleTonesInDegreeOrder(key: KeyScale): number[];
|
|
2418
|
-
|
|
2419
|
-
/**
|
|
2420
|
-
* Spelling: derive letter-name notes for scales and chords from a spelled tonic.
|
|
2421
|
-
*
|
|
2422
|
-
* The theory core works in pitch classes, which cannot choose between (say) a
|
|
2423
|
-
* G# and an Ab. Given a spelled tonic, this module assigns diatonic letters to
|
|
2424
|
-
* scale degrees and chord tones so a C major scale spells as C D E F G A B and
|
|
2425
|
-
* A harmonic minor spells its seventh as G#.
|
|
2426
|
-
*/
|
|
2427
|
-
|
|
2428
|
-
/**
|
|
2429
|
-
* Spell a single pitch class relative to a spelled tonic and key.
|
|
2430
|
-
*
|
|
2431
|
-
* Diatonic pitch classes take the scale's letter for their degree; the common
|
|
2432
|
-
* chromatic tones (b2, b3, #4, b6, b7) and a minor key's raised degrees (#6, #7)
|
|
2433
|
-
* take their conventional, key-correct accidental spelling; anything else falls
|
|
2434
|
-
* back to a sharp spelling of the nearest natural.
|
|
2435
|
-
*
|
|
2436
|
-
* @param pc The pitch class to spell.
|
|
2437
|
-
* @param tonic The spelled tonic (its letter anchors the spelling).
|
|
2438
|
-
* @param key The key/scale.
|
|
2439
|
-
* @returns The spelled note (without octave).
|
|
2440
|
-
*/
|
|
2441
|
-
declare function spellPitchClass(pc: number, tonic: Note$1, key: KeyScale): Note$1;
|
|
2442
|
-
/**
|
|
2443
|
-
* Spell every pitch class of a scale, in ascending scale-degree order.
|
|
2444
|
-
*
|
|
2445
|
-
* Correct for heptatonic scales (each degree gets the next letter). Non-standard
|
|
2446
|
-
* scales are spelled tone-by-tone with a sharp preference.
|
|
2447
|
-
*
|
|
2448
|
-
* @param tonic The spelled tonic.
|
|
2449
|
-
* @param key The key/scale.
|
|
2450
|
-
* @returns Spelled notes, one per scale degree.
|
|
2451
|
-
*/
|
|
2452
|
-
declare function spellScale(tonic: Note$1, key: KeyScale): Note$1[];
|
|
2453
|
-
/**
|
|
2454
|
-
* Spell an arbitrary list of pitch classes relative to a key.
|
|
2455
|
-
*
|
|
2456
|
-
* @param pcs The pitch classes.
|
|
2457
|
-
* @param tonic The spelled tonic.
|
|
2458
|
-
* @param key The key/scale.
|
|
2459
|
-
* @returns Spelled notes, in input order.
|
|
2460
|
-
*/
|
|
2461
|
-
declare function spellPitchClasses(pcs: number[], tonic: Note$1, key: KeyScale): Note$1[];
|
|
2462
|
-
/**
|
|
2463
|
-
* Spell a chord's tones, in the chord's own (tertian) order, relative to a key.
|
|
2464
|
-
*
|
|
2465
|
-
* Diatonic chords spell exactly (e.g. G7 in C major -> G B D F). Chromatic chord
|
|
2466
|
-
* tones take their conventional spelling; enharmonically ambiguous altered
|
|
2467
|
-
* tensions may be spelled by the general convention rather than by chord
|
|
2468
|
-
* function.
|
|
2469
|
-
*
|
|
2470
|
-
* @param chord The chord.
|
|
2471
|
-
* @param tonic The spelled tonic of the key.
|
|
2472
|
-
* @param key The key/scale.
|
|
2473
|
-
* @returns Spelled chord tones, root first.
|
|
2474
|
-
*/
|
|
2475
|
-
declare function spellChord(chord: Chord$1, tonic: Note$1, key: KeyScale): Note$1[];
|
|
2476
|
-
/**
|
|
2477
|
-
* Convenience: render spelled notes as letter-name strings.
|
|
2478
|
-
*
|
|
2479
|
-
* @param notes The notes.
|
|
2480
|
-
* @returns Their formatted names.
|
|
2481
|
-
*/
|
|
2482
|
-
declare function noteNames(notes: Note$1[]): string[];
|
|
2483
|
-
|
|
2484
|
-
/**
|
|
2485
|
-
* Lead-sheet chord symbol parsing and formatting.
|
|
2486
|
-
*
|
|
2487
|
-
* Bridges the informal `<root><quality>[/<bass>]` notation musicians write
|
|
2488
|
-
* (`Cmaj7`, `F#m7b5`, `Bb7`, `C/G`) and the library's structured {@link Chord}
|
|
2489
|
-
* type, so callers can accept/emit plain text at the edges of the API.
|
|
2490
|
-
*/
|
|
2491
|
-
|
|
2492
|
-
/**
|
|
2493
|
-
* Parse a lead-sheet chord symbol into a {@link Chord}.
|
|
2494
|
-
*
|
|
2495
|
-
* Accepts `<root><quality>[/<bass>]`, e.g. `Cmaj7`, `F#m7b5`, `Bb7`, `C/G`,
|
|
2496
|
-
* `C6/9`. The `/` after a quality is ambiguous between a slash bass and the
|
|
2497
|
-
* `6/9` quality; it resolves to a bass only when the token following it is
|
|
2498
|
-
* itself a valid note.
|
|
2499
|
-
*
|
|
2500
|
-
* @param text The chord symbol text.
|
|
2501
|
-
* @returns The parsed chord.
|
|
2502
|
-
* @throws If the root or quality is not recognized.
|
|
2503
|
-
*/
|
|
2504
|
-
declare function parseChordSymbol(text: string): Chord$1;
|
|
2505
|
-
/**
|
|
2506
|
-
* Format a {@link Chord} as a lead-sheet chord symbol.
|
|
2507
|
-
*
|
|
2508
|
-
* The inverse of {@link parseChordSymbol}: each quality maps to one canonical
|
|
2509
|
-
* suffix spelling, and a slash bass is appended only when it differs from the
|
|
2510
|
-
* root.
|
|
2511
|
-
*
|
|
2512
|
-
* @param chord The chord to format.
|
|
2513
|
-
* @param opts Formatting options.
|
|
2514
|
-
* @param opts.flats Prefer flat spellings over sharps for altered roots/basses.
|
|
2515
|
-
* @returns The chord symbol text.
|
|
2516
|
-
*/
|
|
2517
|
-
declare function formatChordSymbol(chord: Chord$1, opts?: {
|
|
2518
|
-
flats?: boolean;
|
|
2519
|
-
}): string;
|
|
2520
|
-
/**
|
|
2521
|
-
* Transpose a chord symbol by a number of semitones.
|
|
2522
|
-
*
|
|
2523
|
-
* @param text The chord symbol text.
|
|
2524
|
-
* @param semitones Signed semitone offset to apply to the root and bass.
|
|
2525
|
-
* @param opts Formatting options for the result; see {@link formatChordSymbol}.
|
|
2526
|
-
* @returns The transposed chord symbol text.
|
|
2527
|
-
* @throws If `text` does not parse as a chord symbol.
|
|
2528
|
-
*/
|
|
2529
|
-
declare function transposeChordSymbol(text: string, semitones: number, opts?: {
|
|
2530
|
-
flats?: boolean;
|
|
2531
|
-
}): string;
|
|
2532
|
-
|
|
2533
|
-
/**
|
|
2534
|
-
* Tuning and microtonality: frequency conversion, cents, arbitrary equal
|
|
2535
|
-
* temperaments (EDO), and just-intonation ratios.
|
|
2536
|
-
*
|
|
2537
|
-
* The rest of the library reasons in twelve-tone pitch classes, which is a
|
|
2538
|
-
* deliberate scope choice for tonal theory. This module is the escape hatch for
|
|
2539
|
-
* anyone who needs actual frequencies, cents, non-12 equal temperaments, or the
|
|
2540
|
-
* acoustic (just) tuning behind the tempered intervals.
|
|
2541
|
-
*/
|
|
2542
|
-
/**
|
|
2543
|
-
* An equal-tempered tuning: a reference pitch and a number of equal divisions of
|
|
2544
|
-
* the octave. With `divisions === 12` a step index is an ordinary MIDI number.
|
|
2545
|
-
*/
|
|
2546
|
-
type Tuning = {
|
|
2547
|
-
/** Step index (MIDI number when `divisions` is 12) whose frequency is `refFreq`. */
|
|
2548
|
-
refStep: number;
|
|
2549
|
-
/** Frequency in Hz of `refStep`. */
|
|
2550
|
-
refFreq: number;
|
|
2551
|
-
/** Equal divisions of the octave (12 standard; e.g. 19 or 31 for microtonal). */
|
|
2552
|
-
divisions: number;
|
|
2553
|
-
};
|
|
2554
|
-
/** Standard twelve-tone equal temperament, A4 (MIDI 69) = 440 Hz. */
|
|
2555
|
-
declare const TWELVE_TET: Tuning;
|
|
2556
|
-
/**
|
|
2557
|
-
* Build an equal temperament with `n` divisions of the octave.
|
|
2558
|
-
*
|
|
2559
|
-
* @param n Divisions of the octave (e.g. 19, 24, 31).
|
|
2560
|
-
* @param refFreq Reference frequency in Hz (default 440).
|
|
2561
|
-
* @param refStep Step index of the reference (default 69).
|
|
2562
|
-
* @returns The tuning.
|
|
2563
|
-
*/
|
|
2564
|
-
declare function edo(n: number, refFreq?: number, refStep?: number): Tuning;
|
|
2565
|
-
/**
|
|
2566
|
-
* Frequency in Hz of a step index under a tuning.
|
|
2567
|
-
*
|
|
2568
|
-
* @param step Step index (a MIDI number under 12-EDO).
|
|
2569
|
-
* @param tuning The tuning (default 12-TET).
|
|
2570
|
-
* @returns The frequency in Hz.
|
|
2571
|
-
*/
|
|
2572
|
-
declare function frequencyOf(step: number, tuning?: Tuning): number;
|
|
2573
|
-
/**
|
|
2574
|
-
* Nearest step index to a frequency under a tuning (the inverse of
|
|
2575
|
-
* {@link frequencyOf}, rounded).
|
|
2576
|
-
*
|
|
2577
|
-
* @param freq Frequency in Hz.
|
|
2578
|
-
* @param tuning The tuning (default 12-TET).
|
|
2579
|
-
* @returns The nearest step index.
|
|
2580
|
-
*/
|
|
2581
|
-
declare function nearestStep(freq: number, tuning?: Tuning): number;
|
|
2582
|
-
/**
|
|
2583
|
-
* Interval in cents between two frequencies.
|
|
2584
|
-
*
|
|
2585
|
-
* @param a Lower/first frequency in Hz.
|
|
2586
|
-
* @param b Upper/second frequency in Hz.
|
|
2587
|
-
* @returns Cents from `a` to `b` (negative if `b` is lower).
|
|
2588
|
-
*/
|
|
2589
|
-
declare function centsBetweenFreq(a: number, b: number): number;
|
|
2590
|
-
/**
|
|
2591
|
-
* Cents spanned by a number of equal-temperament steps.
|
|
2592
|
-
*
|
|
2593
|
-
* @param steps Number of steps.
|
|
2594
|
-
* @param tuning The tuning (default 12-TET).
|
|
2595
|
-
* @returns The cents.
|
|
2596
|
-
*/
|
|
2597
|
-
declare function centsOfSteps(steps: number, tuning?: Tuning): number;
|
|
2598
|
-
/**
|
|
2599
|
-
* Cents of a frequency ratio, e.g. `ratioToCents(3, 2)` ≈ 701.955 for the just
|
|
2600
|
-
* perfect fifth.
|
|
2601
|
-
*
|
|
2602
|
-
* @param numerator Ratio numerator.
|
|
2603
|
-
* @param denominator Ratio denominator.
|
|
2604
|
-
* @returns The interval in cents.
|
|
2605
|
-
*/
|
|
2606
|
-
declare function ratioToCents(numerator: number, denominator: number): number;
|
|
2607
|
-
/**
|
|
2608
|
-
* Five-limit just-intonation ratios for the twelve interval classes above a
|
|
2609
|
-
* unison, indexed by semitone class (0..12).
|
|
2610
|
-
*/
|
|
2611
|
-
declare const JUST_RATIOS: Record<number, [number, number]>;
|
|
2612
|
-
/**
|
|
2613
|
-
* Cents by which a five-limit just interval departs from its 12-TET tempering
|
|
2614
|
-
* (positive means the just interval is wider).
|
|
2615
|
-
*
|
|
2616
|
-
* @param semitoneClass Semitone class in [0, 12].
|
|
2617
|
-
* @returns The deviation in cents, or NaN if the class has no listed ratio.
|
|
2618
|
-
*/
|
|
2619
|
-
declare function justDeviationCents(semitoneClass: number): number;
|
|
2620
|
-
|
|
2621
|
-
export { type AnalyzedNote, type ArrangementAnalysis, type ArrangementOptions, type ArrangementTrack, BLUES_MASK, type BarPosition, type BassLineOptions, type BassSegment, type BassStyle, type BorrowedChord, type BorrowedSource, CHROMATIC_MASK, type Cadence, type CadenceHit, Chord, type ChordAnalysis, type Chord$1 as ChordData, type ChordMatch, type ChordQuality, type ChordScaleMatch, type ChordScaleReportEntry, type ChordSegment, type ChordTimeline, type ChordTimelineOptions, type ChordTimelineResult, type Conflict, type CounterMelodyOptions, DORIAN_MASK, type DrumGenOptions, type DrumHit, type DrumRole, type GenerateMotifOptions, type GenerateProgressionOptions, type GeneratedChord, type GrooveFeel, type GrooveSlot, type GrooveStyle, type GrooveTemplate, HARMONIC_MINOR_MASK, type HarmonicFunction, type HarmonizeOptions, type HarmonizeResult, type HarmonyRole, type HumanizeOptions, Interval, IntervalQuality, JUST_RATIOS, Key, type KeyMatch, type KeyScale, LOCRIAN_MASK, LYDIAN_MASK, type LockLevel, MAJOR_MASK, MAJOR_PENTATONIC_MASK, MELODIC_MINOR_MASK, MINOR_PENTATONIC_MASK, MIXOLYDIAN_MASK, type MelodyNote, type MotifCell, type MotifContour, type MotifNote, type MotifTransform, NAMED_SCALES, NATURAL_MINOR_MASK, Note, type Note$1 as NoteData, type NoteEvent, NoteSafety, OCTATONIC_HALF_WHOLE_MASK, OCTATONIC_WHOLE_HALF_MASK, PHRYGIAN_MASK, type ProgFunction, type ProgStyle, Progression, type ProgressionPreset, ReasonFlag, type RhythmEvent, type RhythmOptions, type Rng, SATB_RANGES, type SafetyProfile, type SafetyQuery, type SafetyResult, type ScaleChoice, type Section, type SpelledInterval, type StyledVoicingOptions, type SubstituteOptions, type Substitution, type SubstitutionType, TWELVE_TET, type TensionPoint, type TheoryLabel, type TimeSignature, type TrackAnalysis, type TrackRole, type Tuning, type VoiceNote, type VoiceRange, type VoiceSnapshot, type VoicedRole, type VoicingOptions, type VoicingStyle, WHOLE_TONE_MASK, analyzeArrangement, analyzeChord, analyzeVoice, applyGrooveTemplate, availableTensions, avoidNotes, barPositionToBeat, beatToBarPosition, beatsPerBar, borrowedSource, centsBetweenFreq, centsOfSteps, chordFromDegree, chordPitchClasses, chordQualities, chordScaleReport, chordScales, chordTimelineFromChords, chordTimelineFromNotes, chordToRoman, chordToneRole, classifyInterval, createRng, createsHiddenParallelPerfect, createsParallelOctave, createsParallelPerfect, createsParallelUnison, createsVerticalDissonance, createsVoiceCrossing, createsVoiceOverlap, detectCadence, detectCadences, detectChord, detectChordBest, detectKey, developMotif, diatonicPitchClasses, diatonicSeventh, diatonicTriad, edo, enumerateSafePitches, evaluateSafety, exceedsSpacing, extractGrooveTemplate, formatChordSymbol, formatNote, formatTimeSignature, frequencyOf, functionOf, generateBassLine, generateCounterMelody, generateDrums, generateMotif, generateProgression, generateRhythm, harmonizeMelody, humanize, isBorrowedChord, isCompound, isConsonantInterval, isDiatonic, isForbiddenMelodicLeap, isLeadingToneResolution, isMinorKey, isPerfectInterval, isScaleTone, isStrongBeat, justDeviationCents, majorKey, makeChord, maskFromOffsets, metricWeight, midiToNote, minorKey, modalInterchangePalette, nearestScaleTone, nearestStep, negativeHarmonyMirror, nextVoicing, noteNames, noteToMidi, noteToPitchClass, onsetWeightCurve, parallelKey, parseChordSymbol, parseNote, parseTimeSignature, pitchToScaleDegree, progressions, progressionsByStyle, pulsesPerBar, ratioToCents, rhythmDensity, roleOf, romanToChord, scaleByName, scaleMatchesChord, scaleTonesInDegreeOrder, scalesForChanges, secondaryDominant, spellChord, spellPitchClass, spellPitchClasses, spellScale, spelledInterval, substituteChord, tensionCurve, transformMotif, transposeChordSymbol, tuplet, voiceChord, voiceChordStyled, voiceLeadingCost, voiceProgression };
|
|
1
|
+
export { AnalyzedNote, ArrangementAnalysis, ArrangementOptions, ArrangementTrack, ChordMatch, Conflict, KeyMatch, TensionPoint, TheoryLabel, TrackAnalysis, TrackRole, VoiceNote, analyzeArrangement, analyzeVoice, chordToRoman, detectChord, detectChordBest, detectKey, romanToChord, tensionCurve } from './analyze/index.js';
|
|
2
|
+
export { B as BorrowedSource, C as Cadence, a as ChordAnalysis, H as HarmonicFunction, b as analyzeChord, c as borrowedSource, d as detectCadence, f as functionOf, i as isBorrowedChord, e as isDiatonic, g as isMinorKey, p as parallelKey, s as secondaryDominant } from './function-2bJW1Zp_.js';
|
|
3
|
+
export { C as CadenceHit, a as ChordSegment, b as ChordTimeline, c as ChordTimelineOptions, d as ChordTimelineResult, e as chordTimelineFromChords, f as chordTimelineFromNotes, g as detectCadences } from './index-BMPxwjwV.js';
|
|
4
|
+
export { IntervalQuality, JUST_RATIOS, Rng, TWELVE_TET, Tuning, centsBetweenFreq, centsOfSteps, classifyInterval, createRng, edo, frequencyOf, isConsonantInterval, isPerfectInterval, justDeviationCents, nearestStep, ratioToCents } from './core/index.js';
|
|
5
|
+
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';
|
|
6
|
+
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';
|
|
7
|
+
export { K as KeyScale, N as NoteEvent } from './types-MGP29r3t.js';
|
|
8
|
+
export { BassLineOptions, BassSegment, BassStyle, BorrowedChord, CounterMelodyOptions, DrumHit, DrumRole, DrumsOptions, EuclideanKick, GrooveFeel, GrooveSlot, GrooveStyle, GrooveTemplate, HarmonizeOptions, HarmonizeResult, HumanizeOptions, MelodyNote, MotifCell, MotifContour, MotifNote, MotifOptions, MotifTransform, ProgFunction, ProgStyle, ProgressionOptions, ProgressionPreset, RhythmEvent, RhythmOptions, Section, SubstituteOptions, Substitution, SubstitutionType, applyGrooveTemplate, developMotif, extractGrooveTemplate, generateBassLine, generateCounterMelody, generateDrums, generateMotif, generateProgression, generateRhythm, harmonizeMelody, humanize, modalInterchangePalette, negativeHarmonyMirror, onsetWeightCurve, progressions, progressionsByStyle, rhythmDensity, substituteChord, transformMotif } from './generate/index.js';
|
|
9
|
+
export { Chord, Interval, Key, Note, Progression } from './model/index.js';
|
|
10
|
+
export { C as ChordData, a as ChordQuality, b as ChordSpan, c as chordFromDegree, d as chordPitchClasses, e as chordQualities, f as chordToneRole, g as diatonicSeventh, h as diatonicTriad, m as makeChord } from './index-CM5W4rcm.js';
|
|
11
|
+
export { C as ChordScaleMatch, a as ChordScaleReportEntry, S as SATB_RANGES, b as ScaleChoice, c as StyledVoicingOptions, V as VoiceRange, d as VoicingOptions, e as VoicingStyle, f as availableTensions, g as avoidNotes, h as chordScaleReport, i as chordScales, s as scaleMatchesChord, j as scalesForChanges, v as voiceChord, k as voiceChordStyled, l as voiceProgression } from './styled-D7BAx3S3.js';
|
|
12
|
+
export { BLUES_MASK, CHROMATIC_MASK, DORIAN_MASK, HARMONIC_MINOR_MASK, LOCRIAN_MASK, LYDIAN_MASK, MAJOR_MASK, MAJOR_PENTATONIC_MASK, MELODIC_MINOR_MASK, MINOR_PENTATONIC_MASK, MIXOLYDIAN_MASK, NAMED_SCALES, NATURAL_MINOR_MASK, OCTATONIC_HALF_WHOLE_MASK, OCTATONIC_WHOLE_HALF_MASK, PHRYGIAN_MASK, WHOLE_TONE_MASK, createsHiddenParallelPerfect, createsParallelOctave, createsParallelPerfect, createsParallelUnison, createsVerticalDissonance, createsVoiceCrossing, createsVoiceOverlap, diatonicPitchClasses, exceedsSpacing, formatChordSymbol, isForbiddenMelodicLeap, isLeadingToneResolution, isScaleTone, majorKey, maskFromOffsets, minorKey, nearestScaleTone, nextVoicing, noteNames, parseChordSymbol, pitchToScaleDegree, scaleByName, scaleTonesInDegreeOrder, spellChord, spellPitchClass, spellPitchClasses, spellScale, transposeChordSymbol, voiceLeadingCost } from './theory/index.js';
|
|
13
|
+
export { H as HarmonyRole, L as LockLevel, V as VoicedRole, r as roleOf } from './index-CP3wAfEH.js';
|
|
14
|
+
export { N as NoteSafety, R as ReasonFlag, S as SafetyProfile, a as SafetyQuery, b as SafetyResult, V as VoiceSnapshot, e as enumerateSafePitches, c as evaluateSafety } from './index-BreoJRw0.js';
|