-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathex.allthenotes-gain.html
102 lines (92 loc) · 2.54 KB
/
ex.allthenotes-gain.html
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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<title>All the notes: with gain</title>
<style>
button {
color: white;
padding: 10px 20px;
font-size: large;
margin-bottom: 10px;
background: #96729E;
cursor: pointer;
border-radius: 4px;
border: 1px solid rgba(0, 0, 0, .15);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25);
}
button:hover, [role="button"]:hover {
filter: brightness(1.2);
color: white;
}
</style>
</head>
<body>
<button onclick="play()">▶ play</button>
<button onclick="stop()">STOP!!!!</button>
<script>
const audioContext = new AudioContext();
function load(files) {
return new Promise((resolve, reject) => {
const buffers = new Map;
files.forEach(f => {
fetch(f)
.then(response => response.arrayBuffer())
.then(arrayBuffer => audioContext.decodeAudioData(arrayBuffer))
.then(audioBuffer => {
buffers.set(f, audioBuffer);
if (buffers.size === files.length) {
resolve(buffers);
}
})
.catch(e => console.log('uff'));
});
});
}
const notes = {
D1: {rate: 1/4, voices: 4},
D2: {rate: 1/2, voices: 4},
A2: {rate: 3/4, voices: 2},
D3: {rate: 1, voices: 2},
A3: {rate: 3/2, voices: 2},
D4: {rate: 2, voices: 2},
A4: {rate: 3, voices: 2},
D5: {rate: 4, voices: 2},
A5: {rate: 6, voices: 2},
D6: {rate: 8, voices: 2},
Fs: {rate: 10, voices: 6},
};
const C3 = 130.81;
const c3d150 = 150 / C3; // 1.1467013225;
const SAMPLE = 'Roland-SC-88-Cello-C3-glued-01.wav';
const sources = [];
const volume = audioContext.createGain();
volume.connect(audioContext.destination);
function play() {
load([SAMPLE]).then(buffers => {
volume.gain.setValueAtTime(0, audioContext.currentTime);
volume.gain.setTargetAtTime(1, audioContext.currentTime, 1);
for (let note in notes) {
for (let i = 0; i < notes[note].voices; i++) {
const source = audioContext.createBufferSource();
source.buffer = buffers.get(SAMPLE);
source.loop = true;
source.playbackRate.value = c3d150 * notes[note].rate;
source.connect(volume);
source.start();
sources.push(source);
}
};
});
}
const releaseTime = 0.1;
function stop() {
volume.gain.linearRampToValueAtTime(0, audioContext.currentTime + releaseTime);
for (let i = 0; i < sources.length; i++) {
sources[i] && sources[i].stop(audioContext.currentTime + 1);
delete sources[i];
}
}
</script>
</body>
</html>