@blibliki/engine 0.1.26 → 0.3.1
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 -0
- package/dist/index.js.map +1 -0
- package/package.json +19 -31
- 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 +202 -148
- 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/build/Engine.d.ts +0 -82
- package/dist/build/core/IO/AudioNode.d.ts +0 -35
- package/dist/build/core/IO/Collection.d.ts +0 -13
- package/dist/build/core/IO/ForwardNode/Base.d.ts +0 -18
- package/dist/build/core/IO/ForwardNode/index.d.ts +0 -27
- package/dist/build/core/IO/ForwardNode.d.ts +0 -38
- package/dist/build/core/IO/MidiNode.d.ts +0 -30
- package/dist/build/core/IO/Node.d.ts +0 -40
- package/dist/build/core/IO/index.d.ts +0 -21
- package/dist/build/core/Module/MonoModule.d.ts +0 -67
- package/dist/build/core/Module/PolyModule.d.ts +0 -61
- package/dist/build/core/Module/index.d.ts +0 -6
- package/dist/build/core/Note/frequencyTable.d.ts +0 -4
- package/dist/build/core/Note/index.d.ts +0 -28
- package/dist/build/core/midi/ComputerKeyboardInput.d.ts +0 -11
- package/dist/build/core/midi/MidiDevice.d.ts +0 -29
- package/dist/build/core/midi/MidiDeviceManager.d.ts +0 -14
- package/dist/build/core/midi/MidiEvent.d.ts +0 -21
- package/dist/build/core/midi/index.d.ts +0 -5
- package/dist/build/index.d.ts +0 -9
- package/dist/build/modules/BitCrusher.d.ts +0 -16
- package/dist/build/modules/Delay.d.ts +0 -19
- package/dist/build/modules/Distortion.d.ts +0 -16
- package/dist/build/modules/Effect.d.ts +0 -19
- package/dist/build/modules/Envelope/AmpEnvelope.d.ts +0 -18
- package/dist/build/modules/Envelope/Base.d.ts +0 -66
- package/dist/build/modules/Envelope/FreqEnvelope.d.ts +0 -25
- package/dist/build/modules/Envelope/index.d.ts +0 -3
- package/dist/build/modules/Filter.d.ts +0 -42
- package/dist/build/modules/LFO.d.ts +0 -44
- package/dist/build/modules/Master.d.ts +0 -11
- package/dist/build/modules/MidiSelector.d.ts +0 -21
- package/dist/build/modules/Oscillator.d.ts +0 -55
- package/dist/build/modules/Reverb.d.ts +0 -19
- package/dist/build/modules/Sequencer.d.ts +0 -42
- package/dist/build/modules/VirtualMidi.d.ts +0 -32
- package/dist/build/modules/VoiceScheduler.d.ts +0 -44
- package/dist/build/modules/Volume.d.ts +0 -26
- package/dist/build/modules/index.d.ts +0 -17
- package/dist/build/routes.d.ts +0 -18
- package/dist/build/types.d.ts +0 -5
- package/dist/build/utils.d.ts +0 -1
- package/dist/main.cjs.js +0 -25
- package/dist/main.cjs.js.map +0 -1
- package/dist/main.esm.js +0 -25
- package/dist/main.esm.js.map +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/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/modules/index.ts
CHANGED
|
@@ -1,84 +1,169 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import {
|
|
1
|
+
import { assertNever } from "@blibliki/utils";
|
|
2
|
+
import { IModule, Module, PropSchema } from "@/core";
|
|
3
|
+
import { IPolyModuleConstructor } from "@/core/module/PolyModule";
|
|
4
|
+
import VoiceScheduler, {
|
|
5
|
+
IVoiceSchedulerProps,
|
|
6
|
+
voiceSchedulerPropSchema,
|
|
7
|
+
} from "@/core/module/VoiceScheduler";
|
|
8
|
+
import BiquadFilter, {
|
|
9
|
+
biquadFilterPropSchema,
|
|
10
|
+
IBiquadFilterProps,
|
|
11
|
+
} from "./BiquadFilter";
|
|
12
|
+
import Constant, { constantPropSchema, IConstantProps } from "./Constant";
|
|
13
|
+
import Envelope, { envelopePropSchema, IEnvelopeProps } from "./Envelope";
|
|
14
|
+
import Filter, { filterPropSchema, IFilterProps } from "./Filter";
|
|
15
|
+
import Gain, { gainPropSchema, IGainProps } from "./Gain";
|
|
16
|
+
import Inspector, { IInspectorProps, inspectorPropSchema } from "./Inspector";
|
|
17
|
+
import Master, { IMasterProps, masterPropSchema } from "./Master";
|
|
18
|
+
import MidiSelector, {
|
|
19
|
+
IMidiSelectorProps,
|
|
20
|
+
midiSelectorPropSchema,
|
|
21
|
+
} from "./MidiSelector";
|
|
22
|
+
import Oscillator, {
|
|
23
|
+
IOscillatorProps,
|
|
24
|
+
oscillatorPropSchema,
|
|
25
|
+
} from "./Oscillator";
|
|
26
|
+
import Scale, { IScaleProps, scalePropSchema } from "./Scale";
|
|
27
|
+
import StepSequencer, {
|
|
28
|
+
IStepSequencerProps,
|
|
29
|
+
stepSequencerPropSchema,
|
|
30
|
+
} from "./StepSequencer";
|
|
31
|
+
import VirtualMidi, {
|
|
32
|
+
IVirtualMidiProps,
|
|
33
|
+
virtualMidiPropSchema,
|
|
34
|
+
} from "./VirtualMidi";
|
|
16
35
|
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
36
|
+
export enum ModuleType {
|
|
37
|
+
Master = "Master",
|
|
38
|
+
Oscillator = "Oscillator",
|
|
39
|
+
Gain = "Gain",
|
|
40
|
+
MidiSelector = "MidiSelector",
|
|
41
|
+
Envelope = "Envelope",
|
|
42
|
+
Filter = "Filter",
|
|
43
|
+
BiquadFilter = "BiquadFilter",
|
|
44
|
+
Scale = "Scale",
|
|
45
|
+
Inspector = "Inspector",
|
|
46
|
+
Constant = "Constant",
|
|
47
|
+
VirtualMidi = "VirtualMidi",
|
|
48
|
+
StepSequencer = "StepSequencer",
|
|
49
|
+
VoiceScheduler = "VoiceScheduler",
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type ModuleTypeToPropsMapping = {
|
|
53
|
+
[ModuleType.Oscillator]: IOscillatorProps;
|
|
54
|
+
[ModuleType.Gain]: IGainProps;
|
|
55
|
+
[ModuleType.Master]: IMasterProps;
|
|
56
|
+
[ModuleType.MidiSelector]: IMidiSelectorProps;
|
|
57
|
+
[ModuleType.Envelope]: IEnvelopeProps;
|
|
58
|
+
[ModuleType.Filter]: IFilterProps;
|
|
59
|
+
[ModuleType.BiquadFilter]: IBiquadFilterProps;
|
|
60
|
+
[ModuleType.Scale]: IScaleProps;
|
|
61
|
+
[ModuleType.Inspector]: IInspectorProps;
|
|
62
|
+
[ModuleType.Constant]: IConstantProps;
|
|
63
|
+
[ModuleType.VirtualMidi]: IVirtualMidiProps;
|
|
64
|
+
[ModuleType.StepSequencer]: IStepSequencerProps;
|
|
65
|
+
[ModuleType.VoiceScheduler]: IVoiceSchedulerProps;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export type ModuleTypeToModuleMapping = {
|
|
69
|
+
[ModuleType.Oscillator]: Oscillator;
|
|
70
|
+
[ModuleType.Gain]: Gain;
|
|
71
|
+
[ModuleType.Master]: Master;
|
|
72
|
+
[ModuleType.MidiSelector]: MidiSelector;
|
|
73
|
+
[ModuleType.Envelope]: Envelope;
|
|
74
|
+
[ModuleType.Filter]: Filter;
|
|
75
|
+
[ModuleType.BiquadFilter]: BiquadFilter;
|
|
76
|
+
[ModuleType.Scale]: Scale;
|
|
77
|
+
[ModuleType.Inspector]: Inspector;
|
|
78
|
+
[ModuleType.Constant]: Constant;
|
|
79
|
+
[ModuleType.VirtualMidi]: VirtualMidi;
|
|
80
|
+
[ModuleType.StepSequencer]: StepSequencer;
|
|
81
|
+
[ModuleType.VoiceScheduler]: VoiceScheduler;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const moduleSchemas: {
|
|
85
|
+
[K in ModuleType]: PropSchema<Partial<ModuleTypeToPropsMapping[K]>>;
|
|
86
|
+
} = {
|
|
87
|
+
[ModuleType.Oscillator]: oscillatorPropSchema,
|
|
88
|
+
[ModuleType.Gain]: gainPropSchema,
|
|
89
|
+
[ModuleType.Master]: masterPropSchema,
|
|
90
|
+
[ModuleType.MidiSelector]: midiSelectorPropSchema,
|
|
91
|
+
[ModuleType.Envelope]: envelopePropSchema,
|
|
92
|
+
[ModuleType.Filter]: filterPropSchema,
|
|
93
|
+
[ModuleType.BiquadFilter]: biquadFilterPropSchema,
|
|
94
|
+
[ModuleType.Scale]: scalePropSchema,
|
|
95
|
+
[ModuleType.Inspector]: inspectorPropSchema,
|
|
96
|
+
[ModuleType.Constant]: constantPropSchema,
|
|
97
|
+
[ModuleType.VirtualMidi]: virtualMidiPropSchema,
|
|
98
|
+
[ModuleType.StepSequencer]: stepSequencerPropSchema,
|
|
99
|
+
[ModuleType.VoiceScheduler]: voiceSchedulerPropSchema,
|
|
100
|
+
};
|
|
24
101
|
|
|
25
|
-
export {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
102
|
+
export type { IOscillator } from "./Oscillator";
|
|
103
|
+
export { OscillatorWave } from "./Oscillator";
|
|
104
|
+
export type { IGain } from "./Gain";
|
|
105
|
+
export type { IMaster } from "./Master";
|
|
106
|
+
export type { IMidiSelector } from "./MidiSelector";
|
|
107
|
+
export type {
|
|
108
|
+
IStepSequencer,
|
|
109
|
+
IStepSequencerProps,
|
|
110
|
+
ISequence,
|
|
111
|
+
} from "./StepSequencer";
|
|
31
112
|
|
|
32
|
-
export
|
|
113
|
+
export type AnyModule = Module<ModuleType>;
|
|
114
|
+
export type IAnyModule = IModule<ModuleType>;
|
|
115
|
+
|
|
116
|
+
export type ICreateModule<T extends ModuleType> = {
|
|
33
117
|
id?: string;
|
|
34
118
|
name: string;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
119
|
+
moduleType: T;
|
|
120
|
+
props: Partial<ModuleTypeToPropsMapping[T]>;
|
|
121
|
+
};
|
|
39
122
|
|
|
40
|
-
export
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
123
|
+
export type ModuleParams = {
|
|
124
|
+
[K in ModuleType]: K extends
|
|
125
|
+
| ModuleType.Oscillator
|
|
126
|
+
| ModuleType.Gain
|
|
127
|
+
| ModuleType.Envelope
|
|
128
|
+
| ModuleType.Filter
|
|
129
|
+
| ModuleType.BiquadFilter
|
|
130
|
+
| ModuleType.VoiceScheduler
|
|
131
|
+
? IPolyModuleConstructor<K>
|
|
132
|
+
: ICreateModule<K>;
|
|
133
|
+
}[ModuleType];
|
|
46
134
|
|
|
47
|
-
function
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return Sequencer;
|
|
79
|
-
case LFO.moduleName:
|
|
80
|
-
return LFO;
|
|
135
|
+
export function createModule(
|
|
136
|
+
engineId: string,
|
|
137
|
+
params: ModuleParams,
|
|
138
|
+
): ModuleTypeToModuleMapping[keyof ModuleTypeToModuleMapping] {
|
|
139
|
+
switch (params.moduleType) {
|
|
140
|
+
case ModuleType.Oscillator:
|
|
141
|
+
return new Oscillator(engineId, params);
|
|
142
|
+
case ModuleType.Gain:
|
|
143
|
+
return new Gain(engineId, params);
|
|
144
|
+
case ModuleType.Master:
|
|
145
|
+
return new Master(engineId, params);
|
|
146
|
+
case ModuleType.MidiSelector:
|
|
147
|
+
return new MidiSelector(engineId, params);
|
|
148
|
+
case ModuleType.Envelope:
|
|
149
|
+
return new Envelope(engineId, params);
|
|
150
|
+
case ModuleType.Filter:
|
|
151
|
+
return new Filter(engineId, params);
|
|
152
|
+
case ModuleType.BiquadFilter:
|
|
153
|
+
return new BiquadFilter(engineId, params);
|
|
154
|
+
case ModuleType.Scale:
|
|
155
|
+
return new Scale(engineId, params);
|
|
156
|
+
case ModuleType.Inspector:
|
|
157
|
+
return new Inspector(engineId, params);
|
|
158
|
+
case ModuleType.Constant:
|
|
159
|
+
return new Constant(engineId, params);
|
|
160
|
+
case ModuleType.VirtualMidi:
|
|
161
|
+
return new VirtualMidi(engineId, params);
|
|
162
|
+
case ModuleType.StepSequencer:
|
|
163
|
+
return new StepSequencer(engineId, params);
|
|
164
|
+
case ModuleType.VoiceScheduler:
|
|
165
|
+
return new VoiceScheduler(engineId, params);
|
|
81
166
|
default:
|
|
82
|
-
|
|
167
|
+
assertNever(params);
|
|
83
168
|
}
|
|
84
169
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AudioContext,
|
|
3
|
+
AnalyserNode,
|
|
4
|
+
AudioParam,
|
|
5
|
+
AudioNode,
|
|
6
|
+
AudioWorkletNode,
|
|
7
|
+
BiquadFilterNode,
|
|
8
|
+
GainNode,
|
|
9
|
+
OfflineAudioContext,
|
|
10
|
+
OscillatorNode,
|
|
11
|
+
ConstantSourceNode,
|
|
12
|
+
WaveShaperNode,
|
|
13
|
+
} from "node-web-audio-api";
|
|
14
|
+
|
|
15
|
+
globalThis.AudioContext = AudioContext;
|
|
16
|
+
globalThis.OfflineAudioContext = OfflineAudioContext;
|
|
17
|
+
globalThis.AudioParam = AudioParam;
|
|
18
|
+
globalThis.AudioNode = AudioNode;
|
|
19
|
+
globalThis.AudioWorkletNode = AudioWorkletNode;
|
|
20
|
+
globalThis.AnalyserNode = AnalyserNode;
|
|
21
|
+
globalThis.GainNode = GainNode;
|
|
22
|
+
globalThis.OscillatorNode = OscillatorNode;
|
|
23
|
+
globalThis.BiquadFilterNode = BiquadFilterNode;
|
|
24
|
+
globalThis.ConstantSourceNode = ConstantSourceNode;
|
|
25
|
+
globalThis.WaveShaperNode = WaveShaperNode;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export const filterProcessorURL = URL.createObjectURL(
|
|
2
|
+
new Blob(
|
|
3
|
+
[
|
|
4
|
+
"(",
|
|
5
|
+
(() => {
|
|
6
|
+
class FilterProcessor extends AudioWorkletProcessor {
|
|
7
|
+
s0: number;
|
|
8
|
+
s1: number;
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
this.s0 = 0;
|
|
13
|
+
this.s1 = 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static get parameterDescriptors() {
|
|
17
|
+
return [
|
|
18
|
+
{
|
|
19
|
+
name: "cutoff",
|
|
20
|
+
defaultValue: 1000,
|
|
21
|
+
minValue: 20,
|
|
22
|
+
maxValue: 20000,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "resonance",
|
|
26
|
+
defaultValue: 0.0,
|
|
27
|
+
minValue: 0.0,
|
|
28
|
+
maxValue: 4.0,
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
process(
|
|
34
|
+
inputs: Float32Array[][],
|
|
35
|
+
outputs: Float32Array[][],
|
|
36
|
+
parameters: Record<string, Float32Array>,
|
|
37
|
+
): boolean {
|
|
38
|
+
const input = inputs[0];
|
|
39
|
+
const output = outputs[0];
|
|
40
|
+
|
|
41
|
+
const cutoff = parameters.cutoff;
|
|
42
|
+
const resonance = parameters.resonance;
|
|
43
|
+
|
|
44
|
+
for (let channelNum = 0; channelNum < input.length; channelNum++) {
|
|
45
|
+
const inputChannel = input[channelNum];
|
|
46
|
+
const outputChannel = output[channelNum];
|
|
47
|
+
|
|
48
|
+
for (let i = 0; i < inputChannel.length; i++) {
|
|
49
|
+
const s = inputChannel[i];
|
|
50
|
+
// Convert Hz to normalized frequency using logarithmic scale
|
|
51
|
+
// This better matches human hearing perception
|
|
52
|
+
const cutoffHz = cutoff.length > 1 ? cutoff[i] : cutoff[0];
|
|
53
|
+
const clampedHz = Math.max(20, Math.min(20000, cutoffHz));
|
|
54
|
+
const normalizedCutoff =
|
|
55
|
+
Math.log(clampedHz / 20) / Math.log(20000 / 20);
|
|
56
|
+
const c = Math.pow(0.5, (1 - normalizedCutoff) / 0.125);
|
|
57
|
+
const r = Math.pow(
|
|
58
|
+
0.5,
|
|
59
|
+
((resonance.length > 1 ? resonance[i] : resonance[0]) +
|
|
60
|
+
0.125) /
|
|
61
|
+
0.125,
|
|
62
|
+
);
|
|
63
|
+
const mrc = 1 - r * c;
|
|
64
|
+
|
|
65
|
+
this.s0 = mrc * this.s0 - c * this.s1 + c * s;
|
|
66
|
+
this.s1 = mrc * this.s1 + c * this.s0;
|
|
67
|
+
|
|
68
|
+
outputChannel[i] = this.s1;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
registerProcessor("filter-processor", FilterProcessor);
|
|
77
|
+
}).toString(),
|
|
78
|
+
")()",
|
|
79
|
+
],
|
|
80
|
+
{ type: "application/javascript" },
|
|
81
|
+
),
|
|
82
|
+
);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { assertNever } from "@blibliki/utils";
|
|
2
|
+
import { IAnyAudioContext } from "@/core";
|
|
3
|
+
import { filterProcessorURL } from "./filter-processor";
|
|
4
|
+
import { scaleProcessorURL } from "./scale-processor";
|
|
5
|
+
|
|
6
|
+
export enum CustomWorklet {
|
|
7
|
+
ScaleProcessor = "ScaleProcessor",
|
|
8
|
+
FilterProcessor = "FilterProcessor",
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function loadProcessors(context: IAnyAudioContext) {
|
|
12
|
+
await context.audioWorklet.addModule(scaleProcessorURL);
|
|
13
|
+
await context.audioWorklet.addModule(filterProcessorURL);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function newAudioWorklet(
|
|
17
|
+
context: IAnyAudioContext,
|
|
18
|
+
worklet: CustomWorklet,
|
|
19
|
+
) {
|
|
20
|
+
switch (worklet) {
|
|
21
|
+
case CustomWorklet.ScaleProcessor:
|
|
22
|
+
return new AudioWorkletNode(context, "scale-processor");
|
|
23
|
+
case CustomWorklet.FilterProcessor:
|
|
24
|
+
return new AudioWorkletNode(context, "filter-processor");
|
|
25
|
+
default:
|
|
26
|
+
assertNever(worklet);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export const scaleProcessorURL = URL.createObjectURL(
|
|
2
|
+
new Blob(
|
|
3
|
+
[
|
|
4
|
+
"(",
|
|
5
|
+
(() => {
|
|
6
|
+
class ScaleProcessor extends AudioWorkletProcessor {
|
|
7
|
+
static get parameterDescriptors() {
|
|
8
|
+
return [
|
|
9
|
+
{
|
|
10
|
+
name: "min",
|
|
11
|
+
defaultValue: 1e-10,
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: "max",
|
|
15
|
+
defaultValue: 1,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: "current",
|
|
19
|
+
defaultValue: 0.5,
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
process(
|
|
25
|
+
inputs: Float32Array[][],
|
|
26
|
+
outputs: Float32Array[][],
|
|
27
|
+
parameters: Record<string, Float32Array>,
|
|
28
|
+
) {
|
|
29
|
+
const input = inputs[0];
|
|
30
|
+
const output = outputs[0];
|
|
31
|
+
|
|
32
|
+
const minValues = parameters.min;
|
|
33
|
+
const maxValues = parameters.max;
|
|
34
|
+
const currentValues = parameters.current;
|
|
35
|
+
|
|
36
|
+
if (!input.length || input[0].length === 0) {
|
|
37
|
+
for (const outputChannel of output) {
|
|
38
|
+
const current =
|
|
39
|
+
parameters.current.length > 1
|
|
40
|
+
? parameters.current[0]
|
|
41
|
+
: parameters.current[0];
|
|
42
|
+
|
|
43
|
+
outputChannel.fill(current);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
for (let channel = 0; channel < input.length; channel++) {
|
|
50
|
+
const inputChannel = input[channel];
|
|
51
|
+
const outputChannel = output[channel];
|
|
52
|
+
|
|
53
|
+
for (let i = 0; i < inputChannel.length; i++) {
|
|
54
|
+
const x = inputChannel[i];
|
|
55
|
+
|
|
56
|
+
const min = minValues.length > 1 ? minValues[i] : minValues[0];
|
|
57
|
+
const max = maxValues.length > 1 ? maxValues[i] : maxValues[0];
|
|
58
|
+
const current =
|
|
59
|
+
currentValues.length > 1
|
|
60
|
+
? currentValues[i]
|
|
61
|
+
: currentValues[0];
|
|
62
|
+
|
|
63
|
+
if (x < 0) {
|
|
64
|
+
outputChannel[i] = current * Math.pow(min / current, -x);
|
|
65
|
+
} else {
|
|
66
|
+
outputChannel[i] = current * Math.pow(max / current, x);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
registerProcessor("scale-processor", ScaleProcessor);
|
|
76
|
+
}).toString(),
|
|
77
|
+
")()",
|
|
78
|
+
],
|
|
79
|
+
{ type: "application/javascript" },
|
|
80
|
+
),
|
|
81
|
+
);
|
package/dist/build/Engine.d.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { MidiDeviceManager } from "./core/midi";
|
|
2
|
-
import { AudioModule } from "./core/Module";
|
|
3
|
-
import { RouteInterface } from "./routes";
|
|
4
|
-
import { AnyObject, Optional } from "./types";
|
|
5
|
-
type LatencyHint = "interactive" | "playback" | "balanced";
|
|
6
|
-
interface ContextInterface {
|
|
7
|
-
latencyHint: LatencyHint;
|
|
8
|
-
lookAhead: number;
|
|
9
|
-
}
|
|
10
|
-
interface InitializeInterface {
|
|
11
|
-
context?: Partial<ContextInterface>;
|
|
12
|
-
}
|
|
13
|
-
export interface UpdateModuleProps {
|
|
14
|
-
id: string;
|
|
15
|
-
changes: {
|
|
16
|
-
name?: string;
|
|
17
|
-
numberOfVoices?: number;
|
|
18
|
-
props?: AnyObject;
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
declare class Engine {
|
|
22
|
-
midiDeviceManager: MidiDeviceManager;
|
|
23
|
-
private static instance;
|
|
24
|
-
private context;
|
|
25
|
-
private propsUpdateCallbacks;
|
|
26
|
-
private _isStarted;
|
|
27
|
-
modules: {
|
|
28
|
-
[Identifier: string]: AudioModule;
|
|
29
|
-
};
|
|
30
|
-
routes: {
|
|
31
|
-
[Identifier: string]: RouteInterface;
|
|
32
|
-
};
|
|
33
|
-
private constructor();
|
|
34
|
-
static getInstance(): Engine;
|
|
35
|
-
initialize(props: InitializeInterface): Promise<unknown>;
|
|
36
|
-
addModule(params: {
|
|
37
|
-
id?: string;
|
|
38
|
-
name: string;
|
|
39
|
-
numberOfVoices?: number;
|
|
40
|
-
type: string;
|
|
41
|
-
props?: AnyObject;
|
|
42
|
-
}): {
|
|
43
|
-
id: string;
|
|
44
|
-
name: string;
|
|
45
|
-
type: string;
|
|
46
|
-
props: any;
|
|
47
|
-
inputs: import(".").IOProps[];
|
|
48
|
-
outputs: import(".").IOProps[];
|
|
49
|
-
};
|
|
50
|
-
removeModule(id: string): string[];
|
|
51
|
-
updateModule(params: UpdateModuleProps): {
|
|
52
|
-
id: string;
|
|
53
|
-
name: string;
|
|
54
|
-
type: string;
|
|
55
|
-
props: any;
|
|
56
|
-
inputs: import(".").IOProps[];
|
|
57
|
-
outputs: import(".").IOProps[];
|
|
58
|
-
};
|
|
59
|
-
onPropsUpdate(callback: (id: string, props: AnyObject) => void): void;
|
|
60
|
-
_triggerPropsUpdate(id: string, props: AnyObject): void;
|
|
61
|
-
addRoute(props: Optional<RouteInterface, "id">): {
|
|
62
|
-
id: string;
|
|
63
|
-
sourceId: string;
|
|
64
|
-
destinationId: string;
|
|
65
|
-
sourceIOId: string;
|
|
66
|
-
destinationIOId: string;
|
|
67
|
-
};
|
|
68
|
-
validRoute(props: Optional<RouteInterface, "id">): boolean;
|
|
69
|
-
removeRoute(id: string): void;
|
|
70
|
-
triggerVirtualMidi(id: string, noteName: string, type: "noteOn" | "noteOff"): void;
|
|
71
|
-
dispose(): void;
|
|
72
|
-
findById(id: string): AudioModule;
|
|
73
|
-
get isStarted(): boolean;
|
|
74
|
-
start(): void;
|
|
75
|
-
stop(): void;
|
|
76
|
-
get bpm(): number;
|
|
77
|
-
set bpm(value: number);
|
|
78
|
-
updateRoutes(): void;
|
|
79
|
-
private moduleRouteIds;
|
|
80
|
-
}
|
|
81
|
-
declare const _default: Engine;
|
|
82
|
-
export default _default;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { InputNode } from "tone";
|
|
2
|
-
import IONode, { IOType, IIONode } from "./Node";
|
|
3
|
-
import MonoModule, { Connectable } from "../Module/index";
|
|
4
|
-
import { AnyObject } from "../../types";
|
|
5
|
-
import { AnyAudioInput, AnyAudioOuput } from ".";
|
|
6
|
-
export type AudioIO = AudioInput | AudioOutput;
|
|
7
|
-
export interface IAudioInput extends IIONode {
|
|
8
|
-
ioType: IOType.AudioInput;
|
|
9
|
-
internalModule: InputNode;
|
|
10
|
-
}
|
|
11
|
-
export interface IAudioOutput extends IIONode {
|
|
12
|
-
ioType: IOType.AudioOutput;
|
|
13
|
-
internalModule: IInternalModule;
|
|
14
|
-
}
|
|
15
|
-
interface IInternalModule extends Connectable {
|
|
16
|
-
}
|
|
17
|
-
export declare class AudioInput extends IONode implements IAudioInput {
|
|
18
|
-
ioType: IOType.AudioInput;
|
|
19
|
-
internalModule: InputNode;
|
|
20
|
-
connections: AudioOutput[];
|
|
21
|
-
constructor(plugableModule: MonoModule<Connectable, AnyObject>, props: IAudioInput);
|
|
22
|
-
plug(io: AnyAudioOuput, plugOther?: boolean): void;
|
|
23
|
-
unPlug(io: AnyAudioOuput, plugOther?: boolean): void;
|
|
24
|
-
unPlugAll(): void;
|
|
25
|
-
}
|
|
26
|
-
export declare class AudioOutput extends IONode implements IAudioOutput {
|
|
27
|
-
ioType: IOType.AudioOutput;
|
|
28
|
-
internalModule: IInternalModule;
|
|
29
|
-
connections: AudioInput[];
|
|
30
|
-
constructor(plugableModule: MonoModule<Connectable, AnyObject>, props: IAudioOutput);
|
|
31
|
-
plug(io: AnyAudioInput, plugOther?: boolean): void;
|
|
32
|
-
unPlug(io: AnyAudioInput, plugOther?: boolean): void;
|
|
33
|
-
unPlugAll(): void;
|
|
34
|
-
}
|
|
35
|
-
export {};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { AudioModule } from "../Module";
|
|
2
|
-
import IO from "./Node";
|
|
3
|
-
import { IAnyIO } from ".";
|
|
4
|
-
export default class IOCollection<AnyIO extends IO> {
|
|
5
|
-
plugableModule: AudioModule;
|
|
6
|
-
collection: AnyIO[];
|
|
7
|
-
constructor(plugableModule: AudioModule);
|
|
8
|
-
add<CurrentIO extends AnyIO>(props: IAnyIO): CurrentIO;
|
|
9
|
-
unPlugAll(): void;
|
|
10
|
-
find(id: string): AnyIO | undefined;
|
|
11
|
-
findByName(name: string): AnyIO | undefined;
|
|
12
|
-
serialize(): import("./Node").IIOSerialize[];
|
|
13
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import IONode, { IIONode } from "../Node";
|
|
2
|
-
import Module, { Connectable, PolyModule } from "../../Module";
|
|
3
|
-
import { AnyObject } from "../../../types";
|
|
4
|
-
import { AnyIO } from "..";
|
|
5
|
-
export default class ForwardBaseNode extends IONode {
|
|
6
|
-
plugableModule: PolyModule<Module<Connectable, AnyObject>, AnyObject>;
|
|
7
|
-
constructor(plugableModule: PolyModule<Module<Connectable, AnyObject>, AnyObject>, props: IIONode);
|
|
8
|
-
get voices(): number;
|
|
9
|
-
get subModules(): Module<Connectable, AnyObject>[];
|
|
10
|
-
subModule(voiceNo: number): Module<Connectable, AnyObject>;
|
|
11
|
-
get subIOs(): IONode[];
|
|
12
|
-
subIO(voiceNo: number): import("..").AudioInput | import("..").MidiInput | import("..").AudioOutput | import("..").MidiOutput;
|
|
13
|
-
plug(io: AnyIO, plugOther?: boolean): void;
|
|
14
|
-
unPlug(io: AnyIO, plugOther?: boolean): void;
|
|
15
|
-
unPlugAll(): void;
|
|
16
|
-
private plugUnplug;
|
|
17
|
-
private checkNameValidity;
|
|
18
|
-
}
|
|
@@ -1,27 +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
|
-
export interface IForwardAudioInput extends IIONode {
|
|
7
|
-
ioType: IOType.ForwardAudioInput;
|
|
8
|
-
}
|
|
9
|
-
export interface IForwardAudioOutput extends IIONode {
|
|
10
|
-
ioType: IOType.ForwardAudioOutput;
|
|
11
|
-
}
|
|
12
|
-
export declare class ForwardAudioInput extends ForwardBaseNode implements IForwardAudioInput {
|
|
13
|
-
plugableModule: PolyModule<Module<Connectable, AnyObject>, AnyObject>;
|
|
14
|
-
ioType: IOType.ForwardAudioInput;
|
|
15
|
-
connections: AnyAudioOuput[];
|
|
16
|
-
constructor(plugableModule: PolyModule<Module<Connectable, AnyObject>, AnyObject>, props: IForwardAudioInput);
|
|
17
|
-
plug(io: AnyOuput, plugOther?: boolean): void;
|
|
18
|
-
unPlug(io: AnyOuput, plugOther?: boolean): void;
|
|
19
|
-
}
|
|
20
|
-
export declare class ForwardAudioOutput extends ForwardBaseNode implements IForwardAudioOutput {
|
|
21
|
-
plugableModule: PolyModule<Module<Connectable, AnyObject>, AnyObject>;
|
|
22
|
-
ioType: IOType.ForwardAudioOutput;
|
|
23
|
-
connections: AnyAudioInput[];
|
|
24
|
-
constructor(plugableModule: PolyModule<Module<Connectable, AnyObject>, AnyObject>, props: IForwardAudioOutput);
|
|
25
|
-
plug(io: AnyInput, plugOther?: boolean): void;
|
|
26
|
-
unPlug(io: AnyInput, plugOther?: boolean): void;
|
|
27
|
-
}
|