-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaudioWorklet.js
More file actions
80 lines (80 loc) · 2.51 KB
/
audioWorklet.js
File metadata and controls
80 lines (80 loc) · 2.51 KB
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
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
globalThis.console.log(globalThis);
let workerPort;
// Promise.withResolvers() not implemented in Firefox Nightly 120
const promiseWithResolvers = () => {
let resolve, reject;
const promise = new Promise(
(_resolve, _reject) => ((resolve = _resolve), (reject = _reject)),
);
return { resolve, reject, promise };
};
class AudioWorkletFetchWorker extends AudioWorkletProcessor {
constructor(options) {
super(options);
// There are several ways to do this. We'll use Array here.
// We could use a Map or resizable ArrayBuffer, where implemented (not implemented on Firefox 120).
this.array = new Array();
this.offset = 0;
this.writes = 0;
this.bytesRead = 0;
this.port.onmessage = async (e) => {
if (!workerPort) {
[workerPort] = e.ports;
const readable = await this.sharedWorkerFetch("1_channel.pcm");
await readable.pipeTo(
new WritableStream({
start: () => {
console.log("Start reading/writing fetch response stream", this.writes);
},
write: (value) => {
for (let i = 0; i < value.length; i++) {
this.array[this.array.length] = value[i];
}
this.bytesRead += value.length;
// We might only get 1 to 2 writes on file: protocol
++this.writes;
},
close: () => {
console.log("Stream closed", this.writes);
},
}),
);
}
};
}
async sharedWorkerFetch(url = "", options = {}) {
const { resolve, promise } = promiseWithResolvers();
const handleMessage = (e) => {
resolve(e.data);
}
if (workerPort) {
workerPort.addEventListener("message", handleMessage, {
once: true
});
workerPort.start();
workerPort.postMessage({ url, options });
}
return promise;
}
process(inputs, [[output]]) {
if (
this.bytesRead > 512 && this.array.length
) {
const data = this.array.splice(0, 512);
this.offset += data.length;
output.set(
new Float32Array(
new Uint8Array(data)
.buffer,
),
);
} else if (this.offset > 0 && this.offset === this.bytesRead) {
console.log(this.bytesRead, this.offset, this.writes, this.array);
workerPort.postMessage("close");
this.port.postMessage("Done streaming in AudioWorklet");
return false;
}
return true;
}
}
registerProcessor("audio-worklet-fetch-worker", AudioWorkletFetchWorker);