@blibliki/engine 0.1.11 → 0.1.13
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/build/Engine.d.ts +5 -0
- package/build/Engine.js +30 -2
- package/build/Engine.js.map +1 -1
- package/build/MidiEvent.d.ts +2 -0
- package/build/MidiEvent.js +8 -0
- package/build/MidiEvent.js.map +1 -1
- package/build/Module/Base.d.ts +0 -2
- package/build/Module/Base.js +9 -7
- package/build/Module/Base.js.map +1 -1
- package/build/Module/DataSequencer.d.ts +24 -0
- package/build/Module/DataSequencer.js +64 -0
- package/build/Module/DataSequencer.js.map +1 -0
- package/build/Module/Envelope/Base.d.ts +0 -1
- package/build/Module/Envelope/Base.js +1 -10
- package/build/Module/Envelope/Base.js.map +1 -1
- package/build/Module/Oscillator.d.ts +5 -2
- package/build/Module/Oscillator.js +26 -11
- package/build/Module/Oscillator.js.map +1 -1
- package/build/Module/PolyModule.d.ts +1 -1
- package/build/Module/PolyModule.js +1 -1
- package/build/Module/PolyModule.js.map +1 -1
- package/build/Module/Sequencer.d.ts +5 -2
- package/build/Module/Sequencer.js +31 -21
- package/build/Module/Sequencer.js.map +1 -1
- package/build/Module/Volume.d.ts +4 -0
- package/build/Module/Volume.js +15 -1
- package/build/Module/Volume.js.map +1 -1
- package/build/Module/index.d.ts +2 -0
- package/build/Module/index.js +4 -0
- package/build/Module/index.js.map +1 -1
- package/build/Note/index.d.ts +5 -2
- package/build/Note/index.js +12 -2
- package/build/Note/index.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/Engine.ts +36 -2
- package/src/MidiEvent.ts +14 -0
- package/src/Module/Base.ts +19 -10
- package/src/Module/DataSequencer.ts +92 -0
- package/src/Module/Envelope/Base.ts +1 -10
- package/src/Module/Oscillator.ts +28 -12
- package/src/Module/PolyModule.ts +1 -1
- package/src/Module/Sequencer.ts +35 -21
- package/src/Module/Volume.ts +19 -1
- package/src/Module/index.ts +5 -0
- package/src/Note/index.ts +17 -5
- package/src/index.ts +6 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Part, Time } from "tone";
|
|
1
|
+
import { now, Part, Time } from "tone";
|
|
2
2
|
import Module, { DummnyInternalModule } from "./Base";
|
|
3
3
|
import MidiEvent from "../MidiEvent";
|
|
4
4
|
const InitialProps = () => ({
|
|
@@ -17,25 +17,29 @@ export default class Sequencer extends Module {
|
|
|
17
17
|
props: { ...InitialProps(), ...props },
|
|
18
18
|
});
|
|
19
19
|
this.initializePart();
|
|
20
|
-
this.start();
|
|
20
|
+
this.start(now());
|
|
21
21
|
this.registerOutputs();
|
|
22
22
|
}
|
|
23
|
+
get props() {
|
|
24
|
+
return super.props;
|
|
25
|
+
}
|
|
26
|
+
set props(value) {
|
|
27
|
+
if (!this.sequences)
|
|
28
|
+
this._props["sequences"] = [];
|
|
29
|
+
super.props = { ...this.props, ...value };
|
|
30
|
+
this.adjust();
|
|
31
|
+
}
|
|
23
32
|
get steps() {
|
|
24
33
|
return this._props["steps"];
|
|
25
34
|
}
|
|
26
35
|
set steps(value) {
|
|
27
36
|
this._props = { ...this.props, steps: value };
|
|
28
|
-
this.adjustNumberOfSequences();
|
|
29
|
-
this.updateBarParts();
|
|
30
37
|
}
|
|
31
38
|
get bars() {
|
|
32
39
|
return this.props["bars"];
|
|
33
40
|
}
|
|
34
41
|
set bars(value) {
|
|
35
42
|
this._props = { ...this.props, bars: value };
|
|
36
|
-
this.adjustNumberOfBars();
|
|
37
|
-
this.adjustNumberOfSequences();
|
|
38
|
-
this.updateBarParts();
|
|
39
43
|
}
|
|
40
44
|
get sequences() {
|
|
41
45
|
return this._props["sequences"];
|
|
@@ -43,10 +47,12 @@ export default class Sequencer extends Module {
|
|
|
43
47
|
set sequences(value) {
|
|
44
48
|
const sequences = value;
|
|
45
49
|
this._props = { ...this.props, sequences };
|
|
46
|
-
this.updateBarParts();
|
|
47
50
|
}
|
|
48
|
-
start() {
|
|
49
|
-
this.part.
|
|
51
|
+
start(time) {
|
|
52
|
+
const state = this.part.context.transport.state;
|
|
53
|
+
if (state !== "started")
|
|
54
|
+
return;
|
|
55
|
+
this.part.start(time);
|
|
50
56
|
}
|
|
51
57
|
stop() {
|
|
52
58
|
this.part.stop();
|
|
@@ -62,6 +68,13 @@ export default class Sequencer extends Module {
|
|
|
62
68
|
this.part.add(`${i}:0:0`, i);
|
|
63
69
|
});
|
|
64
70
|
}
|
|
71
|
+
adjust() {
|
|
72
|
+
if (!this.part)
|
|
73
|
+
return;
|
|
74
|
+
this.adjustNumberOfBars();
|
|
75
|
+
this.adjustNumberOfSteps();
|
|
76
|
+
this.updateBarParts();
|
|
77
|
+
}
|
|
65
78
|
adjustNumberOfBars() {
|
|
66
79
|
const currentBar = this.sequences.length;
|
|
67
80
|
const num = currentBar - this.bars;
|
|
@@ -69,23 +82,15 @@ export default class Sequencer extends Module {
|
|
|
69
82
|
if (num === 0)
|
|
70
83
|
return;
|
|
71
84
|
if (num > 0) {
|
|
72
|
-
if (this.part) {
|
|
73
|
-
this.part.remove(`${currentBar}:0:0`);
|
|
74
|
-
this.part.loopEnd = this.loopEnd;
|
|
75
|
-
}
|
|
76
85
|
sequences.pop();
|
|
77
86
|
}
|
|
78
87
|
else {
|
|
79
|
-
if (this.part) {
|
|
80
|
-
this.part.add(`${currentBar}:0:0`, currentBar);
|
|
81
|
-
this.part.loopEnd = this.loopEnd;
|
|
82
|
-
}
|
|
83
88
|
sequences.push([]);
|
|
84
89
|
}
|
|
85
90
|
this.sequences = sequences;
|
|
86
91
|
this.adjustNumberOfBars();
|
|
87
92
|
}
|
|
88
|
-
|
|
93
|
+
adjustNumberOfSteps(bar = 0) {
|
|
89
94
|
if (!this.bars)
|
|
90
95
|
return;
|
|
91
96
|
const allSequences = [...this.sequences];
|
|
@@ -94,7 +99,7 @@ export default class Sequencer extends Module {
|
|
|
94
99
|
if (num === 0) {
|
|
95
100
|
if (bar === this.bars - 1)
|
|
96
101
|
return;
|
|
97
|
-
this.
|
|
102
|
+
this.adjustNumberOfSteps(bar + 1);
|
|
98
103
|
return;
|
|
99
104
|
}
|
|
100
105
|
if (num > 0) {
|
|
@@ -106,7 +111,7 @@ export default class Sequencer extends Module {
|
|
|
106
111
|
}
|
|
107
112
|
allSequences[bar] = sequences;
|
|
108
113
|
this.sequences = allSequences;
|
|
109
|
-
this.
|
|
114
|
+
this.adjustNumberOfSteps(bar);
|
|
110
115
|
}
|
|
111
116
|
updateBarParts() {
|
|
112
117
|
this.barParts = this.sequences.map((barSeqs, _) => {
|
|
@@ -114,6 +119,11 @@ export default class Sequencer extends Module {
|
|
|
114
119
|
barSeqs.forEach((seq) => part.add(seq.time, seq));
|
|
115
120
|
return part;
|
|
116
121
|
});
|
|
122
|
+
this.part.clear();
|
|
123
|
+
this.barParts.forEach((_, bar) => {
|
|
124
|
+
this.part.add(`${bar}:0:0`, bar);
|
|
125
|
+
});
|
|
126
|
+
this.part.loopEnd = this.loopEnd;
|
|
117
127
|
}
|
|
118
128
|
get loopEnd() {
|
|
119
129
|
return `${this.bars}:0:0`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sequencer.js","sourceRoot":"","sources":["../../src/Module/Sequencer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"Sequencer.js","sourceRoot":"","sources":["../../src/Module/Sequencer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,MAAM,EAAE,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAGtD,OAAO,SAAS,MAAM,cAAc,CAAC;AAarC,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,CAAC;IAC1B,SAAS,EAAE,EAAE;IACb,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,CAAC;CACR,CAAC,CAAC;AAEH,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,MAGtC;IACC,MAAM,CAAC,UAAU,GAAG,WAAW,CAAC;IAChC,UAAU,CAAS;IACX,IAAI,CAAe;IACnB,QAAQ,GAAsB,EAAE,CAAC;IAEzC,YAAY,IAAY,EAAE,KAA0B;QAClD,KAAK,CAAC,IAAI,oBAAoB,EAAE,EAAE;YAChC,IAAI;YACJ,KAAK,EAAE,EAAE,GAAG,YAAY,EAAE,EAAE,GAAG,KAAK,EAAE;SACvC,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAClB,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED,IAAI,KAAK;QACP,OAAO,KAAK,CAAC,KAAK,CAAC;IACrB,CAAC;IAED,IAAI,KAAK,CAAC,KAAiB;QACzB,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;QAEnD,KAAK,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC;QAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,KAAK,CAAC,KAAa;QACrB,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAChD,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,IAAI,IAAI,CAAC,KAAa;QACpB,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAC/C,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,SAAS,CAAC,KAAoB;QAChC,MAAM,SAAS,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,IAAY;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC;QAChD,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO;QAEhC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACnB,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAC9D,CAAC;IAEO,cAAc;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAc,CAAC,CAAC;QACvD,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAEjC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC9B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,MAAM;QACZ,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO;QAEvB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAEO,kBAAkB;QACxB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;QACzC,MAAM,GAAG,GAAG,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC;QACnC,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAEtC,IAAI,GAAG,KAAK,CAAC;YAAE,OAAO;QAEtB,IAAI,GAAG,GAAG,CAAC,EAAE;YACX,SAAS,CAAC,GAAG,EAAE,CAAC;SACjB;aAAM;YACL,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SACpB;QAED,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAEO,mBAAmB,CAAC,GAAG,GAAG,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO;QAEvB,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,SAAS,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC;QAE1C,IAAI,GAAG,KAAK,CAAC,EAAE;YACb,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC;gBAAE,OAAO;YAElC,IAAI,CAAC,mBAAmB,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;YAClC,OAAO;SACR;QAED,IAAI,GAAG,GAAG,CAAC,EAAE;YACX,SAAS,CAAC,GAAG,EAAE,CAAC;SACjB;aAAM;YACL,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC;YAC/B,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;SACpE;QACD,YAAY,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG,YAAY,CAAC;QAE9B,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAEO,cAAc;QACpB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE;YAChD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAsB,CAAC,CAAC;YACpE,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;YAElD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;YAC/B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IACnC,CAAC;IAED,IAAY,OAAO;QACjB,OAAO,GAAG,IAAI,CAAC,IAAI,MAAM,CAAC;IAC5B,CAAC;IAEO,WAAW,GAAG,CAAC,IAAY,EAAE,GAAkB,EAAE,EAAE;QACzD,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO;QAEzB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC;IAEM,eAAe,GAAG,CAAC,IAAY,EAAE,QAAmB,EAAE,EAAE;QAC9D,IAAI,CAAC,QAAQ,CAAC,MAAM;YAAE,OAAO;QAE7B,MAAM,KAAK,GAAG,SAAS,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAErD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC5C,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC"}
|
package/build/Module/Volume.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Volume as Vol } from "tone";
|
|
2
2
|
import Module, { Voicable } from "./Base";
|
|
3
3
|
import PolyModule from "./PolyModule";
|
|
4
|
+
import Note from "../Note";
|
|
4
5
|
export interface VolumeInterface extends Voicable {
|
|
5
6
|
volume: number;
|
|
6
7
|
}
|
|
@@ -8,9 +9,12 @@ declare class MonoVolume extends Module<Vol, VolumeInterface> {
|
|
|
8
9
|
constructor(name: string, props: Partial<VolumeInterface>);
|
|
9
10
|
get volume(): number;
|
|
10
11
|
set volume(value: number);
|
|
12
|
+
triggerAttack: (note: Note, triggeredAt: number) => void;
|
|
13
|
+
triggerRelease: (note: Note, triggeredAt: number) => void;
|
|
11
14
|
}
|
|
12
15
|
export default class Volume extends PolyModule<MonoVolume, VolumeInterface> {
|
|
13
16
|
static moduleName: string;
|
|
14
17
|
constructor(name: string, props: Partial<VolumeInterface>);
|
|
18
|
+
private registerInputs;
|
|
15
19
|
}
|
|
16
20
|
export {};
|
package/build/Module/Volume.js
CHANGED
|
@@ -2,7 +2,7 @@ import { Volume as Vol } from "tone";
|
|
|
2
2
|
import Module from "./Base";
|
|
3
3
|
import PolyModule from "./PolyModule";
|
|
4
4
|
const InitialProps = {
|
|
5
|
-
volume: -
|
|
5
|
+
volume: -Infinity,
|
|
6
6
|
};
|
|
7
7
|
class MonoVolume extends Module {
|
|
8
8
|
constructor(name, props) {
|
|
@@ -18,6 +18,13 @@ class MonoVolume extends Module {
|
|
|
18
18
|
this._props = { ...this.props, volume: value };
|
|
19
19
|
this.internalModule.volume.value = this.volume;
|
|
20
20
|
}
|
|
21
|
+
triggerAttack = (note, triggeredAt) => {
|
|
22
|
+
const db = 20 * Math.log10(note.velocity);
|
|
23
|
+
this.internalModule.volume.exponentialRampToValueAtTime(db, triggeredAt);
|
|
24
|
+
};
|
|
25
|
+
triggerRelease = (note, triggeredAt) => {
|
|
26
|
+
// Do nothing
|
|
27
|
+
};
|
|
21
28
|
}
|
|
22
29
|
export default class Volume extends PolyModule {
|
|
23
30
|
static moduleName = "Volume";
|
|
@@ -29,6 +36,13 @@ export default class Volume extends PolyModule {
|
|
|
29
36
|
});
|
|
30
37
|
this.registerBasicInputs();
|
|
31
38
|
this.registerBasicOutputs();
|
|
39
|
+
this.registerInputs();
|
|
40
|
+
}
|
|
41
|
+
registerInputs() {
|
|
42
|
+
this.registerInput({
|
|
43
|
+
name: "midi in",
|
|
44
|
+
pluggable: this.midiTriggered,
|
|
45
|
+
});
|
|
32
46
|
}
|
|
33
47
|
}
|
|
34
48
|
//# sourceMappingURL=Volume.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Volume.js","sourceRoot":"","sources":["../../src/Module/Volume.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,GAAG,EAAE,MAAM,MAAM,CAAC;AAErC,OAAO,MAAoB,MAAM,QAAQ,CAAC;AAC1C,OAAO,UAAU,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Volume.js","sourceRoot":"","sources":["../../src/Module/Volume.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,GAAG,EAAE,MAAM,MAAM,CAAC;AAErC,OAAO,MAAoB,MAAM,QAAQ,CAAC;AAC1C,OAAO,UAAU,MAAM,cAAc,CAAC;AAOtC,MAAM,YAAY,GAAoB;IACpC,MAAM,EAAE,CAAC,QAAQ;CAClB,CAAC;AAEF,MAAM,UAAW,SAAQ,MAA4B;IACnD,YAAY,IAAY,EAAE,KAA+B;QACvD,KAAK,CAAC,IAAI,GAAG,EAAE,EAAE;YACf,IAAI;YACJ,KAAK,EAAE,EAAE,GAAG,YAAY,EAAE,GAAG,KAAK,EAAE;SACrC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,MAAM,CAAC,KAAa;QACtB,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAE/C,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;IACjD,CAAC;IAED,aAAa,GAAG,CAAC,IAAU,EAAE,WAAmB,EAAE,EAAE;QAClD,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,4BAA4B,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;IAC3E,CAAC,CAAC;IAEF,cAAc,GAAG,CAAC,IAAU,EAAE,WAAmB,EAAE,EAAE;QACnD,aAAa;IACf,CAAC,CAAC;CACH;AAED,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,UAAuC;IACzE,MAAM,CAAC,UAAU,GAAG,QAAQ,CAAC;IAE7B,YAAY,IAAY,EAAE,KAA+B;QACvD,KAAK,CAAC;YACJ,IAAI;YACJ,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE,EAAE,GAAG,YAAY,EAAE,GAAG,KAAK,EAAE;SACrC,CAAC,CAAC;QAEH,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAEO,cAAc;QACpB,IAAI,CAAC,aAAa,CAAC;YACjB,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,IAAI,CAAC,aAAa;SAC9B,CAAC,CAAC;IACL,CAAC"}
|
package/build/Module/index.d.ts
CHANGED
|
@@ -6,7 +6,9 @@ export type { ModuleInterface, Connectable, Triggerable } from "./Base";
|
|
|
6
6
|
export { default as Filter } from "./Filter";
|
|
7
7
|
export { default as Oscillator } from "./Oscillator";
|
|
8
8
|
export { default as Sequencer } from "./Sequencer";
|
|
9
|
+
export { default as DataSequencer } from "./DataSequencer";
|
|
9
10
|
export type { ISequence } from "./Sequencer";
|
|
11
|
+
export type { IDataSequence } from "./DataSequencer";
|
|
10
12
|
export { Envelope, AmpEnvelope, FreqEnvelope, EnvelopeStages, } from "./Envelope";
|
|
11
13
|
export declare type AudioModule = Module<Connectable, any> | PolyModule<Module<Connectable, any>, any>;
|
|
12
14
|
export declare function createModule(name: string, type: string, props: any): AudioModule;
|
package/build/Module/index.js
CHANGED
|
@@ -12,11 +12,13 @@ import Delay from "./Delay";
|
|
|
12
12
|
import Distortion from "./Distortion";
|
|
13
13
|
import BitCrusher from "./BitCrusher";
|
|
14
14
|
import Sequencer from "./Sequencer";
|
|
15
|
+
import DataSequencer from "./DataSequencer";
|
|
15
16
|
export { default } from "./Base";
|
|
16
17
|
export { default as PolyModule } from "./PolyModule";
|
|
17
18
|
export { default as Filter } from "./Filter";
|
|
18
19
|
export { default as Oscillator } from "./Oscillator";
|
|
19
20
|
export { default as Sequencer } from "./Sequencer";
|
|
21
|
+
export { default as DataSequencer } from "./DataSequencer";
|
|
20
22
|
export { Envelope, AmpEnvelope, FreqEnvelope, EnvelopeStages, } from "./Envelope";
|
|
21
23
|
export function createModule(name, type, props) {
|
|
22
24
|
const klass = moduleClassFromType(type);
|
|
@@ -55,6 +57,8 @@ function moduleClassFromType(type) {
|
|
|
55
57
|
return BitCrusher;
|
|
56
58
|
case Sequencer.moduleName:
|
|
57
59
|
return Sequencer;
|
|
60
|
+
case DataSequencer.moduleName:
|
|
61
|
+
return DataSequencer;
|
|
58
62
|
default:
|
|
59
63
|
throw Error(`Unknown module type ${type}`);
|
|
60
64
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/Module/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAG/C,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,OAAO,SAAS,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/Module/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAG/C,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,OAAO,SAAS,MAAM,aAAa,CAAC;AACpC,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AAGrD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAI3D,OAAO,EACL,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC;AAMpB,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,IAAY,EACZ,KAAU;IAEV,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAExC,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY;IACvC,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAEnC,QAAQ,IAAI,EAAE;QACZ,KAAK,UAAU,CAAC,UAAU;YACxB,OAAO,UAAU,CAAC;QACpB,KAAK,QAAQ,CAAC,UAAU;YACtB,OAAO,QAAQ,CAAC;QAClB,KAAK,WAAW,CAAC,UAAU;YACzB,OAAO,WAAW,CAAC;QACrB,KAAK,YAAY,CAAC,UAAU;YAC1B,OAAO,YAAY,CAAC;QACtB,KAAK,MAAM,CAAC,UAAU;YACpB,OAAO,MAAM,CAAC;QAChB,KAAK,MAAM,CAAC,UAAU;YACpB,OAAO,MAAM,CAAC;QAChB,KAAK,MAAM,CAAC,UAAU;YACpB,OAAO,MAAM,CAAC;QAChB,KAAK,cAAc,CAAC,UAAU;YAC5B,OAAO,cAAc,CAAC;QACxB,KAAK,YAAY,CAAC,UAAU;YAC1B,OAAO,YAAY,CAAC;QACtB,KAAK,WAAW,CAAC,UAAU;YACzB,OAAO,WAAW,CAAC;QACrB,KAAK,MAAM,CAAC,UAAU;YACpB,OAAO,MAAM,CAAC;QAChB,KAAK,KAAK,CAAC,UAAU;YACnB,OAAO,KAAK,CAAC;QACf,KAAK,UAAU,CAAC,UAAU;YACxB,OAAO,UAAU,CAAC;QACpB,KAAK,UAAU,CAAC,UAAU;YACxB,OAAO,UAAU,CAAC;QACpB,KAAK,SAAS,CAAC,UAAU;YACvB,OAAO,SAAS,CAAC;QACnB,KAAK,aAAa,CAAC,UAAU;YAC3B,OAAO,aAAa,CAAC;QACvB;YACE,MAAM,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;KAC9C;AACH,CAAC"}
|
package/build/Note/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export interface INote {
|
|
2
2
|
note: string;
|
|
3
|
+
frequency: number;
|
|
3
4
|
duration: string;
|
|
4
5
|
velocity?: number;
|
|
5
6
|
}
|
|
@@ -9,13 +10,15 @@ export default class Note {
|
|
|
9
10
|
octave: number;
|
|
10
11
|
velocity: number;
|
|
11
12
|
duration: string;
|
|
12
|
-
|
|
13
|
+
frequency: number;
|
|
14
|
+
constructor(eventOrString: Partial<INote> | MIDIMessageEvent | string | number);
|
|
13
15
|
static notes(octave?: number): Note[];
|
|
14
16
|
get isSemi(): boolean;
|
|
15
17
|
get fullName(): string;
|
|
16
|
-
|
|
18
|
+
adjustFrequency(range?: number, coarse?: number): number;
|
|
17
19
|
valueOf(): string;
|
|
18
20
|
serialize(): INote;
|
|
21
|
+
private fromFrequency;
|
|
19
22
|
private fromString;
|
|
20
23
|
private fromEvent;
|
|
21
24
|
private fromProps;
|
package/build/Note/index.js
CHANGED
|
@@ -7,8 +7,12 @@ export default class Note {
|
|
|
7
7
|
octave;
|
|
8
8
|
velocity = 1;
|
|
9
9
|
duration;
|
|
10
|
+
frequency;
|
|
10
11
|
constructor(eventOrString) {
|
|
11
|
-
if (typeof eventOrString === "
|
|
12
|
+
if (typeof eventOrString === "number") {
|
|
13
|
+
this.fromFrequency(eventOrString);
|
|
14
|
+
}
|
|
15
|
+
else if (typeof eventOrString === "string") {
|
|
12
16
|
this.fromString(eventOrString);
|
|
13
17
|
}
|
|
14
18
|
else if (eventOrString instanceof MIDIMessageEvent) {
|
|
@@ -27,7 +31,9 @@ export default class Note {
|
|
|
27
31
|
get fullName() {
|
|
28
32
|
return `${this.name}${this.octave}`;
|
|
29
33
|
}
|
|
30
|
-
|
|
34
|
+
adjustFrequency(range = 0, coarse = 0) {
|
|
35
|
+
if (this.frequency)
|
|
36
|
+
return this.frequency;
|
|
31
37
|
let newOctave = this.octave + range;
|
|
32
38
|
let coarseIndex = Notes.indexOf(this.name) + coarse;
|
|
33
39
|
let nameIndex = coarseIndex;
|
|
@@ -48,10 +54,14 @@ export default class Note {
|
|
|
48
54
|
serialize() {
|
|
49
55
|
return {
|
|
50
56
|
note: this.fullName,
|
|
57
|
+
frequency: this.frequency,
|
|
51
58
|
velocity: this.velocity,
|
|
52
59
|
duration: this.duration,
|
|
53
60
|
};
|
|
54
61
|
}
|
|
62
|
+
fromFrequency(frequency) {
|
|
63
|
+
this.frequency = frequency;
|
|
64
|
+
}
|
|
55
65
|
fromString(string) {
|
|
56
66
|
const matches = string.match(/(\w#?)(\d)?/) || [];
|
|
57
67
|
this.name = matches[1];
|
package/build/Note/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/Note/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAE9C,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;AAEhF,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/Note/index.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
CHANGED
|
@@ -4,5 +4,5 @@ export { default as MidiDeviceManager } from "./MidiDeviceManager";
|
|
|
4
4
|
export { default as Note } from "./Note";
|
|
5
5
|
export type { INote } from "./Note";
|
|
6
6
|
export type { MidiDeviceInterface } from "./MidiDevice";
|
|
7
|
-
export type { ModuleInterface, AudioModule, ISequence } from "./Module";
|
|
7
|
+
export type { ModuleInterface, AudioModule, ISequence, IDataSequence, } from "./Module";
|
|
8
8
|
export type { SerializeInterface as IOProps } from "./Module/IO";
|
package/package.json
CHANGED
package/src/Engine.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Context, setContext } from "tone";
|
|
1
|
+
import { Context, now, setContext } from "tone";
|
|
2
2
|
import MidiDeviceManager from "./MidiDeviceManager";
|
|
3
3
|
import MidiEvent, { EType } from "./MidiEvent";
|
|
4
4
|
|
|
@@ -52,6 +52,7 @@ class Engine {
|
|
|
52
52
|
this.context = new Context(props.context);
|
|
53
53
|
setContext(this.context);
|
|
54
54
|
this.context.transport.start();
|
|
55
|
+
|
|
55
56
|
this.midiDeviceManager = new MidiDeviceManager();
|
|
56
57
|
|
|
57
58
|
return {
|
|
@@ -60,7 +61,8 @@ class Engine {
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
registerModule(name: string, type: string, props: any = {}) {
|
|
63
|
-
const audioModule = createModule(name, type,
|
|
64
|
+
const audioModule = createModule(name, type, {});
|
|
65
|
+
audioModule.props = props;
|
|
64
66
|
this.modules[audioModule.id] = audioModule;
|
|
65
67
|
|
|
66
68
|
applyRoutes(Object.values(this.routes));
|
|
@@ -153,6 +155,38 @@ class Engine {
|
|
|
153
155
|
return audioModule;
|
|
154
156
|
}
|
|
155
157
|
|
|
158
|
+
get isStarted() {
|
|
159
|
+
return this.context.transport.state === "started";
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
start() {
|
|
163
|
+
const startTime = now();
|
|
164
|
+
Object.values(this.modules).forEach((audioModule) => {
|
|
165
|
+
const am = audioModule as any;
|
|
166
|
+
if (!am.start) return;
|
|
167
|
+
|
|
168
|
+
am.start(startTime);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
stop() {
|
|
173
|
+
const startTime = now();
|
|
174
|
+
Object.values(this.modules).forEach((audioModule) => {
|
|
175
|
+
const am = audioModule as any;
|
|
176
|
+
if (!am.stop) return;
|
|
177
|
+
|
|
178
|
+
am.stop(startTime);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
get bpm() {
|
|
183
|
+
return this.context.transport.bpm.value;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
set bpm(value: number) {
|
|
187
|
+
this.context.transport.bpm.value = value;
|
|
188
|
+
}
|
|
189
|
+
|
|
156
190
|
private applyRoutesRequired(audioModule: AudioModule, props: any) {
|
|
157
191
|
if (!props.polyNumber) return false;
|
|
158
192
|
if (!(audioModule instanceof VoiceScheduler)) return false;
|
package/src/MidiEvent.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { now } from "tone";
|
|
2
2
|
import { ISequence } from "./Module/Sequencer";
|
|
3
|
+
import { IDataSequence } from "./Module/DataSequencer";
|
|
3
4
|
import Note, { INote } from "./Note";
|
|
4
5
|
|
|
5
6
|
const EventType: { [key: number]: EType } = {
|
|
@@ -16,6 +17,19 @@ export default class MidiEvent {
|
|
|
16
17
|
private data: Uint8Array;
|
|
17
18
|
private event: MIDIMessageEvent;
|
|
18
19
|
|
|
20
|
+
static fromDataSequence(sequence: IDataSequence, triggeredAt: number) {
|
|
21
|
+
const event = new MidiEvent(
|
|
22
|
+
new MIDIMessageEvent("", { data: new Uint8Array([0, 0, 0]) }),
|
|
23
|
+
triggeredAt
|
|
24
|
+
);
|
|
25
|
+
event._type = "noteOn";
|
|
26
|
+
const note = new Note(sequence.frequency);
|
|
27
|
+
note.velocity = sequence.amplitude;
|
|
28
|
+
event.notes = [note];
|
|
29
|
+
|
|
30
|
+
return event;
|
|
31
|
+
}
|
|
32
|
+
|
|
19
33
|
static fromSequence(sequence: ISequence, triggeredAt: number) {
|
|
20
34
|
const event = new MidiEvent(
|
|
21
35
|
new MIDIMessageEvent("", { data: new Uint8Array([0, 0, 0]) }),
|
package/src/Module/Base.ts
CHANGED
|
@@ -15,7 +15,6 @@ export interface Connectable {
|
|
|
15
15
|
export interface Triggerable {
|
|
16
16
|
triggerAttack: Function;
|
|
17
17
|
triggerRelease: Function;
|
|
18
|
-
triggerAttackRelease: Function;
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
export interface Voicable {
|
|
@@ -130,17 +129,28 @@ class Module<InternalModule extends Connectable, PropsInterface>
|
|
|
130
129
|
throw Error("triggerRelease not implemented");
|
|
131
130
|
}
|
|
132
131
|
|
|
133
|
-
triggerAttackRelease(note: Note, triggeredAt: number) {
|
|
134
|
-
throw Error("triggerAttackRelease not implemented");
|
|
135
|
-
}
|
|
136
|
-
|
|
137
132
|
midiTriggered = (midiEvent: MidiEvent, noteIndex?: number) => {
|
|
133
|
+
const { notes, triggeredAt } = midiEvent;
|
|
134
|
+
|
|
138
135
|
switch (midiEvent.type) {
|
|
139
136
|
case "noteOn":
|
|
140
|
-
|
|
137
|
+
const { duration } = notes[0];
|
|
138
|
+
|
|
139
|
+
this.triggerer(this.triggerAttack, notes, triggeredAt, noteIndex);
|
|
140
|
+
|
|
141
|
+
if (duration) {
|
|
142
|
+
const releaseTriggeredAt =
|
|
143
|
+
triggeredAt + (this.internalModule as any).toSeconds(duration);
|
|
144
|
+
this.triggerer(
|
|
145
|
+
this.triggerRelease,
|
|
146
|
+
notes,
|
|
147
|
+
releaseTriggeredAt,
|
|
148
|
+
noteIndex
|
|
149
|
+
);
|
|
150
|
+
}
|
|
141
151
|
break;
|
|
142
152
|
case "noteOff":
|
|
143
|
-
this.triggerer(this.triggerRelease,
|
|
153
|
+
this.triggerer(this.triggerRelease, notes, triggeredAt, noteIndex);
|
|
144
154
|
break;
|
|
145
155
|
default:
|
|
146
156
|
throw Error("This type is not a note");
|
|
@@ -149,11 +159,10 @@ class Module<InternalModule extends Connectable, PropsInterface>
|
|
|
149
159
|
|
|
150
160
|
private triggerer(
|
|
151
161
|
trigger: Function,
|
|
152
|
-
|
|
162
|
+
notes: Note[],
|
|
163
|
+
triggeredAt: number,
|
|
153
164
|
noteIndex?: number
|
|
154
165
|
) {
|
|
155
|
-
const { notes, triggeredAt } = midiEvent;
|
|
156
|
-
|
|
157
166
|
if (noteIndex !== undefined && this.voiceNo !== undefined) {
|
|
158
167
|
trigger(notes[noteIndex], triggeredAt);
|
|
159
168
|
return;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { now } from "tone";
|
|
2
|
+
|
|
3
|
+
import Module, { DummnyInternalModule } from "./Base";
|
|
4
|
+
import { Output } from "./IO";
|
|
5
|
+
import MidiEvent from "../MidiEvent";
|
|
6
|
+
import { uniq } from "lodash";
|
|
7
|
+
|
|
8
|
+
interface IDataSequencer {
|
|
9
|
+
sequences: IDataSequence[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface IDataSequence {
|
|
13
|
+
voiceNo: number;
|
|
14
|
+
time: number;
|
|
15
|
+
frequency: number;
|
|
16
|
+
amplitude: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const InitialProps = () => ({
|
|
20
|
+
sequences: [],
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export default class DataSequencer extends Module<
|
|
24
|
+
DummnyInternalModule,
|
|
25
|
+
IDataSequencer
|
|
26
|
+
> {
|
|
27
|
+
static moduleName = "DataSequencer";
|
|
28
|
+
private midiOutput: Output;
|
|
29
|
+
|
|
30
|
+
constructor(name: string, props: Partial<IDataSequence>) {
|
|
31
|
+
super(new DummnyInternalModule(), {
|
|
32
|
+
name,
|
|
33
|
+
props: { ...InitialProps(), ...props },
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
this.start(now());
|
|
37
|
+
this.registerOutputs();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get sequences() {
|
|
41
|
+
return this._props["sequences"];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
set sequences(value: IDataSequence[]) {
|
|
45
|
+
const sequences = value;
|
|
46
|
+
this._props = { ...this.props, sequences };
|
|
47
|
+
this.updateNumberOfVoices();
|
|
48
|
+
this.start(now());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
start(time: number) {
|
|
52
|
+
this.sequences.forEach((sequence) => {
|
|
53
|
+
this.onPartEvent(time + sequence.time, sequence);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
stop() {}
|
|
58
|
+
|
|
59
|
+
private onPartEvent = (time: number, sequence: IDataSequence) => {
|
|
60
|
+
const { voiceNo } = sequence;
|
|
61
|
+
const event = MidiEvent.fromDataSequence(sequence, time);
|
|
62
|
+
|
|
63
|
+
this.midiOutput.connections.forEach((input) => {
|
|
64
|
+
input.pluggable(event, voiceNo);
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
private get numberOfVoices() {
|
|
69
|
+
return uniq(this.sequences.map((sequence) => sequence.voiceNo)).length;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private updateNumberOfVoices() {
|
|
73
|
+
if (!this.midiOutput) return;
|
|
74
|
+
|
|
75
|
+
this.midiOutput.connections.forEach((input) => {
|
|
76
|
+
if (input.audioModule instanceof Module) return;
|
|
77
|
+
|
|
78
|
+
input.audioModule.numberOfVoices = this.numberOfVoices;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private registerOutputs() {
|
|
83
|
+
this.midiOutput = this.registerOutput({
|
|
84
|
+
name: "midi out",
|
|
85
|
+
onPlug: (input) => {
|
|
86
|
+
if (input.audioModule instanceof Module) return;
|
|
87
|
+
|
|
88
|
+
input.audioModule.numberOfVoices = this.numberOfVoices;
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -90,22 +90,13 @@ export default abstract class EnvelopeModule<EnvelopeLike extends Env>
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
triggerAttack = (note: Note, triggeredAt: number) => {
|
|
93
|
-
if (note.duration) return this.triggerAttackRelease(note, triggeredAt);
|
|
94
|
-
|
|
95
93
|
this.activeNote = note.fullName;
|
|
96
94
|
this.triggeredAt = triggeredAt;
|
|
97
|
-
this.internalModule.triggerAttack(triggeredAt);
|
|
98
|
-
};
|
|
99
95
|
|
|
100
|
-
|
|
101
|
-
this.activeNote = note.fullName;
|
|
102
|
-
this.triggeredAt = triggeredAt;
|
|
103
|
-
this.internalModule.triggerAttackRelease(note.duration, triggeredAt);
|
|
96
|
+
this.internalModule.triggerAttack(triggeredAt, note.velocity);
|
|
104
97
|
};
|
|
105
98
|
|
|
106
99
|
triggerRelease = (note: Note, triggeredAt: number) => {
|
|
107
|
-
if (this.activeNote && this.activeNote !== note.fullName) return;
|
|
108
|
-
|
|
109
100
|
this.internalModule.triggerRelease(triggeredAt);
|
|
110
101
|
};
|
|
111
102
|
|