'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));