123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- var Waterfall = (function(options){
- var id = options.id || 'waterfall';
- var width = options.width || 1024;
- var height = options.height || 400;
- var background = "rgba(0, 0, 0, 1)";
- var audioStream = options.stream;
- var audioContext = options.context;
- var gainNode = audioContext.createGain ? audioContext.createGain() : audioContext.createGainNode();
- gainNode.gain.value = 0.1;
- var osci = audioContext.createOscillator();
- osci.type = "sine";
- gainNode.connect(audioContext.destination);
- osci.start ? osci.start(0) : osci.noteOn(0);
- var timeout = null;
- var target = document.getElementById(id);
- var canvas = document.createElement('canvas');
- var info = document.createElement('div');
- target.appendChild(info);
- canvas.width = width;
- canvas.height = height;
- target.appendChild(canvas);
- var canvasContext = canvas.getContext('2d');
- canvasContext.fillStyle = background;
- canvasContext.fillRect(0, 0, width, height);
- var analyser = audioContext.createAnalyser();
- audioStream.connect(analyser);
- var moveBy = 1;
- var heatmap = ["05000b", "05000b", "0a000a", "0a000a", "0e000f", "0e000f", "130014", "130014", "190018", "190018", "1e001e", "1e001e", "230022", "230022", "290029", "290029", "2e002e", "2e002e", "320033", "320033", "370037", "370037", "3d003d", "3d003d", "450046", "450046", "4e014e", "4e014e", "560157", "560157", "5f005e", "5f005e", "670167", "670167", "6f0070", "6f0070", "780179", "780179", "81017b", "81017b", "870278", "870278", "8d0272", "8d0272", "94036c", "94036c", "9a0467", "9a0467", "a00560", "a00560", "a8065a", "a8065a", "ad0753", "ad0753", "b4084d", "b4084d", "bb0a47", "bb0a47", "c10a40", "c10a40", "c60b38", "c60b38", "cc0c33", "cc0c33", "d30e2c", "d30e2c", "d90d26", "d90d26", "df0f1f", "df0f1f", "e61019", "e61019", "ec1213", "ec1213", "f3120d", "f3120d", "f91306", "f91306", "fc1601", "fc1601", "fe2000", "fe2000", "ff2a01", "ff2a01", "ff3501", "ff3501", "ff3f00", "ff3f00", "ff4b01", "ff4b01", "ff5500", "ff5500", "ff5f01", "ff5f01", "ff6901", "ff6901", "ff7300", "ff7300", "ff7f00", "ff7f00", "ff8901", "ff8901", "ff9400", "ff9400", "ff9f01", "ff9f01", "ffa900", "ffa900", "ffb401", "ffb401", "ffbd02", "ffbd02", "ffc303", "ffc303", "ffc704", "ffc704", "ffcb06", "ffcb06", "ffd009", "ffd009", "ffd30a", "ffd30a", "ffd70d", "ffd70d", "ffdb0d", "ffdb0d", "ffdf10", "ffdf10", "fee310", "fee310", "ffe713", "ffe713", "ffec15", "ffec15", "ffef17", "ffef17", "fff319", "fff319", "fff61b", "fff61b", "fffb1d", "fffb1d", "feff20", "feff20", "f9fb1f", "f9fb1f", "f3f71f", "f3f71f", "eff41f", "eff41f", "eaf01f", "eaf01f", "e5ed20", "e5ed20", "dee920", "dee920", "dae720", "dae720", "d5e320", "d5e320", "cfdf20", "cfdf20", "cbdc21", "cbdc21", "c5d720", "c5d720", "c1d521", "c1d521", "bad020", "bad020", "b5cd21", "b5cd21", "afc920", "afc920", "abc621", "abc621", "a6c220", "a6c220", "a1c021", "a1c021", "9bbc20", "9bbc20", "96b823", "96b823", "93b82a", "93b82a", "91b932", "91b932", "8ebb3c", "8ebb3c", "8bbb43", "8bbb43", "8abc4c", "8abc4c", "88bd54", "88bd54", "85bd5c", "85bd5c", "83be64", "83be64", "80bf6e", "80bf6e", "7dbf75", "7dbf75", "7bc07e", "7bc07e", "7ac187", "7ac187", "78c290", "78c290", "75c298", "75c298", "72c4a1", "72c4a1", "70c5aa", "70c5aa", "6ec4b2", "6ec4b2", "6cc5ba", "6cc5ba", "6ac7c3", "6ac7c3", "6ac6c6", "6ac6c6", "72cbcd", "72cbcd", "7aced1", "7aced1", "83d1d5", "83d1d5", "8ed5d7", "8ed5d7", "97d8da", "97d8da", "a0dcdd", "a0dcdd", "a9dfe1", "a9dfe1", "b3e3e5", "b3e3e5", "bee7e9", "bee7e9", "c6e9eb", "c6e9eb", "d0eef0", "d0eef0", "d9f1f3", "d9f1f3", "e3f5f7", "e3f5f7", "edf9fa", "edf9fa", "f6fcfd", "f6fcfd", "fdffff", "fdffff"];
- var pxToFreq = function(px){
- return (px / width) * 22000;
- };
-
- var addEventListeners = function(elem, events, f){
- if(typeof events == 'string'){events = events.split(' ');}
- for(var i=0; i<events.length; i++){elem.addEventListener(events[i], f)};
- };
- addEventListeners(canvas, "mousemove touchmove", function(e){
- e.preventDefault();
- info.innerText = pxToFreq(e.touches ? e.touches[0].pageX : e.offsetX);
- }, false);
- addEventListeners(canvas, "mousedown touchstart", function(e){
- e.preventDefault();
- var x = pxToFreq(e.touches ? e.touches[0].pageX : e.offsetX);
- info.innerText = x;
- play(x);
- }, false);
- addEventListeners(canvas, "mouseup touchend", function(e){
- e.preventDefault();
- stop();
- }, false);
- var draw = function() {
- window.requestAnimationFrame(draw);
- frequencies = new Uint8Array(analyser.frequencyBinCount);
- analyser.getByteFrequencyData(frequencies);
- canvasContext.drawImage(canvasContext.canvas, 0, 0, width, height - moveBy, 0, moveBy, width, height - moveBy);
- var centroidIndex = 0;
- var valueSum = 0;
-
- for(var i = 0; i < frequencies.length; i++) {
- var mag = frequencies[i];
- //mag = Math.floor(Math.pow(mag/255, 0.5)*255);
- centroidIndex += mag * i;
- valueSum += mag;
- canvasContext.fillStyle = '#'+heatmap[mag]; //"rgba(0,"+mag+",0,1)";
- canvasContext.fillRect(i, 0, 1, moveBy);
- }
- centroidIndex /= valueSum;
- canvasContext.fillStyle = 'white';
- canvasContext.fillRect(centroidIndex, 0, 2, 2*moveBy);
- };
- var sequence = function(seq){
- if(seq.length==0){
- stop();
- }else{
- var fd = seq.shift();
- if(fd[0]==0) stop();
- else play(fd[0]);
- timout = setTimeout(function(){sequence(seq)}, fd[1]);
- }
- };
- var play = function(freq){
- //osci.disconnect();
- osci.frequency.value = freq;
- osci.connect(gainNode);
- };
- var stop = function(){
- if(timeout) clearTimeout(timeout);
- osci.disconnect();
- };
- draw();
- return {
- play: play,
- stop: stop,
- sequence: sequence,
- pxToFreq: pxToFreq,
- };
- });
|