@aelionsdk/audio 1.2.0-rc.5 → 1.2.0
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
CHANGED
|
@@ -5,10 +5,10 @@ Audio scheduling and deterministic PCM processing primitives for AelionSDK.
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @aelionsdk/audio
|
|
8
|
+
npm install @aelionsdk/audio
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
`
|
|
11
|
+
`latest` currently resolves to `1.2.0`. Product applications should prefer
|
|
12
12
|
`@aelionsdk/sdk`; use this package directly when building a custom audio host,
|
|
13
13
|
analysis pipeline or renderer integration.
|
|
14
14
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transferable-worklet-clock.d.ts","sourceRoot":"","sources":["../src/transferable-worklet-clock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EACL,oBAAoB,EACpB,KAAK,4BAA4B,EAClC,MAAM,6BAA6B,CAAC;AAoBrC,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,gEAAgE;IAChE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,qBAAa,6BAA8B,YAAW,UAAU;;IAC9D,SAAgB,OAAO,EAAE,YAAY,CAAC;IACtC,SAAgB,KAAK,EAAE,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"transferable-worklet-clock.d.ts","sourceRoot":"","sources":["../src/transferable-worklet-clock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EACL,oBAAoB,EACpB,KAAK,4BAA4B,EAClC,MAAM,6BAA6B,CAAC;AAoBrC,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,gEAAgE;IAChE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,qBAAa,6BAA8B,YAAW,UAAU;;IAC9D,SAAgB,OAAO,EAAE,YAAY,CAAC;IACtC,SAAgB,KAAK,EAAE,oBAAoB,CAAC;gBAczB,OAAO,GAAE,6BAAkC;IAa9D,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,IAAW,WAAW,IAAI,OAAO,CAEhC;IAED,IAAW,UAAU,IAAI,MAAM,CAE9B;IAED,IAAW,UAAU,IAAI,uBAAuB,GAAG,SAAS,CAE3D;IAEY,UAAU,CACrB,iBAAiB,SAA2C,GAC3D,OAAO,CAAC,IAAI,CAAC;IAyDH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO;IAkB1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB7B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAY5B,KAAK,IAAI,MAAM;IAQf,QAAQ,IAAI,4BAA4B;IAIxC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CA0BhC;AAED,MAAM,MAAM,0BAA0B,GAClC;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAA;CAAE,GAC1E;IAAE,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,iCAAiC,CAAA;CAAE,CAAC;AAEhG,wBAAgB,2BAA2B,CAAC,WAAW,EAAE;IACvD,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,0BAA0B,EAAE,OAAO,CAAC;CAC9C,GAAG,0BAA0B,CAI7B"}
|
|
@@ -19,6 +19,7 @@ export class TransferableAudioWorkletClock {
|
|
|
19
19
|
queue;
|
|
20
20
|
#ownsContext;
|
|
21
21
|
#node;
|
|
22
|
+
#outputConnected = false;
|
|
22
23
|
#initializeTask;
|
|
23
24
|
#disposeTask;
|
|
24
25
|
#disposed = false;
|
|
@@ -97,6 +98,7 @@ export class TransferableAudioWorkletClock {
|
|
|
97
98
|
node.port.start();
|
|
98
99
|
node.connect(this.context.destination);
|
|
99
100
|
connected = true;
|
|
101
|
+
this.#outputConnected = true;
|
|
100
102
|
this.#throwIfInitializationStale(generation);
|
|
101
103
|
this.#contextOriginTime = this.context.currentTime;
|
|
102
104
|
this.#node = node;
|
|
@@ -110,6 +112,7 @@ export class TransferableAudioWorkletClock {
|
|
|
110
112
|
}
|
|
111
113
|
async start() {
|
|
112
114
|
await this.initialize();
|
|
115
|
+
this.#connectOutput();
|
|
113
116
|
this.#node?.port.postMessage({ type: 'start', generation: this.#generation });
|
|
114
117
|
await this.context.resume();
|
|
115
118
|
}
|
|
@@ -130,13 +133,28 @@ export class TransferableAudioWorkletClock {
|
|
|
130
133
|
return true;
|
|
131
134
|
}
|
|
132
135
|
async pause() {
|
|
136
|
+
this.#disconnectOutput();
|
|
133
137
|
if (this.context.state === 'running')
|
|
134
138
|
await this.context.suspend();
|
|
135
139
|
}
|
|
136
140
|
async resume() {
|
|
141
|
+
this.#connectOutput();
|
|
137
142
|
if (this.context.state !== 'running')
|
|
138
143
|
await this.context.resume();
|
|
139
144
|
}
|
|
145
|
+
#connectOutput() {
|
|
146
|
+
if (this.#node === undefined || this.#outputConnected)
|
|
147
|
+
return;
|
|
148
|
+
this.#node.connect(this.context.destination);
|
|
149
|
+
this.#outputConnected = true;
|
|
150
|
+
}
|
|
151
|
+
#disconnectOutput() {
|
|
152
|
+
if (this.#node === undefined || !this.#outputConnected)
|
|
153
|
+
return;
|
|
154
|
+
this.#node.disconnect();
|
|
155
|
+
this.#outputConnected = false;
|
|
156
|
+
this.queue.flush();
|
|
157
|
+
}
|
|
140
158
|
seek(timeUs) {
|
|
141
159
|
if (!Number.isSafeInteger(timeUs) || timeUs < 0) {
|
|
142
160
|
throw new RangeError('Seek target must be a non-negative safe integer microsecond value');
|
|
@@ -166,6 +184,7 @@ export class TransferableAudioWorkletClock {
|
|
|
166
184
|
this.queue.close();
|
|
167
185
|
this.#node?.port.postMessage({ type: 'close' });
|
|
168
186
|
this.#node?.disconnect();
|
|
187
|
+
this.#outputConnected = false;
|
|
169
188
|
this.#node?.port.close();
|
|
170
189
|
this.#node = undefined;
|
|
171
190
|
if (this.#ownsContext && this.context.state !== 'closed')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worklet-clock.d.ts","sourceRoot":"","sources":["../src/worklet-clock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAE1E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;CACpC;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,gEAAgE;IAChE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,MAAM,wBAAwB,GAAG,iBAAiB,GAAG,aAAa,CAAC;AAEzE,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,wBAAwB,EAClC,OAAO,EAAE,wBAAwB,GAChC,aAAa,GAAG,SAAS,GAAG,SAAS,CAIvC;AAoBD,qBAAa,iBAAkB,YAAW,UAAU;;IAClD,SAAgB,OAAO,EAAE,YAAY,CAAC;IACtC,SAAgB,IAAI,EAAE,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"worklet-clock.d.ts","sourceRoot":"","sources":["../src/worklet-clock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAE1E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;CACpC;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,gEAAgE;IAChE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,MAAM,wBAAwB,GAAG,iBAAiB,GAAG,aAAa,CAAC;AAEzE,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,wBAAwB,EAClC,OAAO,EAAE,wBAAwB,GAChC,aAAa,GAAG,SAAS,GAAG,SAAS,CAIvC;AAoBD,qBAAa,iBAAkB,YAAW,UAAU;;IAClD,SAAgB,OAAO,EAAE,YAAY,CAAC;IACtC,SAAgB,IAAI,EAAE,mBAAmB,CAAC;gBAwBvB,OAAO,GAAE,iBAAsB;IAkBlD,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,IAAW,WAAW,IAAI,OAAO,CAEhC;IAED,IAAW,UAAU,IAAI,gBAAgB,GAAG,SAAS,CAEpD;IAED,IAAW,UAAU,IAAI,MAAM,CAE9B;IAEY,UAAU,CAAC,iBAAiB,SAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;IAuDtE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B7B,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GAAG,MAAM,IAAI;IAKjE,YAAY,CAAC,MAAM,SAAI,GAAG,MAAM;IAYhC,KAAK,IAAI,MAAM;IAQf,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAgChC"}
|
package/dist/worklet-clock.js
CHANGED
|
@@ -28,6 +28,7 @@ export class AudioWorkletClock {
|
|
|
28
28
|
#initializeTask;
|
|
29
29
|
#disposeTask;
|
|
30
30
|
#ownsContext;
|
|
31
|
+
#outputConnected = false;
|
|
31
32
|
#disposed = false;
|
|
32
33
|
#lifecycleGeneration = 0;
|
|
33
34
|
#lastReport;
|
|
@@ -114,6 +115,7 @@ export class AudioWorkletClock {
|
|
|
114
115
|
// module-loading latency appears as permanent A/V drift.
|
|
115
116
|
node.connect(this.context.destination);
|
|
116
117
|
connected = true;
|
|
118
|
+
this.#outputConnected = true;
|
|
117
119
|
this.#throwIfInitializationStale(generation);
|
|
118
120
|
this.#contextOriginTime = this.context.currentTime;
|
|
119
121
|
this.#node = node;
|
|
@@ -127,20 +129,41 @@ export class AudioWorkletClock {
|
|
|
127
129
|
}
|
|
128
130
|
async start() {
|
|
129
131
|
await this.initialize();
|
|
132
|
+
this.#connectOutput();
|
|
130
133
|
await withTimeout(this.context.resume(), 5_000, 'AudioContext resume');
|
|
131
134
|
this.#emit('started');
|
|
132
135
|
}
|
|
133
136
|
async pause() {
|
|
137
|
+
this.#disconnectOutput();
|
|
134
138
|
if (this.context.state === 'running')
|
|
135
139
|
await this.context.suspend();
|
|
136
140
|
this.#emit('paused');
|
|
137
141
|
}
|
|
138
142
|
async resume() {
|
|
143
|
+
this.#connectOutput();
|
|
139
144
|
if (this.context.state !== 'running') {
|
|
140
145
|
await withTimeout(this.context.resume(), 5_000, 'AudioContext resume');
|
|
141
146
|
}
|
|
142
147
|
this.#emit('resumed');
|
|
143
148
|
}
|
|
149
|
+
#connectOutput() {
|
|
150
|
+
if (this.#node === undefined || this.#outputConnected)
|
|
151
|
+
return;
|
|
152
|
+
this.#node.connect(this.context.destination);
|
|
153
|
+
this.#outputConnected = true;
|
|
154
|
+
}
|
|
155
|
+
#disconnectOutput() {
|
|
156
|
+
if (this.#node === undefined || !this.#outputConnected)
|
|
157
|
+
return;
|
|
158
|
+
// Disconnect only. A pause does not move the playback position, so the
|
|
159
|
+
// buffered frames are still the ones that come next and resuming should
|
|
160
|
+
// continue from them. Dropping them here would also reset the ring's play
|
|
161
|
+
// and underrun counters, which are reported as session telemetry, and cost
|
|
162
|
+
// a full refill on every resume. An edit while paused is what makes those
|
|
163
|
+
// frames stale, and `AelionPlayer.invalidate` handles that case.
|
|
164
|
+
this.#node.disconnect();
|
|
165
|
+
this.#outputConnected = false;
|
|
166
|
+
}
|
|
144
167
|
subscribe(listener) {
|
|
145
168
|
this.#listeners.add(listener);
|
|
146
169
|
return () => this.#listeners.delete(listener);
|
|
@@ -171,6 +194,7 @@ export class AudioWorkletClock {
|
|
|
171
194
|
this.context.removeEventListener('statechange', this.#onStateChange);
|
|
172
195
|
this.ring.close();
|
|
173
196
|
this.#node?.disconnect();
|
|
197
|
+
this.#outputConnected = false;
|
|
174
198
|
this.#node?.port.close();
|
|
175
199
|
this.#node = undefined;
|
|
176
200
|
if (this.#ownsContext && this.context.state !== 'closed')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aelionsdk/audio",
|
|
3
|
-
"version": "1.2.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "AudioWorklet clock, PCM buffering and audio mixing for AelionSDK",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"provenance": true
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@aelionsdk/core": "1.2.0
|
|
38
|
-
"@aelionsdk/render-ir": "1.2.0
|
|
37
|
+
"@aelionsdk/core": "1.2.0",
|
|
38
|
+
"@aelionsdk/render-ir": "1.2.0"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsc -b",
|