Skip to content

Instantly share code, notes, and snippets.

@jussi-kalliokoski
Created September 24, 2014 06:41
Show Gist options
  • Save jussi-kalliokoski/edf81c322d0b49a97e98 to your computer and use it in GitHub Desktop.
Save jussi-kalliokoski/edf81c322d0b49a97e98 to your computer and use it in GitHub Desktop.
Waveform drawing
function getAudioData (url, time) {
return new Promise(function (resolve, reject) {
var context = new AudioContext();
var track = new Audio(url);
var bufferLength = time * context.sampleRate;
var buffer = new Float32Array(bufferLength);
var collector = context.createScriptProcessor(0, 1);
var audioSource = context.createMediaElementSource(track);
var samplesCollected = 0;
function cleanup () {
track.pause();
collector.disconnect(context.destination);
audioSource.disconnect(collector);
getAudioData._fixChrome82795.splice(getAudioData._fixChrome82795.indexOf(collector), 1);
}
collector.onaudioprocess = function collectAudio (event) {
var samplesToCollect = bufferLength - samplesCollected;
var inputData = event.inputBuffer.getChannelData(0).subarray(0, samplesToCollect);
buffer.set(inputData, samplesCollected);
samplesCollected += inputData.length;
if ( samplesCollected >= bufferLength ) {
cleanup();
resolve(buffer);
}
};
track.onerror = reject;
audioSource.connect(collector);
collector.connect(context.destination);
track.play();
// http://code.google.com/p/chromium/issues/detail?id=82795
getAudioData._fixChrome82795.push(collector);
});
}
getAudioData._fixChrome82795 = [];
function getAmplitudes (attack, decay) {
return function collectAmplitudes (buffer) {
var previousSample = 0;
for ( var i = 0; i < buffer.length; i++ ) {
var factor = 1 + (buffer[i] > previousSample ? attack : decay);
buffer[i] = Math.abs(factor * (previousSample - buffer[i]));
}
return buffer;
};
}
function drawWaveform (width, height) {
return function drawFromBuffer (buffer) {
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
var context = canvas.getContext("2d");
var halfHeight = Math.floor(height / 2);
var middleY = halfHeight;
context.beginPath();
var x = 0;
context.moveTo(x, middleY - buffer[0] * halfHeight);
for ( x = 1; x < width; x++ ) {
context.lineTo(x, middleY - buffer[Math.round(x / width * buffer.length)] * halfHeight);
}
for ( x = width; x-- > 0; ) {
context.lineTo(x, middleY + buffer[Math.round(x / width * buffer.length)] * halfHeight);
}
context.closePath();
context.fill();
document.body.appendChild(canvas);
};
}
getAudioData("audio.mp3", 5)
.then(getAmplitudes(0.1, 0.1))
.then(drawWaveform(800, 600))
.catch(function (error) {
console.error(error);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment