/ proof-of-concept / instrawave-compose
Sign in
proof-of-concept / instrawave-compose
instrawave-compose / index.html
97 lines · 4.4 KBBlameHistoryRaw
1<!doctype html>
2<html lang="en">
3 <head>
4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1" />
6 <title>instrawave-compose</title>
7 <style>
8 :root {
9 color-scheme: light dark;
10 font-family: system-ui, sans-serif;
11 }
12 body {
13 margin: 0 auto;
14 max-width: 72rem;
15 padding: 1rem 1.5rem 4rem;
16 line-height: 1.45;
17 }
18 h1 { font-size: 1.3rem; margin: 0.3rem 0 0; }
19 h1 + p { margin-top: 0.2rem; opacity: 0.75; }
20 h2 { font-size: 0.95rem; margin: 1.4rem 0 0.4rem; }
21 .cost { font-weight: normal; opacity: 0.6; font-size: 0.8rem; }
22 .bar { display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap; margin: 0.5rem 0; }
23 button { font: inherit; padding: 0.3rem 0.8rem; }
24 button:disabled { opacity: 0.5; }
25 select, input[type='text'] { font: inherit; }
26 input[type='range'] { width: 9rem; }
27 .voice-row {
28 display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap;
29 padding: 0.3rem 0.4rem; border-radius: 6px; font-size: 0.9rem;
30 }
31 .voice-row:nth-child(odd) { background: rgba(128, 128, 128, 0.09); }
32 .voice-row .swatch { width: 0.8rem; height: 0.8rem; border-radius: 3px; flex: none; }
33 .voice-row input.name { width: 8rem; border: none; background: transparent; font-weight: 600; }
34 .voice-row .count { opacity: 0.65; font-size: 0.8rem; min-width: 5.5rem; }
35 .voice-row .spacer { flex: 1; }
36 .rec { color: #d33; }
37 canvas.wave { width: 100%; height: 110px; border-radius: 6px; display: block; touch-action: none; }
38 canvas.tl { width: 100%; border-radius: 6px; display: block; touch-action: none; }
39 .meter { width: 7rem; height: 0.55rem; border-radius: 3px; background: rgba(128,128,128,0.25); overflow: hidden; }
40 .meter div { height: 100%; width: 0; background: #3dbb6e; }
41 #capture { border: 1px solid rgba(128,128,128,0.35); border-radius: 8px; padding: 0.6rem 0.8rem; margin-top: 0.8rem; }
42 #status { font-size: 0.85rem; opacity: 0.8; min-height: 1.3em; }
43 .hint { font-size: 0.8rem; opacity: 0.6; }
44 label { display: inline-flex; gap: 0.35rem; align-items: center; }
45 </style>
46 </head>
47 <body>
48 <h1>instrawave-compose</h1>
49 <p>
50 Teach it your sounds as named voices, then perform a rhythm in one take;
51 hits are classified back onto the voices and rendered on instruments.
52 </p>
54 <h2>Voices <span class="cost">record several examples of each sound: a syllable, a tap, anything repeatable</span></h2>
55 <div id="voice-list"></div>
56 <div class="bar">
57 <input id="voice-name" type="text" placeholder="new voice name (e.g. doo)" />
58 <button id="add-voice">Add voice</button>
59 <span class="spacer" style="flex:1"></span>
60 <button id="reset-all">Forget everything</button>
61 </div>
63 <div id="capture" hidden>
64 <div class="bar">
65 <strong id="capture-title"></strong>
66 <span class="hint">click a marker to audition; exclude anything that is not the sound</span>
67 </div>
68 <canvas id="capture-wave" class="wave"></canvas>
69 <div class="bar">
70 <label>sensitivity <input id="capture-sens" type="range" min="0" max="1" step="0.01" value="0.6" /></label>
71 <button id="capture-exclude" disabled>Exclude</button>
72 <span style="flex:1"></span>
73 <button id="capture-commit"></button>
74 <button id="capture-discard">Discard</button>
75 </div>
76 </div>
78 <h2>Take <span class="cost">one pass, exactly as performed; no grid</span></h2>
79 <div class="bar">
80 <button id="take-record">&#9679; Record take</button>
81 <div class="meter" id="meter" hidden><div></div></div>
82 <label>sensitivity <input id="take-sens" type="range" min="0" max="1" step="0.01" value="0.6" /></label>
83 <button id="take-redetect" disabled>Re-detect &amp; classify</button>
84 <span style="flex:1"></span>
85 <button id="take-play" disabled>Play</button>
86 </div>
87 <canvas id="timeline" class="tl"></canvas>
88 <div class="bar">
89 <span class="hint">drag a hit to another lane to reassign &middot; double-click a lane to add a hit &middot; delete key removes</span>
90 <span style="flex:1"></span>
91 <button id="hit-learn" disabled>Learn selected into its voice</button>
92 <button id="hit-delete" disabled>Delete selected</button>
93 </div>
94 <p id="status"></p>
95 <script type="module" src="./src/main.ts"></script>
96 </body>
97</html>
↑↓ move↵openescclose