/ simulated_instruments / woodblock
Sign in
simulated_instruments / woodblock
woodblock / webapp / src / physics / selftest.ts
42 lines · 2.0 KBCodeBlameHistory
982850fWoodblock strike simulator: Python reference model and interactive web appJeremy Magland 1// Validation against the Python reference (woodblock.py at defaults):
2// modes kept : 6
3// partials Hz: 1003, 2766, 5423, 8964, 13390, 18702
4// helmholtz : 484 Hz
5// contact : 0.301 ms, peak 794 N
6// peak press.: 6.132 Pa (109.7 dB SPL)
7// Run with: npm run selftest
9import { DEFAULTS } from '../params';
10import { renderAll } from './render';
12// The app's default mallet stiffness is softer than woodblock.py's; pin the
13// reference value here so the comparison against the Python output holds.
14const REFERENCE = { ...DEFAULTS, mallet_stiffness: 3.0e8 };
16const t0 = performance.now();
17const { y, basis, diag } = renderAll(REFERENCE);
18const t1 = performance.now();
20console.log(`modes kept : ${basis.n}`);
21console.log('partials Hz: ' + Array.from(basis.f).map((f) => f.toFixed(0)).join(', '));
22console.log('ratios : ' + Array.from(basis.f).map((f) => (f / basis.f[0]).toFixed(2)).join(', '));
23console.log(`helmholtz : ${diag.helmholtzHz.toFixed(0)} Hz`);
24console.log(`contact : ${diag.contactMs.toFixed(3)} ms, peak ${diag.peakForceN.toFixed(0)} N`);
25console.log(`peak press.: ${diag.peakPa.toFixed(3)} Pa (${diag.peakSplDb.toFixed(1)} dB SPL)`);
26console.log(`length : ${(y.length / REFERENCE.sample_rate).toFixed(3)} s @ ${REFERENCE.sample_rate} Hz`);
27for (const w of diag.warnings) console.log(`WARNING : ${w}`);
28console.log(`render time: ${((t1 - t0) / 1000).toFixed(2)} s`);
30// Validation listener positions from the spec (§7), peak SPL targets.
31const targets: [number, number, number, number][] = [
32 [0.15, 0.25, 0.30, 109.7],
33 [0.00, 0.00, 0.40, 100.9],
34 [0.00, 0.40, 0.00, 90.9],
35 [0.00, 0.05, 0.02, 125.4],
36];
37for (const [x, yy, z, target] of targets) {
38 const cfg = { ...REFERENCE, listener_x_m: x, listener_y_m: yy, listener_z_m: z };
39 const r = renderAll(cfg);
40 const ok = Math.abs(r.diag.peakSplDb - target) < 0.5 ? 'ok' : 'MISMATCH';
41 console.log(`listener (${x}, ${yy}, ${z}): ${r.diag.peakSplDb.toFixed(1)} dB SPL (target ${target}) ${ok}`);
↑↓ move↵openescclose