Skip to content

Instantly share code, notes, and snippets.

@DanBrink91
Created January 29, 2015 00:41
Show Gist options
  • Save DanBrink91/3840ba1574281eae5615 to your computer and use it in GitHub Desktop.
Save DanBrink91/3840ba1574281eae5615 to your computer and use it in GitHub Desktop.
Peaks in Songs
<body>
<h1>Music</h1>
<button id="play" disabled>Play</button>
<section>
<canvas id="theCanvas" width="400px" height="400px" style="border: 1px solid black"></canvas>
</section>
<script>
var ctx = document.getElementById("theCanvas").getContext('2d');
var btn = document.getElementById("play");
var songBuffer = null;
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
function loadSong(url) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function() {
context.decodeAudioData(request.response, function(buffer) {
btn.disabled = false;
songBuffer = buffer;
analyzeSong(buffer);
});
}
request.send();
}
function playSong(buffer) {
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start(0); // may have to use noteOn(time) on older systems
}
// sampleRate = number of values(volumes?) per second
function analyzeSong(buffer) {
var channels = buffer.numberOfChannels;
// how often we check for a peak in the song
var checkRate = buffer.sampleRate / 3;
for(var channel = 0; channel < channels; channel++) {
var peaksArray = [];
var data = buffer.getChannelData(channel);
var len = data.length;
//var stats = findSongStats(data);
var threshold = 0.5;//stats.mean + stats.stddev;
for(var i = 0, x=0; i < len; i += checkRate, x++) {
if(data[i] > threshold) {
peaksArray.push(i);
}
// y = scale -1.0 to 1.0 to fit in 0 to 400
ctx.fillRect(x, ((data[i] + 1)/2)* 400 , 1, 1);
}
console.log(peaksArray.length, x);
}
}
// returns mean, high, low, and std dev.
function findSongStats(data) {
var len = data.length;
if(!len)
{
return {
"mean" : 0,
"high": 0,
"low": 0,
"stddev": 0
};
}
var sum = 0.0, high = -10.0, low = 10.0, mean = 0.0;
for(var i = 0; i < len; i++) {
sum += data[i];
if(data[i] > high) {
high = data[i];
}
if(data[i] < low) {
low = data[i];
}
}
mean = sum / len;
// now work on std dev
// difference between number and mean squared
var squares = [];
for(var i = 0; i < len; i++) {
squares.push(Math.pow(data[i] - mean, 2));
}
// the average of the squares
var squares_sum = 0.0;
for(var i = 0; i < len; i++) {
squares_sum += squares[i];
}
// square root of the average to find the std_dev
var stddev = Math.sqrt(squares_sum / len);
return {
"mean" : mean,
"high": high,
"low": low,
"stddev": stddev
};
}
loadSong("music/Santogold - L.E.S. Artistes.mp3");
btn.onclick = function() {
if(songBuffer)
playSong(songBuffer);
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment