diff options
author | Justin Worthe <justin@worthe-it.co.za> | 2017-11-09 20:18:35 +0200 |
---|---|---|
committer | Justin Worthe <justin@worthe-it.co.za> | 2017-11-09 20:18:35 +0200 |
commit | b3f8d2eb9866dc8b4e56e3593b64dae2b313957f (patch) | |
tree | 783aa9fd4f5c2aa41dd2d2940edb81da0fd53d95 /web | |
parent | bb980395891d50845f3f3ce3848ea321f5dc9558 (diff) |
Added docs to the complex parts of the rusty microphone javascript
Also refactored some stuff
Diffstat (limited to 'web')
-rw-r--r-- | web/index.html | 16 | ||||
-rw-r--r-- | web/main.js | 54 |
2 files changed, 55 insertions, 15 deletions
diff --git a/web/index.html b/web/index.html index ffd1f9a..f705aaa 100644 --- a/web/index.html +++ b/web/index.html @@ -5,8 +5,20 @@ <link rel="stylesheet" href="style.css"> </head> <body> + <p> + This is a demo for the web build of Rusty Microphone using + Emscripten. It requires a browser that supports WebAssembly + and the Web Audio API. There may still be some rough edges + that need to be refined. If it does not appear to be working, + please make sure that you are using the latest version of your + web browser, since these technologies are still relatively + new. + </p> + + <h1>Rusty Microphone</h1> <div id="rusty-microphone"> - <p>The current note being played is <span id="pitch-label"></span></p> + + <p>The current note being played is <span id="pitch-label">unknown</span></p> <div id="pitch-indicator-bar-container"> <div id="pitch-indicator-bar"></div> </div> @@ -17,7 +29,7 @@ <canvas id="oscilloscope" width="320" height="300"></canvas> - <p>The current framerate is <span id="frame-rate"></span>FPS</p> + <p>The current framerate is <span id="frame-rate">_</span>FPS</p> </div> </body> </html> diff --git a/web/main.js b/web/main.js index 56aec33..ddd39c0 100644 --- a/web/main.js +++ b/web/main.js @@ -5,6 +5,19 @@ var Module = { onRuntimeInitialized: main }; +/** + * Puts at javascript float array onto the heap and provides a pointer + * + * Webassembly's input types are limited to integers and floating + * point numbers. You can get around this limitation by putting the + * data you want (a f32 array in this case) onto the heap, and passing + * Webassembly a pointer and length. A callback is used for the actual + * Webassembly call so that the heap memory can be automatically freed + * afterwards. + * + * @param {array} jsArray - A javascript array, or Float32Array, of numbers + * @param {function} callback - The function to call with a pointer and length of the array + */ function jsArrayToF32ArrayPtr(jsArray, callback) { var data = (jsArray instanceof Float32Array) ? jsArray : new Float32Array(jsArray); var nDataBytes = data.length * data.BYTES_PER_ELEMENT; @@ -20,6 +33,21 @@ function jsArrayToF32ArrayPtr(jsArray, callback) { return result; } +/** + * Puts at javascript float array onto the heap and provides a pointer, for functions that mutate the array in place + * + * Webassembly's input types are limited to integers and floating + * point numbers. You can get around this limitation by putting the + * data you want (a f32 array in this case) onto the heap, and passing + * Webassembly a pointer and length. In this case, we also want to + * return an array of the same lenght, so our Webassembly function + * mutates the input array in place. A callback is used for the actual + * Webassembly call so that the heap memory can be automatically freed + * afterwards. + * + * @param {array} jsArray - A javascript array, or Float32Array, of numbers + * @param {function} callback - The function to call with a pointer and length of the array + */ function jsArrayToF32ArrayPtrMutateInPlace(jsArray, mutate) { var data = new Float32Array(jsArray); var nDataBytes = data.length * data.BYTES_PER_ELEMENT; @@ -47,16 +75,21 @@ function findFundamentalFrequency(data, samplingRate) { var nDataBytes = null; var dataPtr = null; var dataHeap = null; +/** + * Does the same thing as findFundamentalFrequency, except + * 1. assumes the array is already a Float32Array + * 2. assumes that the array will always be the same length of subsequent calls + * 3. does not free the allocated memory on the heap + * 4. reuses the allocated heap memory on subsequent calls + */ function findFundamentalFrequencyNoFree(data, samplingRate) { - var length = Math.min(data.length, 512); - //assume data is already a Float32Array and its length won't change from call to call if (!dataPtr) { - nDataBytes = length * data.BYTES_PER_ELEMENT; + nDataBytes = data.length * data.BYTES_PER_ELEMENT; dataPtr = Module._malloc(nDataBytes); dataHeap = new Uint8Array(Module.HEAPU8.buffer, dataPtr, nDataBytes); } dataHeap.set(new Uint8Array(data.buffer, data.buffer.byteLength - nDataBytes)); - return Module._find_fundamental_frequency(dataPtr, length, samplingRate); + return Module._find_fundamental_frequency(dataPtr, data.length, samplingRate); } @@ -142,10 +175,8 @@ function initView() { } function drawDebugGraph(signal) { - // This draw example is currently heavily based on an example - // from MDN: + // This draw function is heavily based on an example from MDN: // https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode - var bufferLength = Math.min(signal.length, 512); canvasCtx.fillStyle = 'rgb(200, 200, 200)'; canvasCtx.fillRect(0, 0, canvas.width, canvas.height); @@ -155,19 +186,15 @@ function initView() { canvasCtx.beginPath(); - var sliceWidth = canvas.width * 1.0 / bufferLength; - var x = 0; - - for (var i = 0; i < bufferLength; i++) { + for (var i = 0; i < signal.length; i++) { var y = (signal[i] * canvas.height / 2) + canvas.height / 2; + var x = i * canvas.width / signal.length; if (i === 0) { canvasCtx.moveTo(x, y); } else { canvasCtx.lineTo(x, y); } - - x += sliceWidth; } canvasCtx.stroke(); @@ -185,6 +212,7 @@ function main() { var context = new window.AudioContext(); var input = context.createMediaStreamSource(stream); var analyser = context.createAnalyser(); + analyser.fftSize = 512; input.connect(analyser); var view = initView(); |