/ simulated_instruments / woodblock
Sign in
simulated_instruments / woodblock
woodblock / webapp / README.md
41 lines · 4.6 KBCodeBlameHistory
982850fWoodblock strike simulator: Python reference model and interactive web appJeremy Magland 1# Woodblock Simulator — web app
c5866daReimplement the algorithm in MATLAB syntax, run it with numblJeremy Magland 3Interactive browser implementation of the physical model specified in `../woodblock.md` (reference implementation: `../woodblock.py`). The algorithm itself is written in MATLAB syntax, in `../matlab/*.m`, and executed client-side by [numbl](https://numbl.org) 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.
5The signal chain: Hunt-Crossley mallet contact, free-free bar modes two-way coupled to a Helmholtz cavity, retarded-monopole radiation to the listener point, and Kaiser-windowed anti-aliased decimation to 48 kHz.
7## Usage
9```
10npm install
11npm run dev # development server
12npm run build # production build in dist/
c5866daReimplement the algorithm in MATLAB syntax, run it with numblJeremy Magland 13npm run selftest # run ../matlab/woodblock_validate.m through numbl in Node
c5866daReimplement the algorithm in MATLAB syntax, run it with numblJeremy Magland 16The self-test reproduces the woodblock.py reference diagnostics (contact 0.301 ms at 794 N, 6.132 Pa / 109.7 dB SPL at the default listener) and the four validation listener positions from `woodblock.md` §7. The MATLAB code can also be run directly: `cd ../matlab && numbl run woodblock_demo.m` (or `woodblock_validate.m`).
18## The solver
20The reference implementation integrates the whole strike with RK4. The MATLAB implementation instead exploits that the system is nonlinear only while the mallet is in contact (a fraction of a millisecond): it runs RK4 until the mallet has provably separated (receding, and further from the surface than a bound derived from the current modal energy), then evolves the remaining coupled linear body+cavity system in closed form from one eigendecomposition of the (2N+2) system matrix, evaluated vectorized over the time axis. The free-phase solution is exact in time, and the results match the reference to display precision on every published diagnostic.
22## Reading and editing the code in the app
4152426Explicit preview and full renders, as in the cymbal2 appJeremy Magland 24The 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: an edit takes effect on the next render, so changing the physics in the editor is heard and plotted the same way moving a slider is. Editing `sqrt(12)` to `sqrt(48)` in the pitch prefactor, for instance, halves every partial.
4152426Explicit preview and full renders, as in the cymbal2 appJeremy Magland 26Edits 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 (numbl skips a file it cannot parse and then fails at the call site, so the worker captures the parse warning and reports that instead), the failed render leaves nothing playable, so Play and Download go dead until a render succeeds, and reverting recovers.
28## How rendering is tiered
4152426Explicit preview and full renders, as in the cymbal2 appJeremy Magland 30Nothing renders on its own: the Render preview button runs a fast pass (oversample 8, 24 radiating elements), Render full runs the full-quality pass (oversample 16, 48 elements), and either can be cancelled while it runs. The status shows the stage, a progress bar and the elapsed time. While the current result is a preview, the Play and Download buttons and the status badge say so. The worker runs each stage as a separate numbl execution and keys its caches by tier: geometry, material, damping, mallet, and cavity parameters invalidate the solve; listener and slit positions and block height only re-run radiation; pre-delay, normalization, and bit depth only re-run the output stage. Intermediate tensors stay inside the worker as numbl RuntimeValues. Moving the microphone after a full render reuses the cached solve and returns a full-quality result.
4152426Explicit preview and full renders, as in the cymbal2 appJeremy Magland 32The Loop button repeats the last render continuously, swapping in each new render as it completes. Parameters persist in localStorage; "Reset to defaults" restores the values in `src/params.ts` (which `../matlab/woodblock_defaults.m` mirrors).
34## Layout
c5866daReimplement the algorithm in MATLAB syntax, run it with numblJeremy Magland 36- `../matlab/` — the algorithm: `woodblock_basis.m`, `woodblock_solve.m`, `woodblock_radiate.m`, `woodblock_output.m`, plus `woodblock_render.m` / `woodblock_demo.m` / `woodblock_validate.m` for CLI use
982850fWoodblock strike simulator: Python reference model and interactive web appJeremy Magland 37- `src/params.ts` — parameter schema, defaults, tier assignment, persistence
c5866daReimplement the algorithm in MATLAB syntax, run it with numblJeremy Magland 38- `src/mfiles.ts` — the `.m` sources, bundled at build time and hashed for cache keying
39- `src/worker/renderWorker.ts` — off-thread numbl execution with tiered caching
40- `src/components/` — 3D scene (three.js), parameter panel, code panel and editor, plots (waveform, spectrum, spectrogram, contact force, animated mode shapes)
41- `src/selftest.ts` — Node harness for the MATLAB validation script
↑↓ move↵openescclose