4a8abcfString of beads: 3D bead-spring solver, control panel, waveform, spectrogram, wav, displacement viewerJeremy Magland 1# toy-instruments
3A 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.
5```
6npm install
7npm run dev # http://localhost:5173
8npm test # vitest
9npm run build # static site in dist/
10```
12## String of beads (first instrument)
14- `n` point masses on springs with stiffness `k`, spacing `L` at equilibrium, pre-tension `T` (rest length `L0 = L - T/k`). Beads move in 3D and the springs are real (exact length), so geometric nonlinearity is kept: pitch glide at large amplitude, transverse-longitudinal coupling, whirling.
15- Ends: clamped (fixed point), sliding (massless ring on a rod: x fixed, free across, holds tension), or free (no support; only consistent with `T = 0`). Any bead can be pinned.
16- Excitation: pluck (triangle between the nearest supports, released at rest), strike (Gaussian initial velocity), hammer (raised-cosine force pulse). Direction is an angle in the y-z plane.
17- Damping from two decay times: `sigma(omega) = sigma0 + sigma1 omega^2`, fitted to T60 at two frequencies for transverse modes. `sigma0` is mass-proportional; `sigma1` is a dashpot on each spring's relative velocity.
18- Audio: pickup acceleration (forces / mass, at the full-step velocity), from one bead or summed over all beads, along y, z or x. The `.wav` is normalized to -1 dBFS.
19- Solver: velocity Verlet (explicit, symplectic without damping). `dt = cfl * 2 / omega_max` (Gershgorin bound with axial `k` and transverse `T/l`), rounded down to a whole number of steps per audio sample.
d2bfcd73D model view: setup (supports, pins, excitation, pickup) and replay of saved frames on a shared timelineJeremy Magland 20- 3D model view (three.js): Setup shows the beads at rest with supports (wall = clamped, translucent plane + ring = sliding), pinned beads (cubes), excitation (pluck shape, strike velocity arrows, hammer force arrows) and pickup (bead + axis arrow). Replay animates the saved frames ("Replay frames" per second, default 2000) with adjustable exaggeration, on a timeline shared with the 2D side/top views and space-time image.
4a8abcfString of beads: 3D bead-spring solver, control panel, waveform, spectrogram, wav, displacement viewerJeremy Magland 21- Checks shown per run: energy balance (energy + dissipated - work in - initial) relative to peak energy, largest strain. Linear transverse and longitudinal modes (Sturm bisection on the tridiagonal stiffness) are marked on the spectrum.
23Tests (`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.
25## Layout
27- `src/sim/` generic 3D bead-spring system, solver, worker.
28- `src/instruments/<id>/` model (parameters to system), presets, page. Register new instruments in `src/instruments/registry.ts`.
d2bfcd73D model view: setup (supports, pins, excitation, pickup) and replay of saved frames on a shared timelineJeremy Magland 29- `src/ui/` reusable controls form, line plot, spectrogram, chain displacement viewer, 3D scene, shared playback timeline, FFT, WAV.