@libraz/libcantus 0.9.1 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -3
- package/dist/analyze/index.cjs +1970 -0
- package/dist/analyze/index.cjs.map +1 -0
- package/dist/analyze/index.d.cts +341 -0
- package/dist/analyze/index.d.ts +341 -0
- package/dist/analyze/index.js +51 -0
- package/dist/analyze/index.js.map +1 -0
- package/dist/chunk-2ZWMSJH6.js +30 -0
- package/dist/chunk-2ZWMSJH6.js.map +1 -0
- package/dist/chunk-4MHA432G.js +2854 -0
- package/dist/chunk-4MHA432G.js.map +1 -0
- package/dist/chunk-62QZKCJQ.js +49 -0
- package/dist/chunk-62QZKCJQ.js.map +1 -0
- package/dist/chunk-AKLYPWIN.js +83 -0
- package/dist/chunk-AKLYPWIN.js.map +1 -0
- package/dist/chunk-C5XYKUVG.js +904 -0
- package/dist/chunk-C5XYKUVG.js.map +1 -0
- package/dist/chunk-CHMXELDS.js +549 -0
- package/dist/chunk-CHMXELDS.js.map +1 -0
- package/dist/chunk-DYWFNC4A.js +152 -0
- package/dist/chunk-DYWFNC4A.js.map +1 -0
- package/dist/chunk-EH6EM37U.js +315 -0
- package/dist/chunk-EH6EM37U.js.map +1 -0
- package/dist/chunk-FBQK3ZQN.js +131 -0
- package/dist/chunk-FBQK3ZQN.js.map +1 -0
- package/dist/chunk-GOAW4VYL.js +719 -0
- package/dist/chunk-GOAW4VYL.js.map +1 -0
- package/dist/chunk-I5R7ZBJS.js +202 -0
- package/dist/chunk-I5R7ZBJS.js.map +1 -0
- package/dist/chunk-IT2O4XFE.js +154 -0
- package/dist/chunk-IT2O4XFE.js.map +1 -0
- package/dist/chunk-MIWO425M.js +412 -0
- package/dist/chunk-MIWO425M.js.map +1 -0
- package/dist/chunk-N6IHQUOX.js +1 -0
- package/dist/chunk-N6IHQUOX.js.map +1 -0
- package/dist/chunk-SGU7SPLK.js +924 -0
- package/dist/chunk-SGU7SPLK.js.map +1 -0
- package/dist/core/index.cjs +648 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +262 -0
- package/dist/core/index.d.ts +262 -0
- package/dist/core/index.js +93 -0
- package/dist/core/index.js.map +1 -0
- package/dist/function-DVH4Eusr.d.ts +187 -0
- package/dist/function-DYt4iKsn.d.cts +187 -0
- package/dist/generate/index.cjs +4123 -0
- package/dist/generate/index.cjs.map +1 -0
- package/dist/generate/index.d.cts +986 -0
- package/dist/generate/index.d.ts +986 -0
- package/dist/generate/index.js +52 -0
- package/dist/generate/index.js.map +1 -0
- package/dist/index-BNlGP86A.d.cts +157 -0
- package/dist/index-Bg5dYMmZ.d.ts +56 -0
- package/dist/index-Bt4tOUD9.d.ts +157 -0
- package/dist/index-CGMZNCx6.d.cts +140 -0
- package/dist/index-CGMZNCx6.d.ts +140 -0
- package/dist/index-Cl7mhOFM.d.cts +164 -0
- package/dist/index-Cl7mhOFM.d.ts +164 -0
- package/dist/index-CnZCo29u.d.cts +108 -0
- package/dist/index-CpOsP1y9.d.cts +151 -0
- package/dist/index-CxqBQtH1.d.cts +128 -0
- package/dist/index-Dikst44v.d.cts +56 -0
- package/dist/index-DxvARIP2.d.ts +151 -0
- package/dist/index-Jc0Ryi79.d.ts +128 -0
- package/dist/index-JnF4v9bx.d.ts +108 -0
- package/dist/index.cjs +3710 -3143
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -3982
- package/dist/index.d.ts +15 -3982
- package/dist/index.js +191 -6504
- package/dist/index.js.map +1 -1
- package/dist/model/index.cjs +2574 -0
- package/dist/model/index.cjs.map +1 -0
- package/dist/model/index.d.cts +631 -0
- package/dist/model/index.d.ts +631 -0
- package/dist/model/index.js +21 -0
- package/dist/model/index.js.map +1 -0
- package/dist/styled-DZ7GjShb.d.ts +282 -0
- package/dist/styled-ZTbdaVFM.d.cts +282 -0
- package/dist/theory/index.cjs +1823 -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 +150 -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 +61 -5
- package/src/analyze/arrange/index.ts +21 -0
- package/src/analyze/arrange/internal.ts +127 -0
- package/src/analyze/arrange/tension.ts +199 -0
- package/src/analyze/arrange/tracks.ts +312 -0
- package/src/{detect → analyze/detect}/index.ts +50 -13
- 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/{functional/index.ts → analyze/functional/roman.ts} +23 -332
- package/src/analyze/index.ts +49 -0
- package/src/{timeline → analyze/timeline}/index.ts +50 -18
- package/src/{analysis → analyze/voice}/index.ts +19 -7
- package/src/core/event-index/index.ts +104 -0
- package/src/core/index.ts +61 -0
- package/src/{meter → core/meter}/index.ts +24 -4
- package/src/{random → core/random}/index.ts +26 -3
- package/src/{tuning → core/tuning}/index.ts +36 -6
- package/src/core/validation/index.ts +119 -0
- package/src/{bass → generate/bass}/index.ts +28 -5
- package/src/{countermelody → generate/countermelody}/index.ts +176 -85
- package/src/{drums → generate/drums}/euclid.ts +10 -3
- package/src/{drums → generate/drums}/index.ts +58 -26
- package/src/{drums → generate/drums}/percussion.ts +1 -1
- package/src/{drums → generate/drums}/rng.ts +2 -2
- package/src/{groove → generate/groove}/index.ts +28 -3
- package/src/{harmonize → generate/harmonize}/index.ts +68 -57
- package/src/generate/index.ts +58 -0
- package/src/{motif → generate/motif}/index.ts +52 -28
- package/src/{progression → generate/progression}/index.ts +19 -41
- package/src/{reharmony → generate/reharmony}/index.ts +12 -19
- package/src/{rhythm → generate/rhythm}/index.ts +13 -3
- package/src/index.ts +13 -234
- package/src/model/chord.ts +442 -0
- package/src/model/index.ts +5 -1096
- 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 +23 -3
- package/src/{counterpoint → theory/counterpoint}/index.ts +2 -2
- package/src/{harmony → theory/harmony}/index.ts +6 -21
- package/src/theory/index.ts +112 -0
- package/src/{safety → theory/safety}/index.ts +72 -3
- 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 +73 -6
- package/src/{symbol → theory/symbol}/index.ts +8 -1
- 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 +216 -0
- package/src/theory/voicing/styled.ts +199 -0
- package/src/arrange/index.ts +0 -571
- package/src/scale/index.ts +0 -331
- package/src/voicing/index.ts +0 -623
- /package/src/{interval → core/interval}/index.ts +0 -0
- /package/src/{pitch → core/pitch}/index.ts +0 -0
- /package/src/{types.ts → core/types.ts} +0 -0
- /package/src/{drums → generate/drums}/beat.ts +0 -0
- /package/src/{drums → generate/drums}/fills.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}/internal.ts +0 -0
- /package/src/{drums → generate/drums}/kick.ts +0 -0
- /package/src/{drums → generate/drums}/swing.ts +0 -0
- /package/src/{chordscale → theory/chordscale}/index.ts +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
applyGrooveTemplate,
|
|
3
|
+
developMotif,
|
|
4
|
+
extractGrooveTemplate,
|
|
5
|
+
generateBassLine,
|
|
6
|
+
generateCounterMelody,
|
|
7
|
+
generateDrums,
|
|
8
|
+
generateMotif,
|
|
9
|
+
generateProgression,
|
|
10
|
+
generateRhythm,
|
|
11
|
+
harmonizeMelody,
|
|
12
|
+
humanize,
|
|
13
|
+
onsetWeightCurve,
|
|
14
|
+
progressions,
|
|
15
|
+
progressionsByStyle,
|
|
16
|
+
rhythmDensity,
|
|
17
|
+
transformMotif
|
|
18
|
+
} from "../chunk-4MHA432G.js";
|
|
19
|
+
import "../chunk-62QZKCJQ.js";
|
|
20
|
+
import "../chunk-I5R7ZBJS.js";
|
|
21
|
+
import {
|
|
22
|
+
modalInterchangePalette,
|
|
23
|
+
negativeHarmonyMirror,
|
|
24
|
+
substituteChord
|
|
25
|
+
} from "../chunk-IT2O4XFE.js";
|
|
26
|
+
import "../chunk-CHMXELDS.js";
|
|
27
|
+
import "../chunk-2ZWMSJH6.js";
|
|
28
|
+
import "../chunk-EH6EM37U.js";
|
|
29
|
+
import "../chunk-MIWO425M.js";
|
|
30
|
+
import "../chunk-FBQK3ZQN.js";
|
|
31
|
+
export {
|
|
32
|
+
applyGrooveTemplate,
|
|
33
|
+
developMotif,
|
|
34
|
+
extractGrooveTemplate,
|
|
35
|
+
generateBassLine,
|
|
36
|
+
generateCounterMelody,
|
|
37
|
+
generateDrums,
|
|
38
|
+
generateMotif,
|
|
39
|
+
generateProgression,
|
|
40
|
+
generateRhythm,
|
|
41
|
+
harmonizeMelody,
|
|
42
|
+
humanize,
|
|
43
|
+
modalInterchangePalette,
|
|
44
|
+
negativeHarmonyMirror,
|
|
45
|
+
onsetWeightCurve,
|
|
46
|
+
progressions,
|
|
47
|
+
progressionsByStyle,
|
|
48
|
+
rhythmDensity,
|
|
49
|
+
substituteChord,
|
|
50
|
+
transformMotif
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { K as KeyScale } from './types-MGP29r3t.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Chord quality identifiers understood by the chord builder.
|
|
5
|
+
*
|
|
6
|
+
* @category Chords
|
|
7
|
+
*/
|
|
8
|
+
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';
|
|
9
|
+
/**
|
|
10
|
+
* A bare spelled pitch used as an enharmonic hint: a diatonic letter
|
|
11
|
+
* (0..6 = C..B) plus a chromatic alteration (-2 double-flat .. +2 double-sharp).
|
|
12
|
+
* Mirrors the letter/alter half of the pitch module's `Note` without an octave.
|
|
13
|
+
*
|
|
14
|
+
* @category Chords
|
|
15
|
+
*/
|
|
16
|
+
type PitchSpelling = {
|
|
17
|
+
letter: number;
|
|
18
|
+
alter: number;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* A chord expressed as a root pitch class plus semitone offsets.
|
|
22
|
+
*
|
|
23
|
+
* `rootSpelling`/`bassSpelling` are optional enharmonic hints recorded by
|
|
24
|
+
* parsers (e.g. `parseChordSymbol('Bb7')`) so formatters can reproduce the
|
|
25
|
+
* original spelling instead of defaulting to sharps. Consumers may ignore
|
|
26
|
+
* them; a hint is only trusted when its pitch class still matches the
|
|
27
|
+
* corresponding `rootPc`/`bassPc`.
|
|
28
|
+
*
|
|
29
|
+
* @category Chords
|
|
30
|
+
*/
|
|
31
|
+
type Chord = {
|
|
32
|
+
rootPc: number;
|
|
33
|
+
quality: ChordQuality;
|
|
34
|
+
intervals: number[];
|
|
35
|
+
bassPc?: number;
|
|
36
|
+
rootSpelling?: PitchSpelling;
|
|
37
|
+
bassSpelling?: PitchSpelling;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* A chord positioned in time: a root pitch class and quality placed at a beat,
|
|
41
|
+
* with optional harmonic-analysis hints. Serves as the neutral exchange record
|
|
42
|
+
* between progression generators and timeline analysers.
|
|
43
|
+
*
|
|
44
|
+
* @category Composition
|
|
45
|
+
*/
|
|
46
|
+
type ChordSpan = {
|
|
47
|
+
rootPc: number;
|
|
48
|
+
quality: ChordQuality;
|
|
49
|
+
startBeat: number;
|
|
50
|
+
bassPc?: number;
|
|
51
|
+
/** 0-based scale degree of the chord root, when known. */
|
|
52
|
+
degree?: number;
|
|
53
|
+
/** True when the chord is a secondary dominant tonicizing another degree. */
|
|
54
|
+
secondaryDominant?: boolean;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* All chord qualities the builder understands, longest templates last.
|
|
58
|
+
*
|
|
59
|
+
* @category Chords
|
|
60
|
+
*/
|
|
61
|
+
declare function chordQualities(): ChordQuality[];
|
|
62
|
+
/**
|
|
63
|
+
* Build a chord rooted on a diatonic scale degree.
|
|
64
|
+
*
|
|
65
|
+
* The root pitch class is the degree's diatonic pitch class in `key`; the
|
|
66
|
+
* quality's interval template is attached unchanged. Degrees beyond the scale
|
|
67
|
+
* length wrap around.
|
|
68
|
+
*
|
|
69
|
+
* @param degree 0-based scale degree of the chord root.
|
|
70
|
+
* @param ext Chord quality to apply.
|
|
71
|
+
* @param key Key context supplying the diatonic root.
|
|
72
|
+
* @returns The constructed chord.
|
|
73
|
+
*
|
|
74
|
+
* @category Chords
|
|
75
|
+
*/
|
|
76
|
+
declare function chordFromDegree(degree: number, ext: ChordQuality, key: KeyScale): Chord;
|
|
77
|
+
/**
|
|
78
|
+
* Build a chord from an explicit root pitch class and quality.
|
|
79
|
+
*
|
|
80
|
+
* @param rootPc Root pitch class (0..11).
|
|
81
|
+
* @param quality Chord quality supplying the interval template.
|
|
82
|
+
* @param bassPc Optional slash-chord bass pitch class.
|
|
83
|
+
* @returns The constructed chord.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* import { makeChord } from '@libraz/libcantus';
|
|
88
|
+
* const cmaj7 = makeChord(0, 'maj7');
|
|
89
|
+
* // { rootPc: 0, quality: 'maj7', intervals: [0, 4, 7, 11] }
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* @category Chords
|
|
93
|
+
*/
|
|
94
|
+
declare function makeChord(rootPc: number, quality: ChordQuality, bassPc?: number): Chord;
|
|
95
|
+
/**
|
|
96
|
+
* Get the sorted, deduplicated pitch classes of a chord.
|
|
97
|
+
*
|
|
98
|
+
* @param chord The chord to enumerate.
|
|
99
|
+
* @returns The chord's pitch classes, sorted ascending in [0, 11].
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```ts
|
|
103
|
+
* import { makeChord, chordPitchClasses } from '@libraz/libcantus';
|
|
104
|
+
* chordPitchClasses(makeChord(0, 'maj7')); // [0, 4, 7, 11]
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @category Chords
|
|
108
|
+
*/
|
|
109
|
+
declare function chordPitchClasses(chord: Chord): number[];
|
|
110
|
+
/**
|
|
111
|
+
* Determine a pitch's harmonic role within a chord.
|
|
112
|
+
*
|
|
113
|
+
* The role is derived from the pitch's interval above the chord root, reduced
|
|
114
|
+
* modulo 12. A major sixth (9) reads as a `sixth` for sixth chords but as a
|
|
115
|
+
* `seventh` for a diminished-seventh chord; ninths and other tensions have no
|
|
116
|
+
* basic role and return null.
|
|
117
|
+
*
|
|
118
|
+
* @param pitch MIDI pitch or bare pitch class.
|
|
119
|
+
* @param chord The chord providing the root reference.
|
|
120
|
+
* @returns The chord-tone role, or null if the pitch has no basic role.
|
|
121
|
+
*
|
|
122
|
+
* @category Chords
|
|
123
|
+
*/
|
|
124
|
+
declare function chordToneRole(pitch: number, chord: Chord): 'root' | 'third' | 'fifth' | 'sixth' | 'seventh' | null;
|
|
125
|
+
/**
|
|
126
|
+
* Build the diatonic triad rooted on a scale degree by stacking scale thirds.
|
|
127
|
+
*
|
|
128
|
+
* Unlike {@link chordFromDegree}, the chord quality is derived from the scale
|
|
129
|
+
* rather than supplied, so degrees yield their scale-correct triads (e.g. a
|
|
130
|
+
* diminished triad on the leading tone of a major key). Intended for heptatonic
|
|
131
|
+
* scales; other scales stack by scale step regardless.
|
|
132
|
+
*
|
|
133
|
+
* @param degree 0-based scale degree of the chord root.
|
|
134
|
+
* @param key Key/scale context.
|
|
135
|
+
* @returns The diatonic triad.
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```ts
|
|
139
|
+
* import { majorKey, diatonicTriad } from '@libraz/libcantus';
|
|
140
|
+
* const tonic = diatonicTriad(0, majorKey(0)); // C major triad (degree 0 of C major)
|
|
141
|
+
* ```
|
|
142
|
+
*
|
|
143
|
+
* @category Chords
|
|
144
|
+
*/
|
|
145
|
+
declare function diatonicTriad(degree: number, key: KeyScale): Chord;
|
|
146
|
+
/**
|
|
147
|
+
* Build the diatonic seventh chord rooted on a scale degree.
|
|
148
|
+
*
|
|
149
|
+
* @param degree 0-based scale degree of the chord root.
|
|
150
|
+
* @param key Key/scale context.
|
|
151
|
+
* @returns The diatonic seventh chord.
|
|
152
|
+
*
|
|
153
|
+
* @category Chords
|
|
154
|
+
*/
|
|
155
|
+
declare function diatonicSeventh(degree: number, key: KeyScale): Chord;
|
|
156
|
+
|
|
157
|
+
export { type Chord as C, type PitchSpelling as P, type ChordQuality as a, type ChordSpan as b, chordFromDegree as c, chordPitchClasses as d, chordQualities as e, chordToneRole as f, diatonicSeventh as g, diatonicTriad as h, makeChord as m };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { C as Chord } from './index-Bt4tOUD9.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Harmonic role a pitch plays within a chord.
|
|
5
|
+
*
|
|
6
|
+
* @category Functional Harmony
|
|
7
|
+
*/
|
|
8
|
+
type HarmonyRole = 'root' | 'third' | 'fifth' | 'sixth' | 'seventh' | 'tension' | 'doubling';
|
|
9
|
+
/**
|
|
10
|
+
* How firmly a pitch is locked to the chord's identity.
|
|
11
|
+
*
|
|
12
|
+
* - `identity`: moving it produces a different chord (the root).
|
|
13
|
+
* - `quality`: moving it flips the chord quality (the third).
|
|
14
|
+
* - `voicing`: it can move freely without changing chord identity or quality.
|
|
15
|
+
*
|
|
16
|
+
* @category Functional Harmony
|
|
17
|
+
*/
|
|
18
|
+
type LockLevel = 'identity' | 'quality' | 'voicing';
|
|
19
|
+
/**
|
|
20
|
+
* A pitch's role, lock level, and owning chord.
|
|
21
|
+
*
|
|
22
|
+
* @category Functional Harmony
|
|
23
|
+
*/
|
|
24
|
+
type VoicedRole = {
|
|
25
|
+
role: HarmonyRole;
|
|
26
|
+
lock: LockLevel;
|
|
27
|
+
belongsToChordId: number;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Classify a pitch's harmonic role and lock level within a chord.
|
|
31
|
+
*
|
|
32
|
+
* The role comes from the pitch's interval class above the chord root: root (0),
|
|
33
|
+
* third (3/4), fifth (6/7/8), seventh (10/11), and 9/11/13 tensions (2/5/9, and
|
|
34
|
+
* the flat ninth 1). The root locks the chord identity, the third locks its
|
|
35
|
+
* quality, and everything else is free voicing. In a suspended chord (a chord
|
|
36
|
+
* whose intervals include a 4th (5) or 2nd (2) but no third), the suspended tone
|
|
37
|
+
* takes the third's place as the quality-defining tone and is locked to
|
|
38
|
+
* `quality`, since moving it changes the chord. Detecting an octave doubling
|
|
39
|
+
* requires the surrounding voicing, which this single-pitch query does not carry,
|
|
40
|
+
* so `doubling` is part of the type but not returned here.
|
|
41
|
+
*
|
|
42
|
+
* @param pitch MIDI pitch or bare pitch class.
|
|
43
|
+
* @param chord The chord providing the root reference.
|
|
44
|
+
* @param chordId Identifier stored on the result (defaults to 0).
|
|
45
|
+
* @returns The pitch's role, lock level, and owning chord id.
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* import { roleOf, makeChord } from '@libraz/libcantus';
|
|
49
|
+
* roleOf(64, makeChord(0, 'maj')); // E over C major
|
|
50
|
+
* // { role: 'third', lock: 'quality', belongsToChordId: 0 }
|
|
51
|
+
* ```
|
|
52
|
+
* @category Functional Harmony
|
|
53
|
+
*/
|
|
54
|
+
declare function roleOf(pitch: number, chord: Chord, chordId?: number): VoicedRole;
|
|
55
|
+
|
|
56
|
+
export { type HarmonyRole as H, type LockLevel as L, type VoicedRole as V, roleOf as r };
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { K as KeyScale } from './types-MGP29r3t.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Chord quality identifiers understood by the chord builder.
|
|
5
|
+
*
|
|
6
|
+
* @category Chords
|
|
7
|
+
*/
|
|
8
|
+
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';
|
|
9
|
+
/**
|
|
10
|
+
* A bare spelled pitch used as an enharmonic hint: a diatonic letter
|
|
11
|
+
* (0..6 = C..B) plus a chromatic alteration (-2 double-flat .. +2 double-sharp).
|
|
12
|
+
* Mirrors the letter/alter half of the pitch module's `Note` without an octave.
|
|
13
|
+
*
|
|
14
|
+
* @category Chords
|
|
15
|
+
*/
|
|
16
|
+
type PitchSpelling = {
|
|
17
|
+
letter: number;
|
|
18
|
+
alter: number;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* A chord expressed as a root pitch class plus semitone offsets.
|
|
22
|
+
*
|
|
23
|
+
* `rootSpelling`/`bassSpelling` are optional enharmonic hints recorded by
|
|
24
|
+
* parsers (e.g. `parseChordSymbol('Bb7')`) so formatters can reproduce the
|
|
25
|
+
* original spelling instead of defaulting to sharps. Consumers may ignore
|
|
26
|
+
* them; a hint is only trusted when its pitch class still matches the
|
|
27
|
+
* corresponding `rootPc`/`bassPc`.
|
|
28
|
+
*
|
|
29
|
+
* @category Chords
|
|
30
|
+
*/
|
|
31
|
+
type Chord = {
|
|
32
|
+
rootPc: number;
|
|
33
|
+
quality: ChordQuality;
|
|
34
|
+
intervals: number[];
|
|
35
|
+
bassPc?: number;
|
|
36
|
+
rootSpelling?: PitchSpelling;
|
|
37
|
+
bassSpelling?: PitchSpelling;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* A chord positioned in time: a root pitch class and quality placed at a beat,
|
|
41
|
+
* with optional harmonic-analysis hints. Serves as the neutral exchange record
|
|
42
|
+
* between progression generators and timeline analysers.
|
|
43
|
+
*
|
|
44
|
+
* @category Composition
|
|
45
|
+
*/
|
|
46
|
+
type ChordSpan = {
|
|
47
|
+
rootPc: number;
|
|
48
|
+
quality: ChordQuality;
|
|
49
|
+
startBeat: number;
|
|
50
|
+
bassPc?: number;
|
|
51
|
+
/** 0-based scale degree of the chord root, when known. */
|
|
52
|
+
degree?: number;
|
|
53
|
+
/** True when the chord is a secondary dominant tonicizing another degree. */
|
|
54
|
+
secondaryDominant?: boolean;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* All chord qualities the builder understands, longest templates last.
|
|
58
|
+
*
|
|
59
|
+
* @category Chords
|
|
60
|
+
*/
|
|
61
|
+
declare function chordQualities(): ChordQuality[];
|
|
62
|
+
/**
|
|
63
|
+
* Build a chord rooted on a diatonic scale degree.
|
|
64
|
+
*
|
|
65
|
+
* The root pitch class is the degree's diatonic pitch class in `key`; the
|
|
66
|
+
* quality's interval template is attached unchanged. Degrees beyond the scale
|
|
67
|
+
* length wrap around.
|
|
68
|
+
*
|
|
69
|
+
* @param degree 0-based scale degree of the chord root.
|
|
70
|
+
* @param ext Chord quality to apply.
|
|
71
|
+
* @param key Key context supplying the diatonic root.
|
|
72
|
+
* @returns The constructed chord.
|
|
73
|
+
*
|
|
74
|
+
* @category Chords
|
|
75
|
+
*/
|
|
76
|
+
declare function chordFromDegree(degree: number, ext: ChordQuality, key: KeyScale): Chord;
|
|
77
|
+
/**
|
|
78
|
+
* Build a chord from an explicit root pitch class and quality.
|
|
79
|
+
*
|
|
80
|
+
* @param rootPc Root pitch class (0..11).
|
|
81
|
+
* @param quality Chord quality supplying the interval template.
|
|
82
|
+
* @param bassPc Optional slash-chord bass pitch class.
|
|
83
|
+
* @returns The constructed chord.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* import { makeChord } from '@libraz/libcantus';
|
|
88
|
+
* const cmaj7 = makeChord(0, 'maj7');
|
|
89
|
+
* // { rootPc: 0, quality: 'maj7', intervals: [0, 4, 7, 11] }
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* @category Chords
|
|
93
|
+
*/
|
|
94
|
+
declare function makeChord(rootPc: number, quality: ChordQuality, bassPc?: number): Chord;
|
|
95
|
+
/**
|
|
96
|
+
* Get the sorted, deduplicated pitch classes of a chord.
|
|
97
|
+
*
|
|
98
|
+
* @param chord The chord to enumerate.
|
|
99
|
+
* @returns The chord's pitch classes, sorted ascending in [0, 11].
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```ts
|
|
103
|
+
* import { makeChord, chordPitchClasses } from '@libraz/libcantus';
|
|
104
|
+
* chordPitchClasses(makeChord(0, 'maj7')); // [0, 4, 7, 11]
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @category Chords
|
|
108
|
+
*/
|
|
109
|
+
declare function chordPitchClasses(chord: Chord): number[];
|
|
110
|
+
/**
|
|
111
|
+
* Determine a pitch's harmonic role within a chord.
|
|
112
|
+
*
|
|
113
|
+
* The role is derived from the pitch's interval above the chord root, reduced
|
|
114
|
+
* modulo 12. A major sixth (9) reads as a `sixth` for sixth chords but as a
|
|
115
|
+
* `seventh` for a diminished-seventh chord; ninths and other tensions have no
|
|
116
|
+
* basic role and return null.
|
|
117
|
+
*
|
|
118
|
+
* @param pitch MIDI pitch or bare pitch class.
|
|
119
|
+
* @param chord The chord providing the root reference.
|
|
120
|
+
* @returns The chord-tone role, or null if the pitch has no basic role.
|
|
121
|
+
*
|
|
122
|
+
* @category Chords
|
|
123
|
+
*/
|
|
124
|
+
declare function chordToneRole(pitch: number, chord: Chord): 'root' | 'third' | 'fifth' | 'sixth' | 'seventh' | null;
|
|
125
|
+
/**
|
|
126
|
+
* Build the diatonic triad rooted on a scale degree by stacking scale thirds.
|
|
127
|
+
*
|
|
128
|
+
* Unlike {@link chordFromDegree}, the chord quality is derived from the scale
|
|
129
|
+
* rather than supplied, so degrees yield their scale-correct triads (e.g. a
|
|
130
|
+
* diminished triad on the leading tone of a major key). Intended for heptatonic
|
|
131
|
+
* scales; other scales stack by scale step regardless.
|
|
132
|
+
*
|
|
133
|
+
* @param degree 0-based scale degree of the chord root.
|
|
134
|
+
* @param key Key/scale context.
|
|
135
|
+
* @returns The diatonic triad.
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```ts
|
|
139
|
+
* import { majorKey, diatonicTriad } from '@libraz/libcantus';
|
|
140
|
+
* const tonic = diatonicTriad(0, majorKey(0)); // C major triad (degree 0 of C major)
|
|
141
|
+
* ```
|
|
142
|
+
*
|
|
143
|
+
* @category Chords
|
|
144
|
+
*/
|
|
145
|
+
declare function diatonicTriad(degree: number, key: KeyScale): Chord;
|
|
146
|
+
/**
|
|
147
|
+
* Build the diatonic seventh chord rooted on a scale degree.
|
|
148
|
+
*
|
|
149
|
+
* @param degree 0-based scale degree of the chord root.
|
|
150
|
+
* @param key Key/scale context.
|
|
151
|
+
* @returns The diatonic seventh chord.
|
|
152
|
+
*
|
|
153
|
+
* @category Chords
|
|
154
|
+
*/
|
|
155
|
+
declare function diatonicSeventh(degree: number, key: KeyScale): Chord;
|
|
156
|
+
|
|
157
|
+
export { type Chord as C, type PitchSpelling as P, type ChordQuality as a, type ChordSpan as b, chordFromDegree as c, chordPitchClasses as d, chordQualities as e, chordToneRole as f, diatonicSeventh as g, diatonicTriad as h, makeChord as m };
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pitch spelling: letter-name notes, enharmonic-aware conversion, and spelled
|
|
3
|
+
* intervals.
|
|
4
|
+
*
|
|
5
|
+
* The rest of the library works in pitch classes (0..11), which cannot tell a
|
|
6
|
+
* G# from an Ab or an augmented fourth from a diminished fifth. This module adds
|
|
7
|
+
* an explicit spelling layer — a note is a diatonic letter plus a chromatic
|
|
8
|
+
* alteration — so interval quality (P/M/m/A/d) and enharmonic identity are
|
|
9
|
+
* preserved.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* A spelled note: a diatonic letter, a chromatic alteration, and an optional
|
|
13
|
+
* octave.
|
|
14
|
+
*
|
|
15
|
+
* - `letter` is 0..6 for C..B.
|
|
16
|
+
* - `alter` is the number of semitones of alteration: -2 double-flat, -1 flat,
|
|
17
|
+
* 0 natural, +1 sharp, +2 double-sharp.
|
|
18
|
+
* - `octave` follows scientific pitch notation (middle C = C4 = MIDI 60). When
|
|
19
|
+
* absent, the note denotes a bare pitch class.
|
|
20
|
+
*
|
|
21
|
+
* @category Pitch & Intervals
|
|
22
|
+
*/
|
|
23
|
+
type Note = {
|
|
24
|
+
letter: number;
|
|
25
|
+
alter: number;
|
|
26
|
+
octave?: number;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* A spelled interval: a diatonic number, a quality label, and its semitone span.
|
|
30
|
+
*
|
|
31
|
+
* @category Pitch & Intervals
|
|
32
|
+
*/
|
|
33
|
+
type SpelledInterval = {
|
|
34
|
+
/** Diatonic size: 1 = unison, 2 = second, ... 8 = octave, and beyond. */
|
|
35
|
+
number: number;
|
|
36
|
+
/** Quality label: 'P', 'M', 'm', or repeated 'A'/'d' for (multiply) aug/dim. */
|
|
37
|
+
quality: string;
|
|
38
|
+
/** Signed semitone distance from the first note to the second. */
|
|
39
|
+
semitones: number;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Parse scientific pitch notation into a {@link Note}.
|
|
43
|
+
*
|
|
44
|
+
* Accepts a letter (case-insensitive) followed by any number of same-direction
|
|
45
|
+
* accidentals and an optional octave, e.g. `"C"`, `"C#4"`, `"Bb"`, `"F##3"`,
|
|
46
|
+
* `"Ebb2"`. Both `#` and `x` (double-sharp) are accepted for sharps; `b` for
|
|
47
|
+
* flats. Mixing sharps and flats (e.g. `"C#b"`) is rejected.
|
|
48
|
+
*
|
|
49
|
+
* @param text The note text.
|
|
50
|
+
* @returns The parsed note.
|
|
51
|
+
* @throws If the text is not a valid note.
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* import { parseNote, noteToMidi } from '@libraz/libcantus';
|
|
55
|
+
* const n = parseNote('C#4');
|
|
56
|
+
* noteToMidi(n); // 61
|
|
57
|
+
* ```
|
|
58
|
+
* @category Pitch & Intervals
|
|
59
|
+
*/
|
|
60
|
+
declare function parseNote(text: string): Note;
|
|
61
|
+
/**
|
|
62
|
+
* Render a {@link Note} as scientific pitch notation.
|
|
63
|
+
*
|
|
64
|
+
* @param note The note to format.
|
|
65
|
+
* @returns The note text, including the octave when present.
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* import { formatNote, parseNote } from '@libraz/libcantus';
|
|
69
|
+
* formatNote(parseNote('C#4')); // 'C#4'
|
|
70
|
+
* ```
|
|
71
|
+
* @category Pitch & Intervals
|
|
72
|
+
*/
|
|
73
|
+
declare function formatNote(note: Note): string;
|
|
74
|
+
/**
|
|
75
|
+
* Pitch class (0..11) of a note, ignoring octave.
|
|
76
|
+
*
|
|
77
|
+
* @param note The note.
|
|
78
|
+
* @returns The pitch class.
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* import { noteToPitchClass, parseNote } from '@libraz/libcantus';
|
|
82
|
+
* noteToPitchClass(parseNote('Db')); // 1
|
|
83
|
+
* ```
|
|
84
|
+
* @category Pitch & Intervals
|
|
85
|
+
*/
|
|
86
|
+
declare function noteToPitchClass(note: Note): number;
|
|
87
|
+
/**
|
|
88
|
+
* MIDI number of a note (middle C = C4 = 60).
|
|
89
|
+
*
|
|
90
|
+
* @param note The note; must carry an octave.
|
|
91
|
+
* @returns The MIDI number.
|
|
92
|
+
* @throws If the note has no octave.
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* import { noteToMidi, parseNote } from '@libraz/libcantus';
|
|
96
|
+
* noteToMidi(parseNote('A4')); // 69
|
|
97
|
+
* ```
|
|
98
|
+
* @category Pitch & Intervals
|
|
99
|
+
*/
|
|
100
|
+
declare function noteToMidi(note: Note): number;
|
|
101
|
+
/**
|
|
102
|
+
* Name a MIDI number as a {@link Note}, choosing sharp or flat spelling.
|
|
103
|
+
*
|
|
104
|
+
* The input is rounded to the nearest integer but is not clamped to the MIDI
|
|
105
|
+
* range 0..127: out-of-range values extrapolate linearly (e.g. `-1` -> `B-2`,
|
|
106
|
+
* `128` -> `G#9`) and remain an exact inverse of {@link noteToMidi}.
|
|
107
|
+
*
|
|
108
|
+
* @param midi The MIDI number.
|
|
109
|
+
* @param spelling Whether to prefer sharps or flats for black keys.
|
|
110
|
+
* @returns The spelled note, with octave.
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* import { midiToNote, formatNote } from '@libraz/libcantus';
|
|
114
|
+
* formatNote(midiToNote(61)); // 'C#4'
|
|
115
|
+
* formatNote(midiToNote(61, 'flat')); // 'Db4'
|
|
116
|
+
* ```
|
|
117
|
+
* @category Pitch & Intervals
|
|
118
|
+
*/
|
|
119
|
+
declare function midiToNote(midi: number, spelling?: 'sharp' | 'flat'): Note;
|
|
120
|
+
/**
|
|
121
|
+
* The spelled interval from one note to another.
|
|
122
|
+
*
|
|
123
|
+
* When both notes carry octaves, the interval reflects their full signed
|
|
124
|
+
* distance (so `C4 -> C5` is a perfect octave). When either lacks an octave the
|
|
125
|
+
* interval is measured within a single ascending octave from `a` to `b`.
|
|
126
|
+
*
|
|
127
|
+
* @param a The lower/first note.
|
|
128
|
+
* @param b The upper/second note.
|
|
129
|
+
* @returns The diatonic number, quality, and semitone span.
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* import { spelledInterval, parseNote } from '@libraz/libcantus';
|
|
133
|
+
* spelledInterval(parseNote('C4'), parseNote('G4'));
|
|
134
|
+
* // { number: 5, quality: 'P', semitones: 7 }
|
|
135
|
+
* ```
|
|
136
|
+
* @category Pitch & Intervals
|
|
137
|
+
*/
|
|
138
|
+
declare function spelledInterval(a: Note, b: Note): SpelledInterval;
|
|
139
|
+
|
|
140
|
+
export { type Note as N, type SpelledInterval as S, noteToPitchClass as a, formatNote as f, midiToNote as m, noteToMidi as n, parseNote as p, spelledInterval as s };
|