-
Notifications
You must be signed in to change notification settings - Fork 0
/
spectrogram.js
54 lines (48 loc) · 1.71 KB
/
spectrogram.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
let audioElement;
let analyser;
let firstPlay = true;
const FREQUENCY_BIN_COUNT = 128;
const dataArray = new Uint8Array(FREQUENCY_BIN_COUNT);
const setupAudioCtx = () => {
// Create audio context
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// Initialize analyser
analyser = audioCtx.createAnalyser();
analyser.fftSize = 2 * FREQUENCY_BIN_COUNT;
// Analyser's frequencyBinCount is always half of the fftSize (https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/frequencyBinCount)
const source = audioCtx.createMediaElementSource(audioElement);
// Connect source -> analyser -> destination
source.connect(analyser);
analyser.connect(audioCtx.destination);
}
const draw = () => {
analyser.getByteFrequencyData(dataArray);
for (let i = 0; i < FREQUENCY_BIN_COUNT; i++) {
const binI = document.getElementById(`bin-${i}`);
binI.innerHTML = dataArray[i] === 0 ? '_' : '█'.repeat(dataArray[i]);
}
};
const setupOnPlay = () => {
if (firstPlay) {
setupAudioCtx();
setInterval(draw, 50);
firstPlay = false;
}
};
// When the page loads, create a div for each bin, to be filled up with text
window.onload = () => {
const createBins = () => {
for (let i = 0; i < FREQUENCY_BIN_COUNT; i++) {
const bin = document.createElement("div");
bin.setAttribute("id", `bin-${i}`);
bin.innerHTML = '_';
document.getElementById("spectrogram").appendChild(bin);
}
};
const getAudioElement = () => {
audioElement = document.querySelector('audio');
audioElement.onplay = setupOnPlay;
};
createBins();
getAudioElement();
};