-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.js
75 lines (62 loc) · 2.03 KB
/
main.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
import InfiniteBeats from '/algorithm/InfiniteBeats.js';
import makeVisualizer from './lib/makeVisualizer.js';
import AudioQueue from './lib/AudioQueue.js';
import { fetchJson, timeout } from './lib/util.js';
let isPlaying = false;
async function onPlay(track, audioQueue) {
if (isPlaying) return;
isPlaying = true;
const infiniteBeats = new InfiniteBeats(track);
let userRequestedBeat = undefined;
const visualizer = makeVisualizer(track, {
isRunning: () => {
return isPlaying;
},
setNextTile: (tile) => {
// The user clicked a beat to play in the visualization.
userRequestedBeat = tile.q;
},
start: () => {
// The user clicked a beat to play in the visualization and we're not
// currently playing. Not providing an implementation since we're always
// playing.
},
});
let prevBeat = undefined;
while (true) {
const curBeat = (
userRequestedBeat ? userRequestedBeat :
infiniteBeats.getNextBeat(prevBeat)
);
userRequestedBeat = undefined;
audioQueue.queue(curBeat);
visualizer.setBeatIndex(curBeat.which);
// Sleep until just before the last queued beat finishes playing.
const delaySeconds = audioQueue.endOfLastQueuedBeat - audioQueue.currentTime;
const delayMs = delaySeconds * 1000;
await timeout(delayMs - 10);
prevBeat = curBeat;
}
isPlaying = false;
audioQueue.stop();
}
function setHeaderState(state) {
const headerEl = document.getElementById('header');
headerEl.classList.remove('loading', 'ready', 'error');
headerEl.classList.add(state);
}
async function main() {
try {
const track = await fetchJson('data/analysis.json');
const audioQueue = await AudioQueue.fromUrl('data/song.wav');
setHeaderState('ready');
document.getElementById('play-button').addEventListener('click', event => {
onPlay(track, audioQueue);
});
} catch (error) {
console.log('Error:', error);
setHeaderState('error');
document.getElementById('error-message').textContent = error;
}
}
main();