Web Worker Metronome
https://gist.github.com/nick-thompson/4551106
by Patrick Hund
JavaScript
/*!
* Metronome.js
*
* A reliable metronome using HTML5 Web Workers to maintain the tick
* interval even when the parent thread is run in the background.
*
* For details, see:
* http://pivotallabs.com/chrome-and-firefox-throttle-settimeout-setinterval-in-inactive-tabs/
*
* Copyright 2012 Nick Thompson
* MIT License
*/
(function (window, undefined) {
var msgHandler = function (e) {
if (e.data.action === "start") {
var freq = (60000 / e.data.bpm) / e.data.res;
if (e.data.reduce) { freq = freq - (freq * 0.1); }
timer = setInterval(function () {
self.postMessage({});
}, freq);
} else if (e.data.action === "stop") {
clearInterval(timer);
}
}
, inline = "" +
"self.addEventListener('message', " + msgHandler.toString() + ");";
/**
* Metronome class constructor.
*
* @param {number} bpm Beats per minute
* @param {number} res Resolution; metronome ticks per beat
*/
function Metronome (bpm, res) {
this.bpm = bpm;
this.res = res;
this.ticks = 0;
var that = this
, url = window.URL || window.webkitURL
, blob = new Blob([inline])
, blobUrl = url.createObjectURL(blob);
this.worker = new Worker(blobUrl);
this.worker.addEventListener("message", function (e) {
that.ticks++;
that.trigger("tick", that.ticks);
that.trigger(that.ticks);
});
}
/**
* Add an event listener to the Metronome.
*
* On every tick of the metrome, listeners bound to the "tick"
* event will be called with a single argument which is the number
* of times the metronome has ticked so far.
*
* Additionally, on the nth tick of the metronome, listeners bound
* to the event `n` (number) will be called.
*
* @param {string|number} e
* @param {function} listener
*/
Metronome.prototype.on = function (e, listener) {
this._events = this._events || {};
this._events[e] =...