/ challenges-old / cymbal-solutions
Sign in
challenges-old / cymbal-solutions
Experiments section; bell cymbal with three taps and a crash
Jeremy Magland <jmagland@flatironinstitute.org> committed commit a4c6dd73e6e0 parent f56dfa7 Browse files
5 changed files+81−0
experiments/bell-taps-then-crash.jsonadded+55−0View file
@@ -0,0 +1,55 @@
1+{
2+ "description": "The bell cymbal (cymbal-bell-v1 geometry, material and listener) played with three soft taps and then a hard crash, all within two seconds, ringing out to six seconds. Same solver and grid as the top of the bell chain (4 mm, 300 symmetric shell modes, two steps per sample), on the GPU. At the file's scale of 160 Pa the taps peak near 7 Pa and the crash near 60 Pa at the listener.",
3+ "challenge_geometry": "cymbal-bell-v1",
4+ "strikes": [
5+ {
6+ "t": 0.25,
7+ "force": 150.0,
8+ "duration": 0.0015,
9+ "x": 0.17272,
10+ "y": 0.0
11+ },
12+ {
13+ "t": 0.65,
14+ "force": 150.0,
15+ "duration": 0.0015,
16+ "x": 0.17272,
17+ "y": 0.0
18+ },
19+ {
20+ "t": 1.05,
21+ "force": 150.0,
22+ "duration": 0.0015,
23+ "x": 0.17272,
24+ "y": 0.0
25+ },
26+ {
27+ "t": 1.6,
28+ "force": 1000.0,
29+ "duration": 0.001,
30+ "x": 0.17272,
31+ "y": 0.0
32+ }
33+ ],
34+ "parameters": {
35+ "grid_spacing_m": 0.004,
36+ "cells": 8112,
37+ "n_dof": 33268,
38+ "transverse_modes": 300,
39+ "basis_even_in_y": true,
40+ "airy_modes": 300,
41+ "oversampling": 2,
42+ "dt_s": 1.0416666666666666e-05,
43+ "highest_transverse_mode_hz": 14038.5
44+ },
45+ "signal_scale_pa": 160.0,
46+ "peaks_pa": {
47+ "0.25-0.65 s": 6.8,
48+ "0.65-1.05 s": 8.42,
49+ "1.05-1.6 s": 5.16,
50+ "1.6-6.0 s": 44.69
51+ },
52+ "timing_seconds": 551.721,
53+ "hardware": "Intel(R) Xeon(R) w5-3435X (32 threads), numpy/scipy for the setup; coupling tensor and time stepping on NVIDIA RTX 6000 Ada Generation (PyTorch 2.14.0+cu130)",
54+ "note": "Experiment with a strike schedule; not a solution of any challenge."
55+}
\ No newline at end of file
experiments/bell-taps-then-crash.wavadded+0−0View file
Binary file not shown.
web/build.pymodified+9−0View file
@@ -40,6 +40,15 @@ def main():
4040 sol["fields"]["available"] = local.exists() and not is_lfs_pointer(local)
4141 entry["submissions"].append(sub)
4242 shutil.copytree(ROOT / "solutions", out / "solutions")
43+ # experiments: wav files with a JSON note beside them, outside the challenges (strike schedules and the like)
44+ manifest["experiments"] = []
45+ if (ROOT / "experiments").exists():
46+ shutil.copytree(ROOT / "experiments", out / "experiments")
47+ for j in sorted((ROOT / "experiments").glob("*.json")):
48+ meta = json.loads(j.read_text())
49+ wav = j.with_suffix(".wav")
50+ if wav.exists():
51+ manifest["experiments"].append({"id": j.stem, "output": f"experiments/{wav.name}", "meta": meta})
4352 from challenge_tools.build import player_version
4453
4554 html = (ROOT / "web" / "index.html").read_text().replace('src="player.js"', f'src="player.js?v={player_version()}"')
web/index.htmlmodified+4−0View file
@@ -47,6 +47,10 @@ button { font: inherit; padding: 4px 10px; }
4747 <h2>Submissions</h2>
4848 <div id="playback"></div>
4949 <div id="submissions"></div>
50+
51+<h2>Experiments</h2>
52+<p class="muted">Sounds produced with the same solvers outside the challenges, for listening only: strike schedules, alternative strengths. They are not scored and not submissions.</p>
53+<div id="experiments"></div>
5054 </main>
5155 <script src="player.js"></script>
5256 <script type="module" src="viewer.js"></script>
web/viewer.jsmodified+13−0View file
@@ -32,6 +32,19 @@ for (const [cid, ch] of Object.entries(manifest.challenges)) {
3232 }
3333 }
3434
35+// ---------------------------------------------------------------- experiments
36+const expDiv = document.getElementById("experiments");
37+for (const e of manifest.experiments || []) {
38+ const m = e.meta || {};
39+ const p = document.createElement("p");
40+ p.innerHTML = `<b>${esc(e.id)}</b>. ${esc(m.description || m.note || "")}` +
41+ (m.strikes ? ` <span class="muted">Strikes: ${esc(m.strikes.map((s) => `${s.force} N over ${(s.duration * 1e3).toFixed(1)} ms at ${s.t} s`).join("; "))}.</span>` : "") +
42+ (m.parameters ? ` <span class="muted"><code>${esc(JSON.stringify(m.parameters))}</code></span>` : "") +
43+ `<br><div class="cplayer" data-src="${esc(e.output)}"></div> <a href="${esc(e.output)}">wav</a>`;
44+ expDiv.appendChild(p);
45+}
46+if (!(manifest.experiments || []).length) expDiv.innerHTML = '<p class="muted">None yet.</p>';
47+
3548 const gains = manifest.playback_gain_db || {};
3649 const firstGain = Object.values(gains).find((g) => typeof g === "number");
3750 ChallengePlayer.controls(document.getElementById("playback"), { gainDb: typeof firstGain === "number" ? firstGain : 20, limiter: true });
↑↓ move↵openescclose