-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathwaterfall.js
112 lines (88 loc) · 5.4 KB
/
waterfall.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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);
for(var i = 0; i < frequencies.length; i++) {
var mag = frequencies[i];
//mag = Math.floor(Math.pow(mag/255, 0.5)*255);
canvasContext.fillStyle = '#'+heatmap[mag]; //"rgba(0,"+mag+",0,1)";
canvasContext.fillRect(i, 0, 1, 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,
};
});