@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.
Files changed (144) hide show
  1. package/.eslintrc.js +14 -0
  2. package/.parcerc +6 -0
  3. package/README.md +13 -1
  4. package/dist/main.cjs.js +33 -0
  5. package/package.json +21 -22
  6. package/rollup.config.mjs +21 -0
  7. package/src/Engine.ts +27 -36
  8. package/src/core/IO/AudioNode.ts +77 -0
  9. package/src/core/IO/Collection.ts +76 -0
  10. package/src/core/IO/ForwardNode.ts +192 -0
  11. package/src/core/IO/MidiNode.ts +67 -0
  12. package/src/core/IO/Node.ts +117 -0
  13. package/src/core/IO/index.ts +47 -0
  14. package/src/core/Module/MonoModule.ts +219 -0
  15. package/src/core/Module/PolyModule.ts +206 -0
  16. package/src/core/Module/index.ts +15 -0
  17. package/src/{Note → core/Note}/index.ts +19 -4
  18. package/src/{MidiDeviceManager.ts → core/midi/MidiDeviceManager.ts} +20 -15
  19. package/src/core/midi/MidiEvent.ts +91 -0
  20. package/src/core/midi/index.ts +5 -0
  21. package/src/index.ts +8 -12
  22. package/src/{Module → modules}/BitCrusher.ts +15 -4
  23. package/src/{Module → modules}/Delay.ts +15 -4
  24. package/src/{Module → modules}/Distortion.ts +15 -4
  25. package/src/{Module → modules}/Effect.ts +10 -6
  26. package/src/modules/Envelope/AmpEnvelope.ts +23 -0
  27. package/src/{Module → modules}/Envelope/Base.ts +50 -31
  28. package/src/{Module → modules}/Envelope/FreqEnvelope.ts +18 -23
  29. package/src/{Module → modules}/Filter.ts +18 -46
  30. package/src/{Module → modules}/Master.ts +8 -2
  31. package/src/{Module → modules}/MidiSelector.ts +18 -14
  32. package/src/{Module → modules}/Oscillator.ts +27 -16
  33. package/src/{Module → modules}/Reverb.ts +15 -4
  34. package/src/{Module → modules}/Sequencer.ts +17 -13
  35. package/src/{Module → modules}/VirtualMidi.ts +16 -12
  36. package/src/modules/VoiceScheduler.ts +145 -0
  37. package/src/{Module → modules}/Volume.ts +23 -15
  38. package/src/{Module → modules}/index.ts +14 -21
  39. package/src/routes.ts +19 -18
  40. package/src/types.ts +3 -0
  41. package/src/utils.ts +18 -0
  42. package/test/MockingModules.ts +27 -0
  43. package/test/Module/Oscillator.test.ts +1 -1
  44. package/test/core/IO.test.ts +172 -0
  45. package/build/Engine.d.ts +0 -89
  46. package/build/Engine.js +0 -165
  47. package/build/Engine.js.map +0 -1
  48. package/build/MidiDevice.d.ts +0 -25
  49. package/build/MidiDevice.js +0 -45
  50. package/build/MidiDevice.js.map +0 -1
  51. package/build/MidiDeviceManager.d.ts +0 -13
  52. package/build/MidiDeviceManager.js +0 -59
  53. package/build/MidiDeviceManager.js.map +0 -1
  54. package/build/MidiEvent.d.ts +0 -18
  55. package/build/MidiEvent.js +0 -64
  56. package/build/MidiEvent.js.map +0 -1
  57. package/build/Module/Base.d.ts +0 -63
  58. package/build/Module/Base.js +0 -138
  59. package/build/Module/Base.js.map +0 -1
  60. package/build/Module/BitCrusher.d.ts +0 -12
  61. package/build/Module/BitCrusher.js +0 -22
  62. package/build/Module/BitCrusher.js.map +0 -1
  63. package/build/Module/DataSequencer.d.ts +0 -26
  64. package/build/Module/DataSequencer.js +0 -91
  65. package/build/Module/DataSequencer.js.map +0 -1
  66. package/build/Module/Delay.d.ts +0 -15
  67. package/build/Module/Delay.js +0 -30
  68. package/build/Module/Delay.js.map +0 -1
  69. package/build/Module/Distortion.d.ts +0 -12
  70. package/build/Module/Distortion.js +0 -22
  71. package/build/Module/Distortion.js.map +0 -1
  72. package/build/Module/Effect.d.ts +0 -14
  73. package/build/Module/Effect.js +0 -22
  74. package/build/Module/Effect.js.map +0 -1
  75. package/build/Module/Envelope/AmpEnvelope.d.ts +0 -10
  76. package/build/Module/Envelope/AmpEnvelope.js +0 -14
  77. package/build/Module/Envelope/AmpEnvelope.js.map +0 -1
  78. package/build/Module/Envelope/Base.d.ts +0 -47
  79. package/build/Module/Envelope/Base.js +0 -106
  80. package/build/Module/Envelope/Base.js.map +0 -1
  81. package/build/Module/Envelope/FreqEnvelope.d.ts +0 -18
  82. package/build/Module/Envelope/FreqEnvelope.js +0 -50
  83. package/build/Module/Envelope/FreqEnvelope.js.map +0 -1
  84. package/build/Module/Envelope/index.d.ts +0 -3
  85. package/build/Module/Envelope/index.js +0 -4
  86. package/build/Module/Envelope/index.js.map +0 -1
  87. package/build/Module/Filter.d.ts +0 -37
  88. package/build/Module/Filter.js +0 -100
  89. package/build/Module/Filter.js.map +0 -1
  90. package/build/Module/IO.d.ts +0 -39
  91. package/build/Module/IO.js +0 -59
  92. package/build/Module/IO.js.map +0 -1
  93. package/build/Module/Master.d.ts +0 -8
  94. package/build/Module/Master.js +0 -12
  95. package/build/Module/Master.js.map +0 -1
  96. package/build/Module/MidiSelector.d.ts +0 -17
  97. package/build/Module/MidiSelector.js +0 -50
  98. package/build/Module/MidiSelector.js.map +0 -1
  99. package/build/Module/Oscillator.d.ts +0 -45
  100. package/build/Module/Oscillator.js +0 -136
  101. package/build/Module/Oscillator.js.map +0 -1
  102. package/build/Module/PolyModule.d.ts +0 -49
  103. package/build/Module/PolyModule.js +0 -175
  104. package/build/Module/PolyModule.js.map +0 -1
  105. package/build/Module/Reverb.d.ts +0 -15
  106. package/build/Module/Reverb.js +0 -30
  107. package/build/Module/Reverb.js.map +0 -1
  108. package/build/Module/Sequencer.d.ts +0 -38
  109. package/build/Module/Sequencer.js +0 -131
  110. package/build/Module/Sequencer.js.map +0 -1
  111. package/build/Module/VirtualMidi.d.ts +0 -28
  112. package/build/Module/VirtualMidi.js +0 -53
  113. package/build/Module/VirtualMidi.js.map +0 -1
  114. package/build/Module/VoiceScheduler.d.ts +0 -38
  115. package/build/Module/VoiceScheduler.js +0 -130
  116. package/build/Module/VoiceScheduler.js.map +0 -1
  117. package/build/Module/Volume.d.ts +0 -20
  118. package/build/Module/Volume.js +0 -48
  119. package/build/Module/Volume.js.map +0 -1
  120. package/build/Module/index.d.ts +0 -14
  121. package/build/Module/index.js +0 -66
  122. package/build/Module/index.js.map +0 -1
  123. package/build/Note/frequencyTable.d.ts +0 -4
  124. package/build/Note/frequencyTable.js +0 -146
  125. package/build/Note/frequencyTable.js.map +0 -1
  126. package/build/Note/index.d.ts +0 -25
  127. package/build/Note/index.js +0 -81
  128. package/build/Note/index.js.map +0 -1
  129. package/build/index.d.ts +0 -8
  130. package/build/index.js +0 -5
  131. package/build/index.js.map +0 -1
  132. package/build/routes.d.ts +0 -17
  133. package/build/routes.js +0 -31
  134. package/build/routes.js.map +0 -1
  135. package/src/MidiEvent.ts +0 -93
  136. package/src/Module/Base.ts +0 -223
  137. package/src/Module/DataSequencer.ts +0 -121
  138. package/src/Module/Envelope/AmpEnvelope.ts +0 -17
  139. package/src/Module/IO.ts +0 -85
  140. package/src/Module/PolyModule.ts +0 -234
  141. package/src/Module/VoiceScheduler.ts +0 -161
  142. /package/src/{Note → core/Note}/frequencyTable.ts +0 -0
  143. /package/src/{MidiDevice.ts → core/midi/MidiDevice.ts} +0 -0
  144. /package/src/{Module → modules}/Envelope/index.ts +0 -0
