Chris@4: "use strict"; Chris@4: Chris@28: var exampleModule = VampExamplePluginsModule(); Chris@4: Chris@4: // It is possible to declare both parameters and return values as Chris@4: // "string", in which case Emscripten will take care of Chris@4: // conversions. But it's not clear how one would manage memory for Chris@4: // newly-constructed returned C strings -- the returned pointer from Chris@43: // piperRequestJson would appear (?) to be thrown away by the Chris@4: // Emscripten string converter if we declare it as returning a string, Chris@43: // so we have no opportunity to pass it to piperFreeJson, which Chris@4: // suggests this would leak memory if the string isn't static. Not Chris@4: // wholly sure though. Anyway, passing and returning pointers (as Chris@4: // numbers) means we can manage the Emscripten heap memory however we Chris@4: // want in our request wrapper function below. Chris@4: Chris@43: var piperRequestJson = exampleModule.cwrap( Chris@43: 'piperRequestJson', 'number', ['number'] Chris@4: ); Chris@4: Chris@43: var piperFreeJson = exampleModule.cwrap( Chris@43: 'piperFreeJson', 'void', ['number'] Chris@4: ); Chris@4: Chris@6: function note(blah) { Chris@6: document.getElementById("test-result").innerHTML += blah + "
"; Chris@6: } Chris@6: Chris@6: function comment(blah) { Chris@6: note("
" + blah + ""); Chris@6: } Chris@6: Chris@4: function request(jsonStr) { Chris@6: note("Request JSON = " + jsonStr); Chris@4: var m = exampleModule; Chris@4: // Inspection reveals that intArrayFromString converts the string Chris@4: // from utf16 to utf8, which is what we want (though the docs Chris@4: // don't mention this). Note the *Cstr values are Emscripten heap Chris@4: // pointers Chris@4: var inCstr = m.allocate(m.intArrayFromString(jsonStr), 'i8', m.ALLOC_NORMAL); Chris@43: var outCstr = piperRequestJson(inCstr); Chris@4: m._free(inCstr); Chris@4: var result = m.Pointer_stringify(outCstr); Chris@43: piperFreeJson(outCstr); Chris@6: note("Returned JSON = " + result); Chris@4: return result; Chris@4: } Chris@4: Chris@4: function test() { Chris@4: Chris@6: comment("Querying plugin list..."); Chris@40: var result = request('{"method": "list"}'); Chris@4: Chris@6: comment("Loading zero crossings plugin..."); Chris@40: result = request('{"method":"load","params": {"key":"vamp-example-plugins:powerspectrum","inputSampleRate":16,"adapterFlags":["AdaptAllSafe"]}}'); Chris@4: Chris@40: 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..."); Chris@40: result = request('{"method":"configure","params":{"handle":1,"configuration":{"blockSize": 8, "channelCount": 1, "stepSize": 8}}}'); Chris@4: Chris@6: 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."); Chris@40: result = request('{"method":"configure","params":{"handle":1,"configuration":{"blockSize": 8, "channelCount": 1, "stepSize": 8}}}'); Chris@4: Chris@6: comment("Now processing a couple of blocks of data, on the same assumptions..."); Chris@40: result = request('{"method":"process","params":{"handle":1,"processInput":{"timestamp":{"s":0,"n":0},"inputBuffers":[[0,1,-1,0,1,-1,0,1]]}}}'); Chris@40: result = request('{"method":"process","params":{"handle":1,"processInput":{"timestamp":{"s":0,"n":500000000},"inputBuffers":[[0,1,-1,0,1,-1,0,1]]}}}'); Chris@4: Chris@6: comment("Cleaning up the plugin and getting any remaining features..."); Chris@40: result = request('{"method":"finish","params":{"handle":1}}'); Chris@4: Chris@6: comment("A process call should now fail, as the plugin has been cleaned up."); Chris@40: result = request('{"method":"process","params":{"handle":1,"processInput":{"timestamp":{"s":0,"n":1000000000},"inputBuffers":[{"values":[0,1,-1,0,1,-1,0,1]}]}}}'); Chris@4: } Chris@4: Chris@4: window.onload = function() { Chris@4: test(); Chris@4: }