89 lines
2.3 KiB
JavaScript
89 lines
2.3 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
// Dedicated audio output thread
|
||
|
class AudioThread extends AudioWorkletProcessor {
|
||
|
|
||
|
///////////////////////// Initialization Methods //////////////////////////
|
||
|
|
||
|
constructor() {
|
||
|
super();
|
||
|
|
||
|
// Configure instance fields
|
||
|
this.buffers = []; // Input sample buffer queue
|
||
|
this.offset = 0; // Offset into oldest buffer
|
||
|
|
||
|
// Wait for initializer message from parent thread
|
||
|
this.port.onmessage = m=>this.init(m.data);
|
||
|
}
|
||
|
|
||
|
async init(main) {
|
||
|
|
||
|
// Configure message ports
|
||
|
this.core = this.port;
|
||
|
this.core.onmessage = m=>this.onCore(m.data);
|
||
|
this.main = main;
|
||
|
this.main.onmessage = m=>this.onMain(m.data);
|
||
|
|
||
|
// Notify main thread
|
||
|
this.port.postMessage(0);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////// Public Methods //////////////////////////////
|
||
|
|
||
|
// Produce output samples (called by the user agent)
|
||
|
process(inputs, outputs, parameters) {
|
||
|
let output = outputs[0];
|
||
|
let length = output [0].length;
|
||
|
let empty = null;
|
||
|
|
||
|
// Process all samples
|
||
|
for (let x = 0; x < length;) {
|
||
|
|
||
|
// No bufferfed samples are available
|
||
|
if (this.buffers.length == 0) {
|
||
|
for (; x < length; x++)
|
||
|
output[0] = output[1] = 0;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Transfer samples from the oldest buffer
|
||
|
let y, buffer = this.buffers[0];
|
||
|
for (y = this.offset; x < length && y < buffer.length; x++, y+=2) {
|
||
|
output[0][x] = buffer[y ];
|
||
|
output[1][x] = buffer[y + 1];
|
||
|
}
|
||
|
|
||
|
// Advance to the next buffer
|
||
|
if ((this.offset = y) == buffer.length) {
|
||
|
if (empty == null)
|
||
|
empty = [];
|
||
|
empty.push(this.buffers.shift());
|
||
|
this.offset = 0;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// Return emptied sample buffers to the core thread
|
||
|
if (empty != null)
|
||
|
this.core.postMessage(empty, empty.map(e=>e.buffer));
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////// Message Methods /////////////////////////////
|
||
|
|
||
|
// Message received from core thread
|
||
|
onCore(msg) {
|
||
|
}
|
||
|
|
||
|
// Message received from main thread
|
||
|
onMain(msg) {
|
||
|
}
|
||
|
|
||
|
}
|
||
|
registerProcessor("AudioThread", AudioThread);
|