@blibliki/engine 0.1.9 → 0.1.10
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/MidiEvent.d.ts +4 -2
- package/build/MidiEvent.js +14 -6
- package/build/MidiEvent.js.map +1 -1
- package/build/Module/Base.d.ts +6 -4
- package/build/Module/Base.js +15 -9
- package/build/Module/Base.js.map +1 -1
- package/build/Module/Envelope/Base.d.ts +4 -3
- package/build/Module/Envelope/Base.js +14 -14
- package/build/Module/Envelope/Base.js.map +1 -1
- package/build/Module/Oscillator.d.ts +2 -3
- package/build/Module/Oscillator.js +5 -7
- package/build/Module/Oscillator.js.map +1 -1
- package/build/Module/PolyModule.d.ts +1 -1
- package/build/Module/PolyModule.js +2 -2
- package/build/Module/PolyModule.js.map +1 -1
- package/build/Module/Sequencer.d.ts +22 -7
- package/build/Module/Sequencer.js +96 -29
- package/build/Module/Sequencer.js.map +1 -1
- package/build/Module/VirtualMidi.d.ts +3 -2
- package/build/Module/VirtualMidi.js +6 -11
- package/build/Module/VirtualMidi.js.map +1 -1
- package/build/Module/VoiceScheduler.d.ts +2 -2
- package/build/Module/VoiceScheduler.js +29 -16
- package/build/Module/VoiceScheduler.js.map +1 -1
- package/build/Module/index.d.ts +2 -0
- package/build/Module/index.js +1 -0
- package/build/Module/index.js.map +1 -1
- package/build/Note/index.d.ts +4 -7
- package/build/Note/index.js +6 -11
- package/build/Note/index.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/MidiEvent.ts +19 -6
- package/src/Module/Base.ts +23 -8
- package/src/Module/Envelope/Base.ts +14 -14
- package/src/Module/Oscillator.ts +6 -7
- package/src/Module/PolyModule.ts +6 -2
- package/src/Module/Sequencer.ts +113 -33
- package/src/Module/VirtualMidi.ts +7 -11
- package/src/Module/VoiceScheduler.ts +30 -20
- package/src/Module/index.ts +3 -0
- package/src/Note/index.ts +9 -21
- package/src/index.ts +1 -1
|
@@ -22,23 +22,18 @@ export default class VirtualMidi extends Module {
|
|
|
22
22
|
this._props = { ...this.props, activeNotes: value };
|
|
23
23
|
}
|
|
24
24
|
sendMidi(midiEvent) {
|
|
25
|
-
this.midiTriggered(midiEvent);
|
|
26
25
|
this.midiOutput.connections.forEach((input) => {
|
|
27
26
|
input.pluggable(midiEvent);
|
|
28
27
|
});
|
|
29
28
|
}
|
|
30
|
-
triggerAttack(
|
|
31
|
-
|
|
32
|
-
return;
|
|
33
|
-
this.activeNotes = [...this.activeNotes, midiEvent.note.fullName];
|
|
29
|
+
triggerAttack = (note) => {
|
|
30
|
+
this.activeNotes = [...this.activeNotes, note.fullName];
|
|
34
31
|
Engine._triggerPropsUpdate(this.id, this.props);
|
|
35
|
-
}
|
|
36
|
-
triggerRelease(
|
|
37
|
-
|
|
38
|
-
return;
|
|
39
|
-
this.activeNotes = this.activeNotes.filter((name) => name !== midiEvent.note.fullName);
|
|
32
|
+
};
|
|
33
|
+
triggerRelease = (note) => {
|
|
34
|
+
this.activeNotes = this.activeNotes.filter((name) => name !== note.fullName);
|
|
40
35
|
Engine._triggerPropsUpdate(this.id, this.props);
|
|
41
|
-
}
|
|
36
|
+
};
|
|
42
37
|
serialize() {
|
|
43
38
|
return {
|
|
44
39
|
...super.serialize(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualMidi.js","sourceRoot":"","sources":["../../src/Module/VirtualMidi.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"VirtualMidi.js","sourceRoot":"","sources":["../../src/Module/VirtualMidi.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,WAAW,CAAC;AAG/B,OAAO,MAAM,EAAE,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAOtD,MAAM,YAAY,GAAyB;IACzC,WAAW,EAAE,EAAE;CAChB,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,MAGxC;IACC,MAAM,CAAC,UAAU,GAAG,aAAa,CAAC;IAClC,UAAU,CAAS;IAEnB,YAAY,IAAY,EAAE,KAA2B;QACnD,KAAK,CAAC,IAAI,oBAAoB,EAAE,EAAE;YAChC,IAAI;YACJ,KAAK,EAAE,EAAE,GAAG,YAAY,EAAE,GAAG,KAAK,EAAE;SACrC,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IACpC,CAAC;IAED,sBAAsB;IACtB,IAAI,WAAW,CAAC,KAAe;QAC7B,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IACtD,CAAC;IAED,QAAQ,CAAC,SAAoB;QAC3B,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC5C,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,aAAa,GAAG,CAAC,IAAU,EAAE,EAAE;QAC7B,IAAI,CAAC,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxD,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC,CAAC;IAEF,cAAc,GAAG,CAAC,IAAU,EAAE,EAAE;QAC9B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CACxC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CACjC,CAAC;QACF,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC,CAAC;IAEF,SAAS;QACP,OAAO;YACL,GAAG,KAAK,CAAC,SAAS,EAAE;YACpB,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC;IACJ,CAAC;IAEO,cAAc;QACpB,IAAI,CAAC,aAAa,CAAC;YACjB,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,IAAI,CAAC,aAAa;SAC9B,CAAC,CAAC;IACL,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAC9D,CAAC"}
|
|
@@ -21,7 +21,7 @@ export default class VoiceScheduler extends PolyModule<Voice, VoiceSchedulerInte
|
|
|
21
21
|
outputs: import("./IO").SerializeInterface[];
|
|
22
22
|
name: string;
|
|
23
23
|
};
|
|
24
|
-
private
|
|
24
|
+
private findFreeVoices;
|
|
25
25
|
private registerInputs;
|
|
26
26
|
private registerOutputs;
|
|
27
27
|
}
|
|
@@ -33,6 +33,6 @@ declare class Voice extends Module<DummnyInternalModule, VoiceInterface> {
|
|
|
33
33
|
triggeredAt: number;
|
|
34
34
|
midiOutput: Output;
|
|
35
35
|
constructor(name: string, props: VoiceInterface);
|
|
36
|
-
midiTriggered: (midiEvent: MidiEvent) => void;
|
|
36
|
+
midiTriggered: (midiEvent: MidiEvent, noteIndex?: number) => void;
|
|
37
37
|
}
|
|
38
38
|
export {};
|
|
@@ -28,22 +28,28 @@ export default class VoiceScheduler extends PolyModule {
|
|
|
28
28
|
return this.numberOfVoices;
|
|
29
29
|
}
|
|
30
30
|
midiTriggered = (midiEvent) => {
|
|
31
|
-
let
|
|
31
|
+
let voices;
|
|
32
32
|
switch (midiEvent.type) {
|
|
33
33
|
case "noteOn":
|
|
34
|
-
|
|
34
|
+
voices = this.findFreeVoices(midiEvent.notes.length);
|
|
35
35
|
break;
|
|
36
36
|
case "noteOff":
|
|
37
|
-
|
|
37
|
+
voices = midiEvent.notes.map((note) => {
|
|
38
|
+
return this.audioModules.find((v) => v.activeNote === note.fullName);
|
|
39
|
+
});
|
|
38
40
|
break;
|
|
39
41
|
default:
|
|
40
42
|
throw Error("This type is not a note");
|
|
41
43
|
}
|
|
42
|
-
if (
|
|
44
|
+
if (voices.length === 0)
|
|
43
45
|
return;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
voices.forEach((voice, i) => {
|
|
47
|
+
if (!voice)
|
|
48
|
+
return;
|
|
49
|
+
voice.midiTriggered(midiEvent, i);
|
|
50
|
+
this.midiOutput.connections.forEach((input) => {
|
|
51
|
+
input.pluggable(midiEvent, voice.voiceNo, i);
|
|
52
|
+
});
|
|
47
53
|
});
|
|
48
54
|
};
|
|
49
55
|
serialize() {
|
|
@@ -54,16 +60,18 @@ export default class VoiceScheduler extends PolyModule {
|
|
|
54
60
|
props: { ...serialize.props, polyNumber: this.polyNumber },
|
|
55
61
|
};
|
|
56
62
|
}
|
|
57
|
-
|
|
58
|
-
let
|
|
59
|
-
if (
|
|
60
|
-
|
|
63
|
+
findFreeVoices(num = 1) {
|
|
64
|
+
let voices = this.audioModules.filter((v) => !v.activeNote).slice(0, num);
|
|
65
|
+
if (voices.length === 0) {
|
|
66
|
+
voices = this.audioModules
|
|
67
|
+
.sort((a, b) => {
|
|
61
68
|
if (!a || !b)
|
|
62
69
|
return 0;
|
|
63
70
|
return a.triggeredAt - b.triggeredAt;
|
|
64
|
-
})
|
|
71
|
+
})
|
|
72
|
+
.slice(0, num);
|
|
65
73
|
}
|
|
66
|
-
return
|
|
74
|
+
return voices;
|
|
67
75
|
}
|
|
68
76
|
registerInputs() {
|
|
69
77
|
this.registerInput({
|
|
@@ -94,10 +102,15 @@ class Voice extends Module {
|
|
|
94
102
|
props,
|
|
95
103
|
});
|
|
96
104
|
}
|
|
97
|
-
midiTriggered = (midiEvent) => {
|
|
98
|
-
|
|
105
|
+
midiTriggered = (midiEvent, noteIndex) => {
|
|
106
|
+
if (this.voiceNo === undefined)
|
|
107
|
+
throw Error("Voice without voiceNo");
|
|
108
|
+
if (noteIndex === undefined)
|
|
109
|
+
return;
|
|
110
|
+
const { triggeredAt, notes, type } = midiEvent;
|
|
111
|
+
const note = notes[noteIndex];
|
|
99
112
|
if (!note)
|
|
100
|
-
|
|
113
|
+
return;
|
|
101
114
|
const noteName = note.fullName;
|
|
102
115
|
switch (type) {
|
|
103
116
|
case "noteOn":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VoiceScheduler.js","sourceRoot":"","sources":["../../src/Module/VoiceScheduler.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,EAAE,EAAE,oBAAoB,EAAY,MAAM,QAAQ,CAAC;AAGhE,OAAO,UAAU,MAAM,cAAc,CAAC;AAMtC,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,UAG3C;IACC,MAAM,CAAC,UAAU,GAAG,gBAAgB,CAAC;IACrC,UAAU,CAAS;IACnB,iBAAiB,CAAS;IAE1B,YAAY,IAAY,EAAE,KAA8B;QACtD,KAAK,CAAC;YACJ,IAAI;YACJ,KAAK,EAAE,KAAK;YACZ,KAAK;SACN,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC;IACxC,CAAC;IAED,IAAI,UAAU,CAAC,KAAa;QAC1B,KAAK,CAAC,cAAc,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,iBAAiB;YAAE,OAAO;QAEpC,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACnD,IAAI,KAAK,CAAC,WAAW,YAAY,MAAM;gBAAE,OAAO;YAEhD,KAAK,CAAC,WAAW,CAAC,cAAc,GAAG,KAAK,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,aAAa,GAAG,CAAC,SAAoB,EAAE,EAAE;QACvC,IAAI,
|
|
1
|
+
{"version":3,"file":"VoiceScheduler.js","sourceRoot":"","sources":["../../src/Module/VoiceScheduler.ts"],"names":[],"mappings":"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"}
|
package/build/Module/index.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export { default as PolyModule } from "./PolyModule";
|
|
|
5
5
|
export type { ModuleInterface, Connectable, Triggerable } from "./Base";
|
|
6
6
|
export { default as Filter } from "./Filter";
|
|
7
7
|
export { default as Oscillator } from "./Oscillator";
|
|
8
|
+
export { default as Sequencer } from "./Sequencer";
|
|
9
|
+
export type { ISequence } from "./Sequencer";
|
|
8
10
|
export { Envelope, AmpEnvelope, FreqEnvelope, EnvelopeStages, } from "./Envelope";
|
|
9
11
|
export declare type AudioModule = Module<Connectable, any> | PolyModule<Module<Connectable, any>, any>;
|
|
10
12
|
export declare function createModule(name: string, type: string, props: any): AudioModule;
|
package/build/Module/index.js
CHANGED
|
@@ -16,6 +16,7 @@ export { default } from "./Base";
|
|
|
16
16
|
export { default as PolyModule } from "./PolyModule";
|
|
17
17
|
export { default as Filter } from "./Filter";
|
|
18
18
|
export { default as Oscillator } from "./Oscillator";
|
|
19
|
+
export { default as Sequencer } from "./Sequencer";
|
|
19
20
|
export { Envelope, AmpEnvelope, FreqEnvelope, EnvelopeStages, } from "./Envelope";
|
|
20
21
|
export function createModule(name, type, props) {
|
|
21
22
|
const klass = moduleClassFromType(type);
|
|
@@ -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;AAEpC,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,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;YACE,MAAM,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;KAC9C;AACH,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;AAEpC,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;AAGnD,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;YACE,MAAM,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;KAC9C;AACH,CAAC"}
|
package/build/Note/index.d.ts
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import { TimeClass } from "tone";
|
|
2
1
|
export interface INote {
|
|
3
2
|
note: string;
|
|
4
|
-
|
|
3
|
+
duration: string;
|
|
5
4
|
velocity?: number;
|
|
6
|
-
duration?: string;
|
|
7
5
|
}
|
|
8
6
|
export default class Note {
|
|
9
7
|
static _notes: Note[];
|
|
10
8
|
name: string;
|
|
11
9
|
octave: number;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
constructor(eventOrString: INote | MIDIMessageEvent | string, duration?: string);
|
|
10
|
+
velocity: number;
|
|
11
|
+
duration: string;
|
|
12
|
+
constructor(eventOrString: Partial<INote> | MIDIMessageEvent | string);
|
|
16
13
|
static notes(octave?: number): Note[];
|
|
17
14
|
get isSemi(): boolean;
|
|
18
15
|
get fullName(): string;
|
package/build/Note/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Time } from "tone";
|
|
2
1
|
import frequencyTable from "./frequencyTable";
|
|
3
2
|
const Notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
4
3
|
const NotesLength = Notes.length;
|
|
@@ -6,11 +5,9 @@ export default class Note {
|
|
|
6
5
|
static _notes;
|
|
7
6
|
name;
|
|
8
7
|
octave;
|
|
9
|
-
time = Time("0:0:0");
|
|
10
8
|
velocity = 1;
|
|
11
9
|
duration;
|
|
12
|
-
constructor(eventOrString
|
|
13
|
-
this.duration = duration;
|
|
10
|
+
constructor(eventOrString) {
|
|
14
11
|
if (typeof eventOrString === "string") {
|
|
15
12
|
this.fromString(eventOrString);
|
|
16
13
|
}
|
|
@@ -50,10 +47,9 @@ export default class Note {
|
|
|
50
47
|
}
|
|
51
48
|
serialize() {
|
|
52
49
|
return {
|
|
53
|
-
time: this.time.toBarsBeatsSixteenths(),
|
|
54
50
|
note: this.fullName,
|
|
51
|
+
velocity: this.velocity,
|
|
55
52
|
duration: this.duration,
|
|
56
|
-
velocity: 1,
|
|
57
53
|
};
|
|
58
54
|
}
|
|
59
55
|
fromString(string) {
|
|
@@ -66,11 +62,10 @@ export default class Note {
|
|
|
66
62
|
this.octave = Math.floor(event.data[1] / 12) - 2;
|
|
67
63
|
}
|
|
68
64
|
fromProps(props) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
this.
|
|
73
|
-
this.velocity = velocity;
|
|
65
|
+
Object.assign(this, props);
|
|
66
|
+
if (!props.note)
|
|
67
|
+
throw Error("note props is mandatory");
|
|
68
|
+
this.fromString(props.note);
|
|
74
69
|
}
|
|
75
70
|
}
|
|
76
71
|
//# sourceMappingURL=index.js.map
|
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,
|
|
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;AAQjC,MAAM,CAAC,OAAO,OAAO,IAAI;IACvB,MAAM,CAAC,MAAM,CAAS;IACtB,IAAI,CAAS;IACb,MAAM,CAAS;IACf,QAAQ,GAAW,CAAC,CAAC;IACrB,QAAQ,CAAS;IAEjB,YAAY,aAAyD;QACnE,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE;YACrC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;SAChC;aAAM,IAAI,aAAa,YAAY,gBAAgB,EAAE;YACpD,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;SAC/B;aAAM;YACL,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;SAC/B;IACH,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,SAAiB,CAAC;QAC7B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,IAAI,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;IACrC,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IACtC,CAAC;IAED,SAAS,CAAC,QAAgB,CAAC,EAAE,SAAiB,CAAC;QAC7C,IAAI,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpC,IAAI,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;QACpD,IAAI,SAAS,GAAG,WAAW,CAAC;QAE5B,IAAI,WAAW,IAAI,WAAW,EAAE;YAC9B,SAAS,EAAE,CAAC;YACZ,SAAS,GAAG,WAAW,GAAG,WAAW,CAAC;SACvC;aAAM,IAAI,WAAW,GAAG,CAAC,EAAE;YAC1B,SAAS,EAAE,CAAC;YACZ,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;SACrC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;QAEjC,OAAO,cAAc,CAAC,GAAG,OAAO,GAAG,SAAS,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,SAAS;QACP,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,QAAQ;YACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC;IACJ,CAAC;IAEO,UAAU,CAAC,MAAc;QAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QAElD,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IAEO,SAAS,CAAC,KAAuB;QACvC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACnD,CAAC;IAEO,SAAS,CAAC,KAAqB;QACrC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,IAAI;YAAE,MAAM,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAExD,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;CACF"}
|
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 } from "./Module";
|
|
7
|
+
export type { ModuleInterface, AudioModule, ISequence } from "./Module";
|
|
8
8
|
export type { SerializeInterface as IOProps } from "./Module/IO";
|
package/package.json
CHANGED
package/src/MidiEvent.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { now } from "tone";
|
|
2
|
+
import { ISequence } from "./Module/Sequencer";
|
|
2
3
|
import Note, { INote } from "./Note";
|
|
3
4
|
|
|
4
5
|
const EventType: { [key: number]: EType } = {
|
|
@@ -9,12 +10,23 @@ const EventType: { [key: number]: EType } = {
|
|
|
9
10
|
export type EType = "noteOn" | "noteOff";
|
|
10
11
|
|
|
11
12
|
export default class MidiEvent {
|
|
12
|
-
|
|
13
|
+
notes: Note[];
|
|
13
14
|
readonly triggeredAt: number;
|
|
14
15
|
_type: EType;
|
|
15
16
|
private data: Uint8Array;
|
|
16
17
|
private event: MIDIMessageEvent;
|
|
17
18
|
|
|
19
|
+
static fromSequence(sequence: ISequence, triggeredAt: number) {
|
|
20
|
+
const event = new MidiEvent(
|
|
21
|
+
new MIDIMessageEvent("", { data: new Uint8Array([0, 0, 0]) }),
|
|
22
|
+
triggeredAt
|
|
23
|
+
);
|
|
24
|
+
event._type = "noteOn";
|
|
25
|
+
event.notes = sequence.notes.map((n) => new Note(n));
|
|
26
|
+
|
|
27
|
+
return event;
|
|
28
|
+
}
|
|
29
|
+
|
|
18
30
|
static fromNote(
|
|
19
31
|
noteName: string | Note | INote,
|
|
20
32
|
type: EType,
|
|
@@ -26,9 +38,9 @@ export default class MidiEvent {
|
|
|
26
38
|
);
|
|
27
39
|
|
|
28
40
|
if (noteName instanceof Note) {
|
|
29
|
-
event.
|
|
41
|
+
event.notes = [noteName];
|
|
30
42
|
} else {
|
|
31
|
-
event.
|
|
43
|
+
event.notes = [new Note(noteName)];
|
|
32
44
|
}
|
|
33
45
|
event._type = type;
|
|
34
46
|
|
|
@@ -39,7 +51,7 @@ export default class MidiEvent {
|
|
|
39
51
|
this.event = event;
|
|
40
52
|
this.triggeredAt = triggeredAt || now();
|
|
41
53
|
this.data = event.data;
|
|
42
|
-
this.
|
|
54
|
+
this.defineNotes();
|
|
43
55
|
}
|
|
44
56
|
|
|
45
57
|
get type() {
|
|
@@ -58,9 +70,10 @@ export default class MidiEvent {
|
|
|
58
70
|
return this.type === "noteOn" || this.type === "noteOff";
|
|
59
71
|
}
|
|
60
72
|
|
|
61
|
-
|
|
73
|
+
defineNotes() {
|
|
62
74
|
if (!this.isNote) return;
|
|
75
|
+
if (this.notes) return;
|
|
63
76
|
|
|
64
|
-
this.
|
|
77
|
+
this.notes = [new Note(this.event)];
|
|
65
78
|
}
|
|
66
79
|
}
|
package/src/Module/Base.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { InputNode } from "tone";
|
|
|
4
4
|
import { Input, Output, IOInterface } from "./IO";
|
|
5
5
|
import MidiEvent from "../MidiEvent";
|
|
6
6
|
import { AudioModule, PolyModule } from "../Module";
|
|
7
|
+
import Note from "../Note";
|
|
7
8
|
|
|
8
9
|
export interface Connectable {
|
|
9
10
|
connect: (inputNode: InputNode) => void;
|
|
@@ -49,7 +50,7 @@ class Module<InternalModule extends Connectable, PropsInterface>
|
|
|
49
50
|
outputs: Output[] = [];
|
|
50
51
|
readonly voiceNo?: number;
|
|
51
52
|
updatedAt: Date;
|
|
52
|
-
_props: PropsInterface;
|
|
53
|
+
_props: PropsInterface = {} as PropsInterface;
|
|
53
54
|
|
|
54
55
|
constructor(internalModule: InternalModule, props: Partial<ModuleInterface>) {
|
|
55
56
|
this.internalModule = internalModule;
|
|
@@ -60,7 +61,6 @@ class Module<InternalModule extends Connectable, PropsInterface>
|
|
|
60
61
|
|
|
61
62
|
set props(value: PropsInterface) {
|
|
62
63
|
if (!value) return;
|
|
63
|
-
if (!this._props) this._props = value;
|
|
64
64
|
|
|
65
65
|
this.updatedAt = new Date();
|
|
66
66
|
|
|
@@ -122,31 +122,46 @@ class Module<InternalModule extends Connectable, PropsInterface>
|
|
|
122
122
|
this.internalModule.dispose();
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
triggerAttack(
|
|
125
|
+
triggerAttack(note: Note, triggeredAt: number) {
|
|
126
126
|
throw Error("triggerAttack not implemented");
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
triggerRelease(
|
|
129
|
+
triggerRelease(note: Note, triggeredAt: number) {
|
|
130
130
|
throw Error("triggerRelease not implemented");
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
triggerAttackRelease(
|
|
133
|
+
triggerAttackRelease(note: Note, triggeredAt: number) {
|
|
134
134
|
throw Error("triggerAttackRelease not implemented");
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
midiTriggered = (midiEvent: MidiEvent,
|
|
137
|
+
midiTriggered = (midiEvent: MidiEvent, noteIndex?: number) => {
|
|
138
138
|
switch (midiEvent.type) {
|
|
139
139
|
case "noteOn":
|
|
140
|
-
this.triggerAttack
|
|
140
|
+
this.triggerer(this.triggerAttack, midiEvent, noteIndex);
|
|
141
141
|
break;
|
|
142
142
|
case "noteOff":
|
|
143
|
-
this.triggerRelease
|
|
143
|
+
this.triggerer(this.triggerRelease, midiEvent, noteIndex);
|
|
144
144
|
break;
|
|
145
145
|
default:
|
|
146
146
|
throw Error("This type is not a note");
|
|
147
147
|
}
|
|
148
148
|
};
|
|
149
149
|
|
|
150
|
+
private triggerer(
|
|
151
|
+
trigger: Function,
|
|
152
|
+
midiEvent: MidiEvent,
|
|
153
|
+
noteIndex?: number
|
|
154
|
+
) {
|
|
155
|
+
const { notes, triggeredAt } = midiEvent;
|
|
156
|
+
|
|
157
|
+
if (noteIndex !== undefined && this.voiceNo !== undefined) {
|
|
158
|
+
trigger(notes[noteIndex], triggeredAt);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
notes.forEach((note) => trigger(note, triggeredAt));
|
|
163
|
+
}
|
|
164
|
+
|
|
150
165
|
serialize() {
|
|
151
166
|
const klass = this.constructor as typeof Module;
|
|
152
167
|
|
|
@@ -3,6 +3,7 @@ import { Envelope as Env } from "tone";
|
|
|
3
3
|
import Module, { Connectable, Triggerable, Voicable } from "../Base";
|
|
4
4
|
import PolyModule from "../PolyModule";
|
|
5
5
|
import MidiEvent from "../../MidiEvent";
|
|
6
|
+
import Note from "../../Note";
|
|
6
7
|
|
|
7
8
|
export const enum EnvelopeStages {
|
|
8
9
|
Attack = "attack",
|
|
@@ -88,26 +89,25 @@ export default abstract class EnvelopeModule<EnvelopeLike extends Env>
|
|
|
88
89
|
this.internalModule[stage] = calculatedValue;
|
|
89
90
|
}
|
|
90
91
|
|
|
91
|
-
triggerAttack(
|
|
92
|
-
|
|
92
|
+
triggerAttack = (note: Note, triggeredAt: number) => {
|
|
93
|
+
if (note.duration) return this.triggerAttackRelease(note, triggeredAt);
|
|
93
94
|
|
|
94
|
-
this.activeNote = note
|
|
95
|
+
this.activeNote = note.fullName;
|
|
95
96
|
this.triggeredAt = triggeredAt;
|
|
97
|
+
this.internalModule.triggerAttack(triggeredAt);
|
|
98
|
+
};
|
|
96
99
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
triggerRelease(midiEvent: MidiEvent) {
|
|
105
|
-
const { note, triggeredAt } = midiEvent;
|
|
100
|
+
triggerAttackRelease = (note: Note, triggeredAt: number) => {
|
|
101
|
+
this.activeNote = note.fullName;
|
|
102
|
+
this.triggeredAt = triggeredAt;
|
|
103
|
+
this.internalModule.triggerAttackRelease(note.duration, triggeredAt);
|
|
104
|
+
};
|
|
106
105
|
|
|
107
|
-
|
|
106
|
+
triggerRelease = (note: Note, triggeredAt: number) => {
|
|
107
|
+
if (this.activeNote && this.activeNote !== note.fullName) return;
|
|
108
108
|
|
|
109
109
|
this.internalModule.triggerRelease(triggeredAt);
|
|
110
|
-
}
|
|
110
|
+
};
|
|
111
111
|
|
|
112
112
|
private maxTime(stage: EnvelopeStages): number {
|
|
113
113
|
return stage === EnvelopeStages.Sustain ? SUSTAIN_MAX_VALUE : MAX_TIME;
|
package/src/Module/Oscillator.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import MidiEvent from "../MidiEvent";
|
|
2
|
-
import { Oscillator as Osc, ToneOscillatorType } from "tone";
|
|
2
|
+
import { now, Oscillator as Osc, ToneOscillatorType } from "tone";
|
|
3
3
|
|
|
4
4
|
import Note from "../Note";
|
|
5
5
|
import Module, { Voicable } from "./Base";
|
|
@@ -112,14 +112,13 @@ class MonoOscillator extends Module<Osc, OscillatorInterface> {
|
|
|
112
112
|
this.internalModule.start();
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
triggerAttack(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
115
|
+
triggerAttack = (note: Note, triggeredAt: number) => {
|
|
116
|
+
this.setNoteAt(note, triggeredAt);
|
|
117
|
+
};
|
|
119
118
|
|
|
120
|
-
triggerRelease(
|
|
119
|
+
triggerRelease = (note: Note) => {
|
|
121
120
|
// Do nothing
|
|
122
|
-
}
|
|
121
|
+
};
|
|
123
122
|
|
|
124
123
|
private updateFrequency(time?: number) {
|
|
125
124
|
if (!this.note) return;
|
package/src/Module/PolyModule.ts
CHANGED
|
@@ -90,9 +90,13 @@ export default abstract class PolyModule<
|
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
midiTriggered = (
|
|
93
|
+
midiTriggered = (
|
|
94
|
+
midiEvent: MidiEvent,
|
|
95
|
+
voiceNo: number,
|
|
96
|
+
noteIndex?: number
|
|
97
|
+
) => {
|
|
94
98
|
const audioModule = this.findVoice(voiceNo);
|
|
95
|
-
audioModule?.midiTriggered(midiEvent);
|
|
99
|
+
audioModule?.midiTriggered(midiEvent, noteIndex);
|
|
96
100
|
};
|
|
97
101
|
|
|
98
102
|
serialize() {
|