@blibliki/engine 0.1.27 → 0.3.2
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 +252 -76
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +765 -0
- package/dist/index.d.ts +765 -0
- package/dist/index.js +2 -19484
- package/dist/index.js.map +1 -0
- package/package.json +19 -28
- package/src/Engine.ts +158 -177
- package/src/core/IO/AudioIO.ts +72 -0
- package/src/core/IO/Base.ts +118 -0
- package/src/core/IO/Collection.ts +123 -47
- package/src/core/IO/MidiIO.ts +43 -0
- package/src/core/IO/PolyAudioIO.ts +115 -0
- package/src/core/IO/index.ts +7 -61
- package/src/core/Note/frequencyTable.ts +144 -144
- package/src/core/Note/index.ts +49 -59
- package/src/core/Route.ts +79 -0
- package/src/core/Timing/Scheduler.ts +37 -0
- package/src/core/Timing/Time.ts +103 -0
- package/src/core/Timing/Transport.ts +104 -0
- package/src/core/Timing/index.ts +16 -0
- package/src/core/index.ts +36 -0
- package/src/core/midi/{ComputerKeyboardInput.ts → ComputerKeyboardDevice.ts} +31 -11
- package/src/core/midi/MidiDevice.ts +38 -31
- package/src/core/midi/MidiDeviceManager.ts +54 -55
- package/src/core/midi/MidiEvent.ts +36 -60
- package/src/core/module/Module.ts +233 -0
- package/src/core/module/PolyModule.ts +246 -0
- package/src/core/module/VoiceScheduler.ts +121 -0
- package/src/core/module/index.ts +3 -0
- package/src/core/schema.ts +41 -0
- package/src/index.ts +31 -9
- package/src/modules/BiquadFilter.ts +162 -0
- package/src/modules/Constant.ts +72 -0
- package/src/modules/Envelope.ts +178 -0
- package/src/modules/Filter.ts +109 -104
- package/src/modules/Gain.ts +78 -0
- package/src/modules/Inspector.ts +59 -0
- package/src/modules/Master.ts +18 -21
- package/src/modules/MidiSelector.ts +50 -50
- package/src/modules/Oscillator.ts +203 -158
- package/src/modules/Scale.ts +79 -0
- package/src/modules/StepSequencer.ts +61 -0
- package/src/modules/VirtualMidi.ts +33 -49
- package/src/modules/index.ts +159 -74
- package/src/nodePolyfill.ts +25 -0
- package/src/processors/filter-processor.ts +82 -0
- package/src/processors/index.ts +28 -0
- package/src/processors/scale-processor.ts +81 -0
- package/dist/index.umd.cjs +0 -227
- package/dist/src/Engine.d.ts +0 -83
- package/dist/src/core/IO/AudioNode.d.ts +0 -36
- package/dist/src/core/IO/Collection.d.ts +0 -14
- package/dist/src/core/IO/ForwardNode/Base.d.ts +0 -19
- package/dist/src/core/IO/ForwardNode/index.d.ts +0 -28
- package/dist/src/core/IO/MidiNode.d.ts +0 -31
- package/dist/src/core/IO/Node.d.ts +0 -41
- package/dist/src/core/IO/index.d.ts +0 -22
- package/dist/src/core/Module/MonoModule.d.ts +0 -68
- package/dist/src/core/Module/PolyModule.d.ts +0 -62
- package/dist/src/core/Module/index.d.ts +0 -7
- package/dist/src/core/Note/frequencyTable.d.ts +0 -4
- package/dist/src/core/Note/index.d.ts +0 -28
- package/dist/src/core/midi/ComputerKeyboardInput.d.ts +0 -12
- package/dist/src/core/midi/MidiDevice.d.ts +0 -30
- package/dist/src/core/midi/MidiDeviceManager.d.ts +0 -15
- package/dist/src/core/midi/MidiEvent.d.ts +0 -22
- package/dist/src/core/midi/index.d.ts +0 -5
- package/dist/src/index.d.ts +0 -9
- package/dist/src/main.d.ts +0 -0
- package/dist/src/modules/BitCrusher.d.ts +0 -17
- package/dist/src/modules/Delay.d.ts +0 -20
- package/dist/src/modules/Distortion.d.ts +0 -17
- package/dist/src/modules/Effect.d.ts +0 -20
- package/dist/src/modules/Envelope/AmpEnvelope.d.ts +0 -19
- package/dist/src/modules/Envelope/Base.d.ts +0 -67
- package/dist/src/modules/Envelope/FreqEnvelope.d.ts +0 -26
- package/dist/src/modules/Envelope/index.d.ts +0 -3
- package/dist/src/modules/Filter.d.ts +0 -43
- package/dist/src/modules/LFO.d.ts +0 -45
- package/dist/src/modules/Master.d.ts +0 -12
- package/dist/src/modules/MidiSelector.d.ts +0 -22
- package/dist/src/modules/Oscillator.d.ts +0 -56
- package/dist/src/modules/Reverb.d.ts +0 -20
- package/dist/src/modules/Sequencer.d.ts +0 -43
- package/dist/src/modules/VirtualMidi.d.ts +0 -33
- package/dist/src/modules/VoiceScheduler.d.ts +0 -45
- package/dist/src/modules/Volume.d.ts +0 -27
- package/dist/src/modules/index.d.ts +0 -18
- package/dist/src/routes.d.ts +0 -19
- package/dist/src/types.d.ts +0 -5
- package/dist/src/utils.d.ts +0 -1
- package/dist/test/MockingModules.d.ts +0 -22
- package/dist/test/Module/Oscillator.test.d.ts +0 -1
- package/dist/test/core/IO.test.d.ts +0 -1
- package/src/core/IO/AudioNode.ts +0 -82
- package/src/core/IO/ForwardNode/Base.ts +0 -99
- package/src/core/IO/ForwardNode/index.ts +0 -60
- package/src/core/IO/MidiNode.ts +0 -67
- package/src/core/IO/Node.ts +0 -118
- package/src/core/Module/MonoModule.ts +0 -219
- package/src/core/Module/PolyModule.ts +0 -218
- package/src/core/Module/index.ts +0 -15
- package/src/core/midi/index.ts +0 -5
- package/src/main.ts +0 -1
- package/src/modules/BitCrusher.ts +0 -45
- package/src/modules/Delay.ts +0 -53
- package/src/modules/Distortion.ts +0 -45
- package/src/modules/Effect.ts +0 -46
- package/src/modules/Envelope/AmpEnvelope.ts +0 -23
- package/src/modules/Envelope/Base.ts +0 -176
- package/src/modules/Envelope/FreqEnvelope.ts +0 -64
- package/src/modules/Envelope/index.ts +0 -3
- package/src/modules/LFO.ts +0 -149
- package/src/modules/Reverb.ts +0 -53
- package/src/modules/Sequencer.ts +0 -178
- package/src/modules/VoiceScheduler.ts +0 -145
- package/src/modules/Volume.ts +0 -72
- package/src/routes.ts +0 -49
- package/src/types.ts +0 -3
- package/src/utils.ts +0 -18
- package/src/vite-env.d.ts +0 -1
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import IONode, { IIONode, plugCompatibleIO, unPlugCompatibleIO } from "../Node";
|
|
2
|
-
|
|
3
|
-
import Module, { Connectable, PolyModule } from "../../Module";
|
|
4
|
-
import { AnyObject } from "../../../types";
|
|
5
|
-
import { AnyIO, ForwardAudioInput, ForwardAudioOutput } from "..";
|
|
6
|
-
|
|
7
|
-
export default class ForwardBaseNode extends IONode {
|
|
8
|
-
declare plugableModule: PolyModule<Module<Connectable, AnyObject>, AnyObject>;
|
|
9
|
-
|
|
10
|
-
constructor(
|
|
11
|
-
plugableModule: PolyModule<Module<Connectable, AnyObject>, AnyObject>,
|
|
12
|
-
props: IIONode
|
|
13
|
-
) {
|
|
14
|
-
super(plugableModule, props);
|
|
15
|
-
this.checkNameValidity();
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
get voices() {
|
|
19
|
-
return this.subModules.length;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
get subModules() {
|
|
23
|
-
return this.plugableModule.audioModules;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
subModule(voiceNo: number) {
|
|
27
|
-
const adjustedVoiceNo = voiceNo % this.voices;
|
|
28
|
-
const mod = this.subModules.find((m) => m.voiceNo === adjustedVoiceNo);
|
|
29
|
-
if (!mod) throw Error(`Submodule with voiceNo ${voiceNo} not found`);
|
|
30
|
-
|
|
31
|
-
return mod;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
get subIOs() {
|
|
35
|
-
const ios: IONode[] = [];
|
|
36
|
-
|
|
37
|
-
for (let voice = 0; voice < this.voices; voice++) {
|
|
38
|
-
ios.push(this.subIO(voice));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return ios;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
subIO(voiceNo: number) {
|
|
45
|
-
const ios = this.ioType.includes("Input")
|
|
46
|
-
? this.subModule(voiceNo).inputs
|
|
47
|
-
: this.subModule(voiceNo).outputs;
|
|
48
|
-
|
|
49
|
-
const io = ios.findByName(this.name);
|
|
50
|
-
if (!io) throw Error(`Could not forward io ${this.name}`);
|
|
51
|
-
|
|
52
|
-
return io;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
plug(io: AnyIO, plugOther: boolean = true) {
|
|
56
|
-
this.plugUnplug(io, plugOther, true);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
unPlug(io: AnyIO, plugOther: boolean = true) {
|
|
60
|
-
this.plugUnplug(io, plugOther, false);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
unPlugAll() {
|
|
64
|
-
IONode.unPlugAll(this);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
private plugUnplug(io: AnyIO, plugOther: boolean, isPlug: boolean) {
|
|
68
|
-
isPlug ? super.plug(io, plugOther) : super.unPlug(io, plugOther);
|
|
69
|
-
if (
|
|
70
|
-
!plugOther &&
|
|
71
|
-
(io instanceof ForwardAudioOutput || io instanceof ForwardAudioInput)
|
|
72
|
-
)
|
|
73
|
-
return;
|
|
74
|
-
|
|
75
|
-
const plugCallback = isPlug ? plugCompatibleIO : unPlugCompatibleIO;
|
|
76
|
-
|
|
77
|
-
if (io instanceof ForwardAudioOutput || io instanceof ForwardAudioInput) {
|
|
78
|
-
const maxVoices = Math.max(this.voices, io.voices);
|
|
79
|
-
|
|
80
|
-
for (let voice = 0; voice < maxVoices; voice++) {
|
|
81
|
-
const thisIO = this.subIO(voice);
|
|
82
|
-
const otherIO = io.subIO(voice);
|
|
83
|
-
|
|
84
|
-
plugCallback(thisIO, otherIO);
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
for (let voice = 0; voice < this.voices; voice++) {
|
|
88
|
-
const thisIO = this.subIO(voice);
|
|
89
|
-
plugCallback(thisIO, io);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
private checkNameValidity() {
|
|
95
|
-
const io = this.subIO(0);
|
|
96
|
-
|
|
97
|
-
if (!io) throw Error("You should forward to existing input");
|
|
98
|
-
}
|
|
99
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { IOType, IIONode } from "../Node";
|
|
2
|
-
import Module, { Connectable, PolyModule } from "../../Module";
|
|
3
|
-
import { AnyObject } from "../../../types";
|
|
4
|
-
import { AnyAudioInput, AnyAudioOuput, AnyInput, AnyOuput } from "..";
|
|
5
|
-
import ForwardBaseNode from "./Base";
|
|
6
|
-
|
|
7
|
-
export interface IForwardAudioInput extends IIONode {
|
|
8
|
-
ioType: IOType.ForwardAudioInput;
|
|
9
|
-
}
|
|
10
|
-
export interface IForwardAudioOutput extends IIONode {
|
|
11
|
-
ioType: IOType.ForwardAudioOutput;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export class ForwardAudioInput
|
|
15
|
-
extends ForwardBaseNode
|
|
16
|
-
implements IForwardAudioInput
|
|
17
|
-
{
|
|
18
|
-
declare plugableModule: PolyModule<Module<Connectable, AnyObject>, AnyObject>;
|
|
19
|
-
declare ioType: IOType.ForwardAudioInput;
|
|
20
|
-
declare connections: AnyAudioOuput[];
|
|
21
|
-
|
|
22
|
-
constructor(
|
|
23
|
-
plugableModule: PolyModule<Module<Connectable, AnyObject>, AnyObject>,
|
|
24
|
-
props: IForwardAudioInput
|
|
25
|
-
) {
|
|
26
|
-
super(plugableModule, props);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
plug(io: AnyOuput, plugOther: boolean = true) {
|
|
30
|
-
super.plug(io, plugOther);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
unPlug(io: AnyOuput, plugOther: boolean = true) {
|
|
34
|
-
super.unPlug(io, plugOther);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export class ForwardAudioOutput
|
|
39
|
-
extends ForwardBaseNode
|
|
40
|
-
implements IForwardAudioOutput
|
|
41
|
-
{
|
|
42
|
-
declare plugableModule: PolyModule<Module<Connectable, AnyObject>, AnyObject>;
|
|
43
|
-
declare ioType: IOType.ForwardAudioOutput;
|
|
44
|
-
declare connections: AnyAudioInput[];
|
|
45
|
-
|
|
46
|
-
constructor(
|
|
47
|
-
plugableModule: PolyModule<Module<Connectable, AnyObject>, AnyObject>,
|
|
48
|
-
props: IForwardAudioOutput
|
|
49
|
-
) {
|
|
50
|
-
super(plugableModule, props);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
plug(io: AnyInput, plugOther: boolean = true) {
|
|
54
|
-
super.plug(io, plugOther);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
unPlug(io: AnyInput, plugOther: boolean = true) {
|
|
58
|
-
super.unPlug(io, plugOther);
|
|
59
|
-
}
|
|
60
|
-
}
|
package/src/core/IO/MidiNode.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { AnyMidiInput, AnyMidiOuput } from ".";
|
|
2
|
-
import { AudioModule } from "../Module";
|
|
3
|
-
import { MidiEvent } from "../midi";
|
|
4
|
-
import IONode, { IOType, IIONode } from "./Node";
|
|
5
|
-
|
|
6
|
-
export interface IMidiInput extends IIONode {
|
|
7
|
-
ioType: IOType.MidiInput;
|
|
8
|
-
onMidiEvent: (event: MidiEvent) => void;
|
|
9
|
-
}
|
|
10
|
-
export interface IMidiOutput extends IIONode {
|
|
11
|
-
ioType: IOType.MidiOutput;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export class MidiInput extends IONode implements IMidiInput {
|
|
15
|
-
declare ioType: IOType.MidiInput;
|
|
16
|
-
declare connections: MidiOutput[];
|
|
17
|
-
onMidiEvent: (event: MidiEvent) => void;
|
|
18
|
-
|
|
19
|
-
constructor(plugableModule: AudioModule, props: IMidiInput) {
|
|
20
|
-
super(plugableModule, props);
|
|
21
|
-
|
|
22
|
-
this.onMidiEvent = props.onMidiEvent;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
plug(io: AnyMidiOuput, plugOther: boolean = true) {
|
|
26
|
-
super.plug(io, plugOther);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
unPlug(io: AnyMidiOuput, plugOther: boolean = true) {
|
|
30
|
-
super.unPlug(io, plugOther);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
unPlugAll() {
|
|
34
|
-
IONode.unPlugAll(this);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export class MidiOutput extends IONode implements IMidiOutput {
|
|
39
|
-
declare ioType: IOType.MidiOutput;
|
|
40
|
-
declare connections: MidiInput[];
|
|
41
|
-
|
|
42
|
-
constructor(plugableModule: AudioModule, props: IIONode) {
|
|
43
|
-
super(plugableModule, props);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
plug(io: AnyMidiInput, plugOther: boolean = true) {
|
|
47
|
-
super.plug(io, plugOther);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
unPlug(io: AnyMidiInput, plugOther: boolean = true) {
|
|
51
|
-
super.unPlug(io, plugOther);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
unPlugAll() {
|
|
55
|
-
IONode.unPlugAll(this);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
onMidiEvent = (event: MidiEvent) => {
|
|
59
|
-
this.midiConnections.forEach((input) => {
|
|
60
|
-
input.onMidiEvent(event);
|
|
61
|
-
});
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
private get midiConnections() {
|
|
65
|
-
return this.connections.filter((input) => input instanceof MidiInput);
|
|
66
|
-
}
|
|
67
|
-
}
|
package/src/core/IO/Node.ts
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { AudioModule } from "../Module";
|
|
2
|
-
import { AnyIO } from ".";
|
|
3
|
-
import { deterministicId } from "../../utils";
|
|
4
|
-
|
|
5
|
-
export interface IIONode {
|
|
6
|
-
name: string;
|
|
7
|
-
ioType: IOType;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface IIOSerialize {
|
|
11
|
-
id: string;
|
|
12
|
-
name: string;
|
|
13
|
-
ioType: IOType;
|
|
14
|
-
moduleId: string;
|
|
15
|
-
moduleName: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export enum IOType {
|
|
19
|
-
AudioInput = "audioInput",
|
|
20
|
-
AudioOutput = "audioOutput",
|
|
21
|
-
MidiInput = "midiInput",
|
|
22
|
-
MidiOutput = "midiOutput",
|
|
23
|
-
ForwardAudioInput = "forwardAudioInput",
|
|
24
|
-
ForwardAudioOutput = "forwardAudioOutput",
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const AudioIO = [
|
|
28
|
-
IOType.AudioInput,
|
|
29
|
-
IOType.AudioOutput,
|
|
30
|
-
IOType.ForwardAudioInput,
|
|
31
|
-
IOType.ForwardAudioOutput,
|
|
32
|
-
];
|
|
33
|
-
|
|
34
|
-
const MidiIO = [IOType.MidiInput, IOType.MidiOutput];
|
|
35
|
-
|
|
36
|
-
const IOInputs = [
|
|
37
|
-
IOType.AudioInput,
|
|
38
|
-
IOType.MidiInput,
|
|
39
|
-
IOType.ForwardAudioInput,
|
|
40
|
-
];
|
|
41
|
-
const IOOutputs = [
|
|
42
|
-
IOType.AudioOutput,
|
|
43
|
-
IOType.MidiOutput,
|
|
44
|
-
IOType.ForwardAudioOutput,
|
|
45
|
-
];
|
|
46
|
-
|
|
47
|
-
export function plugCompatibleIO(io1: AnyIO, io2: AnyIO): void {
|
|
48
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
49
|
-
// @ts-ignore
|
|
50
|
-
io1.plug(io2);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function unPlugCompatibleIO(io1: AnyIO, io2: AnyIO) {
|
|
54
|
-
if (!io1.connections.some((io) => io.id === io2.id)) return;
|
|
55
|
-
|
|
56
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
57
|
-
// @ts-ignore
|
|
58
|
-
io1.unPlug(io2);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export default abstract class IONode implements IIONode {
|
|
62
|
-
id: string;
|
|
63
|
-
ioType!: IOType;
|
|
64
|
-
name!: string;
|
|
65
|
-
plugableModule: AudioModule;
|
|
66
|
-
connections: IONode[] = [];
|
|
67
|
-
|
|
68
|
-
static unPlugAll(io: IONode): void {
|
|
69
|
-
io.connections.forEach((otherIO) => io.unPlug(otherIO));
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
constructor(plugableModule: AudioModule, props: IIONode) {
|
|
73
|
-
this.plugableModule = plugableModule;
|
|
74
|
-
this.id = deterministicId(plugableModule.id, props.name);
|
|
75
|
-
|
|
76
|
-
Object.assign(this, props);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
plug(io: IONode, plugOther: boolean = true) {
|
|
80
|
-
this.connections.push(io);
|
|
81
|
-
if (plugOther) io.plug(this, false);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
unPlug(io: IONode, plugOther: boolean = true) {
|
|
85
|
-
this.connections = this.connections.filter(
|
|
86
|
-
(currentIO) => currentIO.id !== io.id
|
|
87
|
-
);
|
|
88
|
-
if (plugOther) io.unPlug(this, false);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
get isInput() {
|
|
92
|
-
return IOInputs.indexOf(this.ioType) > -1;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
get isOutput() {
|
|
96
|
-
return IOOutputs.indexOf(this.ioType) > -1;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
get isAudio() {
|
|
100
|
-
return AudioIO.indexOf(this.ioType) > -1;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
get isMidi() {
|
|
104
|
-
return MidiIO.indexOf(this.ioType) > -1;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
abstract unPlugAll(): void;
|
|
108
|
-
|
|
109
|
-
serialize(): IIOSerialize {
|
|
110
|
-
return {
|
|
111
|
-
id: this.id,
|
|
112
|
-
name: this.name,
|
|
113
|
-
moduleId: this.plugableModule.id,
|
|
114
|
-
moduleName: this.plugableModule.name,
|
|
115
|
-
ioType: this.ioType,
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
}
|
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import { v4 as uuidv4 } from "uuid";
|
|
2
|
-
import { InputNode, Time } from "tone";
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
IOCollection,
|
|
6
|
-
AudioInput,
|
|
7
|
-
AudioOutput,
|
|
8
|
-
MidiInput,
|
|
9
|
-
IMidiInput,
|
|
10
|
-
IAudioInput,
|
|
11
|
-
IAudioOutput,
|
|
12
|
-
IOType,
|
|
13
|
-
MidiOutput,
|
|
14
|
-
IMidiOutput,
|
|
15
|
-
} from "../IO";
|
|
16
|
-
import { MidiEvent } from "../../core/midi";
|
|
17
|
-
import { AudioModule } from "./index";
|
|
18
|
-
import Note from "../../core/Note";
|
|
19
|
-
import { plugCompatibleIO } from "../IO/Node";
|
|
20
|
-
import { AtLeast } from "../../types";
|
|
21
|
-
|
|
22
|
-
export interface Startable {
|
|
23
|
-
start(time: number): void;
|
|
24
|
-
stop(time: number): void;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface Connectable {
|
|
28
|
-
connect: (inputNode: InputNode) => void;
|
|
29
|
-
disconnect: (inputNode?: InputNode) => void;
|
|
30
|
-
dispose: () => void;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface Triggerable {
|
|
34
|
-
triggerAttack: (note: Note, triggeredAt: number) => void;
|
|
35
|
-
triggerRelease: (note: Note, triggeredAt: number) => void;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface ModuleInterface<PropsInterface> {
|
|
39
|
-
id: string;
|
|
40
|
-
name: string;
|
|
41
|
-
props: PropsInterface;
|
|
42
|
-
voiceNo?: number;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export class DummnyInternalModule implements Connectable {
|
|
46
|
-
connect() {
|
|
47
|
-
throw Error("This module is not connectable");
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
disconnect() {
|
|
51
|
-
throw Error("This module is not connectable");
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
dispose() {
|
|
55
|
-
// do nothing
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
abstract class Module<InternalModule extends Connectable, PropsInterface>
|
|
60
|
-
implements ModuleInterface<PropsInterface>
|
|
61
|
-
{
|
|
62
|
-
static readonly moduleName: string;
|
|
63
|
-
|
|
64
|
-
readonly id: string;
|
|
65
|
-
name: string;
|
|
66
|
-
internalModule: InternalModule;
|
|
67
|
-
inputs: IOCollection<AudioInput | MidiInput>;
|
|
68
|
-
outputs: IOCollection<AudioOutput | MidiOutput>;
|
|
69
|
-
readonly voiceNo?: number;
|
|
70
|
-
updatedAt: Date;
|
|
71
|
-
_props: PropsInterface = {} as PropsInterface;
|
|
72
|
-
|
|
73
|
-
constructor(
|
|
74
|
-
internalModule: InternalModule,
|
|
75
|
-
props: AtLeast<ModuleInterface<PropsInterface>, "name">
|
|
76
|
-
) {
|
|
77
|
-
this.internalModule = internalModule;
|
|
78
|
-
this.id = props.id || uuidv4();
|
|
79
|
-
delete props.id;
|
|
80
|
-
|
|
81
|
-
this.inputs = new IOCollection<AudioInput | MidiInput>(this);
|
|
82
|
-
this.outputs = new IOCollection<AudioOutput | MidiOutput>(this);
|
|
83
|
-
|
|
84
|
-
Object.assign(this, props);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
set props(value: PropsInterface) {
|
|
88
|
-
if (!value) return;
|
|
89
|
-
|
|
90
|
-
this.updatedAt = new Date();
|
|
91
|
-
|
|
92
|
-
Object.assign(this, value);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
get props() {
|
|
96
|
-
return this._props;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
plug(audioModule: AudioModule, from: string, to: string) {
|
|
100
|
-
const output = this.outputs.findByName(from);
|
|
101
|
-
if (!output) throw Error(`Output ${from} not exist`);
|
|
102
|
-
|
|
103
|
-
const input = audioModule.inputs.findByName(to);
|
|
104
|
-
if (!input) throw Error(`Input ${to} not exist`);
|
|
105
|
-
|
|
106
|
-
plugCompatibleIO(input, output);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
unPlugAll() {
|
|
110
|
-
this.outputs.unPlugAll();
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
dispose() {
|
|
114
|
-
this.inputs.unPlugAll();
|
|
115
|
-
this.outputs.unPlugAll();
|
|
116
|
-
this.internalModule.dispose();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
120
|
-
triggerAttack = (note: Note, triggeredAt: number): void => {
|
|
121
|
-
throw Error("triggerAttack not implemented");
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
125
|
-
triggerRelease = (note: Note, triggeredAt: number): void => {
|
|
126
|
-
throw Error("triggerRelease not implemented");
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
onMidiEvent = (midiEvent: MidiEvent) => {
|
|
130
|
-
if (midiEvent.voiceNo !== undefined && midiEvent.voiceNo !== this.voiceNo)
|
|
131
|
-
return;
|
|
132
|
-
|
|
133
|
-
const { note, triggeredAt } = midiEvent;
|
|
134
|
-
|
|
135
|
-
switch (midiEvent.type) {
|
|
136
|
-
case "noteOn": {
|
|
137
|
-
const { duration } = note;
|
|
138
|
-
|
|
139
|
-
this.triggerer(this.triggerAttack, note, triggeredAt);
|
|
140
|
-
|
|
141
|
-
if (duration) {
|
|
142
|
-
const releaseTriggeredAt = triggeredAt + Time(duration).toSeconds();
|
|
143
|
-
|
|
144
|
-
this.triggerer(this.triggerRelease, note, releaseTriggeredAt);
|
|
145
|
-
}
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
148
|
-
case "noteOff":
|
|
149
|
-
this.triggerer(this.triggerRelease, note, triggeredAt);
|
|
150
|
-
break;
|
|
151
|
-
default:
|
|
152
|
-
throw Error("This type is not a note");
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
private triggerer(
|
|
157
|
-
trigger: (note: Note, triggeredAt: number) => void,
|
|
158
|
-
note: Note,
|
|
159
|
-
triggeredAt: number
|
|
160
|
-
) {
|
|
161
|
-
trigger(note, triggeredAt);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
serialize() {
|
|
165
|
-
const klass = this.constructor as typeof Module;
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
id: this.id,
|
|
169
|
-
name: this.name,
|
|
170
|
-
type: klass.moduleName,
|
|
171
|
-
props: this.props,
|
|
172
|
-
inputs: this.inputs.serialize(),
|
|
173
|
-
outputs: this.outputs.serialize(),
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
protected registerMidiInput(props: Omit<IMidiInput, "ioType">): MidiInput {
|
|
178
|
-
return this.inputs.add({ ...props, ioType: IOType.MidiInput });
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
protected registerAudioInput(props: Omit<IAudioInput, "ioType">): AudioInput {
|
|
182
|
-
return this.inputs.add({ ...props, ioType: IOType.AudioInput });
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
protected registerMidiOutput(props: Omit<IMidiOutput, "ioType">): MidiOutput {
|
|
186
|
-
return this.outputs.add({ ...props, ioType: IOType.MidiOutput });
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
protected registerAudioOutput(
|
|
190
|
-
props: Omit<IAudioOutput, "ioType">
|
|
191
|
-
): AudioOutput {
|
|
192
|
-
return this.outputs.add({ ...props, ioType: IOType.AudioOutput });
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
protected registerBasicOutputs() {
|
|
196
|
-
this.registerAudioOutput({
|
|
197
|
-
name: "output",
|
|
198
|
-
internalModule: this.internalModule,
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
protected registerBasicInputs() {
|
|
203
|
-
this.registerAudioInput({
|
|
204
|
-
name: "input",
|
|
205
|
-
internalModule: this.internalModule as unknown as InputNode,
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
this.registerDefaultMidiInput();
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
protected registerDefaultMidiInput() {
|
|
212
|
-
this.registerMidiInput({
|
|
213
|
-
name: "midi in",
|
|
214
|
-
onMidiEvent: this.onMidiEvent,
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
export default Module;
|