c@117: "use strict"; c@117: c@117: function note(blah) { c@117: document.getElementById("test-result").innerHTML += blah + "
"; c@117: } c@117: c@117: function comment(blah) { c@117: note("
" + blah + ""); c@117: } c@117: c@117: function test() { c@117: cannam@175: VampExamplePluginsModule().then(function(exampleModule) { cannam@175: cannam@175: // It is possible to declare both parameters and return values cannam@175: // as "string", in which case Emscripten will take care of cannam@175: // conversions. But it's not clear how one would manage memory cannam@175: // for newly-constructed returned C strings -- the returned cannam@175: // pointer from piperRequestJson would appear (?) to be thrown cannam@175: // away by the Emscripten string converter if we declare it as cannam@175: // returning a string, so we have no opportunity to pass it to cannam@175: // piperFreeJson, which suggests this would leak memory if the cannam@175: // string isn't static. Not wholly sure though. Anyway, cannam@175: // passing and returning pointers (as numbers) means we can cannam@175: // manage the Emscripten heap memory however we want in our cannam@175: // request wrapper function below. c@117: cannam@175: var piperRequestJson = exampleModule.cwrap( cannam@175: 'piperRequestJson', 'number', ['number'] cannam@175: ); cannam@175: cannam@175: var piperFreeJson = exampleModule.cwrap( cannam@175: 'piperFreeJson', 'void', ['number'] cannam@175: ); c@117: cannam@175: function request(jsonStr) { cannam@175: note("Request JSON = " + jsonStr); cannam@175: var m = exampleModule; cannam@175: // Inspection reveals that intArrayFromString converts the cannam@175: // string from utf16 to utf8, which is what we want cannam@175: // (though the docs don't mention this). Note the *Cstr cannam@175: // values are Emscripten heap pointers cannam@175: var inCstr = m.allocate(m.intArrayFromString(jsonStr), 'i8', m.ALLOC_NORMAL); cannam@175: var outCstr = piperRequestJson(inCstr); cannam@175: m._free(inCstr); cannam@176: var result = m.UTF8ToString(outCstr); cannam@175: piperFreeJson(outCstr); cannam@175: note("Returned JSON = " + result); cannam@175: return result; cannam@175: } c@117: cannam@175: comment("Querying plugin list..."); cannam@175: var result = request('{"method": "list"}'); c@117: cannam@175: comment("Loading zero crossings plugin..."); cannam@175: result = request('{"method":"load","params": {"key":"vamp-example-plugins:powerspectrum","inputSampleRate":16,"adapterFlags":["AdaptAllSafe"]}}'); c@117: cannam@175: comment("I'm now assuming that the load succeeded and the returned handle was 1. I haven't bothered to parse the JSON. If those assumptions are wrong, this obviously isn't going to work. Configuring the plugin..."); cannam@175: result = request('{"method":"configure","params":{"handle":1,"configuration":{"framing": { "blockSize": 8, "stepSize": 8 }, "channelCount": 1 }}}'); c@117: cannam@175: comment("If I try to configure it again, it should fail because it's already configured... but this doesn't change anything, and subsequent processing should work fine. Just an example of a failure call. NB this only works if Emscripten has exception catching enabled -- it's off by default in opt builds, which would just end the script here. Wonder what the performance penalty is like."); cannam@175: result = request('{"method":"configure","params":{"handle":1,"configuration":{"framing": { "blockSize": 8, "stepSize": 8 }, "channelCount": 1 }}}'); cannam@175: cannam@175: comment("Now processing a couple of blocks of data, on the same assumptions..."); cannam@175: result = request('{"method":"process","params":{"handle":1,"processInput":{"timestamp":{"s":0,"n":0},"inputBuffers":[[0,1,-1,0,1,-1,0,1]]}}}'); cannam@175: result = request('{"method":"process","params":{"handle":1,"processInput":{"timestamp":{"s":0,"n":500000000},"inputBuffers":[[0,1,-1,0,1,-1,0,1]]}}}'); cannam@175: cannam@175: comment("Cleaning up the plugin and getting any remaining features..."); cannam@175: result = request('{"method":"finish","params":{"handle":1}}'); cannam@175: cannam@175: comment("A process call should now fail, as the plugin has been cleaned up."); cannam@175: result = request('{"method":"process","params":{"handle":1,"processInput":{"timestamp":{"s":0,"n":1000000000},"inputBuffers":[{"values":[0,1,-1,0,1,-1,0,1]}]}}}'); cannam@175: }); c@117: } c@117: c@117: window.onload = function() { c@117: test(); c@117: }