@gjsify/webaudio 0.3.13 → 0.3.15
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/esm/audio-buffer-source-node.js +60 -58
- package/lib/esm/audio-buffer.js +37 -36
- package/lib/esm/audio-context.js +88 -89
- package/lib/esm/audio-destination-node.js +10 -8
- package/lib/esm/audio-node.js +33 -32
- package/lib/esm/audio-param.js +78 -76
- package/lib/esm/gain-node.js +18 -16
- package/lib/esm/gst-decoder.js +71 -62
- package/lib/esm/gst-init.js +9 -8
- package/lib/esm/gst-player.js +121 -124
- package/lib/esm/html-audio-element.js +59 -59
- package/lib/esm/index.js +7 -15
- package/lib/esm/register.js +11 -5
- package/package.json +10 -10
|
@@ -2,62 +2,64 @@ import { AudioNode } from "./audio-node.js";
|
|
|
2
2
|
import { AudioParam } from "./audio-param.js";
|
|
3
3
|
import { GstPlayer } from "./gst-player.js";
|
|
4
4
|
import { GainNode } from "./gain-node.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
AudioBufferSourceNode
|
|
5
|
+
|
|
6
|
+
//#region src/audio-buffer-source-node.ts
|
|
7
|
+
var AudioBufferSourceNode = class extends AudioNode {
|
|
8
|
+
buffer = null;
|
|
9
|
+
loop = false;
|
|
10
|
+
loopStart = 0;
|
|
11
|
+
loopEnd = 0;
|
|
12
|
+
playbackRate;
|
|
13
|
+
onended = null;
|
|
14
|
+
_player = null;
|
|
15
|
+
_started = false;
|
|
16
|
+
constructor() {
|
|
17
|
+
super(0, 1);
|
|
18
|
+
this.playbackRate = new AudioParam(1, .0625, 16);
|
|
19
|
+
}
|
|
20
|
+
start(when = 0, offset = 0, duration) {
|
|
21
|
+
if (this._started) {
|
|
22
|
+
throw new DOMException("AudioBufferSourceNode can only be started once", "InvalidStateError");
|
|
23
|
+
}
|
|
24
|
+
this._started = true;
|
|
25
|
+
if (!this.buffer) return;
|
|
26
|
+
const gainNode = this._findGainNode();
|
|
27
|
+
const volume = gainNode ? gainNode.gain.value : 1;
|
|
28
|
+
this._player = new GstPlayer({
|
|
29
|
+
audioBuffer: this.buffer,
|
|
30
|
+
volume,
|
|
31
|
+
loop: this.loop,
|
|
32
|
+
offset,
|
|
33
|
+
duration,
|
|
34
|
+
playbackRate: this.playbackRate.value,
|
|
35
|
+
onEnded: () => {
|
|
36
|
+
if (gainNode) {
|
|
37
|
+
gainNode._activePlayers.delete(this._player);
|
|
38
|
+
}
|
|
39
|
+
this._player = null;
|
|
40
|
+
this.onended?.();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
if (gainNode && this._player) {
|
|
44
|
+
gainNode._activePlayers.add(this._player);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
stop(_when = 0) {
|
|
48
|
+
if (this._player) {
|
|
49
|
+
this._player.stop();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Walk the output chain to find a GainNode */
|
|
53
|
+
_findGainNode() {
|
|
54
|
+
for (const node of this._outputs) {
|
|
55
|
+
if (node instanceof GainNode) return node;
|
|
56
|
+
for (const inner of node._outputs) {
|
|
57
|
+
if (inner instanceof GainNode) return inner;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
63
62
|
};
|
|
63
|
+
|
|
64
|
+
//#endregion
|
|
65
|
+
export { AudioBufferSourceNode };
|
package/lib/esm/audio-buffer.js
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
export {
|
|
36
|
-
AudioBuffer
|
|
1
|
+
//#region src/audio-buffer.ts
|
|
2
|
+
var AudioBuffer = class {
|
|
3
|
+
sampleRate;
|
|
4
|
+
length;
|
|
5
|
+
duration;
|
|
6
|
+
numberOfChannels;
|
|
7
|
+
/** @internal */
|
|
8
|
+
_channelData;
|
|
9
|
+
constructor(options) {
|
|
10
|
+
this.sampleRate = options.sampleRate;
|
|
11
|
+
this.length = options.length;
|
|
12
|
+
this.numberOfChannels = options.numberOfChannels;
|
|
13
|
+
this.duration = this.length / this.sampleRate;
|
|
14
|
+
this._channelData = [];
|
|
15
|
+
for (let i = 0; i < this.numberOfChannels; i++) {
|
|
16
|
+
this._channelData.push(new Float32Array(this.length));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
getChannelData(channel) {
|
|
20
|
+
if (channel < 0 || channel >= this.numberOfChannels) {
|
|
21
|
+
throw new RangeError(`channel index ${channel} out of range [0, ${this.numberOfChannels})`);
|
|
22
|
+
}
|
|
23
|
+
return this._channelData[channel];
|
|
24
|
+
}
|
|
25
|
+
copyFromChannel(destination, channelNumber, bufferOffset = 0) {
|
|
26
|
+
const src = this.getChannelData(channelNumber);
|
|
27
|
+
const len = Math.min(destination.length, src.length - bufferOffset);
|
|
28
|
+
destination.set(src.subarray(bufferOffset, bufferOffset + len));
|
|
29
|
+
}
|
|
30
|
+
copyToChannel(source, channelNumber, bufferOffset = 0) {
|
|
31
|
+
const dest = this.getChannelData(channelNumber);
|
|
32
|
+
const len = Math.min(source.length, dest.length - bufferOffset);
|
|
33
|
+
dest.set(source.subarray(0, len), bufferOffset);
|
|
34
|
+
}
|
|
37
35
|
};
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
export { AudioBuffer };
|
package/lib/esm/audio-context.js
CHANGED
|
@@ -1,94 +1,93 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { AudioNode } from "./audio-node.js";
|
|
2
2
|
import { ensureGstInit } from "./gst-init.js";
|
|
3
|
+
import { GainNode } from "./gain-node.js";
|
|
4
|
+
import { AudioBufferSourceNode } from "./audio-buffer-source-node.js";
|
|
3
5
|
import { AudioBuffer } from "./audio-buffer.js";
|
|
4
|
-
import { AudioNode } from "./audio-node.js";
|
|
5
6
|
import { AudioDestinationNode } from "./audio-destination-node.js";
|
|
6
|
-
import { AudioBufferSourceNode } from "./audio-buffer-source-node.js";
|
|
7
|
-
import { GainNode } from "./gain-node.js";
|
|
8
7
|
import { decodeAudioDataSync } from "./gst-decoder.js";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
export {
|
|
93
|
-
AudioContext
|
|
8
|
+
import GLib from "gi://GLib?version=2.0";
|
|
9
|
+
|
|
10
|
+
//#region src/audio-context.ts
|
|
11
|
+
var AudioContext = class {
|
|
12
|
+
state = "suspended";
|
|
13
|
+
sampleRate = 44100;
|
|
14
|
+
destination;
|
|
15
|
+
listener = {};
|
|
16
|
+
_startTime;
|
|
17
|
+
constructor() {
|
|
18
|
+
ensureGstInit();
|
|
19
|
+
this._startTime = GLib.get_monotonic_time();
|
|
20
|
+
this.destination = new AudioDestinationNode();
|
|
21
|
+
}
|
|
22
|
+
/** Monotonically increasing time in seconds since context creation. */
|
|
23
|
+
get currentTime() {
|
|
24
|
+
return (GLib.get_monotonic_time() - this._startTime) / 1e6;
|
|
25
|
+
}
|
|
26
|
+
createGain() {
|
|
27
|
+
return new GainNode();
|
|
28
|
+
}
|
|
29
|
+
createBufferSource() {
|
|
30
|
+
return new AudioBufferSourceNode();
|
|
31
|
+
}
|
|
32
|
+
createBuffer(numberOfChannels, length, sampleRate) {
|
|
33
|
+
return new AudioBuffer({
|
|
34
|
+
numberOfChannels,
|
|
35
|
+
length,
|
|
36
|
+
sampleRate
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Decode encoded audio data (MP3, WAV, OGG, etc.) into an AudioBuffer.
|
|
41
|
+
* Uses GStreamer's decodebin for format-agnostic decoding.
|
|
42
|
+
*/
|
|
43
|
+
decodeAudioData(arrayBuffer, successCallback, errorCallback) {
|
|
44
|
+
try {
|
|
45
|
+
const buffer = decodeAudioDataSync(arrayBuffer);
|
|
46
|
+
successCallback?.(buffer);
|
|
47
|
+
return Promise.resolve(buffer);
|
|
48
|
+
} catch (err) {
|
|
49
|
+
const domErr = err instanceof DOMException ? err : new DOMException("Unable to decode audio data", "EncodingError");
|
|
50
|
+
errorCallback?.(domErr);
|
|
51
|
+
return Promise.reject(domErr);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async resume() {
|
|
55
|
+
this.state = "running";
|
|
56
|
+
}
|
|
57
|
+
async suspend() {
|
|
58
|
+
this.state = "suspended";
|
|
59
|
+
}
|
|
60
|
+
async close() {
|
|
61
|
+
this.state = "closed";
|
|
62
|
+
}
|
|
63
|
+
createAnalyser() {
|
|
64
|
+
return {
|
|
65
|
+
connect: () => {},
|
|
66
|
+
disconnect: () => {},
|
|
67
|
+
fftSize: 2048,
|
|
68
|
+
frequencyBinCount: 1024,
|
|
69
|
+
getByteFrequencyData: () => {},
|
|
70
|
+
getFloatFrequencyData: () => {}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
createDynamicsCompressor() {
|
|
74
|
+
return new AudioNode();
|
|
75
|
+
}
|
|
76
|
+
createBiquadFilter() {
|
|
77
|
+
return new AudioNode();
|
|
78
|
+
}
|
|
79
|
+
createConvolver() {
|
|
80
|
+
return new AudioNode();
|
|
81
|
+
}
|
|
82
|
+
createPanner() {
|
|
83
|
+
return new AudioNode();
|
|
84
|
+
}
|
|
85
|
+
createStereoPanner() {
|
|
86
|
+
return new AudioNode();
|
|
87
|
+
}
|
|
88
|
+
addEventListener(_type, _listener) {}
|
|
89
|
+
removeEventListener(_type, _listener) {}
|
|
94
90
|
};
|
|
91
|
+
|
|
92
|
+
//#endregion
|
|
93
|
+
export { AudioContext };
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { AudioNode } from "./audio-node.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
AudioDestinationNode
|
|
2
|
+
|
|
3
|
+
//#region src/audio-destination-node.ts
|
|
4
|
+
var AudioDestinationNode = class extends AudioNode {
|
|
5
|
+
maxChannelCount = 2;
|
|
6
|
+
constructor() {
|
|
7
|
+
super(1, 0);
|
|
8
|
+
}
|
|
10
9
|
};
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
export { AudioDestinationNode };
|
package/lib/esm/audio-node.js
CHANGED
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
export {
|
|
32
|
-
AudioNode
|
|
1
|
+
//#region src/audio-node.ts
|
|
2
|
+
var AudioNode = class {
|
|
3
|
+
/** @internal downstream connections */
|
|
4
|
+
_outputs = new Set();
|
|
5
|
+
/** @internal upstream connections */
|
|
6
|
+
_inputs = new Set();
|
|
7
|
+
numberOfInputs;
|
|
8
|
+
numberOfOutputs;
|
|
9
|
+
channelCount;
|
|
10
|
+
constructor(numberOfInputs = 1, numberOfOutputs = 1) {
|
|
11
|
+
this.numberOfInputs = numberOfInputs;
|
|
12
|
+
this.numberOfOutputs = numberOfOutputs;
|
|
13
|
+
this.channelCount = 2;
|
|
14
|
+
}
|
|
15
|
+
connect(destination) {
|
|
16
|
+
this._outputs.add(destination);
|
|
17
|
+
destination._inputs.add(this);
|
|
18
|
+
return destination;
|
|
19
|
+
}
|
|
20
|
+
disconnect(destination) {
|
|
21
|
+
if (destination) {
|
|
22
|
+
this._outputs.delete(destination);
|
|
23
|
+
destination._inputs.delete(this);
|
|
24
|
+
} else {
|
|
25
|
+
for (const node of this._outputs) {
|
|
26
|
+
node._inputs.delete(this);
|
|
27
|
+
}
|
|
28
|
+
this._outputs.clear();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
33
31
|
};
|
|
32
|
+
|
|
33
|
+
//#endregion
|
|
34
|
+
export { AudioNode };
|
package/lib/esm/audio-param.js
CHANGED
|
@@ -1,78 +1,80 @@
|
|
|
1
1
|
import GLib from "gi://GLib?version=2.0";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
AudioParam
|
|
2
|
+
|
|
3
|
+
//#region src/audio-param.ts
|
|
4
|
+
var AudioParam = class {
|
|
5
|
+
defaultValue;
|
|
6
|
+
minValue;
|
|
7
|
+
maxValue;
|
|
8
|
+
/** @internal callback invoked when value changes */
|
|
9
|
+
_onChange = null;
|
|
10
|
+
_value;
|
|
11
|
+
_rampTimerId = null;
|
|
12
|
+
constructor(defaultValue = 0, minValue = -34028235e31, maxValue = 34028235e31) {
|
|
13
|
+
this.defaultValue = defaultValue;
|
|
14
|
+
this.minValue = minValue;
|
|
15
|
+
this.maxValue = maxValue;
|
|
16
|
+
this._value = defaultValue;
|
|
17
|
+
}
|
|
18
|
+
get value() {
|
|
19
|
+
return this._value;
|
|
20
|
+
}
|
|
21
|
+
set value(v) {
|
|
22
|
+
this._cancelRamp();
|
|
23
|
+
this._value = Math.max(this.minValue, Math.min(this.maxValue, v));
|
|
24
|
+
this._onChange?.(this._value);
|
|
25
|
+
}
|
|
26
|
+
setValueAtTime(value, _startTime) {
|
|
27
|
+
this.value = value;
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
linearRampToValueAtTime(value, _endTime) {
|
|
31
|
+
this.value = value;
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
exponentialRampToValueAtTime(value, _endTime) {
|
|
35
|
+
this.value = value;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
setTargetAtTime(target, _startTime, timeConstant) {
|
|
39
|
+
this._cancelRamp();
|
|
40
|
+
if (timeConstant <= 0) {
|
|
41
|
+
this.value = target;
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
const stepMs = Math.max(10, Math.round(timeConstant * 100));
|
|
45
|
+
this._rampTimerId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, stepMs, () => {
|
|
46
|
+
const diff = target - this._value;
|
|
47
|
+
if (Math.abs(diff) < .001) {
|
|
48
|
+
this._value = target;
|
|
49
|
+
this._onChange?.(this._value);
|
|
50
|
+
this._rampTimerId = null;
|
|
51
|
+
return GLib.SOURCE_REMOVE;
|
|
52
|
+
}
|
|
53
|
+
const factor = 1 - Math.exp(-stepMs / (timeConstant * 1e3));
|
|
54
|
+
this._value += diff * factor;
|
|
55
|
+
this._onChange?.(this._value);
|
|
56
|
+
return GLib.SOURCE_CONTINUE;
|
|
57
|
+
});
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
setValueCurveAtTime(_values, _startTime, _duration) {
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
cancelScheduledValues(_startTime) {
|
|
64
|
+
this._cancelRamp();
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
cancelAndHoldAtTime(_cancelTime) {
|
|
68
|
+
this._cancelRamp();
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
_cancelRamp() {
|
|
72
|
+
if (this._rampTimerId !== null) {
|
|
73
|
+
GLib.source_remove(this._rampTimerId);
|
|
74
|
+
this._rampTimerId = null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
78
77
|
};
|
|
78
|
+
|
|
79
|
+
//#endregion
|
|
80
|
+
export { AudioParam };
|