@blibliki/engine 0.1.17 → 0.1.19

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.
Files changed (161) hide show
  1. package/README.md +13 -1
  2. package/{build → dist/build}/Engine.d.ts +14 -22
  3. package/dist/build/core/IO/AudioNode.d.ts +35 -0
  4. package/dist/build/core/IO/Collection.d.ts +13 -0
  5. package/dist/build/core/IO/ForwardNode.d.ts +38 -0
  6. package/dist/build/core/IO/MidiNode.d.ts +30 -0
  7. package/dist/build/core/IO/Node.d.ts +36 -0
  8. package/dist/build/core/IO/index.d.ts +12 -0
  9. package/dist/build/core/Module/MonoModule.d.ts +67 -0
  10. package/dist/build/core/Module/PolyModule.d.ts +57 -0
  11. package/dist/build/core/Module/index.d.ts +6 -0
  12. package/{build → dist/build/core}/Note/index.d.ts +3 -0
  13. package/{build → dist/build/core/midi}/MidiDevice.d.ts +1 -1
  14. package/dist/build/core/midi/MidiEvent.d.ts +21 -0
  15. package/dist/build/core/midi/index.d.ts +5 -0
  16. package/dist/build/index.d.ts +9 -0
  17. package/{build/Module → dist/build/modules}/BitCrusher.d.ts +5 -1
  18. package/{build/Module → dist/build/modules}/Delay.d.ts +5 -1
  19. package/{build/Module → dist/build/modules}/Distortion.d.ts +5 -1
  20. package/{build/Module → dist/build/modules}/Effect.d.ts +7 -2
  21. package/{build/Module → dist/build/modules}/Envelope/AmpEnvelope.d.ts +10 -2
  22. package/{build/Module → dist/build/modules}/Envelope/Base.d.ts +30 -11
  23. package/{build/Module → dist/build/modules}/Envelope/FreqEnvelope.d.ts +10 -3
  24. package/{build/Module → dist/build/modules}/Filter.d.ts +13 -13
  25. package/{build/Module → dist/build/modules}/Master.d.ts +5 -2
  26. package/{build/Module → dist/build/modules}/MidiSelector.d.ts +9 -5
  27. package/{build/Module → dist/build/modules}/Oscillator.d.ts +15 -9
  28. package/{build/Module → dist/build/modules}/Reverb.d.ts +5 -1
  29. package/{build/Module → dist/build/modules}/Sequencer.d.ts +9 -5
  30. package/{build/Module → dist/build/modules}/VirtualMidi.d.ts +12 -8
  31. package/dist/build/modules/VoiceScheduler.d.ts +43 -0
  32. package/dist/build/modules/Volume.d.ts +26 -0
  33. package/dist/build/modules/index.d.ts +16 -0
  34. package/{build → dist/build}/routes.d.ts +6 -5
  35. package/dist/build/types.d.ts +5 -0
  36. package/dist/build/utils.d.ts +1 -0
  37. package/dist/main.cjs.js +33 -0
  38. package/dist/main.cjs.js.map +1 -0
  39. package/dist/main.esm.js +33 -0
  40. package/dist/main.esm.js.map +1 -0
  41. package/package.json +26 -22
  42. package/src/Engine.ts +27 -36
  43. package/src/core/IO/AudioNode.ts +77 -0
  44. package/src/core/IO/Collection.ts +76 -0
  45. package/src/core/IO/ForwardNode.ts +192 -0
  46. package/src/core/IO/MidiNode.ts +67 -0
  47. package/src/core/IO/Node.ts +117 -0
  48. package/src/core/IO/index.ts +47 -0
  49. package/src/core/Module/MonoModule.ts +219 -0
  50. package/src/core/Module/PolyModule.ts +206 -0
  51. package/src/core/Module/index.ts +15 -0
  52. package/src/{Note → core/Note}/index.ts +19 -4
  53. package/src/{MidiDeviceManager.ts → core/midi/MidiDeviceManager.ts} +20 -15
  54. package/src/core/midi/MidiEvent.ts +91 -0
  55. package/src/core/midi/index.ts +5 -0
  56. package/src/index.ts +8 -12
  57. package/src/{Module → modules}/BitCrusher.ts +15 -4
  58. package/src/{Module → modules}/Delay.ts +15 -4
  59. package/src/{Module → modules}/Distortion.ts +15 -4
  60. package/src/{Module → modules}/Effect.ts +10 -6
  61. package/src/modules/Envelope/AmpEnvelope.ts +23 -0
  62. package/src/{Module → modules}/Envelope/Base.ts +50 -31
  63. package/src/{Module → modules}/Envelope/FreqEnvelope.ts +18 -23
  64. package/src/{Module → modules}/Filter.ts +18 -46
  65. package/src/{Module → modules}/Master.ts +8 -2
  66. package/src/{Module → modules}/MidiSelector.ts +18 -14
  67. package/src/{Module → modules}/Oscillator.ts +27 -16
  68. package/src/{Module → modules}/Reverb.ts +15 -4
  69. package/src/{Module → modules}/Sequencer.ts +17 -13
  70. package/src/{Module → modules}/VirtualMidi.ts +16 -12
  71. package/src/modules/VoiceScheduler.ts +145 -0
  72. package/src/{Module → modules}/Volume.ts +23 -15
  73. package/src/{Module → modules}/index.ts +14 -21
  74. package/src/routes.ts +19 -18
  75. package/src/types.ts +3 -0
  76. package/src/utils.ts +18 -0
  77. package/build/Engine.js +0 -165
  78. package/build/Engine.js.map +0 -1
  79. package/build/MidiDevice.js +0 -45
  80. package/build/MidiDevice.js.map +0 -1
  81. package/build/MidiDeviceManager.js +0 -59
  82. package/build/MidiDeviceManager.js.map +0 -1
  83. package/build/MidiEvent.d.ts +0 -18
  84. package/build/MidiEvent.js +0 -64
  85. package/build/MidiEvent.js.map +0 -1
  86. package/build/Module/Base.d.ts +0 -63
  87. package/build/Module/Base.js +0 -138
  88. package/build/Module/Base.js.map +0 -1
  89. package/build/Module/BitCrusher.js +0 -22
  90. package/build/Module/BitCrusher.js.map +0 -1
  91. package/build/Module/DataSequencer.d.ts +0 -26
  92. package/build/Module/DataSequencer.js +0 -91
  93. package/build/Module/DataSequencer.js.map +0 -1
  94. package/build/Module/Delay.js +0 -30
  95. package/build/Module/Delay.js.map +0 -1
  96. package/build/Module/Distortion.js +0 -22
  97. package/build/Module/Distortion.js.map +0 -1
  98. package/build/Module/Effect.js +0 -22
  99. package/build/Module/Effect.js.map +0 -1
  100. package/build/Module/Envelope/AmpEnvelope.js +0 -14
  101. package/build/Module/Envelope/AmpEnvelope.js.map +0 -1
  102. package/build/Module/Envelope/Base.js +0 -106
  103. package/build/Module/Envelope/Base.js.map +0 -1
  104. package/build/Module/Envelope/FreqEnvelope.js +0 -50
  105. package/build/Module/Envelope/FreqEnvelope.js.map +0 -1
  106. package/build/Module/Envelope/index.js +0 -4
  107. package/build/Module/Envelope/index.js.map +0 -1
  108. package/build/Module/Filter.js +0 -100
  109. package/build/Module/Filter.js.map +0 -1
  110. package/build/Module/IO.d.ts +0 -39
  111. package/build/Module/IO.js +0 -59
  112. package/build/Module/IO.js.map +0 -1
  113. package/build/Module/Master.js +0 -12
  114. package/build/Module/Master.js.map +0 -1
  115. package/build/Module/MidiSelector.js +0 -50
  116. package/build/Module/MidiSelector.js.map +0 -1
  117. package/build/Module/Oscillator.js +0 -136
  118. package/build/Module/Oscillator.js.map +0 -1
  119. package/build/Module/PolyModule.d.ts +0 -49
  120. package/build/Module/PolyModule.js +0 -175
  121. package/build/Module/PolyModule.js.map +0 -1
  122. package/build/Module/Reverb.js +0 -30
  123. package/build/Module/Reverb.js.map +0 -1
  124. package/build/Module/Sequencer.js +0 -131
  125. package/build/Module/Sequencer.js.map +0 -1
  126. package/build/Module/VirtualMidi.js +0 -53
  127. package/build/Module/VirtualMidi.js.map +0 -1
  128. package/build/Module/VoiceScheduler.d.ts +0 -38
  129. package/build/Module/VoiceScheduler.js +0 -130
  130. package/build/Module/VoiceScheduler.js.map +0 -1
  131. package/build/Module/Volume.d.ts +0 -20
  132. package/build/Module/Volume.js +0 -48
  133. package/build/Module/Volume.js.map +0 -1
  134. package/build/Module/index.d.ts +0 -14
  135. package/build/Module/index.js +0 -66
  136. package/build/Module/index.js.map +0 -1
  137. package/build/Note/frequencyTable.js +0 -146
  138. package/build/Note/frequencyTable.js.map +0 -1
  139. package/build/Note/index.js +0 -81
  140. package/build/Note/index.js.map +0 -1
  141. package/build/index.d.ts +0 -8
  142. package/build/index.js +0 -5
  143. package/build/index.js.map +0 -1
  144. package/build/routes.js +0 -31
  145. package/build/routes.js.map +0 -1
  146. package/jest.config.js +0 -19
  147. package/src/MidiEvent.ts +0 -93
  148. package/src/Module/Base.ts +0 -223
  149. package/src/Module/DataSequencer.ts +0 -121
  150. package/src/Module/Envelope/AmpEnvelope.ts +0 -17
  151. package/src/Module/IO.ts +0 -85
  152. package/src/Module/PolyModule.ts +0 -234
  153. package/src/Module/VoiceScheduler.ts +0 -161
  154. package/test/Module/Oscillator.test.ts +0 -9
  155. package/tsconfig.json +0 -22
  156. /package/{build → dist/build/core}/Note/frequencyTable.d.ts +0 -0
  157. /package/{build → dist/build/core/midi}/MidiDeviceManager.d.ts +0 -0
  158. /package/{build/Module → dist/build/modules}/Envelope/index.d.ts +0 -0
  159. /package/src/{Note → core/Note}/frequencyTable.ts +0 -0
  160. /package/src/{MidiDevice.ts → core/midi/MidiDevice.ts} +0 -0
  161. /package/src/{Module → modules}/Envelope/index.ts +0 -0
