@yume-chan/pcm-player 0.0.20 → 0.0.22
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/CHANGELOG.json +18 -0
- package/CHANGELOG.md +13 -1
- package/README.md +5 -4
- package/esm/index.d.ts +2 -4
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +31 -18
- package/esm/index.js.map +1 -1
- package/esm/worker.js +168 -63
- package/esm/worker.js.map +1 -1
- package/package.json +9 -9
- package/src/index.ts +40 -24
- package/tsconfig.dom.json +9 -8
- package/tsconfig.dom.tsbuildinfo +1 -1
- package/tsconfig.worker.tsbuildinfo +1 -1
- package/worker/worker.ts +229 -101
package/CHANGELOG.json
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yume-chan/pcm-player",
|
|
3
3
|
"entries": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.0.22",
|
|
6
|
+
"tag": "@yume-chan/pcm-player_v0.0.22",
|
|
7
|
+
"date": "Wed, 13 Dec 2023 05:57:27 GMT",
|
|
8
|
+
"comments": {
|
|
9
|
+
"none": [
|
|
10
|
+
{
|
|
11
|
+
"comment": "Add basic OLA algorithm to speed up playback when buffer is too high"
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"version": "0.0.21",
|
|
18
|
+
"tag": "@yume-chan/pcm-player_v0.0.21",
|
|
19
|
+
"date": "Fri, 25 Aug 2023 14:05:18 GMT",
|
|
20
|
+
"comments": {}
|
|
21
|
+
},
|
|
4
22
|
{
|
|
5
23
|
"version": "0.0.20",
|
|
6
24
|
"tag": "@yume-chan/pcm-player_v0.0.20",
|
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
# Change Log - @yume-chan/pcm-player
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Wed, 13 Dec 2023 05:57:27 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 0.0.22
|
|
6
|
+
Wed, 13 Dec 2023 05:57:27 GMT
|
|
7
|
+
|
|
8
|
+
### Updates
|
|
9
|
+
|
|
10
|
+
- Add basic OLA algorithm to speed up playback when buffer is too high
|
|
11
|
+
|
|
12
|
+
## 0.0.21
|
|
13
|
+
Fri, 25 Aug 2023 14:05:18 GMT
|
|
14
|
+
|
|
15
|
+
_Version update only_
|
|
4
16
|
|
|
5
17
|
## 0.0.20
|
|
6
18
|
Mon, 05 Jun 2023 02:51:41 GMT
|
package/README.md
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Play raw audio sample stream using Web Audio API.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- [
|
|
7
|
+
- [x] Arbitrary channel count
|
|
8
|
+
- [x] Arbitrary sample rate
|
|
9
|
+
- [x] Basic OLA (overlap-add) resampler
|
|
10
|
+
- [ ] Adjustable buffer size
|
|
10
11
|
|
|
11
12
|
## Usage
|
|
12
13
|
|
package/esm/index.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
export declare abstract class PcmPlayer<T> {
|
|
2
|
+
#private;
|
|
2
3
|
protected abstract sourceName: string;
|
|
3
|
-
|
|
4
|
-
private _worklet;
|
|
5
|
-
private _buffer;
|
|
6
|
-
constructor(sampleRate: number);
|
|
4
|
+
constructor(sampleRate: number, channelCount: number);
|
|
7
5
|
protected abstract feedCore(worklet: AudioWorkletNode, source: T): void;
|
|
8
6
|
feed(source: T): void;
|
|
9
7
|
start(): Promise<void>;
|
package/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8BAAsB,SAAS,CAAC,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8BAAsB,SAAS,CAAC,CAAC;;IAC7B,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAQ1B,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;IAQpD,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI;IAEvE,IAAI,CAAC,MAAM,EAAE,CAAC;IAaR,KAAK;IAsBL,IAAI;CAWb;AAED,qBAAa,cAAe,SAAQ,SAAS,CAAC,UAAU,CAAC;IACrD,UAAmB,UAAU,SAA4B;cAEtC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU;CAW5E;AAED,qBAAa,gBAAiB,SAAQ,SAAS,CAAC,YAAY,CAAC;IACzD,UAAmB,UAAU,SAA8B;cAExC,QAAQ,CACvB,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,YAAY;CAY3B;AAED,qBAAa,sBAAuB,SAAQ,SAAS,CAAC,YAAY,EAAE,CAAC;IACjE,UAAmB,UAAU,SAAqC;cAE/C,QAAQ,CACvB,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,YAAY,EAAE;CAa7B"}
|
package/esm/index.js
CHANGED
|
@@ -1,37 +1,50 @@
|
|
|
1
1
|
export class PcmPlayer {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
#context;
|
|
3
|
+
#channelCount;
|
|
4
|
+
#worklet;
|
|
5
|
+
#buffers = [];
|
|
6
|
+
#stopped = false;
|
|
7
|
+
constructor(sampleRate, channelCount) {
|
|
8
|
+
this.#context = new AudioContext({
|
|
7
9
|
latencyHint: "interactive",
|
|
8
10
|
sampleRate,
|
|
9
11
|
});
|
|
12
|
+
this.#channelCount = channelCount;
|
|
10
13
|
}
|
|
11
14
|
feed(source) {
|
|
12
|
-
if (this
|
|
13
|
-
|
|
15
|
+
if (this.#stopped) {
|
|
16
|
+
throw new Error("PcmPlayer is stopped");
|
|
17
|
+
}
|
|
18
|
+
if (this.#worklet === undefined) {
|
|
19
|
+
this.#buffers.push(source);
|
|
14
20
|
return;
|
|
15
21
|
}
|
|
16
|
-
this.feedCore(this
|
|
22
|
+
this.feedCore(this.#worklet, source);
|
|
17
23
|
}
|
|
18
24
|
async start() {
|
|
19
|
-
await this.
|
|
20
|
-
|
|
25
|
+
await this.#context.audioWorklet.addModule(new URL("./worker.js", import.meta.url));
|
|
26
|
+
if (this.#stopped) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
this.#worklet = new AudioWorkletNode(this.#context, this.sourceName, {
|
|
21
30
|
numberOfInputs: 0,
|
|
22
31
|
numberOfOutputs: 1,
|
|
23
|
-
outputChannelCount: [
|
|
32
|
+
outputChannelCount: [this.#channelCount],
|
|
24
33
|
});
|
|
25
|
-
this.
|
|
26
|
-
for (const source of this
|
|
27
|
-
this.feedCore(this
|
|
34
|
+
this.#worklet.connect(this.#context.destination);
|
|
35
|
+
for (const source of this.#buffers) {
|
|
36
|
+
this.feedCore(this.#worklet, source);
|
|
28
37
|
}
|
|
29
|
-
this.
|
|
38
|
+
this.#buffers.length = 0;
|
|
30
39
|
}
|
|
31
40
|
async stop() {
|
|
32
|
-
this
|
|
33
|
-
|
|
34
|
-
|
|
41
|
+
if (this.#stopped) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.#stopped = true;
|
|
45
|
+
this.#worklet?.disconnect();
|
|
46
|
+
this.#worklet = undefined;
|
|
47
|
+
await this.#context.close();
|
|
35
48
|
}
|
|
36
49
|
}
|
|
37
50
|
export class Int16PcmPlayer extends PcmPlayer {
|
package/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,OAAgB,SAAS;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/esm/worker.js
CHANGED
|
@@ -1,97 +1,199 @@
|
|
|
1
|
+
const INPUT_HOP_SIZE = 3000;
|
|
2
|
+
const SCALE = 0.9;
|
|
3
|
+
const OUTPUT_HOP_SIZE = (INPUT_HOP_SIZE * SCALE) | 0;
|
|
4
|
+
const WINDOW_SIZE = 6000;
|
|
5
|
+
const WINDOW_WEIGHT_TABLE = new Float32Array(WINDOW_SIZE);
|
|
6
|
+
for (let i = 0; i < WINDOW_SIZE / 2; i += 1) {
|
|
7
|
+
const value = Math.sin((i / WINDOW_SIZE) * Math.PI);
|
|
8
|
+
WINDOW_WEIGHT_TABLE[i] = value;
|
|
9
|
+
WINDOW_WEIGHT_TABLE[WINDOW_SIZE - i - 1] = value;
|
|
10
|
+
}
|
|
1
11
|
class SourceProcessor extends AudioWorkletProcessor {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
12
|
+
channelCount;
|
|
13
|
+
#readBuffer;
|
|
14
|
+
#chunks = [];
|
|
15
|
+
#chunkSampleCounts = [];
|
|
16
|
+
#totalSampleCount = 0;
|
|
17
|
+
#starting = true;
|
|
18
|
+
#speedUp = false;
|
|
19
|
+
#readOffset = 0;
|
|
20
|
+
#inputOffset = 0;
|
|
21
|
+
#outputOffset = 0;
|
|
22
|
+
constructor(options) {
|
|
5
23
|
super();
|
|
24
|
+
this.channelCount = options.outputChannelCount[0];
|
|
25
|
+
this.#readBuffer = new Float32Array(this.channelCount);
|
|
6
26
|
this.port.onmessage = (event) => {
|
|
27
|
+
while (this.#totalSampleCount > 0.35 * 48000) {
|
|
28
|
+
this.#chunks.shift();
|
|
29
|
+
const count = this.#chunkSampleCounts.shift();
|
|
30
|
+
this.#totalSampleCount -= count;
|
|
31
|
+
}
|
|
7
32
|
const data = event.data;
|
|
8
33
|
const [source, length] = this.createSource(data);
|
|
9
|
-
this.
|
|
10
|
-
this.
|
|
34
|
+
this.#chunks.push(source);
|
|
35
|
+
this.#chunkSampleCounts.push(length);
|
|
36
|
+
this.#totalSampleCount += length;
|
|
37
|
+
if (!this.#speedUp && this.#totalSampleCount > 0.25 * 48000) {
|
|
38
|
+
this.#speedUp = true;
|
|
39
|
+
this.#readOffset = 0;
|
|
40
|
+
this.#inputOffset = 0;
|
|
41
|
+
this.#outputOffset = 0;
|
|
42
|
+
}
|
|
11
43
|
};
|
|
12
44
|
}
|
|
13
|
-
process(_inputs, outputs) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
45
|
+
process(_inputs, [outputs]) {
|
|
46
|
+
if (this.#starting) {
|
|
47
|
+
if (this.#totalSampleCount < 0.1 * 48000) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
this.#starting = false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (this.#speedUp && this.#totalSampleCount < 0.15 * 48000) {
|
|
55
|
+
this.#speedUp = false;
|
|
56
|
+
this.#starting = true;
|
|
57
|
+
}
|
|
58
|
+
const outputLength = outputs[0].length;
|
|
59
|
+
if (this.#speedUp) {
|
|
60
|
+
for (let i = 0; i < outputLength; i += 1) {
|
|
61
|
+
let totalWeight = 0;
|
|
62
|
+
const firstWindow = Math.max(0, Math.floor((this.#outputOffset - WINDOW_SIZE) / OUTPUT_HOP_SIZE) + 1);
|
|
63
|
+
let inWindowIndex = this.#outputOffset - firstWindow * OUTPUT_HOP_SIZE;
|
|
64
|
+
let inputIndex = firstWindow * INPUT_HOP_SIZE + inWindowIndex;
|
|
65
|
+
while (inputIndex > 0 && inWindowIndex >= 0) {
|
|
66
|
+
this.#read(inputIndex - this.#readOffset);
|
|
67
|
+
const weight = WINDOW_WEIGHT_TABLE[inWindowIndex];
|
|
68
|
+
for (let j = 0; j < this.channelCount; j += 1) {
|
|
69
|
+
outputs[j][i] += this.#readBuffer[j] * weight;
|
|
70
|
+
}
|
|
71
|
+
totalWeight += weight;
|
|
72
|
+
inputIndex += INPUT_HOP_SIZE - OUTPUT_HOP_SIZE;
|
|
73
|
+
inWindowIndex -= OUTPUT_HOP_SIZE;
|
|
74
|
+
}
|
|
75
|
+
if (totalWeight > 0) {
|
|
76
|
+
for (let j = 0; j < this.channelCount; j += 1) {
|
|
77
|
+
outputs[j][i] /= totalWeight;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
this.#outputOffset += 1;
|
|
81
|
+
if (firstWindow > 0) {
|
|
82
|
+
this.#outputOffset -= OUTPUT_HOP_SIZE;
|
|
83
|
+
this.#readOffset -= INPUT_HOP_SIZE;
|
|
84
|
+
this.#inputOffset += (1 - SCALE) * INPUT_HOP_SIZE;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
this.#inputOffset += outputLength;
|
|
88
|
+
const firstChunkSampleCount = this.#chunkSampleCounts[0];
|
|
89
|
+
if (firstChunkSampleCount !== undefined &&
|
|
90
|
+
this.#inputOffset >= firstChunkSampleCount) {
|
|
91
|
+
this.#chunks.shift();
|
|
92
|
+
this.#chunkSampleCounts.shift();
|
|
93
|
+
this.#totalSampleCount -= firstChunkSampleCount;
|
|
94
|
+
this.#readOffset += firstChunkSampleCount;
|
|
95
|
+
this.#inputOffset -= firstChunkSampleCount;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
this.#copyChunks(outputs);
|
|
100
|
+
}
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
#copyChunks(outputs) {
|
|
17
104
|
let outputIndex = 0;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const beginSourceIndex = sourceIndex | 0;
|
|
25
|
-
let source = this._sources[0];
|
|
26
|
-
[source, sourceIndex, outputIndex] = this.copyChunk(sourceIndex, sourceIndexStep, source, outputLeft, outputRight, outputLength, outputIndex);
|
|
27
|
-
const consumedSampleCount = (sourceIndex | 0) - beginSourceIndex;
|
|
28
|
-
this._sourceSampleCount -= consumedSampleCount;
|
|
29
|
-
sourceIndex -= consumedSampleCount;
|
|
105
|
+
const outputLength = outputs[0].length;
|
|
106
|
+
while (this.#chunks.length > 0 && outputIndex < outputLength) {
|
|
107
|
+
let source = this.#chunks[0];
|
|
108
|
+
let consumedSampleCount = 0;
|
|
109
|
+
[source, consumedSampleCount, outputIndex] = this.copyChunk(source, outputs, outputLength, outputIndex);
|
|
110
|
+
this.#totalSampleCount -= consumedSampleCount;
|
|
30
111
|
if (source) {
|
|
31
112
|
// Output full
|
|
32
|
-
this
|
|
33
|
-
|
|
113
|
+
this.#chunks[0] = source;
|
|
114
|
+
this.#chunkSampleCounts[0] -= consumedSampleCount;
|
|
115
|
+
return;
|
|
34
116
|
}
|
|
35
|
-
this.
|
|
117
|
+
this.#chunks.shift();
|
|
118
|
+
this.#chunkSampleCounts.shift();
|
|
36
119
|
}
|
|
37
|
-
|
|
38
|
-
|
|
120
|
+
}
|
|
121
|
+
#read(offset) {
|
|
122
|
+
for (let i = 0; i < this.#chunks.length; i += 1) {
|
|
123
|
+
const length = this.#chunkSampleCounts[i];
|
|
124
|
+
if (offset < length) {
|
|
125
|
+
this.read(this.#chunks[i], offset, this.#readBuffer);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
offset -= length;
|
|
39
129
|
}
|
|
40
|
-
|
|
130
|
+
this.#readBuffer.fill(0);
|
|
41
131
|
}
|
|
42
132
|
}
|
|
43
133
|
class Int16SourceProcessor extends SourceProcessor {
|
|
44
134
|
createSource(data) {
|
|
45
135
|
const source = new Int16Array(data[0]);
|
|
46
|
-
return [source, source.length /
|
|
136
|
+
return [source, source.length / this.channelCount];
|
|
137
|
+
}
|
|
138
|
+
read(source, offset, target) {
|
|
139
|
+
const sourceOffset = offset * this.channelCount;
|
|
140
|
+
for (let i = 0; i < this.channelCount; i += 1) {
|
|
141
|
+
target[i] = source[sourceOffset + i] / 0x8000;
|
|
142
|
+
}
|
|
47
143
|
}
|
|
48
|
-
copyChunk(
|
|
144
|
+
copyChunk(source, outputs, outputLength, outputIndex) {
|
|
49
145
|
const sourceLength = source.length;
|
|
50
|
-
let
|
|
51
|
-
while (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
146
|
+
let sourceIndex = 0;
|
|
147
|
+
while (sourceIndex < sourceLength) {
|
|
148
|
+
for (let i = 0; i < this.channelCount; i += 1) {
|
|
149
|
+
outputs[i][outputIndex] = source[sourceIndex] / 0x8000;
|
|
150
|
+
sourceIndex += 1;
|
|
151
|
+
}
|
|
56
152
|
outputIndex += 1;
|
|
57
153
|
if (outputIndex === outputLength) {
|
|
58
154
|
return [
|
|
59
|
-
|
|
60
|
-
? source.subarray(
|
|
155
|
+
sourceIndex < sourceLength
|
|
156
|
+
? source.subarray(sourceIndex)
|
|
61
157
|
: undefined,
|
|
62
|
-
sourceIndex,
|
|
158
|
+
sourceIndex / this.channelCount,
|
|
63
159
|
outputIndex,
|
|
64
160
|
];
|
|
65
161
|
}
|
|
66
162
|
}
|
|
67
|
-
return [undefined, sourceIndex, outputIndex];
|
|
163
|
+
return [undefined, sourceIndex / this.channelCount, outputIndex];
|
|
68
164
|
}
|
|
69
165
|
}
|
|
70
166
|
class Float32SourceProcessor extends SourceProcessor {
|
|
71
167
|
createSource(data) {
|
|
72
168
|
const source = new Float32Array(data[0]);
|
|
73
|
-
return [source, source.length /
|
|
169
|
+
return [source, source.length / this.channelCount];
|
|
170
|
+
}
|
|
171
|
+
read(source, offset, target) {
|
|
172
|
+
const sourceOffset = offset * this.channelCount;
|
|
173
|
+
for (let i = 0; i < this.channelCount; i += 1) {
|
|
174
|
+
target[i] = source[sourceOffset + i];
|
|
175
|
+
}
|
|
74
176
|
}
|
|
75
|
-
copyChunk(
|
|
177
|
+
copyChunk(source, outputs, outputLength, outputIndex) {
|
|
76
178
|
const sourceLength = source.length;
|
|
77
|
-
let
|
|
78
|
-
while (
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
179
|
+
let sourceIndex = 0;
|
|
180
|
+
while (sourceIndex < sourceLength) {
|
|
181
|
+
for (let i = 0; i < this.channelCount; i += 1) {
|
|
182
|
+
outputs[i][outputIndex] = source[sourceIndex];
|
|
183
|
+
sourceIndex += 1;
|
|
184
|
+
}
|
|
83
185
|
outputIndex += 1;
|
|
84
186
|
if (outputIndex === outputLength) {
|
|
85
187
|
return [
|
|
86
|
-
|
|
87
|
-
? source.subarray(
|
|
188
|
+
sourceIndex < sourceLength
|
|
189
|
+
? source.subarray(sourceIndex)
|
|
88
190
|
: undefined,
|
|
89
|
-
sourceIndex,
|
|
191
|
+
sourceIndex / this.channelCount,
|
|
90
192
|
outputIndex,
|
|
91
193
|
];
|
|
92
194
|
}
|
|
93
195
|
}
|
|
94
|
-
return [undefined, sourceIndex, outputIndex];
|
|
196
|
+
return [undefined, sourceIndex / this.channelCount, outputIndex];
|
|
95
197
|
}
|
|
96
198
|
}
|
|
97
199
|
class Float32PlanerSourceProcessor extends SourceProcessor {
|
|
@@ -99,21 +201,24 @@ class Float32PlanerSourceProcessor extends SourceProcessor {
|
|
|
99
201
|
const source = data.map((channel) => new Float32Array(channel));
|
|
100
202
|
return [source, source[0].length];
|
|
101
203
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
204
|
+
read(source, offset, target) {
|
|
205
|
+
for (let i = 0; i < target.length; i += 1) {
|
|
206
|
+
target[i] = source[i][offset];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
copyChunk(source, outputs, outputLength, outputIndex) {
|
|
210
|
+
const sourceLength = source[0].length;
|
|
211
|
+
let sourceIndex = 0;
|
|
212
|
+
while (sourceIndex < sourceLength) {
|
|
213
|
+
for (let i = 0; i < this.channelCount; i += 1) {
|
|
214
|
+
outputs[i][outputIndex] = source[i][sourceIndex];
|
|
215
|
+
}
|
|
216
|
+
sourceIndex += 1;
|
|
112
217
|
outputIndex += 1;
|
|
113
218
|
if (outputIndex === outputLength) {
|
|
114
219
|
return [
|
|
115
|
-
|
|
116
|
-
? source.map((channel) => channel.subarray(
|
|
220
|
+
sourceIndex < sourceLength
|
|
221
|
+
? source.map((channel) => channel.subarray(sourceIndex))
|
|
117
222
|
: undefined,
|
|
118
223
|
sourceIndex,
|
|
119
224
|
outputIndex,
|
package/esm/worker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../worker/worker.ts"],"names":[],"mappings":"AAAA,MAAe,eACX,SAAQ,qBAAqB;
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../worker/worker.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yume-chan/pcm-player",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
4
|
"description": "Play raw audio sample stream using Web Audio API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"audio"
|
|
@@ -24,19 +24,19 @@
|
|
|
24
24
|
"main": "esm/index.js",
|
|
25
25
|
"types": "esm/index.d.ts",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"tslib": "^2.
|
|
27
|
+
"tslib": "^2.6.2"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@jest/globals": "^29.
|
|
31
|
-
"@types/audioworklet": "^0.0.
|
|
30
|
+
"@jest/globals": "^29.7.0",
|
|
31
|
+
"@types/audioworklet": "^0.0.52",
|
|
32
32
|
"@yume-chan/eslint-config": "^1.0.0",
|
|
33
33
|
"@yume-chan/tsconfig": "^1.0.0",
|
|
34
34
|
"cross-env": "^7.0.3",
|
|
35
|
-
"eslint": "^8.
|
|
36
|
-
"jest": "^29.
|
|
37
|
-
"prettier": "^
|
|
38
|
-
"ts-jest": "^29.
|
|
39
|
-
"typescript": "^5.
|
|
35
|
+
"eslint": "^8.55.0",
|
|
36
|
+
"jest": "^29.7.0",
|
|
37
|
+
"prettier": "^3.1.0",
|
|
38
|
+
"ts-jest": "^29.1.1",
|
|
39
|
+
"typescript": "^5.3.2"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "tsc -b tsconfig.dom.json && tsc -b tsconfig.worker.json",
|
package/src/index.ts
CHANGED
|
@@ -1,51 +1,67 @@
|
|
|
1
1
|
export abstract class PcmPlayer<T> {
|
|
2
2
|
protected abstract sourceName: string;
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
#context: AudioContext;
|
|
5
|
+
#channelCount: number;
|
|
6
|
+
#worklet: AudioWorkletNode | undefined;
|
|
7
|
+
#buffers: T[] = [];
|
|
8
|
+
#stopped = false;
|
|
9
|
+
|
|
10
|
+
constructor(sampleRate: number, channelCount: number) {
|
|
11
|
+
this.#context = new AudioContext({
|
|
10
12
|
latencyHint: "interactive",
|
|
11
13
|
sampleRate,
|
|
12
14
|
});
|
|
15
|
+
this.#channelCount = channelCount;
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
protected abstract feedCore(worklet: AudioWorkletNode, source: T): void;
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
if (this
|
|
19
|
-
|
|
20
|
+
feed(source: T) {
|
|
21
|
+
if (this.#stopped) {
|
|
22
|
+
throw new Error("PcmPlayer is stopped");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (this.#worklet === undefined) {
|
|
26
|
+
this.#buffers.push(source);
|
|
20
27
|
return;
|
|
21
28
|
}
|
|
22
29
|
|
|
23
|
-
this.feedCore(this
|
|
30
|
+
this.feedCore(this.#worklet, source);
|
|
24
31
|
}
|
|
25
32
|
|
|
26
|
-
|
|
27
|
-
await this.
|
|
28
|
-
new URL("./worker.js", import.meta.url)
|
|
33
|
+
async start() {
|
|
34
|
+
await this.#context.audioWorklet.addModule(
|
|
35
|
+
new URL("./worker.js", import.meta.url),
|
|
29
36
|
);
|
|
30
37
|
|
|
31
|
-
|
|
38
|
+
if (this.#stopped) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
this.#worklet = new AudioWorkletNode(this.#context, this.sourceName, {
|
|
32
43
|
numberOfInputs: 0,
|
|
33
44
|
numberOfOutputs: 1,
|
|
34
|
-
outputChannelCount: [
|
|
45
|
+
outputChannelCount: [this.#channelCount],
|
|
35
46
|
});
|
|
36
|
-
this.
|
|
47
|
+
this.#worklet.connect(this.#context.destination);
|
|
37
48
|
|
|
38
|
-
for (const source of this
|
|
39
|
-
this.feedCore(this
|
|
49
|
+
for (const source of this.#buffers) {
|
|
50
|
+
this.feedCore(this.#worklet, source);
|
|
40
51
|
}
|
|
41
|
-
this.
|
|
52
|
+
this.#buffers.length = 0;
|
|
42
53
|
}
|
|
43
54
|
|
|
44
55
|
async stop() {
|
|
45
|
-
this
|
|
46
|
-
|
|
56
|
+
if (this.#stopped) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
this.#stopped = true;
|
|
60
|
+
|
|
61
|
+
this.#worklet?.disconnect();
|
|
62
|
+
this.#worklet = undefined;
|
|
47
63
|
|
|
48
|
-
await this.
|
|
64
|
+
await this.#context.close();
|
|
49
65
|
}
|
|
50
66
|
}
|
|
51
67
|
|
|
@@ -70,7 +86,7 @@ export class Float32PcmPlayer extends PcmPlayer<Float32Array> {
|
|
|
70
86
|
|
|
71
87
|
protected override feedCore(
|
|
72
88
|
worklet: AudioWorkletNode,
|
|
73
|
-
source: Float32Array
|
|
89
|
+
source: Float32Array,
|
|
74
90
|
) {
|
|
75
91
|
if (
|
|
76
92
|
source.byteOffset !== 0 ||
|
|
@@ -89,7 +105,7 @@ export class Float32PlanerPcmPlayer extends PcmPlayer<Float32Array[]> {
|
|
|
89
105
|
|
|
90
106
|
protected override feedCore(
|
|
91
107
|
worklet: AudioWorkletNode,
|
|
92
|
-
source: Float32Array[]
|
|
108
|
+
source: Float32Array[],
|
|
93
109
|
) {
|
|
94
110
|
const buffers = source.map((channel) => {
|
|
95
111
|
if (
|