3A physically-based simulation of a single woodblock strike, sampled as acoustic pressure at a point in space. The model chain is a Hunt-Crossley mallet contact driving the bending modes of a free-free bar, two-way coupled to a Helmholtz cavity, radiating through distributed surface dipoles and a slit monopole to a listener point, then decimated to 48 kHz.
5There is no microphone model: no directivity, no capsule response, no gain staging. The output is p(r, t) in pascals.
7## Contents
9| Path | What it is |
10|---|---|
11| `woodblock.md` | The specification: physics, equations, state vector, and the traps |
12| `woodblock.py` | Reference implementation (numpy + scipy), and the source of the validation numbers |
13| `matlab/` | The algorithm in MATLAB syntax, run by [numbl](https://numbl.org) |
a37be48Add instrument/: the woodblock behind the track-render interfaceJeremy Magland 14| `instrument/` | The model behind the track-render instrument interface used by [midiboot](../../proof-of-concept/midiboot) and by the web app (worker, note mapping, caching; `npm test` there runs the model in node) |
0bec915Add repository READMEJeremy Magland 15| `webapp/` | Interactive browser app that executes the MATLAB code client-side |
17The MATLAB code runs from the command line with `cd matlab && numbl run woodblock_demo.m`, or `woodblock_validate.m` to check it against the reference. The web app is a Vite project; see `webapp/README.md`.
19## Where the implementations differ
21`woodblock.py` is the reference; where it and the specification disagree, the script is right. The MATLAB implementation departs from it in one place, for speed: the system is nonlinear only while the mallet is in contact, so RK4 runs only until the mallet has provably separated, after which the linear body and cavity system is evolved in closed form from a single eigendecomposition, evaluated vectorized over the time axis. The free-phase solution is exact in time, and the two agree on every published diagnostic.
23The app's default mallet stiffness is 1.0e8, softer than the reference default of 3.0e8; the validation script pins the reference value when comparing.