// Validation against the Python reference (woodblock.py at defaults): // modes kept : 6 // partials Hz: 1003, 2766, 5423, 8964, 13390, 18702 // helmholtz : 484 Hz // contact : 0.301 ms, peak 794 N // peak press.: 6.132 Pa (109.7 dB SPL) // Run with: npm run selftest import { DEFAULTS } from '../params'; import { renderAll } from './render'; // The app's default mallet stiffness is softer than woodblock.py's; pin the // reference value here so the comparison against the Python output holds. const REFERENCE = { ...DEFAULTS, mallet_stiffness: 3.0e8 }; const t0 = performance.now(); const { y, basis, diag } = renderAll(REFERENCE); const t1 = performance.now(); console.log(`modes kept : ${basis.n}`); console.log('partials Hz: ' + Array.from(basis.f).map((f) => f.toFixed(0)).join(', ')); console.log('ratios : ' + Array.from(basis.f).map((f) => (f / basis.f[0]).toFixed(2)).join(', ')); console.log(`helmholtz : ${diag.helmholtzHz.toFixed(0)} Hz`); console.log(`contact : ${diag.contactMs.toFixed(3)} ms, peak ${diag.peakForceN.toFixed(0)} N`); console.log(`peak press.: ${diag.peakPa.toFixed(3)} Pa (${diag.peakSplDb.toFixed(1)} dB SPL)`); console.log(`length : ${(y.length / REFERENCE.sample_rate).toFixed(3)} s @ ${REFERENCE.sample_rate} Hz`); for (const w of diag.warnings) console.log(`WARNING : ${w}`); console.log(`render time: ${((t1 - t0) / 1000).toFixed(2)} s`); // Validation listener positions from the spec (ยง7), peak SPL targets. const targets: [number, number, number, number][] = [ [0.15, 0.25, 0.30, 109.7], [0.00, 0.00, 0.40, 100.9], [0.00, 0.40, 0.00, 90.9], [0.00, 0.05, 0.02, 125.4], ]; for (const [x, yy, z, target] of targets) { const cfg = { ...REFERENCE, listener_x_m: x, listener_y_m: yy, listener_z_m: z }; const r = renderAll(cfg); const ok = Math.abs(r.diag.peakSplDb - target) < 0.5 ? 'ok' : 'MISMATCH'; console.log(`listener (${x}, ${yy}, ${z}): ${r.diag.peakSplDb.toFixed(1)} dB SPL (target ${target}) ${ok}`); }