/
visualisation.js
119 lines (92 loc) · 3.42 KB
/
visualisation.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
112
113
114
115
116
117
118
119
var canvas = document.getElementById("audio-canvas");
var ctx = canvas.getContext('2d');
canvas.width = document.body.clientWidth / 1.4;
// One-liner to resume playback when user interacted with the page.
document.querySelector('button').addEventListener('click', function() {
var sound = new Sound();
sound.load('offkey_070221---snake-eyes-160.mp3');
});
function Sound() {
"use strict";
var self = this;
var context = new AudioContext();
var source = null;
var jsProcessor = null;
var analyser = null;
this.processAudio = function() {
var freqByteData = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(freqByteData);
self.renderFFT(freqByteData);
};
this.renderFFT = function(freqByteData) {
var SPACER_WIDTH = 11;
var numBars = Math.round(canvas.width / SPACER_WIDTH);
ctx.clearRect(0, 0, canvas.width, canvas.height);
//freqByteData = freqByteData.subarray(viewportOffset.valueAsNumber);
var colors = [
'#EB6711', // orange
'#9B000C', // red
'#FAB300' // yellow
];
// Draw rectangle for each frequency bin.
for (var i = 0; i < numBars /*freqByteData.length*/; ++i) {
var magnitude = freqByteData[i];
var lingrad = ctx.createLinearGradient(0, canvas.height, 0, canvas.height - magnitude);
lingrad.addColorStop(0, '#fff');
lingrad.addColorStop(1, colors[i % colors.length]);
ctx.fillStyle = lingrad;
ctx.fillRect(i * SPACER_WIDTH, canvas.height, 10, -magnitude);
}
};
this.initAudio = function(arrayBuffer) {
source = context.createBufferSource();
source.loop = true;
if (context.decodeAudioData) {
context.decodeAudioData(arrayBuffer, function(buffer) {
source.buffer = buffer;
}, function(e) {
console.log(e);
});
} else {
source.buffer = context.createBuffer(arrayBuffer,false /*Mix to mono*/);
}
jsProcessor = context.createScriptProcessor(2048 /*bufferSize*/, 1 /*num inputs*/, 1 /*num outputs*/);
jsProcessor.onaudioprocess = this.processAudio;
analyser = context.createAnalyser();
source.connect(context.destination);
source.connect(analyser);
analyser.connect(jsProcessor);
jsProcessor.connect(context.destination);
var gain = context.createGain();
source.connect(gain);
gain.gain.value = 0.2;
gain.connect(context.destination);
source.start(0);
};
this.load = function(url) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function() {
self.initAudio(request.response);
};
request.send();
};
this.play = function() {
// Connect the processing graph:
// source -> destination
// source -> analyser -> jsProcessor -> destination
source.connect(context.destination);
source.connect(analyser);
analyser.connect(jsProcessor);
jsProcessor.connect(context.destination);
source.noteOn(0);
};
this.stop = function() {
source.noteOff(0);
source.disconnect(0);
jsProcessor.disconnect(0);
analyser.disconnect(0);
};
}
//sound.play();