/ proof-of-concept / toy-instruments
Sign in
proof-of-concept / toy-instruments
toy-instruments
Go to fileHistoryFork
srcString of beads: 3D bead-spring solver, control panel, waveform, spectrogram, wav, displacement viewer
testString of beads: 3D bead-spring solver, control panel, waveform, spectrogram, wav, displacement viewer
.gitignoreString of beads: 3D bead-spring solver, control panel, waveform, spectrogram, wav, displacement viewer
index.htmlString of beads: 3D bead-spring solver, control panel, waveform, spectrogram, wav, displacement viewer
package-lock.jsonString of beads: 3D bead-spring solver, control panel, waveform, spectrogram, wav, displacement viewer
package.jsonString of beads: 3D bead-spring solver, control panel, waveform, spectrogram, wav, displacement viewer
README.mdString of beads: 3D bead-spring solver, control panel, waveform, spectrogram, wav, displacement viewer
tsconfig.jsonString of beads: 3D bead-spring solver, control panel, waveform, spectrogram, wav, displacement viewer
vite.config.tsString of beads: 3D bead-spring solver, control panel, waveform, spectrogram, wav, displacement viewer

toy-instruments#

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.

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

String of beads (first instrument)#

  • 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.
  • 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.
  • 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.
  • 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.
  • 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.
  • 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.
  • 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.

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.

Layout#

  • src/sim/ generic 3D bead-spring system, solver, worker.
  • src/instruments/<id>/ model (parameters to system), presets, page. Register new instruments in src/instruments/registry.ts.
  • src/ui/ reusable controls form, line plot, spectrogram, chain displacement viewer, FFT, WAV.
↑↓ move↵openescclose