@leafo/lml 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +248 -0
- package/dist/auto-chords.d.ts +46 -0
- package/dist/auto-chords.d.ts.map +1 -0
- package/dist/auto-chords.js +240 -0
- package/dist/auto-chords.js.map +1 -0
- package/dist/grammar.d.ts +12 -0
- package/dist/grammar.d.ts.map +1 -0
- package/dist/grammar.js +1431 -0
- package/dist/grammar.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/music.d.ts +107 -0
- package/dist/music.d.ts.map +1 -0
- package/dist/music.js +704 -0
- package/dist/music.js.map +1 -0
- package/dist/note-list.d.ts +10 -0
- package/dist/note-list.d.ts.map +1 -0
- package/dist/note-list.js +88 -0
- package/dist/note-list.js.map +1 -0
- package/dist/parser.d.ts +27 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +181 -0
- package/dist/parser.js.map +1 -0
- package/dist/song.d.ts +50 -0
- package/dist/song.d.ts.map +1 -0
- package/dist/song.js +261 -0
- package/dist/song.js.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# @leafo/lml
|
|
2
|
+
|
|
3
|
+
LML (Leaf's Music Language) is a text-based notation for writing music. It's designed to be easy to write by hand and parse programmatically.
|
|
4
|
+
|
|
5
|
+
WARNING: this is work in progress, expect interfaces to change. This was created for use in <https://sightreading.training>.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @leafo/lml
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import SongParser from "@leafo/lml"
|
|
17
|
+
|
|
18
|
+
// Parse and compile LML to a song
|
|
19
|
+
const song = SongParser.load(`
|
|
20
|
+
ks0 ts4/4
|
|
21
|
+
c5 d5 e5 f5
|
|
22
|
+
g5.2 g5.2
|
|
23
|
+
`)
|
|
24
|
+
|
|
25
|
+
// Access the notes
|
|
26
|
+
for (const note of song) {
|
|
27
|
+
console.log(`${note.note} at beat ${note.start} for ${note.duration} beats`)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Access metadata
|
|
31
|
+
console.log(song.metadata.keySignature) // 0
|
|
32
|
+
console.log(song.metadata.beatsPerMeasure) // 4
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Two-phase parsing
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import SongParser from "@leafo/lml"
|
|
39
|
+
|
|
40
|
+
const parser = new SongParser()
|
|
41
|
+
|
|
42
|
+
// Phase 1: Parse text to AST
|
|
43
|
+
const ast = parser.parse("c5 d5 e5")
|
|
44
|
+
// [["note", "C5"], ["note", "D5"], ["note", "E5"]]
|
|
45
|
+
|
|
46
|
+
// Phase 2: Compile AST to song
|
|
47
|
+
const song = parser.compile(ast)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## LML Syntax
|
|
51
|
+
|
|
52
|
+
### Notes
|
|
53
|
+
|
|
54
|
+
A note is written as the note name followed by the octave. Notes are placed sequentially and must be separated by whitespace.
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
c5 d5 e5
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
A duration multiplier can be specified by appending a period and a number. The default duration is 1 beat.
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
c5.2 d5 d5 e5.4
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Notes can be made sharp with `+`, flat with `-`, or natural with `=`. These modifiers appear after the note name but before the octave.
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
c+5 c-5 b=4
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Rests
|
|
73
|
+
|
|
74
|
+
Insert silence using the rest command `r`, optionally with a duration multiplier.
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
c5 r d5.2
|
|
78
|
+
d5 r2 a4
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Time Commands
|
|
82
|
+
|
|
83
|
+
Change the base duration using time commands. These take effect until the end of the song or block.
|
|
84
|
+
|
|
85
|
+
- `dt` — Double time (notes become half as long)
|
|
86
|
+
- `ht` — Half time (notes become twice as long)
|
|
87
|
+
- `tt` — Triple time (notes become one-third as long)
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
dt
|
|
91
|
+
c5 d5 c5 d5 c5 d5 e5.2
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Time commands stack when repeated:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
dt dt c5 d5 # Each note is 0.25 beats
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Position Restore
|
|
101
|
+
|
|
102
|
+
Move the position back to the start using `|`. This is useful for writing chords or multiple voices.
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
c5 | e5 | g5 # C major chord
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Two voices:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
| c5 g5 e5.2
|
|
112
|
+
| c4.2 f4.2
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Blocks
|
|
116
|
+
|
|
117
|
+
Blocks are delimited with `{` and `}`. They affect how commands work:
|
|
118
|
+
|
|
119
|
+
- `|` moves position back to the start of the block
|
|
120
|
+
- Time commands (`dt`, `ht`, `tt`) reset after the block
|
|
121
|
+
- Track selection resets after the block
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
{
|
|
125
|
+
dt
|
|
126
|
+
c5 { dt e5 f5 } d5.2 e5 g5 a5 c6
|
|
127
|
+
}
|
|
128
|
+
|
|
|
129
|
+
{ ht g4 f4 }
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Measures
|
|
133
|
+
|
|
134
|
+
The `m` command moves the position to a specific measure. Commonly used with blocks:
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
m0 {
|
|
138
|
+
| c5 c5 a5 g5
|
|
139
|
+
| g4.4
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
m1 {
|
|
143
|
+
| d5 d5 a5 e5
|
|
144
|
+
| f4.4
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Key Signature
|
|
149
|
+
|
|
150
|
+
Set the key signature with `ks` followed by the number of sharps (positive) or flats (negative). Notes are automatically adjusted to match the key.
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
ks2 # D major (2 sharps: F#, C#)
|
|
154
|
+
c5 d5 e5 f5 # F becomes F#, C becomes C#
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Use `=` to override the key signature with a natural:
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
ks-2
|
|
161
|
+
b5 c5 b=5 # B natural
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Time Signature
|
|
165
|
+
|
|
166
|
+
Set the time signature with `ts`:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
ts3/4
|
|
170
|
+
c5 d5 e5
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
This affects beats per measure and where measure lines appear.
|
|
174
|
+
|
|
175
|
+
### Chords
|
|
176
|
+
|
|
177
|
+
The `$` command specifies a chord symbol for auto-chord generation:
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
{$G c5.2 a5 d5}
|
|
181
|
+
{$Dm e5 f5 g5.2}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Supported chord types: `M`, `m`, `dim`, `dim7`, `dimM7`, `aug`, `augM7`, `M6`, `m6`, `M7`, `7`, `m7`, `m7b5`, `mM7`
|
|
185
|
+
|
|
186
|
+
### Tracks
|
|
187
|
+
|
|
188
|
+
Songs can have multiple tracks, numbered starting from 0. Use `t` to switch tracks:
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
t0 c5 d5 e5
|
|
192
|
+
t1 g3 g3 g3
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Clefs
|
|
196
|
+
|
|
197
|
+
Set the clef with `/g` (treble), `/f` (bass), or `/c` (alto):
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
/g c5 d5 e5
|
|
201
|
+
/f c3 d3 e3
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Comments
|
|
205
|
+
|
|
206
|
+
Text after `#` is ignored:
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
c5 d5 # this is a comment
|
|
210
|
+
# full line comment
|
|
211
|
+
e5 f5
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Music Theory Utilities
|
|
215
|
+
|
|
216
|
+
The library also exports music theory utilities:
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
import {
|
|
220
|
+
parseNote,
|
|
221
|
+
noteName,
|
|
222
|
+
Chord,
|
|
223
|
+
MajorScale,
|
|
224
|
+
MinorScale,
|
|
225
|
+
KeySignature,
|
|
226
|
+
} from "@leafo/lml"
|
|
227
|
+
|
|
228
|
+
// Note conversion
|
|
229
|
+
parseNote("C5") // 60 (MIDI pitch)
|
|
230
|
+
noteName(60) // "C5"
|
|
231
|
+
|
|
232
|
+
// Scales
|
|
233
|
+
const scale = new MajorScale("C")
|
|
234
|
+
scale.getRange(5, 8) // ["C5", "D5", "E5", "F5", "G5", "A5", "B5", "C6"]
|
|
235
|
+
|
|
236
|
+
// Chords
|
|
237
|
+
const chord = new Chord("C", "M")
|
|
238
|
+
chord.getRange(5, 3) // ["C5", "E5", "G5"]
|
|
239
|
+
|
|
240
|
+
// Key signatures
|
|
241
|
+
const key = new KeySignature(2) // D major
|
|
242
|
+
key.name() // "D"
|
|
243
|
+
key.accidentalNotes() // ["F", "C"]
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## License
|
|
247
|
+
|
|
248
|
+
MIT
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { SongNote, MultiTrackSong } from "./song.js";
|
|
2
|
+
export interface AutoChordsOptions {
|
|
3
|
+
rate?: number;
|
|
4
|
+
chordMinSpacing?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface ChordBlock {
|
|
7
|
+
start: number;
|
|
8
|
+
stop: number;
|
|
9
|
+
chord: [string, string];
|
|
10
|
+
}
|
|
11
|
+
export declare class AutoChords {
|
|
12
|
+
static defaultChords(song: MultiTrackSong, options?: AutoChordsOptions): AutoChords;
|
|
13
|
+
static coerceChord(macro: string): [string, string] | undefined;
|
|
14
|
+
static allGenerators: (typeof AutoChords)[];
|
|
15
|
+
static displayName: string;
|
|
16
|
+
song: MultiTrackSong;
|
|
17
|
+
options: AutoChordsOptions;
|
|
18
|
+
constructor(song: MultiTrackSong, options?: AutoChordsOptions);
|
|
19
|
+
findChordBlocks(): ChordBlock[];
|
|
20
|
+
addChords(): void;
|
|
21
|
+
minPitchInRange(start: number, stop: number): number;
|
|
22
|
+
rootBelow(name: string, maxPitch: number): string;
|
|
23
|
+
notesForChord(_root: string, _shape: string, _blockStart: number, _blockStop: number): SongNote[];
|
|
24
|
+
inDivisions(start: number, stop: number, count: number, fn: (left: number, right: number, k: number) => void): void;
|
|
25
|
+
}
|
|
26
|
+
export declare class RootAutoChords extends AutoChords {
|
|
27
|
+
static displayName: string;
|
|
28
|
+
notesForChord(root: string, _shape: string, blockStart: number, blockStop: number): SongNote[];
|
|
29
|
+
}
|
|
30
|
+
export declare class TriadAutoChords extends AutoChords {
|
|
31
|
+
static displayName: string;
|
|
32
|
+
notesForChord(root: string, shape: string, blockStart: number, blockStop: number): SongNote[];
|
|
33
|
+
}
|
|
34
|
+
export declare class Root5AutoChords extends AutoChords {
|
|
35
|
+
static displayName: string;
|
|
36
|
+
notesForChord(root: string, shape: string, blockStart: number, blockStop: number): SongNote[];
|
|
37
|
+
}
|
|
38
|
+
export declare class ArpAutoChords extends AutoChords {
|
|
39
|
+
static displayName: string;
|
|
40
|
+
notesForChord(root: string, shape: string, blockStart: number, blockStop: number): SongNote[];
|
|
41
|
+
}
|
|
42
|
+
export declare class BossaNovaAutoChords extends AutoChords {
|
|
43
|
+
static displayName: string;
|
|
44
|
+
notesForChord(root: string, shape: string, blockStart: number, blockStop: number): SongNote[];
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=auto-chords.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-chords.d.ts","sourceRoot":"","sources":["../src/auto-chords.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAgB,cAAc,EAAE,MAAM,WAAW,CAAA;AAElE,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACxB;AAED,qBAAa,UAAU;IACrB,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,UAAU;IAKnF,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IAkB/D,MAAM,CAAC,aAAa,EAAE,CAAC,OAAO,UAAU,CAAC,EAAE,CAAK;IAEhD,MAAM,CAAC,WAAW,SAAgB;IAElC,IAAI,EAAE,cAAc,CAAA;IACpB,OAAO,EAAE,iBAAiB,CAAA;gBAEd,IAAI,EAAE,cAAc,EAAE,OAAO,GAAE,iBAAsB;IAKjE,eAAe,IAAI,UAAU,EAAE;IAwC/B,SAAS,IAAI,IAAI;IAyBjB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAkBpD,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAMjD,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,QAAQ,EAAE;IAKjG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;CAmBpH;AAED,qBAAa,cAAe,SAAQ,UAAU;IAC5C,OAAgB,WAAW,SAAS;IAEpC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,EAAE;CAc/F;AAED,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,OAAgB,WAAW,SAAU;IAErC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,EAAE;CAgB9F;AAED,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,OAAgB,WAAW,SAAW;IAEtC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,EAAE;CA+B9F;AAED,qBAAa,aAAc,SAAQ,UAAU;IAC3C,OAAgB,WAAW,SAAQ;IAEnC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,EAAE;CA2C9F;AAED,qBAAa,mBAAoB,SAAQ,UAAU;IACjD,OAAgB,WAAW,SAAe;IAE1C,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,EAAE;CA2C9F"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { Chord, parseNote, noteName, addInterval, MIDDLE_C_PITCH, OCTAVE_SIZE } from "./music.js";
|
|
2
|
+
import { SongNote } from "./song.js";
|
|
3
|
+
export class AutoChords {
|
|
4
|
+
static defaultChords(song, options) {
|
|
5
|
+
return new BossaNovaAutoChords(song, options);
|
|
6
|
+
}
|
|
7
|
+
// attempt to parse chord from macro name
|
|
8
|
+
static coerceChord(macro) {
|
|
9
|
+
const m = macro.match(/([a-gA-G][#b]?)(.*)/);
|
|
10
|
+
if (!m) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
let [, root, shape] = m;
|
|
14
|
+
root = root.substr(0, 1).toUpperCase() + root.substr(1);
|
|
15
|
+
if (shape == "") {
|
|
16
|
+
shape = "M";
|
|
17
|
+
}
|
|
18
|
+
if (!Chord.SHAPES[shape]) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
return [root, shape];
|
|
22
|
+
}
|
|
23
|
+
constructor(song, options = {}) {
|
|
24
|
+
this.song = song;
|
|
25
|
+
this.options = options;
|
|
26
|
+
}
|
|
27
|
+
findChordBlocks() {
|
|
28
|
+
const beatsPerMeasure = this.song.metadata?.beatsPerMeasure;
|
|
29
|
+
if (!beatsPerMeasure) {
|
|
30
|
+
throw new Error("Missing beats per measure for autochords");
|
|
31
|
+
}
|
|
32
|
+
if (!this.song.autoChords) {
|
|
33
|
+
throw new Error("Song missing autochords");
|
|
34
|
+
}
|
|
35
|
+
const chords = [...this.song.autoChords];
|
|
36
|
+
chords.reverse();
|
|
37
|
+
const chordBlocks = [];
|
|
38
|
+
let chordsUntil = null;
|
|
39
|
+
for (const [position, chord] of chords) {
|
|
40
|
+
const start = position;
|
|
41
|
+
let stop = (Math.floor((position / beatsPerMeasure)) + 1) * beatsPerMeasure;
|
|
42
|
+
if (chordsUntil !== null) {
|
|
43
|
+
stop = Math.min(stop, chordsUntil);
|
|
44
|
+
}
|
|
45
|
+
if (start >= stop) {
|
|
46
|
+
console.warn("rejecting chord", chord, start, stop);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
chordBlocks.push({
|
|
50
|
+
start, stop, chord
|
|
51
|
+
});
|
|
52
|
+
chordsUntil = start;
|
|
53
|
+
}
|
|
54
|
+
chordBlocks.reverse();
|
|
55
|
+
return chordBlocks;
|
|
56
|
+
}
|
|
57
|
+
addChords() {
|
|
58
|
+
const blocks = this.findChordBlocks();
|
|
59
|
+
const notesToAdd = []; // the final set of notes added
|
|
60
|
+
for (const block of blocks) {
|
|
61
|
+
const [root, shape] = block.chord;
|
|
62
|
+
const toAdd = this.notesForChord(root, shape, block.start, block.stop);
|
|
63
|
+
if (toAdd) {
|
|
64
|
+
notesToAdd.push(...toAdd);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const trackId = this.song.findEmptyTrackIdx();
|
|
68
|
+
// just mutate the song for now
|
|
69
|
+
for (const note of notesToAdd) {
|
|
70
|
+
this.song.pushWithTrack(note, trackId);
|
|
71
|
+
}
|
|
72
|
+
const track = this.song.getTrack(trackId);
|
|
73
|
+
track.trackName = "Autochords";
|
|
74
|
+
}
|
|
75
|
+
minPitchInRange(start, stop) {
|
|
76
|
+
const notes = this.song.notesInRange(start, stop);
|
|
77
|
+
const pitches = [
|
|
78
|
+
MIDDLE_C_PITCH + 5,
|
|
79
|
+
...notes.map(n => parseNote(n.note))
|
|
80
|
+
];
|
|
81
|
+
let minPitch = Math.min(...pitches);
|
|
82
|
+
if (this.options.chordMinSpacing) {
|
|
83
|
+
minPitch -= this.options.chordMinSpacing;
|
|
84
|
+
}
|
|
85
|
+
return minPitch;
|
|
86
|
+
}
|
|
87
|
+
// find the closest root beneath the notes in range
|
|
88
|
+
rootBelow(name, maxPitch) {
|
|
89
|
+
const rootPitch = parseNote(name + "0");
|
|
90
|
+
const chordRootPitch = Math.floor(((maxPitch - 1) - rootPitch) / 12) * 12 + rootPitch;
|
|
91
|
+
return noteName(chordRootPitch);
|
|
92
|
+
}
|
|
93
|
+
notesForChord(_root, _shape, _blockStart, _blockStop) {
|
|
94
|
+
console.warn("Autochords doesn't generate any notes");
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
inDivisions(start, stop, count, fn) {
|
|
98
|
+
const bpm = this.song.metadata?.beatsPerMeasure || 4;
|
|
99
|
+
const chunkSize = bpm / Math.pow(2, count - 1);
|
|
100
|
+
let left = start;
|
|
101
|
+
let k = 0;
|
|
102
|
+
while (true) {
|
|
103
|
+
const right = Math.min(stop, left + chunkSize);
|
|
104
|
+
fn(left, right, k);
|
|
105
|
+
left += chunkSize;
|
|
106
|
+
k += 1;
|
|
107
|
+
if (right >= stop) {
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
AutoChords.allGenerators = [];
|
|
114
|
+
AutoChords.displayName = "Auto Chords";
|
|
115
|
+
export class RootAutoChords extends AutoChords {
|
|
116
|
+
notesForChord(root, _shape, blockStart, blockStop) {
|
|
117
|
+
const maxPitch = this.minPitchInRange(blockStart, blockStop);
|
|
118
|
+
const rate = this.options.rate || 1;
|
|
119
|
+
const out = [];
|
|
120
|
+
this.inDivisions(blockStart, blockStop, rate, (start, stop) => {
|
|
121
|
+
out.push(new SongNote(this.rootBelow(root, maxPitch), start, stop - start));
|
|
122
|
+
});
|
|
123
|
+
return out;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
RootAutoChords.displayName = "Root";
|
|
127
|
+
export class TriadAutoChords extends AutoChords {
|
|
128
|
+
notesForChord(root, shape, blockStart, blockStop) {
|
|
129
|
+
const maxPitch = this.minPitchInRange(blockStart, blockStop);
|
|
130
|
+
const chordRoot = this.rootBelow(root, maxPitch);
|
|
131
|
+
const rate = this.options.rate || 1;
|
|
132
|
+
const out = [];
|
|
133
|
+
this.inDivisions(blockStart, blockStop, rate, (start, stop) => {
|
|
134
|
+
Chord.notes(chordRoot, shape).map((note) => out.push(new SongNote(note, start, stop - start)));
|
|
135
|
+
});
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
TriadAutoChords.displayName = "Triad";
|
|
140
|
+
export class Root5AutoChords extends AutoChords {
|
|
141
|
+
notesForChord(root, shape, blockStart, blockStop) {
|
|
142
|
+
const maxPitch = this.minPitchInRange(blockStart, blockStop);
|
|
143
|
+
let chordRoot = this.rootBelow(root, maxPitch);
|
|
144
|
+
let chordNotes = Chord.notes(chordRoot, shape);
|
|
145
|
+
if (parseNote(chordNotes[2]) > maxPitch) {
|
|
146
|
+
chordRoot = addInterval(chordRoot, -OCTAVE_SIZE);
|
|
147
|
+
chordNotes = Chord.notes(chordRoot, shape);
|
|
148
|
+
}
|
|
149
|
+
const rate = this.options.rate || 1;
|
|
150
|
+
const bpm = this.song.metadata?.beatsPerMeasure || 2;
|
|
151
|
+
const out = [];
|
|
152
|
+
this.inDivisions(blockStart, blockStop, 1 + rate, (start, stop, k) => {
|
|
153
|
+
if (k % bpm == 0) {
|
|
154
|
+
// root on beat
|
|
155
|
+
out.push(new SongNote(chordNotes[0], start, stop - start));
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// 5 on everything else
|
|
159
|
+
out.push(new SongNote(chordNotes[2], start, stop - start));
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
return out;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
Root5AutoChords.displayName = "Root+5";
|
|
166
|
+
export class ArpAutoChords extends AutoChords {
|
|
167
|
+
notesForChord(root, shape, blockStart, blockStop) {
|
|
168
|
+
const maxPitch = this.minPitchInRange(blockStart, blockStop);
|
|
169
|
+
const chordRoot = this.rootBelow(root, maxPitch);
|
|
170
|
+
const chordNotes = Chord.notes(chordRoot, shape);
|
|
171
|
+
const out = [];
|
|
172
|
+
this.inDivisions(blockStart, blockStop, 3, (start, stop, k) => {
|
|
173
|
+
switch (k) {
|
|
174
|
+
case 0:
|
|
175
|
+
out.push(new SongNote(chordNotes[0], start, stop - start));
|
|
176
|
+
break;
|
|
177
|
+
case 1:
|
|
178
|
+
out.push(new SongNote(chordNotes[1], start, stop - start));
|
|
179
|
+
break;
|
|
180
|
+
case 2:
|
|
181
|
+
out.push(new SongNote(chordNotes[3] || chordNotes[2], start, stop - start));
|
|
182
|
+
break;
|
|
183
|
+
case 3:
|
|
184
|
+
out.push(new SongNote(chordNotes[1], start, stop - start));
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
for (const note of out) {
|
|
189
|
+
while (parseNote(note.note) >= maxPitch) {
|
|
190
|
+
// shift everything down by octave
|
|
191
|
+
for (const n of out) {
|
|
192
|
+
n.note = noteName(parseNote(n.note) - 12);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return out;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
ArpAutoChords.displayName = "Arp";
|
|
200
|
+
export class BossaNovaAutoChords extends AutoChords {
|
|
201
|
+
notesForChord(root, shape, blockStart, blockStop) {
|
|
202
|
+
const maxPitch = this.minPitchInRange(blockStart, blockStop);
|
|
203
|
+
const chordRoot = this.rootBelow(root, maxPitch);
|
|
204
|
+
const chordNotes = Chord.notes(chordRoot, shape);
|
|
205
|
+
const out = [];
|
|
206
|
+
this.inDivisions(blockStart, blockStop, 3, (start, stop, k) => {
|
|
207
|
+
const d = (stop - start) / 2;
|
|
208
|
+
let one = chordNotes[0];
|
|
209
|
+
let two = chordNotes[2];
|
|
210
|
+
if (parseNote(two) >= maxPitch) {
|
|
211
|
+
one = noteName(parseNote(chordNotes[2]) - 12);
|
|
212
|
+
two = chordNotes[0];
|
|
213
|
+
}
|
|
214
|
+
switch (k) {
|
|
215
|
+
case 0:
|
|
216
|
+
out.push(new SongNote(one, start, d * 3));
|
|
217
|
+
break;
|
|
218
|
+
case 1:
|
|
219
|
+
out.push(new SongNote(one, start + d, d));
|
|
220
|
+
break;
|
|
221
|
+
case 2:
|
|
222
|
+
out.push(new SongNote(two, start, d * 3));
|
|
223
|
+
break;
|
|
224
|
+
case 3:
|
|
225
|
+
out.push(new SongNote(two, start + d, d));
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
return out;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
BossaNovaAutoChords.displayName = "Bossa Nova";
|
|
233
|
+
AutoChords.allGenerators = [
|
|
234
|
+
RootAutoChords,
|
|
235
|
+
TriadAutoChords,
|
|
236
|
+
Root5AutoChords,
|
|
237
|
+
ArpAutoChords,
|
|
238
|
+
BossaNovaAutoChords,
|
|
239
|
+
];
|
|
240
|
+
//# sourceMappingURL=auto-chords.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-chords.js","sourceRoot":"","sources":["../src/auto-chords.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare const peg$allowedStartRules: string[];
|
|
2
|
+
declare class peg$SyntaxError extends SyntaxError {
|
|
3
|
+
static buildMessage(expected: any, found: any): string;
|
|
4
|
+
constructor(message: any, expected: any, found: any, location: any);
|
|
5
|
+
expected: any;
|
|
6
|
+
found: any;
|
|
7
|
+
location: any;
|
|
8
|
+
format(sources: any): string;
|
|
9
|
+
}
|
|
10
|
+
declare function peg$parse(input: any, options: any): any;
|
|
11
|
+
export { peg$allowedStartRules as StartRules, peg$SyntaxError as SyntaxError, peg$parse as parse };
|
|
12
|
+
//# sourceMappingURL=grammar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grammar.d.ts","sourceRoot":"","sources":["../src/grammar.js"],"names":[],"mappings":"AAg2CA,8CAEE;AA71CF;IAwCE,uDA2GC;IAlJD,oEAMC;IAJC,cAAwB;IACxB,WAAkB;IAClB,cAAwB;IAI1B,6BA6BC;CA8GF;AAED,0DAmsCC"}
|