var AudioContext = AudioContext || webkitAudioContext;

var context = new AudioContext();

var analyser = context.createAnalyser();
analyser.fftSize = 256;
analyser.smoothingTimeConstant = .75;
var frequencyData = new Uint8Array( analyser.fftSize );

var canvas = document.createElement( 'canvas' ),
	ctx = canvas.getContext( '2d' );
canvas.width = 1024;
canvas.height = 256;
canvas.style.border = '1px solid #666'
document.body.appendChild( canvas );

var source = context.createOscillator(); 
source.type = 'SAWTOOTH';
source.frequency.setValueAtTime( 200, 0 );

var filter = context.createBiquadFilter();
filter.type = 7;
filter.frequency.setValueAtTime( 100, 0 );

window.addEventListener( 'mousemove', function( e ) {
	filter.frequency.setValueAtTime( 1000 * e.clientX / window.innerWidth, context.currentTime + .1 );
	source.frequency.setValueAtTime( 200 * e.clientY / window.innerHeight, context.currentTime + .1 );
} );

var gain = context.createGain();
gain.gain.value = 10;

source.connect( filter );
filter.connect( gain );
gain.connect( analyser );
analyser.connect( context.destination );

source.start();

function update() {

	requestAnimationFrame( update );
	analyser.getByteFrequencyData( frequencyData );

	ctx.clearRect( 0, 0, canvas.width, canvas.height );
	for( var j = 0, m = analyser.frequencyBinCount; j < m; j++ ) {
		ctx.fillRect( j * ( canvas.width / m ), canvas.height, .5 * canvas.width / m, - frequencyData[ j ] * canvas.height / 255 );
	}

}

update();