@fluex/fluexgl-dsp 0.4.7 → 0.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/lib/dist/console-codes.d.ts +2 -1
- package/lib/dist/console-codes.d.ts.map +1 -1
- package/lib/dist/console-codes.js +1 -0
- package/lib/dist/core/classes/AudioClip.d.ts +26 -17
- package/lib/dist/core/classes/AudioClip.d.ts.map +1 -1
- package/lib/dist/core/classes/AudioClip.js +124 -51
- package/lib/dist/core/classes/AudioClipPlayer.d.ts +8 -8
- package/lib/dist/core/classes/AudioClipPlayer.d.ts.map +1 -1
- package/lib/dist/core/classes/AudioClipPlayer.js +22 -24
- package/lib/dist/core/classes/AudioDevice.d.ts +46 -5
- package/lib/dist/core/classes/AudioDevice.d.ts.map +1 -1
- package/lib/dist/core/classes/AudioDevice.js +47 -6
- package/lib/dist/core/classes/Channel.d.ts +20 -20
- package/lib/dist/core/classes/Channel.d.ts.map +1 -1
- package/lib/dist/core/classes/Channel.js +42 -42
- package/lib/dist/core/classes/DpsPipeline.d.ts +6 -6
- package/lib/dist/core/classes/DpsPipeline.d.ts.map +1 -1
- package/lib/dist/core/classes/DpsPipeline.js +18 -18
- package/lib/dist/core/classes/Effector.d.ts +5 -5
- package/lib/dist/core/classes/Effector.d.ts.map +1 -1
- package/lib/dist/core/classes/Effector.js +8 -8
- package/lib/dist/core/classes/Master.d.ts +6 -6
- package/lib/dist/core/classes/Master.d.ts.map +1 -1
- package/lib/dist/core/classes/Master.js +18 -18
- package/lib/dist/effects/classes/Analyser.d.ts +6 -6
- package/lib/dist/effects/classes/Analyser.d.ts.map +1 -1
- package/lib/dist/effects/classes/Analyser.js +7 -7
- package/lib/dist/effects/classes/Chorus.d.ts +7 -7
- package/lib/dist/effects/classes/Chorus.d.ts.map +1 -1
- package/lib/dist/effects/classes/Chorus.js +25 -25
- package/lib/dist/effects/classes/Distortion.d.ts +1 -1
- package/lib/dist/effects/classes/Distortion.d.ts.map +1 -1
- package/lib/dist/effects/classes/Distortion.js +1 -1
- package/lib/dist/effects/classes/Reverb.d.ts +32 -0
- package/lib/dist/effects/classes/Reverb.d.ts.map +1 -0
- package/lib/dist/effects/classes/Reverb.js +61 -0
- package/lib/dist/effects/classes/clips/HardClip.d.ts +5 -5
- package/lib/dist/effects/classes/clips/HardClip.d.ts.map +1 -1
- package/lib/dist/effects/classes/clips/HardClip.js +14 -14
- package/lib/dist/effects/classes/clips/SoftClip.d.ts +4 -4
- package/lib/dist/effects/classes/clips/SoftClip.d.ts.map +1 -1
- package/lib/dist/effects/classes/clips/SoftClip.js +13 -13
- package/lib/dist/effects/classes/filters/HighPassFilter.d.ts +5 -5
- package/lib/dist/effects/classes/filters/HighPassFilter.d.ts.map +1 -1
- package/lib/dist/effects/classes/filters/HighPassFilter.js +16 -16
- package/lib/dist/effects/classes/filters/LowPassFilter.d.ts +5 -5
- package/lib/dist/effects/classes/filters/LowPassFilter.d.ts.map +1 -1
- package/lib/dist/effects/classes/filters/LowPassFilter.js +17 -17
- package/lib/dist/effects/classes/filters/NotchFilter.d.ts +5 -5
- package/lib/dist/effects/classes/filters/NotchFilter.d.ts.map +1 -1
- package/lib/dist/effects/classes/filters/NotchFilter.js +16 -16
- package/lib/dist/effects/exports.d.ts +1 -5
- package/lib/dist/effects/exports.d.ts.map +1 -1
- package/lib/dist/effects/exports.js +1 -5
- package/lib/dist/index.d.ts +2 -2
- package/lib/dist/index.d.ts.map +1 -1
- package/lib/dist/index.js +2 -2
- package/lib/dist/typings.d.ts +11 -0
- package/lib/dist/typings.d.ts.map +1 -1
- package/lib/dist/utilities/debugger.d.ts +4 -4
- package/lib/dist/utilities/debugger.js +8 -8
- package/lib/dist/utilities/helpers.d.ts +13 -13
- package/lib/dist/utilities/helpers.d.ts.map +1 -1
- package/lib/dist/utilities/helpers.js +45 -59
- package/lib/dist/utilities/web-assembly.js +1 -1
- package/lib/src/console-codes.ts +2 -1
- package/lib/src/core/classes/AudioClip.ts +154 -60
- package/lib/src/core/classes/AudioClipPlayer.ts +22 -24
- package/lib/src/core/classes/AudioDevice.ts +49 -6
- package/lib/src/core/classes/Channel.ts +42 -42
- package/lib/src/core/classes/DpsPipeline.ts +19 -19
- package/lib/src/core/classes/Effector.ts +9 -9
- package/lib/src/core/classes/Master.ts +18 -18
- package/lib/src/effects/classes/Analyser.ts +7 -7
- package/lib/src/effects/classes/Chorus.ts +25 -25
- package/lib/src/effects/classes/Distortion.ts +1 -1
- package/lib/src/effects/classes/Reverb.ts +81 -0
- package/lib/src/effects/classes/clips/HardClip.ts +14 -14
- package/lib/src/effects/classes/clips/SoftClip.ts +13 -13
- package/lib/src/effects/classes/filters/HighPassFilter.ts +16 -16
- package/lib/src/effects/classes/filters/LowPassFilter.ts +17 -17
- package/lib/src/effects/classes/filters/NotchFilter.ts +16 -16
- package/lib/src/effects/exports.ts +1 -6
- package/lib/src/index.ts +11 -15
- package/lib/src/typings.ts +13 -0
- package/lib/src/utilities/debugger.ts +4 -4
- package/lib/src/utilities/helpers.ts +47 -60
- package/lib/src/utilities/web-assembly.ts +1 -1
- package/package.json +3 -2
- package/lib/src/effects/classes/reverbs/ChamberReverb.ts +0 -1
- package/lib/src/effects/classes/reverbs/ConvolverReverb.ts +0 -1
- package/lib/src/effects/classes/reverbs/GenericReverb.ts +0 -1
- package/lib/src/effects/classes/reverbs/HallReverb.ts +0 -1
- package/lib/src/effects/classes/reverbs/RoomReverb.ts +0 -1
package/README.md
CHANGED
|
@@ -30,14 +30,14 @@ import { DspPipeline, Channel, LoadAudioSource, AudioClip } from "@fluex/fluexgl
|
|
|
30
30
|
pathToWorklet: "/data/fluexgl-dsp-processor.worklet"
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
await pipeline.
|
|
33
|
+
await pipeline.initializeDpsPipeline();
|
|
34
34
|
|
|
35
|
-
const audioDevice = await pipeline.
|
|
35
|
+
const audioDevice = await pipeline.resolveDefaultAudioOutputDevice();
|
|
36
36
|
|
|
37
37
|
if(!audioDevice) return;
|
|
38
38
|
|
|
39
|
-
const master = audioDevice.
|
|
40
|
-
const context = audioDevice.
|
|
39
|
+
const master = audioDevice.getMasterChannel();
|
|
40
|
+
const context = audioDevice.getContext();
|
|
41
41
|
|
|
42
42
|
const audioSource = await LoadAudioSource("/music.mp3");
|
|
43
43
|
|
|
@@ -46,11 +46,11 @@ import { DspPipeline, Channel, LoadAudioSource, AudioClip } from "@fluex/fluexgl
|
|
|
46
46
|
const audioClip = new AudioClip(audioSource);
|
|
47
47
|
const channel = new Channel(context);
|
|
48
48
|
|
|
49
|
-
channel.
|
|
50
|
-
audioClip.
|
|
49
|
+
channel.send(master);
|
|
50
|
+
audioClip.send(channel);
|
|
51
51
|
|
|
52
52
|
button.addEventListener("click", function() {
|
|
53
|
-
audioClip.
|
|
53
|
+
audioClip.play();
|
|
54
54
|
});
|
|
55
55
|
})();
|
|
56
56
|
```
|
|
@@ -19,7 +19,8 @@ export declare enum ErrorCodes {
|
|
|
19
19
|
AUDIO_CLIP_ALREADY_ATTACHED = "ERROR:FLUEXGL-DSP@0018",
|
|
20
20
|
AUDIO_CLIP_NOT_FOUND = "ERROR:FLUEXGL-DSP@0019",
|
|
21
21
|
AUDIO_CLIP_PLAYER_NO_CONTEXT = "ERROR:FLUEXGL-DSP@0020",
|
|
22
|
-
PANNING_OUT_OF_RANGE = "ERROR:FLUEXGL-DSP@0021"
|
|
22
|
+
PANNING_OUT_OF_RANGE = "ERROR:FLUEXGL-DSP@0021",
|
|
23
|
+
PITCH_OUT_OF_RANGE = "ERROR:FLUEXGL-DSP@0022"
|
|
23
24
|
}
|
|
24
25
|
export declare enum WarningCodes {
|
|
25
26
|
NO_DEFAULT_AUDIO_DEVICE_FOUND = "WARNING:FLUEXGL-DSP@0001"
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;IAC/C,kBAAkB,2BAA2B;CAChD;AAED,oBAAY,YAAY;IACpB,6BAA6B,6BAA6B;CAC7D;AAED,oBAAY,YAAY;CAEvB"}
|
|
@@ -21,6 +21,7 @@ export var ErrorCodes;
|
|
|
21
21
|
ErrorCodes["AUDIO_CLIP_NOT_FOUND"] = "ERROR:FLUEXGL-DSP@0019";
|
|
22
22
|
ErrorCodes["AUDIO_CLIP_PLAYER_NO_CONTEXT"] = "ERROR:FLUEXGL-DSP@0020";
|
|
23
23
|
ErrorCodes["PANNING_OUT_OF_RANGE"] = "ERROR:FLUEXGL-DSP@0021";
|
|
24
|
+
ErrorCodes["PITCH_OUT_OF_RANGE"] = "ERROR:FLUEXGL-DSP@0022";
|
|
24
25
|
})(ErrorCodes || (ErrorCodes = {}));
|
|
25
26
|
export var WarningCodes;
|
|
26
27
|
(function (WarningCodes) {
|
|
@@ -11,6 +11,9 @@ export declare class AudioClip {
|
|
|
11
11
|
startTime: number;
|
|
12
12
|
offsetAtStart: number;
|
|
13
13
|
playbackRate: number;
|
|
14
|
+
pitch: number;
|
|
15
|
+
minPitchSemitones: number;
|
|
16
|
+
maxPitchSemitones: number;
|
|
14
17
|
progressUpdateSpeed: number;
|
|
15
18
|
gainNode: GainNode | null;
|
|
16
19
|
stereoPannerNode: StereoPannerNode | null;
|
|
@@ -18,30 +21,36 @@ export declare class AudioClip {
|
|
|
18
21
|
audioClipPlayer: AudioClipPlayer | null;
|
|
19
22
|
private audioBufferSourceNodes;
|
|
20
23
|
private maxAudioBufferSourceNodes;
|
|
24
|
+
private audioClipPlayers;
|
|
21
25
|
private progressInterval;
|
|
22
26
|
private events;
|
|
23
27
|
constructor(data: AudioSourceData);
|
|
24
28
|
private createBufferSource;
|
|
25
29
|
private connectSourcesTo;
|
|
26
30
|
private safeDisconnect;
|
|
31
|
+
private getOutputNodes;
|
|
27
32
|
private rebuildNodeChain;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
33
|
+
initialize(audioClipPlayer: AudioClipPlayer): void;
|
|
34
|
+
play(timestamp?: number, offset?: number): void | this | null;
|
|
35
|
+
seek(seconds: number): void | this;
|
|
36
|
+
stop(): AudioClip | null;
|
|
37
|
+
setVolume(volume: number): AudioClip;
|
|
38
|
+
setPanLevel(panLevel: number): AudioClip;
|
|
39
|
+
setLoop(loop?: boolean): AudioClip;
|
|
40
|
+
setMaxAudioBufferSourceNodes(value: number): AudioClip;
|
|
41
|
+
disconnectAllAudioBufferSourceNodes(): boolean;
|
|
42
|
+
addEventListener<K extends keyof AudioClipEventMap>(event: K, cb: AudioClipEventMap[K]): () => void;
|
|
43
|
+
once<K extends keyof AudioClipEventMap>(event: K, cb: AudioClipEventMap[K]): () => void;
|
|
44
|
+
removeEventListener<K extends keyof AudioClipEventMap>(event: K, cb: AudioClipEventMap[K]): AudioClip;
|
|
45
|
+
clearEventListeners(event?: keyof AudioClipEventMap): AudioClip;
|
|
46
|
+
getChannelData(channel?: number): Float32Array;
|
|
47
|
+
send(channel: Channel | Master): void;
|
|
48
|
+
unsend(channel: Channel | Master): void;
|
|
49
|
+
detachFromAudioClipPlayer(audioClipPlayer: AudioClipPlayer): void;
|
|
50
|
+
setPitch(semitones: number): AudioClip;
|
|
51
|
+
resetPitch(): AudioClip;
|
|
52
|
+
/** @deprecated Use {@link setPitch} instead. */
|
|
53
|
+
setPlaybackRateInSemitones(semitones: number): AudioClip;
|
|
45
54
|
get currentPlaybackTime(): number;
|
|
46
55
|
get duration(): number;
|
|
47
56
|
get volume(): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioClip.d.ts","sourceRoot":"","sources":["../../../src/core/classes/AudioClip.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"AudioClip.d.ts","sourceRoot":"","sources":["../../../src/core/classes/AudioClip.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,9 @@ export class AudioClip {
|
|
|
12
12
|
startTime = 0;
|
|
13
13
|
offsetAtStart = 0;
|
|
14
14
|
playbackRate = 1;
|
|
15
|
+
pitch = 0;
|
|
16
|
+
minPitchSemitones = -24;
|
|
17
|
+
maxPitchSemitones = 24;
|
|
15
18
|
progressUpdateSpeed = 20;
|
|
16
19
|
gainNode = null;
|
|
17
20
|
stereoPannerNode = null;
|
|
@@ -19,9 +22,12 @@ export class AudioClip {
|
|
|
19
22
|
audioClipPlayer = null;
|
|
20
23
|
audioBufferSourceNodes = [];
|
|
21
24
|
maxAudioBufferSourceNodes = 1;
|
|
25
|
+
audioClipPlayers = [];
|
|
22
26
|
progressInterval = 0;
|
|
23
27
|
events = {
|
|
24
|
-
"progress": []
|
|
28
|
+
"progress": [],
|
|
29
|
+
"initialize": [],
|
|
30
|
+
"play": []
|
|
25
31
|
};
|
|
26
32
|
constructor(data) {
|
|
27
33
|
this.data = data;
|
|
@@ -45,42 +51,74 @@ export class AudioClip {
|
|
|
45
51
|
safeDisconnect(node) {
|
|
46
52
|
node?.disconnect();
|
|
47
53
|
}
|
|
54
|
+
getOutputNodes() {
|
|
55
|
+
const nodes = [];
|
|
56
|
+
for (const player of this.audioClipPlayers) {
|
|
57
|
+
if (player.outputGainNode && !nodes.includes(player.outputGainNode))
|
|
58
|
+
nodes.push(player.outputGainNode);
|
|
59
|
+
}
|
|
60
|
+
return nodes;
|
|
61
|
+
}
|
|
48
62
|
rebuildNodeChain() {
|
|
49
|
-
if (!this.context || !this.gainNode || !this.stereoPannerNode
|
|
50
|
-
Debug.
|
|
63
|
+
if (!this.context || !this.gainNode || !this.stereoPannerNode) {
|
|
64
|
+
Debug.error("Failed to rebuild node chain, because some of the core AudioNodes are missing.");
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
const destinations = this.getOutputNodes();
|
|
68
|
+
if (destinations.length === 0) {
|
|
69
|
+
Debug.error("Failed to rebuild node chain, because no output destinations are available.");
|
|
51
70
|
return false;
|
|
52
71
|
}
|
|
53
|
-
const destination = this.audioClipPlayer.outputGainNode;
|
|
54
72
|
this.safeDisconnect(this.gainNode);
|
|
55
73
|
this.safeDisconnect(this.stereoPannerNode);
|
|
56
74
|
this.gainNode.connect(this.stereoPannerNode);
|
|
57
|
-
|
|
75
|
+
for (const destination of destinations) {
|
|
76
|
+
this.stereoPannerNode.connect(destination);
|
|
77
|
+
}
|
|
58
78
|
this.connectSourcesTo(this.gainNode);
|
|
59
79
|
return true;
|
|
60
80
|
}
|
|
61
|
-
|
|
81
|
+
initialize(audioClipPlayer) {
|
|
82
|
+
const startTimestamp = Date.now(), self = this;
|
|
62
83
|
if (!audioClipPlayer.context)
|
|
63
|
-
return Debug.
|
|
84
|
+
return Debug.error("Could not initialize AudioClip, because the AudioClipPlayer somehow has no audio context.", [
|
|
64
85
|
`AudioClipPlayer id: ${audioClipPlayer.id}`,
|
|
65
86
|
`AudioClip id: ${this.id}`
|
|
66
87
|
], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
|
|
88
|
+
if (this.context && this.context !== audioClipPlayer.context) {
|
|
89
|
+
return Debug.error("Could not initialize AudioClip, because the AudioClipPlayer does not share the same AudioContext.", [
|
|
90
|
+
`AudioClipPlayer id: ${audioClipPlayer.id}`,
|
|
91
|
+
`AudioClip id: ${this.id}`
|
|
92
|
+
], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
|
|
93
|
+
}
|
|
67
94
|
this.audioClipPlayer = audioClipPlayer;
|
|
68
95
|
this.context = audioClipPlayer.context;
|
|
69
|
-
|
|
70
|
-
|
|
96
|
+
if (!this.gainNode)
|
|
97
|
+
this.gainNode = new GainNode(this.context);
|
|
98
|
+
if (!this.stereoPannerNode)
|
|
99
|
+
this.stereoPannerNode = new StereoPannerNode(this.context);
|
|
100
|
+
if (!this.audioClipPlayers.includes(audioClipPlayer))
|
|
101
|
+
this.audioClipPlayers.push(audioClipPlayer);
|
|
102
|
+
const endTimestamp = Date.now(), difference = endTimestamp - startTimestamp;
|
|
103
|
+
this.events.initialize.forEach(function (cb) {
|
|
104
|
+
cb({
|
|
105
|
+
durationOfInitialization: difference,
|
|
106
|
+
context: self.context
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
this.rebuildNodeChain();
|
|
71
110
|
}
|
|
72
|
-
|
|
111
|
+
play(timestamp, offset) {
|
|
73
112
|
if (!this.context)
|
|
74
|
-
return Debug.
|
|
75
|
-
"Make sure to attach this AudioClip to an AudioClipPlayer instance, before calling .
|
|
113
|
+
return Debug.error("Could not play audio clip, because context (AudioContext) is undefined.", [
|
|
114
|
+
"Make sure to attach this AudioClip to an AudioClipPlayer instance, before calling .play on this AudioClip."
|
|
76
115
|
]);
|
|
77
|
-
const context = this.context;
|
|
78
|
-
const self = this;
|
|
116
|
+
const context = this.context, self = this;
|
|
79
117
|
if (this.audioBufferSourceNodes.length > this.maxAudioBufferSourceNodes - 1)
|
|
80
118
|
return null;
|
|
81
119
|
const bufferSource = this.createBufferSource();
|
|
82
120
|
if (!bufferSource) {
|
|
83
|
-
Debug.
|
|
121
|
+
Debug.error("Something went wrong.");
|
|
84
122
|
return null;
|
|
85
123
|
}
|
|
86
124
|
const actualOffset = offset ?? this.offsetAtStart ?? 0;
|
|
@@ -118,12 +156,19 @@ export class AudioClip {
|
|
|
118
156
|
this.audioBufferSourceNodes.push(bufferSource);
|
|
119
157
|
this.rebuildNodeChain();
|
|
120
158
|
bufferSource.start(timestamp ?? this.startTime, actualOffset);
|
|
159
|
+
this.events.play.forEach(function (cb) {
|
|
160
|
+
cb({
|
|
161
|
+
timestamp: Date.now(),
|
|
162
|
+
audioBufferSourceNodes: self.audioBufferSourceNodes,
|
|
163
|
+
context: context,
|
|
164
|
+
});
|
|
165
|
+
});
|
|
121
166
|
return this;
|
|
122
167
|
}
|
|
123
|
-
|
|
168
|
+
seek(seconds) {
|
|
124
169
|
if (!this.context)
|
|
125
|
-
return Debug.
|
|
126
|
-
`Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .
|
|
170
|
+
return Debug.error("Could not seek because the context (AudioContext) of this AudioClip is undefined.", [
|
|
171
|
+
`Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .seek on this AudioClip.`,
|
|
127
172
|
`AudioClip id: ${this.id}`
|
|
128
173
|
]);
|
|
129
174
|
const clamped = Math.max(0, Math.min(seconds, this.duration));
|
|
@@ -131,11 +176,11 @@ export class AudioClip {
|
|
|
131
176
|
this.offsetAtStart = clamped;
|
|
132
177
|
return this;
|
|
133
178
|
}
|
|
134
|
-
this.
|
|
135
|
-
this.
|
|
179
|
+
this.stop();
|
|
180
|
+
this.play(undefined, clamped);
|
|
136
181
|
return this;
|
|
137
182
|
}
|
|
138
|
-
|
|
183
|
+
stop() {
|
|
139
184
|
this.audioBufferSourceNodes.forEach(function (node) {
|
|
140
185
|
node.stop();
|
|
141
186
|
node.disconnect();
|
|
@@ -148,37 +193,37 @@ export class AudioClip {
|
|
|
148
193
|
}
|
|
149
194
|
return this;
|
|
150
195
|
}
|
|
151
|
-
|
|
196
|
+
setVolume(volume) {
|
|
152
197
|
if (!this.context)
|
|
153
|
-
Debug.
|
|
154
|
-
"Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .
|
|
198
|
+
Debug.error("Could not set volume because the context (AudioContext) of this AudioClip is undefined.", [
|
|
199
|
+
"Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .setVolume() on this AudioClip.",
|
|
155
200
|
], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
|
|
156
201
|
this.gainNode?.gain.setValueAtTime(volume, this.context?.currentTime ?? 0);
|
|
157
202
|
return this;
|
|
158
203
|
}
|
|
159
|
-
|
|
204
|
+
setPanLevel(panLevel) {
|
|
160
205
|
if (!this.context)
|
|
161
|
-
Debug.
|
|
162
|
-
"Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .
|
|
206
|
+
Debug.error("Could not set volume because the context (AudioContext) of this AudioClip is undefined.", [
|
|
207
|
+
"Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .setPanLevel() on this AudioClip.",
|
|
163
208
|
], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
|
|
164
209
|
if (panLevel < -1 || panLevel > 1)
|
|
165
|
-
Debug.
|
|
210
|
+
Debug.error("Could not set the pan level because it is not between -1 and 1.", [
|
|
166
211
|
`Given value: ${panLevel}.`,
|
|
167
212
|
`Accepts a value between -1 and 1. Can be a floating number.`
|
|
168
213
|
], ErrorCodes.PANNING_OUT_OF_RANGE);
|
|
169
214
|
this.stereoPannerNode?.pan.setValueAtTime(panLevel, this.context?.currentTime ?? 0);
|
|
170
215
|
return this;
|
|
171
216
|
}
|
|
172
|
-
|
|
217
|
+
setLoop(loop) {
|
|
173
218
|
this.audioBufferSourceNodes.forEach(function (node) {
|
|
174
219
|
node.loop = loop ?? true;
|
|
175
220
|
});
|
|
176
221
|
this.loop = loop ?? true;
|
|
177
222
|
return this;
|
|
178
223
|
}
|
|
179
|
-
|
|
224
|
+
setMaxAudioBufferSourceNodes(value) {
|
|
180
225
|
if (!DSP.overrideMaxAudioBufferNodes) {
|
|
181
|
-
Debug.
|
|
226
|
+
Debug.warn("Cannot set maxAudioBufferSourceNodes because the option to override the current maximum value is disabled.", [
|
|
182
227
|
"Set overrideMaxAudioBufferNodes on DSP to true, in order to override the maximum audio buffer source nodes."
|
|
183
228
|
]);
|
|
184
229
|
return this;
|
|
@@ -186,7 +231,7 @@ export class AudioClip {
|
|
|
186
231
|
this.maxAudioBufferSourceNodes = value;
|
|
187
232
|
return this;
|
|
188
233
|
}
|
|
189
|
-
|
|
234
|
+
disconnectAllAudioBufferSourceNodes() {
|
|
190
235
|
if (!this.context)
|
|
191
236
|
return false;
|
|
192
237
|
const contextCurrentTime = this.context?.currentTime;
|
|
@@ -196,19 +241,19 @@ export class AudioClip {
|
|
|
196
241
|
});
|
|
197
242
|
return true;
|
|
198
243
|
}
|
|
199
|
-
|
|
244
|
+
addEventListener(event, cb) {
|
|
200
245
|
this.events[event].push(cb);
|
|
201
|
-
return () => this.
|
|
246
|
+
return () => this.removeEventListener(event, cb);
|
|
202
247
|
}
|
|
203
|
-
|
|
248
|
+
once(event, cb) {
|
|
204
249
|
const wrapper = ((...args) => {
|
|
205
250
|
// @ts-ignore
|
|
206
251
|
cb(...args);
|
|
207
|
-
this.
|
|
252
|
+
this.removeEventListener(event, wrapper);
|
|
208
253
|
});
|
|
209
|
-
return this.
|
|
254
|
+
return this.addEventListener(event, wrapper);
|
|
210
255
|
}
|
|
211
|
-
|
|
256
|
+
removeEventListener(event, cb) {
|
|
212
257
|
const arr = this.events[event];
|
|
213
258
|
for (let i = 0; i < arr.length; i++) {
|
|
214
259
|
if (arr[i] === cb) {
|
|
@@ -218,7 +263,7 @@ export class AudioClip {
|
|
|
218
263
|
}
|
|
219
264
|
return this;
|
|
220
265
|
}
|
|
221
|
-
|
|
266
|
+
clearEventListeners(event) {
|
|
222
267
|
if (event) {
|
|
223
268
|
this.events[event].length = 0;
|
|
224
269
|
}
|
|
@@ -227,37 +272,65 @@ export class AudioClip {
|
|
|
227
272
|
}
|
|
228
273
|
return this;
|
|
229
274
|
}
|
|
230
|
-
|
|
275
|
+
getChannelData(channel = 0) {
|
|
231
276
|
return this.data.audioBuffer.getChannelData(channel);
|
|
232
277
|
}
|
|
233
|
-
|
|
278
|
+
send(channel) {
|
|
234
279
|
if (!channel.audioClipPlayer)
|
|
235
|
-
return Debug.
|
|
280
|
+
return Debug.error("Could not send AudioClip signal to channel, because the channel's AudioClipPlayer is undefined.", [
|
|
236
281
|
"Make sure to initialize the Channel.",
|
|
237
282
|
`Channel id: ${channel.id}.`,
|
|
238
283
|
`AudioClip id: ${this.id}.`
|
|
239
284
|
]);
|
|
240
|
-
channel.audioClipPlayer.
|
|
285
|
+
channel.audioClipPlayer.attachAudioClip(this);
|
|
241
286
|
}
|
|
242
|
-
|
|
287
|
+
unsend(channel) {
|
|
243
288
|
if (!channel.audioClipPlayer)
|
|
244
|
-
return Debug.
|
|
289
|
+
return Debug.error("Could not unsend AudioClip signal to channel, because the channel's AudioClipPlayer is undefined.", [
|
|
245
290
|
"Make sure to initialize the Channel.",
|
|
246
291
|
`Channel id: ${channel.id}.`,
|
|
247
292
|
`AudioClip id: ${this.id}.`
|
|
248
293
|
]);
|
|
249
|
-
channel.audioClipPlayer.
|
|
294
|
+
channel.audioClipPlayer.detachAudioClip(this);
|
|
295
|
+
}
|
|
296
|
+
detachFromAudioClipPlayer(audioClipPlayer) {
|
|
297
|
+
const idx = this.audioClipPlayers.indexOf(audioClipPlayer);
|
|
298
|
+
if (idx === -1)
|
|
299
|
+
return;
|
|
300
|
+
this.audioClipPlayers.splice(idx, 1);
|
|
301
|
+
if (this.audioClipPlayer === audioClipPlayer) {
|
|
302
|
+
this.audioClipPlayer = this.audioClipPlayers[0] ?? null;
|
|
303
|
+
}
|
|
304
|
+
if (this.audioClipPlayers.length === 0) {
|
|
305
|
+
this.stop();
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
this.rebuildNodeChain();
|
|
250
309
|
}
|
|
251
|
-
|
|
310
|
+
setPitch(semitones) {
|
|
252
311
|
if (!this.context)
|
|
253
|
-
|
|
312
|
+
Debug.error("Could not set pitch because the context (AudioContext) of this AudioClip is undefined.", [
|
|
313
|
+
"Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .setPitch() on this AudioClip.",
|
|
314
|
+
], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
|
|
315
|
+
if (semitones < this.minPitchSemitones || semitones > this.maxPitchSemitones)
|
|
316
|
+
Debug.error("Could not set the pitch because it is not within the allowed semitone range.", [
|
|
317
|
+
`Given value: ${semitones}.`,
|
|
318
|
+
`Accepts a value between ${this.minPitchSemitones} and ${this.maxPitchSemitones} semitones.`
|
|
319
|
+
], ErrorCodes.PITCH_OUT_OF_RANGE);
|
|
254
320
|
const calculatedPlaybackRate = Math.pow(2, semitones / 12);
|
|
255
|
-
for (const buffer of this.audioBufferSourceNodes)
|
|
256
|
-
buffer.playbackRate.setValueAtTime(calculatedPlaybackRate, this.context?.currentTime);
|
|
257
|
-
|
|
321
|
+
for (const buffer of this.audioBufferSourceNodes)
|
|
322
|
+
buffer.playbackRate.setValueAtTime(calculatedPlaybackRate, this.context?.currentTime ?? 0);
|
|
323
|
+
this.pitch = semitones;
|
|
258
324
|
this.playbackRate = calculatedPlaybackRate;
|
|
259
325
|
return this;
|
|
260
326
|
}
|
|
327
|
+
resetPitch() {
|
|
328
|
+
return this.setPitch(0);
|
|
329
|
+
}
|
|
330
|
+
/** @deprecated Use {@link setPitch} instead. */
|
|
331
|
+
setPlaybackRateInSemitones(semitones) {
|
|
332
|
+
return this.setPitch(semitones);
|
|
333
|
+
}
|
|
261
334
|
get currentPlaybackTime() {
|
|
262
335
|
return (!this.isPlaying || !this.context)
|
|
263
336
|
? 0
|
|
@@ -9,14 +9,14 @@ export declare class AudioClipPlayer {
|
|
|
9
9
|
context: AudioContext | null;
|
|
10
10
|
channel: Channel | Master | null;
|
|
11
11
|
constructor(context: AudioContext);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
attachAudioClip(audioClip: AudioClip): void;
|
|
13
|
+
detachAudioClip(clip: AudioClip): void;
|
|
14
|
+
send(channel: Channel | Master): void;
|
|
15
|
+
unsend(): void;
|
|
16
|
+
setVolume(value: number): void;
|
|
17
|
+
stopAll(): void;
|
|
18
|
+
dispose(): void;
|
|
19
|
+
setLabel(label: string): void;
|
|
20
20
|
get length(): number;
|
|
21
21
|
get volume(): number;
|
|
22
22
|
}
|
|
@@ -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;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;
|
|
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;IAE/C,YAAY,OAAO,EAAE,YAAY,EAGhC;IAEM,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAQjD;IAEM,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAY5C;IAEM,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQ3C;IAEM,MAAM,IAAI,IAAI,CAWpB;IAEM,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAQpC;IAEM,OAAO,IAAI,IAAI,CAKrB;IAEM,OAAO,IAAI,IAAI,CAUrB;IAEM,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEnC;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;CACJ"}
|
|
@@ -12,34 +12,32 @@ export class AudioClipPlayer {
|
|
|
12
12
|
this.context = context;
|
|
13
13
|
this.outputGainNode = new GainNode(context);
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
attachAudioClip(audioClip) {
|
|
16
16
|
if (this.audioClips.includes(audioClip))
|
|
17
|
-
return Debug.
|
|
18
|
-
"Call .
|
|
17
|
+
return Debug.error("Could not attach audio clip because it is already part of this channel", [
|
|
18
|
+
"Call .detachAudioClip([clip AudioClip]) before attaching audio clip."
|
|
19
19
|
], ErrorCodes.AUDIO_CLIP_ALREADY_ATTACHED);
|
|
20
|
-
audioClip.
|
|
20
|
+
audioClip.initialize(this);
|
|
21
21
|
this.audioClips.push(audioClip);
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
detachAudioClip(clip) {
|
|
24
24
|
if (!this.audioClips.includes(clip))
|
|
25
|
-
return Debug.
|
|
26
|
-
"Call .
|
|
25
|
+
return Debug.error("Could not detach audio clip because it is not part of this channel", [
|
|
26
|
+
"Call .attachAudioClip([clip AudioClip]) before detaching audio clip."
|
|
27
27
|
], ErrorCodes.AUDIO_CLIP_NOT_FOUND);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return self.audioClips.splice(index, 1);
|
|
33
|
-
});
|
|
28
|
+
const idx = this.audioClips.indexOf(clip);
|
|
29
|
+
if (idx >= 0)
|
|
30
|
+
this.audioClips.splice(idx, 1);
|
|
31
|
+
clip.detachFromAudioClipPlayer(this);
|
|
34
32
|
}
|
|
35
|
-
|
|
33
|
+
send(channel) {
|
|
36
34
|
if (!this.outputGainNode || !channel.input)
|
|
37
|
-
return Debug.
|
|
38
|
-
this.
|
|
35
|
+
return Debug.error("Could not send AudioClipPlayer signal to a channel/master.");
|
|
36
|
+
this.unsend();
|
|
39
37
|
this.channel = channel;
|
|
40
38
|
this.outputGainNode.connect(channel.input);
|
|
41
39
|
}
|
|
42
|
-
|
|
40
|
+
unsend() {
|
|
43
41
|
if (!this.outputGainNode)
|
|
44
42
|
return;
|
|
45
43
|
if (this.channel && this.channel.input) {
|
|
@@ -50,7 +48,7 @@ export class AudioClipPlayer {
|
|
|
50
48
|
}
|
|
51
49
|
this.channel = null;
|
|
52
50
|
}
|
|
53
|
-
|
|
51
|
+
setVolume(value) {
|
|
54
52
|
if (!this.outputGainNode)
|
|
55
53
|
return;
|
|
56
54
|
if (value < 0)
|
|
@@ -59,21 +57,21 @@ export class AudioClipPlayer {
|
|
|
59
57
|
value = 1;
|
|
60
58
|
this.outputGainNode.gain.value = value;
|
|
61
59
|
}
|
|
62
|
-
|
|
60
|
+
stopAll() {
|
|
63
61
|
this.audioClips.forEach(function (clip) {
|
|
64
|
-
clip.
|
|
62
|
+
clip.stop();
|
|
65
63
|
});
|
|
66
64
|
}
|
|
67
|
-
|
|
68
|
-
this.
|
|
69
|
-
this.
|
|
65
|
+
dispose() {
|
|
66
|
+
this.stopAll();
|
|
67
|
+
this.unsend();
|
|
70
68
|
this.outputGainNode?.disconnect();
|
|
71
69
|
this.audioClips = [];
|
|
72
70
|
this.outputGainNode = null;
|
|
73
71
|
this.channel = null;
|
|
74
72
|
this.context = null;
|
|
75
73
|
}
|
|
76
|
-
|
|
74
|
+
setLabel(label) {
|
|
77
75
|
this.label = label;
|
|
78
76
|
}
|
|
79
77
|
get length() {
|
|
@@ -7,11 +7,52 @@ export declare class AudioDevice {
|
|
|
7
7
|
context: AudioContext;
|
|
8
8
|
masterChannel: Master;
|
|
9
9
|
masterChannels: Master[];
|
|
10
|
+
readonly sampleRate: number;
|
|
11
|
+
readonly baseLatency: number;
|
|
12
|
+
readonly outputLatency: number;
|
|
13
|
+
readonly state: AudioContextState;
|
|
14
|
+
readonly currentTime: number;
|
|
15
|
+
readonly maximumFrequency: number;
|
|
10
16
|
constructor(deviceInfo: MediaDeviceInfo);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Returns the master channel associated with this audio device.
|
|
19
|
+
* The master channel is the main output channel for this audio device, and is used to control the overall volume and other properties of the audio output.
|
|
20
|
+
* @returns
|
|
21
|
+
*/
|
|
22
|
+
getMasterChannel(): Master;
|
|
23
|
+
/**
|
|
24
|
+
* Sets the master channel for this audio device.
|
|
25
|
+
* The master channel is normally automatically created when the audio device is initialized, but this method allows for the master channel to be changed if needed.
|
|
26
|
+
* @param channel
|
|
27
|
+
* @returns
|
|
28
|
+
*/
|
|
29
|
+
setMasterChannel(channel: Master): void;
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new master channel based on the this audio device's audio context, and adds it to the master channels array.
|
|
32
|
+
* Normally, an audio device should only have one master channel, but this method allows for multiple master channels to be created and used if needed.
|
|
33
|
+
* @returns
|
|
34
|
+
*/
|
|
35
|
+
createMasterChannel(): Master;
|
|
36
|
+
/**
|
|
37
|
+
* Returns the audio context associated with this audio device.
|
|
38
|
+
* This method is provided for ease of use, and is a wrapper for the context property.
|
|
39
|
+
*
|
|
40
|
+
* The audio context can vary between audio devices, and is used to create channels and master channels that are associated with this audio device.
|
|
41
|
+
*/
|
|
42
|
+
getContext(): AudioContext;
|
|
43
|
+
/**
|
|
44
|
+
* Creates a new channel based on the this audio device's audio context.
|
|
45
|
+
* This method is a wrapper for the Channel constructor, and is provided for ease of use.
|
|
46
|
+
* In case you want to create a channel with a different audio context, you can use the Channel constructor directly.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```
|
|
50
|
+
* const myChannel: Channel = audioDevice.createChannel("My Channel");
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @param label
|
|
54
|
+
* @returns
|
|
55
|
+
*/
|
|
56
|
+
createChannel(label?: string): Channel;
|
|
16
57
|
}
|
|
17
58
|
//# 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;
|
|
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;IAkBD,UAAU,EAAE,eAAe;IAhBvC,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;IAErC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAA2B;IACtD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAA4B;IACxD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAA8B;IAC5D,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAsB;IACvD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAA4B;IAExD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAA+B;IAEhE,YAAmB,UAAU,EAAE,eAAe,EAAI;IAElD;;;;OAIG;IACI,gBAAgB,IAAI,MAAM,CAEhC;IAED;;;;;OAKG;IACI,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAQ7C;IAED;;;;OAIG;IACI,mBAAmB,IAAI,MAAM,CAMnC;IAED;;;;;OAKG;IACI,UAAU,IAAI,YAAY,CAEhC;IAED;;;;;;;;;;;;OAYG;IACI,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAE5C;CACJ"}
|