Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Web Workers: A musical intro

Web Workers: A musical intro

Ritesh Kumar

August 22, 2018
Tweet

More Decks by Ritesh Kumar

Other Decks in Programming

Transcript

  1. • Language syntax • Built-in objects and functions • Global

    objects • Prototype based inheritance system • Error handling mechanisms • document • requestIdleCallback • requestAnimationFrame • setTimeout • setInterval • Promises • And many more Web APIs Core JavaScript
  2. import { parse } from “midiconvert"; const file = new

    FileReader(); file.onload = () !=> { !// heavy computation const parsedMidi = parse(file.result); };
  3. import { parse } from “midiconvert"; const file = new

    FileReader(); file.onload = () !=> { !// heavy computation const parsedMidi = parse(file.result); }; File loading + Parsing
  4. Web Workers is a simple means for web content to

    run scripts in background threads.
  5. !// main.js const myWorker = new Worker('worker.js'); myWorker.postMessage("sending data to

    worker"); myWorker.onmessage = function(e) { console.log('Message received from worker'); } Spawn a worker
  6. !// main.js const myWorker = new Worker('worker.js'); myWorker.postMessage("sending data to

    worker"); myWorker.onmessage = function(e) { console.log('Message received from worker'); } Send message to worker
  7. !// worker.js onmessage = function(e) { console.log('Message received from main

    script'); var workerResult = 'Result: ' + (e.data); console.log('Posting message back to main script'); postMessage(workerResult); } Receive message in worker
  8. !// worker.js onmessage = function(e) { console.log('Message received from main

    script'); var workerResult = 'Result: ' + (e.data); console.log('Posting message back to main script'); postMessage(workerResult); } Send message to the main script
  9. Receive message from worker !// main.js const myWorker = new

    Worker('worker.js'); myWorker.postMessage("sending data to worker"); myWorker.onmessage = function(e) { console.log('Message received from worker'); }
  10. !// This is possible due to the usage of worker-loader

    in webpack. !// You can't do this without that. Only importScripts works. import { parse } from “midiconvert"; const file = new FileReader(); file.onload = () !=> { !// heavy computation const parsedMidi = parse(file.result); self.postMessage({ data: parsedMidi }); }; self.onmessage = e !=> { file.readAsArrayBuffer(e.data); };
  11. Playing Music = Scheduling Notes + Playing those notes WebAudio

    API. Audio plays in different thread by default.
  12. Challenges in scheduling notes. • Minimum time precision in JS

    clock is of 1ms. • The JS timers (setTimeout, setInterval) call can be delayed if the thread is blocked.
  13. • Minimum time precision in JS clock is of 1ms.

    - a combination of setTimeout and audio hardware scheduling. • The JS timers (setTimeout, setInterval) call can be delayed if the thread is blocked. (workers) Challenges in scheduling notes.
  14. Playing Music = Scheduling Notes + Playing those notes WebAudio

    API. Audio plays in different thread by default. WebAudio API’s time + setTimeOut + Web Workers
  15. Main thread const canvasWorker = new Worker("./canvas-worker"); const offscreenCanvas =

    document .getElementById(“canvas”) .transferControlToOffscreen(); canvasWorker.postMessage(offscreenCanvas, [offscreenCanvas]);
  16. Main thread What’s this ? const canvasWorker = new Worker("./canvas-worker");

    const offscreenCanvas = document .getElementById(“canvas”) .transferControlToOffscreen(); canvasWorker.postMessage(offscreenCanvas, [offscreenCanvas]);
  17. Main thread The main thread has tranferred this “transferable” to

    worker and has no control over it anymore. const canvasWorker = new Worker("./canvas-worker"); const offscreenCanvas = document .getElementById(“canvas”) .transferControlToOffscreen(); canvasWorker.postMessage(offscreenCanvas, [offscreenCanvas]);
  18. In worker thread, we get the canvas. import { Visualizer

    } from "@utils/Visualizer"; self.onmessage = e !=> { const canvas = e.data; const visualizer = new Visualizer(canvas); };
  19. Write Mode • Play using 128 sounds. • Record. •

    Save MIDI. • Connect a keyboard/Piano.