@hakerzp/mic
Version:
A simple stream wrapper for arecord (Linux (including Raspbian)) and sox (Mac/Windows). Returns a Passthrough stream object so that stream control like pause(), resume(), pipe(), etc. are all available.
88 lines (76 loc) • 2.77 kB
JavaScript
var Transform = require('stream').Transform;
var util = require("util");
function IsSilence(options) {
var that = this;
if (options && options.debug) {
that.debug = options.debug;
delete options.debug;
}
Transform.call(that, options);
var consecSilenceCount = 0;
var numSilenceFramesExitThresh = 0;
that.getNumSilenceFramesExitThresh = function getNumSilenceFramesExitThresh() {
return numSilenceFramesExitThresh;
};
that.getConsecSilenceCount = function getConsecSilenceCount() {
return consecSilenceCount;
};
that.setNumSilenceFramesExitThresh = function setNumSilenceFramesExitThresh(numFrames) {
numSilenceFramesExitThresh = numFrames;
return;
};
that.incrConsecSilenceCount = function incrConsecSilenceCount() {
consecSilenceCount++;
return consecSilenceCount;
};
that.resetConsecSilenceCount = function resetConsecSilenceCount() {
consecSilenceCount = 0;
return;
};
};
util.inherits(IsSilence, Transform);
IsSilence.prototype._transform = function(chunk, encoding, callback) {
var i;
var speechSample;
var silenceLength = 0;
var self = this;
var debug = self.debug;
var consecutiveSilence = self.getConsecSilenceCount();
var numSilenceFramesExitThresh = self.getNumSilenceFramesExitThresh();
var incrementConsecSilence = self.incrConsecSilenceCount;
var resetConsecSilence = self.resetConsecSilenceCount;
if(numSilenceFramesExitThresh) {
for(i=0; i<chunk.length; i=i+2) {
if(chunk[i+1] > 128) {
speechSample = (chunk[i+1] - 256) * 256;
} else {
speechSample = chunk[i+1] * 256;
}
speechSample += chunk[i];
if(Math.abs(speechSample) > 2000) {
if (debug) {
console.log("Found speech block");
}
//emit 'sound' if we hear a sound after a silence
if(consecutiveSilence>numSilenceFramesExitThresh) self.emit('sound');
resetConsecSilence();
break;
} else {
silenceLength++;
}
}
if(silenceLength == chunk.length/2) {
consecutiveSilence = incrementConsecSilence();
if (debug) {
console.log("Found silence block: %d of %d", consecutiveSilence, numSilenceFramesExitThresh);
}
//emit 'silence' only once each time the threshold condition is met
if( consecutiveSilence === numSilenceFramesExitThresh) {
self.emit('silence');
}
}
}
this.push(chunk);
callback();
};
module.exports = IsSilence;