abr's Audio spectrum fiddle

JavaScript

navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;

navigator.getUserMedia({
    audio: {
        mozAutoGainControl: true,
        echoCancellation: true,
        mozNoiseSuppression: true
    }
},

function (stream) {
    var audioCtx = new window.AudioContext();
    var source = audioCtx.createMediaStreamSource(stream);
    var analyser = audioCtx.createAnalyser();
    source.connect(analyser);

    var canvas = document.createElement("canvas");
    var canvasCtx = canvas.getContext("2d");
    canvas.width = window.innerWidth - 20;
    canvas.height = window.innerHeight - 20;
    document.body.appendChild(canvas);

    var bufferLength = canvas.width;
    var dataArray = new Uint8Array(bufferLength);

    canvasCtx.strokeStyle = 'rgb(0, 125, 0)';

    var draw = function () {
        canvasCtx.fillStyle = "#a0a0a0";
        canvasCtx.fillRect(0, 0, canvas.width, canvas.height);

        analyser.getByteFrequencyData(dataArray);
        canvasCtx.lineWidth = 2;

        for (var x = 0; x < bufferLength; x++) {
            var y = (dataArray[x] / 128) * canvas.height / 4;
            y = canvas.height - y;
            var c = Math.floor((x*255)/bufferLength);
            canvasCtx.fillStyle = "rgb("+c+",0,"+(255-x)+")";
            canvasCtx.fillRect(x, y, 2, canvas.height - y)
        }
        analyser.getByteTimeDomainData(dataArray);

        canvasCtx.lineWidth = 5;
        canvasCtx.strokeStyle = 'rgb(0, 125, 0)';
        canvasCtx.beginPath();
        for (var x = 0; x < bufferLength; x++) {
            var y = (dataArray[x] / 128) * canvas.height / 2;
            y = canvas.height - y;
            x ? canvasCtx.lineTo(x, y) : canvasCtx.moveTo(x, y);
        }
        canvasCtx.stroke();

        // without this, source gets GCed and the whole thing stops.
        var bogus = source;
    }

    var interval = 1000 * canvas.width / audioCtx.sampleRate;
    setInterval(draw, interval);

}, function...