Skip to content

Instantly share code, notes, and snippets.

@pachacamac
Last active April 26, 2022 19:22
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save pachacamac/d7b3d667ecaa0cd39f36 to your computer and use it in GitHub Desktop.
Save pachacamac/d7b3d667ecaa0cd39f36 to your computer and use it in GitHub Desktop.
Clap Detection in JS
<html>
<head>
<title>AudioPlayground</title>
<style>* {box-sizing: border-box;}</style>
</head>
<body>
<h3>AudioPlayground</h3>
<p>If you're happy and you know it, clap your hands!</p>
<script>
var Recording = function(cb){
var recorder = null;
var recording = true;
var audioInput = null;
var volume = null;
var audioContext = null;
var callback = cb;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia;
if(navigator.getUserMedia){
navigator.getUserMedia({audio:true},
function(e){ //success
var AudioContext = window.AudioContext || window.webkitAudioContext;
audioContext = new AudioContext();
volume = audioContext.createGain(); // creates a gain node
audioInput = audioContext.createMediaStreamSource(e); // creates an audio node from the mic stream
audioInput.connect(volume);// connect the stream to the gain node
recorder = audioContext.createScriptProcessor(2048, 1, 1);
recorder.onaudioprocess = function(e){
if(!recording) return;
var left = e.inputBuffer.getChannelData(0);
//var right = e.inputBuffer.getChannelData(1);
callback(new Float32Array(left));
};
volume.connect(recorder);// connect the recorder
recorder.connect(audioContext.destination);
},
function(e){ //failure
alert('Error capturing audio.');
}
);
} else {
alert('getUserMedia not supported in this browser.');
}
};
var lastClap = (new Date()).getTime();
function detectClap(data){
var t = (new Date()).getTime();
if(t - lastClap < 200) return false; // TWEAK HERE
var zeroCrossings = 0, highAmp = 0;
for(var i = 1; i < data.length; i++){
if(Math.abs(data[i]) > 0.25) highAmp++; // TWEAK HERE
if(data[i] > 0 && data[i-1] < 0 || data[i] < 0 && data[i-1] > 0) zeroCrossings++;
}
if(highAmp > 20 && zeroCrossings > 30){ // TWEAK HERE
//console.log(highAmp+' / '+zeroCrossings);
lastClap = t;
return true;
}
return false;
}
var rec = new Recording(function(data){
if(detectClap(data)){
console.log('clap!');
document.bgColor = 'rgb('+Math.random()*255+','+Math.random()*255+','+Math.random()*255+')';
}
});
</script>
</body>
</html>
@netrevisanto
Copy link

MAAAAAAAAAAAAAAAAAAANY THANKS.
SAVED ME HOURS AND MADE MY WEKKEND FUNNY

@adamatan
Copy link

Great work! How do you license it please?

@impishj
Copy link

impishj commented Aug 14, 2017

I'd also like a word on licensing

@Pangamma
Copy link

saving for later

@maxdbn
Copy link

maxdbn commented Feb 23, 2019

Recognize almost every sound, but you already know that
Did you have time by chance to work on an upgrade?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment