-
Notifications
You must be signed in to change notification settings - Fork 0
/
extra.theremin.html
107 lines (94 loc) · 2.49 KB
/
extra.theremin.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
103
104
105
106
107
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<title>WebAudio: theremin</title>
<style>
html {
height: 100%;
}
body {
font-family: monospace;
text-align: center;
height: 100%;
}
#pitch {
width: 1px;
height: 70%;
border-left: 1px solid rgb(0, 0, 0);
display: inline-block;
padding: 0;
margin: 0;
position: relative;
left: 40%;
top: -1px;
}
#volume {
width: 80%;
height: 1px;
border-top: 1px solid rgb(0, 0, 0);
display: inline-block;
position: relative;
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<p><button id="power" onClick="turnOnOff()">Turn ON</button></p>
<div id="pitch"></div>
<div id="volume"></div>
<p id="frequency"></p>
Set the maximum frequency: <input type="range" max="20000" min="100" value="3000" onchange="updateMaxFreq(this)"/><span id="max-freq">3000Hz</span>
<script>
if (!window.AudioContext && window.webkitAudioContext) {
window.AudioContext = window.webkitAudioContext;
}
let on = false;
let pitchPos, volumePos;
let audioContext, oscillator, gain;
let maxFreq = 3000;
function turnOnOff() {
if (on) {
oscillator.stop();
power.innerHTML = 'Turn ON';
on = false;
return;
}
on = true;
power.innerHTML = 'Turn OFF';
resetControls();
audioContext = audioContext || new AudioContext();
oscillator = audioContext.createOscillator();
oscillator.type = 'sine';
oscillator.frequency.value = 3000;
oscillator.start();
gain = audioContext.createGain();
gain.gain.value = 1;
oscillator.connect(gain);
gain.connect(audioContext.destination);
}
function resetControls() {
pitchPos = document.getElementById('pitch').getBoundingClientRect();
volumePos = document.getElementById('volume').getBoundingClientRect();
}
function updateMaxFreq(i) {
maxFreq = Number(Number(i.value).toFixed());
document.getElementById('max-freq').innerText = maxFreq + 'Hz';
}
onmousemove = (e) => {
if (!on) {
return;
}
const freq = Number(maxFreq - (2 * maxFreq / volumePos.width) * Math.abs(e.clientX - pitchPos.x)).toFixed();
const clampedFreq = freq < 0 ? 0 : freq;
oscillator.frequency.value = clampedFreq;
const volume = 1 - (e.clientY - pitchPos.y) / pitchPos.height;
const clampedVolume = volume < 0 ? 0 : volume > 1 ? 1 : volume;
gain.gain.value = clampedVolume;
document.getElementById('frequency').innerText = clampedFreq + 'Hz @ ' + Number(clampedVolume * 100).toFixed(2) + '% volume' ;
};
onresize = resetControls;
</script>
</body>
</html>