# Waves and sound: the wave equation, and what its errors sound like An interactive tutorial on the wave equation in acoustics, for strings, drums and rooms, with every method written as a MATLAB-syntax script that you can edit and run in the page, and almost every result playable as sound. It runs in your browser through [numbl](https://numbl.org); there is no server, nothing to install, and nothing is sent anywhere. The organising idea is the one shared with the sibling tutorials on the Dirichlet problem and on particle filters: every problem has an answer that is known exactly, so the error of every computation is known exactly too, and what is measured is what accuracy a method delivers for what cost. What is particular to this one is the unit of error. Numerical errors in acoustics are heard, so they are measured as a listener would notice them, as a pitch error in cents or a level in decibels, and each lab lets the reader listen to the exact answer, the computed one and, often, their difference. ## Where the exact answers come from **Modes.** The string, the rectangle and the disk separate, and their standing waves are known in closed form: sines, and Bessel functions whose zeros the shared library computes to rounding error. **d'Alembert's solution.** For the string, a sum of two travelling waves that shares no algebra with the modal sum; Chapter 1 checks each against the other. **Images.** A rectangular room with rigid walls is exactly free space with a lattice of mirror-image sources (Chapters 8 and 9). **Causality.** An explicit scheme on a grid larger by M + 2 nodes on every side cannot feel its own edges for M steps, so inside the region of interest it is the scheme's exact free-space solution (Chapter 7). ## The chapters **Introduction**: the acoustic wave equation and its boundary conditions, the four sources of exact answers, and why errors are measured in cents. **Strings** 1. **Sound from an exact solution**: the plucked string by d'Alembert and by Fourier, the gaps a pluck leaves in the harmonic series, and the aliasing that sampling an exact, non-band-limited solution produces: from −26 dB at A2 to −11 dB at E7 for the bridge force, predicted in closed form. 2. **Leapfrog, and the magic time step**: the CFL limit, the Courant number 1 at which the scheme is exact to rounding error over 110,000 steps, the pitch of every partial measured and matching the dispersion relation to 10⁻⁷ cents, and the sound of numerical dispersion as a click travels round a loop of tube. 3. **The digital waveguide**: the exact scheme without its grid, several hundred times faster at 3200 nodes; Karplus–Strong, its f⁻³ decay law, and a tuning error of up to 47 cents that fractional delays reduce below one cent. **Drums** 4. **A square drum**: an inharmonic spectrum, a stability limit of 1/√2, no magic time step, and a pitch error that depends on the direction of travel. 5. **Fewer points per wavelength**: fourth order in space only (a trap: second order in the end), and fourth order in space and time by the modified-equation method, about five times cheaper at 5 cents and fifteen at 1 cent. 6. **A round drum on a square grid**: Bessel modes and what they sound like, a staircase rim that is first-order and erratic, and a Shortley–Weller rim that is second-order at a price paid in time step. **Rooms** 7. **Letting sound out**: a rigid wall, Mur's condition (−23 dB), a damping layer (−21 dB at 40 nodes) and a perfectly matched layer (−62 dB at 5 nodes, −107 at 40), against a reference exact by causality, and heard. 8. **A room, by image sources**: impulse responses, auralisation by convolution, and reverberation time measured against Sabine, Eyring and the lattice prediction that the image model implies, which is Eyring times a room-shape factor of 1.17. 9. **A room, by finite differences**: 3-D leapfrog converging at second order to the exact image sum for rigid walls, and the fourth-power cost law that puts one second of full-band sound in an 81 m³ room at about seven years of computation. A **shared MATLAB library** page lists the function files every lab boots with. ## Using it Each lab has controls above its figures and, behind the "show script" button, the method itself. Edit the script and press run: the session reboots with your version compiled in, and the figures and sounds are whatever your code produces. Ctrl-Enter (Cmd-Enter) runs from inside the editor, and "reset" restores the original. Some labs run as soon as the chapter opens; the heavier ones wait for the run button, which the caption says. Start listening with the volume low. ## Requirements numbl **0.4.21 or later** (the version this was developed and tested against). See [CLAUDE.md](CLAUDE.md) for the numbl performance rules the scripts are written around. ## Development ``` npm install npm run dev # vite dev server npm run build # typecheck and bundle to dist/ npm run test:matlab # the .m layer, through the numbl CLI (needs a numbl checkout); about 90 s npm run test:browser # the built app in headless Chrome npm run figures # one screenshot per static figure, into tmp/figs/ npm run test:site # the deployed site, in headless Chrome ``` `test:matlab` needs a numbl clone; set `NUMBL_DIR` if it is not at `~/src/numbl`, and build its CLI (`npm run build:cli` in that checkout) after updating it. Every assertion in it is a number claimed somewhere in the prose, so a failure means either the code or the text is wrong. `test:browser` needs `npm run build` first, and takes `--shots` to write a full-page screenshot of each chapter into `tmp/`, and `--only ` to run one chapter. ## Deployment `.mochi/workflows/deploy.yml` builds the page on every push to `main` and publishes it as the repository's site on the vault, at `/tutorials/wave-acoustics/site/`. The build is a plain `npm ci && npm run build`; `vite.config.ts` uses a relative `base`, so the sub-path needs no configuration. The vault serves sites sandboxed, which makes `localStorage` throw rather than degrade: nothing here touches it. `npm run test:site` loads the deployed page, checks that numbl runs there and that the audio player starts, which serving the build locally cannot tell you. ## Licence Apache-2.0.