c@102
|
1 "use strict";
|
c@102
|
2
|
c@102
|
3 var exampleModule = VampExamplePluginsModule();
|
c@102
|
4
|
c@102
|
5 // It is possible to declare both parameters and return values as
|
c@102
|
6 // "string", in which case Emscripten will take care of
|
c@102
|
7 // conversions. But it's not clear how one would manage memory for
|
c@102
|
8 // newly-constructed returned C strings -- the returned pointer from
|
c@102
|
9 // vampipeRequestJson would appear (?) to be thrown away by the
|
c@102
|
10 // Emscripten string converter if we declare it as returning a string,
|
c@102
|
11 // so we have no opportunity to pass it to vampipeFreeJson, which
|
c@102
|
12 // suggests this would leak memory if the string isn't static. Not
|
c@102
|
13 // wholly sure though. Anyway, passing and returning pointers (as
|
c@102
|
14 // numbers) means we can manage the Emscripten heap memory however we
|
c@102
|
15 // want in our request wrapper function below.
|
c@102
|
16
|
c@102
|
17 var vampipeRequestJson = exampleModule.cwrap(
|
c@102
|
18 'vampipeRequestJson', 'number', ['number']
|
c@102
|
19 );
|
c@102
|
20
|
c@102
|
21 var vampipeProcessRaw = exampleModule.cwrap(
|
c@102
|
22 "vampipeProcessRaw", "number", ["number", "number", "number", "number"]
|
c@102
|
23 );
|
c@102
|
24
|
c@102
|
25 var vampipeFreeJson = exampleModule.cwrap(
|
c@102
|
26 'vampipeFreeJson', 'void', ['number']
|
c@102
|
27 );
|
c@102
|
28
|
c@102
|
29 function note(blah) {
|
c@102
|
30 document.getElementById("test-result").innerHTML += blah + "<br>";
|
c@102
|
31 }
|
c@102
|
32
|
c@102
|
33 function comment(blah) {
|
c@102
|
34 note("<br><i>" + blah + "</i>");
|
c@102
|
35 }
|
c@102
|
36
|
c@102
|
37 function processRaw(request) {
|
c@102
|
38
|
c@102
|
39 const nChannels = request.processInput.inputBuffers.length;
|
c@102
|
40 const nFrames = request.processInput.inputBuffers[0].values.length;
|
c@102
|
41
|
c@102
|
42 const buffersPtr = exampleModule._malloc(nChannels * 4);
|
c@102
|
43 const buffers = new Uint32Array(
|
c@102
|
44 exampleModule.HEAPU8.buffer, buffersPtr, nChannels);
|
c@102
|
45
|
c@102
|
46 for (let i = 0; i < nChannels; ++i) {
|
c@102
|
47 const framesPtr = exampleModule._malloc(nFrames * 4);
|
c@102
|
48 const frames = new Float32Array(
|
c@102
|
49 exampleModule.HEAPU8.buffer, framesPtr, nFrames);
|
c@102
|
50 frames.set(request.processInput.inputBuffers[i].values);
|
c@102
|
51 buffers[i] = framesPtr;
|
c@102
|
52 }
|
c@102
|
53
|
c@102
|
54 const responseJson = vampipeProcessRaw(
|
c@102
|
55 request.pluginHandle,
|
c@102
|
56 buffersPtr,
|
c@102
|
57 request.processInput.timestamp.s,
|
c@102
|
58 request.processInput.timestamp.n);
|
c@102
|
59
|
c@102
|
60 for (let i = 0; i < nChannels; ++i) {
|
c@102
|
61 exampleModule._free(buffers[i]);
|
c@102
|
62 }
|
c@102
|
63 exampleModule._free(buffersPtr);
|
c@102
|
64
|
c@102
|
65 const response = JSON.parse(
|
c@102
|
66 exampleModule.Pointer_stringify(responseJson));
|
c@102
|
67
|
c@102
|
68 vampipeFreeJson(responseJson);
|
c@102
|
69
|
c@102
|
70 return response;
|
c@102
|
71 }
|
c@102
|
72
|
c@102
|
73 function request(jsonStr) {
|
c@102
|
74 note("Request JSON = " + jsonStr);
|
c@102
|
75 var m = exampleModule;
|
c@102
|
76 // Inspection reveals that intArrayFromString converts the string
|
c@102
|
77 // from utf16 to utf8, which is what we want (though the docs
|
c@102
|
78 // don't mention this). Note the *Cstr values are Emscripten heap
|
c@102
|
79 // pointers
|
c@102
|
80 var inCstr = m.allocate(m.intArrayFromString(jsonStr), 'i8', m.ALLOC_NORMAL);
|
c@102
|
81 var outCstr = vampipeRequestJson(inCstr);
|
c@102
|
82 m._free(inCstr);
|
c@102
|
83 var result = m.Pointer_stringify(outCstr);
|
c@102
|
84 vampipeFreeJson(outCstr);
|
c@102
|
85 note("Returned JSON = " + result);
|
c@102
|
86 return result;
|
c@102
|
87 }
|
c@102
|
88
|
c@102
|
89 function test() {
|
c@102
|
90
|
c@102
|
91 comment("Loading zero crossings plugin...");
|
c@102
|
92 let result = request('{"type":"load","content": {"pluginKey":"vamp-example-plugins:zerocrossing","inputSampleRate":44100,"adapterFlags":["AdaptAllSafe"]}}');
|
c@102
|
93
|
c@102
|
94 const blockSize = 1024;
|
c@102
|
95
|
c@102
|
96 result = request('{"type":"configure","content":{"pluginHandle":1,"configuration":{"blockSize": ' + blockSize + ', "channelCount": 1, "stepSize": ' + blockSize + '}}}');
|
c@102
|
97
|
c@102
|
98 const nblocks = 1000;
|
c@102
|
99
|
c@102
|
100 let processInputBuffers = [new Float32Array(
|
c@102
|
101 Array.from(Array(blockSize).keys(), n => n / blockSize))
|
c@102
|
102 ];
|
c@102
|
103
|
c@102
|
104 comment("Now processing " + nblocks + " blocks of 1024 samples each...");
|
c@102
|
105
|
c@102
|
106 let start = (new Date()).getTime();
|
c@102
|
107 comment("Start at " + start);
|
c@102
|
108
|
c@102
|
109 for (let i = 0; i < nblocks; ++i) {
|
c@102
|
110 let ts = { "s": i, "n": 0 }; // wholly bogus, but ZC plugin doesn't use it
|
c@102
|
111 result = processRaw({
|
c@102
|
112 "pluginHandle": 1,
|
c@102
|
113 "processInput": {
|
c@102
|
114 "timestamp": ts,
|
c@102
|
115 "inputBuffers": processInputBuffers
|
c@102
|
116 }
|
c@102
|
117 });
|
c@102
|
118 }
|
c@102
|
119
|
c@102
|
120 let finish = (new Date()).getTime();
|
c@102
|
121 comment("Finish at " + finish + " for a time of " + (finish - start) + " ms");
|
c@102
|
122
|
c@102
|
123 comment("Again...");
|
c@102
|
124
|
c@102
|
125 start = (new Date()).getTime();
|
c@102
|
126 comment("Start at " + start);
|
c@102
|
127
|
c@102
|
128 for (let i = 0; i < nblocks; ++i) {
|
c@102
|
129 let ts = { "s": i, "n": 0 }; // wholly bogus, but ZC plugin doesn't use it
|
c@102
|
130 result = processRaw({
|
c@102
|
131 "pluginHandle": 1,
|
c@102
|
132 "processInput": {
|
c@102
|
133 "timestamp": ts,
|
c@102
|
134 "inputBuffers": processInputBuffers
|
c@102
|
135 }
|
c@102
|
136 });
|
c@102
|
137 }
|
c@102
|
138
|
c@102
|
139 finish = (new Date()).getTime();
|
c@102
|
140 comment("Finish at " + finish + " for a time of " + (finish - start) + " ms");
|
c@102
|
141
|
c@102
|
142 comment("Cleaning up the plugin and getting any remaining features...");
|
c@102
|
143 result = request('{"type":"finish","content":{"pluginHandle":1}}');
|
c@102
|
144 }
|
c@102
|
145
|
c@102
|
146 window.onload = function() {
|
c@102
|
147 test();
|
c@102
|
148 }
|