@blibliki/engine 0.1.17 → 0.1.18
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/.eslintrc.js +14 -0
- package/.parcerc +6 -0
- package/README.md +13 -1
- package/dist/main.cjs.js +33 -0
- package/package.json +21 -22
- package/rollup.config.mjs +21 -0
- package/src/Engine.ts +27 -36
- package/src/core/IO/AudioNode.ts +77 -0
- package/src/core/IO/Collection.ts +76 -0
- package/src/core/IO/ForwardNode.ts +192 -0
- package/src/core/IO/MidiNode.ts +67 -0
- package/src/core/IO/Node.ts +117 -0
- package/src/core/IO/index.ts +47 -0
- package/src/core/Module/MonoModule.ts +219 -0
- package/src/core/Module/PolyModule.ts +206 -0
- package/src/core/Module/index.ts +15 -0
- package/src/{Note → core/Note}/index.ts +19 -4
- package/src/{MidiDeviceManager.ts → core/midi/MidiDeviceManager.ts} +20 -15
- package/src/core/midi/MidiEvent.ts +91 -0
- package/src/core/midi/index.ts +5 -0
- package/src/index.ts +8 -12
- package/src/{Module → modules}/BitCrusher.ts +15 -4
- package/src/{Module → modules}/Delay.ts +15 -4
- package/src/{Module → modules}/Distortion.ts +15 -4
- package/src/{Module → modules}/Effect.ts +10 -6
- package/src/modules/Envelope/AmpEnvelope.ts +23 -0
- package/src/{Module → modules}/Envelope/Base.ts +50 -31
- package/src/{Module → modules}/Envelope/FreqEnvelope.ts +18 -23
- package/src/{Module → modules}/Filter.ts +18 -46
- package/src/{Module → modules}/Master.ts +8 -2
- package/src/{Module → modules}/MidiSelector.ts +18 -14
- package/src/{Module → modules}/Oscillator.ts +27 -16
- package/src/{Module → modules}/Reverb.ts +15 -4
- package/src/{Module → modules}/Sequencer.ts +17 -13
- package/src/{Module → modules}/VirtualMidi.ts +16 -12
- package/src/modules/VoiceScheduler.ts +145 -0
- package/src/{Module → modules}/Volume.ts +23 -15
- package/src/{Module → modules}/index.ts +14 -21
- package/src/routes.ts +19 -18
- package/src/types.ts +3 -0
- package/src/utils.ts +18 -0
- package/test/MockingModules.ts +27 -0
- package/test/Module/Oscillator.test.ts +1 -1
- package/test/core/IO.test.ts +172 -0
- package/build/Engine.d.ts +0 -89
- package/build/Engine.js +0 -165
- package/build/Engine.js.map +0 -1
- package/build/MidiDevice.d.ts +0 -25
- package/build/MidiDevice.js +0 -45
- package/build/MidiDevice.js.map +0 -1
- package/build/MidiDeviceManager.d.ts +0 -13
- package/build/MidiDeviceManager.js +0 -59
- package/build/MidiDeviceManager.js.map +0 -1
- package/build/MidiEvent.d.ts +0 -18
- package/build/MidiEvent.js +0 -64
- package/build/MidiEvent.js.map +0 -1
- package/build/Module/Base.d.ts +0 -63
- package/build/Module/Base.js +0 -138
- package/build/Module/Base.js.map +0 -1
- package/build/Module/BitCrusher.d.ts +0 -12
- package/build/Module/BitCrusher.js +0 -22
- package/build/Module/BitCrusher.js.map +0 -1
- package/build/Module/DataSequencer.d.ts +0 -26
- package/build/Module/DataSequencer.js +0 -91
- package/build/Module/DataSequencer.js.map +0 -1
- package/build/Module/Delay.d.ts +0 -15
- package/build/Module/Delay.js +0 -30
- package/build/Module/Delay.js.map +0 -1
- package/build/Module/Distortion.d.ts +0 -12
- package/build/Module/Distortion.js +0 -22
- package/build/Module/Distortion.js.map +0 -1
- package/build/Module/Effect.d.ts +0 -14
- package/build/Module/Effect.js +0 -22
- package/build/Module/Effect.js.map +0 -1
- package/build/Module/Envelope/AmpEnvelope.d.ts +0 -10
- package/build/Module/Envelope/AmpEnvelope.js +0 -14
- package/build/Module/Envelope/AmpEnvelope.js.map +0 -1
- package/build/Module/Envelope/Base.d.ts +0 -47
- package/build/Module/Envelope/Base.js +0 -106
- package/build/Module/Envelope/Base.js.map +0 -1
- package/build/Module/Envelope/FreqEnvelope.d.ts +0 -18
- package/build/Module/Envelope/FreqEnvelope.js +0 -50
- package/build/Module/Envelope/FreqEnvelope.js.map +0 -1
- package/build/Module/Envelope/index.d.ts +0 -3
- package/build/Module/Envelope/index.js +0 -4
- package/build/Module/Envelope/index.js.map +0 -1
- package/build/Module/Filter.d.ts +0 -37
- package/build/Module/Filter.js +0 -100
- package/build/Module/Filter.js.map +0 -1
- package/build/Module/IO.d.ts +0 -39
- package/build/Module/IO.js +0 -59
- package/build/Module/IO.js.map +0 -1
- package/build/Module/Master.d.ts +0 -8
- package/build/Module/Master.js +0 -12
- package/build/Module/Master.js.map +0 -1
- package/build/Module/MidiSelector.d.ts +0 -17
- package/build/Module/MidiSelector.js +0 -50
- package/build/Module/MidiSelector.js.map +0 -1
- package/build/Module/Oscillator.d.ts +0 -45
- package/build/Module/Oscillator.js +0 -136
- package/build/Module/Oscillator.js.map +0 -1
- package/build/Module/PolyModule.d.ts +0 -49
- package/build/Module/PolyModule.js +0 -175
- package/build/Module/PolyModule.js.map +0 -1
- package/build/Module/Reverb.d.ts +0 -15
- package/build/Module/Reverb.js +0 -30
- package/build/Module/Reverb.js.map +0 -1
- package/build/Module/Sequencer.d.ts +0 -38
- package/build/Module/Sequencer.js +0 -131
- package/build/Module/Sequencer.js.map +0 -1
- package/build/Module/VirtualMidi.d.ts +0 -28
- package/build/Module/VirtualMidi.js +0 -53
- package/build/Module/VirtualMidi.js.map +0 -1
- package/build/Module/VoiceScheduler.d.ts +0 -38
- package/build/Module/VoiceScheduler.js +0 -130
- package/build/Module/VoiceScheduler.js.map +0 -1
- package/build/Module/Volume.d.ts +0 -20
- package/build/Module/Volume.js +0 -48
- package/build/Module/Volume.js.map +0 -1
- package/build/Module/index.d.ts +0 -14
- package/build/Module/index.js +0 -66
- package/build/Module/index.js.map +0 -1
- package/build/Note/frequencyTable.d.ts +0 -4
- package/build/Note/frequencyTable.js +0 -146
- package/build/Note/frequencyTable.js.map +0 -1
- package/build/Note/index.d.ts +0 -25
- package/build/Note/index.js +0 -81
- package/build/Note/index.js.map +0 -1
- package/build/index.d.ts +0 -8
- package/build/index.js +0 -5
- package/build/index.js.map +0 -1
- package/build/routes.d.ts +0 -17
- package/build/routes.js +0 -31
- package/build/routes.js.map +0 -1
- package/src/MidiEvent.ts +0 -93
- package/src/Module/Base.ts +0 -223
- package/src/Module/DataSequencer.ts +0 -121
- package/src/Module/Envelope/AmpEnvelope.ts +0 -17
- package/src/Module/IO.ts +0 -85
- package/src/Module/PolyModule.ts +0 -234
- package/src/Module/VoiceScheduler.ts +0 -161
- /package/src/{Note → core/Note}/frequencyTable.ts +0 -0
- /package/src/{MidiDevice.ts → core/midi/MidiDevice.ts} +0 -0
- /package/src/{Module → modules}/Envelope/index.ts +0 -0
package/src/Module/PolyModule.ts
DELETED
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import MidiEvent from "../MidiEvent";
|
|
2
|
-
import { v4 as uuidv4 } from "uuid";
|
|
3
|
-
import Module, { Connectable, Voicable } from "./Base";
|
|
4
|
-
import { Input, Output, IOInterface } from "./IO";
|
|
5
|
-
import { AudioModule } from "../Module";
|
|
6
|
-
|
|
7
|
-
interface PolyModuleInterface<MonoAudioModule, PropsInterface> {
|
|
8
|
-
name: string;
|
|
9
|
-
child: new (name: string, props: PropsInterface) => MonoAudioModule;
|
|
10
|
-
props: PropsInterface;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export default abstract class PolyModule<
|
|
14
|
-
MonoAudioModule extends Module<Connectable, any>,
|
|
15
|
-
PropsInterface extends Voicable
|
|
16
|
-
> {
|
|
17
|
-
static readonly moduleName: string;
|
|
18
|
-
|
|
19
|
-
readonly id: string;
|
|
20
|
-
readonly child: new (name: string, props: PropsInterface) => MonoAudioModule;
|
|
21
|
-
_name: string;
|
|
22
|
-
audioModules: MonoAudioModule[];
|
|
23
|
-
inputs: Input[] = [];
|
|
24
|
-
outputs: Output[] = [];
|
|
25
|
-
private _numberOfVoices: number;
|
|
26
|
-
|
|
27
|
-
constructor(params: PolyModuleInterface<MonoAudioModule, PropsInterface>) {
|
|
28
|
-
this.id = uuidv4();
|
|
29
|
-
this.audioModules = [];
|
|
30
|
-
|
|
31
|
-
const { child, props: extraProps, ...basicProps } = params;
|
|
32
|
-
this.child = child;
|
|
33
|
-
Object.assign(this, basicProps);
|
|
34
|
-
|
|
35
|
-
this.numberOfVoices = 1;
|
|
36
|
-
|
|
37
|
-
Object.assign(this, { props: extraProps });
|
|
38
|
-
this.registerNumberOfVoicesInput();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
get name() {
|
|
42
|
-
return this._name;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
set name(value: string) {
|
|
46
|
-
this._name = value;
|
|
47
|
-
this.audioModules.forEach((m) => (m.name = value));
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
get props() {
|
|
51
|
-
if (this.audioModules.length === 0) {
|
|
52
|
-
throw Error("There isn't any initialized module");
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return this.audioModules[0].props;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
set props(value: PropsInterface) {
|
|
59
|
-
Object.assign(this, value);
|
|
60
|
-
this.audioModules.forEach((m) => (m.props = value));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
get numberOfVoices() {
|
|
64
|
-
return this._numberOfVoices;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
set numberOfVoices(value: number) {
|
|
68
|
-
this._numberOfVoices = value;
|
|
69
|
-
this.adjustNumberOfModules();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
plug(audioModule: AudioModule, from: string, to: string) {
|
|
73
|
-
const output = this.outputs.find((i) => i.name === from);
|
|
74
|
-
if (!output) throw Error(`Output ${from} not exist`);
|
|
75
|
-
|
|
76
|
-
const input = audioModule.inputs.find((i) => i.name === to);
|
|
77
|
-
if (!input)
|
|
78
|
-
throw Error(`Input ${to} in module ${audioModule.name} not exist`);
|
|
79
|
-
|
|
80
|
-
output.plug(input);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
unplugAll() {
|
|
84
|
-
this.outputs.forEach((o) => o.unPlugAll());
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
dispose() {
|
|
88
|
-
this.audioModules.forEach((m) => {
|
|
89
|
-
m.dispose();
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
midiTriggered = (
|
|
94
|
-
midiEvent: MidiEvent,
|
|
95
|
-
voiceNo: number = 0,
|
|
96
|
-
noteIndex?: number
|
|
97
|
-
) => {
|
|
98
|
-
const audioModule = this.findVoice(voiceNo);
|
|
99
|
-
audioModule?.midiTriggered(midiEvent, noteIndex);
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
serialize() {
|
|
103
|
-
if (this.audioModules.length === 0)
|
|
104
|
-
throw Error("There isn't any initialized module");
|
|
105
|
-
|
|
106
|
-
const klass = this.constructor as typeof PolyModule;
|
|
107
|
-
|
|
108
|
-
return {
|
|
109
|
-
...this.audioModules[0].serialize(),
|
|
110
|
-
id: this.id,
|
|
111
|
-
type: klass.moduleName,
|
|
112
|
-
inputs: this.inputs.map((i) => i.serialize()),
|
|
113
|
-
outputs: this.outputs.map((i) => i.serialize()),
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
protected connect = (
|
|
118
|
-
inputAudioModule: AudioModule,
|
|
119
|
-
attribute: string = "internalModule"
|
|
120
|
-
) => {
|
|
121
|
-
if (inputAudioModule instanceof PolyModule) {
|
|
122
|
-
inputAudioModule.audioModules.forEach((m) => {
|
|
123
|
-
if (m.voiceNo === undefined) throw Error("Voice error");
|
|
124
|
-
|
|
125
|
-
const audioModule = this.findVoice(m.voiceNo);
|
|
126
|
-
audioModule?.connect(m, attribute);
|
|
127
|
-
});
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
this.audioModules.forEach((m) => m.connect(inputAudioModule, attribute));
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
protected disconnect = (
|
|
135
|
-
inputAudioModule: AudioModule,
|
|
136
|
-
attribute: string = "internalModule"
|
|
137
|
-
) => {
|
|
138
|
-
if (inputAudioModule instanceof PolyModule) {
|
|
139
|
-
inputAudioModule.audioModules.forEach((m) => {
|
|
140
|
-
if (m.voiceNo === undefined) throw Error("Voice error");
|
|
141
|
-
|
|
142
|
-
const audioModule = this.findVoice(m.voiceNo);
|
|
143
|
-
|
|
144
|
-
try {
|
|
145
|
-
audioModule?.disconnect(m, attribute);
|
|
146
|
-
} catch (e) {
|
|
147
|
-
console.log(e);
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
try {
|
|
154
|
-
this.audioModules.forEach((m) =>
|
|
155
|
-
m.disconnect(inputAudioModule, attribute)
|
|
156
|
-
);
|
|
157
|
-
} catch (e) {
|
|
158
|
-
console.log(e);
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
protected registerInput(props: IOInterface): Input {
|
|
163
|
-
const input = new Input(this, props);
|
|
164
|
-
this.inputs.push(input);
|
|
165
|
-
|
|
166
|
-
return input;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
protected registerOutput(props: IOInterface): Output {
|
|
170
|
-
const output = new Output(this, props);
|
|
171
|
-
this.outputs.push(output);
|
|
172
|
-
|
|
173
|
-
return output;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
protected find(callback: (audioModule: MonoAudioModule) => boolean) {
|
|
177
|
-
const audioModule = this.audioModules.find(callback);
|
|
178
|
-
if (!audioModule) throw Error(`Audio module not found`);
|
|
179
|
-
|
|
180
|
-
return audioModule;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
protected findVoice(voiceNo: number) {
|
|
184
|
-
return this.audioModules.find((m) => m.voiceNo === voiceNo);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
protected registerBasicOutputs() {
|
|
188
|
-
this.registerOutput({
|
|
189
|
-
name: "output",
|
|
190
|
-
onPlug: (output: Output) => {
|
|
191
|
-
this.connect(output.audioModule);
|
|
192
|
-
},
|
|
193
|
-
onUnPlug: (output: Output) => {
|
|
194
|
-
this.disconnect(output.audioModule);
|
|
195
|
-
},
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
protected registerBasicInputs() {
|
|
200
|
-
this.registerInput({
|
|
201
|
-
name: "input",
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
private registerNumberOfVoicesInput() {
|
|
206
|
-
this.registerInput({
|
|
207
|
-
name: "number of voices",
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
private adjustNumberOfModules() {
|
|
212
|
-
if (this.audioModules.length === this.numberOfVoices) return;
|
|
213
|
-
|
|
214
|
-
if (this.audioModules.length > this.numberOfVoices) {
|
|
215
|
-
const audioModule = this.audioModules.pop();
|
|
216
|
-
audioModule?.dispose();
|
|
217
|
-
} else {
|
|
218
|
-
const props = this.audioModules.length
|
|
219
|
-
? this.props
|
|
220
|
-
: ({} as PropsInterface);
|
|
221
|
-
const audioModule = new this.child(this.name, {
|
|
222
|
-
...props,
|
|
223
|
-
voiceNo: this.audioModules.length,
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
if (audioModule instanceof PolyModule)
|
|
227
|
-
throw Error("Polymodule not supported");
|
|
228
|
-
|
|
229
|
-
this.audioModules.push(audioModule as MonoAudioModule);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
this.adjustNumberOfModules();
|
|
233
|
-
}
|
|
234
|
-
}
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import Module, { DummnyInternalModule, Voicable } from "./Base";
|
|
2
|
-
import MidiEvent from "../MidiEvent";
|
|
3
|
-
import { Input, Output } from "./IO";
|
|
4
|
-
import PolyModule from "./PolyModule";
|
|
5
|
-
|
|
6
|
-
export interface VoiceSchedulerInterface extends Voicable {
|
|
7
|
-
polyNumber: number;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export default class VoiceScheduler extends PolyModule<
|
|
11
|
-
Voice,
|
|
12
|
-
VoiceSchedulerInterface
|
|
13
|
-
> {
|
|
14
|
-
static moduleName = "VoiceScheduler";
|
|
15
|
-
midiOutput: Output;
|
|
16
|
-
numberOfVoicesOut: Output;
|
|
17
|
-
|
|
18
|
-
constructor(name: string, props: VoiceSchedulerInterface) {
|
|
19
|
-
super({
|
|
20
|
-
name,
|
|
21
|
-
child: Voice,
|
|
22
|
-
props,
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
this.registerInputs();
|
|
26
|
-
this.registerOutputs();
|
|
27
|
-
this.polyNumber = this.numberOfVoices;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
set polyNumber(value: number) {
|
|
31
|
-
super.numberOfVoices = value;
|
|
32
|
-
if (!this.numberOfVoicesOut) return;
|
|
33
|
-
|
|
34
|
-
this.numberOfVoicesOut.connections.forEach((input) => {
|
|
35
|
-
if (input.audioModule instanceof Module) return;
|
|
36
|
-
|
|
37
|
-
input.audioModule.numberOfVoices = value;
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
get polyNumber() {
|
|
42
|
-
return this.numberOfVoices;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
midiTriggered = (midiEvent: MidiEvent) => {
|
|
46
|
-
let voices: Array<Voice | undefined>;
|
|
47
|
-
|
|
48
|
-
switch (midiEvent.type) {
|
|
49
|
-
case "noteOn":
|
|
50
|
-
voices = this.findFreeVoices(midiEvent.notes.length);
|
|
51
|
-
|
|
52
|
-
break;
|
|
53
|
-
case "noteOff":
|
|
54
|
-
voices = midiEvent.notes.map((note) => {
|
|
55
|
-
return this.audioModules.find((v) => v.activeNote === note.fullName);
|
|
56
|
-
});
|
|
57
|
-
break;
|
|
58
|
-
default:
|
|
59
|
-
throw Error("This type is not a note");
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (voices.length === 0) return;
|
|
63
|
-
|
|
64
|
-
voices.forEach((voice, i) => {
|
|
65
|
-
if (!voice) return;
|
|
66
|
-
|
|
67
|
-
voice.midiTriggered(midiEvent, i);
|
|
68
|
-
this.midiOutput.connections.forEach((input) => {
|
|
69
|
-
input.pluggable(midiEvent, voice.voiceNo, i);
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
serialize() {
|
|
75
|
-
const serialize = super.serialize();
|
|
76
|
-
delete serialize.props.voiceNo;
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
...serialize,
|
|
80
|
-
props: { ...serialize.props, polyNumber: this.polyNumber },
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
private findFreeVoices(num: number = 1): Voice[] {
|
|
85
|
-
let voices = this.audioModules.filter((v) => !v.activeNote).slice(0, num);
|
|
86
|
-
|
|
87
|
-
if (voices.length === 0) {
|
|
88
|
-
voices = this.audioModules
|
|
89
|
-
.sort((a, b) => {
|
|
90
|
-
if (!a || !b) return 0;
|
|
91
|
-
|
|
92
|
-
return a.triggeredAt - b.triggeredAt;
|
|
93
|
-
})
|
|
94
|
-
.slice(0, num);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return voices;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
private registerInputs() {
|
|
101
|
-
this.registerInput({
|
|
102
|
-
name: "midi in",
|
|
103
|
-
pluggable: this.midiTriggered,
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
private registerOutputs() {
|
|
108
|
-
this.numberOfVoicesOut = this.registerOutput({
|
|
109
|
-
name: "number of voices",
|
|
110
|
-
onPlug: (input: Input) => {
|
|
111
|
-
if (input.audioModule instanceof Module) return;
|
|
112
|
-
|
|
113
|
-
input.audioModule.numberOfVoices = this.numberOfVoices;
|
|
114
|
-
},
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
this.midiOutput = this.registerOutput({ name: "midi out" });
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export interface VoiceInterface extends Voicable {}
|
|
122
|
-
|
|
123
|
-
class Voice extends Module<DummnyInternalModule, VoiceInterface> {
|
|
124
|
-
midiEvent: MidiEvent | null;
|
|
125
|
-
activeNote: string | null;
|
|
126
|
-
triggeredAt: number;
|
|
127
|
-
midiOutput: Output;
|
|
128
|
-
|
|
129
|
-
constructor(name: string, props: VoiceInterface) {
|
|
130
|
-
super(new DummnyInternalModule(), {
|
|
131
|
-
name,
|
|
132
|
-
props,
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
midiTriggered = (midiEvent: MidiEvent, noteIndex?: number) => {
|
|
137
|
-
if (this.voiceNo === undefined) throw Error("Voice without voiceNo");
|
|
138
|
-
if (noteIndex === undefined) return;
|
|
139
|
-
|
|
140
|
-
const { triggeredAt, notes, type } = midiEvent;
|
|
141
|
-
const note = notes[noteIndex];
|
|
142
|
-
|
|
143
|
-
if (!note) return;
|
|
144
|
-
const noteName = note.fullName;
|
|
145
|
-
|
|
146
|
-
switch (type) {
|
|
147
|
-
case "noteOn":
|
|
148
|
-
this.activeNote = noteName;
|
|
149
|
-
this.triggeredAt = triggeredAt;
|
|
150
|
-
this.midiEvent = midiEvent;
|
|
151
|
-
|
|
152
|
-
break;
|
|
153
|
-
case "noteOff":
|
|
154
|
-
this.activeNote = null;
|
|
155
|
-
this.midiEvent = null;
|
|
156
|
-
break;
|
|
157
|
-
default:
|
|
158
|
-
throw Error("This type is not a note");
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|