-
Notifications
You must be signed in to change notification settings - Fork 9
/
index.html
210 lines (191 loc) · 10.3 KB
/
index.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8">
<meta name="application-name" content="Veremin">
<meta name="description" content="a video theremin based on PoseNet">
<meta name="keywords" content="Posenet,TensorFlow.js">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="theme-color" content="#20d5d2">
<meta name="mobile-web-app-capable" content="yes">
<!-- `getUserMedia` not supported from web app on iOS: https://stackoverflow.com/a/49467964 -->
<!--
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="#20d5d2">
<meta name="apple-mobile-web-app-title" content="Veremin">
<link rel="manifest" href="manifest.json">
-->
<link rel="apple-touch-icon" href="favicons/veremin-120.png"> <!-- iPhone -->
<link rel="apple-touch-icon" sizes="152x152" href="favicons/veremin-152.png"> <!-- iPad -->
<link rel="apple-touch-icon" sizes="180x180" href="favicons/veremin-180.png"> <!-- iPhone retina -->
<link rel="apple-touch-icon" sizes="167x167" href="favicons/veremin-167.png"> <!-- iPad retina -->
<link rel="mask-icon" href="favicons/veremin-pinned.svg" color="#20d5d2"> <!-- Safar pinned tab -->
<link rel="icon" type="image/png" sizes="32x32" href="favicons/veremin-32.png">
<link rel="icon" type="image/png" sizes="16x16" href="favicons/veremin-16.png">
<link rel="shortcut icon" href="favicons/favicon.ico">
<link rel="stylesheet" type="text/css" href="css/fonts.css">
<link rel="stylesheet" type="text/css" href="css/veremin.css">
<title>veremin | a video theremin based on PoseNet</title>
</head>
<body>
<header>
<span>veremin</span><br>
<span>a video theremin based on PoseNet</span>
<span id="v-status"></span>
<div id="btn-grp">
<div class="toggle-btn" title="pause veremin">
<input class="toggle-btn-input" id="toggle-checkbox" type="checkbox" onchange="toggleVeremin();" checked>
<label class="toggle-btn-label" for="toggle-checkbox">
<span class="toggle-btn-ui"></span>
</label>
</div>
<button id="open-cp-btn" onclick="document.getElementById('control-panel').classList.remove('closed')" title="open control panel">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" height="24" width="24">
<path d="M30 7h-5.1a5 5 0 0 0-9.8 0H2v2h13.1a5 5 0 0 0 9.8 0H30zm-10 4a3 3 0 1 1 3-3 3 3 0 0 1-3 3zM2 25h5.1a5 5 0 0 0 9.8 0H30v-2H16.9a5 5 0 0 0-9.8 0H2zm7-1a3 3 0 1 1 3 3 3 3 0 0 1-3-3z"></path>
</svg>
</button>
<button id="show-qr-btn" onclick="document.getElementById('qr-panel').classList.remove('closed')" title="show qr code">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" height="24" width="24">
<path d="M29.25 6.76a6 6 0 0 0-8.5 0l1.42 1.42a4 4 0 1 1 5.67 5.67l-8 8a4 4 0 1 1-5.67-5.66l1.41-1.42-1.41-1.42-1.42 1.42a6 6 0 0 0 0 8.5A6 6 0 0 0 17 25a6 6 0 0 0 4.27-1.76l8-8a6 6 0 0 0-.02-8.48z"></path>
<path d="M4.19 24.82a4 4 0 0 1 0-5.67l8-8a4 4 0 0 1 5.67 0A3.94 3.94 0 0 1 19 14a4 4 0 0 1-1.17 2.85L15.71 19l1.42 1.42 2.12-2.12a6 6 0 0 0-8.51-8.51l-8 8a6 6 0 0 0 0 8.51A6 6 0 0 0 7 28a6.07 6.07 0 0 0 4.28-1.76l-1.42-1.42a4 4 0 0 1-5.67 0z"></path>
</svg>
</button>
<button id="open-info-btn" onclick="document.getElementById('info-panel').classList.remove('closed')" title="open info">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" height="24" width="24">
<path d="M17 22v-9h-4v2h2v7h-3v2h8v-2h-3zM16 7a1.5 1.5 0 1 0 1.5 1.5A1.5 1.5 0 0 0 16 7z"></path>
<path d="M16 30a14 14 0 1 1 14-14 14 14 0 0 1-14 14zm0-26a12 12 0 1 0 12 12A12 12 0 0 0 16 4z"></path>
</svg>
</button>
</div>
</header>
<div class="v-msg">
<button id="open-env-btn" onclick="document.getElementById('env-panel').classList.remove('closed')" title="open environment info">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" height="32" width="32">
<path d="M29.88 27.52l-13-25a1 1 0 0 0-1.76 0l-13 25a1 1 0 0 0 0 1A1 1 0 0 0 3 29h26a1 1 0 0 0 .86-.49 1 1 0 0 0 .02-.99zM14.88 10h2.25v10h-2.25zM16 26a1.5 1.5 0 1 1 1.5-1.5A1.5 1.5 0 0 1 16 26z"></path>
</svg>
</button>
<div id="msg">loading...</div>
</div>
<main id="main">
<div class="v-wrapper">
<video id="video" playsinline controls="true"> </video>
<canvas id="output"></canvas>
</div>
</main>
<canvas id="wave"></canvas>
<div id="qr-panel" class="v-slider closed">
<button id="close-qr-btn" class="close-btn" title="close qr code"
onclick="document.getElementById('qr-panel').classList.add('closed')">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" height="28" width="28">
<path fill="#ffffff" d="M24 9.4L22.6 8 16 14.6 9.4 8 8 9.4l6.6 6.6L8 22.6 9.4 24l6.6-6.6 6.6 6.6 1.4-1.4-6.6-6.6L24 9.4z"/>
</svg>
</button>
<div class="v-slider-container">
<h1>ibm.biz/veremin</h1>
<img src="img/veremin-qr.png" alt="veremin qr code" />
</div>
</div>
<div id="control-panel" class="v-slider closed">
<a id="help-cp-link" href="https://github.com/vabarbosa/veremin/blob/main/CONTROLPANEL.md" target="blank" title="control panel guide">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" height="24" width="24">
<path fill="#20d5d2" d="M10 17a7 7 0 1 0 0-14 7 7 0 0 0 0 14zm0 1a8 8 0 1 1 0-16 8 8 0 0 1 0 16z"></path>
<path fill="#20d5d2" d="M10.5 10.5V12h-1V9.5h1a1.5 1.5 0 0 0 0-3h-1A1.5 1.5 0 0 0 8 8H7a2.5 2.5 0 0 1 2.5-2.5h1a2.5 2.5 0 1 1 0 5zM9 14a1 1 0 1 1 2 0 1 1 0 1 1-2 0"></path>
</svg>
</a>
<button id="close-cp-btn" class="close-btn" title="close control panel"
onclick="document.getElementById('control-panel').classList.add('closed')">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" height="28" width="28">
<path fill="#ffffff" d="M24 9.4L22.6 8 16 14.6 9.4 8 8 9.4l6.6 6.6L8 22.6 9.4 24l6.6-6.6 6.6 6.6 1.4-1.4-6.6-6.6L24 9.4z"/>
</svg>
</button>
</div>
<div id="info-panel" class="v-slider closed">
<button id="close-info-btn" class="close-btn" title="close info"
onclick="document.getElementById('info-panel').classList.add('closed')">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" height="28" width="28">
<path fill="#ffffff" d="M24 9.4L22.6 8 16 14.6 9.4 8 8 9.4l6.6 6.6L8 22.6 9.4 24l6.6-6.6 6.6 6.6 1.4-1.4-6.6-6.6L24 9.4z"/>
</svg>
</button>
<div class="v-slider-container">
<h2>Veremin</h2>
<p>
A video theremin that allows you to make beautiful
music just by waving your arms!
</p>
<h2>Usage</h2>
<p>
After the video loads, it will include an overlay with skeletal
and joint information detected by PoseNet. The overlay also
include two adjacent zones/boxes. Move your wrists within each
of the zones to make sounds.
</p>
<p>
Move your right hand/arm up and down (in the right zone) to
generate different notes.
</p>
<p>
Move your left hand/arm left and right (in the left zone) to adjust the velocity of the note.
</p>
<h2>Requirements</h2>
<p>
At a minimum, your browsers must allow <a href="https://caniuse.com/#feat=stream" target="_blank">access to a webcam</a>
and support the <a href="https://caniuse.com/#feat=audio-api" target="blank">Web Audio API</a>.
</p>
<p>
If your browser supports the <a href="https://caniuse.com/#feat=midi" target="blank">Web MIDI API</a>,
you can connect a MIDI synthesizer to your computer or you can
download and run a software synthesizer such as <a href="http://notahat.com/simplesynth/" target="_blank">SimpleSynth</a>.
</p>
<p>
Also, if you have access to a <a href="https://github.com/mqtt/mqtt.org/wiki/public_brokers" target="blank">MQTT broker that supports WebSockets</a>
you can enable and publish the positional data to the broker for other devices or applications to subscribe to.
</p>
<p>
Depending on your browser, you may need to access this
application using the <strong>https</strong> protocol instead
of the http.
</p>
<p>
Check out the <a href="https://github.com/vabarbosa/veremin/blob/main/README.md" target="_blank">README</a>
for more information.
</p>
<h2>Environment</h2>
<p>
<button id="open-env-link" onclick="document.getElementById('env-panel').classList.remove('closed')" title="open environment info">
Check out your browser environment
</button>
</p>
</div>
</div>
<div id="env-panel" class="v-slider closed">
<button id="close-env-btn" class="close-btn" title="close environment info"
onclick="document.getElementById('env-panel').classList.add('closed')">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" height="28" width="28">
<path fill="#ffffff" d="M24 9.4L22.6 8 16 14.6 9.4 8 8 9.4l6.6 6.6L8 22.6 9.4 24l6.6-6.6 6.6 6.6 1.4-1.4-6.6-6.6L24 9.4z"/>
</svg>
</button>
<div class="v-slider-container">
<h2>Environment</h2>
<dl id="env-list"> </dl>
</div>
</div>
<footer>
from the mind of <a href="https://github.com/johncohn" target="_blank">John Cohn</a> |
in collaboration with <a href="https://github.com/vabarbosa" target="_blank">va barbosa</a> |
fork me on <a href="https://github.com/vabarbosa/veremin" target="_blank">GitHub</a>
</footer>
<script src="https://unpkg.com/dat.gui"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.2.10"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/posenet@2.1.3"></script>
<script src="lib/paho-mqtt-min.js"></script>
<script src="lib/Tone.min.js"></script>
<script type="module" src="js/chord-intervals.js"></script>
<script type="module" src="js/tonejs-presets.js"></script>
<script type="module" src="js/canvas-overlay.js"></script>
<script type="module" src="js/camera-util.js"></script>
<script type="module" src="js/audio-controller.js"></script>
<script type="module" src="js/control-panel.js"></script>
<script type="module" src="js/veremin.js"></script>
</body>
</html>