@@ -1,11 +1,10 @@
1
1
  import { now, Oscillator as Osc, ToneOscillatorType } from "tone";
2
2
  import Engine from "../Engine";
3
3
 
4
- import Note from "../Note";
5
- import Module, { Voicable } from "./Base";
6
- import PolyModule from "./PolyModule";
4
+ import Note from "../core/Note";
5
+ import Module, { PolyModule, Startable } from "../core/Module";
7
6
 
8
- export interface OscillatorInterface extends Voicable {
7
+ export interface OscillatorInterface {
9
8
  noteName: string;
10
9
  fine: number;
11
10
  coarse: number;
@@ -23,15 +22,27 @@ const InitialProps: OscillatorInterface = {
23
22
  volume: 0,
24
23
  };
25
24
 
26
- class MonoOscillator extends Module<Osc, OscillatorInterface> {
25
+ class MonoOscillator
26
+ extends Module<Osc, OscillatorInterface>
27
+ implements Startable
28
+ {
27
29
  private _note: Note;
28
30
 
29
- constructor(name: string, props: Partial<OscillatorInterface>) {
31
+ constructor(params: {
32
+ id?: string;
33
+ name: string;
34
+ props: Partial<OscillatorInterface>;
35
+ }) {
36
+ const { id, name, props } = params;
37
+
30
38
  super(new Osc(), {
39
+ id,
31
40
  name,
32
41
  props: { ...InitialProps, ...props },
33
42
  });
34
43
 
44
+ this.registerBasicOutputs();
45
+ this.registerDefaultMidiInput();
35
46
  this.start(now());
36
47
  }
37
48
 
@@ -126,7 +137,7 @@ class MonoOscillator extends Module<Osc, OscillatorInterface> {
126
137
  this.start(triggeredAt);
127
138
  };
128
139
 
129
- triggerRelease = (note: Note, triggeredAt: number) => {
140
+ triggerRelease = () => {
130
141
  // Do nothing
131
142
  };
132
143
 
@@ -153,15 +164,22 @@ export default class Oscillator extends PolyModule<
153
164
  > {
154
165
  static moduleName = "Oscillator";
155
166
 
156
- constructor(name: string, props: Partial<OscillatorInterface>) {
167
+ constructor(params: {
168
+ id?: string;
169
+ name: string;
170
+ props: Partial<OscillatorInterface>;
171
+ }) {
172
+ const { id, name, props } = params;
173
+
157
174
  super({
175
+ id,
158
176
  name,
159
177
  child: MonoOscillator,
160
178
  props: { ...InitialProps, ...props },
161
179
  });
162
180
 
163
181
  this.registerBasicOutputs();
164
- this.registerInputs();
182
+ this.registerInput({ name: "midi in" });
165
183
  }
166
184
 
167
185
  start(time: number) {
@@ -171,11 +189,4 @@ export default class Oscillator extends PolyModule<
171
189
  stop(time?: number) {
172
190
  this.audioModules.forEach((audioModule) => audioModule.stop(time));
173
191
  }
174
-
175
- private registerInputs() {
176
- this.registerInput({
177
- name: "midi in",
178
- pluggable: this.midiTriggered,
179
- });
180
- }
181
192
  }
@@ -15,10 +15,21 @@ const InitialProps: Partial<ReverbInterface> = {
15
15
  export default class Reverb extends Effect<InternalReverb, ReverbInterface> {
16
16
  static moduleName = "Reverb";
17
17
 
18
- constructor(name: string, props: Partial<ReverbInterface>) {
19
- super(name, new InternalReverb(), {
20
- ...InitialProps,
21
- ...props,
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
+ },
22
33
  });
23
34
  }
24
35
 
@@ -1,8 +1,8 @@
1
- import { now, Part, Time } from "tone";
2
- import Module, { DummnyInternalModule } from "./Base";
3
- import { INote } from "../Note";
4
- import { Output } from "./IO";
5
- import MidiEvent from "../MidiEvent";
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
6
  import Engine from "../Engine";
7
7
 
8
8
  export interface ISequence {
@@ -27,11 +27,17 @@ export default class Sequencer extends Module<
27
27
  ISequencer
28
28
  > {
29
29
  static moduleName = "Sequencer";
30
- midiOutput: Output;
30
+ midiOutput: MidiOutput;
31
31
  private part: Part<ISequence>;
32
32
 
33
- constructor(name: string, props: Partial<ISequencer>) {
33
+ constructor(params: {
34
+ id?: string;
35
+ name: string;
36
+ props: Partial<ISequencer>;
37
+ }) {
38
+ const { id, name, props } = params;
34
39
  super(new DummnyInternalModule(), {
40
+ id,
35
41
  name,
36
42
  props: { ...InitialProps(), ...props },
37
43
  });
@@ -88,7 +94,7 @@ export default class Sequencer extends Module<
88
94
  }
89
95
 
90
96
  private registerOutputs() {
91
- this.midiOutput = this.registerOutput({ name: "midi out" });
97
+ this.midiOutput = this.registerMidiOutput({ name: "midi out" });
92
98
  }
93
99
 
94
100
  private initializePart() {
@@ -151,7 +157,7 @@ export default class Sequencer extends Module<
151
157
  private updateBarParts() {
152
158
  this.part.clear();
153
159
 
154
- this.sequences.forEach((barSeqs, _) => {
160
+ this.sequences.forEach((barSeqs) => {
155
161
  barSeqs.forEach((seq) => this.part.add(seq.time, seq));
156
162
  });
157
163
 
@@ -165,10 +171,8 @@ export default class Sequencer extends Module<
165
171
  private onPartEvent = (time: number, sequence: ISequence) => {
166
172
  if (!sequence.active) return;
167
173
 
168
- const event = MidiEvent.fromSequence(sequence, time);
169
-
170
- this.midiOutput.connections.forEach((input) => {
171
- input.pluggable(event);
174
+ MidiEvent.fromSequence(sequence, time).forEach((event) => {
175
+ this.midiOutput.onMidiEvent(event);
172
176
  });
173
177
  };
174
178
  }
@@ -1,8 +1,8 @@
1
1
  import Engine from "../Engine";
2
- import MidiEvent from "../MidiEvent";
3
- import Note from "../Note";
4
- import Module, { DummnyInternalModule } from "./Base";
5
- import { Output } from "./IO";
2
+ import { MidiEvent } from "../core/midi";
3
+ import Note from "../core/Note";
4
+ import Module, { DummnyInternalModule } from "../core/Module";
5
+ import { MidiOutput } from "../core/IO";
6
6
 
7
7
  export interface VirtualMidiInterface {
8
8
  activeNotes: string[];
@@ -17,10 +17,16 @@ export default class VirtualMidi extends Module<
17
17
  VirtualMidiInterface
18
18
  > {
19
19
  static moduleName = "VirtualMidi";
20
- midiOutput: Output;
20
+ midiOutput: MidiOutput;
21
21
 
22
- constructor(name: string, props: VirtualMidiInterface) {
22
+ constructor(params: {
23
+ id?: string;
24
+ name: string;
25
+ props: VirtualMidiInterface;
26
+ }) {
27
+ const { id, name, props } = params;
23
28
  super(new DummnyInternalModule(), {
29
+ id,
24
30
  name,
25
31
  props: { ...InitialProps, ...props },
26
32
  });
@@ -39,9 +45,7 @@ export default class VirtualMidi extends Module<
39
45
  }
40
46
 
41
47
  sendMidi(midiEvent: MidiEvent) {
42
- this.midiOutput.connections.forEach((input) => {
43
- input.pluggable(midiEvent);
44
- });
48
+ this.midiOutput.onMidiEvent(midiEvent);
45
49
  }
46
50
 
47
51
  triggerAttack = (note: Note) => {
@@ -64,13 +68,13 @@ export default class VirtualMidi extends Module<
64
68
  }
65
69
 
66
70
  private registerInputs() {
67
- this.registerInput({
71
+ this.registerMidiInput({
68
72
  name: "midi in",
69
- pluggable: this.midiTriggered,
73
+ onMidiEvent: this.onMidiEvent,
70
74
  });
71
75
  }
72
76
 
73
77
  private registerOutputs() {
74
- this.midiOutput = this.registerOutput({ name: "midi out" });
78
+ this.midiOutput = this.registerMidiOutput({ name: "midi out" });
75
79
  }
76
80
  }
@@ -0,0 +1,145 @@
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
+ }
@@ -1,10 +1,9 @@
1
1
  import { Volume as Vol } from "tone";
2
2
 
3
- import Module, { Voicable } from "./Base";
4
- import PolyModule from "./PolyModule";
5
- import Note from "../Note";
3
+ import Module, { PolyModule } from "../core/Module";
4
+ import Note from "../core/Note";
6
5
 
7
- export interface VolumeInterface extends Voicable {
6
+ export interface VolumeInterface {
8
7
  volume: number;
9
8
  }
10
9
 
@@ -13,11 +12,21 @@ const InitialProps: VolumeInterface = {
13
12
  };
14
13
 
15
14
  class MonoVolume extends Module<Vol, VolumeInterface> {
16
- constructor(name: string, props: Partial<VolumeInterface>) {
15
+ constructor(params: {
16
+ id?: string;
17
+ name: string;
18
+ props: Partial<VolumeInterface>;
19
+ }) {
20
+ const { id, name, props } = params;
21
+
17
22
  super(new Vol(), {
23
+ id,
18
24
  name,
19
25
  props: { ...InitialProps, ...props },
20
26
  });
27
+
28
+ this.registerBasicInputs();
29
+ this.registerBasicOutputs();
21
30
  }
22
31
 
23
32
  get volume() {
@@ -35,7 +44,7 @@ class MonoVolume extends Module<Vol, VolumeInterface> {
35
44
  this.internalModule.volume.exponentialRampToValueAtTime(db, triggeredAt);
36
45
  };
37
46
 
38
- triggerRelease = (note: Note, triggeredAt: number) => {
47
+ triggerRelease = () => {
39
48
  // Do nothing
40
49
  };
41
50
  }
@@ -43,8 +52,15 @@ class MonoVolume extends Module<Vol, VolumeInterface> {
43
52
  export default class Volume extends PolyModule<MonoVolume, VolumeInterface> {
44
53
  static moduleName = "Volume";
45
54
 
46
- constructor(name: string, props: Partial<VolumeInterface>) {
55
+ constructor(params: {
56
+ id?: string;
57
+ name: string;
58
+ props: Partial<VolumeInterface>;
59
+ }) {
60
+ const { id, name, props } = params;
61
+
47
62
  super({
63
+ id,
48
64
  name,
49
65
  child: MonoVolume,
50
66
  props: { ...InitialProps, ...props },
@@ -52,13 +68,5 @@ export default class Volume extends PolyModule<MonoVolume, VolumeInterface> {
52
68
 
53
69
  this.registerBasicInputs();
54
70
  this.registerBasicOutputs();
55
- this.registerInputs();
56
- }
57
-
58
- private registerInputs() {
59
- this.registerInput({
60
- name: "midi in",
61
- pluggable: this.midiTriggered,
62
- });
63
71
  }
64
72
  }
@@ -1,8 +1,6 @@
1
1
  import { camelCase, upperFirst } from "lodash";
2
- import Module, { Connectable } from "./Base";
3
- import PolyModule from "./PolyModule";
4
- import Oscillator from "./Oscillator";
5
2
  import { Envelope, AmpEnvelope, FreqEnvelope } from "./Envelope";
3
+ import Oscillator from "./Oscillator";
6
4
  import Filter from "./Filter";
7
5
  import Master from "./Master";
8
6
  import VoiceScheduler from "./VoiceScheduler";
@@ -14,18 +12,15 @@ import Delay from "./Delay";
14
12
  import Distortion from "./Distortion";
15
13
  import BitCrusher from "./BitCrusher";
16
14
  import Sequencer from "./Sequencer";
17
- import DataSequencer from "./DataSequencer";
18
-
19
- export { default } from "./Base";
20
- export { default as PolyModule } from "./PolyModule";
21
- export type { ModuleInterface, Connectable, Triggerable } from "./Base";
15
+ import { AudioModule } from "../core/Module";
22
16
 
17
+ export { default as Master } from "./Master";
23
18
  export { default as Filter } from "./Filter";
24
19
  export { default as Oscillator } from "./Oscillator";
20
+ export { default as VirtualMidi } from "./VirtualMidi";
21
+ export { default as VoiceScheduler } from "./VoiceScheduler";
25
22
  export { default as Sequencer } from "./Sequencer";
26
- export { default as DataSequencer } from "./DataSequencer";
27
23
  export type { ISequence } from "./Sequencer";
28
- export type { IDataSequence } from "./DataSequencer";
29
24
 
30
25
  export {
31
26
  Envelope,
@@ -34,18 +29,18 @@ export {
34
29
  EnvelopeStages,
35
30
  } from "./Envelope";
36
31
 
37
- export type AudioModule =
38
- | Module<Connectable, any>
39
- | PolyModule<Module<Connectable, any>, any>;
32
+ export interface ICreateModule {
33
+ id?: string;
34
+ name: string;
35
+ type: string;
36
+ props: any;
37
+ }
40
38
 
41
- export function createModule(
42
- name: string,
43
- type: string,
44
- props: any
45
- ): AudioModule {
39
+ export function createModule(params: ICreateModule): AudioModule {
40
+ const { id, type, name, props } = params;
46
41
  const klass = moduleClassFromType(type);
47
42
 
48
- return new klass(name, props);
43
+ return new klass({ id, name, props });
49
44
  }
50
45
 
51
46
  function moduleClassFromType(type: string) {
@@ -82,8 +77,6 @@ function moduleClassFromType(type: string) {
82
77
  return BitCrusher;
83
78
  case Sequencer.moduleName:
84
79
  return Sequencer;
85
- case DataSequencer.moduleName:
86
- return DataSequencer;
87
80
  default:
88
81
  throw Error(`Unknown module type ${type}`);
89
82
  }
package/src/routes.ts CHANGED
@@ -1,44 +1,45 @@
1
1
  import { v4 as uuidv4 } from "uuid";
2
2
 
3
3
  import Engine from "./";
4
+ import { plugCompatibleIO } from "./core/IO/Node";
5
+ import { Optional } from "./types";
4
6
 
5
7
  export interface RouteProps {
6
8
  sourceId: string;
7
- outputName: string;
9
+ sourceIOId: string;
8
10
  destinationId: string;
9
- inputName: string;
11
+ destinationIOId: string;
10
12
  }
11
13
 
12
14
  export interface RouteInterface extends RouteProps {
13
15
  id: string;
14
16
  }
15
17
 
16
- export function createRoute(props: RouteProps) {
17
- const id = uuidv4();
18
+ export function createRoute(props: Optional<RouteInterface, "id">) {
19
+ const id = props.id || uuidv4();
18
20
 
19
21
  return { ...props, id };
20
22
  }
21
23
 
22
24
  export function applyRoutes(routes: RouteInterface[]) {
23
- Object.values(Engine.modules).forEach((m) => m.unplugAll());
25
+ Object.values(Engine.modules).forEach((m) => {
26
+ m.unPlugAll();
27
+ });
24
28
 
25
- const succesedConnections = routes
26
- .sort((r1, r2) => {
27
- if (r1.outputName === "number of voices") return -1;
28
- if (r2.outputName === "number of voices") return 1;
29
+ const succesedConnections = routes.map((route) => {
30
+ const { sourceId, sourceIOId, destinationId, destinationIOId } = route;
29
31
 
30
- return 0;
31
- })
32
- .map((route) => {
33
- const { sourceId, outputName, destinationId, inputName } = route;
32
+ const source = Engine.findById(sourceId);
33
+ const destination = Engine.findById(destinationId);
34
34
 
35
- const source = Engine.findById(sourceId);
36
- const destination = Engine.findById(destinationId);
35
+ const output = source.outputs.find(sourceIOId);
36
+ const input = destination.inputs.find(destinationIOId);
37
+ if (!input || !output) throw Error("IO not found");
37
38
 
38
- source.plug(destination, outputName, inputName);
39
+ plugCompatibleIO(input, output);
39
40
 
40
- return true;
41
- });
41
+ return true;
42
+ });
42
43
 
43
44
  if (succesedConnections.every((v) => v)) {
44
45
  console.log("######## Routes succesfully applied");
package/src/types.ts ADDED
@@ -0,0 +1,3 @@
1
+ export type AnyObject = { [Key: string]: any };
2
+ export type AtLeast<T, K extends keyof T> = Partial<T> & Pick<T, K>;
3
+ export type Optional<T, K extends keyof T> = Partial<Pick<T, K>> & Omit<T, K>;
package/src/utils.ts ADDED
@@ -0,0 +1,18 @@
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
+ }