sointu/tests/wasm_test_renderer.js
Peter Salomonsen 5120495cb8 run wasm tests
2023-04-06 12:13:15 +00:00

96 lines
3.5 KiB
JavaScript

'use strict';
const fs = require('fs');
const path = require('path');
const { exit } = require('process');
if (process.argv.length <= 3) {
console.log("Usage: wasm_test_renderer.es6 path/to/compiled_wasm_song.wasm path/to/expected_output.raw")
console.log("The test renderer needs to know the location and length of the output buffer in wasm memory; remember to sointu-compile the .wat with TBW")
exit(2)
}
(async () => {
var file,wasm,instance
try {
file = fs.readFileSync(process.argv[2])
} catch (err) {
console.error("could not read wasmfile "+process.argv[2]+": "+err);
return 1
}
try {
wasm = await WebAssembly.compile(file);
} catch (err) {
console.error("could not compile wasmfile "+process.argv[2]+": "+err);
return 1
}
try {
instance = await WebAssembly.instantiate(wasm,{m:Math});
} catch (err) {
console.error("could not instantiate wasmfile "+process.argv[2]+": "+err);
return 1
}
let gotBuffer = instance.exports.t.value ?
new Int16Array(instance.exports.m.buffer,instance.exports.s.value,instance.exports.l.value/2) :
new Float32Array(instance.exports.m.buffer,instance.exports.s.value,instance.exports.l.value/4);
const gotFileName = path.join(path.parse(process.argv[2]).dir,"wasm_got_" + path.parse(process.argv[3]).name+".raw");
try {
const gotByteBuffer = Buffer.from(instance.exports.m.buffer,instance.exports.s.value,instance.exports.l.value);
fs.writeFileSync(gotFileName, gotByteBuffer);
} catch (err) {
console.error("could not save the buffer we got to disk "+gotFileName+": "+err);
return 1
}
const expectedFile = fs.readFileSync(process.argv[3]);
let expectedBuffer = instance.exports.t.value ?
new Int16Array(expectedFile.buffer, expectedFile.offset, expectedFile.byteLength/2) :
new Float32Array(expectedFile.buffer, expectedFile.offset, expectedFile.byteLength/4);
if (gotBuffer.length < expectedBuffer.length)
{
console.error("got shorter buffer than expected");
return 1
}
if (gotBuffer.length > expectedBuffer.length)
{
console.error("got longer buffer than expected");
return 1
}
let margin = 1e-2 * (instance.exports.t.value ? 32767 : 1);
var firstError = true, firstErrorPos, errorCount = 0
// we still have occasional sample wrong here or there. We only consider this a true error
// if the total number of errors is too high
for (var i = 2; i < gotBuffer.length-2; i++) {
// Pulse oscillators with their sharp changes can sometimes be one sample late
// due to rounding errors, causing the test fail. So, we test three samples
// and if none match, then this sample is really wrong. Note that this is stereo
// buffer so -2 index is the previous sample.
// Also, we're pretty liberal on the accuracy, as small rounding errors
// in frequency cause tests fails as the waves developed a phase shift over time
// (or rounding errors in delay buffers etc.)
if (Math.abs(gotBuffer[i] - expectedBuffer[i-2]) > margin &&
Math.abs(gotBuffer[i] - expectedBuffer[i]) > margin &&
Math.abs(gotBuffer[i] - expectedBuffer[i+2]) > margin) {
if (firstError) {
firstErrorPos = i
firstError = false
}
errorCount++
}
if (errorCount > 200) {
console.error("got different buffer than expected. First error at: "+(firstErrorPos/2|0)+(firstErrorPos%1," right"," left"));
return 1;
}
}
return 0;
})().then(retval => exit(retval));