| .. | ||
| src | ||
| .gitignore | ||
| index.html | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| vite.config.ts |
Cymbal2 Simulator — web app#
Interactive browser implementation of the physical model described in ../README.md. The algorithm itself is written in MATLAB syntax, in ../matlab/*.m, and executed client-side by numbl inside a Web Worker; the TypeScript here is only the UI, the plots, the WAV encoder, and the marshalling of parameters and tensors in and out of the numbl runtime.
The signal chain: a prescribed hand stroke drives an Euler-Bernoulli stick with a Hertz-contact mallet head against a von Karman shallow spherical shell on a washer support, integrated step by step in the time domain; the output is the shell's normal acceleration at a pickup point, decimated and normalized.
Usage#
npm install
npm run dev # development server
npm run build # production build in dist/
npm run selftest # run ../matlab/cymbal2_validate.m through numbl in Node
The self-test runs the closed-form and reproducibility checks and the pinned diagnostics; the two full renders inside it make it take a few minutes. The MATLAB code can also be run directly: cd ../matlab && numbl run cymbal2_demo.m (or cymbal2_validate.m), and runs unchanged in MATLAB proper, where it is several times faster.
Where the time goes#
Everywhere. Unlike the sibling cymbal app, whose expensive stage (the eigensolves) could be cached and whose synthesis was an oscillator bank, here the sound is a nonlinear time-domain integration of the whole shell, several hundred thousand steps of coupled solves, and every parameter feeds it. There is therefore no debounced auto-render: the Render preview button runs a cheap pass (no oversampling, tail clamped to 1.5 s; the azimuthal grid is kept, because hard strokes diverge without the full wavenumber ladder), Render full runs the real thing, and both report elapsed time and can be cancelled. Expect tens of seconds for a preview and minutes for a full render in the browser; the only piece the worker caches is the cheap linear mode table that the spectrum plot overlays.
Reading and editing the code in the app#
The Code button opens the MATLAB source in a CodeMirror editor with MATLAB syntax highlighting. Every .m file in ../matlab is listed, tagged by whether the app executes it or it is a CLI entry point. The sources are editable and an edit takes effect on the next render, so the physics can be changed in place: setting the curvature term Rs large in cymbal2_system.m flattens the shell into a plate, and zeroing the Luu term in cymbal2_sim.m removes the stretching nonlinearity, leaving a linear shell that never crashes however hard it is hit.
Edits live in memory only. They are deliberately not persisted, so a reload restores the code the app shipped with; "Revert file" and "Revert all" undo them sooner, and a dot marks the files that differ from the shipped source. A fault in edited code is reported with its file and line, the last successful render stays on screen, and reverting recovers.