mirror of
https://github.com/exoticorn/microw8.git
synced 2026-01-20 11:16:42 +01:00
94 lines
2.8 KiB
JavaScript
94 lines
2.8 KiB
JavaScript
let U8 = (...a) => new Uint8Array(...a);
|
|
class APU extends AudioWorkletProcessor {
|
|
constructor() {
|
|
super();
|
|
this.sampleIndex = 0;
|
|
this.currentTime = 0;
|
|
this.isFirstMessage = true;
|
|
this.pendingUpdates = [];
|
|
this.port.onmessage = (ev) => {
|
|
if(this.memory) {
|
|
if(this.isFirstMessage)
|
|
{
|
|
this.currentTime += (ev.data.t - this.currentTime) / 8;
|
|
this.isFirstMessage = false;
|
|
}
|
|
this.pendingUpdates.push(ev.data);
|
|
} else {
|
|
this.load(ev.data[0], ev.data[1]);
|
|
}
|
|
};
|
|
}
|
|
|
|
async load(platform_data, data) {
|
|
let memory = new WebAssembly.Memory({ initial: 4, maximum: 4 });
|
|
|
|
let importObject = {
|
|
env: {
|
|
memory
|
|
},
|
|
};
|
|
|
|
for (let n of ['acos', 'asin', 'atan', 'atan2', 'cos', 'exp', 'log', 'sin', 'tan', 'pow']) {
|
|
importObject.env[n] = Math[n];
|
|
}
|
|
|
|
for (let i = 9; i < 64; ++i) {
|
|
importObject.env['reserved' + i] = () => { };
|
|
}
|
|
|
|
let logLine = '';
|
|
importObject.env['logChar'] = (c) => {
|
|
if(c == 10) {
|
|
console.log(logLine);
|
|
logLine = '';
|
|
} else {
|
|
logLine += String.fromCharCode(c);
|
|
}
|
|
};
|
|
|
|
for (let i = 0; i < 16; ++i) {
|
|
importObject.env['g_reserved' + i] = 0;
|
|
}
|
|
|
|
let instantiate = async (data) => (await WebAssembly.instantiate(data, importObject)).instance;
|
|
|
|
let platform_instance = await instantiate(platform_data);
|
|
|
|
for (let name in platform_instance.exports) {
|
|
importObject.env[name] = platform_instance.exports[name]
|
|
}
|
|
|
|
let instance = await instantiate(data);
|
|
|
|
this.memory = memory;
|
|
|
|
this.snd = instance.exports.snd || platform_instance.exports.gesSnd;
|
|
|
|
this.port.postMessage(2);
|
|
}
|
|
|
|
process(inputs, outputs, parameters) {
|
|
this.isFirstMessage = true;
|
|
if(this.snd) {
|
|
while(this.pendingUpdates.length > 0 && this.pendingUpdates[0].t <= this.currentTime) {
|
|
U8(this.memory.buffer, 80, 32).set(U8(this.pendingUpdates.shift().r));
|
|
}
|
|
let u32Mem = new Uint32Array(this.memory.buffer);
|
|
u32Mem[16] = this.currentTime;
|
|
let channels = outputs[0];
|
|
let index = this.sampleIndex;
|
|
let numSamples = channels[0].length;
|
|
for(let i = 0; i < numSamples; ++i) {
|
|
channels[0][i] = this.snd(index++);
|
|
channels[1][i] = this.snd(index++);
|
|
}
|
|
this.sampleIndex = index & 0xffffffff;
|
|
this.currentTime += numSamples / 44.1;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
registerProcessor('apu', APU); |