@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
package/src/modules/LFO.ts
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { now, LFO as LFOInternal, ToneOscillatorType } from "tone";
|
|
2
|
-
import Engine from "../Engine";
|
|
3
|
-
import Module, { PolyModule, Startable } from "../core/Module";
|
|
4
|
-
import { TWave } from "./Oscillator";
|
|
5
|
-
import Note from "../core/Note";
|
|
6
|
-
|
|
7
|
-
export interface LFOInterface {
|
|
8
|
-
wave: TWave;
|
|
9
|
-
frequency: number;
|
|
10
|
-
min: number;
|
|
11
|
-
max: number;
|
|
12
|
-
amount: number;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const InitialProps: LFOInterface = {
|
|
16
|
-
wave: "sine",
|
|
17
|
-
frequency: 0.1,
|
|
18
|
-
min: 0,
|
|
19
|
-
max: 1,
|
|
20
|
-
amount: 1,
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
class MonoLFO extends Module<LFOInternal, LFOInterface> implements Startable {
|
|
24
|
-
constructor(params: {
|
|
25
|
-
id?: string;
|
|
26
|
-
name: string;
|
|
27
|
-
props: Partial<LFOInterface>;
|
|
28
|
-
}) {
|
|
29
|
-
const { id, name, props } = params;
|
|
30
|
-
|
|
31
|
-
super(new LFOInternal(), {
|
|
32
|
-
id,
|
|
33
|
-
name,
|
|
34
|
-
props: { ...InitialProps, ...props },
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
this.registerBasicOutputs();
|
|
38
|
-
this.registerInputs();
|
|
39
|
-
this.start(now());
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
get wave() {
|
|
43
|
-
return this._props["wave"];
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
set wave(value: TWave) {
|
|
47
|
-
this._props = { ...this.props, wave: value };
|
|
48
|
-
this.internalModule.type = this.wave as ToneOscillatorType;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
get min() {
|
|
52
|
-
return this._props["min"];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
set min(value: number) {
|
|
56
|
-
this._props = { ...this.props, min: value };
|
|
57
|
-
this.internalModule.min = this.min;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
get max() {
|
|
61
|
-
return this._props["max"];
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
set max(value: number) {
|
|
65
|
-
this._props = { ...this.props, max: value };
|
|
66
|
-
this.internalModule.max = this.max;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
get frequency() {
|
|
70
|
-
return this._props["frequency"];
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
set frequency(value: number) {
|
|
74
|
-
this._props = { ...this.props, frequency: value };
|
|
75
|
-
this.internalModule.frequency.value = this.frequency;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
get amount() {
|
|
79
|
-
return this._props["amount"];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
set amount(value: number) {
|
|
83
|
-
this._props = { ...this.props, amount: value };
|
|
84
|
-
this.internalModule.amplitude.value = this.amount;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
start(time: number) {
|
|
88
|
-
if (!Engine.isStarted) return;
|
|
89
|
-
|
|
90
|
-
const oscState = this.internalModule.state;
|
|
91
|
-
|
|
92
|
-
if (oscState === "started") {
|
|
93
|
-
this.internalModule.stop(time - 2);
|
|
94
|
-
this.internalModule.start(time);
|
|
95
|
-
} else {
|
|
96
|
-
this.internalModule.start(time);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
stop(time?: number) {
|
|
101
|
-
this.internalModule.stop(time);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
triggerAttack = (_: Note, triggeredAt: number) => {
|
|
105
|
-
this.start(triggeredAt);
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
triggerRelease = () => {
|
|
109
|
-
// Do nothing
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
private registerInputs() {
|
|
113
|
-
this.registerAudioInput({
|
|
114
|
-
name: "amount",
|
|
115
|
-
internalModule: this.internalModule.amplitude,
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export default class LFO extends PolyModule<MonoLFO, LFOInterface> {
|
|
121
|
-
static moduleName = "LFO";
|
|
122
|
-
|
|
123
|
-
constructor(params: {
|
|
124
|
-
id?: string;
|
|
125
|
-
name: string;
|
|
126
|
-
props: Partial<LFOInterface>;
|
|
127
|
-
}) {
|
|
128
|
-
const { id, name, props } = params;
|
|
129
|
-
|
|
130
|
-
super({
|
|
131
|
-
id,
|
|
132
|
-
name,
|
|
133
|
-
child: MonoLFO,
|
|
134
|
-
props: { ...InitialProps, ...props },
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
this.registerBasicOutputs();
|
|
138
|
-
this.registerMidiIn();
|
|
139
|
-
this.registerForwardAudioInput({ name: "amount" });
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
start(time: number) {
|
|
143
|
-
this.audioModules.forEach((audioModule) => audioModule.start(time));
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
stop(time?: number) {
|
|
147
|
-
this.audioModules.forEach((audioModule) => audioModule.stop(time));
|
|
148
|
-
}
|
|
149
|
-
}
|
package/src/modules/Reverb.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { Reverb as InternalReverb } from "tone";
|
|
2
|
-
|
|
3
|
-
import Effect, { EffectInterface } from "./Effect";
|
|
4
|
-
|
|
5
|
-
interface ReverbInterface extends EffectInterface {
|
|
6
|
-
decay: number;
|
|
7
|
-
preDelay: number;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const InitialProps: Partial<ReverbInterface> = {
|
|
11
|
-
decay: 1.5,
|
|
12
|
-
preDelay: 0.025,
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export default class Reverb extends Effect<InternalReverb, ReverbInterface> {
|
|
16
|
-
static moduleName = "Reverb";
|
|
17
|
-
|
|
18
|
-
constructor(params: {
|
|
19
|
-
id?: string;
|
|
20
|
-
name: string;
|
|
21
|
-
props: Partial<ReverbInterface>;
|
|
22
|
-
}) {
|
|
23
|
-
const { id, name, props } = params;
|
|
24
|
-
|
|
25
|
-
super({
|
|
26
|
-
id,
|
|
27
|
-
name,
|
|
28
|
-
internalModule: new InternalReverb(),
|
|
29
|
-
props: {
|
|
30
|
-
...InitialProps,
|
|
31
|
-
...props,
|
|
32
|
-
},
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
get decay() {
|
|
37
|
-
return this._props["decay"];
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
set decay(value: number) {
|
|
41
|
-
this._props = { ...this.props, decay: value };
|
|
42
|
-
this.internalModule.decay = this.decay;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
get preDelay() {
|
|
46
|
-
return this._props["preDelay"];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
set preDelay(value: number) {
|
|
50
|
-
this._props = { ...this.props, preDelay: value };
|
|
51
|
-
this.internalModule.preDelay = this.preDelay;
|
|
52
|
-
}
|
|
53
|
-
}
|
package/src/modules/Sequencer.ts
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import { now, Part } from "tone";
|
|
2
|
-
import Module, { DummnyInternalModule } from "../core/Module";
|
|
3
|
-
import { INote } from "../core/Note";
|
|
4
|
-
import { MidiOutput } from "../core/IO";
|
|
5
|
-
import { MidiEvent } from "../core/midi";
|
|
6
|
-
import Engine from "../Engine";
|
|
7
|
-
|
|
8
|
-
export interface ISequence {
|
|
9
|
-
active: boolean;
|
|
10
|
-
time: string;
|
|
11
|
-
notes: INote[];
|
|
12
|
-
}
|
|
13
|
-
interface ISequencer {
|
|
14
|
-
sequences: ISequence[][];
|
|
15
|
-
steps: number;
|
|
16
|
-
bars: number;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const InitialProps = () => ({
|
|
20
|
-
sequences: [],
|
|
21
|
-
steps: 16,
|
|
22
|
-
bars: 1,
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
export default class Sequencer extends Module<
|
|
26
|
-
DummnyInternalModule,
|
|
27
|
-
ISequencer
|
|
28
|
-
> {
|
|
29
|
-
static moduleName = "Sequencer";
|
|
30
|
-
midiOutput: MidiOutput;
|
|
31
|
-
private part: Part<ISequence>;
|
|
32
|
-
|
|
33
|
-
constructor(params: {
|
|
34
|
-
id?: string;
|
|
35
|
-
name: string;
|
|
36
|
-
props: Partial<ISequencer>;
|
|
37
|
-
}) {
|
|
38
|
-
const { id, name, props } = params;
|
|
39
|
-
super(new DummnyInternalModule(), {
|
|
40
|
-
id,
|
|
41
|
-
name,
|
|
42
|
-
props: { ...InitialProps(), ...props },
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
this.initializePart();
|
|
46
|
-
this.start(now());
|
|
47
|
-
this.registerOutputs();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
get props() {
|
|
51
|
-
return super.props;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
set props(value: ISequencer) {
|
|
55
|
-
if (!this.sequences) this._props["sequences"] = [];
|
|
56
|
-
|
|
57
|
-
super.props = { ...this.props, ...value };
|
|
58
|
-
this.adjust();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
get steps() {
|
|
62
|
-
return this._props["steps"];
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
set steps(value: number) {
|
|
66
|
-
this._props = { ...this.props, steps: value };
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
get bars() {
|
|
70
|
-
return this.props["bars"];
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
set bars(value: number) {
|
|
74
|
-
this._props = { ...this.props, bars: value };
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
get sequences() {
|
|
78
|
-
return this._props["sequences"];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
set sequences(value: ISequence[][]) {
|
|
82
|
-
const sequences = value;
|
|
83
|
-
this._props = { ...this.props, sequences };
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
start(time: number) {
|
|
87
|
-
if (!Engine.isStarted) return;
|
|
88
|
-
|
|
89
|
-
this.part.start(time);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
stop() {
|
|
93
|
-
this.part.stop();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
private registerOutputs() {
|
|
97
|
-
this.midiOutput = this.registerMidiOutput({ name: "midi out" });
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
private initializePart() {
|
|
101
|
-
this.part = new Part(this.onPartEvent, [] as ISequence[]);
|
|
102
|
-
this.part.loop = true;
|
|
103
|
-
this.part.loopEnd = this.loopEnd;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
private adjust() {
|
|
107
|
-
if (!this.part) return;
|
|
108
|
-
|
|
109
|
-
this.adjustNumberOfBars();
|
|
110
|
-
this.adjustNumberOfSteps();
|
|
111
|
-
this.updateBarParts();
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
private adjustNumberOfBars() {
|
|
115
|
-
const currentBar = this.sequences.length;
|
|
116
|
-
const num = currentBar - this.bars;
|
|
117
|
-
const sequences = [...this.sequences];
|
|
118
|
-
|
|
119
|
-
if (num === 0) return;
|
|
120
|
-
|
|
121
|
-
if (num > 0) {
|
|
122
|
-
sequences.pop();
|
|
123
|
-
} else {
|
|
124
|
-
sequences.push([]);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
this.sequences = sequences;
|
|
128
|
-
this.adjustNumberOfBars();
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
private adjustNumberOfSteps(bar = 0) {
|
|
132
|
-
if (!this.bars) return;
|
|
133
|
-
|
|
134
|
-
const allSequences = [...this.sequences];
|
|
135
|
-
const sequences = [...allSequences[bar]];
|
|
136
|
-
const num = sequences.length - this.steps;
|
|
137
|
-
|
|
138
|
-
if (num === 0) {
|
|
139
|
-
if (bar === this.bars - 1) return;
|
|
140
|
-
|
|
141
|
-
this.adjustNumberOfSteps(bar + 1);
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if (num > 0) {
|
|
146
|
-
sequences.pop();
|
|
147
|
-
} else {
|
|
148
|
-
const index = sequences.length;
|
|
149
|
-
sequences.push({ active: false, time: `${bar}:0:${index}`, notes: [] });
|
|
150
|
-
}
|
|
151
|
-
allSequences[bar] = sequences;
|
|
152
|
-
this.sequences = allSequences;
|
|
153
|
-
|
|
154
|
-
this.adjustNumberOfSteps(bar);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
private updateBarParts() {
|
|
158
|
-
this.part.clear();
|
|
159
|
-
|
|
160
|
-
this.sequences.forEach((barSeqs) => {
|
|
161
|
-
barSeqs.forEach((seq) => this.part.add(seq.time, seq));
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
this.part.loopEnd = this.loopEnd;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
private get loopEnd() {
|
|
168
|
-
return `${this.bars}:0:0`;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
private onPartEvent = (time: number, sequence: ISequence) => {
|
|
172
|
-
if (!sequence.active) return;
|
|
173
|
-
|
|
174
|
-
MidiEvent.fromSequence(sequence, time).forEach((event) => {
|
|
175
|
-
this.midiOutput.onMidiEvent(event);
|
|
176
|
-
});
|
|
177
|
-
};
|
|
178
|
-
}
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import { MidiEvent } from "../core/midi";
|
|
2
|
-
import Module, { PolyModule, DummnyInternalModule } from "../core/Module";
|
|
3
|
-
import { MidiOutput } from "../core/IO";
|
|
4
|
-
|
|
5
|
-
export interface VoiceSchedulerInterface {
|
|
6
|
-
polyNumber: number;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export default class VoiceScheduler extends PolyModule<
|
|
10
|
-
Voice,
|
|
11
|
-
VoiceSchedulerInterface
|
|
12
|
-
> {
|
|
13
|
-
static moduleName = "VoiceScheduler";
|
|
14
|
-
midiOutput: MidiOutput;
|
|
15
|
-
|
|
16
|
-
constructor(params: {
|
|
17
|
-
id?: string;
|
|
18
|
-
name: string;
|
|
19
|
-
props: VoiceSchedulerInterface;
|
|
20
|
-
}) {
|
|
21
|
-
const { id, name, props } = params;
|
|
22
|
-
|
|
23
|
-
super({
|
|
24
|
-
id,
|
|
25
|
-
name,
|
|
26
|
-
child: Voice,
|
|
27
|
-
props,
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
this.registerInputs();
|
|
31
|
-
this.registerOutputs();
|
|
32
|
-
this.polyNumber = this.numberOfVoices;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
set polyNumber(value: number) {
|
|
36
|
-
super.numberOfVoices = value;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
get polyNumber() {
|
|
40
|
-
return this.numberOfVoices;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
onMidiEvent = (midiEvent: MidiEvent) => {
|
|
44
|
-
let voice: Voice | undefined;
|
|
45
|
-
|
|
46
|
-
switch (midiEvent.type) {
|
|
47
|
-
case "noteOn":
|
|
48
|
-
voice = this.findFreeVoice();
|
|
49
|
-
|
|
50
|
-
break;
|
|
51
|
-
case "noteOff":
|
|
52
|
-
voice = this.audioModules.find(
|
|
53
|
-
(v) => v.activeNote === midiEvent.note.fullName
|
|
54
|
-
);
|
|
55
|
-
break;
|
|
56
|
-
default:
|
|
57
|
-
throw Error("This type is not a note");
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (!voice) return;
|
|
61
|
-
|
|
62
|
-
voice.midiTriggered(midiEvent);
|
|
63
|
-
midiEvent.voiceNo = voice.voiceNo;
|
|
64
|
-
this.midiOutput.onMidiEvent(midiEvent);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
serialize() {
|
|
68
|
-
const serialize = super.serialize();
|
|
69
|
-
|
|
70
|
-
return {
|
|
71
|
-
...serialize,
|
|
72
|
-
props: { ...serialize.props, polyNumber: this.polyNumber },
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
private findFreeVoice(): Voice {
|
|
77
|
-
let voice = this.audioModules.find((v) => !v.activeNote);
|
|
78
|
-
|
|
79
|
-
// If no available voice, get the one with the lowest triggeredAt
|
|
80
|
-
if (!voice) {
|
|
81
|
-
voice = this.audioModules.sort((a, b) => {
|
|
82
|
-
if (!a || !b) return 0;
|
|
83
|
-
|
|
84
|
-
return a.triggeredAt - b.triggeredAt;
|
|
85
|
-
})[0];
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return voice;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
private registerInputs() {
|
|
92
|
-
this.registerMidiInput({
|
|
93
|
-
name: "midi in",
|
|
94
|
-
onMidiEvent: this.onMidiEvent,
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
private registerOutputs() {
|
|
99
|
-
this.midiOutput = this.registerMidiOutput({ name: "midi out" });
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
class Voice extends Module<DummnyInternalModule, VoiceSchedulerInterface> {
|
|
104
|
-
midiEvent: MidiEvent | null;
|
|
105
|
-
activeNote: string | null;
|
|
106
|
-
triggeredAt: number;
|
|
107
|
-
|
|
108
|
-
constructor(params: {
|
|
109
|
-
id?: string;
|
|
110
|
-
name: string;
|
|
111
|
-
props: VoiceSchedulerInterface;
|
|
112
|
-
}) {
|
|
113
|
-
const { id, name, props } = params;
|
|
114
|
-
|
|
115
|
-
super(new DummnyInternalModule(), {
|
|
116
|
-
id,
|
|
117
|
-
name,
|
|
118
|
-
props,
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
midiTriggered = (midiEvent: MidiEvent) => {
|
|
123
|
-
if (this.voiceNo === undefined) throw Error("Voice without voiceNo");
|
|
124
|
-
|
|
125
|
-
const { triggeredAt, note, type } = midiEvent;
|
|
126
|
-
|
|
127
|
-
if (!note) return;
|
|
128
|
-
const noteName = note.fullName;
|
|
129
|
-
|
|
130
|
-
switch (type) {
|
|
131
|
-
case "noteOn":
|
|
132
|
-
this.activeNote = noteName;
|
|
133
|
-
this.triggeredAt = triggeredAt;
|
|
134
|
-
this.midiEvent = midiEvent;
|
|
135
|
-
|
|
136
|
-
break;
|
|
137
|
-
case "noteOff":
|
|
138
|
-
this.activeNote = null;
|
|
139
|
-
this.midiEvent = null;
|
|
140
|
-
break;
|
|
141
|
-
default:
|
|
142
|
-
throw Error("This type is not a note");
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
}
|
package/src/modules/Volume.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { Volume as Vol } from "tone";
|
|
2
|
-
|
|
3
|
-
import Module, { PolyModule } from "../core/Module";
|
|
4
|
-
import Note from "../core/Note";
|
|
5
|
-
|
|
6
|
-
export interface VolumeInterface {
|
|
7
|
-
volume: number;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const InitialProps: VolumeInterface = {
|
|
11
|
-
volume: -Infinity,
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
class MonoVolume extends Module<Vol, VolumeInterface> {
|
|
15
|
-
constructor(params: {
|
|
16
|
-
id?: string;
|
|
17
|
-
name: string;
|
|
18
|
-
props: Partial<VolumeInterface>;
|
|
19
|
-
}) {
|
|
20
|
-
const { id, name, props } = params;
|
|
21
|
-
|
|
22
|
-
super(new Vol(), {
|
|
23
|
-
id,
|
|
24
|
-
name,
|
|
25
|
-
props: { ...InitialProps, ...props },
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
this.registerBasicInputs();
|
|
29
|
-
this.registerBasicOutputs();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
get volume() {
|
|
33
|
-
return this._props["volume"];
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
set volume(value: number) {
|
|
37
|
-
this._props = { ...this.props, volume: value };
|
|
38
|
-
|
|
39
|
-
this.internalModule.volume.value = this.volume;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
triggerAttack = (note: Note, triggeredAt: number) => {
|
|
43
|
-
const db = 20 * Math.log10(note.velocity);
|
|
44
|
-
this.internalModule.volume.exponentialRampToValueAtTime(db, triggeredAt);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
triggerRelease = () => {
|
|
48
|
-
// Do nothing
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export default class Volume extends PolyModule<MonoVolume, VolumeInterface> {
|
|
53
|
-
static moduleName = "Volume";
|
|
54
|
-
|
|
55
|
-
constructor(params: {
|
|
56
|
-
id?: string;
|
|
57
|
-
name: string;
|
|
58
|
-
props: Partial<VolumeInterface>;
|
|
59
|
-
}) {
|
|
60
|
-
const { id, name, props } = params;
|
|
61
|
-
|
|
62
|
-
super({
|
|
63
|
-
id,
|
|
64
|
-
name,
|
|
65
|
-
child: MonoVolume,
|
|
66
|
-
props: { ...InitialProps, ...props },
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
this.registerBasicInputs();
|
|
70
|
-
this.registerBasicOutputs();
|
|
71
|
-
}
|
|
72
|
-
}
|
package/src/routes.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { v4 as uuidv4 } from "uuid";
|
|
2
|
-
|
|
3
|
-
import Engine from "./";
|
|
4
|
-
import { plugCompatibleIO } from "./core/IO/Node";
|
|
5
|
-
import { Optional } from "./types";
|
|
6
|
-
|
|
7
|
-
export interface RouteProps {
|
|
8
|
-
sourceId: string;
|
|
9
|
-
sourceIOId: string;
|
|
10
|
-
destinationId: string;
|
|
11
|
-
destinationIOId: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface RouteInterface extends RouteProps {
|
|
15
|
-
id: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function createRoute(props: Optional<RouteInterface, "id">) {
|
|
19
|
-
const id = props.id || uuidv4();
|
|
20
|
-
|
|
21
|
-
return { ...props, id };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function applyRoutes(routes: RouteInterface[]) {
|
|
25
|
-
Object.values(Engine.modules).forEach((m) => {
|
|
26
|
-
m.unPlugAll();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
const succesedConnections = routes.map((route) => {
|
|
30
|
-
const { sourceId, sourceIOId, destinationId, destinationIOId } = route;
|
|
31
|
-
|
|
32
|
-
const source = Engine.findById(sourceId);
|
|
33
|
-
const destination = Engine.findById(destinationId);
|
|
34
|
-
|
|
35
|
-
const output = source.outputs.find(sourceIOId);
|
|
36
|
-
const input = destination.inputs.find(destinationIOId);
|
|
37
|
-
if (!input || !output) throw Error("IO not found");
|
|
38
|
-
|
|
39
|
-
plugCompatibleIO(input, output);
|
|
40
|
-
|
|
41
|
-
return true;
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
if (succesedConnections.every((v) => v)) {
|
|
45
|
-
console.log("######## Routes succesfully applied");
|
|
46
|
-
} else {
|
|
47
|
-
console.log("######## Routes partialy applied");
|
|
48
|
-
}
|
|
49
|
-
}
|
package/src/types.ts
DELETED
package/src/utils.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import CryptoJS from "crypto-js";
|
|
2
|
-
|
|
3
|
-
export function deterministicId(
|
|
4
|
-
originalId: string,
|
|
5
|
-
additionalString: string
|
|
6
|
-
): string {
|
|
7
|
-
const combinedString = `${originalId}:${additionalString}`;
|
|
8
|
-
const hash = CryptoJS.SHA256(combinedString).toString(CryptoJS.enc.Hex);
|
|
9
|
-
|
|
10
|
-
const newId = `${hash.substring(0, 8)}-${hash.substring(
|
|
11
|
-
8,
|
|
12
|
-
12
|
|
13
|
-
)}-4${hash.substring(13, 16)}-${
|
|
14
|
-
"89AB"[parseInt(hash.substring(17, 18), 16) % 4]
|
|
15
|
-
}${hash.substring(18, 21)}-${hash.substring(21, 33)}`;
|
|
16
|
-
|
|
17
|
-
return newId;
|
|
18
|
-
}
|
package/src/vite-env.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/// <reference types="vite/client" />
|