2<html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 <title>cymplay</title>
7 <link rel="stylesheet" href="./src/style.css" />
8 </head>
9 <body>
10 <header>
11 <h1>cymplay</h1>
12 <span class="sub">design a cymsim cymbal, play it from the keyboard, export the hits for the full render</span>
13 </header>
14 <main>
15 <section class="left">
16 <canvas id="cymbal"></canvas>
17 <div class="keys" id="keyhelp"></div>
18 </section>
19 <section class="right">
9c9fa54Guide the first visit, and separate recording from playingJeremy Magland 20 <div id="ready" class="ready">
21 <button id="ready-action" class="primary">Start</button>
22 <div id="ready-text" class="ready-text"></div>
23 <div class="progress"><div id="progress-bar"></div></div>
24 </div>
26 <details id="cymbalbox" open>
27 <summary>1. The cymbal</summary>
29 <label>start from <select id="preset"></select></label>
30 <label class="file">load YAML <input type="file" id="yamlfile" accept=".yaml,.yml" /></label>
9c9fa54Guide the first visit, and separate recording from playingJeremy Magland 31 <button id="revert">Revert</button>
32 <button id="download-design-yaml">Download YAML</button>
33 </div>
34 <div class="row small">
35 Sliders marked <b>live</b> take effect while you play. The others change the shape of the
36 shell, so the modes have to be computed again; the bar at the top says when they are stale.
37 </div>
38 <div id="design"></div>
39 <div id="design-status" class="status"></div>
40 </details>
42 <details id="setup">
43 <summary>2. Modes</summary>
44 <div class="row small">
45 The modes are the cymbal's own vibration patterns. They are computed once per shape, here
46 in the browser, and kept for next time. A finer mesh reaches higher in frequency and takes
47 much longer.
49 <div class="row">
50 <label>playback mesh <select id="esize">
51 <option value="0.015">15 mm (fast, rough)</option>
52 <option value="0.012">12 mm</option>
53 <option value="0.010" selected>10 mm (default)</option>
54 <option value="0.008">8 mm (slow)</option>
55 <option value="0.006">6 mm (very slow)</option>
56 </select></label>
57 <label>modes up to <input type="number" id="fmax" value="20000" step="1000" min="500" max="24000" /> Hz</label>
58 </div>
59 <div class="row">
60 <button id="compute">Compute modes</button>
61 <button id="download-modes" disabled>Download modes</button>
62 <label class="file">load modes <input type="file" id="modesfile" accept=".bin" /></label>
63 <button id="clear-cache" title="forget every cached modes file">Clear cache</button>
64 </div>
65 <div id="status" class="status">no modes yet</div>
66 </details>
68 <details id="play" open>
69 <summary>3. Play</summary>
9c9fa54Guide the first visit, and separate recording from playingJeremy Magland 71 <label>exciter <select id="exciter">
72 <option value="stick">stick (hard, bright)</option>
73 <option value="mallet">mallet (soft, nearly silent without the cascade)</option>
74 </select></label>
75 <label>master level <input type="range" id="velocity" min="0.3" max="16" step="0.1" value="6" /> <span id="velocity-value">6.0 m/s</span></label>
76 <button id="reset-weights" title="put every position back to the master level">Level the positions</button>
77 </div>
78 <div class="row small">
79 Each position is struck at the velocity printed under its letter. Scroll the wheel over a
80 position to make it harder or softer; the master level scales them all together.
82 <div class="row">
83 <label>volume <input type="range" id="volume" min="0" max="1" step="0.01" value="0.4" /></label>
84 <label>output <select id="signal">
85 <option value="unbaffled">unbaffled (front minus back)</option>
86 <option value="front">baffled (front only)</option>
87 </select></label>
88 <label>contact springs <select id="points" title="springs per patch in real time; the exported YAML always keeps the full patches">
89 <option value="cheap">fewest (mallet 1, stick 3)</option>
90 <option value="mixed" selected>mallet 1, stick 7</option>
91 <option value="full">as in cymsim (7 and 7)</option>
92 </select></label>
93 <label title="the mallet is about 18 dB quieter than the stick in linear theory; this makes it audible and is never written into the exported YAML">
94 <input type="checkbox" id="preview-gain" checked /> lift the mallet preview level
95 </label>
96 </div>
97 <div class="row small" id="audio-info">audio not started</div>
98 </details>
ae4a407cymplay: design and play a cymsim cymbal in the browserJeremy Magland 100 <details id="record" open>
9c9fa54Guide the first visit, and separate recording from playingJeremy Magland 101 <summary>4. Record a performance</summary>
102 <div class="row small">
103 Playing always makes sound. Recording is separate: start it when you want the hits kept,
104 then play them back, save the sound, or download the configuration to render properly.
105 </div>
9c9fa54Guide the first visit, and separate recording from playingJeremy Magland 107 <button id="record-toggle" class="primary">Record hits</button>
108 <button id="play-hits" disabled>Play the recording</button>
109 <button id="stop-hits" disabled>Stop</button>
110 <button id="clear-hits" disabled>Clear</button>
112 <div class="row">
9c9fa54Guide the first visit, and separate recording from playingJeremy Magland 113 <button id="download-yaml" disabled>Download YAML for cymsim</button>
114 <button id="download-wav" disabled>Download WAV</button>
ae4a407cymplay: design and play a cymsim cymbal in the browserJeremy Magland 115 <label>lead-in <input type="number" id="leadin" value="0.05" step="0.05" min="0" /> s</label>
116 <label>tail <input type="number" id="tail" value="3" step="0.5" min="0.1" /> s</label>
9c9fa54Guide the first visit, and separate recording from playingJeremy Magland 117 <label>name <input type="text" id="prefix" value="cymplay" size="10" /></label>
118 </div>
119 <div class="row small">
120 The WAV is the recording played again through this same approximate engine, not a capture
121 of the speakers, so it is exact and includes the whole ring-out. The YAML renders the same
122 performance with the full nonlinear model: <code>cymsim simulate <file></code>.
9c9fa54Guide the first visit, and separate recording from playingJeremy Magland 124 <div id="record-status" class="status">not recording</div>
126 <thead><tr><th>#</th><th>time [s]</th><th>key</th><th>exciter</th><th>r [m]</th><th>phi [rad]</th><th>v [m/s]</th><th>F peak [N]</th><th>contact [ms]</th></tr></thead>
127 <tbody></tbody>
128 </table>
129 </details>
130 </section>
131 </main>
132 <script type="module" src="./src/main.ts"></script>
133 </body>
134</html>