// from https://developer.mozilla.org/en-US/docs/Web/API/AudioWorkletNode function create_thread(func) { } class AudioThread extends AudioWorkletProcessor { constructor(...args) { super(...args); const self = this; this.port.onmessageerror = (e) => { console.error('Error', e); }; this.port.onmessage = (e) => { console.log('Audio onmessage'); const mod = e.data.mod; const memory = e.data.memory; const importObject = { env: { memory }, imports: { imported_func: arg => console.log('thread: ' + arg), create_thread } }; WebAssembly.instantiate(mod, importObject).then((instance) => { console.log('Running audio thread'); self.audio_func = instance.exports.audio_func; self.audio_pointer = instance.exports.malloc(16 * 1024); console.log('Audio pointer: ' + self.audio_pointer); console.log('Memory byteLength: ' + memory.buffer.byteLength); self.audio_data = new Float32Array( memory.buffer, self.audio_pointer, 16 * 256 ); }); }; } process(inputs, outputs, parameters) { const output = outputs[0]; const data = output[0]; //for (let i = 0; i < data.length; ++i) { // data[i] = Math.random() * 2 - 1; //} if (this.audio_func) { let offset = 0; for (;;) { const length = Math.min(data.length - offset, this.audio_data.length); this.audio_func(this.audio_pointer + offset, length); for (let i = 0; i < length; ++i) { data[offset + i] = this.audio_data[i]; } if (offset + this.audio_data.length >= data.length) { break; } offset += this.audio_data.length; } } return true; } } registerProcessor('audio-thread', AudioThread);