@vibuca/synth8-core 0.1.1 → 0.2.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/dist/index.js +58 -49
- package/dist/model/ast.d.ts +5 -1
- package/dist/parser/melody-pattern-parser.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -37,42 +37,46 @@ var e = (e) => {
|
|
|
37
37
|
return a;
|
|
38
38
|
};
|
|
39
39
|
return r();
|
|
40
|
-
}, n = /^[a-gA-G](#|b)?[0-8]$/, r = (e) => e === "_" || n.test(e)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
}, n = /^[a-gA-G](#|b)?[0-8]$/, r = (e) => e === "_" || n.test(e), i = (e) => {
|
|
41
|
+
let t = e.split("+").filter(Boolean);
|
|
42
|
+
return t.length === 1 ? {
|
|
43
|
+
kind: "MelodyNote",
|
|
44
|
+
value: t[0]
|
|
45
|
+
} : {
|
|
46
|
+
kind: "MelodyParallel",
|
|
47
|
+
notes: t.map((e) => ({
|
|
48
|
+
kind: "MelodyNote",
|
|
49
|
+
value: e
|
|
50
|
+
}))
|
|
51
|
+
};
|
|
52
|
+
}, a = (e) => {
|
|
53
|
+
let t = e.split("+").filter(Boolean);
|
|
54
|
+
if (t.length === 0) throw Error("Expected note.");
|
|
55
|
+
for (let e of t) if (!r(e)) throw Error(`Unknown note: ${e}`);
|
|
56
|
+
}, o = (e) => {
|
|
57
|
+
let t = [...e], n = 0, r = () => {
|
|
46
58
|
for (; t[n] === " ";) n++;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
let o = [];
|
|
59
|
+
}, o = (e) => {
|
|
60
|
+
let s = [];
|
|
50
61
|
for (; n < t.length;) {
|
|
51
|
-
if (
|
|
62
|
+
if (r(), e && t[n] === e) return n++, s;
|
|
52
63
|
if (t[n] === "[") {
|
|
53
|
-
n++,
|
|
64
|
+
n++, s.push({
|
|
54
65
|
kind: "MelodyGroup",
|
|
55
|
-
notes:
|
|
66
|
+
notes: o("]")
|
|
56
67
|
});
|
|
57
68
|
continue;
|
|
58
69
|
}
|
|
59
|
-
let
|
|
60
|
-
for (; n < t.length && t[n] !== " " && t[n] !== "[" && t[n] !== "]";)
|
|
61
|
-
if (!
|
|
62
|
-
|
|
63
|
-
o.push({
|
|
64
|
-
kind: "MelodyNote",
|
|
65
|
-
value: s
|
|
66
|
-
});
|
|
70
|
+
let c = "";
|
|
71
|
+
for (; n < t.length && t[n] !== " " && t[n] !== "[" && t[n] !== "]";) c += t[n++];
|
|
72
|
+
if (!c) break;
|
|
73
|
+
a(c), s.push(i(c));
|
|
67
74
|
}
|
|
68
75
|
if (e) throw Error("Unclosed melody group");
|
|
69
|
-
return
|
|
70
|
-
}
|
|
71
|
-
return
|
|
72
|
-
}
|
|
73
|
-
//#endregion
|
|
74
|
-
//#region src/parser/tokenizer.ts
|
|
75
|
-
var a = (e) => {
|
|
76
|
+
return s;
|
|
77
|
+
};
|
|
78
|
+
return o();
|
|
79
|
+
}, s = (e) => {
|
|
76
80
|
let t = [], n = 0;
|
|
77
81
|
for (; n < e.length;) {
|
|
78
82
|
let r = e[n];
|
|
@@ -119,7 +123,7 @@ var a = (e) => {
|
|
|
119
123
|
throw Error(`Unexpected character: ${r}`);
|
|
120
124
|
}
|
|
121
125
|
return t;
|
|
122
|
-
},
|
|
126
|
+
}, c = class {
|
|
123
127
|
tokens;
|
|
124
128
|
index = 0;
|
|
125
129
|
constructor(e) {
|
|
@@ -161,7 +165,7 @@ var a = (e) => {
|
|
|
161
165
|
let t = this.parseOptionalRate();
|
|
162
166
|
return {
|
|
163
167
|
kind: "MelodyExpression",
|
|
164
|
-
notes:
|
|
168
|
+
notes: o(e),
|
|
165
169
|
rate: t
|
|
166
170
|
};
|
|
167
171
|
}
|
|
@@ -211,7 +215,7 @@ var a = (e) => {
|
|
|
211
215
|
isAtEnd() {
|
|
212
216
|
return this.index >= this.tokens.length;
|
|
213
217
|
}
|
|
214
|
-
},
|
|
218
|
+
}, l = (e) => new c(s(e)).parse(), u = "_", d = new Set([
|
|
215
219
|
"kick",
|
|
216
220
|
"snare",
|
|
217
221
|
"clap",
|
|
@@ -220,29 +224,29 @@ var a = (e) => {
|
|
|
220
224
|
"tom",
|
|
221
225
|
"rim",
|
|
222
226
|
"cowbell"
|
|
223
|
-
]),
|
|
224
|
-
if (e !==
|
|
225
|
-
},
|
|
227
|
+
]), f = (e) => {
|
|
228
|
+
if (e !== u && !d.has(e)) throw Error(`Unknown drum sound: ${e}`);
|
|
229
|
+
}, p = (e) => {
|
|
226
230
|
if (e.kind === "BeatGroup") {
|
|
227
|
-
for (let t of e.steps)
|
|
231
|
+
for (let t of e.steps) p(t);
|
|
228
232
|
return;
|
|
229
233
|
}
|
|
230
234
|
if (e.kind === "BeatParallel") {
|
|
231
|
-
for (let t of e.sounds)
|
|
235
|
+
for (let t of e.sounds) f(t.value);
|
|
232
236
|
return;
|
|
233
237
|
}
|
|
234
|
-
|
|
235
|
-
},
|
|
238
|
+
f(e.value);
|
|
239
|
+
}, m = (e, t, n) => {
|
|
236
240
|
if (e.length === 0) return [];
|
|
237
241
|
let r = [], i = n / e.length;
|
|
238
242
|
return e.forEach((e, n) => {
|
|
239
243
|
let a = t + n * i;
|
|
240
244
|
switch (e.kind) {
|
|
241
245
|
case "BeatGroup":
|
|
242
|
-
r.push(...
|
|
246
|
+
r.push(...m(e.steps, a, i));
|
|
243
247
|
break;
|
|
244
248
|
case "BeatParallel":
|
|
245
|
-
for (let t of e.sounds) t.value !==
|
|
249
|
+
for (let t of e.sounds) t.value !== u && r.push({
|
|
246
250
|
time: a,
|
|
247
251
|
dur: i,
|
|
248
252
|
type: "drum",
|
|
@@ -250,7 +254,7 @@ var a = (e) => {
|
|
|
250
254
|
});
|
|
251
255
|
break;
|
|
252
256
|
case "BeatSound":
|
|
253
|
-
if (e.value ===
|
|
257
|
+
if (e.value === u) break;
|
|
254
258
|
r.push({
|
|
255
259
|
time: a,
|
|
256
260
|
dur: i,
|
|
@@ -260,25 +264,25 @@ var a = (e) => {
|
|
|
260
264
|
break;
|
|
261
265
|
}
|
|
262
266
|
}), r;
|
|
263
|
-
},
|
|
267
|
+
}, h = (e) => {
|
|
264
268
|
switch (e.kind) {
|
|
265
269
|
case "BeatExpression": {
|
|
266
|
-
for (let t of e.steps)
|
|
270
|
+
for (let t of e.steps) p(t);
|
|
267
271
|
let t = 1 / e.rate, n = e.steps.length * t;
|
|
268
272
|
return {
|
|
269
273
|
length: n,
|
|
270
|
-
events:
|
|
274
|
+
events: m(e.steps, 0, n)
|
|
271
275
|
};
|
|
272
276
|
}
|
|
273
277
|
case "MelodyExpression": {
|
|
274
278
|
let t = 1 / e.rate, n = e.notes.length * t;
|
|
275
279
|
return {
|
|
276
280
|
length: n,
|
|
277
|
-
events:
|
|
281
|
+
events: g(e.notes, 0, n)
|
|
278
282
|
};
|
|
279
283
|
}
|
|
280
284
|
case "SongExpression": {
|
|
281
|
-
let t = e.tracks.map(
|
|
285
|
+
let t = e.tracks.map(h);
|
|
282
286
|
return {
|
|
283
287
|
length: Math.max(...t.map((e) => e.length)),
|
|
284
288
|
events: t.flatMap((e) => e.events)
|
|
@@ -286,7 +290,7 @@ var a = (e) => {
|
|
|
286
290
|
}
|
|
287
291
|
default: throw Error("Unknown AST node");
|
|
288
292
|
}
|
|
289
|
-
},
|
|
293
|
+
}, g = (e, t, n) => {
|
|
290
294
|
let r = n / e.length;
|
|
291
295
|
return e.flatMap((e, n) => {
|
|
292
296
|
let i = t + n * r;
|
|
@@ -295,8 +299,13 @@ var a = (e) => {
|
|
|
295
299
|
dur: r,
|
|
296
300
|
type: "note",
|
|
297
301
|
value: e.value
|
|
298
|
-
}] :
|
|
302
|
+
}] : e.kind === "MelodyParallel" ? e.notes.filter((e) => e.value !== "_").map((e) => ({
|
|
303
|
+
time: i,
|
|
304
|
+
dur: r,
|
|
305
|
+
type: "note",
|
|
306
|
+
value: e.value
|
|
307
|
+
})) : g(e.notes, i, r);
|
|
299
308
|
});
|
|
300
|
-
},
|
|
309
|
+
}, _ = (e) => h(l(e)), v = "0.1.0";
|
|
301
310
|
//#endregion
|
|
302
|
-
export {
|
|
311
|
+
export { v as VERSION, _ as compile, l as parse, s as tokenize };
|
package/dist/model/ast.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type MelodyExpression = {
|
|
|
13
13
|
notes: MelodyStep[];
|
|
14
14
|
rate: number;
|
|
15
15
|
};
|
|
16
|
-
export type MelodyStep = MelodyNote | MelodyGroup;
|
|
16
|
+
export type MelodyStep = MelodyNote | MelodyGroup | MelodyParallel;
|
|
17
17
|
export type MelodyNote = {
|
|
18
18
|
kind: "MelodyNote";
|
|
19
19
|
value: string;
|
|
@@ -22,6 +22,10 @@ export type MelodyGroup = {
|
|
|
22
22
|
kind: "MelodyGroup";
|
|
23
23
|
notes: MelodyStep[];
|
|
24
24
|
};
|
|
25
|
+
export type MelodyParallel = {
|
|
26
|
+
kind: "MelodyParallel";
|
|
27
|
+
notes: MelodyNote[];
|
|
28
|
+
};
|
|
25
29
|
export type BeatStep = BeatSound | BeatGroup | BeatParallel;
|
|
26
30
|
export type BeatSound = {
|
|
27
31
|
kind: "BeatSound";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { MelodyStep } from '../model/ast';
|
|
2
|
-
export declare
|
|
2
|
+
export declare const parseMelodyPattern: (source: string) => MelodyStep[];
|