/ proof-of-concept / toy-instruments
Sign in
proof-of-concept / toy-instruments
toy-instruments / README.md
16.8 KBPreviewCodeBlameHistoryRaw

toy-instruments#

Live: https://magland.github.io/toy-instruments/ and https://toy-instruments--proof-of-concept.vault1-sites.magland.org/, both deployed from main by .github/workflows/pages.yml (on GitHub, and on vault1, whose site source is set to actions).

A browser gallery of toy physical-model instruments. Pick an instrument, set its geometry, properties and excitation, run the simulation, and get the pickup waveform, a spectrogram, a playable/downloadable .wav, and the bead displacements over time. Static site (Vite + TypeScript); the solver runs in a Web Worker, on the CPU or with WebGPU (see Solvers).

npm install
npm run dev      # http://localhost:5173
npm test         # vitest
npm run build    # static site in dist/

String of beads (first instrument)#

String tests (test/string.test.ts): modes vs the discrete-string formula; small mode-1 motion vs cos(omega_1 t); energy balance with and without damping/forcing; decay at the requested T60.

Bead drum#

Cymbal#

Solvers#

Both solvers integrate the same scheme (src/sim/solver.ts on the CPU in double precision, src/sim/gpu.ts with WebGPU in single precision); the WebGPU toggle next to Run picks one, and a failed GPU run falls back to the CPU with the reason in the run summary. The toggle is on by default for the drum and cymbal and off for the string, whose few dozen beads run faster on the CPU.

Shared result cache#

Runs are cached on artifact-cache (app toy-instruments, src/sim/cache.ts). Reads are public, so anyone opening the site gets a result someone has already computed; writes need the app's passcode, entered once per browser under "Shared cache" in the panel.

"Copy link to these settings" (under the preset) copies …/#/<instrument>?<param>=<value>&…&preset=<index>&gpu=<0|1>: every parameter in SI units, the preset the settings started from (its description is shown) and the WebGPU toggle (CPU and WebGPU results are cached separately). The form shows numbers in display units rounded to 10 digits, so a field the user has not edited keeps its exact value rather than being read back from the text (which can change the last bit, and with it the cache key). Opening the link applies the settings and then removes them from the address bar (history.replaceState), so reloading or sharing the plain address shows the page as usual; the WebGPU setting from a link is not saved as this browser's preference. Parameters missing from a link, invalid or not among a select's options keep the values of the link's preset, and unknown ones are ignored, so links survive added or removed parameters. When the shared cache has a result for the linked settings, the usual Load cached button appears.

Embedding#

src/embed.ts defines a web component for other pages (posts on jeremy.magland.org): one simulation, with the 3D model, its motion and its sound.

<toy-instrument-sim name="crash" exaggeration="5" settings="https://magland.github.io/toy-instruments/#/bead-cymbal?…&preset=0&gpu=1"></toy-instrument-sim>

Layout#

↑↓ move↵openescclose