Mercurial > hg > piper-vamp-js
view perf-test-node.js @ 34:0eafc96a039c
Add quick perf test that can be run under node instead of in-browser
author | Chris Cannam |
---|---|
date | Sun, 25 Sep 2016 09:47:56 +0100 |
parents | |
children | 3faa4e3eedac |
line wrap: on
line source
"use strict"; var VampExamplePlugins = require("./VampExamplePlugins"); var exampleModule = VampExamplePlugins(); // It is possible to declare both parameters and return values as // "string", in which case Emscripten will take care of // conversions. But it's not clear how one would manage memory for // newly-constructed returned C strings -- the returned pointer from // vampipeRequestJson would appear (?) to be thrown away by the // Emscripten string converter if we declare it as returning a string, // so we have no opportunity to pass it to vampipeFreeJson, which // suggests this would leak memory if the string isn't static. Not // wholly sure though. Anyway, passing and returning pointers (as // numbers) means we can manage the Emscripten heap memory however we // want in our request wrapper function below. var vampipeRequestJson = exampleModule.cwrap( 'vampipeRequestJson', 'number', ['number'] ); var vampipeProcessRaw = exampleModule.cwrap( "vampipeProcessRaw", "number", ["number", "number", "number", "number"] ); var vampipeFreeJson = exampleModule.cwrap( 'vampipeFreeJson', 'void', ['number'] ); function note(blah) { console.log(blah); } function comment(blah) { console.log(blah); } function processRaw(request) { const nChannels = request.processInput.inputBuffers.length; const nFrames = request.processInput.inputBuffers[0].values.length; const buffersPtr = exampleModule._malloc(nChannels * 4); const buffers = new Uint32Array( exampleModule.HEAPU8.buffer, buffersPtr, nChannels); for (let i = 0; i < nChannels; ++i) { const framesPtr = exampleModule._malloc(nFrames * 4); const frames = new Float32Array( exampleModule.HEAPU8.buffer, framesPtr, nFrames); frames.set(request.processInput.inputBuffers[i].values); buffers[i] = framesPtr; } const responseJson = vampipeProcessRaw( request.pluginHandle, buffersPtr, request.processInput.timestamp.s, request.processInput.timestamp.n); for (let i = 0; i < nChannels; ++i) { exampleModule._free(buffers[i]); } exampleModule._free(buffersPtr); const response = JSON.parse( exampleModule.Pointer_stringify(responseJson)); vampipeFreeJson(responseJson); return response; } function request(jsonStr) { note("Request JSON = " + jsonStr); var m = exampleModule; // Inspection reveals that intArrayFromString converts the string // from utf16 to utf8, which is what we want (though the docs // don't mention this). Note the *Cstr values are Emscripten heap // pointers var inCstr = m.allocate(m.intArrayFromString(jsonStr), 'i8', m.ALLOC_NORMAL); var outCstr = vampipeRequestJson(inCstr); m._free(inCstr); var result = m.Pointer_stringify(outCstr); vampipeFreeJson(outCstr); note("Returned JSON = " + result); return result; } function test() { comment("Loading zero crossings plugin..."); let result = request('{"type":"load","content": {"pluginKey":"vamp-example-plugins:zerocrossing","inputSampleRate":44100,"adapterFlags":["AdaptAllSafe"]}}'); const blockSize = 1024; result = request('{"type":"configure","content":{"pluginHandle":1,"configuration":{"blockSize": ' + blockSize + ', "channelCount": 1, "stepSize": ' + blockSize + '}}}'); const nblocks = 1000; let processInputBuffers = [new Float32Array( Array.from(Array(blockSize).keys(), n => n / blockSize)) ]; comment("Now processing " + nblocks + " blocks of 1024 samples each..."); let start = (new Date()).getTime(); comment("Start at " + start); for (let i = 0; i < nblocks; ++i) { let ts = { "s": i, "n": 0 }; // wholly bogus, but ZC plugin doesn't use it result = processRaw({ "pluginHandle": 1, "processInput": { "timestamp": ts, "inputBuffers": processInputBuffers } }); } let finish = (new Date()).getTime(); comment("Finish at " + finish + " for a time of " + (finish - start) + " ms"); comment("Again..."); start = (new Date()).getTime(); comment("Start at " + start); for (let i = 0; i < nblocks; ++i) { let ts = { "s": i, "n": 0 }; // wholly bogus, but ZC plugin doesn't use it result = processRaw({ "pluginHandle": 1, "processInput": { "timestamp": ts, "inputBuffers": processInputBuffers } }); } finish = (new Date()).getTime(); comment("Finish at " + finish + " for a time of " + (finish - start) + " ms"); comment("Cleaning up the plugin and getting any remaining features..."); result = request('{"type":"finish","content":{"pluginHandle":1}}'); } test();