@fluex/fluexgl-dsp 0.4.2 → 0.4.3
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/lib/dist/console-codes.d.ts +22 -7
- package/lib/dist/console-codes.d.ts.map +1 -1
- package/lib/dist/console-codes.js +22 -7
- package/lib/dist/core/classes/AudioClip.d.ts.map +1 -1
- package/lib/dist/core/classes/AudioClip.js +5 -12
- package/lib/dist/core/classes/AudioClipPlayer.d.ts +2 -0
- package/lib/dist/core/classes/AudioClipPlayer.d.ts.map +1 -1
- package/lib/dist/core/classes/AudioClipPlayer.js +9 -2
- package/lib/dist/core/classes/AudioDevice.d.ts +1 -1
- package/lib/dist/core/classes/AudioDevice.d.ts.map +1 -1
- package/lib/dist/core/classes/AudioDevice.js +3 -2
- package/lib/dist/core/classes/Channel.d.ts +4 -2
- package/lib/dist/core/classes/Channel.d.ts.map +1 -1
- package/lib/dist/core/classes/Channel.js +28 -9
- package/lib/dist/core/classes/Master.d.ts.map +1 -1
- package/lib/dist/core/classes/Master.js +5 -4
- package/lib/dist/utilities/helpers.js +1 -1
- package/lib/dist/utilities/web-assembly.d.ts.map +1 -1
- package/lib/dist/utilities/web-assembly.js +6 -0
- package/lib/src/console-codes.ts +22 -7
- package/lib/src/core/classes/AudioClip.ts +5 -12
- package/lib/src/core/classes/AudioClipPlayer.ts +11 -2
- package/lib/src/core/classes/AudioDevice.ts +3 -3
- package/lib/src/core/classes/Channel.ts +31 -11
- package/lib/src/core/classes/Master.ts +5 -4
- package/lib/src/utilities/helpers.ts +1 -1
- package/lib/src/utilities/web-assembly.ts +8 -0
- package/package.json +1 -1
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
export declare enum ErrorCodes {
|
|
2
|
-
NO_CONTEXT_PERMISSION = "FLUEXGL@
|
|
3
|
-
NO_FILE_TYPE_FOUND = "FLUEXGL@
|
|
4
|
-
PATH_TO_FILE_NOT_FOUND = "FLUEXGL@
|
|
5
|
-
SAME_MASTER_CHANNEL = "FLUEXGL@
|
|
6
|
-
WASM_MODULE_INITIALIZATION_FAILED = "FLUEXGL@
|
|
7
|
-
PATH_TO_WASM_FILE_NOT_FOUND = "FLUEXGL@
|
|
2
|
+
NO_CONTEXT_PERMISSION = "ERROR:FLUEXGL-DSP@0001",
|
|
3
|
+
NO_FILE_TYPE_FOUND = "ERROR:FLUEXGL-DSP@0002",
|
|
4
|
+
PATH_TO_FILE_NOT_FOUND = "ERROR:FLUEXGL-DSP@0003",
|
|
5
|
+
SAME_MASTER_CHANNEL = "ERROR:FLUEXGL-DSP@0004",
|
|
6
|
+
WASM_MODULE_INITIALIZATION_FAILED = "ERROR:FLUEXGL-DSP@0005",
|
|
7
|
+
PATH_TO_WASM_FILE_NOT_FOUND = "ERROR:FLUEXGL-DSP@0006",
|
|
8
|
+
WASM_COMPILATION_ERROR = "ERROR:FLUEXGL-DSP@0007",
|
|
9
|
+
WORKLET_NO_WASM_MODULE_INSTANTIATED = "ERROR:FLUEXGL-DSP@0008",
|
|
10
|
+
EFFECT_ALREADY_ATTACHED = "ERROR:FLUEXGL-DSP@0009",
|
|
11
|
+
EFFECT_NOT_FOUND = "ERROR:FLUEXGL-DSP@0010",
|
|
12
|
+
CHANNEL_ALREADY_ATTACHED = "ERROR:FLUEXGL-DSP@0011",
|
|
13
|
+
CHANNEL_NOT_FOUND = "ERROR:FLUEXGL-DSP@0012",
|
|
14
|
+
CHANNEL_CANNOT_LINK_TO_ITSELF = "ERROR:FLUEXGL-DSP@0013",
|
|
15
|
+
CHANNEL_NOT_INITIALIZED = "ERROR:FLUEXGL-DSP@0014",
|
|
16
|
+
CHANNEL_NOT_SAME_AUDIO_CONTEXT = "ERROR:FLUEXGL-DSP@0015",
|
|
17
|
+
CHANNEL_ALREADY_LINKED = "ERROR:FLUEXGL-DSP@0016",
|
|
18
|
+
CHANNEL_POSSIBLE_FEEDBACK_LOOP = "ERROR:FLUEXGL-DSP@0017",
|
|
19
|
+
AUDIO_CLIP_ALREADY_ATTACHED = "ERROR:FLUEXGL-DSP@0018",
|
|
20
|
+
AUDIO_CLIP_NOT_FOUND = "ERROR:FLUEXGL-DSP@0019",
|
|
21
|
+
AUDIO_CLIP_PLAYER_NO_CONTEXT = "ERROR:FLUEXGL-DSP@0020",
|
|
22
|
+
PANNING_OUT_OF_RANGE = "ERROR:FLUEXGL-DSP@0021"
|
|
8
23
|
}
|
|
9
24
|
export declare enum WarningCodes {
|
|
10
|
-
NO_DEFAULT_AUDIO_DEVICE_FOUND = "FLUEXGL@
|
|
25
|
+
NO_DEFAULT_AUDIO_DEVICE_FOUND = "WARNING:FLUEXGL-DSP@0001"
|
|
11
26
|
}
|
|
12
27
|
export declare enum SuccessCodes {
|
|
13
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console-codes.d.ts","sourceRoot":"","sources":["../src/console-codes.ts"],"names":[],"mappings":"AAAA,oBAAY,UAAU;IAClB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"console-codes.d.ts","sourceRoot":"","sources":["../src/console-codes.ts"],"names":[],"mappings":"AAAA,oBAAY,UAAU;IAClB,qBAAqB,2BAA2B;IAChD,kBAAkB,2BAA2B;IAC7C,sBAAsB,2BAA2B;IACjD,mBAAmB,2BAA2B;IAC9C,iCAAiC,2BAA2B;IAC5D,2BAA2B,2BAA2B;IACtD,sBAAsB,2BAA2B;IACjD,mCAAmC,2BAA2B;IAC9D,uBAAuB,2BAA2B;IAClD,gBAAgB,2BAA2B;IAC3C,wBAAwB,2BAA2B;IACnD,iBAAiB,2BAA2B;IAC5C,6BAA6B,2BAA2B;IACxD,uBAAuB,2BAA2B;IAClD,8BAA8B,2BAA2B;IACzD,sBAAsB,2BAA2B;IACjD,8BAA8B,2BAA2B;IACzD,2BAA2B,2BAA2B;IACtD,oBAAoB,2BAA2B;IAC/C,4BAA4B,2BAA2B;IACvD,oBAAoB,2BAA2B;CAClD;AAED,oBAAY,YAAY;IACpB,6BAA6B,6BAA6B;CAC7D;AAED,oBAAY,YAAY;CAEvB"}
|
|
@@ -1,15 +1,30 @@
|
|
|
1
1
|
export var ErrorCodes;
|
|
2
2
|
(function (ErrorCodes) {
|
|
3
|
-
ErrorCodes["NO_CONTEXT_PERMISSION"] = "FLUEXGL@
|
|
4
|
-
ErrorCodes["NO_FILE_TYPE_FOUND"] = "FLUEXGL@
|
|
5
|
-
ErrorCodes["PATH_TO_FILE_NOT_FOUND"] = "FLUEXGL@
|
|
6
|
-
ErrorCodes["SAME_MASTER_CHANNEL"] = "FLUEXGL@
|
|
7
|
-
ErrorCodes["WASM_MODULE_INITIALIZATION_FAILED"] = "FLUEXGL@
|
|
8
|
-
ErrorCodes["PATH_TO_WASM_FILE_NOT_FOUND"] = "FLUEXGL@
|
|
3
|
+
ErrorCodes["NO_CONTEXT_PERMISSION"] = "ERROR:FLUEXGL-DSP@0001";
|
|
4
|
+
ErrorCodes["NO_FILE_TYPE_FOUND"] = "ERROR:FLUEXGL-DSP@0002";
|
|
5
|
+
ErrorCodes["PATH_TO_FILE_NOT_FOUND"] = "ERROR:FLUEXGL-DSP@0003";
|
|
6
|
+
ErrorCodes["SAME_MASTER_CHANNEL"] = "ERROR:FLUEXGL-DSP@0004";
|
|
7
|
+
ErrorCodes["WASM_MODULE_INITIALIZATION_FAILED"] = "ERROR:FLUEXGL-DSP@0005";
|
|
8
|
+
ErrorCodes["PATH_TO_WASM_FILE_NOT_FOUND"] = "ERROR:FLUEXGL-DSP@0006";
|
|
9
|
+
ErrorCodes["WASM_COMPILATION_ERROR"] = "ERROR:FLUEXGL-DSP@0007";
|
|
10
|
+
ErrorCodes["WORKLET_NO_WASM_MODULE_INSTANTIATED"] = "ERROR:FLUEXGL-DSP@0008";
|
|
11
|
+
ErrorCodes["EFFECT_ALREADY_ATTACHED"] = "ERROR:FLUEXGL-DSP@0009";
|
|
12
|
+
ErrorCodes["EFFECT_NOT_FOUND"] = "ERROR:FLUEXGL-DSP@0010";
|
|
13
|
+
ErrorCodes["CHANNEL_ALREADY_ATTACHED"] = "ERROR:FLUEXGL-DSP@0011";
|
|
14
|
+
ErrorCodes["CHANNEL_NOT_FOUND"] = "ERROR:FLUEXGL-DSP@0012";
|
|
15
|
+
ErrorCodes["CHANNEL_CANNOT_LINK_TO_ITSELF"] = "ERROR:FLUEXGL-DSP@0013";
|
|
16
|
+
ErrorCodes["CHANNEL_NOT_INITIALIZED"] = "ERROR:FLUEXGL-DSP@0014";
|
|
17
|
+
ErrorCodes["CHANNEL_NOT_SAME_AUDIO_CONTEXT"] = "ERROR:FLUEXGL-DSP@0015";
|
|
18
|
+
ErrorCodes["CHANNEL_ALREADY_LINKED"] = "ERROR:FLUEXGL-DSP@0016";
|
|
19
|
+
ErrorCodes["CHANNEL_POSSIBLE_FEEDBACK_LOOP"] = "ERROR:FLUEXGL-DSP@0017";
|
|
20
|
+
ErrorCodes["AUDIO_CLIP_ALREADY_ATTACHED"] = "ERROR:FLUEXGL-DSP@0018";
|
|
21
|
+
ErrorCodes["AUDIO_CLIP_NOT_FOUND"] = "ERROR:FLUEXGL-DSP@0019";
|
|
22
|
+
ErrorCodes["AUDIO_CLIP_PLAYER_NO_CONTEXT"] = "ERROR:FLUEXGL-DSP@0020";
|
|
23
|
+
ErrorCodes["PANNING_OUT_OF_RANGE"] = "ERROR:FLUEXGL-DSP@0021";
|
|
9
24
|
})(ErrorCodes || (ErrorCodes = {}));
|
|
10
25
|
export var WarningCodes;
|
|
11
26
|
(function (WarningCodes) {
|
|
12
|
-
WarningCodes["NO_DEFAULT_AUDIO_DEVICE_FOUND"] = "FLUEXGL@
|
|
27
|
+
WarningCodes["NO_DEFAULT_AUDIO_DEVICE_FOUND"] = "WARNING:FLUEXGL-DSP@0001";
|
|
13
28
|
})(WarningCodes || (WarningCodes = {}));
|
|
14
29
|
export var SuccessCodes;
|
|
15
30
|
(function (SuccessCodes) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioClip.d.ts","sourceRoot":"","sources":["../../../src/core/classes/AudioClip.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAmB,eAAe,EAAE,MAAM,eAAe,CAAC;AAEpF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"AudioClip.d.ts","sourceRoot":"","sources":["../../../src/core/classes/AudioClip.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAmB,eAAe,EAAE,MAAM,eAAe,CAAC;AAEpF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAMlC,qBAAa,SAAS;IA2BC,IAAI,EAAE,eAAe;IAzBjC,EAAE,EAAE,MAAM,CAAQ;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE5B,IAAI,EAAE,OAAO,CAAS;IACtB,SAAS,EAAE,OAAO,CAAS;IAC3B,SAAS,EAAE,MAAM,CAAK;IACtB,aAAa,EAAE,MAAM,CAAK;IAE1B,mBAAmB,EAAE,MAAM,CAAM;IAEjC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAQ;IACjC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IAEjD,OAAO,EAAE,YAAY,GAAG,IAAI,CAAQ;IACpC,eAAe,EAAE,eAAe,GAAG,IAAI,CAAQ;IAEtD,OAAO,CAAC,sBAAsB,CAA+B;IAC7D,OAAO,CAAC,yBAAyB,CAAa;IAE9C,OAAO,CAAC,gBAAgB,CAAoB;IAE5C,OAAO,CAAC,MAAM,CAEb;gBAEkB,IAAI,EAAE,eAAe;IAExC,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;IAmBjB,UAAU,CAAC,eAAe,EAAE,eAAe;IAc3C,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAqExC,IAAI,CAAC,OAAO,EAAE,MAAM;IAsBpB,IAAI,IAAI,SAAS,GAAG,IAAI;IAkBxB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;IAUpC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS;IAexC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS;IAU/B,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS;IAatD,mCAAmC,IAAI,OAAO;IAc9C,gBAAgB,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAMnG,IAAI,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAYvF,mBAAmB,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,SAAS;IAarG,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,iBAAiB,GAAG,SAAS;IAW/D,cAAc,CAAC,OAAO,GAAE,MAAU,GAAG,YAAY;IAIjD,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM;IAW9B,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM;IAWvC,IAAW,mBAAmB,IAAI,MAAM,CAIvC;IAED,IAAW,QAAQ,IAAI,MAAM,CAE5B;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED,IAAW,aAAa,IAAI,MAAM,CAEjC;IAED,IAAW,iBAAiB,IAAI,MAAM,CAKrC;IAED,IAAW,UAAU,IAAI,MAAM,CAE9B;IAED,IAAW,gBAAgB,IAAI,MAAM,CAEpC;IAED,IAAW,UAAU,IAAI,MAAM,CAE9B;CACJ"}
|
|
@@ -2,6 +2,7 @@ import { v4 } from "uuid";
|
|
|
2
2
|
import { format } from "date-fns";
|
|
3
3
|
import { Debug } from "../../utilities/debugger";
|
|
4
4
|
import { DSP } from "../../index";
|
|
5
|
+
import { ErrorCodes } from "lib/src/console-codes";
|
|
5
6
|
export class AudioClip {
|
|
6
7
|
data;
|
|
7
8
|
id = v4();
|
|
@@ -60,7 +61,7 @@ export class AudioClip {
|
|
|
60
61
|
return Debug.Error("Could not initialize AudioClip, because the AudioClipPlayer somehow has no audio context.", [
|
|
61
62
|
`AudioClipPlayer id: ${audioClipPlayer.id}`,
|
|
62
63
|
`AudioClip id: ${this.id}`
|
|
63
|
-
]);
|
|
64
|
+
], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
|
|
64
65
|
this.audioClipPlayer = audioClipPlayer;
|
|
65
66
|
this.context = audioClipPlayer.context;
|
|
66
67
|
this.gainNode = new GainNode(this.context);
|
|
@@ -149,11 +150,7 @@ export class AudioClip {
|
|
|
149
150
|
if (!this.context)
|
|
150
151
|
Debug.Error("Could not set volume because the context (AudioContext) of this AudioClip is undefined.", [
|
|
151
152
|
"Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .SetVolume() on this AudioClip.",
|
|
152
|
-
]);
|
|
153
|
-
if (!this.gainNode)
|
|
154
|
-
Debug.Error("Could not set volume because the gainNode (GainNode) of this AudioClip is undefined.", [
|
|
155
|
-
"Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .SetVolume() on this AudioClip.",
|
|
156
|
-
]);
|
|
153
|
+
], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
|
|
157
154
|
this.gainNode?.gain.setValueAtTime(volume, this.context?.currentTime ?? 0);
|
|
158
155
|
return this;
|
|
159
156
|
}
|
|
@@ -161,16 +158,12 @@ export class AudioClip {
|
|
|
161
158
|
if (!this.context)
|
|
162
159
|
Debug.Error("Could not set volume because the context (AudioContext) of this AudioClip is undefined.", [
|
|
163
160
|
"Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .SetPanLevel() on this AudioClip.",
|
|
164
|
-
]);
|
|
165
|
-
if (!this.stereoPannerNode)
|
|
166
|
-
Debug.Error("Could not set volume because the stereoPannerNode (StereoPannerNode) of this AudioClip is undefined.", [
|
|
167
|
-
"Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .SetPanLevel() on this AudioClip.",
|
|
168
|
-
]);
|
|
161
|
+
], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
|
|
169
162
|
if (panLevel < -1 || panLevel > 1)
|
|
170
163
|
Debug.Error("Could not set the pan level because it is not between -1 and 1.", [
|
|
171
164
|
`Given value: ${panLevel}.`,
|
|
172
165
|
`Accepts a value between -1 and 1. Can be a floating number.`
|
|
173
|
-
]);
|
|
166
|
+
], ErrorCodes.PANNING_OUT_OF_RANGE);
|
|
174
167
|
this.stereoPannerNode?.pan.setValueAtTime(panLevel, this.context?.currentTime ?? 0);
|
|
175
168
|
return this;
|
|
176
169
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioClipPlayer.d.ts","sourceRoot":"","sources":["../../../src/core/classes/AudioClipPlayer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"AudioClipPlayer.d.ts","sourceRoot":"","sources":["../../../src/core/classes/AudioClipPlayer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,qBAAa,eAAe;IAEjB,KAAK,EAAE,MAAM,CAAqB;IAClC,EAAE,EAAE,MAAM,CAAQ;IAElB,UAAU,EAAE,SAAS,EAAE,CAAM;IAC7B,cAAc,EAAE,QAAQ,GAAG,IAAI,CAAQ;IAEvC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAQ;IACpC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAQ;gBAEnC,OAAO,EAAE,YAAY;IAK1B,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAU3C,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAgBtC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAUrC,MAAM,IAAI,IAAI;IAad,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAU9B,OAAO,IAAI,IAAI;IAOf,OAAO,IAAI,IAAI;IAYf,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIpC,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;CACJ"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { v4 } from "uuid";
|
|
2
2
|
import { Debug } from "../../utilities/debugger";
|
|
3
|
+
import { ErrorCodes } from "lib/src/console-codes";
|
|
3
4
|
export class AudioClipPlayer {
|
|
4
5
|
label = "AudioClipPlayer";
|
|
5
6
|
id = v4();
|
|
@@ -15,7 +16,7 @@ export class AudioClipPlayer {
|
|
|
15
16
|
if (this.audioClips.includes(audioClip))
|
|
16
17
|
return Debug.Error("Could not attach audio clip because it is already part of this channel", [
|
|
17
18
|
"Call .DetachAudioClip([clip AudioClip]) before attaching audio clip."
|
|
18
|
-
]);
|
|
19
|
+
], ErrorCodes.AUDIO_CLIP_ALREADY_ATTACHED);
|
|
19
20
|
audioClip.Initialize(this);
|
|
20
21
|
this.audioClips.push(audioClip);
|
|
21
22
|
}
|
|
@@ -23,7 +24,7 @@ export class AudioClipPlayer {
|
|
|
23
24
|
if (!this.audioClips.includes(clip))
|
|
24
25
|
return Debug.Error("Could not detach audio clip because it is not part of this channel", [
|
|
25
26
|
"Call .AttachAudioClip([clip AudioClip]) before detaching audio clip."
|
|
26
|
-
]);
|
|
27
|
+
], ErrorCodes.AUDIO_CLIP_NOT_FOUND);
|
|
27
28
|
clip.Stop();
|
|
28
29
|
const self = this;
|
|
29
30
|
this.audioClips.forEach(function (_clip, index) {
|
|
@@ -75,4 +76,10 @@ export class AudioClipPlayer {
|
|
|
75
76
|
SetLabel(label) {
|
|
76
77
|
this.label = label;
|
|
77
78
|
}
|
|
79
|
+
get length() {
|
|
80
|
+
return this.audioClips.length;
|
|
81
|
+
}
|
|
82
|
+
get volume() {
|
|
83
|
+
return this.outputGainNode?.gain.value ?? 0;
|
|
84
|
+
}
|
|
78
85
|
}
|
|
@@ -12,6 +12,6 @@ export declare class AudioDevice {
|
|
|
12
12
|
SetMasterChannel(channel: Master): void;
|
|
13
13
|
CreateMasterChannel(): Master;
|
|
14
14
|
GetContext(): AudioContext;
|
|
15
|
-
CreateChannel(): Channel;
|
|
15
|
+
CreateChannel(label?: string): Channel;
|
|
16
16
|
}
|
|
17
17
|
//# sourceMappingURL=AudioDevice.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioDevice.d.ts","sourceRoot":"","sources":["../../../src/core/classes/AudioDevice.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,qBAAa,WAAW;IAUD,UAAU,EAAE,eAAe;IARvC,EAAE,EAAE,MAAM,CAAQ;IAClB,SAAS,EAAE,MAAM,CAAc;IAE/B,OAAO,EAAE,YAAY,CAAsB;IAE3C,aAAa,EAAE,MAAM,CAA4B;IACjD,cAAc,EAAE,MAAM,EAAE,CAAM;gBAElB,UAAU,EAAE,eAAe;IAEvC,gBAAgB,IAAI,MAAM;IAI1B,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAUvC,mBAAmB,IAAI,MAAM;IAQ7B,UAAU,IAAI,YAAY;IAI1B,aAAa,
|
|
1
|
+
{"version":3,"file":"AudioDevice.d.ts","sourceRoot":"","sources":["../../../src/core/classes/AudioDevice.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,qBAAa,WAAW;IAUD,UAAU,EAAE,eAAe;IARvC,EAAE,EAAE,MAAM,CAAQ;IAClB,SAAS,EAAE,MAAM,CAAc;IAE/B,OAAO,EAAE,YAAY,CAAsB;IAE3C,aAAa,EAAE,MAAM,CAA4B;IACjD,cAAc,EAAE,MAAM,EAAE,CAAM;gBAElB,UAAU,EAAE,eAAe;IAEvC,gBAAgB,IAAI,MAAM;IAI1B,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAUvC,mBAAmB,IAAI,MAAM;IAQ7B,UAAU,IAAI,YAAY;IAI1B,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO;CAGhD"}
|
|
@@ -13,6 +13,7 @@ export class AudioDevice {
|
|
|
13
13
|
constructor(deviceInfo) {
|
|
14
14
|
this.deviceInfo = deviceInfo;
|
|
15
15
|
}
|
|
16
|
+
;
|
|
16
17
|
GetMasterChannel() {
|
|
17
18
|
return this.masterChannel;
|
|
18
19
|
}
|
|
@@ -32,7 +33,7 @@ export class AudioDevice {
|
|
|
32
33
|
GetContext() {
|
|
33
34
|
return this.context;
|
|
34
35
|
}
|
|
35
|
-
CreateChannel() {
|
|
36
|
-
return new Channel(this.context);
|
|
36
|
+
CreateChannel(label) {
|
|
37
|
+
return new Channel(this.context, label);
|
|
37
38
|
}
|
|
38
39
|
}
|
|
@@ -14,7 +14,7 @@ export declare class Channel {
|
|
|
14
14
|
context: AudioContext | null;
|
|
15
15
|
sends: Channel[];
|
|
16
16
|
audioClipPlayer: AudioClipPlayer | null;
|
|
17
|
-
constructor(context: AudioContext);
|
|
17
|
+
constructor(context: AudioContext, label?: string);
|
|
18
18
|
private rebuildEffectChain;
|
|
19
19
|
AddEffect(effect: Effector): void;
|
|
20
20
|
AttachEffect(effect: Effector): void;
|
|
@@ -27,6 +27,8 @@ export declare class Channel {
|
|
|
27
27
|
Unsend(channel: Channel | Master): void;
|
|
28
28
|
HasAudioClipPlayer(): boolean;
|
|
29
29
|
UnsendToAllChannels(): void;
|
|
30
|
-
AttachAudioClip(audioClip: AudioClip):
|
|
30
|
+
AttachAudioClip(audioClip: AudioClip): Channel;
|
|
31
|
+
Volume(volume?: number): number;
|
|
32
|
+
Pan(pan?: number): number;
|
|
31
33
|
}
|
|
32
34
|
//# sourceMappingURL=Channel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Channel.d.ts","sourceRoot":"","sources":["../../../src/core/classes/Channel.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"Channel.d.ts","sourceRoot":"","sources":["../../../src/core/classes/Channel.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,qBAAa,OAAO;IAET,EAAE,EAAE,MAAM,CAAQ;IAClB,KAAK,EAAE,MAAM,CAAa;IAE1B,KAAK,EAAE,SAAS,GAAG,IAAI,CAAQ;IAC/B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IACjD,YAAY,EAAE,YAAY,GAAG,IAAI,CAAQ;IACzC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAQ;IACjC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAQ;IAEhC,OAAO,EAAE,QAAQ,EAAE,CAAM;IACzB,OAAO,EAAE,YAAY,GAAG,IAAI,CAAQ;IAEpC,KAAK,EAAE,OAAO,EAAE,CAAM;IACtB,eAAe,EAAE,eAAe,GAAG,IAAI,CAAQ;gBAE1C,OAAO,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,MAAM;IAsBjD,OAAO,CAAC,kBAAkB;IAsCnB,SAAS,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI;IAmBjC,YAAY,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI;IAIpC,YAAY,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI;IAqBpC,YAAY,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI;IAI3C,OAAO,CAAC,oBAAoB;IAqB5B,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,WAAW;IAwBZ,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM;IAkC9B,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM;IAehC,kBAAkB,IAAI,OAAO;IAI7B,mBAAmB;IAQnB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO;IAQ9C,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM;IAS/B,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM;CAQnC"}
|
|
@@ -2,6 +2,7 @@ import { v4 } from "uuid";
|
|
|
2
2
|
import { Debug } from "../../utilities/debugger";
|
|
3
3
|
import { AudioClipPlayer } from "./AudioClipPlayer";
|
|
4
4
|
import { Master } from "./Master";
|
|
5
|
+
import { ErrorCodes } from "../../console-codes";
|
|
5
6
|
export class Channel {
|
|
6
7
|
id = v4();
|
|
7
8
|
label = "Channel";
|
|
@@ -14,8 +15,9 @@ export class Channel {
|
|
|
14
15
|
context = null;
|
|
15
16
|
sends = [];
|
|
16
17
|
audioClipPlayer = null;
|
|
17
|
-
constructor(context) {
|
|
18
|
+
constructor(context, label) {
|
|
18
19
|
this.context = context;
|
|
20
|
+
this.label = label ?? this.label;
|
|
19
21
|
this.disconnectAudioNodes(true);
|
|
20
22
|
this.input = new GainNode(context);
|
|
21
23
|
this.stereoPannerNode = new StereoPannerNode(context);
|
|
@@ -64,7 +66,7 @@ export class Channel {
|
|
|
64
66
|
if (this.effects.includes(effect)) {
|
|
65
67
|
Debug.Error("Could not add effect because it is already part of this channel", [
|
|
66
68
|
"Call .RemoveEffect([effect Effector]) before adding effect."
|
|
67
|
-
]);
|
|
69
|
+
], ErrorCodes.EFFECT_ALREADY_ATTACHED);
|
|
68
70
|
return;
|
|
69
71
|
}
|
|
70
72
|
this.effects.push(effect);
|
|
@@ -78,7 +80,7 @@ export class Channel {
|
|
|
78
80
|
if (!this.effects.includes(effect)) {
|
|
79
81
|
Debug.Error("Could not remove effect, because it is not part of this channel.", [
|
|
80
82
|
"Call .AddEffect([effect Effector]) before removing effect."
|
|
81
|
-
]);
|
|
83
|
+
], ErrorCodes.EFFECT_NOT_FOUND);
|
|
82
84
|
return;
|
|
83
85
|
}
|
|
84
86
|
const self = this;
|
|
@@ -133,27 +135,27 @@ export class Channel {
|
|
|
133
135
|
if (channel.id === this.id)
|
|
134
136
|
return Debug.Error("Could not link channel to itself.", [
|
|
135
137
|
`This channel id: ${this.id}`
|
|
136
|
-
]);
|
|
138
|
+
], ErrorCodes.CHANNEL_CANNOT_LINK_TO_ITSELF);
|
|
137
139
|
if (!this.isInitialized() || !channel.isInitialized())
|
|
138
140
|
return Debug.Error("Could not link channels because one (or both) channels are not initialized.", [
|
|
139
141
|
`This channel id: ${this.id} initialized: ${this.isInitialized()}`,
|
|
140
142
|
`Target channel id: ${channel.id} initialized: ${channel.isInitialized()}`
|
|
141
|
-
]);
|
|
143
|
+
], ErrorCodes.CHANNEL_NOT_INITIALIZED);
|
|
142
144
|
if (this.context !== channel.context)
|
|
143
145
|
return Debug.Error("Could not link channels because they do not share the same AudioContext.", [
|
|
144
146
|
`This channel context: ${this.context ? "set" : "null"}`,
|
|
145
147
|
`Target channel context: ${channel.context ? "set" : "null"}`
|
|
146
|
-
]);
|
|
148
|
+
], ErrorCodes.CHANNEL_NOT_SAME_AUDIO_CONTEXT);
|
|
147
149
|
if (this.sends.includes(channel))
|
|
148
150
|
return Debug.Error("Could not link channels, because the given channel is already linked with this one.", [
|
|
149
151
|
`This channel id: ${this.id}`,
|
|
150
152
|
`Target channel id: ${channel.id}`
|
|
151
|
-
]);
|
|
153
|
+
], ErrorCodes.CHANNEL_ALREADY_LINKED);
|
|
152
154
|
if (channel.isReachable(this))
|
|
153
155
|
return Debug.Error("Could not link channels because it would create a feedback loop.", [
|
|
154
156
|
`This channel id: ${this.id}`,
|
|
155
157
|
`Target channel id: ${channel.id}`
|
|
156
|
-
]);
|
|
158
|
+
], ErrorCodes.CHANNEL_POSSIBLE_FEEDBACK_LOOP);
|
|
157
159
|
this.output.connect(channel.input);
|
|
158
160
|
this.sends.push(channel);
|
|
159
161
|
}
|
|
@@ -178,7 +180,24 @@ export class Channel {
|
|
|
178
180
|
}
|
|
179
181
|
AttachAudioClip(audioClip) {
|
|
180
182
|
if (!this.audioClipPlayer)
|
|
181
|
-
|
|
183
|
+
throw Error("Cannot not link AudioClip to this channel because this channel's AudioClipPlayer is undefined.");
|
|
182
184
|
this.audioClipPlayer.AttachAudioClip(audioClip);
|
|
185
|
+
return this;
|
|
186
|
+
}
|
|
187
|
+
Volume(volume) {
|
|
188
|
+
if (!this.context)
|
|
189
|
+
throw new Error("Could not set volume on channel, because it's context is undefined.");
|
|
190
|
+
if (!this.gainNode)
|
|
191
|
+
throw new Error("Could not set volume on channel, because it's GainNode is undefined.");
|
|
192
|
+
volume && this.gainNode.gain.setValueAtTime(volume, this.context.currentTime);
|
|
193
|
+
return volume ?? this.gainNode.gain.value;
|
|
194
|
+
}
|
|
195
|
+
Pan(pan) {
|
|
196
|
+
if (!this.context)
|
|
197
|
+
throw new Error("Could not set pan on channel, because it's context is undefined.");
|
|
198
|
+
if (!this.stereoPannerNode)
|
|
199
|
+
throw new Error("Cannot set pan on channel, because it's StereoPannerNode is undefined.");
|
|
200
|
+
pan && this.stereoPannerNode.pan.setValueAtTime(pan, this.context.currentTime);
|
|
201
|
+
return pan ?? this.stereoPannerNode.pan.value;
|
|
183
202
|
}
|
|
184
203
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Master.d.ts","sourceRoot":"","sources":["../../../src/core/classes/Master.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"Master.d.ts","sourceRoot":"","sources":["../../../src/core/classes/Master.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,qBAAa,MAAM;IAER,EAAE,EAAE,MAAM,CAAQ;IAElB,QAAQ,EAAE,OAAO,EAAE,CAAM;IACzB,OAAO,EAAE,QAAQ,EAAE,CAAM;IAEzB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAQ;IAC9B,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAQ;IACjC,YAAY,EAAE,YAAY,GAAG,IAAI,CAAQ;IACzC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAQ;IACpC,eAAe,EAAE,eAAe,GAAG,IAAI,CAAQ;gBAE1C,OAAO,EAAE,YAAY;IAmBjC,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,kBAAkB;IAuBnB,YAAY,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI;IAapC,YAAY,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI;IAkBpC,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAcrC,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAkBrC,kBAAkB,IAAI,OAAO;IAI7B,eAAe,CAAC,SAAS,EAAE,SAAS;CAM9C"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { v4 } from "uuid";
|
|
2
2
|
import { Debug } from "../../utilities/debugger";
|
|
3
3
|
import { AudioClipPlayer } from "./AudioClipPlayer";
|
|
4
|
+
import { ErrorCodes } from "lib/src/console-codes";
|
|
4
5
|
export class Master {
|
|
5
6
|
id = v4();
|
|
6
7
|
channels = [];
|
|
@@ -55,7 +56,7 @@ export class Master {
|
|
|
55
56
|
if (this.effects.includes(effect))
|
|
56
57
|
return Debug.Error("Could not attach the effect because it is already part of this master channel.", [
|
|
57
58
|
"Call .DetachEffect([effect Effector]) before attaching the effect."
|
|
58
|
-
]);
|
|
59
|
+
], ErrorCodes.EFFECT_ALREADY_ATTACHED);
|
|
59
60
|
if (!this.context)
|
|
60
61
|
return this.rebuildEffectChain();
|
|
61
62
|
this.effects.push(effect);
|
|
@@ -66,7 +67,7 @@ export class Master {
|
|
|
66
67
|
if (!this.effects.includes(effect))
|
|
67
68
|
return Debug.Error("Could not detach the effect because it is not part of this master channel.", [
|
|
68
69
|
"Call .AttachEffect([effect Effector]) before detaching the effect."
|
|
69
|
-
]);
|
|
70
|
+
], ErrorCodes.EFFECT_NOT_FOUND);
|
|
70
71
|
const self = this;
|
|
71
72
|
this.effects.forEach(function (_effect, index) {
|
|
72
73
|
if (effect.id === _effect.id) {
|
|
@@ -80,7 +81,7 @@ export class Master {
|
|
|
80
81
|
if (this.channels.includes(channel))
|
|
81
82
|
return Debug.Error("Could not attach the channel because it is already part of this master channel.", [
|
|
82
83
|
"Call .DetachChannel([channel Channel]) before attaching the channel."
|
|
83
|
-
]);
|
|
84
|
+
], ErrorCodes.CHANNEL_ALREADY_ATTACHED);
|
|
84
85
|
this.channels.push(channel);
|
|
85
86
|
if (channel.output && this.input)
|
|
86
87
|
channel.output.connect(this.input);
|
|
@@ -90,7 +91,7 @@ export class Master {
|
|
|
90
91
|
if (!this.channels.includes(channel))
|
|
91
92
|
return Debug.Error("Could not detach the channel because it is not part of this master channel.", [
|
|
92
93
|
"Call .AttachChannel([channel Channel]) before detaching the channel."
|
|
93
|
-
]);
|
|
94
|
+
], ErrorCodes.CHANNEL_NOT_FOUND);
|
|
94
95
|
if (channel.output && this.input)
|
|
95
96
|
channel.output.disconnect(this.input);
|
|
96
97
|
const self = this;
|
|
@@ -181,7 +181,7 @@ export function CreateAudioWorkletNode(context, name, data) {
|
|
|
181
181
|
if (!compiledWebAssemblyModule) {
|
|
182
182
|
Debug.Error("Failed to create audio worklet node, because the web assembly module has not been compiled properly.", [
|
|
183
183
|
`Request audio worklet node: ${name}.`
|
|
184
|
-
]);
|
|
184
|
+
], ErrorCodes.WORKLET_NO_WASM_MODULE_INSTANTIATED);
|
|
185
185
|
return null;
|
|
186
186
|
}
|
|
187
187
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-assembly.d.ts","sourceRoot":"","sources":["../../src/utilities/web-assembly.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"web-assembly.d.ts","sourceRoot":"","sources":["../../src/utilities/web-assembly.ts"],"names":[],"mappings":"AAGA,eAAO,IAAI,kBAAkB,EAAE,OAAe,CAAC;AAC/C,eAAO,IAAI,yBAAyB,EAAE,WAAW,CAAC,MAAM,GAAG,IAAW,CAAC;AAEvE,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAcrF"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Debug } from "./debugger";
|
|
2
|
+
import { ErrorCodes } from "../console-codes";
|
|
1
3
|
export let hasInitializedWasm = false;
|
|
2
4
|
export let compiledWebAssemblyModule = null;
|
|
3
5
|
export async function LoadWebAssemblyModule(path) {
|
|
@@ -6,6 +8,10 @@ export async function LoadWebAssemblyModule(path) {
|
|
|
6
8
|
compiledWebAssemblyModule = module;
|
|
7
9
|
resolve(module);
|
|
8
10
|
}).catch(function (error) {
|
|
11
|
+
Debug.Error("Failed to load WebAssembly module from path: " + path, [
|
|
12
|
+
"Make sure the path is correct and the server is serving the .wasm file with the correct MIME type (application/wasm).",
|
|
13
|
+
"Error details: " + error.message
|
|
14
|
+
], ErrorCodes.WASM_COMPILATION_ERROR);
|
|
9
15
|
reject(error);
|
|
10
16
|
});
|
|
11
17
|
});
|
package/lib/src/console-codes.ts
CHANGED
|
@@ -1,14 +1,29 @@
|
|
|
1
1
|
export enum ErrorCodes {
|
|
2
|
-
NO_CONTEXT_PERMISSION = "FLUEXGL@
|
|
3
|
-
NO_FILE_TYPE_FOUND = "FLUEXGL@
|
|
4
|
-
PATH_TO_FILE_NOT_FOUND = "FLUEXGL@
|
|
5
|
-
SAME_MASTER_CHANNEL = "FLUEXGL@
|
|
6
|
-
WASM_MODULE_INITIALIZATION_FAILED = "FLUEXGL@
|
|
7
|
-
PATH_TO_WASM_FILE_NOT_FOUND = "FLUEXGL@
|
|
2
|
+
NO_CONTEXT_PERMISSION = "ERROR:FLUEXGL-DSP@0001",
|
|
3
|
+
NO_FILE_TYPE_FOUND = "ERROR:FLUEXGL-DSP@0002",
|
|
4
|
+
PATH_TO_FILE_NOT_FOUND = "ERROR:FLUEXGL-DSP@0003",
|
|
5
|
+
SAME_MASTER_CHANNEL = "ERROR:FLUEXGL-DSP@0004",
|
|
6
|
+
WASM_MODULE_INITIALIZATION_FAILED = "ERROR:FLUEXGL-DSP@0005",
|
|
7
|
+
PATH_TO_WASM_FILE_NOT_FOUND = "ERROR:FLUEXGL-DSP@0006",
|
|
8
|
+
WASM_COMPILATION_ERROR = "ERROR:FLUEXGL-DSP@0007",
|
|
9
|
+
WORKLET_NO_WASM_MODULE_INSTANTIATED = "ERROR:FLUEXGL-DSP@0008",
|
|
10
|
+
EFFECT_ALREADY_ATTACHED = "ERROR:FLUEXGL-DSP@0009",
|
|
11
|
+
EFFECT_NOT_FOUND = "ERROR:FLUEXGL-DSP@0010",
|
|
12
|
+
CHANNEL_ALREADY_ATTACHED = "ERROR:FLUEXGL-DSP@0011",
|
|
13
|
+
CHANNEL_NOT_FOUND = "ERROR:FLUEXGL-DSP@0012",
|
|
14
|
+
CHANNEL_CANNOT_LINK_TO_ITSELF = "ERROR:FLUEXGL-DSP@0013",
|
|
15
|
+
CHANNEL_NOT_INITIALIZED = "ERROR:FLUEXGL-DSP@0014",
|
|
16
|
+
CHANNEL_NOT_SAME_AUDIO_CONTEXT = "ERROR:FLUEXGL-DSP@0015",
|
|
17
|
+
CHANNEL_ALREADY_LINKED = "ERROR:FLUEXGL-DSP@0016",
|
|
18
|
+
CHANNEL_POSSIBLE_FEEDBACK_LOOP = "ERROR:FLUEXGL-DSP@0017",
|
|
19
|
+
AUDIO_CLIP_ALREADY_ATTACHED = "ERROR:FLUEXGL-DSP@0018",
|
|
20
|
+
AUDIO_CLIP_NOT_FOUND = "ERROR:FLUEXGL-DSP@0019",
|
|
21
|
+
AUDIO_CLIP_PLAYER_NO_CONTEXT = "ERROR:FLUEXGL-DSP@0020",
|
|
22
|
+
PANNING_OUT_OF_RANGE = "ERROR:FLUEXGL-DSP@0021"
|
|
8
23
|
}
|
|
9
24
|
|
|
10
25
|
export enum WarningCodes {
|
|
11
|
-
NO_DEFAULT_AUDIO_DEVICE_FOUND = "FLUEXGL@
|
|
26
|
+
NO_DEFAULT_AUDIO_DEVICE_FOUND = "WARNING:FLUEXGL-DSP@0001"
|
|
12
27
|
}
|
|
13
28
|
|
|
14
29
|
export enum SuccessCodes {
|
|
@@ -7,6 +7,7 @@ import { Channel } from "./Channel";
|
|
|
7
7
|
import { AudioClipPlayer } from "./AudioClipPlayer";
|
|
8
8
|
import { Master } from "./Master";
|
|
9
9
|
import { DSP } from "../../index";
|
|
10
|
+
import { ErrorCodes } from "lib/src/console-codes";
|
|
10
11
|
|
|
11
12
|
type ProgressPayload = Parameters<AudioClipEventMap["progress"]>[0];
|
|
12
13
|
|
|
@@ -87,7 +88,7 @@ export class AudioClip {
|
|
|
87
88
|
if (!audioClipPlayer.context) return Debug.Error("Could not initialize AudioClip, because the AudioClipPlayer somehow has no audio context.", [
|
|
88
89
|
`AudioClipPlayer id: ${audioClipPlayer.id}`,
|
|
89
90
|
`AudioClip id: ${this.id}`
|
|
90
|
-
]);
|
|
91
|
+
], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
|
|
91
92
|
|
|
92
93
|
this.audioClipPlayer = audioClipPlayer;
|
|
93
94
|
this.context = audioClipPlayer.context;
|
|
@@ -209,11 +210,7 @@ export class AudioClip {
|
|
|
209
210
|
|
|
210
211
|
if (!this.context) Debug.Error("Could not set volume because the context (AudioContext) of this AudioClip is undefined.", [
|
|
211
212
|
"Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .SetVolume() on this AudioClip.",
|
|
212
|
-
]);
|
|
213
|
-
|
|
214
|
-
if (!this.gainNode) Debug.Error("Could not set volume because the gainNode (GainNode) of this AudioClip is undefined.", [
|
|
215
|
-
"Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .SetVolume() on this AudioClip.",
|
|
216
|
-
]);
|
|
213
|
+
], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
|
|
217
214
|
|
|
218
215
|
this.gainNode?.gain.setValueAtTime(volume, this.context?.currentTime ?? 0);
|
|
219
216
|
return this;
|
|
@@ -223,16 +220,12 @@ export class AudioClip {
|
|
|
223
220
|
|
|
224
221
|
if (!this.context) Debug.Error("Could not set volume because the context (AudioContext) of this AudioClip is undefined.", [
|
|
225
222
|
"Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .SetPanLevel() on this AudioClip.",
|
|
226
|
-
]);
|
|
227
|
-
|
|
228
|
-
if (!this.stereoPannerNode) Debug.Error("Could not set volume because the stereoPannerNode (StereoPannerNode) of this AudioClip is undefined.", [
|
|
229
|
-
"Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .SetPanLevel() on this AudioClip.",
|
|
230
|
-
]);
|
|
223
|
+
], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
|
|
231
224
|
|
|
232
225
|
if (panLevel < -1 || panLevel > 1) Debug.Error("Could not set the pan level because it is not between -1 and 1.", [
|
|
233
226
|
`Given value: ${panLevel}.`,
|
|
234
227
|
`Accepts a value between -1 and 1. Can be a floating number.`
|
|
235
|
-
]);
|
|
228
|
+
], ErrorCodes.PANNING_OUT_OF_RANGE);
|
|
236
229
|
|
|
237
230
|
this.stereoPannerNode?.pan.setValueAtTime(panLevel, this.context?.currentTime ?? 0);
|
|
238
231
|
return this;
|
|
@@ -4,6 +4,7 @@ import { AudioClip } from "./AudioClip";
|
|
|
4
4
|
import { Debug } from "../../utilities/debugger";
|
|
5
5
|
import { Channel } from "./Channel";
|
|
6
6
|
import { Master } from "./Master";
|
|
7
|
+
import { ErrorCodes } from "lib/src/console-codes";
|
|
7
8
|
|
|
8
9
|
export class AudioClipPlayer {
|
|
9
10
|
|
|
@@ -25,7 +26,7 @@ export class AudioClipPlayer {
|
|
|
25
26
|
|
|
26
27
|
if (this.audioClips.includes(audioClip)) return Debug.Error("Could not attach audio clip because it is already part of this channel", [
|
|
27
28
|
"Call .DetachAudioClip([clip AudioClip]) before attaching audio clip."
|
|
28
|
-
]);
|
|
29
|
+
], ErrorCodes.AUDIO_CLIP_ALREADY_ATTACHED);
|
|
29
30
|
|
|
30
31
|
audioClip.Initialize(this);
|
|
31
32
|
this.audioClips.push(audioClip);
|
|
@@ -35,7 +36,7 @@ export class AudioClipPlayer {
|
|
|
35
36
|
|
|
36
37
|
if (!this.audioClips.includes(clip)) return Debug.Error("Could not detach audio clip because it is not part of this channel", [
|
|
37
38
|
"Call .AttachAudioClip([clip AudioClip]) before detaching audio clip."
|
|
38
|
-
]);
|
|
39
|
+
], ErrorCodes.AUDIO_CLIP_NOT_FOUND);
|
|
39
40
|
|
|
40
41
|
clip.Stop();
|
|
41
42
|
|
|
@@ -102,4 +103,12 @@ export class AudioClipPlayer {
|
|
|
102
103
|
public SetLabel(label: string): void {
|
|
103
104
|
this.label = label;
|
|
104
105
|
}
|
|
106
|
+
|
|
107
|
+
public get length(): number {
|
|
108
|
+
return this.audioClips.length;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
public get volume(): number {
|
|
112
|
+
return this.outputGainNode?.gain.value ?? 0;
|
|
113
|
+
}
|
|
105
114
|
}
|
|
@@ -16,7 +16,7 @@ export class AudioDevice {
|
|
|
16
16
|
public masterChannel: Master = new Master(this.context);
|
|
17
17
|
public masterChannels: Master[] = [];
|
|
18
18
|
|
|
19
|
-
constructor(public deviceInfo: MediaDeviceInfo) {
|
|
19
|
+
constructor(public deviceInfo: MediaDeviceInfo) {};
|
|
20
20
|
|
|
21
21
|
public GetMasterChannel(): Master {
|
|
22
22
|
return this.masterChannel;
|
|
@@ -44,7 +44,7 @@ export class AudioDevice {
|
|
|
44
44
|
return this.context;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
public CreateChannel(): Channel {
|
|
48
|
-
return new Channel(this.context);
|
|
47
|
+
public CreateChannel(label?: string): Channel {
|
|
48
|
+
return new Channel(this.context, label);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -4,6 +4,7 @@ import { AudioClipPlayer } from "./AudioClipPlayer";
|
|
|
4
4
|
import { AudioClip } from "./AudioClip";
|
|
5
5
|
import { Master } from "./Master";
|
|
6
6
|
import { Effector } from "./Effector";
|
|
7
|
+
import { ErrorCodes } from "../../console-codes";
|
|
7
8
|
|
|
8
9
|
export class Channel {
|
|
9
10
|
|
|
@@ -22,8 +23,9 @@ export class Channel {
|
|
|
22
23
|
public sends: Channel[] = [];
|
|
23
24
|
public audioClipPlayer: AudioClipPlayer | null = null;
|
|
24
25
|
|
|
25
|
-
constructor(context: AudioContext) {
|
|
26
|
+
constructor(context: AudioContext, label?: string) {
|
|
26
27
|
this.context = context;
|
|
28
|
+
this.label = label ?? this.label;
|
|
27
29
|
|
|
28
30
|
this.disconnectAudioNodes(true);
|
|
29
31
|
|
|
@@ -91,7 +93,7 @@ export class Channel {
|
|
|
91
93
|
if (this.effects.includes(effect)) {
|
|
92
94
|
Debug.Error("Could not add effect because it is already part of this channel", [
|
|
93
95
|
"Call .RemoveEffect([effect Effector]) before adding effect."
|
|
94
|
-
]);
|
|
96
|
+
], ErrorCodes.EFFECT_ALREADY_ATTACHED);
|
|
95
97
|
return;
|
|
96
98
|
}
|
|
97
99
|
|
|
@@ -109,7 +111,7 @@ export class Channel {
|
|
|
109
111
|
if (!this.effects.includes(effect)) {
|
|
110
112
|
Debug.Error("Could not remove effect, because it is not part of this channel.", [
|
|
111
113
|
"Call .AddEffect([effect Effector]) before removing effect."
|
|
112
|
-
]);
|
|
114
|
+
], ErrorCodes.EFFECT_NOT_FOUND);
|
|
113
115
|
return;
|
|
114
116
|
}
|
|
115
117
|
|
|
@@ -185,27 +187,27 @@ export class Channel {
|
|
|
185
187
|
|
|
186
188
|
if (channel.id === this.id) return Debug.Error("Could not link channel to itself.", [
|
|
187
189
|
`This channel id: ${this.id}`
|
|
188
|
-
]);
|
|
190
|
+
], ErrorCodes.CHANNEL_CANNOT_LINK_TO_ITSELF);
|
|
189
191
|
|
|
190
192
|
if (!this.isInitialized() || !channel.isInitialized()) return Debug.Error("Could not link channels because one (or both) channels are not initialized.", [
|
|
191
193
|
`This channel id: ${this.id} initialized: ${this.isInitialized()}`,
|
|
192
194
|
`Target channel id: ${channel.id} initialized: ${channel.isInitialized()}`
|
|
193
|
-
]);
|
|
195
|
+
], ErrorCodes.CHANNEL_NOT_INITIALIZED);
|
|
194
196
|
|
|
195
197
|
if (this.context !== channel.context) return Debug.Error("Could not link channels because they do not share the same AudioContext.", [
|
|
196
198
|
`This channel context: ${this.context ? "set" : "null"}`,
|
|
197
199
|
`Target channel context: ${channel.context ? "set" : "null"}`
|
|
198
|
-
]);
|
|
200
|
+
], ErrorCodes.CHANNEL_NOT_SAME_AUDIO_CONTEXT);
|
|
199
201
|
|
|
200
202
|
if (this.sends.includes(channel)) return Debug.Error("Could not link channels, because the given channel is already linked with this one.", [
|
|
201
203
|
`This channel id: ${this.id}`,
|
|
202
204
|
`Target channel id: ${channel.id}`
|
|
203
|
-
]);
|
|
205
|
+
], ErrorCodes.CHANNEL_ALREADY_LINKED);
|
|
204
206
|
|
|
205
207
|
if (channel.isReachable(this)) return Debug.Error("Could not link channels because it would create a feedback loop.", [
|
|
206
208
|
`This channel id: ${this.id}`,
|
|
207
209
|
`Target channel id: ${channel.id}`
|
|
208
|
-
]);
|
|
210
|
+
], ErrorCodes.CHANNEL_POSSIBLE_FEEDBACK_LOOP);
|
|
209
211
|
|
|
210
212
|
(this.output as AudioNode).connect(channel.input as AudioNode);
|
|
211
213
|
|
|
@@ -234,16 +236,34 @@ export class Channel {
|
|
|
234
236
|
public UnsendToAllChannels() {
|
|
235
237
|
|
|
236
238
|
for (var i: number = 0; i < this.sends.length; i++) {
|
|
237
|
-
|
|
238
239
|
this.Unsend(this.sends[i]);
|
|
239
240
|
i--;
|
|
240
241
|
}
|
|
241
242
|
}
|
|
242
243
|
|
|
243
|
-
public AttachAudioClip(audioClip: AudioClip) {
|
|
244
|
+
public AttachAudioClip(audioClip: AudioClip): Channel {
|
|
244
245
|
|
|
245
|
-
if (!this.audioClipPlayer)
|
|
246
|
+
if (!this.audioClipPlayer) throw Error("Cannot not link AudioClip to this channel because this channel's AudioClipPlayer is undefined.");
|
|
246
247
|
|
|
247
248
|
this.audioClipPlayer.AttachAudioClip(audioClip);
|
|
249
|
+
return this;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
public Volume(volume?: number): number {
|
|
253
|
+
|
|
254
|
+
if(!this.context) throw new Error("Could not set volume on channel, because it's context is undefined.");
|
|
255
|
+
if(!this.gainNode) throw new Error("Could not set volume on channel, because it's GainNode is undefined.")
|
|
256
|
+
|
|
257
|
+
volume && this.gainNode.gain.setValueAtTime(volume, this.context.currentTime);
|
|
258
|
+
return volume ?? this.gainNode.gain.value;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
public Pan(pan?: number): number {
|
|
262
|
+
|
|
263
|
+
if(!this.context) throw new Error("Could not set pan on channel, because it's context is undefined.");
|
|
264
|
+
if(!this.stereoPannerNode) throw new Error("Cannot set pan on channel, because it's StereoPannerNode is undefined.");
|
|
265
|
+
|
|
266
|
+
pan && this.stereoPannerNode.pan.setValueAtTime(pan, this.context.currentTime);
|
|
267
|
+
return pan ?? this.stereoPannerNode.pan.value;
|
|
248
268
|
}
|
|
249
269
|
}
|
|
@@ -5,6 +5,7 @@ import { Debug } from "../../utilities/debugger";
|
|
|
5
5
|
import { Effector } from "./Effector";
|
|
6
6
|
import { AudioClipPlayer } from "./AudioClipPlayer";
|
|
7
7
|
import { AudioClip } from "./AudioClip";
|
|
8
|
+
import { ErrorCodes } from "lib/src/console-codes";
|
|
8
9
|
|
|
9
10
|
export class Master {
|
|
10
11
|
|
|
@@ -77,7 +78,7 @@ export class Master {
|
|
|
77
78
|
|
|
78
79
|
if (this.effects.includes(effect)) return Debug.Error("Could not attach the effect because it is already part of this master channel.", [
|
|
79
80
|
"Call .DetachEffect([effect Effector]) before attaching the effect."
|
|
80
|
-
]);
|
|
81
|
+
], ErrorCodes.EFFECT_ALREADY_ATTACHED);
|
|
81
82
|
|
|
82
83
|
if(!this.context) return this.rebuildEffectChain();
|
|
83
84
|
|
|
@@ -90,7 +91,7 @@ export class Master {
|
|
|
90
91
|
|
|
91
92
|
if (!this.effects.includes(effect)) return Debug.Error("Could not detach the effect because it is not part of this master channel.", [
|
|
92
93
|
"Call .AttachEffect([effect Effector]) before detaching the effect."
|
|
93
|
-
]);
|
|
94
|
+
], ErrorCodes.EFFECT_NOT_FOUND);
|
|
94
95
|
|
|
95
96
|
const self = this;
|
|
96
97
|
|
|
@@ -108,7 +109,7 @@ export class Master {
|
|
|
108
109
|
|
|
109
110
|
if (this.channels.includes(channel)) return Debug.Error("Could not attach the channel because it is already part of this master channel.", [
|
|
110
111
|
"Call .DetachChannel([channel Channel]) before attaching the channel."
|
|
111
|
-
]);
|
|
112
|
+
], ErrorCodes.CHANNEL_ALREADY_ATTACHED);
|
|
112
113
|
|
|
113
114
|
this.channels.push(channel);
|
|
114
115
|
|
|
@@ -122,7 +123,7 @@ export class Master {
|
|
|
122
123
|
|
|
123
124
|
if (!this.channels.includes(channel)) return Debug.Error("Could not detach the channel because it is not part of this master channel.", [
|
|
124
125
|
"Call .AttachChannel([channel Channel]) before detaching the channel."
|
|
125
|
-
]);
|
|
126
|
+
], ErrorCodes.CHANNEL_NOT_FOUND);
|
|
126
127
|
|
|
127
128
|
if (channel.output && this.input)
|
|
128
129
|
channel.output.disconnect(this.input);
|
|
@@ -261,7 +261,7 @@ export function CreateAudioWorkletNode<T = any>(context: AudioContext, name: Aud
|
|
|
261
261
|
if (!compiledWebAssemblyModule) {
|
|
262
262
|
Debug.Error("Failed to create audio worklet node, because the web assembly module has not been compiled properly.", [
|
|
263
263
|
`Request audio worklet node: ${name}.`
|
|
264
|
-
]);
|
|
264
|
+
], ErrorCodes.WORKLET_NO_WASM_MODULE_INSTANTIATED);
|
|
265
265
|
return null;
|
|
266
266
|
}
|
|
267
267
|
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { Debug } from "./debugger";
|
|
2
|
+
import { ErrorCodes } from "../console-codes";
|
|
3
|
+
|
|
1
4
|
export let hasInitializedWasm: boolean = false;
|
|
2
5
|
export let compiledWebAssemblyModule: WebAssembly.Module | null = null;
|
|
3
6
|
|
|
@@ -7,6 +10,11 @@ export async function LoadWebAssemblyModule(path: string): Promise<WebAssembly.M
|
|
|
7
10
|
compiledWebAssemblyModule = module;
|
|
8
11
|
resolve(module);
|
|
9
12
|
}).catch(function (error: Error) {
|
|
13
|
+
|
|
14
|
+
Debug.Error("Failed to load WebAssembly module from path: " + path, [
|
|
15
|
+
"Make sure the path is correct and the server is serving the .wasm file with the correct MIME type (application/wasm).",
|
|
16
|
+
"Error details: " + error.message
|
|
17
|
+
], ErrorCodes.WASM_COMPILATION_ERROR);
|
|
10
18
|
reject(error);
|
|
11
19
|
});
|
|
12
20
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluex/fluexgl-dsp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "An open-source, web-based DSP library developed alongside FluexGL, designed for creating and manipulating sounds in various contexts.",
|
|
5
5
|
"main": "lib/dist/index.js",
|
|
6
6
|
"types": "lib/dist/index.d.ts",
|