package/build/index.d.ts DELETED
@@ -1,8 +0,0 @@
1
- export { default } from "./Engine";
2
- export { default as MidiDevice } from "./MidiDevice";
3
- export { default as MidiDeviceManager } from "./MidiDeviceManager";
4
- export { default as Note } from "./Note";
5
- export type { INote } from "./Note";
6
- export type { MidiDeviceInterface } from "./MidiDevice";
7
- export type { ModuleInterface, AudioModule, ISequence, IDataSequence, } from "./Module";
8
- export type { SerializeInterface as IOProps } from "./Module/IO";
package/build/index.js DELETED
@@ -1,5 +0,0 @@
1
- export { default } from "./Engine";
2
- export { default as MidiDevice } from "./MidiDevice";
3
- export { default as MidiDeviceManager } from "./MidiDeviceManager";
4
- export { default as Note } from "./Note";
5
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC"}
package/build/routes.d.ts DELETED
@@ -1,17 +0,0 @@
1
- export interface RouteProps {
2
- sourceId: string;
3
- outputName: string;
4
- destinationId: string;
5
- inputName: string;
6
- }
7
- export interface RouteInterface extends RouteProps {
8
- id: string;
9
- }
10
- export declare function createRoute(props: RouteProps): {
11
- id: string;
12
- sourceId: string;
13
- outputName: string;
14
- destinationId: string;
15
- inputName: string;
16
- };
17
- export declare function applyRoutes(routes: RouteInterface[]): void;
package/build/routes.js DELETED
@@ -1,31 +0,0 @@
1
- import { v4 as uuidv4 } from "uuid";
2
- import Engine from "./";
3
- export function createRoute(props) {
4
- const id = uuidv4();
5
- return { ...props, id };
6
- }
7
- export function applyRoutes(routes) {
8
- Object.values(Engine.modules).forEach((m) => m.unplugAll());
9
- const succesedConnections = routes
10
- .sort((r1, r2) => {
11
- if (r1.outputName === "number of voices")
12
- return -1;
13
- if (r2.outputName === "number of voices")
14
- return 1;
15
- return 0;
16
- })
17
- .map((route) => {
18
- const { sourceId, outputName, destinationId, inputName } = route;
19
- const source = Engine.findById(sourceId);
20
- const destination = Engine.findById(destinationId);
21
- source.plug(destination, outputName, inputName);
22
- return true;
23
- });
24
- if (succesedConnections.every((v) => v)) {
25
- console.log("######## Routes succesfully applied");
26
- }
27
- else {
28
- console.log("######## Routes partialy applied");
29
- }
30
- }
31
- //# sourceMappingURL=routes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,MAAM,MAAM,IAAI,CAAC;AAaxB,MAAM,UAAU,WAAW,CAAC,KAAiB;IAC3C,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IAEpB,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAwB;IAClD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IAE5D,MAAM,mBAAmB,GAAG,MAAM;SAC/B,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;QACf,IAAI,EAAE,CAAC,UAAU,KAAK,kBAAkB;YAAE,OAAO,CAAC,CAAC,CAAC;QACpD,IAAI,EAAE,CAAC,UAAU,KAAK,kBAAkB;YAAE,OAAO,CAAC,CAAC;QAEnD,OAAO,CAAC,CAAC;IACX,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;QAEjE,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACzC,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAEnD,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QAEhD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEL,IAAI,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE;QACvC,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;KACpD;SAAM;QACL,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;KACjD;AACH,CAAC"}
package/src/MidiEvent.ts DELETED
@@ -1,93 +0,0 @@
1
- import { now } from "tone";
2
- import { ISequence } from "./Module/Sequencer";
3
- import { IDataSequence } from "./Module/DataSequencer";
4
- import Note, { INote } from "./Note";
5
-
6
- const EventType: { [key: number]: EType } = {
7
- 8: "noteOff",
8
- 9: "noteOn",
9
- };
10
-
11
- export type EType = "noteOn" | "noteOff";
12
-
13
- export default class MidiEvent {
14
- notes: Note[];
15
- readonly triggeredAt: number;
16
- _type: EType;
17
- private data: Uint8Array;
18
- private event: MIDIMessageEvent;
19
-
20
- static fromDataSequence(sequence: IDataSequence, triggeredAt: number) {
21
- const event = new MidiEvent(
22
- new MIDIMessageEvent("", { data: new Uint8Array([0, 0, 0]) }),
23
- triggeredAt
24
- );
25
- event._type = "noteOn";
26
- const note = new Note(sequence.frequency);
27
- note.velocity = sequence.amplitude;
28
- event.notes = [note];
29
-
30
- return event;
31
- }
32
-
33
- static fromSequence(sequence: ISequence, triggeredAt: number) {
34
- const event = new MidiEvent(
35
- new MIDIMessageEvent("", { data: new Uint8Array([0, 0, 0]) }),
36
- triggeredAt
37
- );
38
- event._type = "noteOn";
39
- event.notes = sequence.notes.map((n) => new Note(n));
40
-
41
- return event;
42
- }
43
-
44
- static fromNote(
45
- noteName: string | Note | INote,
46
- type: EType,
47
- triggeredAt?: number
48
- ) {
49
- const event = new MidiEvent(
50
- new MIDIMessageEvent("", { data: new Uint8Array([0, 0, 0]) }),
51
- triggeredAt
52
- );
53
-
54
- if (noteName instanceof Note) {
55
- event.notes = [noteName];
56
- } else {
57
- event.notes = [new Note(noteName)];
58
- }
59
- event._type = type;
60
-
61
- return event;
62
- }
63
-
64
- constructor(event: MIDIMessageEvent, triggeredAt?: number) {
65
- this.event = event;
66
- this.triggeredAt = triggeredAt || now();
67
- this.data = event.data;
68
- this.defineNotes();
69
- }
70
-
71
- get type() {
72
- if (this._type) return this._type;
73
-
74
- let type = EventType[this.data[0] >> 4];
75
-
76
- if (type === "noteOn" && this.data[2] === 0) {
77
- type = "noteOff";
78
- }
79
-
80
- return (this._type = type);
81
- }
82
-
83
- get isNote() {
84
- return this.type === "noteOn" || this.type === "noteOff";
85
- }
86
-
87
- defineNotes() {
88
- if (!this.isNote) return;
89
- if (this.notes) return;
90
-
91
- this.notes = [new Note(this.event)];
92
- }
93
- }
@@ -1,223 +0,0 @@
1
- import { v4 as uuidv4 } from "uuid";
2
- import { InputNode } from "tone";
3
-
4
- import { Input, Output, IOInterface } from "./IO";
5
- import MidiEvent from "../MidiEvent";
6
- import { AudioModule, PolyModule } from "../Module";
7
- import Note from "../Note";
8
-
9
- export interface Connectable {
10
- connect: (inputNode: InputNode) => void;
11
- disconnect: (inputNode?: InputNode) => void;
12
- dispose: () => void;
13
- }
14
-
15
- export interface Triggerable {
16
- triggerAttack: Function;
17
- triggerRelease: Function;
18
- }
19
-
20
- export interface Voicable {
21
- voiceNo?: number;
22
- }
23
-
24
- export interface ModuleInterface<PropsInterface> {
25
- name: string;
26
- props: PropsInterface;
27
- voiceNo?: number;
28
- }
29
-
30
- export class DummnyInternalModule implements Connectable {
31
- connect(inputNode: InputNode) {
32
- throw Error("This module is not connectable");
33
- }
34
-
35
- disconnect(inputNode?: InputNode) {}
36
-
37
- dispose() {}
38
- }
39
-
40
- class Module<InternalModule extends Connectable, PropsInterface>
41
- implements ModuleInterface<PropsInterface>
42
- {
43
- static readonly moduleName: string;
44
-
45
- readonly id: string;
46
- name: string;
47
- internalModule: InternalModule;
48
- inputs: Input[] = [];
49
- outputs: Output[] = [];
50
- readonly voiceNo?: number;
51
- updatedAt: Date;
52
- _props: PropsInterface = {} as PropsInterface;
53
-
54
- constructor(
55
- internalModule: InternalModule,
56
- props: Partial<ModuleInterface<PropsInterface>>
57
- ) {
58
- this.internalModule = internalModule;
59
- this.id = uuidv4();
60
-
61
- Object.assign(this, props);
62
- }
63
-
64
- set props(value: PropsInterface) {
65
- if (!value) return;
66
-
67
- this.updatedAt = new Date();
68
-
69
- Object.assign(this, value);
70
- }
71
-
72
- get props() {
73
- return this._props;
74
- }
75
-
76
- plug(audioModule: AudioModule, from: string, to: string) {
77
- const output = this.outputs.find((i) => i.name === from);
78
- if (!output) throw Error(`Output ${from} not exist`);
79
-
80
- const input = audioModule.inputs.find((i) => i.name === to);
81
- if (!input)
82
- throw Error(`Input ${to} in module ${audioModule.name} not exist`);
83
-
84
- output.plug(input);
85
- }
86
-
87
- unplugAll() {
88
- this.outputs.forEach((o) => o.unPlugAll());
89
- }
90
-
91
- connect = (
92
- inputAudioModule: AudioModule,
93
- attribute: string = "internalModule"
94
- ) => {
95
- if (inputAudioModule instanceof PolyModule) {
96
- inputAudioModule.audioModules.forEach((m) => {
97
- this.internalModule.connect((m as any)[attribute] as InputNode);
98
- });
99
- return;
100
- }
101
-
102
- this.internalModule.connect(
103
- (inputAudioModule as any)[attribute] as InputNode
104
- );
105
- };
106
-
107
- disconnect = (
108
- inputAudioModule: AudioModule,
109
- attribute: string = "internalModule"
110
- ) => {
111
- if (inputAudioModule instanceof PolyModule) {
112
- inputAudioModule.audioModules.forEach((m) => {
113
- this.internalModule.disconnect((m as any)[attribute] as InputNode);
114
- });
115
- return;
116
- }
117
-
118
- this.internalModule.disconnect(
119
- (inputAudioModule as any)[attribute] as InputNode
120
- );
121
- };
122
-
123
- dispose() {
124
- this.internalModule.dispose();
125
- }
126
-
127
- triggerAttack(note: Note, triggeredAt: number) {
128
- throw Error("triggerAttack not implemented");
129
- }
130
-
131
- triggerRelease(note: Note, triggeredAt: number) {
132
- throw Error("triggerRelease not implemented");
133
- }
134
-
135
- midiTriggered = (midiEvent: MidiEvent, noteIndex?: number) => {
136
- const { notes, triggeredAt } = midiEvent;
137
-
138
- switch (midiEvent.type) {
139
- case "noteOn":
140
- const { duration } = notes[0];
141
-
142
- this.triggerer(this.triggerAttack, notes, triggeredAt, noteIndex);
143
-
144
- if (duration) {
145
- const releaseTriggeredAt =
146
- triggeredAt + (this.internalModule as any).toSeconds(duration);
147
- this.triggerer(
148
- this.triggerRelease,
149
- notes,
150
- releaseTriggeredAt,
151
- noteIndex
152
- );
153
- }
154
- break;
155
- case "noteOff":
156
- this.triggerer(this.triggerRelease, notes, triggeredAt, noteIndex);
157
- break;
158
- default:
159
- throw Error("This type is not a note");
160
- }
161
- };
162
-
163
- private triggerer(
164
- trigger: Function,
165
- notes: Note[],
166
- triggeredAt: number,
167
- noteIndex?: number
168
- ) {
169
- if (noteIndex !== undefined && this.voiceNo !== undefined) {
170
- trigger(notes[noteIndex], triggeredAt);
171
- return;
172
- }
173
-
174
- notes.forEach((note) => trigger(note, triggeredAt));
175
- }
176
-
177
- serialize() {
178
- const klass = this.constructor as typeof Module;
179
-
180
- return {
181
- id: this.id,
182
- name: this.name,
183
- type: klass.moduleName,
184
- props: this.props,
185
- inputs: this.inputs.map((i) => i.serialize()),
186
- outputs: this.outputs.map((i) => i.serialize()),
187
- };
188
- }
189
-
190
- protected registerInput(props: IOInterface): Input {
191
- const input = new Input(this, props);
192
- this.inputs.push(input);
193
-
194
- return input;
195
- }
196
-
197
- protected registerOutput(props: IOInterface): Output {
198
- const output = new Output(this, props);
199
- this.outputs.push(output);
200
-
201
- return output;
202
- }
203
-
204
- protected registerBasicOutputs() {
205
- this.registerOutput({
206
- name: "output",
207
- onPlug: (output: Output) => {
208
- this.connect(output.audioModule);
209
- },
210
- onUnPlug: (output: Output) => {
211
- this.disconnect(output.audioModule);
212
- },
213
- });
214
- }
215
-
216
- protected registerBasicInputs() {
217
- this.registerInput({
218
- name: "input",
219
- });
220
- }
221
- }
222
-
223
- export default Module;
@@ -1,121 +0,0 @@
1
- import { Loop, now } from "tone";
2
-
3
- import Module, { DummnyInternalModule } from "./Base";
4
- import { Output } from "./IO";
5
- import MidiEvent from "../MidiEvent";
6
- import { sortBy, uniq } from "lodash";
7
- import Engine from "../Engine";
8
-
9
- interface IDataSequencer {
10
- sequences: IDataSequence[];
11
- }
12
-
13
- export interface IDataSequence {
14
- voiceNo: number;
15
- time: number;
16
- frequency: number;
17
- amplitude: number;
18
- }
19
-
20
- const InitialProps = () => ({
21
- sequences: [],
22
- });
23
-
24
- export default class DataSequencer extends Module<
25
- DummnyInternalModule,
26
- IDataSequencer
27
- > {
28
- static moduleName = "DataSequencer";
29
- private midiOutput: Output;
30
- private prevNumberOfVoices: number;
31
- private loop: Loop;
32
-
33
- constructor(name: string, props: Partial<IDataSequence>) {
34
- super(new DummnyInternalModule(), {
35
- name,
36
- props: { ...InitialProps(), ...props },
37
- });
38
-
39
- this.start(now());
40
- this.registerOutputs();
41
- }
42
-
43
- get sequences() {
44
- return this._props["sequences"];
45
- }
46
-
47
- set sequences(value: IDataSequence[]) {
48
- const sequences = sortBy(value, (seq) => -seq.time);
49
- this._props = { ...this.props, sequences };
50
- this.updateNumberOfVoices();
51
- this.start(now());
52
- }
53
-
54
- start(time: number) {
55
- if (!Engine.isStarted) return;
56
- Engine.updateRoutes();
57
-
58
- const loopLength = 0.1;
59
- const tempSequences = [...this.sequences];
60
- const iterate = (maxTime: number) => {
61
- const sequence = tempSequences.pop();
62
- if (!sequence) return;
63
-
64
- const seqTime = time + sequence.time;
65
- this.onPartEvent(seqTime, sequence);
66
- if (seqTime > maxTime) return;
67
-
68
- iterate(maxTime);
69
- };
70
-
71
- this.loop = new Loop((t) => {
72
- iterate(time + t + loopLength);
73
- }, loopLength).start(time);
74
- }
75
-
76
- stop() {
77
- if (!this.loop) return;
78
-
79
- this.loop.stop();
80
- this.loop.dispose();
81
- }
82
-
83
- private onPartEvent = (time: number, sequence: IDataSequence) => {
84
- const { voiceNo } = sequence;
85
- const event = MidiEvent.fromDataSequence(sequence, time);
86
-
87
- this.midiOutput.connections.forEach((input) => {
88
- input.pluggable(event, voiceNo);
89
- });
90
- };
91
-
92
- private get numberOfVoices() {
93
- return uniq(this.sequences.map((sequence) => sequence.voiceNo)).length;
94
- }
95
-
96
- private updateNumberOfVoices() {
97
- if (!this.midiOutput) return;
98
-
99
- this.midiOutput.connections.forEach((input) => {
100
- if (input.audioModule instanceof Module) return;
101
-
102
- input.audioModule.numberOfVoices = this.numberOfVoices;
103
- });
104
-
105
- if (this.prevNumberOfVoices !== this.numberOfVoices) {
106
- Engine.updateRoutes();
107
- }
108
- this.prevNumberOfVoices = this.numberOfVoices;
109
- }
110
-
111
- private registerOutputs() {
112
- this.midiOutput = this.registerOutput({
113
- name: "midi out",
114
- onPlug: (input) => {
115
- if (input.audioModule instanceof Module) return;
116
-
117
- input.audioModule.numberOfVoices = this.numberOfVoices;
118
- },
119
- });
120
- }
121
- }
@@ -1,17 +0,0 @@
1
- import { AmplitudeEnvelope } from "tone";
2
-
3
- import Base, { EnvelopeInterface, PolyBase } from "./Base";
4
-
5
- class MonoAmpEnvelope extends Base<AmplitudeEnvelope> {
6
- constructor(name: string, props: EnvelopeInterface) {
7
- super(name, new AmplitudeEnvelope(), props);
8
- }
9
- }
10
-
11
- export default class AmpEnvelope extends PolyBase<MonoAmpEnvelope> {
12
- static moduleName = "AmpEnvelope";
13
-
14
- constructor(name: string, props: Partial<EnvelopeInterface>) {
15
- super(name, MonoAmpEnvelope, props);
16
- }
17
- }
package/src/Module/IO.ts DELETED
@@ -1,85 +0,0 @@
1
- import { v4 as uuidv4 } from "uuid";
2
- import { AudioModule } from "../Module";
3
-
4
- export interface IOInterface {
5
- name: string;
6
- pluggable?: any;
7
- onPlug?: (io: IO) => void;
8
- onUnPlug?: (io: IO) => void;
9
- }
10
-
11
- export interface SerializeInterface {
12
- id: string;
13
- name: string;
14
- moduleId: string;
15
- moduleName: string;
16
- }
17
-
18
- enum IOType {
19
- Input = "input",
20
- Output = "output",
21
- }
22
-
23
- abstract class IO {
24
- id: string;
25
- ioType: IOType;
26
- name: string;
27
- audioModule: AudioModule;
28
- pluggable: any;
29
- onPlug: (io: IO) => void;
30
- onUnPlug: (io: IO) => void;
31
- connections: Input[] | Output[] = [];
32
-
33
- constructor(ioType: IOType, audioModule: AudioModule, props: IOInterface) {
34
- this.id = uuidv4();
35
- this.ioType = ioType;
36
- this.audioModule = audioModule;
37
-
38
- Object.assign(this, props);
39
- }
40
-
41
- plug(io: IO) {
42
- this.connections.push(io);
43
-
44
- if (this.onPlug) this.onPlug(io);
45
-
46
- if (this.ioType === IOType.Output) io.plug(this);
47
- }
48
-
49
- unPlug(io: IO) {
50
- if (this.onUnPlug) this.onUnPlug(io);
51
-
52
- if (this.ioType === IOType.Output) {
53
- io.unPlug(this);
54
- }
55
-
56
- this.connections = this.connections.filter(
57
- (current_io) => current_io.id !== io.id
58
- );
59
- }
60
-
61
- unPlugAll() {
62
- this.connections.forEach((c) => this.unPlug(c));
63
- }
64
-
65
- serialize(): SerializeInterface {
66
- return {
67
- id: this.id,
68
- name: this.name,
69
- moduleId: this.audioModule.id,
70
- moduleName: this.audioModule.name,
71
- };
72
- }
73
- }
74
-
75
- export class Input extends IO {
76
- constructor(audioModule: AudioModule, props: IOInterface) {
77
- super(IOType.Input, audioModule, props);
78
- }
79
- }
80
-
81
- export class Output extends IO {
82
- constructor(audioModule: AudioModule, props: IOInterface) {
83
- super(IOType.Output, audioModule, props);
84
- }
85
- }