diff --git a/README.md b/README.md index 83482ab..236736e 100644 --- a/README.md +++ b/README.md @@ -58,14 +58,12 @@ speech.on('speaking', function() { * `stopped_speaking` emitted when the audio doesn't seem to be speaking * `volume_change` emitted on every poll event by the event emitter with the current volume (in decibels) and the current threshold for speech * The hark object also has the following methods to update the config of hark. Both of these options can be passed in on instantiation, but you may wish to alter them either for debug or fine tuning as your app runs. - * `setInterval(interval_in_ms)` change * `setThreshold(threshold_in_db)` change the minimum volume at which the audio will emit a `speaking` event * hark can be stopped by calling this method * `stop()` will stop the polling and events will not be emitted. ## Options -* `interval` (optional, default 100ms) how frequently the analyser polls the audio stream to check if speaking has started or stopped. This will also be the frequency of the `volume_change` events. * `threshold` (optional, default -50db) the volume at which `speaking`/`stopped\_speaking` events will be fired * `play` (optional, default true for audio tags, false for webrtc streams) whether the audio stream should also be piped to the speakers, or just swallowed by the analyser. Typically for audio tags you would want to hear them, but for microphone based webrtc streams you may not to avoid feedback. diff --git a/example/demo.bundle.js b/example/demo.bundle.js index 0958b58..bf9fcfa 100644 --- a/example/demo.bundle.js +++ b/example/demo.bundle.js @@ -232,11 +232,10 @@ module.exports = function(stream, options) { //Config var options = options || {}, smoothing = (options.smoothing || 0.1), - interval = (options.interval || 50), threshold = options.threshold, play = options.play, history = options.history || 10, - running = true; + timer; //Setup Audio Context if (!audioContext) { @@ -270,12 +269,8 @@ module.exports = function(stream, options) { threshold = t; }; - harker.setInterval = function(i) { - interval = i; - }; - harker.stop = function() { - running = false; + cancelAnimationFrame(timer); harker.emit('volume_change', -100, threshold); if (harker.speaking) { harker.speaking = false; @@ -289,47 +284,37 @@ module.exports = function(stream, options) { harker.speakingHistory.push(0); } - // Poll the analyser node to determine if speaking - // and emit events if changed - var looper = function() { - setTimeout(function() { - - //check if stop has been called - if(!running) { - return; - } - - var currentVolume = getMaxVolume(analyser, fftBins); + function checkVolume() { + var currentVolume = getMaxVolume(analyser, fftBins); - harker.emit('volume_change', currentVolume, threshold); + harker.emit('volume_change', currentVolume, threshold); - var history = 0; - if (currentVolume > threshold && !harker.speaking) { - // trigger quickly, short history - for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history >= 2) { - harker.speaking = true; - harker.emit('speaking'); - } - } else if (currentVolume < threshold && harker.speaking) { - for (var i = 0; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history == 0) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } + var history = 0; + if (currentVolume > threshold && !harker.speaking) { + // trigger quickly, short history + for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history >= 2) { + harker.speaking = true; + harker.emit('speaking'); + } + } else if (currentVolume < threshold && harker.speaking) { + for (var i = 0; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; } - harker.speakingHistory.shift(); - harker.speakingHistory.push(0 + (currentVolume > threshold)); + if (history == 0) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + } + harker.speakingHistory.shift(); + harker.speakingHistory.push(0 + (currentVolume > threshold)); - looper(); - }, interval); - }; - looper(); + timer = requestAnimationFrame(checkVolume); + } + checkVolume(); return harker; } diff --git a/hark.bundle.js b/hark.bundle.js index df4d46a..54bc130 100644 --- a/hark.bundle.js +++ b/hark.bundle.js @@ -29,11 +29,10 @@ module.exports = function(stream, options) { //Config var options = options || {}, smoothing = (options.smoothing || 0.1), - interval = (options.interval || 50), threshold = options.threshold, play = options.play, history = options.history || 10, - running = true; + timer; //Setup Audio Context if (!audioContext) { @@ -67,12 +66,8 @@ module.exports = function(stream, options) { threshold = t; }; - harker.setInterval = function(i) { - interval = i; - }; - harker.stop = function() { - running = false; + cancelAnimationFrame(timer); harker.emit('volume_change', -100, threshold); if (harker.speaking) { harker.speaking = false; @@ -86,47 +81,37 @@ module.exports = function(stream, options) { harker.speakingHistory.push(0); } - // Poll the analyser node to determine if speaking - // and emit events if changed - var looper = function() { - setTimeout(function() { - - //check if stop has been called - if(!running) { - return; - } - - var currentVolume = getMaxVolume(analyser, fftBins); + function checkVolume() { + var currentVolume = getMaxVolume(analyser, fftBins); - harker.emit('volume_change', currentVolume, threshold); + harker.emit('volume_change', currentVolume, threshold); - var history = 0; - if (currentVolume > threshold && !harker.speaking) { - // trigger quickly, short history - for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history >= 2) { - harker.speaking = true; - harker.emit('speaking'); - } - } else if (currentVolume < threshold && harker.speaking) { - for (var i = 0; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history == 0) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } + var history = 0; + if (currentVolume > threshold && !harker.speaking) { + // trigger quickly, short history + for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history >= 2) { + harker.speaking = true; + harker.emit('speaking'); } - harker.speakingHistory.shift(); - harker.speakingHistory.push(0 + (currentVolume > threshold)); + } else if (currentVolume < threshold && harker.speaking) { + for (var i = 0; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history == 0) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + } + harker.speakingHistory.shift(); + harker.speakingHistory.push(0 + (currentVolume > threshold)); - looper(); - }, interval); - }; - looper(); + timer = requestAnimationFrame(checkVolume); + } + checkVolume(); return harker; } diff --git a/hark.js b/hark.js index b5e14fd..a340c29 100644 --- a/hark.js +++ b/hark.js @@ -27,11 +27,10 @@ module.exports = function(stream, options) { //Config var options = options || {}, smoothing = (options.smoothing || 0.1), - interval = (options.interval || 50), threshold = options.threshold, play = options.play, history = options.history || 10, - running = true; + timer; //Setup Audio Context if (!audioContext) { @@ -65,12 +64,8 @@ module.exports = function(stream, options) { threshold = t; }; - harker.setInterval = function(i) { - interval = i; - }; - harker.stop = function() { - running = false; + cancelAnimationFrame(timer); harker.emit('volume_change', -100, threshold); if (harker.speaking) { harker.speaking = false; @@ -84,47 +79,37 @@ module.exports = function(stream, options) { harker.speakingHistory.push(0); } - // Poll the analyser node to determine if speaking - // and emit events if changed - var looper = function() { - setTimeout(function() { + function checkVolume() { + var currentVolume = getMaxVolume(analyser, fftBins); - //check if stop has been called - if(!running) { - return; - } + harker.emit('volume_change', currentVolume, threshold); - var currentVolume = getMaxVolume(analyser, fftBins); - - harker.emit('volume_change', currentVolume, threshold); - - var history = 0; - if (currentVolume > threshold && !harker.speaking) { - // trigger quickly, short history - for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history >= 2) { - harker.speaking = true; - harker.emit('speaking'); - } - } else if (currentVolume < threshold && harker.speaking) { - for (var i = 0; i < harker.speakingHistory.length; i++) { - history += harker.speakingHistory[i]; - } - if (history == 0) { - harker.speaking = false; - harker.emit('stopped_speaking'); - } + var history = 0; + if (currentVolume > threshold && !harker.speaking) { + // trigger quickly, short history + for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; + } + if (history >= 2) { + harker.speaking = true; + harker.emit('speaking'); + } + } else if (currentVolume < threshold && harker.speaking) { + for (var i = 0; i < harker.speakingHistory.length; i++) { + history += harker.speakingHistory[i]; } - harker.speakingHistory.shift(); - harker.speakingHistory.push(0 + (currentVolume > threshold)); + if (history == 0) { + harker.speaking = false; + harker.emit('stopped_speaking'); + } + } + harker.speakingHistory.shift(); + harker.speakingHistory.push(0 + (currentVolume > threshold)); - looper(); - }, interval); - }; - looper(); + timer = requestAnimationFrame(checkVolume); + } + checkVolume(); return harker; }