mirror of
https://github.com/vsariola/sointu.git
synced 2025-05-27 19:00:25 -04:00
BREAKING CHANGE: The problem with crush was that it had very few usable values. This changes the crush to map the value nonlinearly, so the crush resolution is bits. Still the upper portion of the values is not very usable (bits 12-24 i.e. hardly any crushing), but at least the lower portion is usable. But now crush resolution has slightly different meaning.
96 lines
3.5 KiB
JavaScript
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 = 2e-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));